Commit:     d1d08d1265810ef1f165864850416dcbc9725ee7
Parent:     1706287f6eb58726a9a0e5cbbde87f49757615e3
Author:     David S. Miller <[EMAIL PROTECTED]>
AuthorDate: Mon Jan 7 20:53:33 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Tue Jan 8 23:30:12 2008 -0800

    [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 <[EMAIL PROTECTED]>
    Acked-by:  Don Fry <[EMAIL PROTECTED]>
 drivers/net/pcnet32.c |    5 +++++
 drivers/net/r8169.c   |    2 ++
 drivers/net/sky2.c    |    3 +++
 3 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index ff92aca..90498ff 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -455,9 +455,14 @@ static void pcnet32_netif_start(struct net_device *dev)
        struct pcnet32_private *lp = netdev_priv(dev);
+       ulong ioaddr = dev->base_addr;
+       u16 val;
+       val = lp->a.read_csr(ioaddr, CSR3);
+       val &= 0x00ff;
+       lp->a.write_csr(ioaddr, CSR3, val);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5863190..af80309 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2398,6 +2398,8 @@ static void rtl8169_wait_for_quiescence(struct net_device 
 #ifdef CONFIG_R8169_NAPI
+       tp->intr_mask = 0xffff;
+       RTL_W16(IntrMask, tp->intr_event);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index a74fc11..52ec89b 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
+       sky2_read32(hw, B0_Y2_SP_LISR);
@@ -2043,6 +2044,7 @@ static int sky2_change_mtu(struct net_device *dev, int 
        err = sky2_rx_start(sky2);
        sky2_write32(hw, B0_IMSK, imask);
+       sky2_read32(hw, B0_Y2_SP_LISR);
        if (err)
@@ -3861,6 +3863,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
                   last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], 
                   sky2_read16(hw, Y2_QADDR(rxqaddr[port], 
+       sky2_read32(hw, B0_Y2_SP_LISR);
        return 0;
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to