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 1d5c3039f53..52c7b188631 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 | ||
