Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net: reduce net_rx_action() latency to 2 HZ
From: Willy Tarreau @ 2013-03-24  1:02 UTC (permalink / raw)
  To: Paul Gortmaker
  Cc: Eric Dumazet, David Miller, netdev, stable, Tom Herbert,
	Steven Rostedt
In-Reply-To: <514B429C.5070605@windriver.com>

On Thu, Mar 21, 2013 at 01:25:48PM -0400, Paul Gortmaker wrote:
> On 13-03-21 11:27 AM, Eric Dumazet wrote:
> > On Thu, 2013-03-21 at 11:03 -0400, Paul Gortmaker wrote:
> >> [CC'ing stable & Willy - for the older releases not fed by
> >> http://patchwork.ozlabs.org/bundle/davem/stable/ ]
> >>
> >> On Tue, Mar 5, 2013 at 12:15 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> >>> From: Eric Dumazet <edumazt@google.com>
> >>>
> >>> We should use time_after_eq() to get maximum latency of two ticks,
> >>> instead of three.
> >>>
> >>> Bug added in commit 24f8b2385 (net: increase receive packet quantum)
> >>
> >> I'm not sure what applications would notice the extra tick, but 24f8b takes
> >> us back to 2.6.29.  It cherry picks cleanly onto 2.6.34, so it probably also
> >> does the same for Willy's 2.6.32 longterm too.
> >>
> >> Commit is now mainline d114a3338747255518 - v3.9-rc3~36^2~34.
> > 
> > BQL (Bytes Queue Limit) relies on TX completion being run often, and
> > Qdisc being serviced often as well. If net_rx_action() hogs the cpu,
> > net_tx_action() is delayed and NIC can stall.
> > 
> > I wrote this patch because I was investigating a regression when a
> > Google application began using BQL enabled kernels.
> > 
> > About the latency in itself, following commit is way more interesting.
> > 
> > commit c10d73671ad30f5 (softirq: reduce latencies)
> > 
> > As without it, I could trigger more than 50ms latencies for the poor
> > user thread interrupted by softirq processing.
> 
> That is also reasonably portable back to 2.6.34.  And it is more
> interesting too -- it will be interesting in a preempt_rt context
> too, once RT moves ahead off the current 3.6 baseline, which still
> has the old count-limit of 10 vs the new 2ms time limit.
> 
> RT (3.4 and 3.6 based) currently has this patch from Steven:
> http://git.kernel.org/cgit/linux/kernel/git/paulg/3.6-rt-patches.git/tree/net-tx-action-avoid-livelock-on-rt.patch
> 
> Anyway, thanks for the heads up on this commit.

And thanks to you Paul for the heads up as well, I'll pick them from
your branch :-)

Cheers,
Willy

^ permalink raw reply

* Re: Atheros Communications Inc. AR8121/AR8113/AR8114 Gigabit or Fast Ethernet (rev b0) 1.0.0.7 md5/sha1 corrupted using NFS and samba (updated) Version 2
From: Sven Hartge @ 2013-03-24  0:36 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20130323150655.GA10779@order.stressinduktion.org>

Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
> On Sat, Mar 23, 2013 at 12:54:25AM -0400, rebelyouth wrote:
>> I applied your patch on my the kernel 3.7.9 and look like the patch do 
>> what you said before :
>> 
>> "This does not solve the real problem, which I have not yet understood 
>> (wrong packets will be discarded now and will be hopefully resend). "
>> 
>> There are errors on the RX side of the server and the speed is 5~10% 
>> less but the files are ok in nfsv4 , SFTP/FTP and samba.
>> 
>> Maybe the Atheros drivers for windows had a patch for the checksum 
>> already in the drivers and the chipset  have some hardware bug, but for 
>> me your patch is already an achievement and I really thank you for your 
>> time and consideration.

> The upstream driver (which is a tarball I found with google
> AR81Family-linux-v1.0.1.14.tar.gz) has this function ifdefed out. I have
> a couple of more things I want to test as soon as I have access to the
> hardware again.  If I don't find a better solution I will submit a patch
> which disables rx checksumming as a whole for inclusion to net-next.

I remember having the some problem with an atl1e chip on my Asus
PQ5-Pro. It would corrupt ethernet frames, resulting in dropped
connections when using SSH (bailing out with a HMAC crypto error) etc.

After some conversations with an Atheros engineer (Jie Yang
<Jie.Yang@Atheros.com>) I got the following patch, which I applied for
some time to my local Debian kernel packages. It fixed the problem for
me, until I switched the board to a newer one.

As far as I understand, this patch rips out any checksumming function
and just advertises the chip as not using and providing any.

My mail archive indicates, this bug has been fixed in the upstream atl1e
driver since version l1c-linux-v1.0.0.11-test.tar.gz.

diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 9fc6d6d..73d44d5 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1343,29 +1343,8 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
 {
       u8 *packet = (u8 *)(prrs + 1);
       struct iphdr *iph;
-      u16 head_len = ETH_HLEN;
-      u16 pkt_flags;
-      u16 err_flags;
 
       skb->ip_summed = CHECKSUM_NONE;
-      pkt_flags = prrs->pkt_flag;
-      err_flags = prrs->err_flag;
-      if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
-              ((pkt_flags & RRS_IS_TCP) || (pkt_flags & RRS_IS_UDP))) {
-              if (pkt_flags & RRS_IS_IPV4) {
-                      if (pkt_flags & RRS_IS_802_3)
-                              head_len += 8;
-                      iph = (struct iphdr *) (packet + head_len);
-                      if (iph->frag_off != 0 && !(pkt_flags & RRS_IS_IP_DF))
-                              goto hw_xsum;
-              }
-              if (!(err_flags & (RRS_ERR_IP_CSUM | RRS_ERR_L4_CSUM))) {
-                      skb->ip_summed = CHECKSUM_UNNECESSARY;
-                      return;
-              }
-      }
-
-hw_xsum :
       return;
 }
 



-- 
Sigmentation fault. Core dumped.

^ permalink raw reply related

* Re: Missing TCP SYN on loopback, retransmits after 1s
From: Jason Oster @ 2013-03-24  0:08 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: jlyo, netdev, davem
In-Reply-To: <B0544E9D-BC59-449D-88A5-6DAFCB676F91@gmail.com>

Hi again,

Resending this; it didn't make it to the netdev list.

On Mar 23, 2013, at 12:17 PM, Jason Oster <parasytic@gmail.com> wrote:

> Hello Eric,
> 
> Thank you for looking into this so quickly! And it sounds like promising news, too. I'll experiment with newer kernels right away.
> 
> Thanks again,
> Jay


FYI net-next may have some changes not available in 3.9.0-rc3, because I can still reproduce it there:

$ uname -a
Linux test 3.9.0-030900rc3-generic #201303171935 SMP Sun Mar 17 23:36:17 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

This is from the Ubuntu kernel mainline PPA (on Raring Ringtail-dev). I haven't built the kernel yet.

^ permalink raw reply

* Re: [PATCH] Fix IXP4xx coherent allocations
From: David Miller @ 2013-03-23 23:57 UTC (permalink / raw)
  To: khc; +Cc: netdev, linux-arm-kernel, linux-kernel, c.aeschlimann
In-Reply-To: <m3obe9lxil.fsf@intrepid.localdomain>

From: Krzysztof Halasa <khc@pm.waw.pl>
Date: Sat, 23 Mar 2013 20:35:46 +0100

> ARM core code currently requires coherent DMA mask to be set. Make sure
> we limit PCI devices to 64 MiB while allowing on-chip devices to access
> the whole 4 GiB address space.
> 
> This fixes a v3.7+ regression which broke IXP4xx built-in network devices.
> 
> Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>

This requirement is not reasonable.

The DMA API documentation clearly states what the default must be,
and what drivers are guarenteed will be the default.

^ permalink raw reply

* Re: [PATCH] bnx2x: fix assignment of signed expression to unsigned variable
From: David Miller @ 2013-03-23 23:56 UTC (permalink / raw)
  To: gmate.amit; +Cc: eilong, netdev, linux-kernel, kernel-janitors
In-Reply-To: <1364064775-19319-1-git-send-email-gmate.amit@gmail.com>

From: Kumar Amit Mehta <gmate.amit@gmail.com>
Date: Sat, 23 Mar 2013 11:52:55 -0700

> fix for incorrect assignment of signed expression to unsigned variable.
> 
> Signed-off-by: Kumar Amit Mehta <gmate.amit@gmail.com>

Returning positive error codes is just as broken as what is there
currently.

These routines should return 0 or 1, the return value isn't even used
in any way, it is just tested against zero.

^ permalink raw reply

* Re: [PATCH net-next] ptp: increase the maximum number of clocks
From: David Miller @ 2013-03-23 23:53 UTC (permalink / raw)
  To: richardcochran; +Cc: jbenc, netdev
In-Reply-To: <20130323175915.GA3036@netboy.at.omicron.at>

From: Richard Cochran <richardcochran@gmail.com>
Date: Sat, 23 Mar 2013 18:59:15 +0100

> On Thu, Mar 21, 2013 at 05:20:17PM -0400, David Miller wrote:
>> 
>> This really needs to be dynamic, and it shows what a bad idea it was
>> to use character drivers for this which introduces arbitrary device
>> arity limitations.
> 
> If a clock is not a character device, what then should it be? Network
> interface?  Block device?  sysfs apparition?
> 
> IIRC, the RTCs appear as char devices. In any case, we are better off
> with char devices than with an enumeration of SYSV clock IDs.

It should be an abstract device created/deleted/changed by netlink
operations.

Then there are no limitations.  PTP devices are then referened by
string names, rather than some bogus set of character device minor
numbers which have no meaning and have arbitrary limitations
wrt. arity.

If, in theory, we can have as many PTP devices as network devices,
we damn well better be able to create as many PTP devices as
network devices.

That means they must have the same capabilities as far as how many
of them you can create.

^ permalink raw reply

* Re: [PATCH net-next] ip_gre: increase inner ip header ID only for IPv4
From: Pravin Shelar @ 2013-03-23 23:36 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, Eric Dumazet, David S. Miller
In-Reply-To: <1364016584-7189-1-git-send-email-amwang@redhat.com>

On Fri, Mar 22, 2013 at 10:29 PM, Cong Wang <amwang@redhat.com> wrote:
> From: Cong Wang <amwang@redhat.com>
>
> Pravin pointed out the inner network header of a GRE tunnel packet
> could be IPv6, where there is no ID. So we should check the version.
>

inet_gso_segment() already increment ip-header identification. What is
problem with that?


> Cc: Pravin B Shelar <pshelar@nicira.com>
> Cc: Eric Dumazet <edumazet@google.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Signed-off-by: Cong Wang <amwang@redhat.com>
>
> ---
> diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
> index e20631c..a2516f5 100644
> --- a/net/ipv4/gre.c
> +++ b/net/ipv4/gre.c
> @@ -128,7 +128,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
>         struct iphdr *iph;
>         int mac_len = skb->mac_len;
>         int tnl_hlen, id;
> -       bool csum;
> +       bool csum, ipv4;
>
>         if (unlikely(skb_shinfo(skb)->gso_type &
>                                 ~(SKB_GSO_TCPV4 |
> @@ -172,7 +172,12 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
>         skb->mac_len = skb_inner_network_offset(skb);
>
>         iph = ip_hdr(skb);
> -       id = ntohs(iph->id);
> +       if (iph->version == 4) {
> +               ipv4 = true;
> +               id = ntohs(iph->id);
> +       } else
> +               ipv4 = false;
> +
>         /* segment inner packet. */
>         enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
>         segs = skb_mac_gso_segment(skb, enc_features);
> @@ -182,8 +187,10 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
>         skb = segs;
>         tnl_hlen = skb_tnl_header_len(skb);
>         do {
> -               iph = (struct iphdr *)skb->data;
> -               iph->id = htons(id++);
> +               if (ipv4) {
> +                       iph = (struct iphdr *)skb->data;
> +                       iph->id = htons(id++);
> +               }
>                 __skb_push(skb, ghl);
>                 if (csum) {
>                         __be32 *pcsum;

^ permalink raw reply

* [PATCHv2 0/5] ARM: sunxi: Add support for A10 Ethernet controller
From: Maxime Ripard @ 2013-03-23 22:30 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kevin, sunny, shuge, netdev, Stefan Roese, Alejandro Mery

Hi,

The Allwinner A10 SoC has an ethernet controller that seem to be specific to
Allwinner. This IP has no public documentation, so exact
details are quite sparse, and this code come from refactored Allwinner
code.

Since we don't have any clock support yet for the Allwinner SoCs, we
rely on the bootloader to enable and gate the EMAC clock.

Thanks,
Maxime

Changes from v1:
  - Use phylib for the phy-related functions
  - Use an optional regulator to power up the phy
  - Rename the driver from Davicom Wemac to Allwinner EMAC, since it's the name
    mentionned in the datasheet, and we have no strong evidence of a
    relationship with Davicom
  - Fix various small things around the driver: add defines for undocumented
    values, fix documentation name and compatible example, etc.

Maxime Ripard (3):
  ARM: sunxi: Add EMAC controller node to sun4i DTSI
  ARM: sun4i: Add muxing options for the ethernet controller
  ARM: hackberry: dt: Add Ethernet controller to the Hackberry device
    tree

Stefan Roese (2):
  net: Add EMAC ethernet driver found on Allwinner A10 SoC's
  ARM: cubieboard: Enable ethernet (WEMAC) support in dts

 .../bindings/net/allwinner,sun4i-emac.txt          |   19 +
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts         |    6 +
 arch/arm/boot/dts/sun4i-a10-hackberry.dts          |   32 +
 arch/arm/boot/dts/sun4i-a10.dtsi                   |   18 +
 drivers/net/ethernet/Kconfig                       |    1 +
 drivers/net/ethernet/Makefile                      |    1 +
 drivers/net/ethernet/allwinner/Kconfig             |   36 +
 drivers/net/ethernet/allwinner/Makefile            |    5 +
 drivers/net/ethernet/allwinner/sun4i-emac.c        | 1033 ++++++++++++++++++++
 drivers/net/ethernet/allwinner/sun4i-emac.h        |  114 +++
 10 files changed, 1265 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
 create mode 100644 drivers/net/ethernet/allwinner/Kconfig
 create mode 100644 drivers/net/ethernet/allwinner/Makefile
 create mode 100644 drivers/net/ethernet/allwinner/sun4i-emac.c
 create mode 100644 drivers/net/ethernet/allwinner/sun4i-emac.h

-- 
1.7.10.4

^ permalink raw reply

* [PATCH 5/5] ARM: hackberry: dt: Add Ethernet controller to the Hackberry device tree
From: Maxime Ripard @ 2013-03-23 22:30 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kevin, sunny, shuge, netdev, Stefan Roese, Alejandro Mery,
	Russell King, linux-kernel
In-Reply-To: <1364077814-2233-1-git-send-email-maxime.ripard@free-electrons.com>

The Hackberry has a PHY that needs to be powered up through a GPIO, so
we need to use a fixed regulator here.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun4i-a10-hackberry.dts |   32 +++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
index f84549a..072d51f 100644
--- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts
+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -23,8 +23,40 @@
 	};
 
 	soc {
+		pio: pinctrl@01c20800 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&hackberry_hogs>;
+
+			hackberry_hogs: hogs@0 {
+				allwinner,pins = "PH19";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+
 		uart0: uart@01c28000 {
 			status = "okay";
 		};
+
+		emac: ethernet@01c0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&emac_pins_a>;
+			phy-supply = <&reg_emac_3v3>;
+			status = "okay";
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_emac_3v3: emac-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "emac-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			enable-active-high;
+			gpio = <&pio 7 19 0>;
+		};
 	};
 };
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 4/5] ARM: cubieboard: Enable ethernet (WEMAC) support in dts
From: Maxime Ripard @ 2013-03-23 22:30 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kevin, sunny, shuge, netdev, Stefan Roese, Alejandro Mery,
	Russell King, linux-kernel
In-Reply-To: <1364077814-2233-1-git-send-email-maxime.ripard@free-electrons.com>

From: Stefan Roese <sr@denx.de>

Signed-off-by: Stefan Roese <sr@denx.de>
---
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 88e2dc1..9bf4b4f 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -43,6 +43,12 @@
 		uart1: uart@01c28400 {
 			status = "okay";
 		};
+
+		emac: ethernet@01c0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&emac_pins_a>;
+			status = "okay";
+		};
 	};
 
 	leds {
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3/5] ARM: sun4i: Add muxing options for the ethernet controller
From: Maxime Ripard @ 2013-03-23 22:30 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kevin, sunny, shuge, netdev, Stefan Roese, Alejandro Mery,
	Russell King, linux-kernel
In-Reply-To: <1364077814-2233-1-git-send-email-maxime.ripard@free-electrons.com>

The EMAC only has one pinset available for muxing, so hopefully, we
cover all cases.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index a6bd36a..e5ef5e5 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -46,6 +46,17 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			emac_pins_a: emac0@0 {
+				allwinner,pins = "PA0", "PA1", "PA2",
+						"PA3", "PA4", "PA5", "PA6",
+						"PA7", "PA8", "PA9", "PA10",
+						"PA11", "PA12", "PA13", "PA14",
+						"PA15", "PA16";
+				allwinner,function = "wemac";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		emac: ethernet@01c0b000 {
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 2/5] ARM: sunxi: Add EMAC controller node to sun4i DTSI
From: Maxime Ripard @ 2013-03-23 22:30 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kevin, sunny, shuge, netdev, Stefan Roese, Alejandro Mery,
	Russell King, linux-kernel
In-Reply-To: <1364077814-2233-1-git-send-email-maxime.ripard@free-electrons.com>

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 03d2b53..a6bd36a 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -47,5 +47,12 @@
 				allwinner,pull = <0>;
 			};
 		};
+
+		emac: ethernet@01c0b000 {
+			compatible = "allwinner,sun4i-emac";
+			reg = <0x01c0b000 0x1000>;
+			interrupts = <55>;
+			status = "disabled";
+		};
 	};
 };
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 1/5] net: Add EMAC ethernet driver found on Allwinner A10 SoC's
From: Maxime Ripard @ 2013-03-23 22:30 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kevin, sunny, shuge, netdev, Stefan Roese, Alejandro Mery,
	Grant Likely, Rob Herring, Rob Landley, devicetree-discuss,
	linux-doc, linux-kernel
In-Reply-To: <1364077814-2233-1-git-send-email-maxime.ripard@free-electrons.com>

From: Stefan Roese <sr@denx.de>

The Allwinner A10 has an ethernet controller that seem to be developped
internally by them.

The exact feature set of this controller is unknown, since there is no
public documentation for this IP, and this driver is mostly the one
published by Allwinner that has been heavily cleaned up.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 .../bindings/net/allwinner,sun4i-emac.txt          |   19 +
 drivers/net/ethernet/Kconfig                       |    1 +
 drivers/net/ethernet/Makefile                      |    1 +
 drivers/net/ethernet/allwinner/Kconfig             |   36 +
 drivers/net/ethernet/allwinner/Makefile            |    5 +
 drivers/net/ethernet/allwinner/sun4i-emac.c        | 1033 ++++++++++++++++++++
 drivers/net/ethernet/allwinner/sun4i-emac.h        |  114 +++
 7 files changed, 1209 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
 create mode 100644 drivers/net/ethernet/allwinner/Kconfig
 create mode 100644 drivers/net/ethernet/allwinner/Makefile
 create mode 100644 drivers/net/ethernet/allwinner/sun4i-emac.c
 create mode 100644 drivers/net/ethernet/allwinner/sun4i-emac.h

diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
new file mode 100644
index 0000000..aaf5013
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
@@ -0,0 +1,19 @@
+* Allwinner EMAC ethernet controller
+
+Required properties:
+- compatible: should be "allwinner,sun4i-emac".
+- reg: address and length of the register set for the device.
+- interrupts: interrupt for the device
+
+Optional properties:
+- phy-supply: phandle to a regulator if the PHY needs one
+- (local-)mac-address: mac address to be used by this driver
+
+Example:
+
+emac: ethernet@01c0b000 {
+       compatible = "allwinner,sun4i-emac";
+       reg = <0x01c0b000 0x1000>;
+       phy-supply = <&reg_emac_3v3>;
+       interrupts = <55>;
+};
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ed956e0..18fd6fb 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -20,6 +20,7 @@ config SUNGEM_PHY
 source "drivers/net/ethernet/3com/Kconfig"
 source "drivers/net/ethernet/adaptec/Kconfig"
 source "drivers/net/ethernet/aeroflex/Kconfig"
+source "drivers/net/ethernet/allwinner/Kconfig"
 source "drivers/net/ethernet/alteon/Kconfig"
 source "drivers/net/ethernet/amd/Kconfig"
 source "drivers/net/ethernet/apple/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 8268d85..009da27 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_VENDOR_3COM) += 3com/
 obj-$(CONFIG_NET_VENDOR_8390) += 8390/
 obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
 obj-$(CONFIG_GRETH) += aeroflex/
+obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/
 obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
 obj-$(CONFIG_NET_VENDOR_AMD) += amd/
 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
diff --git a/drivers/net/ethernet/allwinner/Kconfig b/drivers/net/ethernet/allwinner/Kconfig
new file mode 100644
index 0000000..5d20fb0
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/Kconfig
@@ -0,0 +1,36 @@
+#
+# Allwinner device configuration
+#
+
+config NET_VENDOR_ALLWINNER
+       bool "Allwinner devices"
+       default y
+       depends on ARCH_SUNXI
+       ---help---
+         If you have a network (Ethernet) card belonging to this
+	 class, say Y and read the Ethernet-HOWTO, available from
+	 <http://www.tldp.org/docs.html#howto>.
+
+	 Note that the answer to this question doesn't directly
+	 affect the kernel: saying N will just cause the configurator
+	 to skip all the questions about Davicom cards. If you say Y,
+	 you will be asked for your specific card in the following
+	 questions.
+
+if NET_VENDOR_ALLWINNER
+
+config SUN4I_EMAC
+        tristate "Allwinner A10 EMAC support"
+	depends on ARCH_SUNXI
+	depends on OF
+	select CRC32
+	select NET_CORE
+	select MII
+	select REGULATOR_FIXED_VOLTAGE
+        ---help---
+          Support for Allwinner A10 EMAC ethernet driver.
+
+          To compile this driver as a module, choose M here.  The module
+          will be called sun4i-emac.
+
+endif # NET_VENDOR_ALLWINNER
diff --git a/drivers/net/ethernet/allwinner/Makefile b/drivers/net/ethernet/allwinner/Makefile
new file mode 100644
index 0000000..03129f7
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Allwinner device drivers.
+#
+
+obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
new file mode 100644
index 0000000..66bc089
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -0,0 +1,1033 @@
+/*
+ * Allwinner EMAC Fast Ethernet driver for Linux.
+ *
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997  Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+#include <linux/regulator/consumer.h>
+
+#include "sun4i-emac.h"
+
+#define DRV_NAME		"sun4i-emac"
+#define DRV_VERSION		"1.02"
+
+#define EMAC_MAX_FRAME_LEN	0x0600
+
+/* Transmit timeout, default 5 seconds. */
+static int watchdog = 5000;
+module_param(watchdog, int, 0400);
+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+
+/* EMAC register address locking.
+ *
+ * The EMAC uses an address register to control where data written
+ * to the data register goes. This means that the address register
+ * must be preserved over interrupts or similar calls.
+ *
+ * During interrupt and other critical calls, a spinlock is used to
+ * protect the system, but the calls themselves save the address
+ * in the address register in case they are interrupting another
+ * access to the device.
+ *
+ * For general accesses a lock is provided so that calls which are
+ * allowed to sleep are serialised so that the address register does
+ * not need to be saved. This lock also serves to serialise access
+ * to the EEPROM and PHY access registers which are shared between
+ * these two devices.
+ */
+
+/* The driver supports the original EMACE, and now the two newer
+ * devices, EMACA and EMACB.
+ */
+
+struct emac_board_info {
+	struct clk		*clk;
+	struct device		*dev;
+	struct platform_device	*pdev;
+	spinlock_t		lock;
+	void __iomem		*membase;
+	u32			msg_enable;
+	struct net_device	*ndev;
+	struct regulator	*regulator;
+	struct sk_buff		*skb_last;
+	u16			tx_fifo_stat;
+
+	int			emacrx_completed_flag;
+
+	struct mii_bus		*mii_bus;
+	struct phy_device	*phy_dev;
+	unsigned int		link;
+	unsigned int		speed;
+	unsigned int		duplex;
+
+	phy_interface_t		phy_interface;
+};
+
+static int emac_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+	struct emac_board_info *db = bus->priv;
+	int value;
+
+	/* issue the phy address and reg */
+	writel((mii_id << 8) | regnum, db->membase + EMAC_MAC_MADR_REG);
+	/* pull up the phy io line */
+	writel(0x1, db->membase + EMAC_MAC_MCMD_REG);
+
+	/* Wait read complete */
+	while (readl(db->membase + EMAC_MAC_MIND_REG) & 0x1)
+		cpu_relax();
+
+	/* push down the phy io line */
+	writel(0x0, db->membase + EMAC_MAC_MCMD_REG);
+	/* and read data */
+	value = readl(db->membase + EMAC_MAC_MRDD_REG);
+
+	return value;
+}
+
+static int emac_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+			    u16 value)
+{
+	struct emac_board_info *db = bus->priv;
+
+	/* issue the phy address and reg */
+	writel((mii_id << 8) | regnum, db->membase + EMAC_MAC_MADR_REG);
+	/* pull up the phy io line */
+	writel(0x1, db->membase + EMAC_MAC_MCMD_REG);
+
+	/* Wait read complete */
+	while (readl(db->membase + EMAC_MAC_MIND_REG) & 0x1)
+		cpu_relax();
+
+	/* push down the phy io line */
+	writel(0x0, db->membase + EMAC_MAC_MCMD_REG);
+	/* and write data */
+	writel(value, db->membase + EMAC_MAC_MWTD_REG);
+
+	return 0;
+}
+
+static int emac_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+
+static void emac_init_emac(struct net_device *dev);
+static void emac_handle_link_change(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	struct phy_device *phydev = db->phy_dev;
+	unsigned long flags;
+	int status_change = 0;
+
+	spin_lock_irqsave(&db->lock, flags);
+
+	if (phydev->link) {
+		if ((db->speed != phydev->speed) ||
+		    (db->duplex != phydev->duplex)) {
+			/* Re-init EMAC with new settings */
+			emac_init_emac(dev);
+
+			db->speed = phydev->speed;
+			db->duplex = phydev->duplex;
+			status_change = 1;
+		}
+	}
+
+	if (phydev->link != db->link) {
+		if (!phydev->link) {
+			db->speed = 0;
+			db->duplex = -1;
+		}
+		db->link = phydev->link;
+
+		status_change = 1;
+	}
+
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	if (status_change)
+		phy_print_status(phydev);
+}
+
+static int emac_mii_probe(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	struct phy_device *phydev;
+	int ret;
+
+	phydev = phy_find_first(db->mii_bus);
+	if (!phydev) {
+		netdev_err(dev, "no PHY found\n");
+		return -1;
+	}
+
+	/* to-do: PHY interrupts are currently not supported */
+
+	/* attach the mac to the phy */
+	ret = phy_connect_direct(dev, phydev, &emac_handle_link_change,
+				 db->phy_interface);
+	if (ret) {
+		netdev_err(dev, "Could not attach to PHY\n");
+		return ret;
+	}
+
+	/* mask with MAC supported features */
+	phydev->supported &= PHY_BASIC_FEATURES;
+	phydev->advertising = phydev->supported;
+
+	db->link = 0;
+	db->speed = 0;
+	db->duplex = -1;
+	db->phy_dev = phydev;
+
+	return 0;
+}
+
+int emac_mii_init(struct emac_board_info *db)
+{
+	int err = -ENXIO;
+	int i;
+
+	if (!IS_ERR(db->regulator))
+		regulator_enable(db->regulator);
+
+	db->mii_bus = mdiobus_alloc();
+	if (db->mii_bus == NULL) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	db->mii_bus->name = "EMAC_mii_bus";
+	db->mii_bus->read = &emac_mdio_read;
+	db->mii_bus->write = &emac_mdio_write;
+	db->mii_bus->reset = &emac_mdio_reset;
+	snprintf(db->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+		 db->pdev->name, db->pdev->id);
+	db->mii_bus->priv = db;
+	db->mii_bus->parent = &db->pdev->dev;
+
+	db->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!db->mii_bus->irq) {
+		err = -ENOMEM;
+		goto err_out_free_mdiobus;
+	}
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		db->mii_bus->irq[i] = PHY_POLL;
+
+	if (mdiobus_register(db->mii_bus))
+		goto err_out_free_mdio_irq;
+
+	if (emac_mii_probe(db->ndev) != 0)
+		goto err_out_unregister_bus;
+
+	return 0;
+
+err_out_unregister_bus:
+	mdiobus_unregister(db->mii_bus);
+err_out_free_mdio_irq:
+	kfree(db->mii_bus->irq);
+err_out_free_mdiobus:
+	mdiobus_free(db->mii_bus);
+err_out:
+	return err;
+}
+
+static void emac_reset(struct emac_board_info *db)
+{
+	dev_dbg(db->dev, "resetting device\n");
+
+	/* RESET device */
+	writel(0, db->membase + EMAC_CTL_REG);
+	udelay(200);
+	writel(EMAC_CTL_RESET, db->membase + EMAC_CTL_REG);
+	udelay(200);
+}
+
+static void emac_outblk_32bit(void __iomem *reg, void *data, int count)
+{
+	writesl(reg, data, round_up(count, 4) / 4);
+}
+
+static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
+{
+	readsl(reg, data, round_up(count, 4) / 4);
+}
+
+static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct emac_board_info *dm = netdev_priv(dev);
+	struct phy_device *phydev = dm->phy_dev;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_mii_ioctl(phydev, rq, cmd);
+}
+
+/* ethtool ops */
+static void emac_get_drvinfo(struct net_device *dev,
+			      struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, DRV_NAME, sizeof(DRV_NAME));
+	strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
+	strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info));
+}
+
+static int emac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct emac_board_info *dm = netdev_priv(dev);
+	struct phy_device *phydev = dm->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_gset(phydev, cmd);
+}
+
+static int emac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct emac_board_info *dm = netdev_priv(dev);
+	struct phy_device *phydev = dm->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_sset(phydev, cmd);
+}
+
+static const struct ethtool_ops emac_ethtool_ops = {
+	.get_drvinfo	= emac_get_drvinfo,
+	.get_settings	= emac_get_settings,
+	.set_settings	= emac_set_settings,
+	.get_link	= ethtool_op_get_link,
+};
+
+unsigned int emac_setup(struct net_device *ndev)
+{
+	unsigned int reg_val;
+	struct emac_board_info *db = netdev_priv(ndev);
+
+	/* set up TX */
+	reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+
+	writel(reg_val | EMAC_TX_MODE_ABORTED_FRAME_EN,
+		db->membase + EMAC_TX_MODE_REG);
+
+	/* set up RX */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+
+	writel(reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN |
+		EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN |
+		EMAC_RX_CTL_ACCEPT_MULTICAST_EN |
+		EMAC_RX_CTL_ACCEPT_BROADCAST_EN,
+		db->membase + EMAC_RX_CTL_REG);
+
+	/* set MAC */
+	/* set MAC CTL0 */
+	reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
+	writel(reg_val | EMAC_MAC_CTL0_RX_FLOW_CTL_EN |
+		EMAC_MAC_CTL0_TX_FLOW_CTL_EN,
+		db->membase + EMAC_MAC_CTL0_REG);
+
+	/* set MAC CTL1 */
+	reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
+	reg_val |= EMAC_MAC_CTL1_LEN_CHECK_EN;
+	reg_val |= EMAC_MAC_CTL1_CRC_EN;
+	reg_val |= EMAC_MAC_CTL1_PAD_EN;
+	writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
+
+	/* set up IPGT */
+	writel(EMAC_MAC_IPGT_FULL_DUPLEX, db->membase + EMAC_MAC_IPGT_REG);
+
+	/* set up IPGR */
+	writel((EMAC_MAC_IPGR_IPG1 << 8) | EMAC_MAC_IPGR_IPG2,
+		db->membase + EMAC_MAC_IPGR_REG);
+
+	/* set up Collison window */
+	writel((EMAC_MAC_CLRT_COLLISION_WINDOW << 8) | EMAC_MAC_CLRT_RM,
+		db->membase + EMAC_MAC_CLRT_REG);
+
+	/* set up Max Frame Length */
+	writel(EMAC_MAX_FRAME_LEN,
+		db->membase + EMAC_MAC_MAXF_REG);
+
+	return 0;
+}
+
+unsigned int emac_powerup(struct net_device *ndev)
+{
+	struct emac_board_info *db = netdev_priv(ndev);
+	unsigned int reg_val;
+
+	/* initial EMAC */
+	/* flush RX FIFO */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+	reg_val |= 0x8;
+	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+	udelay(1);
+
+	/* initial MAC */
+	/* soft reset MAC */
+	reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
+	reg_val &= ~EMAC_MAC_CTL0_SOFT_RESET;
+	writel(reg_val, db->membase + EMAC_MAC_CTL0_REG);
+
+	/* set MII clock */
+	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
+	reg_val &= (~(0xf << 2));
+	reg_val |= (0xD << 2);
+	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
+
+	/* clear RX counter */
+	writel(0x0, db->membase + EMAC_RX_FBC_REG);
+
+	/* disable all interrupt and clear interrupt status */
+	writel(0, db->membase + EMAC_INT_CTL_REG);
+	reg_val = readl(db->membase + EMAC_INT_STA_REG);
+	writel(reg_val, db->membase + EMAC_INT_STA_REG);
+
+	udelay(1);
+
+	/* set up EMAC */
+	emac_setup(ndev);
+
+	/* set mac_address to chip */
+	writel(ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev->
+	       dev_addr[2], db->membase + EMAC_MAC_A1_REG);
+	writel(ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev->
+	       dev_addr[5], db->membase + EMAC_MAC_A0_REG);
+
+	mdelay(1);
+
+	return 1;
+}
+
+static int emac_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	struct emac_board_info *db = netdev_priv(dev);
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	writel(dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev->
+	       dev_addr[2], db->membase + EMAC_MAC_A1_REG);
+	writel(dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev->
+	       dev_addr[5], db->membase + EMAC_MAC_A0_REG);
+
+	return 0;
+}
+
+/* Initialize emac board */
+static void emac_init_emac(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned int reg_val;
+
+	/* set EMAC SPEED, depend on PHY  */
+	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
+	reg_val &= ~(0x1 << 8);
+	if (db->speed == SPEED_100)
+		reg_val |= 1 << 8;
+	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
+
+	/* set duplex depend on phy */
+	reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
+	reg_val &= ~EMAC_MAC_CTL1_DUPLEX_EN;
+	if (db->duplex)
+		reg_val |= EMAC_MAC_CTL1_DUPLEX_EN;
+	writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
+
+	/* enable RX/TX */
+	reg_val = readl(db->membase + EMAC_CTL_REG);
+	writel(reg_val | EMAC_CTL_RESET | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN,
+		db->membase + EMAC_CTL_REG);
+
+	/* enable RX/TX0/RX Hlevel interrup */
+	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+	reg_val |= (0xf << 0) | (0x01 << 8);
+	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+}
+
+/* Our watchdog timed out. Called by the networking layer */
+static void emac_timeout(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned long flags;
+
+	if (netif_msg_timer(db))
+		dev_err(db->dev, "tx time out.\n");
+
+	/* Save previous register address */
+	spin_lock_irqsave(&db->lock, flags);
+
+	netif_stop_queue(dev);
+	emac_reset(db);
+	emac_init_emac(dev);
+	/* We can accept TX packets again */
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+
+	/* Restore previous register address */
+	spin_unlock_irqrestore(&db->lock, flags);
+}
+
+/* Hardware start transmission.
+ * Send a packet to media from the upper layer.
+ */
+static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned long channel;
+	unsigned long flags;
+
+	channel = db->tx_fifo_stat & 3;
+	if (channel == 3)
+		return NETDEV_TX_BUSY;
+
+	channel = (channel == 1 ? 1 : 0);
+
+	spin_lock_irqsave(&db->lock, flags);
+
+	writel(channel, db->membase + EMAC_TX_INS_REG);
+
+	emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
+			skb->data, skb->len);
+	dev->stats.tx_bytes += skb->len;
+
+	db->tx_fifo_stat |= 1 << channel;
+	/* TX control: First packet immediately send, second packet queue */
+	if (channel == 0) {
+		/* set TX len */
+		writel(skb->len, db->membase + EMAC_TX_PL0_REG);
+		/* start translate from fifo to phy */
+		writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
+		       db->membase + EMAC_TX_CTL0_REG);
+
+		/* save the time stamp */
+		dev->trans_start = jiffies;
+	} else if (channel == 1) {
+		/* set TX len */
+		writel(skb->len, db->membase + EMAC_TX_PL1_REG);
+		/* start translate from fifo to phy */
+		writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
+		       db->membase + EMAC_TX_CTL1_REG);
+
+		/* save the time stamp */
+		dev->trans_start = jiffies;
+	}
+
+	if ((db->tx_fifo_stat & 3) == 3) {
+		/* Second packet */
+		netif_stop_queue(dev);
+	}
+
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	/* free this SKB */
+	dev_kfree_skb(skb);
+
+	return NETDEV_TX_OK;
+}
+
+/* EMAC interrupt handler
+ * receive the packet to upper layer, free the transmitted packet
+ */
+static void emac_tx_done(struct net_device *dev, struct emac_board_info *db,
+			  unsigned int tx_status)
+{
+	/* One packet sent complete */
+	db->tx_fifo_stat &= ~(tx_status & 3);
+	if (3 == (tx_status & 3))
+		dev->stats.tx_packets += 2;
+	else
+		dev->stats.tx_packets++;
+
+	if (netif_msg_tx_done(db))
+		dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
+
+	netif_wake_queue(dev);
+}
+
+/* Received a packet and pass to upper layer
+ */
+static void emac_rx(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	struct sk_buff *skb;
+	u8 *rdptr;
+	bool good_packet;
+	static int rxlen_last;
+	unsigned int reg_val;
+	u32 rxhdr, rxstatus, rxcount, rxlen;
+
+	/* Check packet ready or not */
+	while (1) {
+		/* race warning: the first packet might arrive with
+		 * the interrupts disabled, but the second will fix
+		 * it
+		 */
+		rxcount = readl(db->membase + EMAC_RX_FBC_REG);
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "RXCount: %x\n", rxcount);
+
+		if ((db->skb_last != NULL) && (rxlen_last > 0)) {
+			dev->stats.rx_bytes += rxlen_last;
+
+			/* Pass to upper layer */
+			db->skb_last->protocol = eth_type_trans(db->skb_last,
+								dev);
+			netif_rx(db->skb_last);
+			dev->stats.rx_packets++;
+			db->skb_last = NULL;
+			rxlen_last = 0;
+
+			reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+			reg_val &= ~EMAC_RX_CTL_DMA_EN;
+			writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+		}
+
+		if (!rxcount) {
+			db->emacrx_completed_flag = 1;
+			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+			reg_val |= (0xf << 0) | (0x01 << 8);
+			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+			/* had one stuck? */
+			rxcount = readl(db->membase + EMAC_RX_FBC_REG);
+			if (!rxcount)
+				return;
+		}
+
+		reg_val = readl(db->membase + EMAC_RX_IO_DATA_REG);
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "receive header: %x\n", reg_val);
+		if (reg_val != EMAC_UNDOCUMENTED_MAGIC) {
+			/* disable RX */
+			reg_val = readl(db->membase + EMAC_CTL_REG);
+			writel(reg_val & ~EMAC_CTL_RX_EN,
+			       db->membase + EMAC_CTL_REG);
+
+			/* Flush RX FIFO */
+			reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+			writel(reg_val | (1 << 3),
+			       db->membase + EMAC_RX_CTL_REG);
+
+			do {
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+			} while (reg_val & (1 << 3));
+
+			/* enable RX */
+			reg_val = readl(db->membase + EMAC_CTL_REG);
+			writel(reg_val | EMAC_CTL_RX_EN,
+			       db->membase + EMAC_CTL_REG);
+			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+			reg_val |= (0xf << 0) | (0x01 << 8);
+			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+			db->emacrx_completed_flag = 1;
+
+			return;
+		}
+
+		/* A packet ready now  & Get status/length */
+		good_packet = true;
+
+		emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+				&rxhdr, sizeof(rxhdr));
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "rxhdr: %x\n", *((int *)(&rxhdr)));
+
+		rxlen = EMAC_RX_IO_DATA_LEN(rxhdr);
+		rxstatus = EMAC_RX_IO_DATA_STATUS(rxhdr);
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "RX: status %02x, length %04x\n",
+				rxstatus, rxlen);
+
+		/* Packet Status check */
+		if (rxlen < 0x40) {
+			good_packet = false;
+			if (netif_msg_rx_err(db))
+				dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
+		}
+
+		if (unlikely(!(rxstatus & EMAC_RX_IO_DATA_STATUS_OK))) {
+			good_packet = false;
+
+			if (rxstatus & EMAC_RX_IO_DATA_STATUS_CRC_ERR) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "crc error\n");
+				dev->stats.rx_crc_errors++;
+			}
+
+			if (rxstatus & EMAC_RX_IO_DATA_STATUS_LEN_ERR) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "length error\n");
+				dev->stats.rx_length_errors++;
+			}
+		}
+
+		/* Move data from EMAC */
+		skb = dev_alloc_skb(rxlen + 4);
+		if (good_packet && skb) {
+			skb_reserve(skb, 2);
+			rdptr = (u8 *) skb_put(skb, rxlen - 4);
+
+			/* Read received packet from RX SRAM */
+			if (netif_msg_rx_status(db))
+				dev_dbg(db->dev, "RxLen %x\n", rxlen);
+
+			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+					rdptr, rxlen);
+			dev->stats.rx_bytes += rxlen;
+
+			/* Pass to upper layer */
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			dev->stats.rx_packets++;
+		}
+	}
+}
+
+static irqreturn_t emac_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct emac_board_info *db = netdev_priv(dev);
+	int int_status;
+	unsigned long flags;
+	unsigned int reg_val;
+
+	/* A real interrupt coming */
+
+	/* holders of db->lock must always block IRQs */
+	spin_lock_irqsave(&db->lock, flags);
+
+	/* Disable all interrupts */
+	writel(0, db->membase + EMAC_INT_CTL_REG);
+
+	/* Got EMAC interrupt status */
+	/* Got ISR */
+	int_status = readl(db->membase + EMAC_INT_STA_REG);
+	/* Clear ISR status */
+	writel(int_status, db->membase + EMAC_INT_STA_REG);
+
+	if (netif_msg_intr(db))
+		dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
+
+	/* Received the coming packet */
+	if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
+		/* carrier lost */
+		db->emacrx_completed_flag = 0;
+		emac_rx(dev);
+	}
+
+	/* Transmit Interrupt check */
+	if (int_status & (0x01 | 0x02))
+		emac_tx_done(dev, db, int_status);
+
+	if (int_status & (0x04 | 0x08))
+		netdev_info(dev, " ab : %x\n", int_status);
+
+	/* Re-enable interrupt mask */
+	if (db->emacrx_completed_flag == 1) {
+		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+		reg_val |= (0xf << 0) | (0x01 << 8);
+		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+	}
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Used by netconsole
+ */
+static void emac_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	emac_interrupt(dev->irq, dev);
+	enable_irq(dev->irq);
+}
+#endif
+
+/*  Open the interface.
+ *  The interface is opened whenever "ifconfig" actives it.
+ */
+static int emac_open(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+
+	if (netif_msg_ifup(db))
+		dev_dbg(db->dev, "enabling %s\n", dev->name);
+
+	if (devm_request_irq(db->dev, dev->irq, &emac_interrupt,
+			     0, dev->name, dev))
+		return -EAGAIN;
+
+	/* Initialize EMAC board */
+	emac_reset(db);
+	emac_init_emac(dev);
+
+	phy_start(db->phy_dev);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static void emac_shutdown(struct net_device *dev)
+{
+	unsigned int reg_val;
+	struct emac_board_info *db = netdev_priv(dev);
+
+	/* Disable all interrupt */
+	writel(0, db->membase + EMAC_INT_CTL_REG);
+
+	/* clear interupt status */
+	reg_val = readl(db->membase + EMAC_INT_STA_REG);
+	writel(reg_val, db->membase + EMAC_INT_STA_REG);
+
+	/* Disable RX/TX */
+	reg_val = readl(db->membase + EMAC_CTL_REG);
+	reg_val &= ~(EMAC_CTL_TX_EN | EMAC_CTL_RX_EN | EMAC_CTL_RESET);
+	writel(reg_val, db->membase + EMAC_CTL_REG);
+}
+
+/* Stop the interface.
+ * The interface is stopped when it is brought.
+ */
+static int emac_stop(struct net_device *ndev)
+{
+	struct emac_board_info *db = netdev_priv(ndev);
+
+	if (netif_msg_ifdown(db))
+		dev_dbg(db->dev, "shutting down %s\n", ndev->name);
+
+	netif_stop_queue(ndev);
+	netif_carrier_off(ndev);
+
+	emac_shutdown(ndev);
+
+	return 0;
+}
+
+static const struct net_device_ops emac_netdev_ops = {
+	.ndo_open		= emac_open,
+	.ndo_stop		= emac_stop,
+	.ndo_start_xmit		= emac_start_xmit,
+	.ndo_tx_timeout		= emac_timeout,
+	.ndo_do_ioctl		= emac_ioctl,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= emac_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= emac_poll_controller,
+#endif
+};
+
+/* Search EMAC board, allocate space and register it
+ */
+static int emac_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct emac_board_info *db;
+	struct net_device *ndev;
+	int ret = 0;
+	const char *mac_addr;
+
+	ndev = alloc_etherdev(sizeof(struct emac_board_info));
+	if (!ndev) {
+		dev_err(&pdev->dev, "could not allocate device.\n");
+		return -ENOMEM;
+	}
+
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	db = netdev_priv(ndev);
+	memset(db, 0, sizeof(*db));
+
+	db->dev = &pdev->dev;
+	db->ndev = ndev;
+	db->pdev = pdev;
+
+	spin_lock_init(&db->lock);
+
+	db->membase = of_iomap(np, 0);
+	if (!db->membase) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		return -ENOMEM;
+		goto out;
+	}
+
+	/* fill in parameters for net-dev structure */
+	ndev->base_addr = (unsigned long)db->membase;
+	ndev->irq = irq_of_parse_and_map(np, 0);
+	if (ndev->irq == -ENXIO) {
+		netdev_err(ndev, "No irq resource\n");
+		ret = ndev->irq;
+		goto out;
+	}
+
+	/* Read MAC-address from DT */
+	mac_addr = of_get_mac_address(np);
+	if (mac_addr)
+		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+
+	/* Check if the MAC address is valid, if not get a random one */
+	if (!is_valid_ether_addr(ndev->dev_addr)) {
+		eth_hw_addr_random(ndev);
+		dev_warn(&pdev->dev, "using random MAC address %pM\n",
+			 ndev->dev_addr);
+	}
+
+	db->regulator = devm_regulator_get(&pdev->dev, "phy");
+	if(IS_ERR(db->regulator)) {
+		if(PTR_ERR(db->regulator) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+
+		dev_info(&pdev->dev, "no regulator found\n");
+	}
+
+	db->emacrx_completed_flag = 1;
+	emac_powerup(ndev);
+	emac_reset(db);
+
+	ether_setup(ndev);
+
+	ndev->netdev_ops = &emac_netdev_ops;
+	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+	ndev->ethtool_ops = &emac_ethtool_ops;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	ndev->poll_controller = &emac_poll_controller;
+#endif
+
+	platform_set_drvdata(pdev, ndev);
+
+	ret = emac_mii_init(db);
+	if (ret) {
+		dev_err(&pdev->dev, "MII init failed!\n");
+		goto out;
+	}
+
+	/* Carrier starts down, phylib will bring it up */
+	netif_carrier_off(ndev);
+
+	ret = register_netdev(ndev);
+	if (ret) {
+		dev_err(&pdev->dev, "Registering netdev failed!\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n",
+		 ndev->name, db->membase, ndev->irq, ndev->dev_addr);
+
+	return 0;
+
+out:
+	dev_err(db->dev, "not found (%d).\n", ret);
+
+	free_netdev(ndev);
+
+	return ret;
+}
+
+static int emac_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct emac_board_info *db = netdev_priv(ndev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	regulator_disable(db->regulator);
+
+	unregister_netdev(ndev);
+	free_netdev(ndev);
+
+	dev_dbg(&pdev->dev, "released and freed device\n");
+	return 0;
+}
+
+static int emac_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+
+	netif_carrier_off(ndev);
+	netif_device_detach(ndev);
+	emac_shutdown(ndev);
+
+	return 0;
+}
+
+static int emac_resume(struct platform_device *dev)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+	struct emac_board_info *db = netdev_priv(ndev);
+
+	emac_reset(db);
+	emac_init_emac(ndev);
+	netif_device_attach(ndev);
+
+	return 0;
+}
+
+static const struct of_device_id emac_of_match[] = {
+	{.compatible = "allwinner,sun4i-emac",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, emac_of_match);
+
+static struct platform_driver emac_driver = {
+	.driver = {
+		.name = "sun4i-emac",
+		.of_match_table = emac_of_match,
+	},
+	.probe = emac_probe,
+	.remove = emac_remove,
+	.suspend = emac_suspend,
+	.resume = emac_resume,
+};
+
+module_platform_driver(emac_driver);
+
+MODULE_AUTHOR("Stefan Roese <sr@denx.de>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner A10 emac network driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
new file mode 100644
index 0000000..f1b262c
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -0,0 +1,114 @@
+/*
+ * Allwinner EMAC Fast Ethernet driver for Linux.
+ *
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997  Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _SUN4I_EMAC_H_
+#define _SUN4I_EMAC_H_
+
+#define EMAC_CTL_REG		(0x00)
+#define EMAC_CTL_RESET			(1 << 0)
+#define EMAC_CTL_TX_EN			(1 << 1)
+#define EMAC_CTL_RX_EN			(1 << 2)
+#define EMAC_TX_MODE_REG	(0x04)
+#define EMAC_TX_MODE_ABORTED_FRAME_EN	(1 << 0)
+#define EMAC_TX_MODE_DMA_EN		(1 << 1)
+#define EMAC_TX_FLOW_REG	(0x08)
+#define EMAC_TX_CTL0_REG	(0x0c)
+#define EMAC_TX_CTL1_REG	(0x10)
+#define EMAC_TX_INS_REG		(0x14)
+#define EMAC_TX_PL0_REG		(0x18)
+#define EMAC_TX_PL1_REG		(0x1c)
+#define EMAC_TX_STA_REG		(0x20)
+#define EMAC_TX_IO_DATA_REG	(0x24)
+#define EMAC_TX_IO_DATA1_REG	(0x28)
+#define EMAC_TX_TSVL0_REG	(0x2c)
+#define EMAC_TX_TSVH0_REG	(0x30)
+#define EMAC_TX_TSVL1_REG	(0x34)
+#define EMAC_TX_TSVH1_REG	(0x38)
+#define EMAC_RX_CTL_REG		(0x3c)
+#define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
+#define EMAC_RX_CTL_DMA_EN		(1 << 2)
+#define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
+#define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
+#define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
+#define EMAC_RX_CTL_PASS_LEN_ERR_EN	(1 << 7)
+#define EMAC_RX_CTL_PASS_LEN_OOR_EN	(1 << 8)
+#define EMAC_RX_CTL_ACCEPT_UNICAST_EN	(1 << 16)
+#define EMAC_RX_CTL_DA_FILTER_EN	(1 << 17)
+#define EMAC_RX_CTL_ACCEPT_MULTICAST_EN	(1 << 20)
+#define EMAC_RX_CTL_HASH_FILTER_EN	(1 << 21)
+#define EMAC_RX_CTL_ACCEPT_BROADCAST_EN	(1 << 22)
+#define EMAC_RX_CTL_SA_FILTER_EN	(1 << 24)
+#define EMAC_RX_CTL_SA_FILTER_INVERT_EN	(1 << 25)
+#define EMAC_RX_HASH0_REG	(0x40)
+#define EMAC_RX_HASH1_REG	(0x44)
+#define EMAC_RX_STA_REG		(0x48)
+#define EMAC_RX_IO_DATA_REG	(0x4c)
+#define EMAC_RX_IO_DATA_LEN(x)		(x & 0xffff)
+#define EMAC_RX_IO_DATA_STATUS(x)	((x >> 16) & 0xffff)
+#define EMAC_RX_IO_DATA_STATUS_CRC_ERR	(1 << 4)
+#define EMAC_RX_IO_DATA_STATUS_LEN_ERR	(3 << 5)
+#define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
+#define EMAC_RX_FBC_REG		(0x50)
+#define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_STA_REG	(0x58)
+#define EMAC_MAC_CTL0_REG	(0x5c)
+#define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
+#define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
+#define EMAC_MAC_CTL0_SOFT_RESET	(1 << 15)
+#define EMAC_MAC_CTL1_REG	(0x60)
+#define EMAC_MAC_CTL1_DUPLEX_EN		(1 << 0)
+#define EMAC_MAC_CTL1_LEN_CHECK_EN	(1 << 1)
+#define EMAC_MAC_CTL1_HUGE_FRAME_EN	(1 << 2)
+#define EMAC_MAC_CTL1_DELAYED_CRC_EN	(1 << 3)
+#define EMAC_MAC_CTL1_CRC_EN		(1 << 4)
+#define EMAC_MAC_CTL1_PAD_EN		(1 << 5)
+#define EMAC_MAC_CTL1_PAD_CRC_EN	(1 << 6)
+#define EMAC_MAC_CTL1_AD_SHORT_FRAME_EN	(1 << 7)
+#define EMAC_MAC_CTL1_BACKOFF_DIS	(1 << 12)
+#define EMAC_MAC_IPGT_REG	(0x64)
+#define EMAC_MAC_IPGT_HALF_DUPLEX	(0x12)
+#define EMAC_MAC_IPGT_FULL_DUPLEX	(0x15)
+#define EMAC_MAC_IPGR_REG	(0x68)
+#define EMAC_MAC_IPGR_IPG1		(0x0c)
+#define EMAC_MAC_IPGR_IPG2		(0x12)
+#define EMAC_MAC_CLRT_REG	(0x6c)
+#define EMAC_MAC_CLRT_COLLISION_WINDOW	(0x37)
+#define EMAC_MAC_CLRT_RM		(0x0f)
+#define EMAC_MAC_MAXF_REG	(0x70)
+#define EMAC_MAC_SUPP_REG	(0x74)
+#define EMAC_MAC_TEST_REG	(0x78)
+#define EMAC_MAC_MCFG_REG	(0x7c)
+#define EMAC_MAC_MCMD_REG	(0x80)
+#define EMAC_MAC_MADR_REG	(0x84)
+#define EMAC_MAC_MWTD_REG	(0x88)
+#define EMAC_MAC_MRDD_REG	(0x8c)
+#define EMAC_MAC_MIND_REG	(0x90)
+#define EMAC_MAC_SSRR_REG	(0x94)
+#define EMAC_MAC_A0_REG		(0x98)
+#define EMAC_MAC_A1_REG		(0x9c)
+#define EMAC_MAC_A2_REG		(0xa0)
+#define EMAC_SAFX_L_REG0	(0xa4)
+#define EMAC_SAFX_H_REG0	(0xa8)
+#define EMAC_SAFX_L_REG1	(0xac)
+#define EMAC_SAFX_H_REG1	(0xb0)
+#define EMAC_SAFX_L_REG2	(0xb4)
+#define EMAC_SAFX_H_REG2	(0xb8)
+#define EMAC_SAFX_L_REG3	(0xbc)
+#define EMAC_SAFX_H_REG3	(0xc0)
+
+#define EMAC_PHY_DUPLEX		(1 << 8)
+
+#define EMAC_EEPROM_MAGIC	(0x444d394b)
+#define EMAC_UNDOCUMENTED_MAGIC	(0x0143414d)
+#endif /* _SUN4I_EMAC_H_ */
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH] bnx2x: fix assignment of signed expression to unsigned variable
From: Dan Carpenter @ 2013-03-23 21:19 UTC (permalink / raw)
  To: Kumar amit mehta; +Cc: eilong, netdev, linux-kernel, kernel-janitors
In-Reply-To: <20130323204511.GA18813@gmail.com>

On Sat, Mar 23, 2013 at 01:45:11PM -0700, Kumar amit mehta wrote:
> On Sat, Mar 23, 2013 at 10:56:47PM +0300, Dan Carpenter wrote:
> >
> > The fix for this is more involved.  The function prototype should
> > be changed to return an int.  The caller should be updated to check
> > for errors.
> >
> I wonder, why these callbacks are restricting the lower layers to return
> only unsigned values, However Updating the prototype doesn't seem a good idea as
> then it would require changes in various existing drivers.

Yes.  Everything will need to be updated.  I've known this code is
buggy for years but I've never tried patching it because I'm very
lazy.  :)

But actually it's only three drivers I think: bnx2x, ixgbe, and
mlx4.   I suspect that most of the functions always return zero and
won't need to be modified.

regards,
dan carpenter

^ permalink raw reply

* Re: [PATCH] bnx2x: fix assignment of signed expression to unsigned variable
From: Kumar amit mehta @ 2013-03-23 20:45 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: eilong, netdev, linux-kernel, kernel-janitors
In-Reply-To: <20130323195454.GB9138@mwanda>

On Sat, Mar 23, 2013 at 10:56:47PM +0300, Dan Carpenter wrote:
> On Sat, Mar 23, 2013 at 11:52:55AM -0700, Kumar Amit Mehta wrote:
> > fix for incorrect assignment of signed expression to unsigned variable.
> > 
> 
> This fix isn't right.
> 
> > Signed-off-by: Kumar Amit Mehta <gmate.amit@gmail.com>
> > ---
> >  drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c |   20 ++++++++++----------
> >  1 file changed, 10 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
> > index 5682054..b90533a 100644
> > --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
> > +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
> > @@ -2139,12 +2139,12 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
> >  			break;
> >  		default:
> >  			BNX2X_ERR("Non valid capability ID\n");
> > -			rval = -EINVAL;
> > +			rval = EINVAL;
> >  			break;
> >  		}
> >  	} else {
> >  		DP(BNX2X_MSG_DCB, "DCB disabled\n");
> > -		rval = -EINVAL;
> > +		rval = EINVAL;
> 
> This function is called from dcbnl_getcap().  It returns zero on
> success, but it's not clear what it should return on failure.  But
> certainly it's not a positive EINVAL.
> 
> >  	}
> >  
> >  	DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap);
> > @@ -2154,7 +2154,7 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
> >  static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
> >  {
> >  	struct bnx2x *bp = netdev_priv(netdev);
> > -	u8 rval = 0;
> > +	s8 rval = 0;
> 
> Just use "int" here.
> 
> >  
> >  	DP(BNX2X_MSG_DCB, "tcid %d\n", tcid);
> >  
> > @@ -2188,7 +2188,7 @@ static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
> >  	return -EINVAL;
> >  }
> >  
> > -static u8  bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
> > +static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
> >  {
> >  	struct bnx2x *bp = netdev_priv(netdev);
> >  	DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
> > @@ -2282,7 +2282,7 @@ static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up)
> >  	else {
> >  		/* app table is full */
> >  		BNX2X_ERR("Application table is too large\n");
> > -		return -EBUSY;
> > +		return EBUSY;
> >  	}
> 
> The fix for this is more involved.  The function prototype should
> be changed to return an int.  The caller should be updated to check
> for errors.
>
I wonder, why these callbacks are restricting the lower layers to return
only unsigned values, However Updating the prototype doesn't seem a good idea as
then it would require changes in various existing drivers.

^ permalink raw reply

* Re: [PATCH] bnx2x: fix assignment of signed expression to unsigned variable
From: Dan Carpenter @ 2013-03-23 19:56 UTC (permalink / raw)
  To: Kumar Amit Mehta; +Cc: eilong, netdev, linux-kernel, kernel-janitors
In-Reply-To: <1364064775-19319-1-git-send-email-gmate.amit@gmail.com>

On Sat, Mar 23, 2013 at 11:52:55AM -0700, Kumar Amit Mehta wrote:
> fix for incorrect assignment of signed expression to unsigned variable.
> 

This fix isn't right.

> Signed-off-by: Kumar Amit Mehta <gmate.amit@gmail.com>
> ---
>  drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c |   20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
> index 5682054..b90533a 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
> @@ -2139,12 +2139,12 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
>  			break;
>  		default:
>  			BNX2X_ERR("Non valid capability ID\n");
> -			rval = -EINVAL;
> +			rval = EINVAL;
>  			break;
>  		}
>  	} else {
>  		DP(BNX2X_MSG_DCB, "DCB disabled\n");
> -		rval = -EINVAL;
> +		rval = EINVAL;

This function is called from dcbnl_getcap().  It returns zero on
success, but it's not clear what it should return on failure.  But
certainly it's not a positive EINVAL.

>  	}
>  
>  	DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap);
> @@ -2154,7 +2154,7 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
>  static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
>  {
>  	struct bnx2x *bp = netdev_priv(netdev);
> -	u8 rval = 0;
> +	s8 rval = 0;

Just use "int" here.

>  
>  	DP(BNX2X_MSG_DCB, "tcid %d\n", tcid);
>  
> @@ -2188,7 +2188,7 @@ static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
>  	return -EINVAL;
>  }
>  
> -static u8  bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
> +static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
>  {
>  	struct bnx2x *bp = netdev_priv(netdev);
>  	DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
> @@ -2282,7 +2282,7 @@ static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up)
>  	else {
>  		/* app table is full */
>  		BNX2X_ERR("Application table is too large\n");
> -		return -EBUSY;
> +		return EBUSY;
>  	}

The fix for this is more involved.  The function prototype should
be changed to return an int.  The caller should be updated to check
for errors.

Etc.

regards,
dan carpenter

^ permalink raw reply

* [PATCH] Fix IXP4xx coherent allocations
From: Krzysztof Halasa @ 2013-03-23 19:35 UTC (permalink / raw)
  To: netdev, linux-arm-kernel, linux-kernel, Christophe Aeschlimann,
	David Miller

ARM core code currently requires coherent DMA mask to be set. Make sure
we limit PCI devices to 64 MiB while allowing on-chip devices to access
the whole 4 GiB address space.

This fixes a v3.7+ regression which broke IXP4xx built-in network devices.

Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
Cc: <stable@vger.kernel.org>

diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index ea1933d..8629fc9 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -454,10 +454,15 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
 
 int dma_set_coherent_mask(struct device *dev, u64 mask)
 {
-	if (mask >= SZ_64M - 1)
-		return 0;
+	if ((mask & DMA_BIT_MASK(26)) != DMA_BIT_MASK(26))
+		return -EIO;
+
+	/* PCI devices are limited to 64 MiB */
+	if (dev_is_pci(dev))
+		mask &= DMA_BIT_MASK(26); /* Use DMA region */
 
-	return -EIO;
+	dev->coherent_dma_mask = mask;
+	return 0;
 }
 
 EXPORT_SYMBOL(ixp4xx_pci_read);
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 6958a5e..7c08269 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -1423,7 +1423,7 @@ static int eth_init_one(struct platform_device *pdev)
 	dev->netdev_ops = &ixp4xx_netdev_ops;
 	dev->ethtool_ops = &ixp4xx_ethtool_ops;
 	dev->tx_queue_len = 100;
-
+	dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
 	netif_napi_add(dev, &port->napi, eth_poll, NAPI_WEIGHT);
 
 	if (!(port->npe = npe_request(NPE_ID(port->id)))) {
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 95d0451..83b4597 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -1367,6 +1367,7 @@ static int hss_init_one(struct platform_device *pdev)
 	port->id = pdev->id;
 	port->dev = &pdev->dev;
 	port->plat = pdev->dev.platform_data;
+	dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
 	netif_napi_add(dev, &port->napi, hss_hdlc_poll, NAPI_WEIGHT);
 
 	if ((err = register_hdlc_device(dev)))

^ permalink raw reply related

* Re: Missing TCP SYN on loopback, retransmits after 1s
From: Jason Oster @ 2013-03-23 19:17 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: jlyo, netdev, davem
In-Reply-To: <1364057885.29473.4.camel@edumazet-glaptop>

Hello Eric,

On Mar 23, 2013, at 9:58 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Hi Jay
> 
> Not reproducible on current kernels (net-next tree for example)

Thank you for looking into this so quickly! And it sounds like promising news, too. I'll experiment with newer kernels right away.

Thanks again,
Jay

^ permalink raw reply

* Re: [PATCH] net: Add support for handling queueing in hardware
From: Guenter Roeck @ 2013-03-23 19:02 UTC (permalink / raw)
  To: Ben Collins; +Cc: David Miller, afleming, linux-kernel, netdev
In-Reply-To: <FE78128C-01DB-4831-ACBE-BA3E3A428BFC@gmail.com>

On Fri, Mar 22, 2013 at 10:43:44AM -0400, Ben Collins wrote:
> On Mar 22, 2013, at 10:33 AM, David Miller <davem@davemloft.net> wrote:
> 
> > From: Fleming Andy-AFLEMING <afleming@freescale.com>
> > Date: Fri, 22 Mar 2013 14:31:50 +0000
> > 
> >> It would appear one of our customers is attempting to upstream our
> >> code for us. We are aware that this current solution is unacceptable
> >> (which is why we have not submitted it), and we are currently trying
> >> to develop a less hacky solution that integrates with qdisc.
> > 
> > Ben, can can you coordinate with people instead of doing crap like
> > this?
> 
> 
> "For us" is a loose term, when it's more that we are attempting to upstream code so our system is supported by a mainline kernel instead of having one-off kernels.
> 
> And we have been talking with Freescale about this for quite some time (couple years?). They have a roadmap that doesn't include getting this driver supported in mainline any time soon, so I'm taking time to get this done for our own system. I'm not meaning to step on any toes.
> 
How true. You are not the only one with thatt problem.

Ben, can you possibly send me your complete patch set on top of 3.8, or point me
to a git tree ?

I have exactly the same problem, I need the code in 3.8, it doesn't seem
like the Freescale code will show up anytime soon, and I don't seem to be able
to get early code for testing either. I can promise you a free test coverage
and bug fixing ...

Thanks,
Guenter

^ permalink raw reply

* [PATCH] bnx2x: fix assignment of signed expression to unsigned variable
From: Kumar Amit Mehta @ 2013-03-23 18:52 UTC (permalink / raw)
  To: eilong; +Cc: netdev, linux-kernel, kernel-janitors

fix for incorrect assignment of signed expression to unsigned variable.

Signed-off-by: Kumar Amit Mehta <gmate.amit@gmail.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
index 5682054..b90533a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
@@ -2139,12 +2139,12 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
 			break;
 		default:
 			BNX2X_ERR("Non valid capability ID\n");
-			rval = -EINVAL;
+			rval = EINVAL;
 			break;
 		}
 	} else {
 		DP(BNX2X_MSG_DCB, "DCB disabled\n");
-		rval = -EINVAL;
+		rval = EINVAL;
 	}
 
 	DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap);
@@ -2154,7 +2154,7 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
 static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
 {
 	struct bnx2x *bp = netdev_priv(netdev);
-	u8 rval = 0;
+	s8 rval = 0;
 
 	DP(BNX2X_MSG_DCB, "tcid %d\n", tcid);
 
@@ -2188,7 +2188,7 @@ static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
 	return -EINVAL;
 }
 
-static u8  bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
+static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
 {
 	struct bnx2x *bp = netdev_priv(netdev);
 	DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
@@ -2282,7 +2282,7 @@ static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up)
 	else {
 		/* app table is full */
 		BNX2X_ERR("Application table is too large\n");
-		return -EBUSY;
+		return EBUSY;
 	}
 
 	/* up configured, if not 0 make sure feature is enabled */
@@ -2312,7 +2312,7 @@ static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype,
 		break;
 	default:
 		DP(BNX2X_MSG_DCB, "Wrong ID type\n");
-		return -EINVAL;
+		return EINVAL;
 	}
 	return bnx2x_set_admin_app_up(bp, idtype, idval, up);
 }
@@ -2390,12 +2390,12 @@ static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
 			break;
 		default:
 			BNX2X_ERR("Non valid featrue-ID\n");
-			rval = -EINVAL;
+			rval = EINVAL;
 			break;
 		}
 	} else {
 		DP(BNX2X_MSG_DCB, "DCB disabled\n");
-		rval = -EINVAL;
+		rval = EINVAL;
 	}
 
 	return rval;
@@ -2431,12 +2431,12 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
 			break;
 		default:
 			BNX2X_ERR("Non valid featrue-ID\n");
-			rval = -EINVAL;
+			rval = EINVAL;
 			break;
 		}
 	} else {
 		DP(BNX2X_MSG_DCB, "dcbnl call not valid\n");
-		rval = -EINVAL;
+		rval = EINVAL;
 	}
 
 	return rval;
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH 1/1 v2 net-next] net: fec: fix the build as module
From: Fabio Estevam @ 2013-03-23 18:12 UTC (permalink / raw)
  To: Frank Li; +Cc: Frank Li, u.kleine-koenig, netdev, davem, linux-arm-kernel
In-Reply-To: <CAHrpEqQU9e-qAYvtHmB9bDhXafHmG=yWJxxv96f94FxVq9QYgQ@mail.gmail.com>

On Thu, Mar 21, 2013 at 11:39 PM, Frank Li <lznuaa@gmail.com> wrote:
>>
>> This error does not not happen in 'net-next' anymore.
>
> what's your suggestion? change commit message or request apply to 3.9

Your motivation now is to generate a single kernel module instead of
two for the fec, rather than fixing the the build error.

So you need to adjust the Subject and commit log.

I am not sure if we really need to rename fec.c though.

^ permalink raw reply

* Re: [PATCH net-next] ptp: increase the maximum number of clocks
From: Richard Cochran @ 2013-03-23 17:59 UTC (permalink / raw)
  To: David Miller; +Cc: jbenc, netdev
In-Reply-To: <20130321.172017.1499060411785395307.davem@davemloft.net>

On Thu, Mar 21, 2013 at 05:20:17PM -0400, David Miller wrote:
> 
> This really needs to be dynamic, and it shows what a bad idea it was
> to use character drivers for this which introduces arbitrary device
> arity limitations.

If a clock is not a character device, what then should it be? Network
interface?  Block device?  sysfs apparition?

IIRC, the RTCs appear as char devices. In any case, we are better off
with char devices than with an enumeration of SYSV clock IDs.
 
> I want to see a better solution to this problem than just bumping this
> limit arbitrarily every once in a while.

Jiri, do you want to work on making the number of clocks essentially
unlimited? If not, I can take a look at this, but not right away.

Thanks,
Richard

^ permalink raw reply

* Re: Missing TCP SYN on loopback, retransmits after 1s
From: Eric Dumazet @ 2013-03-23 16:58 UTC (permalink / raw)
  To: parasytic; +Cc: jlyo, netdev, davem
In-Reply-To: <c873451a-71aa-418b-96e2-d8875e7fec3e@googlegroups.com>

On Fri, 2013-03-22 at 19:03 -0700, parasytic@gmail.com wrote:
> Hi List!
> 
> 
> First, I'm sorry for resurrecting an extremely old thread, but I've
> exhausted all other resources. We're experiencing this same "1 second
> retransmit" with ipv4 (including loopback). And the best part is, it
> can be replicated very easily using the 'closed' and 'tcping' tests
> provided by Jesse Young in the initial post. For reference:
> 
> 
> $ git clone git://github.com/jlyo/tcping.git
> $ cd tcping && make
> 
> 
> $ git clone git://github.com/jlyo/closed.git
> $ cd closed && make
> 
> 
> $ ./closed 0.0.0.0
> 
> 
> $ time ./tcping -f -p8009 0.0.0.0
> 
> 
> Results:
> 
> 
>         ...
>         response from 0.0.0.0:8009, seq=1907 time=0.02 ms
>         response from 0.0.0.0:8009, seq=1908 time=0.03 ms
>         response from 0.0.0.0:8009, seq=1909 time=999.11 ms
>         --- 0.0.0.0:8009 ping statistics ---
>         1909 responses, 1910 ok, 0.00% failed
>         round-trip min/avg/max = 0.0/0.6/999.1 ms
>         
>         
>         real    0m1.125s
>         user    0m0.008s
>         sys     0m0.104s
> 
> 
> 
> 
> Packet captures from tcpdump look remarkably similar to what Eric
> Dumazet shared. That eventually lead me to this thread.
> 
> 
> This happens on a fresh Ubuntu 12.10 install, and also with our tuning
> parameters. (Includes increasing the syn backlog, open file
> descriptors, TCP memory, max orphans, etc.)  I've also seen the
> problem with other kernels, within EC2 and Azure. I have not been able
> to test with ipv6 yet.
> 
> 
> $ uname -a
> Linux test 3.5.0-21-generic #32-Ubuntu SMP Tue Dec 11 18:51:59 UTC
> 2012 x86_64 x86_64 x86_64 GNU/Linux
> 
> 
> I'm hoping to spark some interest in revisiting this issue (with focus
> on ipv4, this time).
> 
> 
> Thanks everyone!
> Jay
> 
Hi Jay

Not reproducible on current kernels (net-next tree for example)

ip netns add eric
ip netns exec eric ifconfig -a
ip netns exec eric ifconfig lo 127.0.0.1 up
ip netns exec eric ./closed 0.0.0.0 &
ip netns exec eric nstat
ip netns exec eric ./tcping -f -p8009 0.0.0.0
127.0.0.1:40832 Connected...response from 0.0.0.0:8009, seq=32799
time=0.04 ms
 closed
127.0.0.1:40999 Connected...response from 0.0.0.0:8009, seq=32800
time=0.04 ms
 closed
127.0.0.1:42795 Connected...response from 0.0.0.0:8009, seq=32801
time=0.20 ms
 closed
127.0.0.1:43226 Connected...response from 0.0.0.0:8009, seq=32802
time=0.07 ms
 closed
error connecting to host (99): Cannot assign requested address
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
 ................................................................................................................................................................^C.--- 0.0.0.0:8009 ping statistics ---
33765 responses, 32803 ok, 0.00% failed
round-trip min/avg/max = 0.0/0.0/0.5 ms

# ip netns exec eric nstat
#kernel
IpInReceives                    197087             0.0
IpInDelivers                    197087             0.0
IpOutRequests                   197087             0.0
TcpActiveOpens                  32803              0.0
TcpPassiveOpens                 32803              0.0
TcpInSegs                       197087             0.0
TcpOutSegs                      197084             0.0
TcpRetransSegs                  3                  0.0
TcpOutRsts                      11                 0.0
TcpExtSyncookiesFailed          11                 0.0
TcpExtDelayedACKs               238                0.0
TcpExtDelayedACKLocked          248                0.0
TcpExtTCPPureAcks               65838              0.0
TcpExtTCPTimeouts               3                  0.0
IpExtInOctets                   10773240           0.0
IpExtOutOctets                  10773240           0.0


But yes, on 3.5.X kernel you might hit a bug somewhere.

Since the same sequence gives suspect TcpExtListenDrops :

# ip netns exec eric nstat 
#kernel
IpInReceives                    49367              0.0
IpInDelivers                    49367              0.0
IpOutRequests                   49367              0.0
TcpActiveOpens                  8184               0.0
TcpPassiveOpens                 8184               0.0
TcpInSegs                       49367              0.0
TcpOutSegs                      49362              0.0
TcpRetransSegs                  5                  0.0
TcpExtDelayedACKs               63                 0.0
TcpExtDelayedACKLocked          32                 0.0
TcpExtListenOverflows           4                  0.0
TcpExtListenDrops               4                  0.0
TcpExtTCPPureAcks               16624              0.0
TcpExtTCPLossUndo               1                  0.0
TcpExtTCPTimeouts               5                  0.0
IpExtInOctets                   2698036            0.0
IpExtOutOctets                  2698036            0.0

^ permalink raw reply

* Re: regression: tethering fails in 3.5 with iwlwifi
From: Luis Henriques @ 2013-03-23 15:45 UTC (permalink / raw)
  To: Johannes Berg
  Cc: artem.bityutskiy, patrik.flykt, Eric Dumazet, linux-wireless,
	netdev, stable
In-Reply-To: <1363894451.8181.4.camel@jlt4.sipsolutions.net>

On Thu, Mar 21, 2013 at 08:34:11PM +0100, Johannes Berg wrote:
> On Mon, 2012-09-17 at 17:41 +0300, Artem Bityutskiy wrote:
> 
> > OK, finally I got it. After 3 days of hardcore intelligent bisecting
> >         I've found out that tethering in 3.5 works for me if I revert
> > these 2
> >         patches:
> >         
> >             56138f5 iwlwifi: dont pull too much payload in skb head
> 
> I got back to this for a customer running 3.5, and after many failed
> attempts realized that you have to have iptables for this problem to
> actually happen. I reverse-bisected that the *fix* is
> 6caab7b0544e83e6c160b5e80f5a4a7dd69545c7, in 3.7.
> 
> Is there still any stable kernel 3.5/3.6 (or possibly before, though for
> iwlwifi before doesn't matter) that this should be applied to?

The 3.5.y.z extended stable tree already contains this commit as well.

Cheers,
--
Luis

^ permalink raw reply

* Re: [PATCH net-next] 8021q: fix a potential use-after-free
From: Eric Dumazet @ 2013-03-23 15:16 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, Patrick McHardy, David S. Miller
In-Reply-To: <1364015648-4195-1-git-send-email-amwang@redhat.com>

On Sat, 2013-03-23 at 13:14 +0800, Cong Wang wrote:
> From: Cong Wang <amwang@redhat.com>
> 
> vlan_vid_del() could possibly free ->vlan_info after a RCU grace
> period, however, we may still refer to the freed memory area
> by 'grp' pointer. Found by code inspection.
> 
> This patch moves vlan_vid_del() as behind as possible.
> 
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: "David S. Miller" <davem@davemloft.net>
> Signed-off-by: Cong Wang <amwang@redhat.com>
> ---
>  net/8021q/vlan.c |   14 +++++++-------
>  1 files changed, 7 insertions(+), 7 deletions(-)

Acked-by: Eric Dumazet <edumazet@google.com>

^ 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