diff options
Diffstat (limited to 'drivers/net/dsa/microchip')
| -rw-r--r-- | drivers/net/dsa/microchip/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz8.h | 1 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz8795.c | 75 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz8795_reg.h | 3 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz8863_smi.c | 9 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz9477.c | 24 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz9477.h | 1 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz9477_i2c.c | 17 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz9477_reg.h | 2 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 150 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_common.h | 17 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/ksz_spi.c | 10 | ||||
| -rw-r--r-- | drivers/net/dsa/microchip/lan937x_main.c | 6 | 
13 files changed, 256 insertions, 60 deletions
| 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;  } |