浏览代码

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 18 年前
父节点
当前提交
0c03bb5a9a
共有 6 个文件被更改,包括 137 次插入18 次删除
  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 查看文件

@@ -56,6 +56,14 @@ static void legacy_poll ( struct net_device *netdev ) {
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 67
 int legacy_probe ( struct pci_device *pci,
60 68
 		   const struct pci_device_id *id __unused,
61 69
 		   int ( * probe ) ( struct nic *nic,
@@ -74,6 +82,8 @@ int legacy_probe ( struct pci_device *pci,
74 82
 	memset ( &nic, 0, sizeof ( nic ) );
75 83
 	pci_set_drvdata ( pci, netdev );
76 84
 
85
+	netdev->open = legacy_open;
86
+	netdev->close = legacy_close;
77 87
 	netdev->transmit = legacy_transmit;
78 88
 	netdev->poll = legacy_poll;
79 89
 	nic.node_addr = netdev->ll_addr;

+ 16
- 0
src/drivers/net/pnic.c 查看文件

@@ -185,6 +185,20 @@ static void pnic_irq ( struct net_device *netdev, irq_action_t action ) {
185 185
 }
186 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 203
 DISABLE - Turn off ethernet interface
190 204
 ***************************************************************************/
@@ -238,6 +252,8 @@ static int pnic_probe ( struct pci_device *pci,
238 252
 				netdev->ll_addr, ETH_ALEN, NULL );
239 253
 
240 254
 	/* Point to NIC specific routines */
255
+	netdev->open	 = pnic_open;
256
+	netdev->close	 = pnic_close;
241 257
 	netdev->poll	 = pnic_poll;
242 258
 	netdev->transmit = pnic_transmit;
243 259
 

+ 2
- 10
src/drivers/net/rtl8139.c 查看文件

@@ -542,8 +542,8 @@ static int rtl_probe ( struct pci_device *pci,
542 542
 	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
543 543
 	
544 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 547
 	netdev->transmit = rtl_transmit;
548 548
 	netdev->poll	 = rtl_poll;
549 549
 
@@ -558,10 +558,6 @@ static int rtl_probe ( struct pci_device *pci,
558 558
 			goto err;
559 559
 	}
560 560
 
561
-#warning "Hack alert"
562
-	rtl_open ( netdev );
563
-
564
-
565 561
 	return 0;
566 562
 
567 563
  err:
@@ -584,10 +580,6 @@ static void rtl_remove ( struct pci_device *pci ) {
584 580
 	struct net_device *netdev = pci_get_drvdata ( pci );
585 581
 	struct rtl8139_nic *rtl = netdev->priv;
586 582
 
587
-
588
-#warning "Hack alert"	
589
-	rtl_close ( netdev );
590
-
591 583
 	if ( rtl->nvo.nvs )
592 584
 		nvo_unregister ( &rtl->nvo );
593 585
 	unregister_netdev ( netdev );

+ 33
- 0
src/include/gpxe/netdevice.h 查看文件

@@ -142,6 +142,23 @@ struct net_device {
142 142
 	/** List of persistent reference holders */
143 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 162
 	/** Transmit packet
146 163
 	 *
147 164
 	 * @v netdev	Network device
@@ -154,6 +171,9 @@ struct net_device {
154 171
 	 * Ownership of the packet buffer is transferred to the @c
155 172
 	 * net_device, which must eventually call free_pkb() to
156 173
 	 * release the buffer.
174
+	 *
175
+	 * This method is guaranteed to be called only when the device
176
+	 * is open.
157 177
 	 */
158 178
 	int ( * transmit ) ( struct net_device *netdev, struct pk_buff *pkb );
159 179
 	/** Poll for received packet
@@ -163,6 +183,9 @@ struct net_device {
163 183
 	 * This method should cause the hardware to check for received
164 184
 	 * packets.  Any received packets should be delivered via
165 185
 	 * netdev_rx().
186
+	 *
187
+	 * This method is guaranteed to be called only when the device
188
+	 * is open.
166 189
 	 */
167 190
 	void ( * poll ) ( struct net_device *netdev );
168 191
 
@@ -174,6 +197,11 @@ struct net_device {
174 197
 	 */
175 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 205
 	/** Received packet queue */
178 206
 	struct list_head rx_queue;
179 207
 
@@ -181,6 +209,9 @@ struct net_device {
181 209
 	void *priv;
182 210
 };
183 211
 
212
+/** Network device is open */
213
+#define NETDEV_OPEN 0x0001
214
+
184 215
 /** Declare a link-layer protocol */
185 216
 #define __ll_protocol  __table ( ll_protocols, 01 )
186 217
 
@@ -209,6 +240,8 @@ extern int netdev_poll ( struct net_device *netdev );
209 240
 extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
210 241
 extern struct net_device * alloc_netdev ( size_t priv_size );
211 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 245
 extern void unregister_netdev ( struct net_device *netdev );
213 246
 extern void free_netdev ( struct net_device *netdev );
214 247
 extern struct net_device * next_netdev ( void );

+ 61
- 5
src/net/netdevice.c 查看文件

@@ -54,6 +54,12 @@ static LIST_HEAD ( net_devices );
54 54
 int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
55 55
 	DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
56 56
 	      pkb->data, pkb_len ( pkb ) );
57
+
58
+	if ( ! ( netdev->state & NETDEV_OPEN ) ) {
59
+		free_pkb ( pkb );
60
+		return -ENETUNREACH;
61
+	}
62
+	
57 63
 	return netdev->transmit ( netdev, pkb );
58 64
 }
59 65
 
@@ -100,7 +106,7 @@ int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
100 106
  * @ret rc		Return status code
101 107
  */
102 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 110
 	struct net_protocol *net_protocol;
105 111
 
106 112
 	/* Hand off to network-layer protocol, if any */
@@ -125,7 +131,10 @@ int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
125 131
  * packets will be added to the RX packet queue via netdev_rx().
126 132
  */
127 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 138
 	return ( ! list_empty ( &netdev->rx_queue ) );
130 139
 }
131 140
 
@@ -186,15 +195,46 @@ int register_netdev ( struct net_device *netdev ) {
186 195
 }
187 196
 
188 197
 /**
189
- * Unregister network device
198
+ * Open network device
190 199
  *
191 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 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 238
 	/* Discard any packets in the RX queue */
199 239
 	while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
200 240
 		DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
@@ -202,6 +242,22 @@ void unregister_netdev ( struct net_device *netdev ) {
202 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 261
 	/* Kill off any persistent references to this device */
206 262
 	forget_references ( &netdev->references );
207 263
 

+ 15
- 3
src/usr/autoboot.c 查看文件

@@ -16,7 +16,9 @@
16 16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18 18
 
19
+#include <string.h>
19 20
 #include <vsprintf.h>
21
+#include <gpxe/netdevice.h>
20 22
 #include <gpxe/autoboot.h>
21 23
 
22 24
 /** @file
@@ -30,11 +32,21 @@ void test_dhcp ( struct net_device *netdev );
30 32
 
31 33
 void autoboot ( void ) {
32 34
 	struct net_device *netdev;
35
+	int rc;
33 36
 
34 37
 	netdev = next_netdev ();
35
-	if ( netdev ) {
36
-		test_dhcp ( netdev );
37
-	} else {
38
+	if ( ! netdev ) {
38 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
 }

正在加载...
取消
保存