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 8301D455F3; Thu, 11 Jul 2024 14:09:41 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 968B542EB0; Thu, 11 Jul 2024 14:08:12 +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 1E3A542E9F for ; Thu, 11 Jul 2024 14:08:04 +0200 (CEST) Received: from EUR03-VI1-obe.outbound.protection.outlook.com (mail-vi1eur03lp2111.outbound.protection.outlook.com [104.47.30.111]) by mx-outbound17-202.eu-central-1b.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 11 Jul 2024 12:08:02 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZYZQ2wnqPB6HpCDK9cucnCcVnuGD0TfxN1eFo06NIQB0cgV2pzokwOL8tRrbMye9vfnHRQtvhw2wxcovkmwseOYD5+8qSnNMF5SXq1x0nQ12jrb1+FW5juk015YdXXTfnSC+dZO6WUHBxXAh36yIpJVbb0skGGJCuFO3/mzGSUjBB77eZfIz2Ldh/JrDG06i8Hn1ahBKj9QAuBPcyHrikffdBnQhEj7nhMOqFhSEqCkAqbBtM1j1GJk7nUWk5NMFuJpgnVWM1WrgJlINe76GfrXS+dANvu8jwsw0HbbTiTRlyjXfJ1/AxoLvCsENWV1XMOqEgaKJVW9pQe4xY+8wNA== 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=0ERiF4PwFqfBEbvlS2ksh34rcf2yfdTuR6/6qH5jXYM=; b=eRgyFixupqFcRGr3Zrju0PYMq38WrOh1zTi4QLC0BoByso2nGfYpc249x8MYGbfTa0+5/Lm96A/5TVUlpbjZlf4WCVVvBGYhokbfQnebnNTDsMp/pcs4wSGZSvvN/JhgtyKDxIq3Ksci6H43GXexkl8ukuB2cThirYeCv9BZ7ZTy3x+S2uJaaZ2FIPE9/G8q7zzWSCno/PekbcqhXvDDM3S0f0Y1S8I/ruNw/KTVFeP4OS017alg+O4If43jLPiiL1k4lr/w6se+GRoPk2R4skQXDFQv4c5ig75Ej0z5+Qiwd0cZoFHuUBPE2MQgf3CGpcPHX6aPWlFnQJy4rkEsqw== 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=0ERiF4PwFqfBEbvlS2ksh34rcf2yfdTuR6/6qH5jXYM=; b=HiGuEVEo/GlSoRhI2Ln7IQyYZnJkZ2Fuaai/EzW+XyPZUC/Q2GxSKeoQ+UaK3WDDjLOkkB96f4Rob9/C6cb+in6DZcy43FN92f4W+fO5FRsbEL04eMksGnMh28xqNDJOwGl7O4iG+6GWjmYoeD6jCiB6SJhWxl23VvxDhOrorbc= Received: from AS9PR04CA0092.eurprd04.prod.outlook.com (2603:10a6:20b:50e::6) by AM8P190MB0930.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:1db::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7762.22; Thu, 11 Jul 2024 12:08:00 +0000 Received: from AMS0EPF0000019F.eurprd05.prod.outlook.com (2603:10a6:20b:50e:cafe::a9) by AS9PR04CA0092.outlook.office365.com (2603:10a6:20b:50e::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7762.22 via Frontend Transport; Thu, 11 Jul 2024 12:08:00 +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 AMS0EPF0000019F.mail.protection.outlook.com (10.167.16.251) with Microsoft SMTP Server id 15.20.7762.17 via Frontend Transport; Thu, 11 Jul 2024 12:08:00 +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 v6 18/21] net/ntnic: add QSFP support Date: Thu, 11 Jul 2024 14:07:29 +0200 Message-ID: <20240711120737.698176-18-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20240711120737.698176-1-sil-plv@napatech.com> References: <20240530144929.4127931-1-sil-plv@napatech.com> <20240711120737.698176-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AMS0EPF0000019F:EE_|AM8P190MB0930:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: e7e5b1a7-ba16-4a83-204a-08dca1a21bd8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|82310400026|376014|1800799024|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?9/+e5qemBkp/9Pp40jwJbem22wANSrSuVMLLlKJl71xbTz34UYAbnaZvqpuW?= =?us-ascii?Q?5SGfd0v/NkfIbAm6VWjarxjuzaJWzjtY8sp6UktblpRjoEPww90ZGKWM+BhL?= =?us-ascii?Q?Ips9aM26S6StoHx8pk+N1BvVrhQN3RkFGS57QndmXIaCZwO4otxUb23w66HQ?= =?us-ascii?Q?2blfwG5gQo4O8UPk+l1Ii75wCaV82UQYkPlWfoHCrVmv59mGR0Wzvd+P9A/Y?= =?us-ascii?Q?74Nki/gvrdkFGnv/BvFm6THiATMQ9IcHF8twu6nc1RjVRSdEoFUoENHs6xfP?= =?us-ascii?Q?1Mz2flhY/3V0mYxpqUTjBC/aHlSSYohNoWH/jUJ7ss8guxGKLSYQxoLoTKOw?= =?us-ascii?Q?P2Fk4Ien7V9qVq+1fd/Y31rbG5omhcpQgS9v9KsEAJ62Pr2QfvwHtrCYVcxJ?= =?us-ascii?Q?nbUnnTbs87v0ZFOVHhQ30mGzm7l0eeDNObXTcI05fpavfsVXR41NUm0lO7e4?= =?us-ascii?Q?0+2LE3oFdX2ZdbEhWmWL4aII7SjwIDj3JTdI6ca3vWeWt8GRNt8KKj4n7Pax?= =?us-ascii?Q?O2uolqpPILIhilJhi9fZQoivubOqWaCn0Y4xVTP0s4sTyxzSafMX3sFeiJdO?= =?us-ascii?Q?r58WaBkmF9eefmrgF0kPoHR0LWJsK6inPLKJ6wcaKLjCVfvCkM901gI4IC7Q?= =?us-ascii?Q?f7B39B0JvcoJ/HpFFp/Ro2wwi17UbXqu0F+THVgeZB2CLNqG7WuVcxyBgGWh?= =?us-ascii?Q?ZSEfd3Op7iggvNi/chAf71Z1dz6a7lc2Nl9+3RmRXFJ6bHA4E0zvM2ilXTKE?= =?us-ascii?Q?HctKCuUCLEMMeXBPvncbbGaIoRHMl7Y14dhlWdIY6u160ToDAk2PQ4+qQz8r?= =?us-ascii?Q?8A4j9aWXDyya4Lc0WfUWC/b1ZTxFI8imdIu1apHqDZ6y/gzCE0cnIiyww54C?= =?us-ascii?Q?ZKd/ybfG+acF2FBBLTLGOEwYU5NCzXxssJNP+TZ7PtxRSsCrVV9l2m1AC4vj?= =?us-ascii?Q?5MxBWGAinUiYTO2DCdahyJgvX8R8WOVMDoRd8Rx6V353+CTO32V7NBXnC/1D?= =?us-ascii?Q?1+2pctNhuiWnM5Tu6gYK8MUQa4v5AlsNgPr2Ga/to90eGKo27tM+Oybt27VW?= =?us-ascii?Q?twla4HZqklWl1v8WAIDGt/Ab3VbXdTe/rly4vDVgyNWZA80Xpd88DF8jKr4B?= =?us-ascii?Q?p5ZzdIKnODjgTJI7D9NIqVGsfycxaCMjTsApXxQCKiu41sJiyaVKK9kL3L+w?= =?us-ascii?Q?FAhP4j40BEv08BPDFmMjaGBzPz6mWLK9CA1usSTo+BvjrVbtxszQqf/vJtol?= =?us-ascii?Q?ziBr9gJMeY2rQ7v5zKzyBf951+BVKUv/7V+nH4kD6bpeadeh1ijOqk6VR7gg?= =?us-ascii?Q?A+qetMXzodgpRkj9W1KkpmHyGVmUsVaUnhHMJUVYz3sbgdxwGKj/8BwlocV3?= =?us-ascii?Q?+vE6InoO8HPU6p2d25ZbYl/Pz9CDmOlWdbF2TwBt6OSdrqRRkWHW8MaKJDFZ?= =?us-ascii?Q?8fUZx1GC77fI8weF7ZGUpYo4YC1kZl6w?= 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)(82310400026)(376014)(1800799024)(36860700013); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 5fi6lavWQgHxeFczulj0I57Qkb9Sxbu+aKJhF6KZIqY5kcVlW1Bpm0kDYpm0vsu5KLDyyDVeVnbmxUimbHJZ41CYI3v+N50ZETPdcGAwQgiksXdhS1uu3V1n7pPLL/VAnfrtn8LdqEBuuSAONDqxpPKHCAN03h7AfO6ZWz6e4OrC2orYpiO1kveP3+GckOIkL8uhG4G8g1FENUoR3oRu+lbw8P29bNsjeS+IOom6pEnl6+4Y7VZkRif4glvcR3uY/M8XD9htHrY+ndf9UESVgURCxtI7JhC2VM7Zw75s6x2iilv5kQLJBPJKqsoPzVZJwxVASAY/Sju3WqjKQSA6PmoQLk0VQya8fahUB7ghLZY4/VEPeQsgPLjEkMm7g+wciYqn+gj4+Prwz4PkiEtY1SxxnygkwmA61Jv+ExLK0pehAusJPyRt/Bs1JEyjfpJ0YaM9q8L9hcyWvM8urvbVRISLsPFTfL6QXbfLH2V0SCI+Q6H5qi0kDuDvDZETWU5Exhs4jGWqZ/n6DW8D+XT7akTKAFUDcymjgRtuvI0gAy6yXh/okTLlK0HlJkhYCZo25diSD5bw0cryY7dg6OwmjHSUzkQ+CgXW1OW0/gcBdaK5JaYv688UBjo1Ef/A4OtIdaPm81msZV8mCjoaTrR9C9bwaVSTPB7/ZFAsXIc67vA= X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jul 2024 12:08:00.2128 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e7e5b1a7-ba16-4a83-204a-08dca1a21bd8 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: AMS0EPF0000019F.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P190MB0930 X-BESS-ID: 1720699682-304554-12683-23908-1 X-BESS-VER: 2019.1_20240702.1505 X-BESS-Apparent-Source-IP: 104.47.30.111 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVoZmhgaGQGYGUDQlxSzJwszSKN k0xTjJ3CjZMNky1dDQPMU4OSkxxcTSVKk2FgBE+GSTQgAAAA== X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.257551 [from cloudscan19-240.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 263875a857..300842b570 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.45.0