Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] 8139cp/8139too: do not read into reserved registers
From: Ben Hutchings @ 2011-12-31 22:20 UTC (permalink / raw)
  To: Jason Wang; +Cc: netdev, davem, linux-kernel, akong
In-Reply-To: <20111231094433.5433.67602.stgit@dhcp-8-146.nay.redhat.com>

On Sat, 2011-12-31 at 17:44 +0800, Jason Wang wrote:
> delay_eeprom() use long read for Cfg9346 register(offset 0x50) which may read
> into the area of reserved register(offset 0x53). Use byte read instead.
[...]

If they've been working like this for so long (from the start of git
history), maybe they're best left alone.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* iproute2: avoid use of implicit declarations
From: Jan Engelhardt @ 2011-12-31 22:22 UTC (permalink / raw)
  To: shemminger; +Cc: Linux Networking Developer Mailing List
In-Reply-To: <alpine.LNX.2.01.1112312317220.24158@frira.zrqbmnf.qr>

From: Jan Engelhardt <jengelh@medozas.de>
Date: 2011-12-31 23:16:27.428349795 +0100

gcc -DLIBDIR=\"/usr/lib64\" -D_GNU_SOURCE -fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wstrict-prototypes -fPIC -DXT_LIB_DIR=\"/usr/lib64/xtables\" -I../include -DRESOLVE_HOSTNAMES -DLIBDIR=\"/usr/lib64\" -fPIC   -c -o ipx_pton.o ipx_pton.c
In file included from ../include/utils.h:8:0,
                 from ipx_ntop.c:5:
../include/libnetlink.h: In function 'rta_getattr_u64':
../include/libnetlink.h:84:2: warning: implicit declaration of function 'memcpy'
../include/libnetlink.h:84:2: warning: incompatible implicit declaration of built-in function 'memcpy'

diff --git a/include/libnetlink.h b/include/libnetlink.h
index b237579..b0656ce 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -1,6 +1,7 @@
 #ifndef __LIBNETLINK_H__
 #define __LIBNETLINK_H__ 1
 
+#include <string.h>
 #include <asm/types.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>

^ permalink raw reply related

* Re: [PATCH RFC] IPv6: Avoid taking write lock for /proc/net/ipv6_route
From: David Miller @ 2011-12-31 22:46 UTC (permalink / raw)
  To: joshhunt00; +Cc: kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel
In-Reply-To: <CAKA=qzb=PYTMO=9KFpTJ9BVdDRkqbaCuW02pbW0onM8gU1E7sw@mail.gmail.com>

From: Josh Hunt <joshhunt00@gmail.com>
Date: Sat, 31 Dec 2011 13:49:38 -0600

> Thanks David. Are you aware if anyone has started the work to make
> IPv6 traversals RCU safe?

Nobody is working on this.

^ permalink raw reply

* [PATCH] bonding: fix error handling if slave is busy (v2)
From: Stephen Hemminger @ 2011-12-31 23:26 UTC (permalink / raw)
  To: Nicolas de Pesloüan
  Cc: David Miller, Jay Vosburgh, Andy Gospodarek, netdev
In-Reply-To: <4EFF3419.4050504@gmail.com>

If slave device already has a receive handler registered, then the
error unwind of bonding device enslave function is broken. 

The following will leave a pointer to freed memory in the slave
device list, causing a later kernel panic.
# modprobe dummy
# ip li add dummy0-1 link dummy0 type macvlan
# modprobe bonding
# echo +dummy0 >/sys/class/net/bond0/bonding/slaves

The fix is to detach the slave (which removes it from the list)
in the unwind path.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
v2 - need to keep original err_close for other unwind

--- a/drivers/net/bonding/bond_main.c	2011-12-30 14:20:03.171823181 -0800
+++ b/drivers/net/bonding/bond_main.c	2011-12-31 15:20:16.493379415 -0800
@@ -1822,7 +1822,7 @@ int bond_enslave(struct net_device *bond
 				 "but new slave device does not support netpoll.\n",
 				 bond_dev->name);
 			res = -EBUSY;
-			goto err_close;
+			goto err_detach;
 		}
 	}
 #endif
@@ -1831,7 +1831,7 @@ int bond_enslave(struct net_device *bond
 
 	res = bond_create_slave_symlinks(bond_dev, slave_dev);
 	if (res)
-		goto err_close;
+		goto err_detach;
 
 	res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
 					 new_slave);
@@ -1852,6 +1852,11 @@ int bond_enslave(struct net_device *bond
 err_dest_symlinks:
 	bond_destroy_slave_symlinks(bond_dev, slave_dev);
 
+err_detach:
+	write_lock_bh(&bond->lock);
+	bond_detach_slave(bond, new_slave);
+	write_unlock_bh(&bond->lock);
+
 err_close:
 	dev_close(slave_dev);
 

^ permalink raw reply

* Re: [PATCH] bonding: fix error handling if slave is busy (v2)
From: Nicolas de Pesloüan @ 2012-01-01  0:09 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Jay Vosburgh, Andy Gospodarek, netdev
In-Reply-To: <20111231152646.6f0f98fc@nehalam.linuxnetplumber.net>

Le 01/01/2012 00:26, Stephen Hemminger a écrit :
> If slave device already has a receive handler registered, then the
> error unwind of bonding device enslave function is broken.
>
> The following will leave a pointer to freed memory in the slave
> device list, causing a later kernel panic.
> # modprobe dummy
> # ip li add dummy0-1 link dummy0 type macvlan
> # modprobe bonding
> # echo +dummy0>/sys/class/net/bond0/bonding/slaves
>
> The fix is to detach the slave (which removes it from the list)
> in the unwind path.
>
> Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>

Thanks Stephen.

Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>

> ---
> v2 - need to keep original err_close for other unwind
>
> --- a/drivers/net/bonding/bond_main.c	2011-12-30 14:20:03.171823181 -0800
> +++ b/drivers/net/bonding/bond_main.c	2011-12-31 15:20:16.493379415 -0800
> @@ -1822,7 +1822,7 @@ int bond_enslave(struct net_device *bond
>   				 "but new slave device does not support netpoll.\n",
>   				 bond_dev->name);
>   			res = -EBUSY;
> -			goto err_close;
> +			goto err_detach;
>   		}
>   	}
>   #endif
> @@ -1831,7 +1831,7 @@ int bond_enslave(struct net_device *bond
>
>   	res = bond_create_slave_symlinks(bond_dev, slave_dev);
>   	if (res)
> -		goto err_close;
> +		goto err_detach;
>
>   	res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
>   					 new_slave);
> @@ -1852,6 +1852,11 @@ int bond_enslave(struct net_device *bond
>   err_dest_symlinks:
>   	bond_destroy_slave_symlinks(bond_dev, slave_dev);
>
> +err_detach:
> +	write_lock_bh(&bond->lock);
> +	bond_detach_slave(bond, new_slave);
> +	write_unlock_bh(&bond->lock);
> +
>   err_close:
>   	dev_close(slave_dev);
>
>
>
>

^ permalink raw reply

* Re: [PATCH] bonding: fix error handling if slave is busy (v2)
From: Stephen Hemminger @ 2012-01-01  0:13 UTC (permalink / raw)
  To: Nicolas de Pesloüan
  Cc: David Miller, Jay Vosburgh, Andy Gospodarek, netdev
In-Reply-To: <4EFFA44E.10507@gmail.com>

On Sun, 01 Jan 2012 01:09:50 +0100
Nicolas de Pesloüan <nicolas.2p.debian@gmail.com> wrote:

> Le 01/01/2012 00:26, Stephen Hemminger a écrit :
> > If slave device already has a receive handler registered, then the
> > error unwind of bonding device enslave function is broken.
> >
> > The following will leave a pointer to freed memory in the slave
> > device list, causing a later kernel panic.
> > # modprobe dummy
> > # ip li add dummy0-1 link dummy0 type macvlan
> > # modprobe bonding
> > # echo +dummy0>/sys/class/net/bond0/bonding/slaves
> >
> > The fix is to detach the slave (which removes it from the list)
> > in the unwind path.
> >
> > Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>
> 
> Thanks Stephen.
> 
> Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>

The locking in bond driver is a tangled web.

Would be cleaner to get rid of bond->lock altogether.
Slave add/delete should be protected by RTNL, and the lookup should
be converted to RCU.  The problem is that bonding driver implements
own form of circular list to handle round-robin etc.

^ permalink raw reply

* Re: [PATCH] bonding: fix error handling if slave is busy (v2)
From: Nicolas de Pesloüan @ 2012-01-01  0:28 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Jay Vosburgh, Andy Gospodarek, netdev
In-Reply-To: <20111231161322.40b16d69@nehalam.linuxnetplumber.net>

Le 01/01/2012 01:13, Stephen Hemminger a écrit :
> On Sun, 01 Jan 2012 01:09:50 +0100
> Nicolas de Pesloüan<nicolas.2p.debian@gmail.com>  wrote:
>
>> Le 01/01/2012 00:26, Stephen Hemminger a écrit :
>>> If slave device already has a receive handler registered, then the
>>> error unwind of bonding device enslave function is broken.
>>>
>>> The following will leave a pointer to freed memory in the slave
>>> device list, causing a later kernel panic.
>>> # modprobe dummy
>>> # ip li add dummy0-1 link dummy0 type macvlan
>>> # modprobe bonding
>>> # echo +dummy0>/sys/class/net/bond0/bonding/slaves
>>>
>>> The fix is to detach the slave (which removes it from the list)
>>> in the unwind path.
>>>
>>> Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>
>>
>> Thanks Stephen.
>>
>> Reviewed-by: Nicolas de Pesloüan<nicolas.2p.debian@free.fr>
>
> The locking in bond driver is a tangled web.
>
> Would be cleaner to get rid of bond->lock altogether.
> Slave add/delete should be protected by RTNL, and the lookup should
> be converted to RCU.  The problem is that bonding driver implements
> own form of circular list to handle round-robin etc.

Bonding has become an incredibly complex thing, due to the large number of corner cases it needs to 
handle. And the locking system in probably part of the problem.

Unfortunately, I'm far from a Linux locking specialist, so I cannot comment on this... I just 
noticed that searching for RTNL in Documentations yields no result... :-(

	Nicolas.

^ permalink raw reply

* tc filter mask for ACK packets off?
From: John A. Sullivan III @ 2012-01-01  2:30 UTC (permalink / raw)
  To: netdev

Hello, all.  I've been noticing that virtually all the documentation
says we should prioritize ACK only packets and that they can be
identified with match u8 0x10 0xff.  However, isn't the actual flag
field only 6 bits longs and the first two belong to a previous 6 bit
reserved field?
If that is true, if ever those bits are set, our filters will
unnecessarily break.  Shouldn't it be match u8 0x10 0x3f? Then again,
I'm very new at this.  Thanks - John

^ permalink raw reply

* tc filter mask for ACK packets off?
From: John A. Sullivan III @ 2012-01-01  2:30 UTC (permalink / raw)
  To: netdev

Hello, all.  I've been noticing that virtually all the documentation
says we should prioritize ACK only packets and that they can be
identified with match u8 0x10 0xff.  However, isn't the actual flag
field only 6 bits longs and the first two belong to a previous 6 bit
reserved field?
If that is true, if ever those bits are set, our filters will
unnecessarily break.  Shouldn't it be match u8 0x10 0x3f? Then again,
I'm very new at this.  Thanks - John

^ permalink raw reply

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Bjarke Istrup Pedersen @ 2012-01-01 12:09 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <20111231121710.GB9842@electric-eye.fr.zoreil.com>

2011/12/31 Francois Romieu <romieu@fr.zoreil.com>:
> Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> [...]
>> Also tried connect a machine to one of the ports, and copying a large
>> file across (something that before could make it lock up within 15
>> secords) - also worked without any problems - CPU usage around 15%
>> (mostly "top" using that), so thats not bad at all.
>>
>> Is there any other testcases that I should try out?
>
> Same thing + random ethtool link management commands.
> Same thing + random cable unplug/plug.
> Same thing + pktgen facing the lan interface.
>
> Everything at the same time.

I tried messing around with plugging cables and playing with ethtool
at the same time, while there was alot of trafic, which went fine :)
Happy new year btw :)

/Bjarke

> --
> Ueimor
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* [PATCH] fix for nfacct infrastructure in net-next
From: pablo @ 2012-01-01 16:22 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>

Hi Dave,

Please, pull the following fix for the nfacct infrastructure already
in your net-next tree.

You can pull it from:

git://1984.lsi.us.es/net-net nf-next

Thanks!

Pablo Neira Ayuso (1):
  netfilter: nfnetlink_acct: fix nfnl_acct_get operation

 net/netfilter/nfnetlink_acct.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

-- 
1.7.7.3


^ permalink raw reply

* [PATCH] netfilter: nfnetlink_acct: fix nfnl_acct_get operation
From: pablo @ 2012-01-01 16:22 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1325434945-21900-1-git-send-email-pablo@netfilter.org>

From: Pablo Neira Ayuso <pablo@netfilter.org>

The get operation was not sending the message that was built to
user-space. This patch also includes the appropriate handling for
the return value of netlink_unicast().

Moreover, fix error codes on error (for example, for non-existing
entry was uncorrect).

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nfnetlink_acct.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 362ab6c..11ba013 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -166,7 +166,7 @@ static int
 nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb,
 	     const struct nlmsghdr *nlh, const struct nlattr * const tb[])
 {
-	int ret = 0;
+	int ret = -ENOENT;
 	struct nf_acct *cur;
 	char *acct_name;
 
@@ -186,17 +186,26 @@ nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb,
 			continue;
 
 		skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-		if (skb2 == NULL)
+		if (skb2 == NULL) {
+			ret = -ENOMEM;
 			break;
+		}
 
 		ret = nfnl_acct_fill_info(skb2, NETLINK_CB(skb).pid,
 					 nlh->nlmsg_seq,
 					 NFNL_MSG_TYPE(nlh->nlmsg_type),
 					 NFNL_MSG_ACCT_NEW, cur);
-		if (ret <= 0)
+		if (ret <= 0) {
 			kfree_skb(skb2);
+			break;
+		}
+		ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).pid,
+					MSG_DONTWAIT);
+		if (ret > 0)
+			ret = 0;
 
-		break;
+		/* this avoids a loop in nfnetlink. */
+		return ret == -EAGAIN ? -ENOBUFS : ret;
 	}
 	return ret;
 }
-- 
1.7.7.3


^ permalink raw reply related

* Re: [PATCH] fix for nfacct infrastructure in net-next
From: Pablo Neira Ayuso @ 2012-01-01 16:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1325434945-21900-1-git-send-email-pablo@netfilter.org>

On Sun, Jan 01, 2012 at 05:22:24PM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> Hi Dave,
> 
> Please, pull the following fix for the nfacct infrastructure already
> in your net-next tree.
> 
> You can pull it from:
> 
> git://1984.lsi.us.es/net-net nf-next
                       ^^^^^^^
I meant to say net-next, of course.

Sorry.

^ permalink raw reply

* [PATCH 1/1] via-rhine: Split driver into .c and .h files.
From: Bjarke Istrup Pedersen @ 2012-01-01 21:15 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl,
	Bjarke Istrup Pedersen

Split the driver into via-rhine.c and via-rhine.h like it should be.

There is also a bit of cleanup of checkpatch warnings, other than that,
there is no changes to how the code works, it is plain refactoring.

Signed-off-by: Bjarke Istrup Pedersen <gurligebis@gentoo.org>
---
 drivers/net/ethernet/via/via-rhine.c |  449 ++--------------------------------
 drivers/net/ethernet/via/via-rhine.h |  440 +++++++++++++++++++++++++++++++++
 2 files changed, 466 insertions(+), 423 deletions(-)
 create mode 100644 drivers/net/ethernet/via/via-rhine.h

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 89ced1b..6c1651e 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -68,25 +68,6 @@ static bool avoid_D3;
    The Rhine has a 64 element 8390-like hash table. */
 static const int multicast_filter_limit = 32;
 
-
-/* Operational parameters that are set at compile time. */
-
-/* Keep the ring sizes a power of two for compile efficiency.
-   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
-   Making the Tx ring too large decreases the effectiveness of channel
-   bonding and packet priority.
-   There are no ill effects from too-large receive rings. */
-#define TX_RING_SIZE	16
-#define TX_QUEUE_LEN	10	/* Limit ring entries actually used. */
-#define RX_RING_SIZE	64
-
-/* Operational parameters that usually are not changed. */
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT	(2*HZ)
-
-#define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer.*/
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -114,16 +95,7 @@ static const int multicast_filter_limit = 32;
 #include <asm/uaccess.h>
 #include <linux/dmi.h>
 
-/* These identify the driver base version and may not be removed. */
-static const char version[] __devinitconst =
-	"v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
-
-/* This driver was written to use PCI memory space. Some early versions
-   of the Rhine may only work correctly with I/O space accesses. */
-#ifdef CONFIG_VIA_RHINE_MMIO
-#define USE_MMIO
-#else
-#endif
+#include "via-rhine.h"
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
@@ -136,9 +108,6 @@ MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
 
-#define MCAM_SIZE	32
-#define VCAM_SIZE	32
-
 /*
 		Theory of Operation
 
@@ -232,290 +201,6 @@ The chip does not pad to minimum transmit length.
 
 */
 
-
-/* This table drives the PCI probe routines. It's mostly boilerplate in all
-   of the drivers, and will likely be provided by some future kernel.
-   Note the matching code -- the first table entry matchs all 56** cards but
-   second only the 1234 card.
-*/
-
-enum rhine_revs {
-	VT86C100A	= 0x00,
-	VTunknown0	= 0x20,
-	VT6102		= 0x40,
-	VT8231		= 0x50,	/* Integrated MAC */
-	VT8233		= 0x60,	/* Integrated MAC */
-	VT8235		= 0x74,	/* Integrated MAC */
-	VT8237		= 0x78,	/* Integrated MAC */
-	VTunknown1	= 0x7C,
-	VT6105		= 0x80,
-	VT6105_B0	= 0x83,
-	VT6105L		= 0x8A,
-	VT6107		= 0x8C,
-	VTunknown2	= 0x8E,
-	VT6105M		= 0x90,	/* Management adapter */
-};
-
-enum rhine_quirks {
-	rqWOL		= 0x0001,	/* Wake-On-LAN support */
-	rqForceReset	= 0x0002,
-	rq6patterns	= 0x0040,	/* 6 instead of 4 patterns for WOL */
-	rqStatusWBRace	= 0x0080,	/* Tx Status Writeback Error possible */
-	rqRhineI	= 0x0100,	/* See comment below */
-};
-/*
- * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
- * MMIO as well as for the collision counter and the Tx FIFO underflow
- * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
- */
-
-/* Beware of PCI posted writes */
-#define IOSYNC	do { ioread8(ioaddr + StationAddr); } while (0)
-
-static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
-	{ 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, },	/* VT86C100A */
-	{ 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6102 */
-	{ 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, },	/* 6105{,L,LOM} */
-	{ 0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6105M */
-	{ }	/* terminate list */
-};
-MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
-
-
-/* Offsets to the device registers. */
-enum register_offsets {
-	StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
-	ChipCmd1=0x09, TQWake=0x0A,
-	IntrStatus=0x0C, IntrEnable=0x0E,
-	MulticastFilter0=0x10, MulticastFilter1=0x14,
-	RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
-	MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E, PCIBusConfig1=0x6F,
-	MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
-	ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
-	RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
-	StickyHW=0x83, IntrStatus2=0x84,
-	CamMask=0x88, CamCon=0x92, CamAddr=0x93,
-	WOLcrSet=0xA0, PwcfgSet=0xA1, WOLcgSet=0xA3, WOLcrClr=0xA4,
-	WOLcrClr1=0xA6, WOLcgClr=0xA7,
-	PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD,
-};
-
-/* Bits in ConfigD */
-enum backoff_bits {
-	BackOptional=0x01, BackModify=0x02,
-	BackCaptureEffect=0x04, BackRandom=0x08
-};
-
-/* Bits in the TxConfig (TCR) register */
-enum tcr_bits {
-	TCR_PQEN=0x01,
-	TCR_LB0=0x02,		/* loopback[0] */
-	TCR_LB1=0x04,		/* loopback[1] */
-	TCR_OFSET=0x08,
-	TCR_RTGOPT=0x10,
-	TCR_RTFT0=0x20,
-	TCR_RTFT1=0x40,
-	TCR_RTSF=0x80,
-};
-
-/* Bits in the CamCon (CAMC) register */
-enum camcon_bits {
-	CAMC_CAMEN=0x01,
-	CAMC_VCAMSL=0x02,
-	CAMC_CAMWR=0x04,
-	CAMC_CAMRD=0x08,
-};
-
-/* Bits in the PCIBusConfig1 (BCR1) register */
-enum bcr1_bits {
-	BCR1_POT0=0x01,
-	BCR1_POT1=0x02,
-	BCR1_POT2=0x04,
-	BCR1_CTFT0=0x08,
-	BCR1_CTFT1=0x10,
-	BCR1_CTSF=0x20,
-	BCR1_TXQNOBK=0x40,	/* for VT6105 */
-	BCR1_VIDFR=0x80,	/* for VT6105 */
-	BCR1_MED0=0x40,		/* for VT6102 */
-	BCR1_MED1=0x80,		/* for VT6102 */
-};
-
-#ifdef USE_MMIO
-/* Registers we check that mmio and reg are the same. */
-static const int mmio_verify_registers[] = {
-	RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
-	0
-};
-#endif
-
-/* Bits in the interrupt status/mask registers. */
-enum intr_status_bits {
-	IntrRxDone	= 0x0001,
-	IntrTxDone	= 0x0002,
-	IntrRxErr	= 0x0004,
-	IntrTxError	= 0x0008,
-	IntrRxEmpty	= 0x0020,
-	IntrPCIErr	= 0x0040,
-	IntrStatsMax	= 0x0080,
-	IntrRxEarly	= 0x0100,
-	IntrTxUnderrun	= 0x0210,
-	IntrRxOverflow	= 0x0400,
-	IntrRxDropped	= 0x0800,
-	IntrRxNoBuf	= 0x1000,
-	IntrTxAborted	= 0x2000,
-	IntrLinkChange	= 0x4000,
-	IntrRxWakeUp	= 0x8000,
-	IntrTxDescRace		= 0x080000,	/* mapped from IntrStatus2 */
-	IntrNormalSummary	= IntrRxDone | IntrTxDone,
-	IntrTxErrSummary	= IntrTxDescRace | IntrTxAborted | IntrTxError |
-				  IntrTxUnderrun,
-};
-
-/* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */
-enum wol_bits {
-	WOLucast	= 0x10,
-	WOLmagic	= 0x20,
-	WOLbmcast	= 0x30,
-	WOLlnkon	= 0x40,
-	WOLlnkoff	= 0x80,
-};
-
-/* The Rx and Tx buffer descriptors. */
-struct rx_desc {
-	__le32 rx_status;
-	__le32 desc_length; /* Chain flag, Buffer/frame length */
-	__le32 addr;
-	__le32 next_desc;
-};
-struct tx_desc {
-	__le32 tx_status;
-	__le32 desc_length; /* Chain flag, Tx Config, Frame length */
-	__le32 addr;
-	__le32 next_desc;
-};
-
-/* Initial value for tx_desc.desc_length, Buffer size goes to bits 0-10 */
-#define TXDESC		0x00e08000
-
-enum rx_status_bits {
-	RxOK=0x8000, RxWholePkt=0x0300, RxErr=0x008F
-};
-
-/* Bits in *_desc.*_status */
-enum desc_status_bits {
-	DescOwn=0x80000000
-};
-
-/* Bits in *_desc.*_length */
-enum desc_length_bits {
-	DescTag=0x00010000
-};
-
-/* Bits in ChipCmd. */
-enum chip_cmd_bits {
-	CmdInit=0x01, CmdStart=0x02, CmdStop=0x04, CmdRxOn=0x08,
-	CmdTxOn=0x10, Cmd1TxDemand=0x20, CmdRxDemand=0x40,
-	Cmd1EarlyRx=0x01, Cmd1EarlyTx=0x02, Cmd1FDuplex=0x04,
-	Cmd1NoTxPoll=0x08, Cmd1Reset=0x80,
-};
-
-struct rhine_private {
-	/* Bit mask for configured VLAN ids */
-	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
-
-	/* Descriptor rings */
-	struct rx_desc *rx_ring;
-	struct tx_desc *tx_ring;
-	dma_addr_t rx_ring_dma;
-	dma_addr_t tx_ring_dma;
-
-	/* The addresses of receive-in-place skbuffs. */
-	struct sk_buff *rx_skbuff[RX_RING_SIZE];
-	dma_addr_t rx_skbuff_dma[RX_RING_SIZE];
-
-	/* The saved address of a sent-in-place packet/buffer, for later free(). */
-	struct sk_buff *tx_skbuff[TX_RING_SIZE];
-	dma_addr_t tx_skbuff_dma[TX_RING_SIZE];
-
-	/* Tx bounce buffers (Rhine-I only) */
-	unsigned char *tx_buf[TX_RING_SIZE];
-	unsigned char *tx_bufs;
-	dma_addr_t tx_bufs_dma;
-
-	struct pci_dev *pdev;
-	long pioaddr;
-	struct net_device *dev;
-	struct napi_struct napi;
-	spinlock_t lock;
-	struct mutex task_lock;
-	bool task_enable;
-	struct work_struct slow_event_task;
-	struct work_struct reset_task;
-
-	u32 msg_enable;
-
-	/* Frequently used values: keep some adjacent for cache effect. */
-	u32 quirks;
-	struct rx_desc *rx_head_desc;
-	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
-	unsigned int cur_tx, dirty_tx;
-	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
-	u8 wolopts;
-
-	u8 tx_thresh, rx_thresh;
-
-	struct mii_if_info mii_if;
-	void __iomem *base;
-};
-
-#define BYTE_REG_BITS_ON(x, p)      do { iowrite8((ioread8((p))|(x)), (p)); } while (0)
-#define WORD_REG_BITS_ON(x, p)      do { iowrite16((ioread16((p))|(x)), (p)); } while (0)
-#define DWORD_REG_BITS_ON(x, p)     do { iowrite32((ioread32((p))|(x)), (p)); } while (0)
-
-#define BYTE_REG_BITS_IS_ON(x, p)   (ioread8((p)) & (x))
-#define WORD_REG_BITS_IS_ON(x, p)   (ioread16((p)) & (x))
-#define DWORD_REG_BITS_IS_ON(x, p)  (ioread32((p)) & (x))
-
-#define BYTE_REG_BITS_OFF(x, p)     do { iowrite8(ioread8((p)) & (~(x)), (p)); } while (0)
-#define WORD_REG_BITS_OFF(x, p)     do { iowrite16(ioread16((p)) & (~(x)), (p)); } while (0)
-#define DWORD_REG_BITS_OFF(x, p)    do { iowrite32(ioread32((p)) & (~(x)), (p)); } while (0)
-
-#define BYTE_REG_BITS_SET(x, m, p)   do { iowrite8((ioread8((p)) & (~(m)))|(x), (p)); } while (0)
-#define WORD_REG_BITS_SET(x, m, p)   do { iowrite16((ioread16((p)) & (~(m)))|(x), (p)); } while (0)
-#define DWORD_REG_BITS_SET(x, m, p)  do { iowrite32((ioread32((p)) & (~(m)))|(x), (p)); } while (0)
-
-
-static int  mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
-static int  rhine_open(struct net_device *dev);
-static void rhine_reset_task(struct work_struct *work);
-static void rhine_slow_event_task(struct work_struct *work);
-static void rhine_tx_timeout(struct net_device *dev);
-static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
-				  struct net_device *dev);
-static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
-static void rhine_tx(struct net_device *dev);
-static int rhine_rx(struct net_device *dev, int limit);
-static void rhine_set_rx_mode(struct net_device *dev);
-static struct net_device_stats *rhine_get_stats(struct net_device *dev);
-static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
-static int  rhine_close(struct net_device *dev);
-static void rhine_shutdown (struct pci_dev *pdev);
-static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
-static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
-static void rhine_restart_tx(struct net_device *dev);
-
-#define RHINE_WAIT_FOR(condition)				\
-do {								\
-	int i = 1024;						\
-	while (!(condition) && --i)				\
-		;						\
-	if (debug > 1 && i < 512)				\
-		pr_info("%4d cycles used @ %s:%d\n",		\
-			1024 - i, __func__, __LINE__);		\
-} while (0)
-
 static u32 rhine_get_events(struct rhine_private *rp)
 {
 	void __iomem *ioaddr = rp->base;
@@ -731,26 +416,6 @@ static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp)
 	ioread16(ioaddr + RxMissed);
 }
 
-#define RHINE_EVENT_NAPI_RX	(IntrRxDone | \
-				 IntrRxErr | \
-				 IntrRxEmpty | \
-				 IntrRxOverflow	| \
-				 IntrRxDropped | \
-				 IntrRxNoBuf | \
-				 IntrRxWakeUp)
-
-#define RHINE_EVENT_NAPI_TX_ERR	(IntrTxError | \
-				 IntrTxAborted | \
-				 IntrTxUnderrun | \
-				 IntrTxDescRace)
-#define RHINE_EVENT_NAPI_TX	(IntrTxDone | RHINE_EVENT_NAPI_TX_ERR)
-
-#define RHINE_EVENT_NAPI	(RHINE_EVENT_NAPI_RX | \
-				 RHINE_EVENT_NAPI_TX | \
-				 IntrStatsMax)
-#define RHINE_EVENT_SLOW	(IntrPCIErr | IntrLinkChange)
-#define RHINE_EVENT		(RHINE_EVENT_NAPI | RHINE_EVENT_SLOW)
-
 static int rhine_napipoll(struct napi_struct *napi, int budget)
 {
 	struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
@@ -814,24 +479,6 @@ static void __devinit rhine_hw_init(struct net_device *dev, long pioaddr)
 	rhine_reload_eeprom(pioaddr, dev);
 }
 
-static const struct net_device_ops rhine_netdev_ops = {
-	.ndo_open		 = rhine_open,
-	.ndo_stop		 = rhine_close,
-	.ndo_start_xmit		 = rhine_start_tx,
-	.ndo_get_stats		 = rhine_get_stats,
-	.ndo_set_rx_mode	 = rhine_set_rx_mode,
-	.ndo_change_mtu		 = eth_change_mtu,
-	.ndo_validate_addr	 = eth_validate_addr,
-	.ndo_set_mac_address 	 = eth_mac_addr,
-	.ndo_do_ioctl		 = netdev_ioctl,
-	.ndo_tx_timeout 	 = rhine_tx_timeout,
-	.ndo_vlan_rx_add_vid	 = rhine_vlan_rx_add_vid,
-	.ndo_vlan_rx_kill_vid	 = rhine_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	 = rhine_poll,
-#endif
-};
-
 static int __devinit rhine_init_one(struct pci_dev *pdev,
 				    const struct pci_device_id *ent)
 {
@@ -1774,21 +1421,6 @@ static void rhine_tx(struct net_device *dev)
 		netif_wake_queue(dev);
 }
 
-/**
- * rhine_get_vlan_tci - extract TCI from Rx data buffer
- * @skb: pointer to sk_buff
- * @data_size: used data area of the buffer including CRC
- *
- * If hardware VLAN tag extraction is enabled and the chip indicates a 802.1Q
- * packet, the extracted 802.1Q header (2 bytes TPID + 2 bytes TCI) is 4-byte
- * aligned following the CRC.
- */
-static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
-{
-	u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
-	return be16_to_cpup((__be16 *)trailer);
-}
-
 /* Process up to limit frames from receive ring */
 static int rhine_rx(struct net_device *dev, int limit)
 {
@@ -1992,17 +1624,6 @@ out_unlock:
 	mutex_unlock(&rp->task_lock);
 }
 
-static struct net_device_stats *rhine_get_stats(struct net_device *dev)
-{
-	struct rhine_private *rp = netdev_priv(dev);
-
-	spin_lock_bh(&rp->lock);
-	rhine_update_rx_crc_and_missed_errord(rp);
-	spin_unlock_bh(&rp->lock);
-
-	return &dev->stats;
-}
-
 static void rhine_set_rx_mode(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
@@ -2142,18 +1763,6 @@ static int rhine_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	return 0;
 }
 
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-	.get_settings		= netdev_get_settings,
-	.set_settings		= netdev_set_settings,
-	.nway_reset		= netdev_nway_reset,
-	.get_link		= netdev_get_link,
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-	.get_wol		= rhine_get_wol,
-	.set_wol		= rhine_set_wol,
-};
-
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct rhine_private *rp = netdev_priv(dev);
@@ -2339,36 +1948,6 @@ static int rhine_resume(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PM */
 
-static struct pci_driver rhine_driver = {
-	.name		= DRV_NAME,
-	.id_table	= rhine_pci_tbl,
-	.probe		= rhine_init_one,
-	.remove		= __devexit_p(rhine_remove_one),
-#ifdef CONFIG_PM
-	.suspend	= rhine_suspend,
-	.resume		= rhine_resume,
-#endif /* CONFIG_PM */
-	.shutdown =	rhine_shutdown,
-};
-
-static struct dmi_system_id __initdata rhine_dmi_table[] = {
-	{
-		.ident = "EPIA-M",
-		.matches = {
-			DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
-			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
-		},
-	},
-	{
-		.ident = "KV7",
-		.matches = {
-			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
-			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
-		},
-	},
-	{ NULL }
-};
-
 static int __init rhine_init(void)
 {
 /* when a module, this is printed whether or not devices are found in probe */
@@ -2386,12 +1965,36 @@ static int __init rhine_init(void)
 	return pci_register_driver(&rhine_driver);
 }
 
-
 static void __exit rhine_cleanup(void)
 {
 	pci_unregister_driver(&rhine_driver);
 }
 
+static struct net_device_stats *rhine_get_stats(struct net_device *dev)
+{
+	struct rhine_private *rp = netdev_priv(dev);
+
+	spin_lock_bh(&rp->lock);
+	rhine_update_rx_crc_and_missed_errord(rp);
+	spin_unlock_bh(&rp->lock);
+
+	return &dev->stats;
+}
+
+/**
+ * rhine_get_vlan_tci - extract TCI from Rx data buffer
+ * @skb: pointer to sk_buff
+ * @data_size: used data area of the buffer including CRC
+ *
+ * If hardware VLAN tag extraction is enabled and the chip indicates a 802.1Q
+ * packet, the extracted 802.1Q header (2 bytes TPID + 2 bytes TCI) is 4-byte
+ * aligned following the CRC.
+ */
+static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
+{
+	u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
+	return be16_to_cpup((__be16 *)trailer);
+}
 
 module_init(rhine_init);
 module_exit(rhine_cleanup);
diff --git a/drivers/net/ethernet/via/via-rhine.h b/drivers/net/ethernet/via/via-rhine.h
new file mode 100644
index 0000000..6add270
--- /dev/null
+++ b/drivers/net/ethernet/via/via-rhine.h
@@ -0,0 +1,440 @@
+/* via-rhine.c: A Linux Ethernet device driver for VIA Rhine family chips. */
+/*
+	Written 1998-2001 by Donald Becker.
+
+	Current Maintainer: Roger Luethi <rl@hellgate.ch>
+
+	This software may be used and distributed according to the terms of
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice.  This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	This driver is designed for the VIA VT86C100A Rhine-I.
+	It also works with the Rhine-II (6102) and Rhine-III (6105/6105L/6105LOM
+	and management NIC 6105M).
+
+	The author may be reached as becker@scyld.com, or C/O
+	Scyld Computing Corporation
+	410 Severn Ave., Suite 210
+	Annapolis MD 21403
+
+
+	This driver contains some changes from the original Donald Becker
+	version. He may or may not be interested in bug reports on this
+	code. You can find his versions at:
+	http://www.scyld.com/network/via-rhine.html
+	[link no longer provides useful info -jgarzik]
+
+*/
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+   Making the Tx ring too large decreases the effectiveness of channel
+   bonding and packet priority.
+   There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE	16
+#define TX_QUEUE_LEN	10	/* Limit ring entries actually used. */
+#define RX_RING_SIZE	64
+
+/* Operational parameters that usually are not changed. */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT	(2*HZ)
+
+#define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer.*/
+
+/* These identify the driver base version and may not be removed. */
+static const char version[] __devinitconst =
+	"v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
+
+/* This driver was written to use PCI memory space. Some early versions
+   of the Rhine may only work correctly with I/O space accesses. */
+#ifdef CONFIG_VIA_RHINE_MMIO
+#define USE_MMIO
+#else
+#endif
+
+#define MCAM_SIZE	32
+#define VCAM_SIZE	32
+
+/* This table drives the PCI probe routines. It's mostly boilerplate in all
+   of the drivers, and will likely be provided by some future kernel.
+   Note the matching code -- the first table entry matchs all 56** cards but
+   second only the 1234 card.
+*/
+
+enum rhine_revs {
+	VT86C100A	= 0x00,
+	VTunknown0	= 0x20,
+	VT6102		= 0x40,
+	VT8231		= 0x50,	/* Integrated MAC */
+	VT8233		= 0x60,	/* Integrated MAC */
+	VT8235		= 0x74,	/* Integrated MAC */
+	VT8237		= 0x78,	/* Integrated MAC */
+	VTunknown1	= 0x7C,
+	VT6105		= 0x80,
+	VT6105_B0	= 0x83,
+	VT6105L		= 0x8A,
+	VT6107		= 0x8C,
+	VTunknown2	= 0x8E,
+	VT6105M		= 0x90,	/* Management adapter */
+};
+
+enum rhine_quirks {
+	rqWOL		= 0x0001,	/* Wake-On-LAN support */
+	rqForceReset	= 0x0002,
+	rq6patterns	= 0x0040,	/* 6 instead of 4 patterns for WOL */
+	rqStatusWBRace	= 0x0080,	/* Tx Status Writeback Error possible */
+	rqRhineI	= 0x0100,	/* See comment below */
+};
+/*
+ * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
+ * MMIO as well as for the collision counter and the Tx FIFO underflow
+ * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
+ */
+
+/* Beware of PCI posted writes */
+#define IOSYNC	do { ioread8(ioaddr + StationAddr); } while (0)
+
+static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
+	{ 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, },	/* VT86C100A */
+	{ 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6102 */
+	{ 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, },	/* 6105{,L,LOM} */
+	{ 0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6105M */
+	{ }	/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
+
+
+/* Offsets to the device registers. */
+enum register_offsets {
+	StationAddr = 0x00, RxConfig = 0x06, TxConfig = 0x07, ChipCmd = 0x08,
+	ChipCmd1 = 0x09, TQWake = 0x0A,
+	IntrStatus = 0x0C, IntrEnable = 0x0E,
+	MulticastFilter0 = 0x10, MulticastFilter1 = 0x14,
+	RxRingPtr = 0x18, TxRingPtr = 0x1C, GFIFOTest = 0x54,
+	MIIPhyAddr = 0x6C, MIIStatus = 0x6D, PCIBusConfig = 0x6E, PCIBusConfig1 = 0x6F,
+	MIICmd = 0x70, MIIRegAddr = 0x71, MIIData = 0x72, MACRegEEcsr = 0x74,
+	ConfigA = 0x78, ConfigB = 0x79, ConfigC = 0x7A, ConfigD = 0x7B,
+	RxMissed = 0x7C, RxCRCErrs = 0x7E, MiscCmd = 0x81,
+	StickyHW = 0x83, IntrStatus2 = 0x84,
+	CamMask = 0x88, CamCon = 0x92, CamAddr = 0x93,
+	WOLcrSet = 0xA0, PwcfgSet = 0xA1, WOLcgSet = 0xA3, WOLcrClr = 0xA4,
+	WOLcrClr1 = 0xA6, WOLcgClr = 0xA7,
+	PwrcsrSet = 0xA8, PwrcsrSet1 = 0xA9, PwrcsrClr = 0xAC, PwrcsrClr1 = 0xAD,
+};
+
+/* Bits in ConfigD */
+enum backoff_bits {
+	BackOptional = 0x01, BackModify = 0x02,
+	BackCaptureEffect = 0x04, BackRandom = 0x08
+};
+
+/* Bits in the TxConfig (TCR) register */
+enum tcr_bits {
+	TCR_PQEN = 0x01,
+	TCR_LB0 = 0x02,		/* loopback[0] */
+	TCR_LB1 = 0x04,		/* loopback[1] */
+	TCR_OFSET = 0x08,
+	TCR_RTGOPT = 0x10,
+	TCR_RTFT0 = 0x20,
+	TCR_RTFT1 = 0x40,
+	TCR_RTSF = 0x80,
+};
+
+/* Bits in the CamCon (CAMC) register */
+enum camcon_bits {
+	CAMC_CAMEN = 0x01,
+	CAMC_VCAMSL = 0x02,
+	CAMC_CAMWR = 0x04,
+	CAMC_CAMRD = 0x08,
+};
+
+/* Bits in the PCIBusConfig1 (BCR1) register */
+enum bcr1_bits {
+	BCR1_POT0 = 0x01,
+	BCR1_POT1 = 0x02,
+	BCR1_POT2 = 0x04,
+	BCR1_CTFT0 = 0x08,
+	BCR1_CTFT1 = 0x10,
+	BCR1_CTSF = 0x20,
+	BCR1_TXQNOBK = 0x40,	/* for VT6105 */
+	BCR1_VIDFR = 0x80,	/* for VT6105 */
+	BCR1_MED0 = 0x40,		/* for VT6102 */
+	BCR1_MED1 = 0x80,		/* for VT6102 */
+};
+
+#ifdef USE_MMIO
+/* Registers we check that mmio and reg are the same. */
+static const int mmio_verify_registers[] = {
+	RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
+	0
+};
+#endif
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {
+	IntrRxDone	= 0x0001,
+	IntrTxDone	= 0x0002,
+	IntrRxErr	= 0x0004,
+	IntrTxError	= 0x0008,
+	IntrRxEmpty	= 0x0020,
+	IntrPCIErr	= 0x0040,
+	IntrStatsMax	= 0x0080,
+	IntrRxEarly	= 0x0100,
+	IntrTxUnderrun	= 0x0210,
+	IntrRxOverflow	= 0x0400,
+	IntrRxDropped	= 0x0800,
+	IntrRxNoBuf	= 0x1000,
+	IntrTxAborted	= 0x2000,
+	IntrLinkChange	= 0x4000,
+	IntrRxWakeUp	= 0x8000,
+	IntrTxDescRace		= 0x080000,	/* mapped from IntrStatus2 */
+	IntrNormalSummary	= IntrRxDone | IntrTxDone,
+	IntrTxErrSummary	= IntrTxDescRace | IntrTxAborted | IntrTxError |
+				  IntrTxUnderrun,
+};
+
+/* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */
+enum wol_bits {
+	WOLucast	= 0x10,
+	WOLmagic	= 0x20,
+	WOLbmcast	= 0x30,
+	WOLlnkon	= 0x40,
+	WOLlnkoff	= 0x80,
+};
+
+/* The Rx and Tx buffer descriptors. */
+struct rx_desc {
+	__le32 rx_status;
+	__le32 desc_length; /* Chain flag, Buffer/frame length */
+	__le32 addr;
+	__le32 next_desc;
+};
+struct tx_desc {
+	__le32 tx_status;
+	__le32 desc_length; /* Chain flag, Tx Config, Frame length */
+	__le32 addr;
+	__le32 next_desc;
+};
+
+/* Initial value for tx_desc.desc_length, Buffer size goes to bits 0-10 */
+#define TXDESC		0x00e08000
+
+enum rx_status_bits {
+	RxOK = 0x8000, RxWholePkt = 0x0300, RxErr = 0x008F
+};
+
+/* Bits in *_desc.*_status */
+enum desc_status_bits {
+	DescOwn = 0x80000000
+};
+
+/* Bits in *_desc.*_length */
+enum desc_length_bits {
+	DescTag = 0x00010000
+};
+
+/* Bits in ChipCmd. */
+enum chip_cmd_bits {
+	CmdInit = 0x01, CmdStart = 0x02, CmdStop = 0x04, CmdRxOn = 0x08,
+	CmdTxOn = 0x10, Cmd1TxDemand = 0x20, CmdRxDemand = 0x40,
+	Cmd1EarlyRx = 0x01, Cmd1EarlyTx = 0x02, Cmd1FDuplex = 0x04,
+	Cmd1NoTxPoll = 0x08, Cmd1Reset = 0x80,
+};
+
+struct rhine_private {
+	/* Bit mask for configured VLAN ids */
+	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+
+	/* Descriptor rings */
+	struct rx_desc *rx_ring;
+	struct tx_desc *tx_ring;
+	dma_addr_t rx_ring_dma;
+	dma_addr_t tx_ring_dma;
+
+	/* The addresses of receive-in-place skbuffs. */
+	struct sk_buff *rx_skbuff[RX_RING_SIZE];
+	dma_addr_t rx_skbuff_dma[RX_RING_SIZE];
+
+	/* The saved address of a sent-in-place packet/buffer, for later free(). */
+	struct sk_buff *tx_skbuff[TX_RING_SIZE];
+	dma_addr_t tx_skbuff_dma[TX_RING_SIZE];
+
+	/* Tx bounce buffers (Rhine-I only) */
+	unsigned char *tx_buf[TX_RING_SIZE];
+	unsigned char *tx_bufs;
+	dma_addr_t tx_bufs_dma;
+
+	struct pci_dev *pdev;
+	long pioaddr;
+	struct net_device *dev;
+	struct napi_struct napi;
+	spinlock_t lock;
+	struct mutex task_lock;
+	bool task_enable;
+	struct work_struct slow_event_task;
+	struct work_struct reset_task;
+
+	u32 msg_enable;
+
+	/* Frequently used values: keep some adjacent for cache effect. */
+	u32 quirks;
+	struct rx_desc *rx_head_desc;
+	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
+	unsigned int cur_tx, dirty_tx;
+	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
+	u8 wolopts;
+
+	u8 tx_thresh, rx_thresh;
+
+	struct mii_if_info mii_if;
+	void __iomem *base;
+};
+
+static struct dmi_system_id __initdata rhine_dmi_table[] = {
+	{
+		.ident = "EPIA-M",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+		},
+	},
+	{
+		.ident = "KV7",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+		},
+	},
+	{ NULL }
+};
+
+#define BYTE_REG_BITS_ON(x, p)      do { iowrite8((ioread8((p))|(x)), (p)); } while (0)
+#define WORD_REG_BITS_ON(x, p)      do { iowrite16((ioread16((p))|(x)), (p)); } while (0)
+#define DWORD_REG_BITS_ON(x, p)     do { iowrite32((ioread32((p))|(x)), (p)); } while (0)
+
+#define BYTE_REG_BITS_IS_ON(x, p)   (ioread8((p)) & (x))
+#define WORD_REG_BITS_IS_ON(x, p)   (ioread16((p)) & (x))
+#define DWORD_REG_BITS_IS_ON(x, p)  (ioread32((p)) & (x))
+
+#define BYTE_REG_BITS_OFF(x, p)     do { iowrite8(ioread8((p)) & (~(x)), (p)); } while (0)
+#define WORD_REG_BITS_OFF(x, p)     do { iowrite16(ioread16((p)) & (~(x)), (p)); } while (0)
+#define DWORD_REG_BITS_OFF(x, p)    do { iowrite32(ioread32((p)) & (~(x)), (p)); } while (0)
+
+#define BYTE_REG_BITS_SET(x, m, p)   do { iowrite8((ioread8((p)) & (~(m)))|(x), (p)); } while (0)
+#define WORD_REG_BITS_SET(x, m, p)   do { iowrite16((ioread16((p)) & (~(m)))|(x), (p)); } while (0)
+#define DWORD_REG_BITS_SET(x, m, p)  do { iowrite32((ioread32((p)) & (~(m)))|(x), (p)); } while (0)
+
+#define RHINE_WAIT_FOR(condition)				\
+do {								\
+	int i = 1024;						\
+	while (!(condition) && --i)				\
+		;						\
+	if (debug > 1 && i < 512)				\
+		pr_info("%4d cycles used @ %s:%d\n",		\
+			1024 - i, __func__, __LINE__);		\
+} while (0)
+
+#define RHINE_EVENT_NAPI_RX	(IntrRxDone | \
+				 IntrRxErr | \
+				 IntrRxEmpty | \
+				 IntrRxOverflow	| \
+				 IntrRxDropped | \
+				 IntrRxNoBuf | \
+				 IntrRxWakeUp)
+
+#define RHINE_EVENT_NAPI_TX_ERR	(IntrTxError | \
+				 IntrTxAborted | \
+				 IntrTxUnderrun | \
+				 IntrTxDescRace)
+#define RHINE_EVENT_NAPI_TX	(IntrTxDone | RHINE_EVENT_NAPI_TX_ERR)
+
+#define RHINE_EVENT_NAPI	(RHINE_EVENT_NAPI_RX | \
+				 RHINE_EVENT_NAPI_TX | \
+				 IntrStatsMax)
+#define RHINE_EVENT_SLOW	(IntrPCIErr | IntrLinkChange)
+#define RHINE_EVENT		(RHINE_EVENT_NAPI | RHINE_EVENT_SLOW)
+
+static const struct ethtool_ops netdev_ethtool_ops;
+
+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev,
+					int phy_id, int location, int value);
+static int rhine_open(struct net_device *dev);
+static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp);
+static int __devinit rhine_init_one(struct pci_dev *pdev,
+				    const struct pci_device_id *ent);
+static void __devexit rhine_remove_one(struct pci_dev *pdev);
+static void rhine_reset_task(struct work_struct *work);
+static void rhine_slow_event_task(struct work_struct *work);
+static void rhine_tx_timeout(struct net_device *dev);
+static netdev_tx_t rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
+static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
+static void rhine_tx(struct net_device *dev);
+static int rhine_rx(struct net_device *dev, int limit);
+static void rhine_set_rx_mode(struct net_device *dev);
+static struct net_device_stats *rhine_get_stats(struct net_device *dev);
+static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int netdev_nway_reset(struct net_device *dev);
+static u32 netdev_get_link(struct net_device *dev);
+static u32 netdev_get_msglevel(struct net_device *dev);
+static void netdev_set_msglevel(struct net_device *dev, u32 value);
+static void rhine_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+static int rhine_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void rhine_task_enable(struct rhine_private *rp);
+static int rhine_close(struct net_device *dev);
+static void rhine_shutdown(struct pci_dev *pdev);
+static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
+static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
+static void rhine_restart_tx(struct net_device *dev);
+static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size);
+
+static const struct net_device_ops rhine_netdev_ops = {
+	.ndo_open		 = rhine_open,
+	.ndo_stop		 = rhine_close,
+	.ndo_start_xmit		 = rhine_start_tx,
+	.ndo_get_stats		 = rhine_get_stats,
+	.ndo_set_rx_mode	 = rhine_set_rx_mode,
+	.ndo_change_mtu		 = eth_change_mtu,
+	.ndo_validate_addr	 = eth_validate_addr,
+	.ndo_set_mac_address	 = eth_mac_addr,
+	.ndo_do_ioctl		 = netdev_ioctl,
+	.ndo_tx_timeout		 = rhine_tx_timeout,
+	.ndo_vlan_rx_add_vid	 = rhine_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	 = rhine_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	 = rhine_poll,
+#endif
+};
+
+static const struct ethtool_ops netdev_ethtool_ops = {
+	.get_drvinfo		= netdev_get_drvinfo,
+	.get_settings		= netdev_get_settings,
+	.set_settings		= netdev_set_settings,
+	.nway_reset		= netdev_nway_reset,
+	.get_link		= netdev_get_link,
+	.get_msglevel		= netdev_get_msglevel,
+	.set_msglevel		= netdev_set_msglevel,
+	.get_wol		= rhine_get_wol,
+	.set_wol		= rhine_set_wol,
+};
+
+static struct pci_driver rhine_driver = {
+	.name		= DRV_NAME,
+	.id_table	= rhine_pci_tbl,
+	.probe		= rhine_init_one,
+	.remove		= __devexit_p(rhine_remove_one),
+#ifdef CONFIG_PM
+	.suspend	= rhine_suspend,
+	.resume		= rhine_resume,
+#endif /* CONFIG_PM */
+	.shutdown =	rhine_shutdown,
+};
-- 
1.7.8.1

^ permalink raw reply related

* Re: [PATCH 1/1] via-rhine: Fix hanging with high CPU load on low-end broads.
From: Bjarke Istrup Pedersen @ 2012-01-01 21:15 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <20111231121710.GB9842@electric-eye.fr.zoreil.com>

2011/12/31 Francois Romieu <romieu@fr.zoreil.com>:
> Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> [...]
>> Also tried connect a machine to one of the ports, and copying a large
>> file across (something that before could make it lock up within 15
>> secords) - also worked without any problems - CPU usage around 15%
>> (mostly "top" using that), so thats not bad at all.
>>
>> Is there any other testcases that I should try out?
>
> Same thing + random ethtool link management commands.
> Same thing + random cable unplug/plug.
> Same thing + pktgen facing the lan interface.
>
> Everything at the same time.

Btw. - I have split up the via-rhine.c file (with all the changes you
have sent me) into via-rhine.c and via-rhine.h , like it should be :-)
I'll send it shortly after this mail - could you incorporate it into your work?

/Bjarke

> --
> Ueimor
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: [PATCH 1/1] via-rhine: Split driver into .c and .h files.
From: Francois Romieu @ 2012-01-01 22:49 UTC (permalink / raw)
  To: Bjarke Istrup Pedersen
  Cc: David Miller, shemminger, bhutchings, linux-kernel, netdev, rl
In-Reply-To: <1325452525-23476-1-git-send-email-gurligebis@gentoo.org>

Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> Split the driver into via-rhine.c and via-rhine.h like it should be.
> There is also a bit of cleanup of checkpatch warnings, other than that,
> there is no changes to how the code works, it is plain refactoring.

Please don't do that. The .h won't be used elsewhere. It's useless
(and register definitions stay barely readable).

Roger, any comment regarding patches #1 .. #3 ?

rhine_task_{enable / disable} should be balanced in open / close and
suspend / resume, ok.

-- 
Ueimor

^ permalink raw reply

* Re: [PATCH] fix for nfacct infrastructure in net-next
From: David Miller @ 2012-01-01 23:02 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev
In-Reply-To: <20120101162358.GA21795@1984>

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sun, 1 Jan 2012 17:23:58 +0100

> On Sun, Jan 01, 2012 at 05:22:24PM +0100, pablo@netfilter.org wrote:
>> From: Pablo Neira Ayuso <pablo@netfilter.org>
>> 
>> Hi Dave,
>> 
>> Please, pull the following fix for the nfacct infrastructure already
>> in your net-next tree.
>> 
>> You can pull it from:
>> 
>> git://1984.lsi.us.es/net-net nf-next
>                        ^^^^^^^
> I meant to say net-next, of course.

I'm not pulling this.

If I pull from your "corrected" URL, "git://1984.lsi.us.es/net-next nf-next"
it starts to download 17937 objects.  Which means it's going to bring in all
of your -next work as well as my net-next tree upon which it is based, not
just this one bug fix.

These mistakes should never happen in the first place.

If you actually use "git request-pull" to generate the pull request
email body, you can NEVER get the URL wrong, GIT enforces it to be
correct and it enforces that the changes in your local tree are
present at the remote URL as well.

You can't make these kinds of errors and oversights when you want to
ask me to pull in bug fixes at the very last minute when Linus is
about to make a final release.

Just toss these fixes, if they are so important submit them to Greg KH
and the -stable branch after 3.2.0-final goes out.

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2012-01-01 23:42 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) mlx4 driver stops working after a ring size change due to forgotten
   clear of the queue vector value, fix from Yevgeny Petrilin.

2) RX multicast filter in skge is not restored after resume, breaking
   ipv6 amongst other things, fix from Florian Zumbiehl.

3) Fix sync message handling in IPVS, from Julian Anastasov.

4) ctnetlink timeout sanity checks never work due to signedness,
   fix from Xi Wang.

Please pull, thanks a lot!

The following changes since commit c7f46b7aa4ae5cbef32eb5e016512a14f936affa:

  Merge branch 'fix/asoc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound (2011-12-31 11:55:06 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master

Florian Zumbiehl (1):
      skge: restore rx multicast filter on resume and after config changes

Julian Anastasov (1):
      ipvs: try also real server with port 0 in backup server

Xi Wang (1):
      netfilter: ctnetlink: fix timeout calculation

Yevgeny Petrilin (1):
      mlx4_en: nullify cq->vector field when closing completion queue

 drivers/net/ethernet/marvell/skge.c        |    3 +++
 drivers/net/ethernet/mellanox/mlx4/en_cq.c |    1 +
 include/net/ip_vs.h                        |    2 +-
 net/netfilter/ipvs/ip_vs_conn.c            |    2 +-
 net/netfilter/ipvs/ip_vs_ctl.c             |   10 ++++++++--
 net/netfilter/ipvs/ip_vs_sync.c            |    2 +-
 net/netfilter/nf_conntrack_netlink.c       |    4 ++--
 7 files changed, 17 insertions(+), 7 deletions(-)

^ permalink raw reply

* Re: [PATCH] fix for nfacct infrastructure in net-next
From: Pablo Neira Ayuso @ 2012-01-02  1:04 UTC (permalink / raw)
  To: David Miller; +Cc: netfilter-devel, netdev
In-Reply-To: <20120101.180229.1338519415596129407.davem@davemloft.net>

Hi Dave,

On Sun, Jan 01, 2012 at 06:02:29PM -0500, David Miller wrote:
> I'm not pulling this.
> 
> If I pull from your "corrected" URL, "git://1984.lsi.us.es/net-next nf-next"
> it starts to download 17937 objects.  Which means it's going to bring in all
> of your -next work as well as my net-next tree upon which it is based, not
> just this one bug fix.
>
> These mistakes should never happen in the first place.
> 
> If you actually use "git request-pull" to generate the pull request
> email body, you can NEVER get the URL wrong, GIT enforces it to be
> correct and it enforces that the changes in your local tree are
> present at the remote URL as well.

You caught me here, I wasn't using git request-pull. I'll do next time,
sorry.

> You can't make these kinds of errors and oversights when you want to
> ask me to pull in bug fixes at the very last minute when Linus is
> about to make a final release.

I think there's a misunderstanding.

This is not intended for current 3.2-rc7. This is a fix for something
that is in your net-next tree (upcoming 3.3).

I can wait and resubmit this later, we have the entire 3.3-rc cycle to
get it fixed. Sorry for rushing you.

> Just toss these fixes, if they are so important submit them to Greg KH
> and the -stable branch after 3.2.0-final goes out.

^ permalink raw reply

* Re: reproducible kernel freeze using r8169 in Linux 3.0
From: Matt Ginzton @ 2012-01-02  2:03 UTC (permalink / raw)
  To: Francois Romieu; +Cc: nic_swsd, netdev
In-Reply-To: <20111218083212.GA28286@electric-eye.fr.zoreil.com>

On Dec 18, 2011, at 12:32 AM, Francois Romieu wrote:

> Matt Ginzton <matt@ginzton.net> :
> [...]
>> Please let me know if I'm reporting this to the right place, or if there's
>> any other helpful info I can provide.
> 
> Please grep for a XID line in dmesg and send it so we can figure the
> specific revision of your chipset (lspci can not figure it).
> 
> If it says something like "blah blah XID 1c4...", you should give current
> -rc a try (who shouldn't ?).

Just to follow up on this old thread:

- my XID line says 1c4000c0
- I tried 3.2-rc7 kernel, and couldn't reproduce any problems at all -- not the complete system freeze from 3.0 kernels, nor the slow_path kernel warning and backtrace from 3.1 kernels. A big improvement indeed -- thank you.

I do note that TX performance as measured by pktgen is lower than r8168 -- with r8169 in 3.2-rc7 I see something like 455MB/sec and with r8168, IIRC, the number was closer to 800MB/sec. This may be a very artificial statistic, and isn't something I happen to care about and I'm certainly not going to use r8168 because of it, but it may be worth looking into?

cheers,

Matt

^ permalink raw reply

* [PATCH net-next] xfrm: Call IP receive handler directly for inbound tunnel-mode packets
From: David Ward @ 2012-01-02  3:32 UTC (permalink / raw)
  To: netdev; +Cc: David Ward, Herbert Xu

For IPsec tunnel mode (or BEET mode), after inbound packets are xfrm'ed,
call the IPv4/IPv6 receive handler directly instead of calling netif_rx.
In addition to avoiding unneeded re-processing of the MAC layer, packets
will not be received a second time on network taps. (Note that outbound
packets are only received on network taps post-xfrm, but inbound packets
were being received both pre- and post-xfrm. So now network taps will
receive packets in either direction only once, in the form that they go
"over the wire".)

Signed-off-by: David Ward <david.ward@ll.mit.edu>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
---
 include/net/xfrm.h     |    3 +++
 net/ipv4/xfrm4_input.c |    5 +++++
 net/ipv4/xfrm4_state.c |    1 +
 net/ipv6/xfrm6_input.c |    5 +++++
 net/ipv6/xfrm6_state.c |    1 +
 net/xfrm/xfrm_input.c  |    4 +++-
 6 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index b203e14..423a779 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -329,6 +329,7 @@ struct xfrm_state_afinfo {
 						 struct sk_buff *skb);
 	int			(*extract_output)(struct xfrm_state *x,
 						  struct sk_buff *skb);
+	int			(*tunnel_finish)(struct sk_buff *skb);
 	int			(*transport_finish)(struct sk_buff *skb,
 						    int async);
 };
@@ -1453,6 +1454,7 @@ extern int xfrm4_extract_header(struct sk_buff *skb);
 extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 			   int encap_type);
+extern int xfrm4_tunnel_finish(struct sk_buff *skb);
 extern int xfrm4_transport_finish(struct sk_buff *skb, int async);
 extern int xfrm4_rcv(struct sk_buff *skb);
 
@@ -1470,6 +1472,7 @@ extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short f
 extern int xfrm6_extract_header(struct sk_buff *skb);
 extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+extern int xfrm6_tunnel_finish(struct sk_buff *skb);
 extern int xfrm6_transport_finish(struct sk_buff *skb, int async);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 06814b6..4903a01 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -46,6 +46,11 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 }
 EXPORT_SYMBOL(xfrm4_rcv_encap);
 
+int xfrm4_tunnel_finish(struct sk_buff *skb)
+{
+	return ip_rcv(skb, skb->dev, NULL, skb->dev);
+}
+
 int xfrm4_transport_finish(struct sk_buff *skb, int async)
 {
 	struct iphdr *iph = ip_hdr(skb);
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 9258e75..1931c42 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -82,6 +82,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.output_finish		= xfrm4_output_finish,
 	.extract_input		= xfrm4_extract_input,
 	.extract_output		= xfrm4_extract_output,
+	.tunnel_finish		= xfrm4_tunnel_finish,
 	.transport_finish	= xfrm4_transport_finish,
 };
 
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index f8c3cf8..dc898a8 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -29,6 +29,11 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 }
 EXPORT_SYMBOL(xfrm6_rcv_spi);
 
+int xfrm6_tunnel_finish(struct sk_buff *skb)
+{
+	return ipv6_rcv(skb, skb->dev, NULL, skb->dev);
+}
+
 int xfrm6_transport_finish(struct sk_buff *skb, int async)
 {
 	skb_network_header(skb)[IP6CB(skb)->nhoff] =
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index f2d72b8..51d31c3 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -182,6 +182,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.output_finish		= xfrm6_output_finish,
 	.extract_input		= xfrm6_extract_input,
 	.extract_output		= xfrm6_extract_output,
+	.tunnel_finish		= xfrm6_tunnel_finish,
 	.transport_finish	= xfrm6_transport_finish,
 };
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 54a0dc2..571af71 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -262,7 +262,9 @@ resume:
 
 	if (decaps) {
 		skb_dst_drop(skb);
-		netif_rx(skb);
+		skb_reset_network_header(skb);
+		skb_reset_transport_header(skb);
+		x->inner_mode->afinfo->tunnel_finish(skb);
 		return 0;
 	} else {
 		return x->inner_mode->afinfo->transport_finish(skb, async);
-- 
1.7.4.1

^ permalink raw reply related

* Re: BQL + Basic Latency under load results - 100Mbit, GSO/TSO off, pfifo_fast vs SFQ vs QFQ
From: Eric Dumazet @ 2012-01-02  4:33 UTC (permalink / raw)
  To: Dave Taht
  Cc: jg, Stephen Hemminger, Juliusz Chroboczek, Kathleen Nichols,
	netdev
In-Reply-To: <CAA93jw7bLnHtVnZGN5wVPQZc46XT_B--cY1ocUbnm1AS=J_YHw@mail.gmail.com>

Le lundi 02 janvier 2012 à 00:17 +0100, Dave Taht a écrit :
> QFQ wins even bigger vs SFQ at 50 iperfs
> 
> http://www.teklibre.com/~d/bloat/pfifo_sfq_vs_qfq_linear50.png
> 
> And I think it's going to win even bigger at 10 Mbit.
> 

Happy new year !

This makes no sense to me for such a low amount of flows, SFQ should
perform the same than QFQ :)

You dont find out why it is so.



Please try following patch :

[PATCH net-next] sch_sfq: dont put new flow at the end of flows

SFQ enqueue algo puts a new flow _behind_ all pre-existing flows in the
circular list. In fact this is probably an old SFQ implementation bug.

100 Mbits = ~8333 full frames per second, or ~8 frames per ms.

With 50 flows, it means your "new flow" will have to wait 50 packets
being sent before its own packet. Thats the ~6ms.

We certainly can change SFQ to give a priority advantage to new flows,
so that next dequeued packet is taken from a new flow, not an old one.

Reported-by: Dave Taht <dave.taht@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index c23b957..f7f62a5 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -366,11 +366,11 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	if (slot->qlen == 1) {		/* The flow is new */
 		if (q->tail == NULL) {	/* It is the first flow */
 			slot->next = x;
+			q->tail = slot;
 		} else {
 			slot->next = q->tail->next;
 			q->tail->next = x;
 		}
-		q->tail = slot;
 		slot->allot = q->scaled_quantum;
 	}
 	if (++sch->q.qlen <= q->limit)

^ permalink raw reply related

* Re: [PATCH] fix for nfacct infrastructure in net-next
From: David Miller @ 2012-01-02  4:42 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev
In-Reply-To: <20120102010415.GA23310@1984>

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 2 Jan 2012 02:04:15 +0100

> This is not intended for current 3.2-rc7. This is a fix for something
> that is in your net-next tree (upcoming 3.3).

I think this is the communication problem we had, I thought this
was a netfilter bug fix that was already in net-next that you wanted
me to include in net.

Now that I understand the situation I've pulled the fix into net-next,
thanks.

^ permalink raw reply

* Re: BQL + Basic Latency under load results - 100Mbit, GSO/TSO off, pfifo_fast vs SFQ vs QFQ
From: Eric Dumazet @ 2012-01-02  4:55 UTC (permalink / raw)
  To: Dave Taht
  Cc: jg, Stephen Hemminger, Juliusz Chroboczek, Kathleen Nichols,
	netdev
In-Reply-To: <1325478811.2526.10.camel@edumazet-laptop>

Le lundi 02 janvier 2012 à 05:33 +0100, Eric Dumazet a écrit :
> Le lundi 02 janvier 2012 à 00:17 +0100, Dave Taht a écrit :
> > QFQ wins even bigger vs SFQ at 50 iperfs
> > 
> > http://www.teklibre.com/~d/bloat/pfifo_sfq_vs_qfq_linear50.png
> > 
> > And I think it's going to win even bigger at 10 Mbit.
> > 
> 
> Happy new year !
> 
> This makes no sense to me for such a low amount of flows, SFQ should
> perform the same than QFQ :)
> 
> You dont find out why it is so.
> 
> 
> 
> Please try following patch :
> 
> [PATCH net-next] sch_sfq: dont put new flow at the end of flows
> 
> SFQ enqueue algo puts a new flow _behind_ all pre-existing flows in the
> circular list. In fact this is probably an old SFQ implementation bug.
> 
> 100 Mbits = ~8333 full frames per second, or ~8 frames per ms.
> 
> With 50 flows, it means your "new flow" will have to wait 50 packets
> being sent before its own packet. Thats the ~6ms.
> 
> We certainly can change SFQ to give a priority advantage to new flows,
> so that next dequeued packet is taken from a new flow, not an old one.
> 
> Reported-by: Dave Taht <dave.taht@gmail.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
> diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
> index c23b957..f7f62a5 100644
> --- a/net/sched/sch_sfq.c
> +++ b/net/sched/sch_sfq.c
> @@ -366,11 +366,11 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
>  	if (slot->qlen == 1) {		/* The flow is new */
>  		if (q->tail == NULL) {	/* It is the first flow */
>  			slot->next = x;
> +			q->tail = slot;
>  		} else {
>  			slot->next = q->tail->next;
>  			q->tail->next = x;
>  		}
> -		q->tail = slot;
>  		slot->allot = q->scaled_quantum;
>  	}
>  	if (++sch->q.qlen <= q->limit)
> 

I tested this patch with a 50 concurrent netperf workload, and indeed
this fixes the problem for me.

# ping 192.168.20.108
PING 192.168.20.108 (192.168.20.108) 56(84) bytes of data.
64 bytes from 192.168.20.108: icmp_req=1 ttl=64 time=0.021 ms
64 bytes from 192.168.20.108: icmp_req=2 ttl=64 time=0.011 ms
64 bytes from 192.168.20.108: icmp_req=3 ttl=64 time=0.011 ms
64 bytes from 192.168.20.108: icmp_req=4 ttl=64 time=0.010 ms
64 bytes from 192.168.20.108: icmp_req=5 ttl=64 time=0.010 ms
64 bytes from 192.168.20.108: icmp_req=6 ttl=64 time=0.010 ms


# tc -s -d qdisc show dev eth3
qdisc htb 1: root refcnt 18 r2q 10 default 1 direct_packets_stat 0 ver 3.17
 Sent 1178661043 bytes 806848 pkt (dropped 9068, overlimits 382834 requeues 3) 
 rate 97748Kbit 8355pps backlog 0b 122p requeues 3 
qdisc sfq 10: parent 1:1 limit 127p quantum 1514b flows 127/1024 divisor 1024 
 Sent 1178661043 bytes 806848 pkt (dropped 17568, overlimits 0 requeues 0) 
 rate 97748Kbit 8355pps backlog 962708b 122p requeues 0 


# tc -s -d cl show dev eth3
class htb 1:1 root leaf 10: prio 0 quantum 80000 rate 100000Kbit ceil 100000Kbit 
burst 40000b/256 mpu 0b overhead 0b cburst 40000b/256 mpu 0b overhead 0b level 0 
 Sent 1367302331 bytes 935622 pkt (dropped 10494, overlimits 0 requeues 0) 
 rate 100156Kbit 8560pps backlog 0b 125p requeues 0 
 lended: 207922 borrowed: 0 giants: 0
 tokens: -14605 ctokens: -14605

class sfq 10:15 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 14678b 3p requeues 0 
 allot -3264 

class sfq 10:17 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 20Kb 3p requeues 0 
 allot -6912 

class sfq 10:22 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 17508b 2p requeues 0 
 allot -808 

class sfq 10:3c parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 17508b 2p requeues 0 
 allot -4208 

class sfq 10:5e parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 27Kb 2p requeues 0 
 allot -6024 

class sfq 10:66 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 11716b 2p requeues 0 
 allot -4856 

class sfq 10:8d parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 14612b 2p requeues 0 
 allot 1296 

class sfq 10:9b parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 7504b 4p requeues 0 
 allot 1184 

class sfq 10:9c parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 14612b 2p requeues 0 
 allot -104 

class sfq 10:a9 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 18956b 2p requeues 0 
 allot -5456 

class sfq 10:ab parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 14678b 3p requeues 0 
 allot -88 

class sfq 10:ba parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 4542b 3p requeues 0 
 allot -624 

class sfq 10:c3 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 27710b 3p requeues 0 
 allot -8440 

class sfq 10:ce parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 18956b 2p requeues 0 
 allot -3160 

class sfq 10:f2 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 20Kb 3p requeues 0 
 allot -672 

class sfq 10:11c parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 5990b 3p requeues 0 
 allot -712 

class sfq 10:17c parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 17508b 2p requeues 0 
 allot -4000 

class sfq 10:188 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 16060b 2p requeues 0 
 allot -6640 

class sfq 10:1b9 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 10202b 1p requeues 0 
 allot 120 

class sfq 10:1c2 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 5924b 2p requeues 0 
 allot 264 

class sfq 10:1cb parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 19022b 3p requeues 0 
 allot -2904 

class sfq 10:1e5 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 23366b 3p requeues 0 
 allot -7800 

class sfq 10:1f9 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 8984b 4p requeues 0 
 allot 560 

class sfq 10:210 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 17574b 3p requeues 0 
 allot -384 

class sfq 10:231 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 19022b 3p requeues 0 
 allot 1416 

class sfq 10:27c parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 20404b 2p requeues 0 
 allot 752 

class sfq 10:289 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 19022b 3p requeues 0 
 allot 1208 

class sfq 10:2a3 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 14612b 2p requeues 0 
 allot -2592 

class sfq 10:2a6 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 19022b 3p requeues 0 
 allot -5008 

class sfq 10:2c7 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 7570b 5p requeues 0 
 allot -1168 

class sfq 10:2d0 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 8820b 2p requeues 0 
 allot -1088 

class sfq 10:2e5 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 20404b 2p requeues 0 
 allot -10648 

class sfq 10:2ec parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 13164b 2p requeues 0 
 allot -1800 

class sfq 10:2ee parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 20Kb 3p requeues 0 
 allot -9016 

class sfq 10:305 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 10400b 4p requeues 0 
 allot -872 

class sfq 10:318 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 4542b 3p requeues 0 
 allot 504 

class sfq 10:31f parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 10400b 4p requeues 0 
 allot -4024 

class sfq 10:328 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 16060b 2p requeues 0 
 allot -16 

class sfq 10:32d parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 21918b 3p requeues 0 
 allot -840 

class sfq 10:37d parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 14612b 2p requeues 0 
 allot 432 

class sfq 10:3ac parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 4542b 3p requeues 0 
 allot 1224 

class sfq 10:3d0 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 20Kb 3p requeues 0 
 allot -11232 

class sfq 10:3d1 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 26262b 3p requeues 0 
 allot -1832 

class sfq 10:3d8 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 5924b 2p requeues 0 
 allot -512 

class sfq 10:3e7 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 29158b 3p requeues 0 
 allot -10976 

class sfq 10:3f0 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 32054b 3p requeues 0 
 allot -2080 

class sfq 10:3f9 parent 10: 
 (dropped 0, overlimits 0 requeues 0) 
 backlog 18956b 2p requeues 0 
 allot -1704 

^ permalink raw reply

* Re: BQL + Basic Latency under load results - 100Mbit, GSO/TSO off, pfifo_fast vs SFQ vs QFQ
From: Eric Dumazet @ 2012-01-02  5:07 UTC (permalink / raw)
  To: Dave Taht
  Cc: jg, Stephen Hemminger, Juliusz Chroboczek, Kathleen Nichols,
	netdev
In-Reply-To: <1325480125.2526.13.camel@edumazet-laptop>

Le lundi 02 janvier 2012 à 05:55 +0100, Eric Dumazet a écrit :

> I tested this patch with a 50 concurrent netperf workload, and indeed
> this fixes the problem for me.
> 
> # ping 192.168.20.108
> PING 192.168.20.108 (192.168.20.108) 56(84) bytes of data.
> 64 bytes from 192.168.20.108: icmp_req=1 ttl=64 time=0.021 ms
> 64 bytes from 192.168.20.108: icmp_req=2 ttl=64 time=0.011 ms
> 64 bytes from 192.168.20.108: icmp_req=3 ttl=64 time=0.011 ms
> 64 bytes from 192.168.20.108: icmp_req=4 ttl=64 time=0.010 ms
> 64 bytes from 192.168.20.108: icmp_req=5 ttl=64 time=0.010 ms
> 64 bytes from 192.168.20.108: icmp_req=6 ttl=64 time=0.010 ms
> 

Oops, pinging a real machine, not myself I get more realistic numbers :)

# ping -c 20 192.168.20.112
PING 192.168.20.112 (192.168.20.112) 56(84) bytes of data.
64 bytes from 192.168.20.112: icmp_req=1 ttl=64 time=0.488 ms
64 bytes from 192.168.20.112: icmp_req=2 ttl=64 time=0.214 ms
64 bytes from 192.168.20.112: icmp_req=3 ttl=64 time=0.696 ms
64 bytes from 192.168.20.112: icmp_req=4 ttl=64 time=0.135 ms
64 bytes from 192.168.20.112: icmp_req=5 ttl=64 time=0.110 ms
64 bytes from 192.168.20.112: icmp_req=6 ttl=64 time=0.401 ms
64 bytes from 192.168.20.112: icmp_req=7 ttl=64 time=0.378 ms
64 bytes from 192.168.20.112: icmp_req=8 ttl=64 time=0.384 ms
64 bytes from 192.168.20.112: icmp_req=9 ttl=64 time=1.03 ms
64 bytes from 192.168.20.112: icmp_req=10 ttl=64 time=0.439 ms
64 bytes from 192.168.20.112: icmp_req=11 ttl=64 time=0.126 ms
64 bytes from 192.168.20.112: icmp_req=12 ttl=64 time=0.093 ms
64 bytes from 192.168.20.112: icmp_req=13 ttl=64 time=0.834 ms
64 bytes from 192.168.20.112: icmp_req=14 ttl=64 time=0.696 ms
64 bytes from 192.168.20.112: icmp_req=15 ttl=64 time=0.776 ms
64 bytes from 192.168.20.112: icmp_req=16 ttl=64 time=0.215 ms
64 bytes from 192.168.20.112: icmp_req=17 ttl=64 time=0.262 ms
64 bytes from 192.168.20.112: icmp_req=18 ttl=64 time=0.554 ms
64 bytes from 192.168.20.112: icmp_req=19 ttl=64 time=0.373 ms
64 bytes from 192.168.20.112: icmp_req=20 ttl=64 time=0.666 ms

--- 192.168.20.112 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19000ms
rtt min/avg/max/mdev = 0.093/0.443/1.035/0.264 ms

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox