drivers/net/dsa/microchip/lan937x_main.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/microchip/lan937x_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/microchip/lan937x_main.c
Extension
.c
Size
27470 bytes
Lines
1007
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (dev->info->cpu_ports & (1 << dp->index)) {
			dev->cpu_port = dp->index;

			/* enable cpu port */
			lan937x_port_setup(dev, dp->index, true);
		}
	}

	dsa_switch_for_each_user_port(dp, ds) {
		ksz_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED);
	}
}

static int lan937x_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{
	struct ksz_device *dev = ds->priv;
	int ret;

	new_mtu += VLAN_ETH_HLEN + ETH_FCS_LEN;

	if (dsa_is_cpu_port(ds, port))
		new_mtu += LAN937X_TAG_LEN;

	if (new_mtu >= FR_MIN_SIZE)
		ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
				       PORT_JUMBO_PACKET, true);
	else
		ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
				       PORT_JUMBO_PACKET, false);
	if (ret < 0) {
		dev_err(ds->dev, "failed to enable jumbo\n");
		return ret;
	}

	/* Write the frame size in PORT_MAX_FR_SIZE register */
	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;
}

static int lan937x_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
{
	struct ksz_device *dev = ds->priv;
	u8 data, mult, value8;
	bool in_msec = false;
	u32 max_val, value;
	u32 secs = msecs;
	int ret;

#define MAX_TIMER_VAL	((1 << 20) - 1)

	/* The aging timer comprises a 3-bit multiplier and a 20-bit second
	 * value.  Either of them cannot be zero.  The maximum timer is then
	 * 7 * 1048575 = 7340025 seconds.  As this value is too large for
	 * practical use it can be interpreted as microseconds, making the
	 * maximum timer 7340 seconds with finer control.  This allows for
	 * maximum 122 minutes compared to 29 minutes in KSZ9477 switch.
	 */
	if (msecs % 1000)
		in_msec = true;
	else
		secs /= 1000;
	if (!secs)
		secs = 1;

	/* Return error if too large. */
	else if (secs > 7 * MAX_TIMER_VAL)
		return -EINVAL;

	/* Configure how to interpret the number value. */
	ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC,
		       in_msec ? SW_AGE_CNT_IN_MICROSEC : 0);
	if (ret < 0)
		return ret;

	ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8);
	if (ret < 0)
		return ret;

	/* Check whether there is need to update the multiplier. */
	mult = FIELD_GET(SW_AGE_CNT_M, value8);
	max_val = MAX_TIMER_VAL;
	if (mult > 0) {
		/* Try to use the same multiplier already in the register as
		 * the hardware default uses multiplier 4 and 75 seconds for
		 * 300 seconds.

Annotation

Implementation Notes