理论章节

引言

⼤部分phy 芯⽚都是使⽤通⽤驱动,有的phy 需要专⽤驱动,因为phy 芯⽚功能强⼤,需要驱动⼀些更
强⼤的功能所以就在通⽤驱动上⾯扩展出专⽤驱动

排查步骤

mdio通信是否正常

(1) 查看phy 地址是否和硬件上⼀致,读半天寄存器读不到值,结果phy地址给错了
(2)读芯⽚Id 02 03寄存器 看和芯⽚⼿册是否⼀致,不⼀致可能mdio 通讯有问题。
(3)link 问题。读取01控制寄存器,看⾃协商是否开着。开着以后,插⽹线之前读取状态寄存器, 插⽹
线之后再读取状态寄存器。看前后值是否有变化,没有变 化就说明link 不上,硬件可能存在问题,link
过程是phy 和⽹线之间的协商
⽹络不通可以查看状态寄存器,状态寄存器是只读的。 phy 芯⽚处于⼀种什么状态,从状态寄存器可
以反馈出来。

用示波器测量数据脚是否有信号

PHY寄存器相关说明

Phy 芯⽚寄存器很多,led 灯的状态⼀般在扩展寄存器中,⽬前碰到两种读写寄存
器的⽅法。

扩展寄存器

  1. 有专⻔读写扩展寄存器的寄存器,例如 1E和1F 往1E中写⼊扩展寄存器的地址,然后读写1F寄存器
    的值,就是读写扩展寄存器的值。
    在这里插入图片描述
    eg:uboot命令行修改物理地址为4的phy芯片0xa012寄存器的值为0x78
=>mdio write 4 0x1e 0xa012
=>mdio write 4  0x1f 0x78
=>mdio read 4 0x1f
Reading from bus emdio-3
PHY at address 4:
31 - 0x78

分页操作

  1. 分⻚操作,⾸先向分⻚寄存器中写⼊⻚,例如分⻚寄存器值是0,就说明在0⻚,想跳转0d4⻚,就
    向分⻚寄存器中写⼊0d4 然后就跳转到0d4 ⻚,然后读写寄存器就是读写0d4 ⻚的寄存器。不管在
    哪⻚,前31寄存器是固定的,分⻚寄存器也就在前31寄存器中。
    在这里插入图片描述

在uboot网卡驱动中配置phy寄存器

以LS1028为例适配YT8521及YT8614

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 9a66e62..92ad5bf 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -383,11 +383,33 @@ int genphy_config(struct phy_device *phydev)
 {
 	int val;
 	u32 features;
-
+        int count =0;
 	features = (SUPPORTED_TP | SUPPORTED_MII
 			| SUPPORTED_AUI | SUPPORTED_FIBRE |
 			SUPPORTED_BNC);
 
+	if( phydev->phy_id == 0x0000011a)
+        {
+		//printf("config yt8521\n");
+        	phy_write(phydev, MDIO_DEVAD_NONE, 4, 0x11e1);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x0, 0x1000);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa00d);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x1870);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa00e);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x2600);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa003);
+        	phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0xf5);
+	}
+	if(phydev->phy_id == 0x4f51e899)
+	{       if(count == 0){
+        	//	printf("config yt8614\n");
+        		phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa000);
+        		phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x2);
+        		phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x0);
+			count ++;
+		}
+	}
+
 	/* Do we support autonegotiation? */
 	val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);

实际问题排查

问题背景

ls1028使用RGMII网口,PHY芯片用的是yt8521,软件修改之后网卡ping不通

问题总结

KH修改的RCW没有生效,YT8521phy芯片没有输出125M的时钟
KH修改的镜像

U-Boot 2019.10 (Jun 20 2022 - 23:25:05 -0700)

SoC:  LS1028A Rev1.0 (0x870b0110)
Clock Configuration:
       CPU0(A72):1500 MHz  CPU1(A72):1500 MHz
       Bus:      400  MHz  DDR:      1600 MT/s
Reset Configuration Word (RCW):
       00000000: 3c004010 00000030 00000000 00000000  
       00000010: 00000000 018f0000 0030c000 00000000
       00000020: 01e031a0 00002580 00000000 000d925e
       00000030: 00000000 00000050 00000000 00000000
       00000040: 00000000 00000000 00000000 00000000
       00000050: 00000000 00000000 00000000 00000000
       00000060: 00000000 00000000 【040e】7000 00000000
       00000070: eb580000 03000000
Model: Forlinx OK1028A-C Board
Board: LS1028A Rev1.0-RDB, Version: A, boot from eMMC
SERDES1 Reference : Clock1 = 100.00MHz Clock2 = 100.00MHz

问题解决

重新修改RCW、uboot设备树、uboot phy驱动

diff --git a/packages/firmware/OK1028-linux-uboot/arch/arm/dts/fsl-ls1028a-rdb.dts b/packages/firmware/OK1028-linux-uboot/arch/arm/dts/fsl-ls1028a-rdb.dts
index c44e5e49e..1d9ce479e 100644
--- a/packages/firmware/OK1028-linux-uboot/arch/arm/dts/fsl-ls1028a-rdb.dts
+++ b/packages/firmware/OK1028-linux-uboot/arch/arm/dts/fsl-ls1028a-rdb.dts
@@ -110,6 +110,12 @@
        phy-handle = <&rdb_phy0>;
 };
 
+&enetc1 {
+       status = "okay";
+       phy-mode = "rgmii";
+       phy-handle = <&rgm_phy0>;
+};
+
 &ethsw_ports {
        port@0 {
                status = "okay";
@@ -138,6 +144,9 @@
        rdb_phy0: phy@2 {
                reg = <2>;
        };
+         rgm_phy0: phy@4 {
+                reg = <4>;
+        };
 
        sw_phy0: phy@8 {
                reg = <0x08>;
diff --git 
a/packages/firmware/OK1028-linux-uboot/drivers/net/phy/phy.c b/packages/firmware/OK1028-linux-uboot/drivers/net/phy/phy.c
index 92ad5bf17..8b1bb46ca 100644
--- a/packages/firmware/OK1028-linux-uboot/drivers/net/phy/phy.c
+++ b/packages/firmware/OK1028-linux-uboot/drivers/net/phy/phy.c
@@ -399,6 +399,9 @@ int genphy_config(struct phy_device *phydev)
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x2600);
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa003);
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0xf5);
+               
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa012);
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x78);
        }
        if(phydev->phy_id == 0x4f51e899)
        {       if(count == 0){
Diff--git a/packages/firmware/rcw/ls1028ardb/R_SQPP_0x85bb/rcw_1500_gpu600.rcw b/packages/firmware/rcw/ls1028ardb/R_SQPP_0x85bb/rcw_1500_gpu600.rcw
index b49931a04..62d3b846c 100644
--- a/packages/firmware/rcw/ls1028ardb/R_SQPP_0x85bb/rcw_1500_gpu600.rcw
+++ b/packages/firmware/rcw/ls1028ardb/R_SQPP_0x85bb/rcw_1500_gpu600.rcw
@@ -30,8 +30,9 @@ IIC5_PMUX=1
 IIC6_PMUX=0
 SPI3_PMUX=0
 CLK_OUT_PMUX=2
-EC1_SAI4_5_PMUX=2
-EC1_SAI3_6_PMUX=1
+EC1_SAI4_5_PMUX=0
+EC1_SAI3_6_PMUX=0
+GTX_CLK125_PMUX=0
 USB3_CLK_FSEL=39
 ENETC_RCW=3
 GTX_CLK125_PMUX=1

问题排查

1、查看RCW值确认相关的引脚复用成功

U-Boot 2019.10 (Jun 29 2022 - 21:49:38 -0700)

SoC:  LS1028A Rev1.0 (0x870b0110)
Clock Configuration:
       CPU0(A72):1500 MHz  CPU1(A72):1500 MHz
       Bus:      400  MHz  DDR:      1600 MT/s
Reset Configuration Word (RCW):
       00000000: 3c004010 00000030 00000000 00000000 //0-15
       00000010: 00000000 018f0000 0030c000 00000000 //16-31
       00000020: 01e031a0 00002580 00000000 00008296 //32-47
       00000030: 00000000 00000050 00000000 00000000//48-63
       00000040: 00000000 00000000 00000000 00000000//64-79
       00000050: 00000000 00000000 00000000 00000000//80-95
       00000060: 00000000 00000000 [000e]7000 00000000//96-111
       00000070: eb580000 03000000                 //112-119
Model: Forlinx OK1028A-C Board
Board: LS1028A Rev1.0-RDB, Version: A, boot from eMMC

分析:
RGMII用到的引脚需要复用为相关功能,对应的RCW如下所示:

GTX_CLK125_PMUX=0
EC1_SAI3_6_PMUX=0
EC1_SAI4_5_PMUX=0

在这里插入图片描述
EC1_SAI4_5_PMUX RCW字段的功能
在这里插入图片描述
EC1_SAI3_6_PMUX RCW字段的功能
在这里插入图片描述
GTX_CLK125_PMUX RCW字段功能
在这里插入图片描述

可以通过计算RCW的值来看修改是否生效,通过上图可以知道EC1_SAI4_5_PMUX字段处于RCW的第833-835位,EC1_SAI3_6_PMUX字段处于 第836-838位,GTX_CLK125_PMUX字段处于860-861位。RCW每一行前面显示的就是RCW的内存地址,每个内存地址中存储着8位数据。
先计算833-835位处于RCW内存地址中的位置:833/8=104,那么我们取出地址104,105的数据

00000060: 00000000 00000000 [000e]7000 00000000 //96-111

因为RCW是16进制显示的,则将000e化为二进制为:
0000 0000 0000 1110
接下来需要知道833-835处于上面的那两位,首先确认上面的数据第一位处于RCW的第几位:104*8=832,则我们可以知道上面的数据的对应关系为:

数据00000000
位数832833834835836837838839

可以看到833-835位为0,即EC1_SAI4_5_PMUX被复用为EC1相关引脚功能,同理可以校验其他RCW是否复用成功。

2、读MDIO总线

可以读到MDIO总线上的phy芯片说明MDIO总线挂载了PHY芯片

=> mdio list
enetc-0:
emdio-3:
2 - Generic PHY <--> enetc-0
4 - Generic PHY <--> enetc-1
8 - Generic PHY <--> swp0
9 - Generic PHY <--> swp1
a - Generic PHY <--> swp2
b - Generic PHY <--> swp3
enetc-2:
felix-switch:

3、读PHY ID

PHY芯片的0x02、0x03寄存器是PHY ID寄存器,查看跟芯片手册是否一致,若不一致可能是mdio通讯有问题。一致说明mdio总线没有问题

=> mdio read 4 0x02
Reading from bus emdio-3
PHY at address 4:
2 - 0x0
=> mdio read 4 0x03
Reading from bus emdio-3
PHY at address 4:
3 - 0x11a

在这里插入图片描述

4、查看link装态

读取01控制寄存器,看⾃协商是否开着。插⽹线之前读取状态寄存器, 插⽹
线之后再读取状态寄存器。看前后值是否有变化,没有变化就说明link 不上,硬件可能存在问题,link过程是phy 和⽹线之间的协商

=>mdio read 4 0x01            //插着网线
Reading from bus emdio-3
PHY at address 4:
1 - 0x796d
=> mdio read 4 0x01          //拔掉网线
Reading from bus emdio-3
PHY at address 4:
1 - 0x7949
=> mdio read 4 0x01
Reading from bus emdio-3
PHY at address 4:
1 - 0x796d

通过以上排查都是没有问题的,用示波器测量信号,发现PHY芯片的TX_CLK(输出信号时钟)、EC2_GTX_CLK125(用于phy提供时钟给MAC)都没有输出,定位到问题在于PHY没有输出

5、通过示波器测量发现Yt8521phy芯片的TX_CLK没有时钟输出

在uboot源码中修改寄存器之后,修改路径:packages/firmware/OK1028-linux-uboot/drivers/net/phy/phy.c
进入uboot读取寄存器可以看到寄存器值修改成功,未修改之前是0x48

=> mdio write 4 0x1e 0xa012
=> mdio read 4 0x1f
 Reading from bus emdio-3
PHY at address 4: 
31 - 0x78 
硬件原理图

在这里插入图片描述
未修改之前用示波器测量EC2_GTX_CLK是没有信号的
在这里插入图片描述
修改完之后测试就有信号了
在这里插入图片描述
客户底板上是没有接EC2_GTX_CLK125信号的
在这里插入图片描述
需要飞线接到RGMIIPHY芯片的CLKOUT,用于phy提供时钟给MAC
在这里插入图片描述

未修改前测试时钟是没有输出的,如下所示:
在这里插入图片描述
修改之后就有时钟输出了
在这里插入图片描述

6、验证测试

进入系统进行ping测试,发现千兆是ping不通的(可能是跟pcb、串联电阻有关系),降速到百兆就可以ping通了

root@forlinx:~# ethtool -s eno1  speed 100 duplex full autoneg off
root@forlinx:~# ethtool eno1
Settings for eno1:
        Supported ports: [ TP MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  100baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 100Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 4
        Transceiver: internal
        Auto-negotiation: off
        Link detected: yes
root@forlinx:~# ping 172.16.0.28
PING 172.16.0.28 (172.16.0.28) 56(84) bytes of data.
64 bytes from 172.16.0.28: icmp_seq=1 ttl=128 time=0.475 ms
64 bytes from 172.16.0.28: icmp_seq=2 ttl=128 time=0.315 ms
^C
--- 172.16.0.28 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1008ms
rtt min/avg/max/mdev = 0.315/0.395/0.475/0.080 ms
root@forlinx:~# ping 172.16.0.28
PING 172.16.0.28 (172.16.0.28) 56(84) bytes of data.
64 bytes from 172.16.0.28: icmp_seq=1 ttl=128 time=0.256 ms
64 bytes from 172.16.0.28: icmp_seq=2 ttl=128 time=0.328 ms
64 bytes from 172.16.0.28: icmp_seq=3 ttl=128 time=0.258 ms
64 bytes from 172.16.0.28: icmp_seq=4 ttl=128 time=0.245 ms
64 bytes from 172.16.0.28: icmp_seq=5 ttl=128 time=0.256 ms
64 bytes from 172.16.0.28: icmp_seq=6 ttl=128 time=0.338 ms
64 bytes from 172.16.0.28: icmp_seq=7 ttl=128 time=0.410 ms
64 bytes from 172.16.0.28: icmp_seq=8 ttl=128 time=0.339 ms
64 bytes from 172.16.0.28: icmp_seq=9 ttl=128 time=0.299 ms
64 bytes from 172.16.0.28: icmp_seq=10 ttl=128 time=0.317 ms
64 bytes from 172.16.0.28: icmp_seq=11 ttl=128 time=0.238 ms
64 bytes from 172.16.0.28: icmp_seq=12 ttl=128 time=0.236 ms
64 bytes from 172.16.0.28: icmp_seq=13 ttl=128 time=0.433 ms
64 bytes from 172.16.0.28: icmp_seq=14 ttl=128 time=0.398 ms
64 bytes from 172.16.0.28: icmp_seq=15 ttl=128 time=0.305 ms
64 bytes from 172.16.0.28: icmp_seq=16 ttl=128 time=0.227 ms
64 bytes from 172.16.0.28: icmp_seq=17 ttl=128 time=0.332 ms
64 bytes from 172.16.0.28: icmp_seq=18 ttl=128 time=0.278 ms
64 bytes from 172.16.0.28: icmp_seq=19 ttl=128 time=0.269 ms
64 bytes from 172.16.0.28: icmp_seq=20 ttl=128 time=0.332 ms
64 bytes from 172.16.0.28: icmp_seq=21 ttl=128 time=0.330 ms
64 bytes from 172.16.0.28: icmp_seq=22 ttl=128 time=0.394 ms
64 bytes from 172.16.0.28: icmp_seq=23 ttl=128 time=0.288 ms
64 bytes from 172.16.0.28: icmp_seq=24 ttl=128 time=0.275 ms
64 bytes from 172.16.0.28: icmp_seq=25 ttl=128 time=0.275 ms
64 bytes from 172.16.0.28: icmp_seq=26 ttl=128 time=0.314 ms
64 bytes from 172.16.0.28: icmp_seq=27 ttl=128 time=0.274 ms
64 bytes from 172.16.0.28: icmp_seq=28 ttl=128 time=0.304 ms
64 bytes from 172.16.0.28: icmp_seq=29 ttl=128 time=0.226 ms
64 bytes from 172.16.0.28: icmp_seq=30 ttl=128 time=0.413 ms
^C
--- 172.16.0.28 ping statistics ---
30 packets transmitted, 30 received, 0% packet loss, time 29701ms
rtt min/avg/max/mdev = 0.226/0.306/0.433/0.058 ms
root@forlinx:~# ping 172.16.0.28
PING 172.16.0.28 (172.16.0.28) 56(84) bytes of data.
64 bytes from 172.16.0.28: icmp_seq=1 ttl=128 time=0.227 ms
64 bytes from 172.16.0.28: icmp_seq=2 ttl=128 time=0.337 ms
^C
--- 172.16.0.28 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1014ms
rtt min/avg/max/mdev = 0.227/0.282/0.337/0.055 ms
root@forlinx:~# ethtool -s eno1  speed 1000 duplex full autoneg off
root@forlinx:~# ethtool eno1
Settings for eno1:
        Supported ports: [ TP MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 1000Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 4
        Transceiver: internal
        Auto-negotiation: off
        Link detected: no
root@forlinx:~# ping 172.16.0.28
PING 172.16.0.28 (172.16.0.28) 56(84) bytes of data.
From 172.16.0.128 icmp_seq=1 Destination Host Unreachable
From 172.16.0.128 icmp_seq=2 Destination Host Unreachable
From 172.16.0.128 icmp_seq=3 Destination Host Unreachable
From 172.16.0.128 icmp_seq=4 Destination Host Unreachable
From 172.16.0.128 icmp_seq=5 Destination Host Unreachable
From 172.16.0.128 icmp_seq=6 Destination Host Unreachable
From 172.16.0.128 icmp_seq=7 Destination Host Unreachable
From 172.16.0.128 icmp_seq=8 Destination Host Unreachable
From 172.16.0.128 icmp_seq=9 Destination Host Unreachable
From 172.16.0.128 icmp_seq=10 Destination Host Unreachable
From 172.16.0.128 icmp_seq=11 Destination Host Unreachable
From 172.16.0.128 icmp_seq=12 Destination Host Unreachable
From 172.16.0.128 icmp_seq=13 Destination Host Unreachable
From 172.16.0.128 icmp_seq=14 Destination Host Unreachable
From 172.16.0.128 icmp_seq=15 Destination Host Unreachable
From 172.16.0.128 icmp_seq=16 Destination Host Unreachable
From 172.16.0.128 icmp_seq=17 Destination Host Unreachable
From 172.16.0.128 icmp_seq=18 Destination Host Unreachable
From 172.16.0.128 icmp_seq=20 Destination Host Unreachable
From 172.16.0.128 icmp_seq=21 Destination Host Unreachable
From 172.16.0.128 icmp_seq=22 Destination Host Unreachable
From 172.16.0.128 icmp_seq=23 Destination Host Unreachable
From 172.16.0.128 icmp_seq=24 Destination Host Unreachable
From 172.16.0.128 icmp_seq=26 Destination Host Unreachable
From 172.16.0.128 icmp_seq=27 Destination Host Unreachable
From 172.16.0.128 icmp_seq=28 Destination Host Unreachable
From 172.16.0.128 icmp_seq=29 Destination Host Unreachable
From 172.16.0.128 icmp_seq=30 Destination Host Unreachable
From 172.16.0.128 icmp_seq=31 Destination Host Unreachable
From 172.16.0.128 icmp_seq=32 Destination Host Unreachable
From 172.16.0.128 icmp_seq=33 Destination Host Unreachable
From 172.16.0.128 icmp_seq=35 Destination Host Unreachable
From 172.16.0.128 icmp_seq=36 Destination Host Unreachable
From 172.16.0.128 icmp_seq=37 Destination Host Unreachable
From 172.16.0.128 icmp_seq=38 Destination Host Unreachable
From 172.16.0.128 icmp_seq=39 Destination Host Unreachable
From 172.16.0.128 icmp_seq=41 Destination Host Unreachable
From 172.16.0.128 icmp_seq=42 Destination Host Unreachable
^C
--- 172.16.0.28 ping statistics ---
45 packets transmitted, 0 received, +38 errors, 100% packet loss, time 45046ms
pipe 4

其他

PHY寄存器的修改

在uboot的phy驱动里面

phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa012);
phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x78);

PHY芯片手册寄存器表SyncE_CFG寄存器用于配置phy输出125M的clock,0x78换算成二进制为0111 1000,对应到寄存器相应位即如下所示:

寄存器位15:765432:10
对应值011110 00

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐