ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

RK3568外挂YT9215交换机:从灯亮到ping通的DSA驱动移植与调试全记录

RK3568外挂YT9215交换机:从灯亮到ping通的DSA驱动移植与调试全记录 简介RK3568基于ARM Cortex-A55架构广泛用于智能盒子、工业控制和网络设备而YT9215承担网络数据包交换转发任务两者协同调试是嵌入式网络方向的高频难点。驱动作为操作系统与硬件设备之间的桥梁在RK3568平台上适配YT9215时需要完成硬件接口分析、驱动框架选择、代码编写、设备树定义及注册测试等一连串环节。这份压缩包正好聚焦于此共2个文件分别为一个C源文件和一个头文件整体仅4KB虽然体量精简但已覆盖YT9215驱动最核心的初始化和数据交互逻辑便于快速查阅寄存器配置、读写函数及中断处理等实现内容。已有218人学习浏览适合正在RK3568平台进行交换机芯片驱动适配、内核移植或底层调试的软硬件工程师参考。通过阅读代码可直观了解物理接口匹配、设备树节点定义、总线注册流程等要点并对照GPIO、SPI、I2C等常见接口的适配思路对排查网口不识别、数据丢包或转发异常等现实问题能提供具体而直接的代码级借鉴。1. RK3568 外挂 YT9215单 GMAC 撑起四个 LAN 口调试却从灯亮翻车到 ping 不通做一台四口千兆边缘网关主控选了 RK3568原本以为两路 GMAC 怎么都够用结果面对“4 个 LAN 口 1 个 WAN 口”的产品定义时SoC 自带 MAC 明显不够。于是方案变成RK3568 的 GMAC0 通过 RGMII 上联一颗 YT9215 交换机芯片由它扩展出 4 个 10/100/1000M 自适应 LAN 口。第一次上电看着交换机指示灯全亮、电脑显示“已连接”但 RK3568 就是收不到也不回任何数据。抓包全是 PC 发出的 ICMP 请求一个应答都没有。问题的根源在于 YT9215 不是普通 PHY它内部有完整的交换核和 VLAN 转发逻辑要让 Linux 真正把它“用”起来必须先完成芯片识别、端口初始化和 CPU 口 tag 数据的解析。这篇笔记就从硬件链路、MDIO 识别、DSA 驱动移植一路写到排错方法覆盖这套方案从“灯亮”到“能出货”的完整路径。2. 先认清 YT9215 在整个链路中的角色它是个交换机不是一个 PHY2.1 为什么 RK3568 要外挂交换机芯片GMAC 数量与成本博弈RK3568 自带的 GMAC 数量并不少常见型号里有两路 GMAC其中一路还可以走 RGMII 接口理论上主板可以轻松做成双网口。但一旦产品定义变成“4 个千兆 LAN”双 GMAC 就不够用了。有人会想USB 转千兆网卡行不行从硬件成本看一颗 USB 网卡芯片加上接口、电源、驱动适配总成本往往高于一颗集成度高的交换机芯片从软件看USB 网卡的驱动栈长、中断与延迟不稳定做二层隔离和 VLAN 也吃力从功耗和可靠性看USB 网卡在长期满负载打流时更容易出现掉线。所以工业网关、路由器、边缘计算盒子里最常见做法是“SoC GMAC 交换芯片”由交换芯片把单路 RGMII 扩展成多个物理网口。选 YT9215 这类芯片的理由也很直接它把多个 PHY、交换核心、端口缓存集成在一颗芯片里板级设计省事BOM 成本低而且通过 MDIO 管理接口可以复用 SoC 自带的 MDIO 总线不需要额外占用 I2C 或 SPI。要注意的是这颗芯片的定位是“带管理功能的二层交换”不是普通 PHY。普通 PHY 只负责把 MAC 的 MII 信号变成双绞线上的差分信号而 YT9215 会对以太网帧做查表、转发、VLAN 标记和端口隔离。这意味着驱动侧要处理的不只是“link up 了没有”还有“这个帧应该从哪个口出去”“这个口要不要打 tag”。2.2 YT9215 的调试入口上行 RGMII、下行多口 PHY、MDIO 管理通路拿到一块 RK3568 YT9215 的板卡先看原理图不要急着写代码。YT9215 的接口可以分成三组第一组是上行口通常通过 RGMII 接到 RK3568 的 GMAC0包含 TX_CLK、TX_CTL、TXD[3:0]、RX_CLK、RX_CTL、RXD[3:0] 这 12 根信号线第二组是下行 LAN 口由芯片内部集成 PHY 直接引出到网口变压器和 RJ45第三组是管理接口YT9215 一般把 MDIO 作为主要配置通道主控通过 MDC/MDIO 两根线读写芯片内部的交换寄存器。调试入口就藏在这三组信号里。上行 RGMII 提供的是数据面通路下行 PHY 提供的是物理层状态而管理接口才是你“指挥”交换芯片怎么工作的唯一通道。很多第一次调交换机芯片的人习惯性把 YT9215 当成一个多口 PHY拿到板子先去找每个 PHY 的地址然后打开 ethtool 看 link。但实际上YT9215 的寄存器空间比普通 PHY 大得多普通 PHY 只有 32 个寄存器且分 basic/status 等标准页而交换机芯片往往有数百个寄存器甚至通过内部间接寻址去访问端口成员表、VLAN 表、镜像控制等。所以拿到 datasheet我一般会按这个顺序看先是芯片的 MDIO 地址怎么由引脚决定再找到 ID 寄存器确认芯片是否响应接着找端口映射表port index 对应哪个物理口最后才看 VLAN 和端口隔离寄存器。2.3 数据流不能用 PHY 的思路理解CPU 口的 tag 是打通 Linux 的关键PHY 芯片的数据面是透明的MAC 发什么帧PHY 就原样送到网线上。YT9215 不一样LAN 口收到的帧会先进入交换核心交换核心根据目的 MAC、VLAN、端口转发规则做决策如果目的 MAC 在另一个 LAN 口就直接在芯片内部转发如果这个帧是要发给 CPU 的交换芯片会把它打上一个内部 tag然后从 RGMII 上行口送到 RK3568 的 GMAC。这个 tag 是整个调试中最容易忽略的东西。它通常在标准以太网头之后、源 MAC 之前插入几个字节或者在 VLAN tag 位置使用私有 ethertype。RK3568 的 GMAC 只是被动接收 RGMII 上的所有数据它不知道这个帧来自 YT9215 的哪一个口。如果 Linux 这侧没有对应解析逻辑这个带 tag 的帧会被当成普通网络包送进协议栈表现就是你抓包能看到一个陌生的以太类型、协议栈不认于是 ping 不通。所以驱动必须完成两件事一是把 YT9215 的各个 LAN 口注册成独立的 Linux 网络设备二是正确解析 CPU 口 tag让从 lan1 进来的包出现在 lan1 接口上。DSADistributed Switch Architecture框架就是干这个的下文所有驱动移植都围绕它展开。3. 最小可跑通的初始化硬件检查、设备树挂载与 MDIO 识别3.1 上电先别写驱动供电、时钟、复位三步检查清单移植驱动之前先用示波器和原理图确认 YT9215 的硬件环境是健康的。这个步骤省了后面所有软件排查都会被“寄存器读不到”带偏。我一般按下面这张表过一遍。检查项检查方法合格特征电源示波器测 YT9215 各路电源引脚电压与 datasheet 要求偏差在 5% 以内纹波不明显系统时钟测晶振两脚或时钟输出引脚频率符合 datasheet 要求常见为 25MHz偏差在可接受范围内复位时序测复位引脚电平变化复位释放时间晚于电源稳定满足最小复位脉宽MDIO 地址测地址设置引脚的上拉/下拉电平平组合与设备树中 reg 值一致RGMII 信号测 TX_CLK/RX_CLK 频率千兆下时钟应稳定在 125MHz重点说两个最容易翻车的点。第一个是复位很多交换机芯片的复位引脚是低有效并且要求电源稳定后再拉高。如果复位由 GPIO 控制GPIO 默认状态是输出高但板子加了 RC 延时导致上电后芯片长时间保持复位MDIO 自然没有应答。第二个是时钟RGMII 的 RX_CLK 在空闲时可能不连续用万用表测不出来必须用示波器或逻辑分析仪看。如果 125MHz 时钟根本没起来后面读 ID 全 F 一点都不奇怪。3.2 设备树最小改动把 YT9215 挂到 GMAC0 的 MDIO 总线上确认硬件没问题后先做最小设备树改动目标只有一个让 Linux 能在 MDIO 总线上看到 YT9215。下面是 RK3568 设备树中最常见形态以 GMAC0 为例。gmac0 { status okay; phy-mode rgmii-id; // 收发时钟延时模式后文排错会细说 pinctrl-names default; pinctrl-0 gmac0_rgmii_pins; mdio { #address-cells 1; #size-cells 0; switch1 { compatible yt9215-switch; // 必须与驱动 match 表一致 reg 1; // MDIO 地址由硬件引脚决定 reset-gpios gpio0 11 GPIO_ACTIVE_LOW; // 低有效复位 }; }; };这段设备树的逻辑是先使能 GMAC0并把 phy-mode 定为 rgmii-id意思是让 MAC 侧同时给 TX 和 RX 时钟加延时。mdio 子节点沿用 stmmac 驱动默认创建的 MDIO 总线在这条总线上注册一个地址为 1 的设备。switch 节点里最重要的是 compatible 和 reg 两个属性前者决定内核用哪个驱动来匹配它后者必须和原理图上 MDIO 地址设置引脚一致。参数上要注意几个细节。reg 1不是随便写的要回到原理图确认 YT9215 的 MDIO 地址引脚。很多交换机芯片支持 8 个甚至 32 个地址地址选错的表现和硬件没上电几乎一样。reset-gpios如果不确定极性先用示波器看复位引脚的默认电平如果默认是低说明芯片一直被复位GPIO 描述必须能让驱动拉高释放如果默认是高芯片已经在工作可以不配这个属性。我的习惯是即使板子默认不复位也把它写进去方便驱动里做严格的上电时序。3.3 用 mdio-tools 读 ID 寄存器确认 YT9215 在总线上有响应设备树编译通过、内核起来后别急着灌驱动先在用户态确认芯片是否响应。mdio-tools 是嵌入式 Linux 里很常用的 MDIO 用户态读写工具如果你用的 SDK 里没有一般也可以从包管理器装或者交叉编译。# 先看内核枚举出了哪些 MDIO 设备 ls /sys/bus/mdio_bus/devices/ # 读标准 PHY ID 寄存器地址 2 和 3设备地址 1 mdio read 1 2 mdio read 1 3 # 读控制寄存器确认 bit15 reset 是否被自动清掉 mdio read 1 0先说这条命令怎么看。mdio read 1 2中1 是要访问的 MDIO 设备地址2 是寄存器地址。IEEE 802.3 规定 PHY ID 高 16 位在寄存器 2低 16 位在寄存器 3绝大多数交换芯片也会遵循这个布局用来暴露芯片识别号。如果两条命令都返回 0xffff说明总线上没有设备应答如果返回 0x0000说明设备有应答但 ID 读取逻辑不对或者芯片还处于复位状态。只有返回值与 datasheet 上的 ID 相符才能进入下一步。这一步还能确认一些隐蔽问题。比如 MDC 时钟有没有正常工作总线上挂 MDIO 设备但主控不产生 MDC 时钟地址引脚悬空导致地址漂移都会表现为全 F。我遇到一次很典型的案例设备树里 gmac0 没有设 status okayMDIO 总线根本没有使能但用户态 mdio 工具照样能执行只是所有读取都返回错误。所以读之前先ls /sys/bus/mdio_bus/devices/看总线节点是否存在能少走很多弯路。4. 把 YT9215 接进 Linux 协议栈DSA 驱动移植与端口转发验证4.1 内核里有没有现成驱动先 grep 再决定造轮子拿到一颗交换芯片第一件事不是从零写驱动而是确认内核或 SDK 里有没有现成支持。在 Linux 内核源码目录下执行# 查 DSA 驱动目录和 PHY 驱动目录 grep -rn yt9215 drivers/net/dsa/ drivers/net/phy/ # 查设备树中是否有已知 compatible grep -rn yt9215 arch/arm/boot/dts/ arch/arm64/boot/dts/如果输出为空说明手头这套内核没有支持需要自己移植。此时先翻 vendor 提供的 SDK很多方案商会在 SDK 里附带交换芯片驱动但目录不一定在内核标准位置可能叫drivers/net/dsa/之外或者干脆以 patch 形式提供。用find . -iname *yt9215* -o -iname *yt*switch*全仓库搜一遍比盲目写驱动快得多。如果 SDK 也找不到就得评估工作量。YT9215 这类芯片要接入 DSA至少需要实现 tag 协议解析、端口初始化、PHY 读写三个模块。若你手头有 datasheet 和寄存器手册建议按 DSA 框架移植若 datasheet 缺失只靠逆向我建议先考虑用户态配置方案不要硬刚驱动。4.2 从 vendor SDK 搬运 DSA 驱动不仅要复制 .c还要改 Kconfig、Makefile 和设备树假设你从 SDK 拿到了 YT9215 的 DSA 驱动源码常见做法是把yt9215.c放进drivers/net/dsa/然后在 Kconfig 和 Makefile 里挂上。Kconfig 片段长这样config NET_DSA_YT9215 tristate YT9215 5-port ethernet switch support depends on NET_DSA help This enables support for YT9215 switch chip.Makefile 加一行obj-$(CONFIG_NET_DSA_YT9215) yt9215.o这些改完后最重要的一步是确认设备树里的 compatible 与驱动中的 of_match_table 严格一致。很多移植失败都发生在“驱动明明编译进去了但 probe 没有跑”。我见过 A同学把设备树写成yt9215驱动里写yt9215-switch结果设备树匹配不上内核日志里连 failed 都不报只剩下一个孤零零的 mdio 设备。驱动注册的核心代码由几个回调函数构成下面是一个精简骨架static const struct dsa_switch_ops yt9215_ops { .get_tag_protocol yt9215_get_tag_protocol, .setup yt9215_setup, .phy_read yt9215_phy_read, .phy_write yt9215_phy_write, }; static const struct of_device_id yt9215_of_match[] { { .compatible yt9215-switch }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, yt9215_of_match); static struct mdio_driver yt9215_mdio_driver { .probe yt9215_probe, .remove yt9215_remove, .mdio-driver { .driver.name yt9215, .of_match_table yt9215_of_match }, }; module_mdio_driver(yt9215_mdio_driver);这段代码先定义 dsa_switch_ops它决定 DSA 框架怎么与芯片交互再定义 of_match_table用于匹配设备树节点。注意module_mdio_driver结尾DSA 驱动通常会注册成 MDIO 总线驱动因为交换芯片挂在 MDIO 总线上。.setup回调里一般做端口数量声明、VLAN 初始化等.phy_read和.phy_write用于让 Linux 通过交换芯片的寄存器空间访问内部 PHY很多交换芯片的内部 PHY 不直接暴露标准 MDIO 地址必须由驱动做地址映射。我的建议是第一次移植驱动setup 里千万别一次性把所有 VLAN、镜像、端口隔离配置全写上。先用最小配置——把 4 个 LAN 口全部按独立 DSA 端口注册CPU 口配好 tag 协议其余功能等跑通转发再逐步加。这样出现问题时比较容易定位是芯片问题还是驱动配置问题。4.3 五个端口在 Linux 里应该长什么样DSA 驱动 probe 成功后内核会动态创建网络接口。预期ip link输出长这样1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 ... 2: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc ... 3: lan1: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc ... 4: lan2: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc ... 5: lan3: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc ... 6: lan4: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc ...其中 eth0 是 RK3568 自己的 GMAC0DSA 把它作为 CPU 口lan1 到 lan4 是 DSA 驱动从 YT9215 注册出来的用户端口。这里的细节是lan1 和 eth0 并不是简单的“下级设备”关系DSA 驱动会在 eth0 上截获网络包剥离或插入 tag再根据 tag 决定把帧派发给 lan1 还是其他端口。如果ip link里只有 eth0看不到 lan1-lan4优先查 dmesg看有没有“DSA: port 0 probe failed”之类的日志。常见原因是驱动 setup 里端口数量声明不对或者设备树里没有定义完整 ports 节点。如果端口出来了但全是 DOWN常是 PHY 探测失败这个问题在第 5 章专门讲。4.4 第一个转发测试把四个 LAN 口桥接起来从 PC 去 ping RK3568端口注册成功后不要急着配 VLAN先把最基础的二层连通性打通。我的做法是建一个网桥把 CPU 口和四个 LAN 口都加进去然后给网桥配置 IP。# 创建网桥 ip link add name br0 type bridge # 把 CPU 口和四个 LAN 口加进网桥 ip link set eth0 master br0 ip link set lan1 master br0 ip link set lan2 master br0 ip link set lan3 master br0 ip link set lan4 master br0 # 给网桥配 IP 并启用 ip addr add 192.168.1.1/24 dev br0 ip link set br0 up这段命令的逻辑是通过网桥把所有端口置于同一个二层转发域然后把网关 IP 放到 br0 上。PC 接在 lan1 上 ping 192.168.1.1 时请求帧从 lan1 进入 YT9215交换核转发到 CPU 口DSA 驱动剥掉 tag 后送入协议栈网桥设备收到请求应答帧再走反向路径。这样测通了说明从物理层到 DSA tag 解析、再到协议栈收发整条链路是通的。这里有个容易忽略的参数ip link set br0 up后如果四个 LAN 口还都是 DOWN应该是驱动初始化没把内部 PHY 拉起来。正常情况插入网线后lan1 应该自动变成 UP。如果还是 DOWN不要急着查网桥先用 ethtool lan1 看链路状态和速率协商结果。另外调试阶段不建议开 STPDSA 端口的 learning/stp state 保持默认 forwarding 即可等组网复杂了再考虑。5. YT9215 调试避坑寄存器读不到、转发不通、CPU 口丢包的全排查5.1 ID 寄存器读出来全是 0xffffMDIO 地址和复位时序最可疑现象执行mdio read 1 2或mdio read 1 3返回值始终是 0xffff内核日志里也看不到任何 YT9215 probe 信息。原因最常见的有三个。第一MDIO 地址设置引脚的上拉/下拉电阻与设备树 reg 不一致总线请求发给了错误的地址第二复位引脚一直被拉在有效电平芯片处于复位状态MDIO 接口完全不工作第三GMAC 的 MDIO 控制器没有工作比如 gmac0 没有使能或者 MDC 时钟没有输出。解决先用示波器测复位引脚的静态电平确认是不是一直低。如果一直低检查复位 GPIO 的默认输出和 device tree 中的极性描述。接着测 MDC 引脚在 idle 状态有没有时钟跳变如果完全没有回去查 gmac0 是否 status okay以及 pinctrl 是否把 MDC/MDIO 两个引脚复用对了。最后再检查地址引脚把原理图上所有设置 MDIO 地址的引脚电平列出来和 reg 逐位比对。我的习惯是把地址引脚做成 4 位拨码或者上下拉电阻排调试时方便切换。5.2 LAN 口物理层 up 了但 DSA 端口一直 DOWN现象YT9215 内部 PHY 的 link 状态正常网口指示灯常亮但 Linux 里lan1状态显示 DOWNethtool lan1 也看不到速率。原因DSA 驱动的 phy_read/phy_write 回调没有正确访问到内部 PHY 的寄存器。很多交换芯片的内部 PHY 并不是标准 MDIO 地址直连而是通过交换芯片的间接访问寄存器映射。驱动 setup 里如果没初始化这个映射Linux 尝试读 PHY ID 时会失败端口自然无法 up。解决先确认驱动里是否实现了 phy_read/phy_write且内部 PHY 地址映射正确。可以在驱动 probe 时加一段调试打印读一下 PHY ID 寄存器的值看返回是否正常。如果驱动还没有实现映射最快的验证办法是在用户态通过交换芯片的全局管理寄存器去读 PHY 状态确认 PHY 有没有真的 link。不要看到“灯亮”就认为 PHY 层面没事很多交换芯片的 LED 是可以通过寄存器强制拉亮的。5.3 整体转发通了但 LAN 口之间互访不通现象PC1 接 lan1 能 ping 通 RK3568但 PC1 访问接在 lan2 上的 PC2 不通PC2 能 ping 通 RK3568说明 CPU 口通路没问题。原因YT9215 的端口隔离或者 VLAN 成员配置没有把 lan1 和 lan2 放进同一个转发域。很多交换芯片默认开启端口隔离所有端口只能和 CPU 口通信端口之间不能互访这是为了安全隔离而设计并不是 bug。解决把 lan1、lan2、lan3、lan4 加入同一个 VLAN 的成员表。通常做法是这些端口设为同一 VLAN 的 untagged 成员PVID 设为该 VLAN IDCPU 口设为该 VLAN 的 tagged 成员保证上行帧带 VLAN tag 送到 CPU。具体寄存器操作要看 datasheet 的 VLAN 表和端口成员表。如果驱动已经封装了 API可以在 setup 里配置如果驱动没做可以先通过用户态 mdio 工具写寄存器验证确认转发正常后再补进驱动。5.4 RGMII 时钟延时两边都加CPU 口丢包、CRC error 暴涨现象能通但一打流就丢包ethtool -S eth0里 rx_crc_errors 或 tx_errors 数值持续增长抓包看到大量错帧。原因RGMII 协议要求 TX 和 RX 时钟相对数据有约 2ns 的偏移MAC 和 PHY 侧必须且只能有一侧加这个 delay。如果 RK3568 的 gmac0 配了rgmii-idMAC 侧加 delay而 YT9215 的寄存器里也开了内部 delay两侧延时叠加采样点正好落在数据跳变沿附近导致收发不稳定。这是 RGMII 调试里最经典的翻车点。解决把 phy-mode 从rgmii-id依次改为rgmii、rgmii-txid、rgmii-rxid测试。每改一次重启网络并用 iperf3 打流看丢包。更准确的办法是看 datasheet 里 YT9215 的 RGMII delay 控制寄存器默认值是开还是关然后与 RK3568 侧的配置配合起来保证链路中总共只有一侧加 delay。我踩过这个坑之后调试任何新板卡都会先用rgmii模式测一遍再决定要不要加延时而不是默认用rgmii-id。5.5 配置 VLAN 后整个管理网络失联连 RK3568 都 ping 不通现象按文档配完 VLAN保存配置并重启网络后原来还能通的 RK3568 突然完全失联串口里看 eth0 是 UP但 PC 无论接哪个 LAN 口都 ping 不通 192.168.1.1。原因CPU 口被错误地设置成了 untagged 成员或者 CPU 口的 PVID 被改了。CPU 口发出的管理帧如果不带 VLAN tag交换芯片查 VLAN 表时发现该 VLAN 没有对应端口成员直接把帧丢弃从 LAN 口进来到 CPU 的帧也会因为入口 PVID 不对被丢。这相当于自己把管理通道切断了。解决先通过串口把 VLAN 配置脚本回滚让设备恢复到刚才还能通的基线。然后检查配置CPU 口必须设为 tagged 成员LAN 口设为 untagged 成员且各 LAN 口的 PVID 与业务 VLAN 一致。这里有一个排查顺序不要一上来就怀疑驱动 bug先画一张 VLAN/端口成员表把每个端口是 tagged 还是 untagged、PVID 是多少列出来对照寄存器配置一步步查。管理面失联这类问题九成是配置逻辑错误不是芯片坏了。6. 从“能通”到“能出货”吞吐验证、统计排查和寄存器基线备份6.1 用 iperf3 做双方向吞吐摸底调试到这一步基本转发已经通了但能不能稳定跑满千兆还需要打流验证。我一般会在 PC 上跑 iperf3 服务端在板卡上跑客户端# 板卡端连打 30 秒 iperf3 -c 192.168.1.100 -t 30 # 反向打流测对向吞吐 iperf3 -c 192.168.1.100 -t 30 -R # 多线程打流模拟多连接场景 iperf3 -c 192.168.1.100 -t 30 -P 4单线程 iperf3 只能测出单流吞吐很多嵌入式平台单线程到不了 940Mbps瓶颈可能在 CPU 中断处理-P 4多线程才能把多核能力压出来。如果多线程能跑满但单线程跑不满要考虑调整 GMAC 的中断绑核和 NAPI 收包而不是交换芯片的问题。6.2 通过 ethtool -S 判断丢包到底发生在哪一段打流有丢包时不要急着改寄存器先用计数定位方向。ethtool -S eth0能看到 GMAC 的收发包统计ip -s link show lan1能看到 DSA 端口的收发包统计。我会先记录一组不打流时的基线值再打流 30 秒对比 rx_crc_errors、rx_error、tx_dropped、rx_dropped 这几个计数。如果eth0的 rx_crc_errors 涨说明问题出在 RGMII 物理链路优先查时钟延时和 RGMII 信号质量如果eth0正常但lan1的 rx_error 涨说明 YT9215 内部 PHY 收线有问题查网口变压器和 PHY 寄存器里的信号质量指示如果错误计数都不涨但应用层掉数据才需要怀疑驱动协议栈或者缓存。这一步能帮你在“硬件问题”和“软件问题”之间切出明确分界线。6.3 保存一份寄存器基线后续调试的后悔药最后分享一个让后续调试省很多时间的习惯当一组配置验证稳定后把 YT9215 的所有管理寄存器读出来保存一份基线。脚本很简单#!/bin/bash # 保存 YT9215 寄存器基线后续改动配置后可 diff 对比 dev1 logyt9215-regs-$(date %Y%m%d-%H%M).txt i0 while [ $i -lt 256 ]; do val$(mdio read $dev $i) echo reg[$i] $val i$((i 1)) done $log保存后每次调完参数发现行为异常都可以重新 dump 一份和基线 diff马上能看到哪些寄存器被环境或驱动改掉了。之前有块板子在实验室正常、到客户现场就丢包就是靠对比寄存器基线发现 TX delay 配置被另一个驱动模块重写。类似问题如果靠肉眼看代码不知道要排查多久。调试交换机芯片先把硬件确认完再把寄存器基线建立起来后面的驱动移植和 VLAN 配置才能少走弯路。希望这一套流程能帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进