From 8b0d3ea555876533b6aa61479335be2c9bdb47e7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 16 May 2017 14:10:33 -0400 Subject: net: dsa: store CPU port pointer in the tree A dsa_switch_tree instance holds a dsa_switch pointer and a port index to identify the switch port to which the CPU is attached. Now that the DSA layer has a dsa_port structure to hold this data, use it to point the switch CPU port. This patch simply substitutes s/dst->cpu_switch/dst->cpu_dp->ds/ and s/dst->cpu_port/dst->cpu_dp->index/. Signed-off-by: Vivien Didelot Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 033b3bfb63dc..2ac62349ba12 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -443,8 +443,8 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst) return err; } - if (dst->cpu_switch) { - err = dsa_cpu_port_ethtool_setup(dst->cpu_switch); + if (dst->cpu_dp) { + err = dsa_cpu_port_ethtool_setup(dst->cpu_dp->ds); if (err) return err; } @@ -484,8 +484,8 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst) dsa_ds_unapply(dst, ds); } - if (dst->cpu_switch) - dsa_cpu_port_ethtool_restore(dst->cpu_switch); + if (dst->cpu_dp) + dsa_cpu_port_ethtool_restore(dst->cpu_dp->ds); pr_info("DSA: tree %d unapplied\n", dst->tree); dst->applied = false; @@ -518,10 +518,8 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, if (!dst->master_netdev) dst->master_netdev = ethernet_dev; - if (!dst->cpu_switch) { - dst->cpu_switch = ds; - dst->cpu_port = index; - } + if (!dst->cpu_dp) + dst->cpu_dp = port; tag_protocol = ds->ops->get_tag_protocol(ds); dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol); -- cgit v1.2.3 From ea5dd34be1cfb2400587a24d1de75e538e77ce74 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Wed, 17 May 2017 15:46:03 -0400 Subject: net: dsa: include dsa.h only once The public include/net/dsa.h file is meant for DSA drivers, while all DSA core files share a common private header net/dsa/dsa_priv.h file. Ensure that dsa_priv.h is the only DSA core file to include net/dsa.h, and add a new line to separate absolute and relative headers at the same time. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 2ac62349ba12..4301f52e4f5a 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -18,7 +18,7 @@ #include #include #include -#include + #include "dsa_priv.h" static LIST_HEAD(dsa_switch_trees); -- cgit v1.2.3 From 23c9ee4934e7a79b49151d0f05c24117d69c73fe Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 26 May 2017 18:12:51 -0400 Subject: net: dsa: remove dev arg of dsa_register_switch The current dsa_register_switch function takes a useless struct device pointer argument, which always equals ds->dev. Drivers either call it with ds->dev, or with the same device pointer passed to dsa_switch_alloc, which ends up being assigned to ds->dev. This patch removes the second argument of the dsa_register_switch and _dsa_register_switch functions. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 4301f52e4f5a..c0a4576db4a2 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -686,10 +686,10 @@ static struct device_node *dsa_get_ports(struct dsa_switch *ds, return ports; } -static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev) +static int _dsa_register_switch(struct dsa_switch *ds) { - struct dsa_chip_data *pdata = dev->platform_data; - struct device_node *np = dev->of_node; + struct dsa_chip_data *pdata = ds->dev->platform_data; + struct device_node *np = ds->dev->of_node; struct dsa_switch_tree *dst; struct device_node *ports; u32 tree, index; @@ -803,12 +803,12 @@ struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n) } EXPORT_SYMBOL_GPL(dsa_switch_alloc); -int dsa_register_switch(struct dsa_switch *ds, struct device *dev) +int dsa_register_switch(struct dsa_switch *ds) { int err; mutex_lock(&dsa2_mutex); - err = _dsa_register_switch(ds, dev); + err = _dsa_register_switch(ds); mutex_unlock(&dsa2_mutex); return err; -- cgit v1.2.3 From 02f840cbc9fa9ee147d882edb96b203999c3ac62 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 1 Jun 2017 16:07:12 -0400 Subject: net: dsa: do not cast dst dsa_ptr is not a void pointer anymore since Nov 2011, as of cf50dcc24f82 ("dsa: Change dsa_uses_{dsa, trailer}_tags() into inline functions"), but an explicit dsa_switch_tree pointer, thus remove the (void *) cast. Reviewed-by: Florian Fainelli Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index c0a4576db4a2..21b44a9828f6 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -454,7 +454,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst) * sent to the tag format's receive function. */ wmb(); - dst->master_netdev->dsa_ptr = (void *)dst; + dst->master_netdev->dsa_ptr = dst; dst->applied = true; return 0; -- cgit v1.2.3 From 937c7df85ce7ce6b2319894f6ad3376f15dff186 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 2 Jun 2017 12:31:21 -0700 Subject: net: dsa: Pass dsa_port reference to ethtool setup/restore We do not need to have a reference to a dsa_switch, instead we should pass a reference to a CPU dsa_port, change that. This is a preliminary change to better support multiple CPU ports. Signed-off-by: Florian Fainelli Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 21b44a9828f6..7f9bf1456a65 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -444,7 +444,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst) } if (dst->cpu_dp) { - err = dsa_cpu_port_ethtool_setup(dst->cpu_dp->ds); + err = dsa_cpu_port_ethtool_setup(dst->cpu_dp); if (err) return err; } @@ -485,7 +485,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst) } if (dst->cpu_dp) - dsa_cpu_port_ethtool_restore(dst->cpu_dp->ds); + dsa_cpu_port_ethtool_restore(dst->cpu_dp); pr_info("DSA: tree %d unapplied\n", dst->tree); dst->applied = false; -- cgit v1.2.3 From e41c1b5030e279c6626d3d052c3ca5ce5e2508df Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 2 Jun 2017 12:31:22 -0700 Subject: net: dsa: Consistently use dsa_port for dsa_*_port_{apply, unapply} We have all the information we need in dsa_port, so use it instead of repeating the same arguments over and over again. Suggested-by: Vivien Didelot Signed-off-by: Florian Fainelli Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 90 ++++++++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 49 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 7f9bf1456a65..067daec644c1 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -214,66 +214,61 @@ static int dsa_dst_complete(struct dsa_switch_tree *dst) return 0; } -static int dsa_dsa_port_apply(struct dsa_port *port, u32 index, - struct dsa_switch *ds) +static int dsa_dsa_port_apply(struct dsa_port *port) { + struct dsa_switch *ds = port->ds; int err; - err = dsa_cpu_dsa_setup(ds, ds->dev, port, index); + err = dsa_cpu_dsa_setup(ds, ds->dev, port, port->index); if (err) { dev_warn(ds->dev, "Failed to setup dsa port %d: %d\n", - index, err); + port->index, err); return err; } - memset(&ds->ports[index].devlink_port, 0, - sizeof(ds->ports[index].devlink_port)); + memset(&port->devlink_port, 0, sizeof(port->devlink_port)); - return devlink_port_register(ds->devlink, - &ds->ports[index].devlink_port, - index); + return devlink_port_register(ds->devlink, &port->devlink_port, + port->index); } -static void dsa_dsa_port_unapply(struct dsa_port *port, u32 index, - struct dsa_switch *ds) +static void dsa_dsa_port_unapply(struct dsa_port *port) { - devlink_port_unregister(&ds->ports[index].devlink_port); + devlink_port_unregister(&port->devlink_port); dsa_cpu_dsa_destroy(port); } -static int dsa_cpu_port_apply(struct dsa_port *port, u32 index, - struct dsa_switch *ds) +static int dsa_cpu_port_apply(struct dsa_port *port) { + struct dsa_switch *ds = port->ds; int err; - err = dsa_cpu_dsa_setup(ds, ds->dev, port, index); + err = dsa_cpu_dsa_setup(ds, ds->dev, port, port->index); if (err) { dev_warn(ds->dev, "Failed to setup cpu port %d: %d\n", - index, err); + port->index, err); return err; } - ds->cpu_port_mask |= BIT(index); + ds->cpu_port_mask |= BIT(port->index); - memset(&ds->ports[index].devlink_port, 0, - sizeof(ds->ports[index].devlink_port)); - err = devlink_port_register(ds->devlink, &ds->ports[index].devlink_port, - index); + memset(&port->devlink_port, 0, sizeof(port->devlink_port)); + err = devlink_port_register(ds->devlink, &port->devlink_port, + port->index); return err; } -static void dsa_cpu_port_unapply(struct dsa_port *port, u32 index, - struct dsa_switch *ds) +static void dsa_cpu_port_unapply(struct dsa_port *port) { - devlink_port_unregister(&ds->ports[index].devlink_port); + devlink_port_unregister(&port->devlink_port); dsa_cpu_dsa_destroy(port); - ds->cpu_port_mask &= ~BIT(index); + port->ds->cpu_port_mask &= ~BIT(port->index); } -static int dsa_user_port_apply(struct dsa_port *port, u32 index, - struct dsa_switch *ds) +static int dsa_user_port_apply(struct dsa_port *port) { + struct dsa_switch *ds = port->ds; const char *name = port->name; int err; @@ -282,35 +277,32 @@ static int dsa_user_port_apply(struct dsa_port *port, u32 index, if (!name) name = "eth%d"; - err = dsa_slave_create(ds, ds->dev, index, name); + err = dsa_slave_create(ds, ds->dev, port->index, name); if (err) { dev_warn(ds->dev, "Failed to create slave %d: %d\n", - index, err); - ds->ports[index].netdev = NULL; + port->index, err); + port->netdev = NULL; return err; } - memset(&ds->ports[index].devlink_port, 0, - sizeof(ds->ports[index].devlink_port)); - err = devlink_port_register(ds->devlink, &ds->ports[index].devlink_port, - index); + memset(&port->devlink_port, 0, sizeof(port->devlink_port)); + err = devlink_port_register(ds->devlink, &port->devlink_port, + port->index); if (err) return err; - devlink_port_type_eth_set(&ds->ports[index].devlink_port, - ds->ports[index].netdev); + devlink_port_type_eth_set(&port->devlink_port, port->netdev); return 0; } -static void dsa_user_port_unapply(struct dsa_port *port, u32 index, - struct dsa_switch *ds) +static void dsa_user_port_unapply(struct dsa_port *port) { - devlink_port_unregister(&ds->ports[index].devlink_port); - if (ds->ports[index].netdev) { - dsa_slave_destroy(ds->ports[index].netdev); - ds->ports[index].netdev = NULL; - ds->enabled_port_mask &= ~(1 << index); + devlink_port_unregister(&port->devlink_port); + if (port->netdev) { + dsa_slave_destroy(port->netdev); + port->netdev = NULL; + port->ds->enabled_port_mask &= ~(1 << port->index); } } @@ -370,20 +362,20 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds) continue; if (dsa_port_is_dsa(port)) { - err = dsa_dsa_port_apply(port, index, ds); + err = dsa_dsa_port_apply(port); if (err) return err; continue; } if (dsa_port_is_cpu(port)) { - err = dsa_cpu_port_apply(port, index, ds); + err = dsa_cpu_port_apply(port); if (err) return err; continue; } - err = dsa_user_port_apply(port, index, ds); + err = dsa_user_port_apply(port); if (err) continue; } @@ -402,16 +394,16 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds) continue; if (dsa_port_is_dsa(port)) { - dsa_dsa_port_unapply(port, index, ds); + dsa_dsa_port_unapply(port); continue; } if (dsa_port_is_cpu(port)) { - dsa_cpu_port_unapply(port, index, ds); + dsa_cpu_port_unapply(port); continue; } - dsa_user_port_unapply(port, index, ds); + dsa_user_port_unapply(port); } if (ds->slave_mii_bus && ds->ops->phy_read) -- cgit v1.2.3 From 14be36c2c96cd18cfa036f230b57ea78d82a303f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 2 Jun 2017 12:31:23 -0700 Subject: net: dsa: Initialize all CPU and enabled ports masks in dsa_ds_parse() There was no reason for duplicating the code that initializes ds->enabled_port_mask in both dsa_parse_ports_dn() and dsa_parse_ports(), instead move this to dsa_ds_parse() which is early enough before ops->setup() has run. While at it, we can now make dsa_is_cpu_port() check ds->cpu_port_mask which is a step towards being multi-CPU port capable. Signed-off-by: Florian Fainelli Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 067daec644c1..cd13bb54a30c 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -250,8 +250,6 @@ static int dsa_cpu_port_apply(struct dsa_port *port) return err; } - ds->cpu_port_mask |= BIT(port->index); - memset(&port->devlink_port, 0, sizeof(port->devlink_port)); err = devlink_port_register(ds->devlink, &port->devlink_port, port->index); @@ -522,6 +520,12 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, dst->rcv = dst->tag_ops->rcv; + /* Initialize cpu_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. + */ + ds->cpu_port_mask |= BIT(index); + return 0; } @@ -533,14 +537,22 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds) for (index = 0; index < ds->num_ports; index++) { port = &ds->ports[index]; - if (!dsa_port_is_valid(port)) + if (!dsa_port_is_valid(port) || + dsa_port_is_dsa(port)) continue; if (dsa_port_is_cpu(port)) { err = dsa_cpu_parse(port, index, dst, ds); if (err) return err; + } else { + /* 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. + */ + ds->enabled_port_mask |= BIT(index); } + } pr_info("DSA: switch %d %d parsed\n", dst->tree, ds->index); @@ -589,13 +601,6 @@ static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds) return -EINVAL; ds->ports[reg].dn = port; - - /* Initialize enabled_port_mask now for ops->setup() - * to have access to a correct value, just like what - * net/dsa/dsa.c::dsa_switch_setup_one does. - */ - if (!dsa_port_is_cpu(&ds->ports[reg])) - ds->enabled_port_mask |= 1 << reg; } return 0; @@ -611,14 +616,6 @@ static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds) continue; ds->ports[i].name = cd->port_names[i]; - - /* 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. - */ - if (!dsa_port_is_cpu(&ds->ports[i])) - ds->enabled_port_mask |= 1 << i; - valid_name_found = true; } -- cgit v1.2.3 From 6d3c8c0dd88a5ffc7e3695997641e4b6d4c11065 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 13 Jun 2017 13:27:19 -0700 Subject: net: dsa: Remove master_netdev and use dst->cpu_dp->netdev In preparation for supporting multiple CPU ports, remove dst->master_netdev and ds->master_netdev and replace them with only one instance of the common object we have for a port: struct dsa_port::netdev. ds->master_netdev is currently write only and would be helpful in the case where we have two switches, both with CPU ports, and also connected within each other, which the multi-CPU port patch series would address. While at it, introduce a helper function used in net/dsa/slave.c to immediately get a reference on the master network device called dsa_master_netdev(). Reviewed-by: Vivien Didelot Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index f88e1dddb74a..ab48c4f989da 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -337,7 +337,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds) return err; if (ds->ops->set_addr) { - err = ds->ops->set_addr(ds, dst->master_netdev->dev_addr); + err = ds->ops->set_addr(ds, dst->cpu_dp->netdev->dev_addr); if (err < 0) return err; } @@ -444,7 +444,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst) * sent to the tag format's receive function. */ wmb(); - dst->master_netdev->dsa_ptr = dst; + dst->cpu_dp->netdev->dsa_ptr = dst; dst->applied = true; return 0; @@ -458,7 +458,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst) if (!dst->applied) return; - dst->master_netdev->dsa_ptr = NULL; + dst->cpu_dp->netdev->dsa_ptr = NULL; /* If we used a tagging format that doesn't have an ethertype * field, make sure that all packets from this point get sent @@ -504,14 +504,10 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, if (!ethernet_dev) return -EPROBE_DEFER; - if (!ds->master_netdev) - ds->master_netdev = ethernet_dev; - - if (!dst->master_netdev) - dst->master_netdev = ethernet_dev; - - if (!dst->cpu_dp) + if (!dst->cpu_dp) { dst->cpu_dp = port; + dst->cpu_dp->netdev = ethernet_dev; + } tag_protocol = ds->ops->get_tag_protocol(ds); dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol); @@ -578,7 +574,7 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) return err; } - if (!dst->master_netdev) { + if (!dst->cpu_dp->netdev) { pr_warn("Tree has no master device\n"); return -EINVAL; } -- cgit v1.2.3 From a29342e739115211615acc33616e547b2d3e0663 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 13 Jun 2017 13:27:21 -0700 Subject: net: dsa: Associate slave network device with CPU port In preparation for supporting multiple CPU ports with DSA, have the dsa_port structure know which CPU it is associated with. This will be important in order to make sure the correct CPU is used for transmission of the frames. If not for functional reasons, for performance (e.g: load balancing) and forwarding decisions. Reviewed-by: Vivien Didelot Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index ab48c4f989da..52af8401af07 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -490,6 +490,8 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, enum dsa_tag_protocol tag_protocol; struct net_device *ethernet_dev; struct device_node *ethernet; + struct dsa_port *p; + unsigned int i; if (port->dn) { ethernet = of_parse_phandle(port->dn, "ethernet", 0); @@ -507,6 +509,15 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, if (!dst->cpu_dp) { dst->cpu_dp = port; dst->cpu_dp->netdev = ethernet_dev; + + for (i = 0; i < ds->num_ports; i++) { + p = &ds->ports[i]; + if (!dsa_port_is_valid(p) || + i == index) + continue; + + p->cpu_dp = port; + } } tag_protocol = ds->ops->get_tag_protocol(ds); -- cgit v1.2.3 From e4b7778769c25f773c514dcc99afcf7c74a9b3e4 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 15 Jun 2017 15:06:54 -0400 Subject: net: dsa: assign default CPU port to all ports The current code only assigns the default cpu_dp to all user ports of the switch to which the CPU port belongs. The user ports of the other switches of the fabric thus don't have a default CPU port. This patch fixes this by assigning the cpu_dp of all user ports of all switches of the fabric when the tree is fully parsed. Fixes: a29342e73911 ("net: dsa: Associate slave network device with CPU port") Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 52af8401af07..56e46090526b 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -490,8 +490,6 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, enum dsa_tag_protocol tag_protocol; struct net_device *ethernet_dev; struct device_node *ethernet; - struct dsa_port *p; - unsigned int i; if (port->dn) { ethernet = of_parse_phandle(port->dn, "ethernet", 0); @@ -509,15 +507,6 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, if (!dst->cpu_dp) { dst->cpu_dp = port; dst->cpu_dp->netdev = ethernet_dev; - - for (i = 0; i < ds->num_ports; i++) { - p = &ds->ports[i]; - if (!dsa_port_is_valid(p) || - i == index) - continue; - - p->cpu_dp = port; - } } tag_protocol = ds->ops->get_tag_protocol(ds); @@ -572,7 +561,9 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds) static int dsa_dst_parse(struct dsa_switch_tree *dst) { struct dsa_switch *ds; + struct dsa_port *dp; u32 index; + int port; int err; for (index = 0; index < DSA_MAX_SWITCHES; index++) { @@ -590,6 +581,23 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) return -EINVAL; } + /* Assign the default CPU port to all ports of the fabric */ + for (index = 0; index < DSA_MAX_SWITCHES; index++) { + ds = dst->ds[index]; + if (!ds) + continue; + + for (port = 0; port < ds->num_ports; port++) { + dp = &ds->ports[port]; + if (!dsa_port_is_valid(dp) || + dsa_port_is_dsa(dp) || + dsa_port_is_cpu(dp)) + continue; + + dp->cpu_dp = dst->cpu_dp; + } + } + pr_info("DSA: tree %d parsed\n", dst->tree); return 0; -- cgit v1.2.3