diff --git a/CMakeLists.txt b/CMakeLists.txt index 41838a4846fc..783e5d5084d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,9 @@ mark_as_advanced(OPAE_MINIMAL_BUILD) option(OPAE_BUILD_TESTS "Enable building of OPAE unit tests" OFF) mark_as_advanced(OPAE_BUILD_TESTS) +option(OPAE_WITH_QSFPINFO_QSFPPRINT "Enable qsfpinfo print qsfp" OFF) +mark_as_advanced(OPAE_WITH_QSFPINFO_QSFPPRINT) + ############################################################################ ## Python Interpreter/Build Env ########################################### ############################################################################ @@ -982,6 +985,7 @@ set(CPACK_COMPONENTS_ALL toolfpgadiagapps toolpackager tooluserclk + toolqsfpinfo toolras toolcoreidle toolmmlink @@ -1049,6 +1053,7 @@ define_pkg(tools define_pkg(tools-extra COMPONENTS tooluserclk + toolqsfpinfo toolras toolmmlink toolcoreidle diff --git a/binaries/CMakeLists.txt b/binaries/CMakeLists.txt index e9158f78e885..a7d0e107842e 100644 --- a/binaries/CMakeLists.txt +++ b/binaries/CMakeLists.txt @@ -31,6 +31,9 @@ opae_add_subdirectory(fpgametrics) option(OPAE_BUILD_USERCLK "Enable building extra tool userclk" ON) mark_as_advanced(OPAE_BUILD_USERCLK) +option(OPAE_BUILD_QSFPINFO "Enable building extra tool qsfpinfo" ON) +mark_as_advanced(OPAE_BUILD_QSFPINFO) + option(OPAE_BUILD_FPGADIAG "Enable building extra tool fpgadiag" ON) mark_as_advanced(OPAE_BUILD_FPGADIAG) @@ -52,6 +55,9 @@ if(OPAE_BUILD_EXTRA_TOOLS) if(OPAE_BUILD_USERCLK) opae_add_subdirectory(userclk) endif() + if(OPAE_BUILD_QSFPINFO) + opae_add_subdirectory(qsfpinfo) + endif() if(OPAE_BUILD_FPGADIAG) set(OPAE_BUILD_CXXUTILS ON) opae_add_subdirectory(fpgadiag) diff --git a/binaries/qsfpinfo/CMakeLists.txt b/binaries/qsfpinfo/CMakeLists.txt new file mode 100644 index 000000000000..085ff8589434 --- /dev/null +++ b/binaries/qsfpinfo/CMakeLists.txt @@ -0,0 +1,94 @@ +## Copyright(c) 2024, Silciom Denmark A/S +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## * Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright notice, +## this list of conditions and the following disclaimer in the documentation +## and/or other materials provided with the distribution. +## * Neither the name of Intel Corporation nor the names of its contributors +## may be used to endorse or promote products derived from this software +## without specific prior written permission. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +## POSSIBILITY OF SUCH DAMAGE. + +if (OPAE_WITH_QSFPINFO_QSFPPRINT) + + opae_add_executable(TARGET qsfpinfo + SOURCE + main.c + cmis_wrap.c + sff-common_wrap.c + LIBS + argsfilter + opae-c + m + COMPONENT toolqsfpinfo + ) + + include(ExternalProject) + + ExternalProject_Add( + ethtool_project + GIT_REPOSITORY "https://git.kernel.org/pub/scm/network/ethtool/ethtool.git" + GIT_TAG "v6.7" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + UPDATE_COMMAND "" + ) + + ExternalProject_Get_Property(ethtool_project SOURCE_DIR) + + add_custom_target(get-ethtool-files + DEPENDS ethtool_project + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${SOURCE_DIR}/cmis.c" + "${SOURCE_DIR}/cmis.h" + "${SOURCE_DIR}/qsfp.c" + "${SOURCE_DIR}/qsfp.h" + "${SOURCE_DIR}/sff-common.c" + "${SOURCE_DIR}/sff-common.h" + "${SOURCE_DIR}/internal.h" + "${SOURCE_DIR}/json_print.h" + "${SOURCE_DIR}/json_writer.h" "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SOURCE_DIR}/netlink/extapi.h" "${CMAKE_CURRENT_SOURCE_DIR}/netlink/extapi.h" + ) + + target_compile_options(qsfpinfo PUBLIC + -D_QSFPPRINT + ) + + add_dependencies(qsfpinfo get-ethtool-files) + +else(OPAE_WITH_QSFPINFO_QSFPPRINT) + + opae_add_executable(TARGET qsfpinfo + SOURCE + main.c + LIBS + argsfilter + opae-c + m + COMPONENT toolqsfpinfo + ) + +endif(OPAE_WITH_QSFPINFO_QSFPPRINT) + +target_include_directories(qsfpinfo + PRIVATE + ${OPAE_LIB_SOURCE}/argsfilter +) + diff --git a/binaries/qsfpinfo/cmis_wrap.c b/binaries/qsfpinfo/cmis_wrap.c new file mode 100644 index 000000000000..0ac4217c0d9d --- /dev/null +++ b/binaries/qsfpinfo/cmis_wrap.c @@ -0,0 +1,28 @@ +// Copyright(c) 2024, Silciom Denmark A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#undef HAVE_CONFIG_H +#include "cmis.c" diff --git a/binaries/qsfpinfo/main.c b/binaries/qsfpinfo/main.c new file mode 100644 index 000000000000..e218ca9120b6 --- /dev/null +++ b/binaries/qsfpinfo/main.c @@ -0,0 +1,417 @@ +// Copyright(c) 2024, Silciom Denmark A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "argsfilter.h" + +#include +#include +#include + +#ifdef QSFPPRINT +// From ethtool +#undef HAVE_CONFIG_H +#include "qsfp.c" + +// Read QSFP SFF-8636 registers into memory and setup pointers so +// sff8636_show_all_common() from ethertool can print result +static int sff8636_show(const char * regmap_path) +{ + + struct sff8636_memory_map map = {}; + __u8 buffer[1024]; + int i = 0; // counting lines read + int bufp = 0; // counting bytes written to buffer + uint32_t value; + + char *line = NULL; + size_t len = 0; + ssize_t read; + char delim[] = ":"; + + FILE *fp = fopen (regmap_path, "r"); + if (!fp) { + OPAE_ERR("Could not open regmap: %s ", regmap_path); + return ENOENT; + } + + while ((read = getline(&line, &len, fp)) != -1) + { + //The first 4 lines are not used + if (i >= 4) + { + // Line has the form : <32 bit little endian value> + char *ptr = strtok(line, delim); + ptr = strtok(NULL, delim); + value = strtol(ptr, NULL, 16); + //printf("value: 0x%x\n", value); + uint32_t *buftemp = (uint32_t *) &buffer[bufp]; + *buftemp = value; + bufp += 4; + } + i++; + } + + map.lower_memory = buffer; // address 0x100 in regmap + map.page_00h = buffer + (0x200 - 0x80); //starts from beginning of lower page 128 bytes before + map.page_03h = buffer + 0x200; //starts 128 bytes before + + // Print info + sff8636_show_all_common(&map); + fclose (fp); + return 0; +} +#endif + +// Define the function to be called when ctrl-c (SIGINT) signal is sent to +// process +static volatile bool stop = false; +void signal_callback_handler(int signum) +{ + switch (signum) { + case SIGINT: + stop = true; + break; + default: + break; + } +} + +#define MAX_PORT 2 +#define NO_SPECIFIC_PORT (MAX_PORT+1) +#define MAX_CARDS 4 + +struct card { + fpga_properties filter; + fpga_token token[MAX_CARDS]; + int32_t port; + uint32_t cards_found; +}; + +static fpga_result fpga_open(struct card *card) +{ + fpga_result res; + res = fpgaPropertiesSetObjectType(card->filter, FPGA_DEVICE); + if (res != FPGA_OK) { + OPAE_ERR("failed to set object type: %s ", fpgaErrStr(res)); + goto error; + } + + res = fpgaEnumerate(&card->filter, 1, card->token, MAX_CARDS, &card->cards_found); + if (res != FPGA_OK) { + OPAE_ERR("failed to enumerate fpga: %s ", fpgaErrStr(res)); + goto error; + } + + if (card->cards_found == 0) { + res = FPGA_NOT_FOUND; + OPAE_ERR("failed to find fpga: %s ", fpgaErrStr(res)); + goto error; + } + +error: + return res; +} + +static void fpga_close(struct card *card) +{ + fpga_result res; + + for(uint32_t i = 0; i < card->cards_found; i++) { + res = fpgaDestroyToken(&card->token[i]); + if (res != FPGA_OK) + OPAE_ERR("failed to destroy token: %s ", fpgaErrStr(res)); + } +} + +// QSFP cable status +#define LPATH_MAX 100 +#define DFL_SYSFS_QSFP "*dfl*dev.%ld/qsfp_connected" +#define REGMAP_PATH "/sys/kernel/debug/regmap/dfl_dev.%ld/registers" +#define MAX_DEV_FEATURE_COUNT 256 + +// from opae board_common.c extended with sff8636_show() +fpga_result qsfp_cable_status(const fpga_token token, const size_t port) +{ + fpga_object fpga_object; + fpga_result res = FPGA_OK; + uint64_t value = 0; + size_t i = 0; + char qsfp_path[LPATH_MAX] = { 0 }; + int retval = 0; + size_t qsfp_count = 0; + + for (i = 0; i < MAX_DEV_FEATURE_COUNT; i++) { + + memset(qsfp_path, 0, sizeof(qsfp_path)); + + retval = snprintf(qsfp_path, sizeof(qsfp_path), + DFL_SYSFS_QSFP, i); + if (retval < 0) { + OPAE_MSG("error in formatting qsfp cable status"); + return FPGA_EXCEPTION; + } + + res = fpgaTokenGetObject(token, qsfp_path, + &fpga_object, FPGA_OBJECT_GLOB); + if (res != FPGA_OK) { + OPAE_MSG("Failed to get token Object"); + continue; + } + + res = fpgaObjectRead64(fpga_object, &value, 0); + if (res == FPGA_OK) { + if (port == NO_SPECIFIC_PORT || port == qsfp_count) { + OPAE_MSG("Failed to Read object "); + + switch (value) { + case 0: + printf("QSFP%-45ld : %s \n", qsfp_count, "Not Connected"); + break; + case 1: + printf("QSFP%-45ld : %s \n", qsfp_count, "Connected"); + +#ifdef QSFPPRINT + char regmap_path[LPATH_MAX] = { 0 }; + retval = snprintf(regmap_path, sizeof(regmap_path), + REGMAP_PATH, i); + if (retval < 0) { + OPAE_MSG("error in formatting qsfp regmap"); + return FPGA_EXCEPTION; + } + sff8636_show(regmap_path); +#endif + break; + default: + printf("QSFP%-28ld : %s \n", qsfp_count, "N/A"); + } + } + qsfp_count++; + + } else { + OPAE_MSG("Failed to Read object "); + } + + res = fpgaDestroyObject(&fpga_object); + if (res != FPGA_OK) { + OPAE_MSG("Failed to Destroy Object"); + } + + } + + return res; +} + +// from opae board_common.c +fpga_result get_fpga_sbdf(fpga_token token, + uint16_t *segment, + uint8_t *bus, + uint8_t *device, + uint8_t *function) + +{ + fpga_result res = FPGA_OK; + fpga_properties props = NULL; + fpga_result resval = FPGA_OK; + + if (!segment || !bus || + !device || !function) { + OPAE_ERR("Invalid input parameters"); + return FPGA_INVALID_PARAM; + } + res = fpgaGetProperties(token, &props); + if (res != FPGA_OK) { + OPAE_ERR("Failed to get properties "); + return res; + } + + res = fpgaPropertiesGetBus(props, bus); + if (res != FPGA_OK) { + OPAE_ERR("Failed to get bus "); + resval = res; + goto out_destroy; + } + + res = fpgaPropertiesGetSegment(props, segment); + if (res != FPGA_OK) { + OPAE_ERR("Failed to get Segment "); + resval = res; + goto out_destroy; + } + res = fpgaPropertiesGetDevice(props, device); + if (res != FPGA_OK) { + OPAE_ERR("Failed to get Device "); + resval = res; + goto out_destroy; + } + + res = fpgaPropertiesGetFunction(props, function); + if (res != FPGA_OK) { + OPAE_ERR("Failed to get Function "); + resval = res; + goto out_destroy; + } + +out_destroy: + res = fpgaDestroyProperties(&props); + if (res != FPGA_OK) { + OPAE_ERR("Failed to destroy properties"); + } + + return resval; +} + + +static void print_usage(FILE *f) +{ + fprintf(f, + "\n" + "qsfpinfo\n" + "Print QSFP EEPROM information\n" + "\n"); + fprintf(f, "Usage:\n"); + fprintf(f, " qsfpinfo [-h] [-p ] [PCI_ADDR]\n"); + fprintf(f,"\n"); + fprintf(f, + " -p,--port Print only information for this QSFP [0..1]\n" + " -S,--segment Set target segment number\n" + " -B,--bus Set target bus number\n" + " -D,--device Set target device number\n" + " -F,--function Set target function number\n" + "\n"); +} + + +static bool parse_port(struct card *card, const char *port_str) +{ + char *endptr; + unsigned long int port = strtoul(port_str, &endptr, 0); + if (port_str == endptr) { + OPAE_ERR("missing port number: '%s'", port_str); + return false; + } + + if (port >= MAX_PORT) { + OPAE_ERR("port number too big: '%d'", port); + return false; + } + + card->port = port; + return true; +} + + +static int parse_args(int argc, char **argv, struct card *card) +{ + struct option options[] = { + {"help", no_argument, NULL, 'h'}, + {"port", required_argument, NULL, 'p'}, + {NULL, 0, NULL, 0}, + }; + + int c; + + while (1) { + c = getopt_long_only(argc, argv, "hg:m:p:d", options, NULL); + if (c == -1) + break; + + switch (c) { + case 'h': + print_usage(stdout); + exit(EXIT_SUCCESS); + case 'p': + if (!parse_port(card, optarg)) + return EXIT_FAILURE; + break; + case '?': + default: + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) +{ + struct card card = {.filter = NULL, .port = NO_SPECIFIC_PORT, .cards_found = 0}; + uint16_t segment; + uint8_t bus; + uint8_t device; + uint8_t function; + fpga_result res; + int err; + + res = fpgaGetProperties(NULL, &card.filter); + if (res != FPGA_OK) { + OPAE_ERR("failed to get properties: %s ", fpgaErrStr(res)); + return res; + } + + if (opae_set_properties_from_args(card.filter, &res, &argc, argv)) { + OPAE_ERR("failed arg parse."); + res = FPGA_EXCEPTION; + goto error2; + } else if (res) { + OPAE_ERR("failed to set properties."); + goto error2; + } + + err = parse_args(argc, argv, &card); + if (err != 0) + goto error2; + + // Install Control-C handler + signal(SIGINT, signal_callback_handler); + + res = fpga_open(&card); + if (res != FPGA_OK) + goto error; + + for(uint32_t i = 0; i < card.cards_found; i++) { + get_fpga_sbdf(card.token[i], &segment, &bus, &device, &function); + printf("%-49s : %04X:%02X:%02X.%01X\n", "PCIe s:b:d.f", segment, bus, device, function); + res = qsfp_cable_status(card.token[i], card.port); + } + +error: + fpga_close(&card); + +error2: + fpgaDestroyProperties(&card.filter); + + return res == FPGA_OK ? EXIT_SUCCESS : res; +} diff --git a/binaries/qsfpinfo/sff-common_wrap.c b/binaries/qsfpinfo/sff-common_wrap.c new file mode 100644 index 000000000000..913b15ac847f --- /dev/null +++ b/binaries/qsfpinfo/sff-common_wrap.c @@ -0,0 +1,28 @@ +// Copyright(c) 2024, Silciom Denmark A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#undef HAVE_CONFIG_H +#include "sff-common.c" diff --git a/doc/sphinx/conf.py.in b/doc/sphinx/conf.py.in index 4e99e66e2595..769de2b22884 100644 --- a/doc/sphinx/conf.py.in +++ b/doc/sphinx/conf.py.in @@ -164,6 +164,7 @@ man_pages = [ ("docs/fpga_tools/hssi/hssi", 'hssi', u'High Speed Serial Interface', [author], 8), ("docs/fpga_tools/opaevfio/opaevfio", 'opaevfio', u'Bind/Unbind accelerator to/from vfio-pci', [author], 8), ("docs/fpga_tools/userclk/userclk", 'userclk', u'Set AFU high and low clock frequency', [author], 8), + ("docs/fpga_tools/qsfpinfo/qsfpinfo", 'qsfpinfo', u'Print QSFP EEPROM information', [author], 8), ("docs/fpga_tools/pci_device/pci_device", 'pci_device', u'Common operations for PCIe devices', [author], 8), ("docs/fpga_tools/opae.io/opae.io", 'opae.io', u'User space access to PCIe devices', [author], 8), ("docs/fpga_tools/host_exerciser/host_exerciser", 'host_exerciser', u'Host Exerciser lpbk and memory', [author], 8), diff --git a/doc/sphinx/index.rst.in b/doc/sphinx/index.rst.in index 6f50e28eec86..c2d3c46f70d7 100644 --- a/doc/sphinx/index.rst.in +++ b/doc/sphinx/index.rst.in @@ -57,6 +57,7 @@ The main documentation for the site is organized into following sections: docs/fpga_tools/mmlink/mmlink docs/fpga_tools/packager/packager docs/fpga_tools/userclk/userclk + docs/fpga_tools/qsfpinfo/qsfpinfo docs/fpga_tools/hssi/hssi docs/fpga_tools/opaevfio/opaevfio docs/fpga_tools/pci_device/pci_device diff --git a/doc/src/fpga_tools/qsfpinfo/qsfpinfo.md b/doc/src/fpga_tools/qsfpinfo/qsfpinfo.md new file mode 100644 index 000000000000..117193efe8d5 --- /dev/null +++ b/doc/src/fpga_tools/qsfpinfo/qsfpinfo.md @@ -0,0 +1,97 @@ +# qsfpinfo # + +## SYNOPSIS ## + +`qsfpinfo [-h] [-p ] [-S ] [-B ] [-D ] [-F ] [PCI_ADDR]` + + +## DESCRIPTION ## + +qsfpinfo prints QSFP EEPROM information for QSFP modules present in cards with qsfp feature (id 0x13) e.g. N6010, N6011, using the qsfp-mem driver. + +qsfpinfo only prints QSFP EEPROM information if OPAE-SDK is compiled with "-DOPAE_WITH_QSFPINFO_QSFPPRINT=ON". +## EXAMPLES ## + +```sh +>sudo qsfpinfo -p 0 0000:98:00.0` +PCIe s:b:d.f : 0000:98:00.0 +QSFP0 : Connected + Identifier : 0x11 (QSFP28) + Extended identifier : 0xcc + Extended identifier description : 3.5W max. Power consumption + Extended identifier description : CDR present in TX, CDR present in RX + Extended identifier description : High Power Class (> 3.5 W) not enabled + Power set : Off + Power override : Off + Connector : 0x0c (MPO Parallel Optic) + Transceiver codes : 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + Transceiver type : 100G Ethernet: 100G Base-SR4 or 25GBase-SR + Encoding : 0x07 ((256B/257B (transcoded FEC-enabled data)) + BR, Nominal : 25500Mbps + Rate identifier : 0x00 + Length (SMF,km) : 0km + Length (OM3 50um) : 70m + Length (OM2 50um) : 0m + Length (OM1 62.5um) : 0m + Length (Copper or Active cable) : 50m + Transmitter technology : 0x00 (850 nm VCSEL) + Laser wavelength : 850.000nm + Laser wavelength tolerance : 10.000nm + Vendor name : FINISAR CORP + Vendor OUI : 00:90:65 + Vendor PN : FTLC9551REPM + Vendor rev : A0 + Vendor SN : XYH0RPZ + Date code : 180512 + Revision Compliance : SFF-8636 Rev 2.5/2.6/2.7 + Rx loss of signal : None + Tx loss of signal : None + Rx loss of lock : [ Yes, Yes, Yes, Yes ] + Tx loss of lock : [ Yes, Yes, Yes, Yes ] + Tx fault : None + Module temperature : 45.22 degrees C / 113.39 degrees F + Module voltage : 3.3359 V + Alarm/warning flags implemented : Yes + Laser tx bias current (Channel 1) : 8.162 mA + Laser tx bias current (Channel 2) : 7.560 mA + Laser tx bias current (Channel 3) : 7.796 mA + Laser tx bias current (Channel 4) : 7.708 mA + Transmit avg optical power (Channel 1) : 1.0391 mW / 0.17 dBm + Transmit avg optical power (Channel 2) : 1.0704 mW / 0.30 dBm + Transmit avg optical power (Channel 3) : 1.0704 mW / 0.30 dBm + Transmit avg optical power (Channel 4) : 0.9449 mW / -0.25 dBm + Rcvr signal avg optical power(Channel 1) : 0.9603 mW / -0.18 dBm + Rcvr signal avg optical power(Channel 2) : 0.9210 mW / -0.36 dBm + Rcvr signal avg optical power(Channel 3) : 1.0281 mW / 0.12 dBm + Rcvr signal avg optical power(Channel 4) : 1.0220 mW / 0.09 dBm +... +``` + +## OPTIONS ## + +`-p,--port` + +Print only information for this QSFP [0..1] + +`-S,--segment` + +FPGA segment number. + +`-B,--bus` + +FPGA Bus number. + +`-D,--device` + +FPGA Device number. + +`-F,--function` + +FPGA function number. + +## Revision History ## + +| Date | Intel Acceleration Stack Version | Changes Made | +|:------|----------------------------|:--------------| +|2024.04.26| IOFS EA | Initial release. | + diff --git a/opae.spec.fedora b/opae.spec.fedora index 4e4e0be3c119..26b24ca0f70c 100644 --- a/opae.spec.fedora +++ b/opae.spec.fedora @@ -93,7 +93,7 @@ Additional OPAE tools -DFETCHCONTENT_FULLY_DISCONNECTED=ON \ -DFETCHCONTENT_BASE_DIR=_build/_deps \ -DOPAE_BUILD_PYTHON_DIST=ON \ - -DOPAE_BUILD_FPGABIST=ON + -DOPAE_BUILD_FPGABIST=ON %if 0%{?rhel} %if 0%{rhel} <= 8 @@ -289,6 +289,7 @@ done %{_bindir}/super-rsu %{_bindir}/mmlink %{_bindir}/userclk +%{_bindir}/qsfpinfo %{_bindir}/hello_fpga %{_bindir}/object_api %{_bindir}/hello_events @@ -385,7 +386,7 @@ done - Various Static code scan bug fixes - Added python3 support. - OPAE USMG API are deprecated. -- Updated OPAE documentation. +- Updated OPAE documentation. * Tue Dec 17 2019 Korde Nakul 1.4.0-1 - Added support to FPGA Linux kernel Device Feature List (DFL) driver patch set2. diff --git a/opae.spec.in b/opae.spec.in index e81cdc6475d9..76127e4dd9ce 100644 --- a/opae.spec.in +++ b/opae.spec.in @@ -215,6 +215,7 @@ ldconfig @CMAKE_INSTALL_PREFIX@/bin/packager @CMAKE_INSTALL_PREFIX@/bin/pac_hssi_config.py @CMAKE_INSTALL_PREFIX@/bin/userclk +@CMAKE_INSTALL_PREFIX@/bin/qsfpinfo @CMAKE_INSTALL_PREFIX@/bin/hps @CMAKE_INSTALL_PREFIX@/bin/vabtool @CMAKE_INSTALL_PREFIX@/@OPAE_LIB_INSTALL_DIR@/libmml-srv.so* diff --git a/opae.spec.rhel b/opae.spec.rhel index 82b1a4d1e50d..e6c7770830e6 100644 --- a/opae.spec.rhel +++ b/opae.spec.rhel @@ -285,6 +285,7 @@ done %{_bindir}/super-rsu %{_bindir}/mmlink %{_bindir}/userclk +%{_bindir}/qsfpinfo %{_bindir}/hello_fpga %{_bindir}/object_api %{_bindir}/hello_events @@ -338,7 +339,7 @@ done - Various Static code scan bug fixes - Added python3 support. - OPAE USMG API are deprecated. -- Updated OPAE documentation. +- Updated OPAE documentation. * Tue Dec 17 2019 Korde Nakul 1.4.0-1 - Added support to FPGA Linux kernel Device Feature List (DFL) driver patch set2. diff --git a/packaging/opae/deb/opae-devel.install b/packaging/opae/deb/opae-devel.install index cc4358c0ad2f..c84c7e982dda 100644 --- a/packaging/opae/deb/opae-devel.install +++ b/packaging/opae/deb/opae-devel.install @@ -30,6 +30,7 @@ usr/bin/fpgaport usr/bin/super-rsu usr/bin/mmlink usr/bin/userclk +usr/bin/qsfpinfo usr/bin/hello_fpga usr/bin/object_api usr/bin/hello_events diff --git a/scripts/opae-clean.py b/scripts/opae-clean.py index 9f7a2972a3a8..c5774c4f15f8 100755 --- a/scripts/opae-clean.py +++ b/scripts/opae-clean.py @@ -449,6 +449,7 @@ def infer_type(expanded): 'super-rsu', 'mmlink', 'userclk', + 'qsfpinfo', 'hello_fpga', 'object_api', 'hello_events',