RE: [PATCH] net: dsa: Fix OF fallback lookup for ports
> -Original Message- > From: Marcus Comstedt > Sent: Monday, May 15, 2023 6:44 PM > To: u-boot@lists.denx.de > Cc: Marcus Comstedt ; Claudiu Manoil > ; Joe Hershberger ; > Ramon Fried > Subject: [PATCH] net: dsa: Fix OF fallback lookup for ports > > The variable 'node' was already invalid, so using it for further lookup will > not > work. > > Signed-off-by: Marcus Comstedt Fixes: fc054d563b (net: Introduce DSA class for Ethernet switches) Reviewed-by: Claudiu Manoil Thanks. Funny the issue was caught so late. Apparently the newer 'ethernet-ports' term had a slow adoption.
RE: [PATCH v4 2/7] net: phy: introduce fixed_phy_create for DSA CPU ports
>-Original Message- >From: Vladimir Oltean >Sent: Monday, January 25, 2021 2:24 PM >To: Tom Rini ; Joe Hershberger >; Simon Glass ; Bin Meng >; u-boot@lists.denx.de >Cc: Michael Walle ; Alexandru Marginean >; Claudiu Manoil > >Subject: [PATCH v4 2/7] net: phy: introduce fixed_phy_create for DSA CPU >ports > >From: Vladimir Oltean > >The DSA (Distributed Switch Architecture) implementation has made a >design decision when it got introduced to the Linux kernel in 2008. >That was to hide away from the user the CPU-facing Ethernet MAC, since >it does not make sense to register it as a struct net_device (UCLASS_ETH >udevice for U-Boot), because that would never be beneficial for a user: >they would not be able to use it for traffic, since conceptually, a >packet delivered to the CPU port should loop back into the system. > >Nonetheless, DSA has had numerous growing pains due to the lack of a >struct net_device for the CPU port, but so far it has overcome them. >It is unlikely at this stage of maturity that this aspect of it will >change. > >We would like U-Boot to present the same information as Linux, to be at >parity in terms of number of interfaces, so that ethNaddr environment >variables could directly be associated between U-Boot and Linux. >Therefore, we would implicitly like U-Boot to hide the CPU port from the >user as well. > >But the paradox is that DSA still needs a struct phy_device to inform >the driver of the parameters of the link that it should configure the >CPU port to. The problem is that the phy_device is typically returned >via a call to phy_connect, which needs an udevice to attach the PHY to, >and to search its ofnode for the 'fixed-link' property. But we don't >have an udevice to present for the CPU port. > >Since 99% of DSA setups are MAC-to-MAC connections between the switch >and the host Ethernet controller, the struct phy_device is going to be a >fixed PHY. This simplifies things quite a bit. In U-Boot, a fixed PHY >does not need an MDIO bus, and does not need an attached dev either. >Basically, the phy_connect call doesn't do any connection, it just >creates the fixed PHY. > >The proposal of this patch is to introduce a new fixed_phy_create >function which will take a single argument: the ofnode that holds this: > > port@4 { > reg = <4>; > phy-mode = "internal"; > > fixed-link { > speed = <2500>; > full-duplex; > }; > }; > >and probe a fixed PHY driver using the information from this ofnode. >DSA will probably be the only user of this function. > >Signed-off-by: Vladimir Oltean Reviewed-by: Claudiu Manoil
RE: [PATCH v4 1/7] net: phy: fixed: support speeds of 2500 and 10000
>-Original Message- >From: Vladimir Oltean >Sent: Monday, January 25, 2021 2:24 PM >To: Tom Rini ; Joe Hershberger >; Simon Glass ; Bin Meng >; u-boot@lists.denx.de >Cc: Michael Walle ; Alexandru Marginean >; Claudiu Manoil > >Subject: [PATCH v4 1/7] net: phy: fixed: support speeds of 2500 and 1 > >From: Vladimir Oltean > >Unlike the Linux fixed PHY driver, the one in U-Boot does not attempt to >emulate the clause 22 register set of a gigabit copper PHY driver >through the swphy framework. Therefore, the limitation of being unable >to support speeds higher than gigabit in fixed-link does not apply to >the U-Boot fixed PHY driver. This makes the fixed-link U-Boot >implementation more similar to the one from phylink, which can work with >any valid link speed. > >Signed-off-by: Vladimir Oltean Reviewed-by: Claudiu Manoil
RE: [PATCH v2 3/5] drivers: net: Add Felix DSA switch driver
>-Original Message- >From: Michael Walle >Sent: Wednesday, January 20, 2021 12:44 AM >To: Claudiu Manoil >Cc: Joe Hershberger ; Simon Glass >; Bin Meng ; u- >b...@lists.denx.de; Vladimir Oltean ; Alexandru >Marginean >Subject: Re: [PATCH v2 3/5] drivers: net: Add Felix DSA switch driver > [...] >> + >> +dsa_foreach_port(pdev, dev) { > >This doesn't work for me. Seems like felix_init() is called before >any ports are added via dsa_port_probe(). > Indeed, looks like we need to extend dsa_ops with a per-port initialization callback (i.e. .port_init()). The general idea of the current dsa API is not to expose all the internal state data inside the dsa per-device uclass platform data, particularly udevice pointers have no place inside platform data structures (like was the case for the previous patch sets). So these per port felix initializations need to be addressed by extending the current API. Thanks.
[PATCH v2 4/5] arm: dts: ls1028a: Add Ethernet switch node and dependencies
From: Alex Marginean The definition follows the DSA binding in kernel and describes the switch, its ports and PHYs. The switch node has the same structure as in Linux and this patch enables it (and relevant ports) for the LS1028A RDB board. ENETC PF6 is the 2nd Eth controller linked to the switch on LS1028A, it is not used in U-Boot and was disabled. Ethernet port aliases were also added to better manage the multitude of ports available now. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- v2: Switch node structure defined in dtsi now consistent with the Linux switch node definition. Moved aliases from dtsi to the RDB DTS to minimize impact on other boards (and for improved flexibility). arch/arm/dts/fsl-ls1028a-rdb.dts | 63 arch/arm/dts/fsl-ls1028a.dtsi| 56 +++- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/fsl-ls1028a-rdb.dts b/arch/arm/dts/fsl-ls1028a-rdb.dts index 85b4815b2e..dd35643efc 100644 --- a/arch/arm/dts/fsl-ls1028a-rdb.dts +++ b/arch/arm/dts/fsl-ls1028a-rdb.dts @@ -15,6 +15,12 @@ compatible = "fsl,ls1028a-rdb", "fsl,ls1028a"; aliases { spi0 = + eth0 = + eth1 = + eth2 = _felix_port0; + eth3 = _felix_port1; + eth4 = _felix_port2; + eth5 = _felix_port3; }; }; @@ -131,9 +137,66 @@ phy-handle = <_phy0>; }; + { + status = "okay"; +}; + +_felix { + status = "okay"; +}; + +_felix_port0 { + label = "swp0"; + phy-handle = <_phy0>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +_felix_port1 { + label = "swp1"; + phy-handle = <_phy1>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +_felix_port2 { + label = "swp2"; + phy-handle = <_phy2>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +_felix_port3 { + label = "swp3"; + phy-handle = <_phy3>; + phy-mode = "qsgmii"; + status = "okay"; +}; + +_felix_port4 { + ethernet = <>; + status = "okay"; +}; + { status = "okay"; rdb_phy0: phy@2 { reg = <2>; }; + + sw_phy0: phy@10 { + reg = <0x10>; + }; + + sw_phy1: phy@11 { + reg = <0x11>; + }; + + sw_phy2: phy@12 { + reg = <0x12>; + }; + + sw_phy3: phy@13 { + reg = <0x13>; + }; }; diff --git a/arch/arm/dts/fsl-ls1028a.dtsi b/arch/arm/dts/fsl-ls1028a.dtsi index d0850237c7..9740006689 100644 --- a/arch/arm/dts/fsl-ls1028a.dtsi +++ b/arch/arm/dts/fsl-ls1028a.dtsi @@ -151,9 +151,63 @@ reg = <0x000300 0 0 0 0>; status = "disabled"; }; + + mscc_felix: pci@0,5 { + reg = <0x000500 0 0 0 0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mscc_felix_port0: port@0 { + reg = <0>; + status = "disabled"; + }; + + mscc_felix_port1: port@1 { + reg = <1>; + status = "disabled"; + }; + + mscc_felix_port2: port@2 { + reg = <2>; + status = "disabled"; + }; + + mscc_felix_port3: port@3 { + reg = <3>; + status = "disabled"; + }; + + mscc_felix_port4: port@4 { + reg = <4>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <2500>; + full-duplex; + }; + }; + +
[PATCH v2 3/5] drivers: net: Add Felix DSA switch driver
From: Alex Marginean This driver is used for the Ethernet switch integrated into LS1028A NXP. Felix on LS1028A has 4 front panel ports and two internal ports, I/O to/from the switch is done through an ENETC Ethernet interface. The 4 front panel ports are available as Ethernet interfaces and can be used with the typical network commands like tftp. Signed-off-by: Alex Marginean Signed-off-by: Vladimir Oltean Signed-off-by: Claudiu Manoil --- v2: none drivers/net/fsl_enetc.h | 5 + drivers/net/mscc_eswitch/Kconfig| 8 + drivers/net/mscc_eswitch/Makefile | 1 + drivers/net/mscc_eswitch/felix_switch.c | 432 4 files changed, 446 insertions(+) create mode 100644 drivers/net/mscc_eswitch/felix_switch.c diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h index 37e7e85843..110c1d78fb 100644 --- a/drivers/net/fsl_enetc.h +++ b/drivers/net/fsl_enetc.h @@ -201,6 +201,11 @@ struct enetc_priv { /* PCS replicator block for USXGMII */ #define ENETC_PCS_DEVAD_REPL 0x1f +#define ENETC_PCS_REPL_LINK_TIMER_10x12 +#define ENETC_PCS_REPL_LINK_TIMER_1_DEF 0x0003 +#define ENETC_PCS_REPL_LINK_TIMER_20x13 +#define ENETC_PCS_REPL_LINK_TIMER_2_DEF 0x06a0 + /* ENETC external MDIO registers */ #define ENETC_MDIO_BASE0x1c00 #define ENETC_MDIO_CFG 0x00 diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig index 80dd22f98b..11fb08edaa 100644 --- a/drivers/net/mscc_eswitch/Kconfig +++ b/drivers/net/mscc_eswitch/Kconfig @@ -36,3 +36,11 @@ config MSCC_SERVAL_SWITCH select PHYLIB help This driver supports the Serval network switch device. + +config MSCC_FELIX_SWITCH + bool "Felix switch driver" + depends on DM_DSA && DM_PCI + select FSL_ENETC + help + This driver supports the Ethernet switch integrated in LS1028A NXP + SoC. diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile index d583fe9fc4..22342ed114 100644 --- a/drivers/net/mscc_eswitch/Makefile +++ b/drivers/net/mscc_eswitch/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o m obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o mscc_miim.o obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o mscc_miim.o obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o +obj-$(CONFIG_MSCC_FELIX_SWITCH) += felix_switch.o diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c new file mode 100644 index 00..ae8b690e76 --- /dev/null +++ b/drivers/net/mscc_eswitch/felix_switch.c @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Felix Ethernet switch driver + * Copyright 2018-2021 NXP + */ + +/* + * This driver is used for the Ethernet switch integrated into LS1028A NXP. + * Felix switch is derived from Microsemi Ocelot but there are several NXP + * adaptations that makes the two U-Boot drivers largely incompatible. + * + * Felix on LS1028A has 4 front panel ports and two internal ports, connected + * to ENETC interfaces. We're using one of the ENETC interfaces to push traffic + * into the switch. Injection/extraction headers are used to identify + * egress/ingress ports in the switch for Tx/Rx. + */ + +#include +#include +#include +#include +#include +#include + +/* defines especially around PCS are reused from enetc */ +#include "../fsl_enetc.h" + +#define PCI_DEVICE_ID_FELIX_ETHSW 0xEEF0 + +/* Felix has in fact 6 ports, but we don't use the last internal one */ +#define FELIX_PORT_COUNT 5 +/* Front panel port mask */ +#define FELIX_FP_PORT_MASK 0xf + +/* Register map for BAR4 */ +#define FELIX_SYS 0x01 +#define FELIX_ES0 0x04 +#define FELIX_IS1 0x05 +#define FELIX_IS2 0x06 +#define FELIX_GMII(port) (0x10 + (port) * 0x1) +#define FELIX_QSYS 0x20 + +#define FELIX_SYS_SYSTEM (FELIX_SYS + 0x0E00) +#define FELIX_SYS_SYSTEM_EN BIT(0) +#define FELIX_SYS_RAM_CTRL (FELIX_SYS + 0x0F24) +#define FELIX_SYS_RAM_CTRL_INIT BIT(1) +#define FELIX_SYS_SYSTEM_PORT_MODE(a) (FELIX_SYS_SYSTEM + 0xC + (a) * 4) +#define FELIX_SYS_SYSTEM_PORT_MODE_CPU0x001e + +#define FELIX_ES0_TCAM_CTRL(FELIX_ES0 + 0x03C0) +#define FELIX_ES0_TCAM_CTRL_ENBIT(0) +#define FELIX_IS1_TCAM_CTRL(FELIX_IS1 + 0x03C0) +#define FELIX_IS1_TCAM_CTRL_ENBIT(0) +#define FELIX_IS2_TCAM_CTRL(FELIX_IS2 + 0x03C0) +#define FELIX_IS2_TCAM_CTRL_ENBIT(0) + +#define FELIX_GMII_CLOCK_CFG(port) (FELIX_GMII(port) + 0x) +#define
[PATCH v2 5/5] configs: ls1028a: Enable the Ethernet switch driver in defconfig
From: Alex Marginean The switch driver for LS1028A Ethernet switch is now compiled in for both LS1028A boards. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- v2: none configs/ls1028aqds_tfa_SECURE_BOOT_defconfig | 2 ++ configs/ls1028aqds_tfa_defconfig | 2 ++ configs/ls1028ardb_tfa_SECURE_BOOT_defconfig | 2 ++ configs/ls1028ardb_tfa_defconfig | 2 ++ 4 files changed, 8 insertions(+) diff --git a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig index 14c49cd0d6..43ddcf9166 100644 --- a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig @@ -61,6 +61,8 @@ CONFIG_DM_MDIO_MUX=y CONFIG_E1000=y CONFIG_FSL_ENETC=y CONFIG_MDIO_MUX_I2CREG=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/ls1028aqds_tfa_defconfig b/configs/ls1028aqds_tfa_defconfig index 09a6923708..c790e99485 100644 --- a/configs/ls1028aqds_tfa_defconfig +++ b/configs/ls1028aqds_tfa_defconfig @@ -67,6 +67,8 @@ CONFIG_DM_MDIO_MUX=y CONFIG_E1000=y CONFIG_FSL_ENETC=y CONFIG_MDIO_MUX_I2CREG=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig index b034580aef..8b9e217c61 100644 --- a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig @@ -58,6 +58,8 @@ CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_E1000=y CONFIG_FSL_ENETC=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/ls1028ardb_tfa_defconfig b/configs/ls1028ardb_tfa_defconfig index 4bed352420..aa82719e5e 100644 --- a/configs/ls1028ardb_tfa_defconfig +++ b/configs/ls1028ardb_tfa_defconfig @@ -64,6 +64,8 @@ CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_E1000=y CONFIG_FSL_ENETC=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y -- 2.17.1
[PATCH v2 1/5] net: Introduce DSA class for Ethernet switches
DSA stands for Distributed Switch Architecture and it covers switches that are connected to the CPU through an Ethernet link and generally use frame tags to pass information about the source/destination ports to/from CPU. Front panel ports are presented as regular ethernet devices in U-Boot and they are expected to support the typical networking commands. DSA switches may be cascaded, DSA class code does not currently support this. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil Reviewed-by: Simon Glass --- v2: none drivers/net/Kconfig| 14 ++ include/dm/uclass-id.h | 1 + include/net.h | 6 + include/net/dsa.h | 206 net/Makefile | 1 + net/dsa-uclass.c | 517 + 6 files changed, 745 insertions(+) create mode 100644 include/net/dsa.h create mode 100644 net/dsa-uclass.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3a5e036880..382224d04c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -37,6 +37,20 @@ config DM_MDIO_MUX This is currently implemented in net/mdio-mux-uclass.c Look in include/miiphy.h for details. +config DM_DSA + bool "Enable Driver Model for DSA switches" + depends on DM_ETH && DM_MDIO + help + Enable driver model for DSA switches + + Adds UCLASS_DSA class supporting switches that follow the Distributed + Switch Architecture (DSA). These switches rely on the presence of a + management switch port connected to an Ethernet controller capable of + receiving frames from the switch. This host Ethernet controller is + called the "master" Ethernet interface in DSA terminology. + This is currently implemented in net/dsa-uclass.c, refer to + include/net/dsa.h for API details. + config MDIO_SANDBOX depends on DM_MDIO && SANDBOX default y diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index ae4425d7a5..d75de368c5 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -46,6 +46,7 @@ enum uclass_id { UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ UCLASS_DSI_HOST,/* Display Serial Interface host */ UCLASS_DMA, /* Direct Memory Access */ + UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */ UCLASS_EFI, /* EFI managed devices */ UCLASS_ETH, /* Ethernet device */ UCLASS_ETH_PHY, /* Ethernet PHY device */ diff --git a/include/net.h b/include/net.h index 13da69b7c1..b95d6a6f60 100644 --- a/include/net.h +++ b/include/net.h @@ -499,7 +499,13 @@ struct icmp_hdr { * maximum packet size and multiple of 32 bytes = 1536 */ #define PKTSIZE1522 +#ifndef CONFIG_DM_DSA #define PKTSIZE_ALIGN 1536 +#else +/* Maximum DSA tagging overhead (headroom and/or tailroom) */ +#define DSA_MAX_OVR256 +#define PKTSIZE_ALIGN (1536 + DSA_MAX_OVR) +#endif /* * Maximum receive ring size; that is, the number of packets diff --git a/include/net/dsa.h b/include/net/dsa.h new file mode 100644 index 00..a2bf4851df --- /dev/null +++ b/include/net/dsa.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019-2021 NXP + */ + +#ifndef __DSA_H__ +#define __DSA_H__ + +#include +#include + +/** + * DSA stands for Distributed Switch Architecture and it is infrastructure + * intended to support drivers for Switches that rely on an intermediary + * Ethernet device for I/O. These switches may support cascading allowing + * them to be arranged as a tree. + * DSA is documented in detail in the Linux kernel documentation under + * Documentation/networking/dsa/dsa.txt + * The network layout of such a switch is shown below: + * + * |--| + * | eth0 | <--- master eth device (regular eth driver) + * |--| + * ^ | + * tag added by switch -->| | + * | | + * | |<-- tag added by DSA driver + * | v + * |--| + * | | CPU port | | <-- DSA (switch) device + * | | (DSA driver) + * | _ _ _ | + * | | port0 | | port1 | ... | portn | | <-- ports as eth devices + * |-+---+--+---+---+---+-| ('dsa-port' eth driver) + * + * In U-Boot the intent is to allow access to front panel ports (shown at the + * bottom of the picture) through the master Ethernet dev (eth0 in the picture). + * Front panel ports are presented as regular Ethernet devices in U-Boot and + * they are expected to support the typical networking commands. + * In general DSA switches require the us
[PATCH v2 2/5] sandbox: Add a DSA sandbox driver and unit test
The DSA sandbox driver is used for unit testing the DSA class code. It implements a simple 2 port switch plus 1 CPU port, and uses a very simple tag to identify the ports. The DSA sandbox device is connected via CPU port to a regular Ethernet sandbox device, called 'dsa-test-eth, managed by the existing eth sandbox driver. The 'dsa-test-eth' is not intended for testing the eth class code however, but it is used to emulate traffic through the 'lan0' and 'lan1' front pannel switch ports. To achieve this the dsa sandbox driver registers a tx handler for the 'dsa-test-eth' device. The switch ports, labeled as 'lan0' and 'lan1', are also registered as eth devices by the dsa class code this time. So pinging through these switch ports is as easy as: => setenv ethact lan0 => ping 1.2.3.5 Unit tests for the dsa class code were also added. The 'dsa_probe' test exercises most API functions from dsa.h. The 'dsa' unit test simply exercises ARP/ICMP traffic through the two switch ports, including tag injection and extraction, with the help of the dsa sandbox driver. I took care to minimize the impact on the existing eth unit tests, though some adjustments needed to be made with the addition of extra eth interfaces used by the dsa unit tests. The additional eth interfaces also require MAC addresses, these have been added to the sandbox default environment. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil Reviewed-by: Simon Glass --- v2: none arch/Kconfig | 1 + arch/sandbox/dts/test.dts | 40 + drivers/net/Kconfig | 9 ++ drivers/net/Makefile | 1 + drivers/net/dsa_sandbox.c | 181 ++ include/configs/sandbox.h | 2 + test/dm/Makefile | 1 + test/dm/dsa.c | 91 +++ test/dm/eth.c | 10 +-- 9 files changed, 331 insertions(+), 5 deletions(-) create mode 100644 drivers/net/dsa_sandbox.c create mode 100644 test/dm/dsa.c diff --git a/arch/Kconfig b/arch/Kconfig index 27843cd79c..8a8130f0c8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -160,6 +160,7 @@ config SANDBOX imply CMD_CLONE imply SILENT_CONSOLE imply BOOTARGS_SUBST + imply DM_DSA config SH bool "SuperH architecture" diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index f86cd0d3b2..e5a5f8ff76 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -14,7 +14,9 @@ aliases { console = eth0 = "/eth@10002000"; + eth2 = _0; eth3 = _3; + eth4 = _eth0; eth5 = _5; gpio1 = _a; gpio2 = _b; @@ -422,6 +424,44 @@ fake-host-hwaddr = [00 00 66 44 22 22]; }; + dsa_eth0: dsa-test-eth { + compatible = "sandbox,eth"; + reg = <0x10006000 0x1000>; + fake-host-hwaddr = [00 00 66 44 22 66]; + }; + + dsa-test { + compatible = "sandbox,dsa"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + swp_0: port@0 { + reg = <0>; + label = "lan0"; + }; + + swp_1: port@1 { + reg = <1>; + label = "lan1"; + phy-mode = "rgmii-txid"; + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + port@2 { + reg = <2>; + ethernet = <_eth0>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + firmware { sandbox_firmware: sandbox-firmware { compatible = "sandbox,firmware"; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 382224d04c..214aebf14a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -77,6 +77,15 @@ config DM_ETH_PHY help Enable driver model for Ethernet Generic PHY . +config DSA_SANDBOX + depends on DM_DSA && SANDBOX + default y + bool "Sandbox: Mocked DSA driver" + help + This driver implements a dummy DSA switch connected to a dummy sandbox + Ethernet device used as DSA master, to test DSA class code, including + exported DSA API and datapath pro
[PATCH v2 0/5] Introduce DSA Ethernet switch class and Felix driver
DSA stands for Distributed Switch Architecture and it is a subsystem introduced in the Linux kernel to support switches that: - have an Ethernet link up to the CPU - use some form of tagging to identify the source/destination port for Rx/Tx - may be cascaded in tree-like structures. DSA is described in depth here: https://www.kernel.org/doc/Documentation/networking/dsa/dsa.txt This patch set introduces a DSA class in U-Boot to support drivers of DSA switches. DSA drivers have to implement the following ops: - enable/disable of switch ports, - insert a tag in frames being transmitted, used by the switch to select the egress port, - parse a tag in frames being received, used for Rx traffic. DSA class code deals with presentation of switch ports as Ethernet interfaces, deals with the master Ethernet device for I/O and helps with parsing of the DT assuming the structure follows the DSA kernel binding. Support for switch cascading is not included yet. In the sandbox environment, the DSA sandbox driver, the switch ports and master eth interface look like this: => dm tree Class Index Probed DriverName --- [...] eth 4 [ + ] eth_sandbox |-- dsa-test-eth dsa 0 [ + ] dsa_sandbox |-- dsa-test eth 5 [ + ] dsa-port | |-- lan0 eth 6 [ + ] dsa-port | `-- lan1 => setenv ethact lan1 => ping 1.2.3.5 Using lan1 device host 1.2.3.5 is alive => This patch set also introduces a driver for the Ethernet switch integrated into NXP LS1028A, called Felix. The switch has 4 front panel ports, I/O to/from it is done though an ENETC Ethernet interface and meta-data is carried between the switch and the driver though an additional header pre-pended to the original frame. Network commands like tftp can be used on these front panel ports. The ports are disabled unless used so they do not cause issues on network topologies that include loops. Felix as seen on LS1028A RDB: => dm tree Class Index Probed DriverName --- [...] dsa 0 [ + ] felix-switch | |-- felix-switch eth 4 [ + ] dsa-port | | |-- swp0 eth 5 [ + ] dsa-port | | |-- swp1 eth 6 [ + ] dsa-port | | |-- swp2 eth 7 [ + ] dsa-port | | `-- swp3 => mdio list [...] 10 - Vitesse VSC8514 <--> swp0 11 - Vitesse VSC8514 <--> swp1 12 - Vitesse VSC8514 <--> swp2 13 - Vitesse VSC8514 <--> swp3 NOTE: This patchset is a major rework of the dsa-class code since the last submission from May 5th: https://patchwork.ozlabs.org/project/uboot/cover/1588700588-8587-1-git-send-email-claudiu.man...@nxp.com/ The basic concepts and data path operation (tagging) in the DSA class code remain the same as in the initial patchset from Alex, however the external API has been changed significantly (simplified), the driver model integration has been improved to the point that the DSA class code no longer needs to allocate extra memory internally (via malloc), reduced memory footprint, internal state data moved from the external API and internalized, cleaner external API, internal code reworked, completely reworked DSA sandbox driver and unit tests for better coverage and to integrate better with the eth sandbox driver and tests, etc. The DSA class code is now ported on top of the latest u-boot master branch (obviously), and I tested it thoroughly with the sandbox driver and unit tests. The felix driver has been tested with an older uboot, since there are some issues booting the latest upstream uboot on a LS1028A RDB board. Note that the felix driver itself didn't change since the last submission, except for the DSA API function calls. v2: Switch node structure defined in dtsi now consistent with the Linux switch node definition. Moved aliases from dtsi to the RDB dts to minimize impact on other boards (and for improved flexibility). Alex Marginean (3): drivers: net: Add Felix DSA switch driver arm: dts: ls1028a: Add Ethernet switch node and dependencies configs: ls1028a: Enable the Ethernet switch driver in defconfig Claudiu Manoil (2): net: Introduce DSA class for Ethernet switches sandbox: Add a DSA sandbox driver and unit test arch/Kconfig | 1 + arch/arm/dts/fsl-ls1028a-rdb.dts | 63 +++ arch/arm/dts/fsl-ls1028a.dtsi| 56 +- arch/sandbox/dts/test.dts| 40 ++ configs/ls1028aqds_tfa_SECURE_BOOT_defconfig | 2 + configs/ls1028aqds_tfa_defconfig | 2 + configs/ls1028ardb_tfa_SECURE_BOOT_defconfig | 2 + configs/ls1028ardb_tfa_defconfig | 2 + drivers/net/Kconfig | 23 + drivers/net/Makefile
RE: [PATCH 4/5] arm: dts: ls1028a: Add Ethernet switch node and dependencies
>-Original Message- >From: Michael Walle >Sent: Thursday, January 14, 2021 5:40 PM >To: Claudiu Manoil >Cc: Joe Hershberger ; Simon Glass >; Bin Meng ; u- >b...@lists.denx.de; Vladimir Oltean ; Alexandru >Marginean >Subject: Re: [PATCH 4/5] arm: dts: ls1028a: Add Ethernet switch node and >dependencies > >Hi Claudiu, > >Am 2021-01-14 16:20, schrieb Claudiu Manoil: >>> -Original Message- >>> From: Michael Walle >>> Sent: Wednesday, January 13, 2021 10:11 PM >> [...] >>>> --- a/arch/arm/dts/fsl-ls1028a.dtsi >>>> +++ b/arch/arm/dts/fsl-ls1028a.dtsi >>>> @@ -14,6 +14,17 @@ >>>>#address-cells = <2>; >>>>#size-cells = <2>; >>>> >>>> + aliases { >>>> + eth0 = >>>> + eth1 = >>>> + eth2 = >>>> + eth3 = >>>> + eth4 = >>>> + eth5 = >>>> + eth6 = >>>> + eth7 = >>>> + }; >>> >>> Don't include the aliases in the common dtsi. There are serveral >>> reasons for that: >>> (1) it is really board dependent. not every board has all these >>> ports. >>> (2) it will mess up the device numbering for boards which use >>> this dtsi. And with this it will also mess up the ethNaddr >>> environment variable logic. >>> >>> Please move them into the corresponding boards. >>> >> I think the point of this patch was to enable the felix switch for the >> LS1028A RDB only for now, >> for simplicity, to make the patch set smaller. Follow-up patches would >> enable it for the remaining >> boards. >> But I understand that keeping the aliases in the fsl-ls1028a.dtsi can >> mess up other boards >> that include it, including the Kontron boards. Would you agree to >> update only the ls1028 RDB >> board DT for now? > >Sure, once accepted, I'll post a follow-up for our board. > >> Alternatively you could test these patches on your boards and maybe >> provide the DT updates for >> the Kontron boards as part of this patch set. > >I'm going to test this anyways and add a Tested-by to this set, once it >tested successfully. > >At the moment the only board variant which this would apply to is not >upstream yet. Patches are pending. But sure, if it will be in upstream >you could pick it up for this set. > >>>> + >>>>sysclk: sysclk { >>>>compatible = "fixed-clock"; >>>>#clock-cells = <0>; >>>> @@ -151,9 +162,51 @@ >>>>reg = <0x000300 0 0 0 0>; >>>>status = "disabled"; >>>>}; >>>> + ethsw: pci@0,5 { >>>> + #address-cells=<0>; >>>> + #size-cells=<1>; >>>> + reg = <0x000500 0 0 0 0>; > >This should also have > status = "disabled" > >>>> + >>>> + ethsw_ports: ports { >>>> + #address-cells = <1>; >>>> + #size-cells = <0>; >>>> + >>>> + felix0: port@0 { >>>> + reg = <0>; >>>> + status = "disabled"; >>>> + label = "swp0"; >>>> + }; >>>> + felix1: port@1 { >>>> + reg = <1>; >>>> + status = "disabled"; >>>> + label = "swp1"; >>>> + }; >>>> + felix2: port@2 { >>>> + reg = <2>; >>>> + status = "disabled"; >>>> + label = "swp2"; >>>> + }; >>>> + felix3: port@3 { >>>> + reg = <3>; >>>> + status = "disabled"; >>>> + label = "swp3"; >>>> + }; >>&
RE: [PATCH 1/5] net: Introduce DSA class for Ethernet switches
>-Original Message- >From: Simon Glass >Sent: Thursday, January 14, 2021 5:42 PM >To: Claudiu Manoil >Cc: Joe Hershberger ; Bin Meng >; Michael Walle ; U-Boot Mailing >List ; Vladimir Oltean ; >Alexandru Marginean >Subject: Re: [PATCH 1/5] net: Introduce DSA class for Ethernet switches > [...] > >Reviewed-by: Simon Glass > >I don't think it is necessary to have the 'if (!pdev)' checks around >the place. We need a way in U-Boot to have checks like that to catch >programming errors but to be able to turn them off in production code >to reduce size. > >I suppose a Kconfig would do it, with: > >if (CONFIG_IS_ENABLED(SAFETY) && !pdev) >return log_,msg_ref("safety", -ENODEV) > >Also note that -ENODEV is used by drive rmodel so it generally isn't >safe to return it as a logic error. I think in this case because it >never happens, it should be OK. > Thanks for the review, Simon. I thought about using assert(pdev) checks, but during development the simple "if (!pdev)..." proved more friendly. I like your idea about enabling the checks at compile time and disabling them in production. For now, since this SAFETY flag is not implemented, my understanding is that you’re ok with leaving the pdev checks in the code as they are right now and sometime in the future these will be converted to the "SAFETY" construct you mention.
RE: [PATCH 4/5] arm: dts: ls1028a: Add Ethernet switch node and dependencies
>-Original Message- >From: Michael Walle >Sent: Wednesday, January 13, 2021 10:11 PM [...] >> --- a/arch/arm/dts/fsl-ls1028a.dtsi >> +++ b/arch/arm/dts/fsl-ls1028a.dtsi >> @@ -14,6 +14,17 @@ >> #address-cells = <2>; >> #size-cells = <2>; >> >> +aliases { >> +eth0 = >> +eth1 = >> +eth2 = >> +eth3 = >> +eth4 = >> +eth5 = >> +eth6 = >> +eth7 = >> +}; > >Don't include the aliases in the common dtsi. There are serveral >reasons for that: > (1) it is really board dependent. not every board has all these > ports. > (2) it will mess up the device numbering for boards which use > this dtsi. And with this it will also mess up the ethNaddr > environment variable logic. > >Please move them into the corresponding boards. > Hi Michael, I think the point of this patch was to enable the felix switch for the LS1028A RDB only for now, for simplicity, to make the patch set smaller. Follow-up patches would enable it for the remaining boards. But I understand that keeping the aliases in the fsl-ls1028a.dtsi can mess up other boards that include it, including the Kontron boards. Would you agree to update only the ls1028 RDB board DT for now? Alternatively you could test these patches on your boards and maybe provide the DT updates for the Kontron boards as part of this patch set. >> + >> sysclk: sysclk { >> compatible = "fixed-clock"; >> #clock-cells = <0>; >> @@ -151,9 +162,51 @@ >> reg = <0x000300 0 0 0 0>; >> status = "disabled"; >> }; >> +ethsw: pci@0,5 { >> +#address-cells=<0>; >> +#size-cells=<1>; >> +reg = <0x000500 0 0 0 0>; >> + >> +ethsw_ports: ports { >> +#address-cells = <1>; >> +#size-cells = <0>; >> + >> +felix0: port@0 { >> +reg = <0>; >> +status = "disabled"; >> +label = "swp0"; >> +}; >> +felix1: port@1 { >> +reg = <1>; >> +status = "disabled"; >> +label = "swp1"; >> +}; >> +felix2: port@2 { >> +reg = <2>; >> +status = "disabled"; >> +label = "swp2"; >> +}; >> +felix3: port@3 { >> +reg = <3>; >> +status = "disabled"; >> +label = "swp3"; >> +}; >> +port@4 { >> +reg = <4>; >> +phy-mode = "internal"; >> +status = "okay"; >> +ethernet = <>; >> +}; > >status = "disabled". > >Why would you enable just this port if all the switch ports >are disabled. > The number of active front panel ports may vary from board to board. These ports are supposed to be enabled in each board DT, depending on setup. But a DSA switch always needs a CPU port regardless of how many front side ports are active in each particular setup, and port@4 is the CPU port. Thanks, Claudiu
[PATCH 4/5] arm: dts: ls1028a: Add Ethernet switch node and dependencies
From: Alex Marginean The definition follows the DSA binding in kernel and describes the switch, its ports and PHYs. ENETC PF6 is the 2nd Eth controller linked to the switch on LS1028A, it is not used in U-Boot and was disabled. Ethernet port aliases were also added to better manage the multitude of ports available now, and to enforce the order in which master and slave ports are probed. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- arch/arm/dts/fsl-ls1028a-rdb.dts | 36 + arch/arm/dts/fsl-ls1028a.dtsi| 55 +++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/fsl-ls1028a-rdb.dts b/arch/arm/dts/fsl-ls1028a-rdb.dts index 85b4815b2e..92d83a5c0c 100644 --- a/arch/arm/dts/fsl-ls1028a-rdb.dts +++ b/arch/arm/dts/fsl-ls1028a-rdb.dts @@ -131,9 +131,45 @@ phy-handle = <_phy0>; }; +_ports { + port@0 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy0>; + }; + port@1 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy1>; + }; + port@2 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy2>; + }; + port@3 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy3>; + }; +}; + { status = "okay"; rdb_phy0: phy@2 { reg = <2>; }; + + sw_phy0: phy@10 { + reg = <0x10>; + }; + sw_phy1: phy@11 { + reg = <0x11>; + }; + sw_phy2: phy@12 { + reg = <0x12>; + }; + sw_phy3: phy@13 { + reg = <0x13>; + }; }; diff --git a/arch/arm/dts/fsl-ls1028a.dtsi b/arch/arm/dts/fsl-ls1028a.dtsi index d0850237c7..e73769392f 100644 --- a/arch/arm/dts/fsl-ls1028a.dtsi +++ b/arch/arm/dts/fsl-ls1028a.dtsi @@ -14,6 +14,17 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + eth0 = + eth1 = + eth2 = + eth3 = + eth4 = + eth5 = + eth6 = + eth7 = + }; + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -151,9 +162,51 @@ reg = <0x000300 0 0 0 0>; status = "disabled"; }; + ethsw: pci@0,5 { + #address-cells=<0>; + #size-cells=<1>; + reg = <0x000500 0 0 0 0>; + + ethsw_ports: ports { + #address-cells = <1>; + #size-cells = <0>; + + felix0: port@0 { + reg = <0>; + status = "disabled"; + label = "swp0"; + }; + felix1: port@1 { + reg = <1>; + status = "disabled"; + label = "swp1"; + }; + felix2: port@2 { + reg = <2>; + status = "disabled"; + label = "swp2"; + }; + felix3: port@3 { + reg = <3>; + status = "disabled"; + label = "swp3"; + }; + port@4 { + reg = <4>; + phy-mode = "internal"; + status = "okay"; + ethernet = <>; + }; + port@5 { + reg = <5>; + phy-mode = "internal"; + status = "disabled"; + }; + }; + }; enetc6: pci@0,6 { reg = <0x000600 0 0 0 0>; - status = "okay"; + status = "disabled"; phy-mode = "internal"; }; }; -- 2.17.1
[PATCH 2/5] sandbox: Add a DSA sandbox driver and unit test
The DSA sandbox driver is used for unit testing the DSA class code. It implements a simple 2 port switch plus 1 CPU port, and uses a very simple tag to identify the ports. The DSA sandbox device is connected via CPU port to a regular Ethernet sandbox device, called 'dsa-test-eth, managed by the existing eth sandbox driver. The 'dsa-test-eth' is not intended for testing the eth class code however, but it is used to emulate traffic through the 'lan0' and 'lan1' front pannel switch ports. To achieve this the dsa sandbox driver registers a tx handler for the 'dsa-test-eth' device. The switch ports, labeled as 'lan0' and 'lan1', are also registered as eth devices by the dsa class code this time. So pinging through these switch ports is as easy as: => setenv ethact lan0 => ping 1.2.3.5 Unit tests for the dsa class code were also added. The 'dsa_probe' test exercises most API functions from dsa.h. The 'dsa' unit test simply exercises ARP/ICMP traffic through the two switch ports, including tag injection and extraction, with the help of the dsa sandbox driver. I took care to minimize the impact on the existing eth unit tests, though some adjustments needed to be made with the addition of extra eth interfaces used by the dsa unit tests. The additional eth interfaces also require MAC addresses, these have been added to the sandbox default environment. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- arch/Kconfig | 1 + arch/sandbox/dts/test.dts | 40 + drivers/net/Kconfig | 9 ++ drivers/net/Makefile | 1 + drivers/net/dsa_sandbox.c | 181 ++ include/configs/sandbox.h | 2 + test/dm/Makefile | 1 + test/dm/dsa.c | 91 +++ test/dm/eth.c | 10 +-- 9 files changed, 331 insertions(+), 5 deletions(-) create mode 100644 drivers/net/dsa_sandbox.c create mode 100644 test/dm/dsa.c diff --git a/arch/Kconfig b/arch/Kconfig index 27843cd79c..8a8130f0c8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -160,6 +160,7 @@ config SANDBOX imply CMD_CLONE imply SILENT_CONSOLE imply BOOTARGS_SUBST + imply DM_DSA config SH bool "SuperH architecture" diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index c9b9b7b75e..8e85b343db 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -14,7 +14,9 @@ aliases { console = eth0 = "/eth@10002000"; + eth2 = _0; eth3 = _3; + eth4 = _eth0; eth5 = _5; gpio1 = _a; gpio2 = _b; @@ -375,6 +377,44 @@ fake-host-hwaddr = [00 00 66 44 22 22]; }; + dsa_eth0: dsa-test-eth { + compatible = "sandbox,eth"; + reg = <0x10006000 0x1000>; + fake-host-hwaddr = [00 00 66 44 22 66]; + }; + + dsa-test { + compatible = "sandbox,dsa"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + swp_0: port@0 { + reg = <0>; + label = "lan0"; + }; + + swp_1: port@1 { + reg = <1>; + label = "lan1"; + phy-mode = "rgmii-txid"; + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + port@2 { + reg = <2>; + ethernet = <_eth0>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + firmware { sandbox_firmware: sandbox-firmware { compatible = "sandbox,firmware"; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 382224d04c..214aebf14a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -77,6 +77,15 @@ config DM_ETH_PHY help Enable driver model for Ethernet Generic PHY . +config DSA_SANDBOX + depends on DM_DSA && SANDBOX + default y + bool "Sandbox: Mocked DSA driver" + help + This driver implements a dummy DSA switch connected to a dummy sandbox + Ethernet device used as DSA master, to test DSA class code, including + exported DSA API and datapath processing of Ethernet traffic. +
[PATCH 3/5] drivers: net: Add Felix DSA switch driver
From: Alex Marginean This driver is used for the Ethernet switch integrated into LS1028A NXP. Felix on LS1028A has 4 front panel ports and two internal ports, I/O to/from the switch is done through an ENETC Ethernet interface. The 4 front panel ports are available as Ethernet interfaces and can be used with the typical network commands like tftp. Signed-off-by: Alex Marginean Signed-off-by: Vladimir Oltean Signed-off-by: Claudiu Manoil --- drivers/net/fsl_enetc.h | 5 + drivers/net/mscc_eswitch/Kconfig| 8 + drivers/net/mscc_eswitch/Makefile | 1 + drivers/net/mscc_eswitch/felix_switch.c | 432 4 files changed, 446 insertions(+) create mode 100644 drivers/net/mscc_eswitch/felix_switch.c diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h index 37e7e85843..110c1d78fb 100644 --- a/drivers/net/fsl_enetc.h +++ b/drivers/net/fsl_enetc.h @@ -201,6 +201,11 @@ struct enetc_priv { /* PCS replicator block for USXGMII */ #define ENETC_PCS_DEVAD_REPL 0x1f +#define ENETC_PCS_REPL_LINK_TIMER_10x12 +#define ENETC_PCS_REPL_LINK_TIMER_1_DEF 0x0003 +#define ENETC_PCS_REPL_LINK_TIMER_20x13 +#define ENETC_PCS_REPL_LINK_TIMER_2_DEF 0x06a0 + /* ENETC external MDIO registers */ #define ENETC_MDIO_BASE0x1c00 #define ENETC_MDIO_CFG 0x00 diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig index 80dd22f98b..11fb08edaa 100644 --- a/drivers/net/mscc_eswitch/Kconfig +++ b/drivers/net/mscc_eswitch/Kconfig @@ -36,3 +36,11 @@ config MSCC_SERVAL_SWITCH select PHYLIB help This driver supports the Serval network switch device. + +config MSCC_FELIX_SWITCH + bool "Felix switch driver" + depends on DM_DSA && DM_PCI + select FSL_ENETC + help + This driver supports the Ethernet switch integrated in LS1028A NXP + SoC. diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile index d583fe9fc4..22342ed114 100644 --- a/drivers/net/mscc_eswitch/Makefile +++ b/drivers/net/mscc_eswitch/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o m obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o mscc_miim.o obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o mscc_miim.o obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o +obj-$(CONFIG_MSCC_FELIX_SWITCH) += felix_switch.o diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c new file mode 100644 index 00..ae8b690e76 --- /dev/null +++ b/drivers/net/mscc_eswitch/felix_switch.c @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Felix Ethernet switch driver + * Copyright 2018-2021 NXP + */ + +/* + * This driver is used for the Ethernet switch integrated into LS1028A NXP. + * Felix switch is derived from Microsemi Ocelot but there are several NXP + * adaptations that makes the two U-Boot drivers largely incompatible. + * + * Felix on LS1028A has 4 front panel ports and two internal ports, connected + * to ENETC interfaces. We're using one of the ENETC interfaces to push traffic + * into the switch. Injection/extraction headers are used to identify + * egress/ingress ports in the switch for Tx/Rx. + */ + +#include +#include +#include +#include +#include +#include + +/* defines especially around PCS are reused from enetc */ +#include "../fsl_enetc.h" + +#define PCI_DEVICE_ID_FELIX_ETHSW 0xEEF0 + +/* Felix has in fact 6 ports, but we don't use the last internal one */ +#define FELIX_PORT_COUNT 5 +/* Front panel port mask */ +#define FELIX_FP_PORT_MASK 0xf + +/* Register map for BAR4 */ +#define FELIX_SYS 0x01 +#define FELIX_ES0 0x04 +#define FELIX_IS1 0x05 +#define FELIX_IS2 0x06 +#define FELIX_GMII(port) (0x10 + (port) * 0x1) +#define FELIX_QSYS 0x20 + +#define FELIX_SYS_SYSTEM (FELIX_SYS + 0x0E00) +#define FELIX_SYS_SYSTEM_EN BIT(0) +#define FELIX_SYS_RAM_CTRL (FELIX_SYS + 0x0F24) +#define FELIX_SYS_RAM_CTRL_INIT BIT(1) +#define FELIX_SYS_SYSTEM_PORT_MODE(a) (FELIX_SYS_SYSTEM + 0xC + (a) * 4) +#define FELIX_SYS_SYSTEM_PORT_MODE_CPU0x001e + +#define FELIX_ES0_TCAM_CTRL(FELIX_ES0 + 0x03C0) +#define FELIX_ES0_TCAM_CTRL_ENBIT(0) +#define FELIX_IS1_TCAM_CTRL(FELIX_IS1 + 0x03C0) +#define FELIX_IS1_TCAM_CTRL_ENBIT(0) +#define FELIX_IS2_TCAM_CTRL(FELIX_IS2 + 0x03C0) +#define FELIX_IS2_TCAM_CTRL_ENBIT(0) + +#define FELIX_GMII_CLOCK_CFG(port) (FELIX_GMII(port) + 0x) +#define FELIX_GMII_C
[PATCH 5/5] configs: ls1028a: Enable the Ethernet switch driver in defconfig
From: Alex Marginean The switch driver for LS1028A Ethernet switch is now compiled in for both LS1028A boards. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- configs/ls1028aqds_tfa_SECURE_BOOT_defconfig | 2 ++ configs/ls1028aqds_tfa_defconfig | 2 ++ configs/ls1028ardb_tfa_SECURE_BOOT_defconfig | 2 ++ configs/ls1028ardb_tfa_defconfig | 2 ++ 4 files changed, 8 insertions(+) diff --git a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig index 14c49cd0d6..43ddcf9166 100644 --- a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig @@ -61,6 +61,8 @@ CONFIG_DM_MDIO_MUX=y CONFIG_E1000=y CONFIG_FSL_ENETC=y CONFIG_MDIO_MUX_I2CREG=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/ls1028aqds_tfa_defconfig b/configs/ls1028aqds_tfa_defconfig index 09a6923708..c790e99485 100644 --- a/configs/ls1028aqds_tfa_defconfig +++ b/configs/ls1028aqds_tfa_defconfig @@ -67,6 +67,8 @@ CONFIG_DM_MDIO_MUX=y CONFIG_E1000=y CONFIG_FSL_ENETC=y CONFIG_MDIO_MUX_I2CREG=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig index b034580aef..8b9e217c61 100644 --- a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig @@ -58,6 +58,8 @@ CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_E1000=y CONFIG_FSL_ENETC=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/ls1028ardb_tfa_defconfig b/configs/ls1028ardb_tfa_defconfig index 4bed352420..aa82719e5e 100644 --- a/configs/ls1028ardb_tfa_defconfig +++ b/configs/ls1028ardb_tfa_defconfig @@ -64,6 +64,8 @@ CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_E1000=y CONFIG_FSL_ENETC=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_NVME=y CONFIG_PCI=y CONFIG_DM_PCI=y -- 2.17.1
[PATCH 1/5] net: Introduce DSA class for Ethernet switches
DSA stands for Distributed Switch Architecture and it covers switches that are connected to the CPU through an Ethernet link and generally use frame tags to pass information about the source/destination ports to/from CPU. Front panel ports are presented as regular ethernet devices in U-Boot and they are expected to support the typical networking commands. DSA switches may be cascaded, DSA class code does not currently support this. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- drivers/net/Kconfig| 14 ++ include/dm/uclass-id.h | 1 + include/net.h | 6 + include/net/dsa.h | 206 net/Makefile | 1 + net/dsa-uclass.c | 517 + 6 files changed, 745 insertions(+) create mode 100644 include/net/dsa.h create mode 100644 net/dsa-uclass.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3a5e036880..382224d04c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -37,6 +37,20 @@ config DM_MDIO_MUX This is currently implemented in net/mdio-mux-uclass.c Look in include/miiphy.h for details. +config DM_DSA + bool "Enable Driver Model for DSA switches" + depends on DM_ETH && DM_MDIO + help + Enable driver model for DSA switches + + Adds UCLASS_DSA class supporting switches that follow the Distributed + Switch Architecture (DSA). These switches rely on the presence of a + management switch port connected to an Ethernet controller capable of + receiving frames from the switch. This host Ethernet controller is + called the "master" Ethernet interface in DSA terminology. + This is currently implemented in net/dsa-uclass.c, refer to + include/net/dsa.h for API details. + config MDIO_SANDBOX depends on DM_MDIO && SANDBOX default y diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index ae4425d7a5..d75de368c5 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -46,6 +46,7 @@ enum uclass_id { UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ UCLASS_DSI_HOST,/* Display Serial Interface host */ UCLASS_DMA, /* Direct Memory Access */ + UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */ UCLASS_EFI, /* EFI managed devices */ UCLASS_ETH, /* Ethernet device */ UCLASS_ETH_PHY, /* Ethernet PHY device */ diff --git a/include/net.h b/include/net.h index 13da69b7c1..b95d6a6f60 100644 --- a/include/net.h +++ b/include/net.h @@ -499,7 +499,13 @@ struct icmp_hdr { * maximum packet size and multiple of 32 bytes = 1536 */ #define PKTSIZE1522 +#ifndef CONFIG_DM_DSA #define PKTSIZE_ALIGN 1536 +#else +/* Maximum DSA tagging overhead (headroom and/or tailroom) */ +#define DSA_MAX_OVR256 +#define PKTSIZE_ALIGN (1536 + DSA_MAX_OVR) +#endif /* * Maximum receive ring size; that is, the number of packets diff --git a/include/net/dsa.h b/include/net/dsa.h new file mode 100644 index 00..a2bf4851df --- /dev/null +++ b/include/net/dsa.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019-2021 NXP + */ + +#ifndef __DSA_H__ +#define __DSA_H__ + +#include +#include + +/** + * DSA stands for Distributed Switch Architecture and it is infrastructure + * intended to support drivers for Switches that rely on an intermediary + * Ethernet device for I/O. These switches may support cascading allowing + * them to be arranged as a tree. + * DSA is documented in detail in the Linux kernel documentation under + * Documentation/networking/dsa/dsa.txt + * The network layout of such a switch is shown below: + * + * |--| + * | eth0 | <--- master eth device (regular eth driver) + * |--| + * ^ | + * tag added by switch -->| | + * | | + * | |<-- tag added by DSA driver + * | v + * |--| + * | | CPU port | | <-- DSA (switch) device + * | | (DSA driver) + * | _ _ _ | + * | | port0 | | port1 | ... | portn | | <-- ports as eth devices + * |-+---+--+---+---+---+-| ('dsa-port' eth driver) + * + * In U-Boot the intent is to allow access to front panel ports (shown at the + * bottom of the picture) through the master Ethernet dev (eth0 in the picture). + * Front panel ports are presented as regular Ethernet devices in U-Boot and + * they are expected to support the typical networking commands. + * In general DSA switches require the use of tags, extra headers added
[PATCH 0/5] Introduce DSA Ethernet switch class and Felix driver
DSA stands for Distributed Switch Architecture and it is a subsystem introduced in the Linux kernel to support switches that: - have an Ethernet link up to the CPU - use some form of tagging to identify the source/destination port for Rx/Tx - may be cascaded in tree-like structures. DSA is described in depth here: https://www.kernel.org/doc/Documentation/networking/dsa/dsa.txt This patch set introduces a DSA class in U-Boot to support drivers of DSA switches. DSA drivers have to implement the following ops: - enable/disable of switch ports, - insert a tag in frames being transmitted, used by the switch to select the egress port, - parse a tag in frames being received, used for Rx traffic. DSA class code deals with presentation of switch ports as Ethernet interfaces, deals with the master Ethernet device for I/O and helps with parsing of the DT assuming the structure follows the DSA kernel binding. Support for switch cascading is not included yet. In the sandbox environment, the DSA sandbox driver, the switch ports and master eth interface look like this: => dm tree Class Index Probed DriverName --- [...] eth 4 [ + ] eth_sandbox |-- dsa-test-eth dsa 0 [ + ] dsa_sandbox |-- dsa-test eth 5 [ + ] dsa-port | |-- lan0 eth 6 [ + ] dsa-port | `-- lan1 => setenv ethact lan1 => ping 1.2.3.5 Using lan1 device host 1.2.3.5 is alive => This patch set also introduces a driver for the Ethernet switch integrated into NXP LS1028A, called Felix. The switch has 4 front panel ports, I/O to/from it is done though an ENETC Ethernet interface and meta-data is carried between the switch and the driver though an additional header pre-pended to the original frame. Network commands like tftp can be used on these front panel ports. The ports are disabled unless used so they do not cause issues on network topologies that include loops. Felix as seen on LS1028A RDB: => dm tree Class Index Probed DriverName --- [...] dsa 0 [ + ] felix-switch | |-- felix-switch eth 4 [ + ] dsa-port | | |-- swp0 eth 5 [ + ] dsa-port | | |-- swp1 eth 6 [ + ] dsa-port | | |-- swp2 eth 7 [ + ] dsa-port | | `-- swp3 => mdio list [...] 10 - Vitesse VSC8514 <--> swp0 11 - Vitesse VSC8514 <--> swp1 12 - Vitesse VSC8514 <--> swp2 13 - Vitesse VSC8514 <--> swp3 NOTE: This patchset is a major rework of the dsa-class code since the last submission from May 5th: https://patchwork.ozlabs.org/project/uboot/cover/1588700588-8587-1-git-send-email-claudiu.man...@nxp.com/ The basic concepts and data path operation (tagging) in the DSA class code remain the same as in the initial patchset from Alex, however the external API has been changed significantly (simplified), the driver model integration has been improved to the point that the DSA class code no longer needs to allocate extra memory internally (via malloc), reduced memory footprint, internal state data moved from the external API and internalized, cleaner external API, internal code reworked, completly reworked DSA sandbox driver and unit tests for better coverage and to integrate better with the eth sandbox driver and tests, etc. The DSA class code is now ported on top of the latest u-boot master branch (obviously), and I tested it thoroughly with the sandbox driver and unit tests. The felix driver has been tested with an older uboot, since there are some issues booting the latest upstream uboot on a LS1028A RDB board. Note that the felix driver itself didn't change since the last submission, except for the DSA API function calls. Alex Marginean (3): drivers: net: Add Felix DSA switch driver arm: dts: ls1028a: Add Ethernet switch node and dependencies configs: ls1028a: Enable the Ethernet switch driver in defconfig Claudiu Manoil (2): net: Introduce DSA class for Ethernet switches sandbox: Add a DSA sandbox driver and unit test arch/Kconfig | 1 + arch/arm/dts/fsl-ls1028a-rdb.dts | 36 ++ arch/arm/dts/fsl-ls1028a.dtsi| 55 +- arch/sandbox/dts/test.dts| 40 ++ configs/ls1028aqds_tfa_SECURE_BOOT_defconfig | 2 + configs/ls1028aqds_tfa_defconfig | 2 + configs/ls1028ardb_tfa_SECURE_BOOT_defconfig | 2 + configs/ls1028ardb_tfa_defconfig | 2 + drivers/net/Kconfig | 23 + drivers/net/Makefile | 1 + drivers/net/dsa_sandbox.c| 181 +++ drivers/net/fsl_enetc.h | 5 + drivers/net/mscc_eswitch/Kconfig | 8 + drivers/
RE: [PATCH v4 2/6] drivers: net: add a DSA sandbox driver
>-Original Message- >From: Priyanka Jain (OSS) [...] > >Kindly fix build error for target >BUILDMAN="sandbox x86" TOOLCHAIN="i386" > >https://travis-ci.org/github/p-priyanka-jain/u-boot/jobs/711090082 > > Hi Priyanka, I will look into rebasing the patches and addressing these new found issues, unfortunately I'll be out of office for the next week. Also note that the patches are based on top of the -net tree (git.denx.de/u-boot-net.git), since they introduce networking features. But -net didn't change for a long time. Should I base the patches on another upstream tree instead? Thanks. Claudiu
RE: [PATCH v4 0/6] Introduce DSA Ethernet switch class and Felix driver
>-Original Message- >From: U-Boot On Behalf Of Claudiu Manoil >Sent: Tuesday, May 5, 2020 8:43 PM >To: u-boot@lists.denx.de >Cc: joe.hershber...@ni.com; Alexandru Marginean >; Vladimir Oltean > >Subject: [PATCH v4 0/6] Introduce DSA Ethernet switch class and Felix driver > Hi Joe, How long would it take to have these patches merged, considering that there are no review comments so far? Thanks, Claudiu
[PATCH v4 4/6] drivers: net: add Felix DSA switch driver
From: Alex Marginean This driver is used for the Ethernet switch integrated into LS1028A NXP. Felix on LS1028A has 4 front panel ports and two internal ports, I/O to/from the switch is done through an ENETC Ethernet interface. The 4 front panel ports are available as Ethernet interfaces and can be used with the typical network commands like tftp. Signed-off-by: Alex Marginean Tested-by: Michael Walle Signed-off-by: Vladimir Oltean Signed-off-by: Claudiu Manoil --- drivers/net/fsl_enetc.h | 5 + drivers/net/mscc_eswitch/Kconfig| 8 + drivers/net/mscc_eswitch/Makefile | 1 + drivers/net/mscc_eswitch/felix_switch.c | 456 4 files changed, 470 insertions(+) create mode 100644 drivers/net/mscc_eswitch/felix_switch.c diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h index 48c3005cb3..ba8f7d5a24 100644 --- a/drivers/net/fsl_enetc.h +++ b/drivers/net/fsl_enetc.h @@ -200,6 +200,11 @@ struct enetc_priv { /* PCS replicator block for USXGMII */ #define ENETC_PCS_DEVAD_REPL 0x1f +#define ENETC_PCS_REPL_LINK_TIMER_10x12 +#define ENETC_PCS_REPL_LINK_TIMER_1_DEF 0x0003 +#define ENETC_PCS_REPL_LINK_TIMER_20x13 +#define ENETC_PCS_REPL_LINK_TIMER_2_DEF 0x06a0 + /* ENETC external MDIO registers */ #define ENETC_MDIO_BASE0x1c00 #define ENETC_MDIO_CFG 0x00 diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig index 80dd22f98b..11fb08edaa 100644 --- a/drivers/net/mscc_eswitch/Kconfig +++ b/drivers/net/mscc_eswitch/Kconfig @@ -36,3 +36,11 @@ config MSCC_SERVAL_SWITCH select PHYLIB help This driver supports the Serval network switch device. + +config MSCC_FELIX_SWITCH + bool "Felix switch driver" + depends on DM_DSA && DM_PCI + select FSL_ENETC + help + This driver supports the Ethernet switch integrated in LS1028A NXP + SoC. diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile index d583fe9fc4..22342ed114 100644 --- a/drivers/net/mscc_eswitch/Makefile +++ b/drivers/net/mscc_eswitch/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o m obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o mscc_miim.o obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o mscc_miim.o obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o +obj-$(CONFIG_MSCC_FELIX_SWITCH) += felix_switch.o diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c new file mode 100644 index 00..80f25d460f --- /dev/null +++ b/drivers/net/mscc_eswitch/felix_switch.c @@ -0,0 +1,456 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Felix Ethernet switch driver + * Copyright 2018-2019 NXP + */ + +/* + * This driver is used for the Ethernet switch integrated into LS1028A NXP. + * Felix switch is derived from Microsemi Ocelot but there are several NXP + * adaptations that makes the two U-Boot drivers largely incompatible. + * + * Felix on LS1028A has 4 front panel ports and two internal ports, connected + * to ENETC interfaces. We're using one of the ENETC interfaces to push traffic + * into the switch. Injection/extraction headers are used to identify + * egress/ingress ports in the switch for Tx/Rx. + */ + +#include +#include +#include +#include +#include +#include + +/* defines especially around PCS are reused from enetc */ +#include "../fsl_enetc.h" + +#define PCI_DEVICE_ID_FELIX_ETHSW 0xEEF0 + +/* Felix has in fact 6 ports, but we don't use the last internal one */ +#define FELIX_PORT_COUNT 5 +/* Front panel port mask */ +#define FELIX_FP_PORT_MASK 0xf + +/* Register map for BAR4 */ +#define FELIX_SYS 0x01 +#define FELIX_ES0 0x04 +#define FELIX_IS1 0x05 +#define FELIX_IS2 0x06 +#define FELIX_GMII(port) (0x10 + (port) * 0x1) +#define FELIX_QSYS 0x20 + +#define FELIX_SYS_SYSTEM (FELIX_SYS + 0x0E00) +#define FELIX_SYS_SYSTEM_EN BIT(0) +#define FELIX_SYS_RAM_CTRL (FELIX_SYS + 0x0F24) +#define FELIX_SYS_RAM_CTRL_INIT BIT(1) +#define FELIX_SYS_SYSTEM_PORT_MODE(a) (FELIX_SYS_SYSTEM + 0xC + (a) * 4) +#define FELIX_SYS_SYSTEM_PORT_MODE_CPU0x001e + +#define FELIX_ES0_TCAM_CTRL(FELIX_ES0 + 0x03C0) +#define FELIX_ES0_TCAM_CTRL_ENBIT(0) +#define FELIX_IS1_TCAM_CTRL(FELIX_IS1 + 0x03C0) +#define FELIX_IS1_TCAM_CTRL_ENBIT(0) +#define FELIX_IS2_TCAM_CTRL(FELIX_IS2 + 0x03C0) +#define FELIX_IS2_TCAM_CTRL_ENBIT(0) + +#define FELIX_GMII_CLOCK_CFG(port) (FELIX_GMII(
[PATCH v4 1/6] net: introduce DSA class for Ethernet switches
From: Alex Marginean DSA stands for Distributed Switch Architecture and it covers switches that are connected to the CPU through an Ethernet link and generally use frame tags to pass information about the source/destination ports to/from CPU. Front panel ports are presented as regular ethernet devices in U-Boot and they are expected to support the typical networking commands. DSA switches may be cascaded, DSA class code does not currently support this. Signed-off-by: Alex Marginean Signed-off-by: Vladimir Oltean Signed-off-by: Claudiu Manoil --- drivers/net/Kconfig| 13 ++ include/dm/uclass-id.h | 1 + include/net.h | 6 + include/net/dsa.h | 137 ++ net/Makefile | 1 + net/dsa-uclass.c | 395 + 6 files changed, 553 insertions(+) create mode 100644 include/net/dsa.h create mode 100644 net/dsa-uclass.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4d1013c984..863314284b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -37,6 +37,19 @@ config DM_MDIO_MUX This is currently implemented in net/mdio-mux-uclass.c Look in include/miiphy.h for details. +config DM_DSA + bool "Enable Driver Model for DSA switches" + depends on DM_ETH && DM_MDIO + help + Enable Driver Model for DSA switches + + Adds UCLASS_DSA class supporting switches that follow the Distributed + Switch Architecture (DSA). These switches rely on the presence of a + management switch port connected to an Ethernet controller capable of + receiving frames from the switch. This host Ethernet controller is + called "master" and "cpu" in DSA terminology. + This is currently implemented in net/dsa-uclass.c + config MDIO_SANDBOX depends on DM_MDIO && SANDBOX default y diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 598f65ea7a..6fc52b72aa 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -44,6 +44,7 @@ enum uclass_id { UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ UCLASS_DSI_HOST,/* Display Serial Interface host */ UCLASS_DMA, /* Direct Memory Access */ + UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */ UCLASS_EFI, /* EFI managed devices */ UCLASS_ETH, /* Ethernet device */ UCLASS_FIRMWARE,/* Firmware */ diff --git a/include/net.h b/include/net.h index 82500eeb30..155f49196e 100644 --- a/include/net.h +++ b/include/net.h @@ -489,7 +489,13 @@ struct icmp_hdr { * maximum packet size and multiple of 32 bytes = 1536 */ #define PKTSIZE1522 +#ifndef CONFIG_DM_DSA #define PKTSIZE_ALIGN 1536 +#else +/* Maximum DSA tagging overhead (headroom or tailroom) */ +#define DSA_MAX_OVR256 +#define PKTSIZE_ALIGN (1536 + DSA_MAX_OVR) +#endif /* * Maximum receive ring size; that is, the number of packets diff --git a/include/net/dsa.h b/include/net/dsa.h new file mode 100644 index 00..45f1d42e7e --- /dev/null +++ b/include/net/dsa.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019-2020 NXP + */ + +#ifndef __DSA_H__ +#define __DSA_H__ + +#include +#include +#include + +/** + * DSA stands for Distributed Switch Architecture and it is infrastructure + * intended to support drivers for Switches that rely on an intermediary + * Ethernet device for I/O. These switches may support cascading allowing + * them to be arranged as a tree. + * DSA is documented in detail in the Linux kernel documentation under + * Documentation/networking/dsa/dsa.txt + * The network layout of such a switch is shown below: + * + * |--- + * | CPU network device (eth0)| + * + * | | + * || + * | Switch driver | + * || + * |||| || + * |---| |---| |---| + * | sw0p0 | | sw0p1 | | sw0p2 | + * |---| |---| |---| + * + * In U-Boot the intent is to allow access to front panel ports (shown at the + * bottom of the picture) though the master Ethernet port (eth0 in the picture). + * Front panel ports are presented as regular Ethernet devices in U-Boot and + * they are expected to support the typical networking commands. + * In general DSA switches require the use of tags, extra headers added both by + * software on Tx and by the switch on Rx. These tags carry at a minimum port + * information and switch information for cascaded set-ups. + * In U-Boot these tags are inserted and parsed by the DSA switch driver, the + * class code helps with headroom/tailroom for the ex
[PATCH v4 3/6] test: dm: add a simple unit test for DSA class
From: Alex Marginean The test pings the local IP address though different ports of a sandbox DSA device. Port traffic is filtered and the test verifies that ping works only on enabled ports. The additional interfaces require MAC addresses, these have been added to sandbox default environment. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- arch/Kconfig | 1 + arch/sandbox/dts/test.dts | 49 + include/configs/sandbox.h | 4 +++ test/dm/Makefile | 1 + test/dm/dsa.c | 58 +++ test/dm/test-fdt.c| 2 +- 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 test/dm/dsa.c diff --git a/arch/Kconfig b/arch/Kconfig index ae9c93ed7b..d13a53a548 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -136,6 +136,7 @@ config SANDBOX imply ACPI_PMC imply ACPI_PMC_SANDBOX imply CMD_PMC + imply DM_DSA config SH bool "SuperH architecture" diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 4a277934a7..7c54200e71 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -40,6 +40,10 @@ usb2 = _2; axi0 = osd0 = "/osd"; + eth8 = _0; + eth9 = _1; + eth10 = _2; + eth11 = _eth0; }; audio: audio-codec { @@ -934,6 +938,51 @@ mdio: mdio-test { compatible = "sandbox,mdio"; }; + + dsa_eth0: dsa-test-eth { + compatible = "sandbox,dsa-eth"; + }; + + dsa-test { + compatible = "sandbox,dsa"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + swp_0: port@0 { + reg = <0>; + label = "lan0"; + }; + + swp_1: port@1 { + reg = <1>; + label = "lan1"; + phy-mode = "rgmii-txid"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + swp_2: port@2 { + reg = <2>; + label = "lan2"; + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + port@3 { + reg = <3>; + ethernet = <_eth0>; + fixed-link { + speed = <100>; + full-duplex; + }; + }; + }; + }; }; #include "sandbox_pmic.dtsi" diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 1c13055cdc..35a5676eb9 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -100,6 +100,10 @@ "eth1addr=00:00:11:22:33:45\0" \ "eth3addr=00:00:11:22:33:46\0" \ "eth5addr=00:00:11:22:33:47\0" \ + "eth8addr=00:00:11:22:33:48\0" \ + "eth9addr=00:00:11:22:33:49\0" \ + "eth10addr=00:00:11:22:33:4a\0" \ + "eth11addr=00:00:11:22:33:4b\0" \ "ipaddr=1.2.3.4\0" #define MEM_LAYOUT_ENV_SETTINGS \ diff --git a/test/dm/Makefile b/test/dm/Makefile index dd1ceff86c..1807795bec 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -70,4 +70,5 @@ obj-$(CONFIG_DMA) += dma.o obj-$(CONFIG_DM_MDIO) += mdio.o obj-$(CONFIG_DM_MDIO_MUX) += mdio_mux.o obj-$(CONFIG_DM_RNG) += rng.o +obj-$(CONFIG_DM_DSA) += dsa.o endif diff --git a/test/dm/dsa.c b/test/dm/dsa.c new file mode 100644 index 00..8a4a0c --- /dev/null +++ b/test/dm/dsa.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019-2020 NXP + */ + +#include +#include +#include + +extern int dsa_sandbox_port_mask; + +/* this test sends ping requests with the local address through each DSA port + * via the dummy DSA master Eth. + * The dummy Eth filters traffic based on DSA port used to Tx and the port + * mask s
[PATCH v4 6/6] configs: ls1028a: enable the Ethernet switch driver in defconfig
From: Alex Marginean The switch driver for LS1028A Ethernet switch is now compiled in for both LS1028A boards. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- configs/ls1028aqds_tfa_SECURE_BOOT_defconfig | 2 ++ configs/ls1028aqds_tfa_defconfig | 2 ++ configs/ls1028ardb_tfa_SECURE_BOOT_defconfig | 2 ++ configs/ls1028ardb_tfa_defconfig | 2 ++ 4 files changed, 8 insertions(+) diff --git a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig index c5f0bd85da..2092009362 100644 --- a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig @@ -56,6 +56,8 @@ CONFIG_DM_MDIO_MUX=y CONFIG_E1000=y CONFIG_FSL_ENETC=y CONFIG_MDIO_MUX_I2CREG=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y diff --git a/configs/ls1028aqds_tfa_defconfig b/configs/ls1028aqds_tfa_defconfig index 7085be77fe..47231f9157 100644 --- a/configs/ls1028aqds_tfa_defconfig +++ b/configs/ls1028aqds_tfa_defconfig @@ -62,6 +62,8 @@ CONFIG_DM_MDIO_MUX=y CONFIG_E1000=y CONFIG_FSL_ENETC=y CONFIG_MDIO_MUX_I2CREG=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y diff --git a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig index 6fa14af6af..40946e2e61 100644 --- a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig @@ -53,6 +53,8 @@ CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_E1000=y CONFIG_FSL_ENETC=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y diff --git a/configs/ls1028ardb_tfa_defconfig b/configs/ls1028ardb_tfa_defconfig index 3ef5520969..9732aa3458 100644 --- a/configs/ls1028ardb_tfa_defconfig +++ b/configs/ls1028ardb_tfa_defconfig @@ -60,6 +60,8 @@ CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_E1000=y CONFIG_FSL_ENETC=y +CONFIG_DM_DSA=y +CONFIG_MSCC_FELIX_SWITCH=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y -- 2.17.1
[PATCH v4 2/6] drivers: net: add a DSA sandbox driver
From: Alex Marginean The DSA sandbox driver is used for DSA unit testing. It implements a simple 4 port switch that uses a very simple tag to identify the ports. The DSA driver comes paired with an Ethernet driver that loops packets back and can selectively filter traffic on DSA switch ports. Signed-off-by: Alex Marginean Signed-off-by: Claudiu Manoil --- drivers/net/Kconfig | 8 ++ drivers/net/Makefile | 1 + drivers/net/dsa_sandbox.c | 272 ++ 3 files changed, 281 insertions(+) create mode 100644 drivers/net/dsa_sandbox.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 863314284b..f982f18d26 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -70,6 +70,14 @@ config MDIO_MUX_SANDBOX This driver is used for testing in test/dm/mdio.c +config DSA_SANDBOX + depends on DM_DSA && SANDBOX + default y + bool "Sandbox: Mocked DSA driver" + help + This driver implements a dummy switch and a dummy Ethernet device used + to test DSA class code. + menuconfig NETDEVICES bool "Network device support" depends on NET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 6e0a68834d..f840b39893 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -83,3 +83,4 @@ obj-y += mscc_eswitch/ obj-$(CONFIG_HIGMACV300_ETH) += higmacv300.o obj-$(CONFIG_MDIO_SANDBOX) += mdio_sandbox.o obj-$(CONFIG_FSL_ENETC) += fsl_enetc.o fsl_enetc_mdio.o +obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o diff --git a/drivers/net/dsa_sandbox.c b/drivers/net/dsa_sandbox.c new file mode 100644 index 00..7475478668 --- /dev/null +++ b/drivers/net/dsa_sandbox.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019-2020 NXP + */ + +#include + +#define DSA_SANDBOX_MAGIC 0x00415344 +#define DSA_SANDBOX_TAG_LENsizeof(struct dsa_sandbox_tag) +/* + * This global flag is used to enable DSA just for DSA test so it doesn't affect + * the existing eth unit test. + */ +int dsa_sandbox_port_mask; + +struct dsa_sandbox_priv { + int enabled; + int port_enabled; +}; + +struct dsa_sandbox_tag { + u32 magic; + u32 port; +}; + +static int dsa_sandbox_port_enable(struct udevice *dev, int port, + struct phy_device *phy) +{ + struct dsa_sandbox_priv *priv = dev->priv; + + if (!priv->enabled) + return -EFAULT; + + priv->port_enabled |= BIT(port); + + return 0; +} + +static void dsa_sandbox_port_disable(struct udevice *dev, int port, +struct phy_device *phy) +{ + struct dsa_sandbox_priv *priv = dev->priv; + + if (!priv->enabled) + return; + + priv->port_enabled &= ~BIT(port); +} + +static int dsa_sandbox_xmit(struct udevice *dev, int port, void *packet, + int length) +{ + struct dsa_sandbox_priv *priv = dev->priv; + struct dsa_sandbox_tag *tag = packet; + + if (!priv->enabled) + return -EFAULT; + + if (!(priv->port_enabled & BIT(port))) + return -EFAULT; + + tag->magic = DSA_SANDBOX_MAGIC; + tag->port = port; + + return 0; +} + +static int dsa_sandbox_rcv(struct udevice *dev, int *port, void *packet, + int length) +{ + struct dsa_sandbox_priv *priv = dev->priv; + struct dsa_sandbox_tag *tag = packet; + + if (!priv->enabled) + return -EFAULT; + + if (tag->magic != DSA_SANDBOX_MAGIC) + return -EFAULT; + + *port = tag->port; + if (!(priv->port_enabled & BIT(*port))) + return -EFAULT; + + return 0; +} + +static const struct dsa_ops dsa_sandbox_ops = { + .port_enable = dsa_sandbox_port_enable, + .port_disable = dsa_sandbox_port_disable, + .xmit = dsa_sandbox_xmit, + .rcv = dsa_sandbox_rcv, +}; + +static int dsa_sandbox_bind(struct udevice *dev) +{ + struct dsa_perdev_platdata *pdata = dev->platdata; + + /* must be at least 4 to match sandbox test DT */ + pdata->num_ports = 4; + pdata->headroom = DSA_SANDBOX_TAG_LEN; + + return 0; +} + +static int dsa_sandbox_probe(struct udevice *dev) +{ + struct dsa_sandbox_priv *priv = dev_get_priv(dev); + + /* +* return error if DSA is not being tested so we don't break existing +* eth test. +*/ + if (!dsa_sandbox_port_mask) + return -EINVAL; + + priv->enabled = 1; + + return 0; +} + +static int dsa_sandbox_remove(struct udevice *dev) +{ + struct dsa_sandbox_priv *priv = dev_get_priv(dev); + + priv->enabled = 0; + + return 0; +} + +static const struct udevice_id dsa_sandbox_ids[] = { + { .compatible = "sandbox,ds
[PATCH v4 0/6] Introduce DSA Ethernet switch class and Felix driver
DSA stands for Distributed Switch Architecture and it is a subsystem introduced in the Linux kernel to support switches that: - have an Ethernet link up to the CPU - use some form of tagging to identify the source/destination port for Rx/Tx - may be cascaded in tree-like structures. DSA is described in depth here: https://www.kernel.org/doc/Documentation/networking/dsa/dsa.txt >From the doc: Summarized, this is basically how DSA looks like from a network device perspective: |--- | CPU network device (eth0)| | | || | Switch driver | || |||| || |---| |---| |---| | sw0p0 | | sw0p1 | | sw0p2 | |---| |---| |---| This patch set introduces a DSA class in U-Boot to support drivers of such switches. DSA drivers have to implement the following ops: - enable/disable of switch ports, - insert a tag in frames being transmitted, used by the switch to select the egress port, - parse a tag in frames being received, used for Rx traffic. DSA class code deals with presentation of switch ports as Ethernet interfaces, deals with the master Ethernet device for I/O and helps with parsing of the DT assuming the structure follows the DSA kernel binding. Support for switch cascading is not included yet. This patch set also introduces a driver for the Ethernet switch integrated into NXP LS1028A, called Felix. The switch has 4 front panel ports, I/O to/fom it is done though an ENETC Ethernet interface and meta-data is carried between the switch and the driver though an additional header pre-pended to the original frame. Network commands like tftp can be used on these front panel ports. The ports are disabled unless used so they do not cause issues on network topologies that include loops. Felix as seen on LS1028A RDB: => dm tree Class Index Probed DriverName --- .. dsa 0 [ + ] felix-switch | |-- felix-switch eth 4 [ + ] dsa-port | | |-- swp0 eth 5 [ + ] dsa-port | | |-- swp1 eth 6 [ + ] dsa-port | | |-- swp2 eth 7 [ + ] dsa-port | | `-- swp3 => mdio list .. 10 - Vitesse VSC8514 <--> swp0 11 - Vitesse VSC8514 <--> swp1 12 - Vitesse VSC8514 <--> swp2 13 - Vitesse VSC8514 <--> swp3 => tftp 8000 test Using swp2 device TFTP from server 192.168.100.1; our IP address is 192.168.100.100 Filename 'test'. Load address: 0x8000 Loading: # # 6.8 MiB/s done Bytes transferred = 949880 (e7e78 hex) Changes in v4: - fixed Rx buffer sizes to accomodate bigger packets, that are closer to the standard MTU size of 1500B. DSA needs extra room for tagging on top of the standard ethernet frame. Reserved a maximum overhead of 256B for DSA tagging, preserving the total packet size alignment. - addressed MAC addr propagation from DSA master eth port to the non-cpu switch ports for ports that don't have MAC addrs configured in the uboot env - added eth port aliases - fixed some in-band autoneg issues if nophy attached, in felix - dsa-uclass code cleanup - ls1028a defconfig cleanup - added missing device_compat.h (preventing build issues) - rebased on top of latest -net/master - updated copyright format and year Changes in v3: - fix Felix platdata size - move include/dsa.h to include/net/dsa.h - updated TODO in dsa.h - other minor fixes Changes in v2: - Don't use NULL PHY in Felix driver - guard dsa.h with #ifndef __DSA__H__, somehow I missed that in v1 - added a TODO for setting master Eth in promiscuous mode - Minor fixes in patch descriptions, API comments - Added address/size-cells to LS1028A DT ports node This patch set replaces v2: https://patchwork.ozlabs.org/project/uboot/list/?series=144912 and depends on: https://patchwork.ozlabs.org/project/uboot/list/?series=144907 https://patchwork.ozlabs.org/project/uboot/list/?series=142879 Alex Marginean (6): net: introduce DSA class for Ethernet switches drivers: net: add a DSA sandbox driver test: dm: add a simple unit test for DSA class drivers: net: add Felix DSA switch driver arm: dts: ls1028a: adds Ethernet switch node and its dependencies configs: ls1028a: enable the Ethernet switch driver in defconfig arch/Kconfig | 1 +
[PATCH v4 5/6] arm: dts: ls1028a: adds Ethernet switch node and its dependencies
From: Alex Marginean The definition follows the DSA binding in kernel and describes the switch, its ports and PHYs. ENETC PF6 is the 2nd Eth controller linked to the switch on LS1028A, it is not used in U-Boot and was disabled. Ethernet port aliases were also added to better manage the multitude of ports available now, and to enforce the order in which master and slave ports are probed. Signed-off-by: Alex Marginean Tested-by: Michael Walle Signed-off-by: Claudiu Manoil --- arch/arm/dts/fsl-ls1028a-rdb.dts | 36 + arch/arm/dts/fsl-ls1028a.dtsi| 55 +++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/fsl-ls1028a-rdb.dts b/arch/arm/dts/fsl-ls1028a-rdb.dts index a8f40855b6..80c3907e94 100644 --- a/arch/arm/dts/fsl-ls1028a-rdb.dts +++ b/arch/arm/dts/fsl-ls1028a-rdb.dts @@ -129,9 +129,45 @@ phy-handle = <_phy0>; }; +_ports { + port@0 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy0>; + }; + port@1 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy1>; + }; + port@2 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy2>; + }; + port@3 { + status = "okay"; + phy-mode = "qsgmii"; + phy-handle = <_phy3>; + }; +}; + { status = "okay"; rdb_phy0: phy@2 { reg = <2>; }; + + sw_phy0: phy@10 { + reg = <0x10>; + }; + sw_phy1: phy@11 { + reg = <0x11>; + }; + sw_phy2: phy@12 { + reg = <0x12>; + }; + sw_phy3: phy@13 { + reg = <0x13>; + }; }; diff --git a/arch/arm/dts/fsl-ls1028a.dtsi b/arch/arm/dts/fsl-ls1028a.dtsi index 5365bfb1a8..4de29149eb 100644 --- a/arch/arm/dts/fsl-ls1028a.dtsi +++ b/arch/arm/dts/fsl-ls1028a.dtsi @@ -14,6 +14,17 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + eth0 = + eth1 = + eth2 = + eth3 = + eth4 = + eth5 = + eth6 = + eth7 = + }; + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -145,9 +156,51 @@ reg = <0x000300 0 0 0 0>; status = "disabled"; }; + ethsw: pci@0,5 { + #address-cells=<0>; + #size-cells=<1>; + reg = <0x000500 0 0 0 0>; + + ethsw_ports: ports { + #address-cells = <1>; + #size-cells = <0>; + + felix0: port@0 { + reg = <0>; + status = "disabled"; + label = "swp0"; + }; + felix1: port@1 { + reg = <1>; + status = "disabled"; + label = "swp1"; + }; + felix2: port@2 { + reg = <2>; + status = "disabled"; + label = "swp2"; + }; + felix3: port@3 { + reg = <3>; + status = "disabled"; + label = "swp3"; + }; + port@4 { + reg = <4>; + phy-mode = "internal"; + status = "okay"; + ethernet = <>; + }; + port@5 { + reg = <5>; + phy-mode = "internal"; + status = "disabled"; + }; + }; + }; enetc6: pci@0,6 { reg = <0x000600 0 0 0 0>; - status = "okay"; + status = "disabled"; phy-mode = "internal"; }; }; -- 2.17.1
Re: [U-Boot] ls1021atwr: Convert to use driver model TSEC driver
>-Original Message- >From: Bin Meng [mailto:bmeng...@gmail.com] >Sent: Tuesday, July 10, 2018 5:43 AM >To: York Sun >Cc: Alison Wang ; Prabhakar Kushwaha >; U-Boot Mailing List ; >Claudiu Manoil >Subject: Re: ls1021atwr: Convert to use driver model TSEC driver > >Hi Claudiu, > >On Mon, Jun 11, 2018 at 10:28 PM, York Sun wrote: >> On 06/10/2018 10:37 PM, Bin Meng wrote: >>> On Tue, Jun 5, 2018 at 9:28 AM, Bin Meng wrote: >>>> Hi Alison, Prabhakar, >>>> >>>> On Fri, Jun 1, 2018 at 12:06 PM, York Sun wrote: >>>>> On May 31, 2018, at 20:58, Bin Meng wrote: >>>>>> >>>>>> Hi, >>>>>> >>>>>>> On Wed, May 30, 2018 at 11:06 AM, York Sun >wrote: >>>>>>> Alison and Prabhakar, >>>>>>> >>>>>>> Please take a look at the mentioned patch. >>>>>>> >>>>>> >>>>>> Would you please take the patch and update all LS1021A boards? thanks! >>>>> >>>>> >>>>> Bin, >>>>> >>>>> I expect LS1021A board maintainers to chime in. >>>> >>>> Would you please comment on this? Thanks! >>> >>> Ping ... >>> >> >> Bin, >> >> Our TSEC driver owner Claudiu Manoil (CC'ed) plans to work on the >> driver a while later. > >Do you have ETA of the DM ETH conversion for LS1021ATWR board? > Hi, No ETA right now. There's not only the LS1021ATRW board, there are also a lot of legacy PowerPC platforms that would have to be converted too. All the platforms featuring the TSEC h/w will have to be verified as well. Converting the TSEC driver to work only for the ls1 twr board will break the other platforms. Is there a urgent need to move to the new DM ETH model? Ensuring backward compatibility, not breaking legacy platforms is the most important part here and I don't have the bandwidth to do that right now. Thanks, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH] ls102xa: etsec: Use proper settings for BE BDs
Replace the DMACTRL[LE] hack with recommended settings for ETSECDMAMCR to get the same end effect - obtaining big-endian buffer descriptors and frame data for eTSEC. The reset / default value for ETSECDMAMCR is preserved, excepting the BD and FR bits which are cleared to enable the BE mode in accordance with the H/W specifications. Fixes: 52d00a8 ls102xa: etsec: Add etsec support for LS102xA Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h | 2 +- board/freescale/ls1021aqds/ls1021aqds.c | 3 ++- board/freescale/ls1021atwr/ls1021atwr.c | 3 ++- drivers/net/tsec.c| 6 -- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h index d34044a..60aa0d3 100644 --- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -143,7 +143,7 @@ struct ccsr_gur { u32 sdhcpcr; }; -#define SCFG_ETSECDMAMCR_LE_BD_FR 0xf8001a0f +#define SCFG_ETSECDMAMCR_LE_BD_FR 0x0c00 #define SCFG_ETSECCMCR_GE2_CLK125 0x0400 #define SCFG_ETSECCMCR_GE0_CLK125 0x #define SCFG_ETSECCMCR_GE1_CLK125 0x0800 diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index d6ef6ba..e585380 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -280,7 +280,8 @@ int board_early_init_f(void) unsigned int major; #ifdef CONFIG_TSEC_ENET - out_be32(scfg-etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); + /* clear BD FR bits for BE BD's and frame data */ + clrbits_be32(scfg-etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); #endif #ifdef CONFIG_FSL_IFC diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index b7458a9..006700f 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -481,7 +481,8 @@ int board_early_init_f(void) unsigned int major; #ifdef CONFIG_TSEC_ENET - out_be32(scfg-etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); + /* clear BD FR bits for BE BD's and frame data */ + clrbits_be32(scfg-etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); out_be32(scfg-etsecmcr, SCFG_ETSECCMCR_GE2_CLK125); #endif diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 42d0374..4bdc188 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -271,9 +271,6 @@ void redundant_init(struct eth_device *dev) out_be32(regs-tstat, TSTAT_CLEAR_THALT); out_be32(regs-rstat, RSTAT_CLEAR_RHALT); clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); -#ifdef CONFIG_LS102XA - setbits_be32(regs-dmactrl, DMACTRL_LE); -#endif do { uint16_t status; @@ -370,9 +367,6 @@ static void startup_tsec(struct eth_device *dev) out_be32(regs-tstat, TSTAT_CLEAR_THALT); out_be32(regs-rstat, RSTAT_CLEAR_RHALT); clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); -#ifdef CONFIG_LS102XA - setbits_be32(regs-dmactrl, DMACTRL_LE); -#endif } /* This returns the status bits of the device. The return value -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] net: tsec: Pending patches
Hello, Would you please consider applying these two net tree patches? http://patchwork.ozlabs.org/patch/299620/ (net: Merge asm/fsl_enet.h into fsl_mdio.h) http://patchwork.ozlabs.org/patch/299447/ (net: tsec: Fix NULL access in case init_phy() fails) Thanks, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] powerpc/p1_p2_rdb_pc: Fix warnings for __iomem pointers
Add the __iomem address space marker for the tsec pointers to struct tsec_mii_mng memory mapped register regions. This solves the sparse warnings for mixig normal pointers with __iomem pointers for tsec. p1_p2_rdb_pc.c:373:24: warning: incorrect type in assignment (different address spaces) p1_p2_rdb_pc.c:373:24:expected struct tsec_mii_mng [noderef] asn:2*regs p1_p2_rdb_pc.c:373:24:got struct tsec_mii_mng *noident Use TSEC_GET_MDIO_REGS_BASE() for the remaining mdio 'regs' initializations to remove the __iomem warnings and for consistency. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c index 966abb2..5f3d6fd 100644 --- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c +++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2011, 2013 Freescale Semiconductor, Inc. * * SPDX-License-Identifier:GPL-2.0+ */ @@ -354,7 +354,7 @@ int board_eth_init(bd_t *bis) puts(No address specified for VSC7385 microcode.\n); #endif - mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.regs = TSEC_GET_MDIO_REGS_BASE(1); mdio_info.name = DEFAULT_MII_NAME; fsl_pq_mdio_init(bis, mdio_info); -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/2] net: Merge asm/fsl_enet.h into fsl_mdio.h
fsl_enet.h defines the mapping of the usual MII management registers, which are included in the MDIO register block common to Freescale ethernet controllers. So it shouldn't depend on the CPU architecture but it should be actually part of the arch independent fsl_mdio.h. To remove the arch dependency, merge the content of asm/fsl_enet.h into fsl_mdio.h. Some files (like fm_eth.h) were simply including fsl_enet.h only for phy.h. These were updated to include phy.h instead. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- arch/powerpc/include/asm/fsl_enet.h | 24 board/freescale/mpc8360emds/mpc8360emds.c | 2 +- board/freescale/mpc837xemds/mpc837xemds.c | 1 - drivers/net/fm/dtsec.c| 1 - drivers/net/fm/fm.h | 2 +- drivers/net/fm/init.c | 1 + drivers/net/fm/memac.c| 1 - drivers/net/fm/tgec.c | 1 - drivers/net/fsl_mdio.c| 1 - drivers/qe/uec.h | 1 - include/fm_eth.h | 2 +- include/fsl_mdio.h| 13 - include/tsec.h| 2 +- 13 files changed, 17 insertions(+), 35 deletions(-) delete mode 100644 arch/powerpc/include/asm/fsl_enet.h diff --git a/arch/powerpc/include/asm/fsl_enet.h b/arch/powerpc/include/asm/fsl_enet.h deleted file mode 100644 index 96146b6..000 --- a/arch/powerpc/include/asm/fsl_enet.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier:GPL-2.0+ - */ - -#ifndef __ASM_PPC_FSL_ENET_H -#define __ASM_PPC_FSL_ENET_H - -#include phy.h - -struct tsec_mii_mng { - u32 miimcfg;/* MII management configuration reg */ - u32 miimcom;/* MII management command reg */ - u32 miimadd;/* MII management address reg */ - u32 miimcon;/* MII management control reg */ - u32 miimstat; /* MII management status reg */ - u32 miimind;/* MII management indication reg */ - u32 ifstat; /* Interface Status Register */ -} __attribute__ ((packed)); - -int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc); - -#endif /* __ASM_PPC_FSL_ENET_H */ diff --git a/board/freescale/mpc8360emds/mpc8360emds.c b/board/freescale/mpc8360emds/mpc8360emds.c index ac96163..5ff9dff 100644 --- a/board/freescale/mpc8360emds/mpc8360emds.c +++ b/board/freescale/mpc8360emds/mpc8360emds.c @@ -11,13 +11,13 @@ #include i2c.h #include miiphy.h #include phy.h +#include fsl_mdio.h #if defined(CONFIG_PCI) #include pci.h #endif #include spd_sdram.h #include asm/mmu.h #include asm/io.h -#include asm/fsl_enet.h #include asm/mmu.h #if defined(CONFIG_OF_LIBFDT) #include libfdt.h diff --git a/board/freescale/mpc837xemds/mpc837xemds.c b/board/freescale/mpc837xemds/mpc837xemds.c index 0a3c972..c749e55 100644 --- a/board/freescale/mpc837xemds/mpc837xemds.c +++ b/board/freescale/mpc837xemds/mpc837xemds.c @@ -10,7 +10,6 @@ #include i2c.h #include asm/io.h #include asm/fsl_mpc83xx_serdes.h -#include asm/fsl_enet.h #include spd_sdram.h #include tsec.h #include libfdt.h diff --git a/drivers/net/fm/dtsec.c b/drivers/net/fm/dtsec.c index 78bbd43..8d3dc0e 100644 --- a/drivers/net/fm/dtsec.c +++ b/drivers/net/fm/dtsec.c @@ -7,7 +7,6 @@ #include common.h #include asm/types.h #include asm/io.h -#include asm/fsl_enet.h #include asm/fsl_dtsec.h #include fsl_mdio.h #include phy.h diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 43de114..c8eba4f 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -8,8 +8,8 @@ #define __FM_H__ #include common.h +#include phy.h #include fm_eth.h -#include asm/fsl_enet.h #include asm/fsl_fman.h /* Port ID */ diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index cd787f4..7371dbf 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -6,6 +6,7 @@ #include common.h #include asm/io.h #include asm/fsl_serdes.h +#include fsl_mdio.h #include fm.h diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 592a67f..9499290 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -12,7 +12,6 @@ #include phy.h #include asm/types.h #include asm/io.h -#include asm/fsl_enet.h #include asm/fsl_memac.h #include fm.h diff --git a/drivers/net/fm/tgec.c b/drivers/net/fm/tgec.c index f450f80..5017123 100644 --- a/drivers/net/fm/tgec.c +++ b/drivers/net/fm/tgec.c @@ -12,7 +12,6 @@ #include phy.h #include asm/types.h #include asm/io.h -#include asm/fsl_enet.h #include asm/fsl_tgec.h #include fm.h diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c index 1d88e65..8d09f5d 100644 --- a/drivers/net/fsl_mdio.c +++ b/drivers/net/fsl_mdio.c @@ -11,7 +11,6 @@ #include fsl_mdio.h #include asm/io.h #include asm/errno.h -#include asm/fsl_enet.h
[U-Boot] [PATCH 1/2] net: tsec: Fix NULL access in case init_phy() fails
If the PHY is not recognized don't access phydev (NULL) and return 0 to signal failure. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index e9138f0..65fb2b0 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -590,6 +590,8 @@ static int init_phy(struct eth_device *dev) tsec_configure_serdes(priv); phydev = phy_connect(priv-bus, priv-phyaddr, dev, priv-interface); + if (!phydev) + return 0; phydev-supported = supported; phydev-advertising = phydev-supported; -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 7/9][v2] net: tsec: Use portable types and accessors for BDs
On 10/5/2013 5:49 PM, Timur Tabi wrote: On Sat, Oct 5, 2013 at 9:31 AM, Timur Tabi ti...@tabi.org wrote: + out_be32(regs-tbase, (u32)txbd[0]); + out_be32(regs-rbase, (u32)rxbd[0]); rxbd[0] is a virtual address. Doesn't rbase require a physical address? You're assuming that virt == phys. Also: - out_be32(regs-tbase, (unsigned int)(rtx.txbd[tx_idx])); - out_be32(regs-rbase, (unsigned int)(rtx.rxbd[rx_idx])); + out_be32(regs-tbase, (u32)txbd[0]); + out_be32(regs-rbase, (u32)rxbd[0]); Are you assuming that rx_idx will always be zero in this case? Hi, This is just initialization code, rx_idx and tx_idx are set to 0 just 4-5 irrelevant lines above (unfortunately format-patch doesn't catch that in the patch's context). Thanks, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 7/9][v2] net: tsec: Use portable types and accessors for BDs
On 10/5/2013 5:31 PM, Timur Tabi wrote: On Fri, Oct 4, 2013 at 11:25 AM, Claudiu Manoil claudiu.man...@freescale.com wrote: [v3] declaring the BDs as __iomem to avoid casting submitted: http://patchwork.ozlabs.org/patch/280664/ + out_be32(regs-tbase, (u32)txbd[0]); + out_be32(regs-rbase, (u32)rxbd[0]); rxbd[0] is a virtual address. Doesn't rbase require a physical address? You're assuming that virt == phys. These SoCs don't feature IOMMU so it cannot be a virtual address. I think you're suggesting that virt_to_phys() should be used to fix that, right? However, virt_to_phys() is equivalent to that simple cast in most cases as there's no CONFIG_PHYS_64BIT for the platforms with eTSEC. I'm actually not sure if there's a platform with eTSEC for which that cast wouldn't be enough. If so, it should be a separate patch as this fix would apply to existing (old) code and is out of the scope of this patch about portable accessors. Thanks. Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 7/9][v2] net: tsec: Use portable types and accessors for BDs
On 10/3/2013 9:37 PM, Scott Wood wrote: On Thu, 2013-10-03 at 14:48 +0300, Claudiu Manoil wrote: +static inline u16 read_txbd_stat(uint idx) +{ + return in_be16((u16 __iomem *)txbd[idx].status); +} + +static inline void write_txbd_stat(uint idx, u16 status) +{ + out_be16((u16 __iomem *)txbd[idx].status, status); +} + +static inline u16 read_rxbd_stat(uint idx) +{ + return in_be16((u16 __iomem *)rxbd[idx].status); +} + +static inline void write_rxbd_stat(uint idx, u16 status) +{ + out_be16((u16 __iomem *)rxbd[idx].status, status); +} Do you need __force on these to make sparse happy? No, we don't need __force in this case, in_be/out_be are less restrictive and take plain unsigned pointers (not __beNN pointers). On the other hand, they require the __iomem address space marker, to make sparse happy. I'd rather see these declared as __iomem than use casts (at which point, you probably don't need per-field accessor functions). Me too, but I wasn't sure how to do that. I thought __iomem works with pointer declarations only. But it turns out it works this way too: -static struct txbd8 txbd[TX_BUF_CNT] __aligned(8); -static struct rxbd8 rxbd[PKTBUFSRX] __aligned(8); [...] +static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); [...] - for (i = 0; read_txbd_stat(tx_idx) TXBD_READY; i++) { + for (i = 0; in_be16(txbd[tx_idx].status) TXBD_READY; i++) { [...] And sparse doesn't complain about it. In this case I'll drop the read_txbd_stat() and friends. Is this acceptable? Thanks. Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 7/9] net: tsec: Use portable types and accessors for BDs
On 10/4/2013 6:12 AM, Timur Tabi wrote: On Mon, Sep 30, 2013 at 4:44 AM, Claudiu Manoil claudiu.man...@freescale.com wrote: +#define GET_BD_STAT(T, i) be16_to_cpu((__force __be16)T##BD(i).status) +#define SET_BD_STAT(T, i, v) T##BD(i).status = (__force __u16)cpu_to_be16(v) +#define GET_BD_BLEN(T, i) be16_to_cpu((__force __be16)T##BD(i).length) +#define SET_BD_BLEN(T, i, v) T##BD(i).length = (__force __u16)cpu_to_be16(v) +#define GET_BD_BPTR(T, i) be32_to_cpu((__force __be32)T##BD(i).bufptr) +#define SET_BD_BPTR(T, i, v) T##BD(i).bufptr = (__force __u32)cpu_to_be32(v) This is pretty ugly. There's got to be a better way to handle this. Are you going to be doing stuff like this for every driver for bi-endian hardware? Some time ago I suggest that we re-purpose iowrite() and ioread() to be native-endian, and not just little endian. I think something like that would make more sense than hacky macros like this. Hi Timur, We dropped these macros in favor of the in_be/out_be() I/O accessors (see http://patchwork.ozlabs.org/patch/280285/). Regards, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 7/9][v3] net: tsec: Use portable types and accessors for BDs
Currently, the buffer descriptor (BD) fields cannot be correctly accessed by a little endian processor. This patch fixes the issue by making the access of BDs to be portable among different cpu architectures. Use portable data types for the Rx/Tx buffer descriptor fields. Use portable I/O accessors to insure that the big endian BDs are correctly accessed by little endian cpus too, and to insure proper sync with the H/W. Removed the redundant RTXBD volatile type, as proper synchronization around BD data accesses is provided by the I/O accessors now. The sparse tool was also used to verify the correctness of these changes. Cc: Scott Wood scottw...@freescale.com Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- v2: * used portable I/O accessors (in_be/out_be) * replaced macro usage * retested on p1020 (ping, tftp) v3: * txbd, rxbd declared as __iomem to avoid casting drivers/net/tsec.c | 88 -- include/tsec.h | 22 +++--- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 289229a..e354fad 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -28,13 +28,10 @@ DECLARE_GLOBAL_DATA_PTR; static uint rx_idx;/* index of the current RX buffer */ static uint tx_idx;/* index of the current TX buffer */ -typedef volatile struct rtxbd { - txbd8_t txbd[TX_BUF_CNT]; - rxbd8_t rxbd[PKTBUFSRX]; -} RTXBD; - #ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); +static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); + #else #error rtx must be 64-bit aligned #endif @@ -275,10 +272,11 @@ void redundant_init(struct eth_device *dev) clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); do { + uint16_t status; tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rx_idx].status RXBD_EMPTY; t++) { + for (t = 0; in_be16(rxbd[rx_idx].status) RXBD_EMPTY; t++) { if (t = 10 * TOUT_LOOP) { printf(%s: tsec: rx error\n, dev-name); break; @@ -288,9 +286,11 @@ void redundant_init(struct eth_device *dev) if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) fail = 0; - rtx.rxbd[rx_idx].length = 0; - rtx.rxbd[rx_idx].status = - RXBD_EMPTY | (((rx_idx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + out_be16(rxbd[rx_idx].length, 0); + status = RXBD_EMPTY; + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + out_be16(rxbd[rx_idx].status, status); rx_idx = (rx_idx + 1) % PKTBUFSRX; if (in_be32(regs-ievent) IEVENT_BSY) { @@ -319,9 +319,10 @@ void redundant_init(struct eth_device *dev) */ static void startup_tsec(struct eth_device *dev) { - int i; struct tsec_private *priv = (struct tsec_private *)dev-priv; struct tsec __iomem *regs = priv-regs; + uint16_t status; + int i; /* reset the indices to zero */ rx_idx = 0; @@ -331,24 +332,26 @@ static void startup_tsec(struct eth_device *dev) #endif /* Point to the buffer descriptors */ - out_be32(regs-tbase, (unsigned int)(rtx.txbd[tx_idx])); - out_be32(regs-rbase, (unsigned int)(rtx.rxbd[rx_idx])); + out_be32(regs-tbase, (u32)txbd[0]); + out_be32(regs-rbase, (u32)rxbd[0]); /* Initialize the Rx Buffer descriptors */ for (i = 0; i PKTBUFSRX; i++) { - rtx.rxbd[i].status = RXBD_EMPTY; - rtx.rxbd[i].length = 0; - rtx.rxbd[i].bufptr = (uint) NetRxPackets[i]; + out_be16(rxbd[i].status, RXBD_EMPTY); + out_be16(rxbd[i].length, 0); + out_be32(rxbd[i].bufptr, (u32)NetRxPackets[i]); } - rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; + status = in_be16(rxbd[PKTBUFSRX - 1].status); + out_be16(rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP); /* Initialize the TX Buffer Descriptors */ for (i = 0; i TX_BUF_CNT; i++) { - rtx.txbd[i].status = 0; - rtx.txbd[i].length = 0; - rtx.txbd[i].bufptr = 0; + out_be16(txbd[i].status, 0); + out_be16(txbd[i].length, 0); + out_be32(txbd[i].bufptr, 0); } - rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; + status = in_be16(txbd[TX_BUF_CNT - 1].status); + out_be16(txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP); #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 svr = get_svr(); @@ -372,29 +375,31 @@ static void startup_tsec(struct eth_device *dev
Re: [U-Boot] [PATCH 7/9][v2] net: tsec: Use portable types and accessors for BDs
On 10/4/2013 6:50 PM, Scott Wood wrote: On Fri, 2013-10-04 at 11:27 +0300, Claudiu Manoil wrote: On 10/3/2013 9:37 PM, Scott Wood wrote: On Thu, 2013-10-03 at 14:48 +0300, Claudiu Manoil wrote: +static inline u16 read_txbd_stat(uint idx) +{ + return in_be16((u16 __iomem *)txbd[idx].status); +} + +static inline void write_txbd_stat(uint idx, u16 status) +{ + out_be16((u16 __iomem *)txbd[idx].status, status); +} + +static inline u16 read_rxbd_stat(uint idx) +{ + return in_be16((u16 __iomem *)rxbd[idx].status); +} + +static inline void write_rxbd_stat(uint idx, u16 status) +{ + out_be16((u16 __iomem *)rxbd[idx].status, status); +} Do you need __force on these to make sparse happy? No, we don't need __force in this case, in_be/out_be are less restrictive and take plain unsigned pointers (not __beNN pointers). On the other hand, they require the __iomem address space marker, to make sparse happy. I thought you'd need __force to convert a non-iomem pointer to an __iomem pointer. I'd rather see these declared as __iomem than use casts (at which point, you probably don't need per-field accessor functions). Me too, but I wasn't sure how to do that. I thought __iomem works with pointer declarations only. But it turns out it works this way too: Even if that were the case, you could put it on the pointers, which is how it's usually used. -static struct txbd8 txbd[TX_BUF_CNT] __aligned(8); -static struct rxbd8 rxbd[PKTBUFSRX] __aligned(8); [...] +static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); [...] - for (i = 0; read_txbd_stat(tx_idx) TXBD_READY; i++) { + for (i = 0; in_be16(txbd[tx_idx].status) TXBD_READY; i++) { [...] And sparse doesn't complain about it. In this case I'll drop the read_txbd_stat() and friends. Is this acceptable? Yes. [v3] declaring the BDs as __iomem to avoid casting submitted: http://patchwork.ozlabs.org/patch/280664/ Thanks. Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 7/9][v2] net: tsec: Use portable types and accessors for BDs
Currently, the buffer descriptor (BD) fields cannot be correctly accessed by a little endian processor. This patch fixes the issue by making the access of BDs to be portable among different cpu architectures. Use portable data types for the Rx/Tx buffer descriptor fields. Use portable I/O accessors to insure that the big endian BDs are correctly accessed by little endian cpus too, and to insure proper sync with the H/W. Removed the redundant RTXBD volatile type, as proper synchronization around BD data accesses is provided by the I/O accessors now. The sparse tool was also used to verify the correctness of these changes. Cc: Scott Wood scottw...@freescale.com Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- v2: * used portable I/O accessors (in_be/out_be) * replaced macro usage * retested on p1020 (ping, tftp) drivers/net/tsec.c | 108 - include/tsec.h | 22 +-- 2 files changed, 76 insertions(+), 54 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 289229a..b48e595 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -28,13 +28,30 @@ DECLARE_GLOBAL_DATA_PTR; static uint rx_idx;/* index of the current RX buffer */ static uint tx_idx;/* index of the current TX buffer */ -typedef volatile struct rtxbd { - txbd8_t txbd[TX_BUF_CNT]; - rxbd8_t rxbd[PKTBUFSRX]; -} RTXBD; - #ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); +static struct txbd8 txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 rxbd[PKTBUFSRX] __aligned(8); + +static inline u16 read_txbd_stat(uint idx) +{ + return in_be16((u16 __iomem *)txbd[idx].status); +} + +static inline void write_txbd_stat(uint idx, u16 status) +{ + out_be16((u16 __iomem *)txbd[idx].status, status); +} + +static inline u16 read_rxbd_stat(uint idx) +{ + return in_be16((u16 __iomem *)rxbd[idx].status); +} + +static inline void write_rxbd_stat(uint idx, u16 status) +{ + out_be16((u16 __iomem *)rxbd[idx].status, status); +} + #else #error rtx must be 64-bit aligned #endif @@ -275,10 +292,11 @@ void redundant_init(struct eth_device *dev) clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); do { + uint16_t status; tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rx_idx].status RXBD_EMPTY; t++) { + for (t = 0; read_rxbd_stat(rx_idx) RXBD_EMPTY; t++) { if (t = 10 * TOUT_LOOP) { printf(%s: tsec: rx error\n, dev-name); break; @@ -288,9 +306,11 @@ void redundant_init(struct eth_device *dev) if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) fail = 0; - rtx.rxbd[rx_idx].length = 0; - rtx.rxbd[rx_idx].status = - RXBD_EMPTY | (((rx_idx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + out_be16((u16 __iomem *)rxbd[rx_idx].length, 0); + status = RXBD_EMPTY; + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + write_rxbd_stat(rx_idx, status); rx_idx = (rx_idx + 1) % PKTBUFSRX; if (in_be32(regs-ievent) IEVENT_BSY) { @@ -319,9 +339,10 @@ void redundant_init(struct eth_device *dev) */ static void startup_tsec(struct eth_device *dev) { - int i; struct tsec_private *priv = (struct tsec_private *)dev-priv; struct tsec __iomem *regs = priv-regs; + uint16_t status; + int i; /* reset the indices to zero */ rx_idx = 0; @@ -331,24 +352,26 @@ static void startup_tsec(struct eth_device *dev) #endif /* Point to the buffer descriptors */ - out_be32(regs-tbase, (unsigned int)(rtx.txbd[tx_idx])); - out_be32(regs-rbase, (unsigned int)(rtx.rxbd[rx_idx])); + out_be32(regs-tbase, (u32)txbd[0]); + out_be32(regs-rbase, (u32)rxbd[0]); /* Initialize the Rx Buffer descriptors */ for (i = 0; i PKTBUFSRX; i++) { - rtx.rxbd[i].status = RXBD_EMPTY; - rtx.rxbd[i].length = 0; - rtx.rxbd[i].bufptr = (uint) NetRxPackets[i]; + write_rxbd_stat(i, RXBD_EMPTY); + out_be16((u16 __iomem *)rxbd[i].length, 0); + out_be32((u32 __iomem *)rxbd[i].bufptr, (u32)NetRxPackets[i]); } - rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; + status = read_rxbd_stat(PKTBUFSRX - 1); + write_rxbd_stat(PKTBUFSRX - 1, status | RXBD_WRAP); /* Initialize the TX Buffer Descriptors */ for (i = 0; i TX_BUF_CNT; i++) { - rtx.txbd[i].status = 0; - rtx.txbd[i].length = 0; - rtx.txbd[i].bufptr = 0; + write_txbd_stat(i, 0
Re: [U-Boot] [PATCH 7/9] net: tsec: Use portable types and accessors for BDs
On 10/3/2013 1:15 AM, Scott Wood wrote: [snip] Yeah, it doesn't help when both types of accesses show up when searching for the ring, and accessors exist with both possible argument orderings. Especially when a driver has custom accessors. It's OK to use explicit synchronization rather than I/O accessors, if you're careful to ensure that it's correct. It looks like drivers/net/fec_mxc.c in U-Boot is an example that uses I/O accessors on ring data, e.g.: writew(length, fec-tbd_base[fec-tbd_index].data_length); Hi Scott, I sent a v2 for this patch (the next 2 patches in the series are not affected by this one): http://patchwork.ozlabs.org/patch/280285/ In this version I dropped the macro usage and used I/O accessors for the ring data, as discussed. This approach does not require the explicit __beNN type for the BD fields, it also removes the need to declare the BD structures as volatile and it's safer because in_be()/ out_be() enforce HW sync. Thanks, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 7/9] net: tsec: Use portable types and accessors for BDs
On 10/1/2013 9:50 PM, Scott Wood wrote: On Tue, 2013-10-01 at 14:38 +0300, Claudiu Manoil wrote: On 10/1/2013 2:22 AM, Scott Wood wrote: On Mon, 2013-09-30 at 12:44 +0300, Claudiu Manoil wrote: +static RTXBD rtx __aligned(8); +#define RXBD(i) rtx.rxbd[i] +#define TXBD(i) rtx.txbd[i] +#define GET_BD_STAT(T, i) be16_to_cpu((__force __be16)T##BD(i).status) +#define SET_BD_STAT(T, i, v) T##BD(i).status = (__force __u16)cpu_to_be16(v) +#define GET_BD_BLEN(T, i) be16_to_cpu((__force __be16)T##BD(i).length) +#define SET_BD_BLEN(T, i, v) T##BD(i).length = (__force __u16)cpu_to_be16(v) +#define GET_BD_BPTR(T, i) be32_to_cpu((__force __be32)T##BD(i).bufptr) +#define SET_BD_BPTR(T, i, v) T##BD(i).bufptr = (__force __u32)cpu_to_be32(v) Why the forcing? Can't you declare the data with __be16/__be32? The __force annotation is obviously needed to suppress the sparse warnings due to BD data declaration type not being __bexx, but the generic uintxx_t, as you noticed as well. Now, why I didn't use __bexx instead? The main reason would be maintainability: the DMA descriptors may not be in big endian format exclusively. The eTSEC hw may actually have an option to interpret the DMA descriptors in little endian format. May have or does have? If it does have such a feature, do you plan to use it? Usually I have not seen such features used for (e.g.) little-endian PCI devices on big endian hosts. I has that option, but I don't really plan to use it, clearly not for big endian hosts. The may have was for future little endian hosts. But I think this option is not really needed by the uboot driver so doing the byte swapping in software should be ok (i.e. performance wise). What's wrong with: for (t = 0; in_be16(rtx.rxbd[rx_idx].status) RXBD_EMPTY; t++) { Or if you don't want to use I/O accessors on the DMA descriptors (Is synchronization ensured some other way? We had problems with this in the Linux driver before...): Synchronization here is is insured by declaring the RTXBD structure type as volatile (see RTXBD declaration, a couple of lines above). That does not achieve hardware synchronization, and even the effects on the compiler are questionable due to volatile's vague semantics. The existing code has been working this way for quite a while on the mpc85xx platforms, It was working for a while in Linux as well, until we encountered a workload where it didn't (though granted, there was no volatile in that case). See Linux commit 3b6330ce2a3e1f152f79a6203f73d23356e243a7 Good point, I guess it would be safer too use some memory barriers around accesses to BD fields in the uboot driver too. However some portable barriers would be needed, eieio() doesn't have an equivalent for ARM. FWIW, I see some other places in U-Boot's TSEC driver that use out_be32() on the descriptors (e.g. startup_tsec after Point to the buffer descriptors). That's only to program the tbase and rbase registers with the physical address of the Tx/Rx BD rings' base. so I thought it would be better not to change this approach. Using i/o accessors for the Buffer Descriptors would be a significant change, and I don't see how to argue such a change: why would the I/O accessors be better than the current approach - i.e. declaring the DMA descriptors as volatile? Is there something wrong with about volatile usage in this case? (afaik, this is a case were the volatile declaration is permitted) Also, there doesn't seem to be other net drivers using I/O accessors for the BD rings. I picked some random examples, and the first driver in Linux in which I could quickly find the BD rings uses I/O accessors (drivers/net/ethernet/realtek/8319too.c). I then checked its U-Boot eqivalent (drivers/net/rtl8139.c) and it also uses I/O accessors for the descriptors. I actually meant accessing buffer descriptor fields (like status, length, dma address). As you can see in this example from linux 8319too.c's Rx routine, there's no I/O accessor involved: /* read size+status of next frame from DMA ring buffer */ rx_status = le32_to_cpu (*(__le32 *) (rx_ring + ring_offset)); However the driver does use a rmb() just before this line. for (t = 0; be16_to_cpup(rtx.rxbd[rx_idx].status) RXBD_EMPTY; t++) { I opted for using macros instead due to code maintainability, Obfuscatory macros do not help. and to avoid overly long lines (80) You could factor out an rxbd_empty() function, or factor that loop out to be its own function, or have a local variable point to rtx.rxbd[rx_idx]... and to better control these changes. For instance, if etsec were to access it's BDs in little endian format in the future, Either don't do that (preferred option), or at that point add tsec16_to_cpup() and friends. I'll have a try with the portable I/O accessors (in_be, out_be) to see how it works that way. Thanks, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de
Re: [U-Boot] [PATCH 7/9] net: tsec: Use portable types and accessors for BDs
On 10/1/2013 2:22 AM, Scott Wood wrote: On Mon, 2013-09-30 at 12:44 +0300, Claudiu Manoil wrote: +static RTXBD rtx __aligned(8); +#define RXBD(i) rtx.rxbd[i] +#define TXBD(i) rtx.txbd[i] +#define GET_BD_STAT(T, i) be16_to_cpu((__force __be16)T##BD(i).status) +#define SET_BD_STAT(T, i, v) T##BD(i).status = (__force __u16)cpu_to_be16(v) +#define GET_BD_BLEN(T, i) be16_to_cpu((__force __be16)T##BD(i).length) +#define SET_BD_BLEN(T, i, v) T##BD(i).length = (__force __u16)cpu_to_be16(v) +#define GET_BD_BPTR(T, i) be32_to_cpu((__force __be32)T##BD(i).bufptr) +#define SET_BD_BPTR(T, i, v) T##BD(i).bufptr = (__force __u32)cpu_to_be32(v) Why the forcing? Can't you declare the data with __be16/__be32? The __force annotation is obviously needed to suppress the sparse warnings due to BD data declaration type not being __bexx, but the generic uintxx_t, as you noticed as well. Now, why I didn't use __bexx instead? The main reason would be maintainability: the DMA descriptors may not be in big endian format exclusively. The eTSEC hw may actually have an option to interpret the DMA descriptors in little endian format. If we decide to use that option for future platforms, then the __bexx type wouldn't be correct anymore. Besides, I noticed that most drivers prefer to use the generic type uintxx_t for buffer descriptors, instead of the annotated __bexx/__lexx types. #else #error rtx must be 64-bit aligned #endif @@ -275,10 +283,11 @@ void redundant_init(struct eth_device *dev) clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); do { + uint16_t status; tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rx_idx].status RXBD_EMPTY; t++) { + for (t = 0; GET_BD_STAT(RX, rx_idx) RXBD_EMPTY; t++) { What's wrong with: for (t = 0; in_be16(rtx.rxbd[rx_idx].status) RXBD_EMPTY; t++) { Or if you don't want to use I/O accessors on the DMA descriptors (Is synchronization ensured some other way? We had problems with this in the Linux driver before...): Synchronization here is is insured by declaring the RTXBD structure type as volatile (see RTXBD declaration, a couple of lines above). The existing code has been working this way for quite a while on the mpc85xx platforms, so I thought it would be better not to change this approach. Using i/o accessors for the Buffer Descriptors would be a significant change, and I don't see how to argue such a change: why would the I/O accessors be better than the current approach - i.e. declaring the DMA descriptors as volatile? Is there something wrong with about volatile usage in this case? (afaik, this is a case were the volatile declaration is permitted) Also, there doesn't seem to be other net drivers using I/O accessors for the BD rings. for (t = 0; be16_to_cpup(rtx.rxbd[rx_idx].status) RXBD_EMPTY; t++) { I opted for using macros instead due to code maintainability, and to avoid overly long lines (80) and to better control these changes. For instance, if etsec were to access it's BDs in little endian format in the future, then it would be enough to update the implementation of the macro accessors without touching the whole code. -Scott Thanks for reviewing this. Regards, Claudiu ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/9] net: Fix mcast function pointer prototype
This fixes the following compiler warnings when activating CONFIG_MCAST_TFTP: tsec.c: In function 'tsec_mcast_addr': tsec.c:130:2: warning: passing argument 2 of 'ether_crc' makes pointer from integer without a cast [enabled by default] In file included from /work/u-boot-net/include/common.h:874:0, from tsec.c:15: /work/u-boot-net/include/net.h:189:5: note: expected 'const unsigned char *' but argument is of type 'u8' tsec.c: In function 'tsec_initialize': tsec.c:646:13: warning: assignment from incompatible pointer type [enabled by default] eth.c: In function 'eth_mcast_join': eth.c:358:2: warning: passing argument 2 of 'eth_current-mcast' makes integer from pointer without a cast [enabled by default] eth.c:358:2: note: expected 'u32' but argument is of type 'u8 *' In the eth_mcast_join() implementation, eth_current-mcast() takes a u8 pointer to the multicast mac address and not a ip address value as implied by its prototype. Fix parameter type mismatch for tsec_macst_addr() (tsec.c): ether_crc() takes a u8 pointer not a u8 value. mcast() is given a u8 pointer to the multicats mac address. Update parameter type for the rest of mcast() instances. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/rtl8139.c | 2 +- drivers/net/tsec.c| 4 ++-- include/net.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 4186699..208ce5c 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -188,7 +188,7 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); #ifdef CONFIG_MCAST_TFTP/* This driver already accepts all b/mcast */ -static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set) +static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set) { return (0); } diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index f5e314b..3428dd0 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -120,14 +120,14 @@ static void tsec_configure_serdes(struct tsec_private *priv) * for PowerPC (tm) is usually the case) in the tregister holds * the entry. */ static int -tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) +tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { struct tsec_private *priv = privlist[1]; volatile tsec_t *regs = priv-regs; volatile u32 *reg_array, value; u8 result, whichbit, whichreg; - result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) 24) 0xff); + result = (u8)((ether_crc(MAC_ADDR_LEN, mcast_mac) 24) 0xff); whichbit = result 0x1f; /* the 5 LSB = which bit to set */ whichreg = result 5; /* the 3 MSB = which reg to set it in */ value = (1 (31-whichbit)); diff --git a/include/net.h b/include/net.h index 5aedc17..0802fad 100644 --- a/include/net.h +++ b/include/net.h @@ -89,7 +89,7 @@ struct eth_device { int (*recv) (struct eth_device *); void (*halt) (struct eth_device *); #ifdef CONFIG_MCAST_TFTP - int (*mcast) (struct eth_device *, u32 ip, u8 set); + int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set); #endif int (*write_hwaddr) (struct eth_device *); struct eth_device *next; -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 5/9] net: fsl_mdio: Fix warnings for __iomem pointers
Add the __iomem address space marker for the tsec pointers to struct tsec_mii_mng memory mapped register regions. This solves the sparse warnings for mixig normal pointers with __iomem pointers for tsec. E.g.: fsl_mdio.c:34:19: warning: incorrect type in argument 1 (different address spaces) fsl_mdio.c:34:19:expected unsigned int volatile [noderef] asn:2*addr fsl_mdio.c:34:19:got unsigned int *noident [...] tsec.c:91:35: warning: incorrect type in argument 1 (different address spaces) tsec.c:91:35:expected struct tsec_mii_mng *phyregs tsec.c:91:35:got struct tsec_mii_mng [noderef] asn:2*phyregs_sgmii [...] tsec.c:680:19: warning: incorrect type in assignment (different address spaces) tsec.c:680:19:expected struct tsec_mii_mng *regs tsec.c:680:19:got struct tsec_mii_mng [noderef] asn:2*noident [...] Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/fsl_mdio.c | 17 ++--- include/fsl_mdio.h | 8 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c index ce36bd7..1d88e65 100644 --- a/drivers/net/fsl_mdio.c +++ b/drivers/net/fsl_mdio.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010 Freescale Semiconductor, Inc. + * Copyright 2009-2010, 2013 Freescale Semiconductor, Inc. * Jun-jie Zhang b18...@freescale.com * Mingkai Hu mingkai...@freescale.com * @@ -13,7 +13,7 @@ #include asm/errno.h #include asm/fsl_enet.h -void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr, +void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int regnum, int value) { int timeout = 100; @@ -26,7 +26,7 @@ void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr, ; } -int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr, +int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int regnum) { int value; @@ -57,7 +57,8 @@ int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr, static int fsl_pq_mdio_reset(struct mii_dev *bus) { - struct tsec_mii_mng *regs = bus-priv; + struct tsec_mii_mng __iomem *regs = + (struct tsec_mii_mng __iomem *)bus-priv; /* Reset MII (due to new addresses) */ out_be32(regs-miimcfg, MIIMCFG_RESET_MGMT); @@ -72,7 +73,8 @@ static int fsl_pq_mdio_reset(struct mii_dev *bus) int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum) { - struct tsec_mii_mng *phyregs = bus-priv; + struct tsec_mii_mng __iomem *phyregs = + (struct tsec_mii_mng __iomem *)bus-priv; return tsec_local_mdio_read(phyregs, addr, dev_addr, regnum); } @@ -80,7 +82,8 @@ int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum) int tsec_phy_write(struct mii_dev *bus, int addr, int dev_addr, int regnum, u16 value) { - struct tsec_mii_mng *phyregs = bus-priv; + struct tsec_mii_mng __iomem *phyregs = + (struct tsec_mii_mng __iomem *)bus-priv; tsec_local_mdio_write(phyregs, addr, dev_addr, regnum, value); @@ -101,7 +104,7 @@ int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info) bus-reset = fsl_pq_mdio_reset; sprintf(bus-name, info-name); - bus-priv = info-regs; + bus-priv = (void *)info-regs; return mdio_register(bus); } diff --git a/include/fsl_mdio.h b/include/fsl_mdio.h index 9c0b762..b58713d 100644 --- a/include/fsl_mdio.h +++ b/include/fsl_mdio.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2012 Freescale Semiconductor, Inc. + * Copyright 2009-2012, 2013 Freescale Semiconductor, Inc. * Jun-jie Zhang b18...@freescale.com * Mingkai Hu mingkai...@freescale.com * @@ -31,9 +31,9 @@ #define MIIMIND_BUSY 0x0001 #define MIIMIND_NOTVALID 0x0004 -void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr, +void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int reg, int value); -int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr, +int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int regnum); int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum); int tsec_phy_write(struct mii_dev *bus, int addr, int dev_addr, int regnum, @@ -44,7 +44,7 @@ int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, int regnum); struct fsl_pq_mdio_info { - struct tsec_mii_mng *regs; + struct tsec_mii_mng __iomem *regs; char *name; }; int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info); -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman
[U-Boot] [PATCH 3/9] net: tsec: Fix priv pointer in tsec_mcast_addr()
Access to privlist[1] (hardcoded referece to the 2nd tsec's priv area) is neither correct nor does it make sense in the current context. Each tsec dev has access to its own priv instance only, and hence to its own set of group address registers (GADDR) to filter multicast addresses. This fix leads to removal of the unused (faulty) privlist[] and related global static vars. Note that mcast() can be called only after eth_device allocation and init, and hence after priv area allocation, so dev-priv is correctly initialized upon mcast() call. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 9ffc801..9371ffa 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -33,11 +33,6 @@ typedef volatile struct rtxbd { rxbd8_t rxbd[PKTBUFSRX]; } RTXBD; -#define MAXCONTROLLERS (8) - -static struct tsec_private *privlist[MAXCONTROLLERS]; -static int num_tsecs = 0; - #ifdef __GNUC__ static RTXBD rtx __attribute__ ((aligned(8))); #else @@ -122,7 +117,7 @@ static void tsec_configure_serdes(struct tsec_private *priv) static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { - struct tsec_private *priv = privlist[1]; + struct tsec_private *priv = (struct tsec_private *)dev-priv; struct tsec __iomem *regs = priv-regs; u32 result, value; u8 whichbit, whichreg; @@ -625,7 +620,6 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info) if (NULL == priv) return 0; - privlist[num_tsecs++] = priv; priv-regs = tsec_info-regs; priv-phyregs_sgmii = tsec_info-miiregs_sgmii; -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/9] net: tsec: Driver portability fixes and cleanup
Though the first 3 patches fix tsec's driver mcast() instance primarily, the fix from net.h was propagated to other drivers too, as appropriate. Notably, these fixes also end up in removal of some unwanted global static vars from the tsec driver. The rest of the patches are driver portability fixes, so that the tsec driver may work on little endian architectures as well. The issues uncovered by the sparse tool where also addressed in the process. All checkpatch issues were addressed, including those on existing code. Only a couple of CamelCase warnings remain, coming from the net stack code (see NetReceive(), NetRxPackets[]). Claudiu Manoil (9): net: Fix mcast function pointer prototype net: tsec: Fix and cleanup tsec_mcast_addr() net: tsec: Fix priv pointer in tsec_mcast_addr() net: tsec: Cleanup tsec regs init and fix __iomem warns net: fsl_mdio: Fix warnings for __iomem pointers net: tsec: Fix CamelCase issues around BD code net: tsec: Use portable types and accessors for BDs net: tsec: Use portable regs type (uint-u32) net: tsec: Fix mac addr setup portability, cleanup drivers/net/fsl_mdio.c | 17 ++- drivers/net/rtl8139.c | 2 +- drivers/net/tsec.c | 200 ++-- include/fsl_mdio.h | 8 +- include/net.h | 2 +- include/tsec.h | 345 + 6 files changed, 296 insertions(+), 278 deletions(-) -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 4/9] net: tsec: Cleanup tsec regs init and fix __iomem warns
Remove tsec_t typedef. Define macros as getters of tsec and mdio register memory regions, for consistent initialization of various 'regs' fields and also to manage overly long initialization lines. Use the __iomem address space marker to address sparse warnings in tsec.c where IO accessors are used, like: tsec.c:394:19: warning: incorrect type in argument 1 (different address spaces) tsec.c:394:19:expected unsigned int volatile [noderef] asn:2*addr tsec.c:394:19:got unsigned int *noident [...] Add the __iomem address space marker for the tsec pointers to struct tsec_mii_mng memory mapped register regions. This solves the sparse warnings for mixig normal pointers with __iomem pointers for tsec. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 26 +- include/tsec.h | 39 +-- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 9371ffa..adb6c12 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -5,7 +5,7 @@ * terms of the GNU Public License, Version 2, incorporated * herein by reference. * - * Copyright 2004-2011 Freescale Semiconductor, Inc. + * Copyright 2004-2011, 2013 Freescale Semiconductor, Inc. * (C) Copyright 2003, Motorola, Inc. * author Andy Fleming * @@ -52,7 +52,7 @@ static struct tsec_info_struct tsec_info[] = { #endif #ifdef CONFIG_MPC85XX_FEC { - .regs = (tsec_t *)(TSEC_BASE_ADDR + 0x2000), + .regs = TSEC_GET_REGS(2, 0x2000), .devname = CONFIG_MPC85XX_FEC_NAME, .phyaddr = FEC_PHY_ADDR, .flags = FEC_FLAGS, @@ -141,7 +141,7 @@ tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) * those we don't care about (unless zero is bad, in which case, * choose a more appropriate value) */ -static void init_registers(tsec_t *regs) +static void init_registers(struct tsec __iomem *regs) { /* Clear IEVENT */ out_be32(regs-ievent, IEVENT_INIT_CLEAR); @@ -188,7 +188,7 @@ static void init_registers(tsec_t *regs) */ static void adjust_link(struct tsec_private *priv, struct phy_device *phydev) { - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; u32 ecntrl, maccfg2; if (!phydev-link) { @@ -242,7 +242,7 @@ static void adjust_link(struct tsec_private *priv, struct phy_device *phydev) void redundant_init(struct eth_device *dev) { struct tsec_private *priv = dev-priv; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; uint t, count = 0; int fail = 1; static const u8 pkt[] = { @@ -321,7 +321,7 @@ static void startup_tsec(struct eth_device *dev) { int i; struct tsec_private *priv = (struct tsec_private *)dev-priv; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; /* reset the indices to zero */ rxIdx = 0; @@ -375,7 +375,7 @@ static int tsec_send(struct eth_device *dev, void *packet, int length) int i; int result = 0; struct tsec_private *priv = (struct tsec_private *)dev-priv; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; /* Find an empty buffer descriptor */ for (i = 0; rtx.txbd[txIdx].status TXBD_READY; i++) { @@ -411,7 +411,7 @@ static int tsec_recv(struct eth_device *dev) { int length; struct tsec_private *priv = (struct tsec_private *)dev-priv; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; while (!(rtx.rxbd[rxIdx].status RXBD_EMPTY)) { @@ -447,7 +447,7 @@ static int tsec_recv(struct eth_device *dev) static void tsec_halt(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev-priv; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); setbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); @@ -473,7 +473,7 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) char tmpbuf[MAC_ADDR_LEN]; int i; struct tsec_private *priv = (struct tsec_private *)dev-priv; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; int ret; /* Make sure the controller is stopped */ @@ -521,7 +521,7 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) static phy_interface_t tsec_get_interface(struct tsec_private *priv) { - tsec_t *regs = priv-regs; + struct tsec __iomem *regs = priv-regs; u32 ecntrl; ecntrl = in_be32(regs-ecntrl); @@ -570,7 +570,7 @@ static int init_phy(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev-priv; struct phy_device *phydev; - tsec_t *regs = priv-regs; + struct tsec __iomem *regs
[U-Boot] [PATCH 9/9] net: tsec: Fix mac addr setup portability, cleanup
Fix the 32-bit memory access that is not endianess safe, i.e. not giving the desired byte layout for LE cpus: tempval = *((uint *) (tmpbuf + 4)), where 'char tmpbuf[]'. Free the stack from rendundant local vars: tmpbuf[] and i. Use a portable type (u32) for the 32bit tsec register value holder: tempval. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 5dfdc94..44cead9 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -486,11 +486,9 @@ static void tsec_halt(struct eth_device *dev) */ static int tsec_init(struct eth_device *dev, bd_t * bd) { - uint tempval; - char tmpbuf[MAC_ADDR_LEN]; - int i; struct tsec_private *priv = (struct tsec_private *)dev-priv; struct tsec __iomem *regs = priv-regs; + u32 tempval; int ret; /* Make sure the controller is stopped */ @@ -503,16 +501,16 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) out_be32(regs-ecntrl, ECNTRL_INIT_SETTINGS); /* Copy the station address into the address registers. -* Backwards, because little endian MACS are dumb */ - for (i = 0; i MAC_ADDR_LEN; i++) - tmpbuf[MAC_ADDR_LEN - 1 - i] = dev-enetaddr[i]; - - tempval = (tmpbuf[0] 24) | (tmpbuf[1] 16) | (tmpbuf[2] 8) | - tmpbuf[3]; +* For a station address of 0x12345678ABCD in transmission +* order (BE), MACnADDR1 is set to 0xCDAB7856 and +* MACnADDR2 is set to 0x3412. +*/ + tempval = (dev-enetaddr[5] 24) | (dev-enetaddr[4] 16) | + (dev-enetaddr[3] 8) | dev-enetaddr[2]; out_be32(regs-macstnaddr1, tempval); - tempval = *((uint *) (tmpbuf + 4)); + tempval = (dev-enetaddr[1] 24) | (dev-enetaddr[0] 16); out_be32(regs-macstnaddr2, tempval); -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 8/9] net: tsec: Use portable regs type (uint-u32)
Use cross arch portable u32 instead of uint for the tsec registers. Remove the typedefs for the register struct definitions in the process. Fix long lines. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 2 +- include/tsec.h | 278 ++--- 2 files changed, 139 insertions(+), 141 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index cf99546..5dfdc94 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -177,7 +177,7 @@ static void init_registers(struct tsec __iomem *regs) out_be32(regs-rctrl, 0x); /* Init RMON mib registers */ - memset((void *)(regs-rmon), 0, sizeof(rmon_mib_t)); + memset((void *)regs-rmon, 0, sizeof(regs-rmon)); out_be32(regs-rmon.cam1, 0x); out_be32(regs-rmon.cam2, 0x); diff --git a/include/tsec.h b/include/tsec.h index 95054be..1046426 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -210,179 +210,177 @@ struct rxbd8 { uint32_t bufptr; /* Buffer Pointer */ }; -typedef struct rmon_mib -{ +struct tsec_rmon_mib { /* Transmit and Receive Counters */ - uinttr64; /* Transmit and Receive 64-byte Frame Counter */ - uinttr127; /* Transmit and Receive 65-127 byte Frame Counter */ - uinttr255; /* Transmit and Receive 128-255 byte Frame Counter */ - uinttr511; /* Transmit and Receive 256-511 byte Frame Counter */ - uinttr1k; /* Transmit and Receive 512-1023 byte Frame Counter */ - uinttrmax; /* Transmit and Receive 1024-1518 byte Frame Counter */ - uinttrmgv; /* Transmit and Receive 1519-1522 byte Good VLAN Frame */ + u32 tr64; /* Tx/Rx 64-byte Frame Counter */ + u32 tr127; /* Tx/Rx 65-127 byte Frame Counter */ + u32 tr255; /* Tx/Rx 128-255 byte Frame Counter */ + u32 tr511; /* Tx/Rx 256-511 byte Frame Counter */ + u32 tr1k; /* Tx/Rx 512-1023 byte Frame Counter */ + u32 trmax; /* Tx/Rx 1024-1518 byte Frame Counter */ + u32 trmgv; /* Tx/Rx 1519-1522 byte Good VLAN Frame */ /* Receive Counters */ - uintrbyt; /* Receive Byte Counter */ - uintrpkt; /* Receive Packet Counter */ - uintrfcs; /* Receive FCS Error Counter */ - uintrmca; /* Receive Multicast Packet (Counter) */ - uintrbca; /* Receive Broadcast Packet */ - uintrxcf; /* Receive Control Frame Packet */ - uintrxpf; /* Receive Pause Frame Packet */ - uintrxuo; /* Receive Unknown OP Code */ - uintraln; /* Receive Alignment Error */ - uintrflr; /* Receive Frame Length Error */ - uintrcde; /* Receive Code Error */ - uintrcse; /* Receive Carrier Sense Error */ - uintrund; /* Receive Undersize Packet */ - uintrovr; /* Receive Oversize Packet */ - uintrfrg; /* Receive Fragments */ - uintrjbr; /* Receive Jabber */ - uintrdrp; /* Receive Drop */ + u32 rbyt; /* Receive Byte Counter */ + u32 rpkt; /* Receive Packet Counter */ + u32 rfcs; /* Receive FCS Error Counter */ + u32 rmca; /* Receive Multicast Packet (Counter) */ + u32 rbca; /* Receive Broadcast Packet */ + u32 rxcf; /* Receive Control Frame Packet */ + u32 rxpf; /* Receive Pause Frame Packet */ + u32 rxuo; /* Receive Unknown OP Code */ + u32 raln; /* Receive Alignment Error */ + u32 rflr; /* Receive Frame Length Error */ + u32 rcde; /* Receive Code Error */ + u32 rcse; /* Receive Carrier Sense Error */ + u32 rund; /* Receive Undersize Packet */ + u32 rovr; /* Receive Oversize Packet */ + u32 rfrg; /* Receive Fragments */ + u32 rjbr; /* Receive Jabber */ + u32 rdrp; /* Receive Drop */ /* Transmit Counters */ - uinttbyt; /* Transmit Byte Counter */ - uinttpkt; /* Transmit Packet */ - uinttmca; /* Transmit Multicast Packet */ - uinttbca; /* Transmit Broadcast Packet */ - uinttxpf; /* Transmit Pause Control Frame */ - uinttdfr; /* Transmit Deferral Packet */ - uinttedf; /* Transmit Excessive Deferral Packet */ - uinttscl; /* Transmit Single Collision Packet */ + u32
[U-Boot] [PATCH 6/9] net: tsec: Fix CamelCase issues around BD code
Fix bufPtr and the rxIdx/ txIdx occurrences to solve the related checkpatch warnings for the coming patches. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 60 +++--- include/tsec.h | 4 ++-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index adb6c12..289229a 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -25,8 +25,8 @@ DECLARE_GLOBAL_DATA_PTR; #define TX_BUF_CNT 2 -static uint rxIdx; /* index of the current RX buffer */ -static uint txIdx; /* index of the current TX buffer */ +static uint rx_idx;/* index of the current RX buffer */ +static uint tx_idx;/* index of the current TX buffer */ typedef volatile struct rtxbd { txbd8_t txbd[TX_BUF_CNT]; @@ -278,20 +278,20 @@ void redundant_init(struct eth_device *dev) tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rxIdx].status RXBD_EMPTY; t++) { + for (t = 0; rtx.rxbd[rx_idx].status RXBD_EMPTY; t++) { if (t = 10 * TOUT_LOOP) { printf(%s: tsec: rx error\n, dev-name); break; } } - if (!memcmp(pkt, (void *)NetRxPackets[rxIdx], sizeof(pkt))) + if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) fail = 0; - rtx.rxbd[rxIdx].length = 0; - rtx.rxbd[rxIdx].status = - RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); - rxIdx = (rxIdx + 1) % PKTBUFSRX; + rtx.rxbd[rx_idx].length = 0; + rtx.rxbd[rx_idx].status = + RXBD_EMPTY | (((rx_idx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + rx_idx = (rx_idx + 1) % PKTBUFSRX; if (in_be32(regs-ievent) IEVENT_BSY) { out_be32(regs-ievent, IEVENT_BSY); @@ -324,21 +324,21 @@ static void startup_tsec(struct eth_device *dev) struct tsec __iomem *regs = priv-regs; /* reset the indices to zero */ - rxIdx = 0; - txIdx = 0; + rx_idx = 0; + tx_idx = 0; #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 uint svr; #endif /* Point to the buffer descriptors */ - out_be32(regs-tbase, (unsigned int)(rtx.txbd[txIdx])); - out_be32(regs-rbase, (unsigned int)(rtx.rxbd[rxIdx])); + out_be32(regs-tbase, (unsigned int)(rtx.txbd[tx_idx])); + out_be32(regs-rbase, (unsigned int)(rtx.rxbd[rx_idx])); /* Initialize the Rx Buffer descriptors */ for (i = 0; i PKTBUFSRX; i++) { rtx.rxbd[i].status = RXBD_EMPTY; rtx.rxbd[i].length = 0; - rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i]; + rtx.rxbd[i].bufptr = (uint) NetRxPackets[i]; } rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; @@ -346,7 +346,7 @@ static void startup_tsec(struct eth_device *dev) for (i = 0; i TX_BUF_CNT; i++) { rtx.txbd[i].status = 0; rtx.txbd[i].length = 0; - rtx.txbd[i].bufPtr = 0; + rtx.txbd[i].bufptr = 0; } rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; @@ -378,31 +378,31 @@ static int tsec_send(struct eth_device *dev, void *packet, int length) struct tsec __iomem *regs = priv-regs; /* Find an empty buffer descriptor */ - for (i = 0; rtx.txbd[txIdx].status TXBD_READY; i++) { + for (i = 0; rtx.txbd[tx_idx].status TXBD_READY; i++) { if (i = TOUT_LOOP) { debug(%s: tsec: tx buffers full\n, dev-name); return result; } } - rtx.txbd[txIdx].bufPtr = (uint) packet; - rtx.txbd[txIdx].length = length; - rtx.txbd[txIdx].status |= + rtx.txbd[tx_idx].bufptr = (uint) packet; + rtx.txbd[tx_idx].length = length; + rtx.txbd[tx_idx].status |= (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); /* Tell the DMA to go */ out_be32(regs-tstat, TSTAT_CLEAR_THALT); /* Wait for buffer to be transmitted */ - for (i = 0; rtx.txbd[txIdx].status TXBD_READY; i++) { + for (i = 0; rtx.txbd[tx_idx].status TXBD_READY; i++) { if (i = TOUT_LOOP) { debug(%s: tsec: tx error\n, dev-name); return result; } } - txIdx = (txIdx + 1) % TX_BUF_CNT; - result = rtx.txbd[txIdx].status TXBD_STATS; + tx_idx = (tx_idx + 1) % TX_BUF_CNT; + result = rtx.txbd[tx_idx].status TXBD_STATS; return result; } @@ -413,25 +413,25 @@ static int tsec_recv(struct eth_device
[U-Boot] [PATCH 7/9] net: tsec: Use portable types and accessors for BDs
Currently, the buffer descriptor (BD) fields cannot be correctly accessed by a little endian processor. This patch fixes the issue by making the access of BDs to be portable among different cpu architectures. Use portable data types for the Rx/Tx buffer descriptor fields. Add macro accessors to insure that the big endian buffer descriptors are correctly accessed by the little endian cpus too. Sparse tool was also used to verify the correctness of these conversion macros. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 89 -- include/tsec.h | 22 ++ 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 289229a..cf99546 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -29,12 +29,20 @@ static uint rx_idx; /* index of the current RX buffer */ static uint tx_idx;/* index of the current TX buffer */ typedef volatile struct rtxbd { - txbd8_t txbd[TX_BUF_CNT]; - rxbd8_t rxbd[PKTBUFSRX]; + struct txbd8 txbd[TX_BUF_CNT]; + struct rxbd8 rxbd[PKTBUFSRX]; } RTXBD; #ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); +static RTXBD rtx __aligned(8); +#define RXBD(i) rtx.rxbd[i] +#define TXBD(i) rtx.txbd[i] +#define GET_BD_STAT(T, i) be16_to_cpu((__force __be16)T##BD(i).status) +#define SET_BD_STAT(T, i, v) T##BD(i).status = (__force __u16)cpu_to_be16(v) +#define GET_BD_BLEN(T, i) be16_to_cpu((__force __be16)T##BD(i).length) +#define SET_BD_BLEN(T, i, v) T##BD(i).length = (__force __u16)cpu_to_be16(v) +#define GET_BD_BPTR(T, i) be32_to_cpu((__force __be32)T##BD(i).bufptr) +#define SET_BD_BPTR(T, i, v) T##BD(i).bufptr = (__force __u32)cpu_to_be32(v) #else #error rtx must be 64-bit aligned #endif @@ -275,10 +283,11 @@ void redundant_init(struct eth_device *dev) clrbits_be32(regs-dmactrl, DMACTRL_GRS | DMACTRL_GTS); do { + uint16_t status; tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rx_idx].status RXBD_EMPTY; t++) { + for (t = 0; GET_BD_STAT(RX, rx_idx) RXBD_EMPTY; t++) { if (t = 10 * TOUT_LOOP) { printf(%s: tsec: rx error\n, dev-name); break; @@ -288,9 +297,11 @@ void redundant_init(struct eth_device *dev) if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) fail = 0; - rtx.rxbd[rx_idx].length = 0; - rtx.rxbd[rx_idx].status = - RXBD_EMPTY | (((rx_idx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + SET_BD_BLEN(RX, rx_idx, 0); + status = RXBD_EMPTY; + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + SET_BD_STAT(RX, rx_idx, status); rx_idx = (rx_idx + 1) % PKTBUFSRX; if (in_be32(regs-ievent) IEVENT_BSY) { @@ -319,9 +330,10 @@ void redundant_init(struct eth_device *dev) */ static void startup_tsec(struct eth_device *dev) { - int i; struct tsec_private *priv = (struct tsec_private *)dev-priv; struct tsec __iomem *regs = priv-regs; + uint16_t status; + int i; /* reset the indices to zero */ rx_idx = 0; @@ -331,24 +343,26 @@ static void startup_tsec(struct eth_device *dev) #endif /* Point to the buffer descriptors */ - out_be32(regs-tbase, (unsigned int)(rtx.txbd[tx_idx])); - out_be32(regs-rbase, (unsigned int)(rtx.rxbd[rx_idx])); + out_be32(regs-tbase, (u32)TXBD(0)); + out_be32(regs-rbase, (u32)RXBD(0)); /* Initialize the Rx Buffer descriptors */ for (i = 0; i PKTBUFSRX; i++) { - rtx.rxbd[i].status = RXBD_EMPTY; - rtx.rxbd[i].length = 0; - rtx.rxbd[i].bufptr = (uint) NetRxPackets[i]; + SET_BD_STAT(RX, i, RXBD_EMPTY); + SET_BD_BLEN(RX, i, 0); + SET_BD_BPTR(RX, i, (u32)NetRxPackets[i]); } - rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; + status = GET_BD_STAT(RX, PKTBUFSRX - 1); + SET_BD_STAT(RX, PKTBUFSRX - 1, status | RXBD_WRAP); /* Initialize the TX Buffer Descriptors */ for (i = 0; i TX_BUF_CNT; i++) { - rtx.txbd[i].status = 0; - rtx.txbd[i].length = 0; - rtx.txbd[i].bufptr = 0; + SET_BD_STAT(TX, i, 0); + SET_BD_BLEN(TX, i, 0); + SET_BD_BPTR(TX, i, 0); } - rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; + status = GET_BD_STAT(TX, TX_BUF_CNT - 1); + SET_BD_STAT(TX, TX_BUF_CNT - 1, status | TXBD_WRAP); #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 svr = get_svr(); @@ -372,29 +386,31 @@ static void
[U-Boot] [PATCH 2/9] net: tsec: Fix and cleanup tsec_mcast_addr()
There are several implementation issues for tsec_mcast_addr() addressed by this patch: * unmanaged, not portable r/w access to registers; fixed with setbits_be32()/ clrbits_be32() * use of volatile pointers * unnecessary forced cast to u8 for the ether_crc() result * removed redundant parens * corrected some comment slips Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 31 +++ 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 3428dd0..9ffc801 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -113,32 +113,31 @@ static void tsec_configure_serdes(struct tsec_private *priv) * result. * 2) Use the 8 most significant bits as a hash into a 256-entry * table. The table is controlled through 8 32-bit registers: - * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is - * gaddr7. This means that the 3 most significant bits in the + * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is entry + * 255. This means that the 3 most significant bits in the * hash index which gaddr register to use, and the 5 other bits * indicate which bit (assuming an IBM numbering scheme, which - * for PowerPC (tm) is usually the case) in the tregister holds + * for PowerPC (tm) is usually the case) in the register holds * the entry. */ static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { struct tsec_private *priv = privlist[1]; - volatile tsec_t *regs = priv-regs; - volatile u32 *reg_array, value; - u8 result, whichbit, whichreg; + struct tsec __iomem *regs = priv-regs; + u32 result, value; + u8 whichbit, whichreg; - result = (u8)((ether_crc(MAC_ADDR_LEN, mcast_mac) 24) 0xff); - whichbit = result 0x1f; /* the 5 LSB = which bit to set */ - whichreg = result 5; /* the 3 MSB = which reg to set it in */ - value = (1 (31-whichbit)); + result = ether_crc(MAC_ADDR_LEN, mcast_mac); + whichbit = (result 24) 0x1f; /* the 5 LSB = which bit to set */ + whichreg = result 29; /* the 3 MSB = which reg to set it in */ - reg_array = (regs-hash.gaddr0); + value = 1 (31-whichbit); + + if (set) + setbits_be32(regs-hash.gaddr0 + whichreg, value); + else + clrbits_be32(regs-hash.gaddr0 + whichreg, value); - if (set) { - reg_array[whichreg] |= value; - } else { - reg_array[whichreg] = ~value; - } return 0; } #endif /* Multicast TFTP ? */ -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/3] net: tsec: Fix and cleanup tsec_mcast_addr()
There are several implementation issues for tsec_mcast_addr() addressed by this patch: * unmanaged, not portable r/w access to registers; fixed with setbits_be32()/ clrbits_be32() * use of volatile pointers * unnecessary forced cast to u8 for the ether_crc() result * removed redundant parens * corrected some comment slips Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 31 +++ 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 3428dd0..9ffc801 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -113,32 +113,31 @@ static void tsec_configure_serdes(struct tsec_private *priv) * result. * 2) Use the 8 most significant bits as a hash into a 256-entry * table. The table is controlled through 8 32-bit registers: - * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is - * gaddr7. This means that the 3 most significant bits in the + * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is entry + * 255. This means that the 3 most significant bits in the * hash index which gaddr register to use, and the 5 other bits * indicate which bit (assuming an IBM numbering scheme, which - * for PowerPC (tm) is usually the case) in the tregister holds + * for PowerPC (tm) is usually the case) in the register holds * the entry. */ static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { struct tsec_private *priv = privlist[1]; - volatile tsec_t *regs = priv-regs; - volatile u32 *reg_array, value; - u8 result, whichbit, whichreg; + struct tsec __iomem *regs = priv-regs; + u32 result, value; + u8 whichbit, whichreg; - result = (u8)((ether_crc(MAC_ADDR_LEN, mcast_mac) 24) 0xff); - whichbit = result 0x1f; /* the 5 LSB = which bit to set */ - whichreg = result 5; /* the 3 MSB = which reg to set it in */ - value = (1 (31-whichbit)); + result = ether_crc(MAC_ADDR_LEN, mcast_mac); + whichbit = (result 24) 0x1f; /* the 5 LSB = which bit to set */ + whichreg = result 29; /* the 3 MSB = which reg to set it in */ - reg_array = (regs-hash.gaddr0); + value = 1 (31-whichbit); + + if (set) + setbits_be32(regs-hash.gaddr0 + whichreg, value); + else + clrbits_be32(regs-hash.gaddr0 + whichreg, value); - if (set) { - reg_array[whichreg] |= value; - } else { - reg_array[whichreg] = ~value; - } return 0; } #endif /* Multicast TFTP ? */ -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/3] net: Fix mcast function pointer prototype
This fixes the following compiler warnings when activating CONFIG_MCAST_TFTP: tsec.c: In function 'tsec_mcast_addr': tsec.c:130:2: warning: passing argument 2 of 'ether_crc' makes pointer from integer without a cast [enabled by default] In file included from /work/u-boot-net/include/common.h:874:0, from tsec.c:15: /work/u-boot-net/include/net.h:189:5: note: expected 'const unsigned char *' but argument is of type 'u8' tsec.c: In function 'tsec_initialize': tsec.c:646:13: warning: assignment from incompatible pointer type [enabled by default] eth.c: In function 'eth_mcast_join': eth.c:358:2: warning: passing argument 2 of 'eth_current-mcast' makes integer from pointer without a cast [enabled by default] eth.c:358:2: note: expected 'u32' but argument is of type 'u8 *' In the eth_mcast_join() implementation, eth_current-mcast() takes a u8 pointer to the multicast mac address and not a ip address value as implied by its prototype. Fix parameter type mismatch for tsec_macst_addr() (tsec.c): ether_crc() takes a u8 pointer not a u8 value. mcast() is given a u8 pointer to the multicats mac address. Update parameter type for the rest of mcast() instances. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/rtl8139.c | 2 +- drivers/net/tsec.c| 4 ++-- include/net.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 4186699..208ce5c 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -188,7 +188,7 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); #ifdef CONFIG_MCAST_TFTP/* This driver already accepts all b/mcast */ -static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set) +static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set) { return (0); } diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index f5e314b..3428dd0 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -120,14 +120,14 @@ static void tsec_configure_serdes(struct tsec_private *priv) * for PowerPC (tm) is usually the case) in the tregister holds * the entry. */ static int -tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) +tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { struct tsec_private *priv = privlist[1]; volatile tsec_t *regs = priv-regs; volatile u32 *reg_array, value; u8 result, whichbit, whichreg; - result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) 24) 0xff); + result = (u8)((ether_crc(MAC_ADDR_LEN, mcast_mac) 24) 0xff); whichbit = result 0x1f; /* the 5 LSB = which bit to set */ whichreg = result 5; /* the 3 MSB = which reg to set it in */ value = (1 (31-whichbit)); diff --git a/include/net.h b/include/net.h index 5aedc17..0802fad 100644 --- a/include/net.h +++ b/include/net.h @@ -89,7 +89,7 @@ struct eth_device { int (*recv) (struct eth_device *); void (*halt) (struct eth_device *); #ifdef CONFIG_MCAST_TFTP - int (*mcast) (struct eth_device *, u32 ip, u8 set); + int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set); #endif int (*write_hwaddr) (struct eth_device *); struct eth_device *next; -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/3] net: tsec: Fix priv pointer in tsec_mcast_addr()
Access to privlist[1] (hardcoded referece to the 2nd tsec's priv area) is neither correct nor does it make sense in the current context. Each tsec dev has access to its own priv instance only, and hence to its own set of group address registers (GADDR) to filter multicast addresses. This fix leads to removal of the unused (faulty) privlist[] and related global static vars. Note that mcast() can be called only after eth_device allocation and init, and hence after priv area allocation, so dev-priv is correctly initialized upon mcast() call. Signed-off-by: Claudiu Manoil claudiu.man...@freescale.com --- drivers/net/tsec.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 9ffc801..9371ffa 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -33,11 +33,6 @@ typedef volatile struct rtxbd { rxbd8_t rxbd[PKTBUFSRX]; } RTXBD; -#define MAXCONTROLLERS (8) - -static struct tsec_private *privlist[MAXCONTROLLERS]; -static int num_tsecs = 0; - #ifdef __GNUC__ static RTXBD rtx __attribute__ ((aligned(8))); #else @@ -122,7 +117,7 @@ static void tsec_configure_serdes(struct tsec_private *priv) static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { - struct tsec_private *priv = privlist[1]; + struct tsec_private *priv = (struct tsec_private *)dev-priv; struct tsec __iomem *regs = priv-regs; u32 result, value; u8 whichbit, whichreg; @@ -625,7 +620,6 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info) if (NULL == priv) return 0; - privlist[num_tsecs++] = priv; priv-regs = tsec_info-regs; priv-phyregs_sgmii = tsec_info-miiregs_sgmii; -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/3] net: tsec: Fixes for mcast() in the tsec driver
Though this patchset fixes tsec's driver mcast() instance primarily, the fix from net.h was propagated to other drivers too, as appropriate. Notably, these fixes also end up in removal of some unwanted global static vars from the tsec driver. Thanks. Claudiu Cc: Joe Hershberger joe.hershber...@gmail.com Claudiu Manoil (3): net: Fix mcast function pointer prototype net: tsec: Fix and cleanup tsec_mcast_addr() net: tsec: Fix priv pointer in tsec_mcast_addr() drivers/net/rtl8139.c | 2 +- drivers/net/tsec.c| 47 --- include/net.h | 2 +- 3 files changed, 22 insertions(+), 29 deletions(-) -- 1.7.11.7 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot