xref: /aosp_15_r20/external/ethtool/sfpdiag.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski  * sfpdiag.c: Implements SFF-8472 optics diagnostics.
3*1b481fc3SMaciej Żenczykowski  *
4*1b481fc3SMaciej Żenczykowski  * Aurelien Guillaume <[email protected]> (C) 2012
5*1b481fc3SMaciej Żenczykowski  *   This implementation is loosely based on DOM patches
6*1b481fc3SMaciej Żenczykowski  *   from Robert Olsson <[email protected]> (C) 2009
7*1b481fc3SMaciej Żenczykowski  *   and SFF-8472 specs (ftp://ftp.seagate.com/pub/sff/SFF-8472.PDF)
8*1b481fc3SMaciej Żenczykowski  *   by SFF Committee.
9*1b481fc3SMaciej Żenczykowski  */
10*1b481fc3SMaciej Żenczykowski 
11*1b481fc3SMaciej Żenczykowski #include <stdio.h>
12*1b481fc3SMaciej Żenczykowski #include <math.h>
13*1b481fc3SMaciej Żenczykowski #include <arpa/inet.h>
14*1b481fc3SMaciej Żenczykowski #include "internal.h"
15*1b481fc3SMaciej Żenczykowski #include "sff-common.h"
16*1b481fc3SMaciej Żenczykowski 
17*1b481fc3SMaciej Żenczykowski /* Offsets in decimal, for direct comparison with the SFF specs */
18*1b481fc3SMaciej Żenczykowski 
19*1b481fc3SMaciej Żenczykowski /* A0-based EEPROM offsets for DOM support checks */
20*1b481fc3SMaciej Żenczykowski #define SFF_A0_DOM                        92
21*1b481fc3SMaciej Żenczykowski #define SFF_A0_OPTIONS                    93
22*1b481fc3SMaciej Żenczykowski #define SFF_A0_COMP                       94
23*1b481fc3SMaciej Żenczykowski 
24*1b481fc3SMaciej Żenczykowski /* EEPROM bit values for various registers */
25*1b481fc3SMaciej Żenczykowski #define SFF_A0_DOM_EXTCAL                 (1 << 4)
26*1b481fc3SMaciej Żenczykowski #define SFF_A0_DOM_INTCAL                 (1 << 5)
27*1b481fc3SMaciej Żenczykowski #define SFF_A0_DOM_IMPL                   (1 << 6)
28*1b481fc3SMaciej Żenczykowski #define SFF_A0_DOM_PWRT                   (1 << 3)
29*1b481fc3SMaciej Żenczykowski 
30*1b481fc3SMaciej Żenczykowski #define SFF_A0_OPTIONS_AW                 (1 << 7)
31*1b481fc3SMaciej Żenczykowski 
32*1b481fc3SMaciej Żenczykowski /*
33*1b481fc3SMaciej Żenczykowski  * See ethtool.c comments about SFF-8472, this is the offset
34*1b481fc3SMaciej Żenczykowski  * at which the A2 page is in the EEPROM blob returned by the
35*1b481fc3SMaciej Żenczykowski  * kernel.
36*1b481fc3SMaciej Żenczykowski  */
37*1b481fc3SMaciej Żenczykowski #define SFF_A2_BASE                       0x100
38*1b481fc3SMaciej Żenczykowski 
39*1b481fc3SMaciej Żenczykowski /* A2-based offsets for DOM */
40*1b481fc3SMaciej Żenczykowski #define SFF_A2_TEMP                       96
41*1b481fc3SMaciej Żenczykowski #define SFF_A2_TEMP_HALRM                 0
42*1b481fc3SMaciej Żenczykowski #define SFF_A2_TEMP_LALRM                 2
43*1b481fc3SMaciej Żenczykowski #define SFF_A2_TEMP_HWARN                 4
44*1b481fc3SMaciej Żenczykowski #define SFF_A2_TEMP_LWARN                 6
45*1b481fc3SMaciej Żenczykowski 
46*1b481fc3SMaciej Żenczykowski #define SFF_A2_VCC                        98
47*1b481fc3SMaciej Żenczykowski #define SFF_A2_VCC_HALRM                  8
48*1b481fc3SMaciej Żenczykowski #define SFF_A2_VCC_LALRM                  10
49*1b481fc3SMaciej Żenczykowski #define SFF_A2_VCC_HWARN                  12
50*1b481fc3SMaciej Żenczykowski #define SFF_A2_VCC_LWARN                  14
51*1b481fc3SMaciej Żenczykowski 
52*1b481fc3SMaciej Żenczykowski #define SFF_A2_BIAS                       100
53*1b481fc3SMaciej Żenczykowski #define SFF_A2_BIAS_HALRM                 16
54*1b481fc3SMaciej Żenczykowski #define SFF_A2_BIAS_LALRM                 18
55*1b481fc3SMaciej Żenczykowski #define SFF_A2_BIAS_HWARN                 20
56*1b481fc3SMaciej Żenczykowski #define SFF_A2_BIAS_LWARN                 22
57*1b481fc3SMaciej Żenczykowski 
58*1b481fc3SMaciej Żenczykowski #define SFF_A2_TX_PWR                     102
59*1b481fc3SMaciej Żenczykowski #define SFF_A2_TX_PWR_HALRM               24
60*1b481fc3SMaciej Żenczykowski #define SFF_A2_TX_PWR_LALRM               26
61*1b481fc3SMaciej Żenczykowski #define SFF_A2_TX_PWR_HWARN               28
62*1b481fc3SMaciej Żenczykowski #define SFF_A2_TX_PWR_LWARN               30
63*1b481fc3SMaciej Żenczykowski 
64*1b481fc3SMaciej Żenczykowski #define SFF_A2_RX_PWR                     104
65*1b481fc3SMaciej Żenczykowski #define SFF_A2_RX_PWR_HALRM               32
66*1b481fc3SMaciej Żenczykowski #define SFF_A2_RX_PWR_LALRM               34
67*1b481fc3SMaciej Żenczykowski #define SFF_A2_RX_PWR_HWARN               36
68*1b481fc3SMaciej Żenczykowski #define SFF_A2_RX_PWR_LWARN               38
69*1b481fc3SMaciej Żenczykowski 
70*1b481fc3SMaciej Żenczykowski #define SFF_A2_ALRM_FLG                   112
71*1b481fc3SMaciej Żenczykowski #define SFF_A2_WARN_FLG                   116
72*1b481fc3SMaciej Żenczykowski 
73*1b481fc3SMaciej Żenczykowski /* 32-bit little-endian calibration constants */
74*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_RXPWR4                 56
75*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_RXPWR3                 60
76*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_RXPWR2                 64
77*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_RXPWR1                 68
78*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_RXPWR0                 72
79*1b481fc3SMaciej Żenczykowski 
80*1b481fc3SMaciej Żenczykowski /* 16-bit little endian calibration constants */
81*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_TXI_SLP                76
82*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_TXI_OFF                78
83*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_TXPWR_SLP              80
84*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_TXPWR_OFF              82
85*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_T_SLP                  84
86*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_T_OFF                  86
87*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_V_SLP                  88
88*1b481fc3SMaciej Żenczykowski #define SFF_A2_CAL_V_OFF                  90
89*1b481fc3SMaciej Żenczykowski 
90*1b481fc3SMaciej Żenczykowski static struct sff8472_aw_flags {
91*1b481fc3SMaciej Żenczykowski 	const char *str;        /* Human-readable string, null at the end */
92*1b481fc3SMaciej Żenczykowski 	int offset;             /* A2-relative address offset */
93*1b481fc3SMaciej Żenczykowski 	__u8 value;             /* Alarm is on if (offset & value) != 0. */
94*1b481fc3SMaciej Żenczykowski } sff8472_aw_flags[] = {
95*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current high alarm",   SFF_A2_ALRM_FLG, (1 << 3) },
96*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current low alarm",    SFF_A2_ALRM_FLG, (1 << 2) },
97*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current high warning", SFF_A2_WARN_FLG, (1 << 3) },
98*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current low warning",  SFF_A2_WARN_FLG, (1 << 2) },
99*1b481fc3SMaciej Żenczykowski 
100*1b481fc3SMaciej Żenczykowski 	{ "Laser output power high alarm",   SFF_A2_ALRM_FLG, (1 << 1) },
101*1b481fc3SMaciej Żenczykowski 	{ "Laser output power low alarm",    SFF_A2_ALRM_FLG, (1 << 0) },
102*1b481fc3SMaciej Żenczykowski 	{ "Laser output power high warning", SFF_A2_WARN_FLG, (1 << 1) },
103*1b481fc3SMaciej Żenczykowski 	{ "Laser output power low warning",  SFF_A2_WARN_FLG, (1 << 0) },
104*1b481fc3SMaciej Żenczykowski 
105*1b481fc3SMaciej Żenczykowski 	{ "Module temperature high alarm",   SFF_A2_ALRM_FLG, (1 << 7) },
106*1b481fc3SMaciej Żenczykowski 	{ "Module temperature low alarm",    SFF_A2_ALRM_FLG, (1 << 6) },
107*1b481fc3SMaciej Żenczykowski 	{ "Module temperature high warning", SFF_A2_WARN_FLG, (1 << 7) },
108*1b481fc3SMaciej Żenczykowski 	{ "Module temperature low warning",  SFF_A2_WARN_FLG, (1 << 6) },
109*1b481fc3SMaciej Żenczykowski 
110*1b481fc3SMaciej Żenczykowski 	{ "Module voltage high alarm",   SFF_A2_ALRM_FLG, (1 << 5) },
111*1b481fc3SMaciej Żenczykowski 	{ "Module voltage low alarm",    SFF_A2_ALRM_FLG, (1 << 4) },
112*1b481fc3SMaciej Żenczykowski 	{ "Module voltage high warning", SFF_A2_WARN_FLG, (1 << 5) },
113*1b481fc3SMaciej Żenczykowski 	{ "Module voltage low warning",  SFF_A2_WARN_FLG, (1 << 4) },
114*1b481fc3SMaciej Żenczykowski 
115*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power high alarm",   SFF_A2_ALRM_FLG + 1, (1 << 7) },
116*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power low alarm",    SFF_A2_ALRM_FLG + 1, (1 << 6) },
117*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power high warning", SFF_A2_WARN_FLG + 1, (1 << 7) },
118*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power low warning",  SFF_A2_WARN_FLG + 1, (1 << 6) },
119*1b481fc3SMaciej Żenczykowski 
120*1b481fc3SMaciej Żenczykowski 	{ NULL, 0, 0 },
121*1b481fc3SMaciej Żenczykowski };
122*1b481fc3SMaciej Żenczykowski 
123*1b481fc3SMaciej Żenczykowski /* Most common case: 16-bit unsigned integer in a certain unit */
124*1b481fc3SMaciej Żenczykowski #define A2_OFFSET_TO_U16(offset) \
125*1b481fc3SMaciej Żenczykowski 	(id[SFF_A2_BASE + (offset)] << 8 | id[SFF_A2_BASE + (offset) + 1])
126*1b481fc3SMaciej Żenczykowski 
127*1b481fc3SMaciej Żenczykowski /* Calibration slope is a number between 0.0 included and 256.0 excluded. */
128*1b481fc3SMaciej Żenczykowski #define A2_OFFSET_TO_SLP(offset) \
129*1b481fc3SMaciej Żenczykowski 	(id[SFF_A2_BASE + (offset)] + id[SFF_A2_BASE + (offset) + 1] / 256.)
130*1b481fc3SMaciej Żenczykowski 
131*1b481fc3SMaciej Żenczykowski /* Calibration offset is an integer from -32768 to 32767 */
132*1b481fc3SMaciej Żenczykowski #define A2_OFFSET_TO_OFF(offset) \
133*1b481fc3SMaciej Żenczykowski 	((__s16)A2_OFFSET_TO_U16(offset))
134*1b481fc3SMaciej Żenczykowski 
135*1b481fc3SMaciej Żenczykowski /* RXPWR(x) are IEEE-754 floating point numbers in big-endian format */
136*1b481fc3SMaciej Żenczykowski #define A2_OFFSET_TO_RXPWRx(offset) \
137*1b481fc3SMaciej Żenczykowski 	(befloattoh((__u32 *)(id + SFF_A2_BASE + (offset))))
138*1b481fc3SMaciej Żenczykowski 
139*1b481fc3SMaciej Żenczykowski /*
140*1b481fc3SMaciej Żenczykowski  * 2-byte internal temperature conversions:
141*1b481fc3SMaciej Żenczykowski  * First byte is a signed 8-bit integer, which is the temp decimal part
142*1b481fc3SMaciej Żenczykowski  * Second byte are 1/256th of degree, which are added to the dec part.
143*1b481fc3SMaciej Żenczykowski  */
144*1b481fc3SMaciej Żenczykowski #define A2_OFFSET_TO_TEMP(offset) ((__s16)A2_OFFSET_TO_U16(offset))
145*1b481fc3SMaciej Żenczykowski 
sff8472_dom_parse(const __u8 * id,struct sff_diags * sd)146*1b481fc3SMaciej Żenczykowski static void sff8472_dom_parse(const __u8 *id, struct sff_diags *sd)
147*1b481fc3SMaciej Żenczykowski {
148*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[MCURR] = A2_OFFSET_TO_U16(SFF_A2_BIAS);
149*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[HALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HALRM);
150*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[LALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LALRM);
151*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[HWARN] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HWARN);
152*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[LWARN] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LWARN);
153*1b481fc3SMaciej Żenczykowski 
154*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[MCURR] = A2_OFFSET_TO_U16(SFF_A2_VCC);
155*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[HALRM] = A2_OFFSET_TO_U16(SFF_A2_VCC_HALRM);
156*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[LALRM] = A2_OFFSET_TO_U16(SFF_A2_VCC_LALRM);
157*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[HWARN] = A2_OFFSET_TO_U16(SFF_A2_VCC_HWARN);
158*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[LWARN] = A2_OFFSET_TO_U16(SFF_A2_VCC_LWARN);
159*1b481fc3SMaciej Żenczykowski 
160*1b481fc3SMaciej Żenczykowski 	sd->tx_power[MCURR] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR);
161*1b481fc3SMaciej Żenczykowski 	sd->tx_power[HALRM] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_HALRM);
162*1b481fc3SMaciej Żenczykowski 	sd->tx_power[LALRM] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_LALRM);
163*1b481fc3SMaciej Żenczykowski 	sd->tx_power[HWARN] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_HWARN);
164*1b481fc3SMaciej Żenczykowski 	sd->tx_power[LWARN] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_LWARN);
165*1b481fc3SMaciej Żenczykowski 
166*1b481fc3SMaciej Żenczykowski 	sd->rx_power[MCURR] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR);
167*1b481fc3SMaciej Żenczykowski 	sd->rx_power[HALRM] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_HALRM);
168*1b481fc3SMaciej Żenczykowski 	sd->rx_power[LALRM] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_LALRM);
169*1b481fc3SMaciej Żenczykowski 	sd->rx_power[HWARN] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_HWARN);
170*1b481fc3SMaciej Żenczykowski 	sd->rx_power[LWARN] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_LWARN);
171*1b481fc3SMaciej Żenczykowski 
172*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[MCURR] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP);
173*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[HALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HALRM);
174*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[LALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LALRM);
175*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[HWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HWARN);
176*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[LWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LWARN);
177*1b481fc3SMaciej Żenczykowski }
178*1b481fc3SMaciej Żenczykowski 
179*1b481fc3SMaciej Żenczykowski /* Converts to a float from a big-endian 4-byte source buffer. */
befloattoh(const __u32 * source)180*1b481fc3SMaciej Żenczykowski static float befloattoh(const __u32 *source)
181*1b481fc3SMaciej Żenczykowski {
182*1b481fc3SMaciej Żenczykowski 	union {
183*1b481fc3SMaciej Żenczykowski 		__u32 src;
184*1b481fc3SMaciej Żenczykowski 		float dst;
185*1b481fc3SMaciej Żenczykowski 	} converter;
186*1b481fc3SMaciej Żenczykowski 
187*1b481fc3SMaciej Żenczykowski 	converter.src = ntohl(*source);
188*1b481fc3SMaciej Żenczykowski 	return converter.dst;
189*1b481fc3SMaciej Żenczykowski }
190*1b481fc3SMaciej Żenczykowski 
sff8472_calibration(const __u8 * id,struct sff_diags * sd)191*1b481fc3SMaciej Żenczykowski static void sff8472_calibration(const __u8 *id, struct sff_diags *sd)
192*1b481fc3SMaciej Żenczykowski {
193*1b481fc3SMaciej Żenczykowski 	__u16 rx_reading;
194*1b481fc3SMaciej Żenczykowski 	unsigned int i;
195*1b481fc3SMaciej Żenczykowski 
196*1b481fc3SMaciej Żenczykowski 	/* Calibration should occur for all values (threshold and current) */
197*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < ARRAY_SIZE(sd->bias_cur); ++i) {
198*1b481fc3SMaciej Żenczykowski 		/*
199*1b481fc3SMaciej Żenczykowski 		 * Apply calibration formula 1 (Temp., Voltage, Bias, Tx Power)
200*1b481fc3SMaciej Żenczykowski 		 */
201*1b481fc3SMaciej Żenczykowski 		sd->bias_cur[i]    *= A2_OFFSET_TO_SLP(SFF_A2_CAL_TXI_SLP);
202*1b481fc3SMaciej Żenczykowski 		sd->tx_power[i]    *= A2_OFFSET_TO_SLP(SFF_A2_CAL_TXPWR_SLP);
203*1b481fc3SMaciej Żenczykowski 		sd->sfp_voltage[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_V_SLP);
204*1b481fc3SMaciej Żenczykowski 		sd->sfp_temp[i]    *= A2_OFFSET_TO_SLP(SFF_A2_CAL_T_SLP);
205*1b481fc3SMaciej Żenczykowski 
206*1b481fc3SMaciej Żenczykowski 		sd->bias_cur[i]    += A2_OFFSET_TO_OFF(SFF_A2_CAL_TXI_OFF);
207*1b481fc3SMaciej Żenczykowski 		sd->tx_power[i]    += A2_OFFSET_TO_OFF(SFF_A2_CAL_TXPWR_OFF);
208*1b481fc3SMaciej Żenczykowski 		sd->sfp_voltage[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_V_OFF);
209*1b481fc3SMaciej Żenczykowski 		sd->sfp_temp[i]    += A2_OFFSET_TO_OFF(SFF_A2_CAL_T_OFF);
210*1b481fc3SMaciej Żenczykowski 
211*1b481fc3SMaciej Żenczykowski 		/*
212*1b481fc3SMaciej Żenczykowski 		 * Apply calibration formula 2 (Rx Power only)
213*1b481fc3SMaciej Żenczykowski 		 */
214*1b481fc3SMaciej Żenczykowski 		rx_reading = sd->rx_power[i];
215*1b481fc3SMaciej Żenczykowski 		sd->rx_power[i]    = A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR0);
216*1b481fc3SMaciej Żenczykowski 		sd->rx_power[i]    += rx_reading *
217*1b481fc3SMaciej Żenczykowski 			A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR1);
218*1b481fc3SMaciej Żenczykowski 		sd->rx_power[i]    += rx_reading *
219*1b481fc3SMaciej Żenczykowski 			A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR2);
220*1b481fc3SMaciej Żenczykowski 		sd->rx_power[i]    += rx_reading *
221*1b481fc3SMaciej Żenczykowski 			A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR3);
222*1b481fc3SMaciej Żenczykowski 	}
223*1b481fc3SMaciej Żenczykowski }
224*1b481fc3SMaciej Żenczykowski 
sff8472_parse_eeprom(const __u8 * id,struct sff_diags * sd)225*1b481fc3SMaciej Żenczykowski static void sff8472_parse_eeprom(const __u8 *id, struct sff_diags *sd)
226*1b481fc3SMaciej Żenczykowski {
227*1b481fc3SMaciej Żenczykowski 	sd->supports_dom = id[SFF_A0_DOM] & SFF_A0_DOM_IMPL;
228*1b481fc3SMaciej Żenczykowski 	sd->supports_alarms = id[SFF_A0_OPTIONS] & SFF_A0_OPTIONS_AW;
229*1b481fc3SMaciej Żenczykowski 	sd->calibrated_ext = id[SFF_A0_DOM] & SFF_A0_DOM_EXTCAL;
230*1b481fc3SMaciej Żenczykowski 	sd->rx_power_type = id[SFF_A0_DOM] & SFF_A0_DOM_PWRT;
231*1b481fc3SMaciej Żenczykowski 
232*1b481fc3SMaciej Żenczykowski 	sff8472_dom_parse(id, sd);
233*1b481fc3SMaciej Żenczykowski 
234*1b481fc3SMaciej Żenczykowski 	/*
235*1b481fc3SMaciej Żenczykowski 	 * If the SFP is externally calibrated, we need to read calibration data
236*1b481fc3SMaciej Żenczykowski 	 * and compensate the already stored readings.
237*1b481fc3SMaciej Żenczykowski 	 */
238*1b481fc3SMaciej Żenczykowski 	if (sd->calibrated_ext)
239*1b481fc3SMaciej Żenczykowski 		sff8472_calibration(id, sd);
240*1b481fc3SMaciej Żenczykowski }
241*1b481fc3SMaciej Żenczykowski 
sff8472_show_all(const __u8 * id)242*1b481fc3SMaciej Żenczykowski void sff8472_show_all(const __u8 *id)
243*1b481fc3SMaciej Żenczykowski {
244*1b481fc3SMaciej Żenczykowski 	struct sff_diags sd = {0};
245*1b481fc3SMaciej Żenczykowski 	char *rx_power_string = NULL;
246*1b481fc3SMaciej Żenczykowski 	int i;
247*1b481fc3SMaciej Żenczykowski 
248*1b481fc3SMaciej Żenczykowski 	sff8472_parse_eeprom(id, &sd);
249*1b481fc3SMaciej Żenczykowski 
250*1b481fc3SMaciej Żenczykowski 	if (!sd.supports_dom) {
251*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : No\n", "Optical diagnostics support");
252*1b481fc3SMaciej Żenczykowski 		return;
253*1b481fc3SMaciej Żenczykowski 	}
254*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : Yes\n", "Optical diagnostics support");
255*1b481fc3SMaciej Żenczykowski 
256*1b481fc3SMaciej Żenczykowski 	PRINT_BIAS("Laser bias current", sd.bias_cur[MCURR]);
257*1b481fc3SMaciej Żenczykowski 	PRINT_xX_PWR("Laser output power", sd.tx_power[MCURR]);
258*1b481fc3SMaciej Żenczykowski 
259*1b481fc3SMaciej Żenczykowski 	if (!sd.rx_power_type)
260*1b481fc3SMaciej Żenczykowski 		rx_power_string = "Receiver signal OMA";
261*1b481fc3SMaciej Żenczykowski 	else
262*1b481fc3SMaciej Żenczykowski 		rx_power_string = "Receiver signal average optical power";
263*1b481fc3SMaciej Żenczykowski 
264*1b481fc3SMaciej Żenczykowski 	PRINT_xX_PWR(rx_power_string, sd.rx_power[MCURR]);
265*1b481fc3SMaciej Żenczykowski 
266*1b481fc3SMaciej Żenczykowski 	PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]);
267*1b481fc3SMaciej Żenczykowski 	PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]);
268*1b481fc3SMaciej Żenczykowski 
269*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : %s\n", "Alarm/warning flags implemented",
270*1b481fc3SMaciej Żenczykowski 	       (sd.supports_alarms ? "Yes" : "No"));
271*1b481fc3SMaciej Żenczykowski 	if (sd.supports_alarms) {
272*1b481fc3SMaciej Żenczykowski 
273*1b481fc3SMaciej Żenczykowski 		for (i = 0; sff8472_aw_flags[i].str; ++i) {
274*1b481fc3SMaciej Żenczykowski 			printf("\t%-41s : %s\n", sff8472_aw_flags[i].str,
275*1b481fc3SMaciej Żenczykowski 			       id[SFF_A2_BASE + sff8472_aw_flags[i].offset]
276*1b481fc3SMaciej Żenczykowski 			       & sff8472_aw_flags[i].value ? "On" : "Off");
277*1b481fc3SMaciej Żenczykowski 		}
278*1b481fc3SMaciej Żenczykowski 		sff_show_thresholds(sd);
279*1b481fc3SMaciej Żenczykowski 	}
280*1b481fc3SMaciej Żenczykowski }
281*1b481fc3SMaciej Żenczykowski 
282