diff options
Diffstat (limited to 'drivers/net/dsa/b53/b53_common.c')
| -rw-r--r-- | drivers/net/dsa/b53/b53_common.c | 101 | 
1 files changed, 43 insertions, 58 deletions
| diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 604f54112665..af4761968733 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1222,7 +1222,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,  		return;  	/* Enable flow control on BCM5301x's CPU port */ -	if (is5301x(dev) && port == dev->cpu_port) +	if (is5301x(dev) && dsa_is_cpu_port(ds, port))  		tx_pause = rx_pause = true;  	if (phydev->pause) { @@ -1291,12 +1291,6 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,  				return;  			}  		} -	} else if (is5301x(dev)) { -		if (port != dev->cpu_port) { -			b53_force_port_config(dev, dev->cpu_port, 2000, -					      DUPLEX_FULL, true, true); -			b53_force_link(dev, dev->cpu_port, 1); -		}  	}  	/* Re-negotiate EEE if it was enabled already */ @@ -1349,10 +1343,8 @@ void b53_phylink_validate(struct dsa_switch *ds, int port,  		phylink_set(mask, 100baseT_Full);  	} -	bitmap_and(supported, supported, mask, -		   __ETHTOOL_LINK_MODE_MASK_NBITS); -	bitmap_and(state->advertising, state->advertising, mask, -		   __ETHTOOL_LINK_MODE_MASK_NBITS); +	linkmode_and(supported, supported, mask); +	linkmode_and(state->advertising, state->advertising, mask);  	phylink_helper_basex_speed(state);  } @@ -1550,7 +1542,7 @@ int b53_vlan_del(struct dsa_switch *ds, int port,  }  EXPORT_SYMBOL(b53_vlan_del); -/* Address Resolution Logic routines */ +/* Address Resolution Logic routines. Caller must hold &dev->arl_mutex. */  static int b53_arl_op_wait(struct b53_device *dev)  {  	unsigned int timeout = 10; @@ -1715,6 +1707,7 @@ int b53_fdb_add(struct dsa_switch *ds, int port,  		const unsigned char *addr, u16 vid)  {  	struct b53_device *priv = ds->priv; +	int ret;  	/* 5325 and 5365 require some more massaging, but could  	 * be supported eventually @@ -1722,7 +1715,11 @@ int b53_fdb_add(struct dsa_switch *ds, int port,  	if (is5325(priv) || is5365(priv))  		return -EOPNOTSUPP; -	return b53_arl_op(priv, 0, port, addr, vid, true); +	mutex_lock(&priv->arl_mutex); +	ret = b53_arl_op(priv, 0, port, addr, vid, true); +	mutex_unlock(&priv->arl_mutex); + +	return ret;  }  EXPORT_SYMBOL(b53_fdb_add); @@ -1730,8 +1727,13 @@ int b53_fdb_del(struct dsa_switch *ds, int port,  		const unsigned char *addr, u16 vid)  {  	struct b53_device *priv = ds->priv; +	int ret; + +	mutex_lock(&priv->arl_mutex); +	ret = b53_arl_op(priv, 0, port, addr, vid, false); +	mutex_unlock(&priv->arl_mutex); -	return b53_arl_op(priv, 0, port, addr, vid, false); +	return ret;  }  EXPORT_SYMBOL(b53_fdb_del); @@ -1788,6 +1790,8 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,  	int ret;  	u8 reg; +	mutex_lock(&priv->arl_mutex); +  	/* Start search operation */  	reg = ARL_SRCH_STDN;  	b53_write8(priv, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, reg); @@ -1795,18 +1799,18 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,  	do {  		ret = b53_arl_search_wait(priv);  		if (ret) -			return ret; +			break;  		b53_arl_search_rd(priv, 0, &results[0]);  		ret = b53_fdb_copy(port, &results[0], cb, data);  		if (ret) -			return ret; +			break;  		if (priv->num_arl_bins > 2) {  			b53_arl_search_rd(priv, 1, &results[1]);  			ret = b53_fdb_copy(port, &results[1], cb, data);  			if (ret) -				return ret; +				break;  			if (!results[0].is_valid && !results[1].is_valid)  				break; @@ -1814,6 +1818,8 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,  	} while (count++ < b53_max_arl_entries(priv) / 2); +	mutex_unlock(&priv->arl_mutex); +  	return 0;  }  EXPORT_SYMBOL(b53_fdb_dump); @@ -1822,6 +1828,7 @@ int b53_mdb_add(struct dsa_switch *ds, int port,  		const struct switchdev_obj_port_mdb *mdb)  {  	struct b53_device *priv = ds->priv; +	int ret;  	/* 5325 and 5365 require some more massaging, but could  	 * be supported eventually @@ -1829,7 +1836,11 @@ int b53_mdb_add(struct dsa_switch *ds, int port,  	if (is5325(priv) || is5365(priv))  		return -EOPNOTSUPP; -	return b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true); +	mutex_lock(&priv->arl_mutex); +	ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true); +	mutex_unlock(&priv->arl_mutex); + +	return ret;  }  EXPORT_SYMBOL(b53_mdb_add); @@ -1839,7 +1850,9 @@ int b53_mdb_del(struct dsa_switch *ds, int port,  	struct b53_device *priv = ds->priv;  	int ret; +	mutex_lock(&priv->arl_mutex);  	ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, false); +	mutex_unlock(&priv->arl_mutex);  	if (ret)  		dev_err(ds->dev, "failed to delete MDB entry\n"); @@ -2302,33 +2315,30 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM5325_DEVICE_ID,  		.dev_name = "BCM5325",  		.vlans = 16, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x3f,  		.arl_bins = 2,  		.arl_buckets = 1024,  		.imp_port = 5, -		.cpu_port = B53_CPU_PORT_25,  		.duplex_reg = B53_DUPLEX_STAT_FE,  	},  	{  		.chip_id = BCM5365_DEVICE_ID,  		.dev_name = "BCM5365",  		.vlans = 256, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x3f,  		.arl_bins = 2,  		.arl_buckets = 1024,  		.imp_port = 5, -		.cpu_port = B53_CPU_PORT_25,  		.duplex_reg = B53_DUPLEX_STAT_FE,  	},  	{  		.chip_id = BCM5389_DEVICE_ID,  		.dev_name = "BCM5389",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x11f,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2338,11 +2348,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM5395_DEVICE_ID,  		.dev_name = "BCM5395",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x11f,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2352,11 +2361,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM5397_DEVICE_ID,  		.dev_name = "BCM5397",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x11f,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS_9798,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2366,11 +2374,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM5398_DEVICE_ID,  		.dev_name = "BCM5398",  		.vlans = 4096, -		.enabled_ports = 0x7f, +		.enabled_ports = 0x17f,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS_9798,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2380,12 +2387,11 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM53115_DEVICE_ID,  		.dev_name = "BCM53115",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x11f,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.vta_regs = B53_VTA_REGS,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,  		.jumbo_size_reg = B53_JUMBO_MAX_SIZE, @@ -2394,11 +2400,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM53125_DEVICE_ID,  		.dev_name = "BCM53125",  		.vlans = 4096, -		.enabled_ports = 0xff, +		.enabled_ports = 0x1ff,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2412,7 +2417,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2426,7 +2430,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS_63XX,  		.duplex_reg = B53_DUPLEX_STAT_63XX,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, @@ -2436,11 +2439,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM53010_DEVICE_ID,  		.dev_name = "BCM53010",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x1bf,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2454,7 +2456,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2468,7 +2469,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2478,11 +2478,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM53018_DEVICE_ID,  		.dev_name = "BCM53018",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x1bf,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2492,11 +2491,10 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.chip_id = BCM53019_DEVICE_ID,  		.dev_name = "BCM53019",  		.vlans = 4096, -		.enabled_ports = 0x1f, +		.enabled_ports = 0x1bf,  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2510,7 +2508,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2524,7 +2521,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2539,7 +2535,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 256,  		.imp_port = 8, -		.cpu_port = 8, /* TODO: ports 4, 5, 8 */  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2553,7 +2548,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 1024,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2567,7 +2561,6 @@ static const struct b53_chip_data b53_switch_chips[] = {  		.arl_bins = 4,  		.arl_buckets = 256,  		.imp_port = 8, -		.cpu_port = B53_CPU_PORT,  		.vta_regs = B53_VTA_REGS,  		.duplex_reg = B53_DUPLEX_STAT_GE,  		.jumbo_pm_reg = B53_JUMBO_PORT_MASK, @@ -2593,7 +2586,6 @@ static int b53_switch_init(struct b53_device *dev)  			dev->vta_regs[2] = chip->vta_regs[2];  			dev->jumbo_pm_reg = chip->jumbo_pm_reg;  			dev->imp_port = chip->imp_port; -			dev->cpu_port = chip->cpu_port;  			dev->num_vlans = chip->vlans;  			dev->num_arl_bins = chip->arl_bins;  			dev->num_arl_buckets = chip->arl_buckets; @@ -2625,16 +2617,8 @@ static int b53_switch_init(struct b53_device *dev)  			break;  #endif  		} -	} else if (dev->chip_id == BCM53115_DEVICE_ID) { -		u64 strap_value; - -		b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); -		/* use second IMP port if GMII is enabled */ -		if (strap_value & SV_GMII_CTRL_115) -			dev->cpu_port = 5;  	} -	dev->enabled_ports |= BIT(dev->cpu_port);  	dev->num_ports = fls(dev->enabled_ports);  	dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS); @@ -2705,6 +2689,7 @@ struct b53_device *b53_switch_alloc(struct device *base,  	mutex_init(&dev->reg_mutex);  	mutex_init(&dev->stats_mutex); +	mutex_init(&dev->arl_mutex);  	return dev;  } |