[X]关闭

RTL8211(工/商)业级网口芯片bsp自适应修改vivado2019.2

文档创建者:虫二198
浏览次数:9583
最后更新:2021-03-09
本帖最后由 虫二198 于 2021-3-9 15:11 编辑

XILINX官方默认的lwip bsp驱动暂时不支持RTL8211网口芯片,在使用该网口的时候需要自己手动修改库文件以支持该芯片,不同版本工具之间的修改方式大同小异,这边仅以Vitis 2019.2为例。
PS端网口以米联客MZU07A board为例:
Step1:首先,找到vitis ide安装目录下的LWIP库的路径,将其拷贝一份放到工程目录下:
RTL8211(工/商)业级网口芯片bsp自适应修改-1.png
Step2:修改lwip211_v1_1\data\lwip211.mld文件(可用Notapad++等编辑器打开),将其中的版本编号
OPTION VERSION =1.1;
修改为
OPTION VERSION = 1.2;;
RTL8211(工/商)业级网口芯片bsp自适应修改-2.png
Step3:打开lwip141_v2_0\src\contrib\ports\xilinx\netif\ xemacpsif_physpeed.c,进行如下修改
根据芯片手册定义Realtek PHY芯片的ID
RTL8211(工/商)业级网口芯片bsp自适应修改-3.png
#define PHY_REALTEK_IDENTIFIER                           0x001c
Step4:在get_Marvell_phy_speed库函数基础上,对rtl8211的特殊状态寄存器进行修改,然后保存
商业级RTL8211手册PHYSR参数:
RTL8211(工/商)业级网口芯片bsp自适应修改-4.png
static u32_t get_Realtek_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
{
         u16_t control;
         u16_t status;
         u16_t status_speed;
         u32_t timeout_counter = 0;
         u32_t temp_speed;

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

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
         control |= IEEE_ASYMMETRIC_PAUSE_MASK;
         control |= IEEE_PAUSE_MASK;
         control |= ADVERTISE_100;
         control |= ADVERTISE_10;
         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
                                               &control);
         control |= ADVERTISE_1000;
         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
                                               control);

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

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
         control |= IEEE_CTRL_RESET_MASK;
         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);

         while (1) {
                   XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
                   if (control & IEEE_CTRL_RESET_MASK)
                            continue;
                   else
                            break;
         }

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);

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

         while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
                   sleep(1);
                   timeout_counter++;

                   if (timeout_counter == 30) {
                            xil_printf("Auto negotiation error \r\n");
                            return XST_FAILURE;
                   }
                   XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
         }
         xil_printf("autonegotiation complete \r\n");


    XEmacPs_PhyRead(xemacpsp, phy_addr,0x11,
                                   &status_speed); /* Commercial RTL8211*/
       if (status_speed & 0x400) {
              temp_speed = status_speed & 0xc000;

              if (temp_speed == 0x8000)
                     return 1000;
              else if(temp_speed == 0x4000)
                     return 100;
              else
                     return 10;
           }


       return XST_SUCCESS;
}
工业级RTL8211手册PHYSR参数:
RTL8211(工/商)业级网口芯片bsp自适应修改-5.png
static u32_t get_Realtek_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)
{
         u16_t control;
         u16_t status;
         u16_t status_speed;
         u32_t timeout_counter = 0;
         u32_t temp_speed;

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

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
         control |= IEEE_ASYMMETRIC_PAUSE_MASK;
         control |= IEEE_PAUSE_MASK;
         control |= ADVERTISE_100;
         control |= ADVERTISE_10;
         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
                                               &control);
         control |= ADVERTISE_1000;
         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
                                               control);

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

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
         control |= IEEE_CTRL_RESET_MASK;
         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);

         while (1) {
                   XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
                   if (control & IEEE_CTRL_RESET_MASK)
                            continue;
                   else
                            break;
         }

         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);

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

         while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
                   sleep(1);
                   timeout_counter++;

                   if (timeout_counter == 30) {
                            xil_printf("Auto negotiation error \r\n");
                            return XST_FAILURE;
                   }
                   XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
         }
         xil_printf("autonegotiation complete \r\n");

   XEmacPs_PhyRead(xemacpsp, phy_addr,0X1A,
                                   &status_speed); /* Industrial RTL8211 */

       if (status_speed & 0x04) {
              temp_speed = status_speed & 0x30;

              if (temp_speed == 0x20)
                     return 1000;
              else if(temp_speed == 0x10)
                     return 100;
              else
                     return 10;
        }

       return XST_SUCCESS;
}
Step5:在vitis软件中导入修改后的lwip库的路径(需根据实际情况更改此路径,若不更改将产生错误)
RTL8211(工/商)业级网口芯片bsp自适应修改-6.png
RTL8211(工/商)业级网口芯片bsp自适应修改-7.png
Step6:导入库文件后重启SDK
RTL8211(工/商)业级网口芯片bsp自适应修改-8.png
Step7: 勾选lwip库文件
RTL8211(工/商)业级网口芯片bsp自适应修改-9.png
Step8: 选择lwip211_1.2版本
RTL8211(工/商)业级网口芯片bsp自适应修改-10.png
Step9: 选择File->New->Application Project->lwip_echo_server
RTL8211(工/商)业级网口芯片bsp自适应修改-11.png
Step10:右击lwip_testàDebug  Asà Debug  Configurations,然后单击debug
RTL8211(工/商)业级网口芯片bsp自适应修改-12.png
Step11:单击运行,查看输出结果
RTL8211(工/商)业级网口芯片bsp自适应修改-13.png
RTL8211(工/商)业级网口芯片bsp自适应修改-14.png
RTL8211(工/商)业级网口芯片bsp自适应修改-15.png
PL端网口以米联客MA703_100T为例
Xilinx SDK 目录下面 xaxiemacif_physpeed.c 文件里面对 PHY 芯片有驱动,目前支持 MARVEL 和 TI 的部分 PHY 芯片,如果使用其他厂家的 PHY 芯片,需要更改驱动,否则协商不能通过。
打开fpga_prj\uisrc\07_sdk_src\lwip211_v1_1\src\contrib\ports\xilinx\netif\xaxiemacif_physpeed.c 源文件,增加宏定义

RTL8211(工/商)业级网口芯片bsp自适应修改-16.png
添加PHY ID的定义
RTL8211(工/商)业级网口芯片bsp自适应修改-17.png
以下驱动程序的修改仅支持工业级RTL8211的千兆协商

unsigned get_IEEE_phy_speed(XAxiEthernet *xaxiemacp)
{
         u8 phytype;
         u16 phy_val;
         u16 phy_identifier;
         u16 phy_model;
         u16 control;
         u16 status;
         u16 partner_capabilities;
         u16 partner_capabilities_1000;
         u16 phylinkspeed;
         int TimeOut;


#ifdef XPAR_AXIETHERNET_0_BASEADDR
         u32 phy_addr = detect_phy(xaxiemacp);

         /* Get the PHY Identifier and Model number */
         XAxiEthernet_PhyRead(xaxiemacp, phy_addr, PHY_IDENTIFIER_1_REG, &phy_identifier);
         XAxiEthernet_PhyRead(xaxiemacp, phy_addr, PHY_IDENTIFIER_2_REG, &phy_model);

/* Depending upon what manufacturer PHY is connected, a different mask is
* needed to determine the specific model number of the PHY. */
         if (phy_identifier == MARVEL_PHY_IDENTIFIER) {
                   phy_model = phy_model & MARVEL_PHY_MODEL_NUM_MASK;

                   if (phy_model == MARVEL_PHY_88E1116R_MODEL) {
                            return get_phy_speed_88E1116R(xaxiemacp, phy_addr);
                   } else if (phy_model == MARVEL_PHY_88E1111_MODEL) {
                            return get_phy_speed_88E1111(xaxiemacp, phy_addr);
                   }
         } else if (phy_identifier == TI_PHY_IDENTIFIER) {
                   phy_model = phy_model & TI_PHY_DP83867_MODEL;
                   phytype = XAxiEthernet_GetPhysicalInterface(xaxiemacp);

                   if (phy_model == TI_PHY_DP83867_MODEL && phytype == XAE_PHY_TYPE_SGMII) {
                            return get_phy_speed_TI_DP83867_SGMII(xaxiemacp, phy_addr);
                   }

                   if (phy_model == TI_PHY_DP83867_MODEL) {
                            return get_phy_speed_TI_DP83867(xaxiemacp, phy_addr);
                   }
         }
         else {
                            if (phy_identifier==PHY_REALTEK_IDENTIFIER){
                      XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0x1A, 0x20);
                            XAxiEthernet_PhyRead(xaxiemacp, phy_addr,IEEE_CONTROL_REG_OFFSET,&control);
                      control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
               control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
                            XAxiEthernet_PhyWrite(xaxiemacp,phy_addr,IEEE_CONTROL_REG_OFFSET,control);
                   }
                            if (phy_identifier==PHY_REALTEK_IDENTIFIER){
                   XAxiEthernet_PhyRead(xaxiemacp, phy_addr, 0, &control);
             XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0,control | IEEE_CTRL_RESET_MASK);
                   for(TimeOut=0;TimeOut<5000;TimeOut++);
             XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, 0x1A, 0x20);
                   XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
                   control |= IEEE_ASYMMETRIC_PAUSE_MASK;
                   control |= IEEE_PAUSE_MASK;
                   control |= ADVERTISE_100;
                   control |= ADVERTISE_10;
                   XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
                   XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,&control);
                   control |= ADVERTISE_1000;
                   XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,control);
                   XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
                   control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
                   control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
                   XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);

                   return 1000;
         }
             LWIP_DEBUGF(NETIF_DEBUG, ("XAxiEthernet get_IEEE_phy_speed: Detected PHY with unknown identifier/model.\r\n"));
         }
设置BSP文件
RTL8211(工/商)业级网口芯片bsp自适应修改-18.png
测试
RTL8211(工/商)业级网口芯片bsp自适应修改-19.png
RTL8211(工/商)业级网口芯片bsp自适应修改-20.png
RTL8211(工/商)业级网口芯片bsp自适应修改-21.png



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则