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 DFE8E45635; Wed, 17 Jul 2024 15:35:16 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 79B1E42DA7; Wed, 17 Jul 2024 15:33:44 +0200 (CEST) Received: from egress-ip42a.ess.de.barracuda.com (egress-ip42a.ess.de.barracuda.com [18.185.115.201]) by mails.dpdk.org (Postfix) with ESMTP id BADB642789 for ; Wed, 17 Jul 2024 15:33:31 +0200 (CEST) Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05lp2109.outbound.protection.outlook.com [104.47.18.109]) by mx-outbound40-186.eu-central-1c.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 17 Jul 2024 13:33:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DEvIvsKAEodCw5TREcBsD/D/tT87nkTQUBJg/XQJAJuIQbREuk3pghThfzll3PqujgHwdsij+gb9Hdy4k6z0ObHSMMYTGubLDszEFqNS5MzOJ/RKgWs4gPYBvtEqIN+Msj5Jzax87d2s2dHwA4pouWNyw+k8hgtOIzkrC4UGCV6R5at2U5pRHeQ0e6AOmIMaBAawrEu3elJtjdYW0j0yanShhujqfLPixbHULegzt2l4ceDk3522WvAtOXtOmeWePNeYvH2fs9BwJ/xWNnHKGa3GoyWWIx9Qu0dqFX5vmvQAoUCzJtPPCS828Np7Zv0S4haAyY0NEDlkPO5EwJUaWw== 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=Lq/T8CUlIG2atAdvemsOH+4hsPuswd4dK49sKhpZ5WY=; b=x3GaWSV1VpWM++MEqeCY6wuYdKkXkSemKI2pXp/LjY+egnNqLgx5g3aEoNxWXmYw07S1Q68CnTdILbm5LvnT0cbp6r/eDwAJaKo6B+nikPed9W41FjT7AAWJ45i/5HAdqxWLEtx3yecHNgc+u6bqz77YxCJxJXDF56EpcpJdK5Z4G4B0DUVyTaWdQ4JCObnZTKPbhiVJ8Xdhws6JuBwDUodP4zgSMDIjf+8nPl/07brVWPGVOYvETrjzQ0kFOBf9NpCDqrt+yd2t85uvnc86gsgmIn2/+Hr1NVAG+gaESWWgtr2ZYo2C/OTEFlogm8CeOcAEK9Wrvv4gFsOiUHOoKg== 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=Lq/T8CUlIG2atAdvemsOH+4hsPuswd4dK49sKhpZ5WY=; b=p8D6QpN4bVCRjQUtY58UtGp/Nn8iaaYSMgXc9GoGjkvS1fV+vra49Sf24YL0a17o8r+sKLw/CKgveMdMED/A2stCgifr6PRR6YBrZga9RdUr9TvFc2qeBUzhZjOEv/Pus8LmvdtygrAOatJXxJSXA1H1q3VlxCRCi/Y5o9W4TuQ= Received: from AM0PR04CA0108.eurprd04.prod.outlook.com (2603:10a6:208:be::49) by AS8P190MB2006.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:528::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7762.29; Wed, 17 Jul 2024 13:33:28 +0000 Received: from AM3PEPF0000A799.eurprd04.prod.outlook.com (2603:10a6:208:be:cafe::92) by AM0PR04CA0108.outlook.office365.com (2603:10a6:208:be::49) 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 19/21] net/ntnic: add QSFP28 support Date: Wed, 17 Jul 2024 15:33:06 +0200 Message-ID: <20240717133313.3104239-19-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_|AS8P190MB2006:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 3ac07260-dd1a-42eb-9a89-08dca6650b23 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|36860700013|82310400026|376014|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?z5kUXBm6LDIulazfeKgnqjaNVaElVzbipPSFpZ6S3KZ5dy71jwv6/GkF/lOe?= =?us-ascii?Q?Cn3lKo0oIkxdUCUga7m7TdoJd/a8Qq5j2i1JKE23KEMkNchF4ehc64acv+YW?= =?us-ascii?Q?H43Ckp7xsJHST027Ivvy2Rjbww6CyUjNmXU3na9lC18nmFm2rlpxiaSsmqz7?= =?us-ascii?Q?lIJ4FX0N9wESb/F3llUADaWJSS2xOjp/jk+Yz5YHf2mhqXtxOZyuSeersEt7?= =?us-ascii?Q?Q2JtY1VnHtj8O9F3T4te4HttOJbaC0pHbXjrGzekW+80nnBWUHM1zbzFIPgE?= =?us-ascii?Q?reGCEN/jQi9nxEVMSZcRI86gBPsSKnHjsJ1rxGUdMybm0LtRdk7Ax3GpjQGn?= =?us-ascii?Q?ad8W4guTTMD15ADv6lwYo9MlSY9TPZuOO4DkUV/aoOEquMDZyQAALX+sEyc2?= =?us-ascii?Q?Ym+JOgNsezjgGkm0WIWJxRP/9BrAqlFllNC5pS7PZwlfUAgACb0YOcAnNuOj?= =?us-ascii?Q?dOoBjHLvBpm8wKkOt4bLtIO5rux0YqUIMpOR5CANZwncRzy9e3B1eGz2XkfE?= =?us-ascii?Q?iCHGYAOMqBsPZ1aFWKO5+LZ/oKjq9GUAy2j40+VhLOo5sFmh73LrJ0ehl5E0?= =?us-ascii?Q?sdPygapiscZ01wgkTkRRjQk6xqLYb5YxY6/9f4BkG+31Gd7je0ZCoSIqMeQ8?= =?us-ascii?Q?wfsRVUGp40Lxq7j2JOGQDlJJ5UJvESNPnUYsoQ5iQE9WJaVBEfjKsNtz9zai?= =?us-ascii?Q?nvs1Dkce0JjLGMFbyCAjIb3fh/ZciztZ3tjkk83Jexz7y0Et4nTyGviAGpL5?= =?us-ascii?Q?xTu1mGvEQdYWHGoNJf9aNSVfhxoqT9TRIRcisBnEVDocC/wS1SCw2wrev/GF?= =?us-ascii?Q?2ZB4hoMbB14N159N1waPDhYpIcveKOmnGKsSyJKd+5S34IIYnbszJwRMIF+n?= =?us-ascii?Q?i1BECCWikMCddBWcDRO9Q9WQ/YW7Tq7/6m11MNKKdU0sRTB4Hp9lBt5ooN4d?= =?us-ascii?Q?wZ1TpHxRHEtsfk36M7LAYt71wFbNzzAvbCiLOLY4nJIR98IBkGGJmKy3XJR5?= =?us-ascii?Q?xAYhBXsBJHjBs+9qnlJRnpb4Wt1L0JczBXEjXPpi7G1PKTfzB53ZaP8+lnQC?= =?us-ascii?Q?QS62rmuXKufRx5VXHCO6gUweJKDRGDW+mK6q1F9+Enc+caGYMf4wcCiQpu5S?= =?us-ascii?Q?1BooI5foFP/3wXWAcCSfVzSleqAnrpnkJdmMdJ7GSRWQLLz/zXsYsBQLciFR?= =?us-ascii?Q?sOyjeWYCtBouSE24IdM+1ZtvOK9wgCi285r4Muef+bxdDgVu9gNyyvIi4z60?= =?us-ascii?Q?sELuAVT+YtVNoMq/etmg2twgUcxMVEw14lt67L5/1HX53ny/86kxB4koqG3g?= =?us-ascii?Q?alnlgoEX7Q03k5h3XKPlE4+KRTLsgNlFcx8LOnp+GtPWGRPU4RFYpdGpYtUH?= =?us-ascii?Q?Vs1UbFkKQnFO/beYzsFQL/tglyb3Ed6Mk05HtLluAjWvhYNGTaRA8FT/mGbx?= =?us-ascii?Q?yBNdZ38YHiwFbP5zoBOIRftaYTFambu6?= 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)(36860700013)(82310400026)(376014)(1800799024); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: GUftCcknCe85HcYQsqsbq4pcPJ0ehepvfzqLYO5AnkedNmya7WAwmp9vz2/+BpBuFV8Kw2NmEeBAM8L7ybZUbTvKlYCschV1VtTpD+hLqkSf/O4WSlgczwtOzapKZkQKXdEzy6K4mUu7v693wZNBd/5O83cXienAjvLzZikBEa4JT4nhb9OeIYZkDx8imfr5jmHzK6Q75I9mXuxBtO11kKDZ6LS7YZ/izy2tu3p8LXOmsDHeXah7/KgiPZGInGSvs8NeKKESDhmHvY9i8UK01EdNmEfOkeMtxmBOQJPWMvri0loeonk1W6jCwhJoxQE8XE1oo0X0mRV+b0V/hKtYV8r9zyFAnr9+Gk1rjGwxEzFRhRwM6NDt1SUR9Kv4kljkxLa9BDnO6bg+ws7RRPSyxWxFAQiWoTYZjx7iwuhsqBfYRu88Tw+iB+NMeXzig8tv625N9sL0ovINL7luN9r6BN/mjx8lKnGb/3qSfB/SsR4rCTV+Eol1LkflQOxMzU2lT79W/hhuLJktiEy9K/EsXQZkRLUOaeoW8OXlUKLKNQZW5qevKKPUSuKASsAdLvNgNv1b7r27Y5ieC34dC+SFTZ1T/M/D5f0Le6EfQ5eWZ5lGH1vf5zZHaaith1PRWbLn2kZSXNxmIPMD6DS+/JpR3Q== X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2024 13:33:28.6526 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3ac07260-dd1a-42eb-9a89-08dca6650b23 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: AS8P190MB2006 X-BESS-ID: 1721223210-310426-12657-15021-1 X-BESS-VER: 2019.1_20240716.1757 X-BESS-Apparent-Source-IP: 104.47.18.109 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVobGhubGQGYGUDQt2czE1NwkzT Il2SjN2NDQJMnS1CIlLdnA0MI0xTQpSak2FgBeleYvQgAAAA== X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.257687 [from cloudscan18-22.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 QSFP28 Signed-off-by: Serhii Iliushyk --- drivers/net/ntnic/include/ntnic_nim.h | 21 ++ drivers/net/ntnic/link_mgmt/nt4ga_link.c | 25 +++ drivers/net/ntnic/nim/i2c_nim.c | 267 ++++++++++++++++++++++- drivers/net/ntnic/nim/nim_defines.h | 1 + 4 files changed, 313 insertions(+), 1 deletion(-) diff --git a/drivers/net/ntnic/include/ntnic_nim.h b/drivers/net/ntnic/include/ntnic_nim.h index 216930af76..58daa8435f 100644 --- a/drivers/net/ntnic/include/ntnic_nim.h +++ b/drivers/net/ntnic/include/ntnic_nim.h @@ -17,6 +17,19 @@ enum nt_port_type_e { 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 */ + NT_PORT_TYPE_QSFP28_NOT_PRESENT,/* QSFP28 type but slot is empty */ + NT_PORT_TYPE_QSFP28, /* QSFP28 type */ + NT_PORT_TYPE_QSFP28_SR4,/* QSFP28-SR4 type */ + NT_PORT_TYPE_QSFP28_LR4,/* QSFP28-LR4 type */ + NT_PORT_TYPE_QSFP28_CR_CA_L, /* QSFP28-CR-CA-L type */ + NT_PORT_TYPE_QSFP28_CR_CA_S, /* QSFP28-CR-CA-S type */ + NT_PORT_TYPE_QSFP28_CR_CA_N, /* QSFP28-CR-CA-N type */ + /* QSFP28-FR type. Uses PAM4 modulation on one lane only */ + NT_PORT_TYPE_QSFP28_FR, + /* QSFP28-DR type. Uses PAM4 modulation on one lane only */ + NT_PORT_TYPE_QSFP28_DR, + /* QSFP28-LR type. Uses PAM4 modulation on one lane only */ + NT_PORT_TYPE_QSFP28_LR, }; typedef enum nt_port_type_e nt_port_type_t, *nt_port_type_p; @@ -56,7 +69,15 @@ typedef struct nim_i2c_ctx { union { struct { bool rx_only; + bool qsfp28; union { + struct { + uint8_t rev_compliance; + bool media_side_fec_ctrl; + bool host_side_fec_ctrl; + bool media_side_fec_ena; + bool host_side_fec_ena; + } qsfp28; } specific_u; } qsfp; diff --git a/drivers/net/ntnic/link_mgmt/nt4ga_link.c b/drivers/net/ntnic/link_mgmt/nt4ga_link.c index bc362776fc..4dc1c3d467 100644 --- a/drivers/net/ntnic/link_mgmt/nt4ga_link.c +++ b/drivers/net/ntnic/link_mgmt/nt4ga_link.c @@ -140,6 +140,26 @@ static uint32_t nt4ga_port_get_loopback_mode(struct adapter_info_s *p, int port) return p_link->port_action[port].port_lpbk_mode; } +/* + * port: tx power + */ +static int nt4ga_port_tx_power(struct adapter_info_s *p, int port, bool disable) +{ + nt4ga_link_t *link_info = &p->nt4ga_link; + + if (link_info->u.nim_ctx[port].port_type == NT_PORT_TYPE_QSFP28_SR4 || + link_info->u.nim_ctx[port].port_type == NT_PORT_TYPE_QSFP28 || + link_info->u.nim_ctx[port].port_type == NT_PORT_TYPE_QSFP28_LR4) { + nim_i2c_ctx_t *nim_ctx = &link_info->u.var100g.nim_ctx[port]; + + if (!nim_ctx->specific_u.qsfp.rx_only) { + if (nim_qsfp_plus_nim_set_tx_laser_disable(nim_ctx, disable, -1) != 0) + return 1; + } + } + + return 0; +} static const struct port_ops ops = { .get_nim_present = nt4ga_port_get_nim_present, @@ -181,6 +201,11 @@ static const struct port_ops ops = { .get_loopback_mode = nt4ga_port_get_loopback_mode, .get_link_speed_capabilities = nt4ga_port_get_link_speed_capabilities, + + /* + * port: tx power + */ + .tx_power = nt4ga_port_tx_power, }; void port_init(void) diff --git a/drivers/net/ntnic/nim/i2c_nim.c b/drivers/net/ntnic/nim/i2c_nim.c index 0071d452bb..e6e256b062 100644 --- a/drivers/net/ntnic/nim/i2c_nim.c +++ b/drivers/net/ntnic/nim/i2c_nim.c @@ -24,6 +24,7 @@ static bool page_addressing(nt_nim_identifier_t id) switch (id) { case NT_NIM_QSFP: case NT_NIM_QSFP_PLUS: + case NT_NIM_QSFP28: return true; default: @@ -185,6 +186,14 @@ static int read_data_lin(nim_i2c_ctx_p ctx, uint16_t lin_addr, uint16_t length, NIM_READ); } +/* Read and return a single byte */ +static uint8_t read_byte(nim_i2c_ctx_p ctx, uint16_t addr) +{ + uint8_t data; + read_data_lin(ctx, addr, sizeof(data), &data); + return data; +} + 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. */ @@ -294,8 +303,12 @@ static int qsfp_nim_state_build(nim_i2c_ctx_t *ctx, sfp_nim_state_t *state) state->br = 103U; /* QSFP+: 4 x 10G = 40G */ break; + case 17U: + state->br = 255U; /* QSFP28: 4 x 25G = 100G */ + break; + default: - NT_LOG(INF, NIM, "nim_id = %u is not an QSFP/QSFP+ module\n", ctx->nim_id); + NT_LOG(INF, NIM, "nim_id = %u is not an QSFP/QSFP+/QSFP28 module\n", ctx->nim_id); res = -1; } @@ -319,6 +332,9 @@ const char *nim_id_to_text(uint8_t nim_id) case 0x0D: return "QSFP+"; + case 0x11: + return "QSFP28"; + default: return "ILLEGAL!"; } @@ -446,6 +462,132 @@ static int qsfpplus_read_basic_data(nim_i2c_ctx_t *ctx) return 0; } +static void qsfp28_find_port_params(nim_i2c_ctx_p ctx) +{ + uint8_t fiber_chan_speed; + + /* Table 6-17 SFF-8636 */ + read_data_lin(ctx, QSFP_SPEC_COMPLIANCE_CODES_ADDR, 1, &fiber_chan_speed); + + if (fiber_chan_speed & (1 << 7)) { + /* SFF-8024, Rev 4.7, Table 4-4 */ + uint8_t extended_specification_compliance_code = 0; + read_data_lin(ctx, QSFP_EXT_SPEC_COMPLIANCE_CODES_ADDR, 1, + &extended_specification_compliance_code); + + switch (extended_specification_compliance_code) { + case 0x02: + ctx->port_type = NT_PORT_TYPE_QSFP28_SR4; + break; + + case 0x03: + ctx->port_type = NT_PORT_TYPE_QSFP28_LR4; + break; + + case 0x0B: + ctx->port_type = NT_PORT_TYPE_QSFP28_CR_CA_L; + break; + + case 0x0C: + ctx->port_type = NT_PORT_TYPE_QSFP28_CR_CA_S; + break; + + case 0x0D: + ctx->port_type = NT_PORT_TYPE_QSFP28_CR_CA_N; + break; + + case 0x25: + ctx->port_type = NT_PORT_TYPE_QSFP28_DR; + break; + + case 0x26: + ctx->port_type = NT_PORT_TYPE_QSFP28_FR; + break; + + case 0x27: + ctx->port_type = NT_PORT_TYPE_QSFP28_LR; + break; + + default: + ctx->port_type = NT_PORT_TYPE_QSFP28; + } + + } else { + ctx->port_type = NT_PORT_TYPE_QSFP28; + } +} + +/* + * If true the user must actively select the desired rate. If false the module + * however can still support several rates without the user is required to select + * one of them. Supported rates must then be deduced from the product number. + * SFF-8636, Rev 2.10a: + * p40: 6.2.7 Rate Select + * p85: A.2 Rate Select + */ +static bool qsfp28_is_rate_selection_enabled(nim_i2c_ctx_p ctx) +{ + const uint8_t ext_rate_select_compl_reg_addr = 141; + const uint8_t options_reg_addr = 195; + const uint8_t enh_options_reg_addr = 221; + + uint8_t rate_select_ena = (read_byte(ctx, options_reg_addr) >> 5) & 0x01; /* bit: 5 */ + + if (rate_select_ena == 0) + return false; + + uint8_t rate_select_type = + (read_byte(ctx, enh_options_reg_addr) >> 2) & 0x03; /* bit 3..2 */ + + if (rate_select_type != 2) { + NT_LOG(DBG, PMD, "NIM has unhandled rate select type (%d)", rate_select_type); + return false; + } + + uint8_t ext_rate_select_ver = + read_byte(ctx, ext_rate_select_compl_reg_addr) & 0x03; /* bit 1..0 */ + + if (ext_rate_select_ver != 0x02) { + NT_LOG(DBG, PMD, "NIM has unhandled extended rate select version (%d)", + ext_rate_select_ver); + return false; + } + + return true; /* When true selectRate() can be used */ +} + +static void qsfp28_set_speed_mask(nim_i2c_ctx_p ctx) +{ + if (ctx->port_type == NT_PORT_TYPE_QSFP28_FR || ctx->port_type == NT_PORT_TYPE_QSFP28_DR || + ctx->port_type == NT_PORT_TYPE_QSFP28_LR) { + if (ctx->lane_idx < 0) + ctx->speed_mask = NT_LINK_SPEED_100G; + + else + /* PAM-4 modules can only run on all lanes together */ + ctx->speed_mask = 0; + + } else { + if (ctx->lane_idx < 0) + ctx->speed_mask = NT_LINK_SPEED_100G; + + else + ctx->speed_mask = NT_LINK_SPEED_25G; + + if (qsfp28_is_rate_selection_enabled(ctx)) { + /* + * It is assumed that if the module supports dual rates then the other rate + * is 10G per lane or 40G for all lanes. + */ + if (ctx->lane_idx < 0) + ctx->speed_mask |= NT_LINK_SPEED_40G; + + else + ctx->speed_mask = NT_LINK_SPEED_10G; + } + } +} + static void qsfpplus_find_port_params(nim_i2c_ctx_p ctx) { uint8_t device_tech; @@ -474,6 +616,7 @@ static void qsfpplus_set_speed_mask(nim_i2c_ctx_p ctx) static void qsfpplus_construct(nim_i2c_ctx_p ctx, int8_t lane_idx) { assert(lane_idx < 4); + ctx->specific_u.qsfp.qsfp28 = false; ctx->lane_idx = lane_idx; ctx->lane_count = 4; } @@ -514,6 +657,124 @@ static int qsfpplus_preinit(nim_i2c_ctx_p ctx, int8_t lane_idx) return res; } +static void qsfp28_wait_for_ready_after_reset(nim_i2c_ctx_p ctx) +{ + uint8_t data; + bool init_complete_flag_present = false; + + /* + * Revision compliance + * 7: SFF-8636 Rev 2.5, 2.6 and 2.7 + * 8: SFF-8636 Rev 2.8, 2.9 and 2.10 + */ + read_data_lin(ctx, 1, sizeof(ctx->specific_u.qsfp.specific_u.qsfp28.rev_compliance), + &ctx->specific_u.qsfp.specific_u.qsfp28.rev_compliance); + NT_LOG(DBG, NTHW, "NIM RevCompliance = %d", + ctx->specific_u.qsfp.specific_u.qsfp28.rev_compliance); + + /* Wait if lane_idx == -1 (all lanes are used) or lane_idx == 0 (the first lane) */ + if (ctx->lane_idx > 0) + return; + + if (ctx->specific_u.qsfp.specific_u.qsfp28.rev_compliance >= 7) { + /* Check if init complete flag is implemented */ + read_data_lin(ctx, 221, sizeof(data), &data); + init_complete_flag_present = (data & (1 << 4)) != 0; + } + + NT_LOG(DBG, NTHW, "NIM InitCompleteFlagPresent = %d", init_complete_flag_present); + + /* + * If the init complete flag is not present then wait 500ms that together with 500ms + * after reset (in the adapter code) should be enough to read data from upper pages + * that otherwise would not be ready. Especially BiDi modules AFBR-89BDDZ have been + * prone to this when trying to read sensor options using getQsfpOptionsFromData() + * Probably because access to the paged address space is required. + */ + if (!init_complete_flag_present) { + nt_os_wait_usec(500000); + return; + } + + /* Otherwise wait for the init complete flag to be set */ + int count = 0; + + while (true) { + if (count > 10) { /* 1 s timeout */ + NT_LOG(WRN, NTHW, "Timeout waiting for module ready"); + break; + } + + read_data_lin(ctx, 6, sizeof(data), &data); + + if (data & 0x01) { + NT_LOG(DBG, NTHW, "Module ready after %dms", count * 100); + break; + } + + nt_os_wait_usec(100000);/* 100 ms */ + count++; + } +} + +static void qsfp28_get_fec_options(nim_i2c_ctx_p ctx) +{ + const char *const nim_list[] = { + "AFBR-89BDDZ", /* Avago BiDi */ + "AFBR-89BRDZ", /* Avago BiDi, RxOnly */ + "FTLC4352RKPL", /* Finisar QSFP28-LR */ + "FTLC4352RHPL", /* Finisar QSFP28-DR */ + "FTLC4352RJPL", /* Finisar QSFP28-FR */ + "SFBR-89BDDZ-CS4", /* Foxconn, QSFP28 100G/40G BiDi */ + }; + + for (size_t i = 0; i < ARRAY_SIZE(nim_list); i++) { + if (ctx->prod_no == nim_list[i]) { + ctx->options |= (1 << NIM_OPTION_MEDIA_SIDE_FEC); + ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena = true; + NT_LOG(DBG, NTHW, "Found FEC info via PN list"); + return; + } + } + + /* + * For modules not in the list find FEC info via registers + * Read if the module has controllable FEC + * SFF-8636, Rev 2.10a TABLE 6-28 Equalizer, Emphasis, Amplitude and Timing) + * (Page 03h, Bytes 224-229) + */ + uint8_t data; + uint16_t addr = 227 + 3 * 128; + read_data_lin(ctx, addr, sizeof(data), &data); + + /* Check if the module has FEC support that can be controlled */ + ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ctrl = (data & (1 << 6)) != 0; + ctx->specific_u.qsfp.specific_u.qsfp28.host_side_fec_ctrl = (data & (1 << 7)) != 0; + + if (ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ctrl) + ctx->options |= (1 << NIM_OPTION_MEDIA_SIDE_FEC); + + if (ctx->specific_u.qsfp.specific_u.qsfp28.host_side_fec_ctrl) + ctx->options |= (1 << NIM_OPTION_HOST_SIDE_FEC); +} + +static int qsfp28_preinit(nim_i2c_ctx_p ctx, int8_t lane_idx) +{ + int res = qsfpplus_preinit(ctx, lane_idx); + + if (!res) { + qsfp28_wait_for_ready_after_reset(ctx); + memset(&ctx->specific_u.qsfp.specific_u.qsfp28, 0, + sizeof(ctx->specific_u.qsfp.specific_u.qsfp28)); + ctx->specific_u.qsfp.qsfp28 = true; + qsfp28_find_port_params(ctx); + qsfp28_get_fec_options(ctx); + qsfp28_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); @@ -523,6 +784,10 @@ int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra) qsfpplus_preinit(ctx, extra ? *(int8_t *)extra : (int8_t)-1); break; + case NT_NIM_QSFP28: + qsfp28_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)); diff --git a/drivers/net/ntnic/nim/nim_defines.h b/drivers/net/ntnic/nim/nim_defines.h index e5a033a3d4..8e17b263c5 100644 --- a/drivers/net/ntnic/nim/nim_defines.h +++ b/drivers/net/ntnic/nim/nim_defines.h @@ -26,6 +26,7 @@ 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+ */ + NT_NIM_QSFP28 = 0x11, /* Nim type = QSFP28 */ }; typedef enum nt_nim_identifier_e nt_nim_identifier_t; -- 2.43.0