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