1.5 px30驱动移植-网卡驱动检测网线插拔

写在前面

本小节主要分析一下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, },
} ;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值