Linux MDIO PHY驱动分析

mdio

网卡驱动或者独立的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

注意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

你可能感兴趣的:(linux内核与驱动开发)