Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/110223/?format=api
https://patches.dpdk.org/api/patches/110223/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/20220425053446.921528-5-robinx.zhang@intel.com/", "project": { "id": 1, "url": "https://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20220425053446.921528-5-robinx.zhang@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20220425053446.921528-5-robinx.zhang@intel.com", "date": "2022-04-25T05:34:45", "name": "[v4,4/5] ethdev: format module EEPROM for SFF-8472", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "83a59120529621636fc018d7c5b5bb36eae0e897", "submitter": { "id": 2004, "url": "https://patches.dpdk.org/api/people/2004/?format=api", "name": "Robin Zhang", "email": "robinx.zhang@intel.com" }, "delegate": null, "mbox": "https://patches.dpdk.org/project/dpdk/patch/20220425053446.921528-5-robinx.zhang@intel.com/mbox/", "series": [ { "id": 22654, "url": "https://patches.dpdk.org/api/series/22654/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=22654", "date": "2022-04-25T05:34:41", "name": "add telemetry command for show module EEPROM", "version": 4, "mbox": "https://patches.dpdk.org/series/22654/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/110223/comments/", "check": "success", "checks": "https://patches.dpdk.org/api/patches/110223/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "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])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B01AFA00BE;\n\tMon, 25 Apr 2022 07:40:23 +0200 (CEST)", "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 14F5542822;\n\tMon, 25 Apr 2022 07:39:46 +0200 (CEST)", "from mga18.intel.com (mga18.intel.com [134.134.136.126])\n by mails.dpdk.org (Postfix) with ESMTP id 998C74281C\n for <dev@dpdk.org>; Mon, 25 Apr 2022 07:39:43 +0200 (CEST)", "from orsmga008.jf.intel.com ([10.7.209.65])\n by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 24 Apr 2022 22:39:43 -0700", "from intel-cd-odc-robin.cd.intel.com ([10.240.178.191])\n by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 24 Apr 2022 22:39:40 -0700" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1650865183; x=1682401183;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=jCmLA9A7++9HEs+XNVBiUI2jMikiJk7V5qZho0bjmfc=;\n b=YjIcF2I5pMgg1Vqzlpt535fP+HWN8LsXji/LDOpQC4z/0mhsn4W6pMqK\n 72hg9crEKg8Xs/MK7OsotlwvaT3N60u+AOtWBj7Zi09zElZcqUy1ykyYL\n ep1q3DtPJSaH+DKQ1XxpbLK6sM21vfXwRM/bU0z0bj3hQx42xHwsJIoQT\n rxTQxgMWHOFO+mPzzgdJm0m/+3QFF3zbiV9U5Ss5b44jR022K+51xdHNT\n qtJ6EQDEX2UcZth9JdBiafuGTSH8QaMmuExeTPjd319UljhoJvP9ctGWL\n C4PqngwGNjOSCuyD1JJFvBz2ya0bLzbL8H8qh894EPfPO4wop4Bsm2AsJ Q==;", "X-IronPort-AV": [ "E=McAfee;i=\"6400,9594,10327\"; a=\"247070542\"", "E=Sophos;i=\"5.90,287,1643702400\"; d=\"scan'208\";a=\"247070542\"", "E=Sophos;i=\"5.90,287,1643702400\"; d=\"scan'208\";a=\"579087330\"" ], "From": "Robin Zhang <robinx.zhang@intel.com>", "To": "dev@dpdk.org", "Cc": "qiming.yang@intel.com, qi.z.zhang@intel.com, stevex.yang@intel.com,\n thomas@monjalon.net, andrew.rybchenko@oktetlabs.ru,\n bruce.richardson@intel.com, david.marchand@redhat.com,\n Robin Zhang <robinx.zhang@intel.com>", "Subject": "[PATCH v4 4/5] ethdev: format module EEPROM for SFF-8472", "Date": "Mon, 25 Apr 2022 05:34:45 +0000", "Message-Id": "<20220425053446.921528-5-robinx.zhang@intel.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20220425053446.921528-1-robinx.zhang@intel.com>", "References": "<20220215101853.919735-1-robinx.zhang@intel.com>\n <20220425053446.921528-1-robinx.zhang@intel.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org" }, "content": "This patch implements format module EEPROM information for\nSFF-8472 Rev 12.0\n\nSigned-off-by: Robin Zhang <robinx.zhang@intel.com>\n---\n lib/ethdev/ethdev_sff_telemetry.c | 4 +\n lib/ethdev/meson.build | 1 +\n lib/ethdev/sff_8472.c | 287 ++++++++++++++++++++++++++++++\n 3 files changed, 292 insertions(+)\n create mode 100644 lib/ethdev/sff_8472.c", "diff": "diff --git a/lib/ethdev/ethdev_sff_telemetry.c b/lib/ethdev/ethdev_sff_telemetry.c\nindex aa1e859068..fa93b35275 100644\n--- a/lib/ethdev/ethdev_sff_telemetry.c\n+++ b/lib/ethdev/ethdev_sff_telemetry.c\n@@ -67,6 +67,10 @@ sff_port_module_eeprom_display(uint16_t port_id, struct sff_item *items)\n \tcase RTE_ETH_MODULE_SFF_8079:\n \t\tsff_8079_show_all(einfo.data, items);\n \t\tbreak;\n+\tcase RTE_ETH_MODULE_SFF_8472:\n+\t\tsff_8079_show_all(einfo.data, items);\n+\t\tsff_8472_show_all(einfo.data, items);\n+\t\tbreak;\n \tdefault:\n \t\tRTE_ETHDEV_LOG(NOTICE, \"Unsupported module type: %u\\n\", minfo.type);\n \t\tbreak;\ndiff --git a/lib/ethdev/meson.build b/lib/ethdev/meson.build\nindex d94860da0c..4d81a35c09 100644\n--- a/lib/ethdev/meson.build\n+++ b/lib/ethdev/meson.build\n@@ -14,6 +14,7 @@ sources = files(\n 'ethdev_sff_telemetry.c',\n 'sff_common.c',\n 'sff_8079.c',\n+ 'sff_8472.c',\n )\n \n headers = files(\ndiff --git a/lib/ethdev/sff_8472.c b/lib/ethdev/sff_8472.c\nnew file mode 100644\nindex 0000000000..b4869d69c0\n--- /dev/null\n+++ b/lib/ethdev/sff_8472.c\n@@ -0,0 +1,287 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Intel Corporation\n+ *\n+ * Implements SFF-8472 optics diagnostics.\n+ *\n+ */\n+\n+#include <stdio.h>\n+#include <math.h>\n+#include <arpa/inet.h>\n+#include <rte_mbuf.h>\n+#include <rte_ethdev.h>\n+#include <rte_flow.h>\n+#include \"sff_common.h\"\n+#include \"ethdev_sff_telemetry.h\"\n+\n+/* Offsets in decimal, for direct comparison with the SFF specs */\n+\n+/* A0-based EEPROM offsets for DOM support checks */\n+#define SFF_A0_DOM 92\n+#define SFF_A0_OPTIONS 93\n+#define SFF_A0_COMP 94\n+\n+/* EEPROM bit values for various registers */\n+#define SFF_A0_DOM_EXTCAL (1 << 4)\n+#define SFF_A0_DOM_INTCAL (1 << 5)\n+#define SFF_A0_DOM_IMPL (1 << 6)\n+#define SFF_A0_DOM_PWRT (1 << 3)\n+\n+#define SFF_A0_OPTIONS_AW (1 << 7)\n+\n+/*\n+ * This is the offset at which the A2 page is in the EEPROM\n+ * blob returned by the kernel.\n+ */\n+#define SFF_A2_BASE 0x100\n+\n+/* A2-based offsets for DOM */\n+#define SFF_A2_TEMP 96\n+#define SFF_A2_TEMP_HALRM 0\n+#define SFF_A2_TEMP_LALRM 2\n+#define SFF_A2_TEMP_HWARN 4\n+#define SFF_A2_TEMP_LWARN 6\n+\n+#define SFF_A2_VCC 98\n+#define SFF_A2_VCC_HALRM 8\n+#define SFF_A2_VCC_LALRM 10\n+#define SFF_A2_VCC_HWARN 12\n+#define SFF_A2_VCC_LWARN 14\n+\n+#define SFF_A2_BIAS 100\n+#define SFF_A2_BIAS_HALRM 16\n+#define SFF_A2_BIAS_LALRM 18\n+#define SFF_A2_BIAS_HWARN 20\n+#define SFF_A2_BIAS_LWARN 22\n+\n+#define SFF_A2_TX_PWR 102\n+#define SFF_A2_TX_PWR_HALRM 24\n+#define SFF_A2_TX_PWR_LALRM 26\n+#define SFF_A2_TX_PWR_HWARN 28\n+#define SFF_A2_TX_PWR_LWARN 30\n+\n+#define SFF_A2_RX_PWR 104\n+#define SFF_A2_RX_PWR_HALRM 32\n+#define SFF_A2_RX_PWR_LALRM 34\n+#define SFF_A2_RX_PWR_HWARN 36\n+#define SFF_A2_RX_PWR_LWARN 38\n+\n+#define SFF_A2_ALRM_FLG 112\n+#define SFF_A2_WARN_FLG 116\n+\n+/* 32-bit little-endian calibration constants */\n+#define SFF_A2_CAL_RXPWR4 56\n+#define SFF_A2_CAL_RXPWR3 60\n+#define SFF_A2_CAL_RXPWR2 64\n+#define SFF_A2_CAL_RXPWR1 68\n+#define SFF_A2_CAL_RXPWR0 72\n+\n+/* 16-bit little endian calibration constants */\n+#define SFF_A2_CAL_TXI_SLP 76\n+#define SFF_A2_CAL_TXI_OFF 78\n+#define SFF_A2_CAL_TXPWR_SLP 80\n+#define SFF_A2_CAL_TXPWR_OFF 82\n+#define SFF_A2_CAL_T_SLP 84\n+#define SFF_A2_CAL_T_OFF 86\n+#define SFF_A2_CAL_V_SLP 88\n+#define SFF_A2_CAL_V_OFF 90\n+\n+static struct sff_8472_aw_flags {\n+\tconst char *str; /* Human-readable string, null at the end */\n+\tint offset; /* A2-relative address offset */\n+\tuint8_t value; /* Alarm is on if (offset & value) != 0. */\n+} sff_8472_aw_flags[] = {\n+\t{ \"Laser bias current high alarm\", SFF_A2_ALRM_FLG, (1 << 3) },\n+\t{ \"Laser bias current low alarm\", SFF_A2_ALRM_FLG, (1 << 2) },\n+\t{ \"Laser bias current high warning\", SFF_A2_WARN_FLG, (1 << 3) },\n+\t{ \"Laser bias current low warning\", SFF_A2_WARN_FLG, (1 << 2) },\n+\n+\t{ \"Laser output power high alarm\", SFF_A2_ALRM_FLG, (1 << 1) },\n+\t{ \"Laser output power low alarm\", SFF_A2_ALRM_FLG, (1 << 0) },\n+\t{ \"Laser output power high warning\", SFF_A2_WARN_FLG, (1 << 1) },\n+\t{ \"Laser output power low warning\", SFF_A2_WARN_FLG, (1 << 0) },\n+\n+\t{ \"Module temperature high alarm\", SFF_A2_ALRM_FLG, (1 << 7) },\n+\t{ \"Module temperature low alarm\", SFF_A2_ALRM_FLG, (1 << 6) },\n+\t{ \"Module temperature high warning\", SFF_A2_WARN_FLG, (1 << 7) },\n+\t{ \"Module temperature low warning\", SFF_A2_WARN_FLG, (1 << 6) },\n+\n+\t{ \"Module voltage high alarm\", SFF_A2_ALRM_FLG, (1 << 5) },\n+\t{ \"Module voltage low alarm\", SFF_A2_ALRM_FLG, (1 << 4) },\n+\t{ \"Module voltage high warning\", SFF_A2_WARN_FLG, (1 << 5) },\n+\t{ \"Module voltage low warning\", SFF_A2_WARN_FLG, (1 << 4) },\n+\n+\t{ \"Laser rx power high alarm\", SFF_A2_ALRM_FLG + 1, (1 << 7) },\n+\t{ \"Laser rx power low alarm\", SFF_A2_ALRM_FLG + 1, (1 << 6) },\n+\t{ \"Laser rx power high warning\", SFF_A2_WARN_FLG + 1, (1 << 7) },\n+\t{ \"Laser rx power low warning\", SFF_A2_WARN_FLG + 1, (1 << 6) },\n+\n+\t{ NULL, 0, 0 },\n+};\n+\n+/* Most common case: 16-bit unsigned integer in a certain unit */\n+#define A2_OFFSET_TO_U16(offset) \\\n+\t(data[SFF_A2_BASE + (offset)] << 8 | data[SFF_A2_BASE + (offset) + 1])\n+\n+/* Calibration slope is a number between 0.0 included and 256.0 excluded. */\n+#define A2_OFFSET_TO_SLP(offset) \\\n+\t(data[SFF_A2_BASE + (offset)] + data[SFF_A2_BASE + (offset) + 1] / 256.)\n+\n+/* Calibration offset is an integer from -32768 to 32767 */\n+#define A2_OFFSET_TO_OFF(offset) \\\n+\t((int16_t)A2_OFFSET_TO_U16(offset))\n+\n+/* RXPWR(x) are IEEE-754 floating point numbers in big-endian format */\n+#define A2_OFFSET_TO_RXPWRx(offset) \\\n+\t(befloattoh((const uint32_t *)(data + SFF_A2_BASE + (offset))))\n+\n+/*\n+ * 2-byte internal temperature conversions:\n+ * First byte is a signed 8-bit integer, which is the temp decimal part\n+ * Second byte are 1/256th of degree, which are added to the dec part.\n+ */\n+#define A2_OFFSET_TO_TEMP(offset) ((int16_t)A2_OFFSET_TO_U16(offset))\n+\n+static void sff_8472_dom_parse(const uint8_t *data, struct sff_diags *sd)\n+{\n+\tsd->bias_cur[MCURR] = A2_OFFSET_TO_U16(SFF_A2_BIAS);\n+\tsd->bias_cur[HALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HALRM);\n+\tsd->bias_cur[LALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LALRM);\n+\tsd->bias_cur[HWARN] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HWARN);\n+\tsd->bias_cur[LWARN] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LWARN);\n+\n+\tsd->sfp_voltage[MCURR] = A2_OFFSET_TO_U16(SFF_A2_VCC);\n+\tsd->sfp_voltage[HALRM] = A2_OFFSET_TO_U16(SFF_A2_VCC_HALRM);\n+\tsd->sfp_voltage[LALRM] = A2_OFFSET_TO_U16(SFF_A2_VCC_LALRM);\n+\tsd->sfp_voltage[HWARN] = A2_OFFSET_TO_U16(SFF_A2_VCC_HWARN);\n+\tsd->sfp_voltage[LWARN] = A2_OFFSET_TO_U16(SFF_A2_VCC_LWARN);\n+\n+\tsd->tx_power[MCURR] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR);\n+\tsd->tx_power[HALRM] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_HALRM);\n+\tsd->tx_power[LALRM] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_LALRM);\n+\tsd->tx_power[HWARN] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_HWARN);\n+\tsd->tx_power[LWARN] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_LWARN);\n+\n+\tsd->rx_power[MCURR] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR);\n+\tsd->rx_power[HALRM] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_HALRM);\n+\tsd->rx_power[LALRM] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_LALRM);\n+\tsd->rx_power[HWARN] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_HWARN);\n+\tsd->rx_power[LWARN] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_LWARN);\n+\n+\tsd->sfp_temp[MCURR] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP);\n+\tsd->sfp_temp[HALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HALRM);\n+\tsd->sfp_temp[LALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LALRM);\n+\tsd->sfp_temp[HWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HWARN);\n+\tsd->sfp_temp[LWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LWARN);\n+}\n+\n+/* Converts to a float from a big-endian 4-byte source buffer. */\n+static float befloattoh(const uint32_t *source)\n+{\n+\tunion {\n+\t\tuint32_t src;\n+\t\tfloat dst;\n+\t} converter;\n+\n+\tconverter.src = ntohl(*source);\n+\treturn converter.dst;\n+}\n+\n+static void sff_8472_calibration(const uint8_t *data, struct sff_diags *sd)\n+{\n+\tunsigned long i;\n+\tuint16_t rx_reading;\n+\n+\t/* Calibration should occur for all values (threshold and current) */\n+\tfor (i = 0; i < ARRAY_SIZE(sd->bias_cur); ++i) {\n+\t\t/*\n+\t\t * Apply calibration formula 1 (Temp., Voltage, Bias, Tx Power)\n+\t\t */\n+\t\tsd->bias_cur[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_TXI_SLP);\n+\t\tsd->tx_power[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_TXPWR_SLP);\n+\t\tsd->sfp_voltage[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_V_SLP);\n+\t\tsd->sfp_temp[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_T_SLP);\n+\n+\t\tsd->bias_cur[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_TXI_OFF);\n+\t\tsd->tx_power[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_TXPWR_OFF);\n+\t\tsd->sfp_voltage[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_V_OFF);\n+\t\tsd->sfp_temp[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_T_OFF);\n+\n+\t\t/*\n+\t\t * Apply calibration formula 2 (Rx Power only)\n+\t\t */\n+\t\trx_reading = sd->rx_power[i];\n+\t\tsd->rx_power[i] = A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR0);\n+\t\tsd->rx_power[i] += rx_reading *\n+\t\t\tA2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR1);\n+\t\tsd->rx_power[i] += rx_reading *\n+\t\t\tA2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR2);\n+\t\tsd->rx_power[i] += rx_reading *\n+\t\t\tA2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR3);\n+\t}\n+}\n+\n+static void sff_8472_parse_eeprom(const uint8_t *data, struct sff_diags *sd)\n+{\n+\tsd->supports_dom = data[SFF_A0_DOM] & SFF_A0_DOM_IMPL;\n+\tsd->supports_alarms = data[SFF_A0_OPTIONS] & SFF_A0_OPTIONS_AW;\n+\tsd->calibrated_ext = data[SFF_A0_DOM] & SFF_A0_DOM_EXTCAL;\n+\tsd->rx_power_type = data[SFF_A0_DOM] & SFF_A0_DOM_PWRT;\n+\n+\tsff_8472_dom_parse(data, sd);\n+\n+\t/*\n+\t * If the SFP is externally calibrated, we need to read calibration data\n+\t * and compensate the already stored readings.\n+\t */\n+\tif (sd->calibrated_ext)\n+\t\tsff_8472_calibration(data, sd);\n+}\n+\n+void sff_8472_show_all(const uint8_t *data, struct sff_item *items)\n+{\n+\tstruct sff_diags sd = {0};\n+\tconst char *rx_power_string = NULL;\n+\tchar val_string[SFF_ITEM_VAL_COMPOSE_SIZE];\n+\tint i;\n+\n+\tsff_8472_parse_eeprom(data, &sd);\n+\n+\tif (!sd.supports_dom) {\n+\t\tadd_item_string(items, \"Optical diagnostics support\", \"No\");\n+\t\treturn;\n+\t}\n+\tadd_item_string(items, \"Optical diagnostics support\", \"Yes\");\n+\n+\tSPRINT_BIAS(val_string, sd.bias_cur[MCURR]);\n+\tadd_item_string(items, \"Laser bias current\", val_string);\n+\n+\tSPRINT_xX_PWR(val_string, sd.tx_power[MCURR]);\n+\tadd_item_string(items, \"Laser output power\", val_string);\n+\n+\tif (!sd.rx_power_type)\n+\t\trx_power_string = \"Receiver signal OMA\";\n+\telse\n+\t\trx_power_string = \"Receiver signal average optical power\";\n+\n+\tSPRINT_xX_PWR(val_string, sd.rx_power[MCURR]);\n+\tadd_item_string(items, rx_power_string, val_string);\n+\n+\tSPRINT_TEMP(val_string, sd.sfp_temp[MCURR]);\n+\tadd_item_string(items, \"Module temperature\", val_string);\n+\n+\tSPRINT_VCC(val_string, sd.sfp_voltage[MCURR]);\n+\tadd_item_string(items, \"Module voltage\", val_string);\n+\n+\tadd_item_string(items, \"Alarm/warning flags implemented\",\n+\t\t\t(sd.supports_alarms ? \"Yes\" : \"No\"));\n+\n+\tif (sd.supports_alarms) {\n+\t\tfor (i = 0; sff_8472_aw_flags[i].str; ++i) {\n+\t\t\tadd_item_string(items, sff_8472_aw_flags[i].str,\n+\t\t\t\t\tdata[SFF_A2_BASE + sff_8472_aw_flags[i].offset]\n+\t\t\t\t\t& sff_8472_aw_flags[i].value ? \"On\" : \"Off\");\n+\t\t}\n+\t\tsff_show_thresholds(sd, items);\n+\t}\n+}\n", "prefixes": [ "v4", "4/5" ] }{ "id": 110223, "url": "