跳到主要内容
版本:当前版本

ZYNQ EMIO 千兆以太网调试教程

基于ZYNQ EMIO的千兆网卡调试​

重要的参考链接https://blog.csdn.net/weixin_43969075/article/details/119872875

ZYNQ硬件端设计​

  • ZYNQ配置

    为了满足测试需求,ZYNQ至少需要配置EMAC,TIMER,UART

  • GMII TO RGMII IP配置

    需要注意的是这里的PHY地址并不是真正的外部PHY芯片的地址,而是一个虚拟地址,需要跟外部PHY的真实地址不一样,才能正常工作,外部PHY的地址是通过3个IO在上电时根据状态来配置的。这个虚拟地址在配置PLATFORM的时候会用到

软件端设计​

  • 生成Platform

    以导出的硬件,生成带FREERTOS的平台。

    配置BSP,包含LWIP

    配置LWIP,把API接口从RAW_API切换到SOCKET_API,使能DHCP,将TCP_WND设置到20480

    修改platform_network/ps7_cortexa9_0/freertos_ps7_cortexa9_0/bsp/libsrc/lwip220/src/lwip-2.2.0/contrib/ports/xilinx/netif/xemacpsif_physpeed.c

    1. 增加分支,我使用的PHY芯片是YT8521,标识是0 无厂商标识
    static u32_t get_IEEE_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
    {
    u16_t phy_identity;
    u32_t RetStatus;

    XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_IDENTIFIER_1_REG,
    &phy_identity);
    if (phy_identity == PHY_TI_IDENTIFIER) {
    RetStatus = get_TI_phy_speed(xemacpsp, phy_addr);
    } else if (phy_identity == PHY_REALTEK_IDENTIFIER) {
    RetStatus = get_Realtek_phy_speed(xemacpsp, phy_addr);
    } else if (phy_identity == PHY_XILINX_PCS_PMA_ID1) {
    RetStatus = get_Xilinx_pcs_pma_phy_speed(xemacpsp, phy_addr);
    } else if (phy_identity == PHY_ADI_IDENTIFIER) {
    RetStatus = get_Adi_phy_speed(xemacpsp, phy_addr);
    } else if (phy_identity == 0) {
    RetStatus = get_Yt8521_phy_speed(xemacpsp, phy_addr);
    } else {
    RetStatus = get_Marvell_phy_speed(xemacpsp, phy_addr);
    }

    return RetStatus;
    }

    2.增加代码获取自己协商到的速度

    static u32_t get_Yt8521_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
    {
    u16_t temp;
    u16_t control;
    u16_t status;

    xil_printf("Yt8521 Start PHY autonegotiation \r\n");

    XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
    control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
    control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
    control &= IEEE_CTRL_ISOLATE_DISABLE;
    XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);

    xil_printf("Waiting for PHY to complete autonegotiation.\r\n");

    XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
    while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
    sleep(1);
    XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
    &status);
    }
    xil_printf("autonegotiation complete \r\n");

    xil_printf("Waiting for Link to be up \r\n");
    XEmacPs_PhyRead(xemacpsp, phy_addr, 0x11, &temp);
    while(!(temp & (1<<10))) {
    XEmacPs_PhyRead(xemacpsp, phy_addr, 0x11, &temp);
    }

    xil_printf("temp:0x%x\n", temp);
    if((temp & 0xc000) == 0x8000) {
    return 1000;
    }
    else if((temp & 0xc000) == 0x4000) {
    return 100;
    }
    else if((temp & 0xc000) == 0x0000) {
    return 10;
    } else {
    xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Defaulting to Speed = 10 Mbps\r\n");
    XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &temp);
    XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, 0x0100);
    return 10;
    }

    return 0;
    }

  • 应用程序

    直接添加基于FREERTOS的PERF SERVER应用

  • 测试

    到另一台机器使用perf测试,可以达到940Mb/s的带宽

其它​

  • 怎么确定PHY地址

    使用了三个复用的IO上电时来确定地址,PHYAD[2:0],当前电路被配置为7

    XILINX检测哪个地址可用的方法是向所有的地址发送信息,检测哪个地址响应不是0XFFFF作为判断依据

  • PHY标识

    PHY中有两个存器用来保存标识信息

​ PHY Identification Register1 (0x02), 组织标识

​ 默认值0x0

​ PHY Identification Register2 (0x03),组织,类型,版本

​ 默认值0x11a

  • 与外部PHY芯片的接口电平

    因为使用了BANK34的EMIO接口,当前BANK被设置为了3.3V,所以接口电平需要使用3.3V

    在PHY端,需要硬件IO端口来配置接口电平为3.3V,此时的PHY内部的LDO被禁用,需要在硬件上给接口提供3.3V电源,这些都需要硬件支持

  • 碰到的问题和最终解决办法

    1、DHCP 超时, 解决办法,需要在PLATFORM中xemacpsif_physpeed.c文件中定义宏#define XPAR_GMII2RGMIICON_0N_ETH0_ADDR 8

    2、速度达不到千兆,解决办法,需要配置lwip,将TCP_WND扩大,测试发现,配置到20480时已经可以达到900M/s以上的速度