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,6 +70,9 @@ struct undi_nic {
70 70
 /** Delay between retries of PXENV_UNDI_INITIALIZE */
71 71
 #define UNDI_INITIALIZE_RETRY_DELAY_MS 200
72 72
 
73
+/** Alignment of received frame payload */
74
+#define UNDI_RX_ALIGN 16
75
+
73 76
 static void undinet_close ( struct net_device *netdev );
74 77
 
75 78
 /** Address of UNDI entry point */
@@ -299,6 +302,7 @@ static void undinet_poll ( struct net_device *netdev ) {
299 302
 	struct s_PXENV_UNDI_ISR undi_isr;
300 303
 	struct io_buffer *iobuf = NULL;
301 304
 	size_t len;
305
+	size_t reserve_len;
302 306
 	size_t frag_len;
303 307
 	size_t max_frag_len;
304 308
 	int rc;
@@ -346,6 +350,8 @@ static void undinet_poll ( struct net_device *netdev ) {
346 350
 			/* Packet fragment received */
347 351
 			len = undi_isr.FrameLength;
348 352
 			frag_len = undi_isr.BufferLength;
353
+			reserve_len = ( -undi_isr.FrameHeaderLength &
354
+					( UNDI_RX_ALIGN - 1 ) );
349 355
 			if ( ( len == 0 ) || ( len < frag_len ) ) {
350 356
 				/* Don't laugh.  VMWare does it. */
351 357
 				DBGC ( undinic, "UNDINIC %p reported insane "
@@ -354,15 +360,17 @@ static void undinet_poll ( struct net_device *netdev ) {
354 360
 				netdev_rx_err ( netdev, NULL, -EINVAL );
355 361
 				break;
356 362
 			}
357
-			if ( ! iobuf )
358
-				iobuf = alloc_iob ( len );
359 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 375
 			max_frag_len = iob_tailroom ( iobuf );
368 376
 			if ( frag_len > max_frag_len ) {

Loading…
Cancel
Save