From 5b32fe070c2ddf31adc42c26dab8af346b652538 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 27 Oct 2017 15:55:13 -0400 Subject: net: dsa: get ports within parsing code There is no point into hiding the -EINVAL error code in ERR_PTR from a dsa_get_ports function, simply get the "ports" node directly from within the dsa_parse_ports_dn function. This also has the effect to make the pdata and device tree handling code symmetrical inside _dsa_register_switch. At the same time, rename dsa_parse_ports_dn to dsa_parse_ports_of because _of is a more common suffix for device tree parsing functions. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 4d1ccf87c59c..9d57f8dee9a1 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -590,11 +590,17 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) return 0; } -static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds) +static int dsa_parse_ports_of(struct device_node *dn, struct dsa_switch *ds) { - struct device_node *port; - int err; + struct device_node *ports, *port; u32 reg; + int err; + + ports = of_get_child_by_name(dn, "ports"); + if (!ports) { + dev_err(ds->dev, "no ports child node found\n"); + return -EINVAL; + } for_each_available_child_of_node(ports, port) { err = of_property_read_u32(port, "reg", ®); @@ -665,26 +671,11 @@ static int dsa_parse_member(struct dsa_chip_data *pd, u32 *tree, u32 *index) return 0; } -static struct device_node *dsa_get_ports(struct dsa_switch *ds, - struct device_node *np) -{ - struct device_node *ports; - - ports = of_get_child_by_name(np, "ports"); - if (!ports) { - dev_err(ds->dev, "no ports child node found\n"); - return ERR_PTR(-EINVAL); - } - - return ports; -} - static int _dsa_register_switch(struct dsa_switch *ds) { 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; int i, err; @@ -693,11 +684,7 @@ static int _dsa_register_switch(struct dsa_switch *ds) if (err) return err; - ports = dsa_get_ports(ds, np); - if (IS_ERR(ports)) - return PTR_ERR(ports); - - err = dsa_parse_ports_dn(ports, ds); + err = dsa_parse_ports_of(np, ds); if (err) return err; } else { -- cgit From fd223e2e66eb076b5dda586db9a5a3c99f76f99a Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 27 Oct 2017 15:55:14 -0400 Subject: net: dsa: add port parse functions Add symmetrical DSA port parsing functions for pdata and device tree, used to parse and validate a given port node or platform data. They don't do much for the moment but will be extended later on to assign a port type and get device references. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 9d57f8dee9a1..a0ee91cd3814 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -590,9 +590,17 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) return 0; } +static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) +{ + dp->dn = dn; + + return 0; +} + static int dsa_parse_ports_of(struct device_node *dn, struct dsa_switch *ds) { struct device_node *ports, *port; + struct dsa_port *dp; u32 reg; int err; @@ -610,22 +618,45 @@ static int dsa_parse_ports_of(struct device_node *dn, struct dsa_switch *ds) if (reg >= ds->num_ports) return -EINVAL; - ds->ports[reg].dn = port; + dp = &ds->ports[reg]; + + err = dsa_port_parse_of(dp, port); + if (err) + return err; } return 0; } +static int dsa_port_parse(struct dsa_port *dp, const char *name, + struct device *dev) +{ + dp->name = name; + + return 0; +} + static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds) { bool valid_name_found = false; + struct dsa_port *dp; + struct device *dev; + const char *name; unsigned int i; + int err; for (i = 0; i < DSA_MAX_PORTS; i++) { - if (!cd->port_names[i]) + name = cd->port_names[i]; + dev = cd->netdev[i]; + dp = &ds->ports[i]; + + if (!name) continue; - ds->ports[i].name = cd->port_names[i]; + err = dsa_port_parse(dp, name, dev); + if (err) + return err; + valid_name_found = true; } -- cgit From 6d4e5c570c2d66c806ecc6bd851fcf881fe8a38e Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 27 Oct 2017 15:55:15 -0400 Subject: net: dsa: get port type at parse time Assign a port's type at parsed time instead of waiting for the tree to be completed. Because this is now done earlier, we can use the port's type in dsa_port_is_* helpers instead of digging again in topology description. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index a0ee91cd3814..895c38427ef0 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -87,23 +87,17 @@ static void dsa_dst_del_ds(struct dsa_switch_tree *dst, */ static bool dsa_port_is_valid(struct dsa_port *port) { - return !!(port->dn || port->name); + return port->type != DSA_PORT_TYPE_UNUSED; } static bool dsa_port_is_dsa(struct dsa_port *port) { - if (port->name && !strcmp(port->name, "dsa")) - return true; - else - return !!of_parse_phandle(port->dn, "link", 0); + return port->type == DSA_PORT_TYPE_DSA; } static bool dsa_port_is_cpu(struct dsa_port *port) { - if (port->name && !strcmp(port->name, "cpu")) - return true; - else - return !!of_parse_phandle(port->dn, "ethernet", 0); + return port->type == DSA_PORT_TYPE_CPU; } static bool dsa_ds_find_port_dn(struct dsa_switch *ds, @@ -183,8 +177,6 @@ static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds) err = dsa_port_complete(dst, ds, port, index); if (err != 0) return err; - - port->type = DSA_PORT_TYPE_DSA; } return 0; @@ -500,8 +492,6 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, dst->cpu_dp->master = ethernet_dev; } - port->type = DSA_PORT_TYPE_CPU; - tag_protocol = ds->ops->get_tag_protocol(ds); tag_ops = dsa_resolve_tag_protocol(tag_protocol); if (IS_ERR(tag_ops)) { @@ -534,8 +524,6 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds) err = dsa_cpu_parse(port, index, dst, ds); if (err) return err; - } else { - port->type = DSA_PORT_TYPE_USER; } } @@ -592,6 +580,17 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) { + struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); + struct device_node *link = of_parse_phandle(dn, "link", 0); + + if (ethernet) { + dp->type = DSA_PORT_TYPE_CPU; + } else if (link) { + dp->type = DSA_PORT_TYPE_DSA; + } else { + dp->type = DSA_PORT_TYPE_USER; + } + dp->dn = dn; return 0; @@ -631,6 +630,14 @@ static int dsa_parse_ports_of(struct device_node *dn, struct dsa_switch *ds) static int dsa_port_parse(struct dsa_port *dp, const char *name, struct device *dev) { + if (!strcmp(name, "cpu")) { + dp->type = DSA_PORT_TYPE_CPU; + } else if (!strcmp(name, "dsa")) { + dp->type = DSA_PORT_TYPE_DSA; + } else { + dp->type = DSA_PORT_TYPE_USER; + } + dp->name = name; return 0; -- cgit From cbabb0ac01052f79cf96d7b7e3d3451ffd275864 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 27 Oct 2017 15:55:17 -0400 Subject: net: dsa: get master device at port parsing time Fetching the master device can be done directly when a port is parsed from device tree or pdata, instead of waiting until dsa_dst_parse. Now that -EPROBE_DEFER is returned before we add the switch to the tree, there is no need to check for this error after dsa_dst_parse. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 895c38427ef0..8cd84c1b3dc0 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -470,27 +470,9 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, { const struct dsa_device_ops *tag_ops; enum dsa_tag_protocol tag_protocol; - struct net_device *ethernet_dev; - struct device_node *ethernet; - if (port->dn) { - ethernet = of_parse_phandle(port->dn, "ethernet", 0); - if (!ethernet) - return -EINVAL; - ethernet_dev = of_find_net_device_by_node(ethernet); - if (!ethernet_dev) - return -EPROBE_DEFER; - } else { - ethernet_dev = dsa_dev_to_net_device(ds->cd->netdev[index]); - if (!ethernet_dev) - return -EPROBE_DEFER; - dev_put(ethernet_dev); - } - - if (!dst->cpu_dp) { + if (!dst->cpu_dp) dst->cpu_dp = port; - dst->cpu_dp->master = ethernet_dev; - } tag_protocol = ds->ops->get_tag_protocol(ds); tag_ops = dsa_resolve_tag_protocol(tag_protocol); @@ -584,7 +566,14 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) struct device_node *link = of_parse_phandle(dn, "link", 0); if (ethernet) { + struct net_device *master; + + master = of_find_net_device_by_node(ethernet); + if (!master) + return -EPROBE_DEFER; + dp->type = DSA_PORT_TYPE_CPU; + dp->master = master; } else if (link) { dp->type = DSA_PORT_TYPE_DSA; } else { @@ -631,7 +620,16 @@ static int dsa_port_parse(struct dsa_port *dp, const char *name, struct device *dev) { if (!strcmp(name, "cpu")) { + struct net_device *master; + + master = dsa_dev_to_net_device(dev); + if (!master) + return -EPROBE_DEFER; + + dev_put(master); + dp->type = DSA_PORT_TYPE_CPU; + dp->master = master; } else if (!strcmp(name, "dsa")) { dp->type = DSA_PORT_TYPE_DSA; } else { @@ -773,14 +771,8 @@ static int _dsa_register_switch(struct dsa_switch *ds) } err = dsa_dst_parse(dst); - if (err) { - if (err == -EPROBE_DEFER) { - dsa_dst_del_ds(dst, ds, ds->index); - return err; - } - + if (err) goto out_del_dst; - } err = dsa_dst_apply(dst); if (err) { -- cgit From 1838fa89a22cbc9ec87e995683e241a82d87e6df Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 27 Oct 2017 15:55:18 -0400 Subject: net: dsa: get port name at parse time Get the optional "label" property and assign a default one directly at parse time instead of doing it when creating the slave. For legacy, simply assign the port name stored in cd->port_names. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli 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 8cd84c1b3dc0..3c134ff26863 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -260,11 +260,6 @@ static int dsa_user_port_apply(struct dsa_port *port) const char *name = port->name; int err; - if (port->dn) - name = of_get_property(port->dn, "label", NULL); - if (!name) - name = "eth%d"; - err = dsa_slave_create(port, name); if (err) { dev_warn(ds->dev, "Failed to create slave %d: %d\n", @@ -564,6 +559,7 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) { struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); struct device_node *link = of_parse_phandle(dn, "link", 0); + const char *name = of_get_property(dn, "label", NULL); if (ethernet) { struct net_device *master; @@ -577,7 +573,11 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) } else if (link) { dp->type = DSA_PORT_TYPE_DSA; } else { + if (!name) + name = "eth%d"; + dp->type = DSA_PORT_TYPE_USER; + dp->name = name; } dp->dn = dn; -- cgit From 951259aa60180e2897d28b538bf68a3a213da471 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 27 Oct 2017 15:55:19 -0400 Subject: net: dsa: remove name arg from slave create Now that slave dsa_port always have their name set, there is no need to pass it to dsa_slave_create() anymore. Remove this argument. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net/dsa/dsa2.c') diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 3c134ff26863..797d1156b4e6 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -257,10 +257,9 @@ static void dsa_cpu_port_unapply(struct dsa_port *port) static int dsa_user_port_apply(struct dsa_port *port) { struct dsa_switch *ds = port->ds; - const char *name = port->name; int err; - err = dsa_slave_create(port, name); + err = dsa_slave_create(port); if (err) { dev_warn(ds->dev, "Failed to create slave %d: %d\n", port->index, err); -- cgit