CMIS 模块管理工具
操作手册

版本 2.211.0
适用软件 CMIS Module Manager
更新日期 2026-08-31
适用平台 Windows 10 / 11(64 位)
公众号二维码

扫码关注公众号

目录

  1. 产品简介
  2. 系统要求
  3. USB 驱动安装指南
  4. 启动程序
  5. 界面总览
  6. 连接模块
  7. Module Info — 模块基本信息
  8. Monitoring — 实时监控
  9. DataPath Config — 数据通道配置
  10. Diagnostics — 诊断工具
  11. Raw Registers — 寄存器直读写
  12. CMIS 5.4 扩展功能
  13. 常见问题排查
  14. 附录:界面按钮速查

1. 产品简介

CMIS Module Manager 是一款用于调测和管理符合 CMIS(Common Management Interface Specification)标准的光模块的桌面工具。支持读取模块身份信息、实时监控光功率与温度、配置数据通道(DataPath)、执行环回 / PRBS 诊断,以及直接读写任意寄存器。

1.1 CMIS 5.4 支持情况(本版起)

本工具自 v2.3.0 起按 OIF CMIS 5.4(2026-05-21 发布)解码。 5.4 与 5.3 完全向后兼容——规范原文即写明"5.3 合规的模块也是 5.4 合规的", 所以手上的 5.3 模块行为不变,界面上只是不会出现 5.4 才有的那几项。 界面中凡是 5.4 才引入的内容,名称后都带一个 5.4 徽标——字段名后如此,卡片标题后也如此。

5.4 相对 5.3 的全部变更,以及本工具的处理

5.4 变更寄存器 / 章节本工具
E14 模块通道数上限从 32 提升到 256 01h:142[1:0] = 11b 时改读 01h:174[4:0] 已支持 连接时读取,界面按实际通道数铺开,跨 Bank 读写。 逃逸路径由 mock_24lane 演示(其余 profile 的通道数旧字段都拼得出来,走不到这条路)
E1 通道默认极性广告 01h:171–172(Table 8-57) 已支持 Module Info 的 Default Polarity 行
新增页广告(0Ch/0Dh/60h/61h/62h) 01h:173–174(Table 8-58) 已支持 Module Info 的 Extra Pages 行
E13 媒体通道交换能力广告 01h:252[5](Table 8-62) 已支持 广告位 + Page 6Dh 的重定向暂存/使能/提交(见 §12)
E10 散热器类型 00h:61[7:4](Table 8-18) 已支持 Module Info 的 Heatsink Type 行
E17 300 GHz 频率栅格 04h:129[5]、04h:166–169,栅格码 1001b 已支持 Laser Tuning 的栅格列表与下拉
E9 可编程相对光功率监督门限 04h:196[6]、12h:216–217、12h:128–135[1] 已支持 Laser Tuning 卡片显示门限偏移与每通道使能
E2 接口 ID 扩展为 12 位 UID(4 位 GID + 8 位 ID) 1Ch NAD 内的 GID 字段 暂不适用 规范注明现存所有 UID 的 GID 均为 0, 非零 GID 只能经 NAD(Page 1Ch)广告,本工具读基本应用描述符
E12 可复位收发采集计数器Page 61h / 60h:192–193 已支持 四类计数器读取 + 按通道复位(见 §12)
E4 固件加载管理Page 0Dh(Table 8-75/8-76)+ CDB 部分支持 Page 0Dh 的固件状态只读显示(各 Bank 有效 / 已提交 / 运行中、版本、Build、描述),见 5.4 页面的 Firmware Loads 卡片;下载、提交等 CDB 命令流程不实现
E11 性能管理Page 0Ch + CDB 未实现 本工具不实现 CDB 命令流程(Page 0Ch 的特性声明照常显示)
E3/E6/E7/E8 新增 CDB 命令Chapter 9 未实现 同上
E15 VDM 降采样省电选项7.1.2 / 8.27.8 不适用 本工具不实现 VDM(5.4 的 VDM 变更为 none)
命名变更:DataPathID → DPIDX、NPID → NPIDX 6.2.3.2.2 等 已同步 见 §9.3 的 AppSelect 说明
术语变更:"flat memory" 改称 static memory6.3.2.3 已同步
ℹ 关于 1.6T 模块:CMIS 5.4 没有针对 1.6T 的专门条款——规范全文未出现 1.6T / 1600G, 接口编码仍引用 SFF-8024 rev 4.10(与 5.3 相同;本工具内置的编码表取自更新的 rev 4.14,新版只增不改,两者都能正确解码)。5.4 真正为高密度模块做的是扩容: 通道数上限 32 → 256,接口码空间 8 位 → 12 位。另需注意规范新增的 §6.4.1 明确: 单个 Application / DataPath 仍限 8 条通道(这一限制 5.3 就存在,5.4 才写明)。 因此 8×200G 的 1.6T 模块可用一个 8 通道数据通道承载,16×100G 则需要两个。
本工具内置两块 1.6T 模拟模块覆盖这两种形态:mock_1600g_dr8(8×200G,单 Bank)与 mock_1600g_16lane(16×100G,双 Bank)。
ℹ 1.6T 模拟模块的光参数取自 IEEE P802.3dj:CMIS 只规定寄存器怎么放,不规定光口指标; 1.6 Tb/s 以太网本身定义在 IEEE P802.3dj/D3.1(2026-06-04)。mock_1600g_dr8 按该草案 第 180 章建模,下表每一行都能在规范里查到出处;表里没有的项目一律是演示数据(见表下说明)。
项目取值出处
PHY 类型名1.6TBASE-DR8(不是 1600GBASE-DR8)Clause 180
每通道波特率 / 调制106.25 GBd PAM4(约 200 Gb/s)Table 180–7
波长范围1304.5 ~ 1317.5 nmTable 180–7
传输距离2 m ~ 500 mTable 180–6
每通道发送光功率−3.1 ~ +4 dBm → 即本工具显示的 Tx 高/低告警门限Table 180–7
每通道接收光功率−6.1 ~ +4 dBm → 即 Rx 高/低告警门限Table 180–8
整条链路 pre-FEC 误码率上限2.921×10⁻⁴(超过它 RS-FEC 就纠不动了)§174A.6
其中分给光模块本身的份额2.28×10⁻⁴(余下分给两端的 AUI)→ mock_1600g_dr8 模拟在 1.5×10⁻⁴,落在这个份额之内Table 174A–1
ℹ 看 1.6T 模块的 BER 时注意:200G/lane PAM4 依赖远强于 100G/lane 的 FEC,其健康的 pre-FEC BER 本就在 1e-4 量级,比 800G 模块差几个数量级,这不是故障;判定要用分给模块的 2.28×10⁻⁴, 不是整条链路的 2.921×10⁻⁴。
别把 §180.2 里的 6.4×10⁻⁵ 当成模块的份额——那是 BERadded,代表链路上除该模块以外所有环节的预算 (§174A.9),测模块时用来替代它们注入的噪声。按它判定会把一块合规的 1.6T 模块误判成超标三倍。
802.3dj 不管的部分是演示数据:功率等级、壳温、CMIS 的 SNR 诊断值属于模块封装/厂商范畴, 802.3dj 不给限值。「警告」门限同样不是规范值——Table 180–7/180–8 只给告警用的工作上下限, 802.3dj 里没有警告这一档,本工具的警告门限取在告警内侧 0.5 dB,是演示取值,别当一致性依据。
mock_1600g_16lane 只有主机侧对得上 802.3dj——16 通道 × 约 100 Gb/s 即 1.6TAUI-16 C2M(Annex 120G);它的光口跑 100G/lane,属 802.3df 的 PMD 而非第 180 章, 所以门限保持通用值。
⚠ 多 Bank(超过 8 通道)路径仅经 Mock 验证。开发时没有 16 通道实机可测, 该路径的通道编号、Bank 切换与读写分组由 mock_1600g_16lane 覆盖。 首次接真实宽通道模块时,请先用 Raw Registers 核对 01h:142 与 01h:174 的广告值与界面显示的通道数是否一致。

支持的接口后端(Backend)

Backend说明
mock_coherent模拟 800GBASE-LR1 数据中心 coherent lite(DP-16QAM, 单波长 O 波段, SMF 10km),光参数按 IEEE P802.3dj/D3.1 第 185 章建模,无需硬件
mock_coherent_zr模拟 800G 可调谐相干模块(C-band DWDM, ZR 类),支持 Laser Tuning(另一块可调谐的是 16 通道的 mock_zr16)
mock_dr8模拟 800GBASE-DR8(8×100G PAM4, SMF 500m, EML 1310nm),无需硬件
mock_sr8模拟 800GBASE-SR8(8×100G PAM4, OM4 100m, VCSEL 850nm),无需硬件
mock_fr4x2模拟 2× 400GBASE-FR4(CWDM4 SMF 2km, EML 1310nm),无需硬件
mock_1600g_dr8模拟 1.6TBASE-DR8(8 × 106.25 GBd PAM4, SMF 500m, 功率等级 8 / 26 W),光参数按 IEEE P802.3dj/D3.1 第 180 章建模,自报 CMIS 5.4 并广告全部 5.4 可选页
mock_1600g_16lane模拟 1.6T 16×100G(主机侧即 1.6TAUI-16 C2M,16 通道 / 双 Bank, 功率等级 8 / 28 W),用于演示跨 Bank 读写与 5.4 新增字段
mock_aoc模拟一根 400G 有源光缆(AOC),20 m。 媒介不可分离——光纤是焊死在模块上的,所以它有连接器类型「无可分离连接器」、 有线缆长度、也有线缆传播时延(01h:148-149,这个寄存器正是为这种模块定义的)。 其余分页 profile 的媒介都是可插拔的,所以几条「为线缆组件写的」逻辑此前只有平坦内存的 DAC 可对照, 传播时延那一条则一个模块都没有。
mock_fewmon模拟一块只实现了部分监控项的 800G DR8。 CMIS 把每一项监控都定义为可选,由 01h:159-160 广告自己有哪些; 这块模块没有电源电压监控、没有发送光功率监控、也没有偏置电流监控, 只保留温度和接收光功率。用来演示「模块没有这一项」和「这一项读数为 0」是两回事。
mock_zr16模拟一块 16 通道的可调谐模块 (C-band,功率等级 5 / 16 W)。它存在的理由只有一个:Page 12h 是按介质通道分 Bank 的 (每 Bank 8 条),而其余可调谐 profile 都正好 8 条、一个 Bank 装得下, 于是「写第二个 Bank」这条路从来没人走过。
mock_24lane模拟一块 24 通道 / 三 Bank 的模块(功率等级 8 / 30 W)。 24 是旧字段拼不出来的通道数(旧字段只能表达 8 / 16 / 32), 因此它是唯一会走 CMIS 5.4 通道数逃逸路径的 profile: 01h:142[1:0] = 11b 时改读 01h:174[4:0]
mock_flat_dac模拟一根 3 m 无源铜缆 DAC,平坦内存(static memory):只有 Lower Memory 和 Page 00h,没有 Page 01h 及以后的页。用来演示工具在没有分页的模块上哪些卡片不适用、哪些字段按线缆组件的含义读
ch341通过 CH341 USB 转 I2C 适配器连接真实模块
ch347通过 CH347 USB 转 I2C 适配器连接真实模块
ftdi通过 FTDI 系列芯片(FT232H / FT2232H)连接真实模块,走 pyftdi / libusb,需要用 Zadig 换成 WinUSB 驱动
ftd2xx同样是 FTDI 芯片,走 FTDI 官方 D2XX 驱动(ftd2xx.dll),不用换驱动
cp2112通过 Silicon Labs CP2112 USB 转 I2C 桥连接真实模块;HID 设备,不用装驱动
mcp2221通过 Microchip MCP2221 / MCP2221A USB 转 I2C 桥连接真实模块;HID 设备,不用装驱动
ℹ 12 种 Mock 模块涵盖了从 800G 到 1.6T 的主流应用:数据中心 coherent lite 10km、C-band 可调谐相干长途、数据中心 500m、机架内 100m、园区 2km,两块 1.6T(8×200G 单 Bank 与 16×100G 双 Bank),一块 24 通道 / 三 Bank 的模块(专门用来走 5.4 的通道数逃逸路径),一块 16 通道的可调谐模块(专门用来走 Page 12h 的第二个 Bank),一块只实现了部分监控项的模块,一块平坦内存的无源铜缆 DAC(只有 Lower Memory 与 Page 00h,用来暴露「读一个模块没有的页」这类问题),以及一根400G 有源光缆(媒介不可分离的分页模块,用来走线缆组件在 Page 01h 上的那些字段),可用于不同场景演示与培训。

2. 系统要求

项目要求
操作系统Windows 10 / Windows 11(64 位)
硬件接口USB 端口(使用真实模块时)
驱动程序 使用真实模块时需提前安装对应 USB 驱动:
· CH341:从 WCH 官网下载 CH341SER.EXE,安装后 CH341DLL.dll 自动注册到系统
· CH347:从 WCH 官网下载 CH347SER.EXE(串口驱动)+ CH347DLL.dll(I2C 通信库,需另行获取,详见第 3 节)
· CH341 安装驱动后 DLL 自动进入 System32;CH347 可能需要手动将 CH347DLL.dll 放入 EXE 同目录或 System32
· Mock 模式(不接硬件)无需安装任何驱动
· WCH 官网(国内):www.wch.cn  官网(国际):www.wch-ic.com
运行时依赖无需安装 Python 或任何运行时,双击 EXE 即可运行
ℹ Mock 模式不需要任何硬件,适合软件演示、界面熟悉和功能验证。

3. USB 驱动安装指南

使用 CH341 或 CH347 适配器连接真实光模块前,需先在 Windows 中安装对应的 WCH USB 驱动。Mock 模式无需此步骤。

步骤一:识别你的硬件

外观特征芯片型号需安装的驱动
黑色小板,常见于淘宝低价 I2C 适配器CH341ACH341 驱动
蓝色板,支持更高速率(USB 2.0 High-Speed)CH347CH347 驱动

步骤二:下载驱动

步骤三:安装

  1. 解压下载的压缩包。
  2. 运行压缩包内的 SETUP.EXE(或 CH341SER.EXE / CH347SER.EXE)。
  3. 在安装界面点击 安装(Install),等待提示"驱动预安装成功"。
  4. 将 USB 适配器插入电脑。
  5. 打开 设备管理器(Win + X → 设备管理器),在"端口(COM 和 LPT)"或"通用串行总线控制器"下应出现:
     · CH341:USB-SERIAL CH341 (COM×)
     · CH347:USB Enhanced Serial Port (COM×)

步骤四:验证

  1. 启动 CMIS_Module_Manager.exe。
  2. 在左侧 Backend 下拉菜单中,应出现 ch341 或 ch347 选项(状态 available)。
  3. 若未出现,点击 ↻ Refresh Backends 重新扫描。
⚠ 不可调谐的模块,调谐页以前会「凭空」列出一堆栅格(v2.66.0 修复)。
这是规范里一条很容易踩的规则:选一个模块没有的页,模块不会报错—— 它会把页号清零、改成给你 Page 00h。 而 Page 00h 的上半区是厂商名、料号、序列号这些 ASCII 文本。
调谐能力表在 Page 04h,只有 01h:155.6 说「发射端可调谐」时才存在。 工具此前不看这一位就去读,于是读回来的其实是厂商名那几个字节, 再按栅格位图解码——一块根本没有可调谐激光器的模块, 调谐页上会显示 「支持 6.25 / 12.5 / 25 / 50 / 150 GHz 五种栅格」, 以及一个「123.36 到 −163.28 dBm」的可编程功率范围 (上下限还是反的)。
现在先看 01h:155.6:这一位是 0 就根本不去读那一页, 页面直接说明该模块没有 Page 04h/12h。 写入侧一直是按这一位拦的,页校验和那部分也一直跳过 Page 04h—— 只有读取这一条漏了。
ℹ 激光器调谐页:同一个栅格,下拉框和悬停提示可能显示成两个名字(v2.65.0 修复)。
规范给每一个栅格编码都定了名字,包括 1111b——它的含义是 「不可用 / Not available」,是一个有意义的值,不是空档。
界面此前自己抄了一份栅格名字表,而那份抄到 1001b(300 GHz)就停了。 于是一条处于 1111b 的通道,悬停提示显示「Not available」, 同一行的下拉框却显示「15」——同一个寄存器,同一行上两个答案。
现在名字只由后端给一份,界面直接用; 规范未定义的那几个编码(1010b–1110b) 也统一用后端解出来的写法,不再各猜各的。
⚠ 「数据通道」页勾选 DP Deinit 时,勾中的通道和实际生效的通道可能对不上(v2.64.0 修复)。
CMIS 要求一条数据通道的所有通道必须整体操作(Table 8-78), 所以勾一个格子会把同一条数据通道的其余格子一起勾上。
问题在于「哪几条通道算同一条数据通道」被算了两遍: 服务端在收到请求时按「相邻且应用相同」归组, 而界面自己按「应用宽度的整块对齐」又算了一遍—— 这是两套不同的算法,在大多数通道配置下结果并不一致。
后果是:界面上勾中的格子,和模块实际停掉的通道,可以是两批不同的通道。 举个本工具自带模块就能复现的例子: 通道 1–4 配 4 通道应用、5–12 配 8 通道应用、13–16 再配 4 通道应用, 这时点通道 5 的格子,界面勾的是 1–8,模块停的却是 5–12。
现在归组只由服务端算一次,界面直接用它——勾中的就是会停的。
⚠ 升级中途如果程序挂了,界面不会再说「已更新完成」(v2.63.2 修复)。
升级到最后,旧版本会主动退出让新文件顶上,所以页面那一刻连不上服务是 正常且预期的结束方式。
问题是:连不上也可能是程序在下载途中崩了。 此前这两种情况被当成同一种,于是下载到一半挂掉,页面照样显示 「已更新到 vX —— 新版本已经装好了」, 可实际上一个文件都没动;用户重新打开,还是原来那个版本, 而且屏幕上没有任何地方说明发生过什么。
现在会区分:只有走到「安装中」之后断开才算成功; 在「下载中」「校验中」断开会明确报错, 并说明当前版本原封未动、可以重试。
ℹ 换一块模块时,标志「历史」会重新开始计(v2.63.1 修复)。
CMIS 的标志是读一次就清掉的,所以工具会自己记一份「从上次清除以来出现过什么」—— 这份记录属于当时那块模块。
先前只有点断开才会清掉它;如果不断开、直接连另一块模块 (接口允许这么做,脚本和自动化也是这么切换的), 上一块的记录会原样留着,「起算时间」也还停在上一块那会儿—— 于是新模块一连上,就显示它在插上之前就报过告警。
现在连接时和断开时一样会清空重新计。 想手动清零仍然用面板上的「清除标志历史」,那只清工具自己的记录, 不会往模块里写任何东西。
⚠ 监控项没有,对应的告警标志也不该显示成「正常」(v2.63.0 修复)。
上一条修的是读数,这一条修的是标志位。 规范里写得很直接:「有门限的监控项才有对应的告警标志、警告标志」, 而且这些标志的类型标的是 Adv.(需广告), 不像模块状态变化那种标 Rqd.(必有)。
所以发送光功率、偏置电流、接收光功率这三项的共 12 个门限标志, 以及温度、电源电压的共 8 个模块级门限标志, 都是跟着监控项走的(01h:159-160), 而不是跟着 01h:157-158——后者只管 Tx 故障、丢失信号、 CDR 失锁、自适应均衡失败这四类。
此前工具只用 01h:157-158 判断,于是那 20 个门限标志 在没有对应监控项的模块上被画成绿点—— 「这里一切正常」,可根本就没有在测。 现在它们显示 n/a,「监控」汇总列在三项全无时也显示 n/a; 模块有的那几项照常显示,是逐项判断的。
顺带:这类标志不会再进入「历史」记录, 也不会点亮顶部的告警提示——历史是会一直留在屏幕上的, 记错一次就要人工清一次。
⚠ 模块没有的监控项,不再当成读数显示(v2.62.0 修复)。
CMIS 把每一项监控都定义为可选——温度、电源电压、发送光功率、偏置电流、接收光功率—— 模块在 01h:159-160 里广告自己到底有哪几项。 没有的那一项,寄存器仍然存在,只是读出来是 0。
此前工具照单全收地把这个 0 显示出来,而 0 在这里不是「空白」,是很吓人的读数: 0.0000 V 是模块没通电,0.000 mA 是激光器灭了, 0 微瓦换算成 dBm 是量程底部——而且会被标成红色告警。 也就是说,工具在替一块根本没有这项监控的模块报一个它从没说过的故障。
现在这些位置显示「not implemented」并注明是哪一位广告的(如 01h:160.0), 不参与告警配色。模块实现了的那些监控照常显示——这是逐项判断的, 不会因为缺一项就把整行藏掉。
⚠ 演示模块不会再自己「定时」报失锁了(v2.62.0 修复)。
此前第 8 条通道的 Tx CDR 失锁每 60 秒、Rx CDR 失锁每 75 秒自己亮一次再灭掉, 而那块模块的所有读数都是健康的。 一个按秒表闪的告警,会让人学会所有告警都不用看—— 这和之前修掉的「温度告警每 30 秒闪一次」是同一个毛病,只是漏了通道级的这两处。
更糟的是那一行是直接赋值而不是置位,所以它还会把真实读数刚刚触发的 Rx 失锁/丢失信号标志抹掉。
现在 Rx 的失锁与丢失信号只由接收光功率决定,健康的模块跑多久都是安静的。 (这两处只影响 Mock 演示,接真实模块时标志一直是模块自己给的。)
⚠ 「寄存器直读直写」页多了一个 Bank 输入框(v2.61.0)。
CMIS 里有一批页是按 Bank 分组的(10h–5Fh、60h–62h、 6Dh、9Fh、A0h–AFh): 同一个页号 + 同一个地址,在不同 Bank 上是不同通道的寄存器, Bank b 对应第 8b+1 到 8b+8 条通道。
此前这个页面只能填页号和地址,读写永远落在 Bank 0—— 也就是说,通道数超过 8 的模块,第 9 条以后的寄存器根本够不着, 而且屏幕上没有任何地方说明你看的是哪个 Bank; 想写第 17 条通道的寄存器,实际会写到第 1 条上。
现在:填 Bank 即可读写对应的那一组通道,十六进制转储上方会写明 「Page 0x11 Bank 2 · lanes 17-24」; Bank 填超出模块实际 Bank 数、或填在不分 Bank 的页上(比如 01h、 02h)、或填在下半区(0x00–0x7F,本来就不分页也不分 Bank), 都会直接报错,而不是默默给你 Bank 0 的内容。
只有 8 条通道的模块只有一个 Bank,这个框填 0 即可, 输入框下方也会写明当前页分不分 Bank、本模块有几个 Bank。
⚠ 通道数超过 8 的可调谐模块,调谐第 9 条及以后的通道现在才真正生效(v2.60.0 修复)。
激光器调谐用的 Page 12h 是按介质通道分 Bank 的,每个 Bank 装 8 条通道, 第 9 条和第 1 条在同一个地址上,靠 Bank 号区分。 此前写入时只认页号、不认 Bank:第 9 条及以后的调谐被悄悄丢掉, 界面却回「已写入」;如果同时改了第 1 条,那一条还会跟着第 9 条一起被改。
现在每次写入都会带上 Bank 号;通道号超出模块实际通道数会直接报错而不是被忽略。
另外:一次请求里只要有一条通道的参数非法,整个请求都不会写, 不会再出现「前几条改了、后几条没改,而且没人知道改到哪」的半截状态。 只有 8 条通道的模块不受这个问题影响。
ℹ 还支持这几种适配器(v2.59.0 起):
CP2112(Silicon Labs)和 MCP2221 / MCP2221A(Microchip)—— 这两种是 HID 设备,Windows 用系统自带的驱动接管, 连驱动都不用装,插上就能在「适配器」里选到。
FTDI(FT232H / FT2232H)现在多了一条 ftd2xx 通道, 用 FTDI 官方驱动即可,不再需要 Zadig 替换驱动 (替换驱动会让机器上其它 FTDI 软件用不了,这也是原来那条 ftdi 通道的代价)。
顺带一提:只有 CH341 看不到「模块没应答」, 所以接 CH341 时连接会额外探一次总线(见下一条)。 CP2112 / MCP2221 / FTDI 能直接拿到应答位,没插模块时会当场报错。
ℹ CH341:安装驱动后 CH341DLL.dll 会自动注册到系统,EXE 无需额外配置, 开箱即用。
为什么本工具的 EXE 是 32 位:WCH 驱动包装进系统的 CH341DLL.dll 是 32 位的,而 64 位程序无法加载 32 位 DLL —— 这是 Windows 的限制,不是驱动或工具的问题。所以从 v2.58.0 起客户版 EXE 改为 32 位, 直接用驱动自带的那个 DLL,不需要你额外下载或放置任何文件。 (顺带:32 位包体积也小了约四成。)
⚠ 没插模块(或模块没插到位)时,工具会明确告诉你,而不是编一只出来。 空的 I2C 总线被上拉电阻拉高,每个字节都读回 0xFF; 而 CH341 的接口看不到缺失的 ACK,会把这次读当成成功返回。
v2.58.0 之前,工具就把这一串 FF 当数据解析了,界面上会出现一只 根本不存在的模块:CMIS 15.15、256 通道、 模块状态 Reserved、厂商名一串乱码、温度 -0.0039 °C。
现在连接时会先读低位内存前 3 个字节:全 FF 或全 00 就判定总线上没有模块应答,直接拒绝连接并说明读到了什么、该检查哪几项 (模块是否插到位、适配器的 I2C 线是否接对、地址是否为 0x50)。
⚠ CH347 注意:CH347SER.EXE 安装的是串口驱动(设备管理器可识别设备),但 I2C 通信所需的 CH347DLL.dll 可能不会自动安装到系统。若工具显示 CH347 unavailable,请从 WCH 官网下载 CH347EVT 开发资料包,找到 CH347DLL.dll,复制到 EXE 同目录或 System32 下。
⚠ 若设备管理器中设备图标有黄色感叹号,说明驱动安装不完整。请右键该设备 → 更新驱动程序,或重新运行安装程序。

4. 启动程序

  1. 找到发行包中的 CMIS_Module_Manager.exe,双击运行。
  2. Windows 可能弹出 SmartScreen 提示"Windows 已保护您的电脑":点击 更多信息 → 仍要运行。
  3. 弹出黑色控制台窗口,显示:
    CMIS Module Manager v2.211.0 starting on http://127.0.0.1:5000
    其中 v2.211.0 即当前版本号,界面标题旁和左侧栏底部也会显示,便于确认版本。
  4. 浏览器自动打开,显示工具主界面。
⚠ 控制台窗口必须保持开启。关闭它会停止服务器,浏览器页面将无法使用。
ℹ 如果浏览器未自动打开,请手动在地址栏输入控制台上显示的地址 (默认 http://127.0.0.1:5000)。

本机端口:查看、修改,以及被占用时

程序只监听本机 127.0.0.1,默认端口 5000。

为什么要这样:macOS 上的「隔空播放接收器」就占用 5000 端口;在 Windows 上, 服务器绑定端口时的方式允许与已经在监听的程序共用同一个端口, 结果浏览器连到哪一个由系统决定——你可能看到的是别的程序,甚至是一个 403 错误页。 现在启动时会先检测,被占用就明确告诉你。

5. 界面总览

CMIS Module Manager 界面截图

5.1 鼠标悬停查看寄存器来源

把鼠标停在任意一个设置项(复选框、下拉框、数值输入框)或信息表格的任意一行上, 会弹出该项对应的寄存器信息,无需再去翻规范手册核对地址:

提示行含义
第 1 行CMIS 规范中的字段名(如 AutoSquelchDisableTx1)
第 2 行所在 Page 与字节地址,十进制与十六进制并列(如 Page 10h · byte 131 (0x83))
第 3 行该字节当前实际读回的值,同时给出三种进制并各自标明: 0x05 hex = 0b00000101 bin = 5 dec
第 4 行该控件占用的位,以及 0/1 各代表什么
ℹ 字段名与地址均严格取自 OIF CMIS 5.4 原文(Table 8-18 / 8-47 / 8-57 / 8-58 / 8-62 / 8-99 / 8-109 等)。 多字节字段(如激光器频率)会显示完整字节范围与单位换算。

5.2 检查并升级到最新版本

标题右侧版本徽章旁有 ↑ Update 按钮,点击即联网检查 GitHub 上是否有新版本:

⚠ 升级会关闭当前程序并重启。若正在连接模块做测量,请先 Disconnect 再升级。
自动重启不保证成功:程序要替换的是自己正在运行的那个文件, 升级助手会尝试两次并轮询新版本是否起来。绝大多数情况下会成功、页面自动回来; 失败时不会有任何损失,双击 EXE 即可,文件已经是新版本。 升级仅在 EXE 版可用;从源码运行时会提示改用 git pull。 本工具只在你点击该按钮时才联网,平时不会主动访问外部网络。
🔒 关于本机端口的安全性:程序只监听 127.0.0.1,外部机器无法访问。 自 v2.1.0 起,所有 /api/ 接口还会拒绝由其它网页发起的请求—— 你在浏览器里打开的任何站点,都无法借你的浏览器去连接模块、改寄存器或触发升级。 即便有人把自己的域名解析到你本机(DNS rebinding),接口同样会因 Host 不在白名单而被拒。
需要说清的一点:自 v2.2.0 起,界面页面本身和 css/js 等静态文件不设此限制, 从任何地方点链接打开 http://127.0.0.1:5000(或你设置的端口)都能正常显示界面—— 因为光是拿到页面并不能操作模块,所有能碰模块的入口都在 /api/ 下面。 可用的本机地址有三个:127.0.0.1、localhost、[::1](带或不带当前端口号,默认 :5000)。
你自己写的脚本、curl、Python 程序不受此限制影响,但有两条硬要求: 带 body 的 POST 必须是 Content-Type: application/json,否则返回 415; 且必须用上面三个本机地址访问,用本机主机名会被拒。

5.3 数值进制的表示约定

寄存器工具里一个裸数字容易被误读,因此界面上所有数值都可判别进制:

进制写法出现位置
十六进制0x 前缀,如 0x83 寄存器地址、Interface ID、Raw 十六进制转储
二进制0b 前缀,如 0b00000101 位掩码,如 Applications 表的 Host Lane Assign
十进制无前缀,表头标注 dec 通道号、lane 数、带单位的监控值

表头的灰色小字会注明该列的进制与所属寄存器;悬停提示则同时给出三种进制,无需心算换算。

5.4 显示设置(v2.2.0 起)

点右上角的 ⚙ Display 打开显示设置。四项设置改动立即生效,无需确认, 并保存在本机浏览器里,下次打开自动沿用。未连接模块时也能调整。

设置可选项说明
主题
Theme
Midnight(默认深色)
Light 浅色
High contrast 高对比
Warm 护眼暖色
Light 适合白天强光或投影;High contrast 适合车间、远距离查看; Warm 降低蓝光,适合长时间盯屏。切换主题时告警红/黄、阈值染色、状态徽标会整套跟着变, 保证任何主题下数值都清晰可读。
界面缩放
UI scale
Auto(默认)
80% / 90% / 100% / 115% / 125% / 150%
整个界面等比放大或缩小,含文字、间距、表格。 Auto 会按你显示器的可用宽度自动选一档:1900px 以上放大到 115%, 2400px 以上 135%,3000px 以上 150%,其余保持 100%。手动选定后就不再自动变。
字号
Text size
Compact / Normal / Large / Extra large 只放大文字、不放大边距,与"界面缩放"是两件事。 它对最小的那些字(寄存器地址注释、状态标记)提升最明显—— 选 Extra large 时这些 10px 的小字会长到 14px,而标题只从 18px 到 22px。
字体
Font
System default
微软雅黑
思源黑体
全等宽
只影响界面文字。寄存器地址、十六进制转储、监控数值永远保持等宽字体, 不受此项影响——否则数字列会对不齐,直接影响读数。 所列字体均取自系统,未选中的字体若系统没装会自动回退。
💡 窄屏(如 1366×768 笔记本,或把缩放调到较大档位)下界面会自动适应: PRBS 的左右两栏改为上下排列,侧边栏收窄,过宽的表格在自己的卡片内横向滚动, 不会溢出到卡片外面。

若想恢复出厂外观,打开显示设置点 Reset to defaults 即可。

5.5 读取失败时各卡片的表现(务必了解)

只有 Monitoring 卡片会在读取失败时把数据置灰并显示过期横幅。 SNR 和 Laser Tuning 两张卡片失败时把表格换成一行 SNR not available / Laser tuning not available 加上原因,旧数值不会留下。其余卡片—— Module Info、带 5.4 标记的卡片、Squelch、Loopback、PRBS、Module Thresholds、DataPath、BER、 Error/Bit Counters、Module Control、Applications——失败时的表现是:

⚠ 后果是:如果你没看见那 3 秒的提示,就会把上一次成功读取的旧值当作当前状态。 记录数据或判断故障前,请先点该卡片的 ↻ Refresh 并确认没有弹出红色提示。 提示条一律出现在窗口右下角,没有历史记录,错过就查不到了。

6. 连接模块

6.1 选择 Backend

点击左侧 Backend 下拉菜单,选择对应接口类型:

Mock 模拟模块(无需硬件,适合演示/培训/开发)

Backend模拟类型典型场景特征
mock_coherent 800GBASE-LR1(802.3dj 第 185 章) 数据中心 coherent lite / 园区 10km DP-16QAM 123.6364 GBd,单波长固定载波(228.675 THz ± 20 GHz,约 1311 nm),不可调谐,13 W
mock_coherent_zr 800G 相干可调谐(C-band,ZR 类) DWDM 长途 / DCI 支持 Laser Tuning,Pre-FEC BER ~1e-9,16 W
mock_dr8 800GBASE-DR8 数据中心内 500m 8×100G PAM4,SMF MPO 1×16,EML 1310nm,14 W
mock_sr8 800GBASE-SR8 机架内 100m (OM4) 8×100G PAM4,MMF MPO 1×16,VCSEL 850nm,12 W(Bias 极低)
mock_fr4x2 2× 400GBASE-FR4 园区 / 楼栋间 2km CWDM4 × 2,双 LC,EML 1310nm,15 W

Mock 模块的所有 CMIS 寄存器值(Vendor Name、Connector、Media Interface Technology、Application Descriptors、Power Class 等)均按 CMIS 5.4 规范和实际产品特征构造。上表只列最常用的 5 种;下拉菜单里共有 12 种,其余 7 种(mock_1600g_dr8、mock_1600g_16lane、mock_24lane、mock_zr16、mock_flat_dac、mock_aoc、mock_fewmon)见第 1 章「支持的接口后端」表。支持 Laser Tuning 的是 mock_coherent_zr 和 16 通道的 mock_zr16(mock_coherent 建模的 800GBASE-LR1 是固定载波,802.3dj 未给它定义调谐栅格);mock_1600g_16lane 是一块 16 通道、自报 CMIS 5.4 的模块,用于演示多 Bank 与 5.4 新增字段。

真实硬件接口

点击 ↻ Refresh Backends 可重新扫描(插入 USB 适配器后刷新)。标注 (unavailable) 的选项表示驱动或硬件不可用。

6.2 填写 Bus 和 I2C 地址

字段说明典型值
Bus / Device IndexUSB 适配器编号,通常为 0;必须是整数,留空按 00
I2C Address光模块 I2C 地址(7 位,0–127)。十六进制写成 0x50 或规范的写法 50h,不带前后缀的按十进制。写不成数字的(如 5O)会被拒绝,不会截成别的地址0x50、50h 或 80

6.3 点击 Connect

6.4 断开连接

点击红色 Disconnect 按钮,断开当前连接并清空所有数据。

7. Module Info — 模块基本信息

连接成功后自动加载,显示模块的身份信息、能力广告与当前运行状态。所有字段寄存器地址严格按 CMIS 5.4 规范(OIF-CMIS-05.4.pdf Table 8-26)。

7.1 身份信息(Vendor Info)

字段说明Page / Addr
Module TypeSFF-8024 Identifier,按 SFF-8024 Rev 4.14 Table 4-1 命名(如 18h QSFP-DD、19h OSFP、1Eh QSFP+ or later with CMIS、21h OSFP-XD with CMIS);27h–7Fh 为 Reserved,80h–FFh 为 Vendor specific。如果这个标识在 Table 4-1 里写明用的是别的管理接口(SFF-8472、SFF-8636/8436、SFP-DD 管理接口),这一行标 ▲ 并注明「not a CMIS module」——规范 8.2.1:模块被识别为 CMIS 模块之后,其余字段才能按 CMIS 解读Lower / 0x00
Module ID同一个标识字节的原始十六进制值;上一行 Module Type 是它的名称Lower / 0x00
CMIS Revision模块自报的 CMIS 规范版本(0x53=5.3、0x54=5.4)。上半字节=主版本,下半字节=次版本。本工具按 5.4 解码,5.x 模块兼容(附录 G.3)。4.x 模块标 ▲:12h:128–135 的 33/75 GHz 栅格代码已按版本换算,Flag 汇总(Lower 4–7)和输出状态(11h:132–133)不显示(Interrupt 行注明「Flags summary not decoded」,Monitoring 的输出列显示「n/a (CMIS 4.x)」);主版本号高于 5 的模块标 ▲「可能无法管理」Lower / 0x01
Memory ModelPaged(支持多页)/ Flat(只有 Page 00h)。Flat 模块上 Monitoring、DataPath Config、Diagnostics 三个标签页的内容大多不适用,页面顶部会用一行说明原因(DataPath Config 仍显示 Supported Applications)Lower / 0x02[7]
Reconfiguration模块支持哪几种重配置流程(SteppedConfigOnly + AutoCommissioning)。regular 对应 ApplyDPInit,hot 对应 ApplyImmediate;模块不支持哪一个,对应的写入就会被默默忽略Lower / 0x02[6],[1:0]
MCI Max Speed模块支持的管理总线最高速率(本工具只走 I2C,按 I2C 一列解:0=400 kHz、1=1 MHz、2=3.4 MHz)。3–15 是保留值,工具直接显示编号而不自己编一个速率出来Lower / 0x02[5:2]
Media Type介质类型,名称照 Table 8-20 原文:Optical Interfaces: MMF / Optical Interfaces: SMF / Passive and Linear Active Copper Cables(CMIS 5.3 起也包括线性有源铜缆)/ Active Cables / BASE-T;它决定 Supported Applications 的媒体接口编码查 SFF-8024 哪张表Lower / 0x55
Module State当前状态机(见下表);处于 ModuleFault 时同时显示故障原因(ModuleFaultCause,Table 8-16),原因为 0 时写明未报告Lower / 0x03[3:1] · 0x29
Vendor Name厂商名称,16 字节 ASCII00h / 0x81–0x90
Vendor OUIIEEE 厂商 OUI,3 字节十六进制00h / 0x91–0x93
Vendor P/N厂商料号,16 字节 ASCII00h / 0x94–0xA3
Vendor Rev产品版本,2 字节 ASCII00h / 0xA4–0xA5
Vendor S/N序列号,16 字节 ASCII00h / 0xA6–0xB5
Date Code生产日期码 YYMMDDLL(Y=年, M=月, D=日, L=批次)00h / 0xB6–0xBD
CLEI CodeCLEI 设备识别码,10 字节 ASCII00h / 0xBE–0xC7

7.2 能力广告(Capabilities)

字段说明Page / Addr
Power Class模块功耗等级 Class 1–8(bits[7:5])00h / 0xC8
Max Power最大功耗(W),原始值 × 0.2500h / 0xC9
Cable Length线缆长度(米)。仅对 Copper/Active Cable 有效;普通光模块按规范这里写 0,显示为 "—(transceiver,见 Link Length)"。线缆组件(Media Type 03h/04h)报 0 时显示 Not stated 并标 ▲;可拆卸光模块报了非 0 长度也标 ▲(Table 8-33 要求它写 0)00h / 0xCA
Link Length模块在每种光纤上的最大支持距离(Table 8-45)。SMF 以 km 计,带两位倍率;OM5/OM4/OM3 以 2 m 为单位,OM2 以 1 m 为单位。不支持的光纤类型写 0,所以只会列出真正支持的那几种。线缆组件没有这张表:规范 8.4.2 要求有源光缆在这里全部写 0、长度改报在 Cable Length,所以线缆显示 "—(cable assembly, see Cable Length)",报了非 0 值则标 ▲。平坦内存模块没有 Page 01h,显示 "no Page 01h"01h / 0x84–0x89
Connector光口类型,按 SFF-8024 Table 4-3 命名(如 LC、MPO 1×12、MPO 2×16、CS、SN、RJ45;线缆组件常见 No Separable Connector),括号里是原始编码00h / 0xCB
Media Interface媒体接口技术,名称照 Table 8-41 原文:850 nm VCSEL、1310 nm DFB laser、C-band tunable laser、Copper cable, passive, equalized 等,括号里是原始编码;15h 以上是保留值,显示 Reserved00h / 0xD4
Nominal Wavelength模块自报的标称波长和容差(Table 8-46,单位 0.05 nm / 0.005 nm)。模块没填(为 0)时不显示这一行;模块带多个波长时注明 several wavelengths on this module——Table 8-46 只为单波长模块定义这个字段01h / 0x8A–0x8D
Tx Input Clocking哪些 Tx 输入通道必须频率同步(Table 8-50):1–8 全部同步 / 1–4 与 5–8 各自同步 / 两两同步 / 可以异步。超过 8 通道的模块在每个 Bank 内按同样方式分组01h / 0x91[6:5]
Transmitter发射器是否制冷(CoolingImplemented,Table 8-50):Cooled / Uncooled01h / 0x91[7]
ePPS是否支持 ePPS(增强型秒脉冲)定时信号(Table 8-50)01h / 0x91[4]
Timing (Page 15h)是否在 Page 15h 提供每条通道的数据通道时延(Table 8-50、Table 8-141);支持时在 DataPath 页显示01h / 0x91[3]
Cable Propagation Delay不可分离有源光缆的传播时延(Table 8-50),10 ns 为单位,0 表示未给出(显示 Not specified)。线缆组件总有这一行;可拆卸光模块只在报了非 0 值时出现,并标 ▲。这是光在线缆里走的时延,DataPath 页的数据通道时延(Page 15h)是经过模块内部的时延,单位相同但不是一回事。平坦内存线缆显示 "no Page 01h"01h / 0x94–0x95
State Machines模块运行哪几个状态机(CmisSmSupport,Table 8-18):模块状态机 MSM、数据通道状态机 DPSM、网络通道状态机 NPSM。编码 0 表示「未声明」(CMIS 5.3 之前的模块),不是「没有」——这时按 Memory Model 判断;5 及以上是保留值Lower / 0x38
Module Function模块功能类型(ModuleFunctionType,Table 8-18):Transmission Module(传输模块)或 ELSFP Resource Module;2–127 显示 Reserved,128 以上显示 CustomLower / 0x39
Module Subtype封装形式的变体(SFF8024ModuleSubtype,Table 8-18),按 SFF-8024 Table 4-11 命名。这张表每种封装一列,由 Identifier 选列:同一个编码在 QSFP-DD、OSFP 等上是不同的变体(如 3 在 QSFP-DD 上是 Type 2A,在 OSFP 上是 Type 3);表里没有列的标识只显示编码。0 为 Unknown or unspecifiedLower / 0x3C[3:0]
LowPwr Restrictions哪些管理功能在 ModuleReady 下支持、进入 ModuleLowPwr 后受低功耗功率限制而不完全可用(LowPowerRestrictions,Table 8-19,CMIS 5.3 新增)。置 1 表示受限,四组都是 CDB:查询类、固件查询类、会改变模块状态的命令、会改变固件状态的命令;都没受限显示 None。bit 7 为 0 表示这个字节不可信(5.3 之前的模块),显示 Not stated。本工具自己不发 CDB 命令,这一行是给在 Raw Registers 里手动操作 CDB 的人看的Lower / 0x3E
Tx CDR有没有 Tx CDR、主机能否旁路它(Table 8-54):Present · host can bypass it / Present · always in circuit / No CDR。声明了旁路控制却没有 CDR 时照实写明——单看旁路位会以为能控制01h / 0xA1[1:0]
Rx CDR同上,Rx 侧(Table 8-54)01h / 0xA2[1:0]
CDR Bypass Saves每个 CDR、每条通道旁路后至少省下的功耗(CDRPowerSavedPerLane,Table 8-50,0.01 W 为单位),以及所有可旁路的 CDR 全部旁路时的合计;模块报 0 时显示 Not stated01h / 0x98
Tx Input EQ Freeze是否支持冻结 Tx 输入均衡器的自适应(Table 8-54)01h / 0xA1[4]
Tx Input EQ Recall模块能存几组 Tx 输入均衡自适应结果,供 Staged Control Set 调回(Table 8-54):Not supported / 1 buffer / 2 buffers;11b 是保留值,显示 Reserved01h / 0xA1[6:5]
Staged Control Set 1是否有第二套 Staged Control Set(Page 10h),主机可以同时备好两套配置(Table 8-54);本工具写的是 Set 001h / 0xA2[5]
Unidirectional Reconfig是否支持单方向重配置(Table 8-54):Page 10h 的 ApplyImmediateTx/Rx 与 Page 19h 的 DPConfigTx/Rx,只重配一个方向、不让另一个方向中断01h / 0xA2[6]
Versatile Control Set是否支持 CMIS-VCS(Table 8-54),其参数空间延伸到 Page 18h 和 19h01h / 0xA2[7]
Network Path Pages是否有网络通道页:Page 16h 及 Page 17h 中与网络通道相关的部分(Table 8-47)01h / 0x8E[7]
VDM Pages是否有 VDM 页 20h–2Fh(可以只实现一部分,详细声明在 Page 2Fh;Table 8-47)01h / 0x8E[6]
Diagnostic Pages是否有诊断页(分 Bank 的 13h–14h):环回、码型发生与检测、SNR、BER 和比特计数器(Table 8-47)。未声明时本工具拒绝这些控制01h / 0x8E[5]
Coherent Pages是否有相干页(分 Bank 的 30h–4Fh,可以只实现一部分,细节见 C-CMIS;Table 8-47)01h / 0x8E[4]
CMIS-FF (Page 05h)是否有 Page 05h 的封装形式专属功能(见 CMIS-FF 补充规范;Table 8-47)01h / 0x8E[3]
User EEPROM (Page 03h)是否有主机可写的 Page 03h 用户 EEPROM(Table 8-47)。CMIS 不规定里面存什么;一次最多写 8 字节,模块内部写完之前拒绝寄存器访问01h / 0x8E[2]
CDB Messaging模块有几个 CDB 实例(CdbInstancesSupported,Table 8-55)。CDB 是固件升级和规范第 9 章命令所走的消息机制;为 0 时显示 Not supported,下面几行 CDB 都不出现;3 是保留值01h / 0xA3[7:6]
CDB Background ModeCDB 命令执行期间能否访问其它寄存器(Table 8-55)。显示 No 的模块在命令执行完之前整个管理接口都不应答,不只是 CDB 页01h / 0xA3[5]
CDB Max Busy模块执行一条 CDB 命令最长可能忙多久,主机据此判断命令是否卡住。Table 8-55 对选择编码的那一位前后说法相反,工具按定义该位的那一行取值、标 ▲,并把另一种读法的数值一起列出01h / 0xA5[4:0] / 0xA6
CDB EPL Pages模块有几页扩展载荷(EPL)页,以及页号范围和总字节数(CdbMaxPagesEPL,Table 8-55)。编码不等于页数:5、6、7 分别表示 8、12、16 页01h / 0xA3[3:0]
CDB Max Access一次访问最多读写多少字节(CdbReadWriteLengthExtension,Table 8-55),EPL 与 LPL 分开列出:同一个值在 Page 9Fh 的 LPL(120 字节)上最多 128,在 EPL 页上最多 204801h / 0xA4
CDB Auto Paging是否支持自动翻页(Table 8-55)。不支持时主机不应写过一页 EPL 的末尾——地址在页内回绕,不会跳到下一页01h / 0xA3[4]
CDB TriggerCDB 命令怎样触发(CdbCommandTriggerMethod,Table 8-55):一次包含 9Fh:129 的写入结束(STOP)时触发,整条消息可以一次写完;或者只在写 CMDID 寄存器时触发,要先写正文、再单独触发01h / 0xA5[7]
Far End Breakout近端各主机通道分别接到远端哪个分立模块(FarEndConfiguration,Table 8-37,编码见 Table 8-38 / 8-39),一分几的均匀分支另外注明。可拆卸光模块这里应为 0,报了非 0 值标 ▲;线缆组件报 0 显示 Not stated 并标 ▲。超过 8 通道时每 8 条重复一次00h / 0xD3[4:0]
Cable Attenuation线缆组件在五个频点的插入损耗,整数 dB(Table 8-35):5、7、12.9、25.8、53.125 GHz。模块声明了 PCIe 应用(Host Interface 70h–73h)时,按表下注释同样五个字节对应 2.5、4.0、8.0、16.0、32.0 GHz,工具按此标频点。报 0 dB 表示该项不可用,显示 not specified,而不是「没有损耗」;五项都是 0 时不显示这一行00h / 0xCC–0xD0
Optical Detector光探测器类型(OpticalDetectorType,Table 8-50):PIN / APD01h / 0x97[7]
Rx Output EQ TypeRx 输出均衡保持哪一种幅度恒定(RxOutputEqType,Table 8-50)01h / 0x97[6:5]
Rx LOS TimingRx LOS 按封装规范的快速模式时限还是常规时限上报(RxLOSIsFast,Table 8-50):Fast mode / Regular01h / 0x97[2]
Tx Disable Timing模块响应 Tx 输出关断有多快(TxDisableIsFast,Table 8-50):Fast mode / Regular01h / 0x97[1]
Heatsink Type散热器类型,按 SFF-8024 Table 4-13 命名(SFF8024HeatsinkType)Lower / 0x3D[7:4]
Fiber Face光连接器的端面接触类型(SFF8024FiberFaceType,Table 8-18,编码见 SFF-8024 Table 4-12):PC/UPC 或 APC,假定所有光接口相同。0 同时表示「不适用」,例如没有光连接器的模块Lower / 0x3D[1:0]
Module Lanes模块物理通道总数和 Bank 数(BanksSupported);11b 转到 01h:174,最多 256 通道01h / 0x8E[1:0]
Default Polarity出厂默认的 Tx 输入 / Rx 输出极性(Table 8-57),列出反相的通道,全部正常时显示 All regular。超过 8 通道的模块上,这 8 位按每 8 条一组套用,除非 Page 60h 给出了逐通道的值(8.4.13)01h / 0xAB–0xAC
Media Lane Switching是否支持媒体侧通道切换(MediaLaneSwitchingSupported,Table 8-62)01h / 0xFC[5]
Host Lane Switching是否支持主机侧通道切换(HostLaneSwitchingSupported,Table 8-62):把主机电通道接到别的标称通道(7.8),CMIS 5.3 新增01h / 0xFC[7]
Link Training (Pages 50h-53h)是否支持 CMIS-LT 补充规范定义的链路训练功能,位于 Page 50h–53h(LinkTrainingSupported,Table 8-62)。本工具不操作这些页01h / 0xFC[6]
Host Scratchpad是否有 Host Scratchpad(13h:184-191,ScratchPadSupported,Table 8-62)。本工具靠它判断模块是否重启过(见 Module Restarts)。四个 01h:251 广告的取值相同:Supported / Not supported / Unknown(未声明,CMIS 5.2 及更早)/ Reserved;平坦内存模块显示 "no Page 01h"01h / 0xFB[7:6]
Password Entry是否支持密码输入 / 修改寄存器 Lower 118–125(PasswordEntrySupported,Table 8-62,规范 8.2.14)01h / 0xFB[5:4]
Password Result密码输入或修改的结果是否会报在 PasswordCmdResult(Lower 42)(PasswordEntryResultSupported,Table 8-62)01h / 0xFB[3:2]
Full Page Read一次 READ 能否读满 128 字节(FullPageReadSupported,Table 8-62);不支持时最多 8 字节(规范 5.2.2.1)。后面注明本工具按多大的块读01h / 0xFB[1:0]
Extra Pages模块声明了哪些附加页:0Ch / 0Dh / 60h / 61h / 62h(Table 8-58);都没有时显示 none advertised01h / 0xAD–0xAE
Host Lanes主机侧最大并发 lane 数(指一个通道组内;CMIS 限定单个 Application 最多 8 条通道,见 5.4 §6.4.1)。模块物理通道总数见 Module Lanes 行——16 通道模块这两处分别显示 8 和 16,并不矛盾。遍历全部 Application Descriptor,把主机 lane 区间互不重叠的应用相加(不是取最大值)——例如 2×400G-FR4 两个应用各占 4 条不重叠的 lane,结果是 8 而不是 4。一个应用若可以从多条通道起始(HostLaneAssignmentOptions 有多个位),每个起点算一个实例:只广告 4×100G-DR(2 条通道,起点 1、3、5、7)的模块是 8 条主机通道、4 条媒体通道。括号里的明细逐个列出各应用,用「·」分隔——它们可能互斥(同一组通道二选一),也可能像 2×400G 那样占不同通道、同时运行;前面的数字已按互不重叠的实例算好。多起点的应用标出实例数,如 2H/1M ×4。NP 应用(16h:248–249)的起点是 Host Path,共用网络通路:媒体通道按网络通路(MediaLaneAssignmentOptions 的每个起点)只算一次,明细写成 AppSel#3 (NP): 1H ×8 → 1M ×2Lower / 0x56+
Media Lanes媒体侧最大并发 lane 数(与 Host Lanes 同一套非重叠相加规则)Lower / 0x56+
FW Revision激活固件 主版本.次版本Lower / 0x27–0x28
Inactive FW备份固件的 主版本.次版本(Table 8-44)。模块内部常带两份固件,升级后想确认新镜像到底落在哪一份,看的就是这一行。平坦内存模块没有 Page 01h,显示 "no Page 01h on a flat memory module"01h / 0x80–0x81
HW Revision硬件版本 主版本.次版本。平坦内存模块同样没有,显示 "no Page 01h"。平坦内存模块的温度、电压、模块 Flag、状态变化、固件故障几行显示 "not for static memory modules"(规范 Table 8-9 / 8-10 只适用于分页模块)01h / 0x82–0x83
ℹ Cable Length 和 Link Length 不会同时有值。规范规定有源光缆(AOC) 把 Table 8-45 整张表写 0,改用 00h:202 报自己的实际长度; 普通可插拔光模块反过来。所以看到一行是 "—" 并不代表模块没报距离, 而是该看另一行。两行都是 "—" 才是真的没广播(比如可调相干模块, 实际距离取决于线路系统,不是光纤类型的固定属性)。

7.3 运行状态

字段说明Page / Addr
Page Checksums每个静态页都带一个校验和(静态字节之和的低 8 位)。工具连接时逐页核对,全部一致显示 N pages verified;不一致时列出页号——那几页的静态数据可能是一次坏读。模块没有的页不核对:平坦内存模块只核对 00h,04h 只在可调谐模块上核对00h:222 · 01h:255 · 02h:255 · 04h:255
Temperature模块内部温度,signed16 ÷ 256 (°C)Lower / 0x0E–0x0F
Supply Voltage供电电压,uint16 × 100 µVLower / 0x10–0x11
Module Flags六个模块级监控(温度 / 电压 / Aux1–3 / 自定义)的告警和警告标志,逐项列出:告警红色、警告黄色;两次刷新之间出现过的保留 ●! 记录Lower / 0x09–0x0B
Interrupt模块有没有在向主机请求中断(IntL 线)。规范里叫 InterruptDeasserted,取值是反的:1 表示没在请求;有标志置位时下方写明它们在哪一页、哪个 Bank(Lower 4–7 标志汇总)Lower / 0x03[0]
Masked module alarms只在有已置位但被屏蔽的模块级标志时出现:这些情况模块在报告,却不会为它们拉起中断线Lower / 0x1F–0x24
Module State ChangesModuleStateChangedFlag:进入 ModuleLowPwr、ModuleReady 或 ModuleFault 时置位(Table 6-9)——复位会点亮,切一次低功耗再回来同样会;保留 ●! 历史Lower / 0x08[0]
Module Restarts由 Host Scratchpad 判断模块是否真的重启过(8.16.13);无法判断时写明原因(见「Module State Changes 与 Module Restarts」)13h / 0xB8–0xBF
Firmware Faults模块 / DSP 固件错误与异常固件指示(Table 8-9);已读清的保留 ●! 记录,被屏蔽时标 masked。异常固件指示是「Adv.」标志,只有模块在 0Ch:194.4 声明支持时才检查,否则格子里注明 no firmware-vs-load checkLower / 0x08[3:1]
Aux1–3辅助监控值,标签随模块而定(如 Aux1 — TEC Current、Aux2 — Laser Temperature)。测的是什么由 01h:145 决定;模块没声明的不显示。无有效采样时标 no valid sample,后面附该项的告警 / 警告标志Lower / 0x12–0x17
Custom Monitor只在模块声明有自定义监控时出现:编码由厂商定义,只显示它的告警 / 警告标志Lower / 0x0B[7:4]
CDB Command Complete只在模块声明支持 CDB(01h:163.7-6)时出现:每个 CDB 实例一项,命令执行完时模块置位(7.2.5.2);已读清的保留 ●! 记录,被屏蔽时标 masked。命令成功与否看 CdbStatus(Lower 37–38)Lower / 0x08[7:6]

7.4 Module State 枚举(CMIS 5.4 Table 8-7)

状态编码 (bits[3:1])含义
ModuleLowPwr001b模块处于低功耗模式
ModulePwrUp010b模块正在上电初始化
ModuleReady011b模块正常工作 正常
ModulePwrDn100b模块正在下电
ModuleFault101b模块故障 异常;原因见 Lower 41,只有复位能离开(6.3.2.5.8)

点击右上角 ↻ Refresh 手动刷新。

8. Monitoring — 实时监控

⚠ 模块不在 ModuleReady 时,这一页以前会报出根本不该被当真的告警。 规范把话说得很直接:模块级监控读数只有在 ModuleReady 状态下 才被要求满足精度指标;告警 / 警告标志的语义,也只在 ModuleReady 状态下有保证。
但模块在别的状态下照样会给你一个数。 以前监控接口只把这些数原样送上来,连模块当前状态都不带—— 状态在另一个接口里,而这张表从来不去看它。 于是把模块切到低功耗(ModuleLowPwr)之后, Tx 光功率读回 -40 dBm,表格就按低告警标成红色: 一块只是睡着了的模块,被界面说成故障。
现在:监控接口每次轮询都带上模块状态; 不在 ModuleReady 时,表格顶部会写明当前是哪个状态、以及为什么这些数不作数, 数值照常显示(模块确实这么答的,看着模块下电的人需要看到它), 但不再上告警配色——颜色才是那个「下结论」的动作。 概要行里按额定温度范围给温度上色,同样只在 ModuleReady 时才做。 回到 ModuleReady 后一切照旧。
⚠ 同一条规矩还有逐通道的那一半:把某条数据通道停掉,这条通道就会被画成「告警」。 规范对数据通道相关的监控另有一句:它们的告警 / 警告标志, 只在 DPInitialized 和 DPActivated 两个状态下有保证—— 七个状态里就这两个。
可通道停掉之后,模块照样报一个光功率: 用本工具的 DPDeinit 把通道拉下来,受影响的每条通道立刻读回 -40 dBm,表格就按低告警标成红色。 而这期间模块本身一直是 ModuleReady, 所以上一条(模块级)的判断不会触发,也不该触发—— 那是另一个范围的另一条规矩。结果就是:你自己刚关掉的通道, 界面回头告诉你它坏了。
现在每条通道单独判断:模块在 ModuleReady 且本通道的数据通道处于 DPInitialized / DPActivated, 两个条件都满足才上告警配色。不满足时该通道的 Tx 光功率、Tx 偏置、Rx 光功率三格转为淡色, 悬停提示里写明本通道当前是哪个状态、以及为什么这些数不作数。 数值照常显示。通道重新起来后一切照旧。

8.1 实时数据表

列说明Page / Addr
Lane通道编号(8 通道模块 1–8;16 通道模块 1–16,第 9 条起在 Bank 1,地址同第 1 条)。模块在 11h:240–255(Table 8-107)声明了映射时,下面一行小字写这条媒体通道的波长和光纤(如 λ1 · TR1/RT1);映射违反规范 8.14.8(保留编码,或波长编号不是从 1 连续编)时前面标 ▲,表格下方说明原因—
Tx Power发送光功率(µW 和 dBm)11h / 0x9A+((n−1)%8)×2
Tx Bias发送偏置电流(mA)。寄存器每个计数是 2 µA 乘以 01h:160.4-3 的倍率(×1 / ×2 / ×4,Table 8-53;计数单位见 Table 8-99),列标题写出本模块一个计数是多少 µA11h / 0xAA+((n−1)%8)×2
Rx Power接收光功率(µW 和 dBm)11h / 0xBA+((n−1)%8)×2
DataPath State数据通道状态,4 bits/lane(见下表枚举)11h / 0x80–0x83
Output该 lane 的 Tx / Rx 输出是否真的在送有效信号(1 bit/lane)11h / 0x84 Rx、0x85 Tx
Config Status上次 Apply 配置的结果(ConfigSuccess / ConfigRejected / ConfigInProgress 等)11h / 0xCA–0xCD

DataPath State 枚举(CMIS 5.4 Table 8-84)

编码名称说明
0x1Deactivated未激活
0x2Init初始化中
0x3Deinit去初始化中
0x4Activated已激活 正常
0x5TxTurnOn发送启动中
0x6TxTurnOff发送关闭中
0x7Initialized初始化完成(未激活发送)
ℹ 七个状态里有四个是“过渡态”。 规范图 6-5 把 DPSM 状态分为稳态(Deactivated、 Initialized、Activated)和过渡态(Init、Deinit、 TxTurnOn、TxTurnOff)。过渡态意味着通道正在 上来或下去,不是故障。
旧版本只认 Activated 和 Init 两个名字,其余五个 全部按“已停止”的灰色显示——于是 Apply 过程中处于 TxTurnOn(正在上来)的通道, 看上去和一条死通道一模一样; Initialized(已初始化、只是 Tx 没开,本身是 稳态)也被当成故障。现在四类各有颜色, 鼠标悬停会说明它是稳态还是在路上。

颜色告警规则

颜色含义
正常功率在该 lane 适用的 Low/High Alarm 阈值之间(Tx 优先用 Page 62h 的每-lane 值,没有则用 Page 02h)
橙色功率低于模块的 Tx/Rx Power Low Alarm
红色功率高于模块的 Tx/Rx Power High Alarm
ℹ Tx 功率的阈值优先看每条 lane 自己的。 Page 02h 里只有一套全模块共用的阈值; 模块如果广播了 Page 62h(规范 8.32), 那里是按媒体 lane 分开的 Tx 功率阈值, 单位 0.01 dBm——对某一条 lane 而言,那一套才是 生效的。工具现在逐 lane 取用,而不是把 全模块那套套到每条 lane 上。
鼠标悬停在 Tx Power 格子上会直接写明这一格 用的是哪一套阈值、区间是多少—— 同一张表里两条 lane 可能按不同规则着色, 不写清楚就看不出来。
Rx 功率没有对应的每-lane 页,仍然用 Page 02h。
ℹ v2.0.3 起着色依据改为模块 Page 02h 广播的真实阈值(即下方 Module Thresholds 卡片显示的值),而非旧版固定的 −10 / +3 dBm。不同模块阈值不同——例如某 DR8 模块的 Tx Low Alarm 是 −8.0 dBm,按旧的固定值判断会把已触发告警的 lane 显示成正常, 与 Lane Flags 表自相矛盾。
仍会用到那对固定值的场合:刚连上模块、Page 02h 阈值尚未读回,或该次读取失败时, 着色会回退到 −10 / +3 dBm。此时颜色仅供参考,请以 Lane Flags 表和 Module Thresholds 卡片为准。
阈值会随 Application 变化(8.5 节):模块在 Data Path 以新 Application 到达 DPInitialized 时更新 Page 02h。 监控刷新时发现某条通道的 Application 或初始化状态变了,工具会重新读取阈值,再着色。

顶部摘要栏同步显示温度和电压。温度按模块在 01h:146–147 声明的工作温度范围判断:超出上限为红色,距上限 5°C 以内为橙色(这 5°C 余量是本工具定的,不是模块的);模块没声明范围时不着色。电压低于模块在 01h:150 声明的最低值时为红色。模块不在 ModuleReady 状态时,温度照实显示、不做判断。

Lane Flags 为什么会"自己消失"——闩锁与读清

这是 CMIS 排障时最容易踩的一条,与工具无关,是规范的设计:

⚠ CMIS 5.4 规定 Flag 是闩锁位,读取包含它的那个字节就会把它清零 (原文:"a Flag bit remains set (latched) until cleared by a READ of the Byte containing the Flag")。
这意味着:一次瞬时故障(光纤没插紧、电源抖动、对端重启)会把 Flag 置位, 模块一直保持到有人来读——而读到它的那一次刷新,也就把它擦掉了。 界面每 2 秒刷新一次,所以这个事件只会在某一帧里出现,看漏了就再也查不到。 这不是模块或工具出错,是 Flag 的定义如此。

因此记住它是主机的责任,本工具替你记:Lane Flags 表里,某个 Flag 曾经触发过、 但现在已经恢复的通道,会保留一个 ●! 标记,与"从未触发"(●) 区分开。点Clear flag history 清空这份记录、从当下重新开始计。 换模块或重新连接也会自动清空。

Flag 显示 n/a:模块在这个状态下不报它

规范 Table 6-21 规定每个通道 Flag 在哪些 DataPath 状态下可以置位。通道处于 DPDeactivated、DPInit、DPDeinit 时,Tx LOS、Tx / Rx CDR LOL、各项低侧告警 / 警告和 Rx Output 不会被置位;DPInitialized 下 Tx 输出被主机关掉或强制静音时,Tx 光功率低侧和全部 Tx 偏置 Flag 也不会。这些格子显示灰色 n/a——这一位是 0 不代表通道没问题,只是模块此时不报。Tx Failure、Rx LOS 以及高侧告警在任何状态下都会报,照常显示。告警汇总列里如果有部分 Flag 不适用,绿点旁会标 partial。

DP Changed —— 数据通道弹过的唯一证据

Lane Flags 表第一列是 DP Changed(11h:134)。按 CMIS 6.3.3, 模块在数据通道经过真实过渡后进入稳定态时置位这一位——换句话说, 它是模块自己记下的"这条通道掉下去又回来了"。

⚠ 链路弹一次之后,状态在前后两次刷新里都是 Activated, 光看状态列什么也看不出来。DP Changed 是唯一的线索。
它同样是 Flag——闩锁、读清——所以和其它标志一样,恢复后会保留 ●! 标记。模块复位后所有通道都会置位, 因为每条通道都重新走了一遍 DPInit,这是正常的。

Output —— 输出到底通没通

Monitoring 表新增一列 Output,分两行显示 Tx 和 Rx, 读的是 11h:132(OutputStatusRx)和 11h:133(OutputStatusTx)。 CMIS 5.4 Table 8-95 把这两个字节定为只读、必需: 1 表示该路输出信号有效,0 表示被静音或无效。

⚠ 输出状态要单独看。规范 8.14.2 写明输出状态 “independent of the state of the DPSM instances”——本工具里四个控制都能把输出静音:
① DataPath 页的 Tx Enable(10h:130 OutputDisableTx)
② Squelch 页的 Force Squelch Tx(10h:132)
③ Squelch 页的 Rx Output Disable(10h:138)
④ 模块自己的自动静音(丢失输入时)
其中 ③④ 不改变 DataPath State,状态列依旧是 Activated; ①② 按 Eq. 6-12 会把整条数据通道从 Activated 带到 Initialized (见下一节)——而 Initialized 下其余通道的 Tx 仍可能在发。 所以状态列说明不了哪一路输出是通的:Output 列会变成 ○,鼠标悬停会说明该去查哪个开关。

Lane Flags 表同时新增一列 Rx Output(11h:153)。 按 8.14.2,只有 Rx 侧有这个变化标志(闩锁、读清), 因为只有 Rx 输出的通断会让主机采取动作;Tx 侧规范明确说不定义。

ℹ 两次刷新之间静音一下又恢复的情况,11h:132 本身看不出来; 这个 Flag 是唯一的记录,和其它标志一样会保留 ●! 历史标记。

停用一条数据通道(DP Deinit)

DataPath Config 表里的 DP Deinit 那一列以前只是个显示(Deinit / Active), 点不动。而 10h:128(Table 8-78)按规范是 可读写、必需的,它是唯一能主动停用一条数据通道的手段。

ℹ 和 Tx Enable 不是一回事:取消 Tx Enable(或 Force Squelch Tx) 会让整条数据通道从 Activated 退到 Initialized(规范 Eq. 6-12)—— 已初始化、只是不算激活,其余通道的 Tx 照常发,重新勾上就经 TxTurnOn 回到 Activated; DP Deinit 才是真的把这条通道停到 Deactivated。

现在它是复选框。按 Table 8-78,一条 Data Path 的所有通道必须取相同值, 所以勾一个会自动带上同条通道的其余几路——在你按 Apply 之前就看得到 会发生什么。两条通道互不影响:停用后四路时,前四路照常运行。

ℹ 放开时通道会重新走一遍 DPInit 回来,因此会留下 ●! 标记(DP Changed)——与其它重新初始化 留下的证据一致。被停用的通道不会被 Apply 抬起来, 要恢复必须先取消勾选。
另:规范规定模块只在 ModuleReady 状态下评估这个字节, 所以主机可以在低功耗状态下先把全部位置上,阻止数据通道自动启动。

接口写入:只改你写了的,写错名字会报错

这一节只关系到直接调 REST 接口的人(写脚本、或让 Claude Code 驱动工具)。界面操作不受影响,因为它每次都把全部字段一起发。

⚠ 以前的行为:没提到的字段默认为 0。于是只设一个控制, 会把其余的静默地清掉,而且返回“成功”。
最危险的一处在数据通道接口:app_select 不提及就默认 全部为 1——只发一个极性改动,会把每一路的 Application 重配成 1。

被拒绝的请求,不会已经改掉一半

PRBS 一次请求里有四个引擎(主机/媒体侧的产生器和检测器)。它此前是校验一个、写一个:如果第四个引擎的参数非法,前三个已经写进模块了,然后才返回错误。

⚠ 看到报错的人——不管是操作员还是脚本——很自然会认为什么都没发生。而实际上主机侧产生器已经被重新配置了。
界面每次 Apply 都会把四个引擎一起发出去,所以只要给其中一个选了模块不支持的码型,就会踩到。

这条规矩激光器调谐接口一直就有(代码里写着「所有写入先算好并校验完,再一起下发」),只是没推广到 PRBS。现在 PRBS 也是:先把四个引擎全部算好校验完,再统一下发;任何一个不合法,一个字节都不写。

现在所有写入接口统一为:

⚠ 这条规矩当初只落实到那四个接口,另外三个漏了——而漏掉的恰好是后果最重的:
· PRBS:只改使能掩码、不提 patterns,每一条通道的码型都被悄悄改成 0 号(PRBS31Q),反相 / 字节交换 / FEC 位置掩码一起清零,然后回复「成功」。
· 激光器调谐:字段名拼错(target_power 少了 _dbm)被静默丢弃,通道号照改、发射功率没动,回复却是「参数已写入」。
· 通道交换:enable 拼成 enabled 直接被忽略,回复「成功」,什么也没切换。
界面每次 Apply 都会把全部字段发出去,所以点界面碰不到;这是走 API 时才会踩的。
ℹ 模块控制寄存器还有一个读写不一致的问题: 读回来叫 low_pwr_request_sw,写进去只认 low_pwr—— 五个控制里四个如此。把读到的状态原样写回去,四个控制都静默无效。 现在两种写法都接受。

❗ Apply 只重启你改过的那条数据通道

按 CMIS 6.2.3.3.1,Apply 必须对该 Data Path 的所有通道同时触发—— 是那一条通道,不是整个模块。工具以前每次都写 0xFF。

⚠ 后果:一个模块上跑着两个 400G 口时(比如 2× 400GBASE-FR4), 你只改了后四路的配置,前四路也会一起断—— 那个口你根本没碰过。
现在只对暂存配置真正发生变化的那几条 Data Path 触发。

分组依据是 Application 声明的主机通道宽度: 一个占 4 条通道的 Application,1–4 路和 5–8 路就是两条独立的 Data Path。 接口返回里多了一个 applied_lanes,写明这次到底重启了哪几路。

ℹ 什么情况下仍然全部重启:你什么都没改就点 Apply。 那是一个明确的“重新调试一遍”请求,静默地什么都不做等于拿掉这个能力。 只有能定位改动时才收窄。
ℹ 有些改动压根不需要 Apply:Page 10h 的 129–142 按规范是“独立于数据通道状态机或控制集”的直接控制: 极性翻转、Tx 关断、静默写下去就生效。 以前只翻一下极性再点 Apply,会为一个本来不需要 Apply 的改动 重启全部数据通道。
⚠ 有两种情况,模块会把 Apply 悄悄丢掉——工具以前照样回报「成功」。 规范写得很清楚:
一、数据通道正处在过渡状态(DPInit / DPDeinit / DPTxTurnOn / DPTxTurnOff)时收到的 Apply, 模块直接忽略(这条针对支持免中断重配置的模块——常规或热流程任一支持即算,只支持常规流程的模块同样适用);
二、ApplyImmediate 在 DPInitialized / DPActivated 之外的任何状态都会被忽略。
以前工具只挡住了第二条里「模块根本不支持免中断重配置」那半边, 两个状态条件都没查:把通道停掉之后马上点 Apply, 工具会返回成功,还会列出它「已经配置好」的是哪几条通道—— 而模块其实什么都没做。 「悄悄丢掉」是操作员唯一分辨不出来的失败: 你会以为这条链路已经在跑新配置了。
现在这两种情况都会被拒绝,并明确写出是哪条通道、当前在哪个状态, 例如「Lane 1 (Deactivated) 不在这两个状态里,请改用 Apply」。 仍然允许的是:停通道和 Apply 写在同一次请求里 (工具按规范的顺序写:停下的等到 DPDeactivated 再 Apply,放开的先 Apply 再放开),以及在 DPDeactivated 上用 Apply(规范推荐的正是这个用法)。 两种免中断流程都不支持的模块(Lower 02h AutoCommissioning = 00b)不做这项拒绝。
这类拒绝信息现在会在界面上停留 12 秒——原来的 3 秒不够把通道号读完。
另外还有第三种:上一次配置命令还在进行中(Config Status 为 ConfigInProgress)时收到的 Apply,模块也会忽略(规范 6.2.4.2),工具同样拒绝(409)并列出仍在进行中的通道,见「演示模块:两个端口可以同时重配」。
ℹ 模块在低功耗(ModuleLowPwr)时,DataPath 照样可以配置——这正是规范推荐的上电流程。 规范 8.13.1:DPDeinit 这个字节,模块只在 ModuleReady 状态下才会去读;同一段接着说: 主机可以在低功耗状态下先把全部 DPDeinit 位置上,阻止数据通道在上电后自动启动(附录 D.1.3 第 6 步)。 低功耗下所有数据通道都是 DPDeactivated,按 Table 6-3,这时的 Apply 是「只拷贝」: 校验暂存配置并拷进 Active Control Set,真正的初始化要等模块进入 ModuleReady。
所以在低功耗下:勾 DP Deinit、按 Apply 都会写入,提示「Provisioned in ModuleLowPwr」。 退出低功耗后,没被 DP Deinit 按住的数据通道按 Active Control Set 初始化; 被按住的保持 DPDeactivated,取消勾选才会起来。
ApplyImmediate 仍会被拒绝——它只在 DPInitialized / DPActivated 下起作用。 模块处于 ModuleFault(只响应复位)或 ModulePwrUp / ModulePwrDn 这两个过渡状态时,这三个操作会被拒绝,并写明模块当前在哪个状态。
10h:129–142 的逐通道控制(极性翻转、输出关断、Squelch)规范明确列为 「与数据通道状态机和控制集无关」、写入即生效;暂存 AppSelect 也只是写内存—— 这些在任何模块状态下都不受限制。
⚠ 点「进入低功耗」之后,面板以前显示的是按下之前那个状态。 模块在 01h:167 里自己声明了两个上电 / 下电过渡最长要多久, 本工具内置的分页演示模块,全都声明「下电最长 1–5 秒」。 可工具写完控制字节只等了 50 毫秒,页面再过 200 毫秒 就去读状态—— 对任何真按自己声明的时间来走的模块,这时读回来的还是按下之前的状态, 却被当作这次操作的结果显示出来。 于是:提示条是绿的(「已请求低功耗」),状态栏还写着 ModuleReady, 操作员自然会再点一次。
现在按模块自己声明的时间等,不再用工具里写死的数字: 状态一到就立刻返回(不会白等满 5 秒), 真等满了还没到,会明确提示模块现在在哪个状态、 以及这是按哪个声明(01h:167)等的。
软复位不宣称目标状态:它要先走 MgmtInit, 最后停在低功耗还是 ModuleReady,取决于它回来时那两个低功耗请求位—— 所以只等到「状态不再变化」为止。
软复位的等待时长是 MgmtInit 的最长 2 秒(Table 10-2 tMgmtInit)加上 ModulePwrUp 的声明时长;MgmtInit 期间模块可能完全不应答,工具会在这段时间内自动重试读取。
模块没声明这个时间时,退回到原来的等待时长。
进入低功耗时还有数据通道在跑,模块会先让它们停下(Eq. 6-6),全部到 DPDeactivated 才离开 ModuleReady(Eq. 6-4),所以等待时长还要加上 DPTxTurnOff(01h:168)和 DPDeinit(01h:144)的声明时长。
演示模块是瞬间切换的,所以这个问题在演示里看不出来—— 它只在按自己声明的时间走的真实模块上出现。
⚠ 同一类问题在媒体通道交换这里更糟:提交还在执行,面板却叫你「再按一次提交」。 模块在 6Dh:128 里声明了一次提交最长要多久, 工具本来就把这个值读出来并显示了,然后转头等自己写死的 100 毫秒。
对声明时间更长的模块,这时读回来的结果是 2:命令正在执行中——工具也正确解码成「进行中」, 可表格下面那行提示只看「生效了没有」,于是照样写着 「暂存的映射尚未生效 —— 请点提交」。 模块明明说了「我正在做」,界面却叫你把正在执行的命令再下一遍。
现在两件事都改了:按模块声明的时间等(而且做完就立刻返回, 不会白等满声明的上限——演示模块上这一步从 100 毫秒降到约 10 毫秒), 并且把「正在执行」和「根本没提交」分成两条不同的提示:
■ 提交仍在执行;本模块声明最长 10-50 ms(6Dh:128)
■ 暂存的映射尚未生效 —— 请点提交
另外,被拒绝(结果码 3–6)不会被当成「正在执行」—— 否则你会一直等一件早就失败了的事。
ℹ 演示模块现在会像真模块一样「换页要等」。 规范规定:写完选页寄存器之后,模块最多要 10 ms (或它在 01h:169 里声明的那一小部分)才会用新页回答; 等不够就会读回上一页的内容——这正是本工具最看重的一条时序规则, 漏了它的表现是时有时无的数据错乱,很难查。
以前演示模块是立刻换页的,所以它分辨不出「守规矩的上位机」和 「不守规矩的上位机」:真把那个等待删掉,演示里也一切正常。 现在演示模块换页后会先继续回答上一页,直到它声明的时间到了为止。
这不改变你使用工具的方式(工具一直是按规矩等的), 但它让这条规则真正被验证了:把等待去掉,测试会立刻大面积失败。 下位内存不受影响(它本来就不分页), 重复选中同一页也不会重新计时。
⚠ 修复:参考时钟丢失的提示,以前只出现一次就消失了。 14h:132.7 是锁存 + 读后自清的标志: 读一次就没了。它带出来的那句提示说的是—— 用参考时钟的发生器 / 检测器「在它恢复之前都不能当真」。 可这条提示以前只看当前这次读到没读到, 于是刷新一次就不见了, 看上去像是参考时钟已经回来了——而模块从没这么说过。 丢失期间产出和校验的数据,在标志被清掉之后依然是可疑的。
现在它和这一页上另外四个锁存标志一样被记住: 当前正丢失时还是原来那句警告; 只是历史上出现过时,改用淡色显示并写明 「这是发生过的记录,不是实时读数」, 点清除标志历史后消失。
顺带把演示模块也修对了:规范里 14h:132–139 整段都是「锁存 + 读后自清」, 而演示模块只对其中两个字节这么做—— 另外五个(参考时钟、两个发生器失锁、两个门控完成)读完还在。 这意味着「工具有没有把这些标志记住」以前根本没被验证过。

Signal Integrity:Apply 一并提交的另一半

点 Apply 提交的是整个 Staged Control Set, 而工具以前只读其中的 AppSelect 和几个掩码。 它的另一半是信号完整性(SI)控制,在 Page 10h 的 153–173(Table 8-83 / 8-84):自适应 Tx 均衡、主机控制的均衡目标值、 Rx CDR 旁路、Rx 输出均衡的前/后游标、Rx 输出幅度。

⚠ 以前这些既不读也不显示,于是工具每次 Apply 都在提交一组它自己也说不出名字的设置。更麻烦的是: ConfigRejectedInvalidSI(5h)本就是一个合法的拒绝理由, 工具也会把它显示出来——但它指向的值在界面上无处可查。
⚠ 超过 8 条通道的模块,这张表以前只有前 8 行。 Page 10h(暂存区)和 Page 11h(生效区)都是按 bank 分组的, 每个 bank 8 条通道;表里这六项全是逐通道的字段—— 自适应 Tx 均衡和 Rx CDR 是每条通道 1 个 bit, 另外四项是每条通道 4 个 bit(4 个字节装 8 条通道)。 也就是说,第 9 条通道起的设置在下一个 bank 的同一批地址上, 而工具这十二处读取全都停在 bank 0。
表格的行数是按读回来的长度铺的,所以结果不是报错,而是 DataPath 页列着 16 条通道、Signal Integrity 表却只有 8 行—— 正好在通道多到需要逐条看均衡设置的模块上, ConfigRejectedInvalidSI(5h)指向的那半边 后 8 条通道无处可查。
现在十二处都逐 bank 读。8 通道模块只有一个 bank, 行为和以前完全一样。

DataPath Config 页现在多了一张 Signal Integrity 表,逐通道列出这些值。 列是动态的——只列出 01h:161–162(Table 8-54)声明支持的那几项, 表尾写出模块声明的上限(01h:153–154)。 目前是只读的:先解决“看不到”,修改交给后续。

ℹ 两个容易读错的地方:
一是 Rx CDR 列的“Bypassed”不等于“关闭了某个开关”—— CDREnableRx 清零的含义是该通道的 CDR 被旁路,信号不再被重定时。
二是当模块只声明前游标控制时,按规范(Table 8-84) 后游标那几个字节里装的是前游标目标值—— 照地址直接叫它“post-cursor”就错了。遇到这种模块表上会先提醒,Rx EQ Pre 一列读的就是这几个字节(10h:166–169,生效值在 11h:227–230),模块会忽略的前游标字节(10h:162–165)不读(规范 6.2.5.2)。
ℹ 演示模块之前 Page 10h 的这一段是空的,读出来全 0—— 那意味着每一路 Rx CDR 都被旁路,而它同时声明自己有 CDR。 现已给出合理默认值。内置的 mock_sr8 故意 SI 能力较弱 (无主机控制 Tx 均衡目标、只有前游标),方便看到列变少的效果。

Rx 光功率读数是 OMA 还是平均功率

01h:151.4(Table 8-50)决定 Rx 光功率监控报的是 OMA(光调制幅度)还是平均功率。 这是两个不同的物理量,在调制信号上相差好几个 dB, 而接收灵敏度限值在规范里是按其中一个写的。

⚠ 以前 Rx Power 列只给一个 dBm 数,没说它是哪一个—— 拿它去对规范限值,对错了自己也不知道。 现在列头直接标出 · OMA 或 · Average power, 鼠标悬停给出寄存器位。

同一个字节里还有几位值得知道:151.7 探测器是 PIN 还是 APD;151.3 Rx LOS 响应的是 OMA 还是 Pav(与上面那位独立); 151.2 / 151.1 是 Rx LOS 和 Tx 关断的快速模式时序。

❗ 有些模块的 Tx Enable 不是逐通道的

01h:151.0(TxDisableIsModuleWide)置位时, 任何一路的 OutputDisableTx 会关掉全部 Tx 输出。

⚠ 而 DataPath Config 页给的是 8 个看上去相互独立的复选框—— 它们说的正好相反。在跑着的链路上,取消勾选第 3 路的代价是 另外七路一起断。
现在这类模块上,勾任意一个框会八个一起动(和模块实际行为一致), 表格上方也会先写明这件事。逐通道的模块不受影响。
ℹ 内置的 mock_fr4x2 故意声明为模块级 Tx 关断, 方便你在没有硬件时看到这个行为。

Aux1–3:同一个寄存器,意义由一个位决定

下部内存 18–23 是三个普通的 S16 寄存器, 但它们到底测的是什么,由 01h:145(Table 8-50)里的三个位决定:

寄存器位 = 0位 = 1
Aux1 Lower 18–19 自定义(厂商定义,无通用单位) TEC 电流
Aux2 Lower 20–21 激光器温度(1/256 °C) TEC 电流
Aux3 Lower 22–23 激光器温度(1/256 °C) 附加电源电压(100 µV)
⚠ 不读 01h:145 就拿这三个数,它们既没有单位也没有含义—— Aux2 的同一个数可能是摄氏度,也可能是 TEC 电流百分比。 工具此前把它们原样返回、界面一个都不显示, 于是制冷模块的激光器温度和 TEC 电流就白白扔了。

现在 Module Info 里按声明的含义逐行列出,带各自的单位。 TEC 电流是有符号百分比(占模块最大 TEC 电流幅度的比例): 正值是加热,负值是制冷。规范里没有任何寄存器给出那个最大值, 所以无法诚实地换算成安培,工具也不会自己编一个。

ℹ 01h:159.4-2 声明这三个监控到底存不存在。 不存在就一行也不显示,而不是显示三个 0—— 0 °C 和“TEC 没在工作”都是看上去很合理的读数。 非制冷模块(内置的 DR8 / SR8 / FR4)本来就没有; 两个相干演示模块是制冷的,三项都有。

输入框里的笔误不再被截成别的数

页面以前用浏览器的 parseInt 读输入框:它读到第一个不认识的字符就停下,把前面那段当结果。服务端从 v2.204.0 起会拒绝格式不对的数据,可它收到的已经是截好的数,所以下面这些笔误一条都没被拦下:

现在:0x50 和 50h 是十六进制,只有数字的是十进制,其余都算写错;Write Data 的每一项都必须是十六进制字节,空格或逗号分隔;数字框里必须是数字(Laser 的微调偏移留空表示不微调,Bus 和 Bank 留空按 0)。写错时提示会点出是哪一格,这一次什么都不发给模块。通道计数复位把所有通道号原样交给服务端,由它指出模块没有的那一条。Raw Registers 的 Bank 提示在页号还读不出时显示 Not a page yet,不再显示 Page 0xNAN。

手册:后端列表、可调谐模块和读取失败时的卡片按实际更正

第 1 章「支持的接口后端」表和 6.1 节写于只有 5 个演示模块、3 种适配器的时候:mock_flat_dac 和 ftd2xx、cp2112、mcp2221 两处都没有。两处连同 10.7 节还说只有 mock_coherent_zr 可调谐、可调谐看 Media Interface Technology——mock_zr16 也可调谐,工具按 01h:155.6 判断。5.5 节把 SNR 列在「读取失败时旧数值原样留着」的卡片里,实际上 SNR 和 Laser Tuning 会把表格换成一行失败原因;真正留着旧数值的 Module Info 和带 5.4 标记的卡片反而没列。现已逐条改正。新增测试让每张卡片的读取各失败一次,按它实际的表现核对 5.5 的名单,并把两处后端列表和可调谐模块跟工具实际的列表对照。

手册:常见问题 Q3 / Q5 / Q7 和通道数明细的说法按实际更正

第 13 章的几条回答写得早,没跟着工具变:Q3 说 Backend 下拉只列 4 个演示模块、没有 USB 适配器——实际总是列出全部 12 个演示模块和 6 种适配器,找不到的适配器置灰并标 (unavailable);Q5 写的是 −inf dBm,页面显示的是 −∞ dBm;Q7 说只有 mock_coherent_zr 可调谐、并按 Media Interface Technology 判断——mock_zr16 也可调谐,工具按 01h:155.6 判断,卡片显示的是 Non-tunable module。另外,Module Info 的 Host Lanes 一行说明细里用「·」分隔的应用「是二选一,不是相加」,而 2×400G 这类模块的两个应用占不同通道、同时运行,前面的 8 正是二者之和;现已改为如实说明两种情况。新增测试把这几条回答和工具实际的后端列表、可调谐判断、页面文字逐条对照。只改文档,工具行为不变。

手册:裸寄存器写入的拒绝清单按实际补全

第 11 章说裸寄存器写入「会被拒绝的只有五种」,并列了五条;v2.204.0 又加了几种(缺页号或地址、数据字节超出 00h–FFh、页号/地址/Bank 不是整数),清单没跟上,Page 9Fh 上包含字节 129 的长写和 Bank 不对这两种也只在别处提过。现在这一节不再报数目,完整列出每一种拒绝和对应的提示文字;另在「Apply 只重启你改过的那条数据通道」一节补上第三种被模块忽略、工具也会拒绝的情况:上一次配置命令仍在 ConfigInProgress。只改文档,工具行为不变。

手册附录「会中断业务的按钮」补全并更正

附录里这张表此前只列了 Reset Module、Enter/Exit LowPwr、Write、DataPath Apply 和 Loopback Apply,其中 DataPath Apply 一行仍写着「重启全部 8 条 lane」(上一版已更正正文,这里漏改);还写着「只有 Reset Module 有确认对话框」——媒体通道切换的 Commit 也会先弹确认框。

现在表里补上了同样会影响业务的 Output Controls Apply(强制静默、关闭接收输出)、媒体通道切换 Commit、PRBS Apply(发生器用测试码型取代业务数据)和 Laser Tuning Apply,DataPath Apply 一行按实际行为改写,确认框一句改为「只有 Reset Module 和媒体通道切换的 Commit 有确认对话框」。只改文档,工具行为不变。

DataPath 页:只改极性或 Tx 关断时,Apply 不再重启数据通道

规范 Table 8-77:10h:129–142 是「独立于数据通道状态机和控制集」的通道控制,极性翻转、Tx 关断写下去就生效,不需要 Apply。页面上改这两项只能通过 DataPath 表的 Apply 按钮,而这个按钮总会请求 Apply;工具把「暂存配置没有变化」一律理解为「重新投运」,于是只翻一条通道的极性,也会重启模块上所有数据通道——在 2×400G 的模块上,两个 400G 端口一起断流。手册从 v2.10.1 起就写着「不会这样」,实际一直是这样。

现在:一次提交里只改了极性或 Tx 关断(AppSelect、NAD 块号、DP Deinit 都没变)时,只写这些通道控制,不触发 ApplyDPInit,接口返回 applied_lanes: [],页面提示「Lane controls written … no Data Path was restarted」。什么都没改就点 Apply,仍然是「重新投运全部」;改了 AppSelect 时,只 Apply 改动的那几条数据通路;DP Deinit 的处理不变。

DataPath 页:有通道暂存在其它 NAD 块时,整张表显示不出来(v2.202.0 引入)

v2.202.0 为「暂存在块 0 以外的通道」在下拉框里加了一项「AN n … — kept」。这一项用到了两个在同一函数里更靠后才声明的名字,浏览器在遇到第一条这样的通道时就报错(Cannot access 'bankOf' before initialization),DataPath 配置表整张不显示——恰好发生在这一项要照顾的模块上。之前的检查只核对了源代码里的文字,文字看不出声明顺序;这次是在浏览器里实际操作 24 通道演示模块时发现的。

现在声明已前移,表格正常显示:通道 1 显示「AN 16 (NAD Block 1, AppSel 1) — kept」,下面照常列出媒体通道和「running App 1」。另外新增了一组回归检查:把页面脚本在 Node 里真正跑一遍,对每个演示模块(以及 NAD 块、Network Path 应用这两种状态)依次执行每个页签的加载函数,任何一个抛出异常就算失败。

激光调谐和连接:同样严格检查字段

上一版的字段检查在激光调谐接口上是用一个不可调谐的演示模块做的——那里每个请求本来就会因「模块不可调谐」被拒绝,所以其实没测到字段本身。换成可调谐的演示模块后,问题和其它接口一样:grid_code、channel、fine_offset_ghz、target_power_dbm 给字符串或 null 得到 500;channel: 0.5 被当成信道 0;true 被当成 1 GHz 的微调偏移或 1 dBm 的目标功率并写入;grid_code: 21 被截成 5(100 GHz);fine_tuning_enabled: "no" 反而打开了微调。

现在:grid_code 是 0–15 的整数(12h:128 高 4 位),lane、channel 是整数,偏移和功率是数字(不收 true;NaN、无穷大会被模块声明的范围拒绝),fine_tuning_enabled 只收 true / false,都在写入之前检查。

连接接口(/api/connect)以前把 true、1.5、-1、256 原样交给 I2C 适配器当总线号或地址。现在地址必须是 0–127 的 7 位 I2C 地址(模块在 80 = 50h),总线号是 0 或以上的整数;十六进制字符串(如 "0x50")照旧可以。被拒绝时,当前连接保持不动。

写入接口:类型或范围不对的值一律拒绝(400),不再被截断、猜真假或补零

对每个写入接口的每个字段逐一送入错误类型和越界的值,发现三类问题:

所有拒绝都发生在写入任何寄存器之前。界面本来就只发送合规的值,日常操作不受影响;受影响的是脚本和直接调用接口的程序。

NAD 块号不为 0 的通道:数据通路按它自己的描述符划分,不再被改成单通道

上一版起,AppSel 没变的通道保留它的 NAD 块号。但工具把通道分成数据通路(写 DPIDX、按整条数据通路 DP Deinit、决定 Apply 哪几条通道)时,仍按基本描述符里同一个 AppSel 的宽度来算——块 b 里的 Application 是 AN = 15b + AppSel,宽度、起始通道、媒体通道都是它自己的(Table 8-173)。实测:块 1 里一个 8 通道的 Application,只点一下极性翻转,暂存的 DPIDX 就被改写成 8 条单通道数据通路(0x30、0x32 … 0x3E),下一次 Apply 模块会回 ConfigRejectedInvalidDataPath;面板把这 8 条通道一条条分开显示,起始通道按错的位图判断,也算不出媒体通道。

现在所有「哪些通道是同一条数据通路」的计算都按 Application 编号(块 0 为 AppSel,其它块为 AN)进行,块 0 以外的描述符从 Page 1Ch 读取——只在确有通道处在其它块时才读。块 0 的通道仍按基本描述符(规范要求块 0 与之一致,不一致时面板另有提示)。起始通道提示里,块 0 以外的应用写作 AN n。

带 NAD 的模块:Application 按「块号 + AppSel」暂存和显示;AppSel 超出 0–15 被拒绝

规范 6.2.1.7 和 8.21.1:模块支持 Normalized Application Descriptor(NAD,Page 1Ch)时,一条通道的 Application 是它的 AppSel 码加上 NAD 块号,AN = 15 × 块号 + AppSel。暂存的块号在 18h:128–135(Table 8-166),运行中的在 19h:144–151(Table 8-171),两者都是「Page 1Ch 支持时必有」。工具此前只读写 AppSel 码:某条通道暂存的块号不是 0 时,在 DataPath 下拉框里选一个基本 Application(块 0),模块实际暂存的是块号不变、同一 AppSel 码的另一个 Application;面板把运行中的 AN 16 也显示成「App 1」。演示模块(24 通道)声明了 NAD,却没有这两页。

现在:

Network Path 应用(NP)单独标出,通道数按网络通路计算

规范 8.19.5.3:支持 Network Path 应用的模块,要在 16h:248–249(Table 8-158,ExtAppDescriptor)里逐个声明每个 AppSel 是 DP 应用还是 NP 应用;01h:142.7 声明模块有 Page 16h。7.6.4:NP 应用的描述符是「部分」的——每个起点是一条 Host Path,若干条 Host Path 复用同一条 Network Path(媒体侧)。工具此前从不读这两个字节,把 NP 应用当成普通数据通道;而主机 / 媒体通道数把每个起点都算成一条自带媒体通道的数据通道,所以 NP 应用没有被更宽的 DP 应用盖住时,媒体通道数会多算:附录 H 表 H-6 的模块去掉两个 400G 应用后,显示 8 / 6,实际是 8 / 5。

现在:模块声明了 Page 16h 时,工具读取 16h:248–249。Supported Applications 表的 AppSel 旁标出 NP(悬停说明:Host Path 只到 DPInitialized,不会到 DPActivated,7.6.2;Network Path 在 Page 16h 配置,本工具没有这个面板);DataPath 下拉框的这一项注明 NP Application (Host Path)。Module Info 的 Host Lanes / Media Lanes 里,NP 应用的媒体通道按网络通路算一次:MediaLaneAssignmentOptions 每个起点是一条网络通路,按顺序由相邻的若干条 Host Path 共用(8.19.5.5);同一混合复用的几个描述符(同一个 MediaInterfaceID、同一媒体起点)也只算一次。括号里的明细写成 AppSel#3 (NP): 1H ×8 → 1M ×2:8 条 Host Path,进 2 条网络通路。接口回复里每个应用多了 np_application。附录 H 的表 H-1、H-5、H-6 已写成回归测试。内置演示模块都没有 NP 应用,显示不变。

停下再换应用:DP Deinit 与 Apply 按规范顺序写入,被拒绝的通道保持停下;过渡状态中的 Apply 一律拒绝

规范 6.2.4:「支持免中断重配置流程时……模块会悄悄忽略在过渡状态(DPInit、DPDeinit、DPTxTurnOn、DPTxTurnOff)中收到的请求」,附录 E 的图 E-19 也这样标注——两种流程(常规 ApplyDPInit、热 ApplyImmediate)任一支持即适用。工具此前只看模块是否支持热重配置,所以只支持常规流程的模块(Lower 02h:SteppedConfigOnly = 1、AutoCommissioning = 01b,演示模块 DR8 就是)在过渡状态里点 Apply,会被发出去、被模块丢掉,工具却回报成功。演示模块也没有丢弃这种触发,所以一直没被发现。

现在只要模块支持任一流程,过渡状态中的 Apply 都会被拒绝(409)并写明是哪条通道;两种都不支持时 ApplyDPInit 只做写入(规范 Table 6-4,任何状态都接受),不拒绝。演示模块现在也按 6.2.4 在这种情况下丢弃触发。

同一次提交里既改 DP Deinit、又点 Apply 时,工具以前先写 DPDeinit、紧接着写 Apply 触发,触发总是落在 DPDeinit 或 DPInit 这两个过渡状态里。规范第 80 页:Apply 只能在所选通道处于稳定状态时置位;Table 6-3:对 DPDeactivated 的数据通道做 ApplyDPInit,是把暂存配置拷贝进 Active Control Set,放开后 DPInit 按 Active Control Set 投入运行。于是在支持免中断流程的模块上,这个触发被丢掉,放开的通道按原来的 Application 起来——规范 6.2.4.3 唯一允许的换宽度流程(停下 → 换应用 → 放开)做不成。演示模块此前把「放开 DPDeinit」当成一次 Apply,按暂存区的配置启动并报告 ConfigSuccess,所以演示里看不出来。

现在的顺序:要停下的通道先写 DPDeinit,等它们到 DPDeactivated(按模块声明的 DPTxTurnOff + DPDeinit 时长,01h:143-144、01h:168)再发 Apply;到时还没停下就不发 Apply,返回 504 并写明是哪条通道。要放开的通道保持按住,先发 Apply,等 Config Status 不再是 ConfigInProgress 才放开;新配置被拒绝(Table 8-101 任一拒绝码)的通道保持停下,界面提示是哪几条——放开它只会按原来的 Application 起来。接口回复新增 kept_deinit。演示模块放开 DPDeinit 时现在按 Active Control Set 启动,不再为此报告新的 Config Status。

Module Info:只做分支(breakout)的模块,通道数不再少算

Application 描述符的 HostLaneAssignmentOptions 列出这个应用可以从哪几条主机通道起始,每个起点都是一条可以并排运行的数据通道——规范附录 C-1 的例子:2 条通道的 100GAUI-2 起点为 55h(1、3、5、7),就是「四个并行的 100GBASE-DR 收发器」。工具计算 Host Lanes / Media Lanes 时每个应用只算了最低的那个起点,所以一个只广告 4×100G-DR 的模块显示 2 / 1,而不是 8 / 4。现在每个起点都算一个实例,重叠的不重复计算。括号里的明细也改了:应用之间是「二选一」,不再用「+」连接,改用「·」;有多个起点的应用标出实例数,例如 AppSel#2: 2H/1M ×4。

演示模块里有源光缆(mock_aoc)的第一个应用是 4 条通道、可从 1 或 5 起始,现在显示 8 / 8(原来 4 / 4);其它演示模块数值不变。附录 C 的四个例子(C-1 至 C-4)已按原表写成回归测试。

PRBS:先写码型、最后写使能;门控中途停下的计数标为可能无效

规范附录 F.1 / F.2 给出启动码型发生器 / 检测器的推荐顺序:先配码型和选项(13h:145-151、161-167 等),最后写使能(13h:144 / 160)。规范 5.2.5.2 又说多字节 WRITE 一般不是原子的。工具此前把每个引擎的 8 个字节一次写入、使能字节在最前,模块可能先按旧码型启动——检测器会按旧码型开始计数。现在先写码型与选项,再单独写使能字节。

附录 F.2 还说:门控测量进行中关掉检测器,所有误码计数都未定义(视为中止)。BER 和计数器面板对停下的检测器显示「held」(保留的结果)——不门控时这是对的,门控时只有在门控结束后才停下才算结果。模块不告诉主机停下时门控是否已结束,所以门控测量下这些格子保留数值,但标「undefined if stopped mid-gate」并在悬停里说明。

非可调谐模块上 Laser Tuning 的 Apply 不再可点

这一版把 12 个演示模块的每个 Apply 按钮都按了一遍(DataPath、Squelch、Apply Immediate、采集计数清零、媒体通道切换、环回、PRBS、激光调谐),只找到一个注定失败的:Laser Tuning 卡片在非可调谐模块上写着「Not a tunable laser module」,Apply 却仍可点,一点就是红色的「This module is not tunable (01h:155.6)」——12 个演示模块里有 9 个是这样。现在没有可写的内容时(非可调谐,或读取失败)Apply 变灰,悬停说明原因;换到可调谐模块后恢复。服务器端的拒绝保持不变。

Media Type 按 Table 8-20 原文命名:03h 包括线性有源铜缆

规范 Table 8-20 把介质类型 03h 叫作 Passive and Linear Active Copper Cables(CMIS 5.3 起把无源铜缆的相关数据扩展到了线性有源铜缆),工具显示的是「Passive Copper」——等于说线性有源铜缆是无源的。其它几项也是简写。现在 Module Info 的 Media Type 按原文显示(Optical Interfaces: MMF / SMF、Active Cables、BASE-T)。Rx 输出均衡类型的 00b 也补上了原文的「or no information」。

Media Interface 按 Table 8-41 原文命名

Module Info 的 Media Interface 行(00h:212)注明按 Table 8-41 解码,但显示的是简写:「Copper unequalized」原文是 Copper cable, passive, unequalized,「1310 nm DFB」原文是 1310 nm DFB laser,「Other」原文是 Others——两个无源铜缆编码的简写把「passive」丢了。现在 21 个编码全部照 Table 8-41 原文显示(0Fh 带上原文的「deprecated, do not use for new designs」)。

接口编码 00h 显示 Undefined,不再显示 Unknown

SFF-8024 Rev 4.14 的主机接口表和五张媒体接口表(Table 4-5 至 4-10)都给 00h 起了名字:Undefined;连接器表(4-3)的 00h 是 Unknown or unspecified。工具的表里没有 00h,Supported Applications 于是显示 Unknown (0x00)——而手册里 Unknown 的含义是「比工具的编码表更新的编号」,等于说模块用了工具不认识的编码。现在按 SFF-8024 显示;连接器 00h 也改为 Unknown or unspecified。

Raw Registers:发出 CDB 命令后等模块处理完;CDB 页的 Bank 是 CDB 实例

规范 Table 10-4:写到 9Fh:129 发出 CDB 命令后,模块可以拒绝一切访问——前台模式(01h:163.5 为 0)一直到命令执行完(最长为模块声明的忙时间,上限 tCDBF 4960 ms),后台模式在接收命令期间(tCDBC 80 ms)。工具在任何写入之后只重试 tWRITE(10 ms),所以在处理稍久的模块上,Raw Registers 写完 CDB 命令头后的回读会失败。

现在写到 9Fh:129 之后,工具按模块的模式把重试窗口放宽到对应时间(前台取 Table 8-55 两种读法里较长的忙时间),结果区写明「CDB command sent (9Fh:129)」、处理模式和等待上限;命令完成显示在 Module Info 的 CDB Command Complete。

规范 7.2:「CDB 实例 1 的相关页在 Bank 0,实例 2 的在 Bank 1」。9Fh 和 A0h–AFh 上的 Bank 是 CDB 实例,不是 8 条通道一组。工具此前按通道 Bank 数判断能不能选、结果区也写成「lanes 1-8」——8 通道、两个 CDB 实例的模块选不到实例 2,16 通道、一个实例的模块却能选到并不存在的 Bank 1。现在这些页按 01h:163.7-6 的实例数判断,结果区写成 Bank 0 · CDB instance 1,Bank 输入框下的提示也写明实例数。

演示模块:支持 CDB 的演示模块现在有 Page 9Fh,执行 CMD 0000h(Query Status),其它命令号按「CMDID unknown」失败;按模块的模式在处理 / 接收期间拒绝访问,完成后更新 CdbStatus(Lower 37)并置 CDB 完成标志。

Monitoring:违反规范约束的通道-波长映射会被标出

规范 8.14.8:波分应用里最短的波长编号为 1,其余从短到长连续编号;「违反这些约束的 Table 8-107 映射是无效的」。编码 1001b–1111b 是保留值。工具此前把 11h:240–255 的任何映射都当事实写在 Lane 号下面,保留编码则和「未知」画法一样。

现在:映射里有保留编码,或者用到的波长编号不是从 1 开始连续编号(按整个模块算,16 通道模块第 9 条起可以接着编 5–8,也可以重新从 1 编)时,Lane 号下的小字前加 ▲,悬停写明原因,表格下方也用一行说明映射无效。演示模块的映射都有效,行为不变。

Raw Registers:密码按 8.2.14 写,只写字节不再误报

规范 8.2.14:密码寄存器「必须用大小匹配的 4 字节 WRITE 写入」,结果「最终」报在 PasswordCmdResult(Lower 42),显示「校验中」时主机不应再用密码寄存器。Raw Registers 此前接受任何写法(例如一次 8 字节把两个区都写了),写完也从不看 Lower 42,所以写密码得不到任何结论。更糟的是写后回读比对把只写字节也算进去——密码区和 Apply 触发字节读回来都是 0,于是每次写密码或 Apply 触发都弹出红色「module reports different values」。

现在:密码寄存器只接受整 4 字节、只写一个区的写入;写完读 Lower 42,结果显示在转储区和提示里(模块报「校验中」时在 tWRITE 内再问);上一次还在校验中时拒绝新的密码写入。回读比对跳过只写字节,并在转储区列出。演示模块实现了 host / module 密码、修改 host 密码、错误密码或复位后重新锁定。

Module Info:补上 Table 8-18 和 01h:251 的其余广告

规范 Table 8-18(Lower 56–63)里的字段都是必需的(Rqd)。工具此前只显示了 56、57 和 61 的散热器类型:模块子类型(Lower 60)和光纤端面(61 的低两位)连接时读了却没有显示,LowPowerRestrictions(Lower 62,Table 8-19,CMIS 5.3 新增)根本没读;平坦内存模块上 60–62 一个都没读,尽管它们和 56–57 一样在 Lower Memory。Page 01h 的 Table 8-62 也有同样的缺口:01h:251 的四项广告(其中「整页读取」本来就决定着工具按多大的块读)和 01h:252.6 链路训练都没有对应的行。

现在 Module Info 多出这些行:

演示模块:相干模块声明在 ModuleLowPwr 下不支持会改变固件状态的 CDB 命令,其余模块没有限制。第 7 章字段表同步补上这八行。

PCIe 线缆的衰减按 PCIe 频点标注;PCIe 接口编码带上代次

规范 Table 8-35 下的注释:模块声明自己是 PCIe 应用时,00h:204-208 这五个衰减值对应 2.5、4.0、8.0、16.0、32.0 GHz,而不是 5、7、12.9、25.8、53.125 GHz。工具此前不分模块一律按后一组频点标注——PCIe 线缆在 32 GHz 的损耗会被写成 53.125 GHz 的损耗。

现在:线缆组件任一 Application 的 Host Interface 是 SFF-8024 的 70h–73h 时,Module Info 的 Cable Attenuation 行按 PCIe 频点标注,并在说明里写明原因。平坦内存模块的 Application 描述符第四个字节是 HostInterfaceGID,只有 GID 为 0(SFF-8024 自己的表)时 70h–73h 才算 PCIe。

另外,SFF-8024 Table 4-5 里这四个编码的名称是 PCIe 4.0、PCIe 5.0、PCIe 6.0、PCIe 7.0;工具此前四个都只显示「PCIe」(表里印在它们上方的分组标题)。Supported Applications 表现在显示完整名称。

手册第 7 章:Module Info 的每一行都能查到

第 7 章的字段表是对照 Module Info 查某一行含义的地方,但它落后页面约四十行——CDB、CDR、状态机、各类页面支持位、远端分支、线缆衰减、页校验和、Aux 监控等行在以往的发布说明里介绍过,却没有进这张表。现在全部补齐;两处名称按页面改正(Connector、Media Interface);原来放在这里的 Host / Media Interface ID 说明移到 9.2 Supported Applications;Tx Bias 行的倍率出处更正为 Table 8-53。这一节只改手册。

手册勘误:通道 Flag 的 Mask 在 Table 8-91

「标志与屏蔽的对应」表里,通道级 Flag(11h:134-153)的 Mask 10h:213-232 此前标注为 Table 8-83;Table 8-83 是 Staged Control Set 0 的 Tx 控制,Mask 所在的是 Table 8-91(Lane-Specific Masks)。已更正。工具的行为没有变化。

CMIS 4.x 模块:Flag 汇总和输出状态不再按 5.x 规则显示

CMIS Rev 5.0 修订记录里另有两条和 4.x 模块不兼容:「Flag summaries now indicate bank and page (instead of bank and lane)」(Lower 4–7 的含义变了),以及「Added OutputStatusRx ... and OutputStatusTx」(11h:132–133 是 5.0 才加的)。

⚠ 上一版只在 CMIS Revision 行说明了这两项仍按 5.x 读。实际效果是:4.x 模块的 11h:132–133 读出来是 0,Monitoring 的输出列把每条通道都显示成「输出无效」;Interrupt 行把按「Bank + 通道」编码的汇总当成「Bank + 页」解读,写出的页名并不是模块说的意思。

现在:4.x 模块上,Monitoring 的输出列显示「n/a (CMIS 4.x)」,Interrupt 行注明「Flags summary not decoded: before CMIS 5.0 it meant bank and lane」,CMIS Revision 行的说明相应改为「Flags summary and output status not shown」。5.x 模块不受影响。

CMIS 4.x 模块:33/75 GHz 栅格代码按模块版本换算,版本差异在 CMIS Revision 行说明

CMIS Rev 5.0 的修订记录:「Frequency grid encoding in field (12h:128-135.7-4) has swapped the codes for 33GHz and 75 GHz」。也就是说,声明 CMIS 4.x 的模块(不少早期可调谐 400ZR 模块就是)在 12h:128–135 里用 6 表示 75 GHz、7 表示 33 GHz,和 5.x 正好相反。附录 G.3:模块主版本号不高于主机时,主机可以通过适配旧版本来管理它;主版本号更高的模块「可能不按主机的预期工作,因此无法管理」。

⚠ 工具以前一律按 5.x 编码读写栅格:在 CMIS 4.x 模块上,75 GHz 栅格会被显示成 33 GHz,由此算出的频率也是错的;在 Laser Tuning 里选 75 GHz 写下去,模块收到的是 33 GHz。CMIS Revision 这一行也从不说明版本差异。

现在:工具内部仍用 5.x 代码,只在读写 12h:128–135 时按模块的主版本号换算(6、7 互换);04h:128 的栅格支持位没有改过编号,不需要换算。CMIS Revision 行对 4.x 模块标 ▲,写明哪些已换算、哪些仍按 5.x 读(Lower 4–7 的 Flag 汇总在 5.0 前是按 Bank 和通道,11h:132–133 的输出状态是 5.0 才加的);对主版本号高于 5 的模块标 ▲ 并引用附录 G.3。另外更正:v2.182.0 的说明把「Apply 触发字节只能单字节写」写成了 CMIS 5.4 的新限制,它其实是 Rev 5.0 引入的。

Module Type:标识符按 SFF-8024 的原表命名,非 CMIS 模块会被标出

Lower 0x00 的模块标识由 SFF-8024 Table 4-1 定义。CMIS 8.2.1:主机要拿它对照一张支持的标识列表,模块被识别为 CMIS 模块之后,其余字段才能按 CMIS 解读。

⚠ 工具里的标识名称表是凭印象写的,和 SFF-8024 对不上:1Fh 写成 OSFP(实为 SFP-DD)、20h 写成 x4 MiniLink(实为 SFP+ with CMIS)、22h 写成 QSFP-DD(实为 OIF-ELSFP)、23h 写成 QSFP56、24h 写成 OSFP-XD(两者实为 CDFP)、25h 写成 CMIS-Compliant(实为 CDFP x16),1Eh 写成「QSFP-DD CMIS」(原表是「QSFP+ or later with CMIS」);21h OSFP-XD、26h XPO 缺失,保留值和厂商自定义值都显示成 Unknown。连接器类型的保留值和厂商自定义值同样显示成 Unknown。另外,接上一个 SFF-8636 的 QSFP28,工具也照样按 CMIS 解读整页,不加任何提示。

现在:标识名称按 SFF-8024 Rev 4.14 Table 4-1 逐条给出,保留值显示 Reserved、80h 以上显示 Vendor specific;连接器类型同理。标识在 Table 4-1 里写明用别的管理接口时,Module Type 行标 ▲「not a CMIS module」。演示模块的标识是 1Eh,现在显示为「QSFP+ or later with CMIS」。

平坦内存模块:三个标签页说明原因,不再逐项报错

规范 8.2:平坦内存(静态)模块只有 Lower Memory 和 Page 00h。Monitoring、DataPath Config、Diagnostics 三个标签页读的是 Page 02h、04h、10h–14h,这种模块上都没有。

⚠ 以前在无源铜缆上切到这三个标签页,每张卡片各自去读、各自被拒绝、各自弹一条红色错误——三个标签页一共十二条,「5.4 pages error」每个标签页都弹一次;Monitoring 还显示「读数已过期,等模块恢复响应后按 ↻ Now」。模块其实一直在正常响应。

现在:平坦模块上这三个标签页不再去读它没有的页,顶部用一行说明「Flat memory module … it has only Lower Memory and Page 00h (CMIS 8.2), so it has no …」,并写明缺的是什么;DataPath Config 保留 Supported Applications(它在 Lower Memory 里)。换接分页模块后一切照常。

同样的情况也出现在没有声明诊断页(01h:142.5 为 0,没有 Page 13h–14h)的分页模块上:Diagnostics 页的环回、PRBS、BER、SNR、计数器五张卡片以前各弹一条错误。现在顶部说明一次,只保留 Laser Tuning(它在 Page 12h)。

Module Info:平坦内存模块(无源铜缆)不再是空白页

平坦内存(静态)模块只有 Lower Memory 和 Page 00h。规范里 Table 8-6(模块状态、Interrupt)和 Table 8-8(Flag 汇总)对它适用,Table 8-9 到 8-12 和 8-16(模块 Flag、监控值、控制、Mask、故障原因)标题都写着「not for static memory modules」。

⚠ 从 v2.80.0 起,状态接口对平坦内存模块一律拒绝(为了不去读它没有的页),而 Module Info 页要状态和身份两个请求都成功才会显示——结果所有无源铜缆的 Module Info 页都是空白,只弹一个「Status error」。演示用平坦铜缆在此之外还有三处不对:Interrupt 显示「已触发」(它根本没有 Flag),连接器是 MPO、介质技术是 1310 nm EML(照抄了光模块的配置)。

现在:平坦模块的状态只读 Lower Memory,返回模块状态、Interrupt 和 Flag 汇总;Temperature、Supply Voltage、Module Flags、Module State Changes、Firmware Faults 几行显示「not for static memory modules (Table 8-x)」,Module Restarts 显示「no Page 13h」。演示用铜缆的 Interrupt 不再触发,连接器改为「No Separable Connector」(23h),介质技术改为「Copper cable, passive, unequalized」(0Ah)。

Module Info:线缆组件和平坦内存模块的几行按自己的规则读

规范 8.3.8:线缆组件(Media Type 03h 无源铜缆、04h 有源线缆)的介质不可拆卸。三个字段在线缆上的含义和可拆卸光模块正好相反:00h:202 线缆长度(光模块写 0)、00h:211 远端分支(可拆卸介质时清零,代码 0 的名字就是「可拆卸介质模块」)、01h:132–137 光纤链路长度(8.4.2:有源光缆必须全写 0,长度改报在 00h:202)。

⚠ 平坦内存模块没有 Page 01h,但 Module Info 照样去读 01h:128–137,读回来的是 Page 00h 的标识符和厂商名:演示用无源铜缆显示「Inactive FW 30.79」「HW Revision 80.69」和五种光纤的链路长度,全是厂商名的字母。同样,线缆报远端分支代码 0 时,这一行写的是「module with detachable media」;报 0 长度时写的是「transceiver」。演示用有源光缆自己也不合规范:它报了 0.5 km 的 SMF 链路长度,远端分支是 0。

现在:平坦内存模块不再读 Page 01h,这三行显示「no Page 01h」(扩展的 Application 描述符 01h:223–250 同样不读);Cable Length、Link Length、Far End Breakout 按模块是不是线缆组件判断,值和模块类型矛盾时标 ▲ 并说明;演示用有源光缆改为链路长度全 0、远端分支代码 2(整根线缆接一个 8 通道远端模块)。

Raw Registers:所有 Apply 触发字节都按只写、单字节处理

CMIS Rev 5.0 修订记录(v2.182.0 的说明误写为 5.4,本版更正):「Apply* 触发寄存器只允许单字节 WRITE(新限制)」;这些字节在各自的寄存器表里都是 WO(只写)。

⚠ 工具以前只认 Staged Control Set 0 的两个触发字节 10h:143/144(这正是 Page 10h 概览表列出的那两个)。另外八个 Apply 触发字节——单向触发 10h:176/177、Staged Control Set 1 的 10h:178/179 与 10h:211/212、Network Path 的 16h:176/177——可以夹在多字节写入里发出去,读到时也不标「write-only」。同样漏掉的只写字节还有 10h:135–136 AdaptiveInputEqStoreTx(存储位置)和 1Dh:160 CommitRedirection。

现在:这十个触发字节夹在多字节写入里都会被拒绝;Raw Registers 读到上面任何一个只写字节,都在十六进制显示上方标出「write-only……not what was written」。演示模块也把它们当只写字节,读出来是 0。

Raw Registers:跨过 0x7F 的读取读的是它标出的字节

规范 B.1.2:字节地址在当前 128 字节内回绕——Lower Memory 从 127 回到 0,上页从 255 回到 128。

⚠ 以前从 0x7C 读 8 个字节是一次读完的,在真实模块上 0x80–0x83 位置显示的其实是 Lower 0x00–0x03(演示模块会接着读进上页,把这个问题藏住了)。 从 0x7F 开始写两个字节也会放行,第二个字节落在 Lower 0x00。 另外 Dump 标题对 Lower Memory 的字节也写 Page 字段(读 Lower 0–3 显示「Page 0x11」),读之前的清除提醒只按起始地址判断,漏掉 0x80 之后的标志字节。

现在:跨过 0x7F 的读取先选好页,分成 Lower Memory 与所填的页两次读;标题写 Lower Memory 或 Lower Memory, then Page 0x.. from 0x80;清除提醒两半都查;越过 0x7F 的写入一律拒绝。演示模块也按 B.1.2 回绕。

顺带修正:读完之后 Dump 上方的 cleared by this read 和 write-only 两类提示行,地址一直显示成 Lower undefined,现在显示真实的字节号(如 Lower 122-125、10h:143)。

模块没声明的异常固件指示,不再算作「没有故障」

Lower 8 bit 3 的 AbnormalFwIndicationFlag 在规范里是「Adv.」(Table 8-9),唯一的声明位是 0Ch:194.4 AbnormalIndicationSupported(Table 8-73);而固件加载管理(0Ch:162–163)没声明时,这些细节位按规范「应被忽略」。

⚠ 以前不管模块有没有声明,工具都读这一位,Module Info 的 Firmware Faults 行把它一起算进「None」——对一个根本没有这项检查的模块,这个 None 是没做过的检查。内置演示模块都没有声明这一项。

现在:没声明时,状态接口里这一位为 null,Firmware Faults 行注明 no firmware-vs-load check (0Ch:194.4)。另外,Page 0Ch 固件加载管理的细节行以前把缺的位写成「X (X is supported)」,读起来像是支持;现在写成「X = 0, full support wants 1 (…)」。

没有的监控,不再显示它的阈值

Page 02h 的温度、Vcc、Tx 光功率、Tx 偏置、Rx 光功率阈值,规范都标为 Cnd.(Table 8-64 / 8-65)——只要求实现了该监控的模块提供。

⚠ Monitoring 表已经会把模块没有的监控显示成 not implemented,但下方的 Module Thresholds 卡片仍把这几项的阈值照常显示成数字,看起来像模块给出的告警门限。演示模块 mock_fewmon(没有 Vcc、Tx 光功率、Tx 偏置监控)就是这样。Aux 监控的阈值行以前就只在模块有该监控时才出现。

现在:模块没有的监控(01h:159–160),阈值卡片那一行显示 no monitor,悬停说明原因;阈值接口多了 monitors_present。

媒体侧起始位图与模块自己的媒体 lane 对不上时,会标出来

规范 Table 8-60:MediaLaneAssignmentOptions 的每一位是一个数据通道可以起始的媒体 lane,每个实例占用连续的媒体 lane,并且「所有实例必须能同时支持」。所以起点不能落在 00h:210 声明不存在的媒体 lane 上,也不能超出 lane 8 或与别的起点重叠。

⚠ 以前工具只把这个位图原样显示,不和 00h:210 对照。演示模块自己就有这个矛盾:只有一条光载波的两个相干模块把 8 个起点都声明了,只有 4 条媒体 lane 的有源光缆把 lane 5–8 也声明成起点。

现在:Supported Applications 表的 Media Lane Assign 格子里会列出不成立的起点及原因;接口回复里每个应用多了 media_lane_assign_problems。演示模块只声明自己能支持的起点。超过 8 通道的模块,00h:210 按规范无法无歧义地声明媒体 lane,这时只检查超界和重叠。

接口名称按 SFF-8024 补全,按媒介类型查表

Supported Applications 表里的 Host / Media Interface 名称来自 SFF-8024 的代码表。对照 SFF-8024 Rev 4.14 逐条核对后发现:

现在这些名称按 SFF-8024 Rev 4.14 更正,补上缺的代码,媒体侧按 Media Type 选表;有源光缆演示模块显示「Active Cable assembly with BER < 2.6x10^-4」,铜缆演示模块显示「Copper cable」。另外,扁平内存模块不再去读并不存在的 Page 01h 的媒体侧起始位图(以前读回的是 Page 00h 的字节)。

只声明前游标控制的模块:Rx EQ Pre 读对字节

规范 6.2.5.2:模块只支持一个输出均衡设置时(01h:162.4-3 为 01b「只有前游标」或 10b「只有后游标」),这个设置都放在后游标字段(OutputEqPostCursorTargetRx),前游标字段被忽略;Table 8-84 也写明前游标字段「只在两者都支持时使用」。

⚠ 工具的提醒一直写着「后游标字节装的是前游标目标值」,Rx EQ Pre 一列读的却是被忽略的前游标字节(10h:162–165 / 11h:223–226)。演示模块 SR8 正是只声明前游标的模块,它也把生效值放在了被忽略的字节里,两边错得一致,所以没被发现。

现在:只声明前游标时,Rx EQ Pre 的暂存值和生效值都从后游标字节读,列标题写 10h / 0xA6–0xA9;两者都声明时照旧。演示模块 SR8 按规范把生效值放进后游标字节,Apply 时也按后游标字节检查是否超过前游标上限。

Tx Bias 列标题写出本模块的刻度

规范 Table 8-99:LaserBiasTx 以「2 µA 为单位,再乘以 Table 8-53 的倍率」——倍率在 01h:160.4-3(×1 / ×2 / ×4)。工具换算读数时一直乘了倍率,但 Monitoring 表 Tx Bias 列的标题固定写着 uint16×2µA,在 ×2、×4 的模块上(内置的相干可调谐演示模块就是 ×2)一个计数其实是 4 µA 或 8 µA。

现在:列标题按模块写,例如 uint16×4µA (2µA × 2, 01h:160.4-3);倍率为保留值 11b 时写 × ?。监控接口的回复多了 tx_bias_scale。手册 8.1 节的表格也补上了这一点和第 9 条以后通道的地址写法。

没数过比特的 BER 不再显示成 0

BER 是误码数除以比特数。一个窗口一个比特都没数过时,模块在那里放的也是 0——最常见的是还没结束过门控的 · last gate 行(模块声明支持门控结果时,连上就是一整行 0),以及刚启用的检测器。规范 Table 8-128 说累计时长要从 TotalBitsCount 推出来。

现在:模块同时报告误码计数(13h:130.1)时,BER 卡片会对照同一窗口的计数器(Selector 02h–05h / 12h–15h),TotalBitsCount 为 0 的通道显示 —(悬停有说明),接口里每条通道多了 host_measured / media_measured。同一个依据也修正了另一处:检测器停下时数过比特但零误码的通道,以前因为 BER 是 0 被显示成 off,现在显示 0 held。

诊断选择器没被接受时,不再显示成 0

BER、误码计数、SNR 都是先写 Page 14h 的 DiagnosticsSelector(14h:128),等 tDDCS,再读结果窗口。规范 Table 8-136 规定:模块不支持的值会退回 0,而 Selector 00h 的内容是全零(Table 8-137)。

⚠ 以前工具写完不读回,选择器被模块退回时,读到的全零窗口会显示成 BER 0、计数 0、SNR 0.00 dB——看起来都像测量结果。演示模块也只对门控选择器(11h–15h)做了退回,其它没声明支持的选择器照样「生效」。

现在:每个 Bank 写完选择器都会读回;没被接受的 Bank,它的通道显示 —,表格下方写明是哪个选择器、哪个 Bank、读回了什么。接口在 /api/module/ber、/counters、/snr 的回复里加了 selector_refused。演示模块按自己 13h:129–130 的声明退回所有不支持的选择器(包括保留值和厂商自定义值)。

CDB 命令完成标志不再被刷新吃掉

Lower 8 的 bit 6–7 是 CdbCmdCompleteFlag1/2(Table 8-9):CDB 命令执行完,模块置位对应实例的这一位(7.2.5.2)。它和同一字节的其它标志一样是闩锁、读后清除的,而 Module Info 每次刷新都会读这个字节。

⚠ 以前工具认为「本工具不发 CDB 命令」,读到这两位就丢掉。可 Raw Registers 页能发 CDB 命令(写到 9Fh:129 即发送),发完再去读 Lower 8,完成标志早已被下一次刷新清掉,看不到。

现在:模块声明支持 CDB 时,Module Info 多一行 CDB Command Complete,每个实例一项——当前置位显示 command complete,已被读清的保留 ●! a command completed since last clear,屏蔽位(Lower 31 bit 6–7)置位时标 masked;与其它标志共用 Clear flag history。它不是告警,不会点亮 ⚠。命令成功与否仍看 CdbStatus(Lower 37–38,Table 8-13)。Raw Registers 读 Lower 8–13 前的清除提示也写明了这一块包含 CDB 命令完成标志。

激光调谐:TuningComplete 在数据通道起来之后才报

Table 6-21 规定 TuningCompleteFlag 在 DPDeactivated、DPInit、DPDeinit 下是 N/A,模块在这些状态下不得置位(6.3.4.2);而换栅格或信道只能在 DPDeactivated 下进行(7.5.2)。所以在停下的数据通道上换信道后,Tuning Flags 列的 Tuned 要等数据通道回到 DPInitialized 才出现。

⚠ 以前演示模块在写入信道的瞬间就置 TuningComplete,不管数据通道停没停。另外,点 Apply 后工具会读这组标志找拒绝原因——这次读取会把它们清掉,而工具只记下了拒绝类的标志:TuningComplete 哪里都没说,Apply 之前已经闩锁的波长失锁标志也被清掉、没有记下。

现在:Apply 的读取按刷新时的规则记下除 TuningComplete 外的所有标志,波长失锁会留在 Tuning Flags 列的历史里;接口回复里的 completed 列出报了 TuningComplete 的通道,页面提示 lane N reports TuningComplete,还没报时提示在停下的数据通道上要等它起来。

同一轮:PRBS Generator 卡片下方补了 LOL 图例(PatternGeneratorLOL,14h/0x88·0x89),Checker 卡片的图例补全了 ●!、– 和 gate done;第 10 章按页面现状更新——10.5 原来说「BER 读取无需 PRBS 使能」,BER 实际来自 PRBS 检测器(规范 8.17)。

0 µW 不是 −40 dBm

光功率寄存器以 0.1 µW 为单位(Table 8-99、8-65),能表达的最小功率是 −40 dBm;读数为 0 就是没有光,没有对应的 dBm 值(−∞)。

⚠ 工具以前把 0 µW 换算成 −40.00 dBm:没有光的接收端、或者被 DPDeinit 关掉的通道,都显示成一个 −40 dBm 的「读数」;阈值页里为 0 µW 的低告警阈值(任何读数都不可能低于它)也显示成「−40 dBm 告警」,并据此给通道上色。

现在:0 µW 显示为 0.0 µW / −∞ dBm;阈值为 0 µW 时显示 −∞ 0 µW,悬停说明低阈值永远不会触发(高阈值则任何读数都超过)。监控表按这个语义上色。接口里对应的 *_dbm 为 null,阈值接口另给出每个功率阈值的 *_uw。

16 通道模块上,第 9 条以后的寄存器提示按 Bank 标注

Page 10h / 12h / 13h / 15h 是按 Bank 分的:Bank b 对应通道 8b+1 到 8b+8,所以 16 通道模块上的第 9 条通道是 Bank 1 的 Lane1,字节和位都与第 1 条通道相同。

⚠ 各表格的悬停说明以前给出的是 Bank 内的字节和位,字段名却按绝对通道号写(「…Lane9」,没有哪个 Bank 有这个字段);Squelch、Loopback、PRBS 表里的说明还根本不写 Bank,读起来就是 Bank 0 的寄存器。几张表的列头公式(例如 11h / 0x9A+(n−1)×2)对第 9 条通道算出来是 0xAA——那是 Tx 偏置的寄存器。

现在:字段名一律写成 Bank 内的通道号并注明 Bank(例如 DPDeinitLane1 (Bank 1)),列头公式写成 ((n−1)%8),即通道在所属 Bank 内的序号。

AppSelect 悬停说明写出暂存的 DPIDX

DataPath 表 AppSelect 列的悬停说明以前写的是「DataPathID bits 3-1」——这是 CMIS 5.4 已改名为 DPIDX 的字段,而且没写里面存的是多少;16 通道模块上第 9 条通道还被标成 10h:0x99 / 11h:0xD6,那是自适应均衡的寄存器,DPConfigLane 按 Bank 计,Bank 1 的第 1 条通道仍在 0x91 / 0xCE。

现在:悬停说明写出暂存的 AppSelCode、DPIDX(以及这个数据通路从第几条通道开始)和 ExplicitControl,地址按所在 Bank 标注。接口 /api/module/datapath 每条通道新增 staged_dpidx、staged_explicit_control。

暂存的 DPIDX 按数据通路写

规范 6.2.3.2.2:数据通路的 DPID 是它占用的最低主机通道号,DPIDX = DPID − 1;「DPConfigLane 里的 DPIDX 字段按 DPIDX 指明这条通道属于哪个数据通路」(Table 8-102 的 bit 3-1)。

⚠ 工具以前往暂存控制集(10h:145–152)里每条通道都写 DPIDX 0。一个 800G 模块拆成 2×400G(通道 1–4、5–8 各一个 4 通道数据通路)时,这等于告诉模块通道 5–8 也属于从通道 1 开始的那个数据通路——这不是该 Application 能占用的通道组合,真实模块会回 ConfigRejectedInvalidDataPath。而且 DataPath 页每次写入都会重写这几个字节,光改一下极性,就可能把模块原本正确的暂存配置改坏。演示模块只按 Application 宽度分组、从不看 DPIDX,所以一直没暴露。

现在:工具按 Application 的主机通道宽度把通道分成数据通路,每条通道写入所在数据通路的 DPIDX(Bank 内计,未使用的通道写 0),ExplicitControl 位保留模块里原有的值。演示模块在 Apply 时检查 DPIDX,指向别的数据通路的通道会得到 ConfigRejectedInvalidDataPath;它默认的暂存控制集也与活动控制集一致。

环回设置被模块拒绝时会说出来

规范 8.16.12:「模块可以拒绝它不支持的环回设置(相关寄存器位不变)」。工具在写入前已经按 13h:128 的声明拦下不支持的环回类型、主机侧和媒体侧同时环回、模块没有的媒体通道;但模块还可能因为别的原因拒绝。

⚠ 工具以前写完就回「Loopback configuration written」,不管模块收没收;页面上的勾选框也保持勾着,显示一个其实并不存在的环回。

现在:写入后逐个 Bank 读回。模块没收下的设置会报错(409),写明哪一项写的是多少、读回是多少;页面随即重新读取,勾选框显示模块实际的状态。写入前的输入错误照旧保留你改过的勾选。

固件 Bank 状态(Page 0Dh)

规范 8.12:Page 0Dh 用来「在寄存器里给出固件状态信息,不强迫主机使用 CDB 消息」——哪个 Bank(A、B、固定的出厂 Load)有效、哪个已提交(复位或上电后运行它)、哪个正在运行,以及每个 Load 的主 / 次版本、Build 号和描述(Table 8-75、8-76)。规范 7.3.1:「从 CMIS 5.4 起,版本信息的全部四项都能在 Page 0Dh 的寄存器里读到」。

⚠ 工具以前读了 Page 0Ch 里「支持固件加载管理」的声明,却从不读这个声明所指的 Page 0Dh;手册还把固件加载管理整个标成「未实现」,理由是工具不做 CDB——而读 Page 0Dh 根本不需要 CDB。于是模块的固件状态只剩 Lower 39–40 和 01h:128–129 两组主.次版本号:没有 Build,没有描述,也看不出复位后会跑哪一个。

现在:模块声明支持 Page 0Dh(01h:173.6)时,5.4 页面出现 Firmware Loads 卡片,逐个 Bank 列出有效 / 已提交 / 运行中、版本、Build、描述。正在运行的 Load 版本与 Lower 39–40 报的不一致、或没有任何 Bank 报告在运行时,卡片下方会写明。mock_1600g_dr8 演示了这一页。

ModuleFault 会说明原因

规范 Table 8-16:Lower 41 ModuleFaultCause 记录模块进入 ModuleFault 的原因——1 TEC 失控、2 数据存储损坏、3 程序存储损坏、4 发送器故障、5 接收器故障、6 温度相关故障,32–63 为厂商自定义;0 表示没有检测到故障或不支持这一字段。ModuleFault 只响应复位(6.3.2.5.8)。

⚠ 工具以前只在 Module State 一行显示「ModuleFault」,从不读原因,用户拿到一个状态却不知道该查什么。演示模块根本停不在 ModuleFault:它的状态机会把任何非 Ready 状态直接拉回 ModuleReady。

现在:模块处于 ModuleFault 时,Module State 一行显示红色的 ModuleFault 和原因(例如「cause: TEC runaway」);原因为 0 时写明「cause not reported」。顶栏同时出现红色 ✖ 图标,悬停说明原因并提示只有复位能让它离开。演示模块进入 ModuleFault 后一直保持到复位,复位时原因清零。

警告不是告警

规范 Table 8-9:Lower 0x09–0x0B 里每个模块级监控(温度、电压、Aux1–3、自定义)都有高 / 低告警和高 / 低警告四个标志,闩锁、读清。

⚠ 工具以前把四个一起算作「告警」:温度只是过了警告阈值,Module Info 就显示红色「Alarms: Active」,状态栏显示「⚠ Alarm Active」,顶栏图标说有值超出了告警阈值。而且这一行只看这一次刷新:两次刷新之间出现过的标志已经记进历史,这一行却显示 None。

现在:这一行改名为 Module Flags,逐项列出是哪个监控的哪一级——告警红色、警告黄色——两次刷新之间出现过的保留 ●! 「since last clear」,点 Clear flag history 清掉。只有告警才显示「⚠ Alarm Active」;只有警告时显示黄色「▲ Warning」,顶栏图标也分开。接口 /api/module/status 新增 warning_active,alarm_active 只算告警。

「模块状态变化」不再叫「重启」

规范 Table 6-9:ModuleStateChangedFlag 只在进入 ModuleLowPwr、ModuleReady、ModuleFault 时置位;如果新状态的退出条件在进入时就已满足(例如复位后没有被要求保持低功耗),这一次不置位。真正判断模块是否重启,规范 8.16.13 给的是 Host Scratchpad:模块每次固件重启都会把它清零。

⚠ Module Info 以前把 ModuleStateChangedFlag 显示成「Module Restarts / Restarted since last clear」:在页面上切一次低功耗再切回来,就报告模块重启过——其实什么都没重启。而规范专门用来回答这个问题的寄存器,工具从来没读过。演示模块声明支持 Host Scratchpad,复位时却不清零;每一次状态变化(包括 ModulePwrUp)都置 ModuleStateChangedFlag。

现在:原来那一行改名为 Module State Changes,显示「State changed since last clear」;新增 Module Restarts 一行,由 Host Scratchpad 判断(说明见「Module State Changes 与 Module Restarts」一节)。顶栏 ↺ 悬停会说明是重启还是状态变化。演示模块复位时清零 Host Scratchpad,并按 Table 6-9 置位 ModuleStateChangedFlag。

13h:177.7 置 1 时,各 Bank 的检测器一起启停

规范 Table 8-127:13h:177.7 StartStopIsGlobal 置 1 时,在一个 Bank 上改启停控制——160 / 168 的检测器使能、177.5 ResetErrorInformation——「如同在所有 Bank 上做了同样的改动」。以哪个 Bank 的这一位为准,看写的是哪个 Bank。门控测量并且只有全局定时器(13h:129.3 = 0)时这一位被忽略(Table 8-129)。

⚠ 页面早就提示「lanes 1, 9, 17 一起启停」,可 PRBS 的写入仍然给每个 Bank 各写各的使能。在这一位生效的模块上,只勾 lane 1:写 Bank 0 时 lane 9 也跟着启动;接着写 Bank 1 的 0,这本身也是一次改动,又把两条一起停掉——结果一条都没在跑,回复却是「已写入」。演示模块也只改被写的那个 Bank,看不出这个问题。工具判断这一位时也只看 Bank 0。

现在:这一位生效时,PRBS Checker 表里勾一个 Bank 的通道,其它 Bank 同一位置的勾选框会跟着一起变;各 Bank 使能不一致的请求会被拒绝(400),并指出是哪两条通道。模块没有的媒体通道不算不一致。工具读每个 Bank 的 13h:177.7,任一 Bank 置位就按「作用于所有 Bank」处理。发生器的使能不是启停控制,不受影响。演示模块把检测器使能和 177.5 的改动带到所有 Bank,只带改动的那几位;门控 + 全局定时器时不带。

误码计数由检测器的启用开始、停止

规范 Table 8-128 ~ 8-130:检测器的使能位(13h:160 主机侧、13h:168 媒体侧)就是误码计数的开关。启用原本关闭的检测器时,这些通道的计数清零后开始累积,门控定时器也从 0 开始;关闭检测器时计数停止,结果仍可通过选择器 01h–05h(以及支持时的 11h–15h)读到。模块声明测量期间不更新(13h:129.4 = 0)时,检测器在跑时数字不动,关掉或门控到时才出结果。

⚠ 演示模块以前不管检测器开没开:一连上就在每条通道上计数,主机侧和媒体侧共用同一个计数;而且只在读到某个计数窗口时才累加,同一秒里第 5–8 通道计的比特数能是第 1–4 通道的好几倍。声明「测量期间不更新」的 mock_fr4x2 数字照样每次都变。PRBS 的 LOL 标志也不对:任何一个引擎在锁定过程中,整个 bank 八条通道全部置位,锁上后直接写 0——只启用一条通道,另外七条也显示失锁;锁上之后才读的主机则根本看不到这次失锁。

现在:演示模块每个检测器各自计数,只在启用期间累加,启用时清零重来,关闭时停住并保留结果;BER 就是它计到的误码数除以比特数。LOL 只在正在锁定的那条通道上置位,闩锁到被读取为止。BER 表和误码计数表里,没有检测器在运行的通道显示灰色 off;检测器已关闭、留有结果的显示数值并标 held(悬停有说明);一个检测器都没开时表下写明「No pattern checker is running」。PRBS 表里没有运行的发生器 / 检测器,Lock 一栏显示「–」,不再是表示已锁定的绿点。

ℹ 检测器刚启用、还没锁上时会置一次 LOL(真实模块通常也是这样),PRBS 表会留下 ●!。要判断测量期间有没有失锁:启用检测器,等它锁上,点一次 Clear flag history,之后再出现的 ●! 才是测量中的失锁。

关断 Tx 输出不是「发送器故障」

规范 Table 8-97:11h:135 的 FailureFlagTx(以前叫 Tx Fault)表示「发送部分内部失效,导致不确定的故障」,闩锁、读清。

⚠ 演示模块以前只要主机关掉某一路 Tx 输出,就把这个标志置位,下一次刷新又直接清掉:取消勾选 Tx Enable,Flags 表就显示发送器故障、历史里记一笔、Interrupt 被拉起——等于告诉用户「关输出 = 发送器坏了」。

现在:演示模块不模拟发送器失效,关断输出不会再置位这个标志;真有置位时会一直保持到被读取。Flags 表的列名改为规范现在的名字 Tx Failure(悬停说明原名 Tx Fault)。

Interrupt 一行写明标志在哪一页

规范 Table 8-8:Lower 0x04–0x07 是标志汇总,每个 Bank 一个字节,分别表示 Page 11h / 12h / 14h / 2Ch 上「至少有一个标志置位」(Bank 0 的 Page 11h 那一位是必需的)。清除汇总位要去读对应页上的标志本身。

⚠ 工具以前不读这几个字节,演示模块也不维护。Module Info 只说 Interrupt 有没有置起,不说是从哪来的——而 Page 2Ch 放的是 VDM 标志,本工具没有任何页面显示它,那里的标志把 Interrupt 拉起来时,屏幕上找不到任何原因。

现在:Module Info 的 Interrupt 一行下方写明「Flags set on: Page 11h / Page 12h bank 1 …」,Page 2Ch 会注明「VDM — not shown by this tool」。演示模块按各页实际置位的标志维护这四个字节。

保留值按「未知」处理

规范 8.1.3.8(CMIS 5.4 维护项 M11):主机遇到保留值时,「应当把它理解为未知、不可用或超出已知范围」。

⚠ 有两处以前是在猜:Tx 偏置电流倍率(01h:160[4:3])读到保留的 11b 时按 ×1 处理,于是每个偏置读数和偏置门限都用一个模块没说过的单位显示,最多差 4 倍;Lower 0x02[1:0] AutoCommissioning 在「只支持分步重配置」时读到保留的 11b,被当成「两种都不支持」,ApplyImmediate 因此被拒绝——理由是模块并没有说过的。

现在:偏置倍率为 11b 时,Monitoring 的 Tx Bias 列和阈值卡片的偏置门限显示 unknown(悬停说明原因),不再给出数字;AutoCommissioning 为 11b 时,Module Info 显示「unknown」,ApplyImmediate 不再以「不支持」为由拒绝,但「过渡状态下不接受 Apply」的保护照旧。

栅格下拉只列模块声明的栅格

规范 Table 8-68:04h:128 的第 n 位声明栅格码 n(3.125–75 GHz),04h:129[6] 声明 150 GHz,04h:129[5] 声明 300 GHz;04h:130–169 的信道范围对每个栅格都是必需字段,本身不代表支持与否。

⚠ 激光调谐表以前按「范围字节是否非零」来决定列出哪些栅格:模块没声明的栅格,只要那几个字节里有值就会被列出来;而声明了、但只有一个信道 n = 0(193.1 THz)的栅格,范围读出来是 [0, 0],反而被漏掉。写入时也不检查栅格是否声明。演示模块判断「栅格没声明」用的也是同一个错误办法。

现在:栅格下拉和范围提示只按声明位列出,[0, 0] 的单信道栅格照常列出;改到未声明的栅格会被拒绝并说明原因(通道本来就停在某个未声明栅格上时,可以原样写回)。演示模块也按声明位判断,未声明的栅格即使信道为 0 也会报 TuningNotAccepted。

微调是「声明才有」的控件

规范 Table 8-109:FineTuningEnableTx(12h:128[0])和 FineTuningOffsetTx(12h:152–167)的类型是 RW Adv.,由 04h:129 声明;CMIS 5.4 的缺陷修正里也专门写了一条「Page 12h 的微调控件是声明才有,不是必需」。8.1.3.7:Adv. 字段「在明确相关的功能声明里标明时才支持」。

⚠ 激光调谐表以前不管 04h:129[7],一律给出微调偏移输入框,写入时也总是写这两个控件,还拿 04h:192–195 做范围检查——而在不支持微调的模块上,这几个字节什么都不代表。

现在:模块未声明微调时,微调偏移框变灰并说明原因,页面不再发送微调字段;接口拒绝非零偏移和「启用微调」(说明 04h:129.7 未置位),偏移为 0 时不写偏移寄存器。演示模块在未声明微调时不会把偏移算进频率。

「5.4」徽标只标 5.4 新增的内容

规范前言里有两份变更清单:第 8–10 页是 Rev 5.3 的,第 11–12 页才是 Rev 5.4 的。主机侧通道切换(01h:252[7]、Page 1Dh)在 5.3 的清单里(E14),Table 6-21 的 Page 12h 几行(E07)和 Page 02h 阈值随 Application 变化的提示也都是 5.3 加的。

⚠ 工具把这三项都当成了 5.4:Module Info 的 Host Lane Switching 一行和 DataPath 页的 Host Lane Switching 卡片都带着 5.4 徽标,手册里也把主机侧通道切换写成了 5.4 新增。而且徽标本身并没有按服务器那份「5.4 新增字段」清单来标——每一行各自写死;那份清单里还有两个任何接口都没有返回过的字段名。

现在:Module Info 每一行写明它显示的字段,是否带 5.4 徽标由清单决定;清单只收 5.4 变更清单里列出的内容,每一项都能在某个接口的返回里找到。Host Lane Switching 的行和卡片不再带 5.4 徽标,手册相关几处改为 5.3,第 12 章的 5.4 可选页表里去掉了 1Dh(12.4a 注明它是 5.3 引入的)。

固件故障标志:读到了就不会再丢

规范 Table 8-9:Lower 0x08 除了 bit 0 的 ModuleStateChangedFlag,还有三个固件标志——bit 1 ModuleFirmwareErrorFlag(主固件自检发现故障)、bit 2 DataPathFirmwareErrorFlag(DSP 等辅助器件的固件故障)、bit 3 AbnormalFwIndicationFlag(CMIS 5.4 新增:正在运行的固件与标称版本不一致)。都是闩锁、读清。

⚠ 状态刷新每次都读这个字节,却只保留 bit 0:模块报告自己的固件或 DSP 固件出错了,这一读就把标志清掉,下一次刷新什么都看不到。

现在 Module Info 多了一行 Firmware Faults:当前置位的显示为红字,已被读清的保留 ●! … since last clear,对应的屏蔽位(Lower 0x1F)置位时标出 masked;前两个固件错误还会在顶部摘要栏出现 ✖。与其它标志共用 Clear flag history。它们不算「监控值超阀值」,不会点亮 ⚠。CdbCmdCompleteFlag(bit 6–7)当时不显示;v2.172.0 起另有一行 CDB Command Complete(见上文)。

门控结束时,PRBS 检测表标出「gate done」

规范 Table 8-138:14h:134 / 14h:135 是逐通道的 PatternCheckGatingCompleteFlag(主机侧 / 媒体侧),「门控完成时,这一位会被置位」——闩锁、读清。它是「上一个门控结果已经就绪」的唯一信号。

⚠ 工具以前读了这两个字节(读就会清掉),然后直接丢弃:不进 Flag 历史,页面上也不显示;演示模块则根本不置位。门控结果什么时候更新了,没有任何地方能看出来。

现在:工具把它记进 Flag 历史,PRBS 页的主机侧 / 媒体侧检测表在对应通道的 LOL 一栏后面标出 gate done(悬停说明结果在 BER / 计数表的 last gate 行里),点「Clear flag history」后清掉。演示模块在门控到时,为正在运行检测器的通道(13h:160 / 13h:168)置位,每个 bank 各自置位。

BER / 计数器:上一个完整门控周期的结果

规范 Table 8-137 把诊断选择器分成两组:01h–06h 是「实时结果」,11h–15h 是「最近一个已完成门控周期的结果(在门控周期内保持不变)」,模块在 13h:129.5 GatingResultsSupported 声明是否提供。Table 8-129 自动重启门控那一行写得很明白:门控到时,当前误码信息清零、门控重新开始,「主机必须用选择器 11h–15h 读取上一个门控时段的误码信息」。

⚠ 工具以前只读 01h–05h,门控测量真正要的那个结果——上一个完整门控周期的 BER 和误码/总比特数——从来没显示过;开了自动重启时,表里看到的只是新一轮刚开始累积的数。演示模块也不管门控:计数器一直累加,11h–15h 显示的也是还在变的实时数。

现在:模块声明支持时,BER 表和误码/比特计数表下面多出几行 · last gate,是上一个完整门控周期的结果(选择器 11h / 12h–15h),在下一个周期结束前保持不变;还没有完成过门控时是 0,测量窗口说明里会写明。演示模块:门控到时把结果复制到 11h–15h;开了自动重启(13h:177.4,且 13h:129.2 声明支持)就清零重新计数,否则停止计数;ResetErrorInformation(13h:177.5)置 1 时冻结并复制,清 0 时重新开始、11h–15h 不变;改门控时间开始新一轮;每个 bank 各有自己的门控;不支持的选择器按规范回到 00h,数据区全 0。

关掉一路 Tx,整条数据通道退到 Initialized

规范 Eq. 6-12:DPDeactivateS = DPReDeinitS OR DPTxDisableT OR DPTxForceSquelchT,后两项是对这条数据通道所有媒体通道取「或」。表注:「在 DPActivated 或 DPTxTurnOn 下,对一条或多条媒体通道设置 OutputDisableTx 或 OutputSquelchForceTx,会让整条数据通道经 DPTxTurnOff 转到 DPInitialized。」附录 D.1.3 的软件上电流程就是先把 Tx 全关,让数据通道初始化后停在 DPInitialized,再打开 Tx。Table 6-18:DPInitialized 下每一路 Tx 输出看它自己的 OutputDisableTx / OutputSquelchForceTx。

⚠ 演示模块以前关掉一路 Tx,数据通道仍显示 Activated;带着 Tx 关断去初始化的数据通道会被放回 DPDeactivated,之后再打开 Tx 也起不来——D.1.3 的流程在演示模块上走不通。手册也写错了:说取消 Tx Enable「数据通道仍处于 Activated」。

现在:演示模块在任一路 Tx 被关断或强制静音时,把整条数据通道经 TxTurnOff 带到 Initialized,恢复后经 TxTurnOn 回到 Activated;带着 Tx 关断初始化、退出低功耗或放开 DP Deinit 的数据通道停在 Initialized;Initialized 下没被关的通道照常发光,Rx 侧照常转发;复位把 Tx 关断和强制静音恢复为 0。16 通道演示模块的第 9–16 通道同样如此。工具在 DataPath 和 Squelch 页的这类写入之后提示「Data Path L1–8 leaves DPActivated for DPInitialized」,Output 列的悬停说明也按 Initialized 下的规则改写。

低功耗下配置数据通道:写入,等上电再生效

规范 8.13.1:模块只在 ModuleReady 下评估 DPDeinit;「主机可以在低功耗状态下把全部 DPDeinit 位置上,阻止自动初始化」——附录 D.1.3 软件上电流程的第 6 步就是这么做的。Table 6-3:对 DPDeactivated 通道的 ApplyDPInit 是「只拷贝」,先写进 Active Control Set,再经状态机初始化;6.3.3 也说 Active Control Set 在 ModuleLowPwr 和 ModuleReady 下都可以更新。

⚠ 工具以前在模块不在 ModuleReady 时拒绝 DP Deinit 和 Apply,理由是「不会生效」——正好挡住了规范推荐的上电流程。演示模块退出低功耗时无视 DPDeinit,把所有数据通道都拉起来;16 通道演示模块在低功耗下,第 9–16 通道仍显示 Activated(规范 6.3.2.5.4:低功耗下所有通道都是 DPDeactivated)。

现在:低功耗下 DP Deinit 和 Apply 都会写入,提示「Provisioned in ModuleLowPwr」;退出低功耗后,没被按住的数据通道按 Active Control Set 初始化,被按住的保持 DPDeactivated。ApplyImmediate 仍被拒绝(DPDeactivated 下不起作用);模块处于 ModuleFault、ModulePwrUp / ModulePwrDn 时,这三个操作被拒绝并说明原因。演示模块:低功耗下 16 个通道都是 DPDeactivated;低功耗下的 Apply 只写进 Active Control Set,上电时才初始化(DPInitPending 随之清除,阈值随之更新);复位把所有 bank 的 DPDeinit 恢复为 0。

只写寄存器读不回写进去的值

规范 Table 8-3:从 WO(只写)元素读,得到的是不可预测的值;从 WO/SC 元素读,得到 0——WO/SC「主要用于需要保护写入数据隐私的场合」。Page 10h 的 ApplyDPInit 和 ApplyImmediate 还规定:「这个字节必须用单字节 WRITE 写入」。

⚠ 演示模块以前把密码区(00h:118–125,WO/SC)读回成刚写进去的密码,ApplyDPInit 一直读回上次写的 0xFF;Raw Registers 的十六进制显示把它们当成普通数值;Raw Registers 还能把触发字节夹在一次多字节写入里发出去。

现在:演示模块的只写字节读出来是 0,夹在多字节写入里的触发字节不生效;工具拒绝把 10h:143 / 10h:144 夹在多字节写入里(提示单独写);Raw Registers 读到只写字节时,在十六进制显示上方标出「write-only……not what was written」。

演示模块:只读寄存器写了也不变

规范 Table 8-3:「对只读元素的 WRITE 是允许的,但没有任何效果。」

⚠ 演示模块以前什么都存:在 Raw Registers 里写 00h:129 能改掉厂商名,写 Lower 0 能改掉模块标识,Module Info 随后就显示新的身份——和真实模块的行为正好相反。

现在演示模块只接受主机能写的位置(控制、掩码、密码、页映射,Page 10h,12h / 13h / 14h / 1Dh / 6Dh / 60h 的可写部分等),写到广告、状态、Flag、监控值和 Page 00h–04h、0Ch、11h、1Ch、61h、62h 上的值会被忽略。写入操作本身仍然回报成功——规范说的是「允许但无效果」;写完用 Read 读回就能看到值没变。真实模块不受影响。

激光调谐表的「锁定」一栏:数据通道停下时不作判断

CMIS 5.3 给 Table 6-21 加了 Page 12h 的几行(E07):WavelengthUnlocked 在 DPDeactivated、DPDeinit 下不报,TuningComplete 在 DPDeactivated、DPInit、DPDeinit 下不报。

⚠ 激光调谐表的锁定栏以前先看解锁状态:数据通道停下后(这时模块不报解锁,激光器也未必开着)照样显示绿色的 Locked;激光器还在调谐、解锁位没来得及置起时,也显示 Locked。

现在先看是否在调谐(显示 Tuning...),数据通道处于 DPDeactivated / DPDeinit 时显示 n/a 并悬停说明,其余情况才显示 Locked / Unlocked。接口每条通道新增 tuning_flags_not_allowed。

微调偏移要落在激光器的步进上

规范 Table 8-68:04h:190–191 FineTuningResolution 是激光器微调的步进(单位 0.001 GHz)。偏移寄存器本身能写任何 0.001 GHz 的值,而规范里没有一个 Flag 会指出「这个偏移落在两个步进之间」——模块只会自己取整到某处。

⚠ 工具以前只查范围(04h:192–195),微调输入框固定按 0.001 GHz 步进。在按 100 MHz 步进的激光器上,写 0.05 GHz 也会回报「已应用」,激光器实际停在哪里没人知道。

现在不是整数个步进的偏移直接拒绝(400),提示两边最近的可用值;微调输入框按模块声明的步进走,悬停说明步进。演示模块声明 1 MHz,所以演示里任何 0.001 GHz 的值都可用。

75 / 150 / 300 GHz 栅格的信道号

规范 Table 8-68 给每种栅格定了信道编号:大多数是 193.1 + n × 间隔,但有三种不是——

  • 75 GHz:193.1 + n × 0.025,n 必须是 3 的倍数
  • 150 GHz:193.1 + (n+3) × 0.025,n 必须是 6 的倍数
  • 300 GHz:193.1 + (n−9) × 0.0125,n 必须是 24 的倍数
⚠ 工具以前只查范围,不查倍数:75 GHz 栅格上写信道 1 也照样下发,而它根本不是一个信道。演示模块则把这三种栅格的频率算错了(按 n × 75 GHz、n × 150 GHz 算,300 GHz 栅格干脆按 100 GHz 算),信道范围也按错误的单位给出,300 GHz 栅格的范围里只有一个可用信道。

现在:不是该栅格信道的编号直接拒绝(400),什么都不写;只改栅格、不改信道时,用原来的信道号一起判断。激光调谐表的信道输入框按栅格步进(×3 / ×6 / ×24),范围提示里注明倍数,悬停显示这个信道按 Table 8-68 对应的频率,可以和模块实测频率对照。演示模块的频率、信道范围和「无效信道」标志也都按这张表来。

换信道要先停下数据通道

规范 7.5.2:「选择另一个光信道(栅格间隔或信道号)时,模块必须处于 DPDeactivated 状态。在其它 Data Path 状态下改信道,可能导致未定义的行为,因为模块可能在改动之前或之后调谐激光器。」微调偏移和目标输出功率则可以在 Data Path 不处于过渡状态时修改。

⚠ 工具以前两条都不检查:正在承载业务的激光器照样换信道,界面也照样提供输入框。

现在:承载该媒体通道的 Data Path 不在 DPDeactivated 时,改栅格或信道会被拒绝(409),什么都不写,并说明原因;Data Path 处于过渡状态时,微调和目标功率也会被拒绝。页面每次 Apply 都会重发所有字段,值没变的不算修改。激光调谐表里,Data Path 在运行时栅格和信道输入框锁定,悬停说明要先在 DataPath 页用 DP Deinit 停下;表格下方加了一行说明。通道 9 以后的寄存器悬停提示也改为引用各自 Bank 的地址(以前通道 9 指向的是 Bank 0 里通道 1 的字节)。

码型时钟源和测量窗口:每个 Bank 各有一份

规范 Table 8-127(时钟与测量控制)在 Page 13h 上,而 13h 是分 Bank 的:每组 8 条通道都有自己的码型时钟源(13h:176 / 178)和自己的门控时间、自动重启、更新周期(13h:177)。只有启停动作可以设成对所有 Bank 生效(177.7)。

⚠ 工具以前只读 Bank 0 的这几个字节,用来描述所有通道。模块的各 Bank 设置不一样时(比如被别的主机设过):通道 9–16 显示的是 Bank 0 的测量窗口;Bank 1 的码型发生器用的是参考时钟,参考时钟丢失时它却不在受影响之列。

现在每个 Bank 都读。Diagnostics 的测量窗口说明里,设置与 Bank 0 不同的 Bank 会单独列出(门控时间、自动重启、更新周期);PRBS 卡片上各 Bank 时钟源不同时逐个列出;参考时钟丢失的提示,只要某个 Bank 里的引擎用了参考时钟就算在内。各 Bank 一致时显示和以前一样。

演示模块:后面几个 Bank 各管各的通道

16 / 24 通道演示模块完整模拟的是 Bank 0,后面的 Bank 只做了部分模拟。上一版修了其中一处(DPDeinit),这次又找到两处写到后面 Bank 的操作,却落到了 Bank 0 的模型上:

  • Apply:给通道 9–16 换 Application,结果是通道 1–8 走了一遍 DPInit、停在 ConfigInProgress(于是下一次 Apply 因为「通道 1–8 还在执行」被拒绝),还置位了它们的 DP Changed;通道 9–16 反而一直没用上新的 Application。
  • PRBS:在 Bank 1 打开码型发生器或检测器,重启的是 Bank 0 的锁定计时,于是通道 1–8 报失锁,真正打开的 9–16 却没有。

工具本身每个 Bank 都写对了,是演示模块显示错了通道。现在后面的 Bank 各自响应:Apply 立即把暂存配置放进该 Bank 的 Active Control Set 并报 ConfigSuccess(完整的校验和状态机流程仍只在 Bank 0 模拟);码型锁定按 Bank 计时。真实模块不受影响。

多于 8 通道的模块:通道掩码覆盖所有通道

DataPath、Squelch、Loopback、PRBS 的写入接口里,通道掩码既可以是按 Bank 的字节列表,也可以是一个数。

⚠ 以前一个数只取低 8 位,后面各 Bank 一律写 0,却回报所有通道都已写入。在 16 通道模块上:
· 对全部 16 条通道做 DPDeinit(0xFFFF),结果是 1–8 停下、9–16 被释放;
· 掩码里的通道 9 什么都不做;
· 只写通道 1–8 的一个字节,会把 9–16 原有的设置清零。
演示模块也有一处配合出错:写到 Bank 1 的 DPDeinit 字节被当成 Bank 0 的,后写的那个覆盖了前一个,所以演示里看不出这个问题。

现在一个数就是覆盖所有通道的掩码(第 i 位对应通道 i+1),按 Bank 拆开写入;超出模块通道范围的位直接拒绝(400),什么都不写。列表形式照旧,每个 Bank 一个字节。页面本身一直按 Bank 发送,不受影响;DataPath 表里通道 9 以后的寄存器悬停提示,现在引用的是它自己那个 Bank 的字节。演示模块的后面几个 Bank 也会响应 DPDeinit 了。

媒体通道切换:正在运行的 Data Path 要整条移动

规范 7.9.4:「主机必须保证,任何已初始化或已激活的 Data Path,在媒体通道切换配置变化时要么整条受影响,要么完全不受影响。」模块只是「应当」校验(结果码 5「与活动 Data Path 不一致」)——不校验的模块会照单提交,把一条 Data Path 拆成两半。

⚠ 工具以前只弹一个确认框,给什么就提交什么。它自己的示例 2,1,4,3,5,6,7,8,在所有内置的媒体通道切换演示模块上,都是在交换那条 8 通道 Data Path 里的两条通道。

现在提交前先检查:如果某条已过 DPInit 的 Data Path(DPInitialized / DPActivated 及二者之间),它的媒体通道只有一部分会换到别处,就拒绝这次提交,什么都不写,并说明是哪条 Data Path、哪几条通道。比较的基准是交换机当前的连接(6Dh:184–191),不是初始的一一对应。只暂存、不提交不受影响。Data Path 停下来后可以随意调整。示例改成了 5,6,7,8,1,2,3,4:前后两半对调,任何对齐的 Data Path 都是整条移动。

目前只能判断第一组 8 条通道里的 Data Path(多于 8 条通道的模块,后面各组的媒体通道分配规范没有写明,本工具不猜)。

媒体通道切换:内部通道少于 8 条的模块

规范 7.9:每组始终有 8 条外部媒体通道,而内部媒体通道数 n 取决于模块(7.9.1:由应用描述符和 00h:210 声明)。7.9.3 规定重定向寄存器只有前 n 个填 1–8 的目标,n 小于 8 时其余填 0;7.9.4 要求的是「n 条内部通道一对一映射到 8 条外部通道中的 n 条」——只有 n = 8 时才是置换。

⚠ 工具以前一律要求 8 条通道的置换。在内部通道较少的模块上——正是 7.9 节点对多点例子里的叶节点——唯一合法的请求(如 5,0,0,0,0,0,0,0,把唯一的内部通道放到外部通道 5)会被拒绝;模块自己填的 0 被标成红色「不是置换」;反而可能给模块没有的内部通道写目标。

现在按 7.9.3 判断:模块有的每条内部通道各对应一条不同的外部通道 1–8,没有的填 0。表格里没有的通道显示 none,悬停说明依据;输入框的示例也按模块的通道数给出。8 条内部通道都有的模块,规则和以前一样就是置换。ZR 相干演示模块只有 1 条内部媒体通道,现在声明支持媒体通道切换,可以直接试 5,0,0,0,0,0,0,0。

进入低功耗:先等数据通道停下来

规范 Eq. 6-6:DPDeinitS = (NOT ModuleReadyT) OR LowPwrS OR DPDeinitT——低功耗请求本身就会让所有数据通道停下来。Eq. 6-4 / 6-5 又规定:只有所有数据通道都到了 DPDeactivated,模块才离开 ModuleReady。所以从正在运行的模块进入低功耗,要依次走完 DPTxTurnOff、DPDeinit,再走 ModulePwrDn。

⚠ 工具以前只按 ModulePwrDn 的声明时长(01h:167)等,超时就报「模块在声明的时间后仍处于 ModuleReady」。数据通道停得比下电慢的模块,明明在按规范先停通道,却会被报成没理会请求。演示模块是瞬间切换的,看不出这个问题。

现在,如果请求时还有数据通道没停,等待时长是三段声明之和:DPTxTurnOff(01h:168,只在有通道开着 Tx 时计入)+ DPDeinit(01h:144)+ ModulePwrDn(01h:167)。任何一段模块没声明,就不替它编一个数字。真等满了还没到,提示里会写明「模块会先让所有数据通道停下,全部到 DPDeactivated 后才离开 ModuleReady」。数据通道都已停下时,仍只按 ModulePwrDn 等。

通道停下来时,Lane Flags 不再显示「一切正常」

规范 Table 6-21(逐通道 Flag 符合性规则)规定了模块在哪些 DataPath 状态下可以置位每个通道 Flag。CMIS 5.3 又给这张表加了 Page 12h 的几行。在 DPDeactivated、DPInit、DPDeinit 下,模块不报 Tx LOS、两个 CDR LOL、所有低侧告警/警告和 Rx 输出变化;DPInitialized 下,主机关掉或强制静音了 Tx 输出的通道,也不报 Tx 光功率低侧和全部 Tx 偏置 Flag(表注 1)。

⚠ 工具以前不看状态:通道停下来后,Lane Flags 表在这些列上照样画绿点,意思是「查过了,没问题」——其实模块在这个状态下根本不会报。
演示模块则从另一边违反了这条规则:停下来的通道光功率和偏置读数都是 0,低于所有低侧门限,于是每次读都置位四个低侧告警,表格显示 ALARM。真实模块不会这样。

现在这些格子显示 n/a,悬停说明依据和当前状态;告警汇总列在部分 Flag 不适用时,绿点旁标 partial,悬停列出哪些不在其内。已经置位的 Flag 照常显示——Flag 是闩锁的,状态变化前触发的那一次仍然有效。接口里每条通道多了 datapath_state 和 not_allowed。演示模块也按这张表只在允许的状态下置位。

换了 Application 之后,阈值跟着换

规范 8.5 节:Page 02h 的告警 / 警告阈值「可能取决于已投入使用的 Application,因此每次投入新的 Application 时都可能改变(包括校验和)」;模块在 Data Path 以新 Application 到达 DPInitialized 时更新它们。CMIS 5.3 把这一点作为提示写进了 Page 02h。

⚠ 工具以前只在打开 Monitoring 标签页时读一次阈值。在 DataPath Config 页切换 Application 后,监控表继续按旧 Application 的阈值给 Rx 光功率着色(没有 Page 62h 的模块,Tx 光功率也一样),Module Thresholds 卡片也显示旧值——除非离开再回到这个标签页,而且恰好是在 Data Path 到达 DPInitialized 之后。

现在每次监控刷新都带上每条通道正在使用的 Application(11h:206–213)。某条通道的 Application 变了,或它的 Data Path 刚过了 DPInit,工具就重新读取阈值,先读完再着色。Module Thresholds 卡片下方加了一行说明。

ZR 相干演示模块(mock_coherent_zr)的 AppSel 2 带有自己的一组光功率阈值(演示值),在 DataPath Config 页切到 AppSel 2 就能看到卡片随之更新。

主机通道切换(Page 1Dh):面板上的通道号可能不是电气通道号

CMIS 5.3 新增了主机侧通道切换(7.8 节、Page 1Dh,由 01h:252[7] 声明):每组 8 条通道内,可以把电气主机通道(线真正接的那条)连到另一条名义通道上。Application 和 Data Path 寄存器按名义通道编号——所以切换生效时,DataPath、Monitoring、Flags 各面板上的「通道 1」不一定是插在电气通道 1 上的那一路。

⚠ 工具以前既不读这一位,也不读 Page 1Dh。切换生效的模块上,所有面板照常显示通道号,没有任何提示:按面板去查通道 1 的线,查到的是通道 2 的业务。

现在:Module Info 多一行 Host Lane Switching(支持 / 不支持);支持的模块在 DataPath Config 标签页多一张 Host Lane Switching 卡片(在 Media Lane Switching 上方),逐条电气通道列出已下发(1Dh:136–143)和当前生效(1Dh:184–191)的名义通道,以及上次提交结果。有通道被换到别处时,卡片顶部写明是哪几条电气通道,并提醒其它面板的通道号是名义通道。多于 8 条通道的模块逐组读取,目标显示为绝对通道号。

这张卡片只读。24 通道演示模块声明支持,第一组里电气通道 1、2 互换,可以直接看到提示。

演示模块:后面几个 Bank 的输出状态不再照抄 Bank 0

在 24 通道演示模块上关掉通道 1,通道 9 和 17 的 Tx 输出状态也跟着显示「关」,而它们自己的光功率照常——这是演示模块的问题,不是工具读错:工具按 Bank 逐个读 11h:132–133(Table 8-95),演示模块却把 Bank 0 算出来的输出状态写进了 Page 11h 的每一个 Bank。

现在演示模块的每个 Bank 按自己的 Tx 关闭、强制静噪、Rx 输出关闭和通路状态给出输出状态;后面 Bank 的通道关掉后光功率也会随之变暗,重新打开恢复原值。连接时不会在这些通道上误报「Rx 输出变化」标志。真实模块不受影响。

诊断页和激光调谐表的「NA」

上一版把 Table 7-8 的 NA 值用到了监控面板。同一张表还规定了:实测激光频率(Page 12h,U32)的 NA 值是 0;SNR(U16)是 0;码型 BER(F16)是 0.5;码型误码数(U64)是最大值。

⚠ 在声明支持 NA 值的模块上,这些读数分别显示成 0 THz 的激光、0 dB 的 SNR、每两个比特错一个的链路、一千八百亿亿个误码——最后这个还会被除以比特数算成一个 BER。激光表更糟:实测频率一旦为空,表格根本画不出来。

现在这四处都显示 NA 并写明依据;误码数是 NA 时,由它算出的 BER 也显示 NA(「no valid error count」)。F16 的 0.5 有不止一种编码,按数值识别。未声明支持的模块照原样显示。

监控读数里的「NA」:模块自己说「没有有效采样」

规范 7.10.2 / Table 7-8 给每个基础监控量规定了一个 NA 值——模块拿不到有效采样时填的特殊数值:温度、TEC 电流、激光器温度是 -32768;Vcc、Tx 偏置、Tx 光功率是 0;Rx 光功率分两种,0 表示通道未使用,1 表示通道在用但暂时没有有效采样。模块在 0Ch:192.7(NaSupported,Table 8-73)声明它使用这些值。

⚠ 工具在 CMIS 5.4 面板上解析并显示了这一位,却没有用到读数上:温度没有有效采样时显示 -128 °C;Rx 通道没有有效采样时显示 0.1 µW(-40 dBm)——正好是真实接收机会报的范围,看上去就是一个读数。内置的 5 个演示模块(1600G DR8 / 16 lane、24 lane、两个相干可调)都声明了支持。

现在模块声明支持 NA 值时,这些读数显示为 NA,并写明原因(Rx 光功率会区分「通道未使用」和「暂无有效采样」);悬停说明依据。没有声明的模块,数值照原样显示——工具不会自己认定 -128 °C 不可能。Tx 关闭的通道在这些模块上报 0,按规范就是 Tx 光功率的 NA 值,所以会显示 NA。

顺带修正:Module Info 里的温度 / 电压行,模块没实现该监控时以前会显示「undefined °C」,现在显示「not implemented」。

软复位之后,先等模块能被管理

规范 Table 10-2:从复位释放到模块能读出寄存器默认值,最长 2 秒(tMgmtInit);Table 8-11 说软件复位「和把 Reset 硬件信号拉低足够时间再释放效果相同」,所以这 2 秒同样适用于 Control 面板上的复位按钮。这段时间里模块可以对任何读写都不应答,之后才开始上电(ModulePwrUp)。

⚠ 工具等待复位完成时只按 ModulePwrUp 的声明时长(01h:167,演示模块是 100–500 ms)算,复位后的第一次读取也不重试。在一个真用满 MgmtInit 时间的模块上,复位后第一次读状态就直接报错,页面的等待也可能在模块一次都没应答之前就结束了。

现在复位的等待预算是「2 秒 MgmtInit(Table 10-2)+ ModulePwrUp 声明时长」,复位后的读写在这 2 秒内被拒会自动重试;超过仍不应答,才报错。进入/退出低功耗不经过 MgmtInit,照旧只按声明时长等。

Tx 开关的时间上限,模块说了不算

规范 Table 10-8 的注 1:「这里给出的数值是 MaxDurationDPTxTurnOff 和 MaxDurationDPTxTurnOn(01h:168)这类声明时长的上限」——Tx 输出关断最长 100 ms(ton_txdis),开启最长 400 ms(toff_txdis)。

⚠ 工具判断一条通道是否卡在 DPTxTurnOn / DPTxTurnOff 时,只看模块自己声明的时长。声明「1–5 s」的模块,通道在 DPTxTurnOn 停了 4 秒,悬停提示还说这是正常的——而这个声明本身就超出了规范允许的范围。

现在这两个状态取「模块声明」和「规范上限」中更严的那个来判断;上限来自规范时,提示会写明「超过了 CMIS 允许的时间(Table 10-8,模块声明的是……)」,而不是说模块自己怎么声明的。模块声明得比规范更严时,仍按模块的来。DPInit / DPDeinit 规范没有另设上限,照旧按声明判断。

写入之后,模块可以暂时不应答

规范 Table 10-4:一次 WRITE 之后,模块可以在最长 10 ms(tWRITE,总线上叫 tNACK)内拒绝接下来的任何读写;写非易失存储器(Page 03h 用户 EEPROM,规范 8.7)之后最长 80 ms。5.2.3 给主机的办法是:按最坏时序等待、被拒后重试,或先探测模块是否就绪。

⚠ 工具三样都没做:所有适配器把「模块没应答」报成错误,工具直接当作失败返回。于是在写入后会短暂不应答的模块上,DataPath、Squelch、Loopback、PRBS 的 Apply 都会报错,Raw Registers 写完也读不回来。上一版把长写入拆成连续几次写入之后,第二段更容易落进第一段的拒绝期。

现在每次写入之后,工具会在规范允许的拒绝期内(一般 10 ms,Page 03h 为 80 ms)对被拒的读写自动重试;超过这个时限仍被拒,才作为真正的错误报告——不会无限等下去。没有写入在先时,被拒就是被拒,不重试。

会变的多字节量,一个一个读

规范 5.2.5.1:用和寄存器同样长的一次 READ 读一个多字节只读标量,模块保证读到的是同一时刻的值——「这条尤其适用于任何 2、4、8 字节的状态或监控寄存器」。而「对多个寄存器或寄存器数组的 READ 不保证一致」。

工具显示的会变的多字节量,之前都是整块读的:

  • 通道监控(Tx 光功率、偏置、Rx 光功率,Page 11h,每个 U16)
  • 诊断窗口(Page 14h:192–255):BER、SNR、误码与总比特计数——支持整页读的模块上是一次 64 字节
  • 实测激光频率(Page 12h,每个 U32)、采集计数器(Page 61h)、数据通路时延(Page 15h)
⚠ 模块在一次 READ 进行中更新数值时,整块读出的某个值可能高字节是上一次采样、低字节是下一次采样,差出 256 个计数——看起来就是一个正常读数。模块级监控(温度、Vcc、Aux)早就是逐个读的,其它都不是。

现在这些量都按各自的长度逐个读取:U16 读 2 字节,U32 读 4 字节,计数器(U64)读 8 字节。代价是读寄存器的次数变多,刷新会略慢一点。Raw Registers 仍按你给的长度读取——在监控区整块读时,单个值同样不保证一致。

一次 WRITE 最多 8 字节

规范 5.2.2.2:「一次成功的 WRITE 写入最多 8 个字节」;更长的只有第 8 章明确允许的地方才行。被拒绝的 WRITE「对模块没有任何作用」。

读取早就按这个上限分块了,写入却没有。两处会一次写超过 8 字节:

  • PRBS 用户码型(13h:224–255,最长 32 字节;Table 8-134 并没有放宽)
  • Raw Registers 写入(可以一直写到页尾)
⚠ 没有哪个适配器会按 8 字节切:CH341 整段一次发出,CP2112 和 MCP2221 按 60 字节左右切——那是它们自己的包长,不是模块的上限。守规矩的模块可以拒绝这次写入,而面板照样说「已写入」。

现在超过 8 字节的写入会拆成多次、每次最多 8 字节;Raw Registers 写完会注明分了几次(规范 5.2.5.2:多字节写入本来就不保证是一次整体写入)。刚好 8 字节的写入(比如一个 PRBS 引擎块、8 个 AppSel 字节)照旧一次写完。

唯一的例外是 Page 9Fh 的 CDB 消息头:写到 9Fh:129 就会发出 CDB 命令(规范 7.2.3),拆开写会让命令在消息头还没写完时就发出。所以超过 8 字节、又包含字节 129 的写入会被拒绝,并提示先写其余部分、最后写含 129 的那段。

内置模拟模块现在也会拒绝超过 8 字节的 WRITE,于是整套测试就成了一次全面检查:其它所有写入口都没有超过这个上限。

13h:177.7 作用到哪里:「被忽略」只在门控测量时成立

13h:177.7 StartStopIsGlobal(Table 8-127)置 1 时,在一个 Bank 上写启停控制——177.5 的复位、160 / 168 的检测器使能——等同于在所有 Bank 上同时写。

Table 8-129 给了一个例外:门控测量、并且模块只有一个全局 gate 定时器(13h:129.3 = 0)时,这个位被忽略。测量窗口那一行把这个例外当成了整条规则:只要 129.3 = 0 就说「被忽略」,不门控时也这么说。而不门控的情况归 Table 8-128 管,那里 177.7 = 1 有专门的一行:切换 177.5 会复位「所有 Bank 的所有通道」。

⚠ 于是在不门控、只有全局定时器的多 Bank 模块上,页面说这一位无效,而它其实让每一次启停都作用到所有 Bank。另外,勾选检测器使能是在 PRBS Checker 卡片上,那里对此一个字都没有:这一位生效时,勾 lane 1 会连带启动 lane 9、17。

现在:

  • 这一位作用到哪里由服务端统一判断,BER、Counters、PRBS 三张卡片用同一个结论:只有门控测量 + 全局定时器时说「被忽略」(标注 Table 8-129);其余情况说「作用于所有 Bank」。模块不做门控(13h:129.7-6 = 00b)时按不门控处理。
  • 该位为 0,或模块只有一个 Bank(无处可去)时,什么都不说。
  • PRBS Checker 卡片顶部会写明哪些通道一起启停,例如 24 通道模块上「lanes 1, 9, 17 start and stop together」。

这一节规范带着编辑注释「应改写以更清楚」,Table 8-130 里还有「因为 129.3 = 0 所以被忽略」这种与表名矛盾的行。工具只采用规范说得明确的部分,不自己补全。

Bank 广播:每一个按 Bank 写入的地方都要检查

Table 8-11:Lower 0x1A[7] BankBroadcastEnable 置 1 时,对通道分 Bank 的页上任何控制寄存器的写入,都会同时写进所有 Bank。

工具早先给 DataPath 和 Squelch 的写入加了这项检查,后来媒体通道切换也加了。另外四个同样逐 Bank 写入的地方却没有:

  • Loopback 和 PRBS(Page 13h)
  • 激光调谐(Page 12h,按媒体通道分 Bank,规范 8.15)
  • 采集计数器清零(Page 60h,「每个 Bank 对应 8 条通道」,规范 8.30)
⚠ 它们一个 Bank 接一个 Bank 地写。开了广播,每一次写都落到全部 Bank,最后一个 Bank 的值盖掉前面所有:在 24 通道模块上只开 lane 1–4 的 PRBS,结果一条都没开;清零 lane 1 和 3,lane 9、11、17、19 也被清掉;只调媒体通道 3 的激光,媒体通道 11 也跟着变——每一次都报告成功。

现在这四处也会拒绝各 Bank 不一致的请求,说明是哪一项,原配置不动;各 Bank 取同一个值时照常写入。激光调谐会指出会被连带改动的媒体通道,例如 setting the channel of media lane 3 would set it on media lane 11 too。PRBS 检查的是每个 Bank 实际要写的整块内容,包括请求里没提、沿用原值的字段。

规则属于写入方式,不属于最先发现它的那个面板:凡是选 Bank 再写的地方都要问这一句。

媒体侧环回与媒体侧 PRBS,同样按媒体通道

上一版把「按媒体通道」这条规则教给了 Page 10h 的通道控制。Page 13h 上有同一类控制,却被漏掉了:

  • 媒体侧环回(MediaSideOutputLoopbackEnable / MediaSideInputLoopbackEnable,Table 8-131)环回的是媒体通道——Figure 8-2 的示意图上就写着「只画出一条媒体通道」。
  • 媒体侧 PRBS 发生器与检测器(Table 8-121 / 8-125)按媒体通道运行:规范 8.16.11.1 说的是逐个切换「媒体(13h:168)通道的检测器使能位」,Table 8-138 也把它们的失锁标志记为「按媒体通道」。
⚠ 两个面板都按主机通道排行。在相干模块上(8 条主机通道、1 条媒体通道),每一行媒体侧里有 7 个勾选框控制的是模块不存在的通道:勾上就在一条不存在的通道上开了发生器,写入照样报告成功。PRBS 表随后还把那条通道的失锁历史显示成「从未失锁」——那是对一条不存在的通道所作的报告。

现在:

  • 媒体侧环回的两行、媒体侧发生器和检测器的整行(En / Invert / ByteSwap / FEC / Pattern),在模块没有的媒体通道上置灰,悬停说明依据 00h:210 和对应的表;置灰但保留原值。
  • 对不存在媒体通道的使能位做改动会被拒绝并说明原因;原值不变照常放行。只判使能位:它才是让东西跑起来的那一位,而页面回写的 FEC 位置对所有通道只有一个合法值。
  • 不支持逐通道环回的模块不受影响:规范规定那种模块上任何一位都代表全部通道,那一位并不指向哪条通道。
  • 失锁历史:不存在的媒体通道显示 n/a,接口里为 null。主机侧照旧。

规则属于寄存器家族:凡是按媒体通道索引的控制,都要问一句「这条媒体通道在不在」。

Tx 输出与 Tx 静噪的开关,也是按媒体通道的

Table 8-79 把 Page 10h 上的三项通道控制定义为按媒体通道:OutputDisableTx(「媒体通道 <i> 的 Tx 输出禁用」)、AutoSquelchDisableTx 和 OutputSquelchForceTx。

写这三项的两个面板——DataPath 表的 TX Enable 列、Squelch 表的两行 Tx——都按主机通道排行,也没有说明索引的其实是另一侧。

⚠ 在相干模块上(8 条主机通道、1 条媒体通道),这些行里有 7 个勾选框控制的是模块不存在的通道:勾上就写下一个无处生效的位,而写入照样报告成功。

现在:

  • 这些格子置灰,悬停说明依据 00h:210 和 Table 8-79;置灰但保留原值——页面整字节回写,清掉反而成了一次改动。
  • 对不存在媒体通道的那一位做改动会被拒绝并说明原因;原值不变照常放行。
  • 表头标明 media lane。两行 Rx(主机侧)不受影响。
  • 模块级 Tx 禁用(01h:151.0)同步勾选时,跳过置灰的格子。

上一版让诊断页学会了「媒体通道可能不存在」;这一版是同一条规则的写入一侧——规则属于寄存器家族,不属于最先发现它的那个面板。

诊断页:对模块没有的媒体通道,不再给出「测量值」

Page 14h 的诊断数据按侧命名(Table 8-139):MediaSideSNRLane<i>、MediaSideBERLane<i>,以及「媒体通道 1–4 / 5–8 的误码与比特计数」——都是媒体通道。

相干模块把 8 条主机通道汇进一路光载波,只有 1 条媒体通道,00h:210 会说明缺哪几条。Monitoring 和 Flags 早已照此处理(不存在的媒体通道显示 n/a),诊断页却没有。

⚠ 在 mock_coherent 上,SNR、BER、误码计数三张表都给出了8 条媒体侧读数,其中 7 条是模块根本没有的通道——比如第 8 条的媒体 BER 显示为 9.92e-05,那是对「不存在的东西」的测量。

现在这三张表对不存在的媒体通道显示 n/a,悬停说明依据是 00h:210;接口里对应的值为 null,并附 media_lanes_present 列表。主机侧不受影响。

误码计数表还有一个反方向的问题:一条通道一个比特都没计数时,接口给出 BER 0.0——也就是「零误码」,这是一个结论;而页面只显示大于 0 的值,于是真正零误码的测量(比如一万亿比特里没有一个错)也显示成「—」。「没有测量」和「完美的测量」看上去一模一样。现在没计到比特时为 null(显示「—」),零误码显示为 0,并说明这是零计数而非测得的下限。

被拒绝的 Apply,此前其实已经动了模块

DataPath 页的 Apply 会拒绝模块会静默丢弃的请求,并说明:「this would report success and change nothing」。

⚠ 但这个判断是在写完之后才做的:极性翻转、Tx 输出关闭、暂存的 Application、DPDeinit 都已经先写下去了。其中 DPDeinit 和通道控制写下去就立即生效(Table 8-77、8-78)。实测:上一次 Apply 还在进行中时,再按一次带着 DPDeinit 和 Tx 关闭的 Apply——提示「被拒绝、什么都没变」,一秒后所有数据通路都掉到了 DPDeactivated,通道 1–4 的 Tx 输出也被关了。

这不只是上一版加的那一条。检查下来,五种拒绝全部如此:配置进行中、数据通路处于过渡态、非初始化态下的 ApplyImmediate、模块不支持 ApplyImmediate、以及同时要两个触发器。

现在这五种判断都挪到了任何写入之前:被拒绝的请求对 Page 10h 一个字节都不写,提示说「什么都没变」就真的什么都没变。不被拒绝的请求照常写入,规范要求的「DPDeinit 与 Apply 同一次写入」的释放流程也不受影响。

一个已经生效了的「拒绝」,比不拒绝更糟——它恰好在模块发生变化的那一刻,告诉操作员去别处找原因。

演示模块:两个端口可以同时重配

上一节的规则是按数据通路的:规范 6.2.4.2 说模块忽略的是「那些通道上的新触发」,并且「不在那些通道所属的数据通路上执行」——不是整个模块。工具从 v2.115.0 起就是这样判断的。

⚠ 内置的演示模块却比规范更严:它整个模块只有一个「进行中的命令」槽位,槽位被占着的时候任何触发都被丢掉。于是在 mock_fr4x2(两个 400G 端口)上,端口 1 正在重配时对空闲的端口 2 按 Apply,工具正确地放行了,演示模块却悄悄扔掉——通道 5–8 从没进入 ConfigInProgress,生效的 Application 也没变。

一个比规范更严的演示模块,教给人的是一条规范里没有的规矩。现在演示模块每条数据通路各自跑自己的命令、各自计时:两个端口可以同时重配、各自报告结果;一次触发如果同时点到忙和闲的两条数据通路,只在闲的那条上执行;忙的那条仍然照规范忽略。

上一次 Apply 还没做完,再按一次就被模块悄悄扔掉

规范 6.2.4.2:

「当某条数据通路的通道上,先前触发的配置命令仍在处理中时,模块忽略这些通道上的新触发……因配置进行中而忽略触发位,不会向主机提示。」

工具此前已经拦下了 6.2.4 里另外两种「静默丢弃」——数据通路处于过渡态、以及在非初始化状态下用 ApplyImmediate——唯独漏了这一种。

⚠ 实测:第一次 Apply 之后,所有通道的 Config Status 都是 ConfigInProgress;紧接着再按一次,工具回复「已应用到通道 1–8」——而模块已经把它丢了。

现在,只要本次要触发的通道里有任何一条仍在 ConfigInProgress,请求就会被拒绝,并点名是哪几条通道;不会写出触发位。等上一条命令出结果(Monitoring 页 Config Status 列)再按即可。

  • 和「过渡态」那条不同,这条对所有模块都成立——规范对「过渡态」的忠告只针对支持无干预重配的模块,而 Table 6-3 和 6-4 的每一种配置流程都以「ConfigStatus = ConfigInProgress」开头。
  • 按数据通路判断。一个带两个 400G 端口的模块,一个端口正在重配时,对另一个端口的 Apply 照常放行。
  • 被拒绝的上一条命令不算「进行中」——它已经结束了,修正后可以立即再次 Apply。

媒体通道切换:禁用时按 Commit,模块什么都不做,也什么都不说

Table 8-196 对 EnableMediaLaneRedirection(6Dh:152)的定义是:

「0b:禁用——commit 命令没有效果。」

注意是「没有效果」,不是「被拒绝」:模块什么都不改,也不写任何 RedirectionCommitResult,所以它从不说自己忽略了什么。

⚠ 工具此前照样写下 commit,回复「已提交、已完成」,页面弹出绿色的 Redirection committed;表下接着提示「press Commit」——也就是刚按过、并且再按还是无效的那个按钮。更糟的是页面每次请求都带上 Enable 复选框的状态,复选框没勾时,每一次 Commit 都变成「先禁用、再提交一个不可能发生的 commit」。

现在这种 commit 会被直接拒绝,且在写任何东西之前——同一请求里的映射也不会被暂存,不会留下半截操作。判断时按「这次请求自己的 Enable 已经写入之后」来算,因为 Enable 先写、Commit 后写。6Dh 按 bank 分组启用,任何一组处于禁用都会被拒绝,错误信息会点名是哪一组。只「暂存」(Stage)不受影响——那本来就是启用之前准备映射用的。

表下的提示也改了:模块处于禁用状态时,它会说「先勾 Enable,再 Commit」,而不是让你再按一次 Commit。

结果列按类着色。Table 8-196 的结果码 3–6 都是拒绝,大于 6 的是保留值。此前它们全部以同一种中性文字显示,「Rejected: conflicts with active DataPath」和「Success」看上去是同一类回答,保留码则显示成「Code 7」。现在成功为绿、执行中为黄、拒绝为红,保留码写作「Reserved (7)」。

通道极性:同样八个位,在宽模块上是三个意思

Module Info 里的 Default Polarity 读的是 01h:171-172,一共八个位。规范 8.4.13 说得很清楚:

「当模块支持多于八条通道时,这里定义的通道极性适用于每一组八条通道,除非模块声明(见 Table 8-58)支持在 Page 60h 上做逐通道说明。」

所以这八个位到底在说哪些通道,取决于通道数和一项声明,而不是取决于寄存器本身:

  • 不超过八条 —— 就是这个模块的通道,无须多说
  • 更宽、且有 Page 60h —— 它们只描述第一组八条通道;逐通道的实际状态在 Page 60h 上(8.30.1)
  • 更宽、且没有 Page 60h —— 第 1 通道那一位同时也是第 9、第 17 通道的,模块没有别的地方可以另行说明
⚠ 工具此前不管哪种情况都只列八条通道。第三种情况代价最大:一个 16 通道、没有 Page 60h 的模块,明明在说「第 1 和第 9 通道是反的」,那一行却对第 9 通道只字不提——照着它接线,十六条里有八条会接反。

现在这一行会按实际适用的通道铺开(第三种情况下列出 1、9),并在后面注明它说的是哪一组通道、依据是哪一节。

Page 60h 的极性表:每个 bank 都从 1 号通道重新编号

规范 8.30 说「Page 60h 的每个 bank 对应 8 条通道」。工具把各 bank 读到的结果直接首尾相接,却没有重新编号——于是一个 24 通道模块返回的数据里,有三条通道都叫「1 号」。

界面上那张表是按位置渲染的,所以看着是对的;错的是每一条数据自己声称的通道号。这种错法不会在屏幕上露馅,只会在有人拿这份数据去对通道时才发作。现在跨 bank 统一编号为 1…N。

极性表底下那段说明,讲的是另一张表

⚠ 「Lane Polarity Status」表下面挂着一段讲标志读后自清、●! 历史标记、DP Changed 的文字——那是「Lane Flags」表的说明,而 Lane Flags 卡片下面一句说明都没有。

放在极性表下面它是错的:60h:128-129 是 RO(Table 8-188),不是 RO/COR——那里没有任何东西是锁存的,读它不清除任何东西,这张表里也没有 DP Changed 这一列。工具自己那张「读后自清」清单里本来就没有 Page 60h。两段说明现在都回到了各自的表下面。

Recall 那一列,从来没跟模块声明的缓冲区数量对过

信号完整性表里,Tx EQ Recall 填的是缓冲区编号(10h:154-155,Table 8-83:01b 是 1 号、10b 是 2 号);而 01h:161.6-5 声明的是缓冲区数量(Table 8-54:01b 表示一个、10b 表示两个)。两者本来就该比一比,而工具从来没比过。

⚠ 于是在一个只有一个缓冲区的模块上,某条通道暂存的「buffer 2」会和真正有效的值一样显示成绿色——而模块根本没有那个缓冲区可以调用。

这一列本来就被单独拎出来渲染过(编号不是量值,1 和 2 是两个缓冲区的名字,不是「更大 / 更小」),而一旦离开通用单元格,它也就离开了通用单元格里那两道「对照模块声明」的检查——旁边的 Tx Input EQ 有上限检查,Rx Amplitude 有编码集检查,只有它什么都没有。

这一列比旁边几列更要紧。规范 6.2.5 说其它暂存的信号完整性值只在 ExplicitControl 置位时才被采用(而本工具写的是清零),唯独 recall 例外——「recall,如果支持,在 ExplicitControl 未置位时同样生效」。所以它是本工具每一次 Apply 都会真正带上的那一个。

现在越界的那一格标红,并写明模块声明了几个缓冲区、以及 Apply 带上它会收到 ConfigRejectedInvalidSI。11b 仍按「保留值」单独标注——它根本没指向任何缓冲区,和「指向一个不存在的缓冲区」是两种不同的错。

声明本身是保留值(11b)时,表下会明说。那种情况下模块没告诉你它有几个缓冲区,下面的编号一个都没法核对;而一张会检查别的列的表在这里一声不吭,读起来就像「查过了,没问题」。

模块控制面板里那一位,从来就不是状态

Table 8-3 里另外两种访问类型让「读」本身撒谎,而 Lower 26.3 的 SoftwareReset 正是其中之一(Table 8-11 把它定为 WO/SC):

WO/SC —— 「从一个 WO/SC 元素读出的值为零,除非读得太早——在模块尚未评估并清除所写入的非零位之前。」

工具里有两个地方相信了这一位。

一是面板。它和另外四个 RW 位并排显示在同一列状态点里,悬停提示写着「Reset in progress」或「Idle」。两个都不对:不管模块在干什么,那个点都是灭的;而它唯一可能亮的时刻,意思是这次读发生得太早,不是「正在复位」。

⚠ 二是写入路径,这一处更严重。字节 0x1A 把几个互不相干的控制打包在一起,所以每次改动都先读回来再合并(这本身是早先一轮的修复:免得切低功耗时顺手清掉 SquelchMethodSelect)。合并却是从读回来的整个字节开始的——于是一次落在那个瞬态窗口里的读,会把第 3 位原样写回去:在一次毫不相干的改动中间,又触发了一次软复位,没有任何人要求过它。

这个窗口等不过去。「evaluated and cleared」在整份规范里只出现一次,就在 Table 8-3,旁边没有给任何时间。所以读-改-写永远无法确认自己已经在窗口之外,只能不信任读回来的那一位:现在合并前先把写-only 的触发位剥掉,只有明确点名要复位的调用者才能触发它——「复位模块」按钮照常工作。

面板那一格现在写的是 WO/SC trigger,不再是一个状态点;访问类型由后端随数值一起送来,页面不另存一份——同一张规范表抄两遍,正是两边开始打架的方式。另外四个位是 RW,照常显示状态。

裸寄存器面板会把模块的故障记录读没了

规范 Table 8-3 定义了六种访问类型,其中一种让「读」本身成为破坏性操作:

RO/COR —— 「一个 RO/COR 字节中的所有位,在该字节被读取之后由模块清零。」

这些字节就是锁存标志——模块记录「发生过某件事」的地方:某条数据通路弹过、某个检测器失锁过、某次调谐被拒绝过。模块不保留第二份。本工具每一个会读这些字节的面板,都会把结果折进「标志历史」,正是为了这个原因;而裸寄存器面板不会——在那里它们只是一串数字。

⚠ 于是在这个面板上读一次 11h:134,模块攒下来的故障记录就没了,而且没有任何提示。十六进制转储看起来完全一样——不管那些字节里原本有没有东西。

现在读之前会先问,并写明具体哪几个字节、以及它们记录的是什么:

This read clears what it returns.

  11h:134-137 — lane Flags (Tables 8-96 to 8-98) — data path state
                changes, Tx failure, LOS, CDR loss of lock, ...

CMIS Table 8-3: all bits in a clear-on-read byte are cleared by the
module once the byte has been read. ... the module keeps no second
copy. ... a raw read cannot, so whatever comes back is the only
record left.

Read anyway?

读完之后,转储顶部会再说一遍——那个确认框一按就没了,而屏幕上的这些字节已经是仅存的记录。

六个块,包括两个本工具没有面板、但这个面板能够到的:模块级标志(Lower 8-13)、通道标志(11h:134-153)、激光器调谐标志(12h:231-238)、诊断标志(14h:132-139)、Network Path 标志(17h:128)、VDM 门限穿越标志(2Ch 整页)。12h:230 故意不在其中——那个汇总寄存器是普通 RO,读它不清任何东西。

范围会按实际读到的字节裁剪。只读了两个字节却提示「整块 134-153 被清掉了」是夸大其词,而一个学会了「这个提示会夸大」的操作员,很快就不再看它了。

Flags 面板:名字里的 Tx / Rx 不等于哪一侧(11h:134-153)

上一版处理了 Monitoring 表的混侧问题。这一版是同一件事在 Flags 面板上,而且更大、也更绕——因为这里连「Tx 归一侧、Rx 归另一侧」这个直觉都是错的。Table 8-96 到 8-98 对每一行都写明了:

字节标志规范原话
134DPStateChangedhost lane
135FailureFlagTxaffecting media lane
136-138LOSFlagTx / CDRLOLFlagTx / AdaptiveInputEqFailhost lane(Tx 的输入来自主机)
139-146Tx 光功率 / 偏置的门限标志media lane
147-152LOSFlagRx / CDRLOLFlagRx / Rx 光功率门限media lane
153OutputStatusChangedFlagRxhost lane

也就是说:Tx 那一组裂成三段,Rx 那一组裂成两段,按名字里的 Tx/Rx 去分,二十个里会错五个。其中 15 个是按媒介通道索引的。

⚠ 后果是这个模式至今最大的一处。一块把八条主机通道汇进一路光载波的相干模块,第 2-8 行每行有 15 个绿点说「已检查,一切正常」——而它们说的是模块根本没有的媒介通道。其中包括 Rx LOS: 无告警,意思是「这条光纤上有信号」,而那条光纤不存在。

现在这 15 个在媒介通道不存在时显示 n/a,悬停说明指出它是按媒介通道索引的、以及模块在 00h:210 里声明没有这条通道;5 个主机侧的照常显示——模块的八条主机通道都在。Flags 表头也和 Monitoring 一样,每一列都标明自己属于哪一侧,并特别点出 Tx Fault 和 Rx Output 这两个不随名字走的例外。

一个 API 形状上的取舍。这个接口里每条通道的字典,原本「每一个为 true 的键都是一个置位的标志」。本想再加一个 media_lane_present 字段,但它会让任何按这个约定收集告警的调用方把一条健康通道读成有告警。所以没有加——null 已经携带了同样的信息,而 /api/module/monitoring 本来就直接给出这个字段。

Monitoring 每一列到底在说哪一侧的通道

上一版把「数据通路走哪几条媒介通道」补到了 DataPath 面板。这一版处理它的另一半:Monitoring 表自己——它的每一列都按通道索引,而 CMIS 对主机侧和媒介侧是独立编号的,表里却只写了「Lane n」。

列寄存器按哪一侧编号
Tx Power / Tx Bias / Rx Power11h:154-201媒介通道(Table 8-99 标题就是 Media Lane-Specific Monitors)
DataPath State11h:128-131主机通道(DPStateHostLane)
Output11h:132 Rx / 133 Tx两侧各一个
Config Status11h:202-205主机通道(「for the Data Path of host lane <i>」)

Output 那一列是最要紧的。Table 8-95 原文:「Rx 输出主机通道的信号有效性在 OutputStatusRx(11h:132)中声明」、「Tx 输出媒介通道的信号有效性在 OutputStatusTx(11h:133)中声明」。同一格里的两个点,说的是模块两侧不同的通道。现在每一列都标出了自己用的是哪一侧,Output 标的是「Rx host · Tx media」。

⚠ 而这不只是标注问题,它有后果。这一行里其余每一个按媒介通道索引的值,在 00h:210 说模块没有这条媒介通道时都会留空——那是之前某一轮为了不把 0.0 µW 画成告警而加的。唯独 OutputStatusTx 没被挡住。于是一块合规的模块只要在那里报 0,面板就会在根本不存在的七条通道上显示「输出被静音了,去查 Tx disable / force squelch / Rx output disable」——而同一行的光功率却是正确留空的。

演示模块此前把这件事盖住了。它对全部八条通道都声明 Tx 输出有效,包括它自己说没有的那些媒介通道——这是任何模块都做不出的声明。现在它只对真有的媒介通道置位;而超过 8 条通道的模块一条都不隐藏——8.3.7 说那类模块无法无歧义地声明自己的媒介通道。

这条数据通路走的是哪几条媒介通道(7.9.1)

主机选的是主机侧通道;媒介侧通道是跟着算出来的,规范 7.9.1 把这个推导定死了:

「第一个 Application 实例(按主机通道编号顺序)将使用该 Application 所通告的、编号最低且可用的媒介通道起始的通道组,这会占用一组连续编号的媒介通道。第二个 Application 将使用下一个编号最低的可用媒介通道起始的通道组,依此类推。」

而这个结果此前没有任何地方报告过。在不支持媒介通道交换的模块上,它不是一个寄存器——规范也不需要一个,因为规则已经决定了它;而本工具从来没有把它算出来。

⚠ 与此同时,Monitoring 表把「媒介侧的测量值」和「主机侧的状态」放在同一个行号上,而 CMIS 对两侧是独立编号的。Table 8-99 的标题就是「Media Lane-Specific Monitors」——Tx/Rx 光功率和 Tx 偏置按媒介通道索引;而 DataPath State、Config Status 按主机通道。当 Application 的媒介宽度等于主机宽度时两者正好对齐,什么问题都没有;不相等时就会错开——两条 4H/1M 的相干数据通路,主机通道 5-8 其实测在媒介通道 2 上,而媒介通道 5 不属于任何一条数据通路。

现在 DataPath 面板的每条数据通路会写明它占用哪几条媒介通道(例如 media 1–4),悬停说明里指明这正是 Monitoring 表里衡量它的那几行。

输入本来就在读,只是没送到该去的地方。MediaLaneAssignmentOptions(01h:176-190)一直以原始位图印在 Applications 页签上;而 DataPath 的两个端点解析描述符时把这一整块传成了空,于是那条路径上这个字段恒为「未声明」。现在两处都传了,并且按连接缓存——它是静态通告,而 DataPath 面板每次刷新都要用。

只答第一个 bank,再往后不作答。7.9.1 说「每个 bank(即 8 条主机通道一组)总是有 8 条外部媒介通道」,所以这个池子不会越过通道 8 继续往下数;而 8.3.7 更说了,超过 8 条通道的模块根本无法无歧义地声明自己的媒介通道。分配怎么跨 bank 延续,规范没有写——替它回答就是凭空造规则。同理,媒介宽度超过一个 bank 的数据通路也不给答案,而不是去编号这个 bank 根本没有的第 9-12 条。

支持媒介通道交换的模块会标注「nominal」。那类模块可以改写这个映射,它实际提交的映射在 Page 6Dh 上,那才是真相。

这个 Application 能从哪条通道开始(HostLaneAssignmentOptions)

规范 6.2.3.2.1 把这件事写成对主机的义务:「主机必须按模块为该 Application 通告的 Lane Assignment Options 来分配通道」。这个字段是 Application 描述符的第 4 个字节:「位 0-7 构成对应主机通道 1-8 的位图。位为 1 表示该 Application 的通道组可以从对应的主机通道开始」。

工具一直在读这个字节,也一直把它以原始位图的形式印在 Applications 页签上。而真正做选择的地方是 DataPath 面板——那里的下拉框把每个 Application 都列在每条通道上,对此只字不提。操作员要等到 Apply 之后,再去把一个 4 位的状态码ConfigRejectedInvalidDataPath(4h)翻译出来才知道。

本版把规则放到了做选择的那一刻:

  • 下拉框每一项后面都写明这个 Application 能从哪几条通道开始,例如「App 2 — 400GBASE-DR4 4H/4M · begins on 1, 5」。
  • 当前暂存的配置里若有数据通路起始在不被允许的通道上,那一行会标出「may not begin here」,并说明模块通告的是哪几条、以及模块会回哪个状态码。
⚠ 但写入照样放行——这是有意的。本工具划的那条线是:模块会不会作答。模块会默默吞掉的写入,工具替你拦(否则「提示已应用、实际什么都没做」是最难查的一种);而数据通路起始越界,模块会在 ConfigStatusLane 里指名道姓地回一个代码。看真实模块拿到一个非法分配会怎么做,本来就是这个工具存在的理由之一。所以规则在写入之前提示,写入本身照旧。

规则管的是「起始」,不是「哪条通道带哪个码」。一个 4 通道的 Application 从通道 1 起,会占用通道 2-4,主机要把同一个 AppSel 写进这四条——后三条是延续通道,位图对它们只字未提。若拿每条通道去对位图,一块完全合规的模块上每四条就会有三条被误标。

位图只有 8 位,对应通道 1-8。超过 8 通道的模块上,规范没有说这 8 个位怎么延伸——通道 9 是不是「bank 1 的通道 1」,还是干脆不在覆盖范围内。所以检查到通道 8 为止,再往后不作判断:替规范回答一个它没回答的问题,等于凭空造一条规则。16 通道的演示模块因此不会被误标。

等得不够,读到的不是错误而是答案(第 10 章的时间参数)

工具里每一处固定等待,都是对规范第 10 章某个时间参数的无声断言。这一版把它们逐个对了一遍——而规范把「等待」分成几类,关键差别在于主机等得不够时会发生什么:

来源类型等不够的后果
Table 10-4ACCESS hold-off模块拒绝访问,主机能发现
Table 10-5内容依赖不拒绝,直接给陈旧数据
Table 10-6条件到标志不拒绝,标志只是还没立起来
⚠ 工具在会报错的那一类上等满了,在两类不报错的上都等短了。Table 10-5 原文:「模块不会阻止访问陈旧数据(即过早的 ACCESS 不会被拒绝)」。所以等短了不会得到一个错误,而是得到一个数。
  • 诊断数据选择器(14h:128):等 5 ms,而 tDDCS 是 10 ms。诊断数据区是 64 个字节,含义完全由选择器决定。读早了拿到的是上一个选择器的那 64 个字节,按这一个选择器的格式解出来——误码率被当成错误计数读,数值完全在合理范围内,哪里都不会报错。
  • 激光器调谐:写完等 50 ms 就去读标志,而 ton_flag 是 200 ms。「模块拒绝了这次调谐」这件事只有 Page 12h 的标志会说,而那个等待就是「没有通道被拒绝」这句话的全部依据。等一半的时间去读一个还没立起来的标志,读到的是「没有」——和「确实没被拒绝」一模一样。

页切换(tBPC)本来就是对的:工具读模块自己通告的 01h:169.3-0,读不到才退回 10 ms。这也正是这三个数现在的写法——每个常量都标注了自己出自哪张表,下一个要加延时的人有地方可查。

还有一件更直接的事:服务端算出了「哪些通道被拒绝」,面板却没看。按下 Apply 之后,无论模块答了什么,界面都弹「Laser tuning applied」。而那些标志是读一次就清零的——错过这条提示,它们不会留在屏幕上等人回来看。现在被拒绝时会弹红色提示,写明是哪条通道、因为什么,并且停留 12 秒。

诊断标志也一样,而且上一版这句话说错了(13h:206-213)

⚠ 先更正:上一版说「12h:239-246 是规范里唯一默认屏蔽的一组」,这是错的。四组里有两组默认屏蔽——除了激光器调谐那组,诊断屏蔽位(13h:206-213)也是,Table 8-133 用一句话写明:「本页所有屏蔽位的默认值为 1(屏蔽)」。另外两组(模块级与通道级)则根本没有规定默认值。这句错话进了工具提示、手册、skill 和发布说明,现在全部改正。

更正的同时也发现:被我说错的那一组,本身就有和上一轮完全相同的毛病。诊断标志在 14h:132-139——参考时钟丢失、各通道门控完成、图案发生器失锁、图案检测器失锁——工具把它们全都读了、还记了历史,而它们的屏蔽位在 13h:206-213,一个都没读。所以一块没人配置过的模块,跑 BER 时检测器中途失锁,主机根本不会被中断,而 PRBS 面板说不出这件事。

现在 LOL 那一列会标注:亮着的标志和历史记录里的标志若被屏蔽都会加 masked;安静的通道只在 tooltip 里说明——因为默认就是屏蔽,四张表全铺上「masked」只会没人看。参考时钟那条提示同理(它的屏蔽位是 13h:206.7,按模块而非按通道)。

顺带修正了块长度。工具此前把这一对按 18 字节配对(14h:132-149 对 13h:206-223),两张总览表确实都这么写。但明细表说了算:Table 8-138 的标志到 139 为止,Table 8-133 的屏蔽位到 213 为止、并把 214-223 标为 Reserved[10],而 Page 14h 总览自己的下一行也把 140-149 标为 Reserved[10]——也就是说那张总览表自相矛盾,而它的 Reserved 行与明细表一致。已对照渲染出的原始页面核实,不是文本抽取错位。目前还没有代码用到这个长度,这是它一直无害的唯一原因。

演示模块此前也不合规。它从不写 13h:206-213,读作「全不屏蔽」;现在按规范默认屏蔽,而且 206 只置定义了的 bit 7(6-0 是 Reserved)、207 保持 0。mock_dr8 则清掉了 212 的低两位——一个真在通道 1、2 上跑误码测试的主机会这么做——这样两种分支才会同时出现。

没有人会被告知的那些标志(12h:239-246 / 230)

规范 8.2.1 用一句话定义中断线:「只要有任何一个标志置位、且它对应的屏蔽位是清零的,Interrupt 就保持有效」。CMIS 一共四组「标志 / 屏蔽」配对,本工具此前只按这句话报告了三组:

标志屏蔽此前
Lower 8-13Lower 31-36已配对
11h:134-15310h:213-232已配对
14h:132-14913h:206-223已配对
12h:231-238(激光器调谐)12h:239-246完全没读
⚠ 漏掉的恰好是最要紧的那一组。Table 8-109 给 12h:239-246 的每一个位都写着「Default: 1」。也就是说,一块没有人配置过的模块,面板上每一个调谐标志都是「模块记下了、但永远不会告诉主机」的条件;而调谐面板此前说不出这件事。

同一页上还有两件事一并补齐:

  • 12h:230 调谐标志汇总此前在代码里有名字、却没有任何读取处。它自己的注记就是主机的操作流程:「主机应当在收到中断后读这个字节,以确定是哪几条通道引起的,再去读对应的通道字节」。
  • 这个汇总是精确定义、不是提示:位 -1 置位「当且仅当」该通道在 231-238 里有任一标志为 1。所以模块可能在这里自相矛盾,而且两个方向是不同的故障——汇总点了名却没有标志,会让主机去找一个不存在的条件;有标志却没被汇总点名,则是那条注记里的流程永远走不到的条件。面板会把方向说清楚。

演示模块此前也是错的,而且没有任何东西能看出来。它从来没有写过 239-246,于是那八个字节读作 0(全不屏蔽),唯一那个可调谐 profile 因此是一种不可能刚上电就存在的模块。现在默认是规范的 0x3F(六个位全屏蔽),并且 mock_coherent_zr 的通道 1 清掉了两个——一个真正关心「调谐请求被拒绝了没有」的主机会这么做——这样两种分支才会同时出现在一块模块上。

均衡器的另一半(10h:134 / 154-155,11h:215-216)

规范 Table 6-5 把发送端输入均衡的控制分成两组,并说明模块在什么时候读哪一组:

类型控制字段AdaptiveInputEqEnableTx
自适应Freeze / Store / Recall1
非自适应HostControlledInputEqTargetTx0

本工具把非自适应那一列做完整了:读暂存值(10h:156-159)、读生效值(11h:217-220)、与模块通告的上限比对,并且在使能位为 1 的通道上把这一格置灰——因为规范明说那里模块会忽略它。而自适应那一列,工具只读了使能位本身。

⚠ 结果是:一个通道一旦报告「自适应开启」,面板反而把唯一那个数字收走,却没有任何东西补上。三个寄存器正描述着那里发生的事,一个都没读:10h:134 自适应还在不在跑、10h:154-155 下一次 Apply 会调用哪个存储缓冲、11h:215-216 模块实际调用了哪个。

更早一层:能力面板从加上那天起就有「Tx Input EQ Freeze」和「Tx Input EQ Recall」两行,而此前没有任何一个演示模块点亮过 01h:161.4 或 161.6-5,所以这两行只渲染过「不支持」那条分支。本版让 mock_sr8 真的通告它们——这块模块本来就没有主机控制的均衡目标,正是那种「自适应开着、面板上却只有一个使能位」的模块。16 通道的 mock_1600g_16lane 也一并通告了——这两个字段的位宽在本工具里是头一次出现的「每通道 2 位」,照着每通道 4 位那份代码抄,在 bank 0 上答案是对的、bank 1 上就读错字节,只有分 Bank 的模块能把它照出来。

规范有两处细节,照搬成一列普通的暂存值就会写错:

  • 134 不是暂存的。Table 8-77 把 129-142 归为 Lane-Specific Control,「独立于 Data Path 状态机或控制集」——它写下去即刻生效,不需要 Apply。这张表其余各列都是暂存的,所以这一列的表头和脚注都会单独说明。
  • Recall 不受 ExplicitControl 约束。6.2.5 明文:「AdaptiveInputEqRecallTx 的调用,若支持,在 ExplicitControl 位未置位时同样有效」。本工具写入的正是未置位,也就是说面板上其余每一个暂存值都只是「请求」、会被模块自己的值替换,唯独这一个不会。

Store(10h:135-136)是只写寄存器,没有可读回的内容,表头会说明这一点——它的缺席是寄存器的性质,不是工具漏了。

「忽略」这条规则是双向的。6.2.5.1 说模块「忽略与当前 AdaptiveInputEqEnableTx 设置无关的控制字段值」。此前只做了一个方向,因为面板上只有非自适应那一列可做。现在两列都在,规则也就两边都走:自适应开启的通道置灰目标值,自适应关闭的通道置灰 Freeze 与 Recall,并各自说明该改哪个位才能让它生效。

颜色是有含义的。这张表里的红色专指「模块会回 ConfigRejectedInvalidSI」,所以保留值 11b(没有第三个缓冲)是红的;而「已冻结」是主机自己要的动作、模块不会拒绝,用琥珀色。另外「自适应正在跑」是正常状态,写作 Adapting 而不是 Off——通用单元格会把清零的位显示成 Off,在这里恰好会把健康状态涂成故障色。

线缆本身要走多久(01h:148-149)

规范 Table 8-50:「不可分离 AOC 的传播时延,以 10 ns 为单位、四舍五入到最近的 10 ns,为 0 表示未规定」。这个字段从解析器写好那天就解对了,却一处都没显示过。

原因不难理解:同一块(01h:146-150)的另外三个字段——最高/最低温度、最低工作电压——都是拿来判定实时读数的(给温度、电压上色),而传播时延没有读数可判,于是没有一个现成的位置接得住它。它属于能力面板。

⚠ 更深一层的原因:演示模块根本表达不了这个字段。它是跨 148-149 的一个 U16,而 mock 把高字节取自 lim[2] >> 8、低字节取自另一个元素 lim[3]。任何 profile 想设一个真实值,两个字节都会被写成 0,读回来就是「未规定」。因为从来没有 profile 设过它,这个错一直不可见。一个夹具承载不了的字段,下游就不会有人为它建任何东西。

而且也没有模块可以承载它:此前每一个分页 profile 的媒介都是可插拔的,唯一的线缆组件 mock_flat_dac 是平坦内存、连 Page 01h 都没有。所以本版新增了 mock_aoc——一根 20 m 的 400G 有源光缆,正是这个寄存器所定义的那种模块。它顺带给另一条此前无人可测的分支补上了真实模块:媒介类型 04h 同时涵盖有源铜缆与有源光缆,而有源光缆用「全 0」回答铜缆衰减、从而让那一行自动消失。

不要和 DataPath 页签那个时延搞混。两个都是纳秒,但不是一回事:这里是光在线缆里走的时间;DataPath 页签上的是 Page 15h 的信号穿过模块的时间。面板上这一行会写明自己是哪一个。另外,媒介可分离的模块不显示这一行——没有线缆,也就无所谓传播时延;若这种模块偏偏报了一个非零值,会被标出来。

合规声明是拿什么来衡量的(Page 0Ch:192-195)

上一版把每个具名特性的合规等级搬上了面板。规范 Table 8-73 给出的,正是这个等级应该被拿来衡量的东西:

地址寄存器完全支持要求
0Ch:192NaSupportDetails(综合性能监控)1011 1100b
0Ch:194FwSupportDetails(固件加载管理)三处说法不一,见下
0Ch:195.7FixedFirmwareFallback「推荐项」,不计入合规要求

规范 8.12 给了两条可以直接执行的规则:

一、「模块声明完全支持某具名特性时,下列特性细节通告必须符合该特性定义的选项集」——所以一个声称「完全合规」、而细节字节对不上的模块,是自相矛盾,工具现在会指出来,并列出具体是哪几位不达标。

二、「模块通告某具名特性不支持时,主机应忽略该特性在下表中的细节」——所以不支持的特性不显示细节,而不是把一串没有含义的位摆出来。演示模块 mock_1600g_16lane 就是这种模块:有性能监控、没有固件加载管理。

⚠ 固件那个寄存器的「完全支持」要求值,规范给了三个互相矛盾的说法。已对照原始页面图核实,不是文本抽取错位。
出处值
Table 8-72 交叉引用「set to 11110000b」0xF0
Table 8-73 表头「1111 1000b: fully supported」0xF8
Table 8-73 逐位行(7-2 各写 1b)0xFC

性能监控那个寄存器三处完全一致(都是 0xBC),这正是固件那个能被看出是缺陷、而不是某种约定的原因。规范其它地方没有第二处说法可以定夺,所以工具不替你选一个当答案:模块的字节只要命中其中任意一个,就算是「按规范某处写的做了」,三个都不中才算矛盾,而且会把三个值一并列出。

还有一个容易做错的细节:NaFeedsSupervision(192.6)和 NaFeedsDiagnostics(192.1)这两位,规范要求的值是 0 而不是 1。把「置位」当成「合规」的解码器,会把一个完全合规的模块报成差两位。工具是逐行按规范写明的要求值比对的,完全支持的位型也是由这些行推导出来、而非另抄一遍。

合规等级不是分数(Page 0Ch 的具名特性)

规范 Table 8-72 在 Page 0Ch 上定义了两个具名特性,结构相同,都用 Table 8-71 的 FeatureAdvertisement:

地址特性此前
0Ch:160-161ConsolidatedPmFeature(综合性能监控)已读
0Ch:162-163LoadManagementFeature(固件加载管理)从未读取

每个特性的第二个字节是两个 4 位的合规等级,规范给了四个名字:

码含义
0undefined, unknown(未定义/未知)
1noncompliant(不合规)
2partially compliant, with exceptions(部分合规,有例外)
3fully compliant(完全合规)
⚠ 代码里早就有这张名字表(COMPLIANCE_NAMES),内容一字不差,却没有任何地方用它——界面直接把 0-3 这两个数字打出来。问题出在 0:它的含义是「模块没有给出答案」,不是最低分。一个 0 挨着一个 3 印出来,读起来就像「两项里较差的那项」,而实际上那一项根本没被评估过。

现在两个特性都会显示,合规等级按名字给出,规范未定义的码(4-15)也如实标为未定义而不是硬套一个名字。演示模块 mock_24lane 的固件加载管理这一项故意设成「部分合规 / 未定义」,既和上面那项不同(换了位置就会露出来),也让「0 = 未给出」这条路径有真实样例。

这一条是靠一次新的扫描找到的:把模块级的每一张常量表逐个查消费者——只被测试和夹具引用、产品代码从不引用的,就是「写好了却没人用的事实」。同一次扫描还查出 PRBS_PATTERN_NAMES 是 PATTERN_NAMES 的陈旧副本(少了 14 Custom、15 User Pattern),任何地方都没引用,已删除。

被人关掉的那些告警(Flag 的 Mask)

CMIS 里每一个 Flag 都配有一个 Mask。Mask 置位的 Flag,模块照样报告这个状况,但不会拉起中断线。工具此前显示 Flag、也显示中断状态,却一个 Mask 字节都没读过——于是最让人困惑的那种组合无法解释:Flag 明明立着,中断却没拉起。

另一面更安静、也更要紧:某条通道上的某个告警可能已经被上一个用过这模块的人关掉了,模块从此永远不会为它中断。界面在此之前没有任何办法说出这件事——一条「安静的」通道和一条「告警被关掉的」通道长得一模一样。

Flag对应的 Mask本版处理
Lower 8-13 模块级Lower 31-36(Table 8-12)已读,中断那一栏会写明
11h:134-153 每通道10h:213-232(Table 8-91)已读,告警表逐格标注
14h:132-149 诊断13h:206-223工具只读了该 Flag 块中的一位、也没有对应面板,暂无可标注处
⚠ 这三组配对在 FLAG_MASK_BLOCKS 里早就写好了:演示模块用它来判定中断线该不该拉起(「任一 Flag 置位且其 Mask 未置位」,规范原文的定义),测试也在核对三组偏移对不对齐。唯独 app.py 从来没引用过它。——一张已经算对了的表,没有人去用。

告警表里,被屏蔽的格子会追加一个「masked」标记,悬停说明它拦住的是什么。告警正常、但被屏蔽的通道也会标——这恰恰是没人会想到去看的时候。而「之前触发过」那个标记优先:一个曾经触发过、又被屏蔽的告警,首先仍然是一条触发过的通道。

那十二个阈值告警(Tx/Rx 功率、Tx 偏置的高低告警与警告)在表里共用一格汇总,所以它们的 Mask 没有别处可显示,会连名字一起写在那一格上——只说「其中某个被关了」没法据以行动。演示模块 mock_fewmon 模拟了一个「接手时就有告警被关掉」的模块,可以直接对照。

旁路一个 CDR 到底省多少(01h:152)

上一版给面板补上了 Tx CDR 那一列、并修正了 Rx 那一列的门禁——也就是让人能看见、能判断 CDR 旁路。而回答「值不值得」的那个字节就在旁边一格,一直没读:

地址字段含义
01h:152CDRPowerSavedPerLane「每个 CDR、每条通道置于旁路时,最少能省下的功耗」,单位 0.01 W,向上取整到下一个 0.01 W

规范 Table 8-50 的 145-154 是「模块特性通告」这一整块,工具此前读了 145、146-150、151、153-154,唯独跳过了 152。注意措辞是「最少」:模块承诺的是至少这么多,不是正好这么多。

面板上这一行同时给出两个数:每 CDR 每通道的值,以及把所有可旁路的 CDR 全部旁路时的合计(按通道数 × 可旁路的侧数算)。后者才是做功耗预算时真正要看的数,但它是算出来的而不是模块报的,所以界面上写明了「全部旁路时」。模块若某一侧不让旁路,那一侧就不计入——演示模块 mock_sr8 没有 Rx CDR,合计就只按一侧算。

⚠ 0 的含义要特别小心,而且和邻居相反。同一张表里 148-150 三个字段都明写「0 表示未规定」,152 这一行没有这句话——照搬邻居的规则正是本审计此前犯过一次的错。但这个字段是向上取整到下一个 0.01 W,任何真实的节省都不可能取整成 0,所以报 0 只能是模块没有给出数值。界面写「未给出」,并说明这个推理依据的是该字段自身的取整规则,不是从上面几行借来的。

这一条是靠一次机械扫描找到的:把 Page 01h 的 128 个字节里工具从没读过的列出来。其余答案分别是 Reserved(170、253-254)、Custom 厂商自定义段(191-222)、页校验和(255,且其覆盖范围 130-254 已按规范正确排除 128-129),以及一处 10 字节块读造成的误报。只有 152 是真缺口。

模块到底跑哪几个状态机(Lower 56)

规范 Table 8-18 有四个字段,工具此前只读了后两个(Lower 60-61 的子型与散热)。前两个都是 RO Required,一直没读:

地址字段取值
Lower 56CmisSmSupport0 未声明 / 1 无状态机(如无源线缆) / 2 仅 MSM / 3 MSM + DPSM / 4 MSM + DPSM + NPSM / 5-FF 保留
Lower 57ModuleFunctionType0 传输模块 / 1 ELSFP 资源模块 / 2-127 保留 / 128-255 自定义
⚠ DataPath 页签整个讲的就是 DPSM——各通道的数据通路状态、Apply、DPInit、DPInitPending。而取值 1 和 2 的意思是:根本没有 DPSM 可言。其中取值 2 是现有检查查不出来的那一类:「仅 MSM(资源模块或固定收发器)」是一个内存分页完整、有 Page 01h、有通告、有监控值的模块,扁平内存那道门禁会直接放行它。只有这个字节能说明数据通路那套机制不在。现在模块声明自己没有 DPSM 时,DataPath 页签顶部会写明这一点。

取值 0 是个坑。它不是「没有状态机」,而是「没声明」——规范原话:「未定义时(CMIS 5.3 之前),模块类型是隐含的,但通常可以从 MemoryModel(00h:2)和其它通告推断出来」。把它当成「没有」,会让所有 5.3 之前的模块都失去 DataPath 页签。所以工具把它报成「模块未声明,由内存模型判断」,保留规范指定的那个回退路径。保留值 5-FF 同理,也不是「没有」。

演示模块里这一位由内存模型推导:扁平内存模块没有 Page 10h,也就没有数据通路可供状态机运行,取 1;分页模块取 3。声明一个自己没有寄存器支撑的状态机,本身就是模块缺陷。

看不见的那个 CDR(Tx)

10h:160 CDREnableTx 和 10h:161 CDREnableRx 是相邻的两个字节,编码完全相同——「1b:CDR 使能,0b:CDR 旁路」。信号完整性表只有 Rx 那一列:Tx 的暂存寄存器连声明都没有,而 11h:221(活动集里的 Tx CDR)声明了却从未读取。

⚠ 于是出现了这样的局面:Flags 面板一直在报「Tx CDR 失锁」,而界面上没有任何地方说明这个 CDR 是不是在回路里。被旁路的 CDR 本来就锁不住,而失锁标志两种情况下长得一模一样。现在 DataPath 页签多了一列 Tx CDR,暂存值与活动值都有。

还有一处是实打实的错答案。每个寄存器写明的通告是两位:10h:161 写的是「Advertisement: 01h:162.0-1」。Table 8-54 把这两位拆成 RxCDRSupported(162.0)和 RxCDRBypassControlSupported(162.1),而后者是有条件地写的——「0b:不支持 Rx CDR 旁路控制(如果有 CDR 的话,它不能被旁路)」。

工具此前只用旁路那一位把门。而 162.0 是这个字节里唯一没有被解析的那一位,它的 Tx 对应位 161.0 反倒解析了。结果:模块说自己没有 Rx CDR,面板照样给出一列可操作的 Rx CDR 开关。演示模块 mock_sr8 通告的正是这个组合(si_162 = 0x0A),可以直接对照。现在两位都要满足才算是主机能控的开关,而能力面板会如实写出「通告了旁路控制,但模块报告自己没有 Rx CDR」。

同这两个字节的其余通告也一并补进了能力面板:Tx 输入均衡的冻结与召回缓冲区数(11b 是保留值,不是缓冲区数量)、第二组暂存控制集、单向重配置、以及 CMIS-VCS。其中「第二组暂存控制集」那一行会写明本工具只写第 0 组。

另外修了一处演示模块的失真:规范 6.2.3.3 要求「模块在退出 MgmtInit 之前,就把暂存控制集 0 和活动控制集都填上模块自定的默认应用与信号完整性设置」。演示模块此前把活动控制集留空,直到主机下发一次配置为止——于是刚连上时「活动」那半边显示成所有均衡器为 0、所有 CDR 被旁路,而这恰恰是这组寄存器存在的意义所要否定的。

模块有哪些可选页组(01h:142)

规范 Table 8-47 用 01h:142 的六个位说明模块有哪些可选页组,外加两位的 bank 数。这六个位工具一直都解析出来了,其中五个从未到达界面。

位字段涵盖的页
.7NetworkPathPagesSupportedPage 16h,以及 Page 17h 中与 NP 相关的部分
.6VDMPagesSupportedVDM 的 Page 20h-2Fh(部分);具体通告在 Page 2Fh
.5DiagnosticPagesSupportedPage 13h-14h —— 环回、码型发生与检查、SNR、BER、比特计数
.4CoherentPagesSupportedPage 30h-4Fh(部分);细节在 C-CMIS 里
.3CmisFfSupportedPage 05h 上的形态相关功能(CMIS-FF 补充规范)
.2Page03hSupportedPage 03h,主机可写的用户 EEPROM
⚠ 此前能力面板显示的是 01h:173-174 的答案(Page 0Ch/0Dh、Page 60h/61h/62h)——也就是扩展字节的结论,却对被扩展的那个字节只字未提。其中就包括模块到底有没有 VDM,而 VDM 是 CMIS 里最主要的那项可选诊断功能。

这次是靠一次机械扫描找到的:把 cmis_registers.py 里每个 parse_* 函数返回的字段名都取出来,再看这些名字有没有在 app.py / app.js / index.html 里出现过。多数「没出现」的是构造显示文本用的内部编码,属于误报;这五个不是。

演示模块 mock_dr8 现在真的带了一页 Page 03h 用户 EEPROM,在「寄存器读写」页签里读 Page 03h 就能看到内容。其余四个页组在所有演示模块上都是「不支持」——因为这些模块确实不提供那些页,通告一个自己没有的页组本身就是模块缺陷,不该在演示模块里出现。规范 8.6 另有两条与这一页有关:一次写入最多 8 字节;写入在模块内部完成之前,模块会拒绝寄存器访问。

CDB 消息机制:规范在这里自相矛盾

CDB(Command Data Block)是固件升级和规范第 9 章整本命令目录所走的通道。模块在 01h:163-166(Table 8-55)里通告自己怎么做 CDB。这四个字节此前工具从未读过,界面上也完全没有提到 CDB。

现在模块能力面板会列出七行。其中两行不是标签,而是会改变操作方式的:

⚠ CDB Background Mode(163.5)清零时,模块在命令执行期间会停止响应「任何寄存器」的访问——不只是 CDB 那几页,是整个管理接口。在这种模块上一边跑固件升级一边轮询监控值,不是「慢」,是根本没人理你。写成单纯的「不支持」会让人以为只是少了个便利功能。

CDB Max Busy 是主机在判定模块已经停摆之前必须愿意等的时间。这一行带一个 ▲ 标记,原因是 OIF-CMIS-05.4 的 Table 8-55 在这里自相矛盾:

字段规范原文怎么说
166.7 CdbMaxBusySpecMethod0 → 由 CdbMaxBusyTime(166.6-0)给出;1 → 由 CdbExtMaxBusyTime(165.4-0)给出
165.4-0 CdbExtMaxBusyTime「……160 ms 到 4960 ms,当 CdbMaxBusySpecMethod=0b 时」
166.6-0 CdbMaxBusyTime「……0 ms 到 80 ms,当 CdbMaxBusySpecMethod=1b 时」

选择位那一行和两个数值字段那两行正好相反,而规范其它地方没有第二处说法可以定夺。两种读法一个是 0-80 ms、一个是 160-4960 ms——差了一个数量级以上,选错就是「该等的时候判模块死了」。

工具的做法:按 166.7(也就是定义这个位含义的那一行)解读,同时把另一种读法并排写出来,并在悬停提示里说明规范为什么矛盾。只给一个数字等于替你悄悄选边。

同一张表里还有两处容易做错的地方:CdbMaxPagesEPL(163.3-0)的编码不是页数——0-4 恰好等于页数,而 5、6、7 分别表示 8、12、16 页;CdbReadWriteLengthExtension(164)一个字节对应两个上限——它以 8 字节为单位放宽访问长度,但 Page 9Fh 只有 120 字节的 LPL、EPL 页最多 2048 字节,同一个值在一边封顶 128、另一边封顶 2048。只报一个数字,就会对一个只能接受 128 字节的页承诺 2048 字节的写入。

装不下的那些 Application(Page 1Ch)

基本 Application 描述符最多只能有 15 条。规范 6.2.1.6.2 为此引入了 Normalized Application Descriptor(NAD),一个模块最多可以通告 255 × 15 = 3825 个 Application,放在分 bank 的 Page 1Ch 上:

地址内容
1Ch:128-24715 个 NAD,每个 连续 8 字节(Table 8-173)
1Ch:248-255Reserved——不是第 16 个

Application 编号 AN = 15 × 块号 + AppSel 码。要选中其中一个,两半都得给:AppSelCode 和 NADBlockIndex——AppSel 码在每个块里都是 1..15,单给一个没有意义。面板上每一行都同时列出这两个值。

⚠ 这里接通了工具里原本的一条死路。基本描述符里的接口 ID 只有 8 位,而 NAD 的 Interface UID 是 12 位(4 位 GID + 8 位 ID)。当 UID 装不进 8 位时,规范要求模块在基本描述符里写入 BEh,工具此前在那里显示「See NAD (0xBE)」——却没有任何地方可以把读者送过去。现在 Page 1Ch 那张表会给出真正的 UID。注意 GID 非零的 ID 不属于 SFF-8024 的命名空间,工具不会去那张表里查名字,而是如实写明这是哪个 GID——查出来的名字会是自信的错答案。

块 0 必须是基本描述符的镜像(6.2.1.6.2)。工具会逐条核对,不一致就标出来——这意味着模块在同一个 AppSel 码下通告了两个不同的 Application。核对时不能简单地比相等:GID 非零时基本描述符里本来就应该是 BEh,把这种情况报成不一致,等于说每个做对了的模块都是坏的。

另外,NAD 的第 5 字节第 7 位是 NetworkPathIndicator:这条描述符描述的可能是 Network Path 而不是 Data Path(8.19.5.3),这一行会标上 NP。

目前的限制:工具能读全部 NAD,但还不能选用块 0 以外的 Application。它读写 Staged Control Set 的 NADBlockIndex(18h:128-135):在 DataPath 下拉框里改选基本 Application 时写 0,AppSel 没变的通道保留原块号;运行中的块号读自 19h:144-151,面板上以 AN 显示。面板上如实写明了这一点。

每通道数据通路时延(Page 15h)

规范 8.18 / Table 8-141 在 Page 15h 给出每条主机通道穿过模块的总时延,单位纳秒:

地址内容说明
15h:224-239Rx 时延8 × U16,按主机通道报,单位 ns
15h:240-255Tx 时延
15h:128-223—Reserved

该页是可选的,模块在 01h:145.3 宣称有没有。有,DataPath 页签就会多出一张「Data Path Latency」表;没有,这张表整张不出现——而不是显示一排 0。

⚠ 这一页是分 bank 的:「Page 15h 的每个 Bank 对应 8 条通道」。16 通道的模块要读两个 bank。只读 bank 0 并不会让通道 9-16 空着——它会把通道 1-8 的时延填到通道 9-16 上,八个数量级完全合理、却属于另外八条通道的数字。演示模块 mock_zr16 两个 bank 的值是不同的,正是为了让这种错误显形。

规范还有一条「shall」:同一条 Data Path 的各通道必须报相同的时延。工具会按模块自己报的 Data Path 分组核对,不一致就把涉及的通道标黄并说明——16 通道跨两个 bank 时是 32 个数字,没人会逐个去比。

两条出自规范的保留意见也一并写在表下:这些数值的精度规范未作规定;对于会动态更新这些寄存器的模块,何时保证有效目前是未定义的。

另外注意:上一节铜缆衰减那里 0 dB 表示「不可用」,这里的 0 就是 0 纳秒。规范只在前者定义了这个特殊值,把它照搬到后者会把一个真实答案说成「未知」。

铜缆衰减:0 dB 不是「没有损耗」

规范 Table 8-35 在 00h:204-208 给出线缆在五个频点上的插入损耗,每计数 1 dB:

地址频点说明
2045 GHz整数 dB。模块报 0 表示「该特性不可用」,不是这根线缆在该频点无损耗
2057 GHz
20612.9 GHz
20725.8 GHz
20853.125 GHz
209—Reserved,不是第六个频点
⚠ 这一段此前从未被读取。铜缆模块的面板能说出线缆多长、分支成什么、用的什么技术,唯独说不出它有多大损耗——而这恰恰是判断链路能否闭合的那个数。两处坑一并处理了:寄存器原本声明成 6 字节,把 Reserved 的 209 也圈了进来,它会以一个没有频点的第六个衰减值出现在面板上;而 0 dB 按普通无符号字节解码就成了「零损耗」,在 53 GHz 上是个一眼假却又完全看不出错的数字。

规范 8.3.6 还限定了适用范围:「对于其它模块,204-209 字节是保留的」。光模块同样能读回这几个字节,但读回来的东西没有含义,所以这一行在光模块上不显示,而不是显示成 0。有源线缆(媒介类型 04h)既包含有源铜缆也包含有源光缆,后者会用「全 0」来回答,这一行同样不出现。

表下方还有一条注:当模块声明自己是 PCIe 应用时,同样这五个字节代表的是 2.5 / 4.0 / 8.0 / 16.0 / 32.0 GHz。仅凭这几个字节无法判断是哪一组频点,所以工具把这条说明写进了该行的悬停提示,而不是替你猜一个。

Rx LOS 是对着哪个量报的

规范 Table 8-50 的 01h:151 里有两个相邻的位:

位字段含义
.4RxPowerMeasurementType0=OMA,1=平均功率
.3RxLOSType0=Rx LOS 对 OMA 响应,1=对 Pav 响应
⚠ Rx 功率那一列从一开始就在表头标明自己报的是哪个量,并提示「OMA 与平均功率不可互换」;而对同样这两个量之一触发的 LOS 标志,却什么也不说——151.3 解析出来就被丢掉了。「LOS 报了,可功率看着正常」正是这一位能回答的问题,而且规范自己注明 LOS 的类型取决于所支持的接口标准,未必与功率列报的是同一个量。

现在 Rx LOS 表头会像功率列一样标出基准(· OMA / · Pav),悬停给出出处。

01h:151 一共七个字段,此前只有两个到达界面。其余的已补进模块能力面板:光电探测器类型、Rx 输出均衡保持的是哪个幅度、以及两个「快速模式」时序位(模块多快报出 Rx LOS、多快响应 Tx 关断)——这两个尤其不是标签,而是决定读者该对模块有什么预期。

固件版本:有两个取值不是版本号

规范 8.2.9 规定了固件主/次版本号的编码,其中两种组合不是版本号:

取值含义
Major = 0 且 Minor = 0模块没有固件
Major = FFh 且 Minor = FFh活动固件映像无效
其余组合固件版本
⚠ 而两者此前都按 主.次 直接打印。于是一块报告固件映像无效的模块,面板上显示的是 255.255——一个故障状态被打扮成了一个像模像样的版本号,而且恰恰是读者最不会去怀疑的那种值。

现在分别显示为「Invalid firmware load」与「No firmware」,无效映像还会被标红——那是故障,不是版本。

Table 8-44 规定非活动固件字段用同一套编码,并补充说「没有非活动固件的模块会清零这两个字段」。所以那里的 0.0 是常见情形(显示为 None),而不是「模块没有固件」——同一套解码,不同的措辞,因此判断放在解码器里、措辞放在调用处。硬件版本号规范未定义任何特殊编码,保持原样。

线缆长度:有两个取值不是长度

规范 8.3.4 说 00h:202:「CableAssemblyLinkLength 取值 1111 1111b 表示链路长度大于 6300 m」。

⚠ 而这个字节按乘数算出来恰好是 6300,于是面板显示「6300 m」——给一根模块自己说「测不出来」的线,报了一个精确数字。整个字节里唯一表示「比我能说的更长」的那个值,恰恰长得最像一个答案。

另外 Table 8-33 对 BaseLength 写明:「取值 0 表示链路长度未定义,例如物理介质可以与模块分离时」。这指的是低六位为 0 的任何字节,不只是 00h —— 有乘数而没有基数一样是未定义。两种情况乘出来都是 0,所以面板此前「等于 0 就当作收发模块」碰巧是对的,但说不出原因,也无法与一个真的测得 0 区分(而那种东西并不存在)。

现在这三种情况分别显示为 greater than 6300 m、— (transceiver, see Link Length)、以及普通的 3 m。0xFE 仍然是普通的 6200 m —— 只有 0xFF 特殊。

顺带修了演示模块:规范说可分离光介质的模块该把这个字节清零,而所有演示模块都报 0,包括新加的无源铜缆 DAC——一根没有长度的铜缆不成其为线缆。它现在报告 3 m。

这根线的远端分成几路,现在看得到了

00h:211 FarEndConfiguration(Table 8-37)此前在寄存器表里声明了,却从来没有被读过——而它就夹在 00h:210 和 00h:212 之间,这两个工具都在读。

⚠ 在线缆组件上,这是唯一说明哪些近端主机通道接到哪个远端模块的地方。Application 描述符说的是这块模块可以怎么配置,不是它插在什么上面。Table 8-39 为编码 1–26 给出每条主机通道所属的分组字母,Table 8-38 另把其中五个编码标为「均匀分支」(1/2/4/8/16 通道)。

模块能力面板新增一行,例如 2 far end modules: 1-4, 5-8,属于均匀分支时还会标出规格。编码 0 是「未定义 · 可拆卸介质的模块」,规范规定这类模块该字节清零——所以光模块上显示的 0 是正确答案而不是没读到。

这一行在平坦内存模块上同样有效(它在 Page 00h),而线缆组件正是这个字段服务的对象。新增的无源铜缆 DAC 演示模块现在会报告 4 通道均匀分支。

关于这 26 行转录:从 PDF 抄 26 行数据是最容易出静默错误的活。规范自己说了字母「取决于该组最低的通道号」,这句话让每一行都可校验:字母必须从它命名的那条通道开始、且必须连续。但这条规则不充分——把某行换成另一个同样合法的排布仍能通过,所以还加了一条:26 行必须两两不同。

一个必备字节里的七个字段,面板此前只显示三个

01h:145(Table 8-50)一共有七个字段,每一个都是 RO / 必备,没有一位是保留位:

位字段此前
7CoolingImplemented解析了,但没有任何面板显示
6-5TxInputClockingCapabilities未解析
4ePPSSupported未解析
3TimingPage15hSupported未解析
2-0Aux3 / Aux2 / Aux1 观测对象已显示
⚠ 这个字节连接时本来就会读,所以少掉的四个字段不是为省一次读写而跳过的,而是在解析那一步就被丢掉了。其中 TxInputClockingCapabilities 是有实际后果的一个:它说明哪些 Tx 输入通道必须频率同步(1-8 / 1-4 与 5-8 / 两两一组 / 可异步),这直接约束主机能怎么划分数据通路——而数据通路面板就在隔壁。模块超过 8 通道时,该分组按每个 Bank 分别适用。

现在模块能力面板新增四行,并各自标注来源位。Page 15h 那一行当时如实写明「本工具并不读 Page 15h」,因为写成单纯的「支持」会让人去找一个并不存在的面板;自 v2.91.0 起那个面板存在了,该行改为指向 DataPath 页签,详见下一节。

数据通路的分组,现在读模块自己的说法

规范 Table 8-102 给 DPConfigLane 的每个字节定义了三个字段,在活动控制集里全部是 RO / 必备:

位字段含义
7-4AppSelCode该通道所属数据通路跑哪个 Application
3-1DPIDX该数据通路的索引,即它占用的最低通道号
0ExplicitControl0=该通道的 SI 设置由 Application 决定;1=由主机定义
⚠ 工具此前只取了第一个字段,后两个直接丢掉,然后又去推断它们:数据通路分组按 Application 的通道宽度推;而信号完整性面板则直接断言「模块按 Application 自行配置这些设置」——这个断言的依据是本工具自己写了什么,而不是模块逐通道报告的那个位。一旦模块是被别的东西(交换机、上一任主机)配置过的,这两处都可能是错的。

现在:数据通路面板同时给出模块报告的分组与工具的推断;信号完整性面板改为按模块报告的 ExplicitControl 逐通道陈述,有主机定义的通道时会点名是哪几条。

演示模块也改了:此前它把主机暂存的字节原样复制进活动控制集,而本工具暂存的 DPIDX 是 0,于是跑着两个数据通路的模块会报告成一个。真实模块是根据自己配置的结果算出这个索引的,演示模块现在也这样做。另外 DPIDX 只有 3 位、按 Bank 计——16 通道模块上两个 Bank 的 DPIDX 0 是两个不同的数据通路,不能按数值合并。

测量窗口那一行,现在会先问模块支不支持

BER 与误码计数面板下方的「Measurement window」一行,此前读了 13h:177 的两个位,却没读那个决定它们是否有意义的字节。

⚠ 13h:129.2 的说明里直接点了名:「AutoRestartGating 控制(13h:177.4)不支持」。而这一行只看 177.4,于是任何一块该位恰好置 1 的模块都会被写成「gate 到期后自动重启」——不管它实现没实现。

现在:模块宣称支持时照旧写「restarting automatically」;宣称不支持而该位又置着时,明确写出「寄存器要求自动重启,但本模块未实现」并标注 13h:129.2 —— 不是默默不显示,因为寄存器里确实写着,拿寄存器对照面板的人需要看到工具注意到了这件事。

另外,13h:177.7(StartStopIsGlobal)此前解析出来就丢掉了。它决定在一个 Bank 上启停测量是否等同于在所有 Bank 上启停——在多 Bank 模块上,这是「一个结果」和「三十二个结果」的区别。现在该位置 1 时会说明;而按 Table 8-129,模块只有两个全局 gate 定时器(13h:129.3 = 0)时这个位是被忽略的,那种情况下会直接说明它无效。该位为 0 是默认行为,不再赘述。更正:Table 8-129 的「被忽略」只针对门控测量;不门控时 Table 8-128 仍让这一位作用到所有 Bank。现在的判断见「13h:177.7 作用到哪里」一节。

被模块忽略的均衡目标值,现在会标出来

规范 Table 6-5 按类型把 Tx 输入均衡的控制分成两组,并写明模块看哪一个:

类型控制AdaptiveInputEqEnableTx
自适应AdaptiveInputEqFreezeTx / StoreTx / RecallTx1
非自适应HostControlledInputEqTargetTx0

6.2.5.1 又对本面板显示的那个字段重申了一遍:「若该通道的 AdaptiveInputEqEnableTx 置位,HostControlledInputEqTargetTx 会被模块忽略」。

⚠ 信号完整性表此前只按 01h:161 的广告门控这两列,再没有别的判断。于是在跑自适应均衡的通道上,那个目标值被当成一项设置显示出来——一个模块根本不看的数字,挨着五个它确实会看的数字。而内置演示模块每条通道都跑自适应,也就是说开箱即见的那一列全都是这种情况。

现在这种格子会置灰并标注「ignored」,悬停说明原因与出处。按通道判断,不是按模块——使能位是每通道一位,模块可以一部分通道跑自适应、另一部分由主机控制。

不是拒绝写入。主机完全可以在同一次 Apply 里既清掉自适应位、又下发目标值,那时这个目标值正是模块要用的。面板只说明它在哪些通道上生效,不替主机做决定。

换页之后读回来核对一下

规范 8.2.15 写得很明确:「当主机写入会让 PageMapping 寄存器指向一个不受支持的页地址时,模块会清零 PageSelect 字节……使得 PageMapping 最终选中 Page 00h」。

⚠ 也就是说,请求一个模块没有的页,任何一步都不会报错:写入被接受,没有任何提示,而之后每一次读都落在 Page 00h——厂商标识信息——并被按调用方期待的格式解码。一次不会失败的读取,不等于一次成功的读取。

规范把答案放在了寄存器里,所以现在读回来核对:每个页在一次连接中只核一次(模块插着不动时,它支持什么不会变;若每次换页都读回,会让每次面板刷新的总线流量翻倍)。页不对就明确报错,并写清模块回了什么。

诊断页也要先看广告

01h:142.5 DiagnosticPagesSupported(「支持 Banked Pages 13h-14h」)在连接时就解析了,却从来没有人去问它。本工具里其它每一个可选页都按各自的广告门控——0Ch、60h、61h、62h 各有一条,就写在同一个函数里相隔三行的地方——唯独诊断这一族没有。

于是在没有这两页的模块上,页选择被清零、Page 00h 一直映射着,厂商信息被解码成环回能力、图案支持情况和误码计数。现在环回、PRBS、SNR、BER、比特与错误计数这几个面板会在触碰页之前就明确拒绝,并点名 01h:142.5。

为什么一直没被发现:内置的演示模块全都实现了 13h/14h,而那条「每个演示模块、每个端点,都不许读到不存在的页」的巡检,力度只能到夹具为止。

平坦内存模块:工具不再读一个它没有的页

规范:「与分页内存模块不同,平坦内存模块不支持动态换页进入上层内存」。而工具在连接时读取的全部通告——有哪些监控、多少条通道、各瞬态最长多久、标称波长是多少——统统住在 Page 01h。

⚠ 平坦模块对这些地址的读取会从 Page 00h 作答,而 Page 00h 那一段是厂商名、料号、序列号。于是读回来的是 ASCII,却被当成能力位解码,并作为「这个模块的通告」显示出来。在新增的无源铜缆 DAC 演示模块上实测,修复前:一根铜缆被解出 873.85 nm 的标称发射波长、被宣称带 Rx 光功率监控,换页保持时间被解成 0.3 微秒(规范默认 10 毫秒)。没有一条是真的,也没有一条看起来不对。

内存模型本身在 Lower Memory(每个模块都有),所以现在先读它;模块说自己是平坦的,就根本不去读 Page 01h,那些通告缺席而不是被捏造。

再进一步:规范 8.2 说平坦内存模块就是静态内存模块(「只提供只读的、不可变的数据」),而 Table 8-9 与 Table 8-10 的标题写着「not for static memory modules」——也就是说模块级标志与监控值本来就不存在于这类模块。所以工具把它们记为「通告为无」,而不是「未知」:未知在下游一律等于「全都显示」。Memory Model 那一行现在会直接说明这一点,免得满屏空行看起来像读取失败。

新增演示模块 mock_flat_dac(无源铜缆 DAC,平坦内存)。此前所有演示模块都是分页的,没有任何东西能暴露这个问题。

平坦内存模块:描述符第 4 字节不是通道分配位图

Application Descriptor 的第 4 字节,两种模块上是两个完全不同的字段:Table 8-22(分页内存模块)把它给了 HostLaneAssignmentOptions——一张位图,说明这个 Application 可以从哪些主机侧通道开始;而 Table 8-23(平坦内存模块)把同一个字节给了 HostInterfaceGID,即定义 HostInterfaceID 的那张 SFF-8024 表的组号。

⚠ 工具此前对两种模块都按位图读。于是在平坦内存模块上,GID 为 1 就成了「可从主机通道 1 开始」,GID 为 2 就成了「通道 2」——看起来很像样的答案,回答的却是模块根本没被问到的问题,而且这个假位图还会进入计算模块通道容量的贪心装箱。实测影响:两个各 4 通道的 Application,GID 分别是 01h 和 10h 时,按位图读会被当成互不重叠,模块因此被记成 8 条主机通道——而它从未宣称过。

现在:平坦内存模块根本没有通道分配掩码(是「没有这个字段」,不是「掩码为 0」),该字节按本来面目显示为 GID 0x__,鼠标悬停会说明这是 Table 8-23 的 HostInterfaceGID、不是通道分配;分页模块一切照旧。容量计算也不再把它当成起始通道。

规范在这一处自己有个小矛盾:GID 那一行写的是 bit 7-0,紧接着又把同一字节的 bit 3-0 标为保留。工具原样显示整个字节,不去替规范决定该怎么移位。

Application 的通道数栏:0 不是「0 条」

规范 Table 8-22 把 Application Descriptor 第 3 字节的两个半字节写得很清楚:「0000b:通道数由接口 ID 决定,或显式给出:0001b:1 条 …… 1000b:8 条。1001b–1111b:保留」。

⚠ 也就是说 0 不是「这个 Application 没有通道」,而是模块不再重复一个它的接口 ID 本来就已确定的宽度;而 9–15 根本不是通道数。此前工具把两者都当数字用:前者在 Application 表里显示成一个破折号、在 Host Lanes 下面的分解里显示成「0H/0M」;后者被当成 9–15 条通道,还加进了模块对外宣称的通道总数。

现在这两种情况分别显示 H=per interface ID 和 H=Reserved (Fh),都不计入通道总数——要把「由接口 ID 决定」解成具体数字,需要 SFF-8024 里接口 ID 对应的通道数,那张表本工具没有收录,所以它说明是哪一种,而不是编一个数字出来。(4H/4M 这种正常宽度显示不变;H/M 只在跟着数字时才当单位用。)

接口 ID 显示 BE 时:去看 NAD

同一张 Table 8-22 对两个接口 ID 字节都写了:「BEh:接口 UID 的 GID 非零,因此必须查阅对应的 NAD」。这是规范定义过的编码,不是 SFF-8024 表里缺的一项,而工具此前显示 Unknown (0xBE)——就在同一块面板上,工具其实已经在告诉你这个模块宣称了几组 Normalized Application Descriptor。现在显示 See NAD (0xBE)。

「Unknown」只在工具真的不知道时才会出现

「Unknown」是在说工具,不是在说模块。它告诉你工具没认出模块给的值,你合理的反应是去找个更新的工具。所以对于规范本身已经定义过的编码,它不该出现。

⚠ 此前两处正好犯了这个毛病,而且都在你最先看到的那块面板上:Media Type(Lower 85)规范 Table 8-20 把整个字节都定义了——06h–3Fh 保留、40h–8Fh 自定义、90h–FFh 保留——工具却把 05h 以上一律显示成 Unknown;Media Interface(00h:212)规范 Table 8-41 到 14h 为止、15h–FFh 保留,而工具的表只到 11h,于是 12h/13h/14h 这三种已定义的铜缆线性均衡技术在对应模块上全被显示成 Unknown。

现在:落在保留区间的显示 Reserved (0x__),落在自定义区间的显示 Custom (0x__),并且都带上原始编码——保留编码是关于模块的问题,自定义编码则意味着这块模块的 Application Descriptor 要按厂商自己的 ID 表去读,这件事在动手解读之前就该知道。缺的三种铜缆技术已补齐并各自区分(近端+远端 / 远端 / 近端线性有源均衡);0Fh 在 CMIS 5.4 里标了「不要用于新设计」,名称里现在也写明已弃用。

工具确实不知道的地方仍然写 Unknown:连接器类型、SFF-8024 标识符、主机接口 ID 这几张表定义在 SFF-8024 里,本工具没有收录,写 Unknown 是实话。

没有逐通道环回的模块,勾一条不再被拒绝

规范 Table 8-131 对四个环回使能字节都写了同一句话:「若『支持逐通道环回』位为 1,环回按通道控制;否则,只要有任何一个使能位置 1,该侧所有通道都进入环回」。

⚠ 也就是说,在不支持逐通道环回的模块上只勾一条通道并不是错误——模块会把该侧全部通道都环回。工具此前直接拒绝了这种请求,等于凭空造了一条模块并没有的限制,而且操作员在自己想明白「必须全选」之前根本没法用环回。

现在这种请求照做,并且把掩码扩成全通道再下发、在返回里说明「已应用到全部通道」。为什么要扩而不是原样写:这个寄存器会被读回到同一个面板——写 0x01 而模块实际环回了 8 条,面板就会显示「1 条在环回」,而真相是 8 条。
清零不会被扩(那是关环回,扩了就变成开);支持逐通道的模块照旧按你勾的来;模块压根没有某个方向的环回时,仍然明确拒绝——那是另一个答案。

Page 62h 的阈值也是每条媒体侧通道一套

Table 8-192 对 62h:128–191 的描述就是「每条媒体侧通道的告警和警告阈值」。工具此前把这份列表按主机侧通道数截断,于是相干模块拿到 8 套阈值,其中 7 套属于它根本没有的媒体侧通道。

ℹ 这是同一个轴搞错的第三处:光功率监控(Table 8-99)、调谐表(8.15)、现在是阈值(Table 8-192)。三处现在共用同一个判断,不是三套规则。
Monitoring 里也一样:没有媒体侧通道的那些行既没有读数、也不再挂阈值窗口——给一个不存在的读数配阈值是没有意义的。

调谐表也是按媒体侧通道排的

规范 8.15 写得很直接:「Page 12h 的每个 Bank 对应 8 条媒体侧通道」,而 Table 8-108 里每一项——栅格间隔、通道号、微调偏移、激光器频率、目标输出功率——都是「每条媒体侧通道一个」。

⚠ 调谐表此前是按主机侧通道排的。相干模块只有一路激光器,却被排出 8 行——后 7 行读的是不存在的寄存器。
更严重的是写:给「第 5 通道」下调谐会被接受并写下去,然后界面把通道号从一个模块根本没有的媒体侧通道读回来显示——操作员以为调好了。

现在调谐表只列真实存在的媒体侧通道,对不存在的通道下调谐会被拒绝并说明依据(00h:210 和 8.15)。并且沿用同一条规矩:一次请求里只要有一条通道不合法,一个字节都不写。

ℹ 和上一条一样,超过 8 条通道的模块不受此限制——规范 8.3.7 说这类模块无法无歧义地声明,所以工具不据此隐藏任何通道。

相干模块只有一条媒体侧通道,别的行不是读数

Monitoring 表里每一行是一条主机侧通道,但其中三列—— Tx Power、Tx Bias、Rx Power ——规范(Table 8-99)叫的是「媒体侧通道监控」。

⚠ 相干模块把 8 条主机侧通道汇进 1 路光载波,所以它只有一条媒体侧通道。第 2–8 行读的是模块声明自己没有的媒体侧通道的寄存器——读出来是 0,而 0.0 µW 是 dBm 量程的底部,正是界面涂成告警红的那个值。
这和「模块没实现这项监控」是同一个错,只是换了一个轴。

00h:210(Table 8-36)就是模块自己说的哪几条媒体侧通道不存在。工具一直在读这个寄存器,只是没有任何地方用它。现在这三列在不存在的媒体侧通道上显示「no such media lane」,和「not implemented」分开写——两者是不同的答案,要查的寄存器也不同。

ℹ 超过 8 条通道的模块不用这个寄存器:规范 8.3.7 自己说了,这类模块「无法无歧义地声明哪些媒体侧通道不受支持」——一句有歧义的话,只用它的一半并不会更安全。
DataPath State、Output、Config Status 这几列是主机侧的,每一行照常显示。

标志亮着、中断却没来:那是被屏蔽了

规范用一句话定义了中断线:「只要有任何一个标志置位、且它对应的屏蔽位是清零的,Interrupt 就保持有效」。也就是说中断状态不是另外一个要读的东西——它就是标志和屏蔽位的组合结果。

ℹ 所以真正有用的是两者不一致的时候:界面上标志亮着、Interrupt 却显示没有请求,就说明这个标志被屏蔽了——模块记下了这件事,但不会去打扰主机。排查「为什么我的主机没收到告警」时,这一行直接给出答案。
屏蔽位的位置:模块级标志 Lower 8–13 对应Lower 31–36;通道标志 11h:134–153 对应 10h:213–232;诊断标志 14h:132–149 对应 13h:206–223。

这个值工具一直都在算(接口里就有),只是界面从来没显示过,两份手册也都没提。演示模块那边则是反过来:中断位被写死成「没有请求」,于是它可以一边挂着温度告警、发送故障和失锁的检测器,一边报告自己没在找主机。现在两边都按规范那句话来。

Aux 监控的告警标志:读一次就没了

下部内存 9–11(Table 8-9)放的是六个模块级监控各自的四个阈值标志(高/低告警、高/低警告),三个字节排法完全一样:

字节位 3–0位 7–4
Lower 9温度供电电压
Lower 10Aux1Aux2
Lower 11Aux3自定义监控
⚠ 这整个块都是 RO/COR:读它的那次读就把它清掉了。工具每次轮询都一次性读 8–13,以前只解析第 9 字节——于是 Aux 和自定义监控的告警被读走、被丢掉,而且没给任何人留下:下一个读它的人只会看到 0。模块侧面板的 Alarms 一行还写着 0x08–0x0D,却对其中两个字节一概不知。

现在 Aux 每一行的读数后面直接跟着模块自己的判决(高告警 / 低告警 / 高警告 / 低警告),告警红、警告黄;没有标志就什么都不显示。因为标志是读后即清的,它说的是“上一次轮询以来”,不是“此刻”;历史区会把它留下。

ℹ 标志归属于监控(§8.14.1),而这六个监控全是可选的(01h:159,Table 8-53)。模块没声明的监控,其标志按“未知”处理而不是“正常”——不存在的标志读回来也是 0,和一个健康的监控一模一样。
自定义监控(Lower 24–25)的编码规范里写的是“S16 或 U16”,由厂商自定,所以工具不会编一个数值出来;它声明了这个监控时,只单列一行显示模块的判决。

Tx 偏置电流的刻度倍数

Tx 偏置寄存器数的是 2 µA 的个数,但 01h:160.4-3(Table 8-53)还给它一个 ×1 / ×2 / ×4 的倍数。工具此前把刻度写死成 2 µA, 从不读这两位。

⚠ 后果不是“少显示一个字段”,而是 数值错了 2 倍或 4 倍——监控读数和阀值都错。
而且这不是假想情况:16 位寄存器 × 2 µA 的上限只有 131.07 mA,所以偏置高于这个值的模块(相干模块很常见) 必须声明 ×2 或 ×4。现在监控与阀值都按声明的倍数换算。
ℹ 内置的 mock_coherent_zr 现在工作在 180 mA、声明 ×2—— 正好超过 ×1 能表达的上限,方便你验证主机软件有没有处理这个倍数。 规范里 11b 是保留值,工具按 ×1 处理,不会自作主张地把读数放大四倍。

读了却没解析的那一个字节

通道标志在 11h:134–153是连续的,工具一次性读 20 个字节——真实硬件上这比 20 次切页加等待快得多。但其中只解析了 19 个:0x8A(Tx 自适应均衡失败)被跳过了。

⚠ 这一整块是读后即清的,所以「读了不用」和「没读」完全不是一回事:这个读动作把标志消耗掉了,谁也再看不到。
更能说明问题的是:这个标志的能力声明(01h:157.3)工具是读了的,接口返回里明确写着模块支持它——却没有任何一条通道带着它的值。

现在 Lane Flags 表里多了一列 Tx AEQ Fail。它的含义值得单独说一句:自适应均衡没能收敛,意味着模块没能把主机发过来的信号均衡干净——问题在进模块的那段链路上(连接器、PCB、主机侧发送参数),而不是模块内部坏了。

模块没实现的标志,不再显示为“正常”

01h:157–158(Table 8-52)声明了模块到底实现了哪些 Flag: Tx Fault、Tx LOS、Tx CDR LOL、Tx 自适应均衡失败、Rx LOS、Rx CDR LOL。

⚠ 一个没实现的 Flag 读出来是 0, 而一个健康通道的 Flag 读出来也是 0——两者完全一样。 以前界面把它们都渲染成绿点,于是 “没人在监视这一项”看起来就像“这一项正常”。
现在未实现的 Flag 显示为灰色 n/a,悬停说明原因。 内置的 mock_sr8 故意不实现 Rx CDR LOL 和 Tx 自适应均衡失败两项。

16 通道以上模块的 SNR / BER:选错了窗口

Page 14h 是分 Bank 的(规范 8.17:「Page 14h 的每个 Bank 对应 8 条通道」)。诊断选择器 14h:128 和它选出来的结果窗口 14h:192–255 都在这一页里——也就是说,每个 Bank 有自己的选择器、自己的结果窗口。

⚠ SNR 和 BER 两个接口只在 Bank 0 里写了一次选择器,然后去每个 Bank 读结果窗口。于是在超过 8 通道的模块上,第 9 条往上的读数来自一个从没被选中的窗口——那里放的是上一次别的功能留下的数据。
实测(16 通道模块,Bank 1 停在误码计数窗口):第 9–16 通道的 SNR 报成了 181 dB、163 dB 和一串 0.00——181 dB 一眼假,但 0.00 看上去就像一个测量值。

误码计数那个接口本来就是对的,代码里还写着这条规矩的注释——只是没推广到另外两个。现在三个接口共用同一个读取函数,在哪个 Bank 读就在哪个 Bank 选。

ℹ 8 通道模块只有一个 Bank,行为完全不变。受影响的是 16 / 24 通道这类模块(内置演示模块里的 mock_zr16、mock_1600g_16lane、mock_24lane)。

演示模块不再自相矛盾

01h:142.5(DiagnosticPagesSupported)声明 Page 13h–14h 存在。 所有内置演示模块都实现并提供这两页(PRBS、环回、BER、SNR、计数器都在里面), 却一直声明“我没有这两页”。同样,它们报告温度、电压、光功率、偏置和各种 Flag, 却在 157–160 里声明“一个都没实现”。现已全部改为如实声明。

模块没有的控制,界面不再给你勾

CMIS 在 01h:155–156(Table 8-51,Supported Controls Advertisement) 里逐位声明了模块到底实现了哪些通道控制。 工具此前从不读它,所以下面这七个控制在任何模块上都可勾:

位控制界面位置
155.5-4SquelchMethodTx(0b’b 为完全不支持) Output Controls 卡片标注
155.3ForcedSquelchTxSupported Output Controls → Force Squelch Tx
155.2AutoSquelchDisableTxSupported Output Controls → Auto Squelch Disable Tx
155.1OutputDisableTxSupported DataPath Config → Tx Enable
155.0InputPolarityFlipTxSupported DataPath Config → Tx Pol
156.2AutoSquelchDisableRxSupported Output Controls → Auto Squelch Disable Rx
156.1OutputDisableRxSupported Output Controls → Rx Output Disable
156.0OutputPolarityFlipRxSupported DataPath Config → Rx Pol
⚠ 一个写进去模块会忽略的寄存器的勾选框,比没有这个框更糟: 你勾上、点 Apply、提示“成功”,而什么都没发生。
现在模块未声明的控制会置灰不可勾,鼠标悬停写出是哪一位没置位; 即使绕过界面直接调 API,服务端也会拒绝并引用对应位。
ℹ Tx 静默的方式也值得看:155.5-4 区分静默时是 降低 OMA 还是 降低 Pav——这直接影响你怎么读静默期间的 Tx 光功率读数。Output Controls 卡片顶部会直接写出来。
另:155.6(TransmitterIsTunable)声明的是 Page 04h/12h 存在, 演示模块的这一位直接由 profile 推导,不会与实际页面矛盾。
ℹ 内置的 mock_fr4x2 故意声明为较简单的模块: 不支持强制 Tx 静默(155.3)、不支持 Rx 极性翻转(156.0), 方便你在没有硬件时看到置灰效果。

PRBS 图案与环回:只列出模块真有的

模块在 13h:128–142 里声明了自己的诊断能力: 有哪几种环回、能不能按通道分别控制、 以及每个发生器/检测器到底支持哪些图案。工具此前从不读它, 所以图案下拉框列出全部 13 种,四种环回全部可勾选。

寄存器内容表
13h:128 四种环回类型;是否支持逐通道(主机侧 / 媒体侧); 是否允许主机侧与媒体侧同时生效 Table 8-111
13h:129 测量能力:门控精度、门控统计、周期更新、 逐通道计时器、自动重启门控 (BER / 误码计数两张卡片的「测量窗口」那行就靠它) Table 8-112
13h:177 门控时长(000b = 不门控、计数无限累加)、 自动重启、周期更新间隔、ResetErrorInformation Table 8-127
13h:176 / 13h:178 四个引擎各自的时钟来源:内部时钟 / 参考时钟 / 恢复时钟(决定参考时钟丢失到底影响不影响这一页) Table 8-127
13h:131 四个图案引擎(主机/媒体 × 发生器/检测器) 模块里到底有没有,以及每个位于自己 FEC 的哪一侧 Table 8-114
13h:140 用户自定义图案最多能放多长(L = 2(n+1),2–32 字节) Table 8-118
13h:224–255 用户自定义图案本身(Pattern ID 15 发的就是它) Table 8-134
13h:132–139 主机/媒体侧 发生器、主机/媒体侧 检测器 各自支持的图案 ID(每角色 2 字节,小端) Table 8-116 / 8-117

现在:图案下拉框只列出该发生器或检测器声明的图案。 内置演示模块声明的是 PRBS31Q/31、PRBS13Q/13、PRBS9Q/9、PRBS7Q/7 和 SSPRQ, 所以 PRBS23/23Q/15/15Q 不会出现在列表里——这就是真实模块的常见情况。 若某通道当前就停在一个未声明的图案上,列表会保留它并标注 not advertised,而不是默默改成别的值。

⚠ 环回有两个很容易踩的限制,都写在 13h:128 里:
一是不支持逐通道的模块,一侧要么全开要么全关—— 以前界面给你一排可以单独勾的框,而实际不是那么回事;
二是不允许主机侧与媒体侧同时生效的模块。
现在不支持的类型直接置灰不可勾;不支持逐通道时, 勾任意一个框会整排一起勾上,并在卡片顶部给出说明。
ℹ 内置的 mock_sr8 故意声明为能力较弱的模块(四种环回都有, 但不支持逐通道、也不允许两侧同时),方便你在没有硬件时 验证主机软件对这类模块的处理。其它演示模块声明为全能力。

激光器调谐:模块不会你写什么就调到哪

调谐面板以前把你填的值直接写进 Page 12h 就报“已写入”。 实际上模块会判断这个请求能不能服务,并在 12h:231–238(Table 8-109)的门锁标志里给回答。那些标志同样是 RO/COR——读一次就清。

位标志含义
5TargetOutputPowerOORFlagTx 目标输出功率超出可编程范围
4FineTuningOutOfRangeFlagTx 微调偏移超出声明范围
3TuningNotAcceptedFlagTx 模块当前状态下无法服务这次调谐; 编程的网格或信道与激光器实际状况不符
2InvalidChannelNumberFlagTx 信道号不在所选网格间隔的声明范围内
1WavelengthUnlockedFlagTx 波长失锁(门锁版)
0TuningCompleteFlagTx 调谐完成

面板右侧新增 Tuning Flags 一列:当前置位的显示为红色, 曾经触发过但已被读清的保留 ●! 样式,与 Lane Flags 一致。

信道范围现在会告诉你

模块在 04h:130–165 里逐网格声明了合法的信道号范围, 但工具以前从不读它。结果是:网格下拉框列出全部 9 种间隔(包括模块根本不支持的), 信道输入框没有任何上下限,你只能猜。

⚠ 以前填一个谱外的信道号,工具会照写,然后面板上的 Frequency 会显示一个物理上不存在的频率(测试中出现过 1193 THz,C 波段在 193 THz 附近)——看起来就像激光器真的调过去了。 填一个超出寄存器宽度的微调值(如 50 GHz)则会弹出一条 Python 内部错误。

现在:网格下拉框只列出模块声明的网格,并在名字后面直接写出该网格的信道范围; 信道输入框带上下限并在下方标出范围;超范围的请求在写入之前就被拒绝, 提示会直接引用它依据的那个声明寄存器,例如:

Lane 1: channel 9999 is outside the range the module
advertises for the 100 GHz grid (-40 to 40, 04h:150-153)
ℹ 内置的相干演示模块也按规范判断了:被拒绝的请求激光器不会移动, Frequency 保持原值,并置位对应的门锁标志。主机侧校验和模块侧标志是两道防线: 前者按声明拦住大部分,后者处理两者不一致的情况。

模块拒绝了你的配置时,页面会说实话

DataPath Config 里的 AppSelect 下拉框读的是 Page 10h 的 Staged Control Set ——也就是“你要求的”。模块实际在跑的是 Page 11h 的 Active Control Set(Table 8-92,206–234)。 平时两者一致,一旦 Apply 被拒绝就会分岔。

按 CMIS 8.13.3,Apply 分四步:命令受理 → 参数校验 → 执行 → 结果反馈。 校验不过时模块直接跳过执行步骤——那条通道继续跑原来的 Application, 数据通道也不会重启。

⚠ 以前这种情况下,下拉框会一直显示你选的那个 Application,看上去就像已经生效了。拒绝提示只弹 8 秒, 错过了就再也看不出来。
现在不一致的通道会在下拉框下方多一行红字 running App N,告诉你模块实际在跑什么; 鼠标悬停会写出两边的具体寄存器地址。
ℹ 什么时候会被拒绝:最常见的是选了模块没有声明过的 AppSelCode(ConfigRejectedInvalidAppSel,代码 3h)。下拉框只列出模块自己声明的 Application,所以正常操作不会碰到;但换了模块、或者通过 API 直接下发时就可能遇到。其它拒绝原因见 CMIS 5.4 Table 8-101, 包括通道不在 DPDeactivated(6h)、只给了 DataPath 的一部分通道(7h)等。
该表把 2h–Bh 和 Dh–Fh 整段都定义为拒绝,工具按代码范围判断, 不依赖名字拼写——模块返回一个规范里保留的拒绝码也不会被当成成功。
⚠ 以前所有拒绝长得一模一样。Table 8-101 给了八种不同的拒绝理由, 每一种对应你该改的东西都不同;旧版本只把枚举名原样显示出来, 等于只告诉你“被拒了”。而 9h–Bh(规范保留)和 Dh–Fh(厂商自定义) 这两段没有名字,于是 Monitoring 表按名字判色时把它们涂成了 “该 lane 未使用”的灰色——同一时刻弹出的红色提示却说配置被拒绝, 同一个寄存器,界面两处自相矛盾。
现在颜色改用代码区间判断,Config Status 单元格鼠标悬停会写出这条码 的含义和补救方向,Apply 提示也按理由分组给出同样的说明。
代码名称含义 / 该改什么
1hConfigSuccess配置已完成
2hConfigRejected校验未通过,模块没有指明是哪一项
3h…InvalidAppSel该 AppSel 码不是模块声明过的;从模块公布的列表里选
4h…InvalidDataPath这个应用放不到这组 lane 上:宽度要是应用 Host Lane Count 的整数倍,且每一段的起始 lane 要在 Host Lane Assign 位图里
5h…InvalidSI同时下发的信号完整性设置不合法
6h…LanesInUse该 DataPath 还有 lane 不在 DPDeactivated;改宽度或释放 lane 之前要先把通道停下来
7h…PartialDataPathApply 只点了这条 DataPath 的一部分 lane;要么整条一起触发,要么用支持热重配的 ApplyImmediate
8h…NoEmulation模块不支持 DataPath 仿真
9h–Bh(规范保留)规范预留给其它校验失败,没有给名字——但它属于拒绝段
ChConfigInProgress模块还在处理,这条 lane 上新的命令会被忽略
Dh–Fh(厂商自定义)模块按自己的理由拒绝,含义查模块文档
⚠ 「这条 lane 不用」以前在界面上说不出来。 规范 6.2.4.3 把 AppSel = 0000b 写成强制要求: 「主机必须给每一条未使用的 host lane 赋 AppSel = 0000b」, 而且缩窄一条数据通道时「任何变为未使用的 lane 都必须这样标出来」。 可下拉框只列模块声明过的 Application,没有 0 这一项—— 于是在这个页面上根本没法释放一条 lane。
反过来读也是错的:模块已经把 lane 5–8 置为未使用时, 表格照样显示「App 1 — 800GBASE-DR8 8H/8M」(因为没有值为 0 的选项, 浏览器只好选中第一项),而专门为这种情况做的 running … 红字提示也不会出现——它的判断条件 active && … 在 0 上短路了,偏偏 0 才是最需要提示的那个值。 这时候再按 Apply,下发的是「4 条 lane 跑 8-lane 的 App 1」,模块按 4h 拒绝: 一个界面自己造出来的死胡同。
现在下拉框第一项就是 — unused (AppSel 0) —, 模块运行中的 0 也能被正确选中;提示文字一律写「no Application」, 不再写成容易误读的「App 0」。
⚠ 换应用之前要先把数据通道停下来。 规范 6.2.4.3 把这条写了两遍:把一条正在用的 lane 释放成“未使用”, 以及改变一条数据通道的宽度(换成通道数不同的 Application), 都只能在 DPDeactivated 状态下做。做不到就是 ConfigRejectedLanesInUse(6h,“有 lane 不在 DPDeactivated”)。
本工具内置的八个演示模块,声明的两个 Application 通道数都不一样 (8 lane 和 4 lane),所以在这些模块上任何一次换应用都要先停通道。 正确顺序是:
1)勾上要改的那条通道的 DP Deinit,按 Apply,等它显示 Deactivated;
2)选好新的 Application,取消 DP Deinit 勾选,再按一次 Apply。
只是重新下发同一个 Application(re-commission)不受这条限制, 把本来就空闲的 lane 编进通道也不受限制——空闲 lane 本来就是 Deactivated。
以前演示模块不检查这个前提,一律回 ConfigSuccess, 所以这个拒绝码从来没在界面上出现过, 工具也就从没提示过这个顺序。现在被拒时提示会直接写出该勾哪个框、按几次 Apply。
⚠ “停下来再改”这套动作以前是无效的。 规范 6.2.4.3 规定,改变一条数据通道的宽度只能在 DPDeactivated 下进行, 所以换应用是两步:先勾 DP Deinit + Apply 把通道停下, 再选新的 Application、取消勾选、Apply。
第二步是一次 Apply 同时带着新配置和释放。释放的那一刻数据通道就开始重启(DPInit), 而 DPInit 投入的是 Active Control Set——暂存区的内容只有经过 Apply 才会进去(Table 6-3)。 工具以前先写 DPDeinit、紧接着写 Apply 触发,触发落在 DPInit 这个过渡状态里, 支持免中断流程的模块会悄悄丢掉它(6.2.4),通道按旧的那个 Application 起来: 规范唯一允许的换应用流程,恰好是工具做不成的那个。
现在同一次提交里:暂存区(AppSelect、两个极性掩码、Tx Disable)先写; 要放开的通道保持按住,先发 Apply、等 Config Status 出结果再放开, 新配置被拒绝的通道保持停下并提示是哪几条; 要停下的通道先写 DPDeinit,等到 DPDeactivated 再发 Apply。
ℹ 未使用的 lane 一定显示 Deactivated。 规范 6.2.3.2:AppSel 0000b「表示该 lane(及其相关资源)未被使用、不属于任何数据通道」, 并且「模块对未使用的 lane 始终报告 DPDeactivated 状态」。 内置演示模块以前不管配的是什么,只要被 Apply 选中就一路走到 Activated—— 于是一条没有任何 Application 的 lane 显示为绿色的“已激活”, 悬停还写着“数据通道已激活”。现在它按规范报 Deactivated。
判断依据取的是 Active Control Set(模块实际在跑的),不是 Staged Control Set——否则你在下拉框里选了 unused 还没按 Apply, 在跑的通道就会先被显示成已停止。
⚠ “Active Control Set”不等于“硬件正在跑的”。 DataPath Config 里下拉框下方的红字 running App N 读的是 Page 11h 的 Active Control Set。但规范里还有一个必备寄存器 DPInitPending(11h:235,Table 8-106)专门说明: ApplyDPInit 的 Provision 已经把暂存区拷进 Active Control Set, 但真正把它落到硬件的那次 DPInit 还没走—— 此时“Active Control Set 的内容可能与实际硬件配置不一致”。 工具以前从来没读过这个寄存器。
对于两种免干预流程都不支持的模块(规范 Table 6-4), 这正是按 Apply 的正常结果:命令被接受、配置被拷贝, 但数据通道不会重启,硬件还在跑原来的配置, 要靠你自己把通道停一下再放开才生效。
现在这种通道会在下拉框下方多一行琥珀色的 awaiting DPInit,悬停写明寄存器位置、含义,以及怎么把它落实。 内置演示模块以前不管 Lower 02h 说什么都会重启通道, 所以 Table 6-4 那一类模块从来没被模拟过。
⚠ 超过 8 条通道的模块,PRBS 的 LOL 那一列以前是错的。 Page 14h 上那六个锁存标志字节——两侧的检测器失锁、 两侧的发生器失锁,以及两个门控完成标志—— 都是每条通道一个 bit,也就是每个 bank(8 条通道)一个字节。 而工具六个全都只读了 bank 0。
对超过 8 条通道的模块,这不是「少了个功能」,是答错了: 第 9 条通道显示的是第 1 条的标志, 而第 16 条通道失锁根本看不见。 检测器有没有失锁,本来就是这一列存在的全部意义。
标志历史还在下一层犯了同样的错: 它按 bit 位置记「谁闪过」,于是第 16 条通道的一次失锁 被记到了第 8 条头上—— 冤枉了一条本来好好的通道,又放过了真正出问题的那条。
现在六个字节都逐 bank 读,历史也按绝对通道号记。 8 通道模块只有一个 bank,行为和以前完全一样。
⚠ Applications 表里那几条,可能不是这只模块的全部。 这张表列的是基本 Application 描述符里的内容——最多 15 条, DataPath 那个 AppSel 下拉框给的也正是这些。
但 01h:175(Table 8-59)说的是:这 15 条是不是全部。 支持 Normalized Application Descriptors(NAD) 的模块, 把其余的 Application 放在 Page 1Ch 的若干个 bank 里, 最多能到 n×15 条。
规范里有一句几乎是照着这个毛病写的: 把这个字段读错的主机「甚至可能退化成只看到基本描述符里的前 15 条 Application」。而工具连这个字段都没读过—— 于是把 15 条当成全部摆出来,一个字都没说。 (这个字段在 CMIS 5.4 加宽成了整字节; 按 4 位读的话,16 个 bank 会变成 0,看着就像根本没有 NAD。)
现在:模块声明了 NAD,Applications 表下面会明确写出 有几个 bank、最多可能有多少条 Application、它们在 Page 1Ch, 并且直说这张表只是基本描述符。
有一点特意没有做:工具不能去投运一条放在块 0 以外的 Application—— 选中那样一条还需要把它的 NAD 块号写进暂存控制集 (18h:128–135);工具只写 0(改选基本 Application 时), 或者保留通道原有的块号。Page 1Ch 的内容后来已能读出并列在表里。 假装能用比原来的沉默更糟,所以这里只把话说清楚, 不做「支持了」的样子。
⚠ 模块自带的页校验和,工具以前一个都没验过。 规范 8.3.11 写得很直白:页校验和是一个字节, 「可以用来验证该页上的只读静态数据是否有效」。 每个静态页都有:00h:222,以及 01h / 02h / 04h 的第 255 字节。 四个,一个都没读过。
这件事对这个工具尤其要紧:它本来就是用来调 会出问题的两线总线的。 一次读串了的声明数据,正是它存在的意义所在—— 而这时模块信息页上其它每一行都是假的。 模块递过来一个字节就能发现,工具却从来没问。
这里有三个不一样的范围,而 01h 是那个特例: 它从 130 开始,因为 「固件版本字节 128–129 被特意排除在页校验和之外, 以免固件一升级就得改内存映射」。
现在连接时会逐页核对:全部对得上,模块信息页会写 「N pages verified」;对不上就点名是哪一页, 并说明这一页的静态数据可能是读错了, 悬停能看到期望值、模块实际报的值,以及这一页校验的是哪段字节。
只核对模块确实有的页:01h / 02h 看内存模型是不是分页的,04h 看发射机是不是可调。 模块没有的页不会去核对——那种页读回来是什么全看模块, 据此报「数据损坏」是误报,比不报还糟。
内置演示模块以前这个字节全是 0, 等于每一只模块一验就是坏的—— 这恰恰就是从来没人去验的原因。 现在它们会算出真的校验和, 而 mock_fr4x2 的 01h 故意对不上, 好让「验不过」这条路也有东西走。
ℹ 「Media Interface: 1310 nm EML」不是模块自己报的波长。 模块信息页里那一行是 Table 8-40 的技术编码—— 它说的是一类技术、一个波段, 不是这一只模块实际发的波长。
01h:138–141(Table 8-46)才是模块自己声明的 标称波长和波长容差,工具此前没读过。 规范还特意写明:波长可编程的模块,这里报的是「实际值」—— 所以在可调模块上,技术编码和这个寄存器根本不是同一个说法。
这里有个很容易写错的地方:两个字段的刻度不一样—— 标称波长按 0.05 nm 计,容差按 0.005 nm 计。 两个用同一个系数,其中一个就会差十倍。
现在模块给了值就在「Media Interface」下面多一行 Nominal Wavelength,例如 1310 nm ±6.5 nm; 没给(两个字段为 0)就不出现这一行。
还有一条按规范办的:Table 8-46 说这两个字段是 给单波长模块定义的;多波长模块可以填(填一个波长、 或者整个范围的中心波长和总容差),但「解释方式没有唯一定义」。 所以工具会先判断这是不是单波长模块—— 靠的正是 11h:240–255 那份通道-波长映射(见上文): 各通道映射到不止一个波长就说明不是。 是多波长的话,这一行会明确标出 「several wavelengths on this module」并在悬停里说明 规范没有唯一定义这个字段在这种模块上的含义—— 而不是把它当成「这只模块的波长」直接摆出来。
ℹ Aux 那几个读数,以前没有任何门限可比。 模块信息页会列出 Aux1–3——TEC 电流、激光器温度、第二路电源—— 但阈值页只有温度、Vcc、Tx 光功率、Tx 偏置、Rx 光功率, Aux 一个都没有。数字摆在那儿,却没有东西可以对照。
02h:144–175(Table 8-64)给的正是这几个监测量各自的 高低告警和高低警告(三个 Aux 各四档,外加一个 Custom 监测量), 工具一个字节都没读过。
这里有个容易踩的点:这三个 Aux 根本不是同一种物理量—— Aux1 可能是TEC 电流(有符号百分比)、 Aux2 是激光器温度(1/256 °C)、 Aux3 是第二路电源电压(100 µV/LSB); 究竟是哪一种由 01h:145 声明。 门限必须按各自监测量来解码, 否则把 TEC 电流的门限当温度读出来, 数值落在一个看着挺合理的范围里,单位却完全不对。
现在阈值页会按模块声明补上 Aux 各自的四档门限, 每行带上自己的名字和单位(如 Aux2 — Laser Temperature (°C))。 模块没有某个 Aux 监测量、 或者四档门限全是 0(等于没给)时,那一行不出现—— 不拿一排 0 冒充门限。
⚠ 温度那个颜色,以前是工具自己定的,不是模块的。 监控页顶部那行温度,以前的规则是: 超过 60 °C 变黄、超过 70 °C 变红—— 这两个数字是直接写死在页面里的, 既不是模块的告警门限,也不是模块的额定范围。
可 01h:146–147(Table 8-50)说的正是 这个模块被允许工作的温度范围, 01h:150 说的是它需要的最低供电电压—— 工具都没读过。
后果很具体:一只额定到 85 °C 的工业级模块, 在 71 °C 时会被标成红色—— 而它离自己的上限还有整整 14 度; 反过来,一只只额定到 55 °C 的模块在 65 °C 时 还是绿色,其实早就超了。 这是整个界面上最先被看的那个数字, 而它的颜色跟模块无关。
现在颜色按模块自己的额定范围来,旁边直接写出 「rated −40…85 °C」;电压也会跟模块声明的最低电压比。 悬停会说明这是哪个寄存器给的。
有一点特意写清楚:那条黄色的「还差 5 °C 到上限」是工具自己加的余量, 模块给的是上限而不是告警级别—— 把工具自己的判断说成模块的,就又犯了同一个毛病, 所以提示语里明说了这 5 °C 是工具的。
模块两个温度字节都是 0 时,规范的含义是「未指定」, 这种情况下工具不上任何颜色,而不是替它编一个门限出来。
⚠ 「这条通道没卡住」——这句话工具以前没有资格说。 DataPath State 那一格悬停时,瞬态(DPInit / DPDeinit / DPTxTurnOn / DPTxTurnOff)写的是「正在状态之间迁移,没有卡住」。 可工具凭什么知道没卡住?
规范里有专门为此存在的字段:01h:144 和 01h:168(Table 8-48 / 8-56,只读、必需) 逐个给出这四个瞬态状态的最长时间, 原文写得很清楚——这些字段的用途就是让主机 「判断模块在这些状态里是不是出了问题,比如固件卡死」。 这些字节工具一个都没读过, 于是某条通道可以永远停在 DPInit,而提示语还在说它没事。
现在:瞬态提示会写明这个模块允许这个状态用多久、 以及已经用了多久;一旦超过模块自己声明的上限, 那一格会变成危险色并带一个「!」, 提示语改成「已经超过模块声明的时间,模块里可能有什么停住了」。 稳态(Activated / Deactivated / Initialized)没有上限可超—— 模块被放在那儿多久就是多久,不会被误报。

DPTxTurnOn / DPTxTurnOff 另有规范上限:Table 10-8 规定 Tx 输出关断最长 100 ms、开启最长 400 ms,并明确说它们是 01h:168 声明值的上限。模块声明得更长时,工具按规范上限判断是否超时,提示里会写明这一点。

ℹ 翻页等待时间现在按模块声明来,不再一律等满 10 ms。 切页(写 0x7F)之后必须等 tBPC 才能读, 否则会读到上一页的内容——规范给的 tBPC 是 10 ms。 但那是最坏情况,不是每个模块的情况: 01h:169.3-0(MaxDurationBPC)声明这个模块 实际只需要 tBPC / 2i。 这个字节工具此前没读,于是每一次切页都按最坏情况等满 10 ms—— 而界面刷新一轮要切很多次页。
现在按模块声明来:声明 i=2 的模块只等 2.5 ms。 实测同样三轮完整刷新,从 0.44 秒降到 0.18 秒。 模块没声明(或声明 0)时仍然等满 10 ms, 连接过程中读到这个字节之前也一律按 10 ms 算—— 毕竟这段等待本身就发生在读到它之前。
ℹ 监控表的「Lane」列现在会写明这条媒体通道是哪个波长、哪根光纤。 表里列着媒体通道 1..N,每条一个光功率读数—— 可这一列看不出模块是并行的还是波分的。 这两者完全不是一回事:波分模块上好几条媒体通道共用一根光纤、 只靠波长区分;并行模块则每条通道各走各的光纤。 于是「第 3 条通道功率低」到底是某个波长弱了, 还是整根光纤有问题,界面上分辨不出来。
11h:240–255(Table 8-107)说的正是这个映射: 高半字节是媒体波长,低半字节是物理光纤 (TR1/RT1/TR2… 这套编号来自对应的硬件规范)。 这 16 个字节工具从来没读过。
现在模块给了映射的通道,Lane 那格下面会多一行小字, 例如 λ1 · TR1/RT1;悬停能看到完整的光纤名称。 两个方向波长相同时只写一次(双工光纤对本来就是这样)。
两个半字节都是 0 的含义是「未知或未定义」—— 这正是并行模块应该给的回答,所以这种模块下这行小字整个不出现, 而不是硬编一个「光纤 0」。
内置演示模块以前全都是 0,等于谁都没说, 所以就算读了也没东西可显示;现在 mock_fr4x2(2× 400G-FR4)会如实声明: 通道 1–4 是同一对光纤上的四个 CWDM 波长, 通道 5–8 走第二对——这正是原先那一列没法表达的情况。
⚠ 这份映射同样是按 bank 存的。 11h:240–255 这 16 个字节描述的是 本 bank 的 8 条媒体通道(先 Tx1–8、再 Rx1–8), 所以 16 通道模块的第 9–16 条在下一个 bank 的同一批地址上。 工具以前只读一个 bank,也只解析 8 条通道, 于是第 9 条通道起没有任何映射—— 而「没有映射」在表里的画法,跟模块自己说 「未知或未定义」(0000b)是一模一样的。 波分模块明明报了波长,界面上却什么都不写。
现在逐 bank 读、按实际通道数解析。8 通道模块只有一个 bank, 行为和以前完全一样。
⚠ 工具以前一次读的字节数,超过了模块必须回答的数量。 规范 5.2.2.1 写得很直白:一次 READ 最多读 Nmax 个字节, 默认 Nmax = 8;只有模块声明支持整页读 (01h:251.1-0,Table 8-62,只读、必需)时才是 128。
这个字节工具从来没读过,而它一次要 64 字节 (诊断结果窗口)、32 字节(用户图案)、28 字节(附加 Application 描述符); Raw 面板更是直接写着「Length must be 1–128」—— 那是模块说了支持整页读之后才成立的上限。 模块碰上超长 READ 怎么办是它自己的事: 地址回绕、中途 NAK 都可能,读回来的东西本来就不能当真。
现在:连接时先读这个字节,再做后面那些长读 (顺序反了的话,找上限的那几次读自己就已经越界了); 超过上限的读会自动拆成若干次,对上层完全透明。 Raw 面板下方会写明这个模块一次答多少字节、 以及这次读是不是被拆开了。
内置演示模块以前来者不拒——要 64 就给 64, 所以这件事在演示里永远暴露不出来。现在它会像真模块一样拒绝, mock_fr4x2 声明不支持整页读(一次只答 8 字节), 其余 profile 支持整页读,两条路径都跑得到。
⚠ 模块声明了的图案,下拉框里可能根本没有。 规范 Table 8-115 一共定义了 16 个 Pattern ID。 工具的寄存器层认得其中 15 个名字, 但网页自己另外存了一份图案名列表,而那份只排到 SSPRQ(ID 12)。 两份必须一致的列表分放两处——而用户看到的是短的那份。
结果:模块声明支持 Custom(14) 或 User Pattern(15) 时, 它们会被无声地从下拉框里滤掉; 某条 lane 本来就停在这两个图案上的话, 界面会显示一个光秃秃的数字并标注 not advertised——而模块明明声明了。
现在图案名由模块读取时一并下发,网页不再自己存一份, 这一类「两份列表迟早对不上」的问题从根上没有了。
ℹ User Pattern(ID 15)现在可以真的用了。 这个图案的内容由主机自己定义,放在 13h:224–255(Table 8-134); 能放多长则写在 13h:140.3-0 (L = 2(n+1),最短 2 字节、最长 32 字节)。 这两处工具此前都没读——也就是说就算选中了 User Pattern, 发出去的也是那段字节里本来碰巧是什么就是什么。
现在:只要有任一发生器或检测器声明了 ID 15, PRBS Generator 卡片下方就会出现用户图案输入框, 显示模块里当前的字节(十六进制),并写明是哪个寄存器、 以及模块最多收多少字节;随 Apply 一起下发。 输入不是完整的十六进制字节会被当场拒绝, 而不是把半个字节发下去。 比声明长度多写会被挡下并说明模块只收几字节。
没有任何角色声明 ID 15 的模块,这个框整个不出现—— 那段字节在这种模块上不是任何人能选中的图案。
内置演示模块里 mock_coherent 支持完整 32 字节, mock_coherent_zr 只收 4 字节—— 规范原文就写着「模块不一定支持完整的 32 字节长度」。
⚠ BER 和误码计数,以前没说是多长时间里的数。 两张表把数字摆出来,却从不说这些数覆盖多长的窗口; 而回答这个问题的两个寄存器都没被读。
13h:129(Table 8-112,只读、必需)说明模块 到底会不会门控一次测量,以及测量还在跑的时候 这些数会不会更新。工具其实早就把它解码了—— 从诊断面板写出来那天起——但解出来的结果没有任何地方用。
13h:177(Table 8-127)则完全没读过。其中 MeasurementTime 取值 000b 的含义是 「不门控,计数无限累加」——也就是说界面上那个 BER 是「自从上次有人翻动 ResetErrorInformation 以来的总账」, 不是任何一段确定时间里的误码率。 内置演示模块全都是这一种,而表格一个字都没提。
现在两张卡片顶部各写一行测量窗口:不门控就直说计数在无限累加、 这是总账不是速率;有门控就写出门控时长(如 60 秒); 模块根本不支持门控时(13h:129.7-6) 就说明窗口取决于你让检测器跑了多久。 模块声明测量期间不做周期更新(13h:129.4)时 还会额外点出来——否则一个会自动刷新的面板, 看着就像数字在实时变。
内置演示模块现在三种写法都能看到: 默认那种不门控、mock_sr8 有 60 秒门控、 mock_fr4x2 既不门控、测量期间数字也不动。
⚠ 「参考时钟丢失」以前是句过头的话。 工具读了 14h:132.7(LossOfReferenceClockFlag), 并在 PRBS 卡片顶部写「本模块的图案发生与检测在它恢复前都不可信」。
这句话模块从来没说过。13h:176 和 13h:178 (Table 8-127)逐字段说明四个引擎各自的时钟来源—— 模块内部时钟、参考时钟,还是从业务里恢复出来的时钟—— 而这两个字节工具从来没读过。 跑在内部时钟上的发生器、跑在恢复时钟上的检测器, 参考时钟丢了照样是原来那个样子。
这两个字段的编码还不一样:176 高半字节按 媒体 lane 数参考时钟,低半字节按主机 lane 数, 而且只有低半字节有「所有 lane 用参考时钟」这个取值。
现在:四个分区各自在标题下写明自己的时钟来源; 参考时钟真丢了的时候,那行字只点名真正用它的引擎, 四个都用就直接说「整页都用它」;一个都不用时, 它降为一条普通提示,说明这一页的图案不受影响。
内置演示模块以前这两个字节都是 0(发生器内部时钟、检测器恢复时钟), 正好是那句警告全说错的那种配置;现在 mock_sr8 四个引擎全跑参考时钟,两种写法都能看到。
⚠ 四张 PRBS 表,模块不一定有那个引擎。 13h:131(Table 8-114,只读、必需)逐位声明 主机侧 / 媒体侧 的发生器与检测器各自存不存在, 以及每个位于自己 FEC 的哪一侧。 四个 Enable 字节(13h:144 / 152 / 160 / 168) 在规范里各自写着「Advertisement: 13h:131.x-y」, 指的就是这个字节——工具把它连同旁边的能力字节一起读了进来, 却直接丢掉。
一对位全为 0,表示模块压根没有这个引擎: 界面照样摆一张八行的表,勾了 Enable 也只是往一个没人读的字节里写数。
只有一位为 1 时,PreFEC / PostFEC 那一列只有一个合法值—— 另一侧没有引擎可跑。规范还特别写明: 没有内部 FEC 的模块,只存在 Post-FEC 发生器和 Pre-FEC 检测器, 也就是这两个框对这类模块本来就该是固定的。
现在:模块没有的引擎,那张表整块换成一行说明并注明是 13h:131 的哪两位决定的;只有一个位置的, FEC 那一列按模块实际所在的位置勾好并置灰,悬停写明原因; Apply 也会挡下「启动一个不存在的引擎」和 「把引擎放到 FEC 的另一侧」这两种写入。
内置演示模块以前把这个字节留成 0x00, 等于声明「本模块没有任何图案发生器和检测器」, 而界面把四张表全摆着——现在它们会如实声明: mock_sr8 是无内部 FEC 的模块(发生器只在 FEC 后、 检测器只在 FEC 前),mock_fr4x2 干脆只有主机侧 的一对引擎。
⚠ PRBS 表里那几列,模块不一定支持。 13h:141–142 是两个必备寄存器, 工具本来就把它们连同旁边的能力字节一起读了进来,却直接丢掉:
141 说明每个角色(主机/媒体 × 发生器/检测器) 到底有没有 DataInvert 和 SwapSymbolBits 这两个字节; 没有的话,勾了也不会有任何效果。
142 说明 Enable 和 Pattern 是不是按 lane 分: 位为 0 时,勾第 3 条 lane 的 Enable 实际上启动的是整个 Bank, 而 Pattern「一律用 lane 1 的」——也就是说第 2–8 行的下拉框 只是摆设。
现在这四列按模块声明置灰,悬停写明是哪个寄存器决定的; lane 1 那一行始终可用(模块确实有这个控制,只是作用范围是整个 Bank)。 内置演示模块之前把这两个字节留成 0,等于声明「全都不支持」, 而界面把四列全摆着——现在它们会如实声明, mock_fr4x2(那个“声明得比较少”的模块) 不支持符号位交换、主机检测器也不支持按 lane 启停。
⚠ PRBS 发生器也会失锁,以前界面上看不出来。 规范 Table 8-138(Page 14h 的锁存诊断标志)一共五个标志字节, 工具以前只读其中两个——检测器的失锁标志, 也就是 Checker 两张表里的 LOL 列。
没读的三个里,最要紧的是 14h:136–137 的 发生器失锁:发生器没锁上,就说明它并没有在发 控制寄存器里写着的那个图案。于是界面会显示某条 lane 正在发 PRBS31,而模块其实报告了失锁—— 对端测到的误码看起来像链路故障,实际上是源头就没发对。
另外两个:14h:132.7 是参考时钟丢失(整模块级, 丢了的话这一页上测什么都不作数), 14h:134–135 是门控测量完成标志。
现在 Generator 两张表也有了 LOL 列,语义和 Checker 一致 (LOL 正在失锁、● 已锁定、 ●! 现在锁着但中途丢过——这些标志是读一次即清的); 参考时钟丢失会在 PRBS Generator 卡片顶部单独标出。
ℹ Applications 表补上了「Media Lane Assign」一列。 规范 6.2.1.6 把 Application 描述符定义为五个字节, 第五个字节 MediaLaneAssignmentOptions 说明这个应用的实例 在媒体侧能落在哪几条 lane 上;它不跟前四个字节放在一起, 而是单独放在 01h:176–190。 工具以前只读前四个字节,所以每条描述符都少了五分之一—— 主机侧的起始 lane 位图有,媒体侧的没有。 对分路(breakout)应用来说,这一位图正是告诉你 每个实例占用哪几条媒体 lane 的唯一依据。
(平坦内存模块没有 01h 页,本来就不带这个字节,这一列会显示 —,不是读失败。)
⚠ 模块最多可以声明 15 个 Application,工具以前只读前 8 个。 AppSelCode 是 4 位,能取 1–15;而低页内存只放得下 8 条 Application 描述符,规范 8.4.17 把第 9–15 条放在 01h:223–250。 工具一直只读低页那 32 字节,于是第 9 个以后的应用完全不可见: 下拉框里没有、DataPath 分组不知道它占几条 lane, 更糟的是——它会被当成“模块从没声明过的码”, Apply 时回 ConfigRejectedInvalidAppSel, 拒绝一个模块其实支持的应用。
现在两段描述符会连起来读,终止符(HostInterfaceID = FFh)落在哪里就读到哪里; 声明 8 个及以下的模块行为完全不变。
⚠ Signal Integrity 表里的数值,模块不一定在用。 这张表读的是 Page 10h 的暂存区——你要求的值。 而规范 Table 8-104 / 8-105 说得很清楚: DPConfigLane 里的 ExplicitControl 位置 1 时, 生效的值才来自暂存区;清 0 时, 「这些值由模块根据所选 Application 自行决定」。
本工具写的一直是 0(一条数据通道、从 lane 1 起、SI 由 Application 决定), 所以每一次 Apply 之后,真正生效的都不是表里显示的数字。 模块把自己实际配置的值发布在 11h:214–234, 紧挨着工具早就在读的 Active AppSel——但这一段从来没被读过, 表格下方却写着“Apply 会把这一套一起下发”。
现在两边不一致的格子会在数值下面标出 in force N(模块实际在用的值), 悬停说明它来自 Active Control Set 以及 ExplicitControl 的含义; 表格下方那句话也改了。
ℹ 信号完整性设置也会被校验了。 模块在 01h:153–154 里声明了三个上限—— Tx 输入均衡最大值、Rx 输出均衡的前/后游标各自的最大值—— 以及它到底有哪几个 Rx 输出幅度码。 要得比模块声明的多,就是 ConfigRejectedInvalidSI(5h)。
以前演示模块根本不看暂存区的信号完整性那一半, Apply 会把模块从没说过自己能做到的值一起提交; 而且八个演示模块把三个上限全都声明成了字段能装下的最大值 (7、7、7,四个幅度码全有), 所以从来没有一个“有真实限制”的模块可以用来对照—— 前后游标两个上限相等,意味着把 01h:154 的两个半字节读反了也看不出来。
现在 mock_fr4x2(本来就是那个“声明得比较少”的演示模块) 声明的是:Tx 均衡最大 3、前游标最大 5、后游标最大 2、 只有 0 和 1 两个幅度码。 Signal Integrity 表里超出上限的数值会标红, 悬停写明模块声明的上限,以及这样 Apply 会得到哪个拒绝码。
ℹ 内置演示模块现在会按这些规则真的拒绝。 以前它只校验 AppSel 码有没有被声明过,别的一律放行, 所以 4h、7h 这些理由在界面上从来没出现过。 现在它按 CMIS 6.2.4.3 的主机规则校验:应用必须整段落在 它声明的起始 lane 上(否则 4h),Apply 必须覆盖整条 DataPath (否则 7h,热重配 ApplyImmediate 除外)。
连带修正了一处演示模块自相矛盾的地方:双 4-lane 端口的 mock_fr4x2 声明 App 1 只能从 lane 1 起、App 2 只能从 lane 5 起,开机默认却是八条 lane 全跑 App 1——这是它自己的 声明所禁止的配置。现在默认是 lane 1–4 跑 App 1、lane 5–8 跑 App 2。
ℹ 连续点两次 Apply:按规范,上一次还在 ConfigInProgress 时到达的新命令会被模块静默丢弃(不给任何反馈)。 工具现在会等 ConfigStatus 出结果再下结论,不会把“还在处理中”报成“已应用”。

标题栏的两个小图标——切到别的页也不会漏

以前只有 Monitoring 页在轮询模块:切到其它任何一页, 工具就完全停了读。你在 DataPath Config 里改一下午配置, 期间模块告警、重启、链路弹过——回到 Monitoring 时什么都不剩, 因为没人去读那些门锁位,历史自然也无从记起。

现在只要连着模块,后台每 5 秒会轻量轮询一次(只读状态和标志, 不拉整张监控表),不管你停在哪一页。门锁位的意义就在于此: 5 秒一次足够接住一个瞬时事件。发现情况时,标题栏会出现小图标:

图标含义来源
⚠ 模块级监控(温度 / 电压 / Aux)这次刷新报了告警;只报警告时显示黄色 ▲ Lower 0x09–0x0B(这次刷新读到的标志,不是历史)
↺ 模块重启过,或进入过新的 Module State(自上次 Clear 起),悬停说明是哪一种 13h:184–191 Host Scratchpad / Lower 0x08[0] ModuleStateChangedFlag
↯ N 有 N 条数据通道弹过(自上次 Clear 起) 11h:134 DPStateChangedFlag
✖ 模块处于 ModuleFault(悬停说明原因),或报告过固件故障(自上次 Clear 起) Lower 0x03[3:1] + 41 ModuleFaultCause / Lower 0x08[2:1] ModuleFirmwareErrorFlag / DataPathFirmwareErrorFlag

图标可以点,点一下直接跳到 Monitoring 看具体哪几条通道。 点 Clear flag history 后图标立即消失,从当下重新开始计。

ℹ 为什么是图标而不是文字:1440×900 的本本在 Windows 150% 缩放下只有 683 CSS 像素宽,写成一整句会把标题栏挤成三行—— 而你正在查间歇性故障时,它会一直亮着。鼠标悬停在图标上有完整说明。
ℹ 连不上模块时会怎样:后台轮询读失败时, 标题栏会只剩一个红色 ⛔,鼠标悬停会写出具体原因。 其它图标会消失——它们描述的是一个现在读不到的模块, 空白的标题栏会被当成“一切正常”,那比不显示更糟。 提示只在“刚刚失联”和“又能读了”两个时刻各弹一次, 不会每 5 秒吹一遍。

服务端重启后,页面会自己认错

升级完成后工具会重启自己,而浏览器那个页是一直开着的。 重启后的进程并不知道你之前连过哪个模块, 所以所有请求都会返回“未连接”。

⚠ 以前这种情况下左上角会一直写着 Connected — mock_dr8…,而你点什么按钮都报错, 错误还是一个一个弹出来的。
现在工具会直接把状态改回 Disconnected、回到 Module Info 页、 弹一条“服务端已没有连接的模块,请重新连接”。重新点 Connect 即可继续,不需要刷新页面。

Module State Changes 与 Module Restarts —— 模块整体的两条记录

上面讲的是单条通道。模块整体有两条对应的记录,在 Module Info 里各占一行:

  • Module State Changes:ModuleStateChangedFlag(Lower 0x08[0])。规范 Table 6-9:进入 ModuleLowPwr、ModuleReady 或 ModuleFault 时置位——复位会点亮它,切一次低功耗再回来同样会点亮它。
  • Module Restarts:规范 8.16.13 的 Host Scratchpad(13h:184–191,01h:251.7-6 声明)。模块每次固件重启(包括自恢复重启)都会把它清零,规范明说主机可以用它发现模块自己重启过。工具连接后在这里留一个标记,每次刷新读回;标记没了,就是重启过。
⚠ 这两种标志都是闩锁的。一个模块在两次刷新之间重启完成, 前后两帧看到的都是 ModuleReady,温度电压也正常—— 没有任何一栏会告诉你它刚刚重启过。 所以两行都保留 ●! 历史 (State changed since last clear / Restarted since last clear), 顶部摘要栏同时出现 ↺。 与 Lane Flags 的历史共用同一个 Clear flag history 按钮。
ℹ Host Scratchpad 是给主机存东西用的,工具只在它全为 0(没人在用)时才写入标记;里面已有别的主机软件的数据时原样不动,这一行显示「Not watched」。模块没有声明支持 Host Scratchpad、或不是分页内存模块时显示「Not detectable」——这时只能看上面那一行。
ℹ 你自己点 Software Reset 也会点亮它,这是正常的。 它不算告警——顶栏的 ⚠ Alarm Active 只代表有读数超出阀值,不会因为重启而亮。

PRBS 检测器中途失锁

Diagnostics 里的 PRBS 表格同样适用这条规则。检测器的 LOL(Loss of Lock)位在 14h:0x8A–0x8B(Table 8-138), 同样是 RO/COR——门限、读清。

⚠ 跑一个长时间的 BER 测试,中途失锁正是你要找的东西, 而下一次刷新它已经重新锁上,表里看起来一切正常。
现在失过锁的通道会在 Lock 列保留 ●! 标记。看到它就说明这条通道的 BER 结果不可信——计数器在失锁期间是无意义的,应该清一次重跑。 检测器刚启用、锁定之前那一次 LOL 也会留下标记:等它锁上后先点一次 Clear flag history 再开始看。
ℹ 排查间歇性链路时的用法:连上模块、点一次 Clear flag history, 然后让它跑着。回来时看哪些通道带 ●! ——那就是这段时间里出过问题的通道, 哪怕它现在一切正常。DP Changed 那一列尤其要看:光功率抖动可能只是脏接头, 而数据通道真的重建过,说明链路断过。

状态列的颜色与图标图例

上面讲的是光功率染色。界面里还有几套颜色和符号,含义各不相同:

出现位置显示含义
Config Status
(Monitoring)
绿色 ConfigSuccess该 lane 的配置被模块接受
琥珀 ConfigInProgress配置进行中,稍等再看
红底 任何拒绝码被拒绝。判据是 Table 8-101 的代码区间(2h–Bh、Dh–Fh),不是名字拼写——规范保留的 9h–Bh 和厂商自定义的 Dh–Fh 同样红底。不是灰色——灰色留给“该 lane 未使用”。鼠标悬停会写出这条码的含义和该改什么
DataPath State
(Monitoring)
绿色 Activated数据通道已激活(稳态)
琥珀 Init / TxTurnOn / TxTurnOff / Deinit过渡态:通道正在上来或下去,不是故障
白字 Initialized稳态,已初始化、只是 Tx 没开
灰色 Deactivated该通道已停止
Lane Flags
(Monitoring)
■ ALARM(红底)该标志位置起:Tx Failure / LOS / CDR LOL 之一
▲ Warn(橙底)仅出现在最右的汇总列,表示有 Warning 级阈值越界但无 Alarm
●(绿色小点)正常,无标志
Module Control
(DataPath)
● / ○●=该位为 1(生效),○=该位为 0
顶部摘要栏绿色圆点仅当全部 lane 都是 Activated 时才出现
⚠ 若某次读取失败,监控区会显示红色「读数已过期」横幅并将数据表置灰。 此时屏幕上的功率、温度和 Lane Flags 都是上一次成功读取的旧值,不可作为当前状态判断依据。
并且自动刷新会就此停住,不会自行恢复。监控主接口读取失败时工具会主动停掉轮询 (否则模块掉线会每秒刷屏报错)。模块恢复正常后屏幕仍然是灰的,必须手动做以下任一操作 才会重新开始刷新:点 ↻ Now、切到别的标签再切回 Monitoring、或改一次自动刷新间隔。
另外:离开 Monitoring 标签页就会停止轮询,本工具不做后台监控;回到该页才重新开始。

8.2 自动刷新间隔

选项说明
1 s每秒刷新一次
2 s(默认)每 2 秒刷新一次
5 s每 5 秒刷新一次
10 s每 10 秒刷新一次
Manual关闭自动刷新,点击 ↻ Now 手动触发

8.3 模块告警阈值表(02h)

参数 Page / Addr High Alarm Low Alarm High Warn Low Warn
Temperature (°C)02h/0x80–87过温告警欠温告警过温警告欠温警告
Vcc (V)02h/0x88–8F过压告警欠压告警过压警告欠压警告
Tx Power (dBm)02h/0xB0–B7光功率上下限阈值
Tx Bias (mA)02h/0xB8–BF偏置电流上下限阈值
Rx Power (dBm)02h/0xC0–C7接收光功率上下限阈值

这几组阈值在规范里都是 Cnd.(Table 8-64 / 8-65):只要求实现了对应监控的模块提供。模块在 01h:159–160 声明没有某个监控时,这一行显示 no monitor,不再把那几个字节当成阈值显示。

8.4 通道标志位(Lane Flags)

列含义Page / Addr
Tx Failure发送器内部失效(规范 FailureFlagTx,原名 Tx Fault);主机关断输出不算11h / 0x87
Tx LOS发送端信号丢失11h / 0x88
Tx CDR-LOL发送 CDR 失锁11h / 0x89
Tx AEQ Fail主机侧输入自适应均衡没能收敛(AdaptiveInputEqFailFlagTx)——故障在进模块的链路上,不是模块内部11h / 0x8A
Rx LOS接收端信号丢失11h / 0x93
Rx CDR-LOL接收 CDR 失锁11h / 0x94
Alarms/Warns功率 / 偏置综合告警状态11h / 0x8B–0x98

图标:● 正常 ▲ WARN ■ ALARM

9. DataPath Config — 数据通道配置

9.1 Module Control(模块控制)

模块级控制寄存器(Lower 0x1A)。表格共四行,只有前两行带操作按钮,后两行是当前状态显示, 本工具不提供修改入口("操作"列显示 —)。

行含义操作Page / Addr
Software Reset向 0x1A[3] 写 1 触发软件复位。所有 DataPath 将重新进入 Init 状态Reset Module 按钮(红色)Lower / 0x1A[3]
Low Power Request (SW)0x1A[4]。写 1 请求进入低功耗模式,清除则请求退出Enter LowPwr / Exit LowPwr 两个按钮Lower / 0x1A[4]
Allow LowPwrRequestHW模块是否响应硬件 LPMode 引脚。●=响应,○=忽略。只读显示—Lower / 0x1A[6]
Squelch MethodSquelch 判据:Pav=按平均光功率,OMA=按调制幅度。只读显示—Lower / 0x1A[5]
⚠ Reset Module 会中断业务,点击后会弹出确认对话框。复位后模块会经历 LowPwr → PwrUp → Ready 状态机流程,本工具随后自动刷新整个标签页。
Enter LowPwr 同样会中断业务,而且没有确认对话框——点下去立即生效。 低功耗模式下模块会关闭发射,Monitoring 页的 TxPower 会掉到 0(这不是读数故障), DataPath 退出 Activated。恢复业务需要点 Exit LowPwr 并等待模块回到 Ready。

9.2 Supported Applications(支持的应用码)

读取 Application Descriptor 表(最多 15 组:前 8 组在 Lower Memory 0x56–0x75,后 7 组在 01h:223–250),列出模块广告的 Host/Media Interface ID 组合。

列说明
AppSel应用码序号(1–15),写入 DataPath 配置表时使用。模块声明了 Page 16h(01h:142.7)时,16h:248–249(Table 8-158)里标为 NP 应用的,旁边显示 NP:它的每个起点是一条 Host Path,几条 Host Path 共用一条 Network Path;Host Path 只到 DPInitialized,Network Path 在 Page 16h 配置,本工具没有这个面板
Host Interface IDSFF-8024 主机侧接口 ID(Table 4-5,如 0x4F = 400GAUI-4-S C2M、0x51 = 800GAUI-8 S C2M、0x71 = PCIe 5.0)。CMIS 本身不定义这些编码,只存编号并指向 SFF-8024(本工具按 Rev 4.14 解名称)。比编码表更新的编号显示 Unknown (0x..)(00h 是 SFF-8024 定义的 Undefined,不算未知),不留空;0xBE 显示 See NAD (0xBE)(真实编号在 Normalized Application Descriptor 里)
Media Interface ID媒体侧接口 ID,按 Media Type(Lower 85)查 SFF-8024 的对应表:MMF(4-6)、SMF(4-7)、无源 / 线性有源铜缆(4-8)、有源线缆(4-9)、BASE-T(4-10)
Host Lanes / Media Lanes该应用需要的主机侧 / 媒体侧 lane 数
Host Lane Assign8-bit 位图,指示该应用可以从哪些主机 lane 起始(bit 0 = lane 1);扁平内存模块上这个字节是 HostInterfaceGID
Media Lane Assign01h:176–190 的位图,该应用的媒体侧可以从哪些 lane 起始;扁平内存模块没有 Page 01h,不显示。按 Table 8-60,每个起点都要有自己连续的若干条媒体 lane、全部同时可用;某个起点超出 lane 8、落在 00h:210 声明不存在的媒体 lane 上、或与前一个起点重叠时,格子里会标 ⚠ 并写明是哪一个

9.3 DataPath 配置表

列说明Page / Addr
Lane通道编号(8 通道模块 1–8;16 通道模块 1–16,第 9 条起在 Bank 1,地址同第 1 条)—
AppSelect应用码选择。下拉只列出该模块实际广播的应用(通常 1–8 个),格式为 App 2 — 0x4F/0x1B 4H/4M,依次是应用码、主机/媒体接口 ID、主机与媒体 lane 数; NP 应用(见 9.2)的那一项末尾注明 NP Application (Host Path)。 带 NAD 的模块上,暂存在块 0 以外的通道顶部多一项 AN n (NAD Block b, AppSel c) — kept(18h:128–135);改选其它 Application 时块号写成 0。 若某 lane 当前停在模块已不再广播的应用码上,会额外出现一条只读的 App n — not advertised 用于保留现值。 寄存器本身:DPConfigLane,每 lane 1 字节,bits[7:4]=AppSelCode(0 表示"无应用",不是 App 0), bits[3:1]=DPIDX(CMIS 5.4 起由 DataPathID 更名,强调它是索引而非编号),bit[0]=ExplicitControl。 工具写入时按 Application 的主机通道宽度把通道分成数据通路,每条通道的 DPIDX 写成它所在数据通路的最低通道号减 1(Bank 内计); ExplicitControl 保留模块里原有的值10h / 0x91+(n−1)
TX Enable勾选 = 发送使能;取消 = 禁用(OutputDisableTx 取反)。运行中的数据通道任一路取消,整条通道退到 Initialized(Eq. 6-12)10h / 0x82[n−1]
TX Pol FlipTX 侧输入极性翻转(InputPolarityFlipTx)10h / 0x81[n−1]
RX Pol FlipRX 侧输出极性翻转(OutputPolarityFlipRx)10h / 0x89[n−1]
DP DeinitDataPath 去初始化位(每 lane 1 bit),可勾选,Apply 时随其它配置一起下发。 勾上并 Apply 会把该 lane 所在的整条 DataPath 停到 DPDeactivated(规范要求同一条通道的所有 lane 取值一致); 取消勾选再 Apply,通道重新走 DPInit 上来。 注意是 10h,Page 11h 的 0x80 是只读的 DataPath State,不要混淆10h / 0x80[n−1]
⚠ Apply 会重启哪些数据通道。点击 Apply 时,工具整体下发 AppSelect、TX Enable 和两个极性掩码, 然后只对暂存配置有改动的数据通路写 ApplyDPInit,模块据此重启这几条数据通路——在线业务会中断。 只改了极性或 TX Enable 时不触发 Apply(这两项写下去就生效,Table 8-77),不重启任何数据通路; 什么都没改就点 Apply,则视为「重新投运」,重启全部数据通路。 Apply 没有确认对话框。若正在跑业务,请先确认可以断流。
  1. 点击 ↻ Refresh 读取当前配置。
  2. 参考 9.2 Supported Applications 表选择合适的 AppSelect。 下拉框第一项是「— unused (AppSel 0) —」,表示这条 lane 不参与任何数据通道。
  3. 勾选 / 取消 TX Enable、Pol Flip。
  4. 点击 Apply 写入模块;暂存配置有改动的数据通路会触发 ApplyDPInit(只改极性或 TX Enable 时不触发)。
  5. 配置结果工具会自动告诉你,不需要自己去 Monitoring 页查。Apply 后工具等 300 ms 重读配置,再检查每条 lane 的 Config Status:全部通过则右下角弹绿色 「DataPath configuration applied」;只要有 lane 被拒,就弹红色提示并点名是哪几条 并按理由分组写清原因和该改什么(形如 L5, L6, L7, L8: 该 AppSel 码不在本模块声明的应用里 —— 从模块自己公布的列表里选),停留 12 秒。 规范规定同一条 DataPath 的所有 lane 报同一个结果,所以按理由分组比逐条列 lane 更贴近模块真正说的话。
  6. 遇到拒绝:模块跳过了执行步骤,该 lane 继续跑原来的 Application。提示里已经写明是哪一类原因; 对照 9.2 的 Host Lane Assign 位图与应用宽度改好之后再 Apply。
ℹ 不可调模块上,这一页的写入会被拒绝。 模块是否可调看 01h:155[6],它同时决定了 Page 04h / 12h 到底存不存在。旧版本不看这一位, 在不可调模块上依然往 Page 12h 写——写进一个 模块根本没实现的页,回读全是 0, 而界面会告诉你“已调谐”。界面上本来就 不会展示这张卡片,所以这主要影响 直接调接口的场景(写脚本、或让 Claude Code 驱动工具)。

Supervision —— 这条 lane 按哪套告警阈值判

Laser Tuning 表新增一列 Supervision。CMIS 5.4 的 7.5.3 允许把一条媒体 lane 的 Tx 功率告警阈值改成 相对于它自己的目标发射功率, 而不是用 Page 02h 那套全模块共用的绝对值。

显示含义Page / Addr
Relative该 lane 已启用相对阈值: 告警窗口 = 目标功率 ± 偏移量。 重新调功率,告警线自己跟着走, 不需要主机再算一遍 12h / 0x80[1]
Absolute该 lane 仍用 Page 02h 全模块共用的绝对阈值 12h / 0x80[1] = 0
n/a模块根本没广播 这项能力04h / 0xC4[6]
ℹ 偏移量在 12h:216-217,不分 lane—— 规范认为“多大的监控窗口才有意义” 是光模块的属性,不是某一条 lane 的属性; 但启用与否是逐 lane 的。所以同一个模块里 两条 lane 可能按两套规则告警,实时监控表的 着色也会相应不同——鼠标悬停在两边都会 写明用的是哪一套。
两个偏移量都是以半个 dB 为步进的 U4, 最小窗口是 ±0.5 dB(不是 0)。
⚠ 已修:改 Grid 会把这个开关关掉。 12h:128-135 这个字节里不只有 Grid, bit 1 正是上面那个启用位。旧版本写 Grid 时 把整个字节重拼了一遍,于是“改一下栅格” 会把该 lane 静静地换回绝对阈值,告警线跟着变。 现在写入会先读回原字节,只改自己那几位。

Apply 和 Apply Immediate —— 两个触发器,不同代价

规范 8.13.3.1 定义了两个生效触发器, 以前工具只有第一个:

按钮写哪里后果
Apply10h:143 ApplyDPInit 数据通道重走一遍 DPInit → TxTurnOn → Activated, 业务会断,且会留下 DP Changed 标志
Apply Immediate10h:144 ApplyImmediate 同样把暂存配置提交到硬件, 但数据通道不离开当前状态(一直是 Activated), 因此不会留下 DP Changed 标志
⚠ 不是每个模块都支持 Apply Immediate。 规范写明:不支持时模块直接忽略 对 10h:144 的写入——不报错、也没任何反应。 所以工具先读 Lower 02h(Module Info 页的 Reconfiguration 行),不支持就把按钮置灰并在 悬停提示里说明原因。按规范,以太网 光模块普遍只支持分步重配置;可调相干 模块这类需要在线调整的场景才用得上 hot 重配置。

Squelch Method —— 这一项未必轮得到主机选

01h:155[5:4](Table 8-51)说的是谁来决定 Tx 输出怎么静音:00b 不支持静音; 01b 模块靠降 OMA 静音;10b 模块靠 降 Pav 静音;只有 11b 才是“主机选”。 主机用来选的位是 Lower 0x1A[5]。

⚠ 模块自己定了方法时,那个位不算数。 旧版本把 0x1A[5] 直接当作“当前方法”显示, 于是在一个声明“我降 OMA”的模块上, 只要那个位被置上,面板就显示 Pav—— 恰好和模块实际做的相反。现在面板显示的是 实际生效的方法,并在模块定方法时标注 “fixed by the module”;接口也不再接受这个写入, 而是告诉你模块定的是哪一种。

Bank Broadcast —— 开了之后“写一个 Bank”就不存在了

Lower 0x1A[7] BankBroadcastEnable(Table 8-11,广告位 01h:156[7])。置 1 之后,向任何一个 Bank 的控制寄存器写入,都会被模块 当作对所有 Bank 的同时写入执行。

⚠ 这会把逐 Bank 不同的配置静静拍平。 多 Bank 模块上,工具本来是按 Bank 分别写入 不同的掩码字节的;开了广播之后, 每一次写都落到全部 Bank,最后一个 Bank 的值会盖掉前面全部。例子:在 24 通道 模块上请求关掉 lane 1 / 10 / 19,开广播后实际 关掉的是 lane 3 / 11 / 19——而接口还回了成功。
现在遇到这种情况工具会直接拒绝并 告诉你是哪一项逐 Bank 不一致,而不是写下去 再报成功;原来的配置不会被动。 这项检查覆盖每一个按 Bank 写入的地方:DataPath、Squelch、 媒体通道切换、Loopback、PRBS、激光调谐(Page 12h) 和采集计数器清零(Page 60h)。 所有 Bank 取同一个值时照常写入(那本来 就是广播能表达的)。
ℹ 这个位在所有模块上都是可读写的, 但只有广告了才真的生效;未广告的 模块上写它只会让界面看起来“开了”。 因此工具对未广告的模块拒绝这个写入。 内置模拟模块里只有 mock_24lane(3 个 Bank) 广告它——单 Bank 模块根本无处可广播。

9.4 Output Controls(输出控制)

控制项含义Page / Addr
AutoSquelchDisableTx勾选 = 禁用 Tx 自动 Squelch 控制器10h / 0x83
OutputSquelchForceTx勾选 = 强制 Tx 输出 Squelch10h / 0x84
OutputDisableRx勾选 = 禁用 Rx 输出10h / 0x8A
AutoSquelchDisableRx勾选 = 禁用 Rx 自动 Squelch 控制器10h / 0x8B

10. Diagnostics — 诊断工具

ℹ v2.0.3 起切换到本标签页会一次性加载全部卡片(Loopback、PRBS、BER、Counters、 SNR、Laser Tuning,以及模块支持时的 Acquisition Counters,见 12.2)。此前只有前两张会自动加载,其余需手动点各自的 ↻, 容易出现"半页是实时数据、半页是空的或复位前的旧值"。各卡片的 ↻ 按钮仍可单独刷新。

10.1 Loopback(环回)

模式说明Page / Addr
MediaSide Output媒体侧输出环回13h / 0xB4
MediaSide Input媒体侧输入环回13h / 0xB5
HostSide Output主机侧输出环回13h / 0xB6
HostSide Input主机侧输入环回13h / 0xB7
⚠ 开启环回会影响正常业务。测试完毕后请全部取消勾选并 Apply 恢复。

媒体侧的两行环回的是媒体通道(Figure 8-2)。模块在 00h:210 里声明没有的媒体通道,对应格子置灰;模块不支持逐通道环回时则不置灰——那时任何一个格子都代表全部通道。

10.2 PRBS Generator(PRBS 发生器)

每个 PRBS 块为 8 字节:Enable(使能位图)/ Invert(数据反转位图)/ ByteSwap(PAM4 MSB/LSB 交换位图)/ PreFEC(FEC 编码前注入)/ Pattern×4(4 字节, 4 bits/lane)。Apply 时按规范附录 F 的顺序写入:先写后 7 个字节(反转、交换、FEC、码型),最后单独写 Enable——多字节写入不保证原子,使能在前可能让引擎按旧码型启动。

分区EnInvertByteSwapPreFECPatternLOL 地址
Host-Side Generator13h/0x900x910x920x930x94–0x9714h/0x88
Media-Side Generator13h/0x980x990x9A0x9B0x9C–0x9F14h/0x89

发生器表的 LOL 列是 PatternGeneratorLOLFlag(Table 8-138):发生器没能产生有效码型。 它和检测器的 LOL 是两个不同的标志,各在自己的卡片上;符号含义见 10.3 的表。

支持码型:PRBS7 / PRBS9 / PRBS13 / PRBS15 / PRBS23 / PRBS31 及其 Q 变体、SSPRQ, 以及 Custom(厂商自定义)和 User Pattern(主机自定义,见上文 13h:224–255)——下拉框里出现哪些,完全按模块自己声明的来。

每个分区标题下会写明该引擎的时钟来源(13h:176 / 13h:178):内部时钟、参考时钟,或从业务里恢复的时钟。 这决定了顶部「参考时钟丢失」那行字对这一页是不是坏消息。

PreFEC 这一列由 13h:131 决定:模块只在 FEC 的一侧有发生器时, 它会按实际位置勾好并置灰;两侧都没有,则整张表换成一行说明—— 那个引擎不在这个模块里(见上文 13h:131)。

10.3 PRBS Checker(PRBS 检测器)

分区EnInvertByteSwapPostFECPatternLOL 地址
Host-Side Checker13h/0xA00xA10xA20xA30xA4–0xA714h/0x8A
Media-Side Checker13h/0xA80xA90xAA0xAB0xAC–0xAF14h/0x8B

PostFEC 这一列同样由 13h:131 决定, 规则与 10.2 的 PreFEC 一致。

多 Bank 模块上若 13h:177.7(StartStopIsGlobal)生效,卡片顶部会提示:在一个 Bank 里启用或停用检测器,等于在每个 Bank 的同一位置都这样做(Table 8-127)。

LOL 列(发生器和检测器两张卡片都有)的每一格是下面几种之一。这些标志都是闩锁、读后清除的(Table 8-138),所以工具把读到过的记下来:

显示含义
●引擎在运行,本次读取标志未置位
LOL本次读取标志置位:检测器失锁 / 发生器没能产生有效码型
●!现在正常,但自上次清除标志历史以来出过一次——长时间跑码型时,中途短暂失锁正是要找的东西
–该通道的引擎没有运行,没有锁定可言
n/a模块没有这条媒体通道(00h:210),这一位不代表任何东西
masked跟在 LOL 或 ●! 后面:Page 13h 上对应的 Mask 置位(Table 8-133,出厂默认全部置位):标志照常置位,但不会触发 Interrupt
gate done仅检测器:该通道的一次门控测量已结束(14h:134 / 14h:135),结果在 BER 和计数器表的 · last gate 行

媒体侧发生器和检测器按媒体通道运行。模块没有的媒体通道(00h:210),整行置灰,LOL 列显示 n/a。

ℹ Checker 卡片没有自己的 Apply 按钮——不要在这张卡上找。改完 Checker 的设置后, 点 PRBS Generator 卡片上的 Apply,Generator 与 Checker 四个分区 (Host/Media × 发生器/检测器)会一次性一起下发。反过来也一样: 只改了 Generator 点 Apply,Checker 当前界面上的设置同样会被写进模块。

10.3b 哪些诊断结果模块真的会报

13h:130(Table 8-113,只读、必需)逐位 声明哪些 DiagnosticsSelector 取值是有意义的:

位含义影响哪张卡片
bit 0支持 Selector 01h(误码率结果)BER Results
bit 1支持 Selector 02h–05h(误码/比特计数)Error / Bit Counters
bit 4支持主机侧输入 SNR 测量(Selector 06h)SNR Results 的 Host 行
bit 5支持媒体侧输入 SNR 测量(Selector 06h)SNR Results 的 Media 行
bit 6 / 7主机侧 / 媒体侧 FEC(可提供 PRBS 错误信息)—
⚠ 不支持的 Selector 也能读出数字。 模块即使不实现某个 Selector,对 Page 14h 结果窗口的读依然会返回内容——那些数字 看起来就像测量值,但不是。 旧版本不看这个字节,三张卡片对任何模块 都直接显示数值。现在不支持时卡片会写明 “本模块不上报此项”并标出具体位, 而不是留一行空白(空白会被看成零); 工具也不再写入那个 Selector。
声明了支持、写进去却没被接受的,工具也看得出来:写完会读回 14h:128——规范 Table 8-136 规定不支持的值「退回 0」,而 Selector 00h 选的是全零,不读回的话会被当成 BER 0、计数 0、SNR 0 dB。没接受的 Bank,表格下方会写明,那些通道显示 — 而不是 0。
两侧 SNR 是分开广告的,所以可能只有一边有值。 内置模拟模块里 mock_sr8 声明不做 SNR 测量(只有 BER 和计数),可用来看这个差别。

10.4 BER Results(误码率)

向 14h/0x80 写入 Selector = 0x01 选择 BER F16 诊断。Host BER 在 14h/0xC0,Media BER 在 14h/0xD0,每通道 2 字节。

F16 解码公式(CMIS 5.4 十进制浮点):BER = mantissa × 10^(exp − 24),其中 bits[15:11]=exp, bits[10:0]=mantissa。

这个 BER 是 PRBS 检测器数出来的。规范 8.17 说明这些误码与 BER 监测基于码型发生器和检测器的侵入式测量, 用于停业务测试;不是业务流量上的 FEC 估计。所以:

  • 检测器没在运行的通道显示 off;运行过又停下的,显示它停下时保留的结果并标 held(门控测量下再加「undefined if stopped mid-gate」:规范附录 F.2,门控中途停下的计数未定义) (Table 8-128–8-130:启用检测器即清零并开始计数,停用即停止并保留)。一个检测器都没开时,表格下方会说明。
  • 模块声明支持门控结果(13h:129.5)时,另有两行 · last gate,读的是 Selector 11h—— 上一个完整门控周期的结果,在下一个周期结束前不变。
  • 支持 NA 值的模块报告 0.5 表示没有有效样本,显示 no valid sample,不是「每两位错一位」。
信号质量典型 pre-FEC BER
接近底噪(优良)< 1e-9 ~ 1e-8
正常工作1e-8 ~ 1e-4
边缘1e-4 ~ 1e-3
劣化> 1e-3
⚠ 表格里显示 0 的含义是"模块报告零错误计数",不是测到的 BER 下限。 上表没有 0 这一档是有意的:真实的可达下限取决于该次统计门累积了多少比特, 模块并不告诉你这个数。请不要把 0 当作实测值写进测试报告—— 需要给出量化结果时,应根据码率与统计时长自行算出置信下限。 鼠标悬停在 0 上也有同样的说明。显示 — 表示该 lane 没有有效读数。
模块同时报告误码计数(13h:130.1)时,工具会对照同一窗口的计数:TotalBitsCount 为 0 的通道——还没结束过门控的 · last gate、刚启用的检测器——BER 显示 —,因为一个比特都没数过,这个 0 不是测量结果。反过来,检测器停下时数过比特、零误码的通道显示 0 held,不再显示成 off。

10.5 SNR Results(信噪比)

向 14h/0x80 写入 Selector = 0x06 选择 SNR 诊断。Host SNR 在 14h/0xD0,Media SNR 在 14h/0xF0,每通道 2 字节小端 u16,单位 1/256 dB。

典型 400G/800G 链路 SNR 范围:PAM4 DSP 输出约 15–22 dB,越高越好。低于 13 dB 通常意味着链路劣化。

ℹ SNR 不需要 PRBS,它是接收端对当前输入信号的实时测量(Table 8-139:real time status)。 BER 和误码计数需要:它们来自 PRBS 检测器,检测器不运行就没有数(见 10.4)。 早先这里写的是「BER / SNR 读取无需 PRBS 使能」,对 BER 不成立。

10.6 Error / Bit Counters(误码/比特计数器)

使用 Page 14h Diagnostic Selectors 0x02–0x05 读取每通道累计的 Error Count 和 Total Bits Count(U64 小端序)。

Selector说明
0x02Host 侧 Lane 1–4 Error + Total Bits 计数
0x03Host 侧 Lane 5–8 计数
0x04Media 侧 Lane 1–4 计数
0x05Media 侧 Lane 5–8 计数

每通道 16 字节(8 字节 ErrorCount + 8 字节 TotalBitsCount)。TotalBitsCount 最低位为 PSL(Pattern Sync Loss)指示位:0=同步正常,1=曾经失锁。

GUI 同时计算并显示 BER(calc) = ErrorCount / TotalBitsCount 方便直读。

和 10.4 一样,计数来自 PRBS 检测器:没在运行的通道显示 off,停下的显示保留的计数并标 held; 模块声明支持门控结果时,下方另有六行 · last gate(Selector 12h–15h)。 ErrorCount 为 U64 最大值是 NA 值(Table 7-8),显示 no valid sample, 基于它的 BER(calc) 显示 no valid error count。

⚠ v2.0.3 起显示失锁提示:某 lane 的 PSL 位为 1 时,该列会置灰、BER 显示为红色 no sync,表格下方给出整体提示。失锁期间计数器仍在累加,但那些数字不是有效的 BER 测量结果,不可写入测试报告。此前版本把失锁数据和正常数据渲染得完全一样。

10.7 Laser Tuning(激光调谐)— 仅限可调谐模块

非可调谐模块(01h:155.6 为 0)上这张卡片只显示一行说明,Apply 是灰的,悬停写明原因。

换栅格或信道前,先在 DataPath 页用 DP Deinit 把承载该通道的 Data Path 停下(规范 7.5.2);运行中这两个输入框是锁定的。微调偏移和目标功率随时可改,只要 Data Path 不在过渡状态。模块没有声明微调能力(04h:129[7])时,微调偏移框是灰的——那是模块没有的控件。

ℹ CMIS 5.4 新增两项,模块广告支持时才出现:
· 300 GHz 栅格(栅格码 1001b,广告位 04h:129[5], 通道范围 04h:166–169)——栅格下拉里会多出一档 300 GHz, 带自己的通道范围提示,写超范围的通道号也会被拦下。
范围表本来只读到栅格码 8(04h:130–165), 而下拉、范围提示、写入校验全部以它为准; 于是 300 GHz 虽然列在上方的能力行里,却选不中、也不受校验。 现在模块广告了就多读那四个字节,不广告就不读—— 那几个字节在 5.3 模块上不保证有意义。
· 相对光功率监督门限(广告位 04h:196[6],门限 12h:216–217)—— 门限以相对标称发射功率的偏移给出,而非绝对值,且对所有通道共用一组。 高门限 = 标称 + (1+offset)×0.5 dB,低门限 = 标称 − (1+offset)×0.5 dB。 每条通道单独用 12h:128–135 的 bit1 使能;一旦某通道启用,Page 02h 的 模块级绝对功率门限对它不再适用,不要再拿 Module Thresholds 卡片的值去判断该通道。

表格的 Status 列依次判断:调谐中显示 Tuning...;数据通道处于 DPDeactivated / DPDeinit 时显示 n/a——Table 6-21 规定模块在这两个状态下不报告波长失锁,激光器也不一定开着;否则显示 Locked / Unlocked。Tuning Flags 列在没有标志时显示 —,TuningComplete 置位时显示 Tuned。在停下的数据通道上换栅格或信道,Tuned 要等数据通道重新起来才出现:TuningCompleteFlag 在 DPDeactivated、DPInit、DPDeinit 下是 N/A(Table 6-21),模块不得置位。

适用于声明发射端可调谐(01h:155.6 = 1)的模块,典型是 C-band / L-band 可调谐激光器(Media Interface Technology = 0x10/0x11,但工具不按它判断)。演示模块里是 mock_coherent_zr 和 mock_zr16。Apply 前每个输入框都要是数字:信道号是整数,目标功率不能留空(以前空框按 0 dBm 发出去),微调偏移留空表示不微调;有一格不是数字就整张表都不写,提示指出是哪条通道的哪一格。

Page 04h(只读能力广告):支持的 Grid 列表、通道范围、Fine Tuning 分辨率/范围、可编程输出功率范围。

Page 12h(读写控制):

字段Access说明Page / Addr
Grid SpacingRWbits 7–4 Grid 选择;bit 1 相对功率门限使能;bit 0 Fine Tuning 使能12h / 0x80+lane
Channel NumberRWS16 通道偏移 n,频率 = 193.1 + n × step (THz)12h / 0x88+lane×2
Fine OffsetRWS16,单位 0.001 GHz (1 MHz)12h / 0x98+lane×2
Current FrequencyROU32,单位 0.001 GHz → THz = val / 10^612h / 0xA8+lane×4
Target PowerRWS16,单位 0.01 dBm12h / 0xC8+lane×2
Tuning StatusRObit 1=TuningInProgress, bit 0=WavelengthUnlocked12h / 0xDE+lane
Tuning FlagsRO/CORbit 5 目标功率超范围、bit 4 微调超范围、bit 3 调谐未被接受、bit 2 通道号无效、bit 1 波长失锁、bit 0 TuningComplete;闩锁、读后清除12h / 0xE7+lane
⚠ 修改 Grid / Channel 需要 DataPath 处于 Deactivated 状态。Fine Tuning 和 Target Power 可在非瞬态状态下修改。

10.7a 本版规范审查修复与 Mock 诊断范围

Apply 后仅在完整 Data Path 的所有相关通道明确返回 ConfigSuccess 时才释放 DP Deinit。尚在处理、未定义或拒绝的结果都会保持停用,并提示刷新 ConfigStatus。等待上限是工具策略,不是 CMIS 定义的 Provision 超时。

每次成功读到的 COR 告警字节都会立即保存在本次连接的历史中,即使随后读取 Mask、状态或下一分块失败。错误信息仍需处理,恢复刷新后可查看之前已采集的事件;清除历史会同时清除原始事件记录。

能力发现读取失败会拒绝连接,未知能力不授权控制;高于 CMIS 5 的主版本也会被拒绝。普通控制与 Raw Registers 的 SoftwareReset 使用相同的 MgmtInit 重试窗口,清除 Bank/Page 缓存;下次访问重新读取能力。发现模块自主重启后也会重新发现能力。

Mock 诊断为合成的管理演示数据。页面说明当前 Checker 测量位置和测试比特流速率;解码前/后使用独立夹具,不运行 FEC 解码算法。线路侧 1.6T DR8 每 lane 为 212.5 Gb/s,LR1 单媒体 carrier 约 989.091 Gb/s;解码后的计数依所声明的测试比特流而定。五秒门控统计完整五秒,结果不随刷新频率变化;自动重启保留最近结束周期,冻结时明确显示 ResetErrorInformation。

ZR profile 的应用为 800GAUI-8 → 800ZR-A/B(OIF-800ZR-01.0、DP-16QAM),默认 150 GHz / 193.175 THz,发射默认 -8 dBm。额外栅格、通道和监督阈值用于管理测试,不能据此宣称相应设置的光学合规。16 lane profile 为 16×100G / 两个独立 800G 应用,不广告 1.6TAUI-16。

LR1 波长广告为 1311.0 ± 0.110 nm;dj DR8 为 1311.0 ± 6.5 nm;SR8 演示广告为 850 ± 6 nm。可调单波长广告随实际名义频率更新。dj 参数依据仍为 D3.1 草案,LR1 光功率监督选用 ETCC ≤ 1 dB 的条件;工具未验证 BLER/直方图方法、D3.3 全文差异或实物 PHY 合规。

10.8 状态机模拟(Mock 模式特性)

Mock 后端完整模拟了 CMIS 状态机行为,方便无硬件演示:

操作响应行为
Software ResetModuleState: Ready → LowPwr (0.3s) → PwrUp (0.5s) → Ready (0.8s),所有 DataPath 经历 Deactivated → Activated;Host Scratchpad(13h:184–191)与 ModuleFaultCause(Lower 41)清零;ModuleStateChangedFlag 只在进入 ModuleReady 时置位(Table 6-9)
Enter LowPwrModuleState → LowPwr,所有 DataPath → Deactivated,TxPower = 0
Exit LowPwrModuleState → Ready;未被 DPDeinit 按住的 DataPath → Activated,被按住的保持 Deactivated
TX Disable该通道 TxPower 降为 0;运行中的整条数据通路经 TxTurnOff 退到 Initialized(Eq. 6-12),重新使能后经 TxTurnOn 回到 Activated;不置 Tx Failure 标志
Apply DataPathConfig Status 先变为 ConfigInProgress,DP State 经历 Init → TxTurnOn → Activated(约 0.5s);暂存的 DPIDX 必须指向该通道所在数据通路,否则 ConfigRejectedInvalidDataPath
PRBS Checker Enable该通道的误码计数清零并开始累积(关闭时停止并保留结果);锁定前在该通道置 LOL,闩锁到被读取为止
13h:177.7 置 1检测器使能和 ResetErrorInformation 的改动带到所有 Bank(门控 + 全局定时器时不带)
DiagnosticsSelector写入 14h:128 的值若不在 13h:129–130 声明支持的范围内(含保留值、厂商自定义值),退回 00h,结果窗口全零(Table 8-136)
Laser Tune被接受的请求:Current Frequency 更新;数据通道在运行时立即置 TuningComplete,在停下的数据通道上(换栅格/信道只能在这时)等它回到 DPInitialized 才置位(Table 6-21)。超出范围或未声明的栅格:置 InvalidChannelNumber / TuningNotAccepted 等标志,频率不变

11. Raw Registers — 寄存器直读写

11.1 读取寄存器

  1. 填写 Page(如 0x00、0x11,也可写规范的 11h;不带前后缀的按十进制)
  2. 填写 Address(起始地址,如 0x80 或 80h;只写 80 是十进制 80 = 0x50)
  3. 填写 Length(读取字节数,1–128)
  4. 点击 Read

结果以十六进制 Dump 格式显示:

0x80: A1 B2 C3 D4 E5 F6 01 02  ........
0x88: 03 04 05 06 07 08 09 0A  ........

格式:地址: 十六进制字节  ASCII(不可打印字符显示为 .)

Dump 上方第一行写明这些字节来自哪里:Lower Memory(地址 < 0x80,不分页,与 Page 字段无关)、Page 0x11,或分 Bank 的页上的 Page 0x11 Bank 1 · lanes 9-16。CDB 页(9Fh、A0h–AFh)上的 Bank 是 CDB 实例,写作 Page 0x9F Bank 0 · CDB instance 1,可选的 Bank 数是模块的 CDB 实例数(01h:163.7-6)。

ℹ 跨过 0x7F 的读取会分成两次读。规范 B.1.2 规定字节地址在自己那块 128 字节里回绕:Lower Memory 读到 127 之后回到 0,不会接着读进上页。 一次读完的话,显示在 0x80 之后的其实是 Lower 0x00 起的内容。 所以工具先选好 Page(和 Bank),读 Lower Memory 到 0x7F,再从 0x80 读所填的页,标题写成 Lower Memory, then Page 0x11 from 0x80。 因为页是先选好的,Dump 里 0x7E / 0x7F(Bank / Page 选择)显示的就是下面那一页。读之前那条 This read clears what it returns 提醒(读到会被读清的标志字节时弹出)两半都会检查。

11.2 写入寄存器

  1. 填写 Page 和 Address
  2. 在 Write Data 输入框填入字节(十六进制,空格或逗号分隔,如 1E 50 00;每个字节也可写成 0x1E 或 1Eh)
  3. 点击 Write
ℹ 地址 ≥ 0x80 为上页寄存器,工具自动切页;地址 < 0x80 为下页,忽略 Page 字段(读取跨过 0x7F 时,0x80 起的部分按 Page 字段读,见 11.1)。
⚠ 本页对写入不设任何护栏,这是有意的。其它标签页只暴露安全的操作,这里能写模块的任意字节—— 它存在的理由正是让你做界面没有提供的事。代价是:在跑着业务的模块上,一次误写就可能断流。
几个后果最直接的地址见下表(工具不会拦,模块会照做)。
地址写下去会发生什么
Lower 0x1A bit 3软复位——模块重启,所有数据通道重新初始化,链路中断数秒
10h:0x8F = FFApplyDataPathInit——按当前暂存配置重新初始化数据通道,相应通道断流
10h:0x82关闭对应通道的发送端,该通道立即无光
Lower 0x7E / 0x7F直接改动 Bank / Page 选择。工具会察觉并作废自己的缓存, 所以后续读取仍然正确;但如果你在中途改页,紧接着的那次读取读到的是你选的页,不是你以为的页
ℹ 会被拒绝的只是格式和规范上的问题,写什么值本身不会被拦(完整列表见下文「在写出去之前就被拒绝」):跨页越界(起始地址 + 长度超过 0xFF);越过 0x7F 的写入(规范 B.1.2:Lower Memory 的地址到 127 回到 0,后面的字节落在 Lower 0x00 起,而不是页里);把 Apply 触发字节(10h:143/144、10h:176–179、10h:211/212、16h:176/177)夹在多字节写入里(规范要求这些字节单字节 WRITE);密码寄存器 Lower 118–125 上不是「整 4 字节、只写一个区」的写入(规范 8.2.14,见下);Page 9Fh 上超过 8 字节、包含字节 129 的写入(见下);以及格式错误——缺页号或地址、数值不是整数或不在字节范围内、Bank 不对。 只读与保留字节可以写,但模块会忽略或钳位——那时出现红色回读提示是正常的(见上一节)。

超过 8 字节的写入会分几次完成

规范 5.2.2.2 规定一次 WRITE 最多 8 字节,所以更长的写入会拆成若干次、每次最多 8 字节,结果区会写明 as N WRITEs of up to 8 bytes each (5.2.2.2)。这样写入的一段寄存器不是一次整体写入的(规范 5.2.5.2)。Page 9Fh 例外:写到 9Fh:129 就会发出 CDB 命令(规范 7.2.3),所以超过 8 字节又包含 129 的写入不会替你拆,而是提示你先写其余部分、最后写含 129 的那段。

写完之后工具会回读比对——看懂那条红色提示

写操作返回成功只代表 I2C 传输完成,不代表模块真的接受了这个值。所以工具写完会立刻 把同样长度的字节读回来,与你写入的逐字节比较,并把读回的内容显示在下方 hex 转储区:

提示含义
绿色 Written and verified …(3 秒) 读回值与写入值完全一致
红色 Write completed but the module reports different values(8 秒) 这不是工具故障。传输成功了,但模块把值改掉或忽略了—— 最常见的原因是写到了只读或保留字节,其次是模块把超范围的值钳位到了合法区间。 写只读寄存器时出现这条提示是正常现象
绿色 Written N write-only byte(s) - these do not read back 写的全是只写字节(Apply 触发、密码区等,规范 Table 8-3 的 WO / WO/SC):它们读回来是 0 或任意值, 不参与比对,转储区会列出 write-only (…), not compared。部分字节只写时,绿色提示注明有几个没比对。 以前这些字节也被拿来比,每次写密码或 Apply 触发都会误报红色
绿色 / 红色 Password: … 写的是密码寄存器时,结果来自 Lower 42(PasswordCmdResult,Table 8-17),转储区也写明 password result (Lower 42): …。被接受(host / module password)为绿色,password entry not accepted 为红色。模块没声明支持这个结果寄存器(01h:251.3-2)时写明「not reported」

以下情况会在写出去之前就被拒绝,此时模块没有收到任何字节:

  • 十六进制无效:Write Data 里任何一项不是十六进制字节(如 CX),提示 Invalid hex data 并列出是哪几项,一个字节都不写。以前只在一项都读不出时才拒绝:AA CX DD 会写成 AA 0C DD,12,34 只写 12
  • 页号、地址、长度、Bank 写不成数字:提示 Not a number 并指出是哪一格。以前 10h 会被读成十进制 10(即 0x0A 页),0x1G 读成 1,空的 Length 按 1
  • 数值不合法:数据字节不在 00h–FFh(例如 1FF),提示 Data bytes are 00h-FFh——以前会截成低 8 位照写;页号、地址、Bank 不是整数,或页号、地址超出 0x00–0xFF。直接调用接口时还必须写明页号和地址(A write names its page and address),界面总会带上
  • 越过页尾:起始地址加字节数超过 0x100,提示 Write would cross end of page
  • 越过 0x7F 的写:规范 B.1.2 规定 Lower Memory 的字节地址到 127 之后回到 0,所以写过 0x7F 的字节 不会进入上页,而是落在 Lower 0x00 起;途中写到的 0x7F 还会改掉页选择。从 0x7F 开始写两个字节也一样。 工具直接拒绝,提示 would run past 0x7F,要求你拆成两次写
  • 密码寄存器没按整 4 字节写:Lower 118–121(新的 host 密码)和 122–125(输入密码) 规范 8.2.14 要求「必须用大小匹配的 4 字节 WRITE 写入」。从 118 一次写 8 字节、只写 2 字节、或从 120 开始写, 都提示 size-matched four-byte WRITE。上一次密码还在校验中(Lower 42 显示 in progress) 时,工具最多等 tWRITE(10 ms),仍未出结果就拒绝这次密码写入(409),因为规范要求主机在结果出来之前不要使用密码寄存器
  • 夹带 Apply 触发字节的多字节写:10h:143/144、10h:176–179、10h:211/212、16h:176/177 这些 Apply 触发字节,规范(Rev 5.0 起)规定「必须用单字节 WRITE 写入」。一次多字节写入里包含其中任何一个,就提示 must be written in a single-byte WRITE,要求你把它单独写
  • Page 9Fh 上超过 8 字节、包含字节 129 的写:写到 9Fh:129 就会发出 CDB 命令(见下「发 CDB 命令」),拆成多次写会让命令在其余字节写完之前发出
  • Bank 不对:在 Lower Memory 或不分 Bank 的页上指定了 Bank,或 Bank 超出模块声明的数量(01h:142.1-0;CDB 页按 01h:163.7-6 的实例数)

发 CDB 命令

CDB 触发格式按能力广告检查。CdbCommandTriggerMethod=0 时必须先写参数,再以结束于 9Fh:129 的一/二字节 WRITE 写 CMDID。方法 1 才允许不超过 8 字节、包含 129 的多字节 WRITE;不符合广告的方法会在写入前拒绝。

写到 9Fh:129 就会发出 CDB 命令(规范 7.2.3)。之后模块可能拒绝一切访问:前台模式直到命令执行完,后台模式在接收命令期间(规范 Table 10-4)。工具这时会按模块声明的时间继续重试,回读因此可能要等一会儿;结果区写明CDB command sent (9Fh:129)、处理模式和最长等待时间。命令结果在 Lower 37(实例 1)/38(实例 2),完成时 Module Info 的 CDB Command Complete 会亮。

写密码

规范 8.2.14 的密码是 32 位大端数。0000 0000h–7FFF FFFFh 是 host 密码(出厂默认 0000 1011h,主机可改), 8000 0000h 以上是 module 密码(厂商定义,主机不能改)。在 Raw Registers 里:

  • 输入密码:Page 任意(Lower Memory),Address 0x7A,Data 如 00 00 10 11
  • 修改 host 密码:先输入正确的当前 host 密码,再在 Address 0x76 写新密码的 4 个字节
  • 写入后结果区显示 Lower 42 的结果。输入错误的密码会重新锁上;模块复位后也回到锁定状态

演示模块按这些规则工作(module 密码为 8BAD F00D);2× 400GBASE-FR4 演示模块(mock_fr4x2)声明不支持密码输入,写了也没有结果。

✕ 警告:直接写寄存器可能影响模块正常工作,请在熟悉 CMIS 规范的前提下操作。 本页的写入没有确认对话框,点 Write 立即执行。

13. 常见问题排查

Q1双击 EXE 后控制台窗口一闪而过
原因:程序启动异常。端口被占用已不再是原因—— 被别的程序占用时会换一个临时端口启动并弹窗让你选端口(见第 4 章「本机端口」), 被本工具自己占用时会直接打开已在运行的那一个。
解决:从命令行(cmd)里运行 EXE,窗口就不会关闭, 最后几行会写明失败原因。
不要试图用"以管理员身份运行"解决:监听 127.0.0.1 上的端口本来就不需要管理员权限。
Q2浏览器显示"无法访问此网站"
原因:控制台窗口已被关闭,服务器停止运行。
解决:重新双击 EXE 启动,保持控制台窗口开启。
Q3Backend 下拉菜单里 ch341 / ch347 / ftdi 等适配器是灰的,后面写着 (unavailable)
下拉菜单总是列出全部后端:12 种 mock_* 演示模块,以及 ch341、ch347、ftdi、ftd2xx、cp2112、mcp2221 六种 USB 适配器。工具找不到某种适配器(或它需要的驱动 / DLL)时,那一项置灰并标 (unavailable),不能选。可能原因及对应解决方法:
  • USB 适配器未插入 → 插入适配器后点击 ↻ Refresh Backends 重新扫描。
  • 驱动未安装 → 参考第 3 节《USB 驱动安装指南》,安装对应型号的 WCH 驱动后再刷新。
  • 驱动已安装但仍不显示 → 打开设备管理器,检查适配器图标是否有黄色感叹号;如有,请重新运行驱动安装程序。尝试拔出适配器并重新插入,再点击 ↻ Refresh Backends。
  • CH347 特有问题:设备管理器正常但工具显示 unavailable → 串口驱动(CH347SER.EXE)只让系统识别设备,但 I2C 通信需要 CH347DLL.dll,该文件可能未随驱动自动安装。从 WCH 官网下载 CH347EVT 开发资料包,找到 CH347DLL.dll,复制到 EXE 同目录,重启工具即可。详见第 3 节。
Q4点击 Connect 提示 "Connect failed"
原因:Backend / Bus / I2C 地址与实际设备不匹配,或模块未正确连接。
解决:确认 I2C 地址(光模块通常为 0x50)、Bus 编号正确;检查模块与适配器的物理连接。
Q5Monitoring 功率显示 −∞ dBm 或全为 0
原因:模块处于低功耗状态(发射关闭,Tx 功率读数为 0),或无光纤输入。0 µW 没有对应的 dBm 值,所以显示为 −∞ dBm,而不是某个很小的读数;模块声明支持 NA 值(0Ch:192.7)时,没有有效采样的通道会写明 no valid sample。
解决:检查 Module Info 中 Module State 是否为 ModuleReady;检查光纤连接。
Q6Mock 模式的数据是真实的吗?
不是。Mock 模式返回按 CMIS 5.4 规范构造的模拟数据(含动态波动和状态机响应),仅用于软件界面验证和培训演示,不反映真实模块状态。当前提供 12 种 profile:mock_coherent(800GBASE-LR1 数据中心 coherent lite)、mock_coherent_zr(800ZR-A/B 可调谐管理演示)、mock_dr8、mock_sr8、mock_fr4x2、1.6T DR8 与 16×100G / 2×800G 多 Bank 演示模块,mock_24lane(24 通道 / 三 Bank),mock_zr16(16 通道可调谐 / 两 Bank),mock_fewmon(只实现部分监控项),mock_aoc(400G 有源光缆,媒介不可分离)和 mock_flat_dac(Flat Memory 无源铜缆)。
Q7为什么 mock_dr8/sr8/fr4x2 等的 Laser Tuning 卡片显示 Non-tunable module?
原因:这些 profile 模拟的是固定波长激光器(EML / VCSEL),01h:155.6(TransmitterTunable,Table 8-51)为 0,所以没有 Page 04h / 12h 可读,Apply 也是灰的。
正常现象。演示模块里 mock_coherent_zr 和 16 通道的 mock_zr16 声明可调谐,可以用 Laser Tuning。真实模块同样以 01h:155.6 为准。
Q8mock_fr4x2 的 Host/Media Lanes 为什么显示 8 而不是 4?
2× 400G-FR4 模块通过 CMIS 广告两个独立的 400GBASE-FR4 应用(AppSel#1 占用 host 通道 1-4,AppSel#2 占用 host 通道 5-8),两个应用并发运行得到 800G 总容量。
GUI 会遍历所有 Application Descriptors 并计算最大并发通道数(非重叠应用相加)。Host Lanes 后括号中显示了每个 AppSel 的明细。
Q9Apply 之后偶尔报 read failed / write failed / NACK
原因:写入之后,模块在规范允许的时间内(一般 10 ms,Page 03h 为 80 ms,Table 10-4)可以暂时不应答。工具会在这段时间里自动重试,所以正常情况下不会看到这类报错。
仍然出现,说明模块超过了规范允许的时间还不应答,或者连线 / 适配器有问题:检查 I2C 连线与上拉、换一个适配器或降低速率再试;同一操作反复出现,记下操作步骤联系模块厂商。

12. CMIS 5.4 扩展功能

CMIS 5.4 新增的几个可选页不设单独标签页,按用途放进对应的功能标签, 卡片标题后带 5.4 徽标(与字段名后的标记同一个),5.4 新增内容一望可辨:

功能所在标签页寄存器页
CMIS 5.4 Optional Pages(广告与页映射)Module Info0Ch
Firmware Loads(各固件 Bank 的状态与版本)Module Info0Dh
Per-Lane Output Power ThresholdsMonitoring62h
Lane Polarity StatusDataPath Config60h
Media Lane SwitchingDataPath Config6Dh
Acquisition CountersDiagnostics61h

这些页是否存在由模块在 01h:173–174 / 01h:252[5] 广告决定——没有广告的页本工具不会去读: 未实现的页不保证返回有意义的内容,读了再渲染等于把总线上的残留值变成"每通道读数"。 没广告的页对应的卡片直接不出现;5.3 模块以及不实现这些页的 5.4 模块, Module Info 里的 CMIS 5.4 Optional Pages 卡片会明确写"没有广告任何可选页",这是正常的。

12.1 Lane Polarity Status(60h:128–129,DataPath Config 标签页)

模块当前实际生效的通道极性。它与 Module Info 里的 Default Polarity (01h:171–172)可以合法地不一致:后者只广告上电时的极性, 而支持可编程极性的模块把实时状态放在 60h。两处不同不是故障。

12.2 Acquisition Counters(61h:128–191,Diagnostics 标签页)

四类饱和计数器:通道 Tx/Rx、数据通道 Tx/Rx。统计的是数据通道投入使用后 接收侧重新锁定信号的次数,模块在 DPInit 时自动清零。

ℹ 这是本页最有诊断价值的一项:链路状态看起来一切正常、误码率也不高, 但该计数持续增长,说明接收端在反复失锁重锁——这种间歇性问题在瞬时读数里看不出来。

填入通道号(如 1,3,9)点复位所选通道计数即可清零,写的是 60h:192–193。模块没有的通道号(如 8 通道模块上的 9)或不是数字的一项会让整个复位被拒绝并说明原因,不会跳过它、只复位其余通道。

⚠ 只提供通道计数器的复位,不提供数据通道(DP)计数器的复位。 规范 Table 8-189 把媒体侧与主机侧 DP 复位寄存器都印成了字节 195, 因此 194 号究竟属于哪一个无法从文档判定。复位命令写错地址会清掉没人要求清的计数器, 所以本工具不猜——需要时请用 Raw Registers 自行确认后写入。

12.3 Per-Lane Output Power Thresholds(62h:128–191,Monitoring 标签页)

按媒体通道给出的绝对发射功率门限(S16,0.01 dBm),每通道一组四个值。 启用了相对门限(见 §10.7)的通道以这里的值为准, Page 02h 的模块级门限对它不再适用。

12.4 Media Lane Switching(6Dh:136–191,DataPath Config 标签页)

把内部媒体通道重定向到不同的外部通道。填入目标顺序(如 5,6,7,8,1,2,3,4 表示内部 1→外部 5、内部 5→外部 1,依此类推),先暂存,确认无误再提交。

  • 映射必须一对一:模块有的每条内部媒体通道各对应一条不同的外部通道 1–8,模块没有的内部通道(00h:210)填 0(7.9.3)。8 条内部通道都有时,这就是一个置换(按组校验,见下方说明)。 不符合的映射本工具直接拒绝下发,因为模块校验后也会拒绝, 而那时你已经被告知"写入成功"了。内部通道只有 1 条的模块,填 5,0,0,0,0,0,0,0 就是把它放到外部通道 5
  • 提交时,正在运行的 Data Path 要整条移动或完全不动(7.9.4):只换其中几条通道的提交会被拒绝,什么都不写。例如一条 8 通道的 Data Path 在运行时,2,1,3,4,5,6,7,8 会被拒绝;先让它停下,或整条移动
  • 当前映射若不符合,表格下方会以红色标出,本工具不会替你排序修正—— 那正是需要你看见的信息
  • 「已下发」是暂存值(6Dh:136–143),「当前生效」是交换机实际在做的 (6Dh:184–191,只读)。勾选 Enable 本身不会提交, 两列不一致表示提交还没做或被拒绝
  • 「上次提交结果」逐通道显示模块回报的状态:成功 / 进行中 / 四种拒绝原因
⚠ 提交会中断业务:重定向发生变化的通道会断流(未变化的通道按规范不受影响)。 点提交前会弹确认框。
⚠ 超过 8 条通道的模块,这个面板以前只管前 8 条,而且没说。 Page 6Dh 是按 bank 分组的,规范原文说每个 bank 提供的是 一组 8 条通道之内的交换能力——表 8-196 里所有字段的取值都是 {1, …, 8},所以目标通道永远是本组内的通道, 交换不能跨组。
以前工具只读第一组,下发时把目标列表截断到 8 个, 使能和提交也只写第一组——然后回报成功。 也就是说:在 16 通道模块上填 16 个目标, 后 8 条通道根本没被写、没被使能、也没被提交, 而面板上写着「已使能、已提交」。这是界面在替模块说一件它没做的事。
另外,寄存器里的目标值以前是原样打印的:第二组里的 3 指的是本组的第 3 条,也就是第 11 条通道, 界面上却写成「3」。
现在:表格列出全部通道并标出所属组,目标列显示绝对通道号 (原始寄存器值放在悬停提示里);映射校验逐组做, 所以两组各自用 1–8 是合法的;暂存、使能、提交都写到每一组; 目标个数超过模块通道数会被直接拒绝,不再默默丢掉多出来的部分。 某几组使能、某几组没使能时,表格下方会明确写出是哪几组。
8 通道模块只有一组,行为和以前完全一样。

12.4a Host Lane Switching(1Dh:128–191,DataPath Config 标签页,只读)

这一页是 CMIS 5.3 引入的(由 01h:252[7] 声明),不是 5.4——放在这里是因为它和 12.4 的 Media Lane Switching 布局相同,卡片标题不带 5.4 徽标。

与 12.4 布局相同,但切换的是主机侧:每一行是一条电气主机通道,「已下发」(1Dh:136–143)是主机写入的名义通道,「当前生效」(1Dh:184–191)是交换机实际连接的名义通道。只在模块于 01h:252[7] 声明支持时读取。

  • 「当前生效」与电气通道号不同的行标黄;卡片顶部列出这些电气通道
  • 切换生效时,本工具其它面板上的通道号都是名义通道——Application 和 Data Path 寄存器就是这样编号的
  • 和媒体侧一样按 8 条一组,每组有自己的使能位;目标显示为绝对通道号
  • 本工具不提供写入;如需改动,请用 Raw Registers

12.5 CMIS 5.4 Optional Pages(0Ch:128–159,Module Info 标签页)

模块用 32 字节位图声明自己实现了哪些页,比逐页试探可靠。下方另显示 Consolidated PM 特性的支持情况(按哪个 CMIS 版本定义、选项与要求的符合度)。

14. 附录:界面按钮速查

按钮位置功能
↻ Refresh Backends左侧面板重新扫描可用 Backend
Connect左侧面板连接模块
Disconnect左侧面板断开连接
↻ Refresh各标签页手动刷新当前页数据
↻ NowMonitoring立即手动刷新一次监控数据;监控因出错停掉后也靠它恢复轮询
ReadRaw Registers读取指定寄存器
⚙ Display右上角显示设置:主题、界面缩放、字号、字体(见 5.4)
Reset to defaults⚙ Display 面板内把四项显示设置恢复默认。只影响外观,不碰模块
↑ Update右上角检查并安装新版本(见 5.2)。是本工具唯一会主动联网的操作

会中断业务的按钮

以下按钮会影响模块的实际工作状态。只有 Reset Module 和媒体通道切换的 Commit 有确认对话框,其余点下去立即生效。

按钮位置影响范围确认框
Reset ModuleDataPath / 9.1软复位整个模块,所有 DataPath 重新初始化有
Enter LowPwrDataPath / 9.1模块进入低功耗,关闭发射,TxPower 掉到 0无
Exit LowPwrDataPath / 9.1请求退出低功耗,恢复到高功耗状态;被 DP Deinit 按住的数据通道保持 Deactivated无
WriteRaw Registers / 11.2任意寄存器写入,后果取决于你写了什么无
Apply(DataPath 配置表)DataPath / 9.3重启暂存配置有改动的数据通路;什么都没改时重启全部数据通路;只改极性或 TX Enable 时不重启,但 TX Enable 取消会直接关掉该路发射无
Apply(Output Controls)DataPath / 9.4Tx Squelch Force、Rx Output Disable 写下去就关掉对应通道的输出无
Commit(Media Lane Switching)DataPath / 12.4目标改变的通道断流,直到新的切换生效有
Apply(Loopback)Diagnostics / 10.1环回会中断正常收发无
Apply(PRBS)Diagnostics / 10.2打开的 Generator 用测试码型取代该通道的业务数据无
Apply(Laser Tuning)Diagnostics / 10.7改栅格或信道要先把数据通路停下(否则拒绝);改目标功率会改变发射光功率无

五个 Apply 的影响范围并不相同

界面上有五个 Apply 按钮,各管各的,互不下发对方的设置——唯一的例外是 PRBS。

Apply 所在卡片实际下发的内容
DataPath 配置表
(9.3)
影响最大:整体下发 AppSelect / TX Enable / 两个极性掩码, 再对暂存配置有改动的数据通路写 ApplyDPInit 并重启它们;只改极性或 TX Enable 时不重启; 什么都没改时重启全部数据通路(重新投运)
Output Controls
(9.4)
只写 Tx Squelch Disable / Tx Squelch Force / Rx Output Disable / Rx Squelch Disable 四个掩码,不触发 DataPath 重启
Loopback
(10.1)
只写媒体侧/主机侧各两个环回掩码
PRBS Generator
(10.2)
一次下发 Generator 和 Checker 共四个分区;Checker 卡片没有自己的 Apply
Laser Tuning
(10.7)
按 lane 下发栅格间隔、通道号、微调偏移与目标功率,仅可调谐模块可用