Skip to content
Snippets Groups Projects
Commit 60e4948b authored by Marek Behun's avatar Marek Behun
Browse files

patches/openwrt: omnia multi cpu DSA


Signed-off-by: default avatarMarek Behún <marek.behun@nic.cz>
parent 3a250978
Branches
Tags
No related merge requests found
From 9e8821be8d387c40aa801e098821978da75722d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz>
Date: Tue, 27 Aug 2019 19:56:07 +0200
Subject: [PATCH] mvebu: turris-omnia: multi cpu dsa
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
.../90500-net-dsa-multi-cpu.patch | 253 ++++++++++++++++++
.../90501-omnia-dts-dsa-multi-cpu.patch | 58 ++++
2 files changed, 311 insertions(+)
create mode 100644 target/linux/mvebu/patches-4.14/90500-net-dsa-multi-cpu.patch
create mode 100644 target/linux/mvebu/patches-4.14/90501-omnia-dts-dsa-multi-cpu.patch
diff --git a/target/linux/mvebu/patches-4.14/90500-net-dsa-multi-cpu.patch b/target/linux/mvebu/patches-4.14/90500-net-dsa-multi-cpu.patch
new file mode 100644
index 0000000..e51ee19
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/90500-net-dsa-multi-cpu.patch
@@ -0,0 +1,253 @@
+diff -Naurp a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+--- a/drivers/net/dsa/mv88e6xxx/chip.c 2019-08-22 10:27:11.763008277 +0200
++++ b/drivers/net/dsa/mv88e6xxx/chip.c 2019-08-27 19:27:30.435568033 +0200
+@@ -1087,6 +1087,7 @@ static u16 mv88e6xxx_port_vlan(struct mv
+ struct dsa_switch *ds = NULL;
+ struct net_device *br;
+ u16 pvlan;
++ u8 upstream;
+ int i;
+
+ if (dev < DSA_MAX_SWITCHES)
+@@ -1097,8 +1098,22 @@ static u16 mv88e6xxx_port_vlan(struct mv
+ return 0;
+
+ /* Frames from DSA links and CPU ports can egress any local port */
+- if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
+- return mv88e6xxx_port_mask(chip);
++ if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
++ u16 pmask = mv88e6xxx_port_mask(chip);
++ pvlan = 0;
++
++ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
++ if (dsa_is_cpu_port(ds, i)) {
++ if (i == port)
++ pvlan |= BIT(i);
++ continue;
++ }
++ if ((pmask & BIT(i)) && dsa_port_upstream_port(chip->ds, i) == port)
++ pvlan |= BIT(i);
++ }
++
++ return pvlan;
++ }
+
+ br = ds->ports[port].bridge_dev;
+ pvlan = 0;
+@@ -1106,8 +1121,9 @@ static u16 mv88e6xxx_port_vlan(struct mv
+ /* Frames from user ports can egress any local DSA links and CPU ports,
+ * as well as any local member of their bridge group.
+ */
++ upstream = dsa_port_upstream_port(ds, port);
+ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
+- if (dsa_is_cpu_port(chip->ds, i) ||
++ if ((dsa_is_cpu_port(chip->ds, i) && i == upstream) ||
+ dsa_is_dsa_port(chip->ds, i) ||
+ (br && chip->ds->ports[i].bridge_dev == br))
+ pvlan |= BIT(i);
+@@ -1943,9 +1959,11 @@ static int mv88e6xxx_setup_message_port(
+
+ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
+ {
+- bool flood = port == dsa_upstream_port(chip->ds);
++ struct dsa_switch *ds = chip->ds;
++ bool flood;
+
+ /* Upstream ports flood frames with unknown unicast or multicast DA */
++ flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
+ if (chip->info->ops->port_set_egress_floods)
+ return chip->info->ops->port_set_egress_floods(chip, port,
+ flood, flood);
+diff -Naurp a/include/net/dsa.h b/include/net/dsa.h
+--- a/include/net/dsa.h 2019-08-22 10:27:11.723008277 +0200
++++ b/include/net/dsa.h 2019-08-27 15:56:37.053514380 +0200
+@@ -188,6 +188,10 @@ struct dsa_port {
+ struct net_device *bridge_dev;
+ struct devlink_port devlink_port;
+ struct phylink *pl;
++
++ struct net_device *ethernet;
++ int upstream;
++
+ /*
+ * Original copy of the master netdev ethtool_ops
+ */
+@@ -269,6 +273,11 @@ static inline bool dsa_is_normal_port(st
+ return !dsa_is_cpu_port(ds, p) && !dsa_is_dsa_port(ds, p);
+ }
+
++static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p)
++{
++ return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p);
++}
++
+ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
+ {
+ struct dsa_switch_tree *dst = ds->dst;
+@@ -285,6 +294,18 @@ static inline u8 dsa_upstream_port(struc
+ return ds->rtable[dst->cpu_dp->ds->index];
+ }
+
++static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port)
++{
++ /*
++ * If this port has a specific upstream cpu port, use it,
++ * otherwise use the switch default.
++ */
++ if (ds->ports[port].upstream)
++ return ds->ports[port].upstream;
++ else
++ return dsa_upstream_port(ds);
++}
++
+ typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
+ bool is_static, void *data);
+ struct dsa_switch_ops {
+diff -Naurp a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+--- a/net/dsa/dsa2.c 2019-08-09 17:53:37.000000000 +0200
++++ b/net/dsa/dsa2.c 2019-08-27 19:44:55.481541248 +0200
+@@ -253,6 +253,8 @@ static int dsa_cpu_port_apply(struct dsa
+ memset(&port->devlink_port, 0, sizeof(port->devlink_port));
+ err = devlink_port_register(ds->devlink, &port->devlink_port,
+ port->index);
++ if (port->netdev)
++ port->netdev->dsa_ptr = ds->dst;
+ return err;
+ }
+
+@@ -262,6 +264,12 @@ static void dsa_cpu_port_unapply(struct
+ dsa_cpu_dsa_destroy(port);
+ port->ds->cpu_port_mask &= ~BIT(port->index);
+
++ if (port->netdev)
++ port->netdev->dsa_ptr = NULL;
++ if (port->ethernet) {
++ dev_put(port->ethernet);
++ port->ethernet = NULL;
++ }
+ }
+
+ static int dsa_user_port_apply(struct dsa_port *port)
+@@ -505,10 +513,9 @@ static int dsa_cpu_parse(struct dsa_port
+ dev_put(ethernet_dev);
+ }
+
+- if (!dst->cpu_dp) {
++ if (!dst->cpu_dp)
+ dst->cpu_dp = port;
+- dst->cpu_dp->netdev = ethernet_dev;
+- }
++ port->netdev = ethernet_dev;
+
+ /* Initialize cpu_port_mask now for drv->setup()
+ * to have access to a correct value, just like what
+@@ -526,6 +533,32 @@ static int dsa_cpu_parse(struct dsa_port
+
+ dst->rcv = dst->tag_ops->rcv;
+
++ dev_hold(ethernet_dev);
++ ds->ports[index].ethernet = ethernet_dev;
++ ds->cpu_port_mask |= BIT(index);
++
++ return 0;
++}
++
++static int dsa_user_parse(struct dsa_port *port, u32 index,
++ struct dsa_switch *ds)
++{
++ struct device_node *cpu_port;
++ const unsigned int *cpu_port_reg;
++ int cpu_port_index;
++
++ cpu_port = of_parse_phandle(port->dn, "cpu", 0);
++ if (cpu_port) {
++ cpu_port_reg = of_get_property(cpu_port, "reg", NULL);
++ if (!cpu_port_reg)
++ return -EINVAL;
++ cpu_port_index = be32_to_cpup(cpu_port_reg);
++ } else {
++ cpu_port_index = ds->dst->cpu_dp->index;
++ }
++
++ ds->ports[index].upstream = cpu_port_index;
++
+ return 0;
+ }
+
+@@ -533,8 +566,9 @@ static int dsa_ds_parse(struct dsa_switc
+ {
+ struct dsa_port *port;
+ u32 index;
+- int err;
++ int err = 0;
+
++ /* first parse only CPU ports */
+ for (index = 0; index < ds->num_ports; index++) {
+ port = &ds->ports[index];
+ if (!dsa_port_is_valid(port) ||
+@@ -545,7 +579,20 @@ static int dsa_ds_parse(struct dsa_switc
+ err = dsa_cpu_parse(port, index, dst, ds);
+ if (err)
+ return err;
+- } else {
++ }
++ }
++
++ /* now parse normal ports */
++ for (index = 0; index < ds->num_ports; index++) {
++ port = &ds->ports[index];
++ if (!dsa_port_is_valid(port) ||
++ dsa_port_is_dsa(port))
++ continue;
++
++ if (!dsa_port_is_cpu(port)) {
++ err = dsa_user_parse(port, index, ds);
++ if (err)
++ return err;
+ /* Initialize enabled_port_mask now for drv->setup()
+ * to have access to a correct value, just like what
+ * net/dsa/dsa.c::dsa_switch_setup_one does.
+diff -Naurp a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
+--- a/net/dsa/dsa_priv.h 2019-08-22 10:27:11.723008277 +0200
++++ b/net/dsa/dsa_priv.h 2019-08-27 15:57:31.323513820 +0200
+@@ -81,6 +81,8 @@ struct dsa_slave_priv {
+
+ /* TC context */
+ struct list_head mall_tc_list;
++
++ struct net_device *master;
+ };
+
+ /* dsa.c */
+@@ -167,7 +169,10 @@ extern const struct dsa_device_ops trail
+
+ static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p)
+ {
+- return p->dp->cpu_dp->netdev;
++ if (p->master)
++ return p->master;
++ else
++ return p->dp->cpu_dp->netdev;
+ }
+
+ static inline struct dsa_port *dsa_get_cpu_port(struct dsa_switch_tree *dst)
+diff -Naurp a/net/dsa/slave.c b/net/dsa/slave.c
+--- a/net/dsa/slave.c 2019-08-22 10:27:11.723008277 +0200
++++ b/net/dsa/slave.c 2019-08-27 15:58:17.039789880 +0200
+@@ -1242,7 +1242,7 @@ int dsa_slave_create(struct dsa_port *po
+ int ret;
+
+ cpu_dp = ds->dst->cpu_dp;
+- master = cpu_dp->netdev;
++ master = ds->ports[port->upstream].ethernet;
+
+ if (!ds->num_tx_queues)
+ ds->num_tx_queues = 1;
+@@ -1280,6 +1280,7 @@ int dsa_slave_create(struct dsa_port *po
+ p->dp = port;
+ INIT_LIST_HEAD(&p->mall_tc_list);
+ p->xmit = dst->tag_ops->xmit;
++ p->master = master;
+
+ port->netdev = slave_dev;
+
diff --git a/target/linux/mvebu/patches-4.14/90501-omnia-dts-dsa-multi-cpu.patch b/target/linux/mvebu/patches-4.14/90501-omnia-dts-dsa-multi-cpu.patch
new file mode 100644
index 0000000..07b6e12
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/90501-omnia-dts-dsa-multi-cpu.patch
@@ -0,0 +1,58 @@
+diff -Naurp a/arch/arm/boot/dts/armada-385-turris-omnia.dtsi b/arch/arm/boot/dts/armada-385-turris-omnia.dtsi
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dtsi 2019-08-22 10:27:11.626341612 +0200
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dtsi 2019-08-27 19:54:51.811729285 +0200
+@@ -369,29 +369,34 @@
+ ports@0 {
+ reg = <0>;
+ label = "lan0";
++ cpu = <&cpu_port5>;
+ };
+
+ ports@1 {
+ reg = <1>;
+ label = "lan1";
++ cpu = <&cpu_port5>;
+ };
+
+ ports@2 {
+ reg = <2>;
+ label = "lan2";
++ cpu = <&cpu_port5>;
+ };
+
+ ports@3 {
+ reg = <3>;
+ label = "lan3";
++ cpu = <&cpu_port5>;
+ };
+
+ ports@4 {
+ reg = <4>;
+ label = "lan4";
++ cpu = <&cpu_port6>;
+ };
+
+- ports@5 {
++ cpu_port5: ports@5 {
+ reg = <5>;
+ label = "cpu";
+ ethernet = <&eth1>;
+@@ -403,7 +408,17 @@
+ };
+ };
+
+- /* port 6 is connected to eth0 */
++ cpu_port6: ports@6 {
++ reg = <6>;
++ label = "cpu";
++ ethernet = <&eth0>;
++ phy-mode = "rgmii-id";
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++ };
+ };
+ };
+ };
--
2.21.0
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment