1 /*- 2 * Copyright (c) 2014, Alexander V. Chernikov 3 * Copyright (c) 2020, Ryan Moeller <freqlabs@FreeBSD.org> 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #pragma once 28 29 #include <stdbool.h> 30 #include <stdint.h> 31 32 #include <libifconfig.h> 33 #include <libifconfig_sfp_tables.h> 34 35 /** SFP module information in raw numeric form 36 * These are static properties of the hardware. 37 */ 38 struct ifconfig_sfp_info; 39 40 /** SFP module information formatted as strings 41 * These are static strings that do not need to be freed. 42 */ 43 struct ifconfig_sfp_info_strings; 44 45 #define SFF_VENDOR_STRING_SIZE 16 /**< max chars in a vendor string */ 46 #define SFF_VENDOR_DATE_SIZE 6 /**< chars in a vendor date code */ 47 48 /** SFP module vendor info strings */ 49 struct ifconfig_sfp_vendor_info { 50 char name[SFF_VENDOR_STRING_SIZE + 1]; /**< vendor name */ 51 char pn[SFF_VENDOR_STRING_SIZE + 1]; /**< vendor part number */ 52 char sn[SFF_VENDOR_STRING_SIZE + 1]; /**< vendor serial number */ 53 char date[SFF_VENDOR_DATE_SIZE + 5]; /**< formatted vendor date */ 54 }; 55 56 /** SFP module status 57 * These are dynamic properties of the hardware. 58 */ 59 struct ifconfig_sfp_status { 60 double temp; /**< module temperature in degrees C, 61 valid range -40.0 to 125.0 */ 62 double voltage; /**< module voltage in volts */ 63 struct sfp_channel { 64 uint16_t rx; /**< channel receive power, LSB 0.1uW */ 65 uint16_t tx; /**< channel transmit bias current, LSB 2uA */ 66 } *channel; /**< array of channel rx/tx status */ 67 uint32_t bitrate; /**< link bitrate, 68 only present for QSFP modules, 69 zero for SFP modules */ 70 }; 71 72 #define SFF_DUMP_SIZE 256 /**< size of the memory dump buffer */ 73 74 #define SFP_DUMP_START 0 /**< start address of an SFP module dump */ 75 #define SFP_DUMP_SIZE 128 /**< bytes in an SFP module dump */ 76 77 #define QSFP_DUMP0_START 0 /**< start address of the first region 78 in a QSFP module dump */ 79 #define QSFP_DUMP0_SIZE 82 /**< bytes in the first region 80 in a QSFP module dump */ 81 #define QSFP_DUMP1_START 128 /**< start address of the second region 82 in a QSFP module dump */ 83 #define QSFP_DUMP1_SIZE 128 /**< bytes in the second region 84 in a QSFP module dump */ 85 86 /** SFP module I2C memory dump 87 * SFP modules have one region, QSFP modules have two regions. 88 */ 89 struct ifconfig_sfp_dump { 90 uint8_t data[SFF_DUMP_SIZE]; /**< memory dump data */ 91 }; 92 93 /** Get information about the static properties of an SFP/QSFP module 94 * The information is returned in numeric form. 95 * @see ifconfig_sfp_get_sfp_info_strings to get corresponding strings. 96 * @param h An open ifconfig state handle 97 * @param name The name of an interface 98 * @param sfp Pointer to an object to fill, will be zeroed by this function 99 * @return 0 if successful, -1 with error info set in the handle otherwise 100 */ 101 int ifconfig_sfp_get_sfp_info(ifconfig_handle_t *h, const char *name, 102 struct ifconfig_sfp_info *sfp); 103 104 /** Get the number of channels present on the given module 105 * @param sfp Pointer to a filled SFP module info object 106 * @return The number of channels or 0 if unknown 107 */ 108 size_t ifconfig_sfp_channel_count(const struct ifconfig_sfp_info *sfp); 109 110 /** Is the given module ID a QSFP 111 * NB: This convenience function is implemented in the header to keep the 112 * classification criteria visible to the user. 113 * @param id The sfp_id field of a SFP module info object 114 * @return A bool true if QSFP-type sfp_id otherwise false 115 */ 116 static inline bool 117 ifconfig_sfp_id_is_qsfp(enum sfp_id id) 118 { 119 switch (id) { 120 case SFP_ID_QSFP: 121 case SFP_ID_QSFPPLUS: 122 case SFP_ID_QSFP28: 123 return (true); 124 default: 125 return (false); 126 } 127 } 128 129 /** Get string descriptions of the given SFP/QSFP module info 130 * The strings are static and do not need to be freed. 131 * @see ifconfig_sfp_get_sfp_info to obtain the input info. 132 * @param sfp Pointer to a filled SFP module info object 133 * @param strings Pointer to an object to be filled with pointers to 134 * static strings describing the given info 135 */ 136 void ifconfig_sfp_get_sfp_info_strings(const struct ifconfig_sfp_info *sfp, 137 struct ifconfig_sfp_info_strings *strings); 138 139 /** Get a string describing the given SFP/QSFP module's physical layer spec 140 * The correct field in ifconfig_sfp_info varies depending on the module. This 141 * function chooses the appropriate string based on the provided module info. 142 * The string returned is static and does not need to be freed. 143 * @param sfp Pointer to a filled SFP module info object 144 * @param strings Pointer to a filled SFP module strings object 145 * @return Pointer to a static string describing the module's spec 146 */ 147 const char *ifconfig_sfp_physical_spec(const struct ifconfig_sfp_info *sfp, 148 const struct ifconfig_sfp_info_strings *strings); 149 150 /** Get the vendor info strings from an SFP/QSFP module 151 * @param h An open ifconfig state handle 152 * @param name The name of an interface 153 * @param vi Pointer to an object to be filled with the vendor info strings, 154 * will be zeroed by this function 155 * @return 0 if successful, -1 with error info set in the handle otherwise 156 */ 157 int ifconfig_sfp_get_sfp_vendor_info(ifconfig_handle_t *h, const char *name, 158 struct ifconfig_sfp_vendor_info *vi); 159 160 /** Get the status of an SFP/QSFP module's dynamic properties 161 * @see ifconfig_sfp_free_sfp_status to free the allocations 162 * @param h An open ifconfig state handle 163 * @param name The name of an interface 164 * @param ss Pointer to an object to be filled with the module's status 165 * @return 0 if successful, -1 with error info set in the handle otherwise 166 * where the errcode `ENXIO` indicates an SFP module that is not 167 * calibrated or does not provide diagnostic status measurements 168 */ 169 int ifconfig_sfp_get_sfp_status(ifconfig_handle_t *h, const char *name, 170 struct ifconfig_sfp_status *ss); 171 172 /** Free the memory allocations in an ifconfig_sfp_status struct 173 * @param ss Pointer to an object whose internal allocations are to be freed 174 * if not NULL 175 */ 176 void ifconfig_sfp_free_sfp_status(struct ifconfig_sfp_status *ss); 177 178 /** Dump the I2C memory of an SFP/QSFP module 179 * SFP modules have one memory region dumped, QSFP modules have two. 180 * @param h An open ifconfig state handle 181 * @param name The name of an interface 182 * @param buf Pointer to a dump data buffer object 183 * @return 0 if successful, -1 with error info set in the handle otherwise 184 */ 185 int ifconfig_sfp_get_sfp_dump(ifconfig_handle_t *h, const char *name, 186 struct ifconfig_sfp_dump *buf); 187 188 /** Get the number of I2C memory dump regions present in the given dump 189 * @param dp Pointer to a filled dump data buffer object 190 * @return The number of regions or 0 if unknown 191 */ 192 size_t ifconfig_sfp_dump_region_count(const struct ifconfig_sfp_dump *dp); 193 194 /** Convert channel power to milliwatts power 195 * This is provided as a convenience for displaying channel power levels. 196 * @see (struct ifconfig_sfp_status).channel 197 * @param power Power in 0.1 mW units 198 * @return Power in milliwatts (mW) 199 */ 200 double power_mW(uint16_t power); 201 202 /** Convert channel power to decibel-milliwats power level 203 * This is provided as a convenience for displaying channel power levels. 204 * @see (struct ifconfig_sfp_status).channel 205 * @param power Power in 0.1 mW units 206 * @return Power level in decibel-milliwatts (dBm) 207 */ 208 209 double power_dBm(uint16_t power); 210 211 /** Convert channel bias current to milliamps 212 * This is provided as a convenience for displaying channel bias currents. 213 * @see (struct ifconfig_sfp_status).channel 214 * @param bias Bias current in 2 mA units 215 * @return Bias current in milliamps (mA) 216 */ 217 double bias_mA(uint16_t bias); 218