Automatizar el sondeo DDM por I2C: qué bytes de A2h contienen los valores en vivo y cuáles los umbrales
Estoy escribiendo un pequeño poller que extrae temperatura, voltaje, bias y potencia óptica directamente de los módulos en nuestras cajas whitebox, para tener una línea de tendencia en vez de que alguien mire el enlace a ojo después de que ya haya empezado a dar errores. El NOS imprime valores bonitos, pero quiero los números crudos con los umbrales del fabricante al lado, para que los niveles de alarma sean consistentes entre ópticas mixtas en vez de escritos a mano por modelo.
Montaje:
- host Linux, jaulas de módulos detrás de un mux I2C simple, bus 1
- ópticas SFP, SFP+ y SFP28 mixtas de tres fabricantes
- lectura solo con i2c-tools, sin SDK del fabricante
Leo la página de diagnósticos así:
# i2cdump -y 1 0x51
y este es mi parser en borrador, que es donde no estoy seguro:
temp = s16(a2[96:98]) / 256.0
vcc = u16(a2[98:100]) * 100e-6
bias = u16(a2[100:102]) * 2e-6
Lo que ya hice:
- comparé mis valores calculados con lo que imprime el NOS: cerca en algunos módulos, claramente desviados en otros
- leí SFF-8472, pero todavía no puedo decir con confianza dónde termina el bloque de umbrales y dónde empieza el área de calibración
- descarté el mux volcando el mismo módulo en un bus directo, mismos números
Así que: ¿cuál es el mapa real de A2h, dónde viven los umbrales, dónde empiezan los valores en tiempo real, y hay en algún lado una bandera que me diga si el módulo espera que haga algo con esas palabras crudas antes de confiar en ellas?
Comments 7
¿Cuáles valores son los que claramente están desviados, los cuatro o solo bias y las potencias? Eso normalmente decide toda la respuesta. También vuelca A0h ya que estás en eso y mira el byte 92: te dice si el módulo reporta diagnósticos siquiera, y si está calibrado internamente o externamente. Si parte de tu flota está calibrada externamente y tu parser trata a todos igual, entonces el desajuste es un comportamiento esperado y no un error en tu aritmética.
Saqué el byte 92 de A0h en toda la bandeja y no es uniforme. Algunos módulos marcan calibración externa, otros no, y los que no coinciden con la salida del NOS son exactamente los externos. Temperatura y voltaje están dentro del ruido en todos; bias y las dos potencias son lo que se desvía. Así que parece que me falta un paso más que estar leyendo los offsets equivocados. ¿Qué tengo que hacer realmente con las palabras crudas en ese subconjunto?
A2h en 0x51 se descompone en cuatro bloques que te importan:
Unidades en el bloque en vivo: temperatura con signo, 1/256 C por LSB; voltaje 100 uV por LSB; bias 2 uA; potencia TX y RX 0,1 uW. Tu fragmento ya escala eso correctamente, así que los offsets no son tu problema.
La pieza que falta es la bandera que acabas de encontrar. En un módulo calibrado externamente, las palabras en 96-105 son salida cruda del ADC, y las constantes en 56-95 tienen que aplicarse antes de que signifiquen algo; un módulo calibrado internamente ya hizo eso por ti. Esa ramificación es la diferencia entre tus dos grupos.
Si quieres un diseño contra el cual comprobar en vez de tomar mi palabra, el header sff8472.h de FreeBSD y py-sfp-eeprom detallan los offsets campo por campo. Aun así verificaría un módulo por fabricante contra un valor de confianza antes de colgar alarmas de esto.
Vale la pena añadir por qué el bloque de umbrales es la mitad interesante. Los valores en 0-55 están en las mismas unidades que el bloque en vivo, así que en cuanto tu escalado esté bien obtienes gratis los propios puntos de alarma y advertencia del fabricante y nunca tienes que inventar límites por modelo. Eso solo justifica leer A2h directamente en vez de parsear el bonito impresor de alguien.
Una nota práctica de correr esto en una bandeja mixta: mantén el intervalo de sondeo moderado. Esa página es una lectura I2C ordinaria y el controlador del módulo no es rápido. Machacar cada módulo cada segundo en un bus que además está detrás de un mux es una buena forma de recolectar lecturas cortas que se ven exactamente como ópticas parpadeando en tus gráficas.
Cuidado con cómo lo formulas, porque la gente lo lee como «siempre aplica las constantes» y luego se pregunta por qué sus números empeoraron. Las constantes en 56-95 solo se aplican cuando el byte 92 en A0h dice que el módulo está calibrado externamente. Aplícalas sobre un módulo calibrado internamente y conviertes lecturas perfectamente buenas en un sinsentido, porque el módulo ya hizo ese trabajo. Lee la bandera primero, ramifica según ella, mantén ambas rutas en el parser y registra qué ruta tomó un módulo dado para poder distinguir los dos modos de fallo más adelante.
Misma clase de trampa con la temperatura: tiene signo. Parséala sin signo y cualquier valor por debajo de cero vuelve como un número disparatadamente alto, lo cual es entretenido la primera mañana fría que te haga saltar una alerta.
Actualización de mi lado. Ramifiqué según el byte 92 de A0h y aplico las constantes solo donde el módulo dice externo. Bias y ambas potencias ahora coinciden con lo que imprime el NOS en cada módulo que pude comparar, y temperatura y voltaje nunca fueron un problema en primer lugar. Dos módulos todavía reportan que tienen diagnósticos pero devuelven umbrales en los que no confiaría, así que para esos recurro a mis propios límites y marco el módulo en el inventario en vez de fingir. No doy todo esto por cerrado, pero el mapa de arriba era exactamente lo que me faltaba.
Una cosa más antes de que esto pase a producción. El byte 110 está en la misma página y es estado más control, y la mitad de control incluye TX disable. Un poller no tiene ningún motivo para escribir en A2h en absoluto, pero si tu biblioteca hace un read-modify-write en algún lado, o te equivocas con i2cset mientras pruebas en una caja en producción, puedes tumbar el enlace de un cliente desde el userspace. Abre el bus en modo solo lectura en el poller y mantén cualquier ruta de escritura en una herramienta separada que tengas que ejecutar deliberadamente.
El mismo byte te da TX fault y RX LOS, y ambos vale la pena exportarlos junto a los valores analógicos. Un módulo con una potencia RX razonable pero con LOS activado te está contando una historia muy distinta a uno que simplemente lee bajo.