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