summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2009-02-12 16:54:13 -0800
committerDavid S. Miller <davem@davemloft.net>2009-02-12 16:54:13 -0800
commit990ec3804bb9fd37fcce3e165c95e8b79a783aa3 (patch)
treea07d5c4aec13b1078f3c7b42cb3a1b1fdf37924f
parent259436a505bedc59a0114f2d17fa56af71d94129 (diff)
downloadblackbird-op-linux-990ec3804bb9fd37fcce3e165c95e8b79a783aa3.tar.gz
blackbird-op-linux-990ec3804bb9fd37fcce3e165c95e8b79a783aa3.zip
bnx2: Fix jumbo frames error handling.
If errors are reported on a frame descriptor, we need to account for the buffer pages that may have been used for this error packet and recycle them. Otherwise, we may get the wrong pages for the next packet. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bnx2.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d4a3dac21dcf..7a610b1b7737 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2910,18 +2910,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
rx_hdr = (struct l2_fhdr *) skb->data;
len = rx_hdr->l2_fhdr_pkt_len;
+ status = rx_hdr->l2_fhdr_status;
- if ((status = rx_hdr->l2_fhdr_status) &
- (L2_FHDR_ERRORS_BAD_CRC |
- L2_FHDR_ERRORS_PHY_DECODE |
- L2_FHDR_ERRORS_ALIGNMENT |
- L2_FHDR_ERRORS_TOO_SHORT |
- L2_FHDR_ERRORS_GIANT_FRAME)) {
-
- bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
- sw_ring_prod);
- goto next_rx;
- }
hdr_len = 0;
if (status & L2_FHDR_STATUS_SPLIT) {
hdr_len = rx_hdr->l2_fhdr_ip_xsum;
@@ -2931,6 +2921,24 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
pg_ring_used = 1;
}
+ if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC |
+ L2_FHDR_ERRORS_PHY_DECODE |
+ L2_FHDR_ERRORS_ALIGNMENT |
+ L2_FHDR_ERRORS_TOO_SHORT |
+ L2_FHDR_ERRORS_GIANT_FRAME))) {
+
+ bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
+ sw_ring_prod);
+ if (pg_ring_used) {
+ int pages;
+
+ pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT;
+
+ bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
+ }
+ goto next_rx;
+ }
+
len -= 4;
if (len <= bp->rx_copy_thresh) {
OpenPOWER on IntegriCloud