|
@@ -1741,8 +1741,12 @@ mapping_error:
|
|
|
/*
|
|
|
* Free ring elements from starting at tx_cons until "done"
|
|
|
*
|
|
|
- * NB: the hardware will tell us about partial completion of multi-part
|
|
|
+ * NB:
|
|
|
+ * 1. The hardware will tell us about partial completion of multi-part
|
|
|
* buffers so make sure not to free skb to early.
|
|
|
+ * 2. This may run in parallel start_xmit because the it only
|
|
|
+ * looks at the tail of the queue of FIFO (tx_cons), not
|
|
|
+ * the head (tx_prod)
|
|
|
*/
|
|
|
static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
|
|
|
{
|
|
@@ -1800,16 +1804,6 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
|
|
|
netif_wake_queue(dev);
|
|
|
}
|
|
|
|
|
|
-/* Cleanup all untransmitted buffers, assume transmitter not running */
|
|
|
-static void sky2_tx_clean(struct net_device *dev)
|
|
|
-{
|
|
|
- struct sky2_port *sky2 = netdev_priv(dev);
|
|
|
-
|
|
|
- netif_tx_lock_bh(dev);
|
|
|
- sky2_tx_complete(sky2, sky2->tx_prod);
|
|
|
- netif_tx_unlock_bh(dev);
|
|
|
-}
|
|
|
-
|
|
|
static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
|
|
|
{
|
|
|
/* Disable Force Sync bit and Enable Alloc bit */
|
|
@@ -1901,7 +1895,9 @@ static int sky2_down(struct net_device *dev)
|
|
|
|
|
|
sky2_tx_reset(hw, port);
|
|
|
|
|
|
- sky2_tx_clean(dev);
|
|
|
+ /* Free any pending frames stuck in HW queue */
|
|
|
+ sky2_tx_complete(sky2, sky2->tx_prod);
|
|
|
+
|
|
|
sky2_rx_clean(sky2);
|
|
|
|
|
|
pci_free_consistent(hw->pdev, RX_LE_BYTES,
|
|
@@ -2378,11 +2374,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
|
|
|
{
|
|
|
struct sky2_port *sky2 = netdev_priv(dev);
|
|
|
|
|
|
- if (likely(netif_running(dev) && !sky2->restarting)) {
|
|
|
- netif_tx_lock(dev);
|
|
|
+ if (likely(netif_running(dev) && !sky2->restarting))
|
|
|
sky2_tx_complete(sky2, last);
|
|
|
- netif_tx_unlock(dev);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
static inline void sky2_skb_rx(const struct sky2_port *sky2,
|