aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-01-07 23:53:33 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-09 02:30:12 -0500
commitd1d08d1265810ef1f165864850416dcbc9725ee7 (patch)
tree9c053e8822e33ff719da72df620f1335207ab73d /drivers/net/sky2.c
parent1706287f6eb58726a9a0e5cbbde87f49757615e3 (diff)
[NET]: Fix drivers to handle napi_disable() disabling interrupts.
When we add the generic napi_disable_pending() breakout logic to net_rx_action() it means that napi_disable() can cause NAPI poll interrupt events to be disabled. And this is exactly what we want. If a napi_disable() is pending, and we are looping in the ->poll(), we want ->poll() event interrupts to stay disabled and we want to complete the NAPI poll ASAP. When ->poll() break out during device down was being handled on a per-driver basis, often these drivers would turn interrupts back on when '!netif_running()' was detected. And this would just cause a reschedule of the NAPI ->poll() in the interrupt handler before the napi_disable() could get in there and grab the NAPI_STATE_SCHED bit. The vast majority of drivers don't care if napi_disable() might have the side effect of disabling NAPI ->poll() event interrupts. In all such cases, when a napi_disable() is performed, the driver just disabled interrupts or is about to. However there were three exceptions to this in PCNET32, R8169, and SKY2. To fix those cases, at the subsequent napi_enable() points, I added code to ensure that the ->poll() interrupt events are enabled in the hardware. Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Don Fry <pcnet32@verizon.net>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index a74fc11a6482..52ec89b82f64 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1168,6 +1168,7 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
1168 TX_VLAN_TAG_OFF); 1168 TX_VLAN_TAG_OFF);
1169 } 1169 }
1170 1170
1171 sky2_read32(hw, B0_Y2_SP_LISR);
1171 napi_enable(&hw->napi); 1172 napi_enable(&hw->napi);
1172 netif_tx_unlock_bh(dev); 1173 netif_tx_unlock_bh(dev);
1173} 1174}
@@ -2043,6 +2044,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
2043 err = sky2_rx_start(sky2); 2044 err = sky2_rx_start(sky2);
2044 sky2_write32(hw, B0_IMSK, imask); 2045 sky2_write32(hw, B0_IMSK, imask);
2045 2046
2047 sky2_read32(hw, B0_Y2_SP_LISR);
2046 napi_enable(&hw->napi); 2048 napi_enable(&hw->napi);
2047 2049
2048 if (err) 2050 if (err)
@@ -3861,6 +3863,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
3861 last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), 3863 last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
3862 sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); 3864 sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
3863 3865
3866 sky2_read32(hw, B0_Y2_SP_LISR);
3864 napi_enable(&hw->napi); 3867 napi_enable(&hw->napi);
3865 return 0; 3868 return 0;
3866} 3869}