bmips: add experimental ethernet support

This adds experimental ethernet support for BCM6318, BCM6328, BCM6362, BCM6368
and BCM63268.
BCM6358 needs a different driver, so there's no support for now.

Working devices:
- Comtrend AR-5315u
- Comtrend AR-5387un
- Comtrend VR-3025u
- Comtrend VR-3032u

Not working devices:
- Netgear DGND3700 v2 (no idea on how the external switch is connected)
- Huawei HG556a ver B (BCM6358 needs a separate driveer)

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Signed-off-by: maurerr <mariusd84@gmail.com>
This commit is contained in:
Álvaro Fernández Rojas 2021-03-01 08:21:59 +01:00 committed by maurerr
parent 60b09bb0e4
commit 7b67efb85b
20 changed files with 2401 additions and 1 deletions

View File

@ -18,6 +18,6 @@ endef
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += kmod-gpio-button-hotplug
DEFAULT_PACKAGES += ethtool kmod-gpio-button-hotplug
$(eval $(call BuildTarget))

View File

@ -3,8 +3,15 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_B53=y
# CONFIG_B53_MDIO_DRIVER is not set
CONFIG_B53_MMAP_DRIVER=y
# CONFIG_B53_SERDES is not set
CONFIG_B53_SPI_DRIVER=y
# CONFIG_B53_SRAB_DRIVER is not set
CONFIG_BCM6345_EXT_IRQ=y
CONFIG_BCM6345_L1_IRQ=y
CONFIG_BCM6368_ENETSW=y
CONFIG_BCM63XX_POWER=y
CONFIG_BCM7038_L1_IRQ=y
CONFIG_BCM7038_WDT=y
@ -103,6 +110,7 @@ CONFIG_GPIOLIB=y
# CONFIG_GPIO_BRCMSTB is not set
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
@ -128,6 +136,8 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_BUS_MUX=y
CONFIG_MDIO_BUS_MUX_BCM6368=y
CONFIG_MDIO_DEVICE=y
CONFIG_MEMFD_CREATE=y
CONFIG_MFD_SYSCON=y
@ -163,7 +173,14 @@ CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_JEDECPROBE=y
# CONFIG_MTD_PARSER_IMAGETAG is not set
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NO_EXCEPT_FILL=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_NR_CPUS=2
@ -181,6 +198,7 @@ CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLINK=y
CONFIG_PHYSICAL_START=0x80010000
CONFIG_PHY_BCM63XX_USBH=y
# CONFIG_PHY_BRCM_SATA is not set

View File

@ -39,6 +39,12 @@
status = "okay";
};
&ethernet {
status = "okay";
mtd-mac-address = <&cferom 0x6a0>;
};
&leds {
status = "okay";
@ -177,6 +183,38 @@
status = "okay";
};
&switch0 {
ports {
port@0 {
reg = <0>;
label = "lan2";
phy-handle = <&phy1>;
};
port@1 {
reg = <1>;
label = "lan3";
phy-handle = <&phy2>;
};
port@2 {
reg = <2>;
label = "lan4";
phy-handle = <&phy3>;
};
port@3 {
reg = <3>;
label = "lan1";
phy-handle = <&phy4>;
};
};
};
&uart0 {
status = "okay";
};

View File

@ -37,6 +37,12 @@
status = "okay";
};
&ethernet {
status = "okay";
mtd-mac-address = <&cfe 0x6a0>;
};
&hsspi {
status = "okay";
@ -168,6 +174,38 @@
};
};
&switch0 {
ports {
port@0 {
reg = <0>;
label = "lan4";
phy-handle = <&phy1>;
};
port@1 {
reg = <1>;
label = "lan3";
phy-handle = <&phy2>;
};
port@2 {
reg = <2>;
label = "lan2";
phy-handle = <&phy3>;
};
port@3 {
reg = <3>;
label = "lan1";
phy-handle = <&phy4>;
};
};
};
&uart0 {
status = "okay";
};

View File

@ -346,5 +346,103 @@
status = "disabled";
};
switch0: switch@10080000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6328-switch";
reg = <0x10080000 0x8000>;
big-endian;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@8 {
reg = <8>;
label = "cpu";
phy-mode = "internal";
ethernet = <&ethernet>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
mdio: mdio@100800b0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6368-mdio-mux";
reg = <0x100800b0 0x8>;
mdio_int: mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
};
phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
};
phy4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
};
};
mdio_ext: mdio@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
};
ethernet: ethernet@10088000 {
compatible = "brcm,bcm6318-enetsw";
reg = <0x10088000 0x80>,
<0x10088200 0x80>,
<0x10088400 0x80>;
reg-names = "dma",
"dma-channels",
"dma-sram";
interrupt-parent = <&periph_intc>;
interrupts = <BCM6318_IRQ_ENETSW_RX_DMA0>,
<BCM6318_IRQ_ENETSW_TX_DMA0>;
interrupt-names = "rx",
"tx";
clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
<&periph_clk BCM6318_CLK_ROBOSW025>,
<&ubus_clk BCM6318_UCLK_ROBOSW>;
resets = <&periph_rst BCM6318_RST_ENETSW>,
<&periph_rst BCM6318_RST_EPHY>;
power-domains = <&periph_pwr BCM6318_POWER_DOMAIN_EPHY0>,
<&periph_pwr BCM6318_POWER_DOMAIN_EPHY1>,
<&periph_pwr BCM6318_POWER_DOMAIN_EPHY2>,
<&periph_pwr BCM6318_POWER_DOMAIN_EPHY3>;
dma-rx = <0>;
dma-tx = <1>;
status = "disabled";
};
};
};

View File

@ -432,5 +432,105 @@
status = "disabled";
};
ethernet: ethernet@1000d800 {
compatible = "brcm,bcm63268-enetsw";
reg = <0x1000d800 0x80>,
<0x1000da00 0x80>,
<0x1000dc00 0x80>;
reg-names = "dma",
"dma-channels",
"dma-sram";
interrupt-parent = <&periph_intc>;
interrupts = <BCM63268_IRQ_ENETSW_RX_DMA0>,
<BCM63268_IRQ_ENETSW_TX_DMA0>;
interrupt-names = "rx",
"tx";
clocks = <&periph_clk BCM63268_CLK_GMAC>,
<&periph_clk BCM63268_CLK_ROBOSW>,
<&periph_clk BCM63268_CLK_ROBOSW250>,
<&timer_clk BCM63268_TCLK_EPHY1>,
<&timer_clk BCM63268_TCLK_EPHY2>,
<&timer_clk BCM63268_TCLK_EPHY3>,
<&timer_clk BCM63268_TCLK_GPHY1>;
resets = <&periph_rst BCM63268_RST_ENETSW>,
<&periph_rst BCM63268_RST_EPHY>,
<&periph_rst BCM63268_RST_GPHY>;
power-domains = <&periph_pwr BCM63268_POWER_DOMAIN_ROBOSW>;
dma-rx = <0>;
dma-tx = <1>;
status = "disabled";
};
switch0: switch@10700000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6328-switch";
reg = <0x10700000 0x8000>;
big-endian;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@8 {
reg = <8>;
label = "cpu";
phy-mode = "internal";
ethernet = <&ethernet>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
mdio: mdio@107000b0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6368-mdio-mux";
reg = <0x107000b0 0x8>;
mdio_int: mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
};
phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
};
phy4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
};
};
mdio_ext: mdio@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
};
};
};

View File

@ -30,6 +30,12 @@
status = "okay";
};
&ethernet {
status = "okay";
mtd-mac-address = <&cfe 0x6a0>;
};
&hsspi {
status = "okay";
@ -113,6 +119,38 @@
};
};
&switch0 {
ports {
port@0 {
reg = <0>;
label = "lan1";
phy-handle = <&phy1>;
};
port@1 {
reg = <1>;
label = "lan2";
phy-handle = <&phy2>;
};
port@2 {
reg = <2>;
label = "lan3";
phy-handle = <&phy3>;
};
port@3 {
reg = <3>;
label = "lan4";
phy-handle = <&phy4>;
};
};
};
&uart0 {
status = "okay";
};

View File

@ -368,5 +368,99 @@
status = "disabled";
};
ethernet: ethernet@1000d800 {
compatible = "brcm,bcm6328-enetsw";
reg = <0x1000d800 0x80>,
<0x1000da00 0x80>,
<0x1000dc00 0x80>;
reg-names = "dma",
"dma-channels",
"dma-sram";
interrupt-parent = <&periph_intc>;
interrupts = <BCM6328_IRQ_ENETSW_RX_DMA0>,
<BCM6328_IRQ_ENETSW_TX_DMA0>;
interrupt-names = "rx",
"tx";
clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
resets = <&periph_rst BCM6328_RST_ENETSW>,
<&periph_rst BCM6328_RST_EPHY>;
power-domains = <&periph_pwr BCM6328_POWER_DOMAIN_ROBOSW>,
<&periph_pwr BCM6328_POWER_DOMAIN_EPHY>;
dma-rx = <0>;
dma-tx = <1>;
status = "disabled";
};
switch0: switch@10e00000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6328-switch";
reg = <0x10e00000 0x8000>;
big-endian;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@8 {
reg = <8>;
label = "cpu";
phy-mode = "internal";
ethernet = <&ethernet>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
mdio: mdio@10e000b0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6368-mdio-mux";
reg = <0x10e000b0 0x8>;
mdio_int: mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
};
phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
};
phy4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
};
};
mdio_ext: mdio@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
};
};
};

View File

@ -62,6 +62,12 @@
status = "okay";
};
&ethernet {
status = "okay";
mtd-mac-address = <&cferom 0x6a0>;
};
&leds {
status = "okay";

View File

@ -465,5 +465,99 @@
status = "disabled";
};
ethernet: ethernet@1000d800 {
compatible = "brcm,bcm6362-enetsw";
reg = <0x1000d800 0x80>,
<0x1000da00 0x80>,
<0x1000dc00 0x80>;
reg-names = "dma",
"dma-channels",
"dma-sram";
interrupt-parent = <&periph_intc>;
interrupts = <BCM6362_IRQ_ENETSW_RX_DMA0>;
interrupt-names = "rx";
clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
<&periph_clk BCM6362_CLK_SWPKT_SAR>,
<&periph_clk BCM6362_CLK_ROBOSW>;
resets = <&periph_rst BCM6362_RST_ENETSW>,
<&periph_rst BCM6362_RST_EPHY>;
power-domains = <&periph_pwr BCM6362_POWER_DOMAIN_ROBOSW>,
<&periph_pwr BCM6362_POWER_DOMAIN_GMII_PADS>;
dma-rx = <0>;
dma-tx = <1>;
status = "disabled";
};
switch0: switch@10e00000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6328-switch";
reg = <0x10e00000 0x8000>;
big-endian;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@8 {
reg = <8>;
label = "cpu";
phy-mode = "internal";
ethernet = <&ethernet>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
mdio: mdio@10e000b0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6368-mdio-mux";
reg = <0x10e000b0 0x8>;
mdio_int: mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
};
phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
};
phy4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
};
};
mdio_ext: mdio@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
};
};
};

View File

@ -59,6 +59,12 @@
status = "okay";
};
&ethernet {
status = "okay";
mtd-mac-address = <&cfe 0x6a0>;
};
&ohci {
status = "okay";
};
@ -96,6 +102,38 @@
&pinctrl_ephy2_led &pinctrl_ephy3_led>;
};
&switch0 {
ports {
port@0 {
reg = <0>;
label = "lan1";
phy-handle = <&phy1>;
};
port@1 {
reg = <1>;
label = "lan2";
phy-handle = <&phy2>;
};
port@2 {
reg = <2>;
label = "lan3";
phy-handle = <&phy3>;
};
port@3 {
reg = <3>;
label = "lan4";
phy-handle = <&phy4>;
};
};
};
&uart0 {
status = "okay";
};

View File

@ -467,6 +467,99 @@
resets = <&periph_rst BCM6368_RST_IPSEC>;
};
ethernet: ethernet@10006800 {
compatible = "brcm,bcm6368-enetsw";
reg = <0x10006800 0x80>,
<0x10006a00 0x80>,
<0x10006c00 0x80>;
reg-names = "dma",
"dma-channels",
"dma-sram";
interrupt-parent = <&periph_intc>;
interrupts = <BCM6368_IRQ_ENETSW_RX_DMA0>,
<BCM6368_IRQ_ENETSW_TX_DMA0>;
interrupt-names = "rx",
"tx";
clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
<&periph_clk BCM6368_CLK_SWPKT_SAR>,
<&periph_clk BCM6368_CLK_ROBOSW>;
resets = <&periph_rst BCM6368_RST_SWITCH>,
<&periph_rst BCM6368_RST_EPHY>;
dma-rx = <0>;
dma-tx = <1>;
status = "disabled";
};
switch0: switch@10f00000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6328-switch";
reg = <0x10f00000 0x8000>;
big-endian;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@8 {
reg = <8>;
label = "cpu";
phy-mode = "internal";
ethernet = <&ethernet>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
mdio: mdio@10f000b0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6368-mdio-mux";
reg = <0x10f000b0 0x8>;
mdio_int: mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
};
phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
};
phy4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
};
};
mdio_ext: mdio@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
};
};
pflash: nor@18000000 {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-or-later
. /lib/functions/uci-defaults.sh
board_config_update
case "$(board_name)" in
comtrend,ar-5315u |\
comtrend,ar-5387un |\
comtrend,vr-3025u)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
esac
board_config_flush
exit 0

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
. /lib/functions/uci-defaults.sh
board_config_update
case "$(board_name)" in
comtrend,vr-3032u)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
esac
board_config_flush
exit 0

View File

@ -0,0 +1,29 @@
From cd6906754bbe3e0665ecaeca2cfb26d927fe9277 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Mon, 1 Mar 2021 07:29:29 +0100
Subject: [PATCH 1/3] net: dsa: b53: relax is63xx() condition
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BCM63xx switches are present on bcm63xx and bmips devices.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
drivers/net/dsa/b53/b53_priv.h | 4 ----
1 file changed, 4 deletions(-)
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -185,11 +185,7 @@ static inline int is531x5(struct b53_dev
static inline int is63xx(struct b53_device *dev)
{
-#ifdef CONFIG_BCM63XX
return dev->chip_id == BCM63XX_DEVICE_ID;
-#else
- return 0;
-#endif
}
static inline int is5301x(struct b53_device *dev)

View File

@ -0,0 +1,82 @@
From f5419e7f362ae1c462baf28a2da7360267f8e4f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Mon, 1 Mar 2021 07:32:32 +0100
Subject: [PATCH 2/3] net: dsa: b53: mmap: Add device tree support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add device tree support to b53_mmap.c while keeping platform devices support.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
drivers/net/dsa/b53/b53_mmap.c | 36 ++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
--- a/drivers/net/dsa/b53/b53_mmap.c
+++ b/drivers/net/dsa/b53/b53_mmap.c
@@ -228,12 +228,64 @@ static const struct b53_io_ops b53_mmap_
.write64 = b53_mmap_write64,
};
+static int b53_mmap_probe_of(struct platform_device *pdev,
+ struct b53_platform_data **ppdata)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *of_ports, *of_port;
+ struct b53_platform_data *pdata;
+ void __iomem *mem;
+
+ mem = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(mem))
+ return PTR_ERR(mem);
+
+ pdata = devm_kzalloc(dev, sizeof(struct b53_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->regs = mem;
+ pdata->chip_id = BCM63XX_DEVICE_ID;
+ pdata->big_endian = of_property_read_bool(np, "big-endian");
+
+ of_ports = of_get_child_by_name(np, "ports");
+ if (!of_ports) {
+ dev_err(dev, "no ports child node found\n");
+ return -EINVAL;
+ }
+
+ for_each_available_child_of_node(of_ports, of_port) {
+ u32 reg;
+
+ if (of_property_read_u32(of_port, "reg", &reg))
+ continue;
+
+ if (reg < B53_CPU_PORT)
+ pdata->enabled_ports |= BIT(reg);
+ }
+
+ *ppdata = pdata;
+
+ return 0;
+}
+
static int b53_mmap_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct b53_platform_data *pdata = pdev->dev.platform_data;
struct b53_mmap_priv *priv;
struct b53_device *dev;
+ if (np) {
+ int ret = b53_mmap_probe_of(pdev, &pdata);
+ if (ret) {
+ dev_err(&pdev->dev, "OF probe error\n");
+ return ret;
+ }
+ }
+
if (!pdata)
return -EINVAL;

View File

@ -0,0 +1,209 @@
From 3bc3d79efdff6e29b80bf35f7a56baaa36e4d8fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Fri, 12 Mar 2021 12:35:39 +0100
Subject: [PATCH] net: dsa: b53: support tags for legacy switches
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
drivers/net/dsa/b53/Kconfig | 1 +
drivers/net/dsa/b53/b53_common.c | 6 +++
include/net/dsa.h | 2 +
net/dsa/Kconfig | 7 +++
net/dsa/tag_brcm.c | 93 ++++++++++++++++++++++++++++++++
5 files changed, 109 insertions(+)
--- a/drivers/net/dsa/b53/Kconfig
+++ b/drivers/net/dsa/b53/Kconfig
@@ -3,6 +3,7 @@ menuconfig B53
tristate "Broadcom BCM53xx managed switch support"
depends on NET_DSA
select NET_DSA_TAG_BRCM
+ select NET_DSA_TAG_BRCM_LEGACY
select NET_DSA_TAG_BRCM_PREPEND
help
This driver adds support for Broadcom managed switch chips. It supports
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1992,6 +1992,7 @@ static bool b53_can_enable_brcm_tags(str
switch (tag_protocol) {
case DSA_TAG_PROTO_BRCM:
+ case DSA_TAG_PROTO_BRCM_LEGACY:
case DSA_TAG_PROTO_BRCM_PREPEND:
dev_warn(ds->dev,
"Port %d is stacked to Broadcom tag switch\n", port);
@@ -2013,12 +2014,16 @@ enum dsa_tag_protocol b53_get_tag_protoc
/* Older models (5325, 5365) support a different tag format that we do
* not support in net/dsa/tag_brcm.c yet.
*/
- if (is5325(dev) || is5365(dev) ||
- !b53_can_enable_brcm_tags(ds, port, mprot)) {
+ if (!b53_can_enable_brcm_tags(ds, port, mprot)) {
dev->tag_protocol = DSA_TAG_PROTO_NONE;
goto out;
}
+ if (is5325(dev) || is5365(dev) || is63xx(dev)) {
+ dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY;
+ goto out;
+ }
+
/* Broadcom BCM58xx chips have a flow accelerator on Port 8
* which requires us to use the prepended Broadcom tag type
*/
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -45,10 +45,12 @@ struct phylink_link_state;
#define DSA_TAG_PROTO_OCELOT_VALUE 15
#define DSA_TAG_PROTO_AR9331_VALUE 16
#define DSA_TAG_PROTO_RTL4_A_VALUE 17
+#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22
enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
DSA_TAG_PROTO_BRCM = DSA_TAG_PROTO_BRCM_VALUE,
+ DSA_TAG_PROTO_BRCM_LEGACY = DSA_TAG_PROTO_BRCM_LEGACY_VALUE,
DSA_TAG_PROTO_BRCM_PREPEND = DSA_TAG_PROTO_BRCM_PREPEND_VALUE,
DSA_TAG_PROTO_DSA = DSA_TAG_PROTO_DSA_VALUE,
DSA_TAG_PROTO_EDSA = DSA_TAG_PROTO_EDSA_VALUE,
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -47,6 +47,13 @@ config NET_DSA_TAG_BRCM
Say Y if you want to enable support for tagging frames for the
Broadcom switches which place the tag after the MAC source address.
+config NET_DSA_TAG_BRCM_LEGACY
+ tristate "Tag driver for Broadcom legacy switches using in-frame headers"
+ select NET_DSA_TAG_BRCM_COMMON
+ help
+ Say Y if you want to enable support for tagging frames for the
+ Broadcom legacy switches which place the tag after the MAC source
+ address.
config NET_DSA_TAG_BRCM_PREPEND
tristate "Tag driver for Broadcom switches using prepended headers"
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -8,9 +8,23 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/types.h>
#include "dsa_priv.h"
+struct bcm_legacy_tag {
+ uint16_t type;
+#define BRCM_LEG_TYPE 0x8874
+
+ uint32_t tag;
+#define BRCM_LEG_TAG_PORT_ID (0xf)
+#define BRCM_LEG_TAG_MULTICAST (1 << 29)
+#define BRCM_LEG_TAG_EGRESS (2 << 29)
+#define BRCM_LEG_TAG_INGRESS (3 << 29)
+} __attribute__((packed));
+
+#define BRCM_LEG_TAG_LEN sizeof(struct bcm_legacy_tag)
+
/* This tag length is 4 bytes, older ones were 6 bytes, we do not
* handle them
*/
@@ -197,6 +211,85 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
#endif
+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
+static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct dsa_port *dp = dsa_slave_to_port(dev);
+ struct bcm_legacy_tag *brcm_tag;
+
+ if (skb_cow_head(skb, BRCM_LEG_TAG_LEN) < 0)
+ return NULL;
+
+ /* The Ethernet switch we are interfaced with needs packets to be at
+ * least 64 bytes (including FCS) otherwise they will be discarded when
+ * they enter the switch port logic. When Broadcom tags are enabled, we
+ * need to make sure that packets are at least 70 bytes
+ * (including FCS and tag) because the length verification is done after
+ * the Broadcom tag is stripped off the ingress packet.
+ *
+ * Let dsa_slave_xmit() free the SKB
+ */
+ if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
+ return NULL;
+
+ skb_push(skb, BRCM_LEG_TAG_LEN);
+
+ memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN);
+
+ brcm_tag = (struct bcm_legacy_tag *) (skb->data + 2 * ETH_ALEN);
+
+ brcm_tag->type = BRCM_LEG_TYPE;
+ brcm_tag->tag = BRCM_LEG_TAG_EGRESS;
+ brcm_tag->tag |= dp->index & BRCM_LEG_TAG_PORT_ID;
+
+ return skb;
+}
+
+
+static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt)
+{
+ int source_port;
+ struct bcm_legacy_tag *brcm_tag;
+
+ if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN)))
+ return NULL;
+
+ brcm_tag = (struct bcm_legacy_tag *) (skb->data - 2);
+
+ source_port = brcm_tag->tag & BRCM_LEG_TAG_PORT_ID;
+
+ skb->dev = dsa_master_find_slave(dev, 0, source_port);
+ if (!skb->dev)
+ return NULL;
+
+ /* Remove Broadcom tag and update checksum */
+ skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
+
+ skb->offload_fwd_mark = 1;
+
+ /* Move the Ethernet DA and SA */
+ memmove(skb->data - ETH_HLEN,
+ skb->data - ETH_HLEN - BRCM_LEG_TAG_LEN,
+ 2 * ETH_ALEN);
+
+ return skb;
+}
+
+static const struct dsa_device_ops brcm_legacy_netdev_ops = {
+ .name = "brcm-legacy",
+ .proto = DSA_TAG_PROTO_BRCM_LEGACY,
+ .xmit = brcm_leg_tag_xmit,
+ .rcv = brcm_leg_tag_rcv,
+ .overhead = BRCM_LEG_TAG_LEN,
+};
+
+DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY);
+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
+
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
struct net_device *dev)
@@ -229,6 +322,9 @@ static struct dsa_tag_driver *dsa_tag_dr
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
&DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
#endif
+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
+ &DSA_TAG_DRIVER_NAME(brcm_legacy_netdev_ops),
+#endif
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
&DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
#endif

View File

@ -0,0 +1,46 @@
From 590b60fb08cb1e70fe02d3f407c6b3dbe9ad06ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Mon, 1 Mar 2021 07:34:39 +0100
Subject: [PATCH 3/4] net: broadcom: add BCM6368 enetsw controller driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This controller is present on BCM6318, BCM6328, BCM6362, BCM6368 and BCM63268
SoCs.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
drivers/net/ethernet/broadcom/Kconfig | 8 +
drivers/net/ethernet/broadcom/Makefile | 1 +
.../net/ethernet/broadcom/bcm6368-enetsw.c | 1111 +++++++++++++++++
3 files changed, 1120 insertions(+)
create mode 100644 drivers/net/ethernet/broadcom/bcm6368-enetsw.c
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -60,6 +60,14 @@ config BCM63XX_ENET
This driver supports the ethernet MACs in the Broadcom 63xx
MIPS chipset family (BCM63XX).
+config BCM6368_ENETSW
+ tristate "Broadcom BCM6368 internal mac support"
+ depends on BMIPS_GENERIC || COMPILE_TEST
+ default y
+ help
+ This driver supports Ethernet controller integrated into Broadcom
+ BCM6368 family SoCs.
+
config BCMGENET
tristate "Broadcom GENET internal MAC support"
depends on HAS_IOMEM
--- a/drivers/net/ethernet/broadcom/Makefile
+++ b/drivers/net/ethernet/broadcom/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_B44) += b44.o
obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
+obj-$(CONFIG_BCM6368_ENETSW) += bcm6368-enetsw.o
obj-$(CONFIG_BCMGENET) += genet/
obj-$(CONFIG_BNX2) += bnx2.o
obj-$(CONFIG_CNIC) += cnic.o

View File

@ -0,0 +1,231 @@
From b6ecb2bca2b8ff80ae4b1b15f09dcf071f4ceaf4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Mon, 1 Mar 2021 16:42:12 +0100
Subject: [PATCH] net: mdio: Add BCM6368 MDIO mux bus controller
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This controller is present on BCM6318, BCM6328, BCM6362, BCM6368 and BCM63268
SoCs.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
drivers/net/mdio/Kconfig | 11 ++
drivers/net/mdio/Makefile | 1 +
drivers/net/mdio/mdio-mux-bcm6368.c | 179 ++++++++++++++++++++++++++++
3 files changed, 191 insertions(+)
create mode 100644 drivers/net/mdio/mdio-mux-bcm6368.c
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -200,6 +200,17 @@ config MDIO_BUS_MUX_MESON_G12A
the amlogic g12a SoC. The multiplexers connects either the external
or the internal MDIO bus to the parent bus.
+config MDIO_BUS_MUX_BCM6368
+ tristate "Broadcom BCM6368 MDIO bus multiplexers"
+ depends on OF && OF_MDIO && (BMIPS_GENERIC || COMPILE_TEST)
+ select MDIO_BUS_MUX
+ default BMIPS_GENERIC
+ help
+ This module provides a driver for MDIO bus multiplexers found in
+ BCM6368 based Broadcom SoCs. This multiplexer connects one of several
+ child MDIO bus to a parent bus. Buses could be internal as well as
+ external and selection logic lies inside the same multiplexer.
+
config MDIO_BUS_MUX_BCM_IPROC
tristate "Broadcom iProc based MDIO bus multiplexers"
depends on OF && OF_MDIO && (ARCH_BCM_IPROC || COMPILE_TEST)
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_MDIO_THUNDER) += mdio-thun
obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o
+obj-$(CONFIG_MDIO_BUS_MUX_BCM6368) += mdio-mux-bcm6368.o
obj-$(CONFIG_MDIO_BUS_MUX_BCM_IPROC) += mdio-mux-bcm-iproc.o
obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o
obj-$(CONFIG_MDIO_BUS_MUX_MESON_G12A) += mdio-mux-meson-g12a.o
--- /dev/null
+++ b/drivers/net/mdio/mdio-mux-bcm6368.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Broadcom BCM6368 mdiomux bus controller driver
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mdio-mux.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#define MDIOC_REG 0x0
+#define MDIOC_EXT_MASK BIT(16)
+#define MDIOC_REG_SHIFT 20
+#define MDIOC_PHYID_SHIFT 25
+#define MDIOC_RD_MASK BIT(30)
+#define MDIOC_WR_MASK BIT(31)
+
+#define MDIOD_REG 0x4
+
+struct bcm6368_mdiomux_desc {
+ void *mux_handle;
+ void __iomem *base;
+ struct device *dev;
+ struct mii_bus *mii_bus;
+ int ext_phy;
+};
+
+static int bcm6368_mdiomux_read(struct mii_bus *bus, int phy_id, int loc)
+{
+ struct bcm6368_mdiomux_desc *md = bus->priv;
+ uint32_t reg;
+ int ret;
+
+ __raw_writel(0, md->base + MDIOC_REG);
+
+ reg = MDIOC_RD_MASK |
+ (phy_id << MDIOC_PHYID_SHIFT) |
+ (loc << MDIOC_REG_SHIFT);
+ if (md->ext_phy)
+ reg |= MDIOC_EXT_MASK;
+
+ __raw_writel(reg, md->base + MDIOC_REG);
+ udelay(50);
+ ret = __raw_readw(md->base + MDIOD_REG);
+
+ return ret;
+}
+
+static int bcm6368_mdiomux_write(struct mii_bus *bus, int phy_id, int loc,
+ uint16_t val)
+{
+ struct bcm6368_mdiomux_desc *md = bus->priv;
+ uint32_t reg;
+
+ __raw_writel(0, md->base + MDIOC_REG);
+
+ reg = MDIOC_WR_MASK |
+ (phy_id << MDIOC_PHYID_SHIFT) |
+ (loc << MDIOC_REG_SHIFT);
+ if (md->ext_phy)
+ reg |= MDIOC_EXT_MASK;
+ reg |= val;
+
+ __raw_writel(reg, md->base + MDIOC_REG);
+ udelay(50);
+
+ return 0;
+}
+
+static int bcm6368_mdiomux_switch_fn(int current_child, int desired_child,
+ void *data)
+{
+ struct bcm6368_mdiomux_desc *md = data;
+
+ md->ext_phy = desired_child;
+
+ return 0;
+}
+
+static int bcm6368_mdiomux_probe(struct platform_device *pdev)
+{
+ struct bcm6368_mdiomux_desc *md;
+ struct mii_bus *bus;
+ struct resource *res;
+ int rc;
+
+ md = devm_kzalloc(&pdev->dev, sizeof(*md), GFP_KERNEL);
+ if (!md)
+ return -ENOMEM;
+ md->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+
+ /* Just ioremap, as this MDIO block is usually integrated into an
+ * Ethernet MAC controller register range
+ */
+ md->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!md->base) {
+ dev_err(&pdev->dev, "failed to ioremap register\n");
+ return -ENOMEM;
+ }
+
+ md->mii_bus = devm_mdiobus_alloc(&pdev->dev);
+ if (!md->mii_bus) {
+ dev_err(&pdev->dev, "mdiomux bus alloc failed\n");
+ return ENOMEM;
+ }
+
+ bus = md->mii_bus;
+ bus->priv = md;
+ bus->name = "BCM6368 MDIO mux bus";
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id);
+ bus->parent = &pdev->dev;
+ bus->read = bcm6368_mdiomux_read;
+ bus->write = bcm6368_mdiomux_write;
+ bus->phy_mask = 0x3f;
+ bus->dev.of_node = pdev->dev.of_node;
+
+ rc = mdiobus_register(bus);
+ if (rc) {
+ dev_err(&pdev->dev, "mdiomux registration failed\n");
+ return rc;
+ }
+
+ platform_set_drvdata(pdev, md);
+
+ rc = mdio_mux_init(md->dev, md->dev->of_node,
+ bcm6368_mdiomux_switch_fn, &md->mux_handle, md,
+ md->mii_bus);
+ if (rc) {
+ dev_info(md->dev, "mdiomux initialization failed\n");
+ goto out_register;
+ }
+
+ dev_info(&pdev->dev, "Broadcom BCM6368 MDIO mux bus\n");
+
+ return 0;
+
+out_register:
+ mdiobus_unregister(bus);
+ return rc;
+}
+
+static int bcm6368_mdiomux_remove(struct platform_device *pdev)
+{
+ struct bcm6368_mdiomux_desc *md = platform_get_drvdata(pdev);
+
+ mdio_mux_uninit(md->mux_handle);
+ mdiobus_unregister(md->mii_bus);
+
+ return 0;
+}
+
+static const struct of_device_id bcm6368_mdiomux_ids[] = {
+ { .compatible = "brcm,bcm6368-mdio-mux", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, bcm6368_mdiomux_ids);
+
+static struct platform_driver bcm6368_mdiomux_driver = {
+ .driver = {
+ .name = "bcm6368-mdio-mux",
+ .of_match_table = bcm6368_mdiomux_ids,
+ },
+ .probe = bcm6368_mdiomux_probe,
+ .remove = bcm6368_mdiomux_remove,
+};
+module_platform_driver(bcm6368_mdiomux_driver);