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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/string.hlinux/errno.hlinux/unistd.hlinux/interrupt.hlinux/delay.hlinux/netdevice.hlinux/netlink.hlinux/etherdevice.hlinux/skbuff.hlinux/mm.hlinux/module.hlinux/mii.hlinux/ethtool.hlinux/ethtool_netlink.hlinux/phy.hlinux/phy_led_triggers.hlinux/sfp.hlinux/workqueue.hlinux/mdio.hlinux/io.hlinux/uaccess.hlinux/atomic.hlinux/suspend.hnet/netlink.hnet/genetlink.hnet/sock.hphylib-internal.hphy-caps.h
Detected Declarations
enum phy_state_workfunction phy_process_state_changefunction phy_link_upfunction phy_link_downfunction phy_print_statusfunction matchingfunction phy_config_interruptfunction phy_restart_anegfunction phy_aneg_donefunction phy_supported_speedsfunction phy_check_validfunction phy_sanitize_settingsfunction phy_ethtool_ksettings_getfunction phy_mii_ioctlfunction phy_do_ioctlfunction phy_do_ioctl_runningfunction __phy_hwtstamp_getfunction __phy_hwtstamp_setfunction phy_queue_state_machinefunction phy_trigger_machinefunction phy_abort_cable_testfunction phy_ethtool_get_stringsfunction phy_ethtool_get_sset_countfunction phy_ethtool_get_statsfunction __phy_ethtool_get_phy_statsfunction __phy_ethtool_get_link_ext_statsfunction phy_ethtool_get_plca_cfgfunction plca_check_validfunction phy_ethtool_set_plca_cfgfunction phy_ethtool_get_plca_statusfunction phy_start_cable_testfunction phy_start_cable_test_tdrfunction phy_config_anegfunction phy_check_link_statusfunction PHYfunction phy_config_inbandfunction _phy_start_anegfunction phy_start_anegfunction phy_poll_aneg_donefunction phy_ethtool_ksettings_setfunction phy_speed_downfunction phy_speed_upfunction phy_start_machinefunction UPfunction phy_process_errorfunction phy_error_precisefunction phy_errorfunction phy_write_barrier
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
- Immediate include surface: `linux/kernel.h`, `linux/string.h`, `linux/errno.h`, `linux/unistd.h`, `linux/interrupt.h`, `linux/delay.h`, `linux/netdevice.h`, `linux/netlink.h`.
- Detected declarations: `enum phy_state_work`, `function phy_process_state_change`, `function phy_link_up`, `function phy_link_down`, `function phy_print_status`, `function matching`, `function phy_config_interrupt`, `function phy_restart_aneg`, `function phy_aneg_done`, `function phy_supported_speeds`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.