diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2008-08-23 21:00:20 -0400 |
---|---|---|
committer | Lennert Buytenhek <buytenh@marvell.com> | 2008-08-23 21:33:44 -0400 |
commit | abe787170bb3888c5e587e8e986711fe32ddf2f9 (patch) | |
tree | a1e1854fe95054adf2c3336bb5713936f2ab4efe /drivers | |
parent | 9e1f37724265725ad4c14fc2ef60a162dc13ac64 (diff) |
mv643xx_eth: enforce multiple-of-8-bytes receive buffer size restriction
The mv643xx_eth hardware ignores the lower three bits of the buffer
size field in receive descriptors, causing the reception of full-sized
packets to fail at some MTUs. Fix this by rounding the size of
allocated receive buffers up to a multiple of eight bytes.
While we are at it, add a bit of extra space to each receive buffer so
that we can handle multiple vlan tags on ingress.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index e33dfc0165f6..a02a5f4a0294 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -474,11 +474,19 @@ static void rxq_refill(struct rx_queue *rxq) | |||
474 | /* | 474 | /* |
475 | * Reserve 2+14 bytes for an ethernet header (the | 475 | * Reserve 2+14 bytes for an ethernet header (the |
476 | * hardware automatically prepends 2 bytes of dummy | 476 | * hardware automatically prepends 2 bytes of dummy |
477 | * data to each received packet), 4 bytes for a VLAN | 477 | * data to each received packet), 16 bytes for up to |
478 | * header, and 4 bytes for the trailing FCS -- 24 | 478 | * four VLAN tags, and 4 bytes for the trailing FCS |
479 | * bytes total. | 479 | * -- 36 bytes total. |
480 | */ | 480 | */ |
481 | skb_size = mp->dev->mtu + 24; | 481 | skb_size = mp->dev->mtu + 36; |
482 | |||
483 | /* | ||
484 | * Make sure that the skb size is a multiple of 8 | ||
485 | * bytes, as the lower three bits of the receive | ||
486 | * descriptor's buffer size field are ignored by | ||
487 | * the hardware. | ||
488 | */ | ||
489 | skb_size = (skb_size + 7) & ~7; | ||
482 | 490 | ||
483 | skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1); | 491 | skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1); |
484 | if (skb == NULL) | 492 | if (skb == NULL) |
@@ -552,7 +560,7 @@ static int rxq_process(struct rx_queue *rxq, int budget) | |||
552 | spin_unlock_irqrestore(&mp->lock, flags); | 560 | spin_unlock_irqrestore(&mp->lock, flags); |
553 | 561 | ||
554 | dma_unmap_single(NULL, rx_desc->buf_ptr + 2, | 562 | dma_unmap_single(NULL, rx_desc->buf_ptr + 2, |
555 | mp->dev->mtu + 24, DMA_FROM_DEVICE); | 563 | rx_desc->buf_size, DMA_FROM_DEVICE); |
556 | rxq->rx_desc_count--; | 564 | rxq->rx_desc_count--; |
557 | rx++; | 565 | rx++; |
558 | 566 | ||