* Re: [PATCH 3/3] ARM: mx5: add basic device tree support for imx51 babbage
From: Grant Likely @ 2011-06-18 16:24 UTC (permalink / raw)
To: Shawn Guo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
patches-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1308410354-21387-4-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On Sat, Jun 18, 2011 at 11:19:14PM +0800, Shawn Guo wrote:
> This patch adds the i.mx51 dt platform with uart and fec support.
> It also adds the dts file imx51 babbage, so that we can have a dt
> kernel on babbage booting into console with nfs root.
>
> Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Looks like a good start to me. I'll pick it up into devicetree/test
(probably on Monday). Only think I see that needs changing is to
modify the compatible properties based on my comments on the first 2
patches.
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
g.
> ---
> arch/arm/boot/dts/imx51-babbage.dts | 89 +++++++++++++++++++++++++++++++++++
> arch/arm/mach-mx5/Kconfig | 8 +++
> arch/arm/mach-mx5/Makefile | 1 +
> arch/arm/mach-mx5/imx51-dt.c | 70 +++++++++++++++++++++++++++
> 4 files changed, 168 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/boot/dts/imx51-babbage.dts
> create mode 100644 arch/arm/mach-mx5/imx51-dt.c
>
> diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
> new file mode 100644
> index 0000000..7976932
> --- /dev/null
> +++ b/arch/arm/boot/dts/imx51-babbage.dts
> @@ -0,0 +1,89 @@
> +/*
> + * Copyright 2011 Freescale Semiconductor, Inc.
> + * Copyright 2011 Linaro Ltd.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +/dts-v1/;
> +/include/ "skeleton.dtsi"
> +
> +/ {
> + model = "Freescale i.MX51 Babbage";
> + compatible = "fsl,imx51-babbage", "fsl,imx51";
> + interrupt-parent = <&tzic>;
> +
> + chosen {
> + bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
> + };
> +
> + memory {
> + reg = <0x90000000 0x20000000>;
> + };
> +
> + tzic: tz-interrupt-controller@e0000000 {
> + compatible = "fsl,imx51-tzic", "fsl,tzic";
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + reg = <0xe0000000 0x4000>;
> + };
> +
> + aips@70000000 { /* aips-1 */
> + compatible = "fsl,aips-bus", "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x70000000 0x10000000>;
> + ranges;
> +
> + spba {
> + compatible = "fsl,spba-bus", "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x70000000 0x40000>;
> + ranges;
> +
> + uart@7000c000 {
> + compatible = "fsl,imx51-uart", "fsl,imx-uart";
> + reg = <0x7000c000 0x4000>;
> + interrupts = <33>;
> + id = <3>;
> + fsl,has-rts-cts;
> + };
> + };
> +
> + uart@73fbc000 {
> + compatible = "fsl,imx51-uart", "fsl,imx-uart";
> + reg = <0x73fbc000 0x4000>;
> + interrupts = <31>;
> + id = <1>;
> + fsl,has-rts-cts;
> + };
> +
> + uart@73fc0000 {
> + compatible = "fsl,imx51-uart", "fsl,imx-uart";
> + reg = <0x73fc0000 0x4000>;
> + interrupts = <32>;
> + id = <2>;
> + fsl,has-rts-cts;
> + };
> + };
> +
> + aips@80000000 { /* aips-2 */
> + compatible = "fsl,aips-bus", "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x80000000 0x10000000>;
> + ranges;
> +
> + fec@83fec000 {
> + compatible = "fsl,imx51-fec", "fsl,fec";
> + reg = <0x83fec000 0x4000>;
> + interrupts = <87>;
> + };
> + };
> +};
> diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
> index 799fbc4..8bdd0c4 100644
> --- a/arch/arm/mach-mx5/Kconfig
> +++ b/arch/arm/mach-mx5/Kconfig
> @@ -62,6 +62,14 @@ endif # ARCH_MX50_SUPPORTED
> if ARCH_MX51
> comment "i.MX51 machines:"
>
> +config MACH_IMX51_DT
> + bool "Support i.MX51 platforms from device tree"
> + select SOC_IMX51
> + select USE_OF
> + help
> + Include support for Freescale i.MX51 based platforms
> + using the device tree for discovery
> +
> config MACH_MX51_BABBAGE
> bool "Support MX51 BABBAGE platforms"
> select SOC_IMX51
> diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
> index 0b9338c..47b483f 100644
> --- a/arch/arm/mach-mx5/Makefile
> +++ b/arch/arm/mach-mx5/Makefile
> @@ -7,6 +7,7 @@ obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
> obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
>
> obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
> +obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
> obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
> obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
> obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o
> diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
> new file mode 100644
> index 0000000..8bfdb91
> --- /dev/null
> +++ b/arch/arm/mach-mx5/imx51-dt.c
> @@ -0,0 +1,70 @@
> +/*
> + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2011 Linaro Ltd.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/irq.h>
> +#include <linux/of_platform.h>
> +
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include <mach/common.h>
> +#include <mach/mx51.h>
> +
> +/*
> + * Lookup table for attaching a specific name and platform_data pointer to
> + * devices as they get created by of_platform_populate(). Ideally this table
> + * would not exist, but the current clock implementation depends on some devices
> + * having a specific name.
> + */
> +static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
> + OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART1_BASE_ADDR, "imx-uart.0", NULL),
> + OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART2_BASE_ADDR, "imx-uart.1", NULL),
> + OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART3_BASE_ADDR, "imx-uart.2", NULL),
> + OF_DEV_AUXDATA("fsl,imx51-fec", MX51_FEC_BASE_ADDR, "fec.0", NULL),
> + {}
> +};
> +
> +static const struct of_device_id tzic_of_match[] __initconst = {
> + { .compatible = "fsl,imx51-tzic", },
> + {}
> +};
> +
> +static void __init imx51_dt_init(void)
> +{
> + irq_domain_generate_simple(tzic_of_match, MX51_TZIC_BASE_ADDR, 0);
> +
> + of_platform_populate(NULL, of_default_bus_match_table,
> + imx51_auxdata_lookup, NULL);
> +}
> +
> +static void __init imx51_timer_init(void)
> +{
> + mx51_clocks_init(32768, 24000000, 22579200, 0);
> +}
> +
> +static struct sys_timer imx51_timer = {
> + .init = imx51_timer_init,
> +};
> +
> +static const char *imx51_dt_board_compat[] __initdata = {
> + "fsl,imx51-babbage",
> + NULL
> +};
> +
> +DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
> + .map_io = mx51_map_io,
> + .init_early = imx51_init_early,
> + .init_irq = mx51_init_irq,
> + .timer = &imx51_timer,
> + .init_machine = imx51_dt_init,
> + .dt_compat = imx51_dt_board_compat,
> +MACHINE_END
> --
> 1.7.4.1
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply
* Re: [PATCH 2/3] net/fec: add device tree support
From: Grant Likely @ 2011-06-18 16:22 UTC (permalink / raw)
To: Shawn Guo
Cc: linux-arm-kernel, patches, netdev, devicetree-discuss, Jason Liu,
linux-kernel, David S. Miller
In-Reply-To: <1308410354-21387-3-git-send-email-shawn.guo@linaro.org>
On Sat, Jun 18, 2011 at 11:19:13PM +0800, Shawn Guo wrote:
> It adds device tree data parsing support for fec driver.
>
> Signed-off-by: Jason Liu <jason.hui@linaro.org>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> Cc: David S. Miller <davem@davemloft.net>
> ---
> Documentation/devicetree/bindings/net/fsl-fec.txt | 14 ++++++++++
> drivers/net/fec.c | 28 +++++++++++++++++++++
> 2 files changed, 42 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/net/fsl-fec.txt
>
> diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
> new file mode 100644
> index 0000000..705111d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
> @@ -0,0 +1,14 @@
> +* Freescale Fast Ethernet Controller (FEC)
> +
> +Required properties:
> +- compatible : should be "fsl,<soc>-fec", "fsl,fec"
Ditto to comment on last patch. "fsl,fec" is to generic.
"fsl,imx51-soc" should be the generic value.
Otherwise looks okay to me, and I don't see any problem with queueing
it up for v3.1 with that change since it doesn't depend on any other
patches.
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> +- reg : address and length of the register set for the device
> +- interrupts : should contain fec interrupt
> +
> +Example:
> +
> +fec@83fec000 {
> + compatible = "fsl,imx51-fec", "fsl,fec";
> + reg = <0x83fec000 0x4000>;
> + interrupts = <87>;
> +};
> diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> index 885d8ba..ef3d175 100644
> --- a/drivers/net/fec.c
> +++ b/drivers/net/fec.c
> @@ -44,6 +44,8 @@
> #include <linux/platform_device.h>
> #include <linux/phy.h>
> #include <linux/fec.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
>
> #include <asm/cacheflush.h>
>
> @@ -78,6 +80,26 @@ static struct platform_device_id fec_devtype[] = {
> { }
> };
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id fec_dt_ids[] = {
> + { .compatible = "fsl,fec", .data = &fec_devtype[0], },
> + {},
> +};
> +
> +static const struct of_device_id *
> +fec_get_of_device_id(struct platform_device *pdev)
> +{
> + return of_match_device(fec_dt_ids, &pdev->dev);
> +}
> +#else
> +#define fec_dt_ids NULL
> +static inline struct of_device_id *
> +fec_get_of_device_id(struct platform_device *pdev)
> +{
> + return NULL;
> +}
> +#endif
> +
> static unsigned char macaddr[ETH_ALEN];
> module_param_array(macaddr, byte, NULL, 0);
> MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
> @@ -1363,6 +1385,11 @@ fec_probe(struct platform_device *pdev)
> struct net_device *ndev;
> int i, irq, ret = 0;
> struct resource *r;
> + const struct of_device_id *of_id;
> +
> + of_id = fec_get_of_device_id(pdev);
> + if (of_id)
> + pdev->id_entry = (struct platform_device_id *) of_id->data;
>
> r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!r)
> @@ -1531,6 +1558,7 @@ static struct platform_driver fec_driver = {
> #ifdef CONFIG_PM
> .pm = &fec_pm_ops,
> #endif
> + .of_match_table = fec_dt_ids,
> },
> .id_table = fec_devtype,
> .probe = fec_probe,
> --
> 1.7.4.1
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply
* Re: [PATCH 1/3] serial/imx: add device tree support
From: Arnd Bergmann @ 2011-06-18 16:21 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Shawn Guo, patches, netdev, devicetree-discuss, Jason Liu,
linux-kernel, Jeremy Kerr, Sascha Hauer
In-Reply-To: <1308410354-21387-2-git-send-email-shawn.guo@linaro.org>
On Saturday 18 June 2011 17:19:12 Shawn Guo wrote:
>
> +Required properties:
> +- compatible : should be "fsl,<soc>-uart", "fsl,imx-uart"
> +- reg : address and length of the register set for the device
> +- interrupts : should contain uart interrupt
> +- id : should be the port ID defined by soc
> +
> +Optional properties:
> +- fsl,has-rts-cts : indicate it has rts-cts
> +- fsl,irda-mode : support irda mode
> +
> +Example:
> +
> +uart@73fbc000 {
> + compatible = "fsl,imx51-uart", "fsl,imx-uart";
> + reg = <0x73fbc000 0x4000>;
> + interrupts = <31>;
> + id = <1>;
> + fsl,has-rts-cts;
> +};
Should this also support the "clock-frequency" property that 8250-style
serial ports support [1]?
For the flow-control properties, should we name that more generic? The
same property certainly makes sense for other serial-ports if it does
here. OTOH, I'm not sure it's actually reliable, because it also depends
on whether the other side of the connection and the cable support hw flow
control.
Arnd
[1] http://playground.sun.com/1275/bindings/devices/html/serial-1_0d.html#HDR9
^ permalink raw reply
* Re: [PATCH 1/3] serial/imx: add device tree support
From: Grant Likely @ 2011-06-18 16:19 UTC (permalink / raw)
To: Shawn Guo
Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jason Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jeremy Kerr, Sascha Hauer,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1308410354-21387-2-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On Sat, Jun 18, 2011 at 11:19:12PM +0800, Shawn Guo wrote:
> It adds device tree data parsing support for imx tty/serial driver.
>
> Signed-off-by: Jeremy Kerr <jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
> Signed-off-by: Jason Liu <jason.hui-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
> .../bindings/tty/serial/fsl-imx-uart.txt | 21 +++++
> drivers/tty/serial/imx.c | 81 +++++++++++++++++---
> 2 files changed, 92 insertions(+), 10 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
>
> diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
> new file mode 100644
> index 0000000..7648e17
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
> @@ -0,0 +1,21 @@
> +* Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART)
> +
> +Required properties:
> +- compatible : should be "fsl,<soc>-uart", "fsl,imx-uart"
I'd make this "fsl,<soc>-uart", "fsl,imx51-uart"
It's better to anchor these things on real silicon, or a real ip block
specification rather than something pseudo-generic. Subsequent chips,
like the imx53, should simply claim compatibility with the older
fsl,imx51-uart.
(in essence, "fsl,imx51-uart" becomes the generic string without the
downside of having no obvious recourse when new silicon shows up that
is an imx part, but isn't compatible with the imx51 uart.
> +- reg : address and length of the register set for the device
> +- interrupts : should contain uart interrupt
> +- id : should be the port ID defined by soc
> +
> +Optional properties:
> +- fsl,has-rts-cts : indicate it has rts-cts
> +- fsl,irda-mode : support irda mode
> +
> +Example:
> +
> +uart@73fbc000 {
> + compatible = "fsl,imx51-uart", "fsl,imx-uart";
> + reg = <0x73fbc000 0x4000>;
> + interrupts = <31>;
> + id = <1>;
> + fsl,has-rts-cts;
> +};
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index a544731..2769353 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -45,6 +45,8 @@
> #include <linux/delay.h>
> #include <linux/rational.h>
> #include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
>
> #include <asm/io.h>
> #include <asm/irq.h>
> @@ -1223,6 +1225,63 @@ static int serial_imx_resume(struct platform_device *dev)
> return 0;
> }
>
> +#ifdef CONFIG_OF
> +static int serial_imx_probe_dt(struct imx_port *sport,
> + struct platform_device *pdev)
> +{
> + struct device_node *node = pdev->dev.of_node;
> + const __be32 *line;
> +
> + if (!node)
> + return -ENODEV;
> +
> + line = of_get_property(node, "id", NULL);
> + if (!line)
> + return -ENODEV;
> +
> + sport->port.line = be32_to_cpup(line) - 1;
Hmmm, I really would like to be rid of this. Instead, if uarts must
be enumerated, the driver should look for a /aliases/uart* property
that matches the of_node. Doing it that way is already established in
the OpenFirmware documentation, and it ensures there are no overlaps
in the global namespace.
We do need some infrastructure to make that easier though. Would you
have time to help put that together?
> +
> + if (of_get_property(node, "fsl,has-rts-cts", NULL))
> + sport->have_rtscts = 1;
> +
> + if (of_get_property(node, "fsl,irda-mode", NULL))
> + sport->use_irda = 1;
> +
> + return 0;
> +}
> +
> +static struct of_device_id imx_uart_dt_ids[] = {
> + { .compatible = "fsl,imx-uart" },
> + {},
> +};
> +#else
> +static int serial_imx_probe_dt(struct imx_port *sport,
> + struct platform_device *pdev)
> +{
> + return -ENODEV;
> +}
> +#define imx_uart_dt_ids NULL
> +#endif
> +
> +static int serial_imx_probe_pdata(struct imx_port *sport,
> + struct platform_device *pdev)
> +{
> + struct imxuart_platform_data *pdata = pdev->dev.platform_data;
> +
> + if (!pdata)
> + return 0;
> +
> + if (pdata->flags & IMXUART_HAVE_RTSCTS)
> + sport->have_rtscts = 1;
> +
> + if (pdata->flags & IMXUART_IRDA)
> + sport->use_irda = 1;
> +
> + sport->port.line = pdev->id;
> +
> + return 0;
> +}
> +
> static int serial_imx_probe(struct platform_device *pdev)
> {
> struct imx_port *sport;
> @@ -1235,6 +1294,12 @@ static int serial_imx_probe(struct platform_device *pdev)
> if (!sport)
> return -ENOMEM;
>
> + ret = serial_imx_probe_dt(sport, pdev);
> + if (ret == -ENODEV)
> + ret = serial_imx_probe_pdata(sport, pdev);
> + if (ret)
> + goto free;
> +
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!res) {
> ret = -ENODEV;
> @@ -1259,7 +1324,6 @@ static int serial_imx_probe(struct platform_device *pdev)
> sport->port.fifosize = 32;
> sport->port.ops = &imx_pops;
> sport->port.flags = UPF_BOOT_AUTOCONF;
> - sport->port.line = pdev->id;
> init_timer(&sport->timer);
> sport->timer.function = imx_timeout;
> sport->timer.data = (unsigned long)sport;
> @@ -1273,17 +1337,13 @@ static int serial_imx_probe(struct platform_device *pdev)
>
> sport->port.uartclk = clk_get_rate(sport->clk);
>
> - imx_ports[pdev->id] = sport;
> + if (imx_ports[sport->port.line]) {
> + ret = -EBUSY;
> + goto clkput;
> + }
> + imx_ports[sport->port.line] = sport;
>
> pdata = pdev->dev.platform_data;
> - if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
> - sport->have_rtscts = 1;
> -
> -#ifdef CONFIG_IRDA
> - if (pdata && (pdata->flags & IMXUART_IRDA))
> - sport->use_irda = 1;
> -#endif
> -
> if (pdata && pdata->init) {
> ret = pdata->init(pdev);
> if (ret)
> @@ -1344,6 +1404,7 @@ static struct platform_driver serial_imx_driver = {
> .driver = {
> .name = "imx-uart",
> .owner = THIS_MODULE,
> + .of_match_table = imx_uart_dt_ids,
> },
> };
>
> --
> 1.7.4.1
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply
* [PATCH]rionet: fix NULL pointer dereference in rionet_remove
From: Yinglin Luan @ 2011-06-18 15:27 UTC (permalink / raw)
To: netdev; +Cc: davem, mporter, jj, cmdkhh, synmyth
Function rionet_remove initializes local variable 'ndev' to NULL
and do nothing changes before the call to unregister_netdev(ndev),
this could cause a NULL pointer dereference.
Reported-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Yinglin Luan <synmyth@gmail.com>
---
drivers/net/rionet.c | 28 +++++++++++++++-------------
1 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 77c5092..5d3436d 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -378,7 +378,7 @@ static int rionet_close(struct net_device *ndev)
static void rionet_remove(struct rio_dev *rdev)
{
- struct net_device *ndev = NULL;
+ struct net_device *ndev = rio_get_drvdata(rdev);
struct rionet_peer *peer, *tmp;
free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
@@ -433,22 +433,12 @@ static const struct net_device_ops
rionet_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
};
-static int rionet_setup_netdev(struct rio_mport *mport)
+static int rionet_setup_netdev(struct rio_mport *mport, struct
net_device *ndev)
{
int rc = 0;
- struct net_device *ndev = NULL;
struct rionet_private *rnet;
u16 device_id;
- /* Allocate our net_device structure */
- ndev = alloc_etherdev(sizeof(struct rionet_private));
- if (ndev == NULL) {
- printk(KERN_INFO "%s: could not allocate ethernet device.\n",
- DRV_NAME);
- rc = -ENOMEM;
- goto out;
- }
-
rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
if (!rionet_active) {
@@ -504,11 +494,21 @@ static int rionet_probe(struct rio_dev *rdev,
const struct rio_device_id *id)
int rc = -ENODEV;
u32 lpef, lsrc_ops, ldst_ops;
struct rionet_peer *peer;
+ struct net_device *ndev = NULL;
/* If local device is not rionet capable, give up quickly */
if (!rionet_capable)
goto out;
+ /* Allocate our net_device structure */
+ ndev = alloc_etherdev(sizeof(struct rionet_private));
+ if (ndev == NULL) {
+ printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+ DRV_NAME);
+ rc = -ENOMEM;
+ goto out;
+ }
+
/*
* First time through, make sure local device is rionet
* capable, setup netdev, and set flags so this is skipped
@@ -529,7 +529,7 @@ static int rionet_probe(struct rio_dev *rdev, const
struct rio_device_id *id)
goto out;
}
- rc = rionet_setup_netdev(rdev->net->hport);
+ rc = rionet_setup_netdev(rdev->net->hport, ndev);
rionet_check = 1;
}
@@ -546,6 +546,8 @@ static int rionet_probe(struct rio_dev *rdev, const
struct rio_device_id *id)
list_add_tail(&peer->node, &rionet_peers);
}
+ rio_set_drvdata(rdev, ndev);
+
out:
return rc;
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH 3/3] ARM: mx5: add basic device tree support for imx51 babbage
From: Shawn Guo @ 2011-06-18 15:19 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
patches-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1308410354-21387-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
This patch adds the i.mx51 dt platform with uart and fec support.
It also adds the dts file imx51 babbage, so that we can have a dt
kernel on babbage booting into console with nfs root.
Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/boot/dts/imx51-babbage.dts | 89 +++++++++++++++++++++++++++++++++++
arch/arm/mach-mx5/Kconfig | 8 +++
arch/arm/mach-mx5/Makefile | 1 +
arch/arm/mach-mx5/imx51-dt.c | 70 +++++++++++++++++++++++++++
4 files changed, 168 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/boot/dts/imx51-babbage.dts
create mode 100644 arch/arm/mach-mx5/imx51-dt.c
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
new file mode 100644
index 0000000..7976932
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Freescale i.MX51 Babbage";
+ compatible = "fsl,imx51-babbage", "fsl,imx51";
+ interrupt-parent = <&tzic>;
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+ };
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+
+ tzic: tz-interrupt-controller@e0000000 {
+ compatible = "fsl,imx51-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe0000000 0x4000>;
+ };
+
+ aips@70000000 { /* aips-1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x10000000>;
+ ranges;
+
+ spba {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x40000>;
+ ranges;
+
+ uart@7000c000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x7000c000 0x4000>;
+ interrupts = <33>;
+ id = <3>;
+ fsl,has-rts-cts;
+ };
+ };
+
+ uart@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupts = <31>;
+ id = <1>;
+ fsl,has-rts-cts;
+ };
+
+ uart@73fc0000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fc0000 0x4000>;
+ interrupts = <32>;
+ id = <2>;
+ fsl,has-rts-cts;
+ };
+ };
+
+ aips@80000000 { /* aips-2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x10000000>;
+ ranges;
+
+ fec@83fec000 {
+ compatible = "fsl,imx51-fec", "fsl,fec";
+ reg = <0x83fec000 0x4000>;
+ interrupts = <87>;
+ };
+ };
+};
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 799fbc4..8bdd0c4 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -62,6 +62,14 @@ endif # ARCH_MX50_SUPPORTED
if ARCH_MX51
comment "i.MX51 machines:"
+config MACH_IMX51_DT
+ bool "Support i.MX51 platforms from device tree"
+ select SOC_IMX51
+ select USE_OF
+ help
+ Include support for Freescale i.MX51 based platforms
+ using the device tree for discovery
+
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
select SOC_IMX51
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 0b9338c..47b483f 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -7,6 +7,7 @@ obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
+obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
new file mode 100644
index 0000000..8bfdb91
--- /dev/null
+++ b/arch/arm/mach-mx5/imx51-dt.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/mx51.h>
+
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate(). Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART1_BASE_ADDR, "imx-uart.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART2_BASE_ADDR, "imx-uart.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART3_BASE_ADDR, "imx-uart.2", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-fec", MX51_FEC_BASE_ADDR, "fec.0", NULL),
+ {}
+};
+
+static const struct of_device_id tzic_of_match[] __initconst = {
+ { .compatible = "fsl,imx51-tzic", },
+ {}
+};
+
+static void __init imx51_dt_init(void)
+{
+ irq_domain_generate_simple(tzic_of_match, MX51_TZIC_BASE_ADDR, 0);
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ imx51_auxdata_lookup, NULL);
+}
+
+static void __init imx51_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer imx51_timer = {
+ .init = imx51_timer_init,
+};
+
+static const char *imx51_dt_board_compat[] __initdata = {
+ "fsl,imx51-babbage",
+ NULL
+};
+
+DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .timer = &imx51_timer,
+ .init_machine = imx51_dt_init,
+ .dt_compat = imx51_dt_board_compat,
+MACHINE_END
--
1.7.4.1
^ permalink raw reply related
* [PATCH 2/3] net/fec: add device tree support
From: Shawn Guo @ 2011-06-18 15:19 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jason Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David S. Miller
In-Reply-To: <1308410354-21387-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
It adds device tree data parsing support for fec driver.
Signed-off-by: Jason Liu <jason.hui-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
---
Documentation/devicetree/bindings/net/fsl-fec.txt | 14 ++++++++++
drivers/net/fec.c | 28 +++++++++++++++++++++
2 files changed, 42 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/fsl-fec.txt
diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
new file mode 100644
index 0000000..705111d
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
@@ -0,0 +1,14 @@
+* Freescale Fast Ethernet Controller (FEC)
+
+Required properties:
+- compatible : should be "fsl,<soc>-fec", "fsl,fec"
+- reg : address and length of the register set for the device
+- interrupts : should contain fec interrupt
+
+Example:
+
+fec@83fec000 {
+ compatible = "fsl,imx51-fec", "fsl,fec";
+ reg = <0x83fec000 0x4000>;
+ interrupts = <87>;
+};
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 885d8ba..ef3d175 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -44,6 +44,8 @@
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/fec.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <asm/cacheflush.h>
@@ -78,6 +80,26 @@ static struct platform_device_id fec_devtype[] = {
{ }
};
+#ifdef CONFIG_OF
+static const struct of_device_id fec_dt_ids[] = {
+ { .compatible = "fsl,fec", .data = &fec_devtype[0], },
+ {},
+};
+
+static const struct of_device_id *
+fec_get_of_device_id(struct platform_device *pdev)
+{
+ return of_match_device(fec_dt_ids, &pdev->dev);
+}
+#else
+#define fec_dt_ids NULL
+static inline struct of_device_id *
+fec_get_of_device_id(struct platform_device *pdev)
+{
+ return NULL;
+}
+#endif
+
static unsigned char macaddr[ETH_ALEN];
module_param_array(macaddr, byte, NULL, 0);
MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -1363,6 +1385,11 @@ fec_probe(struct platform_device *pdev)
struct net_device *ndev;
int i, irq, ret = 0;
struct resource *r;
+ const struct of_device_id *of_id;
+
+ of_id = fec_get_of_device_id(pdev);
+ if (of_id)
+ pdev->id_entry = (struct platform_device_id *) of_id->data;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
@@ -1531,6 +1558,7 @@ static struct platform_driver fec_driver = {
#ifdef CONFIG_PM
.pm = &fec_pm_ops,
#endif
+ .of_match_table = fec_dt_ids,
},
.id_table = fec_devtype,
.probe = fec_probe,
--
1.7.4.1
^ permalink raw reply related
* [PATCH 1/3] serial/imx: add device tree support
From: Shawn Guo @ 2011-06-18 15:19 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jason Liu,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jeremy Kerr, Sascha Hauer
In-Reply-To: <1308410354-21387-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
It adds device tree data parsing support for imx tty/serial driver.
Signed-off-by: Jeremy Kerr <jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
Signed-off-by: Jason Liu <jason.hui-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
.../bindings/tty/serial/fsl-imx-uart.txt | 21 +++++
drivers/tty/serial/imx.c | 81 +++++++++++++++++---
2 files changed, 92 insertions(+), 10 deletions(-)
create mode 100644 Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
new file mode 100644
index 0000000..7648e17
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
@@ -0,0 +1,21 @@
+* Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART)
+
+Required properties:
+- compatible : should be "fsl,<soc>-uart", "fsl,imx-uart"
+- reg : address and length of the register set for the device
+- interrupts : should contain uart interrupt
+- id : should be the port ID defined by soc
+
+Optional properties:
+- fsl,has-rts-cts : indicate it has rts-cts
+- fsl,irda-mode : support irda mode
+
+Example:
+
+uart@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupts = <31>;
+ id = <1>;
+ fsl,has-rts-cts;
+};
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index a544731..2769353 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -45,6 +45,8 @@
#include <linux/delay.h>
#include <linux/rational.h>
#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -1223,6 +1225,63 @@ static int serial_imx_resume(struct platform_device *dev)
return 0;
}
+#ifdef CONFIG_OF
+static int serial_imx_probe_dt(struct imx_port *sport,
+ struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ const __be32 *line;
+
+ if (!node)
+ return -ENODEV;
+
+ line = of_get_property(node, "id", NULL);
+ if (!line)
+ return -ENODEV;
+
+ sport->port.line = be32_to_cpup(line) - 1;
+
+ if (of_get_property(node, "fsl,has-rts-cts", NULL))
+ sport->have_rtscts = 1;
+
+ if (of_get_property(node, "fsl,irda-mode", NULL))
+ sport->use_irda = 1;
+
+ return 0;
+}
+
+static struct of_device_id imx_uart_dt_ids[] = {
+ { .compatible = "fsl,imx-uart" },
+ {},
+};
+#else
+static int serial_imx_probe_dt(struct imx_port *sport,
+ struct platform_device *pdev)
+{
+ return -ENODEV;
+}
+#define imx_uart_dt_ids NULL
+#endif
+
+static int serial_imx_probe_pdata(struct imx_port *sport,
+ struct platform_device *pdev)
+{
+ struct imxuart_platform_data *pdata = pdev->dev.platform_data;
+
+ if (!pdata)
+ return 0;
+
+ if (pdata->flags & IMXUART_HAVE_RTSCTS)
+ sport->have_rtscts = 1;
+
+ if (pdata->flags & IMXUART_IRDA)
+ sport->use_irda = 1;
+
+ sport->port.line = pdev->id;
+
+ return 0;
+}
+
static int serial_imx_probe(struct platform_device *pdev)
{
struct imx_port *sport;
@@ -1235,6 +1294,12 @@ static int serial_imx_probe(struct platform_device *pdev)
if (!sport)
return -ENOMEM;
+ ret = serial_imx_probe_dt(sport, pdev);
+ if (ret == -ENODEV)
+ ret = serial_imx_probe_pdata(sport, pdev);
+ if (ret)
+ goto free;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
@@ -1259,7 +1324,6 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->port.fifosize = 32;
sport->port.ops = &imx_pops;
sport->port.flags = UPF_BOOT_AUTOCONF;
- sport->port.line = pdev->id;
init_timer(&sport->timer);
sport->timer.function = imx_timeout;
sport->timer.data = (unsigned long)sport;
@@ -1273,17 +1337,13 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->port.uartclk = clk_get_rate(sport->clk);
- imx_ports[pdev->id] = sport;
+ if (imx_ports[sport->port.line]) {
+ ret = -EBUSY;
+ goto clkput;
+ }
+ imx_ports[sport->port.line] = sport;
pdata = pdev->dev.platform_data;
- if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
- sport->have_rtscts = 1;
-
-#ifdef CONFIG_IRDA
- if (pdata && (pdata->flags & IMXUART_IRDA))
- sport->use_irda = 1;
-#endif
-
if (pdata && pdata->init) {
ret = pdata->init(pdev);
if (ret)
@@ -1344,6 +1404,7 @@ static struct platform_driver serial_imx_driver = {
.driver = {
.name = "imx-uart",
.owner = THIS_MODULE,
+ .of_match_table = imx_uart_dt_ids,
},
};
--
1.7.4.1
^ permalink raw reply related
* [PATCH 0/3] Add basic device support for imx51 babbage
From: Shawn Guo @ 2011-06-18 15:19 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: linux-kernel, netdev, devicetree-discuss, patches
This patch set adds the basic device tree support for imx51 babbage
board. With uart and fec dt support added, the dt kernel can boot
into console with nfs root on babbage, so that we get a good base
to start playing dt and converting further drivers to use dt on
imx51.
It creates the platform imx51-dt for using the device tree, and
leaves existing board support files alone, so nothing should be
broken. The plan is to add stuff step by step into imx51-dt to
get it support every existing imx51 boards, and then remove the
existing board files.
It works against Linus tree plus the dt infrastructure patches
posted by Grant Likely as part of the following series.
[RFC PATCH 00/11] Full device tree support for ARM Versatile
Comments are appreciated.
Shawn Guo (3):
serial/imx: add device tree support
net/fec: add device tree support
ARM: mx5: add basic device tree support for imx51 babbage
Documentation/devicetree/bindings/net/fsl-fec.txt | 14 +++
.../bindings/tty/serial/fsl-imx-uart.txt | 21 +++++
arch/arm/boot/dts/imx51-babbage.dts | 89 ++++++++++++++++++++
arch/arm/mach-mx5/Kconfig | 8 ++
arch/arm/mach-mx5/Makefile | 1 +
arch/arm/mach-mx5/imx51-dt.c | 70 +++++++++++++++
drivers/net/fec.c | 28 ++++++
drivers/tty/serial/imx.c | 81 ++++++++++++++++--
8 files changed, 302 insertions(+), 10 deletions(-)
^ permalink raw reply
* Re: [RFC 4/5] net: Support sending frame with specified FCS.
From: Eric Dumazet @ 2011-06-18 14:44 UTC (permalink / raw)
To: Ben Greear; +Cc: netdev
In-Reply-To: <4DFCB63F.7030301@candelatech.com>
Le samedi 18 juin 2011 à 07:29 -0700, Ben Greear a écrit :
> On 06/17/2011 10:54 PM, Eric Dumazet wrote:
> >
> > Please take a look at :
> >
> > arch/*/include/asm/socket.h for many arches.
>
> Do I need to update each file, or just make sure the value in
> asm-generic/socket.h is unique for all of them?
You need to update them all.
Check commit 3b885787ea4112 (adding SO_RXQ_OVFL) for reference
^ permalink raw reply
* Re: [RFC 4/5] net: Support sending frame with specified FCS.
From: Ben Greear @ 2011-06-18 14:29 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1308376473.3539.37.camel@edumazet-laptop>
On 06/17/2011 10:54 PM, Eric Dumazet wrote:
> Le vendredi 17 juin 2011 à 17:09 -0700, greearb@candelatech.com a
> écrit :
>> From: Ben Greear<greearb@candelatech.com>
>>
>> This allows user-space to send a packet with the
>> ethernet FCS appended to the end. Supporting NICs
>> will know to disable their own FCS calculations and
>> send frame as is.
>>
>> This is useful for injecting bad frames on a network
>> for testing.
>> diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
>> index 9a6115e..22193a2 100644
>> --- a/include/asm-generic/socket.h
>> +++ b/include/asm-generic/socket.h
>> @@ -64,4 +64,11 @@
>> #define SO_DOMAIN 39
>>
>> #define SO_RXQ_OVFL 40
>> +
>> +/* Instruct lower device to not calculate the frame
>> + * checksum. Useful for generating Ethernet frames
>> + * with custom checksums.
>> + */
>> +#define SO_NOFCS 41
>> +
>
> Please take a look at :
>
> arch/*/include/asm/socket.h for many arches.
Do I need to update each file, or just make sure the value in
asm-generic/socket.h is unique for all of them?
>> + if (unlikely(sk->sk_flags& SOCK_DONT_DO_LL_FCS))
>> + skb->use_specified_ether_crc = 1;
>> + else
>> + skb->use_specified_ether_crc = 0;
>> +
>
> Manipulating a bit field is very expensive, and having an else branch is
> expensive as well, so please avoid setting crc to zero if its already
> guaranteed to be so.
Ok, I'll double-check that it is zero by default. and fix that.
> Also I cant see where you actually _set_ the fcs value : that might
> trigger a kmemcheck warning later when we read it.
It is the last 4 bytes of the payload passed in from user-space.
>> dev_queue_xmit(skb);
>> rcu_read_unlock();
>> return len;
>> @@ -1134,6 +1143,10 @@ static int packet_snd(struct socket *sock,
>> int vnet_hdr_len;
>> struct packet_sock *po = pkt_sk(sk);
>> unsigned short gso_type = 0;
>> + int kludge = 0;
>> +
>> + if (unlikely(sk->sk_flags& SOCK_DONT_DO_LL_FCS))
>> + kludge = 4; /* We're doing our own Ethernet FCS */
>
> kludge ? You mean fcs_len or something ? ;)
Err, yeah :)
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* [PATCH #3 net-next 0/4] Pull request for 'davem-next.r8169' branch
From: Francois Romieu @ 2011-06-18 11:26 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang, Ben Hutchings
Please pull from branch 'davem-next.r8169' in repository
git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6.git davem-next.r8169
to get the changes below.
Since changeset 2 :
- snafu in patch #2/4.
Since changeset 1 :
- fixes and suggestions from Ben Hutchings.
ethtool displays no firmware information after patch #2/4 when the
firmware is invalid. Patch #4/4 unregisters invalid firmwares as soon
as it detects them and thus brings the version string back to "N/A".
I have tested the new firmware format with the rtl8168d-1 existing
firmware and the header below (w/o the version string delimiter)
0000000: 0000 0000 7274 6c38 3136 3864 2d31 5f30 ....rtl8168d-1_0
0000010: 2e30 2e31 2032 3031 3130 3631 3800 3132 .0.1 20110618.12
0000020: 3a30 3000 3000 0000 7501 0000 1a00 0000 :00.0...u.......
^^ version end
@Realtek: it may be useful to include some part of the "rtl.....-."
string extracted from the relevant "#define FIRMWARE_81.." into the
version identifier when you generate firmwares. Comments ?
Distance from 'davem-next' (c4dc4d108ace27cc0c594b67bd6bd945deaac8c2)
---------------------------------------------------------------------
fd112f2e15ba85d387de446a81aeb11e46ecc55d
960aee6c7d5951ac20c0227ad73bad56392f0afc
1c361efb226d609a07403057a71557faf500b17a
b6ffd97f5bcfd12df88ece6bc6df7a761ac5a049
Diffstat
--------
drivers/net/r8169.c | 217 +++++++++++++++++++++++++++++++++++++++------------
1 files changed, 167 insertions(+), 50 deletions(-)
Shortlog
--------
Francois Romieu (3):
r8169: move the firmware down into the device private data.
r8169: explicit firmware format check.
r8169: check firmware content sooner.
Hayes Wang (1):
r8169: support new firmware format.
Patch
-----
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7310824..bc5bb37 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -667,7 +667,18 @@ struct rtl8169_private {
struct rtl8169_counters counters;
u32 saved_wolopts;
- const struct firmware *fw;
+ struct rtl_fw {
+ const struct firmware *fw;
+
+#define RTL_VER_SIZE 32
+
+ char version[RTL_VER_SIZE];
+
+ struct rtl_fw_phy_action {
+ __le32 *code;
+ size_t size;
+ } phy_action;
+ } *rtl_fw;
#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN);
};
@@ -1222,12 +1233,14 @@ static void rtl8169_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct rtl8169_private *tp = netdev_priv(dev);
+ struct rtl_fw *rtl_fw = tp->rtl_fw;
strcpy(info->driver, MODULENAME);
strcpy(info->version, RTL8169_VERSION);
strcpy(info->bus_info, pci_name(tp->pci_dev));
- strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" :
- rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);
+ BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version));
+ strcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" :
+ rtl_fw->version);
}
static int rtl8169_get_regs_len(struct net_device *dev)
@@ -1741,21 +1754,75 @@ static void rtl_writephy_batch(struct rtl8169_private *tp,
#define PHY_DELAY_MS 0xe0000000
#define PHY_WRITE_ERI_WORD 0xf0000000
-static void
-rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
+struct fw_info {
+ u32 magic;
+ char version[RTL_VER_SIZE];
+ __le32 fw_start;
+ __le32 fw_len;
+ u8 chksum;
+} __packed;
+
+#define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code))
+
+static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
- __le32 *phytable = (__le32 *)fw->data;
- struct net_device *dev = tp->dev;
- size_t index, fw_size = fw->size / sizeof(*phytable);
- u32 predata, count;
+ const struct firmware *fw = rtl_fw->fw;
+ struct fw_info *fw_info = (struct fw_info *)fw->data;
+ struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
+ char *version = rtl_fw->version;
+ bool rc = false;
- if (fw->size % sizeof(*phytable)) {
- netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
- return;
+ if (fw->size < FW_OPCODE_SIZE)
+ goto out;
+
+ if (!fw_info->magic) {
+ size_t i, size, start;
+ u8 checksum = 0;
+
+ if (fw->size < sizeof(*fw_info))
+ goto out;
+
+ for (i = 0; i < fw->size; i++)
+ checksum += fw->data[i];
+ if (checksum != 0)
+ goto out;
+
+ start = le32_to_cpu(fw_info->fw_start);
+ if (start > fw->size)
+ goto out;
+
+ size = le32_to_cpu(fw_info->fw_len);
+ if (size > (fw->size - start) / FW_OPCODE_SIZE)
+ goto out;
+
+ memcpy(version, fw_info->version, RTL_VER_SIZE);
+
+ pa->code = (__le32 *)(fw->data + start);
+ pa->size = size;
+ } else {
+ if (fw->size % FW_OPCODE_SIZE)
+ goto out;
+
+ strlcpy(version, rtl_lookup_firmware_name(tp), RTL_VER_SIZE);
+
+ pa->code = (__le32 *)fw->data;
+ pa->size = fw->size / FW_OPCODE_SIZE;
}
+ version[RTL_VER_SIZE - 1] = 0;
- for (index = 0; index < fw_size; index++) {
- u32 action = le32_to_cpu(phytable[index]);
+ rc = true;
+out:
+ return rc;
+}
+
+static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev,
+ struct rtl_fw_phy_action *pa)
+{
+ bool rc = false;
+ size_t index;
+
+ for (index = 0; index < pa->size; index++) {
+ u32 action = le32_to_cpu(pa->code[index]);
u32 regno = (action & 0x0fff0000) >> 16;
switch(action & 0xf0000000) {
@@ -1771,25 +1838,25 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
case PHY_BJMPN:
if (regno > index) {
- netif_err(tp, probe, tp->dev,
+ netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
- return;
+ goto out;
}
break;
case PHY_READCOUNT_EQ_SKIP:
- if (index + 2 >= fw_size) {
- netif_err(tp, probe, tp->dev,
+ if (index + 2 >= pa->size) {
+ netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
- return;
+ goto out;
}
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
- if (index + 1 + regno >= fw_size) {
- netif_err(tp, probe, tp->dev,
+ if (index + 1 + regno >= pa->size) {
+ netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
- return;
+ goto out;
}
break;
@@ -1797,17 +1864,42 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
case PHY_WRITE_MAC_BYTE:
case PHY_WRITE_ERI_WORD:
default:
- netif_err(tp, probe, tp->dev,
+ netif_err(tp, ifup, tp->dev,
"Invalid action 0x%08x\n", action);
- return;
+ goto out;
}
}
+ rc = true;
+out:
+ return rc;
+}
+
+static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+ struct net_device *dev = tp->dev;
+ int rc = -EINVAL;
+
+ if (!rtl_fw_format_ok(tp, rtl_fw)) {
+ netif_err(tp, ifup, dev, "invalid firwmare\n");
+ goto out;
+ }
+
+ if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action))
+ rc = 0;
+out:
+ return rc;
+}
+
+static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+ struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
+ u32 predata, count;
+ size_t index;
- predata = 0;
- count = 0;
+ predata = count = 0;
- for (index = 0; index < fw_size; ) {
- u32 action = le32_to_cpu(phytable[index]);
+ for (index = 0; index < pa->size; ) {
+ u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
@@ -1879,18 +1971,20 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
static void rtl_release_firmware(struct rtl8169_private *tp)
{
- if (!IS_ERR_OR_NULL(tp->fw))
- release_firmware(tp->fw);
- tp->fw = RTL_FIRMWARE_UNKNOWN;
+ if (!IS_ERR_OR_NULL(tp->rtl_fw)) {
+ release_firmware(tp->rtl_fw->fw);
+ kfree(tp->rtl_fw);
+ }
+ tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
}
static void rtl_apply_firmware(struct rtl8169_private *tp)
{
- const struct firmware *fw = tp->fw;
+ struct rtl_fw *rtl_fw = tp->rtl_fw;
/* TODO: release firmware once rtl_phy_write_fw signals failures. */
- if (!IS_ERR_OR_NULL(fw))
- rtl_phy_write_fw(tp, fw);
+ if (!IS_ERR_OR_NULL(rtl_fw))
+ rtl_phy_write_fw(tp, rtl_fw);
}
static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
@@ -3443,7 +3537,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->timer.data = (unsigned long) dev;
tp->timer.function = rtl8169_phy_timer;
- tp->fw = RTL_FIRMWARE_UNKNOWN;
+ tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
rc = register_netdev(dev);
if (rc < 0)
@@ -3512,25 +3606,48 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static void rtl_request_firmware(struct rtl8169_private *tp)
+static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
{
- /* Return early if the firmware is already loaded / cached. */
- if (IS_ERR(tp->fw)) {
- const char *name;
+ struct rtl_fw *rtl_fw;
+ const char *name;
+ int rc = -ENOMEM;
- name = rtl_lookup_firmware_name(tp);
- if (name) {
- int rc;
+ name = rtl_lookup_firmware_name(tp);
+ if (!name)
+ goto out_no_firmware;
- rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev);
- if (rc >= 0)
- return;
+ rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL);
+ if (!rtl_fw)
+ goto err_warn;
- netif_warn(tp, ifup, tp->dev, "unable to load "
- "firmware patch %s (%d)\n", name, rc);
- }
- tp->fw = NULL;
- }
+ rc = request_firmware(&rtl_fw->fw, name, &tp->pci_dev->dev);
+ if (rc < 0)
+ goto err_free;
+
+ rc = rtl_check_firmware(tp, rtl_fw);
+ if (rc < 0)
+ goto err_release_firmware;
+
+ tp->rtl_fw = rtl_fw;
+out:
+ return;
+
+err_release_firmware:
+ release_firmware(rtl_fw->fw);
+err_free:
+ kfree(rtl_fw);
+err_warn:
+ netif_warn(tp, ifup, tp->dev, "unable to load firmware patch %s (%d)\n",
+ name, rc);
+out_no_firmware:
+ tp->rtl_fw = NULL;
+ goto out;
+}
+
+static void rtl_request_firmware(struct rtl8169_private *tp)
+{
+ if (IS_ERR(tp->rtl_fw))
+ rtl_request_uncached_firmware(tp);
}
static int rtl8169_open(struct net_device *dev)
--
Ueimor
^ permalink raw reply related
* [PATCH #3 net-next 4/4] r8169: check firmware content sooner.
From: Francois Romieu @ 2011-06-18 11:27 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang, Ben Hutchings
In-Reply-To: <20110618112605.GA2573@electric-eye.fr.zoreil.com>
Firmware checking is only performed when the firmware is loaded
instead of each time the driver inits the phy.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/r8169.c | 63 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7074989..bc5bb37 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1815,18 +1815,12 @@ out:
return rc;
}
-static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev,
+ struct rtl_fw_phy_action *pa)
{
- struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
- struct net_device *dev = tp->dev;
- u32 predata, count;
+ bool rc = false;
size_t index;
- if (!rtl_fw_format_ok(tp, rtl_fw)) {
- netif_err(tp, probe, dev, "invalid firwmare\n");
- return;
- }
-
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 regno = (action & 0x0fff0000) >> 16;
@@ -1844,25 +1838,25 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
case PHY_BJMPN:
if (regno > index) {
- netif_err(tp, probe, tp->dev,
+ netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
- return;
+ goto out;
}
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size) {
- netif_err(tp, probe, tp->dev,
+ netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
- return;
+ goto out;
}
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size) {
- netif_err(tp, probe, tp->dev,
+ netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
- return;
+ goto out;
}
break;
@@ -1870,14 +1864,39 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
case PHY_WRITE_MAC_BYTE:
case PHY_WRITE_ERI_WORD:
default:
- netif_err(tp, probe, tp->dev,
+ netif_err(tp, ifup, tp->dev,
"Invalid action 0x%08x\n", action);
- return;
+ goto out;
}
}
+ rc = true;
+out:
+ return rc;
+}
- predata = 0;
- count = 0;
+static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+ struct net_device *dev = tp->dev;
+ int rc = -EINVAL;
+
+ if (!rtl_fw_format_ok(tp, rtl_fw)) {
+ netif_err(tp, ifup, dev, "invalid firwmare\n");
+ goto out;
+ }
+
+ if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action))
+ rc = 0;
+out:
+ return rc;
+}
+
+static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+ struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
+ u32 predata, count;
+ size_t index;
+
+ predata = count = 0;
for (index = 0; index < pa->size; ) {
u32 action = le32_to_cpu(pa->code[index]);
@@ -3605,10 +3624,16 @@ static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
if (rc < 0)
goto err_free;
+ rc = rtl_check_firmware(tp, rtl_fw);
+ if (rc < 0)
+ goto err_release_firmware;
+
tp->rtl_fw = rtl_fw;
out:
return;
+err_release_firmware:
+ release_firmware(rtl_fw->fw);
err_free:
kfree(rtl_fw);
err_warn:
--
1.7.4.4
^ permalink raw reply related
* [PATCH #3 net-next 2/4] r8169: explicit firmware format check.
From: Francois Romieu @ 2011-06-18 11:26 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang, Ben Hutchings
In-Reply-To: <20110618112605.GA2573@electric-eye.fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/r8169.c | 62 ++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 3eeefe4..8fc9af2 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -669,6 +669,15 @@ struct rtl8169_private {
struct rtl_fw {
const struct firmware *fw;
+
+#define RTL_VER_SIZE 32
+
+ char version[RTL_VER_SIZE];
+
+ struct rtl_fw_phy_action {
+ __le32 *code;
+ size_t size;
+ } phy_action;
} *rtl_fw;
#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN);
};
@@ -1229,8 +1238,9 @@ static void rtl8169_get_drvinfo(struct net_device *dev,
strcpy(info->driver, MODULENAME);
strcpy(info->version, RTL8169_VERSION);
strcpy(info->bus_info, pci_name(tp->pci_dev));
- strncpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" :
- rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);
+ BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version));
+ strcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" :
+ rtl_fw->version);
}
static int rtl8169_get_regs_len(struct net_device *dev)
@@ -1744,21 +1754,47 @@ static void rtl_writephy_batch(struct rtl8169_private *tp,
#define PHY_DELAY_MS 0xe0000000
#define PHY_WRITE_ERI_WORD 0xf0000000
-static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+#define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code))
+
+static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
- __le32 *phytable = (__le32 *)fw->data;
+ struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
+ char *version = rtl_fw->version;
+ bool rc = false;
+
+ if (fw->size < FW_OPCODE_SIZE)
+ goto out;
+ else {
+ if (fw->size % FW_OPCODE_SIZE)
+ goto out;
+
+ strlcpy(version, rtl_lookup_firmware_name(tp), RTL_VER_SIZE);
+
+ pa->code = (__le32 *)fw->data;
+ pa->size = fw->size / FW_OPCODE_SIZE;
+ }
+ version[RTL_VER_SIZE - 1] = 0;
+
+ rc = true;
+out:
+ return rc;
+}
+
+static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+ struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
struct net_device *dev = tp->dev;
- size_t index, fw_size = fw->size / sizeof(*phytable);
u32 predata, count;
+ size_t index;
- if (fw->size % sizeof(*phytable)) {
- netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
+ if (!rtl_fw_format_ok(tp, rtl_fw)) {
+ netif_err(tp, probe, dev, "invalid firwmare\n");
return;
}
- for (index = 0; index < fw_size; index++) {
- u32 action = le32_to_cpu(phytable[index]);
+ for (index = 0; index < pa->size; index++) {
+ u32 action = le32_to_cpu(pa->code[index]);
u32 regno = (action & 0x0fff0000) >> 16;
switch(action & 0xf0000000) {
@@ -1780,7 +1816,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
}
break;
case PHY_READCOUNT_EQ_SKIP:
- if (index + 2 >= fw_size) {
+ if (index + 2 >= pa->size) {
netif_err(tp, probe, tp->dev,
"Out of range of firmware\n");
return;
@@ -1789,7 +1825,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
- if (index + 1 + regno >= fw_size) {
+ if (index + 1 + regno >= pa->size) {
netif_err(tp, probe, tp->dev,
"Out of range of firmware\n");
return;
@@ -1809,8 +1845,8 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
predata = 0;
count = 0;
- for (index = 0; index < fw_size; ) {
- u32 action = le32_to_cpu(phytable[index]);
+ for (index = 0; index < pa->size; ) {
+ u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH #2 net-next 0/4] Pull request for 'davem-next.r8169' branch
From: Francois Romieu @ 2011-06-17 22:48 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang, Ben Hutchings
In-Reply-To: <20110617224001.GA2483@electric-eye.fr.zoreil.com>
Francois Romieu <romieu@fr.zoreil.com> :
> Please pull from branch 'davem-next.r8169.hayes' in repository
Don't, I have not amended correctly #2.
--
Ueimor
^ permalink raw reply
* [PATCH #3 net-next 1/4] r8169: move the firmware down into the device private data.
From: Francois Romieu @ 2011-06-18 11:26 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang, Ben Hutchings
In-Reply-To: <20110618112605.GA2573@electric-eye.fr.zoreil.com>
No functional difference.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/r8169.c | 74 +++++++++++++++++++++++++++++++++------------------
1 files changed, 48 insertions(+), 26 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7310824..3eeefe4 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -667,7 +667,9 @@ struct rtl8169_private {
struct rtl8169_counters counters;
u32 saved_wolopts;
- const struct firmware *fw;
+ struct rtl_fw {
+ const struct firmware *fw;
+ } *rtl_fw;
#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN);
};
@@ -1222,11 +1224,12 @@ static void rtl8169_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct rtl8169_private *tp = netdev_priv(dev);
+ struct rtl_fw *rtl_fw = tp->rtl_fw;
strcpy(info->driver, MODULENAME);
strcpy(info->version, RTL8169_VERSION);
strcpy(info->bus_info, pci_name(tp->pci_dev));
- strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" :
+ strncpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" :
rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);
}
@@ -1741,9 +1744,9 @@ static void rtl_writephy_batch(struct rtl8169_private *tp,
#define PHY_DELAY_MS 0xe0000000
#define PHY_WRITE_ERI_WORD 0xf0000000
-static void
-rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
+static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
+ const struct firmware *fw = rtl_fw->fw;
__le32 *phytable = (__le32 *)fw->data;
struct net_device *dev = tp->dev;
size_t index, fw_size = fw->size / sizeof(*phytable);
@@ -1879,18 +1882,20 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
static void rtl_release_firmware(struct rtl8169_private *tp)
{
- if (!IS_ERR_OR_NULL(tp->fw))
- release_firmware(tp->fw);
- tp->fw = RTL_FIRMWARE_UNKNOWN;
+ if (!IS_ERR_OR_NULL(tp->rtl_fw)) {
+ release_firmware(tp->rtl_fw->fw);
+ kfree(tp->rtl_fw);
+ }
+ tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
}
static void rtl_apply_firmware(struct rtl8169_private *tp)
{
- const struct firmware *fw = tp->fw;
+ struct rtl_fw *rtl_fw = tp->rtl_fw;
/* TODO: release firmware once rtl_phy_write_fw signals failures. */
- if (!IS_ERR_OR_NULL(fw))
- rtl_phy_write_fw(tp, fw);
+ if (!IS_ERR_OR_NULL(rtl_fw))
+ rtl_phy_write_fw(tp, rtl_fw);
}
static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
@@ -3443,7 +3448,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->timer.data = (unsigned long) dev;
tp->timer.function = rtl8169_phy_timer;
- tp->fw = RTL_FIRMWARE_UNKNOWN;
+ tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
rc = register_netdev(dev);
if (rc < 0)
@@ -3512,25 +3517,42 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static void rtl_request_firmware(struct rtl8169_private *tp)
+static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
{
- /* Return early if the firmware is already loaded / cached. */
- if (IS_ERR(tp->fw)) {
- const char *name;
+ struct rtl_fw *rtl_fw;
+ const char *name;
+ int rc = -ENOMEM;
- name = rtl_lookup_firmware_name(tp);
- if (name) {
- int rc;
+ name = rtl_lookup_firmware_name(tp);
+ if (!name)
+ goto out_no_firmware;
- rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev);
- if (rc >= 0)
- return;
+ rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL);
+ if (!rtl_fw)
+ goto err_warn;
- netif_warn(tp, ifup, tp->dev, "unable to load "
- "firmware patch %s (%d)\n", name, rc);
- }
- tp->fw = NULL;
- }
+ rc = request_firmware(&rtl_fw->fw, name, &tp->pci_dev->dev);
+ if (rc < 0)
+ goto err_free;
+
+ tp->rtl_fw = rtl_fw;
+out:
+ return;
+
+err_free:
+ kfree(rtl_fw);
+err_warn:
+ netif_warn(tp, ifup, tp->dev, "unable to load firmware patch %s (%d)\n",
+ name, rc);
+out_no_firmware:
+ tp->rtl_fw = NULL;
+ goto out;
+}
+
+static void rtl_request_firmware(struct rtl8169_private *tp)
+{
+ if (IS_ERR(tp->rtl_fw))
+ rtl_request_uncached_firmware(tp);
}
static int rtl8169_open(struct net_device *dev)
--
1.7.4.4
^ permalink raw reply related
* [PATCH #3 net-next 3/4] r8169: support new firmware format.
From: Francois Romieu @ 2011-06-18 11:27 UTC (permalink / raw)
To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang, Ben Hutchings
In-Reply-To: <20110618112605.GA2573@electric-eye.fr.zoreil.com>
The new firmware format adds versioning as firmware for a specific
chipset appears to be subject to change. Current "legacy" format is
still supported.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/r8169.c | 36 +++++++++++++++++++++++++++++++++++-
1 files changed, 35 insertions(+), 1 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 8fc9af2..7074989 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1754,18 +1754,52 @@ static void rtl_writephy_batch(struct rtl8169_private *tp,
#define PHY_DELAY_MS 0xe0000000
#define PHY_WRITE_ERI_WORD 0xf0000000
+struct fw_info {
+ u32 magic;
+ char version[RTL_VER_SIZE];
+ __le32 fw_start;
+ __le32 fw_len;
+ u8 chksum;
+} __packed;
+
#define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code))
static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
+ struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
char *version = rtl_fw->version;
bool rc = false;
if (fw->size < FW_OPCODE_SIZE)
goto out;
- else {
+
+ if (!fw_info->magic) {
+ size_t i, size, start;
+ u8 checksum = 0;
+
+ if (fw->size < sizeof(*fw_info))
+ goto out;
+
+ for (i = 0; i < fw->size; i++)
+ checksum += fw->data[i];
+ if (checksum != 0)
+ goto out;
+
+ start = le32_to_cpu(fw_info->fw_start);
+ if (start > fw->size)
+ goto out;
+
+ size = le32_to_cpu(fw_info->fw_len);
+ if (size > (fw->size - start) / FW_OPCODE_SIZE)
+ goto out;
+
+ memcpy(version, fw_info->version, RTL_VER_SIZE);
+
+ pa->code = (__le32 *)(fw->data + start);
+ pa->size = size;
+ } else {
if (fw->size % FW_OPCODE_SIZE)
goto out;
--
1.7.4.4
^ permalink raw reply related
* Re: kernel 2.6.39 eats multicast packets
From: Eric Dumazet @ 2011-06-18 10:25 UTC (permalink / raw)
To: Knut Tidemann; +Cc: netdev, davem
In-Reply-To: <op.vw7on9im1qh6di@localhost.localdomain>
Le vendredi 17 juin 2011 à 10:32 +0200, Knut Tidemann a écrit :
> Hello.
>
> We're seeing an issue where a listening UDP socket in a multicast group
> doesn't receive some multicast packets.
> From simple testing it seems that the first packet from a new host is not
> passed through the kernel and down to the socket, but the next packets
> are. The packets can be
> seen with a tool such as tcpdump, but they never reach the user space
> socket. It is worth noting, that the packet loss does not occur when
> sending to and from the same host,
> to a multicast address. The address and port we have been using in our
> tests are 224.0.1.75:5060. I've also attached the testing code at the end
> of this email. The issue was also present in 3.0-rc1.
>
> This issue is not present in 2.6.38 and I've bisected the issue to the
> following commit:
>
> ----
> b23dd4fe42b455af5c6e20966b7d6959fa8352ea is the first bad commit
> commit b23dd4fe42b455af5c6e20966b7d6959fa8352ea
> Author: David S. Miller <davem@davemloft.net>
> Date: Wed Mar 2 14:31:35 2011 -0800
>
> ipv4: Make output route lookup return rtable directly.
>
> Instead of on the stack.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ----
>
Knut, this is awesome, your bug report is perfect and was really helpful
to let me fix the bug in maybe 15 minutes, including reboot and tests ;)
Many thanks !
[PATCH] ipv4: fix multicast losses
Knut Tidemann found that first packet of a multicast flow was not
correctly received, and bisected the regression to commit b23dd4fe42b4
(Make output route lookup return rtable directly.)
Special thanks to Knut, who provided a very nice bug report, including
sample programs to demonstrate the bug.
Reported-and-bisectedby: Knut Tidemann <knut.andre.tidemann@jotron.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv4/route.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 045f0ec..aa13ef1 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1902,9 +1902,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
rth = rt_intern_hash(hash, rth, skb, dev->ifindex);
- err = 0;
- if (IS_ERR(rth))
- err = PTR_ERR(rth);
+ return IS_ERR(rth) ? PTR_ERR(rth) : 0;
e_nobufs:
return -ENOBUFS;
^ permalink raw reply related
* Re: what's causing "ip_rt_bug"?
From: Tomasz Chmielewski @ 2011-06-18 8:31 UTC (permalink / raw)
To: Julian Anastasov; +Cc: Eric Dumazet, netdev
In-Reply-To: <alpine.LFD.2.00.1106180227400.1583@ja.ssi.bg>
On 18.06.2011 01:56, Julian Anastasov wrote:
>
> Hello,
>
> On Fri, 17 Jun 2011, Tomasz Chmielewski wrote:
>
>>> What your routing table looks like ? (ip ro)
>>
>> It's just a proxy, no special routing set:
>
> Is transparent proxy used?
Yes, it is.
>> # ip ro
>> 58.185.117.18 via 119.46.110.193 dev eth0
>> 119.46.240.13 via 119.46.110.193 dev eth0
>> 58.185.117.29 via 119.46.110.193 dev eth0
>> 119.46.241.13 via 119.46.110.193 dev eth0
>
> Same route for 58.185.117.28 2nd time? Is that possible?:
Not second time, the addresses are similar, but different: 58.185.117.18, 58.185.117.29, 58.185.117.28. Unless there's something I don't see! ;)
>> 58.185.117.28 via 119.46.110.193 dev eth0
>> 119.46.110.192/26 dev eth0 proto kernel scope link src 119.46.110.197
>> 169.254.0.0/16 dev eth0 scope link
>> default via 119.46.110.195 dev eth0
>>
>>
>> The box is also crashing every few days; and I really had no clue why (just connected a serial console to catch any new oops/panic).
>>
>>
>> The last time it crashed, I have this entry in syslog:
>>
>> Jun 17 16:16:17 TRUE-SC02 kernel: [172488.602629] ip_rt_bug: 124.121.155.197 -> 119.46.110.197, ?
>
> The ip_rt_bug messages show that skb->dev is
> NULL (OUTPUT hook), daddr in IP header is local address,
> may be some original received packet. If such packet is
> provided to ip_route_me_harder(skb, RTN_UNSPEC) an
> ip_route_input call can happen. Calling later dst_output
> should lead to this warning. The question is what can
> cause received packet to appear in OUTPUT hook where
> a change in mark or TOS can can trigger such ip_route_input
> call. What kind of netfilter modules are used? nf_queue,
> -j REJECT, NAT? Is 124.121.155.197 a local address?
No, it's not local.
With "ip_rt_bug: 124.121.184.77 -> 119.46.110.197, ?" lines, only the address on the right side is local.
# iptables -L -t nat -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 8080
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
# iptables -L -t mangle -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DIVERT tcp -- 0.0.0.0/0 0.0.0.0/0 socket
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Chain DIVERT (1 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK xset 0x1/0xffffffff
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
# lsmod
Module Size Used by
xt_mark 1171 1
xt_socket 1922 1
nf_tproxy_core 1752 1 xt_socket,[permanent]
ipt_REDIRECT 1093 1
xt_tcpudp 2331 1
ebt_redirect 1234 1
ebt_ip 1562 1
ebtable_broute 1395 1
bridge 64647 1 ebtable_broute
stp 1931 1 bridge
llc 5071 2 bridge,stp
ebtables 20458 1 ebtable_broute
iptable_mangle 1351 1
iptable_nat 3644 1
nf_nat 16977 2 ipt_REDIRECT,iptable_nat
nf_conntrack_ipv4 11077 3 iptable_nat,nf_nat
nf_defrag_ipv4 1337 2 xt_socket,nf_conntrack_ipv4
i2c_dev 4561 0
i2c_core 21774 1 i2c_dev
nf_conntrack_netbios_ns 1486 0
nf_conntrack 65085 5 xt_socket,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_netbios_ns
iptable_filter 1402 0
ip_tables 14931 3 iptable_mangle,iptable_nat,iptable_filter
x_tables 20316 11 xt_mark,xt_socket,ipt_REDIRECT,xt_tcpudp,ebt_redirect,ebt_ip,ebtables,iptable_mangle,iptable_nat,iptable_filter,ip_tables
dm_mirror 11724 0
dm_multipath 14772 0
scsi_dh 5994 1 dm_multipath
video 21310 0
output 2103 1 video
sbs 11378 0
sbshc 4115 1 sbs
battery 10902 0
acpi_memhotplug 4135 0
ac 3274 0
parport_pc 21355 0
lp 9491 0
parport 33290 2 parport_pc,lp
option 16045 0
usb_wwan 10222 1 option
usbserial 34477 2 option,usb_wwan
serio_raw 4064 0
tpm_tis 9203 0
tpm 14317 1 tpm_tis
tpm_bios 5252 1 tpm
rtc_cmos 8731 0
rtc_core 14080 1 rtc_cmos
rtc_lib 2497 1 rtc_core
button 5662 0
igb 131680 0
shpchp 29302 0
pcspkr 1822 0
dm_region_hash 9574 1 dm_mirror
dm_log 8359 2 dm_mirror,dm_region_hash
usb_storage 45133 0
ata_piix 22147 0
libata 169650 1 ata_piix
cciss 88474 24
sd_mod 28117 0
scsi_mod 156163 5 scsi_dh,usb_storage,libata,cciss,sd_mod
ext3 114308 12
jbd 43368 1 ext3
uhci_hcd 18941 0
ohci_hcd 20027 0
ehci_hcd 33605 0
# ifconfig -a
eth0 Link encap:Ethernet HWaddr 18:A9:05:41:CC:CE
inet addr:119.46.110.197 Bcast:119.46.110.255 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4872707550 errors:0 dropped:1177767 overruns:1177767 frame:0
TX packets:5066061004 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3719046973104 (3.3 TiB) TX bytes:4237588228875 (3.8 TiB)
eth0:1 Link encap:Ethernet HWaddr 18:A9:05:41:CC:CE
inet addr:119.46.110.249 Bcast:119.46.110.255 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
--
Tomasz Chmielewski
http://wpkg.org
^ permalink raw reply
* Re: [RFC 4/5] net: Support sending frame with specified FCS.
From: Eric Dumazet @ 2011-06-18 5:54 UTC (permalink / raw)
To: greearb; +Cc: netdev
In-Reply-To: <1308355783-22407-5-git-send-email-greearb@candelatech.com>
Le vendredi 17 juin 2011 à 17:09 -0700, greearb@candelatech.com a
écrit :
> From: Ben Greear <greearb@candelatech.com>
>
> This allows user-space to send a packet with the
> ethernet FCS appended to the end. Supporting NICs
> will know to disable their own FCS calculations and
> send frame as is.
>
> This is useful for injecting bad frames on a network
> for testing.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 9a6115e... 22193a2... M include/asm-generic/socket.h
> :100644 100644 c0a4f3a... 05b15be... M include/linux/skbuff.h
> :100644 100644 f2046e4... d7e0d88... M include/net/sock.h
> :100644 100644 46cbd28... a552560... M net/core/skbuff.c
> :100644 100644 6e81978... 0c5f827... M net/core/sock.c
> :100644 100644 c0c3cda... 0d29d68... M net/packet/af_packet.c
> include/asm-generic/socket.h | 7 +++++++
> include/linux/skbuff.h | 5 ++++-
> include/net/sock.h | 6 ++++++
> net/core/skbuff.c | 1 +
> net/core/sock.c | 7 +++++++
> net/packet/af_packet.c | 22 ++++++++++++++++++++--
> 6 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
> index 9a6115e..22193a2 100644
> --- a/include/asm-generic/socket.h
> +++ b/include/asm-generic/socket.h
> @@ -64,4 +64,11 @@
> #define SO_DOMAIN 39
>
> #define SO_RXQ_OVFL 40
> +
> +/* Instruct lower device to not calculate the frame
> + * checksum. Useful for generating Ethernet frames
> + * with custom checksums.
> + */
> +#define SO_NOFCS 41
> +
Please take a look at :
arch/*/include/asm/socket.h for many arches.
> #endif /* __ASM_GENERIC_SOCKET_H */
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index c0a4f3a..05b15be 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -307,6 +307,8 @@ typedef unsigned char *sk_buff_data_t;
> * @peeked: this packet has been seen already, so stats have been
> * done for it, don't do them again
> * @nf_trace: netfilter packet trace flag
> + * @use_specified_ether_crc: skb is Ethernet frame with FCS already
> + * appended. Use that FCS. Requires special support in NIC.
> * @nfctinfo: Relationship of this skb to the connection
> * @nfct_reasm: netfilter conntrack re-assembly pointer
> * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
> @@ -396,7 +398,8 @@ struct sk_buff {
> #ifdef CONFIG_IPV6_NDISC_NODETYPE
> __u8 ndisc_nodetype:2;
> #endif
> - __u8 ooo_okay:1;
> + __u8 ooo_okay:1,
> + use_specified_ether_crc:1;
> kmemcheck_bitfield_end(flags2);
>
> /* 0/13 bit hole */
> diff --git a/include/net/sock.h b/include/net/sock.h
> index f2046e4..d7e0d88 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -563,6 +563,12 @@ enum sock_flags {
> SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */
> SOCK_FASYNC, /* fasync() active */
> SOCK_RXQ_OVFL,
> + SOCK_DONT_DO_LL_FCS, /* Tell NIC not to do the Ethernet FCS.
> + * Will use last 4 bytes of packet sent from
> + * user-space instead. Requires special
> + * support in NIC.
> + */
> +
> };
>
> static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 46cbd28..a552560 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -541,6 +541,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
> new->tc_verd = old->tc_verd;
> #endif
> #endif
> + new->use_specified_ether_crc = old->use_specified_ether_crc;
> new->vlan_tci = old->vlan_tci;
>
> skb_copy_secmark(new, old);
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 6e81978..0c5f827 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -641,6 +641,13 @@ set_rcvbuf:
> sock_warn_obsolete_bsdism("setsockopt");
> break;
>
> + case SO_NOFCS:
> + if (valbool)
> + sk->sk_flags |= SOCK_DONT_DO_LL_FCS;
> + else
> + sk->sk_flags &= ~(SOCK_DONT_DO_LL_FCS);
> + break;
> +
> case SO_PASSCRED:
> if (valbool)
> set_bit(SOCK_PASSCRED, &sock->flags);
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index c0c3cda..0d29d68 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -430,6 +430,10 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
> struct net_device *dev;
> __be16 proto = 0;
> int err;
> + int kludge = 0;
> +
> + if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> + kludge = 4; /* We're doing our own FCS */
>
> /*
> * Get and verify the address.
> @@ -465,7 +469,7 @@ retry:
> */
>
> err = -EMSGSIZE;
> - if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN)
> + if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN + kludge)
> goto out_unlock;
>
> if (!skb) {
> @@ -518,6 +522,11 @@ retry:
> if (err < 0)
> goto out_unlock;
>
> + if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> + skb->use_specified_ether_crc = 1;
> + else
> + skb->use_specified_ether_crc = 0;
> +
Manipulating a bit field is very expensive, and having an else branch is
expensive as well, so please avoid setting crc to zero if its already
guaranteed to be so.
Also I cant see where you actually _set_ the fcs value : that might
trigger a kmemcheck warning later when we read it.
> dev_queue_xmit(skb);
> rcu_read_unlock();
> return len;
> @@ -1134,6 +1143,10 @@ static int packet_snd(struct socket *sock,
> int vnet_hdr_len;
> struct packet_sock *po = pkt_sk(sk);
> unsigned short gso_type = 0;
> + int kludge = 0;
> +
> + if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> + kludge = 4; /* We're doing our own Ethernet FCS */
kludge ? You mean fcs_len or something ? ;)
>
> /*
> * Get and verify the address.
> @@ -1215,7 +1228,7 @@ static int packet_snd(struct socket *sock,
> }
>
> err = -EMSGSIZE;
> - if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN))
> + if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN + kludge))
> goto out_unlock;
>
> err = -ENOBUFS;
> @@ -1278,6 +1291,11 @@ static int packet_snd(struct socket *sock,
> len += vnet_hdr_len;
> }
>
> + if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> + skb->use_specified_ether_crc = 1;
> + else
> + skb->use_specified_ether_crc = 0;
same remark here : ether_crc is already 0 here.
> +
> /*
> * Now send it
> */
^ permalink raw reply
* Re: [RFC Patch] bonding: move to net/ directory
From: WANG Cong @ 2011-06-18 2:48 UTC (permalink / raw)
To: netdev
In-Reply-To: <1307381465.2698.5740.camel@jtkirshe-linux>
On Mon, 06 Jun 2011 10:31:05 -0700, Jeff Kirsher wrote:
> On Mon, 2011-06-06 at 09:50 -0700, Joe Perches wrote:
>> On Tue, 2011-06-07 at 00:34 +0800, Américo Wang wrote:
>> > I agree with this, IMHO this would help to organize the code better.
>> > And currently only tuntap and bonding are still in net/ directory. In
>> > any aspects, now we are mixing net/ and drivers/net/ currently, which
>> > could be improved.
>>
>> There is a proposal to move some drivers/net content to drivers/net/sw/
>>
>> http://vger.kernel.org/netconf2010_slides/netconf-jtk.pdf
>>
>> I think that'd be fine too.
>>
>> I believe Jeff is going to submit patches soonish.
>>
>> http://comments.gmane.org/gmane.linux.network/197232
>>
>>
>>
> Correct, patches will be sent out here this week.
>
But I still don't see them so far... :-/ Can you Cc me as well?
> As far as moving tunap, bonding, etc into /drivers/net/sw that is the
> eventual plan, but I have not done this work for this upcoming patchset.
> I want to coordinate this work with Stephen Hemminger before I do any
> moves.
Is net/bridge ==> drivers/net/sw/bridge in your plan too?
^ permalink raw reply
* Re: [PATCH 2/2] e100: Support receiving Ethernet FCS.
From: Jeff Kirsher @ 2011-06-18 1:47 UTC (permalink / raw)
To: greearb; +Cc: netdev
In-Reply-To: <1308339615-5866-3-git-send-email-greearb@candelatech.com>
On Fri, Jun 17, 2011 at 12:40, <greearb@candelatech.com> wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> Helps when sniffing packets.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 e336c79... 647d8c6... M drivers/net/e100.c
> drivers/net/e100.c | 35 ++++++++++++++++++++++++++++++++---
> 1 files changed, 32 insertions(+), 3 deletions(-)
>
The patch looks fine to me.
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
--
Cheers,
Jeff
^ permalink raw reply
* [RFC 5/5] e1000e: Support sending frame with custom FCS.
From: greearb @ 2011-06-18 0:09 UTC (permalink / raw)
To: netdev; +Cc: Ben Greear
In-Reply-To: <1308355783-22407-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
This is good for testing by injecting frames with invalid
FCS onto a network.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 3310c3d... 011a95f... M drivers/net/e1000e/netdev.c
drivers/net/e1000e/netdev.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3310c3d..011a95f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4417,6 +4417,7 @@ link_up:
#define E1000_TX_FLAGS_VLAN 0x00000002
#define E1000_TX_FLAGS_TSO 0x00000004
#define E1000_TX_FLAGS_IPV4 0x00000008
+#define E1000_TX_FLAGS_NO_FCS 0x00000010
#define E1000_TX_FLAGS_VLAN_MASK 0xffff0000
#define E1000_TX_FLAGS_VLAN_SHIFT 16
@@ -4681,6 +4682,9 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
}
+ if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
+ txd_lower &= ~(E1000_TXD_CMD_IFCS);
+
i = tx_ring->next_to_use;
do {
@@ -4698,6 +4702,10 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
+ /* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
+ if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
+ tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
+
/*
* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only
@@ -4900,6 +4908,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (skb->protocol == htons(ETH_P_IP))
tx_flags |= E1000_TX_FLAGS_IPV4;
+ if (unlikely(skb->use_specified_ether_crc))
+ tx_flags |= E1000_TX_FLAGS_NO_FCS;
+
/* if count is 0 then mapping error has occurred */
count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
if (count) {
--
1.7.3.4
^ permalink raw reply related
* [RFC 4/5] net: Support sending frame with specified FCS.
From: greearb @ 2011-06-18 0:09 UTC (permalink / raw)
To: netdev; +Cc: Ben Greear
In-Reply-To: <1308355783-22407-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
This allows user-space to send a packet with the
ethernet FCS appended to the end. Supporting NICs
will know to disable their own FCS calculations and
send frame as is.
This is useful for injecting bad frames on a network
for testing.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 9a6115e... 22193a2... M include/asm-generic/socket.h
:100644 100644 c0a4f3a... 05b15be... M include/linux/skbuff.h
:100644 100644 f2046e4... d7e0d88... M include/net/sock.h
:100644 100644 46cbd28... a552560... M net/core/skbuff.c
:100644 100644 6e81978... 0c5f827... M net/core/sock.c
:100644 100644 c0c3cda... 0d29d68... M net/packet/af_packet.c
include/asm-generic/socket.h | 7 +++++++
include/linux/skbuff.h | 5 ++++-
include/net/sock.h | 6 ++++++
net/core/skbuff.c | 1 +
net/core/sock.c | 7 +++++++
net/packet/af_packet.c | 22 ++++++++++++++++++++--
6 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index 9a6115e..22193a2 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -64,4 +64,11 @@
#define SO_DOMAIN 39
#define SO_RXQ_OVFL 40
+
+/* Instruct lower device to not calculate the frame
+ * checksum. Useful for generating Ethernet frames
+ * with custom checksums.
+ */
+#define SO_NOFCS 41
+
#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c0a4f3a..05b15be 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -307,6 +307,8 @@ typedef unsigned char *sk_buff_data_t;
* @peeked: this packet has been seen already, so stats have been
* done for it, don't do them again
* @nf_trace: netfilter packet trace flag
+ * @use_specified_ether_crc: skb is Ethernet frame with FCS already
+ * appended. Use that FCS. Requires special support in NIC.
* @nfctinfo: Relationship of this skb to the connection
* @nfct_reasm: netfilter conntrack re-assembly pointer
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
@@ -396,7 +398,8 @@ struct sk_buff {
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
- __u8 ooo_okay:1;
+ __u8 ooo_okay:1,
+ use_specified_ether_crc:1;
kmemcheck_bitfield_end(flags2);
/* 0/13 bit hole */
diff --git a/include/net/sock.h b/include/net/sock.h
index f2046e4..d7e0d88 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -563,6 +563,12 @@ enum sock_flags {
SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */
SOCK_FASYNC, /* fasync() active */
SOCK_RXQ_OVFL,
+ SOCK_DONT_DO_LL_FCS, /* Tell NIC not to do the Ethernet FCS.
+ * Will use last 4 bytes of packet sent from
+ * user-space instead. Requires special
+ * support in NIC.
+ */
+
};
static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 46cbd28..a552560 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -541,6 +541,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->tc_verd = old->tc_verd;
#endif
#endif
+ new->use_specified_ether_crc = old->use_specified_ether_crc;
new->vlan_tci = old->vlan_tci;
skb_copy_secmark(new, old);
diff --git a/net/core/sock.c b/net/core/sock.c
index 6e81978..0c5f827 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -641,6 +641,13 @@ set_rcvbuf:
sock_warn_obsolete_bsdism("setsockopt");
break;
+ case SO_NOFCS:
+ if (valbool)
+ sk->sk_flags |= SOCK_DONT_DO_LL_FCS;
+ else
+ sk->sk_flags &= ~(SOCK_DONT_DO_LL_FCS);
+ break;
+
case SO_PASSCRED:
if (valbool)
set_bit(SOCK_PASSCRED, &sock->flags);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index c0c3cda..0d29d68 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -430,6 +430,10 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
struct net_device *dev;
__be16 proto = 0;
int err;
+ int kludge = 0;
+
+ if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
+ kludge = 4; /* We're doing our own FCS */
/*
* Get and verify the address.
@@ -465,7 +469,7 @@ retry:
*/
err = -EMSGSIZE;
- if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN)
+ if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN + kludge)
goto out_unlock;
if (!skb) {
@@ -518,6 +522,11 @@ retry:
if (err < 0)
goto out_unlock;
+ if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
+ skb->use_specified_ether_crc = 1;
+ else
+ skb->use_specified_ether_crc = 0;
+
dev_queue_xmit(skb);
rcu_read_unlock();
return len;
@@ -1134,6 +1143,10 @@ static int packet_snd(struct socket *sock,
int vnet_hdr_len;
struct packet_sock *po = pkt_sk(sk);
unsigned short gso_type = 0;
+ int kludge = 0;
+
+ if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
+ kludge = 4; /* We're doing our own Ethernet FCS */
/*
* Get and verify the address.
@@ -1215,7 +1228,7 @@ static int packet_snd(struct socket *sock,
}
err = -EMSGSIZE;
- if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN))
+ if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN + kludge))
goto out_unlock;
err = -ENOBUFS;
@@ -1278,6 +1291,11 @@ static int packet_snd(struct socket *sock,
len += vnet_hdr_len;
}
+ if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
+ skb->use_specified_ether_crc = 1;
+ else
+ skb->use_specified_ether_crc = 0;
+
/*
* Now send it
*/
--
1.7.3.4
^ permalink raw reply related
* [RFC 3/5] e100: Support receiving errored frames.
From: greearb @ 2011-06-18 0:09 UTC (permalink / raw)
To: netdev; +Cc: Ben Greear
In-Reply-To: <1308355783-22407-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
This can be helpful when sniffing dodgy networks.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 647d8c6... aad303d... M drivers/net/e100.c
drivers/net/e100.c | 42 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 647d8c6..aad303d 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -588,6 +588,7 @@ struct nic {
wol_magic = (1 << 3),
ich_10h_workaround = (1 << 4),
save_rxfcs = (1 << 5),
+ save_rxerr = (1 << 6),
} flags ____cacheline_aligned;
enum mac mac;
@@ -1126,9 +1127,13 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
config->full_duplex_force = 0x1; /* 1=force, 0=auto */
if (nic->flags & promiscuous || nic->loopback) {
+ config->promiscuous_mode = 0x1; /* 1=on, 0=off */
+ }
+
+ if (nic->flags & save_rxerr) {
+ config->rx_discard_overruns = 0x1; /* 1=save, 0=discard */
config->rx_save_bad_frames = 0x1; /* 1=save, 0=discard */
config->rx_discard_short_frames = 0x0; /* 1=discard, 0=save */
- config->promiscuous_mode = 0x1; /* 1=on, 0=off */
}
if (nic->flags & save_rxfcs)
@@ -1983,7 +1988,18 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
skb_put(skb, actual_size);
skb->protocol = eth_type_trans(skb, nic->netdev);
- if (unlikely(!(rfd_status & cb_ok))) {
+ if (unlikely(nic->flags & save_rxerr)) {
+ if (!(rfd_status & cb_ok)) {
+ skb->pkt_type = PACKET_INVALID;
+ } else if (actual_size >
+ ETH_DATA_LEN + VLAN_ETH_HLEN + rxfcs_pad) {
+ nic->rx_over_length_errors++;
+ skb->pkt_type = PACKET_INVALID;
+ }
+ goto process_skb;
+ }
+
+ if (unlikely((nic->flags & save_rxerr) && !(rfd_status & cb_ok))) {
/* Don't indicate if hardware indicates errors */
dev_kfree_skb_any(skb);
} else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN + rxfcs_pad) {
@@ -1991,6 +2007,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
nic->rx_over_length_errors++;
dev_kfree_skb_any(skb);
} else {
+process_skb:
dev->stats.rx_packets++;
dev->stats.rx_bytes += actual_size;
netif_receive_skb(skb);
@@ -2397,6 +2414,25 @@ static u32 e100_get_save_rxfcs(struct net_device *netdev)
return !!(nic->flags & save_rxfcs);
}
+static int e100_set_save_rxerr(struct net_device *netdev, u32 data)
+{
+ struct nic *nic = netdev_priv(netdev);
+ if (data)
+ nic->flags |= save_rxerr;
+ else
+ nic->flags &= ~save_rxerr;
+
+ e100_exec_cb(nic, NULL, e100_configure);
+
+ return 0;
+}
+
+static u32 e100_get_save_rxerr(struct net_device *netdev)
+{
+ struct nic *nic = netdev_priv(netdev);
+ return !!(nic->flags & save_rxerr);
+}
+
static void e100_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info)
{
@@ -2718,6 +2754,8 @@ static const struct ethtool_ops e100_ethtool_ops = {
.get_sset_count = e100_get_sset_count,
.set_save_rxfcs = e100_set_save_rxfcs,
.get_save_rxfcs = e100_get_save_rxfcs,
+ .set_save_rxerr = e100_set_save_rxerr,
+ .get_save_rxerr = e100_get_save_rxerr,
};
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
--
1.7.3.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox