Browse Source

[undi] Align the received frame payload for faster processing

The undinet driver always has to make a copy of the received frame
into an I/O buffer.  Align this copy sensibly so that subsequent
operations are as fast as possible.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
76d9c1a001
1 changed files with 16 additions and 8 deletions
  1. 16
    8
      src/arch/i386/drivers/net/undinet.c

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

70
 /** Delay between retries of PXENV_UNDI_INITIALIZE */
70
 /** Delay between retries of PXENV_UNDI_INITIALIZE */
71
 #define UNDI_INITIALIZE_RETRY_DELAY_MS 200
71
 #define UNDI_INITIALIZE_RETRY_DELAY_MS 200
72
 
72
 
73
+/** Alignment of received frame payload */
74
+#define UNDI_RX_ALIGN 16
75
+
73
 static void undinet_close ( struct net_device *netdev );
76
 static void undinet_close ( struct net_device *netdev );
74
 
77
 
75
 /** Address of UNDI entry point */
78
 /** Address of UNDI entry point */
299
 	struct s_PXENV_UNDI_ISR undi_isr;
302
 	struct s_PXENV_UNDI_ISR undi_isr;
300
 	struct io_buffer *iobuf = NULL;
303
 	struct io_buffer *iobuf = NULL;
301
 	size_t len;
304
 	size_t len;
305
+	size_t reserve_len;
302
 	size_t frag_len;
306
 	size_t frag_len;
303
 	size_t max_frag_len;
307
 	size_t max_frag_len;
304
 	int rc;
308
 	int rc;
346
 			/* Packet fragment received */
350
 			/* Packet fragment received */
347
 			len = undi_isr.FrameLength;
351
 			len = undi_isr.FrameLength;
348
 			frag_len = undi_isr.BufferLength;
352
 			frag_len = undi_isr.BufferLength;
353
+			reserve_len = ( -undi_isr.FrameHeaderLength &
354
+					( UNDI_RX_ALIGN - 1 ) );
349
 			if ( ( len == 0 ) || ( len < frag_len ) ) {
355
 			if ( ( len == 0 ) || ( len < frag_len ) ) {
350
 				/* Don't laugh.  VMWare does it. */
356
 				/* Don't laugh.  VMWare does it. */
351
 				DBGC ( undinic, "UNDINIC %p reported insane "
357
 				DBGC ( undinic, "UNDINIC %p reported insane "
354
 				netdev_rx_err ( netdev, NULL, -EINVAL );
360
 				netdev_rx_err ( netdev, NULL, -EINVAL );
355
 				break;
361
 				break;
356
 			}
362
 			}
357
-			if ( ! iobuf )
358
-				iobuf = alloc_iob ( len );
359
 			if ( ! iobuf ) {
363
 			if ( ! iobuf ) {
360
-				DBGC ( undinic, "UNDINIC %p could not "
361
-				       "allocate %zd bytes for RX buffer\n",
362
-				       undinic, len );
363
-				/* Fragment will be dropped */
364
-				netdev_rx_err ( netdev, NULL, -ENOMEM );
365
-				goto done;
364
+				iobuf = alloc_iob ( reserve_len + len );
365
+				if ( ! iobuf ) {
366
+					DBGC ( undinic, "UNDINIC %p could not "
367
+					       "allocate %zd bytes for RX "
368
+					       "buffer\n", undinic, len );
369
+					/* Fragment will be dropped */
370
+					netdev_rx_err ( netdev, NULL, -ENOMEM );
371
+					goto done;
372
+				}
373
+				iob_reserve ( iobuf, reserve_len );
366
 			}
374
 			}
367
 			max_frag_len = iob_tailroom ( iobuf );
375
 			max_frag_len = iob_tailroom ( iobuf );
368
 			if ( frag_len > max_frag_len ) {
376
 			if ( frag_len > max_frag_len ) {

Loading…
Cancel
Save