MII是Medium Independent Interface的縮寫,是一種標準接口,該接口主要應用於MAC層和PHY層之間的以太網數據傳輸。
MII接口的類型有很多,常用的有MII、RMII、SMII、SSMII、SSSMII、GMII、RGMII、SGMII、TBI、RTBI、XGMII、XAUI、XLAUI等。MDIO是Management Data Input/Output的縮寫,是一種串行通信總線,類似於I2C,該總線由IEEE通過以太網標準IEEE 802.3的若干條款加以定義,一般用於微控制器或是mac控制器與phy相連接。MDIO必須於MDC一起使用,MDC是作爲MDIO的時鐘信號。
MDIO是屬於MII接口的一部分。
解析phy驅動:
驅動流程:
phy_driver_regitster -->driver_register-->bus_add_driver-->driver_attach-->bus_for_each_dev-->__driver_attach(通過bus_for_each_dev參數回調)-->driver_probe_device(drv, dev)-->really_probe(dev, drv)-->drv->probe(dev).int phy_driver_register(struct phy_driver *new_driver)
{
int retval;
new_driver->driver.name = new_driver->name;
new_driver->driver.bus = &mdio_bus_type;
new_driver->driver.probe = phy_probe;
new_driver->driver.remove = phy_remove;
retval = driver_register(&new_driver->driver);
if (retval) {
pr_err("%s: Error %d in registering driver\n",
new_driver->name, retval);
return retval;
}
pr_debug("%s: Registered new driver\n", new_driver->name);
return 0;
}
可見phy的driver是掛載在mdio_bus上的。
driver_register(struct device_driver *drv):檢測mdio_bus_type上是否已經註冊該設備了。
bus_add_driver(struct device_driver *drv):Add a driver to the bus.
driver_attach(struct device_driver *drv):讓總線上的設備與驅動匹配.
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach): 回調函數__driver_attach.
__driver_attach(struct device *dev, void *data):
if (!driver_match_device(drv, dev))
return 0;
driver_match_device(drv, dev)就是匹配driver 與 device。
static inline int driver_match_device(struct device_driver *drv,
struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
drv->bus->match 匹配函數 源碼:
static int mdio_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);
if (of_driver_match_device(dev, drv))
return 1;
if (phydrv->match_phy_device)
return phydrv->match_phy_device(phydev);
return ((phydrv->phy_id & phydrv->phy_id_mask) ==
(phydev->phy_id & phydrv->phy_id_mask));
}
可以確定匹配是通過driver和device的phy_id & phy_id_mask, 而不是通過設備於驅動名字匹配。
driver_probe_device(drv, dev):從這裏追蹤代碼可以找到really_probe(dev, drv),繼續追蹤drv->probe(dev),到此結束