diff options
Diffstat (limited to 'drivers/net/dsa/microchip/ksz_common.c')
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 50 | 
1 files changed, 28 insertions, 22 deletions
| diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 7c2968a639eb..8a04302018dc 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -22,21 +22,40 @@  void ksz_update_port_member(struct ksz_device *dev, int port)  { -	struct ksz_port *p; +	struct ksz_port *p = &dev->ports[port]; +	struct dsa_switch *ds = dev->ds; +	u8 port_member = 0, cpu_port; +	const struct dsa_port *dp;  	int i; -	for (i = 0; i < dev->port_cnt; i++) { -		if (i == port || i == dev->cpu_port) +	if (!dsa_is_user_port(ds, port)) +		return; + +	dp = dsa_to_port(ds, port); +	cpu_port = BIT(dsa_upstream_port(ds, port)); + +	for (i = 0; i < ds->num_ports; i++) { +		const struct dsa_port *other_dp = dsa_to_port(ds, i); +		struct ksz_port *other_p = &dev->ports[i]; +		u8 val = 0; + +		if (!dsa_is_user_port(ds, i))  			continue; -		p = &dev->ports[i]; -		if (!(dev->member & (1 << i))) +		if (port == i) +			continue; +		if (!dp->bridge_dev || dp->bridge_dev != other_dp->bridge_dev)  			continue; -		/* Port is a member of the bridge and is forwarding. */ -		if (p->stp_state == BR_STATE_FORWARDING && -		    p->member != dev->member) -			dev->dev_ops->cfg_port_member(dev, i, dev->member); +		if (other_p->stp_state == BR_STATE_FORWARDING && +		    p->stp_state == BR_STATE_FORWARDING) { +			val |= BIT(port); +			port_member |= BIT(i); +		} + +		dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);  	} + +	dev->dev_ops->cfg_port_member(dev, port, port_member | cpu_port);  }  EXPORT_SYMBOL_GPL(ksz_update_port_member); @@ -175,12 +194,6 @@ EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);  int ksz_port_bridge_join(struct dsa_switch *ds, int port,  			 struct net_device *br)  { -	struct ksz_device *dev = ds->priv; - -	mutex_lock(&dev->dev_mutex); -	dev->br_member |= (1 << port); -	mutex_unlock(&dev->dev_mutex); -  	/* port_stp_state_set() will be called after to put the port in  	 * appropriate state so there is no need to do anything.  	 */ @@ -192,13 +205,6 @@ EXPORT_SYMBOL_GPL(ksz_port_bridge_join);  void ksz_port_bridge_leave(struct dsa_switch *ds, int port,  			   struct net_device *br)  { -	struct ksz_device *dev = ds->priv; - -	mutex_lock(&dev->dev_mutex); -	dev->br_member &= ~(1 << port); -	dev->member &= ~(1 << port); -	mutex_unlock(&dev->dev_mutex); -  	/* port_stp_state_set() will be called after to put the port in  	 * forwarding state so there is no need to do anything.  	 */ |