diff --git a/include/net/dsa.h b/include/net/dsa.h index 7e93869819f9..58969b9a090c 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -171,6 +171,7 @@ struct dsa_port { struct dsa_switch *ds; unsigned int index; const char *name; + struct dsa_port *cpu_dp; struct net_device *netdev; struct device_node *dn; unsigned int ageing_time; 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); diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 5c510f4ba0ce..7c2326f3b538 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -185,7 +185,7 @@ extern const struct dsa_device_ops trailer_netdev_ops; static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p) { - return p->dp->ds->dst->cpu_dp->netdev; + return p->dp->cpu_dp->netdev; } #endif diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c index 5d4f6ffa3424..e60906125375 100644 --- a/net/dsa/legacy.c +++ b/net/dsa/legacy.c @@ -129,6 +129,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) ds->dsa_port_mask |= 1 << i; } else { ds->enabled_port_mask |= 1 << i; + ds->ports[i].cpu_dp = dst->cpu_dp; } valid_name_found = true; } diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 9bf4c27f3393..a80b46777a04 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1140,9 +1140,11 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, struct net_device *master; struct net_device *slave_dev; struct dsa_slave_priv *p; + struct dsa_port *cpu_dp; int ret; - master = ds->dst->cpu_dp->netdev; + cpu_dp = ds->dst->cpu_dp; + master = cpu_dp->netdev; slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, NET_NAME_UNKNOWN, ether_setup);