aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bnx2.c55
-rw-r--r--drivers/net/bnx2.h3
2 files changed, 43 insertions, 15 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index affb67372e02..aa6d30e0d829 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1533,10 +1533,11 @@ bnx2_phy_int(struct bnx2 *bp)
1533static void 1533static void
1534bnx2_tx_int(struct bnx2 *bp) 1534bnx2_tx_int(struct bnx2 *bp)
1535{ 1535{
1536 struct status_block *sblk = bp->status_blk;
1536 u16 hw_cons, sw_cons, sw_ring_cons; 1537 u16 hw_cons, sw_cons, sw_ring_cons;
1537 int tx_free_bd = 0; 1538 int tx_free_bd = 0;
1538 1539
1539 hw_cons = bp->status_blk->status_tx_quick_consumer_index0; 1540 hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
1540 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { 1541 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
1541 hw_cons++; 1542 hw_cons++;
1542 } 1543 }
@@ -1591,7 +1592,9 @@ bnx2_tx_int(struct bnx2 *bp)
1591 1592
1592 dev_kfree_skb_irq(skb); 1593 dev_kfree_skb_irq(skb);
1593 1594
1594 hw_cons = bp->status_blk->status_tx_quick_consumer_index0; 1595 hw_cons = bp->hw_tx_cons =
1596 sblk->status_tx_quick_consumer_index0;
1597
1595 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { 1598 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
1596 hw_cons++; 1599 hw_cons++;
1597 } 1600 }
@@ -1636,11 +1639,12 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
1636static int 1639static int
1637bnx2_rx_int(struct bnx2 *bp, int budget) 1640bnx2_rx_int(struct bnx2 *bp, int budget)
1638{ 1641{
1642 struct status_block *sblk = bp->status_blk;
1639 u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; 1643 u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
1640 struct l2_fhdr *rx_hdr; 1644 struct l2_fhdr *rx_hdr;
1641 int rx_pkt = 0; 1645 int rx_pkt = 0;
1642 1646
1643 hw_cons = bp->status_blk->status_rx_quick_consumer_index0; 1647 hw_cons = bp->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
1644 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { 1648 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
1645 hw_cons++; 1649 hw_cons++;
1646 } 1650 }
@@ -1760,6 +1764,15 @@ next_rx:
1760 1764
1761 if ((rx_pkt == budget)) 1765 if ((rx_pkt == budget))
1762 break; 1766 break;
1767
1768 /* Refresh hw_cons to see if there is new work */
1769 if (sw_cons == hw_cons) {
1770 hw_cons = bp->hw_rx_cons =
1771 sblk->status_rx_quick_consumer_index0;
1772 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)
1773 hw_cons++;
1774 rmb();
1775 }
1763 } 1776 }
1764 bp->rx_cons = sw_cons; 1777 bp->rx_cons = sw_cons;
1765 bp->rx_prod = sw_prod; 1778 bp->rx_prod = sw_prod;
@@ -1827,15 +1840,27 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1827 return IRQ_HANDLED; 1840 return IRQ_HANDLED;
1828} 1841}
1829 1842
1843static inline int
1844bnx2_has_work(struct bnx2 *bp)
1845{
1846 struct status_block *sblk = bp->status_blk;
1847
1848 if ((sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) ||
1849 (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
1850 return 1;
1851
1852 if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
1853 bp->link_up)
1854 return 1;
1855
1856 return 0;
1857}
1858
1830static int 1859static int
1831bnx2_poll(struct net_device *dev, int *budget) 1860bnx2_poll(struct net_device *dev, int *budget)
1832{ 1861{
1833 struct bnx2 *bp = dev->priv; 1862 struct bnx2 *bp = dev->priv;
1834 int rx_done = 1;
1835
1836 bp->last_status_idx = bp->status_blk->status_idx;
1837 1863
1838 rmb();
1839 if ((bp->status_blk->status_attn_bits & 1864 if ((bp->status_blk->status_attn_bits &
1840 STATUS_ATTN_BITS_LINK_STATE) != 1865 STATUS_ATTN_BITS_LINK_STATE) !=
1841 (bp->status_blk->status_attn_bits_ack & 1866 (bp->status_blk->status_attn_bits_ack &
@@ -1846,11 +1871,10 @@ bnx2_poll(struct net_device *dev, int *budget)
1846 spin_unlock(&bp->phy_lock); 1871 spin_unlock(&bp->phy_lock);
1847 } 1872 }
1848 1873
1849 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { 1874 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
1850 bnx2_tx_int(bp); 1875 bnx2_tx_int(bp);
1851 }
1852 1876
1853 if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) { 1877 if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) {
1854 int orig_budget = *budget; 1878 int orig_budget = *budget;
1855 int work_done; 1879 int work_done;
1856 1880
@@ -1860,13 +1884,12 @@ bnx2_poll(struct net_device *dev, int *budget)
1860 work_done = bnx2_rx_int(bp, orig_budget); 1884 work_done = bnx2_rx_int(bp, orig_budget);
1861 *budget -= work_done; 1885 *budget -= work_done;
1862 dev->quota -= work_done; 1886 dev->quota -= work_done;
1863
1864 if (work_done >= orig_budget) {
1865 rx_done = 0;
1866 }
1867 } 1887 }
1868 1888
1869 if (rx_done) { 1889 bp->last_status_idx = bp->status_blk->status_idx;
1890 rmb();
1891
1892 if (!bnx2_has_work(bp)) {
1870 netif_rx_complete(dev); 1893 netif_rx_complete(dev);
1871 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 1894 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
1872 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | 1895 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -3222,6 +3245,7 @@ bnx2_init_tx_ring(struct bnx2 *bp)
3222 3245
3223 bp->tx_prod = 0; 3246 bp->tx_prod = 0;
3224 bp->tx_cons = 0; 3247 bp->tx_cons = 0;
3248 bp->hw_tx_cons = 0;
3225 bp->tx_prod_bseq = 0; 3249 bp->tx_prod_bseq = 0;
3226 3250
3227 val = BNX2_L2CTX_TYPE_TYPE_L2; 3251 val = BNX2_L2CTX_TYPE_TYPE_L2;
@@ -3254,6 +3278,7 @@ bnx2_init_rx_ring(struct bnx2 *bp)
3254 3278
3255 ring_prod = prod = bp->rx_prod = 0; 3279 ring_prod = prod = bp->rx_prod = 0;
3256 bp->rx_cons = 0; 3280 bp->rx_cons = 0;
3281 bp->hw_rx_cons = 0;
3257 bp->rx_prod_bseq = 0; 3282 bp->rx_prod_bseq = 0;
3258 3283
3259 rxbd = &bp->rx_desc_ring[0]; 3284 rxbd = &bp->rx_desc_ring[0];
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 012586e4ba0b..76bb5f1a250b 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -3914,6 +3914,9 @@ struct bnx2 {
3914 u16 tx_cons; 3914 u16 tx_cons;
3915 int tx_ring_size; 3915 int tx_ring_size;
3916 3916
3917 u16 hw_tx_cons;
3918 u16 hw_rx_cons;
3919
3917#ifdef BCM_VLAN 3920#ifdef BCM_VLAN
3918 struct vlan_group *vlgrp; 3921 struct vlan_group *vlgrp;
3919#endif 3922#endif