aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-09-26 14:57:42 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-27 17:56:31 -0400
commit2bb8c26242c2393b097a993ffe9b003ec9b85395 (patch)
tree3d800c046bbf663a31038605eb9d849b85b2eb66 /drivers/net
parent291ea6142b94cc3e3ae2216d3937a78697447471 (diff)
[PATCH] sky2: use netif_tx_lock instead of LLTX
Use the netdevice transmit lock via netif_tx_lock rather than putting lock in device specific code and using lockless transmit. The code is cleaner using netif_tx_lock, and the performance is same. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sky2.c57
-rw-r--r--drivers/net/sky2.h1
2 files changed, 17 insertions, 41 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 64af764d0087..c83d7262a5a8 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -942,13 +942,13 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
942 struct sky2_hw *hw = sky2->hw; 942 struct sky2_hw *hw = sky2->hw;
943 u16 port = sky2->port; 943 u16 port = sky2->port;
944 944
945 spin_lock_bh(&sky2->tx_lock); 945 netif_tx_lock_bh(dev);
946 946
947 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON); 947 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
948 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON); 948 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
949 sky2->vlgrp = grp; 949 sky2->vlgrp = grp;
950 950
951 spin_unlock_bh(&sky2->tx_lock); 951 netif_tx_unlock_bh(dev);
952} 952}
953 953
954static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) 954static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -957,14 +957,14 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
957 struct sky2_hw *hw = sky2->hw; 957 struct sky2_hw *hw = sky2->hw;
958 u16 port = sky2->port; 958 u16 port = sky2->port;
959 959
960 spin_lock_bh(&sky2->tx_lock); 960 netif_tx_lock_bh(dev);
961 961
962 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF); 962 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
963 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF); 963 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
964 if (sky2->vlgrp) 964 if (sky2->vlgrp)
965 sky2->vlgrp->vlan_devices[vid] = NULL; 965 sky2->vlgrp->vlan_devices[vid] = NULL;
966 966
967 spin_unlock_bh(&sky2->tx_lock); 967 netif_tx_unlock_bh(dev);
968} 968}
969#endif 969#endif
970 970
@@ -1202,8 +1202,6 @@ static unsigned tx_le_req(const struct sk_buff *skb)
1202 * A single packet can generate multiple list elements, and 1202 * A single packet can generate multiple list elements, and
1203 * the number of ring elements will probably be less than the number 1203 * the number of ring elements will probably be less than the number
1204 * of list elements used. 1204 * of list elements used.
1205 *
1206 * No BH disabling for tx_lock here (like tg3)
1207 */ 1205 */
1208static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) 1206static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1209{ 1207{
@@ -1217,27 +1215,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1217 u16 mss; 1215 u16 mss;
1218 u8 ctrl; 1216 u8 ctrl;
1219 1217
1220 /* No BH disabling for tx_lock here. We are running in BH disabled 1218 if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
1221 * context and TX reclaim runs via poll inside of a software 1219 return NETDEV_TX_BUSY;
1222 * interrupt, and no related locks in IRQ processing.
1223 */
1224 if (!spin_trylock(&sky2->tx_lock))
1225 return NETDEV_TX_LOCKED;
1226
1227 if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
1228 /* There is a known but harmless race with lockless tx
1229 * and netif_stop_queue.
1230 */
1231 if (!netif_queue_stopped(dev)) {
1232 netif_stop_queue(dev);
1233 if (net_ratelimit())
1234 printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
1235 dev->name);
1236 }
1237 spin_unlock(&sky2->tx_lock);
1238
1239 return NETDEV_TX_BUSY;
1240 }
1241 1220
1242 if (unlikely(netif_msg_tx_queued(sky2))) 1221 if (unlikely(netif_msg_tx_queued(sky2)))
1243 printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n", 1222 printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
@@ -1352,8 +1331,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1352 1331
1353 sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); 1332 sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
1354 1333
1355 spin_unlock(&sky2->tx_lock);
1356
1357 dev->trans_start = jiffies; 1334 dev->trans_start = jiffies;
1358 return NETDEV_TX_OK; 1335 return NETDEV_TX_OK;
1359} 1336}
@@ -1408,11 +1385,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1408} 1385}
1409 1386
1410/* Cleanup all untransmitted buffers, assume transmitter not running */ 1387/* Cleanup all untransmitted buffers, assume transmitter not running */
1411static void sky2_tx_clean(struct sky2_port *sky2) 1388static void sky2_tx_clean(struct net_device *dev)
1412{ 1389{
1413 spin_lock_bh(&sky2->tx_lock); 1390 struct sky2_port *sky2 = netdev_priv(dev);
1391
1392 netif_tx_lock_bh(dev);
1414 sky2_tx_complete(sky2, sky2->tx_prod); 1393 sky2_tx_complete(sky2, sky2->tx_prod);
1415 spin_unlock_bh(&sky2->tx_lock); 1394 netif_tx_unlock_bh(dev);
1416} 1395}
1417 1396
1418/* Network shutdown */ 1397/* Network shutdown */
@@ -1496,7 +1475,7 @@ static int sky2_down(struct net_device *dev)
1496 1475
1497 synchronize_irq(hw->pdev->irq); 1476 synchronize_irq(hw->pdev->irq);
1498 1477
1499 sky2_tx_clean(sky2); 1478 sky2_tx_clean(dev);
1500 sky2_rx_clean(sky2); 1479 sky2_rx_clean(sky2);
1501 1480
1502 pci_free_consistent(hw->pdev, RX_LE_BYTES, 1481 pci_free_consistent(hw->pdev, RX_LE_BYTES,
@@ -1748,16 +1727,16 @@ static void sky2_tx_timeout(struct net_device *dev)
1748 } else if (report != sky2->tx_cons) { 1727 } else if (report != sky2->tx_cons) {
1749 printk(KERN_INFO PFX "status report lost?\n"); 1728 printk(KERN_INFO PFX "status report lost?\n");
1750 1729
1751 spin_lock_bh(&sky2->tx_lock); 1730 netif_tx_lock_bh(dev);
1752 sky2_tx_complete(sky2, report); 1731 sky2_tx_complete(sky2, report);
1753 spin_unlock_bh(&sky2->tx_lock); 1732 netif_tx_unlock_bh(dev);
1754 } else { 1733 } else {
1755 printk(KERN_INFO PFX "hardware hung? flushing\n"); 1734 printk(KERN_INFO PFX "hardware hung? flushing\n");
1756 1735
1757 sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); 1736 sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
1758 sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); 1737 sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
1759 1738
1760 sky2_tx_clean(sky2); 1739 sky2_tx_clean(dev);
1761 1740
1762 sky2_qset(hw, txq); 1741 sky2_qset(hw, txq);
1763 sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1); 1742 sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
@@ -1927,9 +1906,9 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
1927 struct sky2_port *sky2 = netdev_priv(dev); 1906 struct sky2_port *sky2 = netdev_priv(dev);
1928 1907
1929 if (netif_running(dev)) { 1908 if (netif_running(dev)) {
1930 spin_lock(&sky2->tx_lock); 1909 netif_tx_lock(dev);
1931 sky2_tx_complete(sky2, last); 1910 sky2_tx_complete(sky2, last);
1932 spin_unlock(&sky2->tx_lock); 1911 netif_tx_unlock(dev);
1933 } 1912 }
1934} 1913}
1935 1914
@@ -3134,7 +3113,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3134 sky2->hw = hw; 3113 sky2->hw = hw;
3135 sky2->msg_enable = netif_msg_init(debug, default_msg); 3114 sky2->msg_enable = netif_msg_init(debug, default_msg);
3136 3115
3137 spin_lock_init(&sky2->tx_lock);
3138 /* Auto speed and flow control */ 3116 /* Auto speed and flow control */
3139 sky2->autoneg = AUTONEG_ENABLE; 3117 sky2->autoneg = AUTONEG_ENABLE;
3140 sky2->tx_pause = 1; 3118 sky2->tx_pause = 1;
@@ -3153,7 +3131,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3153 3131
3154 sky2->port = port; 3132 sky2->port = port;
3155 3133
3156 dev->features |= NETIF_F_LLTX;
3157 if (hw->chip_id != CHIP_ID_YUKON_EC_U) 3134 if (hw->chip_id != CHIP_ID_YUKON_EC_U)
3158 dev->features |= NETIF_F_TSO; 3135 dev->features |= NETIF_F_TSO;
3159 if (highmem) 3136 if (highmem)
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index c1e45123d44f..403486a3831d 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1789,7 +1789,6 @@ struct sky2_port {
1789 u32 msg_enable; 1789 u32 msg_enable;
1790 spinlock_t phy_lock; 1790 spinlock_t phy_lock;
1791 1791
1792 spinlock_t tx_lock ____cacheline_aligned_in_smp;
1793 struct tx_ring_info *tx_ring; 1792 struct tx_ring_info *tx_ring;
1794 struct sky2_tx_le *tx_le; 1793 struct sky2_tx_le *tx_le;
1795 u16 tx_cons; /* next le to check */ 1794 u16 tx_cons; /* next le to check */