From: shemminger@osdl.org Date: Wed, 30 Nov 2005 19:45:19 +0000 (-0800) Subject: [PATCH] sky2: dual port tx completion X-Git-Tag: v2.6.16-rc1~474^2~22^2~7^2~74 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2224795d7e4c7f7e44fe21f0fa067d62539308fb;p=linux-2.6 [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 Signed-off-by: Jeff Garzik --- diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1d5c3039f5..52c7b18863 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) struct net_device *dev = sky2->netdev; unsigned i; + if (done == sky2->tx_cons) + return; + if (unlikely(netif_msg_tx_done(sky2))) printk(KERN_DEBUG "%s: tx done, up to %u\n", dev->name, done); @@ -1711,16 +1714,18 @@ error: goto resubmit; } -/* Transmit ring index in reported status block is encoded as: - * - * | TXS2 | TXA2 | TXS1 | TXA1 +/* + * Check for transmit complete */ -static inline u16 tx_index(u8 port, u32 status, u16 len) +static inline void sky2_tx_check(struct sky2_hw *hw, int port) { - if (port == 0) - return status & 0xfff; - else - return ((status >> 24) & 0xff) | (len & 0xf) << 8; + struct net_device *dev = hw->dev[port]; + + if (dev && netif_running(dev)) { + sky2_tx_complete(netdev_priv(dev), + sky2_read16(hw, port == 0 + ? STAT_TXA1_RIDX : STAT_TXA2_RIDX)); + } } /* @@ -1803,8 +1808,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) break; case OP_TXINDEXLE: - sky2_tx_complete(sky2, - tx_index(sky2->port, status, length)); + /* pick up transmit status later */ break; default: @@ -1816,6 +1820,8 @@ static int sky2_poll(struct net_device *dev0, int *budget) } exit_loop: + sky2_tx_check(hw, 0); + sky2_tx_check(hw, 1); mmiowb();