Linux MDIO PHY駆動分析


mdio
NICドライバまたは独立した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_に注意デバイスメンバー変数の初期値、
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は2つの登録方法を提供し、phy_register_fixup_for_uid、例えば、
	if (IS_BUILTIN(CONFIG_PHYLIB))
		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
					   ar8031_phy_fixup);

2つ目は、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
注意phy_scan_fixupsconfig_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