drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
Extension
.c
Size
7174 bytes
Lines
255
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 (state->link && neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
			state->duplex = rgsmii & GMAC_RGSMII_LNKMOD ?
					DUPLEX_FULL : DUPLEX_HALF;
			switch (FIELD_GET(GMAC_RGSMII_SPEED_MASK, rgsmii)) {
			case GMAC_RGSMII_SPEED_2_5:
				state->speed = SPEED_10;
				break;

			case GMAC_RGSMII_SPEED_25:
				state->speed = SPEED_100;
				break;

			case GMAC_RGSMII_SPEED_125:
				state->speed = SPEED_1000;
				break;

			default:
				state->link = false;
				break;
			}
		}
	}
}

static int dwmac_integrated_pcs_config_aneg(struct stmmac_pcs *spcs,
					    phy_interface_t interface,
					    const unsigned long *advertising)
{
	bool changed = false;
	u32 adv;

	adv = phylink_mii_c22_pcs_encode_advertisement(interface, advertising);
	if (readl(spcs->base + GMAC_ANE_ADV) != adv)
		changed = true;
	writel(adv, spcs->base + GMAC_ANE_ADV);

	return changed;
}

static int dwmac_integrated_pcs_config(struct phylink_pcs *pcs,
				       unsigned int neg_mode,
				       phy_interface_t interface,
				       const unsigned long *advertising,
				       bool permit_pause_to_mac)
{
	struct stmmac_pcs *spcs = phylink_pcs_to_stmmac_pcs(pcs);
	bool changed = false, ane = true;

	/* Only configure the advertisement and allow AN in BASE-X mode if
	 * the core supports TBI/RTBI. AN will be filtered out by via phylink
	 * and the .pcs_inband_caps() method above.
	 */
	if (phy_interface_mode_is_8023z(interface) &&
	    spcs->support_tbi_rtbi) {
		ane = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED;

		changed = dwmac_integrated_pcs_config_aneg(spcs, interface,
							   advertising);
	}

	dwmac_ctrl_ane(spcs->base, 0, ane,
		       spcs->priv->hw->reverse_sgmii_enable);

	return changed;
}

static void dwmac_integrated_pcs_an_restart(struct phylink_pcs *pcs)
{
	struct stmmac_pcs *spcs = phylink_pcs_to_stmmac_pcs(pcs);
	void __iomem *an_control = spcs->base + GMAC_AN_CTRL(0);
	u32 ctrl;

	/* We can only do AN restart if using TBI/RTBI mode */
	if (spcs->support_tbi_rtbi) {
		ctrl = readl(an_control) | GMAC_AN_CTRL_RAN;
		writel(ctrl, an_control);
	}
}

static const struct phylink_pcs_ops dwmac_integrated_pcs_ops = {
	.pcs_inband_caps = dwmac_integrated_pcs_inband_caps,
	.pcs_enable = dwmac_integrated_pcs_enable,
	.pcs_disable = dwmac_integrated_pcs_disable,
	.pcs_get_state = dwmac_integrated_pcs_get_state,
	.pcs_config = dwmac_integrated_pcs_config,
	.pcs_an_restart = dwmac_integrated_pcs_an_restart,
};

void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status,
			       struct stmmac_extra_stats *x)

Annotation

Implementation Notes