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
ifconfig_sfp_id_is_qsfp(enum sfp_id id)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