drivers/net/dsa/mxl862xx/mxl862xx-phylink.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
Extension
.c
Size
13665 bytes
Lines
447
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) {
			state->speed = SPEED_10000;
			state->duplex = DUPLEX_FULL;
		}
		break;

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

static void mxl862xx_pcs_an_restart(struct phylink_pcs *pcs)
{
	struct mxl862xx_pcs *mpcs = pcs_to_mxl862xx_pcs(pcs);
	struct mxl862xx_priv *priv = mpcs->priv;
	struct mxl862xx_xpcs_an_restart an = {};
	int if_mode, lane;

	if_mode = mxl862xx_xpcs_if_mode(mpcs->interface);
	if (if_mode < 0)
		return;

	lane = (mpcs->interface == PHY_INTERFACE_MODE_10G_QXGMII) ?
	       MXL862XX_XPCS_USX_QUAD : MXL862XX_XPCS_USX_SINGLE;

	an.mode = cpu_to_le16(FIELD_PREP(MXL862XX_XPCS_ANR_PORT_ID,
					 mpcs->serdes_id) |
			      FIELD_PREP(MXL862XX_XPCS_ANR_INTERFACE, if_mode) |
			      FIELD_PREP(MXL862XX_XPCS_ANR_USX_SUBPORT,
					 mpcs->slot) |
			      FIELD_PREP(MXL862XX_XPCS_ANR_USX_LANE_MODE, lane));

	MXL862XX_API_WRITE(priv, MXL862XX_XPCS_AN_RESTART, an);
}

static void mxl862xx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
				 phy_interface_t interface, int speed,
				 int duplex)
{
	struct mxl862xx_pcs *mpcs = pcs_to_mxl862xx_pcs(pcs);
	struct mxl862xx_xpcs_pcs_link_up lu = {};
	struct mxl862xx_priv *priv = mpcs->priv;
	int if_mode, lane, dup;

	/* With inband-AN enabled (role=MAC), the XPCS auto-resolves
	 * speed/duplex from the partner's AN word and the firmware
	 * short-circuits link_up. Skip the firmware round-trip, same
	 * as pcs-mtk-lynxi.
	 */
	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
		return;

	if_mode = mxl862xx_xpcs_if_mode(interface);
	if (if_mode < 0)
		return;

	lane = (interface == PHY_INTERFACE_MODE_10G_QXGMII) ?
	       MXL862XX_XPCS_USX_QUAD : MXL862XX_XPCS_USX_SINGLE;
	dup = (duplex == DUPLEX_FULL) ? MXL862XX_XPCS_DUPLEX_FULL :
					MXL862XX_XPCS_DUPLEX_HALF;

	lu.mode = cpu_to_le16(FIELD_PREP(MXL862XX_XPCS_LU_PORT_ID,
					 mpcs->serdes_id) |
			      FIELD_PREP(MXL862XX_XPCS_LU_INTERFACE, if_mode) |
			      FIELD_PREP(MXL862XX_XPCS_LU_USX_SUBPORT,
					 mpcs->slot) |
			      FIELD_PREP(MXL862XX_XPCS_LU_USX_LANE_MODE, lane) |
			      FIELD_PREP(MXL862XX_XPCS_LU_DUPLEX, dup));
	lu.speed = cpu_to_le16(speed);

	MXL862XX_API_WRITE(priv, MXL862XX_XPCS_PCS_LINK_UP, lu);
}

static unsigned int mxl862xx_pcs_inband_caps(struct phylink_pcs *pcs,
					     phy_interface_t interface)
{
	switch (interface) {
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
	case PHY_INTERFACE_MODE_1000BASEX:
	case PHY_INTERFACE_MODE_2500BASEX:
		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
	case PHY_INTERFACE_MODE_USXGMII:
	case PHY_INTERFACE_MODE_10G_QXGMII:
	case PHY_INTERFACE_MODE_10GKR:
		return LINK_INBAND_ENABLE;
	case PHY_INTERFACE_MODE_10GBASER:
		return LINK_INBAND_DISABLE;
	default:

Annotation

Implementation Notes