Re: [patch 1/2] natsemi: NAPI and a bugfix

2006-03-04 Thread Jeff Garzik

Mark Brown wrote:

This patch converts the natsemi driver to use NAPI.  It was originally
based on one written by Harald Welte, though it has since been modified
quite a bit, most extensively in order to remove the ability to disable
NAPI since none of the other drivers seem to provide that functionality
any more.

Signed-off-by: Mark Brown [EMAIL PROTECTED]


applied 1-2


-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[patch 1/2] natsemi: NAPI and a bugfix

2006-02-02 Thread Mark Brown
This patch converts the natsemi driver to use NAPI.  It was originally
based on one written by Harald Welte, though it has since been modified
quite a bit, most extensively in order to remove the ability to disable
NAPI since none of the other drivers seem to provide that functionality
any more.

Signed-off-by: Mark Brown [EMAIL PROTECTED]

Index: linux-2.6.15.2/drivers/net/natsemi.c
===
--- linux-2.6.15.2.orig/drivers/net/natsemi.c   2006-01-31 06:25:07.0 
+
+++ linux-2.6.15.2/drivers/net/natsemi.c2006-02-01 22:59:29.0 
+
@@ -3,6 +3,7 @@
Written/copyright 1999-2001 by Donald Becker.
Portions copyright (c) 2001,2002 Sun Microsystems ([EMAIL PROTECTED])
Portions copyright 2001,2002 Manfred Spraul ([EMAIL PROTECTED])
+   Portions copyright 2004 Harald Welte [EMAIL PROTECTED]
 
This software may be used and distributed according to the terms of
the GNU General Public License (GPL), incorporated herein by reference.
@@ -135,8 +136,6 @@
 
TODO:
* big endian support with CFG:BEM instead of cpu_to_le32
-   * support for an external PHY
-   * NAPI
 */
 
 #include linux/config.h
@@ -160,6 +159,7 @@
 #include linux/mii.h
 #include linux/crc32.h
 #include linux/bitops.h
+#include linux/prefetch.h
 #include asm/processor.h /* Processor type for cache alignment. */
 #include asm/io.h
 #include asm/irq.h
@@ -183,8 +183,6 @@
 NETIF_MSG_TX_ERR)
 static int debug = -1;
 
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
 static int mtu;
 
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
@@ -251,14 +249,11 @@ MODULE_AUTHOR(Donald Becker [EMAIL PROTECTED]
 MODULE_DESCRIPTION(National Semiconductor DP8381x series PCI Ethernet 
driver);
 MODULE_LICENSE(GPL);
 
-module_param(max_interrupt_work, int, 0);
 module_param(mtu, int, 0);
 module_param(debug, int, 0);
 module_param(rx_copybreak, int, 0);
 module_param_array(options, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
-MODULE_PARM_DESC(max_interrupt_work, 
-   DP8381x maximum events handled per interrupt);
 MODULE_PARM_DESC(mtu, DP8381x MTU (all boards));
 MODULE_PARM_DESC(debug, DP8381x default debug level);
 MODULE_PARM_DESC(rx_copybreak, 
@@ -691,6 +686,8 @@ struct netdev_private {
/* Based on MTU+slack. */
unsigned int rx_buf_sz;
int oom;
+   /* Interrupt status */
+   u32 intr_status;
/* Do not touch the nic registers */
int hands_off;
/* external phy that is used: only valid if dev-if_port != PORT_TP */
@@ -748,7 +745,8 @@ static void init_registers(struct net_de
 static int start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs 
*regs);
 static void netdev_error(struct net_device *dev, int intr_status);
-static void netdev_rx(struct net_device *dev);
+static int natsemi_poll(struct net_device *dev, int *budget);
+static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do);
 static void netdev_tx_done(struct net_device *dev);
 static int natsemi_change_mtu(struct net_device *dev, int new_mtu);
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -776,6 +774,18 @@ static inline void __iomem *ns_ioaddr(st
return (void __iomem *) dev-base_addr;
 }
 
+static inline void natsemi_irq_enable(struct net_device *dev)
+{
+   writel(1, ns_ioaddr(dev) + IntrEnable);
+   readl(ns_ioaddr(dev) + IntrEnable);
+}
+
+static inline void natsemi_irq_disable(struct net_device *dev)
+{
+   writel(0, ns_ioaddr(dev) + IntrEnable);
+   readl(ns_ioaddr(dev) + IntrEnable);
+}
+
 static void move_int_phy(struct net_device *dev, int addr)
 {
struct netdev_private *np = netdev_priv(dev);
@@ -879,6 +889,7 @@ static int __devinit natsemi_probe1 (str
spin_lock_init(np-lock);
np-msg_enable = (debug = 0) ? (1debug)-1 : NATSEMI_DEF_MSG;
np-hands_off = 0;
+   np-intr_status = 0;
 
/* Initial port:
 * - If the nic was configured to use an external phy and if find_mii
@@ -932,6 +943,9 @@ static int __devinit natsemi_probe1 (str
dev-do_ioctl = netdev_ioctl;
dev-tx_timeout = tx_timeout;
dev-watchdog_timeo = TX_TIMEOUT;
+   dev-poll = natsemi_poll;
+   dev-weight = 64;
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
dev-poll_controller = natsemi_poll_controller;
 #endif
@@ -2158,68 +2172,92 @@ static void netdev_tx_done(struct net_de
}
 }
 
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
+/* The interrupt handler doesn't actually handle interrupts itself, it
+ * schedules a NAPI poll if there is anything to do. */
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs 
*rgs)
 {
struct