drivers/net/phy/phy.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/phy.c
Extension
.c
Size
53584 bytes
Lines
2107
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (mdio_phy_id_is_c45(mii_data->phy_id)) {
			prtad = mdio_phy_id_prtad(mii_data->phy_id);
			devad = mdio_phy_id_devad(mii_data->phy_id);
			ret = mdiobus_c45_read(phydev->mdio.bus, prtad, devad,
					       mii_data->reg_num);

		} else {
			ret = mdiobus_read(phydev->mdio.bus, mii_data->phy_id,
					   mii_data->reg_num);
		}

		if (ret < 0)
			return ret;

		mii_data->val_out = ret;

		return 0;

	case SIOCSMIIREG:
		if (mdio_phy_id_is_c45(mii_data->phy_id)) {
			prtad = mdio_phy_id_prtad(mii_data->phy_id);
			devad = mdio_phy_id_devad(mii_data->phy_id);
		} else {
			prtad = mii_data->phy_id;
			devad = mii_data->reg_num;
		}
		if (prtad == phydev->mdio.addr) {
			switch (devad) {
			case MII_BMCR:
				if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
					if (phydev->autoneg == AUTONEG_ENABLE)
						change_autoneg = true;
					phydev->autoneg = AUTONEG_DISABLE;
					if (val & BMCR_FULLDPLX)
						phydev->duplex = DUPLEX_FULL;
					else
						phydev->duplex = DUPLEX_HALF;
					if (val & BMCR_SPEED1000)
						phydev->speed = SPEED_1000;
					else if (val & BMCR_SPEED100)
						phydev->speed = SPEED_100;
					else phydev->speed = SPEED_10;
				} else {
					if (phydev->autoneg == AUTONEG_DISABLE)
						change_autoneg = true;
					phydev->autoneg = AUTONEG_ENABLE;
				}
				break;
			case MII_ADVERTISE:
				mii_adv_mod_linkmode_adv_t(phydev->advertising,
							   val);
				change_autoneg = true;
				break;
			case MII_CTRL1000:
				mii_ctrl1000_mod_linkmode_adv_t(phydev->advertising,
							        val);
				change_autoneg = true;
				break;
			default:
				/* do nothing */
				break;
			}
		}

		if (mdio_phy_id_is_c45(mii_data->phy_id))
			mdiobus_c45_write(phydev->mdio.bus, prtad, devad,
					  mii_data->reg_num, val);
		else
			mdiobus_write(phydev->mdio.bus, prtad, devad, val);

		if (prtad == phydev->mdio.addr &&
		    devad == MII_BMCR &&
		    val & BMCR_RESET)
			return phy_init_hw(phydev);

		if (change_autoneg)
			return phy_start_aneg(phydev);

		return 0;

	case SIOCSHWTSTAMP:
		if (phydev->mii_ts && phydev->mii_ts->hwtstamp_set) {
			if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
				return -EFAULT;

			hwtstamp_config_to_kernel(&kernel_cfg, &cfg);
			ret = phydev->mii_ts->hwtstamp_set(phydev->mii_ts,
							   &kernel_cfg,
							   &extack);
			if (ret)

Annotation

Implementation Notes