Commit 7fa28bc6 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'microchip-dsa-driver-improvements'

Oleksij Rempel says:

====================
Microchip DSA Driver Improvements

changes v2:
- set .max_register = U8_MAX, it should be more readable
- clarify in the RMW error handling patch, logging behavior
  expectation.

I'd like to share a set of patches for the Microchip DSA driver. These
patches were chosen from a bigger set because they are simpler and
should be easier to review. The goal is to make the code easier to read,
get rid of unused code, and handle errors better.
====================

Link: https://lore.kernel.org/r/20230526073445.668430-1-o.rempel@pengutronix.de


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents eee2e03c d0dec333
Loading
Loading
Loading
Loading
+5 −23
Original line number Diff line number Diff line
@@ -28,13 +28,13 @@

static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
{
	regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0);
	regmap_update_bits(ksz_regmap_8(dev), addr, bits, set ? bits : 0);
}

static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
			 bool set)
{
	regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset),
	regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
			   bits, set ? bits : 0);
}

@@ -941,7 +941,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
{
	u8 learn[DSA_MAX_PORTS];
	int first, index, cnt;
	struct ksz_port *p;
	const u16 *regs;

	regs = dev->info->regs;
@@ -955,9 +954,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
		cnt = dev->info->port_cnt;
	}
	for (index = first; index < cnt; index++) {
		p = &dev->ports[index];
		if (!p->on)
			continue;
		ksz_pread8(dev, index, regs[P_STP_CTRL], &learn[index]);
		if (!(learn[index] & PORT_LEARN_DISABLE))
			ksz_pwrite8(dev, index, regs[P_STP_CTRL],
@@ -965,9 +961,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
	}
	ksz_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_DYN_MAC_TABLE, true);
	for (index = first; index < cnt; index++) {
		p = &dev->ports[index];
		if (!p->on)
			continue;
		if (!(learn[index] & PORT_LEARN_DISABLE))
			ksz_pwrite8(dev, index, regs[P_STP_CTRL], learn[index]);
	}
@@ -1338,25 +1331,14 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)

	ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true);

	p = &dev->ports[dev->cpu_port];
	p->on = 1;

	ksz8_port_setup(dev, dev->cpu_port, true);

	for (i = 0; i < dev->phy_port_cnt; i++) {
		p = &dev->ports[i];

		ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED);

		/* Last port may be disabled. */
		if (i == dev->phy_port_cnt)
			break;
		p->on = 1;
	}
	for (i = 0; i < dev->phy_port_cnt; i++) {
		p = &dev->ports[i];
		if (!p->on)
			continue;

		if (!ksz_is_ksz88x3(dev)) {
			ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote);
			if (remote & KSZ8_PORT_FIBER_MODE)
@@ -1425,14 +1407,14 @@ int ksz8_setup(struct dsa_switch *ds)
	ksz_cfg(dev, S_LINK_AGING_CTRL, SW_LINK_AUTO_AGING, true);

	/* Enable aggressive back off algorithm in half duplex mode. */
	regmap_update_bits(dev->regmap[0], REG_SW_CTRL_1,
	regmap_update_bits(ksz_regmap_8(dev), REG_SW_CTRL_1,
			   SW_AGGR_BACKOFF, SW_AGGR_BACKOFF);

	/*
	 * Make sure unicast VLAN boundary is set as default and
	 * enable no excessive collision drop.
	 */
	regmap_update_bits(dev->regmap[0], REG_SW_CTRL_2,
	regmap_update_bits(ksz_regmap_8(dev), REG_SW_CTRL_2,
			   UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP,
			   UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP);

+12 −1
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ static const struct regmap_config ksz8863_regmap_config[] = {
		.cache_type = REGCACHE_NONE,
		.lock = ksz_regmap_lock,
		.unlock = ksz_regmap_unlock,
		.max_register = U8_MAX,
	},
	{
		.name = "#16",
@@ -113,6 +114,7 @@ static const struct regmap_config ksz8863_regmap_config[] = {
		.cache_type = REGCACHE_NONE,
		.lock = ksz_regmap_lock,
		.unlock = ksz_regmap_unlock,
		.max_register = U8_MAX,
	},
	{
		.name = "#32",
@@ -122,11 +124,14 @@ static const struct regmap_config ksz8863_regmap_config[] = {
		.cache_type = REGCACHE_NONE,
		.lock = ksz_regmap_lock,
		.unlock = ksz_regmap_unlock,
		.max_register = U8_MAX,
	}
};

static int ksz8863_smi_probe(struct mdio_device *mdiodev)
{
	struct device *ddev = &mdiodev->dev;
	const struct ksz_chip_data *chip;
	struct regmap_config rc;
	struct ksz_device *dev;
	int ret;
@@ -136,9 +141,15 @@ static int ksz8863_smi_probe(struct mdio_device *mdiodev)
	if (!dev)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(ksz8863_regmap_config); i++) {
	chip = device_get_match_data(ddev);
	if (!chip)
		return -EINVAL;

	for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
		rc = ksz8863_regmap_config[i];
		rc.lock_arg = &dev->regmap_mutex;
		rc.wr_table = chip->wr_table;
		rc.rd_table = chip->rd_table;
		dev->regmap[i] = devm_regmap_init(&mdiodev->dev,
						  &regmap_smi[i], dev,
						  &rc);
+12 −12
Original line number Diff line number Diff line
@@ -21,25 +21,25 @@

static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
{
	regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0);
	regmap_update_bits(ksz_regmap_8(dev), addr, bits, set ? bits : 0);
}

static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
			 bool set)
{
	regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset),
	regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
			   bits, set ? bits : 0);
}

static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
{
	regmap_update_bits(dev->regmap[2], addr, bits, set ? bits : 0);
	regmap_update_bits(ksz_regmap_32(dev), addr, bits, set ? bits : 0);
}

static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
			       u32 bits, bool set)
{
	regmap_update_bits(dev->regmap[2], PORT_CTRL_ADDR(port, offset),
	regmap_update_bits(ksz_regmap_32(dev), PORT_CTRL_ADDR(port, offset),
			   bits, set ? bits : 0);
}

@@ -52,7 +52,7 @@ int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu)

	frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;

	return regmap_update_bits(dev->regmap[1], REG_SW_MTU__2,
	return regmap_update_bits(ksz_regmap_16(dev), REG_SW_MTU__2,
				  REG_SW_MTU_MASK, frame_size);
}

@@ -60,7 +60,7 @@ static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev)
{
	unsigned int val;

	return regmap_read_poll_timeout(dev->regmap[0], REG_SW_VLAN_CTRL,
	return regmap_read_poll_timeout(ksz_regmap_8(dev), REG_SW_VLAN_CTRL,
					val, !(val & VLAN_START), 10, 1000);
}

@@ -147,7 +147,7 @@ static int ksz9477_wait_alu_ready(struct ksz_device *dev)
{
	unsigned int val;

	return regmap_read_poll_timeout(dev->regmap[2], REG_SW_ALU_CTRL__4,
	return regmap_read_poll_timeout(ksz_regmap_32(dev), REG_SW_ALU_CTRL__4,
					val, !(val & ALU_START), 10, 1000);
}

@@ -155,7 +155,7 @@ static int ksz9477_wait_alu_sta_ready(struct ksz_device *dev)
{
	unsigned int val;

	return regmap_read_poll_timeout(dev->regmap[2],
	return regmap_read_poll_timeout(ksz_regmap_32(dev),
					REG_SW_ALU_STAT_CTRL__4,
					val, !(val & ALU_STAT_START),
					10, 1000);
@@ -170,7 +170,7 @@ int ksz9477_reset_switch(struct ksz_device *dev)
	ksz_cfg(dev, REG_SW_OPERATION, SW_RESET, true);

	/* turn off SPI DO Edge select */
	regmap_update_bits(dev->regmap[0], REG_SW_GLOBAL_SERIAL_CTRL_0,
	regmap_update_bits(ksz_regmap_8(dev), REG_SW_GLOBAL_SERIAL_CTRL_0,
			   SPI_AUTO_EDGE_DETECTION, 0);

	/* default configuration */
@@ -213,7 +213,7 @@ void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt)
	data |= (addr << MIB_COUNTER_INDEX_S);
	ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);

	ret = regmap_read_poll_timeout(dev->regmap[2],
	ret = regmap_read_poll_timeout(ksz_regmap_32(dev),
			PORT_CTRL_ADDR(port, REG_PORT_MIB_CTRL_STAT__4),
			val, !(val & MIB_COUNTER_READ), 10, 1000);
	/* failed to read MIB. get out of loop */
@@ -346,7 +346,7 @@ void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
	const u16 *regs = dev->info->regs;
	u8 data;

	regmap_update_bits(dev->regmap[0], REG_SW_LUE_CTRL_2,
	regmap_update_bits(ksz_regmap_8(dev), REG_SW_LUE_CTRL_2,
			   SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S,
			   SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S);

@@ -1165,7 +1165,7 @@ int ksz9477_setup(struct dsa_switch *ds)
	ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_JUMBO_PACKET, true);

	/* Now we can configure default MTU value */
	ret = regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, REG_SW_MTU_MASK,
	ret = regmap_update_bits(ksz_regmap_16(dev), REG_SW_MTU__2, REG_SW_MTU_MASK,
				 VLAN_ETH_FRAME_LEN + ETH_FCS_LEN);
	if (ret)
		return ret;
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c)
	if (!dev)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) {
	for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
		rc = ksz9477_regmap_config[i];
		rc.lock_arg = &dev->regmap_mutex;
		dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc);
+44 −3
Original line number Diff line number Diff line
@@ -1075,6 +1075,45 @@ static const struct regmap_access_table ksz9896_register_set = {
	.n_yes_ranges = ARRAY_SIZE(ksz9896_valid_regs),
};

static const struct regmap_range ksz8873_valid_regs[] = {
	regmap_reg_range(0x00, 0x01),
	/* global control register */
	regmap_reg_range(0x02, 0x0f),

	/* port registers */
	regmap_reg_range(0x10, 0x1d),
	regmap_reg_range(0x1e, 0x1f),
	regmap_reg_range(0x20, 0x2d),
	regmap_reg_range(0x2e, 0x2f),
	regmap_reg_range(0x30, 0x39),
	regmap_reg_range(0x3f, 0x3f),

	/* advanced control registers */
	regmap_reg_range(0x60, 0x6f),
	regmap_reg_range(0x70, 0x75),
	regmap_reg_range(0x76, 0x78),
	regmap_reg_range(0x79, 0x7a),
	regmap_reg_range(0x7b, 0x83),
	regmap_reg_range(0x8e, 0x99),
	regmap_reg_range(0x9a, 0xa5),
	regmap_reg_range(0xa6, 0xa6),
	regmap_reg_range(0xa7, 0xaa),
	regmap_reg_range(0xab, 0xae),
	regmap_reg_range(0xaf, 0xba),
	regmap_reg_range(0xbb, 0xbc),
	regmap_reg_range(0xbd, 0xbd),
	regmap_reg_range(0xc0, 0xc0),
	regmap_reg_range(0xc2, 0xc2),
	regmap_reg_range(0xc3, 0xc3),
	regmap_reg_range(0xc4, 0xc4),
	regmap_reg_range(0xc6, 0xc6),
};

static const struct regmap_access_table ksz8873_register_set = {
	.yes_ranges = ksz8873_valid_regs,
	.n_yes_ranges = ARRAY_SIZE(ksz8873_valid_regs),
};

const struct ksz_chip_data ksz_switch_chips[] = {
	[KSZ8563] = {
		.chip_id = KSZ8563_CHIP_ID,
@@ -1214,6 +1253,8 @@ const struct ksz_chip_data ksz_switch_chips[] = {
		.supports_mii = {false, false, true},
		.supports_rmii = {false, false, true},
		.internal_phy = {true, true, false},
		.wr_table = &ksz8873_register_set,
		.rd_table = &ksz8873_register_set,
	},

	[KSZ9477] = {
@@ -2095,7 +2136,7 @@ static int ksz_setup(struct dsa_switch *ds)
	}

	/* set broadcast storm protection 10% rate */
	regmap_update_bits(dev->regmap[1], regs[S_BROADCAST_CTRL],
	regmap_update_bits(ksz_regmap_16(dev), regs[S_BROADCAST_CTRL],
			   BROADCAST_STORM_RATE,
			   (BROADCAST_STORM_VALUE *
			   BROADCAST_STORM_PROT_RATE) / 100);
@@ -2106,7 +2147,7 @@ static int ksz_setup(struct dsa_switch *ds)

	ds->num_tx_queues = dev->info->num_tx_queues;

	regmap_update_bits(dev->regmap[0], regs[S_MULTICAST_CTRL],
	regmap_update_bits(ksz_regmap_8(dev), regs[S_MULTICAST_CTRL],
			   MULTICAST_STORM_DISABLE, MULTICAST_STORM_DISABLE);

	ksz_init_mib_timer(dev);
@@ -2156,7 +2197,7 @@ static int ksz_setup(struct dsa_switch *ds)
	}

	/* start switch */
	regmap_update_bits(dev->regmap[0], regs[S_START_CTRL],
	regmap_update_bits(ksz_regmap_8(dev), regs[S_START_CTRL],
			   SW_START, SW_START);

	return 0;
Loading