写在前面
本小节主要分析一下rk平台px30 GAMC网卡驱动如何检测的网线拔插。linux内核版本 :4.4
拔插网线的调用堆栈
初始化队列
get_phy_device
phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
phy_state_machine //循环检测网卡状态 - 状态机
rkl8367_read_status
genphy_update_link
mdiobus_read
bus->read
//bus->read 也就是这个
static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
{
unsigned int data = 0;
int ret = 0;
ret = rtl8367c_getAsicPHYReg((unsigned int)phyaddr, (unsigned int)phyreg, &data);
if(ret !=0) {
printk("ERROR: %s phyaddr: %x phyreg: %x return %x \n", __func__, phyaddr, phyreg, ret);
ret = -1;
} else {
//printk("%s - phyaddr: %x, phyreg: %x, data: %x \n", __func__, phyaddr, phyreg, data);
}
return (int)data;
}
//重点看一下这个匹配函数函数,使用这个函数,匹配phy device的id和phy driver的id
/**
* mdio_bus_match - determine if given PHY driver supports the given PHY device
* @dev: target PHY device
* @drv: given PHY driver
*
* Description: Given a PHY device, and a PHY driver, return 1 if
* the driver supports the device. Otherwise, return 0.
*/
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);
const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
int i;
if (of_driver_match_device(dev, drv))
return 1;
if (phydrv->match_phy_device)
return phydrv->match_phy_device(phydev);
if (phydev->is_c45) {
for (i = 1; i < num_ids; i++) {
if (!(phydev->c45_ids.devices_in_package & (1 << i)))
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);
}
}
也就是phy driver里的这个结构体
static struct phy_driver genphy_driver[] =
{
.phy_id = 0x001cc942,//这里一定要跟真实探测到的设备id对应,如果发现没有掉用到正确的bus->read ,需要检查一下这个id
.phy_id_mask = 0x001fffff,// 关键位
.name = "rtl8367 PHY",
.soft_reset = rkl8367_soft_reset,
.config_init = rkl8367_config_init,
.features = PHY_GBIT_FEATURES | SUPPORTED_MII |
SUPPORTED_AUI | SUPPORTED_FIBRE |
SUPPORTED_BNC,
.config_aneg = rkl8367_config_aneg,
.read_status = rkl8367_read_status,
.suspend = rkl8367_suspend,
.resume = rkl8367_resume,
.driver = {.owner = THIS_MODULE, },
} ;