[kernel] r6183 - in dists/trunk/linux-2.6/debian: . patches patches/series

Martin Michlmayr tbm at costa.debian.org
Mon Mar 13 18:55:48 UTC 2006


Author: tbm
Date: Mon Mar 13 18:55:47 2006
New Revision: 6183

Added:
   dists/trunk/linux-2.6/debian/patches/mips-sb1-eth-1480.patch
   dists/trunk/linux-2.6/debian/patches/mips-sb1-eth-napi.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/0experimental.1
Log:
SB1 ethernet fixes


Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	(original)
+++ dists/trunk/linux-2.6/debian/changelog	Mon Mar 13 18:55:47 2006
@@ -10,6 +10,8 @@
   * [arm, armeb] Enable the netconsole module.
   * [mipsel/cobalt] Enable the netconsole module.
   * [mips] SB1: Fix interrupt disable hazard (Ralf Baechle).
+  * [mips] SB1: support for 1480 ethernet (Broadcom).
+  * [mips] SB1: support for NAPI (Tom Rix).
 
   [ dann frazier ]
   * [ia64] use yaird on ia64 until #341181 is fixed

Added: dists/trunk/linux-2.6/debian/patches/mips-sb1-eth-1480.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/mips-sb1-eth-1480.patch	Mon Mar 13 18:55:47 2006
@@ -0,0 +1,246 @@
+SB1 1480 support for the sb1 network drivr.
+Status: in linux-mips git; still needs to be synced into mainline
+
+--- linux-2.6/drivers/net/sb1250-mac.c	2006-03-05 19:35:04.000000000 +0000
++++ mips.git/drivers/net/sb1250-mac.c	2006-03-05 18:51:16.000000000 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2001,2002,2003 Broadcom Corporation
++ * Copyright (C) 2001,2002,2003,2004 Broadcom Corporation
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -43,6 +43,7 @@
+ #define SBMAC_ETH0_HWADDR "40:00:00:00:01:00"
+ #define SBMAC_ETH1_HWADDR "40:00:00:00:01:01"
+ #define SBMAC_ETH2_HWADDR "40:00:00:00:01:02"
++#define SBMAC_ETH3_HWADDR "40:00:00:00:01:03"
+ #endif
+ 
+ 
+@@ -57,7 +58,7 @@
+ 
+ #define CONFIG_SBMAC_COALESCE
+ 
+-#define MAX_UNITS 3		/* More are supported, limit only on options */
++#define MAX_UNITS 4		/* More are supported, limit only on options */
+ 
+ /* Time in jiffies before concluding the transmitter is hung. */
+ #define TX_TIMEOUT  (2*HZ)
+@@ -85,11 +86,11 @@
+    The media type is usually passed in 'options[]'.
+ */
+ #ifdef MODULE
+-static int options[MAX_UNITS] = {-1, -1, -1};
++static int options[MAX_UNITS] = {-1, -1, -1, -1};
+ module_param_array(options, int, NULL, S_IRUGO);
+ MODULE_PARM_DESC(options, "1-" __MODULE_STRING(MAX_UNITS));
+ 
+-static int full_duplex[MAX_UNITS] = {-1, -1, -1};
++static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1};
+ module_param_array(full_duplex, int, NULL, S_IRUGO);
+ MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS));
+ #endif
+@@ -105,13 +106,26 @@
+ #endif
+ 
+ #include <asm/sibyte/sb1250.h>
+-#include <asm/sibyte/sb1250_defs.h>
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++#include <asm/sibyte/bcm1480_regs.h>
++#include <asm/sibyte/bcm1480_int.h>
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ #include <asm/sibyte/sb1250_regs.h>
+-#include <asm/sibyte/sb1250_mac.h>
+-#include <asm/sibyte/sb1250_dma.h>
+ #include <asm/sibyte/sb1250_int.h>
++#else
++#error invalid SiByte MAC configuation
++#endif
+ #include <asm/sibyte/sb1250_scd.h>
++#include <asm/sibyte/sb1250_mac.h>
++#include <asm/sibyte/sb1250_dma.h>
+ 
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++#define UNIT_INT(n)		(K_BCM1480_INT_MAC_0 + ((n) * 2))
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
++#define UNIT_INT(n)		(K_INT_MAC_0 + (n))
++#else
++#error invalid SiByte MAC configuation
++#endif
+ 
+ /**********************************************************************
+  *  Simple types
+@@ -142,6 +156,10 @@
+ 
+ #define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES)
+ 
++#define SBMAC_READCSR(t)	__raw_readq((unsigned long)t)
++#define SBMAC_WRITECSR(t,v)	__raw_writeq(v, (unsigned long)t)
++
++
+ #define SBMAC_MAX_TXDESCR	32
+ #define SBMAC_MAX_RXDESCR	32
+ 
+@@ -1476,10 +1494,10 @@
+ 	 * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above
+ 	 * Use a larger RD_THRSH for gigabit
+ 	 */
+-	if (periph_rev >= 2)
+-		th_value = 64;
+-	else
++	if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2)
+ 		th_value = 28;
++	else
++		th_value = 64;
+ 
+ 	fifo = V_MAC_TX_WR_THRSH(4) |	/* Must be '4' or '8' */
+ 		((s->sbm_speed == sbmac_speed_1000)
+@@ -1589,13 +1607,17 @@
+ 	 * Turn on the rest of the bits in the enable register
+ 	 */
+ 
++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
++	__raw_writeq(M_MAC_RXDMA_EN0 |
++		       M_MAC_TXDMA_EN0, s->sbm_macenable);
++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ 	__raw_writeq(M_MAC_RXDMA_EN0 |
+ 		       M_MAC_TXDMA_EN0 |
+ 		       M_MAC_RX_ENABLE |
+ 		       M_MAC_TX_ENABLE, s->sbm_macenable);
+-
+-
+-
++#else
++#error invalid SiByte MAC configuation
++#endif
+ 
+ #ifdef CONFIG_SBMAC_COALESCE
+ 	/*
+@@ -1786,11 +1808,12 @@
+ 	reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15);
+ 	__raw_writeq(reg, sc->sbm_rxfilter);
+ 
+-	/* read system identification to determine revision */
+-	if (periph_rev >= 2) {
+-		sc->rx_hw_checksum = ENABLE;
+-	} else {
++	/* BCM1250 pass1 didn't have hardware checksum.  Everything
++	   later does.  */
++	if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) {
+ 		sc->rx_hw_checksum = DISABLE;
++	} else {
++		sc->rx_hw_checksum = ENABLE;
+ 	}
+ }
+ 
+@@ -2220,7 +2243,7 @@
+ 
+ 
+ 
+-#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
++#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)
+ /**********************************************************************
+  *  SBMAC_PARSE_XDIGIT(str)
+  *
+@@ -2397,6 +2420,11 @@
+ 			sc->sbm_dev->name);
+ 	}
+ 
++	if (periph_rev >= 2) {
++		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
++			sc->sbm_dev->name);
++	}
++
+ 	/*
+ 	 * Display Ethernet address (this is called during the config
+ 	 * process so we need to finish off the config message that
+@@ -2792,7 +2820,7 @@
+ 
+ 
+ 
+-#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
++#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)
+ static void
+ sbmac_setup_hwaddr(int chan,char *addr)
+ {
+@@ -2818,25 +2846,7 @@
+ 	unsigned long port;
+ 	int chip_max_units;
+ 
+-	/*
+-	 * For bringup when not using the firmware, we can pre-fill
+-	 * the MAC addresses using the environment variables
+-	 * specified in this file (or maybe from the config file?)
+-	 */
+-#ifdef SBMAC_ETH0_HWADDR
+-	sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR);
+-#endif
+-#ifdef SBMAC_ETH1_HWADDR
+-	sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR);
+-#endif
+-#ifdef SBMAC_ETH2_HWADDR
+-	sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR);
+-#endif
+-
+-	/*
+-	 * Walk through the Ethernet controllers and find
+-	 * those who have their MAC addresses set.
+-	 */
++	/* Set the number of available units based on the SOC type.  */
+ 	switch (soc_type) {
+ 	case K_SYS_SOC_TYPE_BCM1250:
+ 	case K_SYS_SOC_TYPE_BCM1250_ALT:
+@@ -2848,6 +2858,10 @@
+ 	case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */
+ 		chip_max_units = 2;
+ 		break;
++	case K_SYS_SOC_TYPE_BCM1x55:
++	case K_SYS_SOC_TYPE_BCM1x80:
++		chip_max_units = 4;
++		break;
+ 	default:
+ 		chip_max_units = 0;
+ 		break;
+@@ -2855,6 +2869,32 @@
+ 	if (chip_max_units > MAX_UNITS)
+ 		chip_max_units = MAX_UNITS;
+ 
++	/*
++	 * For bringup when not using the firmware, we can pre-fill
++	 * the MAC addresses using the environment variables
++	 * specified in this file (or maybe from the config file?)
++	 */
++#ifdef SBMAC_ETH0_HWADDR
++	if (chip_max_units > 0)
++	  sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR);
++#endif
++#ifdef SBMAC_ETH1_HWADDR
++	if (chip_max_units > 1)
++	  sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR);
++#endif
++#ifdef SBMAC_ETH2_HWADDR
++	if (chip_max_units > 2)
++	  sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR);
++#endif
++#ifdef SBMAC_ETH3_HWADDR
++	if (chip_max_units > 3)
++	  sbmac_setup_hwaddr(3,SBMAC_ETH3_HWADDR);
++#endif
++
++	/*
++	 * Walk through the Ethernet controllers and find
++	 * those who have their MAC addresses set.
++	 */
+ 	for (idx = 0; idx < chip_max_units; idx++) {
+ 
+ 	        /*
+@@ -2886,7 +2926,7 @@
+ 
+ 		printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
+ 
+-		dev->irq = K_INT_MAC_0 + idx;
++		dev->irq = UNIT_INT(idx);
+ 		dev->base_addr = port;
+ 		dev->mem_end = 0;
+ 		if (sbmac_init(dev, idx)) {

Added: dists/trunk/linux-2.6/debian/patches/mips-sb1-eth-napi.patch
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/mips-sb1-eth-napi.patch	Mon Mar 13 18:55:47 2006
@@ -0,0 +1,379 @@
+Broadcom Sibyte SB1xxx NAPI ethernet support
+Status: submitted to linux-mips for review
+Dependency: mips-sb1-eth-1480.patch
+
+
+From: Tom Rix <trix at specifix.com>
+Subject: [PATCH] Broadcom Sibyte SB1xxx NAPI ethernet support
+Date:   Thu, 09 Mar 2006 22:42:21 -0600
+To: Martin Michlmayr <tbm at cyrius.com>, linux-mips at linux-mips.org
+Cc: Mark E Mason <mark.e.mason at broadcom.com>
+
+This patch adds NAPI support for the Broadcom Sibyte SB1xxx family.  The
+changes are limited to adding a new config key SBMAC_NAPI to the
+drivers/net/Kconfig and by adding the poll op and interrupt support to
+drivers/net/sb1250-mac.c.
+
+This patch also has a fix to drivers/net/sb1250-mac.c, the dma descriptor
+table ptr is allocated, aligned and the aligned ptr is freed.  If the ptr
+was not already aligned (usually is) then the free would not work of what
+was returned by the kmalloc. A variable was added to store the unaligned
+pointer so that it could be properly freed.
+
+I have tested this patch on a BCM91250A-SWARM Pass 2 / An.
+
+Mark Mason from Broadcom was very helpful and tested this patch on at
+least a 1480.
+
+Tom
+
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index aa633fa..84ad238 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -456,6 +456,23 @@ config NET_SB1250_MAC
+ 	tristate "SB1250 Ethernet support"
+ 	depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC
+ 
++config SBMAC_NAPI
++	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
++	depends on NET_SB1250_MAC && EXPERIMENTAL
++	help
++	  NAPI is a new driver API designed to reduce CPU and interrupt load
++	  when the driver is receiving lots of packets from the card. It is
++	  still somewhat experimental and thus not yet enabled by default.
++
++	  If your estimated Rx load is 10kpps or more, or if the card will be
++	  deployed on potentially unfriendly networks (e.g. in a firewall),
++	  then say Y here.
++
++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
++	  information.
++
++	  If in doubt, say y.
++
+ config SGI_IOC3_ETH
+ 	bool "SGI IOC3 Ethernet"
+ 	depends on NET_ETHERNET && PCI && SGI_IP27
+diff -rup a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
+--- a/drivers/net/sb1250-mac.c	2006-03-09 04:25:41.000000000 -0600
++++ b/drivers/net/sb1250-mac.c	2006-03-09 05:30:52.000000000 -0600
+@@ -209,6 +209,7 @@ typedef struct sbmacdma_s {
+ 	 * This stuff is for maintenance of the ring
+ 	 */
+ 
++	sbdmadscr_t     *sbdma_dscrtable_unaligned; 
+ 	sbdmadscr_t     *sbdma_dscrtable;	/* base of descriptor table */
+ 	sbdmadscr_t     *sbdma_dscrtable_end; /* end of descriptor table */
+ 
+@@ -291,8 +292,8 @@ static int sbdma_add_rcvbuffer(sbmacdma_
+ static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *m);
+ static void sbdma_emptyring(sbmacdma_t *d);
+ static void sbdma_fillring(sbmacdma_t *d);
+-static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d);
+-static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d);
++static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll);
++static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll);
+ static int sbmac_initctx(struct sbmac_softc *s);
+ static void sbmac_channel_start(struct sbmac_softc *s);
+ static void sbmac_channel_stop(struct sbmac_softc *s);
+@@ -313,6 +314,10 @@ static struct net_device_stats *sbmac_ge
+ static void sbmac_set_rx_mode(struct net_device *dev);
+ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ static int sbmac_close(struct net_device *dev);
++#if defined (CONFIG_SBMAC_NAPI)
++static int sbmac_poll(struct net_device *poll_dev, int *budget);
++#endif
++
+ static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
+ static int sbmac_mii_probe(struct net_device *dev);
+ 
+@@ -740,7 +745,7 @@ static void sbdma_initctx(sbmacdma_t *d,
+ 
+ 	d->sbdma_maxdescr = maxdescr;
+ 
+-	d->sbdma_dscrtable = (sbdmadscr_t *)
++	d->sbdma_dscrtable_unaligned = d->sbdma_dscrtable = (sbdmadscr_t *)
+ 		kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
+ 
+ 	/*
+@@ -782,7 +787,6 @@ static void sbdma_initctx(sbmacdma_t *d,
+ 		d->sbdma_int_timeout = 0;
+ 	}
+ #endif
+-
+ }
+ 
+ /**********************************************************************
+@@ -1150,13 +1154,14 @@ static void sbdma_fillring(sbmacdma_t *d
+  *  	   nothing
+  ********************************************************************* */
+ 
+-static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
++static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll)
+ {
+ 	int curidx;
+ 	int hwidx;
+ 	sbdmadscr_t *dsc;
+ 	struct sk_buff *sb;
+ 	int len;
++	int work_done = 0;
+ 
+ 	for (;;) {
+ 		/*
+@@ -1234,8 +1239,15 @@ static void sbdma_rx_process(struct sbma
+ 						sb->ip_summed = CHECKSUM_NONE;
+ 					}
+ 				}
+-
++				
++#if defined(CONFIG_SBMAC_NAPI)
++				if (0 == poll)
++					netif_rx(sb);
++				else
++					netif_receive_skb(sb);
++#else
+ 				netif_rx(sb);
++#endif				
+ 			}
+ 		} else {
+ 			/*
+@@ -1252,8 +1264,9 @@ static void sbdma_rx_process(struct sbma
+ 		 */
+ 
+ 		d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
+-
++		work_done++;
+ 	}
++	return work_done;
+ }
+ 
+ 
+@@ -1275,15 +1288,22 @@ static void sbdma_rx_process(struct sbma
+  *  	   nothing
+  ********************************************************************* */
+ 
+-static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
++static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll)
+ {
+ 	int curidx;
+ 	int hwidx;
+ 	sbdmadscr_t *dsc;
+ 	struct sk_buff *sb;
+ 	unsigned long flags;
++	int packets_handled = 0;
+ 
+ 	spin_lock_irqsave(&(sc->sbm_lock), flags);
++	
++	if (d->sbdma_remptr == d->sbdma_addptr)
++		goto end_unlock;
++
++	hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
++			d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+ 
+ 	for (;;) {
+ 		/*
+@@ -1298,15 +1318,12 @@ static void sbdma_tx_process(struct sbma
+ 		 */
+ 
+ 		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
+-		hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+-				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+ 
+ 		/*
+ 		 * If they're the same, that means we've processed all
+ 		 * of the descriptors up to (but not including) the one that
+ 		 * the hardware is working on right now.
+ 		 */
+-
+ 		if (curidx == hwidx)
+ 			break;
+ 
+@@ -1337,6 +1354,7 @@ static void sbdma_tx_process(struct sbma
+ 
+ 		d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
+ 
++		packets_handled++;
+ 	}
+ 
+ 	/*
+@@ -1344,15 +1362,15 @@ static void sbdma_tx_process(struct sbma
+ 	 * Other drivers seem to do this when we reach a low
+ 	 * watermark on the transmit queue.
+ 	 */
++	
++	if (packets_handled)
++		netif_wake_queue(d->sbdma_eth->sbm_dev);
+ 
+-	netif_wake_queue(d->sbdma_eth->sbm_dev);
+-
++ end_unlock:
+ 	spin_unlock_irqrestore(&(sc->sbm_lock), flags);
+ 
+ }
+ 
+-
+-
+ /**********************************************************************
+  *  SBMAC_INITCTX(s)
+  *
+@@ -1396,7 +1414,6 @@ static int sbmac_initctx(struct sbmac_so
+ 	 * Initialize the DMA channels.  Right now, only one per MAC is used
+ 	 * Note: Only do this _once_, as it allocates memory from the kernel!
+ 	 */
+-
+ 	sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR);
+ 	sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR);
+ 
+@@ -1420,9 +1437,9 @@ static int sbmac_initctx(struct sbmac_so
+ 
+ static void sbdma_uninitctx(struct sbmacdma_s *d)
+ {
+-	if (d->sbdma_dscrtable) {
+-		kfree(d->sbdma_dscrtable);
+-		d->sbdma_dscrtable = NULL;
++	if (d->sbdma_dscrtable_unaligned) {
++		kfree(d->sbdma_dscrtable_unaligned);
++		d->sbdma_dscrtable_unaligned = d->sbdma_dscrtable = NULL;
+ 	}
+ 
+ 	if (d->sbdma_ctxtable) {
+@@ -1609,12 +1626,12 @@ static void sbmac_channel_start(struct s
+ 
+ #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ 	__raw_writeq(M_MAC_RXDMA_EN0 |
+-		       M_MAC_TXDMA_EN0, s->sbm_macenable);
++		     M_MAC_TXDMA_EN0, s->sbm_macenable);
+ #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ 	__raw_writeq(M_MAC_RXDMA_EN0 |
+-		       M_MAC_TXDMA_EN0 |
+-		       M_MAC_RX_ENABLE |
+-		       M_MAC_TX_ENABLE, s->sbm_macenable);
++		     M_MAC_TXDMA_EN0 |
++		     M_MAC_RX_ENABLE |
++		     M_MAC_TX_ENABLE, s->sbm_macenable);
+ #else
+ #error invalid SiByte MAC configuation
+ #endif
+@@ -1624,15 +1641,15 @@ static void sbmac_channel_start(struct s
+ 	 * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
+ 	 */
+ 	__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
+-		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr);
++		     ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), 
++		     s->sbm_imr);
+ #else
+ 	/*
+ 	 * Accept any kind of interrupt on TX and RX DMA channel 0
+ 	 */
+ 	__raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+-		       (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
++		     (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
+ #endif
+-
+ 	/*
+ 	 * Enable receiving unicasts and broadcasts
+ 	 */
+@@ -2067,7 +2084,6 @@ static irqreturn_t sbmac_intr(int irq,vo
+ 		 * Read the ISR (this clears the bits in the real
+ 		 * register, except for counter addr)
+ 		 */
+-
+ 		isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
+ 
+ 		if (isr == 0)
+@@ -2079,13 +2095,31 @@ static irqreturn_t sbmac_intr(int irq,vo
+ 		 * Transmits on channel 0
+ 		 */
+ 
++#if defined(CONFIG_SBMAC_NAPI)
+ 		if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
+-			sbdma_tx_process(sc,&(sc->sbm_txdma));
++			sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
+ 		}
+ 
+ 		/*
+ 		 * Receives on channel 0
+ 		 */
++		if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
++			if (netif_rx_schedule_prep(dev))
++			{
++				__raw_writeq(0, sc->sbm_imr);
++				__netif_rx_schedule(dev);
++			}
++			else
++			{
++				sbdma_rx_process(sc,&(sc->sbm_rxdma), 0);
++			}
++		}
++#else
++		/* Non NAPI */
++
++		if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
++			sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
++		}
+ 
+ 		/*
+ 		 * It's important to test all the bits (or at least the
+@@ -2105,8 +2139,9 @@ static irqreturn_t sbmac_intr(int irq,vo
+ 
+ 
+ 		if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
+-			sbdma_rx_process(sc,&(sc->sbm_rxdma));
++			sbdma_rx_process(sc,&(sc->sbm_rxdma), 0);
+ 		}
++#endif
+ 	}
+ 	return IRQ_RETVAL(handled);
+ }
+@@ -2405,7 +2440,10 @@ static int sbmac_init(struct net_device 
+ 	dev->do_ioctl           = sbmac_mii_ioctl;
+ 	dev->tx_timeout         = sbmac_tx_timeout;
+ 	dev->watchdog_timeo     = TX_TIMEOUT;
+-
++#if defined(CONFIG_SBMAC_NAPI)
++	dev->poll               = sbmac_poll;
++	dev->weight             = 16;
++#endif
+ 	dev->change_mtu         = sb1250_change_mtu;
+ 
+ 	/* This is needed for PASS2 for Rx H/W checksum feature */
+@@ -2818,7 +2856,37 @@ static int sbmac_close(struct net_device
+ 	return 0;
+ }
+ 
++#if defined(CONFIG_SBMAC_NAPI)
++static int sbmac_poll(struct net_device *dev, int *budget)
++{
++	int work_to_do;
++	int work_done;
++	struct sbmac_softc *sc = netdev_priv(dev);
++
++	work_to_do = min(*budget, dev->quota);
++	work_done = sbdma_rx_process(sc,&(sc->sbm_rxdma), 1);
+ 
++	sbdma_tx_process(sc,&(sc->sbm_txdma), 1);
++
++	*budget -= work_done;
++	dev->quota -= work_done;
++
++	if (work_done < work_to_do) {
++		netif_rx_complete(dev);
++
++#ifdef CONFIG_SBMAC_COALESCE
++		__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
++			     ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), 
++			     sc->sbm_imr);
++#else
++		__raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
++			     (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr);
++#endif
++	}
++
++	return (work_done >= work_to_do);
++}
++#endif
+ 
+ #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)
+ static void

Modified: dists/trunk/linux-2.6/debian/patches/series/0experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/0experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/0experimental.1	Mon Mar 13 18:55:47 2006
@@ -20,5 +20,7 @@
 + mips-ide-scan.patch
 + mips-sb1-probe-ide.patch
 + mips-sb1-irq-hazard.patch
++ mips-sb1-eth-1480.patch
++ mips-sb1-eth-napi.patch
 + s390-drivers-ccw-uevent-modalias.patch
 + s390-drivers-ccw-uevent-cleanup.patch



More information about the Kernel-svn-changes mailing list