xref: /dpdk/lib/ethdev/sff_common.c (revision 8f1d23ece06adff5eae9f1b4365bdbbd3abee2b2)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2022 Intel Corporation
3  * Implements SFF-8024 Rev 4.0 of pluggable I/O configuration and some
4  * common utilities for SFF-8436/8636 and SFF-8472/8079
5  */
6 
7 #include <math.h>
8 
9 #include "sff_common.h"
10 
11 double sff_convert_mw_to_dbm(double mw)
12 {
13 	return (10. * log10(mw / 1000.)) + 30.;
14 }
15 
16 void sff_show_value_with_unit(const uint8_t *data, unsigned int reg,
17 			      const char *name, unsigned int mult,
18 			      const char *unit, struct rte_tel_data *d)
19 {
20 	unsigned int val = data[reg];
21 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
22 
23 	snprintf(val_string, sizeof(val_string), "%u%s", val * mult, unit);
24 	ssf_add_dict_string(d, name, val_string);
25 }
26 
27 void sff_show_ascii(const uint8_t *data, unsigned int first_reg,
28 		    unsigned int last_reg, const char *name, struct rte_tel_data *d)
29 {
30 	unsigned int reg, val;
31 	char tmp[3];
32 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
33 
34 	memset(val_string, 0, sizeof(val_string));
35 
36 	while (first_reg <= last_reg && data[last_reg] == ' ')
37 		last_reg--;
38 	for (reg = first_reg; reg <= last_reg; reg++) {
39 		val = data[reg];
40 		if ((val >= 32) && (val <= 126)) {
41 			snprintf(tmp, sizeof(tmp), "%c", val);
42 			strlcat(val_string, tmp, sizeof(val_string));
43 		} else {
44 			strlcat(val_string, "_", sizeof(val_string));
45 		}
46 	}
47 	ssf_add_dict_string(d, name, val_string);
48 }
49 
50 void sff_8024_show_oui(const uint8_t *data, int id_offset, struct rte_tel_data *d)
51 {
52 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
53 
54 	snprintf(val_string, sizeof(val_string), "%02x:%02x:%02x",
55 		data[id_offset], data[(id_offset) + 1], data[(id_offset) + 2]);
56 	ssf_add_dict_string(d, "Vendor OUI", val_string);
57 }
58 
59 void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct rte_tel_data *d)
60 {
61 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
62 
63 	snprintf(val_string, sizeof(val_string), "0x%02x", data[id_offset]);
64 
65 	switch (data[id_offset]) {
66 	case SFF_8024_ID_UNKNOWN:
67 		strlcat(val_string, " (no module present, unknown, or unspecified)",
68 			sizeof(val_string));
69 		break;
70 	case SFF_8024_ID_GBIC:
71 		strlcat(val_string, " (GBIC)", sizeof(val_string));
72 		break;
73 	case SFF_8024_ID_SOLDERED_MODULE:
74 		strlcat(val_string, " (module soldered to motherboard)", sizeof(val_string));
75 		break;
76 	case SFF_8024_ID_SFP:
77 		strlcat(val_string, " (SFP)", sizeof(val_string));
78 		break;
79 	case SFF_8024_ID_300_PIN_XBI:
80 		strlcat(val_string, " (300 pin XBI)", sizeof(val_string));
81 		break;
82 	case SFF_8024_ID_XENPAK:
83 		strlcat(val_string, " (XENPAK)", sizeof(val_string));
84 		break;
85 	case SFF_8024_ID_XFP:
86 		strlcat(val_string, " (XFP)", sizeof(val_string));
87 		break;
88 	case SFF_8024_ID_XFF:
89 		strlcat(val_string, " (XFF)", sizeof(val_string));
90 		break;
91 	case SFF_8024_ID_XFP_E:
92 		strlcat(val_string, " (XFP-E)", sizeof(val_string));
93 		break;
94 	case SFF_8024_ID_XPAK:
95 		strlcat(val_string, " (XPAK)", sizeof(val_string));
96 		break;
97 	case SFF_8024_ID_X2:
98 		strlcat(val_string, " (X2)", sizeof(val_string));
99 		break;
100 	case SFF_8024_ID_DWDM_SFP:
101 		strlcat(val_string, " (DWDM-SFP)", sizeof(val_string));
102 		break;
103 	case SFF_8024_ID_QSFP:
104 		strlcat(val_string, " (QSFP)", sizeof(val_string));
105 		break;
106 	case SFF_8024_ID_QSFP_PLUS:
107 		strlcat(val_string, " (QSFP+)", sizeof(val_string));
108 		break;
109 	case SFF_8024_ID_CXP:
110 		strlcat(val_string, " (CXP)", sizeof(val_string));
111 		break;
112 	case SFF_8024_ID_HD4X:
113 		strlcat(val_string, " (Shielded Mini Multilane HD 4X)", sizeof(val_string));
114 		break;
115 	case SFF_8024_ID_HD8X:
116 		strlcat(val_string, " (Shielded Mini Multilane HD 8X)", sizeof(val_string));
117 		break;
118 	case SFF_8024_ID_QSFP28:
119 		strlcat(val_string, " (QSFP28)", sizeof(val_string));
120 		break;
121 	case SFF_8024_ID_CXP2:
122 		strlcat(val_string, " (CXP2/CXP28)", sizeof(val_string));
123 		break;
124 	case SFF_8024_ID_CDFP:
125 		strlcat(val_string, " (CDFP Style 1/Style 2)", sizeof(val_string));
126 		break;
127 	case SFF_8024_ID_HD4X_FANOUT:
128 		strlcat(val_string, " (Shielded Mini Multilane HD 4X Fanout Cable)",
129 			sizeof(val_string));
130 		break;
131 	case SFF_8024_ID_HD8X_FANOUT:
132 		strlcat(val_string, " (Shielded Mini Multilane HD 8X Fanout Cable)",
133 			sizeof(val_string));
134 		break;
135 	case SFF_8024_ID_CDFP_S3:
136 		strlcat(val_string, " (CDFP Style 3)", sizeof(val_string));
137 		break;
138 	case SFF_8024_ID_MICRO_QSFP:
139 		strlcat(val_string, " (microQSFP)", sizeof(val_string));
140 		break;
141 	default:
142 		strlcat(val_string, " (reserved or unknown)", sizeof(val_string));
143 		break;
144 	}
145 	ssf_add_dict_string(d, "Identifier", val_string);
146 }
147 
148 void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct rte_tel_data *d)
149 {
150 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
151 
152 	snprintf(val_string, sizeof(val_string), "0x%02x", data[ctor_offset]);
153 
154 	switch (data[ctor_offset]) {
155 	case  SFF_8024_CTOR_UNKNOWN:
156 		strlcat(val_string, " (unknown or unspecified)", sizeof(val_string));
157 		break;
158 	case SFF_8024_CTOR_SC:
159 		strlcat(val_string, " (SC)", sizeof(val_string));
160 		break;
161 	case SFF_8024_CTOR_FC_STYLE_1:
162 		strlcat(val_string, " (Fibre Channel Style 1 copper)", sizeof(val_string));
163 		break;
164 	case SFF_8024_CTOR_FC_STYLE_2:
165 		strlcat(val_string, " (Fibre Channel Style 2 copper)", sizeof(val_string));
166 		break;
167 	case SFF_8024_CTOR_BNC_TNC:
168 		strlcat(val_string, " (BNC/TNC)", sizeof(val_string));
169 		break;
170 	case SFF_8024_CTOR_FC_COAX:
171 		strlcat(val_string, " (Fibre Channel coaxial headers)", sizeof(val_string));
172 		break;
173 	case SFF_8024_CTOR_FIBER_JACK:
174 		strlcat(val_string, " (FibreJack)", sizeof(val_string));
175 		break;
176 	case SFF_8024_CTOR_LC:
177 		strlcat(val_string, " (LC)", sizeof(val_string));
178 		break;
179 	case SFF_8024_CTOR_MT_RJ:
180 		strlcat(val_string, " (MT-RJ)", sizeof(val_string));
181 		break;
182 	case SFF_8024_CTOR_MU:
183 		strlcat(val_string, " (MU)", sizeof(val_string));
184 		break;
185 	case SFF_8024_CTOR_SG:
186 		strlcat(val_string, " (SG)", sizeof(val_string));
187 		break;
188 	case SFF_8024_CTOR_OPT_PT:
189 		strlcat(val_string, " (Optical pigtail)", sizeof(val_string));
190 		break;
191 	case SFF_8024_CTOR_MPO:
192 		strlcat(val_string, " (MPO Parallel Optic)", sizeof(val_string));
193 		break;
194 	case SFF_8024_CTOR_MPO_2:
195 		strlcat(val_string, " (MPO Parallel Optic - 2x16)", sizeof(val_string));
196 		break;
197 	case SFF_8024_CTOR_HSDC_II:
198 		strlcat(val_string, " (HSSDC II)", sizeof(val_string));
199 		break;
200 	case SFF_8024_CTOR_COPPER_PT:
201 		strlcat(val_string, " (Copper pigtail)", sizeof(val_string));
202 		break;
203 	case SFF_8024_CTOR_RJ45:
204 		strlcat(val_string, " (RJ45)", sizeof(val_string));
205 		break;
206 	case SFF_8024_CTOR_NO_SEPARABLE:
207 		strlcat(val_string, " (No separable connector)", sizeof(val_string));
208 		break;
209 	case SFF_8024_CTOR_MXC_2x16:
210 		strlcat(val_string, " (MXC 2x16)", sizeof(val_string));
211 		break;
212 	default:
213 		strlcat(val_string, " (reserved or unknown)", sizeof(val_string));
214 		break;
215 	}
216 	ssf_add_dict_string(d, "Connector", val_string);
217 }
218 
219 void sff_8024_show_encoding(const uint8_t *data, int encoding_offset,
220 			    int sff_type, struct rte_tel_data *d)
221 {
222 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
223 
224 	snprintf(val_string, sizeof(val_string), "0x%02x", data[encoding_offset]);
225 
226 	switch (data[encoding_offset]) {
227 	case SFF_8024_ENCODING_UNSPEC:
228 		strlcat(val_string, " (unspecified)", sizeof(val_string));
229 		break;
230 	case SFF_8024_ENCODING_8B10B:
231 		strlcat(val_string, " (8B/10B)", sizeof(val_string));
232 		break;
233 	case SFF_8024_ENCODING_4B5B:
234 		strlcat(val_string, " (4B/5B)", sizeof(val_string));
235 		break;
236 	case SFF_8024_ENCODING_NRZ:
237 		strlcat(val_string, " (NRZ)", sizeof(val_string));
238 		break;
239 	case SFF_8024_ENCODING_4h:
240 		if (sff_type == RTE_ETH_MODULE_SFF_8472)
241 			strlcat(val_string, " (Manchester)", sizeof(val_string));
242 		else if (sff_type == RTE_ETH_MODULE_SFF_8636)
243 			strlcat(val_string, " (SONET Scrambled)", sizeof(val_string));
244 		break;
245 	case SFF_8024_ENCODING_5h:
246 		if (sff_type == RTE_ETH_MODULE_SFF_8472)
247 			strlcat(val_string, " (SONET Scrambled)", sizeof(val_string));
248 		else if (sff_type == RTE_ETH_MODULE_SFF_8636)
249 			strlcat(val_string, " (64B/66B)", sizeof(val_string));
250 		break;
251 	case SFF_8024_ENCODING_6h:
252 		if (sff_type == RTE_ETH_MODULE_SFF_8472)
253 			strlcat(val_string, " (64B/66B)", sizeof(val_string));
254 		else if (sff_type == RTE_ETH_MODULE_SFF_8636)
255 			strlcat(val_string, " (Manchester)", sizeof(val_string));
256 		break;
257 	case SFF_8024_ENCODING_256B:
258 		strlcat(val_string,
259 		       " ((256B/257B (transcoded FEC-enabled data))", sizeof(val_string));
260 		break;
261 	case SFF_8024_ENCODING_PAM4:
262 		strlcat(val_string, " (PAM4)", sizeof(val_string));
263 		break;
264 	default:
265 		strlcat(val_string, " (reserved or unknown)", sizeof(val_string));
266 		break;
267 	}
268 	ssf_add_dict_string(d, "Encoding", val_string);
269 }
270 
271 void sff_show_thresholds(struct sff_diags sd, struct rte_tel_data *d)
272 {
273 	char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
274 
275 	SFF_SPRINT_BIAS(val_string, sd.bias_cur[SFF_HALRM]);
276 	ssf_add_dict_string(d, "Laser bias current high alarm threshold", val_string);
277 	SFF_SPRINT_BIAS(val_string, sd.bias_cur[SFF_LALRM]);
278 	ssf_add_dict_string(d, "Laser bias current low alarm threshold", val_string);
279 	SFF_SPRINT_BIAS(val_string, sd.bias_cur[SFF_HWARN]);
280 	ssf_add_dict_string(d, "Laser bias current high warning threshold", val_string);
281 	SFF_SPRINT_BIAS(val_string, sd.bias_cur[SFF_LWARN]);
282 	ssf_add_dict_string(d, "Laser bias current low warning threshold", val_string);
283 
284 	SFF_SPRINT_xX_PWR(val_string, sd.tx_power[SFF_HALRM]);
285 	ssf_add_dict_string(d, "Laser output power high alarm threshold", val_string);
286 	SFF_SPRINT_xX_PWR(val_string, sd.tx_power[SFF_LALRM]);
287 	ssf_add_dict_string(d, "Laser output power low alarm threshold", val_string);
288 	SFF_SPRINT_xX_PWR(val_string, sd.tx_power[SFF_HWARN]);
289 	ssf_add_dict_string(d, "Laser output power high warning threshold", val_string);
290 	SFF_SPRINT_xX_PWR(val_string, sd.tx_power[SFF_LWARN]);
291 	ssf_add_dict_string(d, "Laser output power low warning threshold", val_string);
292 
293 	SFF_SPRINT_TEMP(val_string, sd.sfp_temp[SFF_HALRM]);
294 	ssf_add_dict_string(d, "Module temperature high alarm threshold", val_string);
295 	SFF_SPRINT_TEMP(val_string, sd.sfp_temp[SFF_LALRM]);
296 	ssf_add_dict_string(d, "Module temperature low alarm threshold", val_string);
297 	SFF_SPRINT_TEMP(val_string, sd.sfp_temp[SFF_HWARN]);
298 	ssf_add_dict_string(d, "Module temperature high warning threshold", val_string);
299 	SFF_SPRINT_TEMP(val_string, sd.sfp_temp[SFF_LWARN]);
300 	ssf_add_dict_string(d, "Module temperature low warning threshold", val_string);
301 
302 	SFF_SPRINT_VCC(val_string, sd.sfp_voltage[SFF_HALRM]);
303 	ssf_add_dict_string(d, "Module voltage high alarm threshold", val_string);
304 	SFF_SPRINT_VCC(val_string, sd.sfp_voltage[SFF_LALRM]);
305 	ssf_add_dict_string(d, "Module voltage low alarm threshold", val_string);
306 	SFF_SPRINT_VCC(val_string, sd.sfp_voltage[SFF_HWARN]);
307 	ssf_add_dict_string(d, "Module voltage high warning threshold", val_string);
308 	SFF_SPRINT_VCC(val_string, sd.sfp_voltage[SFF_LWARN]);
309 	ssf_add_dict_string(d, "Module voltage low alarm threshold", val_string);
310 
311 	SFF_SPRINT_xX_PWR(val_string, sd.rx_power[SFF_HALRM]);
312 	ssf_add_dict_string(d, "Laser rx power high alarm threshold", val_string);
313 	SFF_SPRINT_xX_PWR(val_string, sd.rx_power[SFF_LALRM]);
314 	ssf_add_dict_string(d, "Laser rx power low alarm threshold", val_string);
315 	SFF_SPRINT_xX_PWR(val_string, sd.rx_power[SFF_HWARN]);
316 	ssf_add_dict_string(d, "Laser rx power high warning threshold", val_string);
317 	SFF_SPRINT_xX_PWR(val_string, sd.rx_power[SFF_LWARN]);
318 	ssf_add_dict_string(d, "Laser rx power low warning threshold", val_string);
319 }
320