新一块板子
米尔科技的 z-turn 使用的PHY芯片是Micrel的 KSZ9031RNX 而不是zedboard上的Marvell的。
直接使用lwip的echo server demo时会报错 , 无法启动。
在网上找了很久终于找到几篇关于这个问题的文章。
修改PHY的驱动 xemacpsif_physpeed.c 文件
该芯片的PHY Identifier 是 0x0022
bsp设置中修改参数以提速
MEM_SIZE 524288
MEMP_N_PBUF 1024
MEMP_N_TCP_SEG 1024
PBUF_POOL_SIZE 8192
TCP_MSS 4096
TCP_SND_BUF 65535
TCP_WND 65535
N_RX_DESCRIPTORS = 512
N_TX_DESCRIPTORS = 512
TCP_IP_TX_CHECKSUM_OFFLOAD= true
TCP_IP_RX_CHECKSUM_OFFLOAD= true
//********* 2018/11/27********
添加的代码
Code:
#define PHY_MICREL_IDENTIFIER 0x0022 //added by Liny //added by Liny static u32_t get_Micrel_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr) { u16_t temp; u16_t control; u16_t status; u16_t status_speed; u32_t timeout_counter = 0; u32_t temp_speed; //u32_t phyregtemp; xil_printf("Start Micrel PHY autonegotiation \r\n"); //Auto-negotiation Advertisement REG XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control); //reg 0x04 control |= IEEE_ASYMMETRIC_PAUSE_MASK; //0x0800 control |= IEEE_PAUSE_MASK; control |= ADVERTISE_100; control |= ADVERTISE_10; XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control); //1000Basic-T Control REG 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_COPPER_SPECIFIC_CONTROL_REG, &control); //reg 0x0f // control |= (7 << 12); // control |= (1 << 11); // XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG, control); //basic Control XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); //reg 0x00 control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE; control |= IEEE_STAT_AUTONEGOTIATE_RESTART; XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control); //basic 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; } //read extended staus XEmacPs_PhyRead(xemacpsp, phy_addr, 0x0f, &status); xil_printf("extened status:0x%x \r\n",status); //read baisc status reg 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); XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2, &temp); 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"); //#define IEEE_1000BASE_STATUS_REG 0x0a #define MICREL_PHY_CONTROL_REG 0x1f //XEmacPs_PhyRead(xemacpsp, phy_addr,IEEE_SPECIFIC_STATUS_REG, &status_speed); //XEmacPs_PhyRead(xemacpsp, phy_addr,IEEE_1000BASE_STATUS_REG, &status_speed); //if (status_speed & 0x0800) { //xil_printf("micrel phy ksz9031 speed 1000 \r\n"); //return 1000; //} //modify by Liny XEmacPs_PhyRead(xemacpsp, phy_addr,MICREL_PHY_CONTROL_REG, &status_speed); // 读取寄存器17,改为31 0x1f VS_PHY_CONTROL_REG IEEE_SPECIFIC_STATUS_REG if (!(status_speed & 0x01)) { //link on 原来0x400,第10 位 xil_printf("PHY Link stutus:not failing \r\n"); temp_speed = status_speed & 0x70; // 读取最高两位速度 [6:4]status_speed & IEEE_SPEED_MASK if (temp_speed == 0x40)//IEEE_SPEED_1000 return 1000; else if(temp_speed == 0x20)//IEEE_SPEED_100 return 100; else return 10; } return XST_SUCCESS; } //added by Liny 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); } //added by Liny else if(phy_identity == PHY_MICREL_IDENTIFIER){ RetStatus = get_Micrel_phy_speed(xemacpsp, phy_addr); } //added by Liny else { RetStatus = get_Marvell_phy_speed(xemacpsp, phy_addr); } return RetStatus; }
via:
https://forums.xilinx.com/t5/Embedded-Development-Tools/2015-4-lwip-KSZ9031-link-issues/m-p/696975
https://blog.csdn.net/yezizhangxinya/article/details/55805512?locationNum=4&fps=1
https://blog.csdn.net/he_wen_jie/article/details/51880845
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842366/Standalone+LWIP+library
https://blog.csdn.net/ma_cheng_yuan/article/details/78527205?utm_source=copy