diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 8dfd27d4d6e5..ff6557dd079c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1274,7 +1274,7 @@ out: | |||
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | /* Cleanup all untransmitted buffers, assume transmitter not running */ | 1276 | /* Cleanup all untransmitted buffers, assume transmitter not running */ |
1277 | static inline void sky2_tx_clean(struct sky2_port *sky2) | 1277 | static void sky2_tx_clean(struct sky2_port *sky2) |
1278 | { | 1278 | { |
1279 | sky2_tx_complete(sky2, sky2->tx_prod); | 1279 | sky2_tx_complete(sky2, sky2->tx_prod); |
1280 | } | 1280 | } |
@@ -1714,14 +1714,16 @@ error: | |||
1714 | /* | 1714 | /* |
1715 | * Check for transmit complete | 1715 | * Check for transmit complete |
1716 | */ | 1716 | */ |
1717 | static inline void sky2_tx_check(struct sky2_hw *hw, int port) | 1717 | #define TX_NO_STATUS 0xffff |
1718 | { | ||
1719 | struct net_device *dev = hw->dev[port]; | ||
1720 | 1718 | ||
1721 | if (dev && netif_running(dev)) { | 1719 | static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last) |
1722 | sky2_tx_complete(netdev_priv(dev), | 1720 | { |
1723 | sky2_read16(hw, port == 0 | 1721 | if (last != TX_NO_STATUS) { |
1724 | ? STAT_TXA1_RIDX : STAT_TXA2_RIDX)); | 1722 | struct net_device *dev = hw->dev[port]; |
1723 | if (dev && netif_running(dev)) { | ||
1724 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1725 | sky2_tx_complete(sky2, last); | ||
1726 | } | ||
1725 | } | 1727 | } |
1726 | } | 1728 | } |
1727 | 1729 | ||
@@ -1735,6 +1737,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1735 | unsigned int to_do = min(dev0->quota, *budget); | 1737 | unsigned int to_do = min(dev0->quota, *budget); |
1736 | unsigned int work_done = 0; | 1738 | unsigned int work_done = 0; |
1737 | u16 hwidx; | 1739 | u16 hwidx; |
1740 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; | ||
1738 | 1741 | ||
1739 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 1742 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
1740 | hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1743 | hwidx = sky2_read16(hw, STAT_PUT_IDX); |
@@ -1806,7 +1809,10 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1806 | break; | 1809 | break; |
1807 | 1810 | ||
1808 | case OP_TXINDEXLE: | 1811 | case OP_TXINDEXLE: |
1809 | /* pick up transmit status later */ | 1812 | /* TX index reports status for both ports */ |
1813 | tx_done[0] = status & 0xffff; | ||
1814 | tx_done[1] = ((status >> 24) & 0xff) | ||
1815 | | (u16)(length & 0xf) << 8; | ||
1810 | break; | 1816 | break; |
1811 | 1817 | ||
1812 | default: | 1818 | default: |
@@ -1818,16 +1824,13 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1818 | } | 1824 | } |
1819 | 1825 | ||
1820 | exit_loop: | 1826 | exit_loop: |
1821 | sky2_tx_check(hw, 0); | ||
1822 | sky2_tx_check(hw, 1); | ||
1823 | |||
1824 | mmiowb(); | 1827 | mmiowb(); |
1825 | 1828 | ||
1829 | sky2_tx_check(hw, 0, tx_done[0]); | ||
1830 | sky2_tx_check(hw, 1, tx_done[1]); | ||
1831 | |||
1826 | if (work_done < to_do) { | 1832 | if (work_done < to_do) { |
1827 | /* | 1833 | /* need to restart TX timer */ |
1828 | * Another chip workaround, need to restart TX timer if status | ||
1829 | * LE was handled. WA_DEV_43_418 | ||
1830 | */ | ||
1831 | if (is_ec_a1(hw)) { | 1834 | if (is_ec_a1(hw)) { |
1832 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | 1835 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); |
1833 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); | 1836 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); |