Browse Source

Use net_device_operations structure and netdev_nullify() to allow for

safe dropping of the netdev ref by the driver while other refs still
exist.

Add netdev_irq() method.  Net device open()/close() methods should no
longer enable or disable IRQs.

Remove rx_quota; it wasn't used anywhere and added too much complexity
to implementing correct interrupt-masking behaviour in pxe_undi.c.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
4c418d2100

+ 28
- 10
src/arch/i386/drivers/net/undinet.c View File

394
  * Poll for received packets
394
  * Poll for received packets
395
  *
395
  *
396
  * @v netdev		Network device
396
  * @v netdev		Network device
397
- * @v rx_quota		Maximum number of packets to receive
398
  *
397
  *
399
  * Fun, fun, fun.  UNDI drivers don't use polling; they use
398
  * Fun, fun, fun.  UNDI drivers don't use polling; they use
400
  * interrupts.  We therefore cheat and pretend that an interrupt has
399
  * interrupts.  We therefore cheat and pretend that an interrupt has
412
  * of installing a genuine interrupt service routine and dealing with
411
  * of installing a genuine interrupt service routine and dealing with
413
  * the wonderful 8259 Programmable Interrupt Controller.  Joy.
412
  * the wonderful 8259 Programmable Interrupt Controller.  Joy.
414
  */
413
  */
415
-static void undinet_poll ( struct net_device *netdev, unsigned int rx_quota ) {
414
+static void undinet_poll ( struct net_device *netdev ) {
416
 	struct undi_nic *undinic = netdev->priv;
415
 	struct undi_nic *undinic = netdev->priv;
417
 	struct s_PXENV_UNDI_ISR undi_isr;
416
 	struct s_PXENV_UNDI_ISR undi_isr;
418
 	struct io_buffer *iobuf = NULL;
417
 	struct io_buffer *iobuf = NULL;
454
 	}
453
 	}
455
 
454
 
456
 	/* Run through the ISR loop */
455
 	/* Run through the ISR loop */
457
-	while ( rx_quota ) {
456
+	while ( 1 ) {
458
 		if ( ( rc = undinet_call ( undinic, PXENV_UNDI_ISR, &undi_isr,
457
 		if ( ( rc = undinet_call ( undinic, PXENV_UNDI_ISR, &undi_isr,
459
 					   sizeof ( undi_isr ) ) ) != 0 )
458
 					   sizeof ( undi_isr ) ) ) != 0 )
460
 			break;
459
 			break;
487
 				/* Whole packet received; deliver it */
486
 				/* Whole packet received; deliver it */
488
 				netdev_rx ( netdev, iobuf );
487
 				netdev_rx ( netdev, iobuf );
489
 				iobuf = NULL;
488
 				iobuf = NULL;
490
-				--rx_quota;
491
 				/* Etherboot 5.4 fails to return all packets
489
 				/* Etherboot 5.4 fails to return all packets
492
 				 * under mild load; pretend it retriggered.
490
 				 * under mild load; pretend it retriggered.
493
 				 */
491
 				 */
599
 	DBGC ( undinic, "UNDINIC %p closed\n", undinic );
597
 	DBGC ( undinic, "UNDINIC %p closed\n", undinic );
600
 }
598
 }
601
 
599
 
600
+/**
601
+ * Enable/disable interrupts
602
+ *
603
+ * @v netdev		Net device
604
+ * @v enable		Interrupts should be enabled
605
+ */
606
+static void undinet_irq ( struct net_device *netdev, int enable ) {
607
+	struct undi_nic *undinic = netdev->priv;
608
+
609
+	/* Cannot support interrupts yet */
610
+	DBGC ( undinic, "UNDINIC %p cannot %s interrupts\n",
611
+	       undinic, ( enable ? "enable" : "disable" ) );
612
+}
613
+
614
+/** UNDI network device operations */
615
+static struct net_device_operations undinet_operations = {
616
+	.open		= undinet_open,
617
+	.close		= undinet_close,
618
+	.transmit	= undinet_transmit,
619
+	.poll		= undinet_poll,
620
+	.irq   		= undinet_irq,
621
+};
622
+
602
 /**
623
 /**
603
  * Probe UNDI device
624
  * Probe UNDI device
604
  *
625
  *
622
 	netdev = alloc_etherdev ( sizeof ( *undinic ) );
643
 	netdev = alloc_etherdev ( sizeof ( *undinic ) );
623
 	if ( ! netdev )
644
 	if ( ! netdev )
624
 		return -ENOMEM;
645
 		return -ENOMEM;
646
+	netdev_init ( netdev, &undinet_operations );
625
 	undinic = netdev->priv;
647
 	undinic = netdev->priv;
626
 	undi_set_drvdata ( undi, netdev );
648
 	undi_set_drvdata ( undi, netdev );
627
 	netdev->dev = &undi->dev;
649
 	netdev->dev = &undi->dev;
685
 		undinic->hacks |= UNDI_HACK_EB54;
707
 		undinic->hacks |= UNDI_HACK_EB54;
686
 	}
708
 	}
687
 
709
 
688
-	/* Point to NIC specific routines */
689
-	netdev->open	 = undinet_open;
690
-	netdev->close	 = undinet_close;
691
-	netdev->transmit = undinet_transmit;
692
-	netdev->poll	 = undinet_poll;
693
-
694
 	/* Register network device */
710
 	/* Register network device */
695
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
711
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
696
 		goto err_register;
712
 		goto err_register;
716
 	undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
732
 	undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
717
 		       sizeof ( stop_undi ) );
733
 		       sizeof ( stop_undi ) );
718
  err_start_undi:
734
  err_start_undi:
735
+	netdev_nullify ( netdev );
719
 	netdev_put ( netdev );
736
 	netdev_put ( netdev );
720
 	undi_set_drvdata ( undi, NULL );
737
 	undi_set_drvdata ( undi, NULL );
721
 	return rc;
738
 	return rc;
751
 	undi->flags &= ~UNDI_FL_STARTED;
768
 	undi->flags &= ~UNDI_FL_STARTED;
752
 
769
 
753
 	/* Free network device */
770
 	/* Free network device */
771
+	netdev_nullify ( netdev );
754
 	netdev_put ( netdev );
772
 	netdev_put ( netdev );
755
 
773
 
756
 	DBGC ( undinic, "UNDINIC %p removed\n", undinic );
774
 	DBGC ( undinic, "UNDINIC %p removed\n", undinic );

+ 30
- 21
src/drivers/net/legacy.c View File

36
 	return 0;
36
 	return 0;
37
 }
37
 }
38
 
38
 
39
-static void legacy_poll ( struct net_device *netdev, unsigned int rx_quota ) {
39
+static void legacy_poll ( struct net_device *netdev ) {
40
 	struct nic *nic = netdev->priv;
40
 	struct nic *nic = netdev->priv;
41
 	struct io_buffer *iobuf;
41
 	struct io_buffer *iobuf;
42
 
42
 
43
-	if ( ! rx_quota )
44
-		return;
45
-
46
 	iobuf = alloc_iob ( ETH_FRAME_LEN );
43
 	iobuf = alloc_iob ( ETH_FRAME_LEN );
47
 	if ( ! iobuf )
44
 	if ( ! iobuf )
48
 		return;
45
 		return;
57
 	}
54
 	}
58
 }
55
 }
59
 
56
 
60
-static int legacy_open ( struct net_device *netdev ) {
61
-	struct nic *nic = netdev->priv;
62
-
63
-	nic->nic_op->irq ( nic, ENABLE );
57
+static int legacy_open ( struct net_device *netdev __unused ) {
58
+	/* Nothing to do */
64
 	return 0;
59
 	return 0;
65
 }
60
 }
66
 
61
 
67
-static void legacy_close ( struct net_device *netdev ) {
62
+static void legacy_close ( struct net_device *netdev __unused ) {
63
+	/* Nothing to do */
64
+}
65
+
66
+static void legacy_irq ( struct net_device *netdev __unused, int enable ) {
68
 	struct nic *nic = netdev->priv;
67
 	struct nic *nic = netdev->priv;
69
 
68
 
70
-	nic->nic_op->irq ( nic, DISABLE );
69
+	nic->nic_op->irq ( nic, ( enable ? ENABLE : DISABLE ) );
71
 }
70
 }
72
 
71
 
72
+static struct net_device_operations legacy_operations = {
73
+	.open		= legacy_open,
74
+	.close		= legacy_close,
75
+	.transmit	= legacy_transmit,
76
+	.poll		= legacy_poll,
77
+	.irq   		= legacy_irq,
78
+};
79
+
73
 int legacy_probe ( void *hwdev,
80
 int legacy_probe ( void *hwdev,
74
 		   void ( * set_drvdata ) ( void *hwdev, void *priv ),
81
 		   void ( * set_drvdata ) ( void *hwdev, void *priv ),
75
 		   struct device *dev,
82
 		   struct device *dev,
84
 	netdev = alloc_etherdev ( 0 );
91
 	netdev = alloc_etherdev ( 0 );
85
 	if ( ! netdev )
92
 	if ( ! netdev )
86
 		return -ENOMEM;
93
 		return -ENOMEM;
94
+	netdev_init ( netdev, &legacy_operations );
87
 	netdev->priv = &nic;
95
 	netdev->priv = &nic;
88
 	memset ( &nic, 0, sizeof ( nic ) );
96
 	memset ( &nic, 0, sizeof ( nic ) );
89
 	set_drvdata ( hwdev, netdev );
97
 	set_drvdata ( hwdev, netdev );
90
 	netdev->dev = dev;
98
 	netdev->dev = dev;
91
 
99
 
92
-	netdev->open = legacy_open;
93
-	netdev->close = legacy_close;
94
-	netdev->transmit = legacy_transmit;
95
-	netdev->poll = legacy_poll;
96
 	nic.node_addr = netdev->ll_addr;
100
 	nic.node_addr = netdev->ll_addr;
97
 
101
 
98
 	if ( ! probe ( &nic, hwdev ) ) {
102
 	if ( ! probe ( &nic, hwdev ) ) {
99
-		netdev_put ( netdev );
100
-		return -ENODEV;
103
+		rc = -ENODEV;
104
+		goto err_probe;
101
 	}
105
 	}
102
 
106
 
103
-	if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
104
-		disable ( &nic, hwdev );
105
-		netdev_put ( netdev );
106
-		return rc;
107
-	}
107
+	if ( ( rc = register_netdev ( netdev ) ) != 0 )
108
+		goto err_register;
108
 
109
 
109
 	/* Do not remove this message */
110
 	/* Do not remove this message */
110
 	printf ( "WARNING: Using legacy NIC wrapper on %s\n",
111
 	printf ( "WARNING: Using legacy NIC wrapper on %s\n",
112
 
113
 
113
 	legacy_registered = 1;
114
 	legacy_registered = 1;
114
 	return 0;
115
 	return 0;
116
+
117
+ err_register:
118
+	disable ( &nic, hwdev );
119
+ err_probe:
120
+	netdev_nullify ( netdev );
121
+	netdev_put ( netdev );
122
+	return rc;
115
 }
123
 }
116
 
124
 
117
 void legacy_remove ( void *hwdev,
125
 void legacy_remove ( void *hwdev,
122
 
130
 
123
 	unregister_netdev ( netdev );
131
 	unregister_netdev ( netdev );
124
 	disable ( nic, hwdev );
132
 	disable ( nic, hwdev );
133
+	netdev_nullify ( netdev );
125
 	netdev_put ( netdev );
134
 	netdev_put ( netdev );
126
 	legacy_registered = 0;
135
 	legacy_registered = 0;
127
 }
136
 }

+ 34
- 27
src/drivers/net/pnic.c View File

112
 /**************************************************************************
112
 /**************************************************************************
113
 POLL - Wait for a frame
113
 POLL - Wait for a frame
114
 ***************************************************************************/
114
 ***************************************************************************/
115
-static void pnic_poll ( struct net_device *netdev, unsigned int rx_quota ) {
115
+static void pnic_poll ( struct net_device *netdev ) {
116
 	struct pnic *pnic = netdev->priv;
116
 	struct pnic *pnic = netdev->priv;
117
 	struct io_buffer *iobuf;
117
 	struct io_buffer *iobuf;
118
 	uint16_t length;
118
 	uint16_t length;
119
 	uint16_t qlen;
119
 	uint16_t qlen;
120
 
120
 
121
 	/* Fetch all available packets */
121
 	/* Fetch all available packets */
122
-	while ( rx_quota ) {
122
+	while ( 1 ) {
123
 		if ( pnic_command ( pnic, PNIC_CMD_RECV_QLEN, NULL, 0,
123
 		if ( pnic_command ( pnic, PNIC_CMD_RECV_QLEN, NULL, 0,
124
 				    &qlen, sizeof ( qlen ), NULL )
124
 				    &qlen, sizeof ( qlen ), NULL )
125
 		     != PNIC_STATUS_OK )
125
 		     != PNIC_STATUS_OK )
126
-			break;
126
+			return;
127
 		if ( qlen == 0 )
127
 		if ( qlen == 0 )
128
-			break;
128
+			return;
129
 		iobuf = alloc_iob ( ETH_FRAME_LEN );
129
 		iobuf = alloc_iob ( ETH_FRAME_LEN );
130
 		if ( ! iobuf ) {
130
 		if ( ! iobuf ) {
131
 			DBG ( "could not allocate buffer\n" );
131
 			DBG ( "could not allocate buffer\n" );
132
 			netdev_rx_err ( netdev, NULL, -ENOMEM );
132
 			netdev_rx_err ( netdev, NULL, -ENOMEM );
133
-			break;
133
+			return;
134
 		}
134
 		}
135
 		if ( pnic_command ( pnic, PNIC_CMD_RECV, NULL, 0,
135
 		if ( pnic_command ( pnic, PNIC_CMD_RECV, NULL, 0,
136
 				    iobuf->data, ETH_FRAME_LEN, &length )
136
 				    iobuf->data, ETH_FRAME_LEN, &length )
137
 		     != PNIC_STATUS_OK ) {
137
 		     != PNIC_STATUS_OK ) {
138
 			netdev_rx_err ( netdev, iobuf, -EIO );
138
 			netdev_rx_err ( netdev, iobuf, -EIO );
139
-			break;
139
+			return;
140
 		}
140
 		}
141
 		iob_put ( iobuf, length );
141
 		iob_put ( iobuf, length );
142
 		netdev_rx ( netdev, iobuf );
142
 		netdev_rx ( netdev, iobuf );
143
-		--rx_quota;
144
 	}
143
 	}
145
 }
144
 }
146
 
145
 
164
 /**************************************************************************
163
 /**************************************************************************
165
 OPEN - Open network device
164
 OPEN - Open network device
166
 ***************************************************************************/
165
 ***************************************************************************/
167
-static int pnic_open ( struct net_device *netdev ) {
168
-	struct pnic *pnic = netdev->priv;
169
-	static const uint8_t enable = 1;
170
-
171
-	/* Enable interrupts */
172
-	pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &enable,
173
-		       sizeof ( enable ), NULL, 0, NULL );
174
-	
166
+static int pnic_open ( struct net_device *netdev __unused ) {
167
+	/* Nothing to do */
175
 	return 0;
168
 	return 0;
176
 }
169
 }
177
 
170
 
178
 /**************************************************************************
171
 /**************************************************************************
179
 CLOSE - Close network device
172
 CLOSE - Close network device
180
 ***************************************************************************/
173
 ***************************************************************************/
181
-static void pnic_close ( struct net_device *netdev ) {
182
-	struct pnic *pnic = netdev->priv;
183
-	static const uint8_t disable = 0;
174
+static void pnic_close ( struct net_device *netdev __unused ) {
175
+	/* Nothing to do */
176
+}
184
 
177
 
185
-	/* Disable interrupts */
186
-	pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &disable,
187
-		       sizeof ( disable ), NULL, 0, NULL );
178
+/**************************************************************************
179
+IRQ - Enable/disable interrupts
180
+***************************************************************************/
181
+static void pnic_irq ( struct net_device *netdev, int enable ) {
182
+	struct pnic *pnic = netdev->priv;
183
+	uint8_t mask = ( enable ? 1 : 0 );
184
+	
185
+	pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &mask, sizeof ( mask ),
186
+		       NULL, 0, NULL );
188
 }
187
 }
189
 
188
 
189
+/**************************************************************************
190
+OPERATIONS TABLE
191
+***************************************************************************/
192
+static struct net_device_operations pnic_operations = {
193
+	.open		= pnic_open,
194
+	.close		= pnic_close,
195
+	.transmit	= pnic_transmit,
196
+	.poll		= pnic_poll,
197
+	.irq   		= pnic_irq,
198
+};
199
+
190
 /**************************************************************************
200
 /**************************************************************************
191
 DISABLE - Turn off ethernet interface
201
 DISABLE - Turn off ethernet interface
192
 ***************************************************************************/
202
 ***************************************************************************/
196
 
206
 
197
 	unregister_netdev ( netdev );
207
 	unregister_netdev ( netdev );
198
 	pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL );
208
 	pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL );
209
+	netdev_nullify ( netdev );
199
 	netdev_put ( netdev );
210
 	netdev_put ( netdev );
200
 }
211
 }
201
 
212
 
214
 	netdev = alloc_etherdev ( sizeof ( *pnic ) );
225
 	netdev = alloc_etherdev ( sizeof ( *pnic ) );
215
 	if ( ! netdev )
226
 	if ( ! netdev )
216
 		return -ENOMEM;
227
 		return -ENOMEM;
228
+	netdev_init ( netdev, &pnic_operations );
217
 	pnic = netdev->priv;
229
 	pnic = netdev->priv;
218
 	pci_set_drvdata ( pci, netdev );
230
 	pci_set_drvdata ( pci, netdev );
219
 	netdev->dev = &pci->dev;
231
 	netdev->dev = &pci->dev;
238
 	status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0,
250
 	status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0,
239
 				netdev->ll_addr, ETH_ALEN, NULL );
251
 				netdev->ll_addr, ETH_ALEN, NULL );
240
 
252
 
241
-	/* Point to NIC specific routines */
242
-	netdev->open	 = pnic_open;
243
-	netdev->close	 = pnic_close;
244
-	netdev->poll	 = pnic_poll;
245
-	netdev->transmit = pnic_transmit;
246
-
247
 	/* Register network device */
253
 	/* Register network device */
248
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
254
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
249
 		goto err;
255
 		goto err;
252
 
258
 
253
  err:
259
  err:
254
 	/* Free net device */
260
 	/* Free net device */
261
+	netdev_nullify ( netdev );
255
 	netdev_put ( netdev );
262
 	netdev_put ( netdev );
256
 	return rc;
263
 	return rc;
257
 }
264
 }

+ 28
- 20
src/drivers/net/rtl8139.c View File

302
  */
302
  */
303
 static void rtl_reset ( struct rtl8139_nic *rtl ) {
303
 static void rtl_reset ( struct rtl8139_nic *rtl ) {
304
 
304
 
305
-	/* Disable interrupts.  May not be necessary, but datasheet
306
-	 * doesn't say that the reset command also resets the
307
-	 * interrupt mask.
308
-	 */
309
-	outw ( 0, rtl->ioaddr + IntrMask );
310
-
311
 	/* Reset chip */
305
 	/* Reset chip */
312
 	outb ( CmdReset, rtl->ioaddr + ChipCmd );
306
 	outb ( CmdReset, rtl->ioaddr + ChipCmd );
313
 	mdelay ( 10 );
307
 	mdelay ( 10 );
346
 	outl ( ( ( TX_DMA_BURST << 8 ) | ( TX_IPG << 24 ) ),
340
 	outl ( ( ( TX_DMA_BURST << 8 ) | ( TX_IPG << 24 ) ),
347
 	       rtl->ioaddr + TxConfig );
341
 	       rtl->ioaddr + TxConfig );
348
 
342
 
349
-	/* Enable interrupts */
350
-	outw ( ( ROK | RER | TOK | TER ), rtl->ioaddr + IntrMask );
351
-
352
 	return 0;
343
 	return 0;
353
 }
344
 }
354
 
345
 
400
 	return 0;
391
 	return 0;
401
 }
392
 }
402
 
393
 
403
-/** 
394
+/**
404
  * Poll for received packets
395
  * Poll for received packets
405
  *
396
  *
406
  * @v netdev	Network device
397
  * @v netdev	Network device
407
- * @v rx_quota	Maximum number of packets to receive
408
  */
398
  */
409
-static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) {
399
+static void rtl_poll ( struct net_device *netdev ) {
410
 	struct rtl8139_nic *rtl = netdev->priv;
400
 	struct rtl8139_nic *rtl = netdev->priv;
411
 	unsigned int status;
401
 	unsigned int status;
412
 	unsigned int tsad;
402
 	unsigned int tsad;
433
 	}
423
 	}
434
 
424
 
435
 	/* Handle received packets */
425
 	/* Handle received packets */
436
-	while ( rx_quota && ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ){
426
+	while ( ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ) {
437
 		rx_status = * ( ( uint16_t * )
427
 		rx_status = * ( ( uint16_t * )
438
 				( rtl->rx.ring + rtl->rx.offset ) );
428
 				( rtl->rx.ring + rtl->rx.offset ) );
439
 		rx_len = * ( ( uint16_t * )
429
 		rx_len = * ( ( uint16_t * )
461
 				 rtl->rx.ring, wrapped_len );
451
 				 rtl->rx.ring, wrapped_len );
462
 
452
 
463
 			netdev_rx ( netdev, rx_iob );
453
 			netdev_rx ( netdev, rx_iob );
464
-			rx_quota--;
465
 		} else {
454
 		} else {
466
 			DBG ( "RX bad packet (status %#04x len %d)\n",
455
 			DBG ( "RX bad packet (status %#04x len %d)\n",
467
 			      rx_status, rx_len );
456
 			      rx_status, rx_len );
473
 	}
462
 	}
474
 }
463
 }
475
 
464
 
465
+/**
466
+ * Enable/disable interrupts
467
+ *
468
+ * @v netdev	Network device
469
+ * @v enable	Interrupts should be enabled
470
+ */
471
+static void rtl_irq ( struct net_device *netdev, int enable ) {
472
+	struct rtl8139_nic *rtl = netdev->priv;
473
+	
474
+	outw ( ( enable ? ( ROK | RER | TOK | TER ) : 0 ),
475
+	       rtl->ioaddr + IntrMask );
476
+}
477
+
478
+/** RTL8139 net device operations */
479
+static struct net_device_operations rtl_operations = {
480
+	.open		= rtl_open,
481
+	.close		= rtl_close,
482
+	.transmit	= rtl_transmit,
483
+	.poll		= rtl_poll,
484
+	.irq		= rtl_irq,
485
+};
486
+
476
 /**
487
 /**
477
  * Probe PCI device
488
  * Probe PCI device
478
  *
489
  *
490
 	netdev = alloc_etherdev ( sizeof ( *rtl ) );
501
 	netdev = alloc_etherdev ( sizeof ( *rtl ) );
491
 	if ( ! netdev )
502
 	if ( ! netdev )
492
 		return -ENOMEM;
503
 		return -ENOMEM;
504
+	netdev_init ( netdev, &rtl_operations );
493
 	rtl = netdev->priv;
505
 	rtl = netdev->priv;
494
 	pci_set_drvdata ( pci, netdev );
506
 	pci_set_drvdata ( pci, netdev );
495
 	netdev->dev = &pci->dev;
507
 	netdev->dev = &pci->dev;
504
 	rtl_init_eeprom ( rtl );
516
 	rtl_init_eeprom ( rtl );
505
 	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
517
 	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
506
 	
518
 	
507
-	/* Point to NIC specific routines */
508
-	netdev->open	 = rtl_open;
509
-	netdev->close	 = rtl_close;
510
-	netdev->transmit = rtl_transmit;
511
-	netdev->poll	 = rtl_poll;
512
-
513
 	/* Register network device */
519
 	/* Register network device */
514
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
520
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
515
 		goto err_register_netdev;
521
 		goto err_register_netdev;
526
 	unregister_netdev ( netdev );
532
 	unregister_netdev ( netdev );
527
  err_register_netdev:
533
  err_register_netdev:
528
 	rtl_reset ( rtl );
534
 	rtl_reset ( rtl );
535
+	netdev_nullify ( netdev );
529
 	netdev_put ( netdev );
536
 	netdev_put ( netdev );
530
 	return rc;
537
 	return rc;
531
 }
538
 }
543
 		nvo_unregister ( &rtl->nvo );
550
 		nvo_unregister ( &rtl->nvo );
544
 	unregister_netdev ( netdev );
551
 	unregister_netdev ( netdev );
545
 	rtl_reset ( rtl );
552
 	rtl_reset ( rtl );
553
+	netdev_nullify ( netdev );
546
 	netdev_put ( netdev );
554
 	netdev_put ( netdev );
547
 }
555
 }
548
 
556
 

+ 77
- 43
src/include/gpxe/netdevice.h View File

128
 	const uint8_t *ll_broadcast;
128
 	const uint8_t *ll_broadcast;
129
 };
129
 };
130
 
130
 
131
-/**
132
- * Network device statistics
133
- *
134
- */
135
-struct net_device_stats {
136
-	/** Count of successfully completed transmissions */
137
-	unsigned int tx_ok;
138
-	/** Count of transmission errors */
139
-	unsigned int tx_err;
140
-	/** Count of successfully received packets */
141
-	unsigned int rx_ok;
142
-	/** Count of reception errors */
143
-	unsigned int rx_err;
144
-};
145
-
146
-/**
147
- * A network device
148
- *
149
- * This structure represents a piece of networking hardware.  It has
150
- * properties such as a link-layer address and methods for
151
- * transmitting and receiving raw packets.
152
- *
153
- * Note that this structure must represent a generic network device,
154
- * not just an Ethernet device.
155
- */
156
-struct net_device {
157
-	/** Reference counter */
158
-	struct refcnt refcnt;
159
-	/** List of network devices */
160
-	struct list_head list;
161
-	/** Name of this network device */
162
-	char name[8];
163
-	/** Underlying hardware device */
164
-	struct device *dev;
165
-
131
+/** Network device operations */
132
+struct net_device_operations {
166
 	/** Open network device
133
 	/** Open network device
167
 	 *
134
 	 *
168
 	 * @v netdev	Network device
135
 	 * @v netdev	Network device
199
 	 * This method is guaranteed to be called only when the device
166
 	 * This method is guaranteed to be called only when the device
200
 	 * is open.
167
 	 * is open.
201
 	 */
168
 	 */
202
-	int ( * transmit ) ( struct net_device *netdev, struct io_buffer *iobuf );
203
-	/** Poll for received packet
169
+	int ( * transmit ) ( struct net_device *netdev,
170
+			     struct io_buffer *iobuf );
171
+	/** Poll for completed and received packets
204
 	 *
172
 	 *
205
 	 * @v netdev	Network device
173
 	 * @v netdev	Network device
206
-	 * @v rx_quota	Maximum number of packets to receive
207
 	 *
174
 	 *
208
-	 * This method should cause the hardware to check for received
209
-	 * packets.  Any received packets should be delivered via
210
-	 * netdev_rx(), up to a maximum of @c rx_quota packets.
175
+	 * This method should cause the hardware to check for
176
+	 * completed transmissions and received packets.  Any received
177
+	 * packets should be delivered via netdev_rx().
211
 	 *
178
 	 *
212
 	 * This method is guaranteed to be called only when the device
179
 	 * This method is guaranteed to be called only when the device
213
 	 * is open.
180
 	 * is open.
214
 	 */
181
 	 */
215
-	void ( * poll ) ( struct net_device *netdev, unsigned int rx_quota );
182
+	void ( * poll ) ( struct net_device *netdev );
183
+	/** Enable or disable interrupts
184
+	 *
185
+	 * @v netdev	Network device
186
+	 * @v enable	Interrupts should be enabled
187
+	 */
188
+	void ( * irq ) ( struct net_device *netdev, int enable );
189
+};
190
+
191
+/** Network device statistics */
192
+struct net_device_stats {
193
+	/** Count of successfully completed transmissions */
194
+	unsigned int tx_ok;
195
+	/** Count of transmission errors */
196
+	unsigned int tx_err;
197
+	/** Count of successfully received packets */
198
+	unsigned int rx_ok;
199
+	/** Count of reception errors */
200
+	unsigned int rx_err;
201
+};
202
+
203
+/**
204
+ * A network device
205
+ *
206
+ * This structure represents a piece of networking hardware.  It has
207
+ * properties such as a link-layer address and methods for
208
+ * transmitting and receiving raw packets.
209
+ *
210
+ * Note that this structure must represent a generic network device,
211
+ * not just an Ethernet device.
212
+ */
213
+struct net_device {
214
+	/** Reference counter */
215
+	struct refcnt refcnt;
216
+	/** List of network devices */
217
+	struct list_head list;
218
+	/** Name of this network device */
219
+	char name[8];
220
+	/** Underlying hardware device */
221
+	struct device *dev;
222
+
223
+	/** Network device operations */
224
+	struct net_device_operations *op;
216
 
225
 
217
 	/** Link-layer protocol */
226
 	/** Link-layer protocol */
218
 	struct ll_protocol *ll_protocol;
227
 	struct ll_protocol *ll_protocol;
248
 #define __net_protocol __table ( struct net_protocol, net_protocols, 01 )
257
 #define __net_protocol __table ( struct net_protocol, net_protocols, 01 )
249
 
258
 
250
 extern struct list_head net_devices;
259
 extern struct list_head net_devices;
260
+extern struct net_device_operations null_netdev_operations;
261
+
262
+/**
263
+ * Initialise a network device
264
+ *
265
+ * @v netdev		Network device
266
+ * @v op		Network device operations
267
+ */
268
+static inline void netdev_init ( struct net_device *netdev,
269
+				 struct net_device_operations *op ) {
270
+	netdev->op = op;
271
+}
272
+
273
+/**
274
+ * Stop using a network device
275
+ *
276
+ * @v netdev		Network device
277
+ *
278
+ * Drivers should call this method immediately before the final call
279
+ * to netdev_put().
280
+ */
281
+static inline void netdev_nullify ( struct net_device *netdev ) {
282
+	netdev->op = &null_netdev_operations;
283
+}
251
 
284
 
252
 /**
285
 /**
253
  * Get printable network device hardware address
286
  * Get printable network device hardware address
300
 extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
333
 extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
301
 extern void netdev_rx_err ( struct net_device *netdev,
334
 extern void netdev_rx_err ( struct net_device *netdev,
302
 			    struct io_buffer *iobuf, int rc );
335
 			    struct io_buffer *iobuf, int rc );
303
-extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
336
+extern void netdev_poll ( struct net_device *netdev );
304
 extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
337
 extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
305
 extern struct net_device * alloc_netdev ( size_t priv_size );
338
 extern struct net_device * alloc_netdev ( size_t priv_size );
306
 extern int register_netdev ( struct net_device *netdev );
339
 extern int register_netdev ( struct net_device *netdev );
307
 extern int netdev_open ( struct net_device *netdev );
340
 extern int netdev_open ( struct net_device *netdev );
308
 extern void netdev_close ( struct net_device *netdev );
341
 extern void netdev_close ( struct net_device *netdev );
309
 extern void unregister_netdev ( struct net_device *netdev );
342
 extern void unregister_netdev ( struct net_device *netdev );
343
+extern void netdev_irq ( struct net_device *netdev, int enable );
310
 extern struct net_device * find_netdev ( const char *name );
344
 extern struct net_device * find_netdev ( const char *name );
311
 extern struct net_device * find_netdev_by_location ( unsigned int bus_type,
345
 extern struct net_device * find_netdev_by_location ( unsigned int bus_type,
312
 						     unsigned int location );
346
 						     unsigned int location );

+ 17
- 9
src/interface/pxe/pxe_undi.c View File

69
  * @ret rc		Return status code
69
  * @ret rc		Return status code
70
  */
70
  */
71
 static int pxe_netdev_open ( void ) {
71
 static int pxe_netdev_open ( void ) {
72
-	return netdev_open ( pxe_netdev );
72
+	int rc;
73
+
74
+	if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 )
75
+		return rc;
76
+
77
+	netdev_irq ( pxe_netdev, 1 );
78
+	return 0;
73
 }
79
 }
74
 
80
 
75
 /**
81
 /**
77
  *
83
  *
78
  */
84
  */
79
 static void pxe_netdev_close ( void ) {
85
 static void pxe_netdev_close ( void ) {
86
+	netdev_irq ( pxe_netdev, 0 );
80
 	netdev_close ( pxe_netdev );
87
 	netdev_close ( pxe_netdev );
81
 	undi_tx_count = 0;
88
 	undi_tx_count = 0;
82
 }
89
 }
543
 		/* Call poll().  This should acknowledge the device
550
 		/* Call poll().  This should acknowledge the device
544
 		 * interrupt and queue up any received packet.
551
 		 * interrupt and queue up any received packet.
545
 		 */
552
 		 */
546
-		if ( netdev_poll ( pxe_netdev, -1U ) ) {
547
-			/* Packet waiting in queue */
548
-			DBG ( " OURS" );
549
-			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
550
-		} else {
551
-			DBG ( " NOT_OURS" );
552
-			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_NOT_OURS;
553
-		}
553
+		netdev_poll ( pxe_netdev );
554
+
555
+		/* Disable interrupts to avoid interrupt storm */
556
+		netdev_irq ( pxe_netdev, 0 );
557
+
558
+		/* Always say it was ours for the sake of simplicity */
559
+		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
554
 		break;
560
 		break;
555
 	case PXENV_UNDI_ISR_IN_PROCESS :
561
 	case PXENV_UNDI_ISR_IN_PROCESS :
556
 	case PXENV_UNDI_ISR_IN_GET_NEXT :
562
 	case PXENV_UNDI_ISR_IN_GET_NEXT :
570
 		if ( ! iobuf ) {
576
 		if ( ! iobuf ) {
571
 			/* No more packets remaining */
577
 			/* No more packets remaining */
572
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
578
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
579
+			/* Re-enable interrupts */
580
+			netdev_irq ( pxe_netdev, 1 );
573
 			break;
581
 			break;
574
 		}
582
 		}
575
 
583
 

+ 19
- 14
src/net/netdevice.c View File

68
 		goto err;
68
 		goto err;
69
 	}
69
 	}
70
 		
70
 		
71
-	if ( ( rc = netdev->transmit ( netdev, iobuf ) ) != 0 )
71
+	if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
72
 		goto err;
72
 		goto err;
73
 
73
 
74
 	return 0;
74
 	return 0;
187
 }
187
 }
188
 
188
 
189
 /**
189
 /**
190
- * Poll for packet on network device
190
+ * Poll for completed and received packets on network device
191
  *
191
  *
192
  * @v netdev		Network device
192
  * @v netdev		Network device
193
- * @v rx_quota		Maximum number of packets to receive
194
- * @ret True		There are packets present in the receive queue
195
- * @ret False		There are no packets present in the receive queue
196
  *
193
  *
197
- * Polls the network device for received packets.  Any received
198
- * packets will be added to the RX packet queue via netdev_rx().
194
+ * Polls the network device for completed transmissions and received
195
+ * packets.  Any received packets will be added to the RX packet queue
196
+ * via netdev_rx().
199
  */
197
  */
200
-int netdev_poll ( struct net_device *netdev, unsigned int rx_quota ) {
198
+void netdev_poll ( struct net_device *netdev ) {
201
 
199
 
202
 	if ( netdev->state & NETDEV_OPEN )
200
 	if ( netdev->state & NETDEV_OPEN )
203
-		netdev->poll ( netdev, rx_quota );
204
-
205
-	return ( ! list_empty ( &netdev->rx_queue ) );
201
+		netdev->op->poll ( netdev );
206
 }
202
 }
207
 
203
 
208
 /**
204
 /**
317
 	DBGC ( netdev, "NETDEV %p opening\n", netdev );
313
 	DBGC ( netdev, "NETDEV %p opening\n", netdev );
318
 
314
 
319
 	/* Open the device */
315
 	/* Open the device */
320
-	if ( ( rc = netdev->open ( netdev ) ) != 0 )
316
+	if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
321
 		return rc;
317
 		return rc;
322
 
318
 
323
 	/* Mark as opened */
319
 	/* Mark as opened */
339
 	DBGC ( netdev, "NETDEV %p closing\n", netdev );
335
 	DBGC ( netdev, "NETDEV %p closing\n", netdev );
340
 
336
 
341
 	/* Close the device */
337
 	/* Close the device */
342
-	netdev->close ( netdev );
338
+	netdev->op->close ( netdev );
343
 
339
 
344
 	/* Flush TX and RX queues */
340
 	/* Flush TX and RX queues */
345
 	netdev_tx_flush ( netdev );
341
 	netdev_tx_flush ( netdev );
367
 	DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
363
 	DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
368
 }
364
 }
369
 
365
 
366
+/** Enable or disable interrupts
367
+ *
368
+ * @v netdev		Network device
369
+ * @v enable		Interrupts should be enabled
370
+ */
371
+void netdev_irq ( struct net_device *netdev, int enable ) {
372
+	netdev->op->irq ( netdev, enable );
373
+}
374
+
370
 /**
375
 /**
371
  * Get network device by name
376
  * Get network device by name
372
  *
377
  *
462
 	list_for_each_entry ( netdev, &net_devices, list ) {
467
 	list_for_each_entry ( netdev, &net_devices, list ) {
463
 
468
 
464
 		/* Poll for new packets */
469
 		/* Poll for new packets */
465
-		netdev_poll ( netdev, -1U );
470
+		netdev_poll ( netdev );
466
 
471
 
467
 		/* Process at most one received packet.  Give priority
472
 		/* Process at most one received packet.  Give priority
468
 		 * to getting packets out of the NIC over processing
473
 		 * to getting packets out of the NIC over processing

+ 57
- 0
src/net/nullnet.c View File

1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <gpxe/iobuf.h>
21
+#include <gpxe/netdevice.h>
22
+
23
+/** @file
24
+ *
25
+ * Null network device
26
+ *
27
+ */
28
+
29
+static int null_open ( struct net_device *netdev __unused ) {
30
+	return -ENODEV;
31
+};
32
+
33
+static void null_close ( struct net_device *netdev __unused ) {
34
+	/* Do nothing */
35
+};
36
+
37
+static int null_transmit ( struct net_device *netdev __unused,
38
+			   struct io_buffer *iobuf __unused ) {
39
+	return -ENODEV;
40
+};
41
+
42
+static void null_poll ( struct net_device *netdev __unused ) {
43
+	/* Do nothing */
44
+}
45
+
46
+static void null_irq ( struct net_device *netdev __unused,
47
+		       int enable __unused ) {
48
+	/* Do nothing */
49
+}
50
+
51
+struct net_device_operations null_netdev_operations = {
52
+	.open		= null_open,
53
+	.close		= null_close,
54
+	.transmit	= null_transmit,
55
+	.poll		= null_poll,
56
+	.irq   		= null_irq,
57
+};

Loading…
Cancel
Save