From patchwork Wed May 11 02:14:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Zhang X-Patchwork-Id: 111011 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 11E13A0032; Wed, 11 May 2022 04:20:37 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5089942837; Wed, 11 May 2022 04:20:30 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mails.dpdk.org (Postfix) with ESMTP id AB0C84113D for ; Wed, 11 May 2022 04:20:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652235627; x=1683771627; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EBbjneTgsEnnlAzTqbWxewJYEEx0uTGenuc4jaeLsRw=; b=E69TaH8x4+OOw30m2DsekrlsnLy6TfAEis0YXs4wxwpPh2HhBdODuAQw 88Ja7w2A1ZRdsRGd5PrFBIyCUcCul9x8GtHBFbjBIl5z+Ma+QfIpgHCcC RyG7crz27rTnXJ34Qz0b/QaeLQWhbaie3AxIYVXL25wJFi8p2KaTEcWWF JFoWYSQEeHTDlW2SWa2wyhesOjAX3Ex2YwA9O32Ri2waTYElry3g/CpQf I1JYeatpyZDSgnzqkCOFofWOAhTcC5SG+BH1BoBkIF+ZlGNLDDdTIrdRc HRU6Cj1mbmi+DVzrXjMZhXadd9JQxGy/OK9s9KOhZdL/6a9Dr007Qnbhf A==; X-IronPort-AV: E=McAfee;i="6400,9594,10343"; a="355984088" X-IronPort-AV: E=Sophos;i="5.91,215,1647327600"; d="scan'208";a="355984088" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 May 2022 19:20:27 -0700 X-IronPort-AV: E=Sophos;i="5.91,215,1647327600"; d="scan'208";a="593865660" Received: from intel-cd-odc-robin.cd.intel.com ([10.240.178.188]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 May 2022 19:20:25 -0700 From: Robin Zhang To: dev@dpdk.org Cc: Thomas Monjalon , Ferruh Yigit , Andrew Rybchenko , Robin Zhang Subject: [PATCH v6 2/5] ethdev: common utilities for different SFF specs Date: Wed, 11 May 2022 02:14:39 +0000 Message-Id: <20220511021442.811950-3-robinx.zhang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220511021442.811950-1-robinx.zhang@intel.com> References: <20220426024349.1081666-1-robinx.zhang@intel.com> <20220511021442.811950-1-robinx.zhang@intel.com> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch implements SFF-8024 Rev 4.0 of pluggable I/O configuration and some common utilities for SFF-8436/8636 and SFF-8472/8079. Signed-off-by: Robin Zhang --- lib/ethdev/meson.build | 1 + lib/ethdev/sff_common.c | 326 ++++++++++++++++++++++++++++++++++++++++ lib/ethdev/sff_common.h | 174 +++++++++++++++++++++ 3 files changed, 501 insertions(+) create mode 100644 lib/ethdev/sff_common.c create mode 100644 lib/ethdev/sff_common.h diff --git a/lib/ethdev/meson.build b/lib/ethdev/meson.build index 49c77acb3f..8f39739e43 100644 --- a/lib/ethdev/meson.build +++ b/lib/ethdev/meson.build @@ -12,6 +12,7 @@ sources = files( 'rte_mtr.c', 'rte_tm.c', 'ethdev_sff_telemetry.c', + 'sff_common.c', ) headers = files( diff --git a/lib/ethdev/sff_common.c b/lib/ethdev/sff_common.c new file mode 100644 index 0000000000..06d96fac72 --- /dev/null +++ b/lib/ethdev/sff_common.c @@ -0,0 +1,326 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + * + * Implements SFF-8024 Rev 4.0 of pluggable I/O configuration and some + * common utilities for SFF-8436/8636 and SFF-8472/8079 + * + */ + +#include +#include +#include +#include +#include +#include "sff_common.h" +#include "ethdev_sff_telemetry.h" + + +double convert_mw_to_dbm(double mw) +{ + return (10. * log10(mw / 1000.)) + 30.; +} + +void sff_show_value_with_unit(const uint8_t *data, unsigned int reg, + const char *name, unsigned int mult, + const char *unit, struct rte_tel_data *d) +{ + unsigned int val = data[reg]; + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + snprintf(val_string, sizeof(val_string), "%u%s", val * mult, unit); + ssf_add_dict_string(d, name, val_string); +} + +void sff_show_ascii(const uint8_t *data, unsigned int first_reg, + unsigned int last_reg, const char *name, struct rte_tel_data *d) +{ + unsigned int reg, val; + char tmp[3]; + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + memset(val_string, 0, sizeof(val_string)); + + while (first_reg <= last_reg && data[last_reg] == ' ') + last_reg--; + for (reg = first_reg; reg <= last_reg; reg++) { + val = data[reg]; + if ((val >= 32) && (val <= 126)) { + snprintf(tmp, sizeof(tmp), "%c", val); + strlcat(val_string, tmp, sizeof(val_string)); + } else { + strlcat(val_string, "_", sizeof(val_string)); + } + } + ssf_add_dict_string(d, name, val_string); +} + +void sff_8024_show_oui(const uint8_t *data, int id_offset, struct rte_tel_data *d) +{ + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + snprintf(val_string, sizeof(val_string), "%02x:%02x:%02x", + data[id_offset], data[(id_offset) + 1], data[(id_offset) + 2]); + ssf_add_dict_string(d, "Vendor OUI", val_string); +} + +void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct rte_tel_data *d) +{ + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + snprintf(val_string, sizeof(val_string), "0x%02x", data[id_offset]); + + switch (data[id_offset]) { + case SFF_8024_ID_UNKNOWN: + strlcat(val_string, " (no module present, unknown, or unspecified)", + sizeof(val_string)); + break; + case SFF_8024_ID_GBIC: + strlcat(val_string, " (GBIC)", sizeof(val_string)); + break; + case SFF_8024_ID_SOLDERED_MODULE: + strlcat(val_string, " (module soldered to motherboard)", sizeof(val_string)); + break; + case SFF_8024_ID_SFP: + strlcat(val_string, " (SFP)", sizeof(val_string)); + break; + case SFF_8024_ID_300_PIN_XBI: + strlcat(val_string, " (300 pin XBI)", sizeof(val_string)); + break; + case SFF_8024_ID_XENPAK: + strlcat(val_string, " (XENPAK)", sizeof(val_string)); + break; + case SFF_8024_ID_XFP: + strlcat(val_string, " (XFP)", sizeof(val_string)); + break; + case SFF_8024_ID_XFF: + strlcat(val_string, " (XFF)", sizeof(val_string)); + break; + case SFF_8024_ID_XFP_E: + strlcat(val_string, " (XFP-E)", sizeof(val_string)); + break; + case SFF_8024_ID_XPAK: + strlcat(val_string, " (XPAK)", sizeof(val_string)); + break; + case SFF_8024_ID_X2: + strlcat(val_string, " (X2)", sizeof(val_string)); + break; + case SFF_8024_ID_DWDM_SFP: + strlcat(val_string, " (DWDM-SFP)", sizeof(val_string)); + break; + case SFF_8024_ID_QSFP: + strlcat(val_string, " (QSFP)", sizeof(val_string)); + break; + case SFF_8024_ID_QSFP_PLUS: + strlcat(val_string, " (QSFP+)", sizeof(val_string)); + break; + case SFF_8024_ID_CXP: + strlcat(val_string, " (CXP)", sizeof(val_string)); + break; + case SFF_8024_ID_HD4X: + strlcat(val_string, " (Shielded Mini Multilane HD 4X)", sizeof(val_string)); + break; + case SFF_8024_ID_HD8X: + strlcat(val_string, " (Shielded Mini Multilane HD 8X)", sizeof(val_string)); + break; + case SFF_8024_ID_QSFP28: + strlcat(val_string, " (QSFP28)", sizeof(val_string)); + break; + case SFF_8024_ID_CXP2: + strlcat(val_string, " (CXP2/CXP28)", sizeof(val_string)); + break; + case SFF_8024_ID_CDFP: + strlcat(val_string, " (CDFP Style 1/Style 2)", sizeof(val_string)); + break; + case SFF_8024_ID_HD4X_FANOUT: + strlcat(val_string, " (Shielded Mini Multilane HD 4X Fanout Cable)", + sizeof(val_string)); + break; + case SFF_8024_ID_HD8X_FANOUT: + strlcat(val_string, " (Shielded Mini Multilane HD 8X Fanout Cable)", + sizeof(val_string)); + break; + case SFF_8024_ID_CDFP_S3: + strlcat(val_string, " (CDFP Style 3)", sizeof(val_string)); + break; + case SFF_8024_ID_MICRO_QSFP: + strlcat(val_string, " (microQSFP)", sizeof(val_string)); + break; + default: + strlcat(val_string, " (reserved or unknown)", sizeof(val_string)); + break; + } + ssf_add_dict_string(d, "Identifier", val_string); +} + +void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct rte_tel_data *d) +{ + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + snprintf(val_string, sizeof(val_string), "0x%02x", data[ctor_offset]); + + switch (data[ctor_offset]) { + case SFF_8024_CTOR_UNKNOWN: + strlcat(val_string, " (unknown or unspecified)", sizeof(val_string)); + break; + case SFF_8024_CTOR_SC: + strlcat(val_string, " (SC)", sizeof(val_string)); + break; + case SFF_8024_CTOR_FC_STYLE_1: + strlcat(val_string, " (Fibre Channel Style 1 copper)", sizeof(val_string)); + break; + case SFF_8024_CTOR_FC_STYLE_2: + strlcat(val_string, " (Fibre Channel Style 2 copper)", sizeof(val_string)); + break; + case SFF_8024_CTOR_BNC_TNC: + strlcat(val_string, " (BNC/TNC)", sizeof(val_string)); + break; + case SFF_8024_CTOR_FC_COAX: + strlcat(val_string, " (Fibre Channel coaxial headers)", sizeof(val_string)); + break; + case SFF_8024_CTOR_FIBER_JACK: + strlcat(val_string, " (FibreJack)", sizeof(val_string)); + break; + case SFF_8024_CTOR_LC: + strlcat(val_string, " (LC)", sizeof(val_string)); + break; + case SFF_8024_CTOR_MT_RJ: + strlcat(val_string, " (MT-RJ)", sizeof(val_string)); + break; + case SFF_8024_CTOR_MU: + strlcat(val_string, " (MU)", sizeof(val_string)); + break; + case SFF_8024_CTOR_SG: + strlcat(val_string, " (SG)", sizeof(val_string)); + break; + case SFF_8024_CTOR_OPT_PT: + strlcat(val_string, " (Optical pigtail)", sizeof(val_string)); + break; + case SFF_8024_CTOR_MPO: + strlcat(val_string, " (MPO Parallel Optic)", sizeof(val_string)); + break; + case SFF_8024_CTOR_MPO_2: + strlcat(val_string, " (MPO Parallel Optic - 2x16)", sizeof(val_string)); + break; + case SFF_8024_CTOR_HSDC_II: + strlcat(val_string, " (HSSDC II)", sizeof(val_string)); + break; + case SFF_8024_CTOR_COPPER_PT: + strlcat(val_string, " (Copper pigtail)", sizeof(val_string)); + break; + case SFF_8024_CTOR_RJ45: + strlcat(val_string, " (RJ45)", sizeof(val_string)); + break; + case SFF_8024_CTOR_NO_SEPARABLE: + strlcat(val_string, " (No separable connector)", sizeof(val_string)); + break; + case SFF_8024_CTOR_MXC_2x16: + strlcat(val_string, " (MXC 2x16)", sizeof(val_string)); + break; + default: + strlcat(val_string, " (reserved or unknown)", sizeof(val_string)); + break; + } + ssf_add_dict_string(d, "Connector", val_string); +} + +void sff_8024_show_encoding(const uint8_t *data, int encoding_offset, + int sff_type, struct rte_tel_data *d) +{ + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + snprintf(val_string, sizeof(val_string), "0x%02x", data[encoding_offset]); + + switch (data[encoding_offset]) { + case SFF_8024_ENCODING_UNSPEC: + strlcat(val_string, " (unspecified)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_8B10B: + strlcat(val_string, " (8B/10B)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_4B5B: + strlcat(val_string, " (4B/5B)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_NRZ: + strlcat(val_string, " (NRZ)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_4h: + if (sff_type == RTE_ETH_MODULE_SFF_8472) + strlcat(val_string, " (Manchester)", sizeof(val_string)); + else if (sff_type == RTE_ETH_MODULE_SFF_8636) + strlcat(val_string, " (SONET Scrambled)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_5h: + if (sff_type == RTE_ETH_MODULE_SFF_8472) + strlcat(val_string, " (SONET Scrambled)", sizeof(val_string)); + else if (sff_type == RTE_ETH_MODULE_SFF_8636) + strlcat(val_string, " (64B/66B)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_6h: + if (sff_type == RTE_ETH_MODULE_SFF_8472) + strlcat(val_string, " (64B/66B)", sizeof(val_string)); + else if (sff_type == RTE_ETH_MODULE_SFF_8636) + strlcat(val_string, " (Manchester)", sizeof(val_string)); + break; + case SFF_8024_ENCODING_256B: + strlcat(val_string, + " ((256B/257B (transcoded FEC-enabled data))", sizeof(val_string)); + break; + case SFF_8024_ENCODING_PAM4: + strlcat(val_string, " (PAM4)", sizeof(val_string)); + break; + default: + strlcat(val_string, " (reserved or unknown)", sizeof(val_string)); + break; + } + ssf_add_dict_string(d, "Encoding", val_string); +} + +void sff_show_thresholds(struct sff_diags sd, struct rte_tel_data *d) +{ + char val_string[SFF_ITEM_VAL_COMPOSE_SIZE]; + + SPRINT_BIAS(val_string, sd.bias_cur[HALRM]); + ssf_add_dict_string(d, "Laser bias current high alarm threshold", val_string); + SPRINT_BIAS(val_string, sd.bias_cur[LALRM]); + ssf_add_dict_string(d, "Laser bias current low alarm threshold", val_string); + SPRINT_BIAS(val_string, sd.bias_cur[HWARN]); + ssf_add_dict_string(d, "Laser bias current high warning threshold", val_string); + SPRINT_BIAS(val_string, sd.bias_cur[LWARN]); + ssf_add_dict_string(d, "Laser bias current low warning threshold", val_string); + + SPRINT_xX_PWR(val_string, sd.tx_power[HALRM]); + ssf_add_dict_string(d, "Laser output power high alarm threshold", val_string); + SPRINT_xX_PWR(val_string, sd.tx_power[LALRM]); + ssf_add_dict_string(d, "Laser output power low alarm threshold", val_string); + SPRINT_xX_PWR(val_string, sd.tx_power[HWARN]); + ssf_add_dict_string(d, "Laser output power high warning threshold", val_string); + SPRINT_xX_PWR(val_string, sd.tx_power[LWARN]); + ssf_add_dict_string(d, "Laser output power low warning threshold", val_string); + + SPRINT_TEMP(val_string, sd.sfp_temp[HALRM]); + ssf_add_dict_string(d, "Module temperature high alarm threshold", val_string); + SPRINT_TEMP(val_string, sd.sfp_temp[LALRM]); + ssf_add_dict_string(d, "Module temperature low alarm threshold", val_string); + SPRINT_TEMP(val_string, sd.sfp_temp[HWARN]); + ssf_add_dict_string(d, "Module temperature high warning threshold", val_string); + SPRINT_TEMP(val_string, sd.sfp_temp[LWARN]); + ssf_add_dict_string(d, "Module temperature low warning threshold", val_string); + + SPRINT_VCC(val_string, sd.sfp_voltage[HALRM]); + ssf_add_dict_string(d, "Module voltage high alarm threshold", val_string); + SPRINT_VCC(val_string, sd.sfp_voltage[LALRM]); + ssf_add_dict_string(d, "Module voltage low alarm threshold", val_string); + SPRINT_VCC(val_string, sd.sfp_voltage[HWARN]); + ssf_add_dict_string(d, "Module voltage high warning threshold", val_string); + SPRINT_VCC(val_string, sd.sfp_voltage[LWARN]); + ssf_add_dict_string(d, "Module voltage low alarm threshold", val_string); + + SPRINT_xX_PWR(val_string, sd.rx_power[HALRM]); + ssf_add_dict_string(d, "Laser rx power high alarm threshold", val_string); + SPRINT_xX_PWR(val_string, sd.rx_power[LALRM]); + ssf_add_dict_string(d, "Laser rx power low alarm threshold", val_string); + SPRINT_xX_PWR(val_string, sd.rx_power[HWARN]); + ssf_add_dict_string(d, "Laser rx power high warning threshold", val_string); + SPRINT_xX_PWR(val_string, sd.rx_power[LWARN]); + ssf_add_dict_string(d, "Laser rx power low warning threshold", val_string); +} diff --git a/lib/ethdev/sff_common.h b/lib/ethdev/sff_common.h new file mode 100644 index 0000000000..264fb915cd --- /dev/null +++ b/lib/ethdev/sff_common.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + * + * Implements SFF-8024 Rev 4.0 of pluggable I/O configuration and some + * common utilities for SFF-8436/8636 and SFF-8472/8079 + * + */ + +#ifndef _SFF_COMMON_H_ +#define _SFF_COMMON_H_ + +#include +#include +#include +#include +#include "ethdev_sff_telemetry.h" + +#define SFF_8024_ID_OFFSET 0x00 +#define SFF_8024_ID_UNKNOWN 0x00 +#define SFF_8024_ID_GBIC 0x01 +#define SFF_8024_ID_SOLDERED_MODULE 0x02 +#define SFF_8024_ID_SFP 0x03 +#define SFF_8024_ID_300_PIN_XBI 0x04 +#define SFF_8024_ID_XENPAK 0x05 +#define SFF_8024_ID_XFP 0x06 +#define SFF_8024_ID_XFF 0x07 +#define SFF_8024_ID_XFP_E 0x08 +#define SFF_8024_ID_XPAK 0x09 +#define SFF_8024_ID_X2 0x0A +#define SFF_8024_ID_DWDM_SFP 0x0B +#define SFF_8024_ID_QSFP 0x0C +#define SFF_8024_ID_QSFP_PLUS 0x0D +#define SFF_8024_ID_CXP 0x0E +#define SFF_8024_ID_HD4X 0x0F +#define SFF_8024_ID_HD8X 0x10 +#define SFF_8024_ID_QSFP28 0x11 +#define SFF_8024_ID_CXP2 0x12 +#define SFF_8024_ID_CDFP 0x13 +#define SFF_8024_ID_HD4X_FANOUT 0x14 +#define SFF_8024_ID_HD8X_FANOUT 0x15 +#define SFF_8024_ID_CDFP_S3 0x16 +#define SFF_8024_ID_MICRO_QSFP 0x17 +#define SFF_8024_ID_LAST SFF_8024_ID_MICRO_QSFP +#define SFF_8024_ID_UNALLOCATED_LAST 0x7F +#define SFF_8024_ID_VENDOR_START 0x80 +#define SFF_8024_ID_VENDOR_LAST 0xFF + +#define SFF_8024_CTOR_UNKNOWN 0x00 +#define SFF_8024_CTOR_SC 0x01 +#define SFF_8024_CTOR_FC_STYLE_1 0x02 +#define SFF_8024_CTOR_FC_STYLE_2 0x03 +#define SFF_8024_CTOR_BNC_TNC 0x04 +#define SFF_8024_CTOR_FC_COAX 0x05 +#define SFF_8024_CTOR_FIBER_JACK 0x06 +#define SFF_8024_CTOR_LC 0x07 +#define SFF_8024_CTOR_MT_RJ 0x08 +#define SFF_8024_CTOR_MU 0x09 +#define SFF_8024_CTOR_SG 0x0A +#define SFF_8024_CTOR_OPT_PT 0x0B +#define SFF_8024_CTOR_MPO 0x0C +#define SFF_8024_CTOR_MPO_2 0x0D +/* 0E-1Fh --- Reserved */ +#define SFF_8024_CTOR_HSDC_II 0x20 +#define SFF_8024_CTOR_COPPER_PT 0x21 +#define SFF_8024_CTOR_RJ45 0x22 +#define SFF_8024_CTOR_NO_SEPARABLE 0x23 +#define SFF_8024_CTOR_MXC_2x16 0x24 +#define SFF_8024_CTOR_LAST SFF_8024_CTOR_MXC_2x16 +#define SFF_8024_CTOR_UNALLOCATED_LAST 0x7F +#define SFF_8024_CTOR_VENDOR_START 0x80 +#define SFF_8024_CTOR_VENDOR_LAST 0xFF + +/* ENCODING Values */ +#define SFF_8024_ENCODING_UNSPEC 0x00 +#define SFF_8024_ENCODING_8B10B 0x01 +#define SFF_8024_ENCODING_4B5B 0x02 +#define SFF_8024_ENCODING_NRZ 0x03 +/* + * Value: 04h + * SFF-8472 - Manchester + * SFF-8436/8636 - SONET Scrambled + */ +#define SFF_8024_ENCODING_4h 0x04 +/* + * Value: 05h + * SFF-8472 - SONET Scrambled + * SFF-8436/8636 - 64B/66B + */ +#define SFF_8024_ENCODING_5h 0x05 +/* + * Value: 06h + * SFF-8472 - 64B/66B + * SFF-8436/8636 - Manchester + */ +#define SFF_8024_ENCODING_6h 0x06 +#define SFF_8024_ENCODING_256B 0x07 +#define SFF_8024_ENCODING_PAM4 0x08 + +/* Most common case: 16-bit unsigned integer in a certain unit */ +#define OFFSET_TO_U16(offset) \ + (data[offset] << 8 | data[(offset) + 1]) + +#define SPRINT_xX_PWR(str, var) \ + snprintf(str, sizeof(str), "%.4f mW / %.2f dBm", \ + (double)((var) / 10000.), \ + convert_mw_to_dbm((double)((var) / 10000.))) + +#define SPRINT_BIAS(str, bias_cur) \ + snprintf(str, sizeof(str), "%.3f mA", (double)(bias_cur / 500.)) + +#define SPRINT_TEMP(str, temp) \ + snprintf(str, sizeof(str), "%.2f degrees C / %.2f degrees F", \ + (double)(temp / 256.), \ + (double)(temp / 256. * 1.8 + 32.)) + +#define SPRINT_VCC(str, sfp_voltage) \ + snprintf(str, sizeof(str), "%.4f V", (double)(sfp_voltage / 10000.)) + +/* Channel Monitoring Fields */ +struct sff_channel_diags { + uint16_t bias_cur; /* Measured bias current in 2uA units */ + uint16_t rx_power; /* Measured RX Power */ + uint16_t tx_power; /* Measured TX Power */ +}; + +/* Module Monitoring Fields */ +struct sff_diags { + +#define MAX_CHANNEL_NUM 4 +#define LWARN 0 +#define HWARN 1 +#define LALRM 2 +#define HALRM 3 +#define MCURR 4 + + /* Supports DOM */ + uint8_t supports_dom; + /* Supports alarm/warning thold */ + uint8_t supports_alarms; + /* RX Power: 0 = OMA, 1 = Average power */ + uint8_t rx_power_type; + /* TX Power: 0 = Not supported, 1 = Average power */ + uint8_t tx_power_type; + + uint8_t calibrated_ext; /* Is externally calibrated */ + /* [5] tables are low/high warn, low/high alarm, current */ + /* SFP voltage in 0.1mV units */ + uint16_t sfp_voltage[5]; + /* SFP Temp in 16-bit signed 1/256 Celcius */ + int16_t sfp_temp[5]; + /* Measured bias current in 2uA units */ + uint16_t bias_cur[5]; + /* Measured TX Power */ + uint16_t tx_power[5]; + /* Measured RX Power */ + uint16_t rx_power[5]; + struct sff_channel_diags scd[MAX_CHANNEL_NUM]; +}; + +double convert_mw_to_dbm(double mw); +void sff_show_value_with_unit(const uint8_t *data, unsigned int reg, + const char *name, unsigned int mult, + const char *unit, struct rte_tel_data *d); +void sff_show_ascii(const uint8_t *data, unsigned int first_reg, + unsigned int last_reg, const char *name, struct rte_tel_data *d); +void sff_show_thresholds(struct sff_diags sd, struct rte_tel_data *d); + +void sff_8024_show_oui(const uint8_t *data, int id_offset, struct rte_tel_data *d); +void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct rte_tel_data *d); +void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct rte_tel_data *d); +void sff_8024_show_encoding(const uint8_t *data, int encoding_offset, + int sff_type, struct rte_tel_data *d); + +#endif /* _SFF_COMMON_H_ */