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 * $FreeBSD$ 27 */ 28 29 #pragma once 30 31 #include <stdbool.h> 32 #include <stdint.h> 33 34 #include <libifconfig.h> 35 #include <libifconfig_sfp_tables.h> 36 37 /** SFP module information in raw numeric form 38 * These are static properties of the hardware. 39 */ 40 struct ifconfig_sfp_info; 41 42 /** SFP module information formatted as strings 43 * These are static strings that do not need to be freed. 44 */ 45 struct ifconfig_sfp_info_strings; 46 47 #define SFF_VENDOR_STRING_SIZE 16 /**< max chars in a vendor string */ 48 #define SFF_VENDOR_DATE_SIZE 6 /**< chars in a vendor date code */ 49 50 /** SFP module vendor info strings */ 51 struct ifconfig_sfp_vendor_info { 52 char name[SFF_VENDOR_STRING_SIZE + 1]; /**< vendor name */ 53 char pn[SFF_VENDOR_STRING_SIZE + 1]; /**< vendor part number */ 54 char sn[SFF_VENDOR_STRING_SIZE + 1]; /**< vendor serial number */ 55 char date[SFF_VENDOR_DATE_SIZE + 5]; /**< formatted vendor date */ 56 }; 57 58 /** SFP module status 59 * These are dynamic properties of the hardware. 60 */ 61 struct ifconfig_sfp_status { 62 double temp; /**< module temperature in degrees C, 63 valid range -40.0 to 125.0 */ 64 double voltage; /**< module voltage in volts */ 65 struct sfp_channel { 66 uint16_t rx; /**< channel receive power, LSB 0.1uW */ 67 uint16_t tx; /**< channel transmit bias current, LSB 2uA */ 68 } *channel; /**< array of channel rx/tx status */ 69 uint32_t bitrate; /**< link bitrate, 70 only present for QSFP modules, 71 zero for SFP modules */ 72 }; 73 74 #define SFF_DUMP_SIZE 256 /**< size of the memory dump buffer */ 75 76 #define SFP_DUMP_START 0 /**< start address of an SFP module dump */ 77 #define SFP_DUMP_SIZE 128 /**< bytes in an SFP module dump */ 78 79 #define QSFP_DUMP0_START 0 /**< start address of the first region 80 in a QSFP module dump */ 81 #define QSFP_DUMP0_SIZE 82 /**< bytes in the first region 82 in a QSFP module dump */ 83 #define QSFP_DUMP1_START 128 /**< start address of the second region 84 in a QSFP module dump */ 85 #define QSFP_DUMP1_SIZE 128 /**< bytes in the second region 86 in a QSFP module dump */ 87 88 /** SFP module I2C memory dump 89 * SFP modules have one region, QSFP modules have two regions. 90 */ 91 struct ifconfig_sfp_dump { 92 uint8_t data[SFF_DUMP_SIZE]; /**< memory dump data */ 93 }; 94 95 /** Get information about the static properties of an SFP/QSFP module 96 * The information is returned in numeric form. 97 * @see ifconfig_sfp_get_sfp_info_strings to get corresponding strings. 98 * @param h An open ifconfig state handle 99 * @param name The name of an interface 100 * @param sfp Pointer to an object to fill, will be zeroed by this function 101 * @return 0 if successful, -1 with error info set in the handle otherwise 102 */ 103 int ifconfig_sfp_get_sfp_info(ifconfig_handle_t *h, const char *name, 104 struct ifconfig_sfp_info *sfp); 105 106 /** Get the number of channels present on the given module 107 * @param sfp Pointer to a filled SFP module info object 108 * @return The number of channels or 0 if unknown 109 */ 110 size_t ifconfig_sfp_channel_count(const struct ifconfig_sfp_info *sfp); 111 112 /** Is the given module ID a QSFP 113 * NB: This convenience function is implemented in the header to keep the 114 * classification criteria visible to the user. 115 * @param id The sfp_id field of a SFP module info object 116 * @return A bool true if QSFP-type sfp_id otherwise false 117 */ 118 static inline bool 119 ifconfig_sfp_id_is_qsfp(enum sfp_id id) 120 { 121 switch (id) { 122 case SFP_ID_QSFP: 123 case SFP_ID_QSFPPLUS: 124 case SFP_ID_QSFP28: 125 return (true); 126 default: 127 return (false); 128 } 129 } 130 131 /** Get string descriptions of the given SFP/QSFP module info 132 * The strings are static and do not need to be freed. 133 * @see ifconfig_sfp_get_sfp_info to obtain the input info. 134 * @param sfp Pointer to a filled SFP module info object 135 * @param strings Pointer to an object to be filled with pointers to 136 * static strings describing the given info 137 */ 138 void ifconfig_sfp_get_sfp_info_strings(const struct ifconfig_sfp_info *sfp, 139 struct ifconfig_sfp_info_strings *strings); 140 141 /** Get a string describing the given SFP/QSFP module's physical layer spec 142 * The correct field in ifconfig_sfp_info varies depending on the module. This 143 * function chooses the appropriate string based on the provided module info. 144 * The string returned is static and does not need to be freed. 145 * @param sfp Pointer to a filled SFP module info object 146 * @param strings Pointer to a filled SFP module strings object 147 * @return Pointer to a static string describing the module's spec 148 */ 149 const char *ifconfig_sfp_physical_spec(const struct ifconfig_sfp_info *sfp, 150 const struct ifconfig_sfp_info_strings *strings); 151 152 /** Get the vendor info strings from an SFP/QSFP module 153 * @param h An open ifconfig state handle 154 * @param name The name of an interface 155 * @param vi Pointer to an object to be filled with the vendor info strings, 156 * will be zeroed by this function 157 * @return 0 if successful, -1 with error info set in the handle otherwise 158 */ 159 int ifconfig_sfp_get_sfp_vendor_info(ifconfig_handle_t *h, const char *name, 160 struct ifconfig_sfp_vendor_info *vi); 161 162 /** Get the status of an SFP/QSFP module's dynamic properties 163 * @see ifconfig_sfp_free_sfp_status to free the allocations 164 * @param h An open ifconfig state handle 165 * @param name The name of an interface 166 * @param ss Pointer to an object to be filled with the module's status 167 * @return 0 if successful, -1 with error info set in the handle otherwise 168 * where the errcode `ENXIO` indicates an SFP module that is not 169 * calibrated or does not provide diagnostic status measurements 170 */ 171 int ifconfig_sfp_get_sfp_status(ifconfig_handle_t *h, const char *name, 172 struct ifconfig_sfp_status *ss); 173 174 /** Free the memory allocations in an ifconfig_sfp_status struct 175 * @param ss Pointer to an object whose internal allocations are to be freed 176 * if not NULL 177 */ 178 void ifconfig_sfp_free_sfp_status(struct ifconfig_sfp_status *ss); 179 180 /** Dump the I2C memory of an SFP/QSFP module 181 * SFP modules have one memory region dumped, QSFP modules have two. 182 * @param h An open ifconfig state handle 183 * @param name The name of an interface 184 * @param buf Pointer to a dump data buffer object 185 * @return 0 if successful, -1 with error info set in the handle otherwise 186 */ 187 int ifconfig_sfp_get_sfp_dump(ifconfig_handle_t *h, const char *name, 188 struct ifconfig_sfp_dump *buf); 189 190 /** Get the number of I2C memory dump regions present in the given dump 191 * @param dp Pointer to a filled dump data buffer object 192 * @return The number of regions or 0 if unknown 193 */ 194 size_t ifconfig_sfp_dump_region_count(const struct ifconfig_sfp_dump *dp); 195 196 /** Convert channel power to milliwatts power 197 * This is provided as a convenience for displaying channel power levels. 198 * @see (struct ifconfig_sfp_status).channel 199 * @param power Power in 0.1 mW units 200 * @return Power in milliwatts (mW) 201 */ 202 double power_mW(uint16_t power); 203 204 /** Convert channel power to decibel-milliwats power level 205 * This is provided as a convenience for displaying channel power levels. 206 * @see (struct ifconfig_sfp_status).channel 207 * @param power Power in 0.1 mW units 208 * @return Power level in decibel-milliwatts (dBm) 209 */ 210 211 double power_dBm(uint16_t power); 212 213 /** Convert channel bias current to milliamps 214 * This is provided as a convenience for displaying channel bias currents. 215 * @see (struct ifconfig_sfp_status).channel 216 * @param bias Bias current in 2 mA units 217 * @return Bias current in milliamps (mA) 218 */ 219 double bias_mA(uint16_t bias); 220