资讯详情

资讯详情

多速率以太网PHY降级协商与MMD寄存器调试

简介RTL8261N简明数据手册面向硬件与软件工程师、网络设备开发与调试人员围绕Realtek集成100M/1G/2.5G/5G/10G以太网收发器的选型与设计展开。资源为英文原版PDF压缩包内共1个文件约4.71MB对应Rev.0.42022年6月版本属于面向开发合作伙伴的受限文档适合方案评估、原理图设计与驱动联调阶段查阅。正文按章节组织涵盖引脚分配与引脚说明、媒体相关接口MDI与XSGMII接口引脚定义、LED引脚功能以及电气规格与机械尺寸等关键参数修订历史记录了0.1首版至0.4版对HSIP引脚编号、AVDDH电压规格与机械尺寸的调整便于核对版本差异。目前已有1805人学习。读者可据此确认各速率模式下的接口定义与设计约束用于核对PCB连线、排查链路协商与信号完整性问题并借助版权与商标声明明确使用边界。1. 两种速率并存一颗 10G PHY 最难处理的部分藏在从 10G 退回 100M 的时候多数人第一次翻 RTL8261N 这类集成 100M/1G/2.5G/5G/10G 的以太网收发器手册都会先去找 10G 那部分——毕竟速率是卖点。但真正把目录读完后会发现一件反直觉的事寄存器描述里最厚的一块不是 10G 通路而是 PMA/PMD、PCS、自协商这三张表MMD 1、MMD 3、MMD 7 加起来占了整个第四章的绝大部分而 10GBASE-R 的 SerDes 页面只有 Page4、Page5 寥寥十几个寄存器。这个篇幅分布本身就是设计意图的说明书让一颗芯片同时掌握五种速率并不难难的是让它在对端只支持 100M 的时候体面地退下去而且退的过程中链路不能撕裂、时钟不能失锁、上层不能以为网线被拔了。搞清楚这条“降级路径”怎么走比记住 10G 有多快有用得多。2. 多速率共存五种速率为什么不能各说各话2.1 速率能力寄存器里的一组位并非一张简单列表在 RTL8261N 的寄存器地图里“我支持哪些速率”这件事被拆成了至少四个地方分别表达这是很多驱动开发者第一次踩坑的来源。PMA/PMD 侧的 MMD 1.0x0004Speed Ability描述的是物理层收发器本身能跑什么MMD 1.0x000BExtended Ability补充标准速率之外的能力而 2.5G 这种在早期标准里没有位置的速率被单独放进 MMD 1.0x00152.5G PMA/PMD Extended Ability。到了 PCS 这一层MMD 3.0x0004 又有一份自己的 Speed Ability。之所以要分四处是因为这四份能力回答的不是同一个问题。PMA/PMD 回答的是“模拟前端和 SerDes 能做到什么”PCS 回答的是“编码子层能组出哪些速率的帧”两者并不总是重合——比如某条通路在模拟上能跑 5G但 PCS 侧当前配置下只使能了 1G 和 2.5G。写驱动时如果只读其中一处就下结论很容易出现“寄存器说支持 10G实际协商出来只有 1G”的诡异现象。常见的实现思路是初始化时把 MMD 1.0x0004、1.0x000B、1.0x0015 和 MMD 3.0x0004 全部读一遍取交集作为这颗 PHY 在当前固件版本下的“真实能力集”再拿这个集合去构造自协商通告。手册里把这几个寄存器分散在不同小节恰恰是在暗示它们不该被当成同一个东西。2.2 USXGMII 与媒体转换器一颗芯片的两种角色RTL8261N 的通用功能描述里明确列了两种芯片模式USXGMII 模式和 Media Converter 模式。这个划分决定了芯片内部数据通路的走向也决定了你该去配置哪一组寄存器。USXGMII 模式下芯片扮演的是一个标准的以太网 PHYMDI 侧接网线系统侧走 USXGMII 这条串行接口连到 MAC 或交换芯片。此时 XSGMII 接口引脚承担的是“上行”角色速率由链路侧协商结果决定芯片内部做的是并串转换加编码。Media Converter 模式则是另一种用法芯片不再是一个“终点”而是一段“中继”把一侧收到的数据原样转到另一侧。这种模式常见于把光模块和电口对接、或者把两种不同介质桥接起来的场景。它的关键差别在于自协商和链路状态的语义变了——原本“我这条链路通了”变成“我这一侧通了并且对侧也通了”任何一侧断开都要往下游传播。这两种模式在引脚层面是靠配置 strap 引脚在上电时采样决定的也就是引脚描述里那一组 Configuration Strapping Pins。这里有个血泪经验strap 是在复位释放的那一瞬间锁存的之后再改引脚电平不会生效。调试时如果你改了板上的下拉电阻却没断电重启看到的永远是上一次的模式。所以排查芯片模式不对第一步永远是完整断电再上电而不是按一下复位键。2.3 自协商三层协议叠在一起Multi-GBASE-T 的自协商比传统 100M/1G 复杂得多因为它要在同一套握手机制里同时表达 2.5G、5G、10G 这些“新速率”又不能把只认 1G 的老对端搞懵。RTL8261N 的做法是把自协商拆成三层第一层是标准的 Base Page 交互走 MMD 7.0x0010AN Advertisement和 MMD 7.0x0013LP Base Page Ability负责 10M/100M/1G 这些传统速率的通告与对端能力读取。第二层是 Next Page通过 MMD 7.0x0016 到 7.0x0018 这三个寄存器组成的 XNP Transmit 窗口发送扩展信息把 2.5G/5G/10G 的能力塞进去。第三层是 Multi-GBASE-T 专属的控制与状态MMD 7.0x0020AN Control 1、7.0x0021AN Status 1、7.0x0040AN Control 2、7.0x0041AN Status 2成对出现专门管多千兆速率的协商细节。下面这段是改通告的典型写法注意“先关自协商、改完再开”这个顺序不是可选项# 使能/关闭 2.5G 与 5G 通告。位号必须查手册 4.5.6 节不要凭记忆 BIT_2P5G 1 0 # 占位实际位号见 MMD 7.0x0020 表 BIT_5G 1 1 def advertise_multigbase(phy, enable): # 第一步关掉自协商否则新写入的通告可能被当前协商流程忽略 ctrl mmd_read(phy, 7, 0x0000) mmd_write(phy, 7, 0x0000, ctrl ~0x1000) # bit12 AN Enable # 第二步改 Multi-GBASE-T 通告位 mg mmd_read(phy, 7, 0x0020) if enable: mg | (BIT_2P5G | BIT_5G) else: mg ~(BIT_2P5G | BIT_5G) mmd_write(phy, 7, 0x0020, mg) # 第三步重新打开自协商触发一次完整的重新握手 mmd_write(phy, 7, 0x0000, mmd_read(phy, 7, 0x0000) | 0x1000)mmd_read/mmd_write的两个参数分别是 MMD 编号和 MMD 内的寄存器偏移这是第四章整张表用的寻址方式下一章细说。这里真正要留意的是第三步重开 AN Enable 会让链路进入一次完整的重新协商链路会短暂 down 再 up。如果这段代码跑在已经在承载业务的设备上上层会看到一次链路抖动。生产环境的做法通常是先判断目标能力位和当前值是否一致一致就直接返回避免无谓的重协商。2.4 快速重训练降速时避免链路重启Multi-GBASE-T 有一个传统以太网没有的机制Fast Retrain。对应的控制与状态在 MMD 1.0x0093。它的意义在于当链路质量下降需要从 5G 降到 2.5G 时不必走完整的“链路断开—重新协商—重新训练”流程而是在保持链路状态不中断的前提下重新训练均衡器。这个机制带来的直接后果是如果你在驱动里靠“链路状态位翻转”来判断是否发生了速率变化会漏掉 Fast Retrain 这种情况。正确的做法是轮询 MMD 1.0x0093 的状态位并结合 MMD 1.0x0081Multi-GBASE-T Status里的当前速率字段一起判断。我见过有项目因为只监听 link up/down 中断导致面板上的速率灯在降速后一直显示旧值用户以为链路没降速实际带宽已经掉了一半。3. 寄存器地图MMD 寻址为什么把地址空间拆成两段3.1 MMD 间接寻址的时序RTL8261N 的寄存器访问沿用 IEEE 802.3 的 MMD 间接寻址模型管理接口上只有两个“窗口”寄存器一个用来选 MMD 编号一个用来选 MMD 内的偏移并兼作数据口。芯片内部维护着一个“当前选中 MMD”的状态后续对这个数据口的读写都落在这个 MMD 里。# MDIO 间接寻址0x0D 选 MMD 编号0x0E 先当地址、再当数据 MDIO_MMD_DEV 0x0D MDIO_MMD_REG 0x0E def mmd_read(phy, mmd, reg): mdio_write(phy, MDIO_MMD_DEV, mmd) # 1. 选中目标 MMD mdio_write(phy, MDIO_MMD_REG, reg) # 2. 写入 MMD 内的寄存器偏移 mdio_write(phy, MDIO_MMD_DEV, mmd) # 3. 部分控制器要求再选一次保证状态机同步 return mdio_read(phy, MDIO_MMD_REG) # 4. 读回落在数据口上的值 def mmd_write(phy, mmd, reg, val): mdio_write(phy, MDIO_MMD_DEV, mmd) mdio_write(phy, MDIO_MMD_REG, reg) mdio_write(phy, MDIO_MMD_DEV, mmd) mdio_write(phy, MDIO_MMD_REG, val) # 第四次写才是数据这四步里最容易出问题的是第三步。MMD 寻址不是原子的两次 MDIO 事务之间存在时间窗口。如果管理总线上挂了多颗 PHY或者有别的代码路径中断上下文、另一个驱动的轮询线程也在访问同一颗 PHY那么在你写完 MMD 编号、还没写偏移之前状态可能已经被别人改掉了。表现出来就是“偶尔读到的值属于另一个 MMD”而且极难复现。解决办法只有给整个mmd_read/mmd_write序列加锁锁的粒度必须是“一次完整的四步事务”不能是单次 MDIO 读写。3.2 五段地址空间的职责划分把手册第四章的表按 MMD 编号归类能看出一条清晰的分层MMD 编号归属主要职责典型寄存器1PMA/PMD模拟前端、SerDes 速率能力、线对极性、功率回退1.0x0000、1.0x0082、1.0x00833PCS编码子层、EEE 节能、BASE-R 状态3.0x0000、3.0x0014、3.0x00207Auto-Negotiation通告、对端能力、XNP、Multi-GBASE-T 协商7.0x0010、7.0x0020、7.0x003C30TOP厂商段全局配置、封装模式、版本标识30.0xC1、30.0x103、30.0x104Page4/Page5SerDes 10G-R/5G-R10G 与 5G 专属的 PCS 与状态Page4 Reg0~Reg22这张表的读法是MMD 1 管“电”MMD 3 管“码”MMD 7 管“谈”MMD 30 管“我是谁”Page4/Page5 管“10G 那条快车道”。排查链路问题时的顺序也应该是这个顺序——先确认物理层收发器状态正常MMD 1再看编码层有没有误码计数MMD 3最后才怀疑协商MMD 7。反过来查很容易在自协商上绕半天结果发现是线对极性接反导致物理层根本没起来。3.3 Page 切换SerDes 那部分的另一套寻址10G-R/5G-R 那一组寄存器不在 MMD 空间里而是走另一套 Page 机制先往扩展寄存器页选择口写入页号再去访问该页内的寄存器编号。/* SerDes 10G-R/5G-R 寄存器位于 Page4/Page5访问前必须先切页 */ static void serdes_page_sel(uint8_t page) { /* 0x1F 是扩展页选择口切页后 0x00~0x1F 的含义随之改变 */ mdio_write(PHY_ADDR, 0x1F, page); } static uint16_t serdes_read(uint8_t page, uint8_t reg) { serdes_page_sel(page); return mdio_read(PHY_ADDR, reg); }这里有个隐蔽的坑Page 状态是芯片级的不是事务级的。你切到 Page4 读了一个寄存器如果不切回来后续所有对 0x00~0x1F 的访问都会被解释成 Page4 内的寄存器而不是标准寄存器。所以凡是用了 Page 机制的代码函数退出前都应该显式切回 Page0。这件事在单线程的初始化流程里看不出问题一旦有中断服务程序也去读标准寄存器就会读到一片乱值。Page4 里的寄存器编号本身也值得注意Reg0 是 PCS Control 1Reg1 是 PCS Status 1Reg2、Reg3 是 Device IdentifierReg4 是 Speed AbilityReg14、Reg15、Reg20、Reg22 都是 Package Identifier。Identifer 占了四个位置说明这颗芯片在 10G 侧的封装形态存在多种变体驱动里靠这几个寄存器区分具体是哪个料号。4. 链路诊断RTCT 与 SyncE 这两条旁路4.1 RTCT不开链路也能测线RTCTRealtek Cable Test是手册里一个篇幅不大但很实用的功能。它的价值在于不需要建立链路就能对 MDI 侧的电缆做一次测量给出线对长度、开路/短路位置之类的信息。原理上属于时域反射那一类做法——往线对里打一个脉冲测量反射回来的时间和幅度从反射系数推断阻抗不连续点的位置。对产线和现场运维来说这解决了一个很实际的问题一条网线插上去链路起不来传统的排查方式是换线、换口、换设备全凭试。有了 RTCT可以先测一次直接知道是线太长、某对线断了还是远端根本没接设备。手册把这个功能放在通用功能描述而不是寄存器章节说明它是一组“触发—等待—读结果”的流程型操作不是一个可以随时读的即时值。实现时要注意它需要独占 MDI测试期间链路必然是断的别在业务流量跑着的时候随手触发。4.2 SyncE把恢复时钟送到系统侧SyncE同步以太网是另一个容易被忽略的功能。它的核心不是数据传输而是时钟传递从接收到的以太网码流里恢复出对端的发送时钟把这个时钟引到芯片的时钟输出引脚上供系统侧的 PLL 参考。这样整条链路上的所有设备就共享同一个频率基准。这里必须分清楚一件事SyncE 传递的是频率不是时间。它保证的是“大家走时一样快”不保证“大家现在都是几点”。要拿到绝对时间还需要在上层跑 PTP 之类的时间同步协议。手册把 SyncE 单列一节而不是归到 PCS 里正是因为它的配置对象是时钟路径而非数据路径——涉及哪个引脚输出、分频系数多少、失锁时如何切换这些都跟数据通路的寄存器没有关系。调试 SyncE 时最典型的翻车是链路起来了数据也通但下游设备的时钟一直处于 holdover 状态。原因往往是芯片的 SyncE 输出没有使能或者输出的时钟频率跟下游 PLL 期望的不匹配。这两项在手册里分属不同的配置位置需要对着引脚描述和通用功能描述两处一起看。4.3 并行 LED 与掉电模式状态可视化与低功耗并行 LED 这部分看起来是最没技术含量的其实藏着一条容易被忽略的信息Power On Blinking。上电后 LED 会有一个闪烁阶段这个阶段表达的是“芯片正在初始化”闪烁结束才代表初始化完成、可以开始正常指示链路状态。如果板上电后 LED 一直闪个不停说明初始化卡住了这时候别去查链路该查的是时钟和复位。掉电模式Power Down Mode则是另一个方向的取舍。手册把它单独列成一节说明它不是简单地把某个寄存器的某一位清零而是一个有进入条件、有退出时序的状态机。掉电期间管理接口通常仍然可用否则你没法把它唤醒但 MDI 侧完全不工作。做低功耗设计时要注意从掉电模式退出来需要重新走一遍完整的初始化和自协商这个时间在需要快速唤醒的场景里是不可忽略的。5. 排查手册五条“寄存器读出来是对的、链路就是不通”的现场记录5.1 现象复位后立刻读链路状态永远显示 down原因复位释放到内部 PLL 锁定、SerDes 完成初始化之间存在一段不可忽略的时间这段时间里读 MMD 3.0x0001 得到的就是未就绪。手册的引脚描述和通用功能描述里都提到了上电初始化流程但没有给出一个统一的“多久之后可以读”的常数因为这个时间跟参考时钟质量有关。解决不要用固定延时。改成轮询 MMD 30.0x104Version ID能稳定读出非 0 且非全 1 的值作为“管理接口就绪”的标志再轮询 MMD 1.0x0001 的复位完成位作为“PMA 就绪”的标志两级都过了才去碰链路状态。这样在不同板子上都能自适应。5.2 现象对端明确支持 2.5G双方却始终协商到 1G原因MMD 7.0x0020 里的 2.5G 通告位没使能。很多驱动的初始化流程只配置了 MMD 7.0x0010Base Page因为那是传统以太网时代就存在的寄存器从老代码继承下来的路径里根本没有 0x0020 这一项。解决在初始化末尾显式读一次 MMD 7.0x0020 和 7.0x0040把需要支持的多千兆速率位补齐然后按 2.3 节的顺序重开自协商。改完之后用 MMD 7.0x0021 读回对端实际通告的能力确认双方的能力集真的有交集而不是自己一厢情愿。5.3 现象MDI 差分对在 PCB 上接反了链路居然也能通原因MMD 1.0x0082Pair Swap and Polarity支持线对交换和极性自动纠正。芯片检测到极性反了会自己翻回来所以接反也能工作。解决这个“能通”是陷阱。极性自动纠正只在特定速率和特定模式下有效切到 10G 或者进某种测试模式时可能就失效了。正确的做法是先让它通然后立刻读 MMD 1.0x0082 看它报告的实际极性状态如果和 PCB 设计意图不一致改板子而不是依赖自动纠正。另外靠自动纠正工作的链路在 EMC 测试里往往表现更差因为共模抑制的对称性被破坏了。5.4 现象短网线小于 5 米时误码率反而比长网线高原因MMD 1.0x0083TX Power Backoff and PHY Short Reach Setting里的短距设置没配。10GBASE-T 的发送功率是按最长 100 米信道设计的在极短的信道上会因为信号过强导致接收端饱和。解决按实际布线长度配置短距模式或功率回退等级。这一项在很多参考设计里默认关闭因为它需要知道实际线长如果你的产品线固定使用短跳线这一项必须显式打开。验证方法是对比开启前后的 MMD 3.0x0020 里的误码计数应该能看到明显下降。5.5 现象Fast Retrain 发生后驱动记录的当前速率还是旧值原因驱动只监听链路 up/down 变化而 Fast Retrain 不产生 link down 事件。MMD 1.0x0093 的状态位变了但驱动没去读。解决把 MMD 1.0x0093 纳入周期性轮询和 MMD 1.0x0081 的当前速率字段一起判断。轮询周期取 1 秒量级即可Fast Retrain 本身是毫秒级完成的事件不需要高频采样但必须采。6. 版本 ID 与修订历史手册只写了一半另一半要从芯片里读回来这份文档的标题里带着 Brief 这个词页眉印着仅限开发合作伙伴这两件事叠在一起说明了一个事实它是一份“够用就好”的公开版本。你拿到的是引脚表、功能概览和寄存器地图但大量位域的默认值、保留位该怎么写、某些状态位的清除方式在这份文档里是拿不到的。这不是疏漏而是产品资料分层发布的常规做法——完整版只给到签了协议的一方。在这种信息条件下最容易犯的错误是“假设自己的手册和手上的芯片是同一版”。RTL8261N 的修订历史里0.1 到 0.4 四个版本改了三次实质内容一次改 HSIP 引脚编号一次改 AVDDH 电压规格一次改机械尺寸。三条改动没有一条是“修正笔误”级别的——引脚编号变了意味着封装或引脚定义调整过电压规格变了意味着电源设计要跟着改机械尺寸变了意味着结构件要重开。换句话说如果手里的板子是照着 0.1 版做的拿 0.4 版手册去对引脚对不上是正常的。所以拿到芯片的第一件事应该是把它自己报出来的身份信息读出来跟手册对表# 三处身份信息缺一不可 dev_id1 mmd_read(phy, 1, 0x0002) # PMA/PMD Device Identifier 1 dev_id2 mmd_read(phy, 1, 0x0003) # PMA/PMD Device Identifier 2 ver_id mmd_read(phy, 30, 0x0104) # TOP: Version ID pkg_id mmd_read(phy, 30, 0x0103) # TOP: PKG model print(fDEV{dev_id1:04X}{dev_id2:04X} VER{ver_id:04X} PKG{pkg_id:04X})MMD 1.0x0002/0x0003是标准规定的设备标识理论上全球唯一用来确认“这确实是一颗 RTL8261N 家族的芯片”而不是贴错标的料。MMD 30.0x0104是厂商自己的版本号这个值才是真正决定“该用哪版手册、哪版驱动”的依据。MMD 30.0x0103的封装型号则决定了 10G 侧那几个 Package IdentifierPage4 Reg14/15/20/22应该读出什么值——如果这几个对不上说明你手里的料号和手册描述的变体不是同一个。我的一般做法是把这四个值在板子第一次点亮时就打印到启动日志里跟固件版本、手册版本一起做成一条三行的记录。后来产线反馈某批次链路异常我第一件事就是让他们把这四行贴过来五分钟就能判断是不是料号换了、手册对不上而不是从寄存器位域开始一层层往下查。从那以后我每次接手一块新板子都强制先读一遍这四个身份寄存器再动任何配置——这个习惯帮我省掉的返工时间比手册里任何一个功能都值钱。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →