drivers/net/phy/aquantia/aquantia_main.c

Source file repositories/reference/linux-study-clean/drivers/net/phy/aquantia/aquantia_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/aquantia/aquantia_main.c
Extension
.c
Size
46686 bytes
Lines
1594
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

switch (serdes_mode) {
		case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:
			if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)
				interface = PHY_INTERFACE_MODE_USXGMII;
			else
				interface = PHY_INTERFACE_MODE_10GBASER;
			break;

		case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:
			interface = PHY_INTERFACE_MODE_5GBASER;
			break;

		case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:
			interface = PHY_INTERFACE_MODE_2500BASEX;
			break;

		case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:
			interface = PHY_INTERFACE_MODE_SGMII;
			break;

		default:
			phydev_warn(phydev, "unrecognised serdes mode %u\n",
				    serdes_mode);
			interface = PHY_INTERFACE_MODE_NA;
			break;
		}

		syscfg->interface = aqr_translate_interface(phydev, interface);

		switch (rate_adapt) {
		case VEND1_GLOBAL_CFG_RATE_ADAPT_NONE:
			syscfg->rate_adapt = AQR_RATE_ADAPT_NONE;
			break;
		case VEND1_GLOBAL_CFG_RATE_ADAPT_USX:
			syscfg->rate_adapt = AQR_RATE_ADAPT_USX;
			break;
		case VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE:
			syscfg->rate_adapt = AQR_RATE_ADAPT_PAUSE;
			break;
		default:
			phydev_warn(phydev, "unrecognized rate adapt mode %u\n",
				    rate_adapt);
			break;
		}

		phydev_dbg(phydev,
			   "Media speed %d uses host interface %s with %s\n",
			   syscfg->speed, phy_modes(syscfg->interface),
			   syscfg->rate_adapt == AQR_RATE_ADAPT_NONE ? "no rate adaptation" :
			   syscfg->rate_adapt == AQR_RATE_ADAPT_PAUSE ? "rate adaptation through flow control" :
			   syscfg->rate_adapt == AQR_RATE_ADAPT_USX ? "rate adaptation through symbol replication" :
			   "unrecognized rate adaptation type");
	}

	return 0;
}

static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
{
	unsigned long *possible = phydev->possible_interfaces;
	struct aqr107_priv *priv = phydev->priv;
	phy_interface_t interface;
	int i, val, ret;

	/* It's been observed on some models that - when coming out of suspend
	 * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
	 * continue on returning zeroes for some time. Let's poll the 100M
	 * register until it returns a real value as both 113c and 115c support
	 * this mode.
	 */
	if (priv->wait_on_global_cfg) {
		ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
						VEND1_GLOBAL_CFG_100M, val,
						val != 0, 1000, 100000, false);
		if (ret)
			return ret;
	}

	ret = aqr_gen2_read_global_syscfg(phydev);
	if (ret)
		return ret;

	for (i = 0; i < AQR_NUM_GLOBAL_CFG; i++) {
		interface = priv->global_cfg[i].interface;
		if (interface != PHY_INTERFACE_MODE_NA)
			__set_bit(interface, possible);
	}

	return 0;
}

Annotation

Implementation Notes