RK3576 双千兆 GMAC 驱动加载异常问题排查与总结

一、问题背景

平台:RK3576,板载两颗瑞昱的千兆 PHY 芯片 YT8531C-CA。

现象:两个 GMAC 控制器,同一时间打开一个 GMAC0 驱动的状态,对应的两个 GMAC0、GMAC1 的驱动都能加载完成,并且在系统上层都能查看到对应 eth0 和 eth1(这是厂家编写的内核的 netdev 编号)。但是,如果同时两个 GMAC 的驱动状态都设置为 okay 的话,就会出现有一个 GMAC 网卡的驱动无法加载的问题,只能单独有一个 eth0。

部分驱动设备树贴出如下(非公司驱动文件,仅提供参考):

bash 复制代码
&gmac0 {
	phy-mode = "rgmii-rxid";
	clock_in_out = "output";
	snps,reset-gpio = <&xl9555 PCA_IO0_0 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	snps,reset-delays-us = <0 20000 100000>;
	pinctrl-names = "default";
	pinctrl-0 = <&eth0m1_miim
		     &eth0m1_tx_bus2
		     &eth0m1_rx_bus2
		     &eth0m1_rgmii_clk
		     &eth0m1_rgmii_bus>;

	tx_delay = <0x21>;
	/* rx_delay = <0x3f>; */
	phy-handle = <&rgmii_phy0>;
	status = "okay";
};

&gmac1 {
	phy-mode = "rgmii-rxid";
	clock_in_out = "output";

	snps,reset-gpio = <&xl9555 PCA_IO0_1 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	snps,reset-delays-us = <0 20000 100000>;

	pinctrl-names = "default";
	pinctrl-0 = <&eth1m0_miim
		     &eth1m0_tx_bus2
		     &eth1m0_rx_bus2
		     &eth1m0_rgmii_clk
		     &eth1m0_rgmii_bus>;

	tx_delay = <0x20>;
	/* rx_delay = <0x3f>; */

	phy-handle = <&rgmii_phy1>;
	status = "okay";
};

二、疑问

这两个 GMAC 控制器用的都是完全分开独立的引脚,为何一个能正常初始化,另一个也能正常初始化,但是两个同时使能却不能够正常初始化呢?这个问题和芯片分销商的 FAE 沟通过,他没有遇到过这个问题。

三、最终解决

经过排查原理图和硬件工程师分析,其中有一个千兆网的对于 PHY 的复位引脚配置错误。原因有两个:

  1. GMAC0 的配置复位引脚,原理图的标号编写有错误,用了其他引脚。
  2. GMAC1 的复位引脚的电平不对,和原理图规划的 3.3V 不符合,只有 1.78V。

问题大致是如此,但是从驱动工程师角度来看,这个问题还是值得记录。

四、同类问题补充

无独有偶:我在 RK3562 公司的产品上也遇到类似的问题,不过那个是两组 GMAC 控制器的 pin 的电平状态不一致导致的,我怀疑 IO 电压域也有影响。

五、总结

各家厂家的 SoC 内部 IP 核(功能模块)设计只有原厂最为了解,这一个错误应该是一种连带式的错误。

这通常不是一个引脚或一个节点配置错误导致的,而是一个更深层的、系统级的联动反应。在复杂的 SoC 系统中,一个看似独立的硬件模块修改,可能会通过电源/时钟域共享、驱动 Probe 失败连锁反应以及设备树语法错误这三种机制,间接影响到另一个模块。

5.1 共享电源/时钟域:最可能的原因

这是最根本的硬件原因。SoC 内部为了省电和简化设计,会将多个功能模块(IP 核)组合在同一个电源域或时钟域中。

现象:GMAC0 和 GMAC1 这两个网卡控制器,很可能被放在了同一个电源域里。

结果:当你为 GMAC1 配置了错误的复位引脚,导致其驱动初始化失败时,内核的电源管理子系统可能会认为这个电源域整体"出错了",从而将其关闭或重置。这一操作会连带导致同一个域内的 GMAC0 完全掉电或失去时钟,即使 GMAC0 本身的配置是正确的,它也会因此"消失"。

5.2 驱动 Probe 失败引发的连锁反应

这是软件层面的原因。设备树中的节点不是孤立的,驱动在初始化时遵循严格的顺序。

依赖关系:两个 GMAC 接口可能共享同一个 MDIO 总线,或者在初始化流程上有前后依赖。

结果:如果内核先尝试初始化 GMAC1,并且因为你的复位引脚错误而失败(probe fail),这个失败可能会通过共享的初始化函数或总线,中断后续的设备扫描。内核可能因此认为整个 GMAC 控制器集群存在问题,从而跳过或放弃初始化剩余的 GMAC0。

相关推荐
AI_Lab011 小时前
宝塔用了两年,有没有必要换成轻量方案?
linux·运维·服务器
by209991 小时前
Linux GDB 调试与 CGDB 使用
linux·运维·服务器·经验分享
星恒随风2 小时前
Linux网络编程:应用层协议究竟是什么?从网络计算器到TCP Socket抽象基类完整实现
linux·网络·笔记·tcp/ip
feng_you_ying_li4 小时前
linux之网络层
linux·运维·网络
未来之窗软件服务4 小时前
Linux 运维日志删除的多种方式—东方仙盟
linux·运维·服务器·仙盟创梦ide·东方仙盟
小雉系统5 小时前
BcoreOS实战:用一个升级包,让Rocky Linux跑进Debian服务器
linux·运维·服务器·debian
thethefighter5 小时前
快速预览Word、WPS秒开,支持空格弹窗
linux·word·wps·快速预览·空格弹窗·nhdeepview
用户8351414049495 小时前
把日志和寄存器值喂给AI做故障定位,我的实际问法
linux·ubuntu
Ruiery5 小时前
Linux 6.6内核内存管理深度解析(十七):vmalloc — 内核要“虚拟连续“就够:物理页逐个凑,页表来连
linux·运维·服务器
Escalating_xu6 小时前
【Linux 网络编程】ARP 的具体过程与 ARP 欺骗:一条 IP → MAC 映射,怎样改变数据的去向?
linux·网络·tcp/ip