• 理解系统内核linux phy驱动


    PHY设备驱动是基于device、driver、bus的连接方式,驱动涉及如下几个重要部分: 总线 - sturct mii_bus (mii stand for media independent interface) 设备 - struct phy_device 驱动 - struct phy_driver。PHY驱动函数驱动功能:

    函数名称    功能描述
    soft_reset    执行 phy 的软件复位
    config_init    在 phy 复位后将 phy 配置为一个既定的状态
    probe    创建 phy->priv 并执行类似驱动绑定的过程
    suspend/resume    电源管理挂起与恢复功能
    config_aneq    修改速率双工模式自协商等配置
    aneq_done    驱动自协商的结果
    read_status    获取当前的速率双工与自协商配置状态
    ack_interrupt    清楚挂起的中断
    did_interrupt    检查是否 phy 触发了一个中断信号
    config_intr    开启、关闭中断
    remove    当驱动被移除时调用的接口
    ts_info    请求查询 HW 时间戳状态
    hwtstap    设置 phy 的 HW时间戳配置
    rxtstamp    在 phy 这一层为 skb 请求一个接收时间戳
    txtsamp    在 phy 这一层为 skd 请求一个发送时间戳
    set_wol    使能 Wake-on-Lan
    get_wol    获取 Wake-on-Lan 状态
    read_mmd_indirect    读取 phy MMD 间接寄存器
    write_mmd_indirect    写入 phy MMD 间接寄存器

    个驱动都有独立的操作函数来对 phy 进行操作,也就是说网卡会直接调用类似 phy_ops 中的虚函数来使用 phy 的功能。而对于这种 phy 驱动而言,它与网卡驱动是独立的,将网卡驱动与 phy 驱动关联起来步骤:

    PHY驱动的注册:在phy_init函数中不仅注册了mdio_bus总线,还注册了一个通用的PHY驱动作为缺省的内核PHY驱动,但是如果PHY芯片的内部寄存器和802.3定义的并不一样或者需要特殊的功能配置以实现更强的功能,这就需要专有的驱动。

    *phy_start_aneg_priv-启动此phy设备的自动协商
    *@phydev:phy_device结构
    *@sync:表示是否等待工作队列取消
    描述:对设置进行Sanitize(如果我们没有自动协商它们),然后调用驱动程序的config_aeg函数。如果PHYCONTROL层正在运行,我们会更改状态以反映自动协商或强制的开始

    1. static int phy_start_aneg_priv(struct phy_device *phydev, bool sync)
    2. {
    3. bool trigger = 0;
    4. int err;
    5. if (!phydev->drv)
    6. return -EIO;
    7. mutex_lock(&phydev->lock);
    8. printk("111111111111\n");
    9. if (AUTONEG_DISABLE == phydev->autoneg)
    10. phy_sanitize_settings(phydev);
    11. printk("~~phydev->autoneg~~~~~~~~~~\n",phydev->autoneg);
    12. /* Invalidate LP advertising flags */
    13. phydev->lp_advertising = 0;
    14. printk("222222222\n");
    15. err = phydev->drv->config_aneg(phydev);
    16. printk("err=%d\n",err );
    17. if (err < 0)
    18. goto out_unlock;
    19. printk("333333333\n");
    20. if (phydev->state != PHY_HALTED) {
    21. if (AUTONEG_ENABLE == phydev->autoneg) {
    22. phydev->state = PHY_AN;
    23. phydev->link_timeout = PHY_AN_TIMEOUT;
    24. } else {
    25. phydev->state = PHY_FORCING;
    26. phydev->link_timeout = PHY_FORCE_TIMEOUT;
    27. }
    28. }
    29. /* Re-schedule a PHY state machine to check PHY status because
    30. * negotiation may already be done and aneg interrupt may not be
    31. * generated.
    32. */
    33. if (phy_interrupt_is_valid(phydev) && (phydev->state == PHY_AN)) {
    34. err = phy_aneg_done(phydev);
    35. if (err > 0) {
    36. trigger = true;
    37. err = 0;
    38. }
    39. }
    40. out_unlock:
    41. mutex_unlock(&phydev->lock);
    42. if (trigger)
    43. phy_trigger_machine(phydev, sync);
    44. return err;
    45. }

  • 相关阅读:
    canvas 中如何实现物体的框选(六)
    5分钟了解数据结构
    PHP 选课管理系统mysql数据库web结构apache计算机软件工程网页wamp
    一文读懂,WMS仓储管理系统与ERP有什么区别
    网络安全笔记3——双钥密码体制
    基础排序算法详解与对比分析
    iOS APP 转让避坑指南
    Pandas - 数据合并
    Linux中的重定向和管道符
    【产品运营】如何提升B端产品的竞争力(上)
  • 原文地址:https://blog.csdn.net/wangjie36/article/details/134530276