编程器能读出 SFP+ FTLX8571D3BCV-IT,但写入时一直返回 No Acknowledge
我维护着一个小型的模块流转库存:设备分散在全城各处,几乎每接到别人家的一台交换机就得给 SFP 改一次码。千兆模块的流程早就摸熟了,结果在一款万兆模块上卡住了。
桌上的东西:
- 一个带 SFP/SFP+ 插座的编程器,3.3 V 供电
- Finisar FTLX8571D3BCV-IT 和 FTLX1471D3BCV-IT,两个都能读出来
- 老库存里的 Cisco GLC-LH-SM
- HP J4858B 和 J4859C
读取稳定且可重复,两个 bank 都能整段读出来。写入在任何一种情况下都不成功:
read A0 0x00-0xFF ... OK
read A2 0x00-0xFF ... OK
write A0 vendor name ... No Acknowledge
write A0 serial (bytes 68-83) ... No Acknowledge
已经确认过的:
- 用同一个编程器对普通千兆 SFP 做同样的操作是通的,说明电路和供电都是活的;
- 拿了第二片 FTLX8571D3BCV-IT,表现逐字节一模一样;
- 在 GLC-LH-SM 上,还没碰到厂商字段就立刻收到 No Acknowledge。
看起来不是某一片的个体问题。这是模块本身的硬件写保护,还是说 SFP+ 里的存储已经不是裸的 EEPROM 了,普通 I2C 写操作根本碰不到?另外单独想问一下 HP J4858B/J4859C:有没有人用普通编程器写过它们,还是说这条路本来就走不通?
Comments 6
这里混杂着两种不同的机制,修法也不一样。
第一种,是普通 EEPROM 带硬件写保护。存储芯片上有一个 write protect 引脚,只要它被上拉,读操作能进行,写操作就会失败。真正深入干过这个的人给的建议是:在刷写期间把这个引脚接地。对一部分千兆模块来说这就够了。
第二种,就是你在这款万兆模块上遇到的情况。在 SFP+ 里,数据往往不是放在一片独立的 EEPROM 里,而是挂在模块自己的微控制器后面:读 A0 和 A2 是它自己应答的,写入也只接受它自己那套专用的命令序列。标准编程器根本不认识这套序列,不管你瞄准的是哪个字段,都会拿到 No Acknowledge。这种情况下没有引脚可以接地。
真正能绕过这个笼位的做法是:直接用导线焊到模块的第 4 脚和第 7 脚上,也就是 I2C 信号线,绕过编程器的插座。据反馈,这样操作之后,一部分在笼位里毫无反应的模块就能写进去了。这个方法比较粗暴,需要手够稳,而且模块焊完之后能不能正常工作,只能自己承担风险。
HP 是另外一回事。标准编程器动不了它们,需要专门的处理,J4858B/J4859C 用普通电路我不指望能成功。如果目标只是想让一个模块能在别人家的交换机里正常工作,与其死磕 HP,不如换一块存储是老实 EEPROM 的模块,把厂商原厂镜像整段写进去:256 字节的转储里,有意义的是前 128 字节,剩下的是厂商保留区。
当然,没有任何一家厂商会为这种改码提供支持:拿着一个改过码的模块去找官方支持,是没法开口的。
确认几件事,不然只能瞎猜。No Acknowledge 是在设备地址那一步就出现,还是在写完第一个数据字节之后才出现?编程器的日志里通常能看出来。你用的编程器是什么——现成的设备,还是自己搭的电路?这决定了对笼位那 3.3 V 该有什么样的期望。
还有一点想知道,上电之后的表现:刚装上模块就失败,和通电放几分钟之后再失败,是不是一样?还有这四种型号表现是不是一致,还是说 Finisar 和 HP 有差异——HP 那边通常另有自己的失败原因,最好先把它单独分出来看。
汇报一下结果。直接焊在 I2C 信号线的第 4 脚和第 7 脚上,绕过了笼位。Finisar 那两个通了:FTLX8571D3BCV-IT 写进去之后回读也验证成功,FTLX1471D3BCV-IT 也一样。GLC-LH-SM 不再报 No Acknowledge,能正常写入了。
HP 还是没能拿下。J4858B 写操作表面上是接受了,但改完之后交换机拒绝这个模块,J4859C 表现一样。所以对我来说这个问题算是解决了一半:Finisar 和 Cisco 现在能写了,HP 先放在一边等以后再说。
HP 这边的坑比写保护要深,所以你这个结果是意料之中的。在 J4858B 上,修改第 68-83 字节(也就是序列号)之后,第 124-127 字节的校验和会跟着变,模块也就因此被拒绝。这不是 MSA 规定的 CC_BASE 和 CC_EXT,那两个算起来不难;这是 A0 最后四个字节里一个单独的厂商自定义校验和。这个算法从来没人公开破解过,不管多少人折腾过它。
J9150A 也是同一个故事。而更新一代的 HP 和 Aruba 模块干脆彻底放弃了静态校验和,改成了一套请求-应答机制,也就是 HPIDv2,那种情况下编程器根本无能为力。所以「能写进去,但不被接受」正是应该出现的结果。
既然你手上是一整批模块,而不是一片,我说说工具方面的事。针对华为 S5731、S6730 和 HP 6120XG 的改码,我用的是 Ubiquiti 的 UACC-SFP-WIZARD——当廉价编程器用还挺好使。只是 Ubiquiti 自家模块流传着一些密码列表,比如 0x00001011、SFPX、QSFP 这样的条目,没有这些的话,一部分模块写操作根本打不开。我常用的镜像有 FTLX8571D3BCV 和 FTLX8574D3BCV,偶尔也用 SNR-SFP+W73-3 和 W37-3。
纠正一下上面那个概括,免得有人过早就抄起烙铁:不是每一个 SFP+ 的存储都藏在微控制器后面。我这边的 FTLX8574D3BCV 和一对 SNR-SFP+W73-3,用普通编程器直接在笼位里就能写进去,完全不用焊。所以应该先测测手上这一片具体是什么情况,再决定要不要走绕过这条路。
顺带一提,接地 write protect 引脚也不是万能药:在带微控制器的模块上,这么做没有任何作用,那里的拒绝来自控制器的固件逻辑,而不是存储本身。这个操作只有在真正带独立老实 EEPROM 的模块上才有意义,而且要在模块断电的情况下做,不然很容易把一片模块直接变成砖。