aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2005-08-25 18:36:58 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 19:10:38 -0400
commite89bbf1049aac3625fdafe3657ed8d7d5373d351 (patch)
tree15e0fc01d553ce5bc38de546d80f5f2e3736b0bf /drivers/net/bnx2.c
parentcd339a0ed61097d92ce03b6d1042b1e4d58535e7 (diff)
[BNX2]: remove atomics in tx
Remove atomic operations in the fast tx path. Expensive atomic operations were used to keep track of the number of available tx descriptors. The new code uses the difference between the consumer and producer index to determine the number of free tx descriptors. As suggested by Jeff Garzik, the name of the inline function is changed to all lower case. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c35
1 files changed, 17 insertions, 18 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 015ff7906601..da903b3ebfb0 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -107,6 +107,15 @@ static struct flash_spec flash_table[] =
107 107
108MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); 108MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
109 109
110static inline u32 bnx2_tx_avail(struct bnx2 *bp)
111{
112 u32 diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons);
113
114 if (diff > MAX_TX_DESC_CNT)
115 diff = (diff & MAX_TX_DESC_CNT) - 1;
116 return (bp->tx_ring_size - diff);
117}
118
110static u32 119static u32
111bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) 120bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
112{ 121{
@@ -1338,22 +1347,19 @@ bnx2_tx_int(struct bnx2 *bp)
1338 } 1347 }
1339 } 1348 }
1340 1349
1341 atomic_add(tx_free_bd, &bp->tx_avail_bd); 1350 bp->tx_cons = sw_cons;
1342 1351
1343 if (unlikely(netif_queue_stopped(bp->dev))) { 1352 if (unlikely(netif_queue_stopped(bp->dev))) {
1344 unsigned long flags; 1353 unsigned long flags;
1345 1354
1346 spin_lock_irqsave(&bp->tx_lock, flags); 1355 spin_lock_irqsave(&bp->tx_lock, flags);
1347 if ((netif_queue_stopped(bp->dev)) && 1356 if ((netif_queue_stopped(bp->dev)) &&
1348 (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)) { 1357 (bnx2_tx_avail(bp) > MAX_SKB_FRAGS)) {
1349 1358
1350 netif_wake_queue(bp->dev); 1359 netif_wake_queue(bp->dev);
1351 } 1360 }
1352 spin_unlock_irqrestore(&bp->tx_lock, flags); 1361 spin_unlock_irqrestore(&bp->tx_lock, flags);
1353 } 1362 }
1354
1355 bp->tx_cons = sw_cons;
1356
1357} 1363}
1358 1364
1359static inline void 1365static inline void
@@ -2971,7 +2977,6 @@ bnx2_init_tx_ring(struct bnx2 *bp)
2971 bp->tx_prod = 0; 2977 bp->tx_prod = 0;
2972 bp->tx_cons = 0; 2978 bp->tx_cons = 0;
2973 bp->tx_prod_bseq = 0; 2979 bp->tx_prod_bseq = 0;
2974 atomic_set(&bp->tx_avail_bd, bp->tx_ring_size);
2975 2980
2976 val = BNX2_L2CTX_TYPE_TYPE_L2; 2981 val = BNX2_L2CTX_TYPE_TYPE_L2;
2977 val |= BNX2_L2CTX_TYPE_SIZE_L2; 2982 val |= BNX2_L2CTX_TYPE_SIZE_L2;
@@ -4057,9 +4062,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4057 u16 prod, ring_prod; 4062 u16 prod, ring_prod;
4058 int i; 4063 int i;
4059 4064
4060 if (unlikely(atomic_read(&bp->tx_avail_bd) < 4065 if (unlikely(bnx2_tx_avail(bp) < (skb_shinfo(skb)->nr_frags + 1))) {
4061 (skb_shinfo(skb)->nr_frags + 1))) {
4062
4063 netif_stop_queue(dev); 4066 netif_stop_queue(dev);
4064 printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n", 4067 printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
4065 dev->name); 4068 dev->name);
@@ -4156,8 +4159,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4156 prod = NEXT_TX_BD(prod); 4159 prod = NEXT_TX_BD(prod);
4157 bp->tx_prod_bseq += skb->len; 4160 bp->tx_prod_bseq += skb->len;
4158 4161
4159 atomic_sub(last_frag + 1, &bp->tx_avail_bd);
4160
4161 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); 4162 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
4162 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); 4163 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
4163 4164
@@ -4166,16 +4167,14 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4166 bp->tx_prod = prod; 4167 bp->tx_prod = prod;
4167 dev->trans_start = jiffies; 4168 dev->trans_start = jiffies;
4168 4169
4169 if (unlikely(atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS)) { 4170 if (unlikely(bnx2_tx_avail(bp) <= MAX_SKB_FRAGS)) {
4170 unsigned long flags; 4171 unsigned long flags;
4171 4172
4172 spin_lock_irqsave(&bp->tx_lock, flags); 4173 spin_lock_irqsave(&bp->tx_lock, flags);
4173 if (atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS) { 4174 netif_stop_queue(dev);
4174 netif_stop_queue(dev); 4175
4175 4176 if (bnx2_tx_avail(bp) > MAX_SKB_FRAGS)
4176 if (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS) 4177 netif_wake_queue(dev);
4177 netif_wake_queue(dev);
4178 }
4179 spin_unlock_irqrestore(&bp->tx_lock, flags); 4178 spin_unlock_irqrestore(&bp->tx_lock, flags);
4180 } 4179 }
4181 4180