drivers/net/phy/marvell-88x2222.c

Source file repositories/reference/linux-study-clean/drivers/net/phy/marvell-88x2222.c

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/marvell-88x2222.c
Extension
.c
Size
15254 bytes
Lines
605
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 mv2222_data {
	phy_interface_t line_interface;
	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
	bool sfp_link;
};

/* SFI PMA transmit enable */
static int mv2222_tx_enable(struct phy_device *phydev)
{
	return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
				  MDIO_PMD_TXDIS_GLOBAL);
}

/* SFI PMA transmit disable */
static int mv2222_tx_disable(struct phy_device *phydev)
{
	return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
				MDIO_PMD_TXDIS_GLOBAL);
}

static int mv2222_soft_reset(struct phy_device *phydev)
{
	int val, ret;

	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_PORT_RST,
			    MV_PORT_RST_SW);
	if (ret < 0)
		return ret;

	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND2, MV_PORT_RST,
					 val, !(val & MV_PORT_RST_SW),
					 5000, 1000000, true);
}

static int mv2222_disable_aneg(struct phy_device *phydev)
{
	int ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_CTRL,
				     BMCR_ANENABLE | BMCR_ANRESTART);
	if (ret < 0)
		return ret;

	return mv2222_soft_reset(phydev);
}

static int mv2222_enable_aneg(struct phy_device *phydev)
{
	int ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MV_1GBX_CTRL,
				   BMCR_ANENABLE | BMCR_RESET);
	if (ret < 0)
		return ret;

	return mv2222_soft_reset(phydev);
}

static int mv2222_set_sgmii_speed(struct phy_device *phydev)
{
	struct mv2222_data *priv = phydev->priv;

	switch (phydev->speed) {
	default:
	case SPEED_1000:
		if ((linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
				       priv->supported) ||
		     linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
				       priv->supported)))
			return phy_modify_mmd(phydev, MDIO_MMD_PCS,
					      MV_1GBX_CTRL,
					      BMCR_SPEED1000 | BMCR_SPEED100,
					      BMCR_SPEED1000);

		fallthrough;
	case SPEED_100:
		if ((linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
				       priv->supported) ||
		     linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
				       priv->supported)))
			return phy_modify_mmd(phydev, MDIO_MMD_PCS,
					      MV_1GBX_CTRL,
					      BMCR_SPEED1000 | BMCR_SPEED100,
					      BMCR_SPEED100);
		fallthrough;
	case SPEED_10:
		if ((linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
				       priv->supported) ||
		     linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
				       priv->supported)))
			return phy_modify_mmd(phydev, MDIO_MMD_PCS,
					      MV_1GBX_CTRL,
					      BMCR_SPEED1000 | BMCR_SPEED100,
					      BMCR_SPEED10);

Annotation

Implementation Notes