diff options
Diffstat (limited to 'drivers/net/dsa')
34 files changed, 470 insertions, 197 deletions
| diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 07507b4820d7..c26755f662c1 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -18,6 +18,7 @@ config NET_DSA_BCM_SF2  config NET_DSA_LOOP  	tristate "DSA mock-up Ethernet switch chip support" +	select NET_DSA_TAG_NONE  	select FIXED_PHY  	help  	  This enables support for a fake mock-up switch chip which @@ -99,6 +100,7 @@ config NET_DSA_SMSC_LAN9303_MDIO  config NET_DSA_VITESSE_VSC73XX  	tristate +	select NET_DSA_TAG_NONE  	select FIXED_PHY  	select VITESSE_PHY  	select GPIOLIB diff --git a/drivers/net/dsa/b53/Kconfig b/drivers/net/dsa/b53/Kconfig index 90b525160b71..ebaa4a80d544 100644 --- a/drivers/net/dsa/b53/Kconfig +++ b/drivers/net/dsa/b53/Kconfig @@ -2,6 +2,7 @@  menuconfig B53  	tristate "Broadcom BCM53xx managed switch support"  	depends on NET_DSA +	select NET_DSA_TAG_NONE  	select NET_DSA_TAG_BRCM  	select NET_DSA_TAG_BRCM_LEGACY  	select NET_DSA_TAG_BRCM_PREPEND diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c index 951f7935c872..595a548bb0a8 100644 --- a/drivers/net/dsa/hirschmann/hellcreek.c +++ b/drivers/net/dsa/hirschmann/hellcreek.c @@ -1176,11 +1176,6 @@ static int hellcreek_devlink_info_get(struct dsa_switch *ds,  				      struct netlink_ext_ack *extack)  {  	struct hellcreek *hellcreek = ds->priv; -	int ret; - -	ret = devlink_info_driver_name_put(req, "hellcreek"); -	if (ret) -		return ret;  	return devlink_info_version_fixed_put(req,  					      DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c index 80f07bd20593..2e270b479143 100644 --- a/drivers/net/dsa/lan9303-core.c +++ b/drivers/net/dsa/lan9303-core.c @@ -1005,9 +1005,11 @@ static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,  		ret = lan9303_read_switch_port(  			chip, port, lan9303_mib[u].offset, ®); -		if (ret) +		if (ret) {  			dev_warn(chip->dev, "Reading status port %d reg %u failed\n",  				 port, lan9303_mib[u].offset); +			reg = 0; +		}  		data[u] = reg;  	}  } diff --git a/drivers/net/dsa/lan9303_i2c.c b/drivers/net/dsa/lan9303_i2c.c index 7d746cd9ca1b..1cb41c36bd47 100644 --- a/drivers/net/dsa/lan9303_i2c.c +++ b/drivers/net/dsa/lan9303_i2c.c @@ -29,8 +29,7 @@ static const struct regmap_config lan9303_i2c_regmap_config = {  	.cache_type = REGCACHE_NONE,  }; -static int lan9303_i2c_probe(struct i2c_client *client, -			     const struct i2c_device_id *id) +static int lan9303_i2c_probe(struct i2c_client *client)  {  	struct lan9303_i2c *sw_dev;  	int ret; @@ -106,7 +105,7 @@ static struct i2c_driver lan9303_i2c_driver = {  		.name = "LAN9303_I2C",  		.of_match_table = of_match_ptr(lan9303_i2c_of_match),  	}, -	.probe = lan9303_i2c_probe, +	.probe_new = lan9303_i2c_probe,  	.remove = lan9303_i2c_remove,  	.shutdown = lan9303_i2c_shutdown,  	.id_table = lan9303_i2c_id, diff --git a/drivers/net/dsa/microchip/Kconfig b/drivers/net/dsa/microchip/Kconfig index 06b1efdb5e7d..913f83ef013c 100644 --- a/drivers/net/dsa/microchip/Kconfig +++ b/drivers/net/dsa/microchip/Kconfig @@ -3,6 +3,7 @@ menuconfig NET_DSA_MICROCHIP_KSZ_COMMON  	tristate "Microchip KSZ8795/KSZ9477/LAN937x series switch support"  	depends on NET_DSA  	select NET_DSA_TAG_KSZ +	select NET_DSA_TAG_NONE  	help  	  This driver adds support for Microchip KSZ9477 series switch and  	  KSZ8795/KSZ88x3 switch chips. diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h index 8582b4b67d98..ea05abfbd51d 100644 --- a/drivers/net/dsa/microchip/ksz8.h +++ b/drivers/net/dsa/microchip/ksz8.h @@ -57,5 +57,6 @@ int ksz8_reset_switch(struct ksz_device *dev);  int ksz8_switch_detect(struct ksz_device *dev);  int ksz8_switch_init(struct ksz_device *dev);  void ksz8_switch_exit(struct ksz_device *dev); +int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu);  #endif diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index bd3b133e7085..003b0ac2854c 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -76,6 +76,57 @@ int ksz8_reset_switch(struct ksz_device *dev)  	return 0;  } +static int ksz8863_change_mtu(struct ksz_device *dev, int frame_size) +{ +	u8 ctrl2 = 0; + +	if (frame_size <= KSZ8_LEGAL_PACKET_SIZE) +		ctrl2 |= KSZ8863_LEGAL_PACKET_ENABLE; +	else if (frame_size > KSZ8863_NORMAL_PACKET_SIZE) +		ctrl2 |= KSZ8863_HUGE_PACKET_ENABLE; + +	return ksz_rmw8(dev, REG_SW_CTRL_2, KSZ8863_LEGAL_PACKET_ENABLE | +			KSZ8863_HUGE_PACKET_ENABLE, ctrl2); +} + +static int ksz8795_change_mtu(struct ksz_device *dev, int frame_size) +{ +	u8 ctrl1 = 0, ctrl2 = 0; +	int ret; + +	if (frame_size > KSZ8_LEGAL_PACKET_SIZE) +		ctrl2 |= SW_LEGAL_PACKET_DISABLE; +	else if (frame_size > KSZ8863_NORMAL_PACKET_SIZE) +		ctrl1 |= SW_HUGE_PACKET; + +	ret = ksz_rmw8(dev, REG_SW_CTRL_1, SW_HUGE_PACKET, ctrl1); +	if (ret) +		return ret; + +	return ksz_rmw8(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, ctrl2); +} + +int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu) +{ +	u16 frame_size; + +	if (!dsa_is_cpu_port(dev->ds, port)) +		return 0; + +	frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + +	switch (dev->chip_id) { +	case KSZ8795_CHIP_ID: +	case KSZ8794_CHIP_ID: +	case KSZ8765_CHIP_ID: +		return ksz8795_change_mtu(dev, frame_size); +	case KSZ8830_CHIP_ID: +		return ksz8863_change_mtu(dev, frame_size); +	} + +	return -EOPNOTSUPP; +} +  static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue)  {  	u8 hi, lo; @@ -1233,8 +1284,6 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)  	masks = dev->info->masks;  	regs = dev->info->regs; -	/* Switch marks the maximum frame with extra byte as oversize. */ -	ksz_cfg(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, true);  	ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true);  	p = &dev->ports[dev->cpu_port]; @@ -1308,6 +1357,18 @@ int ksz8_setup(struct dsa_switch *ds)  	struct ksz_device *dev = ds->priv;  	int i; +	ds->mtu_enforcement_ingress = true; + +	/* We rely on software untagging on the CPU port, so that we +	 * can support both tagged and untagged VLANs +	 */ +	ds->untag_bridge_pvid = true; + +	/* VLAN filtering is partly controlled by the global VLAN +	 * Enable flag +	 */ +	ds->vlan_filtering_is_global = true; +  	ksz_cfg(dev, S_REPLACE_VID_CTRL, SW_FLOW_CTRL, true);  	/* Enable automatic fast aging when link changed detected. */ @@ -1367,16 +1428,6 @@ int ksz8_switch_init(struct ksz_device *dev)  	dev->phy_port_cnt = dev->info->port_cnt - 1;  	dev->port_mask = (BIT(dev->phy_port_cnt) - 1) | dev->info->cpu_ports; -	/* We rely on software untagging on the CPU port, so that we -	 * can support both tagged and untagged VLANs -	 */ -	dev->ds->untag_bridge_pvid = true; - -	/* VLAN filtering is partly controlled by the global VLAN -	 * Enable flag -	 */ -	dev->ds->vlan_filtering_is_global = true; -  	return 0;  } diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h index 77487d611824..7a57c6088f80 100644 --- a/drivers/net/dsa/microchip/ksz8795_reg.h +++ b/drivers/net/dsa/microchip/ksz8795_reg.h @@ -48,6 +48,9 @@  #define NO_EXC_COLLISION_DROP		BIT(3)  #define SW_LEGAL_PACKET_DISABLE		BIT(1) +#define KSZ8863_HUGE_PACKET_ENABLE	BIT(2) +#define KSZ8863_LEGAL_PACKET_ENABLE	BIT(1) +  #define REG_SW_CTRL_3			0x05   #define WEIGHTED_FAIR_QUEUE_ENABLE	BIT(3) diff --git a/drivers/net/dsa/microchip/ksz8863_smi.c b/drivers/net/dsa/microchip/ksz8863_smi.c index ddb40838181e..2f4623f3bd85 100644 --- a/drivers/net/dsa/microchip/ksz8863_smi.c +++ b/drivers/net/dsa/microchip/ksz8863_smi.c @@ -152,11 +152,10 @@ static int ksz8863_smi_probe(struct mdio_device *mdiodev)  						  ®map_smi[i], dev,  						  &rc);  		if (IS_ERR(dev->regmap[i])) { -			ret = PTR_ERR(dev->regmap[i]); -			dev_err(&mdiodev->dev, -				"Failed to initialize regmap%i: %d\n", -				ksz8863_regmap_config[i].val_bits, ret); -			return ret; +			return dev_err_probe(&mdiodev->dev, +					     PTR_ERR(dev->regmap[i]), +					     "Failed to initialize regmap%i\n", +					     ksz8863_regmap_config[i].val_bits);  		}  	} diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index a6a0321a8931..47b54ecf2c6f 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -45,24 +45,15 @@ static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,  int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu)  { -	u16 frame_size, max_frame = 0; -	int i; - -	frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; +	u16 frame_size; -	/* Cache the per-port MTU setting */ -	dev->ports[port].max_frame = frame_size; +	if (!dsa_is_cpu_port(dev->ds, port)) +		return 0; -	for (i = 0; i < dev->info->port_cnt; i++) -		max_frame = max(max_frame, dev->ports[i].max_frame); +	frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;  	return regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, -				  REG_SW_MTU_MASK, max_frame); -} - -int ksz9477_max_mtu(struct ksz_device *dev, int port) -{ -	return KSZ9477_MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN; +				  REG_SW_MTU_MASK, frame_size);  }  static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev) @@ -195,7 +186,8 @@ int ksz9477_reset_switch(struct ksz_device *dev)  	/* KSZ9893 compatible chips do not support refclk configuration */  	if (dev->chip_id == KSZ9893_CHIP_ID || -	    dev->chip_id == KSZ8563_CHIP_ID) +	    dev->chip_id == KSZ8563_CHIP_ID || +	    dev->chip_id == KSZ9563_CHIP_ID)  		return 0;  	data8 = SW_ENABLE_REFCLKO; @@ -1142,6 +1134,8 @@ int ksz9477_setup(struct dsa_switch *ds)  	struct ksz_device *dev = ds->priv;  	int ret = 0; +	ds->mtu_enforcement_ingress = true; +  	/* Required for port partitioning. */  	ksz9477_cfg32(dev, REG_SW_QM_CTRL__4, UNICAST_VLAN_BOUNDARY,  		      true); diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h index 00862c4cfb7f..7c5bb3032772 100644 --- a/drivers/net/dsa/microchip/ksz9477.h +++ b/drivers/net/dsa/microchip/ksz9477.h @@ -50,7 +50,6 @@ int ksz9477_mdb_add(struct ksz_device *dev, int port,  int ksz9477_mdb_del(struct ksz_device *dev, int port,  		    const struct switchdev_obj_port_mdb *mdb, struct dsa_db db);  int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu); -int ksz9477_max_mtu(struct ksz_device *dev, int port);  void ksz9477_config_cpu_port(struct dsa_switch *ds);  int ksz9477_enable_stp_addr(struct ksz_device *dev);  int ksz9477_reset_switch(struct ksz_device *dev); diff --git a/drivers/net/dsa/microchip/ksz9477_i2c.c b/drivers/net/dsa/microchip/ksz9477_i2c.c index 3763930dc6fc..c1a633ca1e6d 100644 --- a/drivers/net/dsa/microchip/ksz9477_i2c.c +++ b/drivers/net/dsa/microchip/ksz9477_i2c.c @@ -14,8 +14,7 @@  KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0); -static int ksz9477_i2c_probe(struct i2c_client *i2c, -			     const struct i2c_device_id *i2c_id) +static int ksz9477_i2c_probe(struct i2c_client *i2c)  {  	struct regmap_config rc;  	struct ksz_device *dev; @@ -30,17 +29,17 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c,  		rc.lock_arg = &dev->regmap_mutex;  		dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc);  		if (IS_ERR(dev->regmap[i])) { -			ret = PTR_ERR(dev->regmap[i]); -			dev_err(&i2c->dev, -				"Failed to initialize regmap%i: %d\n", -				ksz9477_regmap_config[i].val_bits, ret); -			return ret; +			return dev_err_probe(&i2c->dev, PTR_ERR(dev->regmap[i]), +					     "Failed to initialize regmap%i\n", +					     ksz9477_regmap_config[i].val_bits);  		}  	}  	if (i2c->dev.platform_data)  		dev->pdata = i2c->dev.platform_data; +	dev->irq = i2c->irq; +  	ret = ksz_switch_register(dev);  	/* Main DSA driver may not be started yet. */ @@ -101,7 +100,7 @@ static const struct of_device_id ksz9477_dt_ids[] = {  	},  	{  		.compatible = "microchip,ksz9563", -		.data = &ksz_switch_chips[KSZ9893] +		.data = &ksz_switch_chips[KSZ9563]  	},  	{  		.compatible = "microchip,ksz8563", @@ -120,7 +119,7 @@ static struct i2c_driver ksz9477_i2c_driver = {  		.name	= "ksz9477-switch",  		.of_match_table = of_match_ptr(ksz9477_dt_ids),  	}, -	.probe	= ksz9477_i2c_probe, +	.probe_new = ksz9477_i2c_probe,  	.remove	= ksz9477_i2c_remove,  	.shutdown = ksz9477_i2c_shutdown,  	.id_table = ksz9477_i2c_id, diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h index 53c68d286dd3..cc457fa64939 100644 --- a/drivers/net/dsa/microchip/ksz9477_reg.h +++ b/drivers/net/dsa/microchip/ksz9477_reg.h @@ -1615,6 +1615,4 @@  #define PTP_TRIG_UNIT_M			(BIT(MAX_TRIG_UNIT) - 1)  #define PTP_TS_UNIT_M			(BIT(MAX_TIMESTAMP_UNIT) - 1) -#define KSZ9477_MAX_FRAME_SIZE		9000 -  #endif /* KSZ9477_REGS_H */ diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index d612181b3226..423f944cc34c 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -14,6 +14,7 @@  #include <linux/phy.h>  #include <linux/etherdevice.h>  #include <linux/if_bridge.h> +#include <linux/if_vlan.h>  #include <linux/irq.h>  #include <linux/irqdomain.h>  #include <linux/of_mdio.h> @@ -69,6 +70,43 @@ struct ksz_stats_raw {  	u64 tx_discards;  }; +struct ksz88xx_stats_raw { +	u64 rx; +	u64 rx_hi; +	u64 rx_undersize; +	u64 rx_fragments; +	u64 rx_oversize; +	u64 rx_jabbers; +	u64 rx_symbol_err; +	u64 rx_crc_err; +	u64 rx_align_err; +	u64 rx_mac_ctrl; +	u64 rx_pause; +	u64 rx_bcast; +	u64 rx_mcast; +	u64 rx_ucast; +	u64 rx_64_or_less; +	u64 rx_65_127; +	u64 rx_128_255; +	u64 rx_256_511; +	u64 rx_512_1023; +	u64 rx_1024_1522; +	u64 tx; +	u64 tx_hi; +	u64 tx_late_col; +	u64 tx_pause; +	u64 tx_bcast; +	u64 tx_mcast; +	u64 tx_ucast; +	u64 tx_deferred; +	u64 tx_total_col; +	u64 tx_exc_col; +	u64 tx_single_col; +	u64 tx_mult_col; +	u64 rx_discards; +	u64 tx_discards; +}; +  static const struct ksz_mib_names ksz88xx_mib_names[] = {  	{ 0x00, "rx" },  	{ 0x01, "rx_hi" }, @@ -155,6 +193,7 @@ static const struct ksz_dev_ops ksz8_dev_ops = {  	.w_phy = ksz8_w_phy,  	.r_mib_cnt = ksz8_r_mib_cnt,  	.r_mib_pkt = ksz8_r_mib_pkt, +	.r_mib_stat64 = ksz88xx_r_mib_stats64,  	.freeze_mib = ksz8_freeze_mib,  	.port_init_cnt = ksz8_port_init_cnt,  	.fdb_dump = ksz8_fdb_dump, @@ -171,6 +210,7 @@ static const struct ksz_dev_ops ksz8_dev_ops = {  	.reset = ksz8_reset_switch,  	.init = ksz8_switch_init,  	.exit = ksz8_switch_exit, +	.change_mtu = ksz8_change_mtu,  };  static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port, @@ -206,7 +246,6 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {  	.mdb_add = ksz9477_mdb_add,  	.mdb_del = ksz9477_mdb_del,  	.change_mtu = ksz9477_change_mtu, -	.max_mtu = ksz9477_max_mtu,  	.phylink_mac_link_up = ksz9477_phylink_mac_link_up,  	.config_cpu_port = ksz9477_config_cpu_port,  	.enable_stp_addr = ksz9477_enable_stp_addr, @@ -243,7 +282,6 @@ static const struct ksz_dev_ops lan937x_dev_ops = {  	.mdb_add = ksz9477_mdb_add,  	.mdb_del = ksz9477_mdb_del,  	.change_mtu = lan937x_change_mtu, -	.max_mtu = ksz9477_max_mtu,  	.phylink_mac_link_up = ksz9477_phylink_mac_link_up,  	.config_cpu_port = lan937x_config_cpu_port,  	.enable_stp_addr = ksz9477_enable_stp_addr, @@ -1039,6 +1077,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {  		.num_statics = 16,  		.cpu_ports = 0x07,	/* can be configured as cpu port */  		.port_cnt = 3,		/* total port count */ +		.port_nirqs = 3,  		.ops = &ksz9477_dev_ops,  		.mib_names = ksz9477_mib_names,  		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names), @@ -1282,6 +1321,31 @@ const struct ksz_chip_data ksz_switch_chips[] = {  		.gbit_capable = {true, true, true},  	}, +	[KSZ9563] = { +		.chip_id = KSZ9563_CHIP_ID, +		.dev_name = "KSZ9563", +		.num_vlans = 4096, +		.num_alus = 4096, +		.num_statics = 16, +		.cpu_ports = 0x07,	/* can be configured as cpu port */ +		.port_cnt = 3,		/* total port count */ +		.port_nirqs = 3, +		.ops = &ksz9477_dev_ops, +		.mib_names = ksz9477_mib_names, +		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names), +		.reg_mib_cnt = MIB_COUNTER_NUM, +		.regs = ksz9477_regs, +		.masks = ksz9477_masks, +		.shifts = ksz9477_shifts, +		.xmii_ctrl0 = ksz9477_xmii_ctrl0, +		.xmii_ctrl1 = ksz8795_xmii_ctrl1, /* Same as ksz8795 */ +		.supports_mii = {false, false, true}, +		.supports_rmii = {false, false, true}, +		.supports_rgmii = {false, false, true}, +		.internal_phy = {true, true, false}, +		.gbit_capable = {true, true, true}, +	}, +  	[KSZ9567] = {  		.chip_id = KSZ9567_CHIP_ID,  		.dev_name = "KSZ9567", @@ -1557,6 +1621,55 @@ void ksz_r_mib_stats64(struct ksz_device *dev, int port)  	spin_unlock(&mib->stats64_lock);  } +void ksz88xx_r_mib_stats64(struct ksz_device *dev, int port) +{ +	struct ethtool_pause_stats *pstats; +	struct rtnl_link_stats64 *stats; +	struct ksz88xx_stats_raw *raw; +	struct ksz_port_mib *mib; + +	mib = &dev->ports[port].mib; +	stats = &mib->stats64; +	pstats = &mib->pause_stats; +	raw = (struct ksz88xx_stats_raw *)mib->counters; + +	spin_lock(&mib->stats64_lock); + +	stats->rx_packets = raw->rx_bcast + raw->rx_mcast + raw->rx_ucast + +		raw->rx_pause; +	stats->tx_packets = raw->tx_bcast + raw->tx_mcast + raw->tx_ucast + +		raw->tx_pause; + +	/* HW counters are counting bytes + FCS which is not acceptable +	 * for rtnl_link_stats64 interface +	 */ +	stats->rx_bytes = raw->rx + raw->rx_hi - stats->rx_packets * ETH_FCS_LEN; +	stats->tx_bytes = raw->tx + raw->tx_hi - stats->tx_packets * ETH_FCS_LEN; + +	stats->rx_length_errors = raw->rx_undersize + raw->rx_fragments + +		raw->rx_oversize; + +	stats->rx_crc_errors = raw->rx_crc_err; +	stats->rx_frame_errors = raw->rx_align_err; +	stats->rx_dropped = raw->rx_discards; +	stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors + +		stats->rx_frame_errors  + stats->rx_dropped; + +	stats->tx_window_errors = raw->tx_late_col; +	stats->tx_fifo_errors = raw->tx_discards; +	stats->tx_aborted_errors = raw->tx_exc_col; +	stats->tx_errors = stats->tx_window_errors + stats->tx_fifo_errors + +		stats->tx_aborted_errors; + +	stats->multicast = raw->rx_mcast; +	stats->collisions = raw->tx_total_col; + +	pstats->tx_pause_frames = raw->tx_pause; +	pstats->rx_pause_frames = raw->rx_pause; + +	spin_unlock(&mib->stats64_lock); +} +  static void ksz_get_stats64(struct dsa_switch *ds, int port,  			    struct rtnl_link_stats64 *s)  { @@ -2389,7 +2502,8 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,  	if (dev->chip_id == KSZ8830_CHIP_ID ||  	    dev->chip_id == KSZ8563_CHIP_ID || -	    dev->chip_id == KSZ9893_CHIP_ID) +	    dev->chip_id == KSZ9893_CHIP_ID || +	    dev->chip_id == KSZ9563_CHIP_ID)  		proto = DSA_TAG_PROTO_KSZ9893;  	if (dev->chip_id == KSZ9477_CHIP_ID || @@ -2473,10 +2587,29 @@ static int ksz_max_mtu(struct dsa_switch *ds, int port)  {  	struct ksz_device *dev = ds->priv; -	if (!dev->dev_ops->max_mtu) -		return -EOPNOTSUPP; +	switch (dev->chip_id) { +	case KSZ8795_CHIP_ID: +	case KSZ8794_CHIP_ID: +	case KSZ8765_CHIP_ID: +		return KSZ8795_HUGE_PACKET_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN; +	case KSZ8830_CHIP_ID: +		return KSZ8863_HUGE_PACKET_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN; +	case KSZ8563_CHIP_ID: +	case KSZ9477_CHIP_ID: +	case KSZ9563_CHIP_ID: +	case KSZ9567_CHIP_ID: +	case KSZ9893_CHIP_ID: +	case KSZ9896_CHIP_ID: +	case KSZ9897_CHIP_ID: +	case LAN9370_CHIP_ID: +	case LAN9371_CHIP_ID: +	case LAN9372_CHIP_ID: +	case LAN9373_CHIP_ID: +	case LAN9374_CHIP_ID: +		return KSZ9477_MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN; +	} -	return dev->dev_ops->max_mtu(dev, port); +	return -EOPNOTSUPP;  }  static void ksz_set_xmii(struct ksz_device *dev, int port, @@ -2509,7 +2642,8 @@ static void ksz_set_xmii(struct ksz_device *dev, int port,  		data8 |= bitval[P_RGMII_SEL];  		/* On KSZ9893, disable RGMII in-band status support */  		if (dev->chip_id == KSZ9893_CHIP_ID || -		    dev->chip_id == KSZ8563_CHIP_ID) +		    dev->chip_id == KSZ8563_CHIP_ID || +		    dev->chip_id == KSZ9563_CHIP_ID)  			data8 &= ~P_MII_MAC_MODE;  		break;  	default: @@ -2782,6 +2916,8 @@ static int ksz_switch_detect(struct ksz_device *dev)  			if (id4 == SKU_ID_KSZ8563)  				dev->chip_id = KSZ8563_CHIP_ID; +			else if (id4 == SKU_ID_KSZ9563) +				dev->chip_id = KSZ9563_CHIP_ID;  			else  				dev->chip_id = KSZ9893_CHIP_ID; diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 9cfa179575ce..055d61ff3fb8 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -95,7 +95,6 @@ struct ksz_port {  	struct ksz_port_mib mib;  	phy_interface_t interface; -	u16 max_frame;  	u32 rgmii_tx_val;  	u32 rgmii_rx_val;  	struct ksz_device *ksz_dev; @@ -154,6 +153,7 @@ enum ksz_model {  	KSZ9896,  	KSZ9897,  	KSZ9893, +	KSZ9563,  	KSZ9567,  	LAN9370,  	LAN9371, @@ -172,6 +172,7 @@ enum ksz_chip_id {  	KSZ9896_CHIP_ID = 0x00989600,  	KSZ9897_CHIP_ID = 0x00989700,  	KSZ9893_CHIP_ID = 0x00989300, +	KSZ9563_CHIP_ID = 0x00956300,  	KSZ9567_CHIP_ID = 0x00956700,  	LAN9370_CHIP_ID = 0x00937000,  	LAN9371_CHIP_ID = 0x00937100, @@ -320,7 +321,6 @@ struct ksz_dev_ops {  	void (*get_caps)(struct ksz_device *dev, int port,  			 struct phylink_config *config);  	int (*change_mtu)(struct ksz_device *dev, int port, int mtu); -	int (*max_mtu)(struct ksz_device *dev, int port);  	void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);  	void (*port_init_cnt)(struct ksz_device *dev, int port);  	void (*phylink_mac_config)(struct ksz_device *dev, int port, @@ -345,6 +345,7 @@ void ksz_switch_remove(struct ksz_device *dev);  void ksz_init_mib_timer(struct ksz_device *dev);  void ksz_r_mib_stats64(struct ksz_device *dev, int port); +void ksz88xx_r_mib_stats64(struct ksz_device *dev, int port);  void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);  bool ksz_get_gbit(struct ksz_device *dev, int port);  phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit); @@ -454,6 +455,11 @@ static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value)  	return regmap_bulk_write(dev->regmap[2], reg, val, 2);  } +static inline int ksz_rmw8(struct ksz_device *dev, int offset, u8 mask, u8 val) +{ +	return regmap_update_bits(dev->regmap[0], offset, mask, val); +} +  static inline int ksz_pread8(struct ksz_device *dev, int port, int offset,  			     u8 *data)  { @@ -551,6 +557,7 @@ static inline int is_lan937x(struct ksz_device *dev)  /* KSZ9893, KSZ9563, KSZ8563 specific register  */  #define REG_CHIP_ID4			0x0f  #define SKU_ID_KSZ8563			0x3c +#define SKU_ID_KSZ9563			0x1c  /* Driver set switch broadcast storm protection at 10% rate. */  #define BROADCAST_STORM_PROT_RATE	10 @@ -585,6 +592,12 @@ static inline int is_lan937x(struct ksz_device *dev)  #define PORT_SRC_PHY_INT		1 +#define KSZ8795_HUGE_PACKET_SIZE	2000 +#define KSZ8863_HUGE_PACKET_SIZE	1916 +#define KSZ8863_NORMAL_PACKET_SIZE	1536 +#define KSZ8_LEGAL_PACKET_SIZE		1518 +#define KSZ9477_MAX_FRAME_SIZE		9000 +  /* Regmap tables generation */  #define KSZ_SPI_OP_RD		3  #define KSZ_SPI_OP_WR		2 diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c index 1b6ab891b986..96c52e8fb51b 100644 --- a/drivers/net/dsa/microchip/ksz_spi.c +++ b/drivers/net/dsa/microchip/ksz_spi.c @@ -71,11 +71,9 @@ static int ksz_spi_probe(struct spi_device *spi)  		dev->regmap[i] = devm_regmap_init_spi(spi, &rc);  		if (IS_ERR(dev->regmap[i])) { -			ret = PTR_ERR(dev->regmap[i]); -			dev_err(&spi->dev, -				"Failed to initialize regmap%i: %d\n", -				regmap_config[i].val_bits, ret); -			return ret; +			return dev_err_probe(&spi->dev, PTR_ERR(dev->regmap[i]), +					     "Failed to initialize regmap%i\n", +					     regmap_config[i].val_bits);  		}  	} @@ -163,7 +161,7 @@ static const struct of_device_id ksz_dt_ids[] = {  	},  	{  		.compatible = "microchip,ksz9563", -		.data = &ksz_switch_chips[KSZ9893] +		.data = &ksz_switch_chips[KSZ9563]  	},  	{  		.compatible = "microchip,ksz8563", diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index 7e4f307a0387..06d3d0308cba 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -242,7 +242,11 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)  	}  	/* Write the frame size in PORT_MAX_FR_SIZE register */ -	ksz_pwrite16(dev, port, PORT_MAX_FR_SIZE, new_mtu); +	ret = ksz_pwrite16(dev, port, PORT_MAX_FR_SIZE, new_mtu); +	if (ret) { +		dev_err(ds->dev, "failed to update mtu for port %d\n", port); +		return ret; +	}  	return 0;  } diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile index c8eca2b6f959..49bf358b9c4f 100644 --- a/drivers/net/dsa/mv88e6xxx/Makefile +++ b/drivers/net/dsa/mv88e6xxx/Makefile @@ -15,3 +15,7 @@ mv88e6xxx-objs += port_hidden.o  mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o  mv88e6xxx-objs += serdes.o  mv88e6xxx-objs += smi.o +mv88e6xxx-objs += trace.o + +# for tracing framework to find trace.h +CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 2479be3a1e35..ba4fff8690aa 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -833,10 +833,13 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,  	chip->info->ops->phylink_get_caps(chip, port, config); -	/* Internal ports need GMII for PHYLIB */ -	if (mv88e6xxx_phy_is_internal(ds, port)) +	if (mv88e6xxx_phy_is_internal(ds, port)) { +		__set_bit(PHY_INTERFACE_MODE_INTERNAL, +			  config->supported_interfaces); +		/* Internal ports with no phy-mode need GMII for PHYLIB */  		__set_bit(PHY_INTERFACE_MODE_GMII,  			  config->supported_interfaces); +	}  }  static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, @@ -4074,6 +4077,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {  	.port_sync_link = mv88e6xxx_port_sync_link,  	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,  	.port_tag_remap = mv88e6095_port_tag_remap, +	.port_set_policy = mv88e6352_port_set_policy,  	.port_set_frame_mode = mv88e6351_port_set_frame_mode,  	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,  	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood, @@ -4346,6 +4350,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {  	.port_sync_link = mv88e6xxx_port_sync_link,  	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,  	.port_tag_remap = mv88e6095_port_tag_remap, +	.port_set_policy = mv88e6352_port_set_policy,  	.port_set_frame_mode = mv88e6351_port_set_frame_mode,  	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,  	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood, @@ -5029,6 +5034,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {  	.phy_write = mv88e6xxx_g2_smi_phy_write,  	.port_set_link = mv88e6xxx_port_set_link,  	.port_sync_link = mv88e6xxx_port_sync_link, +	.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,  	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,  	.port_tag_remap = mv88e6095_port_tag_remap,  	.port_set_frame_mode = mv88e6351_port_set_frame_mode, @@ -5073,6 +5079,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {  	.phy_write = mv88e6xxx_g2_smi_phy_write,  	.port_set_link = mv88e6xxx_port_set_link,  	.port_sync_link = mv88e6xxx_port_sync_link, +	.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,  	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,  	.port_tag_remap = mv88e6095_port_tag_remap,  	.port_set_frame_mode = mv88e6351_port_set_frame_mode, diff --git a/drivers/net/dsa/mv88e6xxx/devlink.c b/drivers/net/dsa/mv88e6xxx/devlink.c index 1266eabee086..a08dab75e0c0 100644 --- a/drivers/net/dsa/mv88e6xxx/devlink.c +++ b/drivers/net/dsa/mv88e6xxx/devlink.c @@ -821,11 +821,6 @@ int mv88e6xxx_devlink_info_get(struct dsa_switch *ds,  			       struct netlink_ext_ack *extack)  {  	struct mv88e6xxx_chip *chip = ds->priv; -	int err; - -	err = devlink_info_driver_name_put(req, "mv88e6xxx"); -	if (err) -		return err;  	return devlink_info_version_fixed_put(req,  					      DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c index 40bd67a5c8e9..61ae2d61e25c 100644 --- a/drivers/net/dsa/mv88e6xxx/global1_atu.c +++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c @@ -12,6 +12,7 @@  #include "chip.h"  #include "global1.h" +#include "trace.h"  /* Offset 0x01: ATU FID Register */ @@ -114,6 +115,19 @@ static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip)  	return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0);  } +static int mv88e6xxx_g1_read_atu_violation(struct mv88e6xxx_chip *chip) +{ +	int err; + +	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_OP, +				 MV88E6XXX_G1_ATU_OP_BUSY | +				 MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION); +	if (err) +		return err; + +	return mv88e6xxx_g1_atu_op_wait(chip); +} +  static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)  {  	u16 val; @@ -159,6 +173,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid)  	return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB);  } +static int mv88e6xxx_g1_atu_fid_read(struct mv88e6xxx_chip *chip, u16 *fid) +{ +	u16 val = 0, upper = 0, op = 0; +	int err = -EOPNOTSUPP; + +	if (mv88e6xxx_num_databases(chip) > 256) { +		err = mv88e6xxx_g1_read(chip, MV88E6352_G1_ATU_FID, &val); +		val &= 0xfff; +		if (err) +			return err; +	} else { +		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &op); +		if (err) +			return err; +		if (mv88e6xxx_num_databases(chip) > 64) { +			/* ATU DBNum[7:4] are located in ATU Control 15:12 */ +			err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL, +						&upper); +			if (err) +				return err; + +			upper = (upper >> 8) & 0x00f0; +		} else if (mv88e6xxx_num_databases(chip) > 16) { +			/* ATU DBNum[5:4] are located in ATU Operation 9:8 */ +			upper = (op >> 4) & 0x30; +		} + +		/* ATU DBNum[3:0] are located in ATU Operation 3:0 */ +		val = (op & 0xf) | upper; +	} +	*fid = val; + +	return err; +} +  /* Offset 0x0C: ATU Data Register */  static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip, @@ -353,14 +402,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)  {  	struct mv88e6xxx_chip *chip = dev_id;  	struct mv88e6xxx_atu_entry entry; -	int spid; -	int err; -	u16 val; +	int err, spid; +	u16 val, fid;  	mv88e6xxx_reg_lock(chip); -	err = mv88e6xxx_g1_atu_op(chip, 0, -				  MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION); +	err = mv88e6xxx_g1_read_atu_violation(chip);  	if (err)  		goto out; @@ -368,6 +415,10 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)  	if (err)  		goto out; +	err = mv88e6xxx_g1_atu_fid_read(chip, &fid); +	if (err) +		goto out; +  	err = mv88e6xxx_g1_atu_data_read(chip, &entry);  	if (err)  		goto out; @@ -378,30 +429,24 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)  	spid = entry.state; -	if (val & MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION) { -		dev_err_ratelimited(chip->dev, -				    "ATU age out violation for %pM\n", -				    entry.mac); -	} -  	if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) { -		dev_err_ratelimited(chip->dev, -				    "ATU member violation for %pM portvec %x spid %d\n", -				    entry.mac, entry.portvec, spid); +		trace_mv88e6xxx_atu_member_violation(chip->dev, spid, +						     entry.portvec, entry.mac, +						     fid);  		chip->ports[spid].atu_member_violation++;  	}  	if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) { -		dev_err_ratelimited(chip->dev, -				    "ATU miss violation for %pM portvec %x spid %d\n", -				    entry.mac, entry.portvec, spid); +		trace_mv88e6xxx_atu_miss_violation(chip->dev, spid, +						   entry.portvec, entry.mac, +						   fid);  		chip->ports[spid].atu_miss_violation++;  	}  	if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) { -		dev_err_ratelimited(chip->dev, -				    "ATU full violation for %pM portvec %x spid %d\n", -				    entry.mac, entry.portvec, spid); +		trace_mv88e6xxx_atu_full_violation(chip->dev, spid, +						   entry.portvec, entry.mac, +						   fid);  		chip->ports[spid].atu_full_violation++;  	}  	mv88e6xxx_reg_unlock(chip); diff --git a/drivers/net/dsa/mv88e6xxx/global1_vtu.c b/drivers/net/dsa/mv88e6xxx/global1_vtu.c index 38e18f5811bf..bcfb4a812055 100644 --- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c +++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c @@ -13,6 +13,7 @@  #include "chip.h"  #include "global1.h" +#include "trace.h"  /* Offset 0x02: VTU FID Register */ @@ -628,14 +629,12 @@ static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)  	spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;  	if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) { -		dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n", -				    vid, spid); +		trace_mv88e6xxx_vtu_member_violation(chip->dev, spid, vid);  		chip->ports[spid].vtu_member_violation++;  	}  	if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) { -		dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n", -				    vid, spid); +		trace_mv88e6xxx_vtu_miss_violation(chip->dev, spid, vid);  		chip->ports[spid].vtu_miss_violation++;  	} diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index 5c4195c635b0..f79cf716c541 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -133,6 +133,15 @@ int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,  	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);  } +int mv88e6320_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, +				   phy_interface_t mode) +{ +	if (port != 2 && port != 5 && port != 6) +		return -EOPNOTSUPP; + +	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); +} +  int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)  {  	u16 reg; diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index cb04243f37c1..aec9d4fd20e3 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h @@ -332,6 +332,8 @@ int mv88e6xxx_port_wait_bit(struct mv88e6xxx_chip *chip, int port, int reg,  int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,  			     int pause); +int mv88e6320_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, +				   phy_interface_t mode);  int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,  				   phy_interface_t mode);  int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, diff --git a/drivers/net/dsa/mv88e6xxx/trace.c b/drivers/net/dsa/mv88e6xxx/trace.c new file mode 100644 index 000000000000..7833cb50ca5d --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/trace.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright 2022 NXP + */ + +#define CREATE_TRACE_POINTS +#include "trace.h" diff --git a/drivers/net/dsa/mv88e6xxx/trace.h b/drivers/net/dsa/mv88e6xxx/trace.h new file mode 100644 index 000000000000..f59ca04768e7 --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/trace.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright 2022 NXP + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM	mv88e6xxx + +#if !defined(_MV88E6XXX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _MV88E6XXX_TRACE_H + +#include <linux/device.h> +#include <linux/if_ether.h> +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(mv88e6xxx_atu_violation, + +	TP_PROTO(const struct device *dev, int spid, u16 portvec, +		 const unsigned char *addr, u16 fid), + +	TP_ARGS(dev, spid, portvec, addr, fid), + +	TP_STRUCT__entry( +		__string(name, dev_name(dev)) +		__field(int, spid) +		__field(u16, portvec) +		__array(unsigned char, addr, ETH_ALEN) +		__field(u16, fid) +	), + +	TP_fast_assign( +		__assign_str(name, dev_name(dev)); +		__entry->spid = spid; +		__entry->portvec = portvec; +		memcpy(__entry->addr, addr, ETH_ALEN); +		__entry->fid = fid; +	), + +	TP_printk("dev %s spid %d portvec 0x%x addr %pM fid %u", +		  __get_str(name), __entry->spid, __entry->portvec, +		  __entry->addr, __entry->fid) +); + +DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_member_violation, +	     TP_PROTO(const struct device *dev, int spid, u16 portvec, +		      const unsigned char *addr, u16 fid), +	     TP_ARGS(dev, spid, portvec, addr, fid)); + +DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_miss_violation, +	     TP_PROTO(const struct device *dev, int spid, u16 portvec, +		      const unsigned char *addr, u16 fid), +	     TP_ARGS(dev, spid, portvec, addr, fid)); + +DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_full_violation, +	     TP_PROTO(const struct device *dev, int spid, u16 portvec, +		      const unsigned char *addr, u16 fid), +	     TP_ARGS(dev, spid, portvec, addr, fid)); + +DECLARE_EVENT_CLASS(mv88e6xxx_vtu_violation, + +	TP_PROTO(const struct device *dev, int spid, u16 vid), + +	TP_ARGS(dev, spid, vid), + +	TP_STRUCT__entry( +		__string(name, dev_name(dev)) +		__field(int, spid) +		__field(u16, vid) +	), + +	TP_fast_assign( +		__assign_str(name, dev_name(dev)); +		__entry->spid = spid; +		__entry->vid = vid; +	), + +	TP_printk("dev %s spid %d vid %u", +		  __get_str(name), __entry->spid, __entry->vid) +); + +DEFINE_EVENT(mv88e6xxx_vtu_violation, mv88e6xxx_vtu_member_violation, +	     TP_PROTO(const struct device *dev, int spid, u16 vid), +	     TP_ARGS(dev, spid, vid)); + +DEFINE_EVENT(mv88e6xxx_vtu_violation, mv88e6xxx_vtu_miss_violation, +	     TP_PROTO(const struct device *dev, int spid, u16 vid), +	     TP_ARGS(dev, spid, vid)); + +#endif /* _MV88E6XXX_TRACE_H */ + +/* We don't want to use include/trace/events */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE	trace +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index dd3a18cc89dd..3b738cb2ae6e 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -1048,21 +1048,14 @@ static void felix_phylink_get_caps(struct dsa_switch *ds, int port,  	 */  	config->legacy_pre_march2020 = false; +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | +				   MAC_10 | MAC_100 | MAC_1000FD | +				   MAC_2500FD; +  	__set_bit(ocelot->ports[port]->phy_mode,  		  config->supported_interfaces);  } -static void felix_phylink_validate(struct dsa_switch *ds, int port, -				   unsigned long *supported, -				   struct phylink_link_state *state) -{ -	struct ocelot *ocelot = ds->priv; -	struct felix *felix = ocelot_to_felix(ocelot); - -	if (felix->info->phylink_validate) -		felix->info->phylink_validate(ocelot, port, supported, state); -} -  static struct phylink_pcs *felix_phylink_mac_select_pcs(struct dsa_switch *ds,  							int port,  							phy_interface_t iface) @@ -1370,7 +1363,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)  		return -ENOMEM;  	ocelot->map		= felix->info->map; -	ocelot->stats_layout	= felix->info->stats_layout;  	ocelot->num_mact_rows	= felix->info->num_mact_rows;  	ocelot->vcap		= felix->info->vcap;  	ocelot->vcap_pol.base	= felix->info->vcap_pol_base; @@ -2050,7 +2042,6 @@ const struct dsa_switch_ops felix_switch_ops = {  	.get_sset_count			= felix_get_sset_count,  	.get_ts_info			= felix_get_ts_info,  	.phylink_get_caps		= felix_phylink_get_caps, -	.phylink_validate		= felix_phylink_validate,  	.phylink_mac_select_pcs		= felix_phylink_mac_select_pcs,  	.phylink_mac_link_down		= felix_phylink_mac_link_down,  	.phylink_mac_link_up		= felix_phylink_mac_link_up, diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index c9c29999c336..be22d6ccd7c8 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -28,7 +28,6 @@ struct felix_info {  	const struct ocelot_ops		*ops;  	const u32			*port_modes;  	int				num_mact_rows; -	const struct ocelot_stat_layout	*stats_layout;  	int				num_ports;  	int				num_tx_queues;  	struct vcap_props		*vcap; @@ -52,9 +51,6 @@ struct felix_info {  	int	(*mdio_bus_alloc)(struct ocelot *ocelot);  	void	(*mdio_bus_free)(struct ocelot *ocelot); -	void	(*phylink_validate)(struct ocelot *ocelot, int port, -				    unsigned long *supported, -				    struct phylink_link_state *state);  	int	(*port_setup_tc)(struct dsa_switch *ds, int port,  				 enum tc_setup_type type, void *type_data);  	void	(*tas_guard_bands_update)(struct ocelot *ocelot, int port); diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 26a35ae322d1..01ac70fd7ddf 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -565,10 +565,6 @@ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {  	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),  }; -static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS] = { -	OCELOT_COMMON_STATS, -}; -  static const struct vcap_field vsc9959_vcap_es0_keys[] = {  	[VCAP_ES0_EGR_PORT]			= {  0,  3},  	[VCAP_ES0_IGR_PORT]			= {  3,  3}, @@ -885,35 +881,6 @@ static int vsc9959_reset(struct ocelot *ocelot)  	return 0;  } -static void vsc9959_phylink_validate(struct ocelot *ocelot, int port, -				     unsigned long *supported, -				     struct phylink_link_state *state) -{ -	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - -	phylink_set_port_modes(mask); -	phylink_set(mask, Autoneg); -	phylink_set(mask, Pause); -	phylink_set(mask, Asym_Pause); -	phylink_set(mask, 10baseT_Half); -	phylink_set(mask, 10baseT_Full); -	phylink_set(mask, 100baseT_Half); -	phylink_set(mask, 100baseT_Full); -	phylink_set(mask, 1000baseT_Half); -	phylink_set(mask, 1000baseT_Full); -	phylink_set(mask, 1000baseX_Full); - -	if (state->interface == PHY_INTERFACE_MODE_INTERNAL || -	    state->interface == PHY_INTERFACE_MODE_2500BASEX || -	    state->interface == PHY_INTERFACE_MODE_USXGMII) { -		phylink_set(mask, 2500baseT_Full); -		phylink_set(mask, 2500baseX_Full); -	} - -	linkmode_and(supported, supported, mask); -	linkmode_and(state->advertising, state->advertising, mask); -} -  /* Watermark encode   * Bit 8:   Unit; 0:1, 1:16   * Bit 7-0: Value to be multiplied with unit @@ -2575,7 +2542,6 @@ static const struct felix_info felix_info_vsc9959 = {  	.regfields		= vsc9959_regfields,  	.map			= vsc9959_regmap,  	.ops			= &vsc9959_ops, -	.stats_layout		= vsc9959_stats_layout,  	.vcap			= vsc9959_vcap_props,  	.vcap_pol_base		= VSC9959_VCAP_POLICER_BASE,  	.vcap_pol_max		= VSC9959_VCAP_POLICER_MAX, @@ -2588,7 +2554,6 @@ static const struct felix_info felix_info_vsc9959 = {  	.ptp_caps		= &vsc9959_ptp_caps,  	.mdio_bus_alloc		= vsc9959_mdio_bus_alloc,  	.mdio_bus_free		= vsc9959_mdio_bus_free, -	.phylink_validate	= vsc9959_phylink_validate,  	.port_modes		= vsc9959_port_modes,  	.port_setup_tc		= vsc9959_port_setup_tc,  	.port_sched_speed_set	= vsc9959_sched_speed_set, diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c index 7af33b2c685d..88ed3a2e487a 100644 --- a/drivers/net/dsa/ocelot/seville_vsc9953.c +++ b/drivers/net/dsa/ocelot/seville_vsc9953.c @@ -543,10 +543,6 @@ static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {  	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 11, 4),  }; -static const struct ocelot_stat_layout vsc9953_stats_layout[OCELOT_NUM_STATS] = { -	OCELOT_COMMON_STATS, -}; -  static const struct vcap_field vsc9953_vcap_es0_keys[] = {  	[VCAP_ES0_EGR_PORT]			= {  0,  4},  	[VCAP_ES0_IGR_PORT]			= {  4,  4}, @@ -840,32 +836,6 @@ static int vsc9953_reset(struct ocelot *ocelot)  	return 0;  } -static void vsc9953_phylink_validate(struct ocelot *ocelot, int port, -				     unsigned long *supported, -				     struct phylink_link_state *state) -{ -	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - -	phylink_set_port_modes(mask); -	phylink_set(mask, Autoneg); -	phylink_set(mask, Pause); -	phylink_set(mask, Asym_Pause); -	phylink_set(mask, 10baseT_Full); -	phylink_set(mask, 10baseT_Half); -	phylink_set(mask, 100baseT_Full); -	phylink_set(mask, 100baseT_Half); -	phylink_set(mask, 1000baseT_Full); -	phylink_set(mask, 1000baseX_Full); - -	if (state->interface == PHY_INTERFACE_MODE_INTERNAL) { -		phylink_set(mask, 2500baseT_Full); -		phylink_set(mask, 2500baseX_Full); -	} - -	linkmode_and(supported, supported, mask); -	linkmode_and(state->advertising, state->advertising, mask); -} -  /* Watermark encode   * Bit 9:   Unit; 0:1, 1:16   * Bit 8-0: Value to be multiplied with unit @@ -996,7 +966,6 @@ static const struct felix_info seville_info_vsc9953 = {  	.regfields		= vsc9953_regfields,  	.map			= vsc9953_regmap,  	.ops			= &vsc9953_ops, -	.stats_layout		= vsc9953_stats_layout,  	.vcap			= vsc9953_vcap_props,  	.vcap_pol_base		= VSC9953_VCAP_POLICER_BASE,  	.vcap_pol_max		= VSC9953_VCAP_POLICER_MAX, @@ -1007,7 +976,6 @@ static const struct felix_info seville_info_vsc9953 = {  	.num_tx_queues		= OCELOT_NUM_TC,  	.mdio_bus_alloc		= vsc9953_mdio_bus_alloc,  	.mdio_bus_free		= vsc9953_mdio_bus_free, -	.phylink_validate	= vsc9953_phylink_validate,  	.port_modes		= vsc9953_port_modes,  }; diff --git a/drivers/net/dsa/sja1105/sja1105_devlink.c b/drivers/net/dsa/sja1105/sja1105_devlink.c index 10c6fea1227f..30b1f1ba762f 100644 --- a/drivers/net/dsa/sja1105/sja1105_devlink.c +++ b/drivers/net/dsa/sja1105/sja1105_devlink.c @@ -95,6 +95,8 @@ static int sja1105_setup_devlink_regions(struct dsa_switch *ds)  		if (IS_ERR(region)) {  			while (--i >= 0)  				dsa_devlink_region_destroy(priv->regions[i]); + +			kfree(priv->regions);  			return PTR_ERR(region);  		} @@ -120,16 +122,10 @@ int sja1105_devlink_info_get(struct dsa_switch *ds,  			     struct netlink_ext_ack *extack)  {  	struct sja1105_private *priv = ds->priv; -	int rc; - -	rc = devlink_info_driver_name_put(req, "sja1105"); -	if (rc) -		return rc; -	rc = devlink_info_version_fixed_put(req, -					    DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, -					    priv->info->name); -	return rc; +	return devlink_info_version_fixed_put(req, +					      DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, +					      priv->info->name);  }  int sja1105_devlink_setup(struct dsa_switch *ds) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 412666111b0c..b70dcf32a26d 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -1038,7 +1038,7 @@ static int sja1105_init_l2_policing(struct sja1105_private *priv)  		policing[bcast].sharindx = port;  		/* Only SJA1110 has multicast policers */ -		if (mcast <= table->ops->max_entry_count) +		if (mcast < table->ops->max_entry_count)  			policing[mcast].sharindx = port;  	} diff --git a/drivers/net/dsa/xrs700x/xrs700x_i2c.c b/drivers/net/dsa/xrs700x/xrs700x_i2c.c index 54065cdedd35..14ff6887a225 100644 --- a/drivers/net/dsa/xrs700x/xrs700x_i2c.c +++ b/drivers/net/dsa/xrs700x/xrs700x_i2c.c @@ -76,8 +76,7 @@ static const struct regmap_config xrs700x_i2c_regmap_config = {  	.val_format_endian = REGMAP_ENDIAN_BIG  }; -static int xrs700x_i2c_probe(struct i2c_client *i2c, -			     const struct i2c_device_id *i2c_id) +static int xrs700x_i2c_probe(struct i2c_client *i2c)  {  	struct xrs700x *priv;  	int ret; @@ -148,7 +147,7 @@ static struct i2c_driver xrs700x_i2c_driver = {  		.name	= "xrs700x-i2c",  		.of_match_table = of_match_ptr(xrs700x_i2c_dt_ids),  	}, -	.probe	= xrs700x_i2c_probe, +	.probe_new = xrs700x_i2c_probe,  	.remove	= xrs700x_i2c_remove,  	.shutdown = xrs700x_i2c_shutdown,  	.id_table = xrs700x_i2c_id, |