1f732123eSAlexander V. Chernikov /*-
2f732123eSAlexander V. Chernikov * Copyright (c) 2014 Alexander V. Chernikov. All rights reserved.
3f732123eSAlexander V. Chernikov *
4f732123eSAlexander V. Chernikov * Redistribution and use in source and binary forms, with or without
5f732123eSAlexander V. Chernikov * modification, are permitted provided that the following conditions
6f732123eSAlexander V. Chernikov * are met:
7f732123eSAlexander V. Chernikov * 1. Redistributions of source code must retain the above copyright
8f732123eSAlexander V. Chernikov * notice, this list of conditions and the following disclaimer.
9f732123eSAlexander V. Chernikov * 2. Redistributions in binary form must reproduce the above copyright
10f732123eSAlexander V. Chernikov * notice, this list of conditions and the following disclaimer in the
11f732123eSAlexander V. Chernikov * documentation and/or other materials provided with the distribution.
12f732123eSAlexander V. Chernikov *
13f732123eSAlexander V. Chernikov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14f732123eSAlexander V. Chernikov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15f732123eSAlexander V. Chernikov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16f732123eSAlexander V. Chernikov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17f732123eSAlexander V. Chernikov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18f732123eSAlexander V. Chernikov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19f732123eSAlexander V. Chernikov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20f732123eSAlexander V. Chernikov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21f732123eSAlexander V. Chernikov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22f732123eSAlexander V. Chernikov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23f732123eSAlexander V. Chernikov * SUCH DAMAGE.
24f732123eSAlexander V. Chernikov */
25f732123eSAlexander V. Chernikov
26f732123eSAlexander V. Chernikov #include <sys/types.h>
27f732123eSAlexander V. Chernikov #include <sys/param.h>
28f732123eSAlexander V. Chernikov #include <sys/ioctl.h>
29f732123eSAlexander V. Chernikov #include <sys/socket.h>
30f732123eSAlexander V. Chernikov
31f732123eSAlexander V. Chernikov #include <net/if.h>
32c59adfc6SAlexander V. Chernikov #include <net/sff8436.h>
33f88c9741SAlexander V. Chernikov #include <net/sff8472.h>
34f732123eSAlexander V. Chernikov
35f732123eSAlexander V. Chernikov #include <math.h>
36f732123eSAlexander V. Chernikov #include <err.h>
37f732123eSAlexander V. Chernikov #include <errno.h>
38c59adfc6SAlexander V. Chernikov #include <fcntl.h>
3994cba803SRyan Moeller #include <stdbool.h>
40f732123eSAlexander V. Chernikov #include <stdio.h>
41f732123eSAlexander V. Chernikov #include <stdlib.h>
42f732123eSAlexander V. Chernikov #include <string.h>
43f732123eSAlexander V. Chernikov #include <unistd.h>
44f732123eSAlexander V. Chernikov
4594cba803SRyan Moeller #include <libutil.h>
4694cba803SRyan Moeller
4794cba803SRyan Moeller #include <libifconfig.h>
4894cba803SRyan Moeller #include <libifconfig_sfp.h>
4994cba803SRyan Moeller
50f732123eSAlexander V. Chernikov #include "ifconfig.h"
51f732123eSAlexander V. Chernikov
52f732123eSAlexander V. Chernikov void
sfp_status(if_ctx * ctx)530c2beef7SAlexander V. Chernikov sfp_status(if_ctx *ctx)
54f732123eSAlexander V. Chernikov {
5594cba803SRyan Moeller struct ifconfig_sfp_info info;
5694cba803SRyan Moeller struct ifconfig_sfp_info_strings strings;
5794cba803SRyan Moeller struct ifconfig_sfp_vendor_info vendor_info;
5894cba803SRyan Moeller struct ifconfig_sfp_status status;
5994cba803SRyan Moeller size_t channel_count;
600c2beef7SAlexander V. Chernikov int verbose = ctx->args->verbose;
61c59adfc6SAlexander V. Chernikov
62*85e0016aSAlexander V. Chernikov if (ifconfig_sfp_get_sfp_info(lifh, ctx->ifname, &info) == -1)
638b222425SRyan Moeller return;
6494cba803SRyan Moeller
6594cba803SRyan Moeller ifconfig_sfp_get_sfp_info_strings(&info, &strings);
6694cba803SRyan Moeller
6794cba803SRyan Moeller printf("\tplugged: %s %s (%s)\n",
6894cba803SRyan Moeller ifconfig_sfp_id_display(info.sfp_id),
6994cba803SRyan Moeller ifconfig_sfp_physical_spec(&info, &strings),
7094cba803SRyan Moeller strings.sfp_conn);
7194cba803SRyan Moeller
72*85e0016aSAlexander V. Chernikov if (ifconfig_sfp_get_sfp_vendor_info(lifh, ctx->ifname, &vendor_info) == -1)
738b222425SRyan Moeller return;
7494cba803SRyan Moeller
7594cba803SRyan Moeller printf("\tvendor: %s PN: %s SN: %s DATE: %s\n",
7694cba803SRyan Moeller vendor_info.name, vendor_info.pn, vendor_info.sn, vendor_info.date);
7794cba803SRyan Moeller
7894cba803SRyan Moeller if (ifconfig_sfp_id_is_qsfp(info.sfp_id)) {
7994cba803SRyan Moeller if (verbose > 1)
8094cba803SRyan Moeller printf("\tcompliance level: %s\n", strings.sfp_rev);
8194cba803SRyan Moeller } else {
8294cba803SRyan Moeller if (verbose > 5) {
8394cba803SRyan Moeller printf("Class: %s\n",
8494cba803SRyan Moeller ifconfig_sfp_physical_spec(&info, &strings));
8594cba803SRyan Moeller printf("Length: %s\n", strings.sfp_fc_len);
8694cba803SRyan Moeller printf("Tech: %s\n", strings.sfp_cab_tech);
8794cba803SRyan Moeller printf("Media: %s\n", strings.sfp_fc_media);
8894cba803SRyan Moeller printf("Speed: %s\n", strings.sfp_fc_speed);
8980c7cc1cSPedro F. Giffuni }
90f732123eSAlexander V. Chernikov }
91f732123eSAlexander V. Chernikov
92*85e0016aSAlexander V. Chernikov if (ifconfig_sfp_get_sfp_status(lifh, ctx->ifname, &status) == 0) {
9394cba803SRyan Moeller if (ifconfig_sfp_id_is_qsfp(info.sfp_id) && verbose > 1)
9494cba803SRyan Moeller printf("\tnominal bitrate: %u Mbps\n", status.bitrate);
9594cba803SRyan Moeller printf("\tmodule temperature: %.2f C voltage: %.2f Volts\n",
9694cba803SRyan Moeller status.temp, status.voltage);
9794cba803SRyan Moeller channel_count = ifconfig_sfp_channel_count(&info);
9894cba803SRyan Moeller for (size_t chan = 0; chan < channel_count; ++chan) {
9994cba803SRyan Moeller uint16_t rx = status.channel[chan].rx;
10094cba803SRyan Moeller uint16_t tx = status.channel[chan].tx;
10194cba803SRyan Moeller printf("\tlane %zu: "
10294cba803SRyan Moeller "RX power: %.2f mW (%.2f dBm) TX bias: %.2f mA\n",
10394cba803SRyan Moeller chan + 1, power_mW(rx), power_dBm(rx), bias_mA(tx));
10494cba803SRyan Moeller }
10594cba803SRyan Moeller ifconfig_sfp_free_sfp_status(&status);
10694cba803SRyan Moeller }
10794cba803SRyan Moeller
10894cba803SRyan Moeller if (verbose > 2) {
10994cba803SRyan Moeller struct ifconfig_sfp_dump dump;
11094cba803SRyan Moeller
111*85e0016aSAlexander V. Chernikov if (ifconfig_sfp_get_sfp_dump(lifh, ctx->ifname, &dump) == -1)
1128b222425SRyan Moeller return;
11394cba803SRyan Moeller
11494cba803SRyan Moeller if (ifconfig_sfp_id_is_qsfp(info.sfp_id)) {
11594cba803SRyan Moeller printf("\n\tSFF8436 DUMP (0xA0 128..255 range):\n");
11694cba803SRyan Moeller hexdump(dump.data + QSFP_DUMP1_START, QSFP_DUMP1_SIZE,
11794cba803SRyan Moeller "\t", HD_OMIT_COUNT | HD_OMIT_CHARS);
11894cba803SRyan Moeller printf("\n\tSFF8436 DUMP (0xA0 0..81 range):\n");
11994cba803SRyan Moeller hexdump(dump.data + QSFP_DUMP0_START, QSFP_DUMP0_SIZE,
12094cba803SRyan Moeller "\t", HD_OMIT_COUNT | HD_OMIT_CHARS);
12194cba803SRyan Moeller } else {
12294cba803SRyan Moeller printf("\n\tSFF8472 DUMP (0xA0 0..127 range):\n");
12394cba803SRyan Moeller hexdump(dump.data + SFP_DUMP_START, SFP_DUMP_SIZE,
12494cba803SRyan Moeller "\t", HD_OMIT_COUNT | HD_OMIT_CHARS);
12594cba803SRyan Moeller }
12694cba803SRyan Moeller }
12794cba803SRyan Moeller }
128