From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7E0F745635; Wed, 17 Jul 2024 15:35:48 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B4CA042E44; Wed, 17 Jul 2024 15:33:49 +0200 (CEST) Received: from egress-ip11b.ess.de.barracuda.com (egress-ip11b.ess.de.barracuda.com [18.185.115.215]) by mails.dpdk.org (Postfix) with ESMTP id 9EAAE427C4 for ; Wed, 17 Jul 2024 15:33:34 +0200 (CEST) Received: from EUR02-DB5-obe.outbound.protection.outlook.com (mail-db5eur02lp2105.outbound.protection.outlook.com [104.47.11.105]) by mx-outbound23-33.eu-central-1b.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 17 Jul 2024 13:33:33 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MCuYmT7XW2Bgc0MTSS8HrEmZ5DI2yJqF2+gfaYn67vct/heHF5a5a4dj5nG+gdR2gKtM7C2yR8BCEJnJ/g7mjVYmhVx4Pn2p4tAjkFQO48bcmSLOk+6QdfkywrqycTU5F7xlFfTaFEGMeJY9TMje9NdA+LoRh2z7vq5unGpgfktEXAzPpxYz7Y7DoZ9zY2T5QHkKRt7rZyFATImwmmiMNhWzH2vRnLBJqGePGruL0RT0MiNNzXO47X30cEaQvhS4uNGbnKv+phEK5644kdxTTgrcIt2wIoCVKcl1eAVrsq/xey9QvmhQem/fxFYmntglvLlKFPZM6dfb14uou1RcuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Bfi/MmGzU7zVeHFuJsCDA/2EGnPAMZaC1AyhuZnMaJI=; b=uWaFg42FjLzsepUszNigyFc6jWqQXv3khq7Mp4ZMvApkOdPV3x+9hDuQg5F7c9u31BfcUKgdLz0W5GBtzTRacmIHULMNDKRCn2upZCnkKcfu1zuZqUfZgwDrKHV87vGIUAAAHRrxG0HX8wF0YdQTD/iDWtZe+VEepCJGeGgLotqckTjPyFei8IECRp0TFI0fDEvKsU/lbfiKtY6hDOCOmyvuMoK+RoLFnTFK61DVR2eNj3FRqCSmh5N0v0sJ1OOuNFqvmGbH3twB7RVVBno8TBE/MXCtKP4TCxWk+SLqIhyoD3359GoeXIxSZO1xAUpLjuchtOUtLj2HxvX52H5OOQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 178.72.21.4) smtp.rcpttodomain=dpdk.org smtp.mailfrom=napatech.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=napatech.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=napatech.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Bfi/MmGzU7zVeHFuJsCDA/2EGnPAMZaC1AyhuZnMaJI=; b=nGkku7McxiwIwj27HvWdwZ1p8izA2mHsoQQpAqD4EvlD+K+HJgnSs6riSSvx0/lWHBqvh8yLxr45qxZ1QXO+kC3qpPhHbAAvj3HOjQyH4dvd5tnguBqhU8fOpng0ql4USZO8mhGgjHV9CaStJAMomBWYdA1Se+dxFDxqbux3n1E= Received: from AM0PR04CA0106.eurprd04.prod.outlook.com (2603:10a6:208:be::47) by AS4P190MB1736.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:4b0::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7784.14; Wed, 17 Jul 2024 13:33:28 +0000 Received: from AM3PEPF0000A799.eurprd04.prod.outlook.com (2603:10a6:208:be:cafe::86) by AM0PR04CA0106.outlook.office365.com (2603:10a6:208:be::47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7762.29 via Frontend Transport; Wed, 17 Jul 2024 13:33:28 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 178.72.21.4) smtp.mailfrom=napatech.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=napatech.com; Received-SPF: Fail (protection.outlook.com: domain of napatech.com does not designate 178.72.21.4 as permitted sender) receiver=protection.outlook.com; client-ip=178.72.21.4; helo=localhost.localdomain; Received: from localhost.localdomain (178.72.21.4) by AM3PEPF0000A799.mail.protection.outlook.com (10.167.16.104) with Microsoft SMTP Server id 15.20.7784.11 via Frontend Transport; Wed, 17 Jul 2024 13:33:28 +0000 From: Serhii Iliushyk To: dev@dpdk.org Cc: mko-plv@napatech.com, sil-plv@napatech.com, ckm@napatech.com, andrew.rybchenko@oktetlabs.ru, ferruh.yigit@amd.com Subject: [PATCH v10 18/21] net/ntnic: add QSFP support Date: Wed, 17 Jul 2024 15:33:05 +0200 Message-ID: <20240717133313.3104239-18-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20240717133313.3104239-1-sil-plv@napatech.com> References: <20240530144929.4127931-1-sil-plv@napatech.com> <20240717133313.3104239-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM3PEPF0000A799:EE_|AS4P190MB1736:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 2c14de51-b0e5-4cdc-3c41-08dca6650ac4 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|82310400026|1800799024|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?G0gJkHo8RXq7f52GzyRlXHmi0+BEnLlx0R0qNxQxsyk3XP0fHyOqi2PcU1Sp?= =?us-ascii?Q?DeWEqjns5LhSu0Mw5d+85ZGJKuYBZGCuCmMRi1u8BJOYir9jm2Wt4addybAy?= =?us-ascii?Q?Bl50AgZKLwn2/DbtYBtxHRt57FjqPfl/7cQJmgf+IOV6Av1C8CzQbGCKqvkj?= =?us-ascii?Q?aEaQ7Y4RLst3NZZOGdDSwMo+Ssl8BAYJmBAbcBBhdLOthuaU1xQi/tqrof62?= =?us-ascii?Q?0GI4t5q6tf/nOfeuOzErgLsd7+iEDVOTjH+9ttDYWOhlynm4Ky6nC2vf6qpo?= =?us-ascii?Q?+S8XBjM4ITkWB9U0FChcRNJj7E3Mv4maK/IzDJpW58TwGo8WcYBL2YOWR0Lr?= =?us-ascii?Q?GbvJEA9i2zV7LM1GhY52emszjGQLczxlWFDoYlFix/21yqY3jMXgTvDhCsbo?= =?us-ascii?Q?gcBwjvSZRIrQh+bwuFhuoKEBXdpESYgMSV1J40sk01we2InKWy7vBLP9xB+e?= =?us-ascii?Q?4dqpH+IHJ2A/DB5mNgrV4B/XiiVWDuN8Tho9fODzQqSqwvxGZUtMAsjtqAgM?= =?us-ascii?Q?/6GNGNmpy6ZT23GqqAXUe7Ps9APFNCV1I7VLCItEpAFkmTyCPtm9RfPMTYsH?= =?us-ascii?Q?LofVtG31W8K/HsSztfcu/le2MWFP3rDodX/ChFG9UaZnke5Pic+j1c3PlZQK?= =?us-ascii?Q?+y2fpxLY1pA1awXrLfcZ5ClOuVWhUp+D0QLc7bcpwcuru3kVpcJvNEYZzwiI?= =?us-ascii?Q?xTAIdV1xERglfulIY8Ug9qf80Hc7RP53oCBvYOBXcGTXIiSWqc4DXGCoaBq1?= =?us-ascii?Q?Uqa/OEmg6tFnRDgi7KrKy7ulK3+eWwJ1Fl2h5MDrYbw/jlGjS3ky/H1Wk3Cq?= =?us-ascii?Q?6KMwkaqqNPn6wQOaf+V7HzIvo0Qsz0351y1aznfCOoy9G3Tk3/dLDpIjuVJC?= =?us-ascii?Q?aQmyctKbLmm7cP7JEhXeYi9FM7uiH2g70KmshbzLB7K6Ty0JjdavROnyz46d?= =?us-ascii?Q?wFi7gAQRCcQN6ej1DuyzRLH6kAfQT3AXxKmUS9mwbiP3akdxWBZU6gbezKo4?= =?us-ascii?Q?BGDfRwi+fzUhP8tn/Kqx+Uk7aU3hmbuvcPyUXDH61QFSVRGcE9GK4lOCQce9?= =?us-ascii?Q?/WOQX1MDYrPr0YW2GZtB8vzv+88Onc0zVg+oJr8kXyV+pdq1gSTrYdagiflw?= =?us-ascii?Q?PcZg4iLzw+3NMK7XrwSvrJHpK4v0ICL267rmdZu49Z/t2PnSou/1iwaCBVvM?= =?us-ascii?Q?UZ8xBTFdIDW9WUC+R4qDEsule0PscSs1J3UfsvgHztarpm54QgQW6v+F1nsF?= =?us-ascii?Q?SYWGVxb3Vik7OnTDLzDsmsr+OeQ1sotiDOAbvvf76zPrWSv0AZFlNbpZ6r2u?= =?us-ascii?Q?Z8LCI+FoNW7cMrIJRqAsnpGHZpvunMtrxhh9RRla02K4+TJ+q3Y9JYjp7FeV?= =?us-ascii?Q?YEprUdyjZ2yusJ+Iz2w9JCCHm2RN98G6jxcVV6g3Ji3BlXlk9s5BSuaEfi7U?= =?us-ascii?Q?01lP/jAFwQOq/a0fyaf1phaetuF9AffM?= X-Forefront-Antispam-Report: CIP:178.72.21.4; CTRY:DK; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:localhost.localdomain; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(376014)(82310400026)(1800799024)(36860700013); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: aI/ra3hs3kCisYiE8A3UKzSZj34DlEyYNgfGeH1qrJ5oPKyOLxjXZ0rbggBswhRlp0HczRTqPdEuvak+TUDGefu6ecRPfOyOQC4H8O6ApANd6I9Yv/sP95qa/9Rtqb9NgnJk+JM3kgGFjLNYrbM6MEAJRzdFCwQrWYw2FHGCDVsyudoFgvS3BuOCdskzlpDYvXyeasskHdhdzExj0vmJgGQrtUUVvXlZhlrUSvSbeLYElc8hDS/aiIsYVeqGwfr97jI3OM/NjSifMCFnjh6X+82fMDjrki5NgieEKLmLIlE9LnNYOy2cGQ93qwx478F5jG+u4EAV/GcQjWQvxPb7Xy147qYAPaq/0KbC7y6blqTVPp9HqwGGlzfKgq25k85sUz77gTBjthbiPcFfxQy9gQfTSYUbr2o/NKpBd2+EJaaf4jwcz2DOU/94XyWrvrmzi0wxvLbls7F7FwbDvyrfjvemJsmdJu0YTVXeRqGERz/YmDjdcaXk9B0MTjlcvRcEs6PyXI5jV5i/XaTpCwWDF2TWCkbtF7YOx6uh4Ful9cy4EiFELsJXVImWbdLwiBFAmRRKcZnc/HCN/ITdsdLPPYj2mmMDnmuNBv3j6Q6X9XshHWg/fRkAVgDGfh8d00V86lAmmc1xn0UkwS/obeyTyQ== X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2024 13:33:28.0901 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2c14de51-b0e5-4cdc-3c41-08dca6650ac4 X-MS-Exchange-CrossTenant-Id: c4540d0b-728a-4233-9da5-9ea30c7ec3ed X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=c4540d0b-728a-4233-9da5-9ea30c7ec3ed; Ip=[178.72.21.4]; Helo=[localhost.localdomain] X-MS-Exchange-CrossTenant-AuthSource: AM3PEPF0000A799.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS4P190MB1736 X-BESS-ID: 1721223210-305921-12774-14962-2 X-BESS-VER: 2019.1_20240716.1757 X-BESS-Apparent-Source-IP: 104.47.11.105 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVoZmhgaGQGYGUNTU3MLczDzJIN HUyNQ80dTYKDEl0TwpLcXY0DQtzdzYSKk2FgAu7TC5QgAAAA== X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.257687 [from cloudscan23-102.eu-central-1b.ess.aws.cudaops.com] Rule breakdown below pts rule name description ---- ---------------------- -------------------------------- 0.50 BSF_RULE7568M META: Custom Rule 7568M 0.00 BSF_BESS_OUTBOUND META: BESS Outbound X-BESS-Outbound-Spam-Status: SCORE=0.50 using account:ESS113687 scores of KILL_LEVEL=7.0 tests=BSF_RULE7568M, BSF_BESS_OUTBOUND X-BESS-BRTS-Status: 1 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 Includes support for QSFP and QSFP+. Signed-off-by: Serhii Iliushyk --- drivers/net/ntnic/include/ntnic_nim.h | 10 + .../link_mgmt/link_100g/nt4ga_link_100g.c | 12 +- drivers/net/ntnic/nim/i2c_nim.c | 310 +++++++++++++++++- drivers/net/ntnic/nim/i2c_nim.h | 14 +- drivers/net/ntnic/nim/nim_defines.h | 3 + drivers/net/ntnic/nim/qsfp_registers.h | 43 +++ 6 files changed, 389 insertions(+), 3 deletions(-) create mode 100644 drivers/net/ntnic/nim/qsfp_registers.h diff --git a/drivers/net/ntnic/include/ntnic_nim.h b/drivers/net/ntnic/include/ntnic_nim.h index fd4a915811..216930af76 100644 --- a/drivers/net/ntnic/include/ntnic_nim.h +++ b/drivers/net/ntnic/include/ntnic_nim.h @@ -15,6 +15,8 @@ typedef enum i2c_type { enum nt_port_type_e { NT_PORT_TYPE_NOT_AVAILABLE = 0, /* The NIM/port type is not available (unknown) */ NT_PORT_TYPE_NOT_RECOGNISED, /* The NIM/port type not recognized */ + NT_PORT_TYPE_QSFP_PLUS_NOT_PRESENT, /* QSFP type but slot is empty */ + NT_PORT_TYPE_QSFP_PLUS, /* QSFP type */ }; typedef enum nt_port_type_e nt_port_type_t, *nt_port_type_p; @@ -51,6 +53,14 @@ typedef struct nim_i2c_ctx { bool tx_disable; bool dmi_supp; + union { + struct { + bool rx_only; + union { + } specific_u; + } qsfp; + + } specific_u; } nim_i2c_ctx_t, *nim_i2c_ctx_p; struct nim_sensor_group { diff --git a/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c b/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c index 4a8d28af9c..69d0a5d24a 100644 --- a/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c +++ b/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c @@ -18,6 +18,7 @@ static int _create_nim(adapter_info_t *drv, int port) int res = 0; const uint8_t valid_nim_id = 17U; nim_i2c_ctx_t *nim_ctx; + sfp_nim_state_t nim; nt4ga_link_t *link_info = &drv->nt4ga_link; assert(port >= 0 && port < NUM_ADAPTER_PORTS_MAX); @@ -31,11 +32,20 @@ static int _create_nim(adapter_info_t *drv, int port) */ nt_os_wait_usec(1000000); /* pause 1.0s */ - res = construct_and_preinit_nim(nim_ctx); + res = construct_and_preinit_nim(nim_ctx, NULL); if (res) return res; + res = nim_state_build(nim_ctx, &nim); + + if (res) + return res; + + NT_LOG(DBG, NTHW, "%s: NIM id = %u (%s), br = %u, vendor = '%s', pn = '%s', sn='%s'\n", + drv->mp_port_id_str[port], nim_ctx->nim_id, nim_id_to_text(nim_ctx->nim_id), nim.br, + nim_ctx->vendor_name, nim_ctx->prod_no, nim_ctx->serial_no); + /* * Does the driver support the NIM module type? */ diff --git a/drivers/net/ntnic/nim/i2c_nim.c b/drivers/net/ntnic/nim/i2c_nim.c index 3281058822..0071d452bb 100644 --- a/drivers/net/ntnic/nim/i2c_nim.c +++ b/drivers/net/ntnic/nim/i2c_nim.c @@ -10,6 +10,7 @@ #include "ntlog.h" #include "nt_util.h" #include "ntnic_mod_reg.h" +#include "qsfp_registers.h" #include "nim_defines.h" #define NIM_READ false @@ -17,6 +18,25 @@ #define NIM_PAGE_SEL_REGISTER 127 #define NIM_I2C_0XA0 0xA0 /* Basic I2C address */ + +static bool page_addressing(nt_nim_identifier_t id) +{ + switch (id) { + case NT_NIM_QSFP: + case NT_NIM_QSFP_PLUS: + return true; + + default: + NT_LOG(DBG, NTNIC, "Unknown NIM identifier %d\n", id); + return false; + } +} + +static nt_nim_identifier_t translate_nimid(const nim_i2c_ctx_t *ctx) +{ + return (nt_nim_identifier_t)ctx->nim_id; +} + static int nim_read_write_i2c_data(nim_i2c_ctx_p ctx, bool do_write, uint16_t lin_addr, uint8_t i2c_addr, uint8_t a_reg_addr, uint8_t seq_cnt, uint8_t *p_data) @@ -158,6 +178,13 @@ static int nim_read_write_data_lin(nim_i2c_ctx_p ctx, bool m_page_addressing, ui return 0; } +static int read_data_lin(nim_i2c_ctx_p ctx, uint16_t lin_addr, uint16_t length, void *data) +{ + /* Wrapper for using Mutex for QSFP TODO */ + return nim_read_write_data_lin(ctx, page_addressing(ctx->nim_id), lin_addr, length, data, + NIM_READ); +} + static int nim_read_id(nim_i2c_ctx_t *ctx) { /* We are only reading the first byte so we don't care about pages here. */ @@ -205,20 +232,301 @@ static int i2c_nim_common_construct(nim_i2c_ctx_p ctx) return 0; } +/* + * Read vendor information at a certain address. Any trailing whitespace is + * removed and a missing string termination in the NIM data is handled. + */ +static int nim_read_vendor_info(nim_i2c_ctx_p ctx, uint16_t addr, uint8_t max_len, char *p_data) +{ + const bool pg_addr = page_addressing(ctx->nim_id); + int i; + /* Subtract "1" from max_len that includes a terminating "0" */ + + if (nim_read_write_data_lin(ctx, pg_addr, addr, (uint8_t)(max_len - 1), (uint8_t *)p_data, + NIM_READ) != 0) { + return -1; + } + + /* Terminate at first found white space */ + for (i = 0; i < max_len - 1; i++) { + if (*p_data == ' ' || *p_data == '\n' || *p_data == '\t' || *p_data == '\v' || + *p_data == '\f' || *p_data == '\r') { + *p_data = '\0'; + return 0; + } + + p_data++; + } + + /* + * Add line termination as the very last character, if it was missing in the + * NIM data + */ + *p_data = '\0'; + return 0; +} + +static void qsfp_read_vendor_info(nim_i2c_ctx_t *ctx) +{ + nim_read_vendor_info(ctx, QSFP_VENDOR_NAME_LIN_ADDR, sizeof(ctx->vendor_name), + ctx->vendor_name); + nim_read_vendor_info(ctx, QSFP_VENDOR_PN_LIN_ADDR, sizeof(ctx->prod_no), ctx->prod_no); + nim_read_vendor_info(ctx, QSFP_VENDOR_SN_LIN_ADDR, sizeof(ctx->serial_no), ctx->serial_no); + nim_read_vendor_info(ctx, QSFP_VENDOR_DATE_LIN_ADDR, sizeof(ctx->date), ctx->date); + nim_read_vendor_info(ctx, QSFP_VENDOR_REV_LIN_ADDR, (uint8_t)(sizeof(ctx->rev) - 2), + ctx->rev); /*OBS Only two bytes*/ +} +static int qsfp_nim_state_build(nim_i2c_ctx_t *ctx, sfp_nim_state_t *state) +{ + int res = 0; /* unused due to no readings from HW */ + + assert(ctx && state); + assert(ctx->nim_id != NT_NIM_UNKNOWN && "Nim is not initialized"); + + (void)memset(state, 0, sizeof(*state)); + + switch (ctx->nim_id) { + case 12U: + state->br = 10U;/* QSFP: 4 x 1G = 4G */ + break; + + case 13U: + state->br = 103U; /* QSFP+: 4 x 10G = 40G */ + break; + + default: + NT_LOG(INF, NIM, "nim_id = %u is not an QSFP/QSFP+ module\n", ctx->nim_id); + res = -1; + } + + return res; +} + +int nim_state_build(nim_i2c_ctx_t *ctx, sfp_nim_state_t *state) +{ + return qsfp_nim_state_build(ctx, state); +} + const char *nim_id_to_text(uint8_t nim_id) { switch (nim_id) { case 0x0: return "UNKNOWN"; + case 0x0C: + return "QSFP"; + + case 0x0D: + return "QSFP+"; + default: return "ILLEGAL!"; } } -int construct_and_preinit_nim(nim_i2c_ctx_p ctx) +/* + * Disable laser for specific lane or all lanes + */ +int nim_qsfp_plus_nim_set_tx_laser_disable(nim_i2c_ctx_p ctx, bool disable, int lane_idx) +{ + uint8_t value; + uint8_t mask; + const bool pg_addr = page_addressing(ctx->nim_id); + + if (lane_idx < 0) /* If no lane is specified then all lanes */ + mask = QSFP_SOFT_TX_ALL_DISABLE_BITS; + + else + mask = (uint8_t)(1U << lane_idx); + + if (nim_read_write_data_lin(ctx, pg_addr, QSFP_CONTROL_STATUS_LIN_ADDR, sizeof(value), + &value, NIM_READ) != 0) { + return -1; + } + + if (disable) + value |= mask; + + else + value &= (uint8_t)(~mask); + + if (nim_read_write_data_lin(ctx, pg_addr, QSFP_CONTROL_STATUS_LIN_ADDR, sizeof(value), + &value, NIM_WRITE) != 0) { + return -1; + } + + return 0; +} + +/* + * Import length info in various units from NIM module data and convert to meters + */ +static void nim_import_len_info(nim_i2c_ctx_p ctx, uint8_t *p_nim_len_info, uint16_t *p_nim_units) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(ctx->len_info); i++) + if (*(p_nim_len_info + i) == 255) { + ctx->len_info[i] = 65535; + + } else { + uint32_t len = *(p_nim_len_info + i) * *(p_nim_units + i); + + if (len > 65535) + ctx->len_info[i] = 65535; + + else + ctx->len_info[i] = (uint16_t)len; + } +} + +static int qsfpplus_read_basic_data(nim_i2c_ctx_t *ctx) +{ + const bool pg_addr = page_addressing(ctx->nim_id); + uint8_t options; + uint8_t value; + uint8_t nim_len_info[5]; + uint16_t nim_units[5] = { 1000, 2, 1, 1, 1 }; /* QSFP MSA units in meters */ + const char *yes_no[2] = { "No", "Yes" }; + (void)yes_no; + NT_LOG(DBG, NTNIC, "Instance %d: NIM id: %s (%d)\n", ctx->instance, + nim_id_to_text(ctx->nim_id), ctx->nim_id); + + /* Read DMI options */ + if (nim_read_write_data_lin(ctx, pg_addr, QSFP_DMI_OPTION_LIN_ADDR, sizeof(options), + &options, NIM_READ) != 0) { + return -1; + } + + ctx->avg_pwr = options & QSFP_DMI_AVG_PWR_BIT; + NT_LOG(DBG, NTNIC, "Instance %d: NIM options: (DMI: Yes, AvgPwr: %s)\n", ctx->instance, + yes_no[ctx->avg_pwr]); + + qsfp_read_vendor_info(ctx); + NT_LOG(DBG, PMD, + "Instance %d: NIM info: (Vendor: %s, PN: %s, SN: %s, Date: %s, Rev: %s)\n", + ctx->instance, ctx->vendor_name, ctx->prod_no, ctx->serial_no, ctx->date, ctx->rev); + + if (nim_read_write_data_lin(ctx, pg_addr, QSFP_SUP_LEN_INFO_LIN_ADDR, sizeof(nim_len_info), + nim_len_info, NIM_READ) != 0) { + return -1; + } + + /* + * Returns supported length information in meters for various fibers as 5 indivi- + * dual values: [SM(9um), EBW(50um), MM(50um), MM(62.5um), Copper] + * If no length information is available for a certain entry, the returned value + * will be zero. This will be the case for SFP modules - EBW entry. + * If the MSBit is set the returned value in the lower 31 bits indicates that the + * supported length is greater than this. + */ + + nim_import_len_info(ctx, nim_len_info, nim_units); + + /* Read required power level */ + if (nim_read_write_data_lin(ctx, pg_addr, QSFP_EXTENDED_IDENTIFIER, sizeof(value), &value, + NIM_READ) != 0) { + return -1; + } + + /* + * Get power class according to SFF-8636 Rev 2.7, Table 6-16, Page 43: + * If power class >= 5 setHighPower must be called for the module to be fully + * functional + */ + if ((value & QSFP_POWER_CLASS_BITS_5_7) == 0) { + /* NIM in power class 1 - 4 */ + ctx->pwr_level_req = (uint8_t)(((value & QSFP_POWER_CLASS_BITS_1_4) >> 6) + 1); + + } else { + /* NIM in power class 5 - 7 */ + ctx->pwr_level_req = (uint8_t)((value & QSFP_POWER_CLASS_BITS_5_7) + 4); + } + + return 0; +} + +static void qsfpplus_find_port_params(nim_i2c_ctx_p ctx) +{ + uint8_t device_tech; + read_data_lin(ctx, QSFP_TRANSMITTER_TYPE_LIN_ADDR, sizeof(device_tech), &device_tech); + + switch (device_tech & 0xF0) { + case 0xA0: /* Copper cable unequalized */ + break; + + case 0xC0: /* Copper cable, near and far end limiting active equalizers */ + case 0xD0: /* Copper cable, far end limiting active equalizers */ + case 0xE0: /* Copper cable, near end limiting active equalizers */ + break; + + default:/* Optical */ + ctx->port_type = NT_PORT_TYPE_QSFP_PLUS; + break; + } +} + +static void qsfpplus_set_speed_mask(nim_i2c_ctx_p ctx) +{ + ctx->speed_mask = (ctx->lane_idx < 0) ? NT_LINK_SPEED_40G : (NT_LINK_SPEED_10G); +} + +static void qsfpplus_construct(nim_i2c_ctx_p ctx, int8_t lane_idx) +{ + assert(lane_idx < 4); + ctx->lane_idx = lane_idx; + ctx->lane_count = 4; +} + +static int qsfpplus_preinit(nim_i2c_ctx_p ctx, int8_t lane_idx) +{ + qsfpplus_construct(ctx, lane_idx); + int res = qsfpplus_read_basic_data(ctx); + + if (!res) { + qsfpplus_find_port_params(ctx); + + /* + * Read if TX_DISABLE has been implemented + * For passive optical modules this is required while it for copper and active + * optical modules is optional. Under all circumstances register 195.4 will + * indicate, if TX_DISABLE has been implemented in register 86.0-3 + */ + uint8_t value; + read_data_lin(ctx, QSFP_OPTION3_LIN_ADDR, sizeof(value), &value); + + ctx->tx_disable = (value & QSFP_OPTION3_TX_DISABLE_BIT) != 0; + + if (ctx->tx_disable) + ctx->options |= (1 << NIM_OPTION_TX_DISABLE); + + /* + * Previously - considering AFBR-89BRDZ - code tried to establish if a module was + * RxOnly by testing the state of the lasers after reset. Lasers were for this + * module default disabled. + * However that code did not work for GigaLight, GQS-MPO400-SR4C so it was + * decided that this option should not be detected automatically but from PN + */ + ctx->specific_u.qsfp.rx_only = (ctx->options & (1 << NIM_OPTION_RX_ONLY)) != 0; + qsfpplus_set_speed_mask(ctx); + } + + return res; +} + +int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra) { int res = i2c_nim_common_construct(ctx); + switch (translate_nimid(ctx)) { + case NT_NIM_QSFP_PLUS: + qsfpplus_preinit(ctx, extra ? *(int8_t *)extra : (int8_t)-1); + break; + + default: + res = 1; + NT_LOG(ERR, NTHW, "NIM type %s is not supported.\n", nim_id_to_text(ctx->nim_id)); + } + return res; } diff --git a/drivers/net/ntnic/nim/i2c_nim.h b/drivers/net/ntnic/nim/i2c_nim.h index e89ae47835..edb6dcf1b6 100644 --- a/drivers/net/ntnic/nim/i2c_nim.h +++ b/drivers/net/ntnic/nim/i2c_nim.h @@ -8,17 +8,29 @@ #include "ntnic_nim.h" +typedef struct sfp_nim_state { + uint8_t br; /* bit rate, units of 100 MBits/sec */ +} sfp_nim_state_t, *sfp_nim_state_p; + +/* + * Builds an nim state for the port implied by `ctx`, returns zero + * if successful, and non-zero otherwise. SFP and QSFP nims are supported + */ +int nim_state_build(nim_i2c_ctx_t *ctx, sfp_nim_state_t *state); + /* * Returns a type name such as "SFP/SFP+" for a given NIM type identifier, * or the string "ILLEGAL!". */ const char *nim_id_to_text(uint8_t nim_id); +int nim_qsfp_plus_nim_set_tx_laser_disable(nim_i2c_ctx_t *ctx, bool disable, int lane_idx); + /* * This function tries to classify NIM based on it's ID and some register reads * and collects information into ctx structure. The @extra parameter could contain * the initialization argument for specific type of NIMS. */ -int construct_and_preinit_nim(nim_i2c_ctx_p ctx); +int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra); #endif /* I2C_NIM_H_ */ diff --git a/drivers/net/ntnic/nim/nim_defines.h b/drivers/net/ntnic/nim/nim_defines.h index 9ba861bb4f..e5a033a3d4 100644 --- a/drivers/net/ntnic/nim/nim_defines.h +++ b/drivers/net/ntnic/nim/nim_defines.h @@ -7,6 +7,7 @@ #define NIM_DEFINES_H_ #define NIM_IDENTIFIER_ADDR 0 /* 1 byte */ +#define QSFP_EXTENDED_IDENTIFIER 129 /* I2C addresses */ #define NIM_I2C_0XA0 0xA0 /* Basic I2C address */ @@ -23,6 +24,8 @@ typedef enum { enum nt_nim_identifier_e { NT_NIM_UNKNOWN = 0x00, /* Nim type is unknown */ + NT_NIM_QSFP = 0x0C, /* Nim type = QSFP */ + NT_NIM_QSFP_PLUS = 0x0D,/* Nim type = QSFP+ */ }; typedef enum nt_nim_identifier_e nt_nim_identifier_t; diff --git a/drivers/net/ntnic/nim/qsfp_registers.h b/drivers/net/ntnic/nim/qsfp_registers.h new file mode 100644 index 0000000000..13172ce30b --- /dev/null +++ b/drivers/net/ntnic/nim/qsfp_registers.h @@ -0,0 +1,43 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef _QSFP_REGISTERS_H +#define _QSFP_REGISTERS_H + +/* + * QSFP Registers + */ +#define QSFP_INT_STATUS_RX_LOS_ADDR 3 +#define QSFP_TEMP_LIN_ADDR 22 +#define QSFP_VOLT_LIN_ADDR 26 +#define QSFP_RX_PWR_LIN_ADDR 34 /* uint16_t [0..3] */ +#define QSFP_TX_BIAS_LIN_ADDR 42/* uint16_t [0..3] */ +#define QSFP_TX_PWR_LIN_ADDR 50 /* uint16_t [0..3] */ + +#define QSFP_CONTROL_STATUS_LIN_ADDR 86 +#define QSFP_SOFT_TX_ALL_DISABLE_BITS 0x0F + +#define QSFP_POWER_CLASS_BITS_1_4 0xC0 +#define QSFP_POWER_CLASS_BITS_5_7 0x03 + +#define QSFP_SUP_LEN_INFO_LIN_ADDR 142 /* 5bytes */ +#define QSFP_TRANSMITTER_TYPE_LIN_ADDR 147 /* 1byte */ +#define QSFP_VENDOR_NAME_LIN_ADDR 148 /* 16bytes */ +#define QSFP_VENDOR_PN_LIN_ADDR 168 /* 16bytes */ +#define QSFP_VENDOR_SN_LIN_ADDR 196 /* 16bytes */ +#define QSFP_VENDOR_DATE_LIN_ADDR 212 /* 8bytes */ +#define QSFP_VENDOR_REV_LIN_ADDR 184 /* 2bytes */ + +#define QSFP_SPEC_COMPLIANCE_CODES_ADDR 131 /* 8 bytes */ +#define QSFP_EXT_SPEC_COMPLIANCE_CODES_ADDR 192 /* 1 byte */ + +#define QSFP_OPTION3_LIN_ADDR 195 +#define QSFP_OPTION3_TX_DISABLE_BIT (1 << 4) + +#define QSFP_DMI_OPTION_LIN_ADDR 220 +#define QSFP_DMI_AVG_PWR_BIT (1 << 3) + + +#endif /* _QSFP_REGISTERS_H */ -- 2.43.0