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
sff_convert_mw_to_dbm(double mw)11 double sff_convert_mw_to_dbm(double mw)
12 {
13 return (10. * log10(mw / 1000.)) + 30.;
14 }
15
sff_show_value_with_unit(const uint8_t * data,unsigned int reg,const char * name,unsigned int mult,const char * unit,struct rte_tel_data * d)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
sff_show_ascii(const uint8_t * data,unsigned int first_reg,unsigned int last_reg,const char * name,struct rte_tel_data * d)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
sff_8024_show_oui(const uint8_t * data,int id_offset,struct rte_tel_data * d)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
sff_8024_show_identifier(const uint8_t * data,int id_offset,struct rte_tel_data * d)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
sff_8024_show_connector(const uint8_t * data,int ctor_offset,struct rte_tel_data * d)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
sff_8024_show_encoding(const uint8_t * data,int encoding_offset,int sff_type,struct rte_tel_data * d)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
sff_show_thresholds(struct sff_diags sd,struct rte_tel_data * d)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