xref: /dpdk/lib/ethdev/sff_8636.c (revision c42754fd581a4298b9db54aa063285a4ead5e23a)
1*c42754fdSRobin Zhang /* SPDX-License-Identifier: BSD-3-Clause
2*c42754fdSRobin Zhang  * Copyright(c) 2022 Intel Corporation
3*c42754fdSRobin Zhang  * Implements SFF-8636 based QSFP+/QSFP28 Diagnostics Memory map.
4*c42754fdSRobin Zhang  */
5*c42754fdSRobin Zhang 
6*c42754fdSRobin Zhang #include <stdio.h>
7*c42754fdSRobin Zhang #include <math.h>
8*c42754fdSRobin Zhang 
9*c42754fdSRobin Zhang #include "sff_common.h"
10*c42754fdSRobin Zhang #include "sff_8636.h"
11*c42754fdSRobin Zhang 
12*c42754fdSRobin Zhang #define SFF_MAX_DESC_SIZE	42
13*c42754fdSRobin Zhang 
14*c42754fdSRobin Zhang static const uint8_t sff_8636_rx_power_offset[SFF_MAX_CHANNEL_NUM] = {
15*c42754fdSRobin Zhang 	SFF_8636_RX_PWR_1_OFFSET,
16*c42754fdSRobin Zhang 	SFF_8636_RX_PWR_2_OFFSET,
17*c42754fdSRobin Zhang 	SFF_8636_RX_PWR_3_OFFSET,
18*c42754fdSRobin Zhang 	SFF_8636_RX_PWR_4_OFFSET,
19*c42754fdSRobin Zhang };
20*c42754fdSRobin Zhang static const uint8_t sff_8636_tx_power_offset[SFF_MAX_CHANNEL_NUM] = {
21*c42754fdSRobin Zhang 	SFF_8636_TX_PWR_1_OFFSET,
22*c42754fdSRobin Zhang 	SFF_8636_TX_PWR_2_OFFSET,
23*c42754fdSRobin Zhang 	SFF_8636_TX_PWR_3_OFFSET,
24*c42754fdSRobin Zhang 	SFF_8636_TX_PWR_4_OFFSET,
25*c42754fdSRobin Zhang };
26*c42754fdSRobin Zhang static const uint8_t sff_8636_tx_bias_offset[SFF_MAX_CHANNEL_NUM] = {
27*c42754fdSRobin Zhang 	SFF_8636_TX_BIAS_1_OFFSET,
28*c42754fdSRobin Zhang 	SFF_8636_TX_BIAS_2_OFFSET,
29*c42754fdSRobin Zhang 	SFF_8636_TX_BIAS_3_OFFSET,
30*c42754fdSRobin Zhang 	SFF_8636_TX_BIAS_4_OFFSET,
31*c42754fdSRobin Zhang };
32*c42754fdSRobin Zhang 
33*c42754fdSRobin Zhang static struct sff_8636_aw_flags {
34*c42754fdSRobin Zhang 	const char *str;        /* Human-readable string, null at the end */
35*c42754fdSRobin Zhang 	int offset;             /* A2-relative address offset */
36*c42754fdSRobin Zhang 	uint8_t value;             /* Alarm is on if (offset & value) != 0. */
37*c42754fdSRobin Zhang } sff_8636_aw_flags[] = {
38*c42754fdSRobin Zhang 	{ "Laser bias current high alarm   (Chan 1)",
39*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_1_HALARM) },
40*c42754fdSRobin Zhang 	{ "Laser bias current low alarm    (Chan 1)",
41*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_1_LALARM) },
42*c42754fdSRobin Zhang 	{ "Laser bias current high warning (Chan 1)",
43*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_1_HWARN) },
44*c42754fdSRobin Zhang 	{ "Laser bias current low warning  (Chan 1)",
45*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_1_LWARN) },
46*c42754fdSRobin Zhang 
47*c42754fdSRobin Zhang 	{ "Laser bias current high alarm   (Chan 2)",
48*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_2_HALARM) },
49*c42754fdSRobin Zhang 	{ "Laser bias current low alarm    (Chan 2)",
50*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_2_LALARM) },
51*c42754fdSRobin Zhang 	{ "Laser bias current high warning (Chan 2)",
52*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_2_HWARN) },
53*c42754fdSRobin Zhang 	{ "Laser bias current low warning  (Chan 2)",
54*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_12_AW_OFFSET, (SFF_8636_TX_BIAS_2_LWARN) },
55*c42754fdSRobin Zhang 
56*c42754fdSRobin Zhang 	{ "Laser bias current high alarm   (Chan 3)",
57*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_3_HALARM) },
58*c42754fdSRobin Zhang 	{ "Laser bias current low alarm    (Chan 3)",
59*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_3_LALARM) },
60*c42754fdSRobin Zhang 	{ "Laser bias current high warning (Chan 3)",
61*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_3_HWARN) },
62*c42754fdSRobin Zhang 	{ "Laser bias current low warning  (Chan 3)",
63*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_3_LWARN) },
64*c42754fdSRobin Zhang 
65*c42754fdSRobin Zhang 	{ "Laser bias current high alarm   (Chan 4)",
66*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_4_HALARM) },
67*c42754fdSRobin Zhang 	{ "Laser bias current low alarm    (Chan 4)",
68*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_4_LALARM) },
69*c42754fdSRobin Zhang 	{ "Laser bias current high warning (Chan 4)",
70*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_4_HWARN) },
71*c42754fdSRobin Zhang 	{ "Laser bias current low warning  (Chan 4)",
72*c42754fdSRobin Zhang 		SFF_8636_TX_BIAS_34_AW_OFFSET, (SFF_8636_TX_BIAS_4_LWARN) },
73*c42754fdSRobin Zhang 
74*c42754fdSRobin Zhang 	{ "Module temperature high alarm",
75*c42754fdSRobin Zhang 		SFF_8636_TEMP_AW_OFFSET, (SFF_8636_TEMP_HALARM_STATUS) },
76*c42754fdSRobin Zhang 	{ "Module temperature low alarm",
77*c42754fdSRobin Zhang 		SFF_8636_TEMP_AW_OFFSET, (SFF_8636_TEMP_LALARM_STATUS) },
78*c42754fdSRobin Zhang 	{ "Module temperature high warning",
79*c42754fdSRobin Zhang 		SFF_8636_TEMP_AW_OFFSET, (SFF_8636_TEMP_HWARN_STATUS) },
80*c42754fdSRobin Zhang 	{ "Module temperature low warning",
81*c42754fdSRobin Zhang 		SFF_8636_TEMP_AW_OFFSET, (SFF_8636_TEMP_LWARN_STATUS) },
82*c42754fdSRobin Zhang 
83*c42754fdSRobin Zhang 	{ "Module voltage high alarm",
84*c42754fdSRobin Zhang 		SFF_8636_VCC_AW_OFFSET, (SFF_8636_VCC_HALARM_STATUS) },
85*c42754fdSRobin Zhang 	{ "Module voltage low alarm",
86*c42754fdSRobin Zhang 		SFF_8636_VCC_AW_OFFSET, (SFF_8636_VCC_LALARM_STATUS) },
87*c42754fdSRobin Zhang 	{ "Module voltage high warning",
88*c42754fdSRobin Zhang 		SFF_8636_VCC_AW_OFFSET, (SFF_8636_VCC_HWARN_STATUS) },
89*c42754fdSRobin Zhang 	{ "Module voltage low warning",
90*c42754fdSRobin Zhang 		SFF_8636_VCC_AW_OFFSET, (SFF_8636_VCC_LWARN_STATUS) },
91*c42754fdSRobin Zhang 
92*c42754fdSRobin Zhang 	{ "Laser tx power high alarm   (Channel 1)",
93*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_1_HALARM) },
94*c42754fdSRobin Zhang 	{ "Laser tx power low alarm    (Channel 1)",
95*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_1_LALARM) },
96*c42754fdSRobin Zhang 	{ "Laser tx power high warning (Channel 1)",
97*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_1_HWARN) },
98*c42754fdSRobin Zhang 	{ "Laser tx power low warning  (Channel 1)",
99*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_1_LWARN) },
100*c42754fdSRobin Zhang 
101*c42754fdSRobin Zhang 	{ "Laser tx power high alarm   (Channel 2)",
102*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_2_HALARM) },
103*c42754fdSRobin Zhang 	{ "Laser tx power low alarm    (Channel 2)",
104*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_2_LALARM) },
105*c42754fdSRobin Zhang 	{ "Laser tx power high warning (Channel 2)",
106*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_2_HWARN) },
107*c42754fdSRobin Zhang 	{ "Laser tx power low warning  (Channel 2)",
108*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_12_AW_OFFSET, (SFF_8636_TX_PWR_2_LWARN) },
109*c42754fdSRobin Zhang 
110*c42754fdSRobin Zhang 	{ "Laser tx power high alarm   (Channel 3)",
111*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_3_HALARM) },
112*c42754fdSRobin Zhang 	{ "Laser tx power low alarm    (Channel 3)",
113*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_3_LALARM) },
114*c42754fdSRobin Zhang 	{ "Laser tx power high warning (Channel 3)",
115*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_3_HWARN) },
116*c42754fdSRobin Zhang 	{ "Laser tx power low warning  (Channel 3)",
117*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_3_LWARN) },
118*c42754fdSRobin Zhang 
119*c42754fdSRobin Zhang 	{ "Laser tx power high alarm   (Channel 4)",
120*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_4_HALARM) },
121*c42754fdSRobin Zhang 	{ "Laser tx power low alarm    (Channel 4)",
122*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_4_LALARM) },
123*c42754fdSRobin Zhang 	{ "Laser tx power high warning (Channel 4)",
124*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_4_HWARN) },
125*c42754fdSRobin Zhang 	{ "Laser tx power low warning  (Channel 4)",
126*c42754fdSRobin Zhang 		SFF_8636_TX_PWR_34_AW_OFFSET, (SFF_8636_TX_PWR_4_LWARN) },
127*c42754fdSRobin Zhang 
128*c42754fdSRobin Zhang 	{ "Laser rx power high alarm   (Channel 1)",
129*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_1_HALARM) },
130*c42754fdSRobin Zhang 	{ "Laser rx power low alarm    (Channel 1)",
131*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_1_LALARM) },
132*c42754fdSRobin Zhang 	{ "Laser rx power high warning (Channel 1)",
133*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_1_HWARN) },
134*c42754fdSRobin Zhang 	{ "Laser rx power low warning  (Channel 1)",
135*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_1_LWARN) },
136*c42754fdSRobin Zhang 
137*c42754fdSRobin Zhang 	{ "Laser rx power high alarm   (Channel 2)",
138*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_2_HALARM) },
139*c42754fdSRobin Zhang 	{ "Laser rx power low alarm    (Channel 2)",
140*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_2_LALARM) },
141*c42754fdSRobin Zhang 	{ "Laser rx power high warning (Channel 2)",
142*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_2_HWARN) },
143*c42754fdSRobin Zhang 	{ "Laser rx power low warning  (Channel 2)",
144*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_12_AW_OFFSET, (SFF_8636_RX_PWR_2_LWARN) },
145*c42754fdSRobin Zhang 
146*c42754fdSRobin Zhang 	{ "Laser rx power high alarm   (Channel 3)",
147*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_3_HALARM) },
148*c42754fdSRobin Zhang 	{ "Laser rx power low alarm    (Channel 3)",
149*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_3_LALARM) },
150*c42754fdSRobin Zhang 	{ "Laser rx power high warning (Channel 3)",
151*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_3_HWARN) },
152*c42754fdSRobin Zhang 	{ "Laser rx power low warning  (Channel 3)",
153*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_3_LWARN) },
154*c42754fdSRobin Zhang 
155*c42754fdSRobin Zhang 	{ "Laser rx power high alarm   (Channel 4)",
156*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_4_HALARM) },
157*c42754fdSRobin Zhang 	{ "Laser rx power low alarm    (Channel 4)",
158*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_4_LALARM) },
159*c42754fdSRobin Zhang 	{ "Laser rx power high warning (Channel 4)",
160*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_4_HWARN) },
161*c42754fdSRobin Zhang 	{ "Laser rx power low warning  (Channel 4)",
162*c42754fdSRobin Zhang 		SFF_8636_RX_PWR_34_AW_OFFSET, (SFF_8636_RX_PWR_4_LWARN) },
163*c42754fdSRobin Zhang 
164*c42754fdSRobin Zhang 	{ NULL, 0, 0 },
165*c42754fdSRobin Zhang };
166*c42754fdSRobin Zhang 
sff_8636_show_identifier(const uint8_t * data,struct rte_tel_data * d)167*c42754fdSRobin Zhang static void sff_8636_show_identifier(const uint8_t *data, struct rte_tel_data *d)
168*c42754fdSRobin Zhang {
169*c42754fdSRobin Zhang 	sff_8024_show_identifier(data, SFF_8636_ID_OFFSET, d);
170*c42754fdSRobin Zhang }
171*c42754fdSRobin Zhang 
sff_8636_show_ext_identifier(const uint8_t * data,struct rte_tel_data * d)172*c42754fdSRobin Zhang static void sff_8636_show_ext_identifier(const uint8_t *data, struct rte_tel_data *d)
173*c42754fdSRobin Zhang {
174*c42754fdSRobin Zhang 	static const char *name = "Extended identifier description";
175*c42754fdSRobin Zhang 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
176*c42754fdSRobin Zhang 	snprintf(val_string, sizeof(val_string), "0x%02x", data[SFF_8636_EXT_ID_OFFSET]);
177*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Extended identifier", val_string);
178*c42754fdSRobin Zhang 
179*c42754fdSRobin Zhang 	switch (data[SFF_8636_EXT_ID_OFFSET] & SFF_8636_EXT_ID_PWR_CLASS_MASK) {
180*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_1:
181*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "1.5W max. Power consumption");
182*c42754fdSRobin Zhang 		break;
183*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_2:
184*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "2.0W max. Power consumption");
185*c42754fdSRobin Zhang 		break;
186*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_3:
187*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "2.5W max. Power consumption");
188*c42754fdSRobin Zhang 		break;
189*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_4:
190*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "3.5W max. Power consumption");
191*c42754fdSRobin Zhang 		break;
192*c42754fdSRobin Zhang 	}
193*c42754fdSRobin Zhang 
194*c42754fdSRobin Zhang 	if (data[SFF_8636_EXT_ID_OFFSET] & SFF_8636_EXT_ID_CDR_TX_MASK)
195*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "CDR present in TX");
196*c42754fdSRobin Zhang 	else
197*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "No CDR in TX");
198*c42754fdSRobin Zhang 
199*c42754fdSRobin Zhang 	if (data[SFF_8636_EXT_ID_OFFSET] & SFF_8636_EXT_ID_CDR_RX_MASK)
200*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "CDR present in RX");
201*c42754fdSRobin Zhang 	else
202*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "No CDR in RX");
203*c42754fdSRobin Zhang 
204*c42754fdSRobin Zhang 	switch (data[SFF_8636_EXT_ID_OFFSET] & SFF_8636_EXT_ID_EPWR_CLASS_MASK) {
205*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_LEGACY:
206*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%s", "");
207*c42754fdSRobin Zhang 		break;
208*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_5:
209*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%s", "4.0W max. Power consumption, ");
210*c42754fdSRobin Zhang 		break;
211*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_6:
212*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%s", "4.5W max. Power consumption, ");
213*c42754fdSRobin Zhang 		break;
214*c42754fdSRobin Zhang 	case SFF_8636_EXT_ID_PWR_CLASS_7:
215*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%s", "5.0W max. Power consumption, ");
216*c42754fdSRobin Zhang 		break;
217*c42754fdSRobin Zhang 	}
218*c42754fdSRobin Zhang 
219*c42754fdSRobin Zhang 	if (data[SFF_8636_PWR_MODE_OFFSET] & SFF_8636_HIGH_PWR_ENABLE)
220*c42754fdSRobin Zhang 		strlcat(val_string, "High Power Class (> 3.5 W) enabled", sizeof(val_string));
221*c42754fdSRobin Zhang 	else
222*c42754fdSRobin Zhang 		strlcat(val_string, "High Power Class (> 3.5 W) not enabled", sizeof(val_string));
223*c42754fdSRobin Zhang 
224*c42754fdSRobin Zhang 	ssf_add_dict_string(d, name, val_string);
225*c42754fdSRobin Zhang }
226*c42754fdSRobin Zhang 
sff_8636_show_connector(const uint8_t * data,struct rte_tel_data * d)227*c42754fdSRobin Zhang static void sff_8636_show_connector(const uint8_t *data, struct rte_tel_data *d)
228*c42754fdSRobin Zhang {
229*c42754fdSRobin Zhang 	sff_8024_show_connector(data, SFF_8636_CTOR_OFFSET, d);
230*c42754fdSRobin Zhang }
231*c42754fdSRobin Zhang 
sff_8636_show_transceiver(const uint8_t * data,struct rte_tel_data * d)232*c42754fdSRobin Zhang static void sff_8636_show_transceiver(const uint8_t *data, struct rte_tel_data *d)
233*c42754fdSRobin Zhang {
234*c42754fdSRobin Zhang 	static const char *name = "Transceiver type";
235*c42754fdSRobin Zhang 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
236*c42754fdSRobin Zhang 
237*c42754fdSRobin Zhang 	snprintf(val_string, sizeof(val_string), "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
238*c42754fdSRobin Zhang 		data[SFF_8636_ETHERNET_COMP_OFFSET],
239*c42754fdSRobin Zhang 		data[SFF_8636_SONET_COMP_OFFSET],
240*c42754fdSRobin Zhang 		data[SFF_8636_SAS_COMP_OFFSET],
241*c42754fdSRobin Zhang 		data[SFF_8636_GIGE_COMP_OFFSET],
242*c42754fdSRobin Zhang 		data[SFF_8636_FC_LEN_OFFSET],
243*c42754fdSRobin Zhang 		data[SFF_8636_FC_TECH_OFFSET],
244*c42754fdSRobin Zhang 		data[SFF_8636_FC_TRANS_MEDIA_OFFSET],
245*c42754fdSRobin Zhang 		data[SFF_8636_FC_SPEED_OFFSET]);
246*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Transceiver codes", val_string);
247*c42754fdSRobin Zhang 
248*c42754fdSRobin Zhang 	/* 10G/40G Ethernet Compliance Codes */
249*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_10G_LRM)
250*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "10G Ethernet: 10G Base-LRM");
251*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_10G_LR)
252*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "10G Ethernet: 10G Base-LR");
253*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_10G_SR)
254*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "10G Ethernet: 10G Base-SR");
255*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_40G_CR4)
256*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "40G Ethernet: 40G Base-CR4");
257*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_40G_SR4)
258*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "40G Ethernet: 40G Base-SR4");
259*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_40G_LR4)
260*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "40G Ethernet: 40G Base-LR4");
261*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_40G_ACTIVE)
262*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "40G Ethernet: 40G Active Cable (XLPPI)");
263*c42754fdSRobin Zhang 
264*c42754fdSRobin Zhang 	/* Extended Specification Compliance Codes from SFF-8024 */
265*c42754fdSRobin Zhang 	if (data[SFF_8636_ETHERNET_COMP_OFFSET] & SFF_8636_ETHERNET_RSRVD) {
266*c42754fdSRobin Zhang 		switch (data[SFF_8636_OPTION_1_OFFSET]) {
267*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_UNSPECIFIED:
268*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "(reserved or unknown)");
269*c42754fdSRobin Zhang 			break;
270*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_AOC:
271*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
272*c42754fdSRobin Zhang 			"100G Ethernet: 100G AOC or 25GAUI C2M AOC with worst BER of 5x10^(-5)");
273*c42754fdSRobin Zhang 			break;
274*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_SR4:
275*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
276*c42754fdSRobin Zhang 					"100G Ethernet: 100G Base-SR4 or 25GBase-SR");
277*c42754fdSRobin Zhang 			break;
278*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_LR4:
279*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "100G Ethernet: 100G Base-LR4");
280*c42754fdSRobin Zhang 			break;
281*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_ER4:
282*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "100G Ethernet: 100G Base-ER4");
283*c42754fdSRobin Zhang 			break;
284*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_SR10:
285*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "100G Ethernet: 100G Base-SR10");
286*c42754fdSRobin Zhang 			break;
287*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_CWDM4_FEC:
288*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "100G Ethernet: 100G CWDM4 MSA with FEC");
289*c42754fdSRobin Zhang 			break;
290*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_PSM4:
291*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "100G Ethernet: 100G PSM4 Parallel SMF");
292*c42754fdSRobin Zhang 			break;
293*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_ACC:
294*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
295*c42754fdSRobin Zhang 			"100G Ethernet: 100G ACC or 25GAUI C2M ACC with worst BER of 5x10^(-5)");
296*c42754fdSRobin Zhang 			break;
297*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_CWDM4_NO_FEC:
298*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
299*c42754fdSRobin Zhang 					"100G Ethernet: 100G CWDM4 MSA without FEC");
300*c42754fdSRobin Zhang 			break;
301*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_RSVD1:
302*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "(reserved or unknown)");
303*c42754fdSRobin Zhang 			break;
304*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_CR4:
305*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
306*c42754fdSRobin Zhang 					"100G Ethernet: 100G Base-CR4 or 25G Base-CR CA-L");
307*c42754fdSRobin Zhang 			break;
308*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_25G_CR_CA_S:
309*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "25G Ethernet: 25G Base-CR CA-S");
310*c42754fdSRobin Zhang 			break;
311*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_25G_CR_CA_N:
312*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "25G Ethernet: 25G Base-CR CA-N");
313*c42754fdSRobin Zhang 			break;
314*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_40G_ER4:
315*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "40G Ethernet: 40G Base-ER4");
316*c42754fdSRobin Zhang 			break;
317*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_4X10_SR:
318*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "4x10G Ethernet: 10G Base-SR");
319*c42754fdSRobin Zhang 			break;
320*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_40G_PSM4:
321*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "40G Ethernet: 40G PSM4 Parallel SMF");
322*c42754fdSRobin Zhang 			break;
323*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_G959_P1I1_2D1:
324*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
325*c42754fdSRobin Zhang 				"Ethernet: G959.1 profile P1I1-2D1 (10709 MBd, 2km, 1310nm SM)");
326*c42754fdSRobin Zhang 			break;
327*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_G959_P1S1_2D2:
328*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
329*c42754fdSRobin Zhang 				"Ethernet: G959.1 profile P1S1-2D2 (10709 MBd, 40km, 1550nm SM)");
330*c42754fdSRobin Zhang 			break;
331*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_G959_P1L1_2D2:
332*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
333*c42754fdSRobin Zhang 				"Ethernet: G959.1 profile P1L1-2D2 (10709 MBd, 80km, 1550nm SM)");
334*c42754fdSRobin Zhang 			break;
335*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_10GT_SFI:
336*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
337*c42754fdSRobin Zhang 				"10G Ethernet: 10G Base-T with SFI electrical interface");
338*c42754fdSRobin Zhang 			break;
339*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_CLR4:
340*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "100G Ethernet: 100G CLR4");
341*c42754fdSRobin Zhang 			break;
342*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_AOC2:
343*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
344*c42754fdSRobin Zhang 			"100G Ethernet: 100G AOC or 25GAUI C2M AOC with worst BER of 10^(-12)");
345*c42754fdSRobin Zhang 			break;
346*c42754fdSRobin Zhang 		case SFF_8636_ETHERNET_100G_ACC2:
347*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name,
348*c42754fdSRobin Zhang 			"100G Ethernet: 100G ACC or 25GAUI C2M ACC with worst BER of 10^(-12)");
349*c42754fdSRobin Zhang 			break;
350*c42754fdSRobin Zhang 		default:
351*c42754fdSRobin Zhang 			ssf_add_dict_string(d, name, "(reserved or unknown)");
352*c42754fdSRobin Zhang 			break;
353*c42754fdSRobin Zhang 		}
354*c42754fdSRobin Zhang 	}
355*c42754fdSRobin Zhang 
356*c42754fdSRobin Zhang 	/* SONET Compliance Codes */
357*c42754fdSRobin Zhang 	if (data[SFF_8636_SONET_COMP_OFFSET] & SFF_8636_SONET_40G_OTN)
358*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "40G OTN (OTU3B/OTU3C)");
359*c42754fdSRobin Zhang 	if (data[SFF_8636_SONET_COMP_OFFSET] & SFF_8636_SONET_OC48_LR)
360*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SONET: OC-48, long reach");
361*c42754fdSRobin Zhang 	if (data[SFF_8636_SONET_COMP_OFFSET] & SFF_8636_SONET_OC48_IR)
362*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SONET: OC-48, intermediate reach");
363*c42754fdSRobin Zhang 	if (data[SFF_8636_SONET_COMP_OFFSET] & SFF_8636_SONET_OC48_SR)
364*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SONET: OC-48, short reach");
365*c42754fdSRobin Zhang 
366*c42754fdSRobin Zhang 	/* SAS/SATA Compliance Codes */
367*c42754fdSRobin Zhang 	if (data[SFF_8636_SAS_COMP_OFFSET] & SFF_8636_SAS_6G)
368*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SAS 6.0G");
369*c42754fdSRobin Zhang 	if (data[SFF_8636_SAS_COMP_OFFSET] & SFF_8636_SAS_3G)
370*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SAS 3.0G");
371*c42754fdSRobin Zhang 
372*c42754fdSRobin Zhang 	/* Ethernet Compliance Codes */
373*c42754fdSRobin Zhang 	if (data[SFF_8636_GIGE_COMP_OFFSET] & SFF_8636_GIGE_1000_BASE_T)
374*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "Ethernet: 1000BASE-T");
375*c42754fdSRobin Zhang 	if (data[SFF_8636_GIGE_COMP_OFFSET] & SFF_8636_GIGE_1000_BASE_CX)
376*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "Ethernet: 1000BASE-CX");
377*c42754fdSRobin Zhang 	if (data[SFF_8636_GIGE_COMP_OFFSET] & SFF_8636_GIGE_1000_BASE_LX)
378*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "Ethernet: 1000BASE-LX");
379*c42754fdSRobin Zhang 	if (data[SFF_8636_GIGE_COMP_OFFSET] & SFF_8636_GIGE_1000_BASE_SX)
380*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "Ethernet: 1000BASE-SX");
381*c42754fdSRobin Zhang 
382*c42754fdSRobin Zhang 	/* Fibre Channel link length */
383*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_LEN_VERY_LONG)
384*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: very long distance (V)");
385*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_LEN_SHORT)
386*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: short distance (S)");
387*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_LEN_INT)
388*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: intermediate distance (I)");
389*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_LEN_LONG)
390*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: long distance (L)");
391*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_LEN_MED)
392*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: medium distance (M)");
393*c42754fdSRobin Zhang 
394*c42754fdSRobin Zhang 	/* Fibre Channel transmitter technology */
395*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_TECH_LONG_LC)
396*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Longwave laser (LC)");
397*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_LEN_OFFSET] & SFF_8636_FC_TECH_ELEC_INTER)
398*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Electrical inter-enclosure (EL)");
399*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TECH_OFFSET] & SFF_8636_FC_TECH_ELEC_INTRA)
400*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Electrical intra-enclosure (EL)");
401*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TECH_OFFSET] & SFF_8636_FC_TECH_SHORT_WO_OFC)
402*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Shortwave laser w/o OFC (SN)");
403*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TECH_OFFSET] & SFF_8636_FC_TECH_SHORT_W_OFC)
404*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Shortwave laser with OFC (SL)");
405*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TECH_OFFSET] & SFF_8636_FC_TECH_LONG_LL)
406*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Longwave laser (LL)");
407*c42754fdSRobin Zhang 
408*c42754fdSRobin Zhang 	/* Fibre Channel transmission media */
409*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_TW)
410*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Twin Axial Pair (TW)");
411*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_TP)
412*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Twisted Pair (TP)");
413*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_MI)
414*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Miniature Coax (MI)");
415*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_TV)
416*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Video Coax (TV)");
417*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_M6)
418*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Multimode, 62.5m (M6)");
419*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_M5)
420*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Multimode, 50m (M5)");
421*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_OM3)
422*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Multimode, 50um (OM3)");
423*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_TRANS_MEDIA_OFFSET] & SFF_8636_FC_TRANS_MEDIA_SM)
424*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: Single Mode (SM)");
425*c42754fdSRobin Zhang 
426*c42754fdSRobin Zhang 	/* Fibre Channel speed */
427*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_SPEED_OFFSET] & SFF_8636_FC_SPEED_1200_MBPS)
428*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: 1200 MBytes/sec");
429*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_SPEED_OFFSET] & SFF_8636_FC_SPEED_800_MBPS)
430*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: 800 MBytes/sec");
431*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_SPEED_OFFSET] & SFF_8636_FC_SPEED_1600_MBPS)
432*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: 1600 MBytes/sec");
433*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_SPEED_OFFSET] & SFF_8636_FC_SPEED_400_MBPS)
434*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: 400 MBytes/sec");
435*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_SPEED_OFFSET] & SFF_8636_FC_SPEED_200_MBPS)
436*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: 200 MBytes/sec");
437*c42754fdSRobin Zhang 	if (data[SFF_8636_FC_SPEED_OFFSET] & SFF_8636_FC_SPEED_100_MBPS)
438*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "FC: 100 MBytes/sec");
439*c42754fdSRobin Zhang }
440*c42754fdSRobin Zhang 
sff_8636_show_encoding(const uint8_t * data,struct rte_tel_data * d)441*c42754fdSRobin Zhang static void sff_8636_show_encoding(const uint8_t *data, struct rte_tel_data *d)
442*c42754fdSRobin Zhang {
443*c42754fdSRobin Zhang 	sff_8024_show_encoding(data, SFF_8636_ENCODING_OFFSET,
444*c42754fdSRobin Zhang 			       RTE_ETH_MODULE_SFF_8636, d);
445*c42754fdSRobin Zhang }
446*c42754fdSRobin Zhang 
sff_8636_show_rate_identifier(const uint8_t * data,struct rte_tel_data * d)447*c42754fdSRobin Zhang static void sff_8636_show_rate_identifier(const uint8_t *data, struct rte_tel_data *d)
448*c42754fdSRobin Zhang {
449*c42754fdSRobin Zhang 	char val_string[20];
450*c42754fdSRobin Zhang 
451*c42754fdSRobin Zhang 	snprintf(val_string, sizeof(val_string), "0x%02x", data[SFF_8636_EXT_RS_OFFSET]);
452*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Rate identifier", val_string);
453*c42754fdSRobin Zhang }
454*c42754fdSRobin Zhang 
sff_8636_show_oui(const uint8_t * data,struct rte_tel_data * d)455*c42754fdSRobin Zhang static void sff_8636_show_oui(const uint8_t *data, struct rte_tel_data *d)
456*c42754fdSRobin Zhang {
457*c42754fdSRobin Zhang 	sff_8024_show_oui(data, SFF_8636_VENDOR_OUI_OFFSET, d);
458*c42754fdSRobin Zhang }
459*c42754fdSRobin Zhang 
sff_8636_show_wavelength_or_copper_compliance(const uint8_t * data,struct rte_tel_data * d)460*c42754fdSRobin Zhang static void sff_8636_show_wavelength_or_copper_compliance(const uint8_t *data,
461*c42754fdSRobin Zhang 							  struct rte_tel_data *d)
462*c42754fdSRobin Zhang {
463*c42754fdSRobin Zhang 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
464*c42754fdSRobin Zhang 	snprintf(val_string, sizeof(val_string), "0x%02x",
465*c42754fdSRobin Zhang 		(data[SFF_8636_DEVICE_TECH_OFFSET] & SFF_8636_TRANS_TECH_MASK));
466*c42754fdSRobin Zhang 
467*c42754fdSRobin Zhang 	switch (data[SFF_8636_DEVICE_TECH_OFFSET] & SFF_8636_TRANS_TECH_MASK) {
468*c42754fdSRobin Zhang 	case SFF_8636_TRANS_850_VCSEL:
469*c42754fdSRobin Zhang 		strlcat(val_string, " (850 nm VCSEL)", sizeof(val_string));
470*c42754fdSRobin Zhang 		break;
471*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1310_VCSEL:
472*c42754fdSRobin Zhang 		strlcat(val_string, " (1310 nm VCSEL)", sizeof(val_string));
473*c42754fdSRobin Zhang 		break;
474*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1550_VCSEL:
475*c42754fdSRobin Zhang 		strlcat(val_string, " (1550 nm VCSEL)", sizeof(val_string));
476*c42754fdSRobin Zhang 		break;
477*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1310_FP:
478*c42754fdSRobin Zhang 		strlcat(val_string, " (1310 nm FP)", sizeof(val_string));
479*c42754fdSRobin Zhang 		break;
480*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1310_DFB:
481*c42754fdSRobin Zhang 		strlcat(val_string, " (1310 nm DFB)", sizeof(val_string));
482*c42754fdSRobin Zhang 		break;
483*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1550_DFB:
484*c42754fdSRobin Zhang 		strlcat(val_string, " (1550 nm DFB)", sizeof(val_string));
485*c42754fdSRobin Zhang 		break;
486*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1310_EML:
487*c42754fdSRobin Zhang 		strlcat(val_string, " (1310 nm EML)", sizeof(val_string));
488*c42754fdSRobin Zhang 		break;
489*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1550_EML:
490*c42754fdSRobin Zhang 		strlcat(val_string, " (1550 nm EML)", sizeof(val_string));
491*c42754fdSRobin Zhang 		break;
492*c42754fdSRobin Zhang 	case SFF_8636_TRANS_OTHERS:
493*c42754fdSRobin Zhang 		strlcat(val_string, " (Others/Undefined)", sizeof(val_string));
494*c42754fdSRobin Zhang 		break;
495*c42754fdSRobin Zhang 	case SFF_8636_TRANS_1490_DFB:
496*c42754fdSRobin Zhang 		strlcat(val_string, " (1490 nm DFB)", sizeof(val_string));
497*c42754fdSRobin Zhang 		break;
498*c42754fdSRobin Zhang 	case SFF_8636_TRANS_COPPER_PAS_UNEQUAL:
499*c42754fdSRobin Zhang 		strlcat(val_string, " (Copper cable unequalized)", sizeof(val_string));
500*c42754fdSRobin Zhang 		break;
501*c42754fdSRobin Zhang 	case SFF_8636_TRANS_COPPER_PAS_EQUAL:
502*c42754fdSRobin Zhang 		strlcat(val_string, " (Copper cable passive equalized)", sizeof(val_string));
503*c42754fdSRobin Zhang 		break;
504*c42754fdSRobin Zhang 	case SFF_8636_TRANS_COPPER_LNR_FAR_EQUAL:
505*c42754fdSRobin Zhang 		strlcat(val_string,
506*c42754fdSRobin Zhang 		       " (Copper cable, near and far end limiting active equalizers)",
507*c42754fdSRobin Zhang 		       sizeof(val_string));
508*c42754fdSRobin Zhang 		break;
509*c42754fdSRobin Zhang 	case SFF_8636_TRANS_COPPER_FAR_EQUAL:
510*c42754fdSRobin Zhang 		strlcat(val_string,
511*c42754fdSRobin Zhang 			" (Copper cable, far end limiting active equalizers)",
512*c42754fdSRobin Zhang 			sizeof(val_string));
513*c42754fdSRobin Zhang 		break;
514*c42754fdSRobin Zhang 	case SFF_8636_TRANS_COPPER_NEAR_EQUAL:
515*c42754fdSRobin Zhang 		strlcat(val_string,
516*c42754fdSRobin Zhang 			" (Copper cable, near end limiting active equalizers)",
517*c42754fdSRobin Zhang 			sizeof(val_string));
518*c42754fdSRobin Zhang 		break;
519*c42754fdSRobin Zhang 	case SFF_8636_TRANS_COPPER_LNR_EQUAL:
520*c42754fdSRobin Zhang 		strlcat(val_string,
521*c42754fdSRobin Zhang 			" (Copper cable, linear active equalizers)",
522*c42754fdSRobin Zhang 			sizeof(val_string));
523*c42754fdSRobin Zhang 		break;
524*c42754fdSRobin Zhang 	}
525*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Transmitter technology", val_string);
526*c42754fdSRobin Zhang 
527*c42754fdSRobin Zhang 	if ((data[SFF_8636_DEVICE_TECH_OFFSET] & SFF_8636_TRANS_TECH_MASK)
528*c42754fdSRobin Zhang 			>= SFF_8636_TRANS_COPPER_PAS_UNEQUAL) {
529*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%udb",
530*c42754fdSRobin Zhang 			 data[SFF_8636_WAVELEN_HIGH_BYTE_OFFSET]);
531*c42754fdSRobin Zhang 		ssf_add_dict_string(d, "Attenuation at 2.5GHz", val_string);
532*c42754fdSRobin Zhang 
533*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%udb",
534*c42754fdSRobin Zhang 			 data[SFF_8636_WAVELEN_HIGH_BYTE_OFFSET]);
535*c42754fdSRobin Zhang 		ssf_add_dict_string(d, "Attenuation at 5.0GHz", val_string);
536*c42754fdSRobin Zhang 
537*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%udb",
538*c42754fdSRobin Zhang 			 data[SFF_8636_WAVELEN_HIGH_BYTE_OFFSET]);
539*c42754fdSRobin Zhang 		ssf_add_dict_string(d, "Attenuation at 7.0GHz", val_string);
540*c42754fdSRobin Zhang 
541*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%udb",
542*c42754fdSRobin Zhang 			 data[SFF_8636_WAVELEN_HIGH_BYTE_OFFSET]);
543*c42754fdSRobin Zhang 		ssf_add_dict_string(d, "Attenuation at 12.9GHz", val_string);
544*c42754fdSRobin Zhang 	} else {
545*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%.3lfnm",
546*c42754fdSRobin Zhang 			(((data[SFF_8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
547*c42754fdSRobin Zhang 			data[SFF_8636_WAVELEN_LOW_BYTE_OFFSET])*0.05));
548*c42754fdSRobin Zhang 		ssf_add_dict_string(d, "Laser wavelength", val_string);
549*c42754fdSRobin Zhang 
550*c42754fdSRobin Zhang 		snprintf(val_string, sizeof(val_string), "%.3lfnm",
551*c42754fdSRobin Zhang 			(((data[SFF_8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
552*c42754fdSRobin Zhang 			data[SFF_8636_WAVE_TOL_LOW_BYTE_OFFSET])*0.005));
553*c42754fdSRobin Zhang 		ssf_add_dict_string(d, "Laser wavelength tolerance", val_string);
554*c42754fdSRobin Zhang 	}
555*c42754fdSRobin Zhang }
556*c42754fdSRobin Zhang 
sff_8636_show_revision_compliance(const uint8_t * data,struct rte_tel_data * d)557*c42754fdSRobin Zhang static void sff_8636_show_revision_compliance(const uint8_t *data, struct rte_tel_data *d)
558*c42754fdSRobin Zhang {
559*c42754fdSRobin Zhang 	static const char *name = "Revision Compliance";
560*c42754fdSRobin Zhang 
561*c42754fdSRobin Zhang 	switch (data[SFF_8636_REV_COMPLIANCE_OFFSET]) {
562*c42754fdSRobin Zhang 	case SFF_8636_REV_UNSPECIFIED:
563*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "Revision not specified");
564*c42754fdSRobin Zhang 		break;
565*c42754fdSRobin Zhang 	case SFF_8636_REV_8436_48:
566*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8436 Rev 4.8 or earlier");
567*c42754fdSRobin Zhang 		break;
568*c42754fdSRobin Zhang 	case SFF_8636_REV_8436_8636:
569*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8436 Rev 4.8 or earlier");
570*c42754fdSRobin Zhang 		break;
571*c42754fdSRobin Zhang 	case SFF_8636_REV_8636_13:
572*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8636 Rev 1.3 or earlier");
573*c42754fdSRobin Zhang 		break;
574*c42754fdSRobin Zhang 	case SFF_8636_REV_8636_14:
575*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8636 Rev 1.4");
576*c42754fdSRobin Zhang 		break;
577*c42754fdSRobin Zhang 	case SFF_8636_REV_8636_15:
578*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8636 Rev 1.5");
579*c42754fdSRobin Zhang 		break;
580*c42754fdSRobin Zhang 	case SFF_8636_REV_8636_20:
581*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8636 Rev 2.0");
582*c42754fdSRobin Zhang 		break;
583*c42754fdSRobin Zhang 	case SFF_8636_REV_8636_27:
584*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "SFF-8636 Rev 2.5/2.6/2.7");
585*c42754fdSRobin Zhang 		break;
586*c42754fdSRobin Zhang 	default:
587*c42754fdSRobin Zhang 		ssf_add_dict_string(d, name, "Unallocated");
588*c42754fdSRobin Zhang 		break;
589*c42754fdSRobin Zhang 	}
590*c42754fdSRobin Zhang }
591*c42754fdSRobin Zhang 
592*c42754fdSRobin Zhang /*
593*c42754fdSRobin Zhang  * 2-byte internal temperature conversions:
594*c42754fdSRobin Zhang  * First byte is a signed 8-bit integer, which is the temp decimal part
595*c42754fdSRobin Zhang  * Second byte are 1/256th of degree, which are added to the dec part.
596*c42754fdSRobin Zhang  */
597*c42754fdSRobin Zhang #define SFF_8636_OFFSET_TO_TEMP(offset) ((int16_t)SFF_OFFSET_TO_U16(offset))
598*c42754fdSRobin Zhang 
sff_8636_dom_parse(const uint8_t * data,struct sff_diags * sd)599*c42754fdSRobin Zhang static void sff_8636_dom_parse(const uint8_t *data, struct sff_diags *sd)
600*c42754fdSRobin Zhang {
601*c42754fdSRobin Zhang 	int i = 0;
602*c42754fdSRobin Zhang 
603*c42754fdSRobin Zhang 	/* Monitoring Thresholds for Alarms and Warnings */
604*c42754fdSRobin Zhang 	sd->sfp_voltage[SFF_MCURR] = SFF_OFFSET_TO_U16(SFF_8636_VCC_CURR);
605*c42754fdSRobin Zhang 	sd->sfp_voltage[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_VCC_HALRM);
606*c42754fdSRobin Zhang 	sd->sfp_voltage[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_VCC_LALRM);
607*c42754fdSRobin Zhang 	sd->sfp_voltage[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_VCC_HWARN);
608*c42754fdSRobin Zhang 	sd->sfp_voltage[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_VCC_LWARN);
609*c42754fdSRobin Zhang 
610*c42754fdSRobin Zhang 	sd->sfp_temp[SFF_MCURR] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_CURR);
611*c42754fdSRobin Zhang 	sd->sfp_temp[SFF_HALRM] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_HALRM);
612*c42754fdSRobin Zhang 	sd->sfp_temp[SFF_LALRM] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_LALRM);
613*c42754fdSRobin Zhang 	sd->sfp_temp[SFF_HWARN] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_HWARN);
614*c42754fdSRobin Zhang 	sd->sfp_temp[SFF_LWARN] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_LWARN);
615*c42754fdSRobin Zhang 
616*c42754fdSRobin Zhang 	sd->bias_cur[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_HALRM);
617*c42754fdSRobin Zhang 	sd->bias_cur[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_LALRM);
618*c42754fdSRobin Zhang 	sd->bias_cur[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_HWARN);
619*c42754fdSRobin Zhang 	sd->bias_cur[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_LWARN);
620*c42754fdSRobin Zhang 
621*c42754fdSRobin Zhang 	sd->tx_power[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_HALRM);
622*c42754fdSRobin Zhang 	sd->tx_power[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_LALRM);
623*c42754fdSRobin Zhang 	sd->tx_power[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_HWARN);
624*c42754fdSRobin Zhang 	sd->tx_power[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_LWARN);
625*c42754fdSRobin Zhang 
626*c42754fdSRobin Zhang 	sd->rx_power[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_HALRM);
627*c42754fdSRobin Zhang 	sd->rx_power[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_LALRM);
628*c42754fdSRobin Zhang 	sd->rx_power[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_HWARN);
629*c42754fdSRobin Zhang 	sd->rx_power[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_LWARN);
630*c42754fdSRobin Zhang 
631*c42754fdSRobin Zhang 
632*c42754fdSRobin Zhang 	/* Channel Specific Data */
633*c42754fdSRobin Zhang 	for (i = 0; i < SFF_MAX_CHANNEL_NUM; i++) {
634*c42754fdSRobin Zhang 		sd->scd[i].bias_cur = SFF_OFFSET_TO_U16(sff_8636_tx_bias_offset[i]);
635*c42754fdSRobin Zhang 		sd->scd[i].rx_power = SFF_OFFSET_TO_U16(sff_8636_rx_power_offset[i]);
636*c42754fdSRobin Zhang 		sd->scd[i].tx_power = SFF_OFFSET_TO_U16(sff_8636_tx_power_offset[i]);
637*c42754fdSRobin Zhang 	}
638*c42754fdSRobin Zhang 
639*c42754fdSRobin Zhang }
640*c42754fdSRobin Zhang 
sff_8636_show_dom(const uint8_t * data,uint32_t eeprom_len,struct rte_tel_data * d)641*c42754fdSRobin Zhang static void sff_8636_show_dom(const uint8_t *data, uint32_t eeprom_len, struct rte_tel_data *d)
642*c42754fdSRobin Zhang {
643*c42754fdSRobin Zhang 	struct sff_diags sd = {0};
644*c42754fdSRobin Zhang 	const char *rx_power_string = NULL;
645*c42754fdSRobin Zhang 	char power_string[SFF_MAX_DESC_SIZE];
646*c42754fdSRobin Zhang 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
647*c42754fdSRobin Zhang 	int i;
648*c42754fdSRobin Zhang 
649*c42754fdSRobin Zhang 	/*
650*c42754fdSRobin Zhang 	 * There is no clear identifier to signify the existence of
651*c42754fdSRobin Zhang 	 * optical diagnostics similar to SFF-8472. So checking existence
652*c42754fdSRobin Zhang 	 * of page 3, will provide the guarantee for existence of alarms
653*c42754fdSRobin Zhang 	 * and thresholds
654*c42754fdSRobin Zhang 	 * If pagging support exists, then supports_alarms is marked as 1
655*c42754fdSRobin Zhang 	 */
656*c42754fdSRobin Zhang 
657*c42754fdSRobin Zhang 	if (eeprom_len == RTE_ETH_MODULE_SFF_8636_MAX_LEN) {
658*c42754fdSRobin Zhang 		if (!(data[SFF_8636_STATUS_2_OFFSET] &
659*c42754fdSRobin Zhang 					SFF_8636_STATUS_PAGE_3_PRESENT)) {
660*c42754fdSRobin Zhang 			sd.supports_alarms = 1;
661*c42754fdSRobin Zhang 		}
662*c42754fdSRobin Zhang 	}
663*c42754fdSRobin Zhang 
664*c42754fdSRobin Zhang 	sd.rx_power_type = data[SFF_8636_DIAG_TYPE_OFFSET] &
665*c42754fdSRobin Zhang 						SFF_8636_RX_PWR_TYPE_MASK;
666*c42754fdSRobin Zhang 	sd.tx_power_type = data[SFF_8636_DIAG_TYPE_OFFSET] &
667*c42754fdSRobin Zhang 						SFF_8636_RX_PWR_TYPE_MASK;
668*c42754fdSRobin Zhang 
669*c42754fdSRobin Zhang 	sff_8636_dom_parse(data, &sd);
670*c42754fdSRobin Zhang 
671*c42754fdSRobin Zhang 	SFF_SPRINT_TEMP(val_string, sd.sfp_temp[SFF_MCURR]);
672*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Module temperature", val_string);
673*c42754fdSRobin Zhang 
674*c42754fdSRobin Zhang 	SFF_SPRINT_VCC(val_string, sd.sfp_voltage[SFF_MCURR]);
675*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Module voltage", val_string);
676*c42754fdSRobin Zhang 
677*c42754fdSRobin Zhang 	/*
678*c42754fdSRobin Zhang 	 * SFF-8636/8436 spec is not clear whether RX power/ TX bias
679*c42754fdSRobin Zhang 	 * current fields are supported or not. A valid temperature
680*c42754fdSRobin Zhang 	 * reading is used as existence for TX/RX power.
681*c42754fdSRobin Zhang 	 */
682*c42754fdSRobin Zhang 	if ((sd.sfp_temp[SFF_MCURR] == 0x0) ||
683*c42754fdSRobin Zhang 	    (sd.sfp_temp[SFF_MCURR] == (int16_t)0xFFFF))
684*c42754fdSRobin Zhang 		return;
685*c42754fdSRobin Zhang 
686*c42754fdSRobin Zhang 	ssf_add_dict_string(d, "Alarm/warning flags implemented",
687*c42754fdSRobin Zhang 			(sd.supports_alarms ? "Yes" : "No"));
688*c42754fdSRobin Zhang 
689*c42754fdSRobin Zhang 	for (i = 0; i < SFF_MAX_CHANNEL_NUM; i++) {
690*c42754fdSRobin Zhang 		snprintf(power_string, SFF_MAX_DESC_SIZE, "%s (Channel %d)",
691*c42754fdSRobin Zhang 					"Laser tx bias current", i+1);
692*c42754fdSRobin Zhang 		SFF_SPRINT_BIAS(val_string, sd.scd[i].bias_cur);
693*c42754fdSRobin Zhang 		ssf_add_dict_string(d, power_string, val_string);
694*c42754fdSRobin Zhang 	}
695*c42754fdSRobin Zhang 
696*c42754fdSRobin Zhang 	for (i = 0; i < SFF_MAX_CHANNEL_NUM; i++) {
697*c42754fdSRobin Zhang 		snprintf(power_string, SFF_MAX_DESC_SIZE, "%s (Channel %d)",
698*c42754fdSRobin Zhang 					"Transmit avg optical power", i+1);
699*c42754fdSRobin Zhang 		SFF_SPRINT_xX_PWR(val_string, sd.scd[i].tx_power);
700*c42754fdSRobin Zhang 		ssf_add_dict_string(d, power_string, val_string);
701*c42754fdSRobin Zhang 	}
702*c42754fdSRobin Zhang 
703*c42754fdSRobin Zhang 	if (!sd.rx_power_type)
704*c42754fdSRobin Zhang 		rx_power_string = "Receiver signal OMA";
705*c42754fdSRobin Zhang 	else
706*c42754fdSRobin Zhang 		rx_power_string = "Rcvr signal avg optical power";
707*c42754fdSRobin Zhang 
708*c42754fdSRobin Zhang 	for (i = 0; i < SFF_MAX_CHANNEL_NUM; i++) {
709*c42754fdSRobin Zhang 		snprintf(power_string, SFF_MAX_DESC_SIZE, "%s(Channel %d)",
710*c42754fdSRobin Zhang 					rx_power_string, i+1);
711*c42754fdSRobin Zhang 		SFF_SPRINT_xX_PWR(val_string, sd.scd[i].rx_power);
712*c42754fdSRobin Zhang 		ssf_add_dict_string(d, power_string, val_string);
713*c42754fdSRobin Zhang 	}
714*c42754fdSRobin Zhang 
715*c42754fdSRobin Zhang 	if (sd.supports_alarms) {
716*c42754fdSRobin Zhang 		for (i = 0; sff_8636_aw_flags[i].str; ++i) {
717*c42754fdSRobin Zhang 			ssf_add_dict_string(d, sff_8636_aw_flags[i].str,
718*c42754fdSRobin Zhang 					data[sff_8636_aw_flags[i].offset]
719*c42754fdSRobin Zhang 					& sff_8636_aw_flags[i].value ? "On" : "Off");
720*c42754fdSRobin Zhang 		}
721*c42754fdSRobin Zhang 
722*c42754fdSRobin Zhang 		sff_show_thresholds(sd, d);
723*c42754fdSRobin Zhang 	}
724*c42754fdSRobin Zhang 
725*c42754fdSRobin Zhang }
sff_8636_show_all(const uint8_t * data,uint32_t eeprom_len,struct rte_tel_data * d)726*c42754fdSRobin Zhang void sff_8636_show_all(const uint8_t *data, uint32_t eeprom_len, struct rte_tel_data *d)
727*c42754fdSRobin Zhang {
728*c42754fdSRobin Zhang 	sff_8636_show_identifier(data, d);
729*c42754fdSRobin Zhang 	if ((data[SFF_8636_ID_OFFSET] == SFF_8024_ID_QSFP) ||
730*c42754fdSRobin Zhang 		(data[SFF_8636_ID_OFFSET] == SFF_8024_ID_QSFP_PLUS) ||
731*c42754fdSRobin Zhang 		(data[SFF_8636_ID_OFFSET] == SFF_8024_ID_QSFP28)) {
732*c42754fdSRobin Zhang 		sff_8636_show_ext_identifier(data, d);
733*c42754fdSRobin Zhang 		sff_8636_show_connector(data, d);
734*c42754fdSRobin Zhang 		sff_8636_show_transceiver(data, d);
735*c42754fdSRobin Zhang 		sff_8636_show_encoding(data, d);
736*c42754fdSRobin Zhang 		sff_show_value_with_unit(data, SFF_8636_BR_NOMINAL_OFFSET,
737*c42754fdSRobin Zhang 				"BR, Nominal", 100, "Mbps", d);
738*c42754fdSRobin Zhang 		sff_8636_show_rate_identifier(data, d);
739*c42754fdSRobin Zhang 		sff_show_value_with_unit(data, SFF_8636_SM_LEN_OFFSET,
740*c42754fdSRobin Zhang 			     "Length (SMF,km)", 1, "km", d);
741*c42754fdSRobin Zhang 		sff_show_value_with_unit(data, SFF_8636_OM3_LEN_OFFSET,
742*c42754fdSRobin Zhang 				"Length (OM3 50um)", 2, "m", d);
743*c42754fdSRobin Zhang 		sff_show_value_with_unit(data, SFF_8636_OM2_LEN_OFFSET,
744*c42754fdSRobin Zhang 				"Length (OM2 50um)", 1, "m", d);
745*c42754fdSRobin Zhang 		sff_show_value_with_unit(data, SFF_8636_OM1_LEN_OFFSET,
746*c42754fdSRobin Zhang 			     "Length (OM1 62.5um)", 1, "m", d);
747*c42754fdSRobin Zhang 		sff_show_value_with_unit(data, SFF_8636_CBL_LEN_OFFSET,
748*c42754fdSRobin Zhang 			     "Length (Copper or Active cable)", 1, "m", d);
749*c42754fdSRobin Zhang 		sff_8636_show_wavelength_or_copper_compliance(data, d);
750*c42754fdSRobin Zhang 		sff_show_ascii(data, SFF_8636_VENDOR_NAME_START_OFFSET,
751*c42754fdSRobin Zhang 			     SFF_8636_VENDOR_NAME_END_OFFSET, "Vendor name", d);
752*c42754fdSRobin Zhang 		sff_8636_show_oui(data, d);
753*c42754fdSRobin Zhang 		sff_show_ascii(data, SFF_8636_VENDOR_PN_START_OFFSET,
754*c42754fdSRobin Zhang 			     SFF_8636_VENDOR_PN_END_OFFSET, "Vendor PN", d);
755*c42754fdSRobin Zhang 		sff_show_ascii(data, SFF_8636_VENDOR_REV_START_OFFSET,
756*c42754fdSRobin Zhang 			     SFF_8636_VENDOR_REV_END_OFFSET, "Vendor rev", d);
757*c42754fdSRobin Zhang 		sff_show_ascii(data, SFF_8636_VENDOR_SN_START_OFFSET,
758*c42754fdSRobin Zhang 			     SFF_8636_VENDOR_SN_END_OFFSET, "Vendor SN", d);
759*c42754fdSRobin Zhang 		sff_show_ascii(data, SFF_8636_DATE_YEAR_OFFSET,
760*c42754fdSRobin Zhang 			     SFF_8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code", d);
761*c42754fdSRobin Zhang 		sff_8636_show_revision_compliance(data, d);
762*c42754fdSRobin Zhang 		sff_8636_show_dom(data, eeprom_len, d);
763*c42754fdSRobin Zhang 	}
764*c42754fdSRobin Zhang }
765