|
@@ -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 ) {
|