zoukankan      html  css  js  c++  java
  • Xilinx Uboot网卡驱动分析

    1、MAC控制器、网卡、PHY、MDIO、mii、gmii、rgmii概念扫盲

    网卡在功能上包含OSI模型的两个层,数据链路层和物理层。物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。数据链路层则提供寻址机构、数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能。网卡中负责数据链路的芯片叫做MAC控制器,负责物理层的芯片叫做PHY。所以,一个网卡由MAC控制器和PHY组成。

    MAC控制器与PHY连接使用MII(Medium independent interface)媒体独立接口,这个接口是IEEE-802.3定义的以太网行业标准定义的接口,包括一个数据接口和一个MAC和PHY之间的管理接口即MDIO。MII标准接口用于连接MAC和PHY,媒体独立表示不对MAC硬件重新设计或替换的情况下,任何类型的PHY设备接到当前MAC控制器上都可以正常工作。

    MII支持10M和100M的网络速率,由于网卡的速率不同,所以在其他速率下工作的与MII等效的接口有:AUI(10M 以太网)、GMII(Gigabit 以太网)和XAUI(10-Gigabit 以太网)。此外还有RMII、RGMII、SMII、SGMII等。所有这些接口都是由MII而来。MII支持10兆和100兆的操作,一个接口由14根线组成。 RMII是简化的MII接口,在数据的收发上它比MII接口少了一倍的信号线。SMII是由思科提出的一种媒体接口,它有比RMII更少的信号线数目,S表示串行的意思。因为它只用一根信号线传送发送数据,一根信号线传输接受数据,所以在时钟上为了满足100的需求,它的时钟频率很高,达到了125兆,为什么用125兆,是因为数据线里面会传送一些控制信息。GMII采用8位接口数据,工作时钟125MHz,因此传输速率可达1000Mbps。同时兼容MII所规定的10/100 Mbps工作方式。RGMII又是GMII接口的精简版。SGMII又是GMII的串行版。

    MAC控制器和PHY除了数据传输的交流外,MAC和PHY控制信息的交流通过MDIO(管理数据输入输出)接口来完成。具体MAC控制器进行PHY检测、MAC控制器回去PHY当前状态、MAC控制器控制PHY速率等操作就通过MDIO来完成。

    2. xilinx uboot网卡驱动分析

    xilinx网卡模式比较灵活,可以外接PHY芯片也可以用FPGA做PHY芯片。

    以zynqmp_zcu102为例,在其dts中定义的网卡设备树为

    &gem3 {
    status = "okay";
    local-mac-address = [00 0a 35 00 02 90];
    phy-handle = <&phy0>;
    phy-mode = "rgmii-id";
    phy0: phy@21 {
    reg = <21>;
    ti,rx-internal-delay = <0x8>;
    ti,tx-internal-delay = <0xa>;
    ti,fifo-depth = <0x1>;
    };
    };

    uboot加载设备树种的信息创建device后,与driver匹配后执行zynq_gem_probe函数。

    在uboot中管理整个网卡驱动的结构为

    struct zynq_gem_priv {
    struct emac_bd *tx_bd;
    struct emac_bd *rx_bd;
    char *rxbuffers;
    u32 rxbd_current;
    u32 rx_first_buf;
    int phyaddr;
    u32 emio;
    int init;
    struct zynq_gem_regs *iobase;
    phy_interface_t interface;
    struct phy_device *phydev;
    int phy_of_handle;
    struct mii_dev *bus;
    };

    由变量名可知,它包含了所有操作网卡需要的信息。

    zynq_gem_probe(struct udevice *dev)函数中具体做的操作有:
    
    priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); 为priv分配接收buffers
    
    priv->tx_bd = (struct emac_bd *)bd_space; //分配tx_bd的空间
    priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);//分配rx_bd的空间
    
    priv->bus = mdio_alloc();//分配mdio bus,主要是初始化了一个bus链表
    
    priv->bus->read = zynq_gem_miiphy_read; //mdio总线读函数,用于读取phy信息
    priv->bus->write = zynq_gem_miiphy_write;//mdio写总线函数
    priv->bus->priv = priv;
    strcpy(priv->bus->name, "gem");//总线名为gem
    
    ret = mdio_register(priv->bus);//注册mdio,主要进行的操作是list_add_tail(&bus->link, &mii_devs);
    
    return zynq_phy_init(dev); //phy初始化

    接下来看下 zynq_phy_init函数里干了啥。

    zynq_phy_init(struct udevice *dev)

    writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs->nwctrl);写MAC控制器寄存器,Enable MDIO bus

    ret = phy_detection(dev);//通过MDIO来检测phy,通过phyread函数检测正确的phy地址,如果没有检测到,zynq_phy_init将会退出,后面的初始化就不会有,网卡就不能使用,在调试的时候可以注意下这个过程。

    priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev,priv->interface);

    本文转载自: https://blog.csdn.net/u012075739/article/details/52966751

  • 相关阅读:
    XtraBackup2.3.3安装配置使用(innobakupex)
    MySQL主从配置问题整理
    saltstack之(十二)配置管理mount
    常用HTTP状态码和CURL 000问题
    RHEL6解决无法使用YUM源问题
    zabbix监控MySQL
    ELK-Python(三)
    解决eclipse项目下出现deployment descriptor和jax-ws web services
    【未来畅想】未来的电信通讯行业,账号密码将取代sim卡
    最新samba.tar.gz安装方法
  • 原文地址:https://www.cnblogs.com/Ph-one/p/9034834.html
Copyright © 2011-2022 走看看