diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bnx2.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 469d259e6a20..f19a1e9a6b7f 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2323,17 +2323,25 @@ bnx2_phy_int(struct bnx2 *bp) | |||
2323 | 2323 | ||
2324 | } | 2324 | } |
2325 | 2325 | ||
2326 | static inline u16 | ||
2327 | bnx2_get_hw_tx_cons(struct bnx2 *bp) | ||
2328 | { | ||
2329 | u16 cons; | ||
2330 | |||
2331 | cons = bp->status_blk->status_tx_quick_consumer_index0; | ||
2332 | |||
2333 | if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) | ||
2334 | cons++; | ||
2335 | return cons; | ||
2336 | } | ||
2337 | |||
2326 | static void | 2338 | static void |
2327 | bnx2_tx_int(struct bnx2 *bp) | 2339 | bnx2_tx_int(struct bnx2 *bp) |
2328 | { | 2340 | { |
2329 | struct status_block *sblk = bp->status_blk; | ||
2330 | u16 hw_cons, sw_cons, sw_ring_cons; | 2341 | u16 hw_cons, sw_cons, sw_ring_cons; |
2331 | int tx_free_bd = 0; | 2342 | int tx_free_bd = 0; |
2332 | 2343 | ||
2333 | hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0; | 2344 | hw_cons = bnx2_get_hw_tx_cons(bp); |
2334 | if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { | ||
2335 | hw_cons++; | ||
2336 | } | ||
2337 | sw_cons = bp->tx_cons; | 2345 | sw_cons = bp->tx_cons; |
2338 | 2346 | ||
2339 | while (sw_cons != hw_cons) { | 2347 | while (sw_cons != hw_cons) { |
@@ -2385,14 +2393,10 @@ bnx2_tx_int(struct bnx2 *bp) | |||
2385 | 2393 | ||
2386 | dev_kfree_skb(skb); | 2394 | dev_kfree_skb(skb); |
2387 | 2395 | ||
2388 | hw_cons = bp->hw_tx_cons = | 2396 | hw_cons = bnx2_get_hw_tx_cons(bp); |
2389 | sblk->status_tx_quick_consumer_index0; | ||
2390 | |||
2391 | if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { | ||
2392 | hw_cons++; | ||
2393 | } | ||
2394 | } | 2397 | } |
2395 | 2398 | ||
2399 | bp->hw_tx_cons = hw_cons; | ||
2396 | bp->tx_cons = sw_cons; | 2400 | bp->tx_cons = sw_cons; |
2397 | /* Need to make the tx_cons update visible to bnx2_start_xmit() | 2401 | /* Need to make the tx_cons update visible to bnx2_start_xmit() |
2398 | * before checking for netif_queue_stopped(). Without the | 2402 | * before checking for netif_queue_stopped(). Without the |
@@ -2822,7 +2826,7 @@ bnx2_has_work(struct bnx2 *bp) | |||
2822 | struct status_block *sblk = bp->status_blk; | 2826 | struct status_block *sblk = bp->status_blk; |
2823 | 2827 | ||
2824 | if ((bnx2_get_hw_rx_cons(bp) != bp->rx_cons) || | 2828 | if ((bnx2_get_hw_rx_cons(bp) != bp->rx_cons) || |
2825 | (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)) | 2829 | (bnx2_get_hw_tx_cons(bp) != bp->hw_tx_cons)) |
2826 | return 1; | 2830 | return 1; |
2827 | 2831 | ||
2828 | if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) != | 2832 | if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) != |
@@ -2851,7 +2855,7 @@ static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget) | |||
2851 | REG_RD(bp, BNX2_HC_COMMAND); | 2855 | REG_RD(bp, BNX2_HC_COMMAND); |
2852 | } | 2856 | } |
2853 | 2857 | ||
2854 | if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) | 2858 | if (bnx2_get_hw_tx_cons(bp) != bp->hw_tx_cons) |
2855 | bnx2_tx_int(bp); | 2859 | bnx2_tx_int(bp); |
2856 | 2860 | ||
2857 | if (bnx2_get_hw_rx_cons(bp) != bp->rx_cons) | 2861 | if (bnx2_get_hw_rx_cons(bp) != bp->rx_cons) |
@@ -4917,7 +4921,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
4917 | REG_RD(bp, BNX2_HC_COMMAND); | 4921 | REG_RD(bp, BNX2_HC_COMMAND); |
4918 | 4922 | ||
4919 | udelay(5); | 4923 | udelay(5); |
4920 | rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0; | 4924 | rx_start_idx = bnx2_get_hw_rx_cons(bp); |
4921 | 4925 | ||
4922 | num_pkts = 0; | 4926 | num_pkts = 0; |
4923 | 4927 | ||
@@ -4947,11 +4951,10 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
4947 | pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); | 4951 | pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); |
4948 | dev_kfree_skb(skb); | 4952 | dev_kfree_skb(skb); |
4949 | 4953 | ||
4950 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) { | 4954 | if (bnx2_get_hw_tx_cons(bp) != bp->tx_prod) |
4951 | goto loopback_test_done; | 4955 | goto loopback_test_done; |
4952 | } | ||
4953 | 4956 | ||
4954 | rx_idx = bp->status_blk->status_rx_quick_consumer_index0; | 4957 | rx_idx = bnx2_get_hw_rx_cons(bp); |
4955 | if (rx_idx != rx_start_idx + num_pkts) { | 4958 | if (rx_idx != rx_start_idx + num_pkts) { |
4956 | goto loopback_test_done; | 4959 | goto loopback_test_done; |
4957 | } | 4960 | } |