drivers/net/ethernet/sfc/falcon/tenxpress.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/falcon/tenxpress.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sfc/falcon/tenxpress.c
Extension
.c
Size
13410 bytes
Lines
492
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

struct tenxpress_phy_data {
	enum ef4_loopback_mode loopback_mode;
	enum ef4_phy_mode phy_mode;
	int bad_lp_tries;
};

static int tenxpress_init(struct ef4_nic *efx)
{
	/* Enable 312.5 MHz clock */
	ef4_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
		       1 << CLK312_EN_LBN);

	/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
	ef4_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
			  1 << PMA_PMA_LED_ACTIVITY_LBN, true);
	ef4_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
		       SFX7101_PMA_PMD_LED_DEFAULT);

	return 0;
}

static int tenxpress_phy_probe(struct ef4_nic *efx)
{
	struct tenxpress_phy_data *phy_data;

	/* Allocate phy private storage */
	phy_data = kzalloc_obj(*phy_data);
	if (!phy_data)
		return -ENOMEM;
	efx->phy_data = phy_data;
	phy_data->phy_mode = efx->phy_mode;

	efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
	efx->mdio.mode_support = MDIO_SUPPORTS_C45;

	efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;

	efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
				 ADVERTISED_10000baseT_Full);

	return 0;
}

static int tenxpress_phy_init(struct ef4_nic *efx)
{
	int rc;

	falcon_board(efx)->type->init_phy(efx);

	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
		rc = ef4_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
		if (rc < 0)
			return rc;

		rc = ef4_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS);
		if (rc < 0)
			return rc;
	}

	rc = tenxpress_init(efx);
	if (rc < 0)
		return rc;

	/* Reinitialise flow control settings */
	ef4_link_set_wanted_fc(efx, efx->wanted_fc);
	ef4_mdio_an_reconfigure(efx);

	schedule_timeout_uninterruptible(HZ / 5); /* 200ms */

	/* Let XGXS and SerDes out of reset */
	falcon_reset_xaui(efx);

	return 0;
}

/* Perform a "special software reset" on the PHY. The caller is
 * responsible for saving and restoring the PHY hardware registers
 * properly, and masking/unmasking LASI */
static int tenxpress_special_reset(struct ef4_nic *efx)
{
	int rc, reg;

	/* The XGMAC clock is driven from the SFX7101 312MHz clock, so
	 * a special software reset can glitch the XGMAC sufficiently for stats
	 * requests to fail. */
	falcon_stop_nic_stats(efx);

	/* Initiate reset */
	reg = ef4_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
	reg |= (1 << PMA_PMD_EXT_SSR_LBN);

Annotation

Implementation Notes