Netdev List
 help / color / mirror / Atom feed
* [PATCH] pch_gbe: support ML7223 IOH
From: Tomoya MORINAGA @ 2011-05-09 11:19 UTC (permalink / raw)
  To: David S. Miller, Toshiharu Okada, Eric Dumazet, Jon Mason, netdev
  Cc: qi.wang, yong.y.wang, joel.clark, kok.howg.ewe, Tomoya MORINAGA

Support new device OKI SEMICONDUCTOR ML7223 IOH(Input/Output Hub).
The ML7223 IOH is for MP(Media Phone) use.
The ML7223 is companion chip for Intel Atom E6xx series.
The ML7223 is completely compatible for Intel EG20T PCH.

Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
---
 drivers/net/Kconfig                |    8 +++++++-
 drivers/net/pch_gbe/pch_gbe_main.c |   11 +++++++++++
 2 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dc280bc..6c884ef 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2536,7 +2536,7 @@ config S6GMAC
 source "drivers/net/stmmac/Kconfig"
 
 config PCH_GBE
-	tristate "PCH Gigabit Ethernet"
+	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GbE"
 	depends on PCI
 	select MII
 	---help---
@@ -2548,6 +2548,12 @@ config PCH_GBE
 	  to Gigabit Ethernet.
 	  This driver enables Gigabit Ethernet function.
 
+	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+	  Output Hub), ML7223.
+	  ML7223 IOH is for MP(Media Phone) use.
+	  ML7223 is companion chip for Intel Atom E6xx series.
+	  ML7223 is completely compatible for Intel EG20T PCH.
+
 endif # NETDEV_1000
 
 #
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 2ef2f9c..bd27e1d 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -34,6 +34,10 @@ const char pch_driver_version[] = DRV_VERSION;
 #define PCH_GBE_COPYBREAK_DEFAULT	256
 #define PCH_GBE_PCI_BAR			1
 
+/* Macros for ML7223 */
+#define PCI_VENDOR_ID_ROHM			0x10db
+#define PCI_DEVICE_ID_ROHM_ML7223_GBE		0x8013
+
 #define PCH_GBE_TX_WEIGHT         64
 #define PCH_GBE_RX_WEIGHT         64
 #define PCH_GBE_RX_BUFFER_WRITE   16
@@ -2420,6 +2424,13 @@ static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = {
 	 .class = (PCI_CLASS_NETWORK_ETHERNET << 8),
 	 .class_mask = (0xFFFF00)
 	 },
+	{.vendor = PCI_VENDOR_ID_ROHM,
+	 .device = PCI_DEVICE_ID_ROHM_ML7223_GBE,
+	 .subvendor = PCI_ANY_ID,
+	 .subdevice = PCI_ANY_ID,
+	 .class = (PCI_CLASS_NETWORK_ETHERNET << 8),
+	 .class_mask = (0xFFFF00)
+	 },
 	/* required last entry */
 	{0}
 };
-- 
1.7.4


^ permalink raw reply related

* Re: For the netdev list
From: Tom Goetz @ 2011-05-09 12:36 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev
In-Reply-To: <20110507182632.GA20492@electric-eye.fr.zoreil.com>


On May 7, 2011, at 2:26 PM, Francois Romieu wrote:

> Tom Goetz <tom.goetz@virtualcomputer.com> :
>> We recently obtained a new a Lenovo Edge 0578-CTO. The r8169 driver causes
>> instability in the system on this machine. The problem is that in
>> rtl8169_rx_interrupt (status & 0x00001FFF) returns values less than four
> 
> This is unexpected. :o(
> 
> [...]
>> For a work around we've added a patch to drop packets when we see this
>> condition. I have attached lspci -vvv for this device and a patch for the
>> work around we're using.
> 
> Thank you for debugging.
> 
> Can you grep for the XID of the device in the kernel's dmesg and specify
> a bit of context for the problem (MTU ? features enabled through ethtool ?
> kernel version ?) ?

This is 2.6.38 PVOPs Dom0 on Xen. The distro is Ubuntu 11.04. We have not had issues with this driver in the past. This is a new issue with the Lenovo Edge.

Here's a log fragment with the XID and output from ifconfig and ethtool:

[    3.197341] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[    3.197387] xen: registering gsi 17 triggering 0 polarity 1
[    3.197394] xen_map_pirq_gsi: returning irq 17 for gsi 17
[    3.197397] xen: --> irq=17
[    3.197406] Already setup the GSI :17
[    3.197412] r8169 0000:09:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
[    3.197524] r8169 0000:09:00.0: setting latency timer to 64
[    3.197990] r8169 0000:09:00.0: eth0: RTL8168d/8111d at 0xffffc9001117c000, e8:9a:8f:0c:6c:62, XID 083000c0 IRQ 299

eth0      Link encap:Ethernet  HWaddr e8:9a:8f:0c:6c:62  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1138 errors:0 dropped:0 overruns:0 frame:0
          TX packets:284 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:183700 (183.7 KB)  TX bytes:107686 (107.6 KB)
          Interrupt:43 Base address:0xc000 

root@edge-11-04:~# ethtool eth0
Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Half 1000baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Half 1000baseT/Full 
	Advertised pause frame use: No
	Advertised auto-negotiation: Yes
	Link partner advertised link modes:  10baseT/Half 10baseT/Full 
	                                     100baseT/Half 100baseT/Full 
	                                     1000baseT/Full 
	Link partner advertised pause frame use: No
	Link partner advertised auto-negotiation: Yes
	Speed: 1000Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 0
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pumbg
	Wake-on: g
	Current message level: 0x00000033 (51)
			       drv probe ifdown ifup
	Link detected: yes

-Tom




^ permalink raw reply

* Re: [PATCH net-next] ethtool: Add 20G bit definitions
From: Ben Hutchings @ 2011-05-09 12:50 UTC (permalink / raw)
  To: Yaniv Rosner
  Cc: David Miller, Yaniv Rosner, netdev@vger.kernel.org,
	Eilon Greenstein
In-Reply-To: <1304936217.32472.10.camel@lb-tlvb-dmitry>

On Mon, 2011-05-09 at 13:16 +0300, Yaniv Rosner wrote:
> On Sun, 2011-05-08 at 15:43 -0700, David Miller wrote:
> > From: "Yaniv Rosner" <yanivr@broadcom.com>
> > Date: Tue, 3 May 2011 10:30:08 +0300
> > 
> > > Add 20G supported and advertising bit definitions.
> > > 20G will be supported with the 57840 chips.
> > > 
> > > 
> > > Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
> > > Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
> > 
> > Applied to net-next-2.6, thanks.
> > 
> Ben,
> Please note that I haven't added new definition for 20000 link speed
> because my understanding is that it no longer required.
> Let me know if you think it is required, mainly for the speed
> extension in the ethtool application.

There is no need (yet) for specific support of the speed.  However you
should provide a patch for ethtool to make it report these flags in the
advertised/lp_advertised/supported masks.

Ben.

-- 
Ben Hutchings, Senior Software 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

* [PATCH net-next-2.6] garp: remove one synchronize_rcu() call
From: Eric Dumazet @ 2011-05-09 13:35 UTC (permalink / raw)
  To: David Miller; +Cc: Ben Greear, Patrick McHardy, netdev, Paul E. McKenney

Speedup vlan dismantling in CONFIG_VLAN_8021Q_GVRP=y cases,
by using a call_rcu() to free the memory instead of waiting with
expensive synchronize_rcu() [ while RTNL is held ]

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Ben Greear <greearb@candelatech.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
Note: I'll take care of using kfree_rcu() when available in net-next-2.6

 include/net/garp.h |    1 +
 net/802/garp.c     |    8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/garp.h b/include/net/garp.h
index f4c2959..8cabbf08 100644
--- a/include/net/garp.h
+++ b/include/net/garp.h
@@ -108,6 +108,7 @@ struct garp_applicant {
 
 struct garp_port {
 	struct garp_applicant __rcu	*applicants[GARP_APPLICATION_MAX + 1];
+	struct rcu_head			rcu;
 };
 
 extern int	garp_register_application(struct garp_application *app);
diff --git a/net/802/garp.c b/net/802/garp.c
index c1df2da..5dbe896 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -544,6 +544,11 @@ static int garp_init_port(struct net_device *dev)
 	return 0;
 }
 
+static void garp_kfree_rcu(struct rcu_head *head)
+{
+	kfree(container_of(head, struct garp_port, rcu));
+}
+
 static void garp_release_port(struct net_device *dev)
 {
 	struct garp_port *port = rtnl_dereference(dev->garp_port);
@@ -554,8 +559,7 @@ static void garp_release_port(struct net_device *dev)
 			return;
 	}
 	rcu_assign_pointer(dev->garp_port, NULL);
-	synchronize_rcu();
-	kfree(port);
+	call_rcu(&port->rcu, garp_kfree_rcu);
 }
 
 int garp_init_applicant(struct net_device *dev, struct garp_application *appl)



^ permalink raw reply related

* Re: [PATCH net-next-2.6] sfc: Implement NETIF_F_LOOPBACK
From: Ben Hutchings @ 2011-05-09 13:47 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: David Miller, netdev, linux-net-drivers, Mahesh Bandewar
In-Reply-To: <20110509073635.GA16708@rere.qmqm.pl>

On Mon, 2011-05-09 at 09:36 +0200, Michał Mirosław wrote:
> On Fri, May 06, 2011 at 01:12:31AM +0100, Ben Hutchings wrote:
> > We already have comprehensive support for loopback testing, so pick
> > the nearest mode and run with it.
> > 
> > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
> > ---
> > David, this depends on Mahesh's patch to define NETIF_F_LOOPBACK
> > <http://patchwork.ozlabs.org/patch/94190/>.  Although you've marked that
> > as RFC, I think it is ready to apply.
> > 
> > Ben.
> > 
> >  drivers/net/sfc/efx.c |   24 ++++++++++++++++++++++--
> >  1 files changed, 22 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
> > index 38a55e9..b7bfb49 100644
> > --- a/drivers/net/sfc/efx.c
> > +++ b/drivers/net/sfc/efx.c
> > @@ -1884,6 +1884,25 @@ static int efx_set_features(struct net_device *net_dev, u32 data)
> >  	if (net_dev->features & ~data & NETIF_F_NTUPLE)
> >  		efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
> >  
> > +	/* Toggle loopback if required */
> > +	if ((net_dev->features ^ data) & NETIF_F_LOOPBACK) {
> > +		enum efx_loopback_mode old_mode;
> > +		int rc;
> > +
> > +		mutex_lock(&efx->mac_lock);
> > +		old_mode = efx->loopback_mode;
> > +		if (data & NETIF_F_LOOPBACK)
> > +			efx->loopback_mode = __ffs(efx->loopback_modes);
> > +		else
> > +			efx->loopback_mode = LOOPBACK_NONE;
> > +		rc = __efx_reconfigure_port(efx);
> > +		if (rc)
> > +			efx->loopback_mode = old_mode;
> > +		mutex_unlock(&efx->mac_lock);
> > +		if (rc)
> > +			return rc;
> > +	}
> > +
> >  	return 0;
> >  }
> 
> If other features than NETIF_F_LOOPBACK were changed correctly, this should
> update dev->features of what changed before error return. If not, device's
> state will diverge to what is in dev->features.

In general __efx_reconfigure_port() might fail because PHYs are tricky
beasts, but for internal loopback that isn't an issue.  So this is very
unlikely to fail.  But I suppose I should move it to the top of the
function.

> > @@ -2472,8 +2491,9 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
> >  	net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
> >  				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
> >  				   NETIF_F_RXCSUM);
> > -	/* All offloads can be toggled */
> > -	net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA;
> > +	/* All offloads can be toggled, and so can loopback */
> > +	net_dev->hw_features = ((net_dev->features & ~NETIF_F_HIGHDMA) |
> > +				NETIF_F_LOOPBACK);
> >  	efx = netdev_priv(net_dev);
> >  	pci_set_drvdata(pci_dev, efx);
> >  	SET_NETDEV_DEV(net_dev, &pci_dev->dev);
> 
> You can remove the '& ~NETIF_F_HIGHDMA' part, as it's now allowed to be
> changed (commit fa2bd7ff9247f4218dfc907db14d000cd7edd862).

OK.

Ben.

-- 
Ben Hutchings, Senior Software 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

* Re: [oss-security] Bluetooth: l2cap and rfcomm: fix 1 byte infoleak to userspace.
From: Vasiliy Kulikov @ 2011-05-09 14:31 UTC (permalink / raw)
  To: Filip Palian
  Cc: Marcel Holtmann, Gustavo F. Padovan, David S. Miller,
	linux-bluetooth, netdev, linux-kernel, security
In-Reply-To: <BANLkTik7WyQ977-+8XapTgBrVRMyexyHKg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1049 bytes --]

On Sun, May 08, 2011 at 21:57 +0200, Filip Palian wrote:
> Structures "l2cap_conninfo" and "rfcomm_conninfo" have one padding
> byte each. This byte in "cinfo" is copied to userspace uninitialized.

Your mail client mangles the patch, it should contain original
identation tabs, not spaces.  Please see Documentation/email-clients.txt.

> patch no.1:

Don't send 2 patches as one email.  Either send 2 email or merge them
into one patch (if they are similar changes).  You'll ease maintainers'
work.

> Found by Marek Kroemeke and Filip Palian.

Please see Documentation/SubmittingPatches, chapter 12 to find out how
to sign the patch.

And please don't crosspost to oss-security and LKML - send a separate
email to o-s with a short description of a bug and a link to the LKML
thread.  LKML thread is a place to argue and discuss the solution, but
o-s subscribers are probably not interested in such a discussion.

Thanks,

-- 
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH net-next-2.6] vlan: remove one synchronize_net() call
From: Eric Dumazet @ 2011-05-09 14:40 UTC (permalink / raw)
  To: David Miller
  Cc: Ben Greear, Patrick McHardy, netdev, Paul E. McKenney,
	Jesse Gross, Michał Mirosław
In-Reply-To: <1304948155.3342.32.camel@edumazet-laptop>

At VLAN dismantle phase, unregister_vlan_dev() makes one
synchronize_net() call after vlan_group_set_device(grp, vlan_id, NULL).

This call can be safely removed because we are calling
unregister_netdevice_queue() to queue device for deletion, and this
process needs at least one rcu grace period to complete.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Ben Greear <greearb@candelatech.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Jesse Gross <jesse@nicira.com>
Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 include/linux/if_vlan.h |    1 -
 net/8021q/vlan.c        |   10 ++++------
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 546d9d3..290bd8a 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -86,7 +86,6 @@ struct vlan_group {
 					    * the vlan is attached to.
 					    */
 	unsigned int		nr_vlans;
-	int			killall;
 	struct hlist_node	hlist;	/* linked list */
 	struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
 	struct rcu_head		rcu;
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 969e700..718d635d 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -120,9 +120,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 	grp->nr_vlans--;
 
 	vlan_group_set_device(grp, vlan_id, NULL);
-	if (!grp->killall)
-		synchronize_net();
-
+	/* Because unregister_netdevice_queue() makes sure at least one rcu
+	 * grace period is respected before device freeing,
+	 * we dont need to call synchronize_net() here.
+	 */
 	unregister_netdevice_queue(dev, head);
 
 	/* If the group is now empty, kill off the group. */
@@ -478,9 +479,6 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 		if (dev->reg_state != NETREG_UNREGISTERING)
 			break;
 
-		/* Delete all VLANs for this dev. */
-		grp->killall = 1;
-
 		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)



^ permalink raw reply related

* Re: future developments of usbnet
From: Ming Lei @ 2011-05-09 15:22 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <201105091042.01014.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>

Hi,

2011/5/9 Oliver Neukum <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>:

> Do we really need to avoid it, or do we just need to recover?
> If avoidance is needed, should we use NAPI?

IMO, OOM can recover it certainly but with much cost, so we should
avoid the case. I don't think NAPI can avoid it, because NAPI will
cause skb to be allocated without any limit if there are packets
coming, still no chance left for usbnet_bh to handle and free these
SKBs.


thanks,
-- 
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: future developments of usbnet
From: Alan Stern @ 2011-05-09 15:31 UTC (permalink / raw)
  To: Ming Lei; +Cc: Oliver Neukum, netdev, linux-usb
In-Reply-To: <BANLkTi=AGQyvG58n9FG2Axbz7Ue8a6E3kg@mail.gmail.com>

On Mon, 9 May 2011, Ming Lei wrote:

> Hi,
> 
> 2011/5/9 Oliver Neukum <oliver@neukum.org>:
> 
> > Do we really need to avoid it, or do we just need to recover?
> > If avoidance is needed, should we use NAPI?
> 
> IMO, OOM can recover it certainly but with much cost, so we should
> avoid the case. I don't think NAPI can avoid it, because NAPI will
> cause skb to be allocated without any limit if there are packets
> coming, still no chance left for usbnet_bh to handle and free these
> SKBs.

How do other network drivers handle this problem?  Can the same 
strategy be used?

Alan Stern


^ permalink raw reply

* Re: future developments of usbnet
From: Stephen Hemminger @ 2011-05-09 15:46 UTC (permalink / raw)
  To: Alan Stern; +Cc: Ming Lei, Oliver Neukum, netdev, linux-usb
In-Reply-To: <Pine.LNX.4.44L0.1105091130440.2002-100000@iolanthe.rowland.org>

On Mon, 9 May 2011 11:31:16 -0400 (EDT)
Alan Stern <stern@rowland.harvard.edu> wrote:

> On Mon, 9 May 2011, Ming Lei wrote:
> 
> > Hi,
> > 
> > 2011/5/9 Oliver Neukum <oliver@neukum.org>:
> > 
> > > Do we really need to avoid it, or do we just need to recover?
> > > If avoidance is needed, should we use NAPI?
> > 
> > IMO, OOM can recover it certainly but with much cost, so we should
> > avoid the case. I don't think NAPI can avoid it, because NAPI will
> > cause skb to be allocated without any limit if there are packets
> > coming, still no chance left for usbnet_bh to handle and free these
> > SKBs.
> 
> How do other network drivers handle this problem?  Can the same 
> strategy be used?
> 
> Alan Stern

Most Ethernet drivers have a fixed size receive ring and pass preallocated
memory (skb's or pages) for the hardware to fill in. When NAPI poll is run
it refills the ring and passes the data up to netif_receive_skb. NAPI allows
the poll routine to process a limited number of packets (weight) and after
that the poll loop exits and gets rerun by soft interrupt.  If data is
arriving faster than the kernel can process, eventually the receive ring
passed to hardware gets exhausted and the hardware drops packets.

There is no explicit memory bound limit, instead the flow control happens
when the receive ring gets full.

^ permalink raw reply

* [PATCH V3 2/3] MIPS: lantiq: add ethernet driver
From: John Crispin @ 2011-05-09 15:49 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: John Crispin, Ralph Hempel, linux-mips, netdev
In-Reply-To: <1304956198-20426-1-git-send-email-blogic@openwrt.org>

This patch adds the driver for the ETOP Packet Processing Engine (PPE32) found
inside the XWAY family of Lantiq MIPS SoCs. This driver makes 100MBit ethernet
work. Support for all 8 dma channels, gbit and the embedded switch found on
the ar9/vr9 still needs to be implemented.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Acked-by: David S. Miller <davem@davemloft.net>
Cc: linux-mips@linux-mips.org
Cc: netdev@vger.kernel.org

---

Changes in V2:
* use spinlocks
* use NAPI
* remove duplicate stats counter

Changes in V3:
* validate the MAC passed inside the platform data
* make checkpatch happy

 .../mips/include/asm/mach-lantiq/lantiq_platform.h |    7 +
 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    4 +-
 arch/mips/lantiq/xway/devices.c                    |   23 +
 arch/mips/lantiq/xway/devices.h                    |    2 +
 drivers/net/Kconfig                                |    7 +
 drivers/net/Makefile                               |    1 +
 drivers/net/lantiq_etop.c                          |  805 ++++++++++++++++++++
 7 files changed, 847 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/lantiq_etop.c

diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
index 1f1dba6..a305f1d 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
@@ -10,6 +10,7 @@
 #define _LANTIQ_PLATFORM_H__
 
 #include <linux/mtd/partitions.h>
+#include <linux/socket.h>
 
 /* struct used to pass info to the pci core */
 enum {
@@ -43,4 +44,10 @@ struct ltq_pci_data {
 	int irq[16];
 };
 
+/* struct used to pass info to network drivers */
+struct ltq_eth_data {
+	struct sockaddr mac;
+	int mii_mode;
+};
+
 #endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index 4827afb..8a3c6be 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -82,8 +82,8 @@
 #define PMU_SWITCH		0x10000000
 
 /* ETOP - ethernet */
-#define LTQ_PPE32_BASE_ADDR	0xBE180000
-#define LTQ_PPE32_SIZE		0x40000
+#define LTQ_ETOP_BASE_ADDR	0x1E180000
+#define LTQ_ETOP_SIZE		0x40000
 
 /* DMA */
 #define LTQ_DMA_BASE_ADDR	0x1E104100
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
index 7d58ae5..c257026 100644
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -75,3 +75,26 @@ void __init ltq_register_gpio_stp(void)
 {
 	platform_device_register_simple("ltq_stp", 0, &ltq_stp_resource, 1);
 }
+
+/* ethernet */
+static struct resource ltq_etop_resources = {
+	.name	= "etop",
+	.start	= LTQ_ETOP_BASE_ADDR,
+	.end	= LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device ltq_etop = {
+	.name		= "ltq_etop",
+	.resource	= &ltq_etop_resources,
+	.num_resources	= 1,
+};
+
+void __init
+ltq_register_etop(struct ltq_eth_data *eth)
+{
+	if (eth) {
+		ltq_etop.dev.platform_data = eth;
+		platform_device_register(&ltq_etop);
+	}
+}
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h
index 87ba61e..2deb68e 100644
--- a/arch/mips/lantiq/xway/devices.h
+++ b/arch/mips/lantiq/xway/devices.h
@@ -10,8 +10,10 @@
 #define _LTQ_DEVICES_XWAY_H__
 
 #include "../devices.h"
+#include <linux/phy.h>
 
 extern void ltq_register_gpio(void);
 extern void ltq_register_gpio_stp(void);
+extern void ltq_register_etop(struct ltq_eth_data *eth);
 
 #endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b30c688..4878587 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2017,6 +2017,13 @@ config FTMAC100
 	  from Faraday. It is used on Faraday A320, Andes AG101 and some
 	  other ARM/NDS32 SoC's.
 
+config LANTIQ_ETOP
+	tristate "Lantiq SoC ETOP driver"
+	depends on SOC_TYPE_XWAY
+	help
+	  Support for the MII0 inside the Lantiq SoC
+
+
 source "drivers/net/fs_enet/Kconfig"
 
 source "drivers/net/octeon/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fbfca11..df71da7 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -261,6 +261,7 @@ obj-$(CONFIG_MLX4_CORE) += mlx4/
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 obj-$(CONFIG_ETHOC) += ethoc.o
 obj-$(CONFIG_GRETH) += greth.o
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
 
 obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
 
diff --git a/drivers/net/lantiq_etop.c b/drivers/net/lantiq_etop.c
new file mode 100644
index 0000000..45f252b
--- /dev/null
+++ b/drivers/net/lantiq_etop.c
@@ -0,0 +1,805 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify it
+ *   under the terms of the GNU General Public License version 2 as published
+ *   by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/phy.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/checksum.h>
+
+#include <lantiq_soc.h>
+#include <xway_dma.h>
+#include <lantiq_platform.h>
+
+#define LTQ_ETOP_MDIO		0x11804
+#define MDIO_REQUEST		0x80000000
+#define MDIO_READ		0x40000000
+#define MDIO_ADDR_MASK		0x1f
+#define MDIO_ADDR_OFFSET	0x15
+#define MDIO_REG_MASK		0x1f
+#define MDIO_REG_OFFSET		0x10
+#define MDIO_VAL_MASK		0xffff
+
+#define PPE32_CGEN		0x800
+#define LQ_PPE32_ENET_MAC_CFG	0x1840
+
+#define LTQ_ETOP_ENETS0		0x11850
+#define LTQ_ETOP_MAC_DA0	0x1186C
+#define LTQ_ETOP_MAC_DA1	0x11870
+#define LTQ_ETOP_CFG		0x16020
+#define LTQ_ETOP_IGPLEN		0x16080
+
+#define MAX_DMA_CHAN		0x8
+#define MAX_DMA_CRC_LEN		0x4
+#define MAX_DMA_DATA_LEN	0x600
+
+#define ETOP_FTCU		BIT(28)
+#define ETOP_MII_MASK		0xf
+#define ETOP_MII_NORMAL		0xd
+#define ETOP_MII_REVERSE	0xe
+#define ETOP_PLEN_UNDER		0x40
+#define ETOP_CGEN		0x800
+
+/* use 2 static channels for TX/RX */
+#define LTQ_ETOP_TX_CHANNEL	1
+#define LTQ_ETOP_RX_CHANNEL	6
+#define IS_TX(x)		(x == LTQ_ETOP_TX_CHANNEL)
+#define IS_RX(x)		(x == LTQ_ETOP_RX_CHANNEL)
+
+#define ltq_etop_r32(x)		ltq_r32(ltq_etop_membase + (x))
+#define ltq_etop_w32(x, y)	ltq_w32(x, ltq_etop_membase + (y))
+#define ltq_etop_w32_mask(x, y, z)	\
+		ltq_w32_mask(x, y, ltq_etop_membase + (z))
+
+#define DRV_VERSION	"1.0"
+
+static void __iomem *ltq_etop_membase;
+
+struct ltq_etop_chan {
+	int idx;
+	int tx_free;
+	struct net_device *netdev;
+	struct napi_struct napi;
+	struct ltq_dma_channel dma;
+	struct sk_buff *skb[LTQ_DESC_NUM];
+};
+
+struct ltq_etop_priv {
+	struct net_device *netdev;
+	struct ltq_eth_data *pldata;
+	struct resource *res;
+
+	struct mii_bus *mii_bus;
+	struct phy_device *phydev;
+
+	struct ltq_etop_chan ch[MAX_DMA_CHAN];
+	int tx_free[MAX_DMA_CHAN >> 1];
+
+	spinlock_t lock;
+};
+
+static int
+ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
+{
+	ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
+	if (!ch->skb[ch->dma.desc])
+		return -ENOMEM;
+	ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
+		ch->skb[ch->dma.desc]->data, MAX_DMA_DATA_LEN,
+		DMA_FROM_DEVICE);
+	ch->dma.desc_base[ch->dma.desc].addr =
+		CPHYSADDR(ch->skb[ch->dma.desc]->data);
+	ch->dma.desc_base[ch->dma.desc].ctl =
+		LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
+		MAX_DMA_DATA_LEN;
+	skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN);
+	return 0;
+}
+
+static void
+ltq_etop_hw_receive(struct ltq_etop_chan *ch)
+{
+	struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
+	struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+	struct sk_buff *skb = ch->skb[ch->dma.desc];
+	int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (ltq_etop_alloc_skb(ch)) {
+		netdev_err(ch->netdev,
+			"failed to allocate new rx buffer, stopping DMA\n");
+		ltq_dma_close(&ch->dma);
+	}
+	ch->dma.desc++;
+	ch->dma.desc %= LTQ_DESC_NUM;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	skb_put(skb, len);
+	skb->dev = ch->netdev;
+	skb->protocol = eth_type_trans(skb, ch->netdev);
+	netif_receive_skb(skb);
+}
+
+static int
+ltq_etop_poll_rx(struct napi_struct *napi, int budget)
+{
+	struct ltq_etop_chan *ch = container_of(napi,
+				struct ltq_etop_chan, napi);
+	int rx = 0;
+	int complete = 0;
+
+	while ((rx < budget) && !complete) {
+		struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+
+		if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
+			ltq_etop_hw_receive(ch);
+			rx++;
+		} else {
+			complete = 1;
+		}
+	}
+	if (complete || !rx) {
+		napi_complete(&ch->napi);
+		ltq_dma_ack_irq(&ch->dma);
+	}
+	return rx;
+}
+
+static int
+ltq_etop_poll_tx(struct napi_struct *napi, int budget)
+{
+	struct ltq_etop_chan *ch =
+		container_of(napi, struct ltq_etop_chan, napi);
+	struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
+	struct netdev_queue *txq =
+		netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	while ((ch->dma.desc_base[ch->tx_free].ctl &
+			(LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
+		dev_kfree_skb_any(ch->skb[ch->tx_free]);
+		ch->skb[ch->tx_free] = NULL;
+		memset(&ch->dma.desc_base[ch->tx_free], 0,
+			sizeof(struct ltq_dma_desc));
+		ch->tx_free++;
+		ch->tx_free %= LTQ_DESC_NUM;
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (netif_tx_queue_stopped(txq))
+		netif_tx_start_queue(txq);
+	napi_complete(&ch->napi);
+	ltq_dma_ack_irq(&ch->dma);
+	return 1;
+}
+
+static irqreturn_t
+ltq_etop_dma_irq(int irq, void *_priv)
+{
+	struct ltq_etop_priv *priv = _priv;
+	int ch = irq - LTQ_DMA_CH0_INT;
+
+	napi_schedule(&priv->ch[ch].napi);
+	return IRQ_HANDLED;
+}
+
+static void
+ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	ltq_dma_free(&ch->dma);
+	if (ch->dma.irq)
+		free_irq(ch->dma.irq, priv);
+	if (IS_RX(ch->idx)) {
+		int desc;
+		for (desc = 0; desc < LTQ_DESC_NUM; desc++)
+			dev_kfree_skb_any(ch->skb[ch->dma.desc]);
+	}
+}
+
+static void
+ltq_etop_hw_exit(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	ltq_pmu_disable(PMU_PPE);
+	for (i = 0; i < MAX_DMA_CHAN; i++)
+		if (IS_TX(i) || IS_RX(i))
+			ltq_etop_free_channel(dev, &priv->ch[i]);
+}
+
+static int
+ltq_etop_hw_init(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	ltq_pmu_enable(PMU_PPE);
+
+	switch (priv->pldata->mii_mode) {
+	case PHY_INTERFACE_MODE_RMII:
+		ltq_etop_w32_mask(ETOP_MII_MASK,
+			ETOP_MII_REVERSE, LTQ_ETOP_CFG);
+		break;
+
+	case PHY_INTERFACE_MODE_MII:
+		ltq_etop_w32_mask(ETOP_MII_MASK,
+			ETOP_MII_NORMAL, LTQ_ETOP_CFG);
+		break;
+
+	default:
+		netdev_err(dev, "unknown mii mode %d\n",
+			priv->pldata->mii_mode);
+		return -ENOTSUPP;
+	}
+
+	/* enable crc generation */
+	ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
+
+	ltq_dma_init_port(DMA_PORT_ETOP);
+
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		int irq = LTQ_DMA_CH0_INT + i;
+		struct ltq_etop_chan *ch = &priv->ch[i];
+
+		ch->idx = ch->dma.nr = i;
+
+		if (IS_TX(i)) {
+			ltq_dma_alloc_tx(&ch->dma);
+			request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+				"etop_tx", priv);
+		} else if (IS_RX(i)) {
+			ltq_dma_alloc_rx(&ch->dma);
+			for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
+					ch->dma.desc++)
+				if (ltq_etop_alloc_skb(ch))
+					return -ENOMEM;
+			ch->dma.desc = 0;
+			request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+				"etop_rx", priv);
+		}
+		ch->dma.irq = irq;
+	}
+	return 0;
+}
+
+static void
+ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "Lantiq ETOP");
+	strcpy(info->bus_info, "internal");
+	strcpy(info->version, DRV_VERSION);
+}
+
+static int
+ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int
+ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int
+ltq_etop_nway_reset(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	return phy_start_aneg(priv->phydev);
+}
+
+static const struct ethtool_ops ltq_etop_ethtool_ops = {
+	.get_drvinfo = ltq_etop_get_drvinfo,
+	.get_settings = ltq_etop_get_settings,
+	.set_settings = ltq_etop_set_settings,
+	.nway_reset = ltq_etop_nway_reset,
+};
+
+static int
+ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
+{
+	u32 val = MDIO_REQUEST |
+		((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
+		((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
+		phy_data;
+
+	while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+		;
+	ltq_etop_w32(val, LTQ_ETOP_MDIO);
+	return 0;
+}
+
+static int
+ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+	u32 val = MDIO_REQUEST | MDIO_READ |
+		((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
+		((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
+
+	while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+		;
+	ltq_etop_w32(val, LTQ_ETOP_MDIO);
+	while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+		;
+	val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
+	return val;
+}
+
+static void
+ltq_etop_mdio_link(struct net_device *dev)
+{
+	/* nothing to do  */
+}
+
+static int
+ltq_etop_mdio_probe(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	struct phy_device *phydev = NULL;
+	int phy_addr;
+
+	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+		if (priv->mii_bus->phy_map[phy_addr]) {
+			phydev = priv->mii_bus->phy_map[phy_addr];
+			break;
+		}
+	}
+
+	if (!phydev) {
+		netdev_err(dev, "no PHY found\n");
+		return -ENODEV;
+	}
+
+	phydev = phy_connect(dev, dev_name(&phydev->dev), &ltq_etop_mdio_link,
+			0, priv->pldata->mii_mode);
+
+	if (IS_ERR(phydev)) {
+		netdev_err(dev, "Could not attach to PHY\n");
+		return PTR_ERR(phydev);
+	}
+
+	phydev->supported &= (SUPPORTED_10baseT_Half
+			      | SUPPORTED_10baseT_Full
+			      | SUPPORTED_100baseT_Half
+			      | SUPPORTED_100baseT_Full
+			      | SUPPORTED_Autoneg
+			      | SUPPORTED_MII
+			      | SUPPORTED_TP);
+
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
+	       dev->name, phydev->drv->name,
+	       dev_name(&phydev->dev), phydev->irq);
+
+	return 0;
+}
+
+static int
+ltq_etop_mdio_init(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+	int err;
+
+	priv->mii_bus = mdiobus_alloc();
+	if (!priv->mii_bus) {
+		netdev_err(dev, "failed to allocate mii bus\n");
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	priv->mii_bus->priv = dev;
+	priv->mii_bus->read = ltq_etop_mdio_rd;
+	priv->mii_bus->write = ltq_etop_mdio_wr;
+	priv->mii_bus->name = "ltq_mii";
+	snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
+	priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!priv->mii_bus->irq) {
+		err = -ENOMEM;
+		goto err_out_free_mdiobus;
+	}
+
+	for (i = 0; i < PHY_MAX_ADDR; ++i)
+		priv->mii_bus->irq[i] = PHY_POLL;
+
+	if (mdiobus_register(priv->mii_bus)) {
+		err = -ENXIO;
+		goto err_out_free_mdio_irq;
+	}
+
+	if (ltq_etop_mdio_probe(dev)) {
+		err = -ENXIO;
+		goto err_out_unregister_bus;
+	}
+	return 0;
+
+err_out_unregister_bus:
+	mdiobus_unregister(priv->mii_bus);
+err_out_free_mdio_irq:
+	kfree(priv->mii_bus->irq);
+err_out_free_mdiobus:
+	mdiobus_free(priv->mii_bus);
+err_out:
+	return err;
+}
+
+static void
+ltq_etop_mdio_cleanup(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	phy_disconnect(priv->phydev);
+	mdiobus_unregister(priv->mii_bus);
+	kfree(priv->mii_bus->irq);
+	mdiobus_free(priv->mii_bus);
+}
+
+static int
+ltq_etop_open(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		struct ltq_etop_chan *ch = &priv->ch[i];
+
+		if (!IS_TX(i) && (!IS_RX(i)))
+			continue;
+		ltq_dma_open(&ch->dma);
+		napi_enable(&ch->napi);
+	}
+	phy_start(priv->phydev);
+	netif_tx_start_all_queues(dev);
+	return 0;
+}
+
+static int
+ltq_etop_stop(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	netif_tx_stop_all_queues(dev);
+	phy_stop(priv->phydev);
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		struct ltq_etop_chan *ch = &priv->ch[i];
+
+		if (!IS_RX(i) && !IS_TX(i))
+			continue;
+		napi_disable(&ch->napi);
+		ltq_dma_close(&ch->dma);
+	}
+	return 0;
+}
+
+static int
+ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	int queue = skb_get_queue_mapping(skb);
+	struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
+	struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+	int len;
+	unsigned long flags;
+	u32 byte_offset;
+
+	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+
+	if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+		dev_kfree_skb_any(skb);
+		netdev_err(dev, "tx ring full\n");
+		netif_tx_stop_queue(txq);
+		return NETDEV_TX_BUSY;
+	}
+
+	/* dma needs to start on a 16 byte aligned address */
+	byte_offset = CPHYSADDR(skb->data) % 16;
+	ch->skb[ch->dma.desc] = skb;
+
+	dev->trans_start = jiffies;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len,
+						DMA_TO_DEVICE)) - byte_offset;
+	wmb();
+	desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
+		LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
+	ch->dma.desc++;
+	ch->dma.desc %= LTQ_DESC_NUM;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
+		netif_tx_stop_queue(txq);
+
+	return NETDEV_TX_OK;
+}
+
+static int
+ltq_etop_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int ret = eth_change_mtu(dev, new_mtu);
+
+	if (!ret) {
+		struct ltq_etop_priv *priv = netdev_priv(dev);
+		unsigned long flags;
+
+		spin_lock_irqsave(&priv->lock, flags);
+		ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
+			LTQ_ETOP_IGPLEN);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+	return ret;
+}
+
+static int
+ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	/* TODO: mii-toll reports "No MII transceiver present!." ?!*/
+	return phy_mii_ioctl(priv->phydev, rq, cmd);
+}
+
+static int
+ltq_etop_set_mac_address(struct net_device *dev, void *p)
+{
+	int ret = eth_mac_addr(dev, p);
+
+	if (!ret) {
+		struct ltq_etop_priv *priv = netdev_priv(dev);
+		unsigned long flags;
+
+		/* store the mac for the unicast filter */
+		spin_lock_irqsave(&priv->lock, flags);
+		ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0);
+		ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16,
+			LTQ_ETOP_MAC_DA1);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+	return ret;
+}
+
+static void
+ltq_etop_set_multicast_list(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	/* ensure that the unicast filter is not enabled in promiscious mode */
+	spin_lock_irqsave(&priv->lock, flags);
+	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI))
+		ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0);
+	else
+		ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0);
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static u16
+ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+	/* we are currently only using the first queue */
+	return 0;
+}
+
+static int
+ltq_etop_init(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	struct sockaddr mac;
+	int err;
+
+	ether_setup(dev);
+	dev->watchdog_timeo = 10 * HZ;
+	err = ltq_etop_hw_init(dev);
+	if (err)
+		goto err_hw;
+	ltq_etop_change_mtu(dev, 1500);
+
+	memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
+	if (!is_valid_ether_addr(mac.sa_data)) {
+		pr_warn("etop: invalid MAC, using random\n");
+		random_ether_addr(mac.sa_data);
+	}
+
+	err = ltq_etop_set_mac_address(dev, &mac);
+	if (err)
+		goto err_netdev;
+	ltq_etop_set_multicast_list(dev);
+	err = ltq_etop_mdio_init(dev);
+	if (err)
+		goto err_netdev;
+	return 0;
+
+err_netdev:
+	unregister_netdev(dev);
+	free_netdev(dev);
+err_hw:
+	ltq_etop_hw_exit(dev);
+	return err;
+}
+
+static void
+ltq_etop_tx_timeout(struct net_device *dev)
+{
+	int err;
+
+	ltq_etop_hw_exit(dev);
+	err = ltq_etop_hw_init(dev);
+	if (err)
+		goto err_hw;
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+	return;
+
+err_hw:
+	ltq_etop_hw_exit(dev);
+	netdev_err(dev, "failed to restart etop after TX timeout\n");
+}
+
+static const struct net_device_ops ltq_eth_netdev_ops = {
+	.ndo_open = ltq_etop_open,
+	.ndo_stop = ltq_etop_stop,
+	.ndo_start_xmit = ltq_etop_tx,
+	.ndo_change_mtu = ltq_etop_change_mtu,
+	.ndo_do_ioctl = ltq_etop_ioctl,
+	.ndo_set_mac_address = ltq_etop_set_mac_address,
+	.ndo_validate_addr = eth_validate_addr,
+	.ndo_set_multicast_list = ltq_etop_set_multicast_list,
+	.ndo_select_queue = ltq_etop_select_queue,
+	.ndo_init = ltq_etop_init,
+	.ndo_tx_timeout = ltq_etop_tx_timeout,
+};
+
+static int __init
+ltq_etop_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct ltq_etop_priv *priv;
+	struct resource *res;
+	int err;
+	int i;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get etop resource\n");
+		err = -ENOENT;
+		goto err_out;
+	}
+
+	res = devm_request_mem_region(&pdev->dev, res->start,
+		resource_size(res), dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request etop resource\n");
+		err = -EBUSY;
+		goto err_out;
+	}
+
+	ltq_etop_membase = devm_ioremap_nocache(&pdev->dev,
+		res->start, resource_size(res));
+	if (!ltq_etop_membase) {
+		dev_err(&pdev->dev, "failed to remap etop engine %d\n",
+			pdev->id);
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
+	strcpy(dev->name, "eth%d");
+	dev->netdev_ops = &ltq_eth_netdev_ops;
+	dev->ethtool_ops = &ltq_etop_ethtool_ops;
+	priv = netdev_priv(dev);
+	priv->res = res;
+	priv->pldata = dev_get_platdata(&pdev->dev);
+	priv->netdev = dev;
+	spin_lock_init(&priv->lock);
+
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		if (IS_TX(i))
+			netif_napi_add(dev, &priv->ch[i].napi,
+				ltq_etop_poll_tx, 8);
+		else if (IS_RX(i))
+			netif_napi_add(dev, &priv->ch[i].napi,
+				ltq_etop_poll_rx, 32);
+		priv->ch[i].netdev = dev;
+	}
+
+	err = register_netdev(dev);
+	if (err)
+		goto err_free;
+
+	platform_set_drvdata(pdev, dev);
+	return 0;
+
+err_free:
+	kfree(dev);
+err_out:
+	return err;
+}
+
+static int __devexit
+ltq_etop_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	if (dev) {
+		netif_tx_stop_all_queues(dev);
+		ltq_etop_hw_exit(dev);
+		ltq_etop_mdio_cleanup(dev);
+		unregister_netdev(dev);
+	}
+	return 0;
+}
+
+static struct platform_driver ltq_mii_driver = {
+	.remove = __devexit_p(ltq_etop_remove),
+	.driver = {
+		.name = "ltq_etop",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init
+init_ltq_etop(void)
+{
+	int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
+
+	if (ret)
+		pr_err("ltq_etop: Error registering platfom driver!");
+	return ret;
+}
+
+static void __exit
+exit_ltq_etop(void)
+{
+	platform_driver_unregister(&ltq_mii_driver);
+}
+
+module_init(init_ltq_etop);
+module_exit(exit_ltq_etop);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq SoC ETOP");
+MODULE_LICENSE("GPL");
-- 
1.7.2.3


^ permalink raw reply related

* Re: [PATCH] rtlwifi: rtl8192cu: Fix memset using sizeof(ptr) not sizeof(*ptr)
From: Larry Finger @ 2011-05-09 16:02 UTC (permalink / raw)
  To: Joe Perches; +Cc: Chaoming Li, John W. Linville, linux-wireless, netdev, LKML
In-Reply-To: <1304919832.19586.15.camel@Joe-Laptop>

On 05/09/2011 12:43 AM, Joe Perches wrote:
> Found via coccinelle script
>
> @@
> type T;
> T* ptr;
> expression E1;
> @@
>
> * memset(E1, 0, sizeof(ptr));
>
> Signed-off-by: Joe Perches<joe@perches.com>
> ---
>   drivers/net/wireless/rtlwifi/rtl8192cu/trx.c |    2 +-
>   1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
> index 79c98f6..c16fc1c 100644
> --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
> +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
> @@ -372,7 +372,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
>   	__le16 fc;
>   	struct ieee80211_hdr *hdr;
>
> -	memset(rx_status, 0, sizeof(rx_status));
> +	memset(rx_status, 0, sizeof(*rx_status));
>   	rxdesc	= skb->data;
>   	skb_len	= skb->len;
>   	drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);

ACK.

Larry

^ permalink raw reply

* Re: [PATCH V3 2/3] MIPS: lantiq: add ethernet driver
From: Ralf Baechle @ 2011-05-09 17:08 UTC (permalink / raw)
  To: John Crispin; +Cc: Ralph Hempel, linux-mips, netdev
In-Reply-To: <1304956198-20426-3-git-send-email-blogic@openwrt.org>

Queued for 2.6.40.  

Thanks,

  Ralf

^ permalink raw reply

* [PATCH V2] rtlwifi: rtl8192cu: Fix memset/memcpy using sizeof(ptr) not sizeof(*ptr)
From: Joe Perches @ 2011-05-09 17:09 UTC (permalink / raw)
  To: Larry Finger; +Cc: Chaoming Li, John W. Linville, linux-wireless, netdev, LKML
In-Reply-To: <4DC81009.5060501@lwfinger.net>

On Mon, 2011-05-09 at 11:02 -0500, Larry Finger wrote:
> On 05/09/2011 12:43 AM, Joe Perches wrote:
> > Found via coccinelle script
> > @@
> > type T;
> > T* ptr;
> > expression E1;
> > @@
> > * memset(E1, 0, sizeof(ptr));
> > Signed-off-by: Joe Perches<joe@perches.com>
> > ---
> >   drivers/net/wireless/rtlwifi/rtl8192cu/trx.c |    2 +-
> >   1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
> > @@ -372,7 +372,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
[]
> > +	memset(rx_status, 0, sizeof(*rx_status));
> ACK.

Hey Larry.

If this is correct, then probably the memcpy at the
end of the routine needs conversion too.

---

 drivers/net/wireless/rtlwifi/rtl8192cu/trx.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 79c98f6..3a92ba3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -372,7 +372,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
 	__le16 fc;
 	struct ieee80211_hdr *hdr;
 
-	memset(rx_status, 0, sizeof(rx_status));
+	memset(rx_status, 0, sizeof(*rx_status));
 	rxdesc	= skb->data;
 	skb_len	= skb->len;
 	drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);
@@ -434,7 +434,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
 		 "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
 		 (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
 		 (u32)hdr->addr1[5]));
-	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+	memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
 	ieee80211_rx_irqsafe(hw, skb);
 }
 

^ permalink raw reply related

* Re: Scalability of interface creation and deletion
From: Jesse Gross @ 2011-05-09 17:30 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: paulmck, Alex Bligh, netdev
In-Reply-To: <1304888447.3207.66.camel@edumazet-laptop>

On Sun, May 8, 2011 at 2:00 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> For example, in the VLAN dismantle phase (ip link del eth0.103)
> we have 3 calls to synchronize_rcu() and one call to rcu_barrier()
>
> [ the 'extra' synchronize_rcu() call comes from unregister_vlan_dev() ]
>
> Maybe with new VLAN model, we could now remove this synchronize_net()
> call from vlan code. Jesse what do you think ?
> Once vlan_group_set_device(grp, vlan_id, NULL) had been called, why
> should we respect one rcu grace period at all, given dev is queued to
> unregister_netdevice_queue() [ which has its own couples of
> synchronize_net() / rcu_barrier() ]

Yes, I agree that the extra call to synchronize_net() provides no
value, though I think that's actually been true for a while.

^ permalink raw reply

* Re: [PATCH net-next-2.6] vlan: remove one synchronize_net() call
From: Jesse Gross @ 2011-05-09 17:30 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Ben Greear, Patrick McHardy, netdev,
	Paul E. McKenney, Michał Mirosław
In-Reply-To: <1304952044.3342.42.camel@edumazet-laptop>

On Mon, May 9, 2011 at 7:40 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> At VLAN dismantle phase, unregister_vlan_dev() makes one
> synchronize_net() call after vlan_group_set_device(grp, vlan_id, NULL).
>
> This call can be safely removed because we are calling
> unregister_netdevice_queue() to queue device for deletion, and this
> process needs at least one rcu grace period to complete.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Ben Greear <greearb@candelatech.com>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Jesse Gross <jesse@nicira.com>
> Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>

Acked-by: Jesse Gross <jesse@nicira.com>

^ permalink raw reply

* [PATCH] net/usb: mark LG VL600 LTE modem ethernet interface as WWAN
From: Dan Williams @ 2011-05-09 17:43 UTC (permalink / raw)
  To: netdev; +Cc: Andrzej Zaborowski, Oliver Neukum

Like other mobile broadband device ethernet interfaces, mark the LG
VL600 with the 'wwan' devtype so userspace knows it needs additional
configuration via the AT port before the interface can be used.

Signed-off-by: Dan Williams <dcbw@redhat.com>
---

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a301479..c924ea2 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -567,7 +567,7 @@ static const struct usb_device_id	products [] = {
 {
 	USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-	.driver_info		= 0,
+	.driver_info = (unsigned long)&wwan_info,
 },
 
 /*



^ permalink raw reply related

* Multicast issue on 2.6.39-rc6
From: Rolando Martins @ 2011-05-09 18:10 UTC (permalink / raw)
  To: netdev

Hi,
is anyone experiencing problems with the receiving of multicast
packets in 2.6.39-rc6?

Thanks,
Rolando

^ permalink raw reply

* Re: [PATCH net-next-2.6] garp: remove one synchronize_rcu() call
From: Patrick McHardy @ 2011-05-09 18:25 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, Ben Greear, netdev, Paul E. McKenney
In-Reply-To: <1304948155.3342.32.camel@edumazet-laptop>

Am 09.05.2011 15:35, schrieb Eric Dumazet:
> Speedup vlan dismantling in CONFIG_VLAN_8021Q_GVRP=y cases,
> by using a call_rcu() to free the memory instead of waiting with
> expensive synchronize_rcu() [ while RTNL is held ]
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Ben Greear <greearb@candelatech.com>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> ---
> Note: I'll take care of using kfree_rcu() when available in net-next-2.6
> 

Looks good to me.


^ permalink raw reply

* Re: [PATCH net-next-2.6] vlan: remove one synchronize_net() call
From: Patrick McHardy @ 2011-05-09 18:26 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Ben Greear, netdev, Paul E. McKenney, Jesse Gross,
	Michał Mirosław
In-Reply-To: <1304952044.3342.42.camel@edumazet-laptop>

Am 09.05.2011 16:40, schrieb Eric Dumazet:
> At VLAN dismantle phase, unregister_vlan_dev() makes one
> synchronize_net() call after vlan_group_set_device(grp, vlan_id, NULL).
> 
> This call can be safely removed because we are calling
> unregister_netdevice_queue() to queue device for deletion, and this
> process needs at least one rcu grace period to complete.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Ben Greear <greearb@candelatech.com>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Jesse Gross <jesse@nicira.com>
> Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
>  include/linux/if_vlan.h |    1 -
>  net/8021q/vlan.c        |   10 ++++------
>  2 files changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
> index 546d9d3..290bd8a 100644
> --- a/include/linux/if_vlan.h
> +++ b/include/linux/if_vlan.h
> @@ -86,7 +86,6 @@ struct vlan_group {
>  					    * the vlan is attached to.
>  					    */
>  	unsigned int		nr_vlans;
> -	int			killall;

Looks good, thanks Eric.

^ permalink raw reply

* Testing interface removal speedup patches from Eric Dumazet.
From: Ben Greear @ 2011-05-09 18:37 UTC (permalink / raw)
  To: netdev; +Cc: Eric Dumazet

[-- Attachment #1: Type: text/plain, Size: 1879 bytes --]

These two patches look good to me.  My benchmark has lots of extraneous
overhead (process launch per action, primarily), so the numbers bounce around
quite a bit on different runs, but it seems consistent that removing vlans
is slightly faster, and removing VETH is much faster.

NOTE:  for VETH, it's creating and dealing with pairs..so 500 veth
means 1000 interfaces in the results below.

The script to generate these results is attached.

System is Atom N270, running Fedora 14.  Kernel has HZ 1000,
pre-empt, SMP, compiled for Pentium II.


With patches:

Created 500 veth in 17.874695 seconds (0.03574939 per interface).
Added IP addresses in 23.306214 seconds (0.046612428 per addr).
Deleted 500 veth in 17.023607 seconds. (0.034047214 per interface)

Created 1000 macvlan in 20.005472 seconds (0.020005472 per interface).
Added IP addresses in 24.870693 seconds (0.024870693 per addr).
Deleted 1000 macvlan in 44.899769 seconds. (0.044899769 per interface)

Created 1000 vlan in 21.343862 seconds (0.021343862 per interface).
Added IP addresses in 24.088452 seconds (0.024088452 per addr).
Deleted 1000 vlan in 42.623666 seconds. (0.042623666 per interface)


Without:

Created 500 veth in 22.507598 seconds (0.045015196 per interface).
Added IP addresses in 28.637194 seconds (0.057274388 per addr).
Deleted 500 veth in 34.998733 seconds. (0.069997466 per interface)

Created 1000 macvlan in 27.903848 seconds (0.027903848 per interface).
Added IP addresses in 29.725436 seconds (0.029725436 per addr).
Deleted 1000 macvlan in 58.552433 seconds. (0.058552433 per interface)

Created 1000 vlan in 33.733169 seconds (0.033733169 per interface).
Added IP addresses in 29.755363 seconds (0.029755363 per addr).
Deleted 1000 vlan in 54.858484 seconds. (0.054858484 per interface)

--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


[-- Attachment #2: test_macvlans.pl --]
[-- Type: application/x-perl, Size: 2070 bytes --]

^ permalink raw reply

* Re: [PATCH net-next-2.6] net: use batched device unregister in veth and macvlan
From: David Miller @ 2011-05-09 18:42 UTC (permalink / raw)
  To: eric.dumazet; +Cc: mirqus, alex, netdev, jesse, paulmck, greearb
In-Reply-To: <1304932677.3342.17.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 09 May 2011 11:17:57 +0200

> veth devices dont use the batched device unregisters yet.
> 
> Since veth are a pair of devices, it makes sense to use a batch of two
> unregisters, this roughly divides dismantle time by two.
> 
> Fix this by changing dellink() callers to always provide a non NULL
> head. (Idea from Michał Mirosław)
> 
> This patch also handles macvlan case : We now dismantle all macvlans on
> top of a lower dev at once.
> 
> Reported-by: Alex Bligh <alex@alex.org.uk>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next-2.6] garp: remove one synchronize_rcu() call
From: David Miller @ 2011-05-09 18:42 UTC (permalink / raw)
  To: eric.dumazet; +Cc: greearb, kaber, netdev, paulmck
In-Reply-To: <1304948155.3342.32.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 09 May 2011 15:35:55 +0200

> Speedup vlan dismantling in CONFIG_VLAN_8021Q_GVRP=y cases,
> by using a call_rcu() to free the memory instead of waiting with
> expensive synchronize_rcu() [ while RTNL is held ]
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next-2.6] vlan: remove one synchronize_net() call
From: David Miller @ 2011-05-09 18:42 UTC (permalink / raw)
  To: eric.dumazet; +Cc: greearb, kaber, netdev, paulmck, jesse, mirq-linux
In-Reply-To: <1304952044.3342.42.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 09 May 2011 16:40:44 +0200

> At VLAN dismantle phase, unregister_vlan_dev() makes one
> synchronize_net() call after vlan_group_set_device(grp, vlan_id, NULL).
> 
> This call can be safely removed because we are calling
> unregister_netdevice_queue() to queue device for deletion, and this
> process needs at least one rcu grace period to complete.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next 0/4] tulip: logging cleanups
From: David Miller @ 2011-05-09 18:47 UTC (permalink / raw)
  To: joe; +Cc: netdev, linux-kernel
In-Reply-To: <cover.1304733889.git.joe@perches.com>

From: Joe Perches <joe@perches.com>
Date: Fri,  6 May 2011 19:08:41 -0700

> Joe Perches (4):
>   tulip: xircom_cb: Convert #ifdef DEBUG blocks and enter/leave uses
>   tulip: Convert printks to netdev_<level>
>   tulip: Convert uses of KERN_DEBUG
>   tulip: Use pr_<level> where appropriate

With the advent of the function tracer, those silly function entry/exit
logging things are entirely superfluous.

They make the code look ugly too.

So you have my approval to just kill those things off entirely.

Please do that and respin this patch set, thanks Joe!

^ 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