1. 简介
MDIO接口中有特定的术语定义总线上的各种设备,驱动MDIO总线的设备被定义为站管理实体(STA),而被MDC管理的目标设备称为可被MDIO管理的设备(MMD)。
STA初始化MDIO所有的通信,同时负责驱动时钟MDC。
2. 22号条款
22号条款的MDIO通信的帧格式定义如下:
3. 45号条款
扩充了帧格式,能够访问更多的设备和寄存器,45号MDIO通信帧格式如下:
地址空间从5位增加到16位,这使得STA访问65536个不同的寄存器。
45号协议在数据帧的组成部分进行了一些变化,定义了新的ST代码(00),用于标识第45号条款的数据帧。
4. mdio总线的match方法
mdio总线的match方法为mdio_bus_match,其主要实现如下三方面的匹配检测功能:
1.先进行设备树驱动模型的支持(若系统支持设备树,则先调用该接口进行匹配检测,主要是将phy_driver与phy_device设备树节点的compatible变量进行匹配检测),若匹配则返回匹配成功;
2.若1没有匹配成功,则确认phy_driver是否提供了match_phy_device方法,若提供匹配检测方法,则再次进行匹配检测,若匹配成功,则返回成功;
3.若以上均没有匹配成功,则判断phy_device的phyid与phy_driver支持的phyid进行匹配检测,若匹配成功则返回成功。
static int mdio_bus_match(struct device *dev, struct device_driver *drv)
{
struct mdio_device *mdio = to_mdio_device(dev);
if (of_driver_match_device(dev, drv)) //compatible匹配
return 1;
if (mdio->bus_match)
return mdio->bus_match(dev, drv);
return 0;
}
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
bool is_c45,
struct phy_c45_device_ids *c45_ids)
{
mdiodev->bus_match = phy_bus_match;//真正实现PHY设备和驱动匹配的函数
}
static int phy_bus_match(struct device *dev, struct device_driver *drv)
{
struct phy_device *phydev = to_phy_device(dev);
struct phy_driver *phydrv = to_phy_driver(drv);
const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
int i;
if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
return 0;
if (phydrv->match_phy_device)
return phydrv->match_phy_device(phydev);//调用phy_driver提供的match_phy_device方法
if (phydev->is_c45) {
for (i = 1; i < num_ids; i++) {
if (phydev->c45_ids.device_ids[i] == 0xffffffff)
continue;
if ((phydrv->phy_id & phydrv->phy_id_mask) ==
(phydev->c45_ids.device_ids[i] &
phydrv->phy_id_mask))
return 1;
}
return 0;
} else {
return (phydrv->phy_id & phydrv->phy_id_mask) ==
(phydev->phy_id & phydrv->phy_id_mask); //对比phydev和phydrv里的phy_id是否相同
}
}