网卡驱动或者独立的mdio驱动,首先会注册到系统总线,然后开始扫描总线上的PHY芯片,
mdiobus_register
mdiobus_scan
get_phy_device
get_phy_id
phy_device_create
phy_device_register
phy_scan_fixups
在phy_device_create
中,注意phy_device成员变量的初始值,
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
bool is_c45,
struct phy_c45_device_ids *c45_ids)
{
struct phy_device *dev;
...
dev->speed = 0;
dev->duplex = -1;
dev->pause = 0;
dev->asym_pause = 0;
dev->link = 1;
dev->interface = PHY_INTERFACE_MODE_GMII;
dev->autoneg = AUTONEG_ENABLE;
...
}
注意phy_scan_fixups
可以对phy进行一些预设,可以在MAC驱动里注册fixup函数,在这儿就会进行调用,linux提供了两种注册方法,phy_register_fixup_for_uid
,例如,
if (IS_BUILTIN(CONFIG_PHYLIB))
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
ar8031_phy_fixup);
第二种,phy_register_fixup_for_id
,例如,
if (of_machine_is_compatible("atmel,sama5d4ek") &&
IS_ENABLED(CONFIG_PHYLIB)) {
phy_register_fixup_for_id("fc028000.etherne:00",
ksz8081_phy_fixup);
}
注意phy_scan_fixups
在config_init
之前被调用,
phy_connect_direct
phy_attach_direct
phy_init_hw
phydev->drv->soft_reset
phy_scan_fixups
phydev->drv->config_init
phy_resume
phy_prepare_link
phy_start_machine
phy_start_interrupts