drivers/net/phy/dp83867.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/dp83867.c
Extension
.c
Size
33713 bytes
Lines
1231
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 dp83867_private {
	u32 rx_id_delay;
	u32 tx_id_delay;
	u32 tx_fifo_depth;
	u32 rx_fifo_depth;
	int io_impedance;
	int port_mirroring;
	bool rxctrl_strap_quirk;
	bool set_clk_output;
	u32 clk_output_sel;
	bool sgmii_ref_clk_en;
};

static int dp83867_ack_interrupt(struct phy_device *phydev)
{
	int err = phy_read(phydev, MII_DP83867_ISR);

	if (err < 0)
		return err;

	return 0;
}

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

	val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
	val_micr = phy_read(phydev, MII_DP83867_MICR);

	if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
			    WAKE_BCAST)) {
		val_rxcfg |= DP83867_WOL_ENH_MAC;
		val_micr |= MII_DP83867_MICR_WOL_INT_EN;

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

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

			phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
				      (mac[1] << 8 | mac[0]));
			phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
				      (mac[3] << 8 | mac[2]));
			phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
				      (mac[5] << 8 | mac[4]));

			val_rxcfg |= DP83867_WOL_MAGIC_EN;
		} else {
			val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
		}

		if (wol->wolopts & WAKE_MAGICSECURE) {
			phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
				      (wol->sopass[1] << 8) | wol->sopass[0]);
			phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP2,
				      (wol->sopass[3] << 8) | wol->sopass[2]);
			phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP3,
				      (wol->sopass[5] << 8) | wol->sopass[4]);

			val_rxcfg |= DP83867_WOL_SEC_EN;
		} else {
			val_rxcfg &= ~DP83867_WOL_SEC_EN;
		}

		if (wol->wolopts & WAKE_UCAST)
			val_rxcfg |= DP83867_WOL_UCAST_EN;
		else
			val_rxcfg &= ~DP83867_WOL_UCAST_EN;

		if (wol->wolopts & WAKE_BCAST)
			val_rxcfg |= DP83867_WOL_BCAST_EN;
		else
			val_rxcfg &= ~DP83867_WOL_BCAST_EN;
	} else {
		val_rxcfg &= ~DP83867_WOL_ENH_MAC;
		val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
	}

	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
	phy_write(phydev, MII_DP83867_MICR, val_micr);

	return 0;
}

static void dp83867_get_wol(struct phy_device *phydev,

Annotation

Implementation Notes