Commit 13b97b74 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik

[PATCH] sky2: transmit complete index optimization

Change transmit complete handling to use the status values
in the poll list because they are in-cache, rather than reading
non-cached memory for chips status.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 0e3ff6aa
...@@ -1274,7 +1274,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) ...@@ -1274,7 +1274,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
} }
/* Cleanup all untransmitted buffers, assume transmitter not running */ /* Cleanup all untransmitted buffers, assume transmitter not running */
static inline void sky2_tx_clean(struct sky2_port *sky2) static void sky2_tx_clean(struct sky2_port *sky2)
{ {
sky2_tx_complete(sky2, sky2->tx_prod); sky2_tx_complete(sky2, sky2->tx_prod);
} }
...@@ -1714,14 +1714,16 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, ...@@ -1714,14 +1714,16 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2,
/* /*
* Check for transmit complete * Check for transmit complete
*/ */
static inline void sky2_tx_check(struct sky2_hw *hw, int port) #define TX_NO_STATUS 0xffff
{
struct net_device *dev = hw->dev[port];
if (dev && netif_running(dev)) { static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
sky2_tx_complete(netdev_priv(dev), {
sky2_read16(hw, port == 0 if (last != TX_NO_STATUS) {
? STAT_TXA1_RIDX : STAT_TXA2_RIDX)); struct net_device *dev = hw->dev[port];
if (dev && netif_running(dev)) {
struct sky2_port *sky2 = netdev_priv(dev);
sky2_tx_complete(sky2, last);
}
} }
} }
...@@ -1735,6 +1737,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) ...@@ -1735,6 +1737,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
unsigned int to_do = min(dev0->quota, *budget); unsigned int to_do = min(dev0->quota, *budget);
unsigned int work_done = 0; unsigned int work_done = 0;
u16 hwidx; u16 hwidx;
u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
hwidx = sky2_read16(hw, STAT_PUT_IDX); hwidx = sky2_read16(hw, STAT_PUT_IDX);
...@@ -1806,7 +1809,10 @@ static int sky2_poll(struct net_device *dev0, int *budget) ...@@ -1806,7 +1809,10 @@ static int sky2_poll(struct net_device *dev0, int *budget)
break; break;
case OP_TXINDEXLE: case OP_TXINDEXLE:
/* pick up transmit status later */ /* TX index reports status for both ports */
tx_done[0] = status & 0xffff;
tx_done[1] = ((status >> 24) & 0xff)
| (u16)(length & 0xf) << 8;
break; break;
default: default:
...@@ -1818,16 +1824,13 @@ static int sky2_poll(struct net_device *dev0, int *budget) ...@@ -1818,16 +1824,13 @@ static int sky2_poll(struct net_device *dev0, int *budget)
} }
exit_loop: exit_loop:
sky2_tx_check(hw, 0);
sky2_tx_check(hw, 1);
mmiowb(); mmiowb();
sky2_tx_check(hw, 0, tx_done[0]);
sky2_tx_check(hw, 1, tx_done[1]);
if (work_done < to_do) { if (work_done < to_do) {
/* /* need to restart TX timer */
* Another chip workaround, need to restart TX timer if status
* LE was handled. WA_DEV_43_418
*/
if (is_ec_a1(hw)) { if (is_ec_a1(hw)) {
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment