Browse Source

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 years ago
parent
commit
b7fcfe8ece

+ 8
- 4
src/arch/i386/drivers/net/undinet.c View File

349
 		= ( ( unsigned ) & __from_data16 ( undinet_pkb ) );
349
 		= ( ( unsigned ) & __from_data16 ( undinet_pkb ) );
350
 
350
 
351
 	/* Issue PXE API call */
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
 	return rc;
361
 	return rc;
358
 }
362
 }
359
 
363
 

+ 1
- 1
src/drivers/net/legacy.c View File

34
 	nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
34
 	nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
35
 				ntohs ( ethhdr->h_protocol ),
35
 				ntohs ( ethhdr->h_protocol ),
36
 				pkb_len ( pkb ), pkb->data );
36
 				pkb_len ( pkb ), pkb->data );
37
-	free_pkb ( pkb );
37
+	netdev_tx_complete ( netdev, pkb );
38
 	return 0;
38
 	return 0;
39
 }
39
 }
40
 
40
 

+ 1
- 1
src/drivers/net/pnic.c View File

158
 	pnic_command ( pnic, PNIC_CMD_XMIT, pkb->data, pkb_len ( pkb ),
158
 	pnic_command ( pnic, PNIC_CMD_XMIT, pkb->data, pkb_len ( pkb ),
159
 		       NULL, 0, NULL );
159
 		       NULL, 0, NULL );
160
 
160
 
161
-	free_pkb ( pkb );
161
+	netdev_tx_complete ( netdev, pkb );
162
 	return 0;
162
 	return 0;
163
 }
163
 }
164
 
164
 

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

304
 	/* Reset chip */
304
 	/* Reset chip */
305
 	outb ( CmdReset, rtl->ioaddr + ChipCmd );
305
 	outb ( CmdReset, rtl->ioaddr + ChipCmd );
306
 	mdelay ( 10 );
306
 	mdelay ( 10 );
307
-	rtl->tx.next = 0;
307
+	memset ( &rtl->tx, 0, sizeof ( rtl->tx ) );
308
 	rtl->rx.offset = 0;
308
 	rtl->rx.offset = 0;
309
 }
309
 }
310
 
310
 
349
  */
349
  */
350
 static void rtl_close ( struct net_device *netdev ) {
350
 static void rtl_close ( struct net_device *netdev ) {
351
 	struct rtl8139_nic *rtl = netdev->priv;
351
 	struct rtl8139_nic *rtl = netdev->priv;
352
-	int i;
353
 
352
 
354
 	/* Reset the hardware to disable everything in one go */
353
 	/* Reset the hardware to disable everything in one go */
355
 	rtl_reset ( rtl );
354
 	rtl_reset ( rtl );
357
 	/* Free RX ring */
356
 	/* Free RX ring */
358
 	free ( rtl->rx.ring );
357
 	free ( rtl->rx.ring );
359
 	rtl->rx.ring = NULL;
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
 	/* Check for space in TX ring */
373
 	/* Check for space in TX ring */
384
 	if ( rtl->tx.pkb[rtl->tx.next] != NULL ) {
374
 	if ( rtl->tx.pkb[rtl->tx.next] != NULL ) {
385
 		printf ( "TX overflow\n" );
375
 		printf ( "TX overflow\n" );
386
-		free_pkb ( pkb );
387
 		return -ENOBUFS;
376
 		return -ENOBUFS;
388
 	}
377
 	}
389
 
378
 
437
 	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
426
 	for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
438
 		if ( ( rtl->tx.pkb[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
427
 		if ( ( rtl->tx.pkb[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
439
 			DBG ( "TX id %d complete\n", i );
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
 			rtl->tx.pkb[i] = NULL;
430
 			rtl->tx.pkb[i] = NULL;
442
 		}
431
 		}
443
 	}
432
 	}

+ 14
- 8
src/include/gpxe/netdevice.h View File

168
 	 * This method should cause the hardware to initiate
168
 	 * This method should cause the hardware to initiate
169
 	 * transmission of the packet buffer.
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
 	 * This method is guaranteed to be called only when the device
177
 	 * This method is guaranteed to be called only when the device
176
 	 * is open.
178
 	 * is open.
202
 	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
204
 	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
203
 	 */
205
 	 */
204
 	unsigned int state;
206
 	unsigned int state;
205
-	/** Received packet queue */
207
+	/** TX packet queue */
208
+	struct list_head tx_queue;
209
+	/** RX packet queue */
206
 	struct list_head rx_queue;
210
 	struct list_head rx_queue;
207
 
211
 
208
 	/** Driver private data */
212
 	/** Driver private data */
231
 }
235
 }
232
 
236
 
233
 extern int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb );
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
 extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
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
 extern int netdev_poll ( struct net_device *netdev );
241
 extern int netdev_poll ( struct net_device *netdev );
240
 extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
242
 extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
241
 extern struct net_device * alloc_netdev ( size_t priv_size );
243
 extern struct net_device * alloc_netdev ( size_t priv_size );
245
 extern void unregister_netdev ( struct net_device *netdev );
247
 extern void unregister_netdev ( struct net_device *netdev );
246
 extern void free_netdev ( struct net_device *netdev );
248
 extern void free_netdev ( struct net_device *netdev );
247
 extern struct net_device * next_netdev ( void );
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
 #endif /* _GPXE_NETDEVICE_H */
255
 #endif /* _GPXE_NETDEVICE_H */

+ 101
- 50
src/net/netdevice.c View File

52
  * function takes ownership of the packet buffer.
52
  * function takes ownership of the packet buffer.
53
  */
53
  */
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 ),
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
 	if ( ! ( netdev->state & NETDEV_OPEN ) ) {
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
  * @v netdev		Network device
82
  * @v netdev		Network device
70
  * @v pkb		Packet buffer
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
  * @v netdev		Network device
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
  * @v netdev		Network device
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
 	netdev = calloc ( 1, sizeof ( *netdev ) + priv_size );
173
 	netdev = calloc ( 1, sizeof ( *netdev ) + priv_size );
172
 	if ( netdev ) {
174
 	if ( netdev ) {
173
 		INIT_LIST_HEAD ( &netdev->references );
175
 		INIT_LIST_HEAD ( &netdev->references );
176
+		INIT_LIST_HEAD ( &netdev->tx_queue );
174
 		INIT_LIST_HEAD ( &netdev->rx_queue );
177
 		INIT_LIST_HEAD ( &netdev->rx_queue );
175
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
178
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
176
 	}
179
 	}
189
 	
192
 	
190
 	/* Add to device list */
193
 	/* Add to device list */
191
 	list_add_tail ( &netdev->list, &net_devices );
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
 	return 0;
198
 	return 0;
195
 }
199
 }
207
 	if ( netdev->state & NETDEV_OPEN )
211
 	if ( netdev->state & NETDEV_OPEN )
208
 		return 0;
212
 		return 0;
209
 
213
 
210
-	DBG ( "%s opening\n", netdev_name ( netdev ) );
214
+	DBGC ( netdev, "NETDEV %p opening\n", netdev );
211
 
215
 
212
 	/* Open the device */
216
 	/* Open the device */
213
 	if ( ( rc = netdev->open ( netdev ) ) != 0 )
217
 	if ( ( rc = netdev->open ( netdev ) ) != 0 )
230
 	if ( ! ( netdev->state & NETDEV_OPEN ) )
234
 	if ( ! ( netdev->state & NETDEV_OPEN ) )
231
 		return;
235
 		return;
232
 
236
 
233
-	DBG ( "%s closing\n", netdev_name ( netdev ) );
237
+	DBGC ( netdev, "NETDEV %p closing\n", netdev );
234
 
238
 
235
 	/* Close the device */
239
 	/* Close the device */
236
 	netdev->close ( netdev );
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
 	/* Discard any packets in the RX queue */
247
 	/* Discard any packets in the RX queue */
239
 	while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
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
 		free_pkb ( pkb );
251
 		free_pkb ( pkb );
243
 	}
252
 	}
244
 
253
 
263
 
272
 
264
 	/* Remove from device list */
273
 	/* Remove from device list */
265
 	list_del ( &netdev->list );
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
 	return NULL;
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
  * Single-step the network stack
350
  * Single-step the network stack
300
  *
351
  *
321
 
372
 
322
 		/* Handle at most one received packet per poll */
373
 		/* Handle at most one received packet per poll */
323
 		if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
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
 			netdev->ll_protocol->rx ( pkb, netdev );
377
 			netdev->ll_protocol->rx ( pkb, netdev );
327
 		}
378
 		}
328
 	}
379
 	}

Loading…
Cancel
Save