修网(AXI Ethernet)
故障现象
今日发现我之前搭建的基于Rocket Chip的SoC,在U-Boot中网卡工作,但Linux中网卡一直无法工作。并发现经常在Linux中使用ip link set eth0 up在看到dmesg输出3行网卡开启信息后系统就卡死,并在reset核心后U-boot(XIP)载入到开始访问DRAM的位置就停下。看起来像是AXI总线上(因为我没有进行Reset)有请求在我reset期间没有完成,这大概可以说明AXI总线上发了一些核的Slave无法处理的请求。
起初我怀疑问题有一部分和中断有关,因为U-Boot没有使用中断,但通过检查/proc/interrupts发现连接在PLIC上两个网卡的中断号都能在set eth0 up后出现多次中断。然后看了下Linux的Documentation中的设备树相关部分,发现我的网卡中断和DMA中断设置不对(要求把DMA中断也放在网卡中断中,但实测是等价的),修改后问题依旧,按照一个别人能工作的设备树写法修改后问题依旧。
而继续搜索相关资料发现,别人遇到的问题多数都是PHY相关。然而我使用的是SFP接口的1000BaseX,AXI Ethernet会自己实例化一个PHY,并不是外置的。
解决方法
后来我对比了我的SoC和别人的SoC,发现我拖出来的AXI DMA IP核的Memory Map Data Width没有修改,为默认的32。改成64并在TX和RX都开启Unalign后问题就解决了。
事后发现保持Data Width为64关闭Unalign后继续不工作,而在设备树中指定xlnx,addrwidth = <32>;
和xlnx,datawidth = <32>;
且关闭Unalign并设置Width为32也是不工作,有关原因等后续有时间进一步研究。
我最终的设备树
其中L8是PLIC。网卡的mac_irq接在PLIC的2号中断口上。然后s2mm和mm2s分别接3号和4号口。
axi_eth_0_dma: eth_dma@60300000 {
compatible = "xlnx,eth-dma";
reg = <0x60300000 0x100000>;
interrupt-parent = <&L8>;
interrupts = <4 3>;
};
eth0: ethernet@60200000 {
axistream-connected = <&axi_eth_0_dma>;
compatible = "xlnx,axi-ethernet-1.00.a";
device_type = "network";
interrupt-parent = <&L8>;
interrupts = <2>;
phy-handle = <&axi_eth_phy>;
phy-mode = "internal";
reg = <0x60200000 0x100000>;
mac-address = [23 33 66 01 23 45];
fixed-link {
speed = <1000>;
full-duplex;
};
eth_0: mdio {
#address-cells = <1>;
#size-cells = <0>;
axi_eth_phy: phy@1 {
device_type = "ethernet-phy";
reg = <1>;
xlnx,phy-type = <0x5>;
};
};
};