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 9CA4B455F3; Thu, 11 Jul 2024 14:10:01 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A458B42EDE; Thu, 11 Jul 2024 14:08:16 +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 8FE0442E9F for ; Thu, 11 Jul 2024 14:08:06 +0200 (CEST) Received: from EUR03-VI1-obe.outbound.protection.outlook.com (mail-vi1eur03lp2110.outbound.protection.outlook.com [104.47.30.110]) by mx-outbound13-152.eu-central-1a.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 11 Jul 2024 12:08:05 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=HzSK4mbgUsw34J9UT0iwFC7cyrgeIaCqxVxWAfIPNsW+0fTPhF4WYy4KW6ex3dzRelMtYTNbXmBCq0k1VBj4ixDBVurH5cHvrvflIRyNXXUm6IbnXfk8kndduSLc/vSyZSrqNyz1jqWmGsalXzWyZP6/S3B8MS1nkr4c+t8W5O+lo81JozzEj/qPkCqDD20XiicTl6xLXSAIZDd5gHjX9PkJ25TL+ilhwA5eCtiypYLyoLrsiH3XvewhClr7xm0PD1H+oxA2GKBsqpCULdfRjzJUiXNmbVLvBEOqB/lq9QSLBlKeYc6IAmgtPe6VWxUH+gp8wLTG+GbUxzHOZUYMpw== 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=ZIfJxc6l2lmO05KvcqwbSDyoENATdbduKYHIsRPqwy4=; b=YGCSSL2UPd7y6tfjA7LUDN3Z8k0t8vKDTVWNRCPvSZI1VH8Z7cZlqSZvPPE3sposw7DlQ/nLWmNrL9SYlVP8Sus7CFOm8ibR4W55zSlncb7qEDOD3X/bxJBVcpNnNetNV5B1QaRBqhwkVKhHmIhMP29UqvdOpFBJA4tRWgfIcEF/P3h8u0mM6CpeOsihiwUQOD3uqkkXb1cfyPrcPghETnmBVxwNnPHXWe6EEZTzHJXI5geJmSG44OSpWQemmEo/cQiAqOj4DxzUQjCTjEjB1OGBMMMzN8o0dGyiowHVLr7gtIJ5Oz5xnBPuACiPINJ/vxufDOtSAYv++Qt5cHlviw== 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=ZIfJxc6l2lmO05KvcqwbSDyoENATdbduKYHIsRPqwy4=; b=JyR8efMusd0X9gmNy/1Z7oLO8Qo+AaKG2Xq/XlCHk6wj3XL1l68j3x5nsclNHqKOGxDbr+kpXB9XdKELCM91egcav4CMHVo9pvM3uAYk2UXRCaqUNPkWDDsbIoJYt+7AY3X2lkYKEKcYFw/0UbzIMNQ59YcFis1f5AP+tvtHNDk= Received: from AS9PR04CA0104.eurprd04.prod.outlook.com (2603:10a6:20b:50e::17) by AM9P190MB1154.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:271::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7762.20; Thu, 11 Jul 2024 12:08:00 +0000 Received: from AMS0EPF0000019F.eurprd05.prod.outlook.com (2603:10a6:20b:50e:cafe::fc) by AS9PR04CA0104.outlook.office365.com (2603:10a6:20b:50e::17) 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 19/21] net/ntnic: add QSFP28 support Date: Thu, 11 Jul 2024 14:07:30 +0200 Message-ID: <20240711120737.698176-19-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_|AM9P190MB1154:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: ca4e52e1-d7c8-4da5-5749-08dca1a21c30 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|82310400026|36860700013|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?qNGvVrMnPfBrWZAtIBj8cGhDRrHnaQoExViyCAQjl1xW97ec+LG0lKfnbaVU?= =?us-ascii?Q?uYIn/AXeE5mJY7YsLCbhABxi72jVyRiuEphyaHPuthXqD5xm8no3+uqeOsof?= =?us-ascii?Q?kb+JTxt6UR4vrDvy9517qwKPRiuJA5zNJy7CYGaTyTCiGyl5OP31xTqn4y6W?= =?us-ascii?Q?yqRxPOh8Xb+qDVqw47xD9ADYD6BoRmyqRFf0zZaHNc//F7qpy1f7NXm7oU/Y?= =?us-ascii?Q?Dt0dLRMSn7zcyeh0ux3v+HC6S7bIBdDqZ++GaU5+qJPatPNvbTpNil8aCFUx?= =?us-ascii?Q?3jZtBKHXy8lROpxHto3tkAOv91l/hgRy7p2c2Nb0Du3QyBqx5CsX2vfV0tcU?= =?us-ascii?Q?vFFhq8c3iLnheRo/MWRpEEkHxkfYC0kRXcPsbDk3HmLGlGMjP93WQ2DVodL7?= =?us-ascii?Q?sUT9+jfilK9TXMavSO/5xnsH9An/uFezw+vF+AcQAMnvG3osuztpNHTBVLAn?= =?us-ascii?Q?vBZ134ARYlYZ5zq2Ps7IXXn+lTzSLvoAz3RBaHHKNu3BHr3hr4iIBjBBpQXA?= =?us-ascii?Q?3IMxDeV5UiFbFl7iSjazBMibQM/dz2nbMJFwhSV7NsQfYKH9UbAKUBSmRmQg?= =?us-ascii?Q?bB6oeRHqWnj2wT61dfBivokZU5TPpE2b/YxMCoxcDH6taAnaYdwjSEl3nA3C?= =?us-ascii?Q?pOtysO39ZhGBQ7sr26K9LQ/ori0aj7aVb9wLJRO7/sapYq/S5utuX+86EBW9?= =?us-ascii?Q?8nw3QAZWYJt7TCQHX4bxzKD12s4+WfC82Zr8Yka2XiFVEqeY3FQbUkSUbNgA?= =?us-ascii?Q?ebRc1rXYBdkBR8352GgfkQTpuI83obcSyWJnn12MH3db4jcB8j/lDHGbkLad?= =?us-ascii?Q?OWiusyi5lKtYLWfoENkDc3kfDMDsJ/kvb4voKlClxgVklojmhPpjmHgRRXMd?= =?us-ascii?Q?NcYuNaS5ds9TfAPe2m8qLCWvEes+9B7a7aWiHWWYD3KXMi0uAireqy6fjm1o?= =?us-ascii?Q?hZQjbaqmIR6LdoE1u3xRM/i8n26wekohMKtFjck1fe2BYoNcH91MbTxSLjMN?= =?us-ascii?Q?yXcuvCtsEkArKAFBlxTDa548PWTWXDtNm/9HRikFLRKsqGAMbv1G/a9B/38A?= =?us-ascii?Q?TU0VIFfr3NDgUIuMIkabhYumBnBzfn86rudJNMM6ds6njEA0cnHck5DAuu65?= =?us-ascii?Q?sadV6ffaZ6n4ZtDzMytC6D9t99GiWTn58jjmkz8M9xXIzb0/vayjyFHPEvC6?= =?us-ascii?Q?ohfeHxE7ofHdt1UMftbXkEvVt27sjCK+aeqNyed/1rwaP8LDog6IasmyJiOa?= =?us-ascii?Q?NJh92esUfd4qPuPsDXFIdt0EM5BIQskcDJF5gOHv5/j3Q0LtocCHoJwSkPIL?= =?us-ascii?Q?d5ae5EPMnupFflbiK0Dt2C3h90+AVAbCObNC+5GKgSN42UMV6g9p3g4ABsx7?= =?us-ascii?Q?MAvlHalgT3GMvu5j1Fdl6GHNFYAsEGgOvCd+ED5TqlQCuWOqSU2xcprNJHaB?= =?us-ascii?Q?Sg4sTDVRPsR2ruMNL92T3BD1F7SGLAYx?= 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)(1800799024)(82310400026)(36860700013)(376014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: omMcdXtdeadPuaUj8DDkXFo6wkk2dNB+//+/LMYpzE3oFxL7ZhLJTiodlHY6xzYeU088imhj23g0OjxqHFXomXut4xNP8cgTdUOiyPsJqmnqbu8BqjlzgkcwiAF0NGY3NKp/xXSutwTqpUqKwWthkAenLjGtuApmJCXm5JCx5oaQxTPwcQt+jkq8O3ifgSGovwo/hFbdwR64DuTof/OExNqDQy7OD5u1uKWhp6iTqFh01nZogFit6QNhQhGx5hxwIMpnPrzga7qMN+TFMe/e8rVU3gv0CdKQB/CHp0alP6YnCxcyeSBFM5VkRXn4hS6baXwkGE9OcdSa/cnQ0p+1JwkPDiPn6U2VkwSsWUxErspX4z6dUNNZouC3TlJpirq1Axay1l3R7MyyUXeag4p5dBwJtJmO0i9ViwZaQFig7Vu0Pgwm4QOgqqbyQsgZc91oq+w6DNRJhFpEO5yOxOtRrBihD4ygPcNqsYrKBNp2hodiDyfMEFTwMjB/Kw7UfjN7hUZYYZIjUuoSzoEf3H+mGwFEvhd4MXbCVEiiqNn2M86YpScJ+gz2ghHmKAKO2iUNXRr0IfMWVO+BQhdT0K0ZYK+T9cej69L/kA6sAA3Q/jXVEcUgRvEoCsi+yeUkwMYkHY94NkkooFxvnD9EAw4x6GRrFwGCQy9A9FHxV5Xgers= X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jul 2024 12:08:00.7284 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ca4e52e1-d7c8-4da5-5749-08dca1a21c30 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: AM9P190MB1154 X-BESS-ID: 1720699683-303480-12645-24467-2 X-BESS-VER: 2019.1_20240702.1505 X-BESS-Apparent-Source-IP: 104.47.30.110 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVobGhubGQGYGUNTQIjUxzSzRyM jAAihokpZmkZhskmZpYGCaYmhilmiiVBsLAKBp9ZlCAAAA X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.257551 [from cloudscan21-78.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 300842b570..f3bd159130 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.45.0