drivers/net/dsa/mt7530.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mt7530.c
Extension
.c
Size
99552 bytes
Lines
3514
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (tmp_age_unit <= AGE_UNIT_MAX) {
			unsigned int tmp_error = secs -
				(tmp_age_count + 1) * (tmp_age_unit + 1);

			/* found a closer pair */
			if (error > tmp_error) {
				error = tmp_error;
				age_count = tmp_age_count;
				age_unit = tmp_age_unit;
			}

			/* found the exact match, so break the loop */
			if (!error)
				break;
		}
	}

	mt7530_write(priv, MT7530_AAC, AGE_CNT(age_count) | AGE_UNIT(age_unit));

	return 0;
}

static const char *mt7530_p5_mode_str(unsigned int mode)
{
	switch (mode) {
	case MUX_PHY_P0:
		return "MUX PHY P0";
	case MUX_PHY_P4:
		return "MUX PHY P4";
	default:
		return "GMAC5";
	}
}

static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
{
	struct mt7530_priv *priv = ds->priv;
	u8 tx_delay = 0;
	int val;

	mutex_lock(&priv->reg_mutex);

	val = mt7530_read(priv, MT753X_MTRAP);

	val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE;

	switch (priv->p5_mode) {
	/* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
	case MUX_PHY_P0:
		val |= MT7530_P5_PHY0_SEL;
		fallthrough;

	/* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
	case MUX_PHY_P4:
		/* Setup the MAC by default for the cpu port */
		mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
		break;

	/* GMAC5: P5 -> SoC MAC or external PHY */
	default:
		val |= MT7530_P5_MAC_SEL;
		break;
	}

	/* Setup RGMII settings */
	if (phy_interface_mode_is_rgmii(interface)) {
		val |= MT7530_P5_RGMII_MODE;

		/* P5 RGMII RX Clock Control: delay setting for 1000M */
		mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);

		/* Don't set delay in DSA mode */
		if (!dsa_is_dsa_port(priv->ds, 5) &&
		    (interface == PHY_INTERFACE_MODE_RGMII_TXID ||
		     interface == PHY_INTERFACE_MODE_RGMII_ID))
			tx_delay = 4; /* n * 0.5 ns */

		/* P5 RGMII TX Clock Control: delay x */
		mt7530_write(priv, MT7530_P5RGMIITXCR,
			     CSR_RGMII_TXC_CFG(0x10 + tx_delay));

		/* reduce P5 RGMII Tx driving, 8mA */
		mt7530_write(priv, MT7530_IO_DRV_CR,
			     P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
	}

	mt7530_write(priv, MT753X_MTRAP, val);

	dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val,
		mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface));

Annotation

Implementation Notes