drivers/net/phy/dp83822.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/dp83822.c
Extension
.c
Size
35160 bytes
Lines
1262
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 dp83822_private {
	bool fx_signal_det_low;
	int fx_enabled;
	u16 fx_sd_enable;
	u8 cfg_dac_minus;
	u8 cfg_dac_plus;
	struct ethtool_wolinfo wol;
	bool set_gpio2_clk_out;
	u32 gpio2_clk_out;
	bool led_pin_enable[DP83822_MAX_LED_PINS];
	int tx_amplitude_100base_tx_index;
	int mac_termination_index;
};

static int dp83822_config_wol(struct phy_device *phydev,
			      struct ethtool_wolinfo *wol)
{
	struct net_device *ndev = phydev->attached_dev;
	u16 value;
	const u8 *mac;

	if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
		mac = (const u8 *)ndev->dev_addr;

		if (!is_valid_ether_addr(mac))
			return -EINVAL;

		/* MAC addresses start with byte 5, but stored in mac[0].
		 * 822 PHYs store bytes 4|5, 2|3, 0|1
		 */
		phy_write_mmd(phydev, MDIO_MMD_VEND2, MII_DP83822_WOL_DA1,
			      (mac[1] << 8) | mac[0]);
		phy_write_mmd(phydev, MDIO_MMD_VEND2, MII_DP83822_WOL_DA2,
			      (mac[3] << 8) | mac[2]);
		phy_write_mmd(phydev, MDIO_MMD_VEND2, MII_DP83822_WOL_DA3,
			      (mac[5] << 8) | mac[4]);

		value = phy_read_mmd(phydev, MDIO_MMD_VEND2,
				     MII_DP83822_WOL_CFG);
		if (wol->wolopts & WAKE_MAGIC)
			value |= DP83822_WOL_MAGIC_EN;
		else
			value &= ~DP83822_WOL_MAGIC_EN;

		if (wol->wolopts & WAKE_MAGICSECURE) {
			phy_write_mmd(phydev, MDIO_MMD_VEND2,
				      MII_DP83822_RXSOP1,
				      (wol->sopass[1] << 8) | wol->sopass[0]);
			phy_write_mmd(phydev, MDIO_MMD_VEND2,
				      MII_DP83822_RXSOP2,
				      (wol->sopass[3] << 8) | wol->sopass[2]);
			phy_write_mmd(phydev, MDIO_MMD_VEND2,
				      MII_DP83822_RXSOP3,
				      (wol->sopass[5] << 8) | wol->sopass[4]);
			value |= DP83822_WOL_SECURE_ON;
		} else {
			value &= ~DP83822_WOL_SECURE_ON;
		}

		/* Clear any pending WoL interrupt */
		phy_read(phydev, MII_DP83822_MISR2);

		value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
			 DP83822_WOL_CLR_INDICATION;

		return phy_write_mmd(phydev, MDIO_MMD_VEND2,
				     MII_DP83822_WOL_CFG, value);
	} else {
		return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
					  MII_DP83822_WOL_CFG,
					  DP83822_WOL_EN |
					  DP83822_WOL_MAGIC_EN |
					  DP83822_WOL_SECURE_ON);
	}
}

static int dp83822_set_wol(struct phy_device *phydev,
			   struct ethtool_wolinfo *wol)
{
	struct dp83822_private *dp83822 = phydev->priv;
	int ret;

	ret = dp83822_config_wol(phydev, wol);
	if (!ret)
		memcpy(&dp83822->wol, wol, sizeof(*wol));
	return ret;
}

static void dp83822_get_wol(struct phy_device *phydev,
			    struct ethtool_wolinfo *wol)

Annotation

Implementation Notes