Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* |
| 3 | * Copyright (C) 2020 Marvell International Ltd. |
| 4 | * |
| 5 | * Helper functions to abstract SFP and QSFP connectors |
| 6 | */ |
| 7 | |
| 8 | #ifndef __CVMX_HELPER_SFP_H__ |
| 9 | #define __CVMX_HELPER_SFP_H__ |
| 10 | |
| 11 | /** |
| 12 | * Maximum size for the SFP EEPROM. Currently only 96 bytes are used. |
| 13 | */ |
| 14 | #define CVMX_SFP_MAX_EEPROM_SIZE 0x100 |
| 15 | |
| 16 | /** |
| 17 | * Default address of sfp EEPROM |
| 18 | */ |
| 19 | #define CVMX_SFP_DEFAULT_I2C_ADDR 0x50 |
| 20 | |
| 21 | /** |
| 22 | * Default address of SFP diagnostics chip |
| 23 | */ |
| 24 | #define CVMX_SFP_DEFAULT_DIAG_I2C_ADDR 0x51 |
| 25 | |
| 26 | struct cvmx_fdt_sfp_info; |
| 27 | struct cvmx_fdt_gpio_info; |
| 28 | /** |
| 29 | * Connector type for module, usually we only see SFP and QSFPP |
| 30 | */ |
| 31 | enum cvmx_phy_sfp_conn_type { |
| 32 | CVMX_SFP_CONN_GBIC = 0x01, /** GBIC */ |
| 33 | CVMX_SFP_CONN_SFP = 0x03, /** SFP/SFP+/SFP28 */ |
| 34 | CVMX_SFP_CONN_QSFP = 0x0C, /** 1G QSFP (obsolete) */ |
| 35 | CVMX_SFP_CONN_QSFPP = 0x0D, /** QSFP+ or later */ |
| 36 | CVMX_SFP_CONN_QSFP28 = 0x11, /** QSFP28 (100Gbps) */ |
| 37 | CVMX_SFP_CONN_MICRO_QSFP = 0x17, /** Micro QSFP */ |
| 38 | CVMX_SFP_CONN_QSFP_DD = 0x18, /** QSFP-DD Double Density 8X */ |
| 39 | CVMX_SFP_CONN_SFP_DD = 0x1A, /** SFP-DD Double Density 2X */ |
| 40 | }; |
| 41 | |
| 42 | /** |
| 43 | * module type plugged into a SFP/SFP+/QSFP+ port |
| 44 | */ |
| 45 | enum cvmx_phy_sfp_mod_type { |
| 46 | CVMX_SFP_MOD_UNKNOWN = 0, /** Unknown or unspecified */ |
| 47 | /** Fiber optic module (LC connector) */ |
| 48 | CVMX_SFP_MOD_OPTICAL_LC = 0x7, |
| 49 | /** Multiple optical */ |
| 50 | CVMX_SFP_MOD_MULTIPLE_OPTICAL = 0x9, |
| 51 | /** Fiber optic module (pigtail, no connector) */ |
| 52 | CVMX_SFP_MOD_OPTICAL_PIGTAIL = 0xB, |
| 53 | CVMX_SFP_MOD_COPPER_PIGTAIL = 0x21, /** copper module */ |
| 54 | CVMX_SFP_MOD_RJ45 = 0x22, /** RJ45 (i.e. 10GBase-T) */ |
| 55 | /** No separable connector (SFP28/copper) */ |
| 56 | CVMX_SFP_MOD_NO_SEP_CONN = 0x23, |
| 57 | /** MXC 2X16 */ |
| 58 | CVMX_SFP_MOD_MXC_2X16 = 0x24, |
| 59 | /** CS optical connector */ |
| 60 | CVMX_SFP_MOD_CS_OPTICAL = 0x25, |
| 61 | /** Mini CS optical connector */ |
| 62 | CVMX_SFP_MOD_MINI_CS_OPTICAL = 0x26, |
| 63 | /** Unknown/other module type */ |
| 64 | CVMX_SFP_MOD_OTHER |
| 65 | }; |
| 66 | |
| 67 | /** Peak rate supported by SFP cable */ |
| 68 | enum cvmx_phy_sfp_rate { |
| 69 | CVMX_SFP_RATE_UNKNOWN, /** Unknown rate */ |
| 70 | CVMX_SFP_RATE_1G, /** 1Gbps */ |
| 71 | CVMX_SFP_RATE_10G, /** 10Gbps */ |
| 72 | CVMX_SFP_RATE_25G, /** 25Gbps */ |
| 73 | CVMX_SFP_RATE_40G, /** 40Gbps */ |
| 74 | CVMX_SFP_RATE_100G /** 100Gbps */ |
| 75 | }; |
| 76 | |
| 77 | /** |
| 78 | * Cable compliance specification |
| 79 | * See table 4-4 from SFF-8024 for the extended specification compliance codes |
| 80 | */ |
| 81 | enum cvmx_phy_sfp_cable_ext_compliance { |
| 82 | CVMX_SFP_CABLE_UNSPEC = 0, |
| 83 | CVMX_SFP_CABLE_100G_25GAUI_C2M_AOC_HIGH_BER = 0x01, /** Active optical cable */ |
| 84 | CVMX_SFP_CABLE_100G_SR4_25G_SR = 0x2, |
| 85 | CVMX_SFP_CABLE_100G_LR4_25G_LR = 0x3, |
| 86 | CVMX_SFP_CABLE_100G_ER4_25G_ER = 0x4, |
| 87 | CVMX_SFP_CABLE_100G_SR10 = 0x5, |
| 88 | CVMX_SFP_CABLE_100G_CWDM4_MSA = 0x6, |
| 89 | CVMX_SFP_CABLE_100G_PSM4 = 0x7, |
| 90 | CVMX_SFP_CABLE_100G_25GAUI_C2M_ACC_HIGH_BER = 0x8, |
| 91 | CVMX_SFP_CABLE_100G_CWDM4 = 0x9, |
| 92 | CVMX_SFP_CABLE_100G_CR4_25G_CR_CA_L = 0xB, |
| 93 | CVMX_SFP_CABLE_25G_CR_CA_S = 0xC, |
| 94 | CVMX_SFP_CABLE_25G_CR_CA_N = 0xD, |
| 95 | CVMX_SFP_CABLE_40G_ER4 = 0x10, |
| 96 | CVMX_SFP_CABLE_4X10G_SR = 0x11, |
| 97 | CVMX_SFP_CABLE_40G_PSM4 = 0x12, |
| 98 | CVMX_SFP_CABLE_G959_1_P1I1_2D1 = 0x13, |
| 99 | CVMX_SFP_CABLE_G959_1_P1S1_2D2 = 0x14, |
| 100 | CVMX_SFP_CABLE_G959_1_P1L1_2D2 = 0x15, |
| 101 | CVMX_SFP_CABLE_10GBASE_T = 0x16, |
| 102 | CVMX_SFP_CABLE_100G_CLR4 = 0x17, |
| 103 | CVMX_SFP_CABLE_100G_25GAUI_C2M_AOC_LOW_BER = 0x18, |
| 104 | CVMX_SFP_CABLE_100G_25GAUI_C2M_ACC_LOW_BER = 0x19, |
| 105 | CVMX_SFP_CABLE_100G_2_LAMBDA_DWDM = 0x1a, |
| 106 | CVMX_SFP_CABLE_100G_1550NM_WDM = 0x1b, |
| 107 | CVMX_SFP_CABLE_10GBASE_T_SR = 0x1c, |
| 108 | CVMX_SFP_CABLE_5GBASE_T = 0x1d, |
| 109 | CVMX_SFP_CABLE_2_5GBASE_T = 0x1e, |
| 110 | CVMX_SFP_CABLE_40G_SWDM4 = 0x1f, |
| 111 | CVMX_SFP_CABLE_100G_SWDM4 = 0x20, |
| 112 | CVMX_SFP_CABLE_100G_PAM4_BIDI = 0x21, |
| 113 | CVMX_SFP_CABLE_100G_4WDM_10_FEC_HOST = 0x22, |
| 114 | CVMX_SFP_CABLE_100G_4WDM_20_FEC_HOST = 0x23, |
| 115 | CVMX_SFP_CABLE_100G_4WDM_40_FEC_HOST = 0x24, |
| 116 | CVMX_SFP_CABLE_100GBASE_DR_CAUI4_NO_FEC = 0x25, |
| 117 | CVMX_SFP_CABLE_100G_FR_CAUI4_NO_FEC = 0x26, |
| 118 | CVMX_SFP_CABLE_100G_LR_CAUI4_NO_FEC = 0x27, |
| 119 | CVMX_SFP_CABLE_ACTIVE_COPPER_50_100_200GAUI_LOW_BER = 0x30, |
| 120 | CVMX_SFP_CABLE_ACTIVE_OPTICAL_50_100_200GAUI_LOW_BER = 0x31, |
| 121 | CVMX_SFP_CABLE_ACTIVE_COPPER_50_100_200GAUI_HI_BER = 0x32, |
| 122 | CVMX_SFP_CABLE_ACTIVE_OPTICAL_50_100_200GAUI_HI_BER = 0x33, |
| 123 | CVMX_SFP_CABLE_50_100_200G_CR = 0x40, |
| 124 | CVMX_SFP_CABLE_50_100_200G_SR = 0x41, |
| 125 | CVMX_SFP_CABLE_50GBASE_FR_200GBASE_DR4 = 0x42, |
| 126 | CVMX_SFP_CABLE_200GBASE_FR4 = 0x43, |
| 127 | CVMX_SFP_CABLE_200G_1550NM_PSM4 = 0x44, |
| 128 | CVMX_SFP_CABLE_50GBASE_LR = 0x45, |
| 129 | CVMX_SFP_CABLE_200GBASE_LR4 = 0x46, |
| 130 | CVMX_SFP_CABLE_64GFC_EA = 0x50, |
| 131 | CVMX_SFP_CABLE_64GFC_SW = 0x51, |
| 132 | CVMX_SFP_CABLE_64GFC_LW = 0x52, |
| 133 | CVMX_SFP_CABLE_128GFC_EA = 0x53, |
| 134 | CVMX_SFP_CABLE_128GFC_SW = 0x54, |
| 135 | CVMX_SFP_CABLE_128GFC_LW = 0x55, |
| 136 | |
| 137 | }; |
| 138 | |
| 139 | /** Optical modes module is compliant with */ |
| 140 | enum cvmx_phy_sfp_10g_eth_compliance { |
| 141 | CVMX_SFP_CABLE_10GBASE_ER = 0x80, /** 10G ER */ |
| 142 | CVMX_SFP_CABLE_10GBASE_LRM = 0x40, /** 10G LRM */ |
| 143 | CVMX_SFP_CABLE_10GBASE_LR = 0x20, /** 10G LR */ |
| 144 | CVMX_SFP_CABLE_10GBASE_SR = 0x10 /** 10G SR */ |
| 145 | }; |
| 146 | |
| 147 | /** Diagnostic ASIC compatibility */ |
| 148 | enum cvmx_phy_sfp_sff_8472_diag_rev { |
| 149 | CVMX_SFP_SFF_8472_NO_DIAG = 0x00, |
| 150 | CVMX_SFP_SFF_8472_REV_9_3 = 0x01, |
| 151 | CVMX_SFP_SFF_8472_REV_9_5 = 0x02, |
| 152 | CVMX_SFP_SFF_8472_REV_10_2 = 0x03, |
| 153 | CVMX_SFP_SFF_8472_REV_10_4 = 0x04, |
| 154 | CVMX_SFP_SFF_8472_REV_11_0 = 0x05, |
| 155 | CVMX_SFP_SFF_8472_REV_11_3 = 0x06, |
| 156 | CVMX_SFP_SFF_8472_REV_11_4 = 0x07, |
| 157 | CVMX_SFP_SFF_8472_REV_12_0 = 0x08, |
| 158 | CVMX_SFP_SFF_8472_REV_UNALLOCATED = 0xff |
| 159 | }; |
| 160 | |
| 161 | /** |
| 162 | * Data structure describing the current SFP or QSFP EEPROM |
| 163 | */ |
| 164 | struct cvmx_sfp_mod_info { |
| 165 | enum cvmx_phy_sfp_conn_type conn_type; /** Connector type */ |
| 166 | enum cvmx_phy_sfp_mod_type mod_type; /** Module type */ |
| 167 | enum cvmx_phy_sfp_rate rate; /** Rate of module */ |
| 168 | /** 10G Ethernet Compliance codes (logical OR) */ |
| 169 | enum cvmx_phy_sfp_10g_eth_compliance eth_comp; |
| 170 | /** Extended Cable compliance */ |
| 171 | enum cvmx_phy_sfp_cable_ext_compliance cable_comp; |
| 172 | u8 vendor_name[17]; /** Module vendor name */ |
| 173 | u8 vendor_oui[3]; /** vendor OUI */ |
| 174 | u8 vendor_pn[17]; /** Vendor part number */ |
| 175 | u8 vendor_rev[5]; /** Vendor revision */ |
| 176 | u8 vendor_sn[17]; /** Vendor serial number */ |
| 177 | u8 date_code[9]; /** Date code */ |
| 178 | bool valid; /** True if module is valid */ |
| 179 | bool active_cable; /** False for passive copper */ |
| 180 | bool copper_cable; /** True if cable is copper */ |
| 181 | /** True if module is limiting (i.e. not passive copper) */ |
| 182 | bool limiting; |
| 183 | /** Maximum length of copper cable in meters */ |
| 184 | int max_copper_cable_len; |
| 185 | /** Max single mode cable length in meters */ |
| 186 | int max_single_mode_cable_length; |
| 187 | /** Max 50um OM2 cable length */ |
| 188 | int max_50um_om2_cable_length; |
| 189 | /** Max 62.5um OM1 cable length */ |
| 190 | int max_62_5um_om1_cable_length; |
| 191 | /** Max 50um OM4 cable length */ |
| 192 | int max_50um_om4_cable_length; |
| 193 | /** Max 50um OM3 cable length */ |
| 194 | int max_50um_om3_cable_length; |
| 195 | /** Minimum bitrate in Mbps */ |
| 196 | int bitrate_min; |
| 197 | /** Maximum bitrate in Mbps */ |
| 198 | int bitrate_max; |
| 199 | /** |
| 200 | * Set to true if forward error correction is required, |
| 201 | * for example, a 25GBase-CR CA-S cable. |
| 202 | * |
| 203 | * FEC should only be disabled at 25G with CA-N cables. FEC is required |
| 204 | * with 5M and longer cables. |
| 205 | */ |
| 206 | bool fec_required; |
| 207 | /** True if RX output is linear */ |
| 208 | bool linear_rx_output; |
| 209 | /** Power level, can be 1, 2 or 3 */ |
| 210 | int power_level; |
| 211 | /** False if conventional cooling is used, true for active cooling */ |
| 212 | bool cooled_laser; |
| 213 | /** True if internal retimer or clock and data recovery circuit */ |
| 214 | bool internal_cdr; |
| 215 | /** True if LoS is implemented */ |
| 216 | bool los_implemented; |
| 217 | /** True if LoS is inverted from the standard */ |
| 218 | bool los_inverted; |
| 219 | /** True if TX_FAULT is implemented */ |
| 220 | bool tx_fault_implemented; |
| 221 | /** True if TX_DISABLE is implemented */ |
| 222 | bool tx_disable_implemented; |
| 223 | /** True if RATE_SELECT is implemented */ |
| 224 | bool rate_select_implemented; |
| 225 | /** True if tuneable transmitter technology is used */ |
| 226 | bool tuneable_transmitter; |
| 227 | /** True if receiver decision threshold is implemented */ |
| 228 | bool rx_decision_threshold_implemented; |
| 229 | /** True if diagnostic monitoring present */ |
| 230 | bool diag_monitoring; |
| 231 | /** True if diagnostic address 0x7f is used for selecting the page */ |
| 232 | bool diag_paging; |
| 233 | /** Diagnostic feature revision */ |
| 234 | enum cvmx_phy_sfp_sff_8472_diag_rev diag_rev; |
| 235 | /** True if an address change sequence is required for diagnostics */ |
| 236 | bool diag_addr_change_required; |
| 237 | /** True if RX power is averaged, false if OMA */ |
| 238 | bool diag_rx_power_averaged; |
| 239 | /** True if diagnostics are externally calibrated */ |
| 240 | bool diag_externally_calibrated; |
| 241 | /** True if diagnostics are internally calibrated */ |
| 242 | bool diag_internally_calibrated; |
| 243 | /** True of soft rate select control implemented per SFF-8431 */ |
| 244 | bool diag_soft_rate_select_control; |
| 245 | /** True if application select control implemented per SFF-8079 */ |
| 246 | bool diag_app_select_control; |
| 247 | /** True if soft RATE_SELECT control and moonitoring implemented */ |
| 248 | bool diag_soft_rate_select_implemented; |
| 249 | /** True if soft RX_LOS monitoring implemented */ |
| 250 | bool diag_soft_rx_los_implemented; |
| 251 | /** True if soft TX_FAULT monitoring implemented */ |
| 252 | bool diag_soft_tx_fault_implemented; |
| 253 | /** True if soft TX_DISABLE control and monitoring implemented */ |
| 254 | bool diag_soft_tx_disable_implemented; |
| 255 | /** True if alarm/warning flags implemented */ |
| 256 | bool diag_alarm_warning_flags_implemented; |
| 257 | }; |
| 258 | |
| 259 | /** |
| 260 | * Reads the SFP EEPROM using the i2c bus |
| 261 | * |
| 262 | * @param[out] buffer Buffer to store SFP EEPROM data in |
| 263 | * The buffer should be SFP_MAX_EEPROM_SIZE bytes. |
| 264 | * @param i2c_bus i2c bus number to read from for SFP port |
| 265 | * @param i2c_addr i2c address to use, 0 for default |
| 266 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 267 | * Return: -1 if invalid bus or i2c read error, 0 for success |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 268 | */ |
| 269 | int cvmx_phy_sfp_read_i2c_eeprom(u8 *buffer, int i2c_bus, int i2c_addr); |
| 270 | |
| 271 | /** |
| 272 | * Reads the SFP/SFP+/QSFP EEPROM and outputs the type of module or cable |
| 273 | * plugged in |
| 274 | * |
| 275 | * @param[out] sfp_info Info about SFP module |
| 276 | * @param[in] buffer SFP EEPROM buffer to parse |
| 277 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 278 | * Return: 0 on success, -1 if error reading EEPROM or if EEPROM corrupt |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 279 | */ |
| 280 | int cvmx_phy_sfp_parse_eeprom(struct cvmx_sfp_mod_info *sfp_info, const u8 *buffer); |
| 281 | |
| 282 | /** |
| 283 | * Prints out information about a SFP/QSFP device |
| 284 | * |
| 285 | * @param[in] sfp_info data structure to print |
| 286 | */ |
| 287 | void cvmx_phy_sfp_print_info(const struct cvmx_sfp_mod_info *sfp_info); |
| 288 | |
| 289 | /** |
| 290 | * Reads and parses SFP/QSFP EEPROM |
| 291 | * |
| 292 | * @param sfp sfp handle to read |
| 293 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 294 | * Return: 0 for success, -1 on error. |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 295 | */ |
| 296 | int cvmx_sfp_read_i2c_eeprom(struct cvmx_fdt_sfp_info *sfp); |
| 297 | |
| 298 | /** |
| 299 | * Returns the information about a SFP/QSFP device |
| 300 | * |
| 301 | * @param sfp sfp handle |
| 302 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 303 | * Return: sfp_info Pointer sfp mod info data structure |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 304 | */ |
| 305 | const struct cvmx_sfp_mod_info *cvmx_phy_get_sfp_mod_info(const struct cvmx_fdt_sfp_info *sfp); |
| 306 | |
| 307 | /** |
| 308 | * Function called to check and return the status of the mod_abs pin or |
| 309 | * mod_pres pin for QSFPs. |
| 310 | * |
| 311 | * @param sfp Handle to SFP information. |
| 312 | * @param data User-defined data passed to the function |
| 313 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 314 | * Return: 0 if absent, 1 if present, -1 on error |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 315 | */ |
| 316 | int cvmx_sfp_check_mod_abs(struct cvmx_fdt_sfp_info *sfp, void *data); |
| 317 | |
| 318 | /** |
| 319 | * Registers a function to be called to check mod_abs/mod_pres for a SFP/QSFP |
| 320 | * slot. |
| 321 | * |
| 322 | * @param sfp Handle to SFP data structure |
| 323 | * @param check_mod_abs Function to be called or NULL to remove |
| 324 | * @param mod_abs_data User-defined data to be passed to check_mod_abs |
| 325 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 326 | * Return: 0 for success |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 327 | */ |
| 328 | int cvmx_sfp_register_check_mod_abs(struct cvmx_fdt_sfp_info *sfp, |
| 329 | int (*check_mod_abs)(struct cvmx_fdt_sfp_info *sfp, void *data), |
| 330 | void *mod_abs_data); |
| 331 | |
| 332 | /** |
| 333 | * Registers a function to be called whenever the mod_abs/mod_pres signal |
| 334 | * changes. |
| 335 | * |
| 336 | * @param sfp Handle to SFP data structure |
| 337 | * @param mod_abs_changed Function called whenever mod_abs is changed |
| 338 | * or NULL to remove. |
| 339 | * @param mod_abs_changed_data User-defined data passed to |
| 340 | * mod_abs_changed |
| 341 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 342 | * Return: 0 for success |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 343 | */ |
| 344 | int cvmx_sfp_register_mod_abs_changed(struct cvmx_fdt_sfp_info *sfp, |
| 345 | int (*mod_abs_changed)(struct cvmx_fdt_sfp_info *sfp, int val, |
| 346 | void *data), |
| 347 | void *mod_abs_changed_data); |
| 348 | |
| 349 | /** |
| 350 | * Function called to check and return the status of the tx_fault pin |
| 351 | * |
| 352 | * @param sfp Handle to SFP information. |
| 353 | * @param data User-defined data passed to the function |
| 354 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 355 | * Return: 0 if signal present, 1 if signal absent, -1 on error |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 356 | */ |
| 357 | int cvmx_sfp_check_tx_fault(struct cvmx_fdt_sfp_info *sfp, void *data); |
| 358 | |
| 359 | /** |
| 360 | * Function called to check and return the status of the rx_los pin |
| 361 | * |
| 362 | * @param sfp Handle to SFP information. |
| 363 | * @param data User-defined data passed to the function |
| 364 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 365 | * Return: 0 if signal present, 1 if signal absent, -1 on error |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 366 | */ |
| 367 | int cvmx_sfp_check_rx_los(struct cvmx_fdt_sfp_info *sfp, void *data); |
| 368 | |
| 369 | /** |
| 370 | * Registers a function to be called whenever rx_los changes |
| 371 | * |
| 372 | * @param sfp Handle to SFP data structure |
| 373 | * @param rx_los_changed Function to be called when rx_los changes |
| 374 | * or NULL to remove the function |
| 375 | * @param rx_los_changed_data User-defined data passed to |
| 376 | * rx_los_changed |
| 377 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 378 | * Return: 0 for success |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 379 | */ |
| 380 | int cvmx_sfp_register_rx_los_changed(struct cvmx_fdt_sfp_info *sfp, |
| 381 | int (*rx_los_changed)(struct cvmx_fdt_sfp_info *sfp, int val, |
| 382 | void *data), |
| 383 | void *rx_los_changed_data); |
| 384 | |
| 385 | /** |
| 386 | * Parses the device tree for SFP and QSFP slots |
| 387 | * |
| 388 | * @param fdt_addr Address of flat device-tree |
| 389 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 390 | * Return: 0 for success, -1 on error |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 391 | */ |
| 392 | int cvmx_sfp_parse_device_tree(const void *fdt_addr); |
| 393 | |
| 394 | /** |
| 395 | * Given an IPD port number find the corresponding SFP or QSFP slot |
| 396 | * |
| 397 | * @param ipd_port IPD port number to search for |
| 398 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 399 | * Return: pointer to SFP data structure or NULL if not found |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 400 | */ |
| 401 | struct cvmx_fdt_sfp_info *cvmx_sfp_find_slot_by_port(int ipd_port); |
| 402 | |
| 403 | /** |
| 404 | * Given a fdt node offset find the corresponding SFP or QSFP slot |
| 405 | * |
| 406 | * @param of_offset flat device tree node offset |
| 407 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 408 | * Return: pointer to SFP data structure or NULL if not found |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 409 | */ |
| 410 | struct cvmx_fdt_sfp_info *cvmx_sfp_find_slot_by_fdt_node(int of_offset); |
| 411 | |
| 412 | /** |
| 413 | * Reads the EEPROMs of all SFP modules. |
| 414 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 415 | * Return: 0 for success |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 416 | */ |
| 417 | int cvmx_sfp_read_all_modules(void); |
| 418 | |
| 419 | /** |
| 420 | * Validates if the module is correct for the specified port |
| 421 | * |
| 422 | * @param[in] sfp SFP port to check |
| 423 | * @param mode interface mode |
| 424 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 425 | * Return: true if module is valid, false if invalid |
Aaron Williams | 3bda89d | 2020-12-11 17:05:24 +0100 | [diff] [blame] | 426 | * NOTE: This will also toggle the error LED, if present |
| 427 | */ |
| 428 | bool cvmx_sfp_validate_module(struct cvmx_fdt_sfp_info *sfp, int mode); |
| 429 | |
| 430 | /** |
| 431 | * Prints information about the SFP module |
| 432 | * |
| 433 | * @param[in] sfp sfp data structure |
| 434 | */ |
| 435 | void cvmx_sfp_print_info(const struct cvmx_fdt_sfp_info *sfp); |
| 436 | |
| 437 | #endif /* __CVMX_HELPER_SFP_H__ */ |