diff options
| -rw-r--r-- | drivers/net/bnx2.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index dfe50c286d95..14119fb5964d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -2379,6 +2379,27 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb, | |||
| 2379 | prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; | 2379 | prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; |
| 2380 | } | 2380 | } |
| 2381 | 2381 | ||
| 2382 | static int | ||
| 2383 | bnx2_rx_skb(struct bnx2 *bp, struct sk_buff *skb, unsigned int len, | ||
| 2384 | dma_addr_t dma_addr, u32 ring_idx) | ||
| 2385 | { | ||
| 2386 | int err; | ||
| 2387 | u16 prod = ring_idx & 0xffff; | ||
| 2388 | |||
| 2389 | err = bnx2_alloc_rx_skb(bp, prod); | ||
| 2390 | if (unlikely(err)) { | ||
| 2391 | bnx2_reuse_rx_skb(bp, skb, (u16) (ring_idx >> 16), prod); | ||
| 2392 | return err; | ||
| 2393 | } | ||
| 2394 | |||
| 2395 | skb_reserve(skb, bp->rx_offset); | ||
| 2396 | pci_unmap_single(bp->pdev, dma_addr, bp->rx_buf_use_size, | ||
| 2397 | PCI_DMA_FROMDEVICE); | ||
| 2398 | |||
| 2399 | skb_put(skb, len); | ||
| 2400 | return 0; | ||
| 2401 | } | ||
| 2402 | |||
| 2382 | static inline u16 | 2403 | static inline u16 |
| 2383 | bnx2_get_hw_rx_cons(struct bnx2 *bp) | 2404 | bnx2_get_hw_rx_cons(struct bnx2 *bp) |
| 2384 | { | 2405 | { |
| @@ -2434,7 +2455,8 @@ bnx2_rx_int(struct bnx2 *bp, int budget) | |||
| 2434 | L2_FHDR_ERRORS_TOO_SHORT | | 2455 | L2_FHDR_ERRORS_TOO_SHORT | |
| 2435 | L2_FHDR_ERRORS_GIANT_FRAME)) { | 2456 | L2_FHDR_ERRORS_GIANT_FRAME)) { |
| 2436 | 2457 | ||
| 2437 | goto reuse_rx; | 2458 | bnx2_reuse_rx_skb(bp, skb, sw_ring_cons, sw_ring_prod); |
| 2459 | goto next_rx; | ||
| 2438 | } | 2460 | } |
| 2439 | 2461 | ||
| 2440 | /* Since we don't have a jumbo ring, copy small packets | 2462 | /* Since we don't have a jumbo ring, copy small packets |
| @@ -2444,8 +2466,11 @@ bnx2_rx_int(struct bnx2 *bp, int budget) | |||
| 2444 | struct sk_buff *new_skb; | 2466 | struct sk_buff *new_skb; |
| 2445 | 2467 | ||
| 2446 | new_skb = netdev_alloc_skb(bp->dev, len + 2); | 2468 | new_skb = netdev_alloc_skb(bp->dev, len + 2); |
| 2447 | if (new_skb == NULL) | 2469 | if (new_skb == NULL) { |
| 2448 | goto reuse_rx; | 2470 | bnx2_reuse_rx_skb(bp, skb, sw_ring_cons, |
| 2471 | sw_ring_prod); | ||
| 2472 | goto next_rx; | ||
| 2473 | } | ||
| 2449 | 2474 | ||
| 2450 | /* aligned copy */ | 2475 | /* aligned copy */ |
| 2451 | skb_copy_from_linear_data_offset(skb, bp->rx_offset - 2, | 2476 | skb_copy_from_linear_data_offset(skb, bp->rx_offset - 2, |
| @@ -2457,20 +2482,9 @@ bnx2_rx_int(struct bnx2 *bp, int budget) | |||
| 2457 | sw_ring_cons, sw_ring_prod); | 2482 | sw_ring_cons, sw_ring_prod); |
| 2458 | 2483 | ||
| 2459 | skb = new_skb; | 2484 | skb = new_skb; |
| 2460 | } | 2485 | } else if (unlikely(bnx2_rx_skb(bp, skb, len, dma_addr, |
| 2461 | else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) { | 2486 | (sw_ring_cons << 16) | sw_ring_prod))) |
| 2462 | pci_unmap_single(bp->pdev, dma_addr, | ||
| 2463 | bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); | ||
| 2464 | |||
| 2465 | skb_reserve(skb, bp->rx_offset); | ||
| 2466 | skb_put(skb, len); | ||
| 2467 | } | ||
| 2468 | else { | ||
| 2469 | reuse_rx: | ||
| 2470 | bnx2_reuse_rx_skb(bp, skb, | ||
| 2471 | sw_ring_cons, sw_ring_prod); | ||
| 2472 | goto next_rx; | 2487 | goto next_rx; |
| 2473 | } | ||
| 2474 | 2488 | ||
| 2475 | skb->protocol = eth_type_trans(skb, bp->dev); | 2489 | skb->protocol = eth_type_trans(skb, bp->dev); |
| 2476 | 2490 | ||
