zoukankan      html  css  js  c++  java
  • 以太网驱动的流程浅析(三)-ifconfig的-19错误最底层分析【原创】

    以太网驱动流程浅析(三)-ifconfig的-19错误最底层分析

    **Author:张昺华
    Email:920052390@qq.com
    Time:2019年3月23日星期六
    **

    此文也在我的个人公众号以及《Linux内核之旅》上有发表:以太网驱动流程浅析(三)-ifconfig的-19错误最底层分析

    很喜欢一群人在研究技术,一起做有意思的东西,一起分享技术带给我们的快乐,也希望中国有更多的人热爱技术,喜欢一起研究、分享技术,然后可以一起用我们的技术来做一些好玩的东西,可以为这个社会创造一些东西来改善人们的生活。

    如下是本人调试过程中的一点经验分享,以太网驱动架构毕竟涉及的东西太多,如下仅仅是针对加载流程和围绕这个问题产生的分析过程和驱动加载流程部分,并不涉及以太网协议层的数据流程分析。

    【硬件环境】 Imx6ul

    【Linux kernel版本】 Linux4.1.15

    【以太网phy】 Realtek8201f

    1. 以太网流程分析跟踪

    1.1 ifconfig的-19错误最底层分析


    看了后我们知道是fec_enet_mii_probe函数返回的-19,继续跟踪进去:

    哈哈,看到这里答案出来了,-19就是这里返回的,也就是说phy_dev是NULL
    那为什么呢?我们跟进去看下,of_phy_connect,功能注释已经写的很清楚了
    Connect to the phy described in the device tree,从设备树上获取phy的相关描述信息,路径:drivers/of/of_mdio.c

    既然phy_device是空的,也就是说struct phy_device *phy = of_phy_find_device(phy_np);
    没有从这里面拿到phy_device

    看下如下两个函数

    这里我需要解释下了,bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
    从bus总线上找到device,也就是我们的phy_device,

    如果找到就返回phy_device,否则就返回NULL
    这个bus是指mdio_bus_type,如下:

    1.2 以太网硬件知识

    那mdio又是什么呢?这就是以太网的知识了,我们看下以太网的硬件接法:

    如下内容转自:https://blog.csdn.net/fun_tion/article/details/70270632

    1.概述
    MII即“媒体独立接口”,也叫“独立于介质的接口”。它是IEEE-802.3定义的以太网行业标准。它包括一个数据接口,以及一个MAC和PHY之间的管理接口。RMII全称为“简化的媒体独立接口”,是IEEE-802.3u标准中除MII接口之外的另一种实现。(此处内容来源于网络)

    2.独立于介质的接口(MII)
    独立于介质的接口(MII)用于MAC与外接的PHY互联,支持10Mbit/s和100Mbit/s数据传输模式。MII的信号线如下图所示:

    MII_TX_CLK:发送数据使用的时钟信号,对于10M位/s的数据传输,此时钟为2.5MHz,对于100M位/s的数据传输,此时钟为25MHz。
    MII_RX_CLK:接收数据使用的时钟信号,对于10M位/s的数据传输,此时钟为2.5MHz,对于100M位/s的数据传输,此时钟为25MHz。
    MII_TX_EN:传输使能信号,此信号必需与数据前导符的起始位同步出现,并在传输完毕前一直保持。
    MII_TXD[3:0]:发送数据线,每次传输4位数据,数据在MII_TX_EN信号有效时有效。MII_TXD[0]是数据的最低位,MII_TXD[3]是最高位。当MII_TX_EN信号无效时,PHY忽略传输的数据。
    MII_CRS:载波侦听信号,仅工作在半双工模式下,由PHY控制,当发送或接收的介质非空闲时,使能此信号。 PHY必需保证MII_CRS信号在发生冲突的整个时间段内都保持有效,不需要此信号与发送/接收的时钟同步。
    MII_COL:冲突检测信号,仅工作在半双工模式下,由PHY控制,当检测到介质发生冲突时,使能此信号,并且在整个冲突的持续时间内,保持此信号有效。此信号不需要和发送/接收的时钟同步。
    MII_RXD[3:0]:接收数据线,每次接收4位数据,数据在MII_RX_DV信号有效时有效。MII_RXD[0]是数据的最低位,MII_RXD[3]是最高位。当MII_RX_EN无效,而MII_RX_ER有效时,MII_RXD[3:0]数据值代表特定的信息(请参考表194)。
    MII_RX_DV:接收数据使能信号,由PHY控制,当PHY准备好数据供MAC接收时,使能该信号。此信号必需和帧数据的首位同步出现,并保持有效直到数据传输完成。在传送最后4位数据后的第一个时钟之前,此信号必需变为无效状态。为了正确的接收一个帧,有效电平不能滞后于数据线上的SFD位出现。
    MII_RX_ER:接收出错信号,保持一个或多个时钟周期(MII_RX_CLK)的有效状态,表明MAC在接收过程中检测到错误。具体错误原因需配合MII_RX_DV的状态及MII_RXD[3:0]的数据值。
    3.精简的独立于介质的接口(RMII)
    精简的独立于介质接口(RMII)规范减少了以太网通信所需要的引脚数。根据IEEE802.3标准,MII接口需要16个数据和控制信号引脚,而RMII标准则将引脚数减少到了7个。RMII具有以下特性:
    时钟信号需要提高到50MHz。
    MAC和外部的以太网PHY需要使用同样的时钟源
    使用2位宽度的数据收发
    RMII的信号线如下图所示:

    **
    如上内容转自:https://blog.csdn.net/fun_tion/article/details/70270632
    **

    1.3 Mdio总线没有找到phy_device

    接下来回归到软件层面,那以太网的通信收发数据包就是使用MDC/MDIO这样的硬件接口
    软件的接口是:mdiobus_read与mdiobus_write


    那这块最终的read / write的实现函数在哪里呢?去以太网控制器drvier里看就好了fec_main.c中:



    回归到刚刚的-19错误最终发现是phy_device为NULL了,也就是在mdio bus上没有找到对应的phy_device,那么从这里我们可以猜想注册的时候是否根本就没注册进去呢?或者是注册成功了后,在某个阶段phy_device消失了?带着这个疑问我们就要看下以太网控制器加载的流程了。

    4. 网址分享

    http://stackoverflow.com/questions/5308090/set-ip-address-using-siocsifaddr-ioctl
    http://www.ibm.com/support/knowledgecenter/ssw_aix_72/com.ibm.aix.commtrf2/ioctl_socket_control_operations.htm
    https://lkml.org/lkml/2017/2/3/396
    linux PHY驱动
    http://www.latelee.org/programming-under-linux/linux-phy-driver.html
    Linux PHY几个状态的跟踪
    http://www.latelee.org/programming-under-linux/linux-phy-state.html
    第十六章PHY -基于Linux3.10
    https://blog.csdn.net/shichaog/article/details/44682931

    ### End
  • 相关阅读:
    scp 利用 ssh 协议 复制文件
    linux (fedora 28) 制作启动U盘,启动盘
    nc 命令使用详解
    env :让系统决定你命令的位置
    tali -f 和 tail -F 之间的区别
    斯诺克台球比赛规则 (Snooker)
    中式台球 规则 ( ChinaBilliards )
    美式九球比赛规则 (Nine-ball)
    Tmux 使用教程 on Fedora 28
    python 3.6 的 venv 模块
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/11941884.html
Copyright © 2011-2022 走看看