修网(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>;
            };
        };
    };

发表评论

您的电子邮箱地址不会被公开。

Back to Top