Browse Source

Make open() and close() an official part of the netdevice API.

Call netdevice's poll() and transmit() methods only when device is open.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
0c03bb5a9a
6 changed files with 137 additions and 18 deletions
  1. 10
    0
      src/drivers/net/legacy.c
  2. 16
    0
      src/drivers/net/pnic.c
  3. 2
    10
      src/drivers/net/rtl8139.c
  4. 33
    0
      src/include/gpxe/netdevice.h
  5. 61
    5
      src/net/netdevice.c
  6. 15
    3
      src/usr/autoboot.c

+ 10
- 0
src/drivers/net/legacy.c View File

56
 	}
56
 	}
57
 }
57
 }
58
 
58
 
59
+static int legacy_open ( struct net_device *netdev __unused ) {
60
+	return 0;
61
+}
62
+
63
+static void legacy_close ( struct net_device *netdev __unused ) {
64
+	/* Nothing to do */
65
+}
66
+
59
 int legacy_probe ( struct pci_device *pci,
67
 int legacy_probe ( struct pci_device *pci,
60
 		   const struct pci_device_id *id __unused,
68
 		   const struct pci_device_id *id __unused,
61
 		   int ( * probe ) ( struct nic *nic,
69
 		   int ( * probe ) ( struct nic *nic,
74
 	memset ( &nic, 0, sizeof ( nic ) );
82
 	memset ( &nic, 0, sizeof ( nic ) );
75
 	pci_set_drvdata ( pci, netdev );
83
 	pci_set_drvdata ( pci, netdev );
76
 
84
 
85
+	netdev->open = legacy_open;
86
+	netdev->close = legacy_close;
77
 	netdev->transmit = legacy_transmit;
87
 	netdev->transmit = legacy_transmit;
78
 	netdev->poll = legacy_poll;
88
 	netdev->poll = legacy_poll;
79
 	nic.node_addr = netdev->ll_addr;
89
 	nic.node_addr = netdev->ll_addr;

+ 16
- 0
src/drivers/net/pnic.c View File

185
 }
185
 }
186
 #endif
186
 #endif
187
 
187
 
188
+/**************************************************************************
189
+OPEN - Open network device
190
+***************************************************************************/
191
+static int pnic_open ( struct net_device *netdev __unused ) {
192
+	return 0;
193
+}
194
+
195
+/**************************************************************************
196
+CLOSE - Close network device
197
+***************************************************************************/
198
+static void pnic_close ( struct net_device *netdev __unused ) {
199
+	/* Nothing to do */
200
+}
201
+
188
 /**************************************************************************
202
 /**************************************************************************
189
 DISABLE - Turn off ethernet interface
203
 DISABLE - Turn off ethernet interface
190
 ***************************************************************************/
204
 ***************************************************************************/
238
 				netdev->ll_addr, ETH_ALEN, NULL );
252
 				netdev->ll_addr, ETH_ALEN, NULL );
239
 
253
 
240
 	/* Point to NIC specific routines */
254
 	/* Point to NIC specific routines */
255
+	netdev->open	 = pnic_open;
256
+	netdev->close	 = pnic_close;
241
 	netdev->poll	 = pnic_poll;
257
 	netdev->poll	 = pnic_poll;
242
 	netdev->transmit = pnic_transmit;
258
 	netdev->transmit = pnic_transmit;
243
 
259
 

+ 2
- 10
src/drivers/net/rtl8139.c View File

542
 	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
542
 	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
543
 	
543
 	
544
 	/* Point to NIC specific routines */
544
 	/* Point to NIC specific routines */
545
-	//	netdev->open	 = rtl_open;
546
-	//	netdev->close	 = rtl_close;
545
+	netdev->open	 = rtl_open;
546
+	netdev->close	 = rtl_close;
547
 	netdev->transmit = rtl_transmit;
547
 	netdev->transmit = rtl_transmit;
548
 	netdev->poll	 = rtl_poll;
548
 	netdev->poll	 = rtl_poll;
549
 
549
 
558
 			goto err;
558
 			goto err;
559
 	}
559
 	}
560
 
560
 
561
-#warning "Hack alert"
562
-	rtl_open ( netdev );
563
-
564
-
565
 	return 0;
561
 	return 0;
566
 
562
 
567
  err:
563
  err:
584
 	struct net_device *netdev = pci_get_drvdata ( pci );
580
 	struct net_device *netdev = pci_get_drvdata ( pci );
585
 	struct rtl8139_nic *rtl = netdev->priv;
581
 	struct rtl8139_nic *rtl = netdev->priv;
586
 
582
 
587
-
588
-#warning "Hack alert"	
589
-	rtl_close ( netdev );
590
-
591
 	if ( rtl->nvo.nvs )
583
 	if ( rtl->nvo.nvs )
592
 		nvo_unregister ( &rtl->nvo );
584
 		nvo_unregister ( &rtl->nvo );
593
 	unregister_netdev ( netdev );
585
 	unregister_netdev ( netdev );

+ 33
- 0
src/include/gpxe/netdevice.h View File

142
 	/** List of persistent reference holders */
142
 	/** List of persistent reference holders */
143
 	struct list_head references;
143
 	struct list_head references;
144
 
144
 
145
+	/** Open network device
146
+	 *
147
+	 * @v netdev	Network device
148
+	 * @ret rc	Return status code
149
+	 *
150
+	 * This method should allocate RX packet buffers and enable
151
+	 * the hardware to start transmitting and receiving packets.
152
+	 */
153
+	int ( * open ) ( struct net_device *netdev );
154
+	/** Close network device
155
+	 *
156
+	 * @v netdev	Network device
157
+	 *
158
+	 * This method should stop the flow of packets, and free up
159
+	 * any packets that are currently in the device's TX queue.
160
+	 */
161
+	void ( * close ) ( struct net_device *netdev );
145
 	/** Transmit packet
162
 	/** Transmit packet
146
 	 *
163
 	 *
147
 	 * @v netdev	Network device
164
 	 * @v netdev	Network device
154
 	 * Ownership of the packet buffer is transferred to the @c
171
 	 * Ownership of the packet buffer is transferred to the @c
155
 	 * net_device, which must eventually call free_pkb() to
172
 	 * net_device, which must eventually call free_pkb() to
156
 	 * release the buffer.
173
 	 * release the buffer.
174
+	 *
175
+	 * This method is guaranteed to be called only when the device
176
+	 * is open.
157
 	 */
177
 	 */
158
 	int ( * transmit ) ( struct net_device *netdev, struct pk_buff *pkb );
178
 	int ( * transmit ) ( struct net_device *netdev, struct pk_buff *pkb );
159
 	/** Poll for received packet
179
 	/** Poll for received packet
163
 	 * This method should cause the hardware to check for received
183
 	 * This method should cause the hardware to check for received
164
 	 * packets.  Any received packets should be delivered via
184
 	 * packets.  Any received packets should be delivered via
165
 	 * netdev_rx().
185
 	 * netdev_rx().
186
+	 *
187
+	 * This method is guaranteed to be called only when the device
188
+	 * is open.
166
 	 */
189
 	 */
167
 	void ( * poll ) ( struct net_device *netdev );
190
 	void ( * poll ) ( struct net_device *netdev );
168
 
191
 
174
 	 */
197
 	 */
175
 	uint8_t ll_addr[MAX_LL_ADDR_LEN];
198
 	uint8_t ll_addr[MAX_LL_ADDR_LEN];
176
 
199
 
200
+	/** Current device state
201
+	 *
202
+	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
203
+	 */
204
+	unsigned int state;
177
 	/** Received packet queue */
205
 	/** Received packet queue */
178
 	struct list_head rx_queue;
206
 	struct list_head rx_queue;
179
 
207
 
181
 	void *priv;
209
 	void *priv;
182
 };
210
 };
183
 
211
 
212
+/** Network device is open */
213
+#define NETDEV_OPEN 0x0001
214
+
184
 /** Declare a link-layer protocol */
215
 /** Declare a link-layer protocol */
185
 #define __ll_protocol  __table ( ll_protocols, 01 )
216
 #define __ll_protocol  __table ( ll_protocols, 01 )
186
 
217
 
209
 extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
240
 extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
210
 extern struct net_device * alloc_netdev ( size_t priv_size );
241
 extern struct net_device * alloc_netdev ( size_t priv_size );
211
 extern int register_netdev ( struct net_device *netdev );
242
 extern int register_netdev ( struct net_device *netdev );
243
+extern int netdev_open ( struct net_device *netdev );
244
+extern void netdev_close ( struct net_device *netdev );
212
 extern void unregister_netdev ( struct net_device *netdev );
245
 extern void unregister_netdev ( struct net_device *netdev );
213
 extern void free_netdev ( struct net_device *netdev );
246
 extern void free_netdev ( struct net_device *netdev );
214
 extern struct net_device * next_netdev ( void );
247
 extern struct net_device * next_netdev ( void );

+ 61
- 5
src/net/netdevice.c View File

54
 int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
54
 int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
55
 	DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
55
 	DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
56
 	      pkb->data, pkb_len ( pkb ) );
56
 	      pkb->data, pkb_len ( pkb ) );
57
+
58
+	if ( ! ( netdev->state & NETDEV_OPEN ) ) {
59
+		free_pkb ( pkb );
60
+		return -ENETUNREACH;
61
+	}
62
+	
57
 	return netdev->transmit ( netdev, pkb );
63
 	return netdev->transmit ( netdev, pkb );
58
 }
64
 }
59
 
65
 
100
  * @ret rc		Return status code
106
  * @ret rc		Return status code
101
  */
107
  */
102
 int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
108
 int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
103
-	      uint16_t net_proto, const void *ll_source ) {
109
+	     uint16_t net_proto, const void *ll_source ) {
104
 	struct net_protocol *net_protocol;
110
 	struct net_protocol *net_protocol;
105
 
111
 
106
 	/* Hand off to network-layer protocol, if any */
112
 	/* Hand off to network-layer protocol, if any */
125
  * packets will be added to the RX packet queue via netdev_rx().
131
  * packets will be added to the RX packet queue via netdev_rx().
126
  */
132
  */
127
 int netdev_poll ( struct net_device *netdev ) {
133
 int netdev_poll ( struct net_device *netdev ) {
128
-	netdev->poll ( netdev );
134
+
135
+	if ( netdev->state & NETDEV_OPEN )
136
+		netdev->poll ( netdev );
137
+
129
 	return ( ! list_empty ( &netdev->rx_queue ) );
138
 	return ( ! list_empty ( &netdev->rx_queue ) );
130
 }
139
 }
131
 
140
 
186
 }
195
 }
187
 
196
 
188
 /**
197
 /**
189
- * Unregister network device
198
+ * Open network device
190
  *
199
  *
191
  * @v netdev		Network device
200
  * @v netdev		Network device
201
+ * @ret rc		Return status code
202
+ */
203
+int netdev_open ( struct net_device *netdev ) {
204
+	int rc;
205
+
206
+	/* Do nothing if device is already open */
207
+	if ( netdev->state & NETDEV_OPEN )
208
+		return 0;
209
+
210
+	DBG ( "%s opening\n", netdev_name ( netdev ) );
211
+
212
+	/* Open the device */
213
+	if ( ( rc = netdev->open ( netdev ) ) != 0 )
214
+		return rc;
215
+
216
+	/* Mark as opened */
217
+	netdev->state |= NETDEV_OPEN;
218
+	return 0;
219
+}
220
+
221
+/**
222
+ * Close network device
192
  *
223
  *
193
- * Removes the network device from the list of network devices.
224
+ * @v netdev		Network device
194
  */
225
  */
195
-void unregister_netdev ( struct net_device *netdev ) {
226
+void netdev_close ( struct net_device *netdev ) {
196
 	struct pk_buff *pkb;
227
 	struct pk_buff *pkb;
197
 
228
 
229
+	/* Do nothing if device is already closed */
230
+	if ( ! ( netdev->state & NETDEV_OPEN ) )
231
+		return;
232
+
233
+	DBG ( "%s closing\n", netdev_name ( netdev ) );
234
+
235
+	/* Close the device */
236
+	netdev->close ( netdev );
237
+
198
 	/* Discard any packets in the RX queue */
238
 	/* Discard any packets in the RX queue */
199
 	while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
239
 	while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
200
 		DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
240
 		DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
202
 		free_pkb ( pkb );
242
 		free_pkb ( pkb );
203
 	}
243
 	}
204
 
244
 
245
+	/* Mark as closed */
246
+	netdev->state &= ~NETDEV_OPEN;
247
+}
248
+
249
+/**
250
+ * Unregister network device
251
+ *
252
+ * @v netdev		Network device
253
+ *
254
+ * Removes the network device from the list of network devices.
255
+ */
256
+void unregister_netdev ( struct net_device *netdev ) {
257
+
258
+	/* Ensure device is closed */
259
+	netdev_close ( netdev );
260
+
205
 	/* Kill off any persistent references to this device */
261
 	/* Kill off any persistent references to this device */
206
 	forget_references ( &netdev->references );
262
 	forget_references ( &netdev->references );
207
 
263
 

+ 15
- 3
src/usr/autoboot.c View File

16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
  */
17
  */
18
 
18
 
19
+#include <string.h>
19
 #include <vsprintf.h>
20
 #include <vsprintf.h>
21
+#include <gpxe/netdevice.h>
20
 #include <gpxe/autoboot.h>
22
 #include <gpxe/autoboot.h>
21
 
23
 
22
 /** @file
24
 /** @file
30
 
32
 
31
 void autoboot ( void ) {
33
 void autoboot ( void ) {
32
 	struct net_device *netdev;
34
 	struct net_device *netdev;
35
+	int rc;
33
 
36
 
34
 	netdev = next_netdev ();
37
 	netdev = next_netdev ();
35
-	if ( netdev ) {
36
-		test_dhcp ( netdev );
37
-	} else {
38
+	if ( ! netdev ) {
38
 		printf ( "No network device found\n" );
39
 		printf ( "No network device found\n" );
40
+		return;
41
+	}
42
+
43
+	if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
44
+		printf ( "Could not open %s: %s\n", netdev_name ( netdev ),
45
+			 strerror ( rc ) );
46
+		return;
39
 	}
47
 	}
48
+
49
+	test_dhcp ( netdev );
50
+
51
+	netdev_close ( netdev );
40
 }
52
 }

Loading…
Cancel
Save