1.涉及的文件:
macb_main.c phy_device.c dp83867.c
phy_device.c 在内核启动就会运行该驱动,它是匹配PHY和配置phy的重要接口。
2.驱动之间的关系
macb_mii_probe ——> phy_connect_direct ---》 phy_attach_direct
phy_init -----》 phy_driver_register
2.1 初始化phy
phy_init_hw ---》 phydev->drv->config_init(phydev)
2.2 把phy的设备和驱动关联起来
mdio_bus_match
|
get_phy_device --》phy_device_create——》 phy_bus_match --》 phydrv->match_phy_device
2.3phy状态机的关系
phy_device.c phy.c
| |
*phy_device_create ———》 phy_state_machine
2.4设置自协商相关代码(phy_start_aneg(phydev))
phy_ethtool_sset
phy_ethtool_ksettings_set
phy_mii_ioctl
phy.c phy_device.c
| |
phy_state_machine ---> phy_start_aneg_priv ---> err = phydev->drv->config_aneg(phydev); --> genphy_config_aneg --> genphy_setup_forced --->设置PHY固定速率
2.5 自协商完成是通过中断通知
phy.c phy_device.c
| |
phy_start_aneg_priv --》 phy_aneg_done --》 genphy_aneg_done
2.6 phy_device.c创建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;
struct mdio_device *mdiodev;
/* We allocate the device, and initialize the default values */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return ERR_PTR(-ENOMEM);
mdiodev = &dev->mdio;
mdiodev->dev.release = phy_device_release;
mdiodev->dev.parent = &bus->dev;
mdiodev->dev.bus = &mdio_bus_type;
mdiodev->bus = bus;
mdiodev->pm_ops = MDIO_BUS_PHY_PM_OPS;
mdiodev->bus_match = phy_bus_match;
mdiodev->addr = addr;
mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
mdiodev->device_free = phy_mdio_device_free;
mdiodev->device_remove = phy_mdio_device_remove;
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;
dev->is_c45 = is_c45;