diff options
Diffstat (limited to 'net/dsa/dsa2.c')
| -rw-r--r-- | net/dsa/dsa2.c | 64 | 
1 files changed, 38 insertions, 26 deletions
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index c00ee464afc7..3b5f434cad3f 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -18,6 +18,7 @@  #include <linux/rtnetlink.h>  #include <linux/of.h>  #include <linux/of_net.h> +#include <net/devlink.h>  #include "dsa_priv.h" @@ -257,14 +258,39 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)  static int dsa_port_setup(struct dsa_port *dp)  { +	enum devlink_port_flavour flavour;  	struct dsa_switch *ds = dp->ds; -	int err = 0; +	struct dsa_switch_tree *dst = ds->dst; +	int err; + +	if (dp->type == DSA_PORT_TYPE_UNUSED) +		return 0;  	memset(&dp->devlink_port, 0, sizeof(dp->devlink_port)); +	dp->mac = of_get_mac_address(dp->dn); -	if (dp->type != DSA_PORT_TYPE_UNUSED) -		err = devlink_port_register(ds->devlink, &dp->devlink_port, -					    dp->index); +	switch (dp->type) { +	case DSA_PORT_TYPE_CPU: +		flavour = DEVLINK_PORT_FLAVOUR_CPU; +		break; +	case DSA_PORT_TYPE_DSA: +		flavour = DEVLINK_PORT_FLAVOUR_DSA; +		break; +	case DSA_PORT_TYPE_USER: /* fall-through */ +	default: +		flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; +		break; +	} + +	/* dp->index is used now as port_number. However +	 * CPU and DSA ports should have separate numbering +	 * independent from front panel port numbers. +	 */ +	devlink_port_attrs_set(&dp->devlink_port, flavour, +			       dp->index, false, 0, +			       (const char *) &dst->index, sizeof(dst->index)); +	err = devlink_port_register(ds->devlink, &dp->devlink_port, +				    dp->index);  	if (err)  		return err; @@ -272,13 +298,6 @@ static int dsa_port_setup(struct dsa_port *dp)  	case DSA_PORT_TYPE_UNUSED:  		break;  	case DSA_PORT_TYPE_CPU: -		/* dp->index is used now as port_number. However -		 * CPU ports should have separate numbering -		 * independent from front panel port numbers. -		 */ -		devlink_port_attrs_set(&dp->devlink_port, -				       DEVLINK_PORT_FLAVOUR_CPU, -				       dp->index, false, 0);  		err = dsa_port_link_register_of(dp);  		if (err) {  			dev_err(ds->dev, "failed to setup link for port %d.%d\n", @@ -287,13 +306,6 @@ static int dsa_port_setup(struct dsa_port *dp)  		}  		break;  	case DSA_PORT_TYPE_DSA: -		/* dp->index is used now as port_number. However -		 * DSA ports should have separate numbering -		 * independent from front panel port numbers. -		 */ -		devlink_port_attrs_set(&dp->devlink_port, -				       DEVLINK_PORT_FLAVOUR_DSA, -				       dp->index, false, 0);  		err = dsa_port_link_register_of(dp);  		if (err) {  			dev_err(ds->dev, "failed to setup link for port %d.%d\n", @@ -302,9 +314,6 @@ static int dsa_port_setup(struct dsa_port *dp)  		}  		break;  	case DSA_PORT_TYPE_USER: -		devlink_port_attrs_set(&dp->devlink_port, -				       DEVLINK_PORT_FLAVOUR_PHYSICAL, -				       dp->index, false, 0);  		err = dsa_slave_create(dp);  		if (err)  			dev_err(ds->dev, "failed to create slave for port %d.%d\n", @@ -326,6 +335,8 @@ static void dsa_port_teardown(struct dsa_port *dp)  	case DSA_PORT_TYPE_UNUSED:  		break;  	case DSA_PORT_TYPE_CPU: +		dsa_tag_driver_put(dp->tag_ops); +		/* fall-through */  	case DSA_PORT_TYPE_DSA:  		dsa_port_link_unregister_of(dp);  		break; @@ -360,14 +371,14 @@ static int dsa_switch_setup(struct dsa_switch *ds)  	if (err)  		return err; -	err = ds->ops->setup(ds); -	if (err < 0) -		return err; -  	err = dsa_switch_register_notifier(ds);  	if (err)  		return err; +	err = ds->ops->setup(ds); +	if (err < 0) +		return err; +  	if (!ds->slave_mii_bus && ds->ops->phy_read) {  		ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);  		if (!ds->slave_mii_bus) @@ -568,13 +579,14 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master)  	enum dsa_tag_protocol tag_protocol;  	tag_protocol = ds->ops->get_tag_protocol(ds, dp->index); -	tag_ops = dsa_resolve_tag_protocol(tag_protocol); +	tag_ops = dsa_tag_driver_get(tag_protocol);  	if (IS_ERR(tag_ops)) {  		dev_warn(ds->dev, "No tagger for this switch\n");  		return PTR_ERR(tag_ops);  	}  	dp->type = DSA_PORT_TYPE_CPU; +	dp->filter = tag_ops->filter;  	dp->rcv = tag_ops->rcv;  	dp->tag_ops = tag_ops;  	dp->master = master;  |