xref: /freebsd/lib/libifconfig/libifconfig_sfp.h (revision 1d386b48)
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