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