drivers/net/ethernet/amd/xgbe/xgbe-mdio.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
Extension
.c
Size
40773 bytes
Lines
1625
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 (time_after(jiffies, an_timeout)) {
			/* Auto-negotiation timed out, reset state */
			pdata->kr_state = XGBE_RX_BPA;
			pdata->kx_state = XGBE_RX_BPA;

			pdata->an_start = jiffies;

			netif_dbg(pdata, link, pdata->netdev,
				  "CL73 AN timed out, resetting state\n");
		}
	}

	state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state
				       : &pdata->kx_state;

	switch (*state) {
	case XGBE_RX_BPA:
		ret = xgbe_an73_rx_bpa(pdata, state);
		break;

	case XGBE_RX_XNP:
		ret = xgbe_an73_rx_xnp(pdata, state);
		break;

	default:
		ret = XGBE_AN_ERROR;
	}

	return ret;
}

static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
{
	struct ethtool_link_ksettings *lks = &pdata->phy.lks;

	/* Be sure we aren't looping trying to negotiate */
	if (xgbe_in_kr_mode(pdata)) {
		pdata->kr_state = XGBE_RX_ERROR;

		if (!XGBE_ADV(lks, 1000baseKX_Full) &&
		    !XGBE_ADV(lks, 2500baseX_Full))
			return XGBE_AN_NO_LINK;

		if (pdata->kx_state != XGBE_RX_BPA)
			return XGBE_AN_NO_LINK;
	} else {
		pdata->kx_state = XGBE_RX_ERROR;

		if (!XGBE_ADV(lks, 10000baseKR_Full))
			return XGBE_AN_NO_LINK;

		if (pdata->kr_state != XGBE_RX_BPA)
			return XGBE_AN_NO_LINK;
	}

	xgbe_an_disable(pdata);

	xgbe_switch_mode(pdata);

	pdata->an_result = XGBE_AN_READY;

	xgbe_an_restart(pdata);

	return XGBE_AN_INCOMPAT_LINK;
}

static void xgbe_an37_isr(struct xgbe_prv_data *pdata)
{
	unsigned int reg;

	/* Disable AN interrupts */
	xgbe_an37_disable_interrupts(pdata);

	/* Save the interrupt(s) that fired */
	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
	pdata->an_int = reg & XGBE_AN_CL37_INT_MASK;
	pdata->an_status = reg & ~XGBE_AN_CL37_INT_MASK;

	if (pdata->an_int) {
		/* Clear the interrupt(s) that fired and process them */
		reg &= ~XGBE_AN_CL37_INT_MASK;
		XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);

		queue_work(pdata->an_workqueue, &pdata->an_irq_work);
	} else {
		/* Enable AN interrupts */
		xgbe_an37_enable_interrupts(pdata);

		/* Reissue interrupt if status is not clear */
		if (pdata->vdata->irq_reissue_support)

Annotation

Implementation Notes