diff options
author | shemminger@osdl.org <shemminger@osdl.org> | 2005-11-30 14:45:19 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-12-01 02:20:20 -0500 |
commit | 2224795d7e4c7f7e44fe21f0fa067d62539308fb (patch) | |
tree | 6414d3d4307daa181b6fc2b19762bd75f2d19ba7 /drivers/net/sky2.c | |
parent | 018d1c667ef4dce5299dd79d38447840789c97d6 (diff) |
[PATCH] sky2: dual port tx completion
Sometimes on dual port cards, one tx complete may cover both
ports. To handle that rearrange poll routine to lookup at
end.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1d5c3039f53a..52c7b1886314 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1242,6 +1242,9 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1242 | struct net_device *dev = sky2->netdev; | 1242 | struct net_device *dev = sky2->netdev; |
1243 | unsigned i; | 1243 | unsigned i; |
1244 | 1244 | ||
1245 | if (done == sky2->tx_cons) | ||
1246 | return; | ||
1247 | |||
1245 | if (unlikely(netif_msg_tx_done(sky2))) | 1248 | if (unlikely(netif_msg_tx_done(sky2))) |
1246 | printk(KERN_DEBUG "%s: tx done, up to %u\n", | 1249 | printk(KERN_DEBUG "%s: tx done, up to %u\n", |
1247 | dev->name, done); | 1250 | dev->name, done); |
@@ -1711,16 +1714,18 @@ error: | |||
1711 | goto resubmit; | 1714 | goto resubmit; |
1712 | } | 1715 | } |
1713 | 1716 | ||
1714 | /* Transmit ring index in reported status block is encoded as: | 1717 | /* |
1715 | * | 1718 | * Check for transmit complete |
1716 | * | TXS2 | TXA2 | TXS1 | TXA1 | ||
1717 | */ | 1719 | */ |
1718 | static inline u16 tx_index(u8 port, u32 status, u16 len) | 1720 | static inline void sky2_tx_check(struct sky2_hw *hw, int port) |
1719 | { | 1721 | { |
1720 | if (port == 0) | 1722 | struct net_device *dev = hw->dev[port]; |
1721 | return status & 0xfff; | 1723 | |
1722 | else | 1724 | if (dev && netif_running(dev)) { |
1723 | return ((status >> 24) & 0xff) | (len & 0xf) << 8; | 1725 | sky2_tx_complete(netdev_priv(dev), |
1726 | sky2_read16(hw, port == 0 | ||
1727 | ? STAT_TXA1_RIDX : STAT_TXA2_RIDX)); | ||
1728 | } | ||
1724 | } | 1729 | } |
1725 | 1730 | ||
1726 | /* | 1731 | /* |
@@ -1803,8 +1808,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1803 | break; | 1808 | break; |
1804 | 1809 | ||
1805 | case OP_TXINDEXLE: | 1810 | case OP_TXINDEXLE: |
1806 | sky2_tx_complete(sky2, | 1811 | /* pick up transmit status later */ |
1807 | tx_index(sky2->port, status, length)); | ||
1808 | break; | 1812 | break; |
1809 | 1813 | ||
1810 | default: | 1814 | default: |
@@ -1816,6 +1820,8 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1816 | } | 1820 | } |
1817 | 1821 | ||
1818 | exit_loop: | 1822 | exit_loop: |
1823 | sky2_tx_check(hw, 0); | ||
1824 | sky2_tx_check(hw, 1); | ||
1819 | 1825 | ||
1820 | mmiowb(); | 1826 | mmiowb(); |
1821 | 1827 | ||