Netdev List
 help / color / mirror / Atom feed
* Re: 'tcp: bind() fix when many ports are bound' problem
From: Daniel Baluta @ 2011-01-05  9:00 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Gaspar Chilingarov, netdev
In-Reply-To: <1294140172.3579.81.camel@edumazet-laptop>

On Tue, Jan 4, 2011 at 1:22 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le mardi 04 janvier 2011 à 13:12 +0400, Gaspar Chilingarov a écrit :
>> Hi there!
>>
>> Well, that looks strange.
>>
>> On my own side I've just put workaround (manually binding to all ports
>> in sequence :)
>> and moved production code to FreeBSD as it has better scalable network stack.
>>
>> I can see the potential problem with that bind() problem on highly
>> loaded DNS servers/resolvers which establish tons of outgoing UDP
>> connections.
>>
>> In some cases that connections could fail and as not receiving the
>> answer it is normal condition for DNS this will go totally unnoticed.
>>
>> I don't think anyone will hit this bug in production environment
>> except the very high load applications.
>
> Dont mix TCP and UDP, they are not the same.
>
> Problem with TCP is you can have TIME_WAIT sockets, disallowing a port
> to be reused. Not with UDP.

Isn't SO_REUSEADDR supposed to fix this problem?

Anyhow, inet_csk_get_port the function used by bind(0) performs bad.

Short reminder:
100 IP addr  - 70K sockets created => 700 sockets per IP.
bind(0) for all sockets will results in a large number of
(port, addr) duplicates although there are more than 30000 ports available.

This wouldn't be so bad if you won't try to connect duplicates to the same
remote (addr, port) which will result in a connect failure.

Eric's patch introduced the restriction 'forbid two reuse enabled sockets
to bind on same (addr, port) tuple with a (non ANY addr)'.

Well, I think this will break rule #2 from inet_hastable.h:
"
If all sockets have sk->sk_reuse set, and none of them are in
TCP_LISTEN state, the port may be shared.
"
and also caused problem ([1]), don't really know if they are the same.

An attempt, to fix this was to "always allow a reuse listen if
no other listen is already active on the same IP".

The problem with this fix, is that at the moment of bind() we
don't know what will be the usage of this socket. It can be,
bind -> connect or bind -> listen.
>
> The connect() [without a previous bind()], or a sendto() [without a
> previous bind()] problem is more an API problem.

Can you share your thoughts on this?

Going back to my first email, are there any follow ups on your
"tcp: bind() fix when many ports are bound" patch. I've searched
netdev archives but no luck. I might have missed something.

I really appreciate your help.

thanks,
Daniel.

^ permalink raw reply

* Re: [PATCH v2 05/10] net/fec: add dual fec support for mx28
From: Uwe Kleine-König @ 2011-01-05  9:03 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Sascha Hauer, Baruch Siach, B32542, netdev, bryan.wu, gerg,
	w.sang, r64343, eric, davem, linux-arm-kernel, lw
In-Reply-To: <20110105084513.GA26617@pengutronix.de>

Hello Shawn,

On Wed, Jan 05, 2011 at 09:45:13AM +0100, Sascha Hauer wrote:
> On Tue, Jan 04, 2011 at 10:13:09PM +0800, Shawn Guo wrote:
> > Hi Baruch,
> > 
> > On Tue, Jan 04, 2011 at 11:59:16AM +0200, Baruch Siach wrote:
> > > Hi Shawn,
> > > 
> > > On Tue, Jan 04, 2011 at 05:24:11PM +0800, Shawn Guo wrote:
> > > > This patch is to add mx28 dual fec support. Here are some key notes
> > > > for mx28 fec controller.
> > > > 
> > > >  - mx28 fec design made an assumption that it runs on a
> > > >    big-endian system, which is incorrect. As the result, the
> > > >    driver has to swap every frame going to and coming from
> > > >    the controller.
> > > >  - external phys can only be configured by fec0, which means
> > > >    fec1 can not work independently and both phys need to be
> > > >    configured by mii_bus attached on fec0.
> > > >  - mx28 fec reset will get mac address registers reset too.
> > > >  - MII/RMII mode and 10M/100M speed are configured differently
> > > >    from i.mx/mxs fec controller.
> > > >  - ETHER_EN bit must be set to get interrupt work.
> > > > 
> > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > ---
> > > > Changes for v2:
> > > >  - Use module parameter fec.macaddr over new kernel command line
> > > >    fec_mac to pass mac address
> > > 
> > > Since you introduce this new kernel command line parameter in patch #3 of this 
> > > series, why not just make it right in the first place? This should make both 
> > > patches smaller and easier for review.
> > > 
> > > >  - Update comment in fec_get_mac() to stop using confusing word
> > > >    "default"
> > > >  - Fix copyright breakage in fec.h
> > > 
> > > Ditto.
> > > 
> > Sorry for rushing to send the patch set out. All these updates
> > should happen on patch #3 than #5.  This is a serious problem,
> > and I will fix it soon and resend as v3.
> > 
> > > >  drivers/net/Kconfig |    7 ++-
> > > >  drivers/net/fec.c   |  139 ++++++++++++++++++++++++++++++++++++++++----------
> > > >  drivers/net/fec.h   |    5 +-
> > > >  include/linux/fec.h |    3 +-
> > > >  4 files changed, 120 insertions(+), 34 deletions(-)
> > > 
> > > [snip]
> > > 
> > > > diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> > > > index f147508..b2b3e37 100644
> > > > --- a/drivers/net/fec.c
> > > > +++ b/drivers/net/fec.c
> > > > @@ -17,6 +17,8 @@
> > > >   *
> > > >   * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
> > > >   * Copyright (c) 2004-2006 Macq Electronique SA.
> > > > + *
> > > > + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> > > >   */
> > > >  
> > > >  #include <linux/module.h>
> > > > @@ -45,21 +47,34 @@
> > > >  
> > > >  #include <asm/cacheflush.h>
> > > >  
> > > > -#ifndef CONFIG_ARCH_MXC
> > > > +#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_SOC_IMX28)
> > > >  #include <asm/coldfire.h>
> > > >  #include <asm/mcfsim.h>
> > > >  #endif
> > > >  
> > > >  #include "fec.h"
> > > >  
> > > > -#ifdef CONFIG_ARCH_MXC
> > > > -#include <mach/hardware.h>
> > > 
> > > Since you now remove mach/hardware.h for ARCH_MXC, does this build for all 
> > > i.MX variants?
> > > 
> > Did the test build for mx25, mx27, mx3 and mx51.
> > 
> > > > +#ifdef CONFIG_SOC_IMX28
> > > > +/*
> > > > + * mx28 does not have MIIGSK registers
> > > > + */
> > > > +#undef FEC_MIIGSK_ENR
> > > > +#include <mach/mxs.h>
> > > > +#else
> > > > +#define cpu_is_mx28()	(0)
> > > > +#endif
> > > 
> > > This breaks kernels for multiple archs (e.g. i.MX28 and i.MX25). Please use 
> > > run-time detection of CPU type, and do the MII/RMII etc. configuration 
> > > accordingly.
> > > 
> > I do not find a good way to detect cpu type.  Neither adding a new
> > platform data field nor using __machine_arch_type to enumerate all
> > mx28 based machine (though there is only one currently) seems to be
> > good for me.
> > 
> > I will try to manipulate some mx28 unique register to identify mx28
> > from other i.mx variants.  Hopefully, it will work.
> 
> There won't be a register which you can safely read on all i.MX
> variants.
> Why don't you implement it the same way the other i.MX do? They do not
> need SoC detection and the macro expands to 0 at compile time when the
> cpu is not enabled.
Alternatively you can use the approach I used for spi-imx and identify
the device by name.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* Re: [PATCH v2 05/10] net/fec: add dual fec support for mx28
From: Shawn Guo @ 2011-01-05  9:40 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Sascha Hauer, Baruch Siach, B32542, netdev, bryan.wu, gerg,
	w.sang, r64343, eric, davem, linux-arm-kernel, lw
In-Reply-To: <20110105090312.GO25121@pengutronix.de>

On Wed, Jan 05, 2011 at 10:03:12AM +0100, Uwe Kleine-König wrote:
> Hello Shawn,
> 
> On Wed, Jan 05, 2011 at 09:45:13AM +0100, Sascha Hauer wrote:
> > On Tue, Jan 04, 2011 at 10:13:09PM +0800, Shawn Guo wrote:
> > > Hi Baruch,
> > > 
> > > On Tue, Jan 04, 2011 at 11:59:16AM +0200, Baruch Siach wrote:
> > > > Hi Shawn,
> > > > 
> > > > On Tue, Jan 04, 2011 at 05:24:11PM +0800, Shawn Guo wrote:
> > > > > This patch is to add mx28 dual fec support. Here are some key notes
> > > > > for mx28 fec controller.
> > > > > 
> > > > >  - mx28 fec design made an assumption that it runs on a
> > > > >    big-endian system, which is incorrect. As the result, the
> > > > >    driver has to swap every frame going to and coming from
> > > > >    the controller.
> > > > >  - external phys can only be configured by fec0, which means
> > > > >    fec1 can not work independently and both phys need to be
> > > > >    configured by mii_bus attached on fec0.
> > > > >  - mx28 fec reset will get mac address registers reset too.
> > > > >  - MII/RMII mode and 10M/100M speed are configured differently
> > > > >    from i.mx/mxs fec controller.
> > > > >  - ETHER_EN bit must be set to get interrupt work.
> > > > > 
> > > > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > > > ---
> > > > > Changes for v2:
> > > > >  - Use module parameter fec.macaddr over new kernel command line
> > > > >    fec_mac to pass mac address
> > > > 
> > > > Since you introduce this new kernel command line parameter in patch #3 of this 
> > > > series, why not just make it right in the first place? This should make both 
> > > > patches smaller and easier for review.
> > > > 
> > > > >  - Update comment in fec_get_mac() to stop using confusing word
> > > > >    "default"
> > > > >  - Fix copyright breakage in fec.h
> > > > 
> > > > Ditto.
> > > > 
> > > Sorry for rushing to send the patch set out. All these updates
> > > should happen on patch #3 than #5.  This is a serious problem,
> > > and I will fix it soon and resend as v3.
> > > 
> > > > >  drivers/net/Kconfig |    7 ++-
> > > > >  drivers/net/fec.c   |  139 ++++++++++++++++++++++++++++++++++++++++----------
> > > > >  drivers/net/fec.h   |    5 +-
> > > > >  include/linux/fec.h |    3 +-
> > > > >  4 files changed, 120 insertions(+), 34 deletions(-)
> > > > 
> > > > [snip]
> > > > 
> > > > > diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> > > > > index f147508..b2b3e37 100644
> > > > > --- a/drivers/net/fec.c
> > > > > +++ b/drivers/net/fec.c
> > > > > @@ -17,6 +17,8 @@
> > > > >   *
> > > > >   * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
> > > > >   * Copyright (c) 2004-2006 Macq Electronique SA.
> > > > > + *
> > > > > + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> > > > >   */
> > > > >  
> > > > >  #include <linux/module.h>
> > > > > @@ -45,21 +47,34 @@
> > > > >  
> > > > >  #include <asm/cacheflush.h>
> > > > >  
> > > > > -#ifndef CONFIG_ARCH_MXC
> > > > > +#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_SOC_IMX28)
> > > > >  #include <asm/coldfire.h>
> > > > >  #include <asm/mcfsim.h>
> > > > >  #endif
> > > > >  
> > > > >  #include "fec.h"
> > > > >  
> > > > > -#ifdef CONFIG_ARCH_MXC
> > > > > -#include <mach/hardware.h>
> > > > 
> > > > Since you now remove mach/hardware.h for ARCH_MXC, does this build for all 
> > > > i.MX variants?
> > > > 
> > > Did the test build for mx25, mx27, mx3 and mx51.
> > > 
> > > > > +#ifdef CONFIG_SOC_IMX28
> > > > > +/*
> > > > > + * mx28 does not have MIIGSK registers
> > > > > + */
> > > > > +#undef FEC_MIIGSK_ENR
> > > > > +#include <mach/mxs.h>
> > > > > +#else
> > > > > +#define cpu_is_mx28()	(0)
> > > > > +#endif
> > > > 
> > > > This breaks kernels for multiple archs (e.g. i.MX28 and i.MX25). Please use 
> > > > run-time detection of CPU type, and do the MII/RMII etc. configuration 
> > > > accordingly.
> > > > 
> > > I do not find a good way to detect cpu type.  Neither adding a new
> > > platform data field nor using __machine_arch_type to enumerate all
> > > mx28 based machine (though there is only one currently) seems to be
> > > good for me.
> > > 
> > > I will try to manipulate some mx28 unique register to identify mx28
> > > from other i.mx variants.  Hopefully, it will work.
> > 
> > There won't be a register which you can safely read on all i.MX
> > variants.FEC_TRUNC_FL

Register FEC_TRUNC_FL (offset 0x1b0) is one I found I can use to
distinguish ENET-MAC from FEC.  This address is being reserved on
FEC, and I knew from designer that access the address on FEC
will not generate exception as it's valid in FEC address range.
I proved it on mx51.

        /*
         * Detect ENET-MAC by writing and reading back on TRUNC_FL register,
         * which is accessible on ENET-MAC while always return 0 on FEC.
         */
        writel(0x7ff, fep->hwp + 0x1b0);
        if (readl(fep->hwp + 0x1b0) == 0x7ff)
                fec_is_enetmac = 1;

But it does not matter.  I more like the solution that offered by Uwe
below.

Thanks, Sascha.

> > Why don't you implement it the same way the other i.MX do? They do not
> > need SoC detection and the macro expands to 0 at compile time when the
> > cpu is not enabled.
> Alternatively you can use the approach I used for spi-imx and identify
> the device by name.
> 
Thanks, Uwe.

> Best regards
> Uwe
> 
> -- 
> Pengutronix e.K.                           | Uwe Kleine-König            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> 

-- 
Regards,
Shawn


^ permalink raw reply

* Re: [PATCH] net: r6040: Return proper error for r6040_init_one
From: Florian Fainelli @ 2011-01-05  9:50 UTC (permalink / raw)
  To: Axel Lin; +Cc: linux-kernel, David S. Miller, netdev
In-Reply-To: <1294216804.19064.2.camel@mola>

On Wednesday 05 January 2011 09:40:04 Axel Lin wrote:
> Return -ENOMEM instead of 0 for the case of mdiobus_alloc and kmalloc
> failure.
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>

Acked-by: Florian Fainelli <florian@openwrt.org>

> ---
>  drivers/net/r6040.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
> index 0b014c89..27e6f6d 100644
> --- a/drivers/net/r6040.c
> +++ b/drivers/net/r6040.c
> @@ -1153,6 +1153,7 @@ static int __devinit r6040_init_one(struct pci_dev
> *pdev, lp->mii_bus = mdiobus_alloc();
>  	if (!lp->mii_bus) {
>  		dev_err(&pdev->dev, "mdiobus_alloc() failed\n");
> +		err = -ENOMEM;
>  		goto err_out_unmap;
>  	}
> 
> @@ -1165,6 +1166,7 @@ static int __devinit r6040_init_one(struct pci_dev
> *pdev, lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
> if (!lp->mii_bus->irq) {
>  		dev_err(&pdev->dev, "mii_bus irq allocation failed\n");
> +		err = -ENOMEM;
>  		goto err_out_mdio;
>  	}

^ permalink raw reply

* السلام عليكم أخي
From: aliamdulilahi2 @ 2011-01-05 10:13 UTC (permalink / raw)


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



[-- Attachment #2: salamiah.doc --]
[-- Type: application/msword, Size: 28672 bytes --]

^ permalink raw reply

* Re: [PATCH v2 00/12] make rpc_pipefs be mountable multiple time
From: Al Viro @ 2011-01-05 11:41 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Trond Myklebust, J. Bruce Fields, Neil Brown, Pavel Emelyanov,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, David S. Miller,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1293628470-28386-1-git-send-email-kas-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>

On Wed, Dec 29, 2010 at 03:14:18PM +0200, Kirill A. Shutemov wrote:
> Prepare nfs/sunrpc stack to use multiple instances of rpc_pipefs.

Won't that make sunrpc impossible to rmmod once you've got it in?
Note that having a reference to vfsmount pins it down, which pins
the superblock down, which pins the file_system_type down, which
pins the damn module down.  So cleanup_sunrpc() won't be ever called,
AFAICS...
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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

* [RFC] ipmr: About origin IP address of flow in multicast routing API
From: François-Xavier Le Bail @ 2011-01-05 12:59 UTC (permalink / raw)
  To: netdev

Hello,

Context: IGMP Proxying.

For using multicast routing API with setsockopt and MRT_ADD_MFC, we need to set the mfcc_origin in a struct mfcctl.

Is there a way to use a wildcard for mfcc_origin to say "any origin" IP address, by example 0.0.0.0 ?

Thus we could add a MFC with only the multicast group and the mfcc_parent, reading a SOCK_RAW/IPPROTO_IGMP socket, without the need to listen the multicast flow to find the origin IP.

Any thought ?

Francois-Xavier Le Bail



      

^ permalink raw reply

* unmet direct dependencies (NET && NET_SCHED)
From: Toralf Förster @ 2011-01-05 13:22 UTC (permalink / raw)
  To: netfilter; +Cc: netdev

Hello,

a "make randconfig 1>/dev/null" gave today :

tfoerste@n22 ~/devel/linux-2.6 $ make randconfig 1>/dev/null
warning: (NETFILTER_XT_MATCH_REALM && NET && INET && NETFILTER && 
NETFILTER_XTABLES && NETFILTER_ADVANCED || NET_CLS_ROUTE4 && NET && NET_SCHED) 
selects NET_CLS_ROUTE which has unmet direct dependencies (NET && NET_SCHED)

for the current git kernel sources.
Is this an already known issue ?

-- 
MfG/Kind regards
Toralf Förster

pgp finger print: 7B1A 07F4 EC82 0F90 D4C2 8936 872A E508 7DB6 9DA3


^ permalink raw reply

* [PATCH] xen: netfront: Drop GSO SKBs which do not have csum_blank.
From: Ian Campbell @ 2011-01-05 13:23 UTC (permalink / raw)
  To: netdev; +Cc: Ian Campbell, Jeremy Fitzhardinge, xen-devel

The Linux network stack expects all GSO SKBs to have ip_summed ==
CHECKSUM_PARTIAL (which implies that the frame contains a partial
checksum) and the Xen network ring protocol similarly expects an SKB
which has GSO set to also have NETRX_csum_blank (which also implies a
partial checksum). Therefore drop such frames on receive otherwise
they will trigger the warning in skb_gso_segment.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: xen-devel@lists.xensource.com
Cc: netdev@vger.kernel.org
---
 drivers/net/xen-netfront.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index cdbeec9..8b8c480 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -836,6 +836,11 @@ static int handle_incoming_queue(struct net_device *dev,
 				dev->stats.rx_errors++;
 				continue;
 			}
+		} else if (skb_is_gso(skb)) {
+			kfree_skb(skb);
+			packets_dropped++;
+			dev->stats.rx_errors++;
+			continue;
 		}
 
 		dev->stats.rx_packets++;
-- 
1.5.6.5


^ permalink raw reply related

* Re: [PATCH] net: bridge: check the length of skb after nf_bridge_maybe_copy_header()
From: Changli Gao @ 2011-01-05 13:37 UTC (permalink / raw)
  To: David Miller; +Cc: shemminger, bridge, netdev
In-Reply-To: <20110103.121336.212692696.davem@davemloft.net>

On Tue, Jan 4, 2011 at 4:13 AM, David Miller <davem@davemloft.net> wrote:
> From: Stephen Hemminger <shemminger@linux-foundation.org>
>>
>> Because PPPOE happens afterwards and is not part the calculation.
>> The check should be moved until after skb has reached final form.
>
> That works for me.
>

So, is my patch acceptable?

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: [PATCH v2 00/12] make rpc_pipefs be mountable multiple time
From: Kirill A. Shutemov @ 2011-01-05 13:40 UTC (permalink / raw)
  To: Al Viro
  Cc: Kirill A. Shutemov, Trond Myklebust, J. Bruce Fields, Neil Brown,
	Pavel Emelyanov, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	David S. Miller, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110105114155.GN19804-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>

On Wed, Jan 05, 2011 at 11:41:55AM +0000, Al Viro wrote:
> On Wed, Dec 29, 2010 at 03:14:18PM +0200, Kirill A. Shutemov wrote:
> > Prepare nfs/sunrpc stack to use multiple instances of rpc_pipefs.
> 
> Won't that make sunrpc impossible to rmmod once you've got it in?

Oops.. Nice catch.

I'll fix it by relacing remaing references of init_rpc_pipefs with
get_rpc_pipefs(NULL) at the end of the patchset and move init_rpc_pipefs
mounting to get_rpc_pipefs(). So, we will have temporary regression in the
middle of the patchset, but I think it's not a problem.

-- 
 Kirill A. Shutemov
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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

* [PATCH] ipv4: IP defragmentation must be ECN aware
From: Eric Dumazet @ 2011-01-05 13:59 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <1294186431.3420.19.camel@edumazet-laptop>

RFC3168 (The Addition of Explicit Congestion Notification to IP)
states :

5.3.  Fragmentation

   ECN-capable packets MAY have the DF (Don't Fragment) bit set.
   Reassembly of a fragmented packet MUST NOT lose indications of
   congestion.  In other words, if any fragment of an IP packet to be
   reassembled has the CE codepoint set, then one of two actions MUST be
   taken:

      * Set the CE codepoint on the reassembled packet.  However, this
        MUST NOT occur if any of the other fragments contributing to
        this reassembly carries the Not-ECT codepoint.

      * The packet is dropped, instead of being reassembled, for any
        other reason.

This patch implements this requirement for IPv4, choosing the first
action : 

If one fragment had NO-ECT codepoint
	reassembled frame has NO-ECT
ElIf one fragment had CE codepoint
	reassembled frame has CE

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/ipv4/ip_fragment.c |   34 ++++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+)

diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index e6215bd..e6b53a7 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -45,6 +45,7 @@
 #include <linux/udp.h>
 #include <linux/inet.h>
 #include <linux/netfilter_ipv4.h>
+#include <net/inet_ecn.h>
 
 /* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
  * code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
@@ -70,11 +71,28 @@ struct ipq {
 	__be32		daddr;
 	__be16		id;
 	u8		protocol;
+	u8		ecn; /* RFC3168 support */
 	int             iif;
 	unsigned int    rid;
 	struct inet_peer *peer;
 };
 
+#define IPFRAG_ECN_CLEAR  0x01 /* one frag had INET_ECN_NOT_ECT */
+#define IPFRAG_ECN_SET_CE 0x04 /* one frag had INET_ECN_CE */
+
+static inline int ip4_frag_ecn(int tos)
+{
+	tos = (tos & INET_ECN_MASK) + 1;
+	/*
+	 * After the last operation we have (in binary):
+	 * INET_ECN_NOT_ECT => 001
+	 * INET_ECN_ECT_1   => 010
+	 * INET_ECN_ECT_0   => 011
+	 * INET_ECN_CE      => 100
+	 */
+	return (tos & 2) ? 0 : tos;
+}
+
 static struct inet_frags ip4_frags;
 
 int ip_frag_nqueues(struct net *net)
@@ -137,6 +155,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a)
 
 	qp->protocol = arg->iph->protocol;
 	qp->id = arg->iph->id;
+	qp->ecn = ip4_frag_ecn(arg->iph->tos);
 	qp->saddr = arg->iph->saddr;
 	qp->daddr = arg->iph->daddr;
 	qp->user = arg->user;
@@ -316,6 +335,7 @@ static int ip_frag_reinit(struct ipq *qp)
 	qp->q.fragments = NULL;
 	qp->q.fragments_tail = NULL;
 	qp->iif = 0;
+	qp->ecn = 0;
 
 	return 0;
 }
@@ -328,6 +348,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 	int flags, offset;
 	int ihl, end;
 	int err = -ENOENT;
+	u8 ecn;
 
 	if (qp->q.last_in & INET_FRAG_COMPLETE)
 		goto err;
@@ -339,6 +360,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 		goto err;
 	}
 
+	ecn = ip4_frag_ecn(ip_hdr(skb)->tos);
 	offset = ntohs(ip_hdr(skb)->frag_off);
 	flags = offset & ~IP_OFFSET;
 	offset &= IP_OFFSET;
@@ -472,6 +494,7 @@ found:
 	}
 	qp->q.stamp = skb->tstamp;
 	qp->q.meat += skb->len;
+	qp->ecn |= ecn;
 	atomic_add(skb->truesize, &qp->q.net->mem);
 	if (offset == 0)
 		qp->q.last_in |= INET_FRAG_FIRST_IN;
@@ -583,6 +606,17 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
 	iph = ip_hdr(head);
 	iph->frag_off = 0;
 	iph->tot_len = htons(len);
+	/* RFC3168 5.3 Fragmentation support :
+	 * If one fragment had INET_ECN_NOT_ECT,
+	 *	reassembled frame also has INET_ECN_NOT_ECT
+	 * Elif one fragment had INET_ECN_CE
+	 *	reassembled frame also has INET_ECN_CE
+	 */
+	if (qp->ecn & IPFRAG_ECN_CLEAR)
+		iph->tos &= ~INET_ECN_MASK;
+	else if (qp->ecn & IPFRAG_ECN_SET_CE)
+		iph->tos |= INET_ECN_CE;
+
 	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
 	qp->q.fragments = NULL;
 	qp->q.fragments_tail = NULL;



^ permalink raw reply related

* [PATCH v3 00/10] net/fec: add dual fec support for i.MX28
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig

This patch series is to add dual fec support for mx28, which is
a mxs-based soc. Some code changes related to the following commits
are also made in this patch set for some reasons.

 e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
 netdev/fec.c: add phylib supporting to enable carrier detection (v2)

 e3fe8558c7fc182972c3d947d88744482111f304
 net/fec: fix pm to survive to suspend/resume

It's been tested on mx28 evk and mx51 babbage. For mx28, it has
to work against the tree

 git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38

plus patch

 [PATCH v4] ARM: mxs: Change duart device to use amba-pl011

Changes for v3:
 - Move v2 changes on patch #5 to #3
 - Use device name to detect the running of mx28 fec controller
   naming ENET-MAC

The 3 patches below preceding with * have changes since v2, and
the detailed change log can be found in individual patch.

 [PATCH v3 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
 [PATCH v3 02/10] net/fec: remove the use of "index" which is legacy
*[PATCH v3 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
 [PATCH v3 04/10] net/fec: improve pm for better suspend/resume
*[PATCH v3 05/10] net/fec: add dual fec support for mx28
*[PATCH v3 06/10] ARM: mx28: update clock and device name for dual fec support
 [PATCH v3 07/10] ARM: mx28: add the second fec device registration
 [PATCH v3 08/10] ARM: mxs: add ocotp read function
 [PATCH v3 09/10] ARM: mx28: read fec mac address from ocotp
 [PATCH v3 10/10] ARM: mxs: add initial pm support

Thanks for the review.

Regards,
Shawn


^ permalink raw reply

* [PATCH v3 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

FEC_MMFR_OP_WRITE should be used than FEC_MMFR_OP_READ in
a mdio write operation.

It's probably a typo introduced by commit:

e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
netdev/fec.c: add phylib supporting to enable carrier detection (v2)

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index cce32d4..52e9ca8 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -651,8 +651,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 	fep->mii_timeout = 0;
 	init_completion(&fep->mdio_done);
 
-	/* start a read op */
-	writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+	/* start a write op */
+	writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
 		FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
 		FEC_MMFR_TA | FEC_MMFR_DATA(value),
 		fep->hwp + FEC_MII_DATA);
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

Add mac field into fec_platform_data and consolidate function
fec_get_mac to get mac address in following order.

 1) module parameter via kernel command line fec.macaddr=0x00,0x04,...
 2) from flash in case of CONFIG_M5272 or fec_platform_data mac
    field for others, which typically have mac stored in fuse
 3) fec mac address registers set by bootloader

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Use module parameter than new kernel command line to pass
   mac address
 - Change variable name and comment to remove confusing word
   "default"
 - Fix copyright breakage in fec.h

 drivers/net/fec.c   |   81 ++++++++++++++++++++++++---------------------------
 include/linux/fec.h |    3 ++
 2 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47f6b3b..47a3c7b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -59,15 +59,11 @@
 #define FEC_ALIGNMENT	0x3
 #endif
 
-/*
- * Define the fixed address of the FEC hardware.
- */
-#if defined(CONFIG_M5272)
-
-static unsigned char	fec_mac_default[] = {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+static unsigned char macaddr[ETH_ALEN];
+module_param_array(macaddr, byte, NULL, 0);
+MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
 
+#if defined(CONFIG_M5272)
 /*
  * Some hardware gets it MAC address out of local flash memory.
  * if this is non-zero then assume it is the address to get MAC from.
@@ -537,37 +533,50 @@ rx_processing_done:
 }
 
 /* ------------------------------------------------------------------------- */
-#ifdef CONFIG_M5272
 static void __inline__ fec_get_mac(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	unsigned char *iap, tmpaddr[ETH_ALEN];
 
-	if (FEC_FLASHMAC) {
-		/*
-		 * Get MAC address from FLASH.
-		 * If it is all 1's or 0's, use the default.
-		 */
-		iap = (unsigned char *)FEC_FLASHMAC;
-		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-			iap = fec_mac_default;
-		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
-		    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
-			iap = fec_mac_default;
-	} else {
-		*((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
-		*((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
+	/*
+	 * try to get mac address in following order:
+	 *
+	 * 1) module parameter via kernel command line in form
+	 *    fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0
+	 */
+	iap = macaddr;
+
+	/*
+	 * 2) from flash or fuse (via platform data)
+	 */
+	if (!is_valid_ether_addr(iap)) {
+#ifdef CONFIG_M5272
+		if (FEC_FLASHMAC)
+			iap = (unsigned char *)FEC_FLASHMAC;
+#else
+		if (pdata)
+			memcpy(iap, pdata->mac, ETH_ALEN);
+#endif
+	}
+
+	/*
+	 * 3) FEC mac registers set by bootloader
+	 */
+	if (!is_valid_ether_addr(iap)) {
+		*((unsigned long *) &tmpaddr[0]) =
+			be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));
+		*((unsigned short *) &tmpaddr[4]) =
+			be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
 		iap = &tmpaddr[0];
 	}
 
 	memcpy(dev->dev_addr, iap, ETH_ALEN);
 
-	/* Adjust MAC if using default MAC address */
-	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
+	/* Adjust MAC if using macaddr */
+	if (iap == macaddr)
+		 dev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id;
 }
-#endif
 
 /* ------------------------------------------------------------------------- */
 
@@ -1087,22 +1096,8 @@ static int fec_enet_init(struct net_device *dev)
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
-	/* Set the Ethernet address */
-#ifdef CONFIG_M5272
+	/* Get the Ethernet address */
 	fec_get_mac(dev);
-#else
-	{
-		unsigned long l;
-		l = readl(fep->hwp + FEC_ADDR_LOW);
-		dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
-		dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
-		dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
-		dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
-		l = readl(fep->hwp + FEC_ADDR_HIGH);
-		dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
-		dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
-	}
-#endif
 
 	/* Set receive and transmit descriptor base. */
 	fep->rx_bd_base = cbd_base;
diff --git a/include/linux/fec.h b/include/linux/fec.h
index 5d3523d..bcff455 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -3,6 +3,8 @@
  * Copyright (c) 2009 Orex Computed Radiography
  *   Baruch Siach <baruch@tkos.co.il>
  *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
  * Header file for the FEC platform data
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,6 +18,7 @@
 
 struct fec_platform_data {
 	phy_interface_t phy;
+	unsigned char mac[ETH_ALEN];
 };
 
 #endif
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 02/10] net/fec: remove the use of "index" which is legacy
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

The "index" becomes legacy since fep->pdev->id starts working
to identify the instance.

Moreover, the call of fec_enet_init(ndev, 0) always passes 0
to fep->index. This makes the following code in fec_get_mac buggy.

	/* Adjust MAC if using default MAC address */
	if (iap == fec_mac_default)
		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;

It may be the time to remove "index" and use fep->pdev->id instead.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 52e9ca8..47f6b3b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -186,7 +186,6 @@ struct fec_enet_private {
 	int     mii_timeout;
 	uint    phy_speed;
 	phy_interface_t	phy_interface;
-	int	index;
 	int	link;
 	int	full_duplex;
 	struct	completion mdio_done;
@@ -566,7 +565,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
 
 	/* Adjust MAC if using default MAC address */
 	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
 }
 #endif
 
@@ -1067,9 +1066,8 @@ static const struct net_device_ops fec_netdev_ops = {
  /*
   * XXX:  We need to clean up on failure exits here.
   *
-  * index is only used in legacy code
   */
-static int fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	struct bufdesc *cbd_base;
@@ -1086,7 +1084,6 @@ static int fec_enet_init(struct net_device *dev, int index)
 
 	spin_lock_init(&fep->hw_lock);
 
-	fep->index = index;
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
@@ -1316,7 +1313,7 @@ fec_probe(struct platform_device *pdev)
 	}
 	clk_enable(fep->clk);
 
-	ret = fec_enet_init(ndev, 0);
+	ret = fec_enet_init(ndev);
 	if (ret)
 		goto failed_init;
 
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 04/10] net/fec: improve pm for better suspend/resume
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

The following commit made a fix to use fec_enet_open/fec_enet_close
over fec_enet_init/fec_stop for suspend/resume, because fec_enet_init
does not allow to have a working network interface at resume.

  e3fe8558c7fc182972c3d947d88744482111f304
  net/fec: fix pm to survive to suspend/resume

This fix works for i.mx/mxc fec controller, but fails on mx28 fec
which gets a different interrupt logic design. On i.mx fec, interrupt
can be triggered even bit ETHER_EN of ECR register is not set. But
on mx28 fec, ETHER_EN must be set to get interrupt work. Meanwhile,
MII interrupt is mandatory to resume the driver, because MDIO
read/write changed to interrupt mode by commit below.

  97b72e4320a9aaa4a7f1592ee7d2da7e2c9bd349
  fec: use interrupt for MDIO completion indication

fec_restart/fec_stop comes out as the solution working for both
cases.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 drivers/net/fec.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47a3c7b..8a1c51f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1372,8 +1372,10 @@ fec_suspend(struct device *dev)
 
 	if (ndev) {
 		fep = netdev_priv(ndev);
-		if (netif_running(ndev))
-			fec_enet_close(ndev);
+		if (netif_running(ndev)) {
+			fec_stop(ndev);
+			netif_device_detach(ndev);
+		}
 		clk_disable(fep->clk);
 	}
 	return 0;
@@ -1388,8 +1390,10 @@ fec_resume(struct device *dev)
 	if (ndev) {
 		fep = netdev_priv(ndev);
 		clk_enable(fep->clk);
-		if (netif_running(ndev))
-			fec_enet_open(ndev);
+		if (netif_running(ndev)) {
+			fec_restart(ndev, fep->full_duplex);
+			netif_device_attach(ndev);
+		}
 	}
 	return 0;
 }
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 05/10] net/fec: add dual fec support for mx28
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

This patch is to add mx28 dual fec support. Here are some key notes
for mx28 fec controller.

 - The mx28 fec controller naming ENET-MAC is a different IP from FEC
   used on other i.mx variants.  But they are basically compatible
   on software interface, so it's possible to share the same driver.
 - ENET-MAC design made an improper assumption that it runs on a
   big-endian system. As the result, driver has to swap every frame
   going to and coming from the controller.
 - The external phys can only be configured by fec0, which means fec1
   can not work independently and both phys need to be configured by
   mii_bus attached on fec0.
 - ENET-MAC reset will get mac address registers reset too.
 - ENET-MAC MII/RMII mode and 10M/100M speed are configured
   differently FEC.
 - ETHER_EN bit must be set to get ENET-MAC interrupt work.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Move v2 changes into patch #3
 - Use device name to check if it's running on ENET-MAC

 drivers/net/Kconfig |    7 ++-
 drivers/net/fec.c   |  140 +++++++++++++++++++++++++++++++++++++++++++++------
 drivers/net/fec.h   |    5 +-
 3 files changed, 131 insertions(+), 21 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f1755b..f34629b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1944,18 +1944,19 @@ config 68360_ENET
 config FEC
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
-		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
+		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
 	select PHYLIB
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
 
 config FEC2
-	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
+	bool "Second FEC ethernet controller"
 	depends on FEC
 	help
 	  Say Y here if you want to use the second built-in 10/100 Fast
-	  ethernet controller on some Motorola ColdFire processors.
+	  ethernet controller on some Motorola ColdFire and Freescale
+	  i.MX processors.
 
 config FEC_MPC52xx
 	tristate "MPC52xx FEC driver"
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 8a1c51f..67ba263 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -17,6 +17,8 @@
  *
  * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
  * Copyright (c) 2004-2006 Macq Electronique SA.
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
  */
 
 #include <linux/module.h>
@@ -45,20 +47,33 @@
 
 #include <asm/cacheflush.h>
 
-#ifndef CONFIG_ARCH_MXC
+#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_SOC_IMX28)
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #endif
 
 #include "fec.h"
 
-#ifdef CONFIG_ARCH_MXC
-#include <mach/hardware.h>
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 #define FEC_ALIGNMENT	0xf
 #else
 #define FEC_ALIGNMENT	0x3
 #endif
 
+#define DRIVER_NAME	"fec"
+#define ENET_MAC_NAME	"enet-mac"
+
+static struct platform_device_id fec_devtype[] = {
+	{
+		.name = DRIVER_NAME,
+	}, {
+		.name = ENET_MAC_NAME,
+	}
+};
+
+static unsigned fec_is_enetmac;
+static struct mii_bus *fec_mii_bus;
+
 static unsigned char macaddr[ETH_ALEN];
 module_param_array(macaddr, byte, NULL, 0);
 MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -129,7 +144,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
  * account when setting it.
  */
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -208,6 +224,17 @@ static void fec_stop(struct net_device *dev);
 /* Transmitter timeout */
 #define TX_TIMEOUT (2 * HZ)
 
+static void *swap_buffer(void *bufaddr, int len)
+{
+	int i;
+	unsigned int *buf = bufaddr;
+
+	for (i = 0; i < (len + 3) / 4; i++, buf++)
+		*buf = __swab32(*buf);
+
+	return bufaddr;
+}
+
 static netdev_tx_t
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -256,6 +283,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		bufaddr = fep->tx_bounce[index];
 	}
 
+	/*
+	 * enet-mac design made an improper assumption that it's running
+	 * on a big endian system. As the result, driver has to swap
+	 * every frame going to and coming from the controller.
+	 */
+	if (fec_is_enetmac)
+		swap_buffer(bufaddr, skb->len);
+
 	/* Save skb pointer */
 	fep->tx_skbuff[fep->skb_cur] = skb;
 
@@ -487,6 +522,9 @@ fec_enet_rx(struct net_device *dev)
 	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
         			DMA_FROM_DEVICE);
 
+		if (fec_is_enetmac)
+			swap_buffer(data, pkt_len);
+
 		/* This does 16 byte alignment, exactly what we need.
 		 * The packet length includes FCS, but we don't want to
 		 * include that when passing upstream as it messes up
@@ -689,6 +727,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
 	char mdio_bus_id[MII_BUS_ID_SIZE];
 	char phy_name[MII_BUS_ID_SIZE + 3];
 	int phy_id;
+	int dev_id = fep->pdev->id;
 
 	fep->phy_dev = NULL;
 
@@ -700,6 +739,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
 			continue;
 		if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
 			continue;
+		if (fec_is_enetmac && dev_id--)
+			continue;
 		strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
 		break;
 	}
@@ -741,6 +782,28 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	struct fec_enet_private *fep = netdev_priv(dev);
 	int err = -ENXIO, i;
 
+	/*
+	 * The dual fec interfaces are not equivalent with enet-mac.
+	 * Here are the differences:
+	 *
+	 *  - fec0 supports MII & RMII modes while fec1 only supports RMII
+	 *  - fec0 acts as the 1588 time master while fec1 is slave
+	 *  - external phys can only be configured by fec0
+	 *
+	 * That is to say fec1 can not work independently. It only works
+	 * when fec0 is working. The reason behind this design is that the
+	 * second interface is added primarily for Switch mode.
+	 *
+	 * Because of the last point above, both phys are attached on fec0
+	 * mdio interface in board design, and need to be configured by
+	 * fec0 mii_bus.
+	 */
+	if (fec_is_enetmac && pdev->id) {
+		/* fec1 uses fec0 mii_bus */
+		fep->mii_bus = fec_mii_bus;
+		return 0;
+	}
+
 	fep->mii_timeout = 0;
 
 	/*
@@ -777,6 +840,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	if (mdiobus_register(fep->mii_bus))
 		goto err_out_free_mdio_irq;
 
+	/* save fec0 mii_bus */
+	if (fec_is_enetmac)
+		fec_mii_bus = fep->mii_bus;
+
 	return 0;
 
 err_out_free_mdio_irq:
@@ -1149,11 +1216,22 @@ fec_restart(struct net_device *dev, int duplex)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	int i;
+	u32 val, temp_mac[2];
 
 	/* Whack a reset.  We should wait for this. */
 	writel(1, fep->hwp + FEC_ECNTRL);
 	udelay(10);
 
+	/*
+	 * enet-mac reset will reset mac address registers too,
+	 * so need to reconfigure it.
+	 */
+	if (fec_is_enetmac) {
+		memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
+		writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
+		writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
+	}
+
 	/* Clear any outstanding interrupt. */
 	writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
@@ -1200,20 +1278,45 @@ fec_restart(struct net_device *dev, int duplex)
 	/* Set MII speed */
 	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
-#ifdef FEC_MIIGSK_ENR
-	if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
-		/* disable the gasket and wait */
-		writel(0, fep->hwp + FEC_MIIGSK_ENR);
-		while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
-			udelay(1);
+	/*
+	 * The phy interface and speed need to get configured
+	 * differently on enet-mac.
+	 */
+	if (fec_is_enetmac) {
+		val = readl(fep->hwp + FEC_R_CNTRL);
 
-		/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
-		writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+		/* MII or RMII */
+		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+			val |= (1 << 8);
+		else
+			val &= ~(1 << 8);
 
-		/* re-enable the gasket */
-		writel(2, fep->hwp + FEC_MIIGSK_ENR);
-	}
+		/* 10M or 100M */
+		if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
+			val &= ~(1 << 9);
+		else
+			val |= (1 << 9);
+
+		writel(val, fep->hwp + FEC_R_CNTRL);
+	} else {
+#ifdef FEC_MIIGSK_ENR
+		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
+			/* disable the gasket and wait */
+			writel(0, fep->hwp + FEC_MIIGSK_ENR);
+			while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
+				udelay(1);
+
+			/*
+			 * configure the gasket:
+			 *   RMII, 50 MHz, no loopback, no echo
+			 */
+			writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+
+			/* re-enable the gasket */
+			writel(2, fep->hwp + FEC_MIIGSK_ENR);
+		}
 #endif
+	}
 
 	/* And last, enable the transmit and receive processing */
 	writel(2, fep->hwp + FEC_ECNTRL);
@@ -1301,6 +1404,10 @@ fec_probe(struct platform_device *pdev)
 		}
 	}
 
+	/* check if it's ENET-MAC controller via device name */
+	if (!strcmp(pdev->name, ENET_MAC_NAME))
+		fec_is_enetmac = 1;
+
 	fep->clk = clk_get(&pdev->dev, "fec_clk");
 	if (IS_ERR(fep->clk)) {
 		ret = PTR_ERR(fep->clk);
@@ -1410,12 +1517,13 @@ static const struct dev_pm_ops fec_pm_ops = {
 
 static struct platform_driver fec_driver = {
 	.driver	= {
-		.name	= "fec",
+		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
 #ifdef CONFIG_PM
 		.pm	= &fec_pm_ops,
 #endif
 	},
+	.id_table = fec_devtype,
 	.probe	= fec_probe,
 	.remove	= __devexit_p(fec_drv_remove),
 };
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 2c48b25..ace318d 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,8 @@
 /****************************************************************************/
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
@@ -78,7 +79,7 @@
 /*
  *	Define the buffer descriptor structure.
  */
-#ifdef CONFIG_ARCH_MXC
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
 struct bufdesc {
 	unsigned short cbd_datlen;	/* Data length */
 	unsigned short cbd_sc;	/* Control and status info */
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 06/10] ARM: mx28: update clock and device name for dual fec support
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

Change device name from "fec" to "enet-mac", so that fec driver
can distinguish ENET-MAC controller from FEC.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Change device name to "enet-mac"

 arch/arm/mach-mxs/clock-mx28.c           |    3 ++-
 arch/arm/mach-mxs/devices/platform-fec.c |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index f20b254..933d3e6 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
 	/* for amba-pl011 driver */
 	_REGISTER_CLOCK("duart", NULL, uart_clk)
-	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("enet-mac.0", NULL, fec_clk)
+	_REGISTER_CLOCK("enet-mac.1", NULL, fec_clk)
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c08168c..754bd83 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
 		},
 	};
 
-	return mxs_add_platform_device("fec", data->id,
+	return mxs_add_platform_device("enet-mac", data->id,
 			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 08/10] ARM: mxs: add ocotp read function
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Add mutex locking for mxs_read_ocotp()
 - Use type size_t for count and i
 - Add comment for clk_enable/disable skipping
 - Add ERROR bit clearing and polling step

 arch/arm/mach-mxs/Makefile              |    2 +-
 arch/arm/mach-mxs/include/mach/common.h |    1 +
 arch/arm/mach-mxs/ocotp.c               |   79 +++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-mxs/ocotp.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..f23ebbd 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,5 +1,5 @@
 # Common support
-obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
 
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..cf02552 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
 
 struct clk;
 
+extern int mxs_read_ocotp(int offset, int count, u32 *values);
 extern int mxs_reset_block(void __iomem *);
 extern void mxs_timer_init(struct clk *, int);
 
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..902ef59
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define BM_OCOTP_CTRL_BUSY		(1 << 8)
+#define BM_OCOTP_CTRL_ERROR		(1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+
+int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
+{
+	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+	int timeout = 0x400;
+	size_t i;
+
+	mutex_lock(&ocotp_mutex);
+
+	/*
+	 * clk_enable(hbus_clk) for ocotp can be skipped
+	 * as it must be on when system is running.
+	 */
+
+	/* try to clear ERROR bit */
+	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+	/* check both BUSY and ERROR cleared */
+	while ((__raw_readl(ocotp_base) &
+		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+		/* nothing */;
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	/* open OCOTP banks for read */
+	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	/* approximately wait 32 hclk cycles */
+	udelay(1);
+
+	/* poll BUSY bit becoming cleared */
+	timeout = 0x400;
+	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+		/* nothing */;
+
+	if (unlikely(!timeout))
+		goto error_unlock;
+
+	for (i = 0; i < count; i++, offset += 4)
+		*values++ = __raw_readl(ocotp_base + offset);
+
+	/* close banks for power saving */
+	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+	mutex_unlock(&ocotp_mutex);
+
+	return 0;
+
+error_unlock:
+	mutex_unlock(&ocotp_mutex);
+	pr_err("%s: timeout in reading OCOTP\n", __func__);
+	return -ETIMEDOUT;
+}
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 07/10] ARM: mx28: add the second fec device registration
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx28evk.c |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..def6519 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET |
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	/* fec1 */
+	MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_COL__ENET1_TX_EN |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
 	/* phy power line */
 	MX28_PAD_SSP1_DATA3__GPIO_2_15 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
 
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
-	.phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+	{
+		/* fec0 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	}, {
+		/* fec1 */
+		.phy = PHY_INTERFACE_MODE_RMII,
+	},
 };
 
 static void __init mx28evk_init(void)
@@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
 	mx28_add_duart();
 
 	mx28evk_fec_reset();
-	mx28_add_fec(0, &mx28_fec_pdata);
+	mx28_add_fec(0, &mx28_fec_pdata[0]);
+#ifdef CONFIG_FEC2
+	mx28_add_fec(1, &mx28_fec_pdata[1]);
+#endif
 }
 
 static void __init mx28evk_timer_init(void)
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 10/10] ARM: mxs: add initial pm support
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Let build of pm.c depend on CONFIG_PM
 - Remove the blank line above device_initcall in pm.c

 arch/arm/mach-mxs/Makefile |    2 ++
 arch/arm/mach-mxs/pm.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/pm.c

diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index f23ebbd..45a2925 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
 # Common support
 obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
 
+obj-$(CONFIG_PM) += pm.o
+
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		arch_idle();
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+	.enter = mxs_suspend_enter,
+	.valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+	suspend_set_ops(&mxs_suspend_ops);
+	return 0;
+}
+device_initcall(mxs_pm_init);
-- 
1.7.1



^ permalink raw reply related

* [PATCH v3 09/10] ARM: mx28: read fec mac address from ocotp
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
  To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
	u.kleine-koenig
  Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>

Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - It's not necessary to remove "const" for fec_platform_data from
   platform-fec.c and devices-common.h, so add it back.
 - Hard-coding Freescale OUI (00:04:9f) instead of just the first
   two two octets.
 - Correct the return of mx28evk_fec_get_mac() and check it
   with caller

 arch/arm/mach-mxs/mach-mx28evk.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index def6519..54fa512 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
 	},
 };
 
+static int __init mx28evk_fec_get_mac(void)
+{
+	int i, ret;
+	u32 val;
+
+	/*
+	 * OCOTP only stores the last 4 octets for each mac address,
+	 * so hard-code Freescale OUI (00:04:9f) here.
+	 */
+	for (i = 0; i < 2; i++) {
+		ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
+		if (ret)
+			goto error;
+
+		mx28_fec_pdata[i].mac[0] = 0x00;
+		mx28_fec_pdata[i].mac[1] = 0x04;
+		mx28_fec_pdata[i].mac[2] = 0x9f;
+		mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+		mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+		mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+	}
+
+	return 0;
+
+error:
+	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+	return ret;
+}
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	if (mx28evk_fec_get_mac())
+		pr_warn("%s: failed on fec mac setup\n", __func__);
+
 	mx28evk_fec_reset();
 	mx28_add_fec(0, &mx28_fec_pdata[0]);
 #ifdef CONFIG_FEC2
-- 
1.7.1



^ permalink raw reply related

* [PATCH v2] netfilter: fix the race when initializing nf_ct_expect_hash_rnd
From: Changli Gao @ 2011-01-05 14:23 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, David S. Miller, netdev, Changli Gao

Since nf_ct_expect_dst_hash() may be called without nf_conntrack_lock
locked, nf_ct_expect_hash_rnd should be initialized in the atomic way.

In this patch, we use nf_conntrack_hash_rnd instead of
nf_ct_expect_hash_rnd.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
v2: use nf_conntrack_hash_rnd.
 include/net/netfilter/nf_conntrack.h |    2 ++
 net/netfilter/nf_conntrack_core.c    |   30 +++++++++++++++++-------------
 net/netfilter/nf_conntrack_expect.c  |   10 +++-------
 3 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index caf17db..d85cff1 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -298,6 +298,8 @@ static inline int nf_ct_is_untracked(const struct nf_conn *ct)
 extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
 extern unsigned int nf_conntrack_htable_size;
 extern unsigned int nf_conntrack_max;
+extern unsigned int nf_conntrack_hash_rnd;
+void init_nf_conntrack_hash_rnd(void);
 
 #define NF_CT_STAT_INC(net, count)	\
 	__this_cpu_inc((net)->ct.stat->count)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 27a5ea6..e615119 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max);
 DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
 EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
 
-static unsigned int nf_conntrack_hash_rnd __read_mostly;
+unsigned int nf_conntrack_hash_rnd __read_mostly;
 
 static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone)
 {
@@ -596,6 +596,21 @@ static noinline int early_drop(struct net *net, unsigned int hash)
 	return dropped;
 }
 
+void init_nf_conntrack_hash_rnd(void)
+{
+	unsigned int rand;
+
+	/*
+	 * Why not initialize nf_conntrack_rnd in a "init()" function ?
+	 * Because there isn't enough entropy when system initializing,
+	 * and we initialize it as late as possible.
+	 */
+	do {
+		get_random_bytes(&rand, sizeof(rand));
+	} while (!rand);
+	cmpxchg(&nf_conntrack_hash_rnd, 0, rand);
+}
+
 static struct nf_conn *
 __nf_conntrack_alloc(struct net *net, u16 zone,
 		     const struct nf_conntrack_tuple *orig,
@@ -605,18 +620,7 @@ __nf_conntrack_alloc(struct net *net, u16 zone,
 	struct nf_conn *ct;
 
 	if (unlikely(!nf_conntrack_hash_rnd)) {
-		unsigned int rand;
-
-		/*
-		 * Why not initialize nf_conntrack_rnd in a "init()" function ?
-		 * Because there isn't enough entropy when system initializing,
-		 * and we initialize it as late as possible.
-		 */
-		do {
-			get_random_bytes(&rand, sizeof(rand));
-		} while (!rand);
-		cmpxchg(&nf_conntrack_hash_rnd, 0, rand);
-
+		init_nf_conntrack_hash_rnd();
 		/* recompute the hash as nf_conntrack_hash_rnd is initialized */
 		hash = hash_conntrack_raw(orig, zone);
 	}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 46e8966..a20fb0b 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -32,9 +32,7 @@
 unsigned int nf_ct_expect_hsize __read_mostly;
 EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
 
-static unsigned int nf_ct_expect_hash_rnd __read_mostly;
 unsigned int nf_ct_expect_max __read_mostly;
-static int nf_ct_expect_hash_rnd_initted __read_mostly;
 
 static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
 
@@ -77,15 +75,13 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
 {
 	unsigned int hash;
 
-	if (unlikely(!nf_ct_expect_hash_rnd_initted)) {
-		get_random_bytes(&nf_ct_expect_hash_rnd,
-				 sizeof(nf_ct_expect_hash_rnd));
-		nf_ct_expect_hash_rnd_initted = 1;
+	if (unlikely(!nf_conntrack_hash_rnd)) {
+		init_nf_conntrack_hash_rnd();
 	}
 
 	hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
 		      (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
-		       (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd);
+		       (__force __u16)tuple->dst.u.all) ^ nf_conntrack_hash_rnd);
 	return ((u64)hash * nf_ct_expect_hsize) >> 32;
 }
 

^ permalink raw reply related

* Re: linux-next: manual merge of the trivial tree with the net tree
From: Jiri Kosina @ 2011-01-05 14:51 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: linux-next, linux-kernel, Justin P. Mattock, Wey-Yi Guy,
	John W. Linville, David Miller, netdev
In-Reply-To: <20110104142229.7aa6b99f.sfr@canb.auug.org.au>

On Tue, 4 Jan 2011, Stephen Rothwell wrote:

> Today's linux-next merge of the trivial tree got a conflict in
> drivers/net/wireless/iwlwifi/iwl-core.c between commit
> 81baf6ec9c190ae128748cf2a026bff5cb811b70 ("iwlwifi: Legacy isr only used
> by legacy devices") from the net tree and commit
> 62e45c14fb9a978dca6c7a5dc8372cc8ea2f42c8 ("wireless: comment typo fix
> diable -> disable") from the trivial tree.
> 
> The former moves the code modified by the latter to
> drivers/net/wireless/iwlwifi/iwl-legacy.c. I didn't bother refixing the
> typo there.

I will definitely be merging to Linus trivial queue later than davem will, 
so I'll be resolving this. Thanks,

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ 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