瀏覽代碼

Added net device TX queue; this will be needed to support the PXE UNDI API

(which will need us to wait for TX completions).

Added debug autocolourisation to netdevice.c
tags/v0.9.3
Michael Brown 18 年之前
父節點
當前提交
b7fcfe8ece
共有 6 個文件被更改,包括 127 次插入77 次删除
  1. 8
    4
      src/arch/i386/drivers/net/undinet.c
  2. 1
    1
      src/drivers/net/legacy.c
  3. 1
    1
      src/drivers/net/pnic.c
  4. 2
    13
      src/drivers/net/rtl8139.c
  5. 14
    8
      src/include/gpxe/netdevice.h
  6. 101
    50
      src/net/netdevice.c

+ 8
- 4
src/arch/i386/drivers/net/undinet.c 查看文件

@@ -349,11 +349,15 @@ static int undinet_transmit ( struct net_device *netdev,
349 349
 		= ( ( unsigned ) & __from_data16 ( undinet_pkb ) );
350 350
 
351 351
 	/* Issue PXE API call */
352
-	rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT, &undi_transmit,
353
-			    sizeof ( undi_transmit ) );
352
+	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT,
353
+				   &undi_transmit,
354
+				   sizeof ( undi_transmit ) ) ) != 0 )
355
+		goto done;
354 356
 
355
-	/* Free packet buffer and return */
356
-	free_pkb ( pkb );
357
+	/* Free packet buffer */
358
+	netdev_tx_complete ( netdev, pkb );
359
+
360
+ done:
357 361
 	return rc;
358 362
 }
359 363
 

+ 1
- 1
src/drivers/net/legacy.c 查看文件

@@ -34,7 +34,7 @@ static int legacy_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
34 34
 	nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
35 35
 				ntohs ( ethhdr->h_protocol ),
36 36
 				pkb_len ( pkb ), pkb->data );
37
-	free_pkb ( pkb );
37
+	netdev_tx_complete ( netdev, pkb );
38 38
 	return 0;
39 39
 }
40 40
 

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

@@ -158,7 +158,7 @@ static int pnic_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
158 158
 	pnic_command ( pnic, PNIC_CMD_XMIT, pkb->data, pkb_len ( pkb ),
159 159
 		       NULL, 0, NULL );
160 160
 
161
-	free_pkb ( pkb );
161
+	netdev_tx_complete ( netdev, pkb );
162 162
 	return 0;
163 163
 }
164 164
 

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

@@ -304,7 +304,7 @@ static void rtl_reset ( struct rtl8139_nic *rtl ) {
304 304
 	/* Reset chip */
305 305
 	outb ( CmdReset, rtl->ioaddr + ChipCmd );
306 306
 	mdelay ( 10 );
307
-	rtl->tx.next = 0;
307
+	memset ( &rtl->tx, 0, sizeof ( rtl->tx ) );
308 308
 	rtl->rx.offset = 0;
309 309
 }
310 310
 
@@ -349,7 +349,6 @@ static int rtl_open ( struct net_device *netdev ) {
349 349
  */
350 350
 static void rtl_close ( struct net_device *netdev ) {
351 351
 	struct rtl8139_nic *rtl = netdev->priv;
352
-	int i;
353 352
 
354 353
 	/* Reset the hardware to disable everything in one go */
355 354
 	rtl_reset ( rtl );
@@ -357,15 +356,6 @@ static void rtl_close ( struct net_device *netdev ) {
357 356
 	/* Free RX ring */
358 357
 	free ( rtl->rx.ring );
359 358
 	rtl->rx.ring = NULL;
360
-
361
-	/* Free any old TX buffers that hadn't yet completed */
362
-	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
363
-		if ( rtl->tx.pkb[i] ) {
364
-			free_pkb ( rtl->tx.pkb[i] );
365
-			rtl->tx.pkb[i] = NULL;
366
-			DBG ( "TX id %d discarded\n", i );
367
-		}
368
-	}
369 359
 }
370 360
 
371 361
 /** 
@@ -383,7 +373,6 @@ static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
383 373
 	/* Check for space in TX ring */
384 374
 	if ( rtl->tx.pkb[rtl->tx.next] != NULL ) {
385 375
 		printf ( "TX overflow\n" );
386
-		free_pkb ( pkb );
387 376
 		return -ENOBUFS;
388 377
 	}
389 378
 
@@ -437,7 +426,7 @@ static void rtl_poll ( struct net_device *netdev ) {
437 426
 	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
438 427
 		if ( ( rtl->tx.pkb[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
439 428
 			DBG ( "TX id %d complete\n", i );
440
-			free_pkb ( rtl->tx.pkb[i] );
429
+			netdev_tx_complete ( netdev, rtl->tx.pkb[i] );
441 430
 			rtl->tx.pkb[i] = NULL;
442 431
 		}
443 432
 	}

+ 14
- 8
src/include/gpxe/netdevice.h 查看文件

@@ -168,9 +168,11 @@ struct net_device {
168 168
 	 * This method should cause the hardware to initiate
169 169
 	 * transmission of the packet buffer.
170 170
 	 *
171
-	 * Ownership of the packet buffer is transferred to the @c
172
-	 * net_device, which must eventually call free_pkb() to
173
-	 * release the buffer.
171
+	 * If this method returns success, the packet buffer remains
172
+	 * owned by the net device's TX queue, and the net device must
173
+	 * eventually call netdev_tx_complete() to free the buffer.
174
+	 * If this method returns failure, the packet buffer is
175
+	 * immediately released.
174 176
 	 *
175 177
 	 * This method is guaranteed to be called only when the device
176 178
 	 * is open.
@@ -202,7 +204,9 @@ struct net_device {
202 204
 	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
203 205
 	 */
204 206
 	unsigned int state;
205
-	/** Received packet queue */
207
+	/** TX packet queue */
208
+	struct list_head tx_queue;
209
+	/** RX packet queue */
206 210
 	struct list_head rx_queue;
207 211
 
208 212
 	/** Driver private data */
@@ -231,11 +235,9 @@ static inline const char * netdev_name ( struct net_device *netdev ) {
231 235
 }
232 236
 
233 237
 extern int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb );
238
+void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb );
239
+void netdev_tx_complete_next ( struct net_device *netdev );
234 240
 extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
235
-extern int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
236
-		    struct net_protocol *net_protocol, const void *ll_dest );
237
-extern int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
238
-		    uint16_t net_proto, const void *ll_source );
239 241
 extern int netdev_poll ( struct net_device *netdev );
240 242
 extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
241 243
 extern struct net_device * alloc_netdev ( size_t priv_size );
@@ -245,5 +247,9 @@ extern void netdev_close ( struct net_device *netdev );
245 247
 extern void unregister_netdev ( struct net_device *netdev );
246 248
 extern void free_netdev ( struct net_device *netdev );
247 249
 extern struct net_device * next_netdev ( void );
250
+extern int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
251
+		    struct net_protocol *net_protocol, const void *ll_dest );
252
+extern int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
253
+		    uint16_t net_proto, const void *ll_source );
248 254
 
249 255
 #endif /* _GPXE_NETDEVICE_H */

+ 101
- 50
src/net/netdevice.c 查看文件

@@ -52,72 +52,74 @@ static LIST_HEAD ( net_devices );
52 52
  * function takes ownership of the packet buffer.
53 53
  */
54 54
 int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
55
-	DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
56
-	      pkb->data, pkb_len ( pkb ) );
55
+	int rc;
56
+
57
+	DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
58
+	       netdev, pkb, pkb->data, pkb_len ( pkb ) );
59
+
60
+	list_add_tail ( &pkb->list, &netdev->tx_queue );
57 61
 
58 62
 	if ( ! ( netdev->state & NETDEV_OPEN ) ) {
59
-		free_pkb ( pkb );
60
-		return -ENETUNREACH;
63
+		rc = -ENETUNREACH;
64
+		goto err;
61 65
 	}
62
-	
63
-	return netdev->transmit ( netdev, pkb );
66
+		
67
+	if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 )
68
+		goto err;
69
+
70
+	return 0;
71
+
72
+ err:
73
+	DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
74
+	       netdev, pkb, strerror ( rc ) );
75
+	netdev_tx_complete ( netdev, pkb );
76
+	return rc;
64 77
 }
65 78
 
66 79
 /**
67
- * Add packet to receive queue
80
+ * Complete network transmission
68 81
  *
69 82
  * @v netdev		Network device
70 83
  * @v pkb		Packet buffer
71 84
  *
72
- * The packet is added to the network device's RX queue.  This
73
- * function takes ownership of the packet buffer.
85
+ * The packet must currently be in the network device's TX queue.
74 86
  */
75
-void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
76
-	DBG ( "%s received %p+%zx\n", netdev_name ( netdev ),
77
-	      pkb->data, pkb_len ( pkb ) );
78
-	list_add_tail ( &pkb->list, &netdev->rx_queue );
87
+void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb ) {
88
+	DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, pkb );
89
+
90
+	list_del ( &pkb->list );
91
+	free_pkb ( pkb );
79 92
 }
80 93
 
81 94
 /**
82
- * Transmit network-layer packet
95
+ * Complete network transmission
83 96
  *
84
- * @v pkb		Packet buffer
85 97
  * @v netdev		Network device
86
- * @v net_protocol	Network-layer protocol
87
- * @v ll_dest		Destination link-layer address
88
- * @ret rc		Return status code
89 98
  *
90
- * Prepends link-layer headers to the packet buffer and transmits the
91
- * packet via the specified network device.  This function takes
92
- * ownership of the packet buffer.
99
+ * Completes the oldest outstanding packet in the TX queue.
93 100
  */
94
-int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
95
-	     struct net_protocol *net_protocol, const void *ll_dest ) {
96
-	return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
101
+void netdev_tx_complete_next ( struct net_device *netdev ) {
102
+	struct pk_buff *pkb;
103
+
104
+	list_for_each_entry ( pkb, &netdev->tx_queue, list ) {
105
+		netdev_tx_complete ( netdev, pkb );
106
+		return;
107
+	}
97 108
 }
98 109
 
99 110
 /**
100
- * Process received network-layer packet
111
+ * Add packet to receive queue
101 112
  *
102
- * @v pkb		Packet buffer
103 113
  * @v netdev		Network device
104
- * @v net_proto		Network-layer protocol, in network-byte order
105
- * @v ll_source		Source link-layer address
106
- * @ret rc		Return status code
114
+ * @v pkb		Packet buffer
115
+ *
116
+ * The packet is added to the network device's RX queue.  This
117
+ * function takes ownership of the packet buffer.
107 118
  */
108
-int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
109
-	     uint16_t net_proto, const void *ll_source ) {
110
-	struct net_protocol *net_protocol;
111
-
112
-	/* Hand off to network-layer protocol, if any */
113
-	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
114
-	      net_protocol++ ) {
115
-		if ( net_protocol->net_proto == net_proto ) {
116
-			return net_protocol->rx ( pkb, netdev, ll_source );
117
-		}
118
-	}
119
-	free_pkb ( pkb );
120
-	return 0;
119
+void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
120
+	DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
121
+	       netdev, pkb, pkb->data, pkb_len ( pkb ) );
122
+	list_add_tail ( &pkb->list, &netdev->rx_queue );
121 123
 }
122 124
 
123 125
 /**
@@ -171,6 +173,7 @@ struct net_device * alloc_netdev ( size_t priv_size ) {
171 173
 	netdev = calloc ( 1, sizeof ( *netdev ) + priv_size );
172 174
 	if ( netdev ) {
173 175
 		INIT_LIST_HEAD ( &netdev->references );
176
+		INIT_LIST_HEAD ( &netdev->tx_queue );
174 177
 		INIT_LIST_HEAD ( &netdev->rx_queue );
175 178
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
176 179
 	}
@@ -189,7 +192,8 @@ int register_netdev ( struct net_device *netdev ) {
189 192
 	
190 193
 	/* Add to device list */
191 194
 	list_add_tail ( &netdev->list, &net_devices );
192
-	DBG ( "%s registered\n", netdev_name ( netdev ) );
195
+	DBGC ( netdev, "NETDEV %p registered as %s\n",
196
+	       netdev, netdev_name ( netdev ) );
193 197
 
194 198
 	return 0;
195 199
 }
@@ -207,7 +211,7 @@ int netdev_open ( struct net_device *netdev ) {
207 211
 	if ( netdev->state & NETDEV_OPEN )
208 212
 		return 0;
209 213
 
210
-	DBG ( "%s opening\n", netdev_name ( netdev ) );
214
+	DBGC ( netdev, "NETDEV %p opening\n", netdev );
211 215
 
212 216
 	/* Open the device */
213 217
 	if ( ( rc = netdev->open ( netdev ) ) != 0 )
@@ -230,15 +234,20 @@ void netdev_close ( struct net_device *netdev ) {
230 234
 	if ( ! ( netdev->state & NETDEV_OPEN ) )
231 235
 		return;
232 236
 
233
-	DBG ( "%s closing\n", netdev_name ( netdev ) );
237
+	DBGC ( netdev, "NETDEV %p closing\n", netdev );
234 238
 
235 239
 	/* Close the device */
236 240
 	netdev->close ( netdev );
237 241
 
242
+	/* Discard any packets in the TX queue */
243
+	while ( ! list_empty ( &netdev->tx_queue ) ) {
244
+		netdev_tx_complete_next ( netdev );
245
+	}
246
+
238 247
 	/* Discard any packets in the RX queue */
239 248
 	while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
240
-		DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
241
-		      pkb->data, pkb_len ( pkb ) );
249
+		DBGC ( netdev, "NETDEV %p discarding received %p\n",
250
+		       netdev, pkb );
242 251
 		free_pkb ( pkb );
243 252
 	}
244 253
 
@@ -263,7 +272,7 @@ void unregister_netdev ( struct net_device *netdev ) {
263 272
 
264 273
 	/* Remove from device list */
265 274
 	list_del ( &netdev->list );
266
-	DBG ( "%s unregistered\n", netdev_name ( netdev ) );
275
+	DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
267 276
 }
268 277
 
269 278
 /**
@@ -295,6 +304,48 @@ struct net_device * next_netdev ( void ) {
295 304
 	return NULL;
296 305
 }
297 306
 
307
+/**
308
+ * Transmit network-layer packet
309
+ *
310
+ * @v pkb		Packet buffer
311
+ * @v netdev		Network device
312
+ * @v net_protocol	Network-layer protocol
313
+ * @v ll_dest		Destination link-layer address
314
+ * @ret rc		Return status code
315
+ *
316
+ * Prepends link-layer headers to the packet buffer and transmits the
317
+ * packet via the specified network device.  This function takes
318
+ * ownership of the packet buffer.
319
+ */
320
+int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
321
+	     struct net_protocol *net_protocol, const void *ll_dest ) {
322
+	return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
323
+}
324
+
325
+/**
326
+ * Process received network-layer packet
327
+ *
328
+ * @v pkb		Packet buffer
329
+ * @v netdev		Network device
330
+ * @v net_proto		Network-layer protocol, in network-byte order
331
+ * @v ll_source		Source link-layer address
332
+ * @ret rc		Return status code
333
+ */
334
+int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
335
+	     uint16_t net_proto, const void *ll_source ) {
336
+	struct net_protocol *net_protocol;
337
+
338
+	/* Hand off to network-layer protocol, if any */
339
+	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
340
+	      net_protocol++ ) {
341
+		if ( net_protocol->net_proto == net_proto ) {
342
+			return net_protocol->rx ( pkb, netdev, ll_source );
343
+		}
344
+	}
345
+	free_pkb ( pkb );
346
+	return 0;
347
+}
348
+
298 349
 /**
299 350
  * Single-step the network stack
300 351
  *
@@ -321,8 +372,8 @@ static void net_step ( struct process *process ) {
321 372
 
322 373
 		/* Handle at most one received packet per poll */
323 374
 		if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
324
-			DBG ( "%s processing %p+%zx\n", netdev_name ( netdev ),
325
-			      pkb->data, pkb_len ( pkb ) );
375
+			DBGC ( netdev, "NETDEV %p processing %p\n",
376
+			       netdev, pkb );
326 377
 			netdev->ll_protocol->rx ( pkb, netdev );
327 378
 		}
328 379
 	}

Loading…
取消
儲存