[RESEND PATCH v6 5/6] ARM: dts: stm32f429: Align Ethernet node with new bindings properties
This patch aligns clocks names and node reference according to new stm32-dwmac glue binding. It also renames Ethernet pinctrl phandle (indeed there is no need to add 0 as Ethernet instance as there is only one IP in SOC). Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index 35df462..5995998 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -304,7 +304,7 @@ }; }; - ethernet0_mii: mii@0 { + ethernet_mii: mii@0 { pins { pinmux = , , @@ -363,13 +363,13 @@ st,mem2mem; }; - ethernet0: dwmac@40028000 { + mac: ethernet@40028000 { compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; reg = <0x40028000 0x8000>; reg-names = "stmmaceth"; interrupts = <61>, <62>; interrupt-names = "macirq", "eth_wake_irq"; - clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx"; clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; st,syscon = <&syscfg 0x4>; snps,pbl = <8>; -- 1.9.1
[RESEND PATCH v6 6/6] ARM: dts: stm32f429: Update Ethernet node on Eval board
Update new pinctrl phandle name and use new node name. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 6bfc595..9a72445 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -94,9 +94,9 @@ clock-frequency = <2500>; }; -ðernet0 { +&mac { status = "okay"; - pinctrl-0 = <ðernet0_mii>; + pinctrl-0 = <ðernet_mii>; pinctrl-names = "default"; phy-mode= "mii-id"; mdio0 { -- 1.9.1
[RESEND PATCH v6 1/6] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Reviewed-by: Joachim Eastwood Acked-by: Giuseppe Cavallaro Tested-by: Maxime Coquelin Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..235d679 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -104,6 +104,18 @@ config DWMAC_STI device driver. This driver is used on for the STi series SOCs GMAC ethernet controller. +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF && HAS_IOMEM + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. + config DWMAC_SUNXI tristate "Allwinner GMAC support" default ARCH_SUNXI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 0fb362d..8828ada 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA)+= dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o stmmac-platform-objs:= stmmac_platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 000..79d8b92 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,193 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) +{ + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; + u32 reg = dwmac->mode_reg; + u32 val; + int ret; + + val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + clk_disable_unprepare(dwmac->clk_tx); + + return ret; +} + +static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) +{ + clk_disable_unprepare(dwmac->clk_tx); + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) +{ + struct device_node *np = dev->of_node; + int err; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); + if (IS_ERR(dwmac->clk_tx)) { + dev_err(dev, "No tx clock provided...\n"); + return PTR_ERR(dwmac->clk_tx); + } + dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); + if (IS_ERR(dwmac->clk_rx)) { + dev_err(dev, "No rx clock provided...\n"); + return PTR_ERR(dwmac->clk_rx); + } + + /* Get mode register */ + dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(dwmac->regmap)) + return PTR_ERR(dwmac->regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) + dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); + + return err; +} + +static int stm32_dwmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct stm32_dwmac *dwmac; + int ret; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return ret; + + plat_
[RESEND PATCH v6 0/6] Add Ethernet support on STM32F429
STM32F429 Chip embeds a Synopsys 3.50a MAC IP. This series: -enhance current stmmac driver to control it (code already available) and adds basic glue for STM32F429 chip. -Enable basic Net config in kernel. Changes since v5: -Fix typo in bindings documentation patch. -Change clocks names in stm32-dwmac glue driver / Documentation. -After rebase, stm32 ethernet node is now available. It has to be updated according to new clocks names. Changes since v4: -Fix dirty copy/past in bindings documentation patch. Changes since v3: -Fix "tx-clk" and "rx-clk" as required clocks. Driver and bindings are modified. Changes since v2: -Fix alphabetic order in Kconfig and Makefile. -Improve code according to Joachim review. -Binding: remove useless entry. Changes since v1: -Fix Kbuild issue in Kconfig. -Remove init/exit callbacks. Suspend/Resume and remove driver is no more driven in stmmac_pltfr but directly in dwmac-stm32 glue driver. -Take into account Joachim review. Regards. Alexandre. Alexandre TORGUE (6): net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Documentation: Bindings: Add STM32 DWMAC glue net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP ARM: STM32: Enable Ethernet in stm32_defconfig ARM: dts: stm32f429: Align Ethernet node with new bindings properties ARM: dts: stm32f429: Update Ethernet node on Eval board .../devicetree/bindings/net/stm32-dwmac.txt| 32 arch/arm/boot/dts/stm32429i-eval.dts | 4 +- arch/arm/boot/dts/stm32f429.dtsi | 6 +- arch/arm/configs/stm32_defconfig | 9 + drivers/net/ethernet/stmicro/stmmac/Kconfig| 12 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 193 + .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 8 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -- 1.9.1
[RESEND PATCH v6 4/6] ARM: STM32: Enable Ethernet in stm32_defconfig
Enable basic Ethernet support (IPV4) for stm32 defconfig. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index 1e5ec2a..719218b 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -33,11 +33,20 @@ CONFIG_XIP_PHYS_ADDR=0x08008000 CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_SHARED_FLAT=y # CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set # CONFIG_BLK_DEV is not set CONFIG_EEPROM_93CX6=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -- 1.9.1
[RESEND PATCH v6 3/6] net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP
Adds support of Synopsys 3.50a MAC IP in stmmac driver. Acked-by: Giuseppe Cavallaro Tested-by: Maxime Coquelin Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 409db91..7718247 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -262,6 +262,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || + of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the -- 1.9.1
[RESEND PATCH v6 2/6] Documentation: Bindings: Add STM32 DWMAC glue
Acked-by: Rob Herring Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt new file mode 100644 index 000..c35afb7 --- /dev/null +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -0,0 +1,32 @@ +STMicroelectronics STM32 / MCU DWMAC glue layer controller + +This file documents platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +The device node has following properties. + +Required properties: +- compatible: Should be "st,stm32-dwmac" to select glue, and + "snps,dwmac-3.50a" to select IP version. +- clocks: Must contain a phandle for each entry in clock-names. +- clock-names: Should be "stmmaceth" for the host clock. + Should be "mac-clk-tx" for the MAC TX clock. + Should be "mac-clk-rx" for the MAC RX clock. +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which + encompases the glue register, and the offset of the control register. +Example: + + ethernet@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + snps,mixed-burst; + dma-ranges; + }; -- 1.9.1
[PATCH 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..a94dd15 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -114,6 +114,18 @@ config DWMAC_SUNXI This selects Allwinner SoC glue layer support for the stmmac device driver. This driver is used for A20/A31 GMAC ethernet controller. + +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. endif config STMMAC_PCI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..9fb2061 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o stmmac-platform-objs:= stmmac_platform.o obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 000..56ccc20 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,177 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + int interface; /* MII interface */ + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct device *dev; + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(struct platform_device *pdev, void *priv) +{ + struct stm32_dwmac *dwmac = priv; + struct regmap *regmap = dwmac->regmap; + int ret, iface = dwmac->interface; + u32 reg = dwmac->mode_reg; + u32 val; + + if (dwmac->clk_tx) + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + goto out; + + if (dwmac->clk_rx) + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + goto out_disable_clk_tx; + + val = (iface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + goto out_disable_clk_tx_rx; + + return 0; + +out_disable_clk_tx_rx: + clk_disable_unprepare(dwmac->clk_rx); +out_disable_clk_tx: + clk_disable_unprepare(dwmac->clk_tx); +out: + return ret; +} + +static void stm32_dwmac_exit(struct platform_device *pdev, void *priv) +{ + struct stm32_dwmac *dwmac = priv; + + if (dwmac->clk_tx) + clk_disable_unprepare(dwmac->clk_tx); + if (dwmac->clk_rx) + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct regmap *regmap; + int err; + + if (!np) + return -EINVAL; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "tx-clk"); + if (IS_ERR(dwmac->clk_tx)) { + dev_warn(dev, "No tx clock provided...\n"); + dwmac->clk_tx = NULL; + } + dwmac->clk_rx = devm_clk_get(dev, "rx-clk"); + if (IS_ERR(dwmac->clk_rx)) { + dev_warn(dev, "No rx clock provided...\n"); + dwmac->clk_rx = NULL; + } + + /* Get mode register */ + regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) { +
[PATCH 4/4] ARM: STM32: Enable Ethernet in stm32_defconfig
Enable basic Ethernet support (IPV4) for stm32 defconfig. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec52505..8b8abe0 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -33,11 +33,20 @@ CONFIG_XIP_PHYS_ADDR=0x08008000 CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_SHARED_FLAT=y # CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set # CONFIG_BLK_DEV is not set CONFIG_EEPROM_93CX6=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -- 1.9.1
[PATCH 3/4] net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP
Adds support of Synopsys 3.50a MAC IP in stmmac driver. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 6a52fa1..6cca626 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -178,6 +178,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || + of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the -- 1.9.1
[PATCH 0/4] Add Ethernet support on STM32F429
STM32F429 Chip embeds a Synopsys 3.50a MAC IP. This series: -enhance current stmmac driver to control it (code already available) and adds basic glue for STM32F429 chip. -Enable basic Net config in kernel. Note that DT patches are not present because STM32 pinctrl code is not yet avalaible. Regards Alexandre Alexandre TORGUE (4): net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Documentation: Bindings: Add STM32 DWMAC glue net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP ARM: STM32: Enable Ethernet in stm32_defconfig .../devicetree/bindings/net/stm32-dwmac.txt| 41 + arch/arm/configs/stm32_defconfig | 9 ++ drivers/net/ethernet/stmicro/stmmac/Kconfig| 12 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 177 + .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 6 files changed, 241 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -- 1.9.1
[PATCH 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt new file mode 100644 index 000..18734b3 --- /dev/null +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -0,0 +1,41 @@ +STMicroelectronics STM32 / MCU DWMAC glue layer controller + +This file documents platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +The device node has following properties. + +Required properties: +- compatible: Should be "st,stm32-dwmac" to select glue, and + "snps,dwmac-3.50a" to select IP vesrion. +- clocks: Should contain the GMAC main clock, and tx clock +- compatible: Should be "st,stm32-dwmac" to select glue and + "snps,dwmac-3.50a" to select IP version. +- clocks: Should contain the MAC main clock +- clock-names: Should contain the clock names "stmmaceth". +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which + encompases the glue register, and the offset of the control register. + +Optional properties: +- clocks: Could contain: + - the tx clock, + - the rx clock +- clock-names: Could contain the clock names "tx-clk", "rx-clk" + +Example: + + ethernet0: dwmac@40028000 { + device_type = "network"; + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <32>; + snps,mixed-burst; + dma-ranges; + }; -- 1.9.1
Re: [PATCH 0/4] Add Ethernet support on STM32F429
Hi David, I will fix it in next patch version. I just find a corruption issue in stmmac driver, I will also fix it in next version. Best regards Alex 2016-02-09 10:52 GMT+01:00 David Miller : > From: Alexandre TORGUE > Date: Wed, 3 Feb 2016 15:54:31 +0100 > >> STM32F429 Chip embeds a Synopsys 3.50a MAC IP. >> This series: >> -enhance current stmmac driver to control it (code already available) >> and >>adds basic glue for STM32F429 chip. >> -Enable basic Net config in kernel. >> >> Note that DT patches are not present because STM32 pinctrl code is not >> yet avalaible. > > Looks like this needs to be respun to deal with the warnings the kbuild > robot reported. > > Thanks.
Re: [PATCH 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
2016-02-13 14:48 GMT+01:00 Joachim Eastwood : > On 3 February 2016 at 15:54, Alexandre TORGUE > wrote: >> stm324xx family chips support Synopsys MAC 3.510 IP. >> This patch adds settings for logical glue logic: >> -clocks >> -mode selection MII or RMII. >> >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig >> b/drivers/net/ethernet/stmicro/stmmac/Kconfig >> index cec147d..a94dd15 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig >> +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig >> @@ -114,6 +114,18 @@ config DWMAC_SUNXI >> This selects Allwinner SoC glue layer support for the >> stmmac device driver. This driver is used for A20/A31 >> GMAC ethernet controller. >> + >> +config DWMAC_STM32 >> + tristate "STM32 DWMAC support" >> + default ARCH_STM32 >> + depends on OF >> + select MFD_SYSCON >> + ---help--- >> + Support for ethernet controller on STM32 SOCs. >> + >> + This selects STM32 SoC glue layer support for the stmmac >> + device driver. This driver is used on for the STM32 series >> + SOCs GMAC ethernet controller. >> endif >> >> config STMMAC_PCI >> diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile >> b/drivers/net/ethernet/stmicro/stmmac/Makefile >> index b390161..9fb2061 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/Makefile >> +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile >> @@ -14,6 +14,7 @@ obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o >> obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o >> obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o >> obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o >> +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o > > Keep these sorted. There also a comment in the Makefile that states > that the generic should always be last. ok > > >> stmmac-platform-objs:= stmmac_platform.o >> >> obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c >> b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c >> new file mode 100644 >> index 000..56ccc20 >> --- /dev/null >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c >> @@ -0,0 +1,177 @@ >> +/* >> + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU >> + * >> + * Copyright (C) Alexandre Torgue 2015 >> + * Author: Alexandre Torgue >> + * License terms: GNU General Public License (GPL), version 2 >> + * >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include > > Consider sorting the includes. ok > >> + >> +#include "stmmac_platform.h" >> + >> +#define MII_PHY_SEL_MASK BIT(23) >> + >> +struct stm32_dwmac { >> + int interface; /* MII interface */ >> + struct clk *clk_tx; >> + struct clk *clk_rx; >> + u32 mode_reg; /* MAC glue-logic mode register */ >> + struct device *dev; > > dev doesn't seem to be used anywhere. ok > >> + struct regmap *regmap; >> + u32 speed; >> +}; >> + >> +static int stm32_dwmac_init(struct platform_device *pdev, void *priv) >> +{ >> + struct stm32_dwmac *dwmac = priv; >> + struct regmap *regmap = dwmac->regmap; >> + int ret, iface = dwmac->interface; >> + u32 reg = dwmac->mode_reg; >> + u32 val; >> + >> + if (dwmac->clk_tx) >> + ret = clk_prepare_enable(dwmac->clk_tx); > > The clk API handles a NULL clk so you don't really need to check for it. I agree > > >> + if (ret) >> + goto out; >> + >> + if (dwmac->clk_rx) >> + ret = clk_prepare_enable(dwmac->clk_rx); > > Same here. I agree > > >> + if (ret) >> + goto out_disable_clk_tx; >> + >> + val = (iface == PHY_INTERFACE_MODE_MII) ? 0 : 1; >> + ret = regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, val); >> + if (ret) >> + goto out_disable_clk_tx_rx; >> + >> + return 0; >> + >> +out_disable_clk_tx_rx: >> + clk_disable_unprepare(dwmac->clk_rx); &g
Re: [PATCH 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
2016-02-22 22:52 GMT+01:00 Joachim Eastwood : > On 22 February 2016 at 15:50, Alexandre Torgue > wrote: >> 2016-02-13 14:48 GMT+01:00 Joachim Eastwood : >>> On 3 February 2016 at 15:54, Alexandre TORGUE >>> wrote: >>>> + plat_dat->bsp_priv = dwmac; >>>> + plat_dat->init = stm32_dwmac_init; >>>> + plat_dat->exit = stm32_dwmac_exit; >>> >>> Instead of using these callbacks could you rather implement the PM >>> callbacks directly in this driver? >>> I don't think it should add much code and it will make it look more >>> like standard driver. This will also give you some more control and >>> flexibility in your code. >> >> I prefer to keep the code as it is. Glue layer is directly linked to >> stmmac driver and I don't want to brake the link between the glue and >> the stmmac driver. > > What do you mean by break the link? > I thought that you wanted to split stmmac_pltfr_supend (glue part and stmamc part), but I well understood it is not the case (sorry for mistake). > There has been numerous of patch sets to make the stmmac "glue" > drivers into more standard platform drivers. > http://marc.info/?l=linux-netdev&m=143159850631093&w=2 > http://marc.info/?l=linux-netdev&m=143708560009851&w=2 > http://marc.info/?l=linux-netdev&m=143812136600541&w=2 > > Do you see any advantage by using the init and exit hooks in your > driver instead of using the standard driver PM callbacks and remove > function? > The only "cost" I see is slightly more boilerplate code. But since you > already have init/exit functions you could easily make them into PM > resume/suspend so I doubt there would be much increase in code size. > If I well understood you want to continue the stmmac glue driver rework by moving stmmac_pltfr_suspend/resume/remove in each glue driver (stm32, sun, sti ). Each glue driver will call directly stmmac_suspend/resume/remove and their own init/exit function. If it is what you meant, I can do it. > One other thing; > Do you need to have the PHY mode setup code in the init function which > is called each time on resume? I can't guarantee that after a suspend the sysconfig register will contain same data than before suspend. Best regards. Alex > If you could move it to probe you could drop the interface priv data > member and use plat_dat->interface as stmmac_probe_config_dt() has > already done of_get_phy_mode(). > > > regards, > Joachim Eastwood
Re: [PATCH 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
2016-02-23 12:21 GMT+01:00 Joachim Eastwood : > On 23 February 2016 at 10:59, Alexandre Torgue > wrote: >> 2016-02-22 22:52 GMT+01:00 Joachim Eastwood : >>> On 22 February 2016 at 15:50, Alexandre Torgue >>> wrote: >>>> 2016-02-13 14:48 GMT+01:00 Joachim Eastwood : >>>>> On 3 February 2016 at 15:54, Alexandre TORGUE >>>>> wrote: >>>>>> + plat_dat->bsp_priv = dwmac; >>>>>> + plat_dat->init = stm32_dwmac_init; >>>>>> + plat_dat->exit = stm32_dwmac_exit; >>>>> >>>>> Instead of using these callbacks could you rather implement the PM >>>>> callbacks directly in this driver? >>>>> I don't think it should add much code and it will make it look more >>>>> like standard driver. This will also give you some more control and >>>>> flexibility in your code. >>>> >>>> I prefer to keep the code as it is. Glue layer is directly linked to >>>> stmmac driver and I don't want to brake the link between the glue and >>>> the stmmac driver. >>> >>> What do you mean by break the link? >>> >> >> I thought that you wanted to split stmmac_pltfr_supend (glue part and >> stmamc part), but I well understood it is not the case (sorry for >> mistake). >> >>> There has been numerous of patch sets to make the stmmac "glue" >>> drivers into more standard platform drivers. >>> http://marc.info/?l=linux-netdev&m=143159850631093&w=2 >>> http://marc.info/?l=linux-netdev&m=143708560009851&w=2 >>> http://marc.info/?l=linux-netdev&m=143812136600541&w=2 >>> >>> Do you see any advantage by using the init and exit hooks in your >>> driver instead of using the standard driver PM callbacks and remove >>> function? >>> The only "cost" I see is slightly more boilerplate code. But since you >>> already have init/exit functions you could easily make them into PM >>> resume/suspend so I doubt there would be much increase in code size. >>> >> >> If I well understood you want to continue the stmmac glue driver >> rework by moving stmmac_pltfr_suspend/resume/remove in each glue >> driver (stm32, sun, sti ). > > At least I want to avoid the init/exit callbacks for new drivers like > stm32-dwmac. > > >> Each glue driver will call directly stmmac_suspend/resume/remove and >> their own init/exit function. >> If it is what you meant, I can do it. > > Yes, in your stm32 driver's suspend/resume/remove functions call > stmmac_suspend/stmmac_resume/stmmac_dvr_remove directly. Then you > shouldn't need to use the init/exit callbacks. Just put the need code > in the driver's suspend/resume/remove functions instead of init/exit > functions. > > For example: > static int stm32_dwmac_resume(struct device *dev) > { > struct net_device *ndev = dev_get_drvdata(dev); > struct plat_stmmacenet_data *plat_dat = get_stmmac_plat_data(ndev) > struct stm32_dwmac *dwmac =plat_dat->bsp_priv; > > /* enable clocks */ > /* set phy mode */ > > return stmmac_resume(ndev); > } > > If it makes sense to have the enable clk/phy mode stuff in it's own > function that is fine too. Ok. I will send v2 with this approach. After this series I could provide a new series to change all glues with this approach ? (but I will not able to test on each platform). Best regards Alexandre > > >>> One other thing; >>> Do you need to have the PHY mode setup code in the init function which >>> is called each time on resume? >> >> I can't guarantee that after a suspend the sysconfig register will >> contain same data than before suspend. > > I see. > > > regards, > Joachim Eastwood
[PATCH v2 4/4] ARM: STM32: Enable Ethernet in stm32_defconfig
Enable basic Ethernet support (IPV4) for stm32 defconfig. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec52505..8b8abe0 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -33,11 +33,20 @@ CONFIG_XIP_PHYS_ADDR=0x08008000 CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_SHARED_FLAT=y # CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set # CONFIG_BLK_DEV is not set CONFIG_EEPROM_93CX6=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -- 1.9.1
[PATCH v2 3/4] net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP
Adds support of Synopsys 3.50a MAC IP in stmmac driver. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 6a52fa1..6cca626 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -178,6 +178,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || + of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the -- 1.9.1
[PATCH v2 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt new file mode 100644 index 000..18734b3 --- /dev/null +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -0,0 +1,41 @@ +STMicroelectronics STM32 / MCU DWMAC glue layer controller + +This file documents platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +The device node has following properties. + +Required properties: +- compatible: Should be "st,stm32-dwmac" to select glue, and + "snps,dwmac-3.50a" to select IP vesrion. +- clocks: Should contain the GMAC main clock, and tx clock +- compatible: Should be "st,stm32-dwmac" to select glue and + "snps,dwmac-3.50a" to select IP version. +- clocks: Should contain the MAC main clock +- clock-names: Should contain the clock names "stmmaceth". +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which + encompases the glue register, and the offset of the control register. + +Optional properties: +- clocks: Could contain: + - the tx clock, + - the rx clock +- clock-names: Could contain the clock names "tx-clk", "rx-clk" + +Example: + + ethernet0: dwmac@40028000 { + device_type = "network"; + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <32>; + snps,mixed-burst; + dma-ranges; + }; -- 1.9.1
[PATCH v2 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..f63bdcf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -114,6 +114,18 @@ config DWMAC_SUNXI This selects Allwinner SoC glue layer support for the stmmac device driver. This driver is used for A20/A31 GMAC ethernet controller. + +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF && HAS_IOMEM + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. endif config STMMAC_PCI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..559086d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA)+= dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o stmmac-platform-objs:= stmmac_platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 000..0b48ee7 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,208 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + int interface; /* MII interface */ + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(void *priv) +{ + struct stm32_dwmac *dwmac = priv; + struct regmap *regmap = dwmac->regmap; + int ret, iface = dwmac->interface; + u32 reg = dwmac->mode_reg; + u32 val; + + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + goto out; + + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + goto out_disable_clk_tx; + + val = (iface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + goto out_disable_clk_tx_rx; + + return 0; + +out_disable_clk_tx_rx: + clk_disable_unprepare(dwmac->clk_rx); +out_disable_clk_tx: + clk_disable_unprepare(dwmac->clk_tx); +out: + return ret; +} + +static void stm32_dwmac_exit(void *priv) +{ + struct stm32_dwmac *dwmac = priv; + + clk_disable_unprepare(dwmac->clk_tx); + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct regmap *regmap; + int err; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "tx-clk"); + if (IS_ERR(dwmac->clk_tx)) { + dev_warn(dev, "No tx clock provided...\n"); + dwmac->clk_tx = NULL; + } + dwmac->clk_rx = devm_clk_get(dev, "rx-clk"); + if (IS_ERR(dwmac->clk_rx)) { + dev_warn(dev, "No rx clock provided...\n"); + dwmac->clk_rx = NULL; + } + + /* Get mode register */ + regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) { + dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); + return err; + } + + dwmac->interface = of_get_phy_mode(np); + dwmac->regmap = regmap; + + return 0; +} + +static int stm32_dwmac_probe(struct platform_de
[PATCH v2 0/4] Add Ethernet support on STM32F429
STM32F429 Chip embeds a Synopsys 3.50a MAC IP. This series: -enhance current stmmac driver to control it (code already available) and adds basic glue for STM32F429 chip. -Enable basic Net config in kernel. Note that DT patches are not present because STM32 pinctrl code is not yet avalaible. Changes since v1: -Fix Kbuild issue in Kconfig. -Remove init/exit callbacks. Suspend/Resume and remove driver is no more driven in stmmac_pltfr but directly in dwmac-stm32 glue driver. -Take into account Joachim review. Regards. Alexandre. Alexandre TORGUE (4): net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Documentation: Bindings: Add STM32 DWMAC glue net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP ARM: STM32: Enable Ethernet in stm32_defconfig .../devicetree/bindings/net/stm32-dwmac.txt| 41 arch/arm/configs/stm32_defconfig | 9 + drivers/net/ethernet/stmicro/stmmac/Kconfig| 12 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 208 + .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 6 files changed, 272 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -- 1.9.1
Re: [PATCH v2 2/4] Documentation: Bindings: Add STM32 DWMAC glue
2016-02-23 23:37 GMT+01:00 Joachim Eastwood : > Hi Alexandre, > > You should copy 'devicet...@vger.kernel.org' on bindings doc. Adding cc here. > > On 23 February 2016 at 16:10, Alexandre TORGUE > wrote: >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> new file mode 100644 >> index 000..18734b3 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> @@ -0,0 +1,41 @@ >> +STMicroelectronics STM32 / MCU DWMAC glue layer controller >> + >> +This file documents platform glue layer for stmmac. >> +Please see stmmac.txt for the other unchanged properties. >> + >> +The device node has following properties. >> + >> +Required properties: >> +- compatible: Should be "st,stm32-dwmac" to select glue, and >> + "snps,dwmac-3.50a" to select IP vesrion. >> +- clocks: Should contain the GMAC main clock, and tx clock >> +- compatible: Should be "st,stm32-dwmac" to select glue and >> + "snps,dwmac-3.50a" to select IP version. >> +- clocks: Should contain the MAC main clock >> +- clock-names: Should contain the clock names "stmmaceth". >> +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node >> which >> + encompases the glue register, and the offset of the control >> register. >> + >> +Optional properties: >> +- clocks: Could contain: >> + - the tx clock, >> + - the rx clock >> +- clock-names: Could contain the clock names "tx-clk", "rx-clk" >> + >> +Example: >> + >> + ethernet0: dwmac@40028000 { >> + device_type = "network"; > > What is this 'device_type = "network"' for? > It seems to used in a lot of powerpc DTs, but only a couple of arm DTs. > > Maybe Rob could enlighten us? > >> + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; >> + status = "disabled"; >> + reg = <0x40028000 0x8000>; >> + reg-names = "stmmaceth"; >> + interrupts = <0 61 0>, <0 62 0>; >> + interrupt-names = "macirq", "eth_wake_irq"; >> + clock-names = "stmmaceth", "tx-clk", "rx-clk"; >> + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; >> + st,syscon = <&syscfg 0x4>; >> + snps,pbl = <32>; > > Regarding snps,pbl; using 32 here might not give you what you would except. > See comment in dwmac1000_dma_init(). > > The driver is hard coded to use PBL4X/PBL8X mode. Just a heads up. > Hi Joachim, My fault, It is not working with 32. I will modify it (should be 8 for example) Regards Alexandre > > regards, > Joachim Eastwood
Re: [PATCH v2 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
2016-02-23 23:16 GMT+01:00 Joachim Eastwood : > Hi Alexandre, > > On 23 February 2016 at 16:10, Alexandre TORGUE > wrote: >> stm324xx family chips support Synopsys MAC 3.510 IP. >> This patch adds settings for logical glue logic: >> -clocks >> -mode selection MII or RMII. >> >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig >> b/drivers/net/ethernet/stmicro/stmmac/Kconfig >> index cec147d..f63bdcf 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig >> +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig >> @@ -114,6 +114,18 @@ config DWMAC_SUNXI >> This selects Allwinner SoC glue layer support for the >> stmmac device driver. This driver is used for A20/A31 >> GMAC ethernet controller. >> + >> +config DWMAC_STM32 >> + tristate "STM32 DWMAC support" >> + default ARCH_STM32 >> + depends on OF && HAS_IOMEM >> + select MFD_SYSCON >> + ---help--- >> + Support for ethernet controller on STM32 SOCs. >> + >> + This selects STM32 SoC glue layer support for the stmmac >> + device driver. This driver is used on for the STM32 series >> + SOCs GMAC ethernet controller. >> endif >> >> config STMMAC_PCI >> diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile >> b/drivers/net/ethernet/stmicro/stmmac/Makefile >> index b390161..559086d 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/Makefile >> +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile >> @@ -13,6 +13,7 @@ obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o >> obj-$(CONFIG_DWMAC_SOCFPGA)+= dwmac-socfpga.o >> obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o >> obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o >> +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o > Hi Joachim, > Put them in alphabetic order. Same goes for the KConfig entry. Ok > > >> obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o >> stmmac-platform-objs:= stmmac_platform.o > ... >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c >> b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c >> +struct stm32_dwmac { >> + int interface; /* MII interface */ >> + struct clk *clk_tx; >> + struct clk *clk_rx; >> + u32 mode_reg; /* MAC glue-logic mode register */ >> + struct regmap *regmap; >> + u32 speed; >> +}; >> + >> +static int stm32_dwmac_init(void *priv) > > If you used 'struct stm32_dwmac *' instead of 'void *' you could skip > the local variable assignment. > > Even better; you could pass 'struct plat_stmmacenet_data *' and use > it's 'interface' member to set the phy mode. Then you could drop the > interface member in your priv data struct and remove of_get_phy_mode() > in stm32_dwmac_parse_data(). Yes, interesting. > > >> +{ >> + struct stm32_dwmac *dwmac = priv; >> + struct regmap *regmap = dwmac->regmap; >> + int ret, iface = dwmac->interface; >> + u32 reg = dwmac->mode_reg; >> + u32 val; >> + >> + ret = clk_prepare_enable(dwmac->clk_tx); >> + if (ret) >> + goto out; >> + >> + ret = clk_prepare_enable(dwmac->clk_rx); >> + if (ret) >> + goto out_disable_clk_tx; >> + >> + val = (iface == PHY_INTERFACE_MODE_MII) ? 0 : 1; >> + ret = regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, val); >> + if (ret) >> + goto out_disable_clk_tx_rx; >> + >> + return 0; >> + >> +out_disable_clk_tx_rx: >> + clk_disable_unprepare(dwmac->clk_rx); >> +out_disable_clk_tx: >> + clk_disable_unprepare(dwmac->clk_tx); >> +out: >> + return ret; >> +} >> + >> +static void stm32_dwmac_exit(void *priv) >> +{ >> + struct stm32_dwmac *dwmac = priv; > > Again; instead of 'void *' use 'struct stm32_dwmac *' to avoid the > local assignment. > > >> + >> + clk_disable_unprepare(dwmac->clk_tx); >> + clk_disable_unprepare(dwmac->clk_rx); >> +} > > To be honest I really don't see the point in having a function with > just two other function calls in it. Consider dropping the function > altogether and place the clk_disable_unprepare() calls where it's > called from. If you still want to keep it, plea
[PATCH v5 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Reviewed-by: Joachim Eastwood Acked-by: Giuseppe Cavallaro Tested-by: Maxime Coquelin Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..235d679 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -104,6 +104,18 @@ config DWMAC_STI device driver. This driver is used on for the STi series SOCs GMAC ethernet controller. +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF && HAS_IOMEM + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. + config DWMAC_SUNXI tristate "Allwinner GMAC support" default ARCH_SUNXI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..5f7ff0a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA)+= dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o stmmac-platform-objs:= stmmac_platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 000..88c8573 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,193 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) +{ + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; + u32 reg = dwmac->mode_reg; + u32 val; + int ret; + + val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + clk_disable_unprepare(dwmac->clk_tx); + + return ret; +} + +static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) +{ + clk_disable_unprepare(dwmac->clk_tx); + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) +{ + struct device_node *np = dev->of_node; + int err; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "tx-clk"); + if (IS_ERR(dwmac->clk_tx)) { + dev_err(dev, "No tx clock provided...\n"); + return PTR_ERR(dwmac->clk_tx); + } + dwmac->clk_rx = devm_clk_get(dev, "rx-clk"); + if (IS_ERR(dwmac->clk_rx)) { + dev_err(dev, "No rx clock provided...\n"); + return PTR_ERR(dwmac->clk_rx); + } + + /* Get mode register */ + dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(dwmac->regmap)) + return PTR_ERR(dwmac->regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) + dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); + + return err; +} + +static int stm32_dwmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct stm32_dwmac *dwmac; + int ret; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return ret; + + plat_
[PATCH v5 0/4] Add Ethernet support on STM32F429
STM32F429 Chip embeds a Synopsys 3.50a MAC IP. This series: -enhance current stmmac driver to control it (code already available) and adds basic glue for STM32F429 chip. -Enable basic Net config in kernel. Note that DT patches are not present because STM32 pinctrl code is not yet avalaible. Changes since v4: -Fix dirty copy/past in bindings documentation patch. Changes since v3: -Fix "tx-clk" and "rx-clk" as required clocks. Driver and bindings are modified. Changes since v2: -Fix alphabetic order in Kconfig and Makefile. -Improve code according to Joachim review. -Binding: remove useless entry. Changes since v1: -Fix Kbuild issue in Kconfig. -Remove init/exit callbacks. Suspend/Resume and remove driver is no more driven in stmmac_pltfr but directly in dwmac-stm32 glue driver. -Take into account Joachim review. Regards. Alexandre. Alexandre TORGUE (4): net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Documentation: Bindings: Add STM32 DWMAC glue net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP ARM: STM32: Enable Ethernet in stm32_defconfig .../devicetree/bindings/net/stm32-dwmac.txt| 32 arch/arm/configs/stm32_defconfig | 9 + drivers/net/ethernet/stmicro/stmmac/Kconfig| 12 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 193 + .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 6 files changed, 248 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -- 1.9.1
[PATCH v5 4/4] ARM: STM32: Enable Ethernet in stm32_defconfig
Enable basic Ethernet support (IPV4) for stm32 defconfig. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec52505..8b8abe0 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -33,11 +33,20 @@ CONFIG_XIP_PHYS_ADDR=0x08008000 CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_SHARED_FLAT=y # CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set # CONFIG_BLK_DEV is not set CONFIG_EEPROM_93CX6=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -- 1.9.1
[PATCH v5 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt new file mode 100644 index 000..ada2aa4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -0,0 +1,32 @@ +STMicroelectronics STM32 / MCU DWMAC glue layer controller + +This file documents platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +The device node has following properties. + +Required properties: +- compatible: Should be "st,stm32-dwmac" to select glue, and + "snps,dwmac-3.50a" to select IP vesrion. +- clocks: Must contain a phandle for each entry in clock-names. +- clock-names: Should be "stmmaceth" for the host clock. + Should be "tx-clk" for the MAC TX clock. + Should be "rx-clk" for the MAC RX clock. +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which + encompases the glue register, and the offset of the control register. +Example: + + ethernet0: dwmac@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + snps,mixed-burst; + dma-ranges; + }; -- 1.9.1
[PATCH v5 3/4] net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP
Adds support of Synopsys 3.50a MAC IP in stmmac driver. Acked-by: Giuseppe Cavallaro Tested-by: Maxime Coquelin Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 6a52fa1..6cca626 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -178,6 +178,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || + of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the -- 1.9.1
Re: [PATCH v5 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Hi, 2016-03-18 17:00 GMT+01:00 Chen-Yu Tsai : > Hi, > > On Fri, Mar 18, 2016 at 11:37 PM, Alexandre TORGUE > wrote: >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> new file mode 100644 >> index 000..ada2aa4 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> @@ -0,0 +1,32 @@ >> +STMicroelectronics STM32 / MCU DWMAC glue layer controller >> + >> +This file documents platform glue layer for stmmac. >> +Please see stmmac.txt for the other unchanged properties. >> + >> +The device node has following properties. >> + >> +Required properties: >> +- compatible: Should be "st,stm32-dwmac" to select glue, and >> + "snps,dwmac-3.50a" to select IP vesrion. > > If you need have sort of hardware glue, then it is not compatible. > We could have the case where the glue is set by a bootloader. In this case, we will select IP version in compatible and we will use generic dwmac glue to probe stmmac driver. Regards Alex. > ChenYu > >> +- clocks: Must contain a phandle for each entry in clock-names. >> +- clock-names: Should be "stmmaceth" for the host clock. >> + Should be "tx-clk" for the MAC TX clock. >> + Should be "rx-clk" for the MAC RX clock. >> +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node >> which >> + encompases the glue register, and the offset of the control >> register. >> +Example: >> + >> + ethernet0: dwmac@40028000 { >> + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; >> + status = "disabled"; >> + reg = <0x40028000 0x8000>; >> + reg-names = "stmmaceth"; >> + interrupts = <0 61 0>, <0 62 0>; >> + interrupt-names = "macirq", "eth_wake_irq"; >> + clock-names = "stmmaceth", "tx-clk", "rx-clk"; >> + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; >> + st,syscon = <&syscfg 0x4>; >> + snps,pbl = <8>; >> + snps,mixed-burst; >> + dma-ranges; >> + }; >> -- >> 1.9.1 >> >> >> ___ >> linux-arm-kernel mailing list >> linux-arm-ker...@lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v5 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Hi guys, I will fix typo issues (s/vesrion/version and ethernet @). Concerning compatible string. For sure "snps,dwmac-3.50a" string is not used inside glue driver. I perfere to keep it for information but if you really want that I remove it I will not block ;) 2016-03-21 16:36 GMT+01:00 Joachim Eastwood : > On 21 March 2016 at 13:40, Rob Herring wrote: >> On Sat, Mar 19, 2016 at 12:00:22AM +0800, Chen-Yu Tsai wrote: >>> Hi, >>> >>> On Fri, Mar 18, 2016 at 11:37 PM, Alexandre TORGUE >>> wrote: >>> > +- clocks: Must contain a phandle for each entry in clock-names. >>> > +- clock-names: Should be "stmmaceth" for the host clock. >> We can remove host clock (stmmac eth) entry here and refer to stmmac.txt binding for common entry >> This doesn't sound like the clock input signal name... >> >>> > + Should be "tx-clk" for the MAC TX clock. >>> > + Should be "rx-clk" for the MAC RX clock. >> >> How can other DWMAC blocks not have these clocks? The glue can't really >> add these clocks. It could combine them into one or a new version of >> DWMAC could have a different number of clock inputs. So if there is >> variation here, then some of the bindings are probably wrong. I guess >> the only change I'm suggesting is possibly moving these into common >> binding doc. > > The LPC18xx implementation probably have these clocks as well but the > LPC1850 user manual only documents the main clock. Someone with access > to the IP block doc from Synopsys should be able to check which clocks > the MAC really needs. > > Rockchip bindings have two clocks named "mac_clk_rx" and "mac_clk_tx". > These are probably the same as stm32 needs so maybe use these names > and move them into the main doc and update the rockchip binding. > I think we can use same name. But I have a doubt on moving it in a common bindings (maybe I don't well understood). When you say "common binding file" is it "stmmac.txt" binding ? If yes does it mean that we have to control it inside stmmac driver (no more in glue) ? In this case those clocks will become "required" for stm32 and rockship but not for others chip. It could create confusion? Best regards Alex > > regards, > Joachim Eastwood
[PATCH 00/13] Enhance stmmac driver to support GMAC4.x IP
This is a subset of patch to enhance current stmmac driver to support new GMAC4.x chips. New set of callbacks is defined to support this new family: descriptors, dma, core. One of main changes of GMAC 4.xx IP is descriptors management. -descriptors are only used in ring mode. -A descriptor is composed of 4 32bits registers (no more extended descriptors) -descriptor mechanism (Tx for example, but it is exactly the same for RX): -useful registers: -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring -DMA_CH#_TxDesc_List_Address: start address of the ring -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1. -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor -The descriptor Tail Pointer register contains the pointer to the descriptor address (N). The base address and the current descriptor decide the address of the current descriptor that the DMA can process. The descriptors up to one location less than the one indicated by the descriptor tail pointer (N-1) are owned by the DMA. The DMA continues to process the descriptors until the following condition occurs: "current descriptor pointer == Descriptor Tail pointer" Then the DMA goes into suspend mode. The application must perform a write to descriptor tail pointer register and update the tail pointer to have the following condition and to start a new transfer: "current descriptor pointer < Descriptor tail pointer" The DMA automatically wraps around the base address when the end of ring is reached. New features are available on IP: -TSO (TCP Segmentation Offload) for TX only -Split header: to have header and payload in 2 different buffers (not yet implemented) Below some throughput figures obtained on some boxes: iperf (mbps) -- tcp udp tx rx tx rx - GMAC4.x 935 930 750 800 Note: There is a change in 4.10a databook on bitfield mapping of DMA_CHANx_INTR_ENA register. This requires to have � diffrent set of callbacks between IP 4.00a and 4.10a. Best regards Alex Alexandre TORGUE (13): stmmac: rework get_hw_feature function stmmac: rework the routines to show the ring status stmmac: rework synopsys id read, moved to dwmac setup stmmac: add descriptors function for GMAC 4.xx stmmac: add GMAC4 DMA/CORE Header File stmmac: add DMA support for GMAC 4.xx stmmac: add GMAC4 core support stmmac: enhance mmc counter management stmmac: add new DT platform entries for GMAC4 stmmac: support new GMAC4 Documentation: networking: update stmmac stmmac: update version to Jan_2016 stmmac: update MAINTAINERS Documentation/devicetree/bindings/net/stmmac.txt | 2 + Documentation/networking/stmmac.txt| 44 +- MAINTAINERS| 1 + drivers/net/ethernet/stmicro/stmmac/Makefile | 3 +- drivers/net/ethernet/stmicro/stmmac/common.h | 64 +- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 7 +- .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c| 35 +- .../net/ethernet/stmicro/stmmac/dwmac100_core.c| 5 +- drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 255 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 407 + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 396 + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h | 129 + drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 354 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h | 202 +++ drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 225 +++ drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 21 + drivers/net/ethernet/stmicro/stmmac/mmc.h | 4 + drivers/net/ethernet/stmicro/stmmac/mmc_core.c | 349 +-- drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 21 + drivers/net/ethernet/stmicro/stmmac/stmmac.h | 7 +- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 643 +++-- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 7 + include/linux/stmmac.h | 2 + 24 files changed, 2821 insertions(+), 369 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -- 1.9.1
[PATCH 01/13] stmmac: rework get_hw_feature function
On next GMAC IP generation (4.xx), the way to get hw feature is not the same than on previous 3.xx. As it is hardware dependent, the way to get hw capabilities should be defined in dma ops of each MAC IP. It will avoid also a huge computation of hw capabilities in stmmac_main. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index f96d257..797a913 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -412,7 +412,8 @@ struct stmmac_dma_ops { int (*dma_interrupt) (void __iomem *ioaddr, struct stmmac_extra_stats *x); /* If supported then get the optional core features */ - unsigned int (*get_hw_feature) (void __iomem *ioaddr); + void (*get_hw_feature)(void __iomem *ioaddr, + struct dma_features *dma_cap); /* Program the HW RX Watchdog */ void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt); }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index da32d60..99074695 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -215,9 +215,40 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) } } -static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr) +static void dwmac1000_get_hw_feature(void __iomem *ioaddr, +struct dma_features *dma_cap) { - return readl(ioaddr + DMA_HW_FEATURE); + u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE); + + dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); + dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; + dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; + dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; + dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; + dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; + dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; + dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; + dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; + /* MMC */ + dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; + /* IEEE 1588-2002 */ + dma_cap->time_stamp = + (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; + /* IEEE 1588-2008 */ + dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; + /* 802.3az - Energy-Efficient Ethernet (EEE) */ + dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; + dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; + /* TX and RX csum */ + dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; + dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; + dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; + dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; + /* TX and RX number of channels */ + dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; + dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; + /* Alternate (enhanced) DESC mode */ + dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; } static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4c5ce98..d3ebfea 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1558,51 +1558,15 @@ static void stmmac_selec_desc_mode(struct stmmac_priv *priv) */ static int stmmac_get_hw_features(struct stmmac_priv *priv) { - u32 hw_cap = 0; + u32 ret = 0; if (priv->hw->dma->get_hw_feature) { - hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); - - priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); - priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; - priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; - priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; - priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; - priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; - priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >>
[PATCH 12/13] stmmac: update version to Jan_2016
This patch just updates the driver to the version fully tested on STi platforms. This version is Jan_2016. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 317ce35..ff67506 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -24,7 +24,7 @@ #define __STMMAC_H__ #define STMMAC_RESOURCE_NAME "stmmaceth" -#define DRV_MODULE_VERSION "Dec_2015" +#define DRV_MODULE_VERSION "Jan_2016" #include #include -- 1.9.1
[PATCH 05/13] stmmac: add GMAC4 DMA/CORE Header File
This is the main header file to define all the macro used for GMAC4 DMA and CORE parts. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h new file mode 100644 index 000..c12f15c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -0,0 +1,224 @@ +/* + * DWMAC4 Header file. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Author: Alexandre Torgue + */ + +#ifndef __DWMAC4_H__ +#define __DWMAC4_H__ + +#include "common.h" + +/* MAC registers */ +#define GMAC_CONFIG0x +#define GMAC_PACKET_FILTER 0x0008 +#define GMAC_HASH_TAB_0_31 0x0010 +#define GMAC_HASH_TAB_32_630x0014 +#define GMAC_RX_FLOW_CTRL 0x0090 +#define GMAC_QX_TX_FLOW_CTRL(x)(0x70 + x * 4) +#define GMAC_INT_STATUS0x00b0 +#define GMAC_INT_EN0x00b4 +#define GMAC_AN_CTRL 0x00e0 +#define GMAC_AN_STATUS 0x00e4 +#define GMAC_AN_ADV0x00e8 +#define GMAC_AN_LPA0x00ec +#define GMAC_PMT 0x00c0 +#define GMAC_VERSION 0x0110 +#define GMAC_DEBUG 0x0114 +#define GMAC_HW_FEATURE0 0x011c +#define GMAC_HW_FEATURE1 0x0120 +#define GMAC_HW_FEATURE2 0x0124 +#define GMAC_MDIO_ADDR 0x0200 +#define GMAC_MDIO_DATA 0x0204 +#define GMAC_ADDR_HIGH(reg)(0x300 + reg * 8) +#define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) + +/* MAC Packet Filtering */ +#define GMAC_PACKET_FILTER_PR BIT(0) +#define GMAC_PACKET_FILTER_HMC BIT(2) +#define GMAC_PACKET_FILTER_PM BIT(4) + +#define GMAC_MAX_PERFECT_ADDRESSES 128 + +/* MAC Flow Control RX */ +#define GMAC_RX_FLOW_CTRL_RFE BIT(0) + +/* MAC Flow Control TX */ +#define GMAC_TX_FLOW_CTRL_TFE BIT(1) +#define GMAC_TX_FLOW_CTRL_PT_SHIFT 16 + +/* MAC Interrupt bitmap*/ +#define GMAC_INT_PMT_ENBIT(4) +#define GMAC_INT_LPI_ENBIT(5) + +enum dwmac4_irq_status { + time_stamp_irq = 0x1000, + mmc_rx_csum_offload_irq = 0x0800, + mmc_tx_irq = 0x0400, + mmc_rx_irq = 0x0200, + mmc_irq = 0x0100, + pmt_irq = 0x0010, + pcs_ane_irq = 0x0004, + pcs_link_irq = 0x0002, +}; + +/* MAC Auto-Neg bitmap*/ +#defineGMAC_AN_CTRL_RANBIT(9) +#defineGMAC_AN_CTRL_ANEBIT(12) +#define GMAC_AN_CTRL_ELE BIT(14) +#define GMAC_AN_FD BIT(5) +#define GMAC_AN_HD BIT(6) +#define GMAC_AN_PSE_MASK GENMASK(8, 7) +#define GMAC_AN_PSE_SHIFT 7 + +/* MAC PMT bitmap */ +enum power_event { + pointer_reset = 0x8000, + global_unicast = 0x0200, + wake_up_rx_frame = 0x0040, + magic_frame = 0x0020, + wake_up_frame_en = 0x0004, + magic_pkt_en = 0x0002, + power_down = 0x0001, +}; + +/* MAC Debug bitmap */ +#define GMAC_DEBUG_TFCSTS_MASK GENMASK(18, 17) +#define GMAC_DEBUG_TFCSTS_SHIFT17 +#define GMAC_DEBUG_TFCSTS_IDLE 0 +#define GMAC_DEBUG_TFCSTS_WAIT 1 +#define GMAC_DEBUG_TFCSTS_GEN_PAUSE2 +#define GMAC_DEBUG_TFCSTS_XFER 3 +#define GMAC_DEBUG_TPESTS BIT(16) +#define GMAC_DEBUG_RFCFCSTS_MASK GENMASK(2, 1) +#define GMAC_DEBUG_RFCFCSTS_SHIFT 1 +#define GMAC_DEBUG_RPESTS BIT(0) + +/* MAC config */ +#define GMAC_CONFIG_IPCBIT(27) +#define GMAC_CONFIG_2K BIT(22) +#define GMAC_CONFIG_ACSBIT(20) +#define GMAC_CONFIG_BE BIT(18) +#define GMAC_CONFIG_JD BIT(17) +#define GMAC_CONFIG_JE BIT(16) +#define GMAC_CONFIG_PS BIT(15) +#define GMAC_CONFIG_FESBIT(14) +#define GMAC_CONFIG_DM BIT(13) +#define GMAC_CONFIG_DCRS BIT(9) +#define GMAC_CONFIG_TE BIT(1) +#define GMAC_CONFIG_RE BIT(0) + +/* MAC HW features0 bitmap */ +#define GMAC_HW_FEAT_ADDMACBIT(18) +#define GMAC_HW_FEAT_RXCOESEL BIT(16) +#define GMAC_HW_FEAT_TXCOSEL BIT(14) +#define GMAC_HW_FEAT_EEESELBIT(13) +#define GMAC_HW_FEAT_TSSEL BIT(12) +#define GMAC_HW_FEAT_MMCSELBIT(8) +#define GMAC_HW_FEAT_MGKSELBIT(7
[PATCH 07/13] stmmac: add GMAC4 core support
This is the initial support for GMAC4 that includes the main callbacks to setup the core module: including Csum, basic filtering, mac address and interrupt (MMC, MTL, PMT) No LPI added. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 9398ace..0fb362d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -3,7 +3,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ - dwmac4_dma.o dwmac4_lib.o $(stmmac-y) + dwmac4_dma.o dwmac4_lib.o dwmac4_core.o $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 2a5126e..eabe86b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -527,15 +527,21 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, int perfect_uc_entries, int *synopsys_id); struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id); - +struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins, +int perfect_uc_entries, int *synopsys_id); void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low); void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int high, unsigned int low); - void stmmac_set_mac(void __iomem *ioaddr, bool enable); +void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, u8 addr[6], + unsigned int high, unsigned int low); +void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, + unsigned int high, unsigned int low); +void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable); + void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index c12f15c..bc50952 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -221,4 +221,35 @@ enum power_event { /* To dump the core regs excluding the Address Registers */ #defineGMAC_REG_NUM132 +/* MTL debug */ +#define MTL_DEBUG_TXSTSFSTSBIT(5) +#define MTL_DEBUG_TXFSTS BIT(4) +#define MTL_DEBUG_TWCSTS BIT(3) + +/* MTL debug: Tx FIFO Read Controller Status */ +#define MTL_DEBUG_TRCSTS_MASK GENMASK(2, 1) +#define MTL_DEBUG_TRCSTS_SHIFT 1 +#define MTL_DEBUG_TRCSTS_IDLE 0 +#define MTL_DEBUG_TRCSTS_READ 1 +#define MTL_DEBUG_TRCSTS_TXW 2 +#define MTL_DEBUG_TRCSTS_WRITE 3 +#define MTL_DEBUG_TXPAUSED BIT(0) + +/* MAC debug: GMII or MII Transmit Protocol Engine Status */ +#define MTL_DEBUG_RXFSTS_MASK GENMASK(5, 4) +#define MTL_DEBUG_RXFSTS_SHIFT 4 +#define MTL_DEBUG_RXFSTS_EMPTY 0 +#define MTL_DEBUG_RXFSTS_BT1 +#define MTL_DEBUG_RXFSTS_AT2 +#define MTL_DEBUG_RXFSTS_FULL 3 +#define MTL_DEBUG_RRCSTS_MASK GENMASK(2, 1) +#define MTL_DEBUG_RRCSTS_SHIFT 1 +#define MTL_DEBUG_RRCSTS_IDLE 0 +#define MTL_DEBUG_RRCSTS_RDATA 1 +#define MTL_DEBUG_RRCSTS_RSTAT 2 +#define MTL_DEBUG_RRCSTS_FLUSH 3 +#define MTL_DEBUG_RWCSTS BIT(0) + +extern const struct stmmac_dma_ops dwmac4_dma_ops; +extern const struct stmmac_dma_ops dwmac410_dma_ops; #endif /* __DWMAC4_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c new file mode 100644 index 000..4f7283d --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -0,0 +1,407 @@ +/* + * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs. + * DWC Ether MAC version 4.00 has been used for developing this code. + * + * This only implements the mac core functions for this chip. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Author: Alexandre Torgue
[PATCH 03/13] stmmac: rework synopsys id read, moved to dwmac setup
synopsys_uid is only used once after setup, to get synopsys_id by using shitf/mask operation. It's no longer used then. So, remove this temporary variable and directly compute synopsys_id from setup routine. Acked-by: Giuseppe Cavallaro Signed-off-by: Fabrice Gasnier Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 6cea61b..66e132f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -498,7 +498,6 @@ struct mac_device_info { const struct stmmac_hwtimestamp *ptp; struct mii_regs mii;/* MII register Addresses */ struct mac_link link; - unsigned int synopsys_uid; void __iomem *pcsr; /* vpointer to device CSRs */ int multicast_filter_bins; int unicast_filter_entries; @@ -507,8 +506,10 @@ struct mac_device_info { }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, - int perfect_uc_entries); -struct mac_device_info *dwmac100_setup(void __iomem *ioaddr); + int perfect_uc_entries, + int *synopsys_id); +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id); + void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low); @@ -521,4 +522,24 @@ void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; +/** + * stmmac_get_synopsys_id - return the SYINID. + * @priv: driver private structure + * Description: this simple function is to decode and return the SYINID + * starting from the HW core register. + */ +static inline u32 stmmac_get_synopsys_id(u32 hwid) +{ + /* Check Synopsys Id (not available on old chips) */ + if (likely(hwid)) { + u32 uid = ((hwid & 0xff00) >> 8); + u32 synid = (hwid & 0x00ff); + + pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", + uid, synid); + + return synid; + } + return 0; +} #endif /* __COMMON_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index c294117..fb1eb57 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -491,7 +491,8 @@ static const struct stmmac_ops dwmac1000_ops = { }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, - int perfect_uc_entries) + int perfect_uc_entries, + int *synopsys_id) { struct mac_device_info *mac; u32 hwid = readl(ioaddr + GMAC_VERSION); @@ -516,7 +517,9 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, mac->link.speed = GMAC_CONTROL_FES; mac->mii.addr = GMAC_MII_ADDR; mac->mii.data = GMAC_MII_DATA; - mac->synopsys_uid = hwid; + + /* Get and dump the chip ID */ + *synopsys_id = stmmac_get_synopsys_id(hwid); return mac; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index f8dd773..6418b2e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -173,7 +173,7 @@ static const struct stmmac_ops dwmac100_ops = { .get_umac_addr = dwmac100_get_umac_addr, }; -struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id) { struct mac_device_info *mac; @@ -192,7 +192,8 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) mac->link.speed = 0; mac->mii.addr = MAC_MII_ADDR; mac->mii.data = MAC_MII_DATA; - mac->synopsys_uid = 0; + /* Synopsys Id is not available on old chips */ + *synopsys_id = 0; return mac; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8103527..2ebee81 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1468,29 +1468,6 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) } /** - * stmmac_get_synopsys_id - return the SYINID. - * @priv: driver private structure - * Description: this simple function is to decode and return the SYINID - * starting from the HW core register. - */ -static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) -{ - u32 hwid = priv->hw->synopsys_uid;
[PATCH 13/13] stmmac: update MAINTAINERS
Signed-off-by: Alexandre TORGUE diff --git a/MAINTAINERS b/MAINTAINERS index b70294e..394e233 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3293,6 +3293,7 @@ F:Documentation/powerpc/cxlflash.txt STMMAC ETHERNET DRIVER M: Giuseppe Cavallaro +M: Alexandre Torgue L: netdev@vger.kernel.org W: http://www.stlinux.com S: Supported -- 1.9.1
[PATCH 02/13] stmmac: rework the routines to show the ring status
To avoid lot of check in stmmac_main for display ring management and support the GMAC4 chip, the display_ring function is moved into dedicated descriptor file. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 797a913..6cea61b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -380,6 +380,8 @@ struct stmmac_desc_ops { u64(*get_timestamp) (void *desc, u32 ats); /* get rx timestamp status */ int (*get_rx_timestamp_status) (void *desc, u32 ats); + /* Display ring */ + void (*display_ring)(void *head, unsigned int size, bool rx); }; extern const struct stmmac_desc_ops enh_desc_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index cfb018c..3e1b249 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -411,6 +411,26 @@ static int enh_desc_get_rx_timestamp_status(void *desc, u32 ats) } } +static void enh_desc_display_ring(void *head, unsigned size, bool rx) +{ + struct dma_extended_desc *ep = (struct dma_extended_desc *)head; + int i; + + pr_info("Extended %s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { + u64 x; + + x = *(u64 *)ep; + pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", + i, (unsigned int)virt_to_phys(ep), + (unsigned int)x, (unsigned int)(x >> 32), + ep->basic.des2, ep->basic.des3); + ep++; + } + pr_info("\n"); +} + const struct stmmac_desc_ops enh_desc_ops = { .tx_status = enh_desc_get_tx_status, .rx_status = enh_desc_get_rx_status, @@ -430,4 +450,5 @@ const struct stmmac_desc_ops enh_desc_ops = { .get_tx_timestamp_status = enh_desc_get_tx_timestamp_status, .get_timestamp = enh_desc_get_timestamp, .get_rx_timestamp_status = enh_desc_get_rx_timestamp_status, + .display_ring = enh_desc_display_ring, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index e13228f..d93323d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -279,6 +279,26 @@ static int ndesc_get_rx_timestamp_status(void *desc, u32 ats) return 1; } +static void ndesc_display_ring(void *head, unsigned size, bool rx) +{ + struct dma_desc *p = (struct dma_desc *)head; + int i; + + pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { + u64 x; + + x = *(u64 *)p; + pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", + i, (unsigned int)virt_to_phys(p), + (unsigned int)x, (unsigned int)(x >> 32), + p->des2, p->des3); + p++; + } + pr_info("\n"); +} + const struct stmmac_desc_ops ndesc_ops = { .tx_status = ndesc_get_tx_status, .rx_status = ndesc_get_rx_status, @@ -297,4 +317,5 @@ const struct stmmac_desc_ops ndesc_ops = { .get_tx_timestamp_status = ndesc_get_tx_timestamp_status, .get_timestamp = ndesc_get_timestamp, .get_rx_timestamp_status = ndesc_get_rx_timestamp_status, + .display_ring = ndesc_display_ring, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d3ebfea..8103527 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -883,53 +883,22 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } -/** - * stmmac_display_ring - display ring - * @head: pointer to the head of the ring passed. - * @size: size of the ring. - * @extend_desc: to verify if extended descriptors are used. - * Description: display the control/status and buffer descriptors. - */ -static void stmmac_display_ring(void *head, int size, int extend_desc) -{ - int i; - struct dma_extended_desc *ep = (struct dma_extended_desc *)head; - struct dma_desc *p = (struct dma_desc *)head; - - for (i = 0; i < size; i++) { - u64 x; - if (extend_desc) { - x = *(u64 *) ep; - pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", - i, (unsigned int)virt_to_phys(ep), - (unsigned int)x, (unsigned int)(x >> 32), - ep->basic.des2, ep->basic.des3)
[PATCH 06/13] stmmac: add DMA support for GMAC 4.xx
DMA behavior is linked to descriptor management: -descriptor mechanism (Tx for example, but it is exactly the same for RX): -useful registers: -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring -DMA_CH#_TxDesc_List_Address: start address of the ring -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1. -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor -The descriptor Tail Pointer register contains the pointer to the descriptor address (N). The base address and the current descriptor decide the address of the current descriptor that the DMA can process. The descriptors up to one location less than the one indicated by the descriptor tail pointer (N-1) are owned by the DMA. The DMA continues to process the descriptors until the following condition occurs: "current descriptor pointer == Descriptor Tail pointer" Then the DMA goes into suspend mode. The application must perform a write to descriptor tail pointer register and update the tail pointer to have the following condition and to start a new transfer: "current descriptor pointer < Descriptor tail pointer" The DMA automatically wraps around the base address when the end of ring is reached. Up to 8 DMA could be use but currently we only use one (channel0) Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index fa000fd..9398ace 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -3,7 +3,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ - $(stmmac-y) + dwmac4_dma.o dwmac4_lib.o $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index ea7eb0d..2a5126e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -41,6 +41,8 @@ /* Synopsys Core versions */ #defineDWMAC_CORE_3_40 0x34 #defineDWMAC_CORE_3_50 0x35 +#defineDWMAC_CORE_4_00 0x40 +#define STMMAC_CHAN0 0 /* Always supported and default for all chips */ #define DMA_TX_SIZE 512 #define DMA_RX_SIZE 512 @@ -270,6 +272,7 @@ enum dma_irq_status { #defineCORE_PCS_ANE_COMPLETE (1 << 5) #defineCORE_PCS_LINK_STATUS(1 << 6) #defineCORE_RGMII_IRQ (1 << 7) +#define CORE_IRQ_MTL_RX_OVERFLOW BIT(8) /* Physical Coding Sublayer */ struct rgmii_adv { @@ -301,8 +304,10 @@ struct dma_features { /* 802.3az - Energy-Efficient Ethernet (EEE) */ unsigned int eee; unsigned int av; + unsigned int tsoen; /* TX and RX csum */ unsigned int tx_coe; + unsigned int rx_coe; unsigned int rx_coe_type1; unsigned int rx_coe_type2; unsigned int rxfifo_over_2048; @@ -425,6 +430,11 @@ struct stmmac_dma_ops { struct dma_features *dma_cap); /* Program the HW RX Watchdog */ void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt); + void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len); + void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len); + void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan); + void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan); + void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan); }; struct mac_device_info; @@ -473,6 +483,7 @@ struct stmmac_hwtimestamp { }; extern const struct stmmac_hwtimestamp stmmac_ptp; +extern const struct stmmac_mode_ops dwmac4_ring_mode_ops; struct mac_link { int port; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c new file mode 100644 index 000..116151c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -0,0 +1,354 @@ +/* + * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs. + * DWC Ether MAC version 4.xx has been used for developing this code. + * + * This contains the functions to handle the dma. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * A
[PATCH 08/13] stmmac: enhance mmc counter management
For gmac3, the MMC addr map is: 0x100 - 0x2fc For gmac4, the MMC addr map is: 0x700 - 0x8fc So instead of adding 0x600 to the IO address when setup the mmc, the RMON base address is saved inside the private structure and then used to manage the counters. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index 192c249..38a1a56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h @@ -35,6 +35,10 @@ * current value.*/ #define MMC_CNTRL_PRESET 0x10 #define MMC_CNTRL_FULL_HALF_PRESET 0x20 + +#define MMC_GMAC4_OFFSET 0x700 +#define MMC_GMAC3_X_OFFSET 0x100 + struct stmmac_counters { unsigned int mmc_tx_octetcount_gb; unsigned int mmc_tx_framecount_gb; diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 3f20bb1..ce9aa79 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -28,12 +28,12 @@ /* MAC Management Counters register offset */ -#define MMC_CNTRL 0x0100 /* MMC Control */ -#define MMC_RX_INTR0x0104 /* MMC RX Interrupt */ -#define MMC_TX_INTR0x0108 /* MMC TX Interrupt */ -#define MMC_RX_INTR_MASK 0x010c /* MMC Interrupt Mask */ -#define MMC_TX_INTR_MASK 0x0110 /* MMC Interrupt Mask */ -#define MMC_DEFAULT_MASK 0x +#define MMC_CNTRL 0x00/* MMC Control */ +#define MMC_RX_INTR0x04/* MMC RX Interrupt */ +#define MMC_TX_INTR0x08/* MMC TX Interrupt */ +#define MMC_RX_INTR_MASK 0x0c/* MMC Interrupt Mask */ +#define MMC_TX_INTR_MASK 0x10/* MMC Interrupt Mask */ +#define MMC_DEFAULT_MASK 0x /* MMC TX counter registers */ @@ -41,115 +41,115 @@ * _GB register stands for good and bad frames * _G is for good only. */ -#define MMC_TX_OCTETCOUNT_GB 0x0114 -#define MMC_TX_FRAMECOUNT_GB 0x0118 -#define MMC_TX_BROADCASTFRAME_G0x011c -#define MMC_TX_MULTICASTFRAME_G0x0120 -#define MMC_TX_64_OCTETS_GB0x0124 -#define MMC_TX_65_TO_127_OCTETS_GB 0x0128 -#define MMC_TX_128_TO_255_OCTETS_GB0x012c -#define MMC_TX_256_TO_511_OCTETS_GB0x0130 -#define MMC_TX_512_TO_1023_OCTETS_GB 0x0134 -#define MMC_TX_1024_TO_MAX_OCTETS_GB 0x0138 -#define MMC_TX_UNICAST_GB 0x013c -#define MMC_TX_MULTICAST_GB0x0140 -#define MMC_TX_BROADCAST_GB0x0144 -#define MMC_TX_UNDERFLOW_ERROR 0x0148 -#define MMC_TX_SINGLECOL_G 0x014c -#define MMC_TX_MULTICOL_G 0x0150 -#define MMC_TX_DEFERRED0x0154 -#define MMC_TX_LATECOL 0x0158 -#define MMC_TX_EXESSCOL0x015c -#define MMC_TX_CARRIER_ERROR 0x0160 -#define MMC_TX_OCTETCOUNT_G0x0164 -#define MMC_TX_FRAMECOUNT_G0x0168 -#define MMC_TX_EXCESSDEF 0x016c -#define MMC_TX_PAUSE_FRAME 0x0170 -#define MMC_TX_VLAN_FRAME_G0x0174 +#define MMC_TX_OCTETCOUNT_GB 0x14 +#define MMC_TX_FRAMECOUNT_GB 0x18 +#define MMC_TX_BROADCASTFRAME_G0x1c +#define MMC_TX_MULTICASTFRAME_G0x20 +#define MMC_TX_64_OCTETS_GB0x24 +#define MMC_TX_65_TO_127_OCTETS_GB 0x28 +#define MMC_TX_128_TO_255_OCTETS_GB0x2c +#define MMC_TX_256_TO_511_OCTETS_GB0x30 +#define MMC_TX_512_TO_1023_OCTETS_GB 0x34 +#define MMC_TX_1024_TO_MAX_OCTETS_GB 0x38 +#define MMC_TX_UNICAST_GB 0x3c +#define MMC_TX_MULTICAST_GB0x40 +#define MMC_TX_BROADCAST_GB0x44 +#define MMC_TX_UNDERFLOW_ERROR 0x48 +#define MMC_TX_SINGLECOL_G 0x4c +#define MMC_TX_MULTICOL_G 0x50 +#define MMC_TX_DEFERRED0x54 +#define MMC_TX_LATECOL 0x58 +#define MMC_TX_EXESSCOL0x5c +#define MMC_TX_CARRIER_ERROR 0x60 +#define MMC_TX_OCTETCOUNT_G0x64 +#define MMC_TX_FRAMECOUNT_G0x68 +#define MMC_TX_EXCESSDEF 0x6c +#define MMC_TX_PAUSE_FRAME 0x70 +#define MMC_TX_VLAN_FRAME_G0x74 /* MMC RX counter registers */ -#define MMC_RX_FRAMECOUNT_GB 0x0180 -#define MMC_RX_OCTETCOUNT_GB 0x0184 -#define MMC_RX_OCTETCOUNT_G0x0188 -#define MMC_RX_BROADCASTFRAME_G0x018c -#define MMC_RX_MULTICASTFRAME_G0x0190 -#define MMC_RX_CRC_ERROR 0x0194 -#define
[PATCH 11/13] Documentation: networking: update stmmac
Update stmmac driver documentation according to new GMAC 4.x family. Signed-off-by: Alexandre TORGUE diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index d64a147..671fe3d 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -1,6 +1,6 @@ STMicroelectronics 10/100/1000 Synopsys Ethernet driver -Copyright (C) 2007-2014 STMicroelectronics Ltd +Copyright (C) 2007-2015 STMicroelectronics Ltd Author: Giuseppe Cavallaro This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers @@ -138,6 +138,8 @@ struct plat_stmmacenet_data { int (*init)(struct platform_device *pdev, void *priv); void (*exit)(struct platform_device *pdev, void *priv); void *bsp_priv; + int has_gmac4; + bool tso_en; }; Where: @@ -181,6 +183,8 @@ Where: registers. init/exit callbacks should not use or modify platform data. o bsp_priv: another private pointer. + o has_gmac4: uses GMAC4 core. + o tso_en: Enables TSO (TCP Segmentation Offload) feature. For MDIO bus The we have: @@ -278,6 +282,13 @@ Please see the following document: o stmmac_ethtool.c: to implement the ethtool support; o stmmac.h: private driver structure; o common.h: common definitions and VFTs; + o mmc_core.c/mmc.h: Management MAC Counters; + o stmmac_hwtstamp.c: HW timestamp support for PTP; + o stmmac_ptp.c: PTP 1588 clock; + o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c + for STMicroelectronics SoCs. + +- GMAC 3.x o descs.h: descriptor structure definitions; o dwmac1000_core.c: dwmac GiGa core functions; o dwmac1000_dma.c: dma functions for the GMAC chip; @@ -289,11 +300,32 @@ Please see the following document: o enh_desc.c: functions for handling enhanced descriptors; o norm_desc.c: functions for handling normal descriptors; o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes; - o mmc_core.c/mmc.h: Management MAC Counters; - o stmmac_hwtstamp.c: HW timestamp support for PTP; - o stmmac_ptp.c: PTP 1588 clock; - o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c - for STMicroelectronics SoCs. + +- GMAC4.x generation + o dwmac4_core.c: dwmac GMAC4.x core functions; + o dwmac4_desc.c: functions for handling GMAC4.x descriptors; + o dwmac4_descs.h: descriptor definitions; + o dwmac4_dma.c: dma functions for the GMAC4.x chip; + o dwmac4_dma.h: dma definitions for the GMAC4.x chip; + o dwmac4.h: core definitions for the GMAC4.x chip; + o dwmac4_lib.c: generic GMAC4.x functions; + +4.12) TSO support (GMAC4.x) + +TSO (Tcp Segmentation Offload) feature is supported by GMAC 4.x chip family. +When a packet is sent through TCP protocol, the TCP stack ensures that +the SKB provided to the low level driver (stmmac in our case) matches with +the maximum frame len (IP header + TCP header + payload <= 1500 bytes (for +MTU set to 1500)). It means that if an application using TCP want to send a +packet which will have a length (after adding headers) > 1514 the packet +will be split in several TCP packets: The data payload is split and headers +(TCP/IP ..) are added. It is done by software. + +When TSO is enabled, the TCP stack doesn't care about the maximum frame +length and provide SKB packet to stmmac as it is. The GMAC IP will have to +perform the segmentation by it self to match with maximum frame length. + +This feature can be enabled in device tree through "snps,tso" entry. 5) Debug Information -- 1.9.1
[PATCH 09/13] stmmac: add new DT platform entries for GMAC4
This is to support the snps,dwmac-4.00 and snps,dwmac-4.10a and related features on the platform driver. See binding doc for further details. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index 6605d19..4d302db 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -59,6 +59,8 @@ Optional properties: - snps,fb: fixed-burst - snps,mb: mixed-burst - snps,rb: rebuild INCRx Burst + - snps,tso: this enables the TSO feature otherwise it will be managed by + MAC HW capability register. - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus. Examples: diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index dcbd2a1..6ca32f7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -243,6 +243,13 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) plat->pmt = 1; } + if (of_device_is_compatible(np, "snps,dwmac-4.00") || + of_device_is_compatible(np, "snps,dwmac-4.10a")) { + plat->has_gmac4 = 1; + plat->pmt = 1; + plat->tso_en = of_property_read_bool(np, "snps,tso"); + } + if (of_device_is_compatible(np, "snps,dwmac-3.610") || of_device_is_compatible(np, "snps,dwmac-3.710")) { plat->enh_desc = 1; diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 4bcf5a6..3aa1870 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -138,5 +138,7 @@ struct plat_stmmacenet_data { void (*exit)(struct platform_device *pdev, void *priv); void *bsp_priv; struct stmmac_axi *axi; + int has_gmac4; + bool tso_en; }; #endif -- 1.9.1
[PATCH 04/13] stmmac: add descriptors function for GMAC 4.xx
One of main changes of GMAC 4.xx IP is descriptors management. -descriptors are only used in ring mode. -A descriptor is composed of 4 32bits registers (no more extended descriptors) -descriptor mechanism (Tx for example, but it is exactly the same for RX): -useful registers: -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring -DMA_CH#_TxDesc_List_Address: start address of the ring -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1. -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor -The descriptor Tail Pointer register contains the pointer to the descriptor address (N). The base address and the current descriptor decide the address of the current descriptor that the DMA can process. The descriptors up to one location less than the one indicated by the descriptor tail pointer (N-1) are owned by the DMA. The DMA continues to process the descriptors until the following condition occurs: "current descriptor pointer == Descriptor Tail pointer" Then the DMA goes into suspend mode. The application must perform a write to descriptor tail pointer register and update the tail pointer to have the following condition and to start a new transfer: "current descriptor pointer < Descriptor tail pointer" The DMA automatically wraps around the base address when the end of ring is reached. -New features are available on IP: -TSO (TCP Segmentation Offload) for TX only -Split header: to have header and payload in 2 different buffers Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..fa000fd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -2,7 +2,8 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ - mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y) + mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ + $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 66e132f..ea7eb0d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -243,6 +243,7 @@ enum rx_frame_status { csum_none = 0x2, llc_snap = 0x4, dma_own = 0x8, + rx_not_ls = 0x10, }; /* Tx status */ @@ -348,6 +349,10 @@ struct stmmac_desc_ops { void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len, bool csum_flag, int mode, bool tx_own, bool ls); + void (*prepare_tso_tx_desc)(struct dma_desc *p, int is_fs, int len1, + int len2, bool tx_own, bool ls, + unsigned int tcphdrlen, + unsigned int tcppayloadlen); /* Set/get the owner of the descriptor */ void (*set_tx_owner) (struct dma_desc *p); int (*get_tx_owner) (struct dma_desc *p); @@ -382,6 +387,8 @@ struct stmmac_desc_ops { int (*get_rx_timestamp_status) (void *desc, u32 ats); /* Display ring */ void (*display_ring)(void *head, unsigned int size, bool rx); + /* set MSS via context descriptor */ + void (*set_mss)(struct dma_desc *p, unsigned int mss); }; extern const struct stmmac_desc_ops enh_desc_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c new file mode 100644 index 000..33cbec3 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -0,0 +1,396 @@ +/* + * This contains the functions to handle the descriptors for DesignWare databook + * 4.xx. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Author: Alexandre Torgue + */ + +#include +#include "common.h" +#include "dwmac4_descs.h" + +static int dwmac4_wrback_get_tx_status(void *data, struct stmmac_extra_stats *x, + struct dma_desc *p, + void __iomem *ioaddr) +{ + struct net_device_stats *stats = (struct net_device_stats *)data; + un
[PATCH 10/13] stmmac: support new GMAC4
This patch adds the whole GMAC4 support inside the stmmac d.d. now able to use the new HW and some new features i.e.: TSO. It is missing the multi-queue and split Header support at this stage. This patch also updates the driver version and the stmmac.txt. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index eabe86b..fc60368 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -169,6 +169,9 @@ struct stmmac_extra_stats { unsigned long mtl_rx_fifo_ctrl_active; unsigned long mac_rx_frame_ctrl_fifo; unsigned long mac_gmii_rx_proto_engine; + /* TSO */ + unsigned long tx_tso_frames; + unsigned long tx_tso_nfrags; }; /* CSR Frequency Access Defines*/ @@ -545,6 +548,7 @@ void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable); void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; +extern const struct stmmac_desc_ops dwmac4_desc_ops; /** * stmmac_get_synopsys_id - return the SYINID. diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 26fb855..317ce35 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -24,7 +24,7 @@ #define __STMMAC_H__ #define STMMAC_RESOURCE_NAME "stmmaceth" -#define DRV_MODULE_VERSION "Oct_2015" +#define DRV_MODULE_VERSION "Dec_2015" #include #include @@ -67,6 +67,7 @@ struct stmmac_priv { spinlock_t tx_lock; bool tx_path_in_lpi_mode; struct timer_list txtimer; + bool tso; struct dma_desc *dma_rx cacheline_aligned_in_smp; struct dma_extended_desc *dma_erx; @@ -129,6 +130,9 @@ struct stmmac_priv { int irq_wake; spinlock_t ptp_lock; void __iomem *mmcaddr; + u32 rx_tail_addr; + u32 tx_tail_addr; + u32 mss; #ifdef CONFIG_DEBUG_FS struct dentry *dbgfs_dir; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index fb2e7fc85..e2b98b0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -161,6 +161,9 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { STMMAC_STAT(mtl_rx_fifo_ctrl_active), STMMAC_STAT(mac_rx_frame_ctrl_fifo), STMMAC_STAT(mac_gmii_rx_proto_engine), + /* TSO */ + STMMAC_STAT(tx_tso_frames), + STMMAC_STAT(tx_tso_nfrags), }; #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) @@ -499,7 +502,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, int i, j = 0; /* Update the DMA HW counters for dwmac10/100 */ - if (!priv->plat->has_gmac) + if (priv->hw->dma->dma_diagnostic_fr) priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats, priv->ioaddr); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 977487a..cb21884 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -56,6 +56,7 @@ #include "dwmac1000.h" #define STMMAC_ALIGN(x)L1_CACHE_ALIGN(x) +#defineTSO_MAX_BUFF_SIZE (SZ_16K - 1) /* Module parameters */ #define TX_TIMEO 5000 @@ -726,13 +727,15 @@ static void stmmac_adjust_link(struct net_device *dev) new_state = 1; switch (phydev->speed) { case 1000: - if (likely(priv->plat->has_gmac)) + if (likely((priv->plat->has_gmac) || + (priv->plat->has_gmac4))) ctrl &= ~priv->hw->link.port; stmmac_hw_fix_mac_speed(priv); break; case 100: case 10: - if (priv->plat->has_gmac) { + if (likely((priv->plat->has_gmac) || + (priv->plat->has_gmac4))) { ctrl |= priv->hw->link.port; if (phydev->speed == SPEED_100) { ctrl |= priv->hw->link.speed; @@ -977,7 +980,10 @@ static int stmmac_init_rx_buffer
Re: [PATCH 00/13] Enhance stmmac driver to support GMAC4.x IP
Hi, On 03/25/2016 04:11 PM, David Miller wrote: It is absolutely not appropriate to submit new feature patches at this time. Please resubmit this after the net-next tree opens back out. No pb, I will wait and resend. Regards Alex Thank you.
[RESEND PATCH net-next 11/13] Documentation: networking: update stmmac
Update stmmac driver documentation according to new GMAC 4.x family. Signed-off-by: Alexandre TORGUE diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index d64a147..671fe3d 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -1,6 +1,6 @@ STMicroelectronics 10/100/1000 Synopsys Ethernet driver -Copyright (C) 2007-2014 STMicroelectronics Ltd +Copyright (C) 2007-2015 STMicroelectronics Ltd Author: Giuseppe Cavallaro This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers @@ -138,6 +138,8 @@ struct plat_stmmacenet_data { int (*init)(struct platform_device *pdev, void *priv); void (*exit)(struct platform_device *pdev, void *priv); void *bsp_priv; + int has_gmac4; + bool tso_en; }; Where: @@ -181,6 +183,8 @@ Where: registers. init/exit callbacks should not use or modify platform data. o bsp_priv: another private pointer. + o has_gmac4: uses GMAC4 core. + o tso_en: Enables TSO (TCP Segmentation Offload) feature. For MDIO bus The we have: @@ -278,6 +282,13 @@ Please see the following document: o stmmac_ethtool.c: to implement the ethtool support; o stmmac.h: private driver structure; o common.h: common definitions and VFTs; + o mmc_core.c/mmc.h: Management MAC Counters; + o stmmac_hwtstamp.c: HW timestamp support for PTP; + o stmmac_ptp.c: PTP 1588 clock; + o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c + for STMicroelectronics SoCs. + +- GMAC 3.x o descs.h: descriptor structure definitions; o dwmac1000_core.c: dwmac GiGa core functions; o dwmac1000_dma.c: dma functions for the GMAC chip; @@ -289,11 +300,32 @@ Please see the following document: o enh_desc.c: functions for handling enhanced descriptors; o norm_desc.c: functions for handling normal descriptors; o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes; - o mmc_core.c/mmc.h: Management MAC Counters; - o stmmac_hwtstamp.c: HW timestamp support for PTP; - o stmmac_ptp.c: PTP 1588 clock; - o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c - for STMicroelectronics SoCs. + +- GMAC4.x generation + o dwmac4_core.c: dwmac GMAC4.x core functions; + o dwmac4_desc.c: functions for handling GMAC4.x descriptors; + o dwmac4_descs.h: descriptor definitions; + o dwmac4_dma.c: dma functions for the GMAC4.x chip; + o dwmac4_dma.h: dma definitions for the GMAC4.x chip; + o dwmac4.h: core definitions for the GMAC4.x chip; + o dwmac4_lib.c: generic GMAC4.x functions; + +4.12) TSO support (GMAC4.x) + +TSO (Tcp Segmentation Offload) feature is supported by GMAC 4.x chip family. +When a packet is sent through TCP protocol, the TCP stack ensures that +the SKB provided to the low level driver (stmmac in our case) matches with +the maximum frame len (IP header + TCP header + payload <= 1500 bytes (for +MTU set to 1500)). It means that if an application using TCP want to send a +packet which will have a length (after adding headers) > 1514 the packet +will be split in several TCP packets: The data payload is split and headers +(TCP/IP ..) are added. It is done by software. + +When TSO is enabled, the TCP stack doesn't care about the maximum frame +length and provide SKB packet to stmmac as it is. The GMAC IP will have to +perform the segmentation by it self to match with maximum frame length. + +This feature can be enabled in device tree through "snps,tso" entry. 5) Debug Information -- 1.9.1
[RESEND PATCH net-next 04/13] stmmac: add descriptors function for GMAC 4.xx
One of main changes of GMAC 4.xx IP is descriptors management. -descriptors are only used in ring mode. -A descriptor is composed of 4 32bits registers (no more extended descriptors) -descriptor mechanism (Tx for example, but it is exactly the same for RX): -useful registers: -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring -DMA_CH#_TxDesc_List_Address: start address of the ring -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1. -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor -The descriptor Tail Pointer register contains the pointer to the descriptor address (N). The base address and the current descriptor decide the address of the current descriptor that the DMA can process. The descriptors up to one location less than the one indicated by the descriptor tail pointer (N-1) are owned by the DMA. The DMA continues to process the descriptors until the following condition occurs: "current descriptor pointer == Descriptor Tail pointer" Then the DMA goes into suspend mode. The application must perform a write to descriptor tail pointer register and update the tail pointer to have the following condition and to start a new transfer: "current descriptor pointer < Descriptor tail pointer" The DMA automatically wraps around the base address when the end of ring is reached. -New features are available on IP: -TSO (TCP Segmentation Offload) for TX only -Split header: to have header and payload in 2 different buffers Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..fa000fd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -2,7 +2,8 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ - mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y) + mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ + $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 66e132f..ea7eb0d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -243,6 +243,7 @@ enum rx_frame_status { csum_none = 0x2, llc_snap = 0x4, dma_own = 0x8, + rx_not_ls = 0x10, }; /* Tx status */ @@ -348,6 +349,10 @@ struct stmmac_desc_ops { void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len, bool csum_flag, int mode, bool tx_own, bool ls); + void (*prepare_tso_tx_desc)(struct dma_desc *p, int is_fs, int len1, + int len2, bool tx_own, bool ls, + unsigned int tcphdrlen, + unsigned int tcppayloadlen); /* Set/get the owner of the descriptor */ void (*set_tx_owner) (struct dma_desc *p); int (*get_tx_owner) (struct dma_desc *p); @@ -382,6 +387,8 @@ struct stmmac_desc_ops { int (*get_rx_timestamp_status) (void *desc, u32 ats); /* Display ring */ void (*display_ring)(void *head, unsigned int size, bool rx); + /* set MSS via context descriptor */ + void (*set_mss)(struct dma_desc *p, unsigned int mss); }; extern const struct stmmac_desc_ops enh_desc_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c new file mode 100644 index 000..d4952c7 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -0,0 +1,396 @@ +/* + * This contains the functions to handle the descriptors for DesignWare databook + * 4.xx. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Author: Alexandre Torgue + */ + +#include +#include "common.h" +#include "dwmac4_descs.h" + +static int dwmac4_wrback_get_tx_status(void *data, struct stmmac_extra_stats *x, + struct dma_desc *p, + void __iomem *ioaddr) +{ + struct net_device_stats *stats = (struct net_device_stats *)data; + un
[RESEND PATCH net-next 01/13] stmmac: rework get_hw_feature function
On next GMAC IP generation (4.xx), the way to get hw feature is not the same than on previous 3.xx. As it is hardware dependent, the way to get hw capabilities should be defined in dma ops of each MAC IP. It will avoid also a huge computation of hw capabilities in stmmac_main. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index f96d257..797a913 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -412,7 +412,8 @@ struct stmmac_dma_ops { int (*dma_interrupt) (void __iomem *ioaddr, struct stmmac_extra_stats *x); /* If supported then get the optional core features */ - unsigned int (*get_hw_feature) (void __iomem *ioaddr); + void (*get_hw_feature)(void __iomem *ioaddr, + struct dma_features *dma_cap); /* Program the HW RX Watchdog */ void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt); }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index da32d60..99074695 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -215,9 +215,40 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) } } -static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr) +static void dwmac1000_get_hw_feature(void __iomem *ioaddr, +struct dma_features *dma_cap) { - return readl(ioaddr + DMA_HW_FEATURE); + u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE); + + dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); + dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; + dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; + dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; + dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; + dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; + dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; + dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; + dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; + /* MMC */ + dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; + /* IEEE 1588-2002 */ + dma_cap->time_stamp = + (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; + /* IEEE 1588-2008 */ + dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; + /* 802.3az - Energy-Efficient Ethernet (EEE) */ + dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; + dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; + /* TX and RX csum */ + dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; + dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; + dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; + dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; + /* TX and RX number of channels */ + dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; + dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; + /* Alternate (enhanced) DESC mode */ + dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; } static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4c5ce98..d3ebfea 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1558,51 +1558,15 @@ static void stmmac_selec_desc_mode(struct stmmac_priv *priv) */ static int stmmac_get_hw_features(struct stmmac_priv *priv) { - u32 hw_cap = 0; + u32 ret = 0; if (priv->hw->dma->get_hw_feature) { - hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); - - priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); - priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; - priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; - priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; - priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; - priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; - priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >>
[RESEND PATCH net-next 00/13] Enhance stmmac driver to support GMAC4.x IP
This is a subset of patch to enhance current stmmac driver to support new GMAC4.x chips. New set of callbacks is defined to support this new family: descriptors, dma, core. One of main changes of GMAC 4.xx IP is descriptors management. -descriptors are only used in ring mode. -A descriptor is composed of 4 32bits registers (no more extended descriptors) -descriptor mechanism (Tx for example, but it is exactly the same for RX): -useful registers: -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring -DMA_CH#_TxDesc_List_Address: start address of the ring -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1. -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor -The descriptor Tail Pointer register contains the pointer to the descriptor address (N). The base address and the current descriptor decide the address of the current descriptor that the DMA can process. The descriptors up to one location less than the one indicated by the descriptor tail pointer (N-1) are owned by the DMA. The DMA continues to process the descriptors until the following condition occurs: "current descriptor pointer == Descriptor Tail pointer" Then the DMA goes into suspend mode. The application must perform a write to descriptor tail pointer register and update the tail pointer to have the following condition and to start a new transfer: "current descriptor pointer < Descriptor tail pointer" The DMA automatically wraps around the base address when the end of ring is reached. New features are available on IP: -TSO (TCP Segmentation Offload) for TX only -Split header: to have header and payload in 2 different buffers (not yet implemented) Below some throughput figures obtained on some boxes: iperf (mbps) -- tcp udp tx rx tx rx - GMAC4.x 935 930 750 800 Note: There is a change in 4.10a databook on bitfield mapping of DMA_CHANx_INTR_ENA register. This requires to have � diffrent set of callbacks between IP 4.00a and 4.10a. Best regards Alex I'm resending this series because first sending was badly done during merge window. Alexandre TORGUE (13): stmmac: rework get_hw_feature function stmmac: rework the routines to show the ring status stmmac: rework synopsys id read, moved to dwmac setup stmmac: add descriptors function for GMAC 4.xx stmmac: add GMAC4 DMA/CORE Header File stmmac: add DMA support for GMAC 4.xx stmmac: add GMAC4 core support stmmac: enhance mmc counter management stmmac: add new DT platform entries for GMAC4 stmmac: support new GMAC4 Documentation: networking: update stmmac stmmac: update version to Jan_2016 stmmac: update MAINTAINERS Documentation/devicetree/bindings/net/stmmac.txt | 2 + Documentation/networking/stmmac.txt| 44 +- MAINTAINERS| 1 + drivers/net/ethernet/stmicro/stmmac/Makefile | 3 +- drivers/net/ethernet/stmicro/stmmac/common.h | 64 +- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 7 +- .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c| 35 +- .../net/ethernet/stmicro/stmmac/dwmac100_core.c| 5 +- drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 255 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 407 + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 396 + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h | 129 + drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 354 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h | 202 +++ drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 225 +++ drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 21 + drivers/net/ethernet/stmicro/stmmac/mmc.h | 4 + drivers/net/ethernet/stmicro/stmmac/mmc_core.c | 349 +-- drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 21 + drivers/net/ethernet/stmicro/stmmac/stmmac.h | 7 +- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 643 +++-- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 7 + include/linux/stmmac.h | 2 + 24 files changed, 2821 insertions(+), 369 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c -- 1.9.1
[RESEND PATCH net-next 09/13] stmmac: add new DT platform entries for GMAC4
This is to support the snps,dwmac-4.00 and snps,dwmac-4.10a and related features on the platform driver. See binding doc for further details. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index 6605d19..4d302db 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -59,6 +59,8 @@ Optional properties: - snps,fb: fixed-burst - snps,mb: mixed-burst - snps,rb: rebuild INCRx Burst + - snps,tso: this enables the TSO feature otherwise it will be managed by + MAC HW capability register. - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus. Examples: diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index dcbd2a1..6ca32f7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -243,6 +243,13 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) plat->pmt = 1; } + if (of_device_is_compatible(np, "snps,dwmac-4.00") || + of_device_is_compatible(np, "snps,dwmac-4.10a")) { + plat->has_gmac4 = 1; + plat->pmt = 1; + plat->tso_en = of_property_read_bool(np, "snps,tso"); + } + if (of_device_is_compatible(np, "snps,dwmac-3.610") || of_device_is_compatible(np, "snps,dwmac-3.710")) { plat->enh_desc = 1; diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 4bcf5a6..3aa1870 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -138,5 +138,7 @@ struct plat_stmmacenet_data { void (*exit)(struct platform_device *pdev, void *priv); void *bsp_priv; struct stmmac_axi *axi; + int has_gmac4; + bool tso_en; }; #endif -- 1.9.1
[RESEND PATCH net-next 03/13] stmmac: rework synopsys id read, moved to dwmac setup
synopsys_uid is only used once after setup, to get synopsys_id by using shitf/mask operation. It's no longer used then. So, remove this temporary variable and directly compute synopsys_id from setup routine. Acked-by: Giuseppe Cavallaro Signed-off-by: Fabrice Gasnier Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 6cea61b..66e132f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -498,7 +498,6 @@ struct mac_device_info { const struct stmmac_hwtimestamp *ptp; struct mii_regs mii;/* MII register Addresses */ struct mac_link link; - unsigned int synopsys_uid; void __iomem *pcsr; /* vpointer to device CSRs */ int multicast_filter_bins; int unicast_filter_entries; @@ -507,8 +506,10 @@ struct mac_device_info { }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, - int perfect_uc_entries); -struct mac_device_info *dwmac100_setup(void __iomem *ioaddr); + int perfect_uc_entries, + int *synopsys_id); +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id); + void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low); @@ -521,4 +522,24 @@ void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; +/** + * stmmac_get_synopsys_id - return the SYINID. + * @priv: driver private structure + * Description: this simple function is to decode and return the SYINID + * starting from the HW core register. + */ +static inline u32 stmmac_get_synopsys_id(u32 hwid) +{ + /* Check Synopsys Id (not available on old chips) */ + if (likely(hwid)) { + u32 uid = ((hwid & 0xff00) >> 8); + u32 synid = (hwid & 0x00ff); + + pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", + uid, synid); + + return synid; + } + return 0; +} #endif /* __COMMON_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index c294117..fb1eb57 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -491,7 +491,8 @@ static const struct stmmac_ops dwmac1000_ops = { }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, - int perfect_uc_entries) + int perfect_uc_entries, + int *synopsys_id) { struct mac_device_info *mac; u32 hwid = readl(ioaddr + GMAC_VERSION); @@ -516,7 +517,9 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, mac->link.speed = GMAC_CONTROL_FES; mac->mii.addr = GMAC_MII_ADDR; mac->mii.data = GMAC_MII_DATA; - mac->synopsys_uid = hwid; + + /* Get and dump the chip ID */ + *synopsys_id = stmmac_get_synopsys_id(hwid); return mac; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index f8dd773..6418b2e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -173,7 +173,7 @@ static const struct stmmac_ops dwmac100_ops = { .get_umac_addr = dwmac100_get_umac_addr, }; -struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id) { struct mac_device_info *mac; @@ -192,7 +192,8 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) mac->link.speed = 0; mac->mii.addr = MAC_MII_ADDR; mac->mii.data = MAC_MII_DATA; - mac->synopsys_uid = 0; + /* Synopsys Id is not available on old chips */ + *synopsys_id = 0; return mac; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8103527..2ebee81 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1468,29 +1468,6 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) } /** - * stmmac_get_synopsys_id - return the SYINID. - * @priv: driver private structure - * Description: this simple function is to decode and return the SYINID - * starting from the HW core register. - */ -static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) -{ - u32 hwid = priv->hw->synopsys_uid;
[RESEND PATCH net-next 06/13] stmmac: add DMA support for GMAC 4.xx
DMA behavior is linked to descriptor management: -descriptor mechanism (Tx for example, but it is exactly the same for RX): -useful registers: -DMA_CH#_TxDesc_Ring_Len: length of transmit descriptor ring -DMA_CH#_TxDesc_List_Address: start address of the ring -DMA_CH#_TxDesc_Tail_Pointer: address of the last descriptor to send + 1. -DMA_CH#_TxDesc_Current_App_TxDesc: address of the current descriptor -The descriptor Tail Pointer register contains the pointer to the descriptor address (N). The base address and the current descriptor decide the address of the current descriptor that the DMA can process. The descriptors up to one location less than the one indicated by the descriptor tail pointer (N-1) are owned by the DMA. The DMA continues to process the descriptors until the following condition occurs: "current descriptor pointer == Descriptor Tail pointer" Then the DMA goes into suspend mode. The application must perform a write to descriptor tail pointer register and update the tail pointer to have the following condition and to start a new transfer: "current descriptor pointer < Descriptor tail pointer" The DMA automatically wraps around the base address when the end of ring is reached. Up to 8 DMA could be use but currently we only use one (channel0) Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index fa000fd..9398ace 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -3,7 +3,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ - $(stmmac-y) + dwmac4_dma.o dwmac4_lib.o $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index ea7eb0d..2a5126e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -41,6 +41,8 @@ /* Synopsys Core versions */ #defineDWMAC_CORE_3_40 0x34 #defineDWMAC_CORE_3_50 0x35 +#defineDWMAC_CORE_4_00 0x40 +#define STMMAC_CHAN0 0 /* Always supported and default for all chips */ #define DMA_TX_SIZE 512 #define DMA_RX_SIZE 512 @@ -270,6 +272,7 @@ enum dma_irq_status { #defineCORE_PCS_ANE_COMPLETE (1 << 5) #defineCORE_PCS_LINK_STATUS(1 << 6) #defineCORE_RGMII_IRQ (1 << 7) +#define CORE_IRQ_MTL_RX_OVERFLOW BIT(8) /* Physical Coding Sublayer */ struct rgmii_adv { @@ -301,8 +304,10 @@ struct dma_features { /* 802.3az - Energy-Efficient Ethernet (EEE) */ unsigned int eee; unsigned int av; + unsigned int tsoen; /* TX and RX csum */ unsigned int tx_coe; + unsigned int rx_coe; unsigned int rx_coe_type1; unsigned int rx_coe_type2; unsigned int rxfifo_over_2048; @@ -425,6 +430,11 @@ struct stmmac_dma_ops { struct dma_features *dma_cap); /* Program the HW RX Watchdog */ void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt); + void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len); + void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len); + void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan); + void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan); + void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan); }; struct mac_device_info; @@ -473,6 +483,7 @@ struct stmmac_hwtimestamp { }; extern const struct stmmac_hwtimestamp stmmac_ptp; +extern const struct stmmac_mode_ops dwmac4_ring_mode_ops; struct mac_link { int port; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c new file mode 100644 index 000..116151c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -0,0 +1,354 @@ +/* + * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs. + * DWC Ether MAC version 4.xx has been used for developing this code. + * + * This contains the functions to handle the dma. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * A
[RESEND PATCH net-next 13/13] stmmac: update MAINTAINERS
Signed-off-by: Alexandre TORGUE diff --git a/MAINTAINERS b/MAINTAINERS index 32bafda..37fc112 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3348,6 +3348,7 @@ F:Documentation/powerpc/cxlflash.txt STMMAC ETHERNET DRIVER M: Giuseppe Cavallaro +M: Alexandre Torgue L: netdev@vger.kernel.org W: http://www.stlinux.com S: Supported -- 1.9.1
[RESEND PATCH net-next 05/13] stmmac: add GMAC4 DMA/CORE Header File
This is the main header file to define all the macro used for GMAC4 DMA and CORE parts. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h new file mode 100644 index 000..c12f15c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -0,0 +1,224 @@ +/* + * DWMAC4 Header file. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Author: Alexandre Torgue + */ + +#ifndef __DWMAC4_H__ +#define __DWMAC4_H__ + +#include "common.h" + +/* MAC registers */ +#define GMAC_CONFIG0x +#define GMAC_PACKET_FILTER 0x0008 +#define GMAC_HASH_TAB_0_31 0x0010 +#define GMAC_HASH_TAB_32_630x0014 +#define GMAC_RX_FLOW_CTRL 0x0090 +#define GMAC_QX_TX_FLOW_CTRL(x)(0x70 + x * 4) +#define GMAC_INT_STATUS0x00b0 +#define GMAC_INT_EN0x00b4 +#define GMAC_AN_CTRL 0x00e0 +#define GMAC_AN_STATUS 0x00e4 +#define GMAC_AN_ADV0x00e8 +#define GMAC_AN_LPA0x00ec +#define GMAC_PMT 0x00c0 +#define GMAC_VERSION 0x0110 +#define GMAC_DEBUG 0x0114 +#define GMAC_HW_FEATURE0 0x011c +#define GMAC_HW_FEATURE1 0x0120 +#define GMAC_HW_FEATURE2 0x0124 +#define GMAC_MDIO_ADDR 0x0200 +#define GMAC_MDIO_DATA 0x0204 +#define GMAC_ADDR_HIGH(reg)(0x300 + reg * 8) +#define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) + +/* MAC Packet Filtering */ +#define GMAC_PACKET_FILTER_PR BIT(0) +#define GMAC_PACKET_FILTER_HMC BIT(2) +#define GMAC_PACKET_FILTER_PM BIT(4) + +#define GMAC_MAX_PERFECT_ADDRESSES 128 + +/* MAC Flow Control RX */ +#define GMAC_RX_FLOW_CTRL_RFE BIT(0) + +/* MAC Flow Control TX */ +#define GMAC_TX_FLOW_CTRL_TFE BIT(1) +#define GMAC_TX_FLOW_CTRL_PT_SHIFT 16 + +/* MAC Interrupt bitmap*/ +#define GMAC_INT_PMT_ENBIT(4) +#define GMAC_INT_LPI_ENBIT(5) + +enum dwmac4_irq_status { + time_stamp_irq = 0x1000, + mmc_rx_csum_offload_irq = 0x0800, + mmc_tx_irq = 0x0400, + mmc_rx_irq = 0x0200, + mmc_irq = 0x0100, + pmt_irq = 0x0010, + pcs_ane_irq = 0x0004, + pcs_link_irq = 0x0002, +}; + +/* MAC Auto-Neg bitmap*/ +#defineGMAC_AN_CTRL_RANBIT(9) +#defineGMAC_AN_CTRL_ANEBIT(12) +#define GMAC_AN_CTRL_ELE BIT(14) +#define GMAC_AN_FD BIT(5) +#define GMAC_AN_HD BIT(6) +#define GMAC_AN_PSE_MASK GENMASK(8, 7) +#define GMAC_AN_PSE_SHIFT 7 + +/* MAC PMT bitmap */ +enum power_event { + pointer_reset = 0x8000, + global_unicast = 0x0200, + wake_up_rx_frame = 0x0040, + magic_frame = 0x0020, + wake_up_frame_en = 0x0004, + magic_pkt_en = 0x0002, + power_down = 0x0001, +}; + +/* MAC Debug bitmap */ +#define GMAC_DEBUG_TFCSTS_MASK GENMASK(18, 17) +#define GMAC_DEBUG_TFCSTS_SHIFT17 +#define GMAC_DEBUG_TFCSTS_IDLE 0 +#define GMAC_DEBUG_TFCSTS_WAIT 1 +#define GMAC_DEBUG_TFCSTS_GEN_PAUSE2 +#define GMAC_DEBUG_TFCSTS_XFER 3 +#define GMAC_DEBUG_TPESTS BIT(16) +#define GMAC_DEBUG_RFCFCSTS_MASK GENMASK(2, 1) +#define GMAC_DEBUG_RFCFCSTS_SHIFT 1 +#define GMAC_DEBUG_RPESTS BIT(0) + +/* MAC config */ +#define GMAC_CONFIG_IPCBIT(27) +#define GMAC_CONFIG_2K BIT(22) +#define GMAC_CONFIG_ACSBIT(20) +#define GMAC_CONFIG_BE BIT(18) +#define GMAC_CONFIG_JD BIT(17) +#define GMAC_CONFIG_JE BIT(16) +#define GMAC_CONFIG_PS BIT(15) +#define GMAC_CONFIG_FESBIT(14) +#define GMAC_CONFIG_DM BIT(13) +#define GMAC_CONFIG_DCRS BIT(9) +#define GMAC_CONFIG_TE BIT(1) +#define GMAC_CONFIG_RE BIT(0) + +/* MAC HW features0 bitmap */ +#define GMAC_HW_FEAT_ADDMACBIT(18) +#define GMAC_HW_FEAT_RXCOESEL BIT(16) +#define GMAC_HW_FEAT_TXCOSEL BIT(14) +#define GMAC_HW_FEAT_EEESELBIT(13) +#define GMAC_HW_FEAT_TSSEL BIT(12) +#define GMAC_HW_FEAT_MMCSELBIT(8) +#define GMAC_HW_FEAT_MGKSELBIT(7
[RESEND PATCH net-next 02/13] stmmac: rework the routines to show the ring status
To avoid lot of check in stmmac_main for display ring management and support the GMAC4 chip, the display_ring function is moved into dedicated descriptor file. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 797a913..6cea61b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -380,6 +380,8 @@ struct stmmac_desc_ops { u64(*get_timestamp) (void *desc, u32 ats); /* get rx timestamp status */ int (*get_rx_timestamp_status) (void *desc, u32 ats); + /* Display ring */ + void (*display_ring)(void *head, unsigned int size, bool rx); }; extern const struct stmmac_desc_ops enh_desc_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index cfb018c..38f19c9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -411,6 +411,26 @@ static int enh_desc_get_rx_timestamp_status(void *desc, u32 ats) } } +static void enh_desc_display_ring(void *head, unsigned int size, bool rx) +{ + struct dma_extended_desc *ep = (struct dma_extended_desc *)head; + int i; + + pr_info("Extended %s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { + u64 x; + + x = *(u64 *)ep; + pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", + i, (unsigned int)virt_to_phys(ep), + (unsigned int)x, (unsigned int)(x >> 32), + ep->basic.des2, ep->basic.des3); + ep++; + } + pr_info("\n"); +} + const struct stmmac_desc_ops enh_desc_ops = { .tx_status = enh_desc_get_tx_status, .rx_status = enh_desc_get_rx_status, @@ -430,4 +450,5 @@ const struct stmmac_desc_ops enh_desc_ops = { .get_tx_timestamp_status = enh_desc_get_tx_timestamp_status, .get_timestamp = enh_desc_get_timestamp, .get_rx_timestamp_status = enh_desc_get_rx_timestamp_status, + .display_ring = enh_desc_display_ring, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index e13228f..b9f6e3f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -279,6 +279,26 @@ static int ndesc_get_rx_timestamp_status(void *desc, u32 ats) return 1; } +static void ndesc_display_ring(void *head, unsigned int size, bool rx) +{ + struct dma_desc *p = (struct dma_desc *)head; + int i; + + pr_info("%s descriptor ring:\n", rx ? "RX" : "TX"); + + for (i = 0; i < size; i++) { + u64 x; + + x = *(u64 *)p; + pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", + i, (unsigned int)virt_to_phys(p), + (unsigned int)x, (unsigned int)(x >> 32), + p->des2, p->des3); + p++; + } + pr_info("\n"); +} + const struct stmmac_desc_ops ndesc_ops = { .tx_status = ndesc_get_tx_status, .rx_status = ndesc_get_rx_status, @@ -297,4 +317,5 @@ const struct stmmac_desc_ops ndesc_ops = { .get_tx_timestamp_status = ndesc_get_tx_timestamp_status, .get_timestamp = ndesc_get_timestamp, .get_rx_timestamp_status = ndesc_get_rx_timestamp_status, + .display_ring = ndesc_display_ring, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d3ebfea..8103527 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -883,53 +883,22 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } -/** - * stmmac_display_ring - display ring - * @head: pointer to the head of the ring passed. - * @size: size of the ring. - * @extend_desc: to verify if extended descriptors are used. - * Description: display the control/status and buffer descriptors. - */ -static void stmmac_display_ring(void *head, int size, int extend_desc) -{ - int i; - struct dma_extended_desc *ep = (struct dma_extended_desc *)head; - struct dma_desc *p = (struct dma_desc *)head; - - for (i = 0; i < size; i++) { - u64 x; - if (extend_desc) { - x = *(u64 *) ep; - pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", - i, (unsigned int)virt_to_phys(ep), - (unsigned int)x, (unsigned int)(x >> 32), - ep->basic.des2, ep->basi
[RESEND PATCH net-next 07/13] stmmac: add GMAC4 core support
This is the initial support for GMAC4 that includes the main callbacks to setup the core module: including Csum, basic filtering, mac address and interrupt (MMC, MTL, PMT) No LPI added. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 9398ace..0fb362d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -3,7 +3,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ - dwmac4_dma.o dwmac4_lib.o $(stmmac-y) + dwmac4_dma.o dwmac4_lib.o dwmac4_core.o $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 2a5126e..eabe86b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -527,15 +527,21 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, int perfect_uc_entries, int *synopsys_id); struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id); - +struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins, +int perfect_uc_entries, int *synopsys_id); void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low); void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int high, unsigned int low); - void stmmac_set_mac(void __iomem *ioaddr, bool enable); +void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, u8 addr[6], + unsigned int high, unsigned int low); +void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, + unsigned int high, unsigned int low); +void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable); + void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index c12f15c..bc50952 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -221,4 +221,35 @@ enum power_event { /* To dump the core regs excluding the Address Registers */ #defineGMAC_REG_NUM132 +/* MTL debug */ +#define MTL_DEBUG_TXSTSFSTSBIT(5) +#define MTL_DEBUG_TXFSTS BIT(4) +#define MTL_DEBUG_TWCSTS BIT(3) + +/* MTL debug: Tx FIFO Read Controller Status */ +#define MTL_DEBUG_TRCSTS_MASK GENMASK(2, 1) +#define MTL_DEBUG_TRCSTS_SHIFT 1 +#define MTL_DEBUG_TRCSTS_IDLE 0 +#define MTL_DEBUG_TRCSTS_READ 1 +#define MTL_DEBUG_TRCSTS_TXW 2 +#define MTL_DEBUG_TRCSTS_WRITE 3 +#define MTL_DEBUG_TXPAUSED BIT(0) + +/* MAC debug: GMII or MII Transmit Protocol Engine Status */ +#define MTL_DEBUG_RXFSTS_MASK GENMASK(5, 4) +#define MTL_DEBUG_RXFSTS_SHIFT 4 +#define MTL_DEBUG_RXFSTS_EMPTY 0 +#define MTL_DEBUG_RXFSTS_BT1 +#define MTL_DEBUG_RXFSTS_AT2 +#define MTL_DEBUG_RXFSTS_FULL 3 +#define MTL_DEBUG_RRCSTS_MASK GENMASK(2, 1) +#define MTL_DEBUG_RRCSTS_SHIFT 1 +#define MTL_DEBUG_RRCSTS_IDLE 0 +#define MTL_DEBUG_RRCSTS_RDATA 1 +#define MTL_DEBUG_RRCSTS_RSTAT 2 +#define MTL_DEBUG_RRCSTS_FLUSH 3 +#define MTL_DEBUG_RWCSTS BIT(0) + +extern const struct stmmac_dma_ops dwmac4_dma_ops; +extern const struct stmmac_dma_ops dwmac410_dma_ops; #endif /* __DWMAC4_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c new file mode 100644 index 000..4f7283d --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -0,0 +1,407 @@ +/* + * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs. + * DWC Ether MAC version 4.00 has been used for developing this code. + * + * This only implements the mac core functions for this chip. + * + * Copyright (C) 2015 STMicroelectronics Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Author: Alexandre Torgue
[RESEND PATCH net-next 08/13] stmmac: enhance mmc counter management
For gmac3, the MMC addr map is: 0x100 - 0x2fc For gmac4, the MMC addr map is: 0x700 - 0x8fc So instead of adding 0x600 to the IO address when setup the mmc, the RMON base address is saved inside the private structure and then used to manage the counters. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index 192c249..38a1a56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h @@ -35,6 +35,10 @@ * current value.*/ #define MMC_CNTRL_PRESET 0x10 #define MMC_CNTRL_FULL_HALF_PRESET 0x20 + +#define MMC_GMAC4_OFFSET 0x700 +#define MMC_GMAC3_X_OFFSET 0x100 + struct stmmac_counters { unsigned int mmc_tx_octetcount_gb; unsigned int mmc_tx_framecount_gb; diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 3f20bb1..ce9aa79 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -28,12 +28,12 @@ /* MAC Management Counters register offset */ -#define MMC_CNTRL 0x0100 /* MMC Control */ -#define MMC_RX_INTR0x0104 /* MMC RX Interrupt */ -#define MMC_TX_INTR0x0108 /* MMC TX Interrupt */ -#define MMC_RX_INTR_MASK 0x010c /* MMC Interrupt Mask */ -#define MMC_TX_INTR_MASK 0x0110 /* MMC Interrupt Mask */ -#define MMC_DEFAULT_MASK 0x +#define MMC_CNTRL 0x00/* MMC Control */ +#define MMC_RX_INTR0x04/* MMC RX Interrupt */ +#define MMC_TX_INTR0x08/* MMC TX Interrupt */ +#define MMC_RX_INTR_MASK 0x0c/* MMC Interrupt Mask */ +#define MMC_TX_INTR_MASK 0x10/* MMC Interrupt Mask */ +#define MMC_DEFAULT_MASK 0x /* MMC TX counter registers */ @@ -41,115 +41,115 @@ * _GB register stands for good and bad frames * _G is for good only. */ -#define MMC_TX_OCTETCOUNT_GB 0x0114 -#define MMC_TX_FRAMECOUNT_GB 0x0118 -#define MMC_TX_BROADCASTFRAME_G0x011c -#define MMC_TX_MULTICASTFRAME_G0x0120 -#define MMC_TX_64_OCTETS_GB0x0124 -#define MMC_TX_65_TO_127_OCTETS_GB 0x0128 -#define MMC_TX_128_TO_255_OCTETS_GB0x012c -#define MMC_TX_256_TO_511_OCTETS_GB0x0130 -#define MMC_TX_512_TO_1023_OCTETS_GB 0x0134 -#define MMC_TX_1024_TO_MAX_OCTETS_GB 0x0138 -#define MMC_TX_UNICAST_GB 0x013c -#define MMC_TX_MULTICAST_GB0x0140 -#define MMC_TX_BROADCAST_GB0x0144 -#define MMC_TX_UNDERFLOW_ERROR 0x0148 -#define MMC_TX_SINGLECOL_G 0x014c -#define MMC_TX_MULTICOL_G 0x0150 -#define MMC_TX_DEFERRED0x0154 -#define MMC_TX_LATECOL 0x0158 -#define MMC_TX_EXESSCOL0x015c -#define MMC_TX_CARRIER_ERROR 0x0160 -#define MMC_TX_OCTETCOUNT_G0x0164 -#define MMC_TX_FRAMECOUNT_G0x0168 -#define MMC_TX_EXCESSDEF 0x016c -#define MMC_TX_PAUSE_FRAME 0x0170 -#define MMC_TX_VLAN_FRAME_G0x0174 +#define MMC_TX_OCTETCOUNT_GB 0x14 +#define MMC_TX_FRAMECOUNT_GB 0x18 +#define MMC_TX_BROADCASTFRAME_G0x1c +#define MMC_TX_MULTICASTFRAME_G0x20 +#define MMC_TX_64_OCTETS_GB0x24 +#define MMC_TX_65_TO_127_OCTETS_GB 0x28 +#define MMC_TX_128_TO_255_OCTETS_GB0x2c +#define MMC_TX_256_TO_511_OCTETS_GB0x30 +#define MMC_TX_512_TO_1023_OCTETS_GB 0x34 +#define MMC_TX_1024_TO_MAX_OCTETS_GB 0x38 +#define MMC_TX_UNICAST_GB 0x3c +#define MMC_TX_MULTICAST_GB0x40 +#define MMC_TX_BROADCAST_GB0x44 +#define MMC_TX_UNDERFLOW_ERROR 0x48 +#define MMC_TX_SINGLECOL_G 0x4c +#define MMC_TX_MULTICOL_G 0x50 +#define MMC_TX_DEFERRED0x54 +#define MMC_TX_LATECOL 0x58 +#define MMC_TX_EXESSCOL0x5c +#define MMC_TX_CARRIER_ERROR 0x60 +#define MMC_TX_OCTETCOUNT_G0x64 +#define MMC_TX_FRAMECOUNT_G0x68 +#define MMC_TX_EXCESSDEF 0x6c +#define MMC_TX_PAUSE_FRAME 0x70 +#define MMC_TX_VLAN_FRAME_G0x74 /* MMC RX counter registers */ -#define MMC_RX_FRAMECOUNT_GB 0x0180 -#define MMC_RX_OCTETCOUNT_GB 0x0184 -#define MMC_RX_OCTETCOUNT_G0x0188 -#define MMC_RX_BROADCASTFRAME_G0x018c -#define MMC_RX_MULTICASTFRAME_G0x0190 -#define MMC_RX_CRC_ERROR 0x0194 -#define
[RESEND PATCH net-next 10/13] stmmac: support new GMAC4
This patch adds the whole GMAC4 support inside the stmmac d.d. now able to use the new HW and some new features i.e.: TSO. It is missing the multi-queue and split Header support at this stage. This patch also updates the driver version and the stmmac.txt. Signed-off-by: Alexandre TORGUE Signed-off-by: Giuseppe Cavallaro diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index eabe86b..fc60368 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -169,6 +169,9 @@ struct stmmac_extra_stats { unsigned long mtl_rx_fifo_ctrl_active; unsigned long mac_rx_frame_ctrl_fifo; unsigned long mac_gmii_rx_proto_engine; + /* TSO */ + unsigned long tx_tso_frames; + unsigned long tx_tso_nfrags; }; /* CSR Frequency Access Defines*/ @@ -545,6 +548,7 @@ void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable); void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; +extern const struct stmmac_desc_ops dwmac4_desc_ops; /** * stmmac_get_synopsys_id - return the SYINID. diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 26fb855..317ce35 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -24,7 +24,7 @@ #define __STMMAC_H__ #define STMMAC_RESOURCE_NAME "stmmaceth" -#define DRV_MODULE_VERSION "Oct_2015" +#define DRV_MODULE_VERSION "Dec_2015" #include #include @@ -67,6 +67,7 @@ struct stmmac_priv { spinlock_t tx_lock; bool tx_path_in_lpi_mode; struct timer_list txtimer; + bool tso; struct dma_desc *dma_rx cacheline_aligned_in_smp; struct dma_extended_desc *dma_erx; @@ -129,6 +130,9 @@ struct stmmac_priv { int irq_wake; spinlock_t ptp_lock; void __iomem *mmcaddr; + u32 rx_tail_addr; + u32 tx_tail_addr; + u32 mss; #ifdef CONFIG_DEBUG_FS struct dentry *dbgfs_dir; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index fb2e7fc85..e2b98b0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -161,6 +161,9 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { STMMAC_STAT(mtl_rx_fifo_ctrl_active), STMMAC_STAT(mac_rx_frame_ctrl_fifo), STMMAC_STAT(mac_gmii_rx_proto_engine), + /* TSO */ + STMMAC_STAT(tx_tso_frames), + STMMAC_STAT(tx_tso_nfrags), }; #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) @@ -499,7 +502,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, int i, j = 0; /* Update the DMA HW counters for dwmac10/100 */ - if (!priv->plat->has_gmac) + if (priv->hw->dma->dma_diagnostic_fr) priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats, priv->ioaddr); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 977487a..cb21884 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -56,6 +56,7 @@ #include "dwmac1000.h" #define STMMAC_ALIGN(x)L1_CACHE_ALIGN(x) +#defineTSO_MAX_BUFF_SIZE (SZ_16K - 1) /* Module parameters */ #define TX_TIMEO 5000 @@ -726,13 +727,15 @@ static void stmmac_adjust_link(struct net_device *dev) new_state = 1; switch (phydev->speed) { case 1000: - if (likely(priv->plat->has_gmac)) + if (likely((priv->plat->has_gmac) || + (priv->plat->has_gmac4))) ctrl &= ~priv->hw->link.port; stmmac_hw_fix_mac_speed(priv); break; case 100: case 10: - if (priv->plat->has_gmac) { + if (likely((priv->plat->has_gmac) || + (priv->plat->has_gmac4))) { ctrl |= priv->hw->link.port; if (phydev->speed == SPEED_100) { ctrl |= priv->hw->link.speed; @@ -977,7 +980,10 @@ static int stmmac_init_rx_buffer
[RESEND PATCH net-next 12/13] stmmac: update version to Jan_2016
This patch just updates the driver to the version fully tested on STi platforms. This version is Jan_2016. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 317ce35..ff67506 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -24,7 +24,7 @@ #define __STMMAC_H__ #define STMMAC_RESOURCE_NAME "stmmaceth" -#define DRV_MODULE_VERSION "Dec_2015" +#define DRV_MODULE_VERSION "Jan_2016" #include #include -- 1.9.1
Re: [PATCH v5 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Hi Rob, 2016-03-22 17:11 GMT+01:00 Alexandre Torgue : > Hi guys, > > I will fix typo issues (s/vesrion/version and ethernet @). > > Concerning compatible string. For sure "snps,dwmac-3.50a" string is > not used inside glue driver. > I perfere to keep it for information but if you really want that I > remove it I will not block ;) > > 2016-03-21 16:36 GMT+01:00 Joachim Eastwood : >> On 21 March 2016 at 13:40, Rob Herring wrote: >>> On Sat, Mar 19, 2016 at 12:00:22AM +0800, Chen-Yu Tsai wrote: >>>> Hi, >>>> >>>> On Fri, Mar 18, 2016 at 11:37 PM, Alexandre TORGUE >>>> wrote: >>>> > +- clocks: Must contain a phandle for each entry in clock-names. >>>> > +- clock-names: Should be "stmmaceth" for the host clock. >>> > We can remove host clock (stmmac eth) entry here and refer to > stmmac.txt binding for common entry > >>> This doesn't sound like the clock input signal name... >>> >>>> > + Should be "tx-clk" for the MAC TX clock. >>>> > + Should be "rx-clk" for the MAC RX clock. >>> >>> How can other DWMAC blocks not have these clocks? The glue can't really >>> add these clocks. It could combine them into one or a new version of >>> DWMAC could have a different number of clock inputs. So if there is >>> variation here, then some of the bindings are probably wrong. I guess >>> the only change I'm suggesting is possibly moving these into common >>> binding doc. >> >> The LPC18xx implementation probably have these clocks as well but the >> LPC1850 user manual only documents the main clock. Someone with access >> to the IP block doc from Synopsys should be able to check which clocks >> the MAC really needs. >> >> Rockchip bindings have two clocks named "mac_clk_rx" and "mac_clk_tx". >> These are probably the same as stm32 needs so maybe use these names >> and move them into the main doc and update the rockchip binding. >> > I think we can use same name. But I have a doubt on moving it in a > common bindings (maybe I don't well understood). When you say "common > binding file" is it "stmmac.txt" binding ? If yes does it mean that we > have to control it inside stmmac driver (no more in glue) ? In this > case those clocks will become "required" for stm32 and rockship but > not for others chip. It could create confusion? A gentle ping. Can you give me your feedback please ? I will send next patchset version according to your answer. Thanks in advance Alex > > Best regards > > Alex > >> >> regards, >> Joachim Eastwood
[PATCH net-next] net: ethernet: stmmac: GMAC4.xx: Fix TX descriptor preparation
On GMAC4.xx each descriptor contains 2 buffers of 16KB (each). Initially, those 2 buffers was filled in dwmac4_rd_prepare_tx_desc but it is actually not needed. Indeed, stmmac driver supports frame up to 9000 bytes (jumbo). So only one buffer is needed. Reported-by: Dan Carpenter Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index d4952c7..4ec7397 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -254,14 +254,7 @@ static void dwmac4_rd_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, { unsigned int tdes3 = p->des3; - if (unlikely(len > BUF_SIZE_16KiB)) { - p->des2 |= (((len - BUF_SIZE_16KiB) << -TDES2_BUFFER2_SIZE_MASK_SHIFT) - & TDES2_BUFFER2_SIZE_MASK) - | (BUF_SIZE_16KiB & TDES2_BUFFER1_SIZE_MASK); - } else { - p->des2 |= (len & TDES2_BUFFER1_SIZE_MASK); - } + p->des2 |= (len & TDES2_BUFFER1_SIZE_MASK); if (is_fs) tdes3 |= TDES3_FIRST_DESCRIPTOR; -- 1.9.1
Re: [PATCH v2 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Hi Joachim, 2016-02-23 23:37 GMT+01:00 Joachim Eastwood : > Hi Alexandre, > > You should copy 'devicet...@vger.kernel.org' on bindings doc. Adding cc here. > > On 23 February 2016 at 16:10, Alexandre TORGUE > wrote: >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> new file mode 100644 >> index 000..18734b3 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> @@ -0,0 +1,41 @@ >> +STMicroelectronics STM32 / MCU DWMAC glue layer controller >> + >> +This file documents platform glue layer for stmmac. >> +Please see stmmac.txt for the other unchanged properties. >> + >> +The device node has following properties. >> + >> +Required properties: >> +- compatible: Should be "st,stm32-dwmac" to select glue, and >> + "snps,dwmac-3.50a" to select IP vesrion. >> +- clocks: Should contain the GMAC main clock, and tx clock >> +- compatible: Should be "st,stm32-dwmac" to select glue and >> + "snps,dwmac-3.50a" to select IP version. >> +- clocks: Should contain the MAC main clock >> +- clock-names: Should contain the clock names "stmmaceth". >> +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node >> which >> + encompases the glue register, and the offset of the control >> register. >> + >> +Optional properties: >> +- clocks: Could contain: >> + - the tx clock, >> + - the rx clock >> +- clock-names: Could contain the clock names "tx-clk", "rx-clk" >> + >> +Example: >> + >> + ethernet0: dwmac@40028000 { >> + device_type = "network"; > > What is this 'device_type = "network"' for? > It seems to used in a lot of powerpc DTs, but only a couple of arm DTs. Actually it seems that this entry is deprecated for ARM (http://lists.openwall.net/linux-kernel/2013/12/11/372) Concerning stmmac driver I don't see an issue to remove it (tested). So If Rob and Peppe could confirm, I will remove it in my V3. Br Alexandre > > Maybe Rob could enlighten us? > >> + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; >> + status = "disabled"; >> + reg = <0x40028000 0x8000>; >> + reg-names = "stmmaceth"; >> + interrupts = <0 61 0>, <0 62 0>; >> + interrupt-names = "macirq", "eth_wake_irq"; >> + clock-names = "stmmaceth", "tx-clk", "rx-clk"; >> + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; >> + st,syscon = <&syscfg 0x4>; >> + snps,pbl = <32>; > > Regarding snps,pbl; using 32 here might not give you what you would except. > See comment in dwmac1000_dma_init(). > > The driver is hard coded to use PBL4X/PBL8X mode. Just a heads up. > > > regards, > Joachim Eastwood
[PATCH v3 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt new file mode 100644 index 000..67fceda --- /dev/null +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -0,0 +1,40 @@ +STMicroelectronics STM32 / MCU DWMAC glue layer controller + +This file documents platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +The device node has following properties. + +Required properties: +- compatible: Should be "st,stm32-dwmac" to select glue, and + "snps,dwmac-3.50a" to select IP vesrion. +- clocks: Should contain the GMAC main clock, and tx clock +- compatible: Should be "st,stm32-dwmac" to select glue and + "snps,dwmac-3.50a" to select IP version. +- clocks: Should contain the MAC main clock +- clock-names: Should contain the clock names "stmmaceth". +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which + encompases the glue register, and the offset of the control register. + +Optional properties: +- clocks: Could contain: + - the tx clock, + - the rx clock +- clock-names: Could contain the clock names "tx-clk", "rx-clk" + +Example: + + ethernet0: dwmac@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + snps,mixed-burst; + dma-ranges; + }; -- 1.9.1
[PATCH v3 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..235d679 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -104,6 +104,18 @@ config DWMAC_STI device driver. This driver is used on for the STi series SOCs GMAC ethernet controller. +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF && HAS_IOMEM + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. + config DWMAC_SUNXI tristate "Allwinner GMAC support" default ARCH_SUNXI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..5f7ff0a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA)+= dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o stmmac-platform-objs:= stmmac_platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 000..036ac90 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,193 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) +{ + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; + u32 reg = dwmac->mode_reg; + u32 val; + int ret; + + val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + clk_disable_unprepare(dwmac->clk_tx); + + return ret; +} + +static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) +{ + clk_disable_unprepare(dwmac->clk_tx); + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) +{ + struct device_node *np = dev->of_node; + int err; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "tx-clk"); + if (IS_ERR(dwmac->clk_tx)) { + dev_warn(dev, "No tx clock provided...\n"); + dwmac->clk_tx = NULL; + } + dwmac->clk_rx = devm_clk_get(dev, "rx-clk"); + if (IS_ERR(dwmac->clk_rx)) { + dev_warn(dev, "No rx clock provided...\n"); + dwmac->clk_rx = NULL; + } + + /* Get mode register */ + dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(dwmac->regmap)) + return PTR_ERR(dwmac->regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) + dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); + + return err; +} + +static int stm32_dwmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct stm32_dwmac *dwmac; + int ret; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return ret; + + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); + if (IS_ERR(plat_dat)) + return PT
[PATCH v3 3/4] net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP
Adds support of Synopsys 3.50a MAC IP in stmmac driver. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 6a52fa1..6cca626 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -178,6 +178,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || + of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the -- 1.9.1
[PATCH v3 0/4] Add Ethernet support on STM32F429
STM32F429 Chip embeds a Synopsys 3.50a MAC IP. This series: -enhance current stmmac driver to control it (code already available) and adds basic glue for STM32F429 chip. -Enable basic Net config in kernel. Note that DT patches are not present because STM32 pinctrl code is not yet avalaible. Changes since v2: -Fix alphabetic order in Kconfig and Makefile. -Improve code according to Joachim review. -Binding: remove useless entry. Changes since v1: -Fix Kbuild issue in Kconfig. -Remove init/exit callbacks. Suspend/Resume and remove driver is no more driven in stmmac_pltfr but directly in dwmac-stm32 glue driver. -Take into account Joachim review. Regards. Alexandre. Alexandre TORGUE (4): net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Documentation: Bindings: Add STM32 DWMAC glue net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP ARM: STM32: Enable Ethernet in stm32_defconfig .../devicetree/bindings/net/stm32-dwmac.txt| 40 + arch/arm/configs/stm32_defconfig | 9 + drivers/net/ethernet/stmicro/stmmac/Kconfig| 12 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 193 + .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 6 files changed, 256 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -- 1.9.1
[PATCH v3 4/4] ARM: STM32: Enable Ethernet in stm32_defconfig
Enable basic Ethernet support (IPV4) for stm32 defconfig. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec52505..8b8abe0 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -33,11 +33,20 @@ CONFIG_XIP_PHYS_ADDR=0x08008000 CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_SHARED_FLAT=y # CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set # CONFIG_BLK_DEV is not set CONFIG_EEPROM_93CX6=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -- 1.9.1
[PATCH v3 01/17] stmmac: share reset function between dwmac100 and dwmac1000
From: Giuseppe Cavallaro This patch is to share the same reset procedure between dwmac100 and dwmac1000 chips. This will also help on enhancing the driver and support new chips. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 1e19c8f..bac0e44 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -376,7 +376,8 @@ extern const struct stmmac_desc_ops ndesc_ops; /* Specific DMA helpers */ struct stmmac_dma_ops { /* DMA core initialization */ - int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb, + int (*reset)(void __iomem *ioaddr); + void (*init)(void __iomem *ioaddr, int pbl, int fb, int mb, int burst_len, u32 dma_tx, u32 dma_rx, int atds); /* Dump DMA registers */ void (*dump_regs) (void __iomem *ioaddr); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h index 2ec6aea..1657acf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h @@ -95,7 +95,6 @@ #define DMA_BUS_MODE_DSL_MASK 0x007c /* Descriptor Skip Length */ #define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */ #define DMA_BUS_MODE_BAR_BUS 0x0002 /* Bar-Bus Arbitration */ -#define DMA_BUS_MODE_SFT_RESET 0x0001 /* Software Reset */ #define DMA_BUS_MODE_DEFAULT 0x /* DMA Control register defines */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 8831a05..9d36ae7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -221,7 +221,6 @@ enum inter_frame_gap { /*--- DMA BLOCK defines ---*/ /* DMA Bus Mode register defines */ -#define DMA_BUS_MODE_SFT_RESET 0x0001 /* Software Reset */ #define DMA_BUS_MODE_DA0x0002 /* Arbitration scheme */ #define DMA_BUS_MODE_DSL_MASK 0x007c /* Descriptor Skip Length */ #define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index 0e8937c..5f0aea5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -30,23 +30,10 @@ #include "dwmac1000.h" #include "dwmac_dma.h" -static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, - int burst_len, u32 dma_tx, u32 dma_rx, int atds) +static void dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, + int burst_len, u32 dma_tx, u32 dma_rx, int atds) { - u32 value = readl(ioaddr + DMA_BUS_MODE); - int limit; - - /* DMA SW reset */ - value |= DMA_BUS_MODE_SFT_RESET; - writel(value, ioaddr + DMA_BUS_MODE); - limit = 10; - while (limit--) { - if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) - break; - mdelay(10); - } - if (limit < 0) - return -EBUSY; + u32 value; /* * Set the DMA PBL (Programmable Burst Length) mode @@ -102,8 +89,6 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, */ writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR); writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR); - - return 0; } static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz) @@ -205,6 +190,7 @@ static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt) } const struct stmmac_dma_ops dwmac1000_dma_ops = { + .reset = dwmac_dma_reset, .init = dwmac1000_dma_init, .dump_regs = dwmac1000_dump_dma_regs, .dma_mode = dwmac1000_dma_operation_mode, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 9d0971c..c40582a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -32,24 +32,9 @@ #include "dwmac100.h" #include "dwmac_dma.h" -static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, -int burst_len, u32 dma_tx, u32 dma_rx, int atds) +static void dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, + int burst_len, u32 dma_tx, u32 dma_rx, int atds) { - u32 value = readl(ioaddr + DMA_BUS_MODE); - int limit; - - /* DMA SW reset */ - value |= DMA_BUS_MODE_SFT_RESET; - writel(value, ioaddr + DMA_BUS_MODE); - limit = 10; - while (limit--) { -
[PATCH v3 03/17] stmmac: change descriptor layout
From: Giuseppe Cavallaro This patch completely changes the descriptor layout to improve the whole performances due to the single read usage of the descriptors in critical paths. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h index 799c292..2e4c171 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs.h @@ -1,6 +1,6 @@ /*** - Header File to describe the DMA descriptors. - Enhanced descriptors have been in case of DWMAC1000 Cores. + Header File to describe the DMA descriptors and related definitions. + This is for DWMAC100 and 1000 cores. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -24,198 +24,164 @@ #ifndef __DESCS_H__ #define __DESCS_H__ +#include + +/* Normal receive descriptor defines */ + +/* RDES0 */ +#defineRDES0_PAYLOAD_CSUM_ERR BIT(0) +#defineRDES0_CRC_ERROR BIT(1) +#defineRDES0_DRIBBLING BIT(2) +#defineRDES0_MII_ERROR BIT(3) +#defineRDES0_RECEIVE_WATCHDOG BIT(4) +#defineRDES0_FRAME_TYPEBIT(5) +#defineRDES0_COLLISION BIT(6) +#defineRDES0_IPC_CSUM_ERRORBIT(7) +#defineRDES0_LAST_DESCRIPTOR BIT(8) +#defineRDES0_FIRST_DESCRIPTOR BIT(9) +#defineRDES0_VLAN_TAG BIT(10) +#defineRDES0_OVERFLOW_ERRORBIT(11) +#defineRDES0_LENGTH_ERROR BIT(12) +#defineRDES0_SA_FILTER_FAILBIT(13) +#defineRDES0_DESCRIPTOR_ERROR BIT(14) +#defineRDES0_ERROR_SUMMARY BIT(15) +#defineRDES0_FRAME_LEN_MASKGENMASK(29, 16) +#define RDES0_FRAME_LEN_SHIFT 16 +#defineRDES0_DA_FILTER_FAILBIT(30) +#defineRDES0_OWN BIT(31) + /* RDES1 */ +#defineRDES1_BUFFER1_SIZE_MASK GENMASK(10, 0) +#defineRDES1_BUFFER2_SIZE_MASK GENMASK(21, 11) +#defineRDES1_BUFFER2_SIZE_SHIFT11 +#defineRDES1_SECOND_ADDRESS_CHAINEDBIT(24) +#defineRDES1_END_RING BIT(25) +#defineRDES1_DISABLE_ICBIT(31) + +/* Enhanced receive descriptor defines */ + +/* RDES0 (similar to normal RDES) */ +#define ERDES0_RX_MAC_ADDR BIT(0) + +/* RDES1: completely differ from normal desc definitions */ +#defineERDES1_BUFFER1_SIZE_MASKGENMASK(12, 0) +#defineERDES1_SECOND_ADDRESS_CHAINED BIT(14) +#defineERDES1_END_RING BIT(15) +#defineERDES1_BUFFER2_SIZE_MASKGENMASK(28, 16) +#define ERDES1_BUFFER2_SIZE_SHIFT 16 +#defineERDES1_DISABLE_IC BIT(31) + +/* Normal transmit descriptor defines */ +/* TDES0 */ +#defineTDES0_DEFERRED BIT(0) +#defineTDES0_UNDERFLOW_ERROR BIT(1) +#defineTDES0_EXCESSIVE_DEFERRALBIT(2) +#defineTDES0_COLLISION_COUNT_MASK GENMASK(6, 3) +#defineTDES0_VLAN_FRAMEBIT(7) +#defineTDES0_EXCESSIVE_COLLISIONS BIT(8) +#defineTDES0_LATE_COLLISIONBIT(9) +#defineTDES0_NO_CARRIERBIT(10) +#defineTDES0_LOSS_CARRIER BIT(11) +#defineTDES0_PAYLOAD_ERROR BIT(12) +#defineTDES0_FRAME_FLUSHED BIT(13) +#defineTDES0_JABBER_TIMEOUTBIT(14) +#defineTDES0_ERROR_SUMMARY BIT(15) +#defineTDES0_IP_HEADER_ERROR BIT(16) +#defineTDES0_TIME_STAMP_STATUS BIT(17) +#defineTDES0_OWN BIT(31) +/* TDES1 */ +#defineTDES1_BUFFER1_SIZE_MASK GENMASK(10, 0) +#defineTDES1_BUFFER2_SIZE_MASK GENMASK(21, 11) +#defineTDES1_BUFFER2_SIZE_SHIFT11 +#defineTDES1_TIME_STAMP_ENABLE BIT(22) +#defineTDES1_DISABLE_PADDING BIT(23) +#defineTDES1_SECOND_ADDRESS_CHAINEDBIT(24) +#defineTDES1_END_RING BIT(25) +#defineTDES1_CRC_DISABLE BIT(26) +#defineTDES1_CHECKSUM_INSERTION_MASK GENMASK(28, 27) +#defineTDES1_CHECKSUM_INSERTION_SHIFT 27 +#defineTDES1_FIRST_SEGMENT BIT(29) +#defineTDES1_LAST_SEGMENT BIT(30) +#defineTDES1_INTERRUPT BIT(31) + +/* Enhanced transmit descriptor defines */ +/* TDES0 */ +#defineETDES0_DEFERRED BIT(0) +#defineETDES0_UNDERFLOW_ERROR BIT(1) +#defineETDES0_EXCESSIVE_DEFERRAL BIT(2) +#defineETDES0_COLLISION_COUNT_MASK GENMASK(6, 3) +#defineETDES0_VLAN_FRAME BIT(7
[PATCH v3 00/17] stmmac: enhance driver performances and update the version
According to Giuseppe, I send the v3 series. This is a subset of patches to rework the driver in order to improve its performances and make it more robust under stress conditions. All patches have been ported on STi mainstream kernel branch and tested on ARM STiH4xx platforms and newer ones. This series also updates the driver version and prepares it to include further development to support new chips. In detail, these patches are: o to rework and improve the internal DMA bus settings Fine tuning is mandatory on some platforms for both performance and stability issues. o to rework and optimize the descriptor management. This will help a lot on performance side and preparing the inclusion on the GMAC4.x. o to add a set of optimizations for both xmit and rx functions. These will help a lot on performance side and making the driver more robust in case of low memory conditions and under some stress test, performed for example on IP-STB. Below some throughput figures obtained on some boxes before and after the patches. nuttcp (mbps) iperf (Mbps) -- tcp udp tcp udp tx rx tx rx tx rx tx rx -- old 680 800 480 506760 800 600 700 new 830 880 540 630840 880 700 800 == V2: - rx_copybreak is now managed by using ethtool. V3: - improve comments on PCIe detailing that there are no regressions - rework some APIs to properly define some params as bool as expected - rework the formula to get the element inside the ring. Comparing V2, patches 4 and 13 have been merged because the same formula have been used. After this rework, no evident benefit has been noticed in terms of performances so the table above is still valid. Disassembling the code for SH4 and ARM, with the new formula just an instr is saved (depending on compiler flags) and this gives us not so relevanti gain, for example, on SH4 where some instr are executed in the same pipeline stage. Ring sizes are now fixed and maybe they can be reworked to be tuned w/o using stmmaceth= cmdline option. Indeed, nobody change these sizes and indeed the numbers selected by default respect the budget and avoid to pass invalid setup. These are the best driver default sizes for ring and chain. == Fabrice Gasnier (3): stmmac: merge get_rx_owner into rx_status routine. stmmac: optimize tx clean function stmmac: fix phy init when attached to a phy Giuseppe Cavallaro (14): stmmac: share reset function between dwmac100 and dwmac1000 stmmac: rework DMA bus setting and introduce new platform AXI structure stmmac: change descriptor layout stmmac: review RX/TX ring management stmmac: add length field to dma data stmmac: add last_segment field to dma data stmmac: add is_jumbo field to dma data stmmac: optimize tx desc management stmmac: set dirty index out of the loop stmmac: first frame prep at the end of xmit routine stmmac: do not poll phy handler when attach a switch stmmac: do not perform zero-copy for rx frames stmmac: tune rx copy via threshold. stmmac: update version to Oct_2015 Documentation/devicetree/bindings/net/stmmac.txt | 54 ++- drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 37 +- drivers/net/ethernet/stmicro/stmmac/common.h | 39 +- drivers/net/ethernet/stmicro/stmmac/descs.h| 330 +++--- drivers/net/ethernet/stmicro/stmmac/descs_com.h| 77 ++-- drivers/net/ethernet/stmicro/stmmac/dwmac100.h | 1 - drivers/net/ethernet/stmicro/stmmac/dwmac1000.h| 3 +- .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c| 111 +++-- drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c | 22 +- drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h| 39 +- drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c| 21 + drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 226 +- drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 150 --- drivers/net/ethernet/stmicro/stmmac/ring_mode.c| 32 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 9 +- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 41 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 473 - drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 +- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 42 +- include/linux/stmmac.h | 17 +- 20 files changed, 1016 insertions(+), 712 deletions(-) -- 1.9.1
[PATCH v3 05/17] stmmac: add length field to dma data
From: Giuseppe Cavallaro Currently, the code pulls out the length field when unmapping a buffer directly from the descriptor. This will result in an uncached read to a dma_alloc_coherent() region. There is no need to do this, so this patch simply puts the value directly into a data structure which will hit the cache. Signed-off-by: Fabrice Gasnier Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index 2763772..7fa7ab0d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -49,6 +49,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) if (dma_mapping_error(priv->device, desc->des2)) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; + priv->tx_skbuff_dma[entry].len = bmax; priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE); while (len != 0) { @@ -63,6 +64,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) if (dma_mapping_error(priv->device, desc->des2)) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; + priv->tx_skbuff_dma[entry].len = bmax; priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum, STMMAC_CHAIN_MODE); priv->hw->desc->set_tx_owner(desc); @@ -75,6 +77,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) if (dma_mapping_error(priv->device, desc->des2)) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; + priv->tx_skbuff_dma[entry].len = len; priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, STMMAC_CHAIN_MODE); priv->hw->desc->set_tx_owner(desc); diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index 4358a87..cfc2f24 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -56,6 +56,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; + priv->tx_skbuff_dma[entry].len = bmax; + desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_RING_MODE); @@ -73,6 +75,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) if (dma_mapping_error(priv->device, desc->des2)) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; + priv->tx_skbuff_dma[entry].len = len; + desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, STMMAC_RING_MODE); @@ -84,6 +88,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) if (dma_mapping_error(priv->device, desc->des2)) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; + priv->tx_skbuff_dma[entry].len = nopaged_len; desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum, STMMAC_RING_MODE); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 7ae7c64..c497460 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -45,6 +45,7 @@ struct stmmac_resources { struct stmmac_tx_info { dma_addr_t buf; bool map_as_page; + unsigned len; }; struct stmmac_priv { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index eb555f0..90a946f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1093,6 +1093,7 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) p->des2 = 0; priv->tx_skbuff_dma[i].buf = 0; priv->tx_skbuff_dma[i].map_as_page = false; + priv->tx_skbuff_dma[i].len = 0;
[PATCH v3 02/17] stmmac: rework DMA bus setting and introduce new platform AXI structure
From: Giuseppe Cavallaro This patch restructures the DMA bus settings and this is done by introducing a new platform structure used for programming the AXI Bus Mode Register inside the DMA module. This structure can be populated from device-tree as documented in the binding txt file. After initializing the DMA, the AXI register can be optionally tuned for platform drivers based. This patch also reworks some parameters to make coherent the DMA configuration now that AXI register is introduced. For example, the burst_len is managed by using the mentioned axi support above; so the snps,burst-len parameter has been removed. It makes sense to provide the AAL parameter from DT to Address-Aligned Beats inside the Register0 and review the PBL settings when initialize the engine. For PCI glue, rebuilding the story of this setting, it was added to align a configuration so not for fixing some known problem. No issue raised after this patch. It is safe to use the default burst length instead of tuning it to the maximum value Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index e862a92..6605d19 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -17,7 +17,25 @@ Required properties: The 1st cell is reset pre-delay in micro seconds. The 2nd cell is reset pulse in micro seconds. The 3rd cell is reset post-delay in micro seconds. + +Optional properties: +- resets: Should contain a phandle to the STMMAC reset signal, if any +- reset-names: Should contain the reset signal name "stmmaceth", if a + reset phandle is given +- max-frame-size: See ethernet.txt file in the same directory +- clocks: If present, the first clock should be the GMAC main clock and + the second clock should be peripheral's register interface clock. Further + clocks may be specified in derived bindings. +- clock-names: One name for each entry in the clocks property, the + first one should be "stmmaceth" and the second one should be "pclk". +- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is + available this clock is used for programming the Timestamp Addend Register. + If not passed then the system clock will be used and this is fine on some + platforms. +- tx-fifo-depth: See ethernet.txt file in the same directory +- rx-fifo-depth: See ethernet.txt file in the same directory - snps,pbl Programmable Burst Length +- snps,aal Address-Aligned Beats - snps,fixed-burst Program the DMA to use the fixed burst mode - snps,mixed-burst Program the DMA to use the mixed burst mode - snps,force_thresh_dma_mode Force DMA to use the threshold mode for @@ -29,27 +47,28 @@ Required properties: supported by this device instance - snps,perfect-filter-entries: Number of perfect filter entries supported by this device instance - -Optional properties: -- resets: Should contain a phandle to the STMMAC reset signal, if any -- reset-names: Should contain the reset signal name "stmmaceth", if a - reset phandle is given -- max-frame-size: See ethernet.txt file in the same directory -- clocks: If present, the first clock should be the GMAC main clock - The optional second clock should be peripheral's register interface clock. - The third optional clock should be the ptp reference clock. - Further clocks may be specified in derived bindings. -- clock-names: One name for each entry in the clocks property. - The first one should be "stmmaceth". - The optional second one should be "pclk". - The optional third one should be "clk_ptp_ref". -- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register. -- tx-fifo-depth: See ethernet.txt file in the same directory -- rx-fifo-depth: See ethernet.txt file in the same directory +- AXI BUS Mode parameters: below the list of all the parameters to program the + AXI register inside the DMA module: + - snps,lpi_en: enable Low Power Interface + - snps,xit_frm: unlock on WoL + - snps,wr_osr_lmt: max write oustanding req. limit + - snps,rd_osr_lmt: max read oustanding req. limit + - snps,kbbe: do not cross 1KiB boundary. + - snps,axi_all: align address + - snps,blen: this is a vector of supported burst length. + - snps,fb: fixed-burst + - snps,mb: mixed-burst + - snps,rb: rebuild INCRx Burst - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus. Examples: + stmmac_axi_setup: stmmac-axi-config { + snps,wr_osr_lmt = <0xf>; + snps,rd_osr_lmt = <0xf>; + snps,blen = <256 128 64 32 0 0 0>; +
[PATCH v3 07/17] stmmac: add is_jumbo field to dma data
From: Giuseppe Cavallaro Optimize tx_clean by avoiding a des3 read in stmmac_clean_desc3(). In ring mode, TX, des3 seems only used when xmit a jumbo frame. In case of normal descriptors, it may also be used for time stamping. Clean it in the above two case, without reading it. Signed-off-by: Fabrice Gasnier Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index 355eafb..dacb654 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -152,7 +152,8 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p) struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; unsigned int entry = priv->dirty_tx; - if (priv->tx_skbuff_dma[entry].last_segment && !priv->extend_desc) + if (priv->tx_skbuff_dma[entry].last_segment && !priv->extend_desc && + priv->hwts_tx_en) /* NOTE: Device will overwrite des3 with timestamp value if * 1588-2002 time stamping is enabled, hence reinitialize it * to keep explicit chaining in the descriptor. diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index cfc2f24..c648774 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -57,6 +57,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) priv->tx_skbuff_dma[entry].buf = desc->des2; priv->tx_skbuff_dma[entry].len = bmax; + priv->tx_skbuff_dma[entry].is_jumbo = true; desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, @@ -76,6 +77,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; priv->tx_skbuff_dma[entry].len = len; + priv->tx_skbuff_dma[entry].is_jumbo = true; desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, @@ -89,6 +91,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; priv->tx_skbuff_dma[entry].len = nopaged_len; + priv->tx_skbuff_dma[entry].is_jumbo = true; desc->des3 = desc->des2 + BUF_SIZE_4KiB; priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum, STMMAC_RING_MODE); @@ -126,7 +129,13 @@ static void stmmac_init_desc3(struct dma_desc *p) static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p) { - if (unlikely(p->des3)) + struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; + unsigned int entry = priv->dirty_tx; + + /* des3 is only used for jumbo frames tx or time stamping */ + if (unlikely(priv->tx_skbuff_dma[entry].is_jumbo || +(priv->tx_skbuff_dma[entry].last_segment && + !priv->extend_desc && priv->hwts_tx_en))) p->des3 = 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 0436918..0d01f3e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -47,6 +47,7 @@ struct stmmac_tx_info { bool map_as_page; unsigned len; bool last_segment; + bool is_jumbo; }; struct stmmac_priv { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index feae0de..0194a8f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1361,6 +1361,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) } priv->hw->mode->clean_desc3(priv, p); priv->tx_skbuff_dma[entry].last_segment = false; + priv->tx_skbuff_dma[entry].is_jumbo = false; if (likely(skb != NULL)) { pkts_compl++; -- 1.9.1
[PATCH v3 09/17] stmmac: optimize tx desc management
From: Giuseppe Cavallaro This patch is to optimize the way to manage the TDES inside the xmit function. When prepare the frame, some settings (e.g. OWN bit) can be merged. This has been reworked to improve the tx performances. Signed-off-by: Fabrice Gasnier Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index dacb654..b3e669a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -50,7 +50,9 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; priv->tx_skbuff_dma[entry].len = bmax; - priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE); + /* do not close the descriptor and do not set own bit */ + priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE, + 0, false); while (len != 0) { priv->tx_skbuff[entry] = NULL; @@ -66,8 +68,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) priv->tx_skbuff_dma[entry].buf = desc->des2; priv->tx_skbuff_dma[entry].len = bmax; priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum, - STMMAC_CHAIN_MODE); - priv->hw->desc->set_tx_owner(desc); + STMMAC_CHAIN_MODE, 1, + false); len -= bmax; i++; } else { @@ -78,9 +80,10 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) return -1; priv->tx_skbuff_dma[entry].buf = desc->des2; priv->tx_skbuff_dma[entry].len = len; + /* last descriptor can be set now */ priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, - STMMAC_CHAIN_MODE); - priv->hw->desc->set_tx_owner(desc); + STMMAC_CHAIN_MODE, 1, + true); len = 0; } } diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 3ba268e..885c0f9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -338,12 +338,11 @@ struct stmmac_desc_ops { /* Invoked by the xmit function to prepare the tx descriptor */ void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len, -int csum_flag, int mode); +bool csum_flag, int mode, bool tx_own, +bool ls_ic); /* Set/get the owner of the descriptor */ void (*set_tx_owner) (struct dma_desc *p); int (*get_tx_owner) (struct dma_desc *p); - /* Invoked by the xmit function to close the tx descriptor */ - void (*close_tx_desc) (struct dma_desc *p); /* Clean the tx descriptor as soon as the tx irq is received */ void (*release_tx_desc) (struct dma_desc *p, int mode); /* Clear interrupt on tx frame completion. When this bit is diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 1a2fce9..1abd80e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -302,7 +302,8 @@ static void enh_desc_release_tx_desc(struct dma_desc *p, int mode) } static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, -int csum_flag, int mode) +bool csum_flag, int mode, bool tx_own, +bool ls_ic) { unsigned int tdes0 = p->des0; @@ -316,6 +317,19 @@ static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, else tdes0 &= ~(TX_CIC_FULL << ETDES0_CHECKSUM_INSERTION_SHIFT); + if (tx_own) + tdes0 |= ETDES0_OWN; + + if (is_fs & tx_own) + /* When the own bit, for the first frame, has to be set, all +* descriptors for the same frame has to be set before, to +* avoid race condition. +*/ + wmb(); + + if (ls_ic) + tdes0 |= ETDES0_LAST_SEGMENT | ETDES0_INTERRUPT;
[PATCH v3 08/17] stmmac: merge get_rx_owner into rx_status routine.
From: Fabrice Gasnier The RDES0 register can be read several times while doing RX of a packet. This patch slightly improves RX path performance by reading rdes0 once for two operation: check rx owner, get rx status bits. Signed-off-by: Fabrice Gasnier Acked-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 09291af..3ba268e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -238,10 +238,11 @@ struct stmmac_extra_stats { /* Rx IPC status */ enum rx_frame_status { - good_frame = 0, - discard_frame = 1, - csum_none = 2, - llc_snap = 4, + good_frame = 0x0, + discard_frame = 0x1, + csum_none = 0x2, + llc_snap = 0x4, + dma_own = 0x8, }; enum dma_irq_status { @@ -356,7 +357,6 @@ struct stmmac_desc_ops { /* Get the buffer size from the descriptor */ int (*get_tx_len) (struct dma_desc *p); /* Handle extra events on specific interrupts hw dependent */ - int (*get_rx_owner) (struct dma_desc *p); void (*set_rx_owner) (struct dma_desc *p); /* Get the receive frame size */ int (*get_rx_frame_len) (struct dma_desc *p, int rx_coe_type); diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 716b807..1a2fce9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -186,6 +186,9 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, unsigned int rdes0 = p->des0; int ret = good_frame; + if (unlikely(rdes0 & RDES0_OWN)) + return dma_own; + if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) { if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) { x->rx_desc++; @@ -272,11 +275,6 @@ static int enh_desc_get_tx_owner(struct dma_desc *p) return (p->des0 & ETDES0_OWN) >> 31; } -static int enh_desc_get_rx_owner(struct dma_desc *p) -{ - return (p->des0 & RDES0_OWN) >> 31; -} - static void enh_desc_set_tx_owner(struct dma_desc *p) { p->des0 |= ETDES0_OWN; @@ -402,7 +400,6 @@ const struct stmmac_desc_ops enh_desc_ops = { .init_rx_desc = enh_desc_init_rx_desc, .init_tx_desc = enh_desc_init_tx_desc, .get_tx_owner = enh_desc_get_tx_owner, - .get_rx_owner = enh_desc_get_rx_owner, .release_tx_desc = enh_desc_release_tx_desc, .prepare_tx_desc = enh_desc_prepare_tx_desc, .clear_tx_ic = enh_desc_clear_tx_ic, diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index 460c573..5a91932 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -82,6 +82,9 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x, unsigned int rdes0 = p->des0; struct net_device_stats *stats = (struct net_device_stats *)data; + if (unlikely(rdes0 & RDES0_OWN)) + return dma_own; + if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { pr_warn("%s: Oversized frame spanned multiple buffers\n", __func__); @@ -155,11 +158,6 @@ static int ndesc_get_tx_owner(struct dma_desc *p) return (p->des0 & TDES0_OWN) >> 31; } -static int ndesc_get_rx_owner(struct dma_desc *p) -{ - return (p->des0 & RDES0_OWN) >> 31; -} - static void ndesc_set_tx_owner(struct dma_desc *p) { p->des0 |= TDES0_OWN; @@ -277,7 +275,6 @@ const struct stmmac_desc_ops ndesc_ops = { .init_rx_desc = ndesc_init_rx_desc, .init_tx_desc = ndesc_init_tx_desc, .get_tx_owner = ndesc_get_tx_owner, - .get_rx_owner = ndesc_get_rx_owner, .release_tx_desc = ndesc_release_tx_desc, .prepare_tx_desc = ndesc_prepare_tx_desc, .clear_tx_ic = ndesc_clear_tx_ic, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 0194a8f..796d7c6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2205,7 +2205,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) else p = priv->dma_rx + entry; - if (priv->hw->desc->get_rx_owner(p)) + /* read the status of the incoming frame */ + status = priv->hw->desc->rx_status(&priv->dev->stats, + &priv->xstats, p); + /* check if managed by the DMA otherwise go ahead */ + if (unlikely(status &a
[PATCH v3 04/17] stmmac: review RX/TX ring management
From: Giuseppe Cavallaro This patch is to rework the ring management now optimized. The indexes into the ring buffer are always incremented, and the entry is accessed via doing a modulo to find the "real" position in the ring. It is inefficient, modulo is an expensive operation. The formula [(entry + 1) & (size - 1)] is now adopted on a ring that is power-of-2 in size. Then, the number of elements cannot be set by command line but it is fixed. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index cf28dab..2763772 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -31,8 +31,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) { struct stmmac_priv *priv = (struct stmmac_priv *)p; - unsigned int txsize = priv->dma_tx_size; - unsigned int entry = priv->cur_tx % txsize; + unsigned int entry = priv->cur_tx; struct dma_desc *desc = priv->dma_tx + entry; unsigned int nopaged_len = skb_headlen(skb); unsigned int bmax; @@ -54,7 +53,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) while (len != 0) { priv->tx_skbuff[entry] = NULL; - entry = (++priv->cur_tx) % txsize; + entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); desc = priv->dma_tx + entry; if (len > bmax) { @@ -82,6 +81,9 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) len = 0; } } + + priv->cur_tx = entry; + return entry; } @@ -138,7 +140,7 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p) */ p->des3 = (unsigned int)(priv->dma_rx_phy + (((priv->dirty_rx) + 1) % - priv->dma_rx_size) * + DMA_RX_SIZE) * sizeof(struct dma_desc)); } @@ -151,10 +153,9 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p) * 1588-2002 time stamping is enabled, hence reinitialize it * to keep explicit chaining in the descriptor. */ - p->des3 = (unsigned int)(priv->dma_tx_phy + -(((priv->dirty_tx + 1) % - priv->dma_tx_size) * - sizeof(struct dma_desc))); + p->des3 = (unsigned int)((priv->dma_tx_phy + + ((priv->dirty_tx + 1) % DMA_TX_SIZE)) + * sizeof(struct dma_desc)); } const struct stmmac_mode_ops chain_mode_ops = { diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 586a336..09291af 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -42,6 +42,10 @@ #defineDWMAC_CORE_3_40 0x34 #defineDWMAC_CORE_3_50 0x35 +#define DMA_TX_SIZE 512 +#define DMA_RX_SIZE 512 +#define STMMAC_GET_ENTRY(x, size) ((x + 1) & (size - 1)) + #undef FRAME_FILTER_DEBUG /* #define FRAME_FILTER_DEBUG */ diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index 5dd50c6..4358a87 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -31,8 +31,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) { struct stmmac_priv *priv = (struct stmmac_priv *)p; - unsigned int txsize = priv->dma_tx_size; - unsigned int entry = priv->cur_tx % txsize; + unsigned int entry = priv->cur_tx; struct dma_desc *desc; unsigned int nopaged_len = skb_headlen(skb); unsigned int bmax, len; @@ -62,7 +61,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) STMMAC_RING_MODE); wmb(); priv->tx_skbuff[entry] = NULL; - entry = (++priv->cur_tx) % txsize; + entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); if (priv->extend_desc) desc = (struct dma_desc *)(priv->dma_etx + entry); @@ -90,6 +89,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) STMMAC_RING_MODE); } + priv->cur_tx = entry; + return entry; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/et
[PATCH v3 10/17] stmmac: optimize tx clean function
From: Fabrice Gasnier This patch "inline" get_tx_owner and get_ls routines. It Results in a unique read to tdes0, instead of three, to check TX_OWN and LS bits, and other status bits. It helps improve driver TX path by removing two uncached read/writes inside TX clean loop for enhanced descriptors but not for normal ones because the des1 must be read in any case. Signed-off-by: Fabrice Gasnier Acked-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 885c0f9..7ccb147 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -245,6 +245,14 @@ enum rx_frame_status { dma_own = 0x8, }; +/* Tx status */ +enum tx_frame_status { + tx_done = 0x0, + tx_not_ls = 0x1, + tx_err = 0x2, + tx_dma_own = 0x4, +}; + enum dma_irq_status { tx_hard_error = 0x1, tx_hard_error_bump_tc = 0x2, diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 1abd80e..957610b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -31,7 +31,15 @@ static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x, { struct net_device_stats *stats = (struct net_device_stats *)data; unsigned int tdes0 = p->des0; - int ret = 0; + int ret = tx_done; + + /* Get tx owner first */ + if (unlikely(tdes0 & ETDES0_OWN)) + return tx_dma_own; + + /* Verify tx error by looking at the last segment. */ + if (likely(!(tdes0 & ETDES0_LAST_SEGMENT))) + return tx_not_ls; if (unlikely(tdes0 & ETDES0_ERROR_SUMMARY)) { if (unlikely(tdes0 & ETDES0_JABBER_TIMEOUT)) @@ -71,7 +79,7 @@ static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x, dwmac_dma_flush_tx_fifo(ioaddr); } - ret = -1; + ret = tx_err; } if (unlikely(tdes0 & ETDES0_DEFERRED)) diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index 19cc12d..122fb5a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -31,7 +31,16 @@ static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x, { struct net_device_stats *stats = (struct net_device_stats *)data; unsigned int tdes0 = p->des0; - int ret = 0; + unsigned int tdes1 = p->des1; + int ret = tx_done; + + /* Get tx owner first */ + if (unlikely(tdes0 & TDES0_OWN)) + return tx_dma_own; + + /* Verify tx error by looking at the last segment. */ + if (likely(!(tdes1 & TDES1_LAST_SEGMENT))) + return tx_not_ls; if (unlikely(tdes0 & TDES0_ERROR_SUMMARY)) { if (unlikely(tdes0 & TDES0_UNDERFLOW_ERROR)) { @@ -54,7 +63,7 @@ static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x, collisions = (tdes0 & TDES0_COLLISION_COUNT_MASK) >> 3; stats->collisions += collisions; } - ret = -1; + ret = tx_err; } if (tdes0 & TDES0_VLAN_FRAME) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 24c3608..d31179f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1313,32 +1313,31 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) priv->xstats.tx_clean++; while (entry != priv->cur_tx) { - int last; struct sk_buff *skb = priv->tx_skbuff[entry]; struct dma_desc *p; + int status; if (priv->extend_desc) p = (struct dma_desc *)(priv->dma_etx + entry); else p = priv->dma_tx + entry; - /* Check if the descriptor is owned by the DMA. */ - if (priv->hw->desc->get_tx_owner(p)) - break; - - /* Verify tx error by looking at the last segment. */ - last = priv->tx_skbuff_dma[entry].last_segment; - if (likely(last)) { - int tx_error = - priv->hw->desc->tx_status(&priv->dev->stats, + status = priv->hw->desc->tx_status(&priv->dev->stats, &priv->xstats, p, priv->ioaddr
[PATCH v3 12/17] stmmac: first frame prep at the end of xmit routine
From: Giuseppe Cavallaro This patch is to fill the first descriptor just before granting the DMA engine so at the end of the xmit. The patch takes care about the algorithm adopted to mitigate the interrupts, then it fixes the last segment in case of no fragments. Moreover, this new implementation does not pass any "ter" field when prepare the descriptors because this is not necessary. The patch also details the memory barrier in the xmit. As final results, this patch guarantees the same performances but fixing a case if small datagram are sent. In fact, this kind of test is impacted if no coalesce is done. Signed-off-by: Fabrice Gasnier Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 7ccb147..f96d257 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -100,7 +100,7 @@ struct stmmac_extra_stats { unsigned long napi_poll; unsigned long tx_normal_irq_n; unsigned long tx_clean; - unsigned long tx_reset_ic_bit; + unsigned long tx_set_ic_bit; unsigned long irq_receive_pmt_irq_n; /* MMC info */ unsigned long mmc_tx_irq_n; @@ -347,7 +347,7 @@ struct stmmac_desc_ops { /* Invoked by the xmit function to prepare the tx descriptor */ void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len, bool csum_flag, int mode, bool tx_own, -bool ls_ic); +bool ls); /* Set/get the owner of the descriptor */ void (*set_tx_owner) (struct dma_desc *p); int (*get_tx_owner) (struct dma_desc *p); @@ -355,7 +355,7 @@ struct stmmac_desc_ops { void (*release_tx_desc) (struct dma_desc *p, int mode); /* Clear interrupt on tx frame completion. When this bit is * set an interrupt happens as soon as the frame is transmitted */ - void (*clear_tx_ic) (struct dma_desc *p); + void (*set_tx_ic)(struct dma_desc *p); /* Last tx segment reports the transmit status */ int (*get_tx_ls) (struct dma_desc *p); /* Return the transmit status looking at the TDES1 */ diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 957610b..cfb018c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -311,10 +311,15 @@ static void enh_desc_release_tx_desc(struct dma_desc *p, int mode) static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, bool csum_flag, int mode, bool tx_own, -bool ls_ic) +bool ls) { unsigned int tdes0 = p->des0; + if (mode == STMMAC_CHAIN_MODE) + enh_set_tx_desc_len_on_chain(p, len); + else + enh_set_tx_desc_len_on_ring(p, len); + if (is_fs) tdes0 |= ETDES0_FIRST_SEGMENT; else @@ -325,6 +330,10 @@ static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, else tdes0 &= ~(TX_CIC_FULL << ETDES0_CHECKSUM_INSERTION_SHIFT); + if (ls) + tdes0 |= ETDES0_LAST_SEGMENT; + + /* Finally set the OWN bit. Later the DMA will start! */ if (tx_own) tdes0 |= ETDES0_OWN; @@ -335,20 +344,12 @@ static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, */ wmb(); - if (ls_ic) - tdes0 |= ETDES0_LAST_SEGMENT | ETDES0_INTERRUPT; - p->des0 = tdes0; - - if (mode == STMMAC_CHAIN_MODE) - enh_set_tx_desc_len_on_chain(p, len); - else - enh_set_tx_desc_len_on_ring(p, len); } -static void enh_desc_clear_tx_ic(struct dma_desc *p) +static void enh_desc_set_tx_ic(struct dma_desc *p) { - p->des0 &= ~ETDES0_INTERRUPT; + p->des0 |= ETDES0_INTERRUPT; } static int enh_desc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type) @@ -419,7 +420,7 @@ const struct stmmac_desc_ops enh_desc_ops = { .get_tx_owner = enh_desc_get_tx_owner, .release_tx_desc = enh_desc_release_tx_desc, .prepare_tx_desc = enh_desc_prepare_tx_desc, - .clear_tx_ic = enh_desc_clear_tx_ic, + .set_tx_ic = enh_desc_set_tx_ic, .get_tx_ls = enh_desc_get_tx_ls, .set_tx_owner = enh_desc_set_tx_owner, .set_rx_owner = enh_desc_set_rx_owner, diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index 122fb5a..e13228f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -195,10 +195,15 @@ stat
[PATCH v3 15/17] stmmac: do not perform zero-copy for rx frames
From: Giuseppe Cavallaro This patch is to allow this driver to copy tiny frames during the reception process. This is giving more stability while stressing the driver on STi embedded systems. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 0d01f3e..221f5cd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -74,6 +74,7 @@ struct stmmac_priv { unsigned int cur_rx; unsigned int dirty_rx; unsigned int dma_buf_sz; + unsigned int rx_copybreak; u32 rx_riwt; int hwts_rx_en; dma_addr_t *rx_skbuff_dma; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index c803d4c..3c7928e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -781,6 +781,43 @@ static int stmmac_get_ts_info(struct net_device *dev, return ethtool_op_get_ts_info(dev, info); } +static int stmmac_get_tunable(struct net_device *dev, + const struct ethtool_tunable *tuna, void *data) +{ + struct stmmac_priv *priv = netdev_priv(dev); + int ret = 0; + + switch (tuna->id) { + case ETHTOOL_RX_COPYBREAK: + *(u32 *)data = priv->rx_copybreak; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int stmmac_set_tunable(struct net_device *dev, + const struct ethtool_tunable *tuna, + const void *data) +{ + struct stmmac_priv *priv = netdev_priv(dev); + int ret = 0; + + switch (tuna->id) { + case ETHTOOL_RX_COPYBREAK: + priv->rx_copybreak = *(u32 *)data; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + static const struct ethtool_ops stmmac_ethtool_ops = { .begin = stmmac_check_if_running, .get_drvinfo = stmmac_ethtool_getdrvinfo, @@ -803,6 +840,8 @@ static const struct ethtool_ops stmmac_ethtool_ops = { .get_ts_info = stmmac_get_ts_info, .get_coalesce = stmmac_get_coalesce, .set_coalesce = stmmac_set_coalesce, + .get_tunable = stmmac_get_tunable, + .set_tunable = stmmac_set_tunable, }; void stmmac_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 3cc1355..2ffe8dd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -91,6 +91,8 @@ static int buf_sz = DEFAULT_BUFSIZE; module_param(buf_sz, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(buf_sz, "DMA buffer size"); +#defineSTMMAC_RX_COPYBREAK 256 + static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); @@ -1808,6 +1810,7 @@ static int stmmac_open(struct net_device *dev) priv->xstats.threshold = tc; priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); + priv->rx_copybreak = STMMAC_RX_COPYBREAK; ret = alloc_dma_desc_resources(priv); if (ret < 0) { @@ -2159,8 +2162,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) struct sk_buff *skb; skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); - - if (unlikely(skb == NULL)) + if (unlikely(!skb)) break; priv->rx_skbuff[entry] = skb; @@ -2282,23 +2284,52 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) pr_debug("\tframe size %d, COE: %d\n", frame_len, status); } - skb = priv->rx_skbuff[entry]; - if (unlikely(!skb)) { - pr_err("%s: Inconsistent Rx descriptor chain\n", - priv->dev->name); - priv->dev->stats.rx_dropped++; - break; + + if (unlikely(frame_len < priv->rx_copybreak)) { + skb = netdev_alloc_skb_ip_align(priv->dev, + frame_len); + if (unlikely(!skb)) { + if (ne
[PATCH v3 13/17] stmmac: do not poll phy handler when attach a switch
From: Giuseppe Cavallaro This patch avoids to call the stmmac_adjust_link when the driver is connected to a switch by using the FIXED_PHY support. Prior this patch the phydev->irq was set as PHY_POLL so periodically the phy handler was invoked spending useless time because the link cannot actually change. Note that the stmmac_adjust_link will be called just one time and this guarantees that the ST glue logic will be setup according to the mode and speed fixed. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 90b2612..eab7ac0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -866,6 +866,11 @@ static int stmmac_init_phy(struct net_device *dev) phy_disconnect(phydev); return -ENODEV; } + + /* If attached to a switch, there is no reason to poll phy handler */ + if (!strcmp(priv->plat->phy_bus_name, "fixed")) + phydev->irq = PHY_IGNORE_INTERRUPT; + pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" " Link = %d\n", dev->name, phydev->phy_id, phydev->link); -- 1.9.1
[PATCH v3 17/17] stmmac: update version to Oct_2015
From: Giuseppe Cavallaro This patch just updates the driver to the version fully tested on STi platforms. This version is Oct_2015. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index d6c244f..8bbab97 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -24,7 +24,7 @@ #define __STMMAC_H__ #define STMMAC_RESOURCE_NAME "stmmaceth" -#define DRV_MODULE_VERSION "March_2013" +#define DRV_MODULE_VERSION "Oct_2015" #include #include -- 1.9.1
[PATCH v3 11/17] stmmac: set dirty index out of the loop
From: Giuseppe Cavallaro The dirty index can be updated out of the loop where all the tx resources are claimed. This will help on performances too. Also a useless debug printk has been removed from the main loop. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d31179f..2e4c10a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1340,9 +1340,6 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) } stmmac_get_tx_hwtstamp(priv, entry, skb); } - if (netif_msg_tx_done(priv)) - pr_debug("%s: curr %d, dirty %d\n", __func__, -priv->cur_tx, priv->dirty_tx); if (likely(priv->tx_skbuff_dma[entry].buf)) { if (priv->tx_skbuff_dma[entry].map_as_page) @@ -1372,8 +1369,8 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) priv->hw->desc->release_tx_desc(p, priv->mode); entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); - priv->dirty_tx = entry; } + priv->dirty_tx = entry; netdev_completed_queue(priv->dev, pkts_compl, bytes_compl); -- 1.9.1
[PATCH v3 16/17] stmmac: tune rx copy via threshold.
From: Giuseppe Cavallaro There is a threshold now used to also limit the skb allocation when use zero-copy. This is to avoid that there are incoherence in the ring due to a failure on skb allocation under very aggressive testing and under low memory conditions. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 221f5cd..d6c244f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -75,6 +75,7 @@ struct stmmac_priv { unsigned int dirty_rx; unsigned int dma_buf_sz; unsigned int rx_copybreak; + unsigned int rx_zeroc_thresh; u32 rx_riwt; int hwts_rx_en; dma_addr_t *rx_skbuff_dma; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 2ffe8dd..4c5ce98 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -72,6 +72,7 @@ module_param(phyaddr, int, S_IRUGO); MODULE_PARM_DESC(phyaddr, "Physical device address"); #define STMMAC_TX_THRESH (DMA_TX_SIZE / 4) +#define STMMAC_RX_THRESH (DMA_RX_SIZE / 4) static int flow_ctrl = FLOW_OFF; module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); @@ -2138,6 +2139,14 @@ static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) } +static inline int stmmac_rx_threshold_count(struct stmmac_priv *priv) +{ + if (priv->rx_zeroc_thresh < STMMAC_RX_THRESH) + return 0; + + return 1; +} + /** * stmmac_rx_refill - refill used skb preallocated buffers * @priv: driver private structure @@ -2162,8 +2171,15 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) struct sk_buff *skb; skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); - if (unlikely(!skb)) + if (unlikely(!skb)) { + /* so for a while no zero-copy! */ + priv->rx_zeroc_thresh = STMMAC_RX_THRESH; + if (unlikely(net_ratelimit())) + dev_err(priv->device, + "fail to alloc skb entry %d\n", + entry); break; + } priv->rx_skbuff[entry] = skb; priv->rx_skbuff_dma[entry] = @@ -2179,9 +2195,13 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) priv->hw->mode->refill_desc3(priv, p); + if (priv->rx_zeroc_thresh > 0) + priv->rx_zeroc_thresh--; + if (netif_msg_rx_status(priv)) pr_debug("\trefill entry #%d\n", entry); } + wmb(); priv->hw->desc->set_rx_owner(p); wmb(); @@ -2285,7 +2305,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) frame_len, status); } - if (unlikely(frame_len < priv->rx_copybreak)) { + if (unlikely((frame_len < priv->rx_copybreak) || +stmmac_rx_threshold_count(priv))) { skb = netdev_alloc_skb_ip_align(priv->dev, frame_len); if (unlikely(!skb)) { @@ -2320,6 +2341,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) } prefetch(skb->data - NET_IP_ALIGN); priv->rx_skbuff[entry] = NULL; + priv->rx_zeroc_thresh++; skb_put(skb, frame_len); dma_unmap_single(priv->device, -- 1.9.1
[PATCH v3 14/17] stmmac: fix phy init when attached to a phy
From: Fabrice Gasnier phy_bus_name can be NULL when "fixed-link" property isn't used. Then, since "stmmac: do not poll phy handler when attach a switch", phy_bus_name ptr needs to be checked before strcmp is called. Signed-off-by: Fabrice Gasnier Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index eab7ac0..3cc1355 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -868,8 +868,9 @@ static int stmmac_init_phy(struct net_device *dev) } /* If attached to a switch, there is no reason to poll phy handler */ - if (!strcmp(priv->plat->phy_bus_name, "fixed")) - phydev->irq = PHY_IGNORE_INTERRUPT; + if (priv->plat->phy_bus_name) + if (!strcmp(priv->plat->phy_bus_name, "fixed")) + phydev->irq = PHY_IGNORE_INTERRUPT; pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" " Link = %d\n", dev->name, phydev->phy_id, phydev->link); -- 1.9.1
[PATCH v3 06/17] stmmac: add last_segment field to dma data
From: Giuseppe Cavallaro last_segment field is read twice from dma descriptors in stmmac_clean(). Add last_segment to dma data so that this flag is from priv structure in cache instead of memory. It avoids reading twice from memory for each loop in stmmac_clean(). Signed-off-by: Fabrice Gasnier Signed-off-by: Giuseppe Cavallaro Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index 7fa7ab0d..355eafb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -150,8 +150,9 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p) static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p) { struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; + unsigned int entry = priv->dirty_tx; - if (priv->hw->desc->get_tx_ls(p) && !priv->extend_desc) + if (priv->tx_skbuff_dma[entry].last_segment && !priv->extend_desc) /* NOTE: Device will overwrite des3 with timestamp value if * 1588-2002 time stamping is enabled, hence reinitialize it * to keep explicit chaining in the descriptor. diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index c497460..0436918 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -46,6 +46,7 @@ struct stmmac_tx_info { dma_addr_t buf; bool map_as_page; unsigned len; + bool last_segment; }; struct stmmac_priv { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 90a946f..feae0de 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1094,6 +1094,7 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) priv->tx_skbuff_dma[i].buf = 0; priv->tx_skbuff_dma[i].map_as_page = false; priv->tx_skbuff_dma[i].len = 0; + priv->tx_skbuff_dma[i].last_segment = false; priv->tx_skbuff[i] = NULL; } @@ -1326,7 +1327,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) break; /* Verify tx error by looking at the last segment. */ - last = priv->hw->desc->get_tx_ls(p); + last = priv->tx_skbuff_dma[entry].last_segment; if (likely(last)) { int tx_error = priv->hw->desc->tx_status(&priv->dev->stats, @@ -1359,6 +1360,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) priv->tx_skbuff_dma[entry].map_as_page = false; } priv->hw->mode->clean_desc3(priv, p); + priv->tx_skbuff_dma[entry].last_segment = false; if (likely(skb != NULL)) { pkts_compl++; @@ -2028,6 +2030,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) /* Finalize the latest segment. */ priv->hw->desc->close_tx_desc(desc); + priv->tx_skbuff_dma[entry].last_segment = true; wmb(); /* According to the coalesce parameter the IC bit for the latest -- 1.9.1
[PATCH 1/3] ARM: dts: stm32f429: Add system config bank node
Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index 598362e..bb7a736 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -171,6 +171,11 @@ status = "disabled"; }; + syscfg: system-config@40013800 { + compatible = "syscon"; + reg = <0x40013800 0x400>; + }; + pin-controller { #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH 3/3] ARM: dts: stm32f429: Enable Ethernet on Eval board
MAC is connected to a PHY in MII mode. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 1ae57fa..e345459 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -87,6 +87,21 @@ clock-frequency = <2500>; }; +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_mii>; + pinctrl-names = "default"; + phy-mode= "mii-id"; + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; -- 1.9.1
[PATCH 2/3] ARM: dts: stm32f429: Add Ethernet support
Add Ethernet support (Synopsys MAC IP 3.50a) on stm32f429 SOC. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index bb7a736..af0367c 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -283,6 +283,26 @@ bias-disable; }; }; + + ethernet0_mii: mii@0 { + mii { + slew-rate = <2>; + pinmux = , + , + , + , + , + , +, +, + , + , + , + , + , + ; + }; + }; }; rcc: rcc@40023810 { @@ -323,6 +343,21 @@ st,mem2mem; }; + ethernet0: dwmac@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + snps,mixed-burst; + dma-ranges; + }; + rng: rng@50060800 { compatible = "st,stm32-rng"; reg = <0x50060800 0x400>; -- 1.9.1
[PATCH 0/3] Enable Ethernet on STM32F429 EVAL board
This series adds Ethernet support on STM32F429 SOC and enable it on Eval board: -Add Ethernet node in SOC file: -Define MII mode pinctrl -use Mixed burst and PBL 8 -Add system config node for glue. -Enable Ethernet for Eval board: -mii mode -connected to a PHY through MDIO. Note, this series follow the series which adds glue and update stmmac driver: https://lkml.org/lkml/2016/2/26/329 Best regards. Alex Alexandre TORGUE (3): ARM: dts: stm32f429: Add system config bank node ARM: dts: stm32f429: Add Ethernet support ARM: dts: stm32f429: Enable Ethernet on Eval board arch/arm/boot/dts/stm32429i-eval.dts | 15 ++ arch/arm/boot/dts/stm32f429.dtsi | 40 2 files changed, 55 insertions(+) -- 1.9.1
Re: [PATCH 2/3] ARM: dts: stm32f429: Add Ethernet support
Hi Maxime, 2016-03-01 18:24 GMT+01:00 Maxime Coquelin : > Hi Alex, > > I have made a handful of changes on your patch, let me know if this is > ok for you. > If ok, it will be part of the PR I'll send tomorrow. I agree with modifications. Regards alex > > On 02/29/2016 05:29 PM, Alexandre TORGUE wrote: >> >> Add Ethernet support (Synopsys MAC IP 3.50a) on stm32f429 SOC. >> >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/arch/arm/boot/dts/stm32f429.dtsi >> b/arch/arm/boot/dts/stm32f429.dtsi >> index bb7a736..af0367c 100644 >> --- a/arch/arm/boot/dts/stm32f429.dtsi >> +++ b/arch/arm/boot/dts/stm32f429.dtsi >> @@ -283,6 +283,26 @@ >> bias-disable; >> }; >> }; >> + >> + ethernet0_mii: mii@0 { >> + mii { >> + slew-rate = <2>; > > I moved slew-rate property below the pinmux one for consistency with other > pin configs in the file. >> >> + pinmux = >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> , >> + >> ; >> + }; >> + }; >> }; >> rcc: rcc@40023810 { >> @@ -323,6 +343,21 @@ >> st,mem2mem; >> }; >> + ethernet0: dwmac@40028000 { >> + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; >> + status = "disabled"; > > I moved status property at the end of the node for consistency >> >> + reg = <0x40028000 0x8000>; >> + reg-names = "stmmaceth"; >> + interrupts = <0 61 0>, <0 62 0>; > > #interrupt-cells is set to 1 in the nvic node, meaning that a single cell is > expected here: > > interrupts = <61>, <62>; > >> + interrupt-names = "macirq", "eth_wake_irq"; >> + clock-names = "stmmaceth", "tx-clk", "rx-clk"; >> + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; >> + st,syscon = <&syscfg 0x4>; >> + snps,pbl = <8>; >> + snps,mixed-burst; >> + dma-ranges; >> + }; >> + >> rng: rng@50060800 { >> compatible = "st,stm32-rng"; >> reg = <0x50060800 0x400>; > > > Regards, > Maxime > >
Re: [PATCH v3 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Hi Rob, 2016-03-02 19:33 GMT+01:00 Rob Herring : > On Fri, Feb 26, 2016 at 11:51:50AM +0100, Alexandre TORGUE wrote: >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> new file mode 100644 >> index 000..67fceda >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> @@ -0,0 +1,40 @@ >> +STMicroelectronics STM32 / MCU DWMAC glue layer controller >> + >> +This file documents platform glue layer for stmmac. >> +Please see stmmac.txt for the other unchanged properties. >> + >> +The device node has following properties. >> + >> +Required properties: >> +- compatible: Should be "st,stm32-dwmac" to select glue, and >> +"snps,dwmac-3.50a" to select IP vesrion. >> +- clocks: Should contain the GMAC main clock, and tx clock >> +- compatible: Should be "st,stm32-dwmac" to select glue and >> +"snps,dwmac-3.50a" to select IP version. >> +- clocks: Should contain the MAC main clock >> +- clock-names: Should contain the clock names "stmmaceth". >> +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node >> which >> + encompases the glue register, and the offset of the control >> register. >> + >> +Optional properties: >> +- clocks: Could contain: >> + - the tx clock, >> + - the rx clock >> +- clock-names: Could contain the clock names "tx-clk", "rx-clk" > > Either the IP block has 3 clocks or it has 1. If you have a case where 1 > clock feeds all 3 inputs, then list the clock 3 times. I agree. I will move rx/tx clock to required properties and then send a v4. Regards. Alexandre > > Rob
Re: [PATCH] stmmac: fix noderef.cocci warnings
Hi, On 03/03/2016 02:55 AM, kbuild test robot wrote: drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c:115:15-21: ERROR: application of sizeof to pointer sizeof when applied to a pointer typed expression gives the size of the pointer Generated by: scripts/coccinelle/misc/noderef.cocci CC: Giuseppe Cavallaro Signed-off-by: Fengguang Wu --- stmmac_platform.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -112,7 +112,7 @@ static struct stmmac_axi *stmmac_axi_set if (!np) return NULL; - axi = kzalloc(sizeof(axi), GFP_KERNEL); + axi = kzalloc(sizeof(*axi), GFP_KERNEL); if (!axi) return ERR_PTR(-ENOMEM); Thanks. You can add my Acked-by: Alexandre Torgue -- Regards Alex
[PATCH v4 4/4] ARM: STM32: Enable Ethernet in stm32_defconfig
Enable basic Ethernet support (IPV4) for stm32 defconfig. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec52505..8b8abe0 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -33,11 +33,20 @@ CONFIG_XIP_PHYS_ADDR=0x08008000 CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_SHARED_FLAT=y # CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set # CONFIG_BLK_DEV is not set CONFIG_EEPROM_93CX6=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -- 1.9.1
[PATCH v4 3/4] net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP
Adds support of Synopsys 3.50a MAC IP in stmmac driver. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 6a52fa1..6cca626 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -178,6 +178,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || + of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the -- 1.9.1
[PATCH v4 0/4] Add Ethernet support on STM32F429
STM32F429 Chip embeds a Synopsys 3.50a MAC IP. This series: -enhance current stmmac driver to control it (code already available) and adds basic glue for STM32F429 chip. -Enable basic Net config in kernel. Note that DT patches are not present because STM32 pinctrl code is not yet avalaible. Changes since v3: -Fix "tx-clk" and "rx-clk" as required clocks. Driver and bindings are modified. Changes since v2: -Fix alphabetic order in Kconfig and Makefile. -Improve code according to Joachim review. -Binding: remove useless entry. Changes since v1: -Fix Kbuild issue in Kconfig. -Remove init/exit callbacks. Suspend/Resume and remove driver is no more driven in stmmac_pltfr but directly in dwmac-stm32 glue driver. -Take into account Joachim review. Regards. Alexandre. Alexandre TORGUE (4): net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Documentation: Bindings: Add STM32 DWMAC glue net: ethernet: stmmac: add support of Synopsys 3.50a MAC IP ARM: STM32: Enable Ethernet in stm32_defconfig .../devicetree/bindings/net/stm32-dwmac.txt| 35 arch/arm/configs/stm32_defconfig | 9 + drivers/net/ethernet/stmicro/stmmac/Kconfig| 12 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 193 + .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 6 files changed, 251 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -- 1.9.1
[PATCH v4 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Signed-off-by: Alexandre TORGUE diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt new file mode 100644 index 000..fd3566f --- /dev/null +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -0,0 +1,35 @@ +STMicroelectronics STM32 / MCU DWMAC glue layer controller + +This file documents platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +The device node has following properties. + +Required properties: +- compatible: Should be "st,stm32-dwmac" to select glue, and + "snps,dwmac-3.50a" to select IP vesrion. +- clocks: Should contain the GMAC main clock, and tx clock +- compatible: Should be "st,stm32-dwmac" to select glue and + "snps,dwmac-3.50a" to select IP version. +- clocks: Must contain an entry for each entry in clock-names. +- clock-names: Should be "stmmaceth" for the host clock. + Should be "tx-clk" for the MAC TX clock. + Should be "rx-clk" for the MAC RX clock. +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which + encompases the glue register, and the offset of the control register. +Example: + + ethernet0: dwmac@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + status = "disabled"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <0 61 0>, <0 62 0>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + snps,mixed-burst; + dma-ranges; + }; -- 1.9.1
[PATCH v4 1/4] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip
stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..235d679 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -104,6 +104,18 @@ config DWMAC_STI device driver. This driver is used on for the STi series SOCs GMAC ethernet controller. +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF && HAS_IOMEM + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. + config DWMAC_SUNXI tristate "Allwinner GMAC support" default ARCH_SUNXI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index b390161..5f7ff0a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA)+= dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI)+= dwmac-sti.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_GENERIC)+= dwmac-generic.o stmmac-platform-objs:= stmmac_platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 000..88c8573 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,193 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) +{ + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; + u32 reg = dwmac->mode_reg; + u32 val; + int ret; + + val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + clk_disable_unprepare(dwmac->clk_tx); + + return ret; +} + +static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) +{ + clk_disable_unprepare(dwmac->clk_tx); + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) +{ + struct device_node *np = dev->of_node; + int err; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "tx-clk"); + if (IS_ERR(dwmac->clk_tx)) { + dev_err(dev, "No tx clock provided...\n"); + return PTR_ERR(dwmac->clk_tx); + } + dwmac->clk_rx = devm_clk_get(dev, "rx-clk"); + if (IS_ERR(dwmac->clk_rx)) { + dev_err(dev, "No rx clock provided...\n"); + return PTR_ERR(dwmac->clk_rx); + } + + /* Get mode register */ + dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(dwmac->regmap)) + return PTR_ERR(dwmac->regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) + dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); + + return err; +} + +static int stm32_dwmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct stm32_dwmac *dwmac; + int ret; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return ret; + + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); + if (IS_ERR(plat_
Re: [PATCH v4 2/4] Documentation: Bindings: Add STM32 DWMAC glue
Hi Rob, 2016-03-05 5:31 GMT+01:00 Rob Herring : > On Fri, Mar 04, 2016 at 04:58:04PM +0100, Alexandre TORGUE wrote: >> Signed-off-by: Alexandre TORGUE >> >> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> new file mode 100644 >> index 000..fd3566f >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt >> @@ -0,0 +1,35 @@ >> +STMicroelectronics STM32 / MCU DWMAC glue layer controller >> + >> +This file documents platform glue layer for stmmac. >> +Please see stmmac.txt for the other unchanged properties. >> + >> +The device node has following properties. >> + >> +Required properties: > >> +- compatible: Should be "st,stm32-dwmac" to select glue, and >> +"snps,dwmac-3.50a" to select IP vesrion. >> +- clocks: Should contain the GMAC main clock, and tx clock > >> +- compatible: Should be "st,stm32-dwmac" to select glue and >> +"snps,dwmac-3.50a" to select IP version. >> +- clocks: Must contain an entry for each entry in clock-names. > > ??? Shame on me, it is a stupid copy/paste issue. For clocks, final description could be: clocks: Must contain an entry for each entry in clock-names. clock-names: Should be "stmmaceth" for the host clock. Should be "tx-clk" for the MAC TX clock. Should be "rx-clk" for the MAC RX clock. Does it seem good for you ? Regards. Alex > >> +- clock-names: Should be "stmmaceth" for the host clock. >> +Should be "tx-clk" for the MAC TX clock. >> +Should be "rx-clk" for the MAC RX clock. >> +- st,syscon : Should be phandle/offset pair. The phandle to the syscon node >> which >> + encompases the glue register, and the offset of the control >> register. >> +Example: >> + >> + ethernet0: dwmac@40028000 { >> + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; >> + status = "disabled"; >> + reg = <0x40028000 0x8000>; >> + reg-names = "stmmaceth"; >> + interrupts = <0 61 0>, <0 62 0>; >> + interrupt-names = "macirq", "eth_wake_irq"; >> + clock-names = "stmmaceth", "tx-clk", "rx-clk"; >> + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; >> + st,syscon = <&syscfg 0x4>; >> + snps,pbl = <8>; >> + snps,mixed-burst; >> + dma-ranges; >> + }; >> -- >> 1.9.1 >>
[PATCH v6 5/6] ARM: dts: stm32f429: Align Ethernet node with new bindings properties
This patch aligns clocks names and node reference according to new stm32-dwmac glue binding. It also renames Ethernet pinctrl phandle (indeed there is no need to add 0 as Ethernet instance as there is only one IP in SOC). Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index 35df462..5995998 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -304,7 +304,7 @@ }; }; - ethernet0_mii: mii@0 { + ethernet_mii: mii@0 { pins { pinmux = , , @@ -363,13 +363,13 @@ st,mem2mem; }; - ethernet0: dwmac@40028000 { + mac: ethernet@40028000 { compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; reg = <0x40028000 0x8000>; reg-names = "stmmaceth"; interrupts = <61>, <62>; interrupt-names = "macirq", "eth_wake_irq"; - clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx"; clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; st,syscon = <&syscfg 0x4>; snps,pbl = <8>; -- 1.9.1
[PATCH v6 6/6] ARM: dts: stm32f429: Update Ethernet node on Eval board
Update new pinctrl phandle name and use new node name. Signed-off-by: Alexandre TORGUE diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 6bfc595..9a72445 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -94,9 +94,9 @@ clock-frequency = <2500>; }; -ðernet0 { +&mac { status = "okay"; - pinctrl-0 = <ðernet0_mii>; + pinctrl-0 = <ðernet_mii>; pinctrl-names = "default"; phy-mode= "mii-id"; mdio0 { -- 1.9.1