接前一篇文章:Linux网络驱动之Fixed-Link(32)
本文内容参考:
RK3588+TRL8367s 四网口千兆交换机配置与性能优化实战-CSDN博客
特此致谢!
上一回开始结合dts文件,讲解Linux内核(5.10版本)中对于board.dts文件中gmac0结点中的fixed-link属性的处理。
&gmac0 { phy-mode = "rgmii-id"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&gmac0_pins_default &gmac0_pins_pg11>; pinctrl-1 = <&gmac0_pins_sleep>; sunxi,phy-clk-type = <0>; use_ephy25m = <1>; tx-delay = <2>; rx-delay = <0>; status = "okay"; fixed-link { speed = <1000>; full-duplex; }; };原本要沿着bsp/drivers/gmac/sunxi-gmac.c文件中的代码逐步展开来,但笔者今天(2026.06.15)特意咨询了当初完成这一部分工作的驱动工程师,他给我讲了完整的步骤以及全部的工作。笔者刷新了认知,原本笔者以为顶多也就是改一改dts文件,顶多再改几行驱动代码也就可以了,但实际的工作量远超笔者此前想象,涉及到了驱动移植、添加,并且设备树中的内容也与之前笔者认知大相径庭。
先说上边这个gmac0,虽然其中有了“fixed-link”属性,但是实际上是不够的,还需要另外一处也定义这个“fixed-link”属性,这个结点就是mdio0,其相关代码在bsp/configs/linux-5.10-origin/sun8iw20p1.dtsi中,如下:
mdio0: mdio0@4500048 { compatible = "allwinner,sunxi-mdio"; #address-cells = <1>; #size-cells = <0>; reg = <0x0 0x04500048 0x0 0x8>; status = "okay"; gmac0_phy0: ethernet-phy@1 { /* IP101GR(0x02430c54) */ reg = <1>; max-speed = <1000>; /* Max speed capability */ reset-gpios = <&pio PB 7 GPIO_ACTIVE_LOW>; /* PHY datasheet rst time */ reset-assert-us = <10000>; reset-deassert-us = <150000>; ethernet = <&gmac0>; phy-mode = "rgmii-id"; fixed-link { speed = <1000>; full-duplex; }; }; };实际上,这个sun8iw20p1.dtsi文件就是在board.dts开头包含的:
/* * Allwinner Technology CO., Ltd. */ /dts-v1/; #include "sun8iw20p1.dtsi"这就是说,要配置Fixed-Link,需要同时配置MDIO以及GMAC。
实际上,全志的这个SDK做得并不好,没按标准(规矩)来,瑞芯微RK3588 SDK中的dts文件中,就规矩多了:
// 这是假设你的RK3588 GMAC0控制器对应的MDIO总线节点是 &mdio0 &mdio0 { status = "okay"; // 删除可能自动生成的PHY节点,因为我们接的是交换机,不是直接PHY /delete-node/ phy@0; // 定义我们的交换机节点 switch: switch@0 { compatible = "realtek,rtl8367s"; // 驱动匹配的关键字 reg = <0>; // 在MDIO总线上的地址,通常是0 reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; // 复位引脚,低电平有效 // ldo-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; // 如果芯片有外部LDO控制,则启用 realtek,disable-leds; // 可选,禁用交换机的LED指示,如果硬件没接LED可以加上避免报错 // DSA相关,表明这是交换机成员 dsa,member = <0 0>; // 中断控制器(可选但推荐) switch_intc: interrupt-controller { interrupt-parent = <&gpio3>; interrupts = <16 IRQ_TYPE_LEVEL_LOW>; // 连接的中断GPIO interrupt-controller; #interrupt-cells = <1>; }; // 端口定义:这是核心! ports { #address-cells = <1>; #size-cells = <0>; // 定义连接到内部PHY的4个LAN口 port@1 { reg = <1>; // 端口号,对应芯片物理端口 label = "lan1"; // 系统内显示的接口名,如 sw0p1 phy-handle = <&phy1>; // 指向下面MDIO总线定义的PHY // interrupt-parent = <&switch_intc>; // 如果需要端口中断则关联 // interrupts = <1>; }; port@2 { reg = <2>; label = "lan2"; phy-handle = <&phy2>; }; port@3 { reg = <3>; label = "lan3"; phy-handle = <&phy3>; }; port@4 { reg = <4>; label = "lan4"; phy-handle = <&phy4>; }; // 定义CPU口,连接RK3588的GMAC port@6 { // 注意:RTL8367S的扩展口1通常映射为端口6 reg = <6>; label = "cpu"; ethernet = <&gmac0>; // 指向RK3588的以太网控制器节点 phy-mode = "rgmii"; // 连接模式,必须与硬件一致 fixed-link { // 因为直连MAC,所以是固定链接,无需协商 speed = <1000>; // 强制千兆,也可设为<100>测试 full-duplex; pause; // 启用流控,推荐 }; }; }; // 定义交换机内部的MDIO总线,用于管理其内部的PHY mdio { compatible = "realtek,smi-mdio"; #address-cells = <1>; #size-cells = <0>; phy1: phy@1 { reg = <1>; // 可以关联中断 interrupt-parent = <&switch_intc>; interrupts = <1>; }; phy2: phy@2 { reg = <2>; interrupt-parent = <&switch_intc>; interrupts = <2>; }; phy3: phy@3 { reg = <3>; interrupt-parent = <&switch_intc>; interrupts = <3>; }; phy4: phy@4 { reg = <4>; interrupt-parent = <&switch_intc>; interrupts = <4>; }; }; }; };人家瑞芯微就写得很清楚,可以说是“小葱拌豆腐 —— 一清二白”,而不像全志这样“葡萄拌豆腐 —— 一嘟噜一块”。对于RTL8367,是一个switch(交换机)结点,其中一共包含4个PHY,也有“fixed-link”属性。
反过来再看全志的dts:
mdio0: mdio0@4500048 { compatible = "allwinner,sunxi-mdio"; #address-cells = <1>; #size-cells = <0>; reg = <0x0 0x04500048 0x0 0x8>; status = "okay"; gmac0_phy0: ethernet-phy@1 { /* IP101GR(0x02430c54) */ reg = <1>; max-speed = <1000>; /* Max speed capability */ reset-gpios = <&pio PB 7 GPIO_ACTIVE_LOW>; /* PHY datasheet rst time */ reset-assert-us = <10000>; reset-deassert-us = <150000>; ethernet = <&gmac0>; phy-mode = "rgmii-id"; fixed-link { speed = <1000>; full-duplex; }; }; };里边完全看不出来有几个PHY、有几个port。
除了配置交换机(Switch),还需要配置GMAC控制器,它连接的是一个固定链接。这通常在GMAC的节点里配置。RK3588相关dts内容如下:
&gmac0 { // 其他配置,如时钟、phy-mode等可能已在核心板DTS中定义 // 我们需要确保phy-mode也是rgmii,并指定fixed-link phy-mode = "rgmii"; fixed-link { speed = <1000>; full-duplex; pause; }; };T113相关dts内容如下:
&gmac0 { phy-mode = "rgmii-id"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&gmac0_pins_default &gmac0_pins_pg11>; pinctrl-1 = <&gmac0_pins_sleep>; sunxi,phy-clk-type = <0>; use_ephy25m = <1>; tx-delay = <2>; rx-delay = <0>; status = "okay"; fixed-link { speed = <1000>; full-duplex; }; };GMAC内容两者倒是差不多。
更多内容请看下回。