cvmx-helper-sfp.h 14 KB

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