[PATCH] 8139too: add CONFIG_8139TOO_NAPI This patch adds the CONFIG_8139TOO_NAPI. --- drivers/net/8139too.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++-- drivers/net/Kconfig | 4 + 2 files changed, 102 insertions(+), 4 deletions(-) diff -puN drivers/net/8139too.c~8139too-config-napi drivers/net/8139too.c --- linux-2.6.4-rc1/drivers/net/8139too.c~8139too-config-napi 2004-03-01 01:46:55.000000000 +0900 +++ linux-2.6.4-rc1-hirofumi/drivers/net/8139too.c 2004-03-01 02:54:46.000000000 +0900 @@ -159,6 +159,11 @@ static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; +#ifndef CONFIG_8139TOO_NAPI +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int max_interrupt_work = 20; +#endif + /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). The RTL chips use a 64 element hash table based on the Ethernet CRC. */ static int multicast_filter_limit = 32; @@ -592,6 +597,10 @@ MODULE_AUTHOR ("Jeff Garzik open = rtl8139_open; dev->hard_start_xmit = rtl8139_start_xmit; +#ifdef CONFIG_8139TOO_NAPI dev->poll = rtl8139_poll; dev->weight = 64; +#endif dev->stop = rtl8139_close; dev->get_stats = rtl8139_get_stats; dev->set_multicast_list = rtl8139_set_rx_mode; @@ -1938,7 +1951,10 @@ static int rtl8139_rx(struct net_device RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); - while (netif_running(dev) && received < budget + while (netif_running(dev) +#ifdef CONFIG_8139TOO_NAPI + && received < budget +#endif && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { u32 ring_offset = cur_rx % RX_BUF_LEN; u32 rx_status; @@ -2009,8 +2025,11 @@ static int rtl8139_rx(struct net_device dev->last_rx = jiffies; tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; - +#ifdef CONFIG_8139TOO_NAPI netif_receive_skb (skb); +#else + netif_rx (skb); +#endif } else { if (net_ratelimit()) printk (KERN_WARNING @@ -2088,6 +2107,7 @@ static void rtl8139_weird_interrupt (str } } +#ifdef CONFIG_8139TOO_NAPI static int rtl8139_poll(struct net_device *dev, int *budget) { struct rtl8139_private *tp = dev->priv; @@ -2138,13 +2158,13 @@ static irqreturn_t rtl8139_interrupt (in status = RTL_R16 (IntrStatus); /* shared irq? */ - if (unlikely((status & rtl8139_intr_mask) == 0)) + if (unlikely((status & rtl8139_intr_mask) == 0)) goto out; handled = 1; /* h/w no longer present (hotplug?) or major error, bail */ - if (unlikely(status == 0xFFFF)) + if (unlikely(status == 0xFFFF)) goto out; /* close possible race's with dev_close */ @@ -2188,6 +2208,80 @@ static irqreturn_t rtl8139_interrupt (in dev->name, RTL_R16 (IntrStatus)); return IRQ_RETVAL(handled); } +#else /* !CONFIG_8139TOO_NAPI */ +static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) dev_instance; + struct rtl8139_private *tp = dev->priv; + int boguscnt = max_interrupt_work; + void *ioaddr = tp->mmio_addr; + u16 status, ackstat; + int link_changed = 0; /* avoid bogus "uninit" warning */ + int handled = 0; + + spin_lock (&tp->lock); + + do { + status = RTL_R16 (IntrStatus); + + /* shared irq? */ + if (unlikely((status & rtl8139_intr_mask) == 0)) + goto out; + + handled = 1; + + /* h/w no longer present (hotplug?) or major error, bail */ + if (unlikely(status == 0xFFFF)) + goto out; + + /* close possible race's with dev_close */ + if (unlikely(!netif_running(dev))) { + RTL_W16 (IntrMask, 0); + goto out; + } + + /* Acknowledge all of the current interrupt sources ASAP, but + an first get an additional status bit from CSCR. */ + if (unlikely(status & RxUnderrun)) + link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit; + + ackstat = status & ~(RxAckBits | TxErr); + if (ackstat) + RTL_W16 (IntrStatus, ackstat); + + if (status & RxAckBits) + rtl8139_rx (dev, tp, 0); + + /* Check uncommon events with one test. */ + if (unlikely(status & (PCIErr|PCSTimeout|RxUnderrun|RxErr))) + rtl8139_weird_interrupt (dev, tp, ioaddr, + status, link_changed); + + if (status & (TxOK | TxErr)) { + rtl8139_tx_interrupt (dev, tp, ioaddr); + if (status & TxErr) + RTL_W16 (IntrStatus, TxErr); + } + + boguscnt--; + } while (boguscnt > 0); + out: + if (boguscnt <= 0) { + printk (KERN_WARNING "%s: Too much work at interrupt, " + "IntrStatus=0x%4.4x.\n", dev->name, status); + + /* Clear all interrupt sources. */ + RTL_W16 (IntrStatus, 0xffff); + } + + spin_unlock (&tp->lock); + + DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n", + dev->name, RTL_R16 (IntrStatus)); + return IRQ_RETVAL(handled); +} +#endif /* !CONFIG_8139TOO_NAPI */ #ifdef CONFIG_NET_POLL_CONTROLLER /* diff -puN drivers/net/Kconfig~8139too-config-napi drivers/net/Kconfig --- linux-2.6.4-rc1/drivers/net/Kconfig~8139too-config-napi 2004-03-01 01:46:55.000000000 +0900 +++ linux-2.6.4-rc1-hirofumi/drivers/net/Kconfig 2004-03-01 01:46:55.000000000 +0900 @@ -1543,6 +1543,10 @@ config 8139TOO To compile this driver as a module, choose M here: the module will be called 8139too. This is recommended. +config 8139TOO_NAPI + bool "Use Rx Polling (NAPI)" + depends on 8139TOO + config 8139TOO_PIO bool "Use PIO instead of MMIO" default y _