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
9 #include "sff_common.h"
11 double sff_convert_mw_to_dbm(double mw)
13 return (10. * log10(mw / 1000.)) + 30.;
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)
20 unsigned int val = data[reg];
21 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
23 snprintf(val_string, sizeof(val_string), "%u%s", val * mult, unit);
24 ssf_add_dict_string(d, name, val_string);
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)
30 unsigned int reg, val;
32 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
34 memset(val_string, 0, sizeof(val_string));
36 while (first_reg <= last_reg && data[last_reg] == ' ')
38 for (reg = first_reg; reg <= last_reg; reg++) {
40 if ((val >= 32) && (val <= 126)) {
41 snprintf(tmp, sizeof(tmp), "%c", val);
42 strlcat(val_string, tmp, sizeof(val_string));
44 strlcat(val_string, "_", sizeof(val_string));
47 ssf_add_dict_string(d, name, val_string);
50 void sff_8024_show_oui(const uint8_t *data, int id_offset, struct rte_tel_data *d)
52 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
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);
59 void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct rte_tel_data *d)
61 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
63 snprintf(val_string, sizeof(val_string), "0x%02x", data[id_offset]);
65 switch (data[id_offset]) {
66 case SFF_8024_ID_UNKNOWN:
67 strlcat(val_string, " (no module present, unknown, or unspecified)",
70 case SFF_8024_ID_GBIC:
71 strlcat(val_string, " (GBIC)", sizeof(val_string));
73 case SFF_8024_ID_SOLDERED_MODULE:
74 strlcat(val_string, " (module soldered to motherboard)", sizeof(val_string));
77 strlcat(val_string, " (SFP)", sizeof(val_string));
79 case SFF_8024_ID_300_PIN_XBI:
80 strlcat(val_string, " (300 pin XBI)", sizeof(val_string));
82 case SFF_8024_ID_XENPAK:
83 strlcat(val_string, " (XENPAK)", sizeof(val_string));
86 strlcat(val_string, " (XFP)", sizeof(val_string));
89 strlcat(val_string, " (XFF)", sizeof(val_string));
91 case SFF_8024_ID_XFP_E:
92 strlcat(val_string, " (XFP-E)", sizeof(val_string));
94 case SFF_8024_ID_XPAK:
95 strlcat(val_string, " (XPAK)", sizeof(val_string));
98 strlcat(val_string, " (X2)", sizeof(val_string));
100 case SFF_8024_ID_DWDM_SFP:
101 strlcat(val_string, " (DWDM-SFP)", sizeof(val_string));
103 case SFF_8024_ID_QSFP:
104 strlcat(val_string, " (QSFP)", sizeof(val_string));
106 case SFF_8024_ID_QSFP_PLUS:
107 strlcat(val_string, " (QSFP+)", sizeof(val_string));
109 case SFF_8024_ID_CXP:
110 strlcat(val_string, " (CXP)", sizeof(val_string));
112 case SFF_8024_ID_HD4X:
113 strlcat(val_string, " (Shielded Mini Multilane HD 4X)", sizeof(val_string));
115 case SFF_8024_ID_HD8X:
116 strlcat(val_string, " (Shielded Mini Multilane HD 8X)", sizeof(val_string));
118 case SFF_8024_ID_QSFP28:
119 strlcat(val_string, " (QSFP28)", sizeof(val_string));
121 case SFF_8024_ID_CXP2:
122 strlcat(val_string, " (CXP2/CXP28)", sizeof(val_string));
124 case SFF_8024_ID_CDFP:
125 strlcat(val_string, " (CDFP Style 1/Style 2)", sizeof(val_string));
127 case SFF_8024_ID_HD4X_FANOUT:
128 strlcat(val_string, " (Shielded Mini Multilane HD 4X Fanout Cable)",
131 case SFF_8024_ID_HD8X_FANOUT:
132 strlcat(val_string, " (Shielded Mini Multilane HD 8X Fanout Cable)",
135 case SFF_8024_ID_CDFP_S3:
136 strlcat(val_string, " (CDFP Style 3)", sizeof(val_string));
138 case SFF_8024_ID_MICRO_QSFP:
139 strlcat(val_string, " (microQSFP)", sizeof(val_string));
142 strlcat(val_string, " (reserved or unknown)", sizeof(val_string));
145 ssf_add_dict_string(d, "Identifier", val_string);
148 void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct rte_tel_data *d)
150 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
152 snprintf(val_string, sizeof(val_string), "0x%02x", data[ctor_offset]);
154 switch (data[ctor_offset]) {
155 case SFF_8024_CTOR_UNKNOWN:
156 strlcat(val_string, " (unknown or unspecified)", sizeof(val_string));
158 case SFF_8024_CTOR_SC:
159 strlcat(val_string, " (SC)", sizeof(val_string));
161 case SFF_8024_CTOR_FC_STYLE_1:
162 strlcat(val_string, " (Fibre Channel Style 1 copper)", sizeof(val_string));
164 case SFF_8024_CTOR_FC_STYLE_2:
165 strlcat(val_string, " (Fibre Channel Style 2 copper)", sizeof(val_string));
167 case SFF_8024_CTOR_BNC_TNC:
168 strlcat(val_string, " (BNC/TNC)", sizeof(val_string));
170 case SFF_8024_CTOR_FC_COAX:
171 strlcat(val_string, " (Fibre Channel coaxial headers)", sizeof(val_string));
173 case SFF_8024_CTOR_FIBER_JACK:
174 strlcat(val_string, " (FibreJack)", sizeof(val_string));
176 case SFF_8024_CTOR_LC:
177 strlcat(val_string, " (LC)", sizeof(val_string));
179 case SFF_8024_CTOR_MT_RJ:
180 strlcat(val_string, " (MT-RJ)", sizeof(val_string));
182 case SFF_8024_CTOR_MU:
183 strlcat(val_string, " (MU)", sizeof(val_string));
185 case SFF_8024_CTOR_SG:
186 strlcat(val_string, " (SG)", sizeof(val_string));
188 case SFF_8024_CTOR_OPT_PT:
189 strlcat(val_string, " (Optical pigtail)", sizeof(val_string));
191 case SFF_8024_CTOR_MPO:
192 strlcat(val_string, " (MPO Parallel Optic)", sizeof(val_string));
194 case SFF_8024_CTOR_MPO_2:
195 strlcat(val_string, " (MPO Parallel Optic - 2x16)", sizeof(val_string));
197 case SFF_8024_CTOR_HSDC_II:
198 strlcat(val_string, " (HSSDC II)", sizeof(val_string));
200 case SFF_8024_CTOR_COPPER_PT:
201 strlcat(val_string, " (Copper pigtail)", sizeof(val_string));
203 case SFF_8024_CTOR_RJ45:
204 strlcat(val_string, " (RJ45)", sizeof(val_string));
206 case SFF_8024_CTOR_NO_SEPARABLE:
207 strlcat(val_string, " (No separable connector)", sizeof(val_string));
209 case SFF_8024_CTOR_MXC_2x16:
210 strlcat(val_string, " (MXC 2x16)", sizeof(val_string));
213 strlcat(val_string, " (reserved or unknown)", sizeof(val_string));
216 ssf_add_dict_string(d, "Connector", val_string);
219 void sff_8024_show_encoding(const uint8_t *data, int encoding_offset,
220 int sff_type, struct rte_tel_data *d)
222 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
224 snprintf(val_string, sizeof(val_string), "0x%02x", data[encoding_offset]);
226 switch (data[encoding_offset]) {
227 case SFF_8024_ENCODING_UNSPEC:
228 strlcat(val_string, " (unspecified)", sizeof(val_string));
230 case SFF_8024_ENCODING_8B10B:
231 strlcat(val_string, " (8B/10B)", sizeof(val_string));
233 case SFF_8024_ENCODING_4B5B:
234 strlcat(val_string, " (4B/5B)", sizeof(val_string));
236 case SFF_8024_ENCODING_NRZ:
237 strlcat(val_string, " (NRZ)", sizeof(val_string));
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));
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));
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));
257 case SFF_8024_ENCODING_256B:
259 " ((256B/257B (transcoded FEC-enabled data))", sizeof(val_string));
261 case SFF_8024_ENCODING_PAM4:
262 strlcat(val_string, " (PAM4)", sizeof(val_string));
265 strlcat(val_string, " (reserved or unknown)", sizeof(val_string));
268 ssf_add_dict_string(d, "Encoding", val_string);
271 void sff_show_thresholds(struct sff_diags sd, struct rte_tel_data *d)
273 char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
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);
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);
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);
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);
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);