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 28D0A45501; Wed, 26 Jun 2024 21:59:03 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0EF2B40651; Wed, 26 Jun 2024 21:57:21 +0200 (CEST) Received: from egress-ip11a.ess.de.barracuda.com (egress-ip11a.ess.de.barracuda.com [18.184.203.234]) by mails.dpdk.org (Postfix) with ESMTP id D414640676 for ; Wed, 26 Jun 2024 21:57:17 +0200 (CEST) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05lp2104.outbound.protection.outlook.com [104.47.17.104]) by mx-outbound14-103.eu-central-1a.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jun 2024 19:57:16 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OYiPbG/luHrspGwkdtBVU0WMK0N+LYZWM5vMY8xBglM9/XIZ14v/wCxTSAg0/TeHbx0WiV3LG8rS+x6tASyfDjh8fxalU5BYrWdtvb3Q+OpGWCANHpVwDfysP8yFhszo65QNJVTNwm0DBfqSiuizhSaopoUWf/VN1FxwzdHFp8jwaQlEuO8Rxmi76AqVaxwCvLGVeYWN6qo1qVFaR37p616QF5ajv8/BnhBDUqh3v4gXHBt6niCCWHVojNEJnj5D6BRJ9ugXG1araAcsuenla2f6tAKqEXdHXRTUe+vOX53Q1MiYAqu6LzoA0163fcngwPoSg2Qf5BHwnlMoFaX8Aw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=XviLURW+C1SKvypJ0/YayToZrH0XKHWrCY5DTKj84Rg=; b=FpmyypExgWojmtpPpGKhnGOtJw5ilUz5tCSZF+XVST7/CvxoqHOqrvX33+taFql7Un0E2XlHQobcOMeoP35UA09eM/8VNGjtNzfEVgXEZR519zPq1kzzUuJRT4324sYHqAxbsVW3E30hwrzyqu3CvXJ+TWT/rfgQ9sZ8H2g9VgbbCym5tEaWpMYn/aLEBs8IbgMrUbaV/Ox+v0Hjk2JWo15ekRnYUZjZQkQU7GRmaU+cZqdxxywedtDXuCnvl6roxuvWon7QEuUt6OXIL6wc9Yz2nhp4MbGssfH8Aushs5SsaCDtHILD2nsZedsub0N7FtA1ut3rWKW70YS9re8htw== 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=XviLURW+C1SKvypJ0/YayToZrH0XKHWrCY5DTKj84Rg=; b=UUQ+kus4PgtG1X901IGrV7WA3KvbwZ+u4Z9TNifNwArZSR4QdLHtxpV0SqnaWl7go/EY3zdF4lZ8WeIKgFT1hOPdRHWOFlwnrzdDEQcYWt73vttFCRKQlFHHnVZv58mxOJ2D09MezRRJyy+Ke1DLy1/ay4kwZ42vcGz/DhzqPu0= Received: from AS4P250CA0018.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:5e3::13) by AS8P190MB1126.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:2e5::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.32; Wed, 26 Jun 2024 19:56:14 +0000 Received: from AMS0EPF000001AC.eurprd05.prod.outlook.com (2603:10a6:20b:5e3:cafe::86) by AS4P250CA0018.outlook.office365.com (2603:10a6:20b:5e3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7719.25 via Frontend Transport; Wed, 26 Jun 2024 19:56:14 +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 AMS0EPF000001AC.mail.protection.outlook.com (10.167.16.152) with Microsoft SMTP Server id 15.20.7677.15 via Frontend Transport; Wed, 26 Jun 2024 19:56:13 +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 v4 20/23] net/ntnic: add QSFP28 support Date: Wed, 26 Jun 2024 21:55:30 +0200 Message-ID: <20240626195545.1793419-20-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20240626195545.1793419-1-sil-plv@napatech.com> References: <20240530144929.4127931-1-sil-plv@napatech.com> <20240626195545.1793419-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AMS0EPF000001AC:EE_|AS8P190MB1126:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: da57fc6f-8c2e-4ff3-96e7-08dc961a08d5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230038|36860700011|82310400024|1800799022|376012; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?JUGlaDLm05OC6oDoovjdGo154r0AaAtUDG5sP08T4LN0p2DNSPTKySMg23Oj?= =?us-ascii?Q?aB/SQb1P13tN6wZP98W4JNycccekDOHwzGCZLl2kC1Eus296Esq2tVViZ8aP?= =?us-ascii?Q?dYbOXMn2jGahCxLmLaryz7wl4IbW5+qpof8WWF9T14DygOkwNXEGBwELUB6H?= =?us-ascii?Q?dzpAXLoOJFIlJSxzbG+OmtGmCi9FHJBrE71YYSOpDkRpQSGusSosgS/VA5Xx?= =?us-ascii?Q?MhFNQqZ2CPA3pRPK4r3+3OZV0KugQ8tIlQt/acL7JL5BrAyO8VkFqZmaLPnc?= =?us-ascii?Q?mruiTcSR2CaiNBiBD5KZzdL4fLMyyu+F8EQRMeyZbQz1HiekYAstrXT8wOBw?= =?us-ascii?Q?8TA6usieNIgdzgu5EQKE5Ipdy+DgOGZ0+pK750RITfkAYXY/KL8KSysr9Kwt?= =?us-ascii?Q?D0Y5KH8CfqCafeCFOhlqzQu7bgfs5kg29vkCgv6/goIQGT2iTBMLOU24ccYM?= =?us-ascii?Q?6DdSbFzdeAT6BtwTrQN1p9FDXy7v0YVlEo91xZC8tQTp7sHD0Qk/vey6qO11?= =?us-ascii?Q?9sNa2cHgN6mgKs2KBum2mYjqvSTBxdgQLsUNeVyECwfi21Pst0fZ6lpxIFVr?= =?us-ascii?Q?QcJV3twn6yTxFggT27h2co8SqvcjFYnC+aDfoW6S8ACxaa/Mrtaca4kfAyos?= =?us-ascii?Q?nJV+sD3gKvZnqAr3dFKDMgDZedWvJuO6h4NvkWy6uysAq0rTVFGqnvk6GiHB?= =?us-ascii?Q?g7EoTCYq3i6YBZWtKT6Bh0mvtGB3eqOvw6A6zpXScQjbYNgQNfxd0bdceKRJ?= =?us-ascii?Q?NglnaJI6BrNQOxSaDylbhCICu4o83WcyjdFQ2LQDaLI5YTVAZC4iUehRNTN+?= =?us-ascii?Q?zLwv1MUsTDGP0BdDJ1d3z8fa86MGUwCdbPPEiIkfdwtwenAljopFfSfatnC/?= =?us-ascii?Q?k6rpJH6H7FsKcteoFNjeIGZuw/sKYba+KpLuAEgMvLV3AIPnvfijHINWebLS?= =?us-ascii?Q?VlFDtfT0wUa7jN3ZU6xE1SH7X10bQgSCWd6NKGeoqgsn94E4GVRV6sPtPSnX?= =?us-ascii?Q?7OTCYqmvTjBP+Wx7OWKmtbt/j+8Sm1X5n+YnQEmqKycAkls+nOC8cqD572lR?= =?us-ascii?Q?UWm1xpCPljxEkFh+gr5DEZXLsMYutk0UL15lEqBqOCfFZW3xawAjcY0QsfvL?= =?us-ascii?Q?APLDpUtgOyMmJSt3CFz3iAatKeK3/quJ+y3kjhhSNNHS098t1Ytosm7ZucOV?= =?us-ascii?Q?Fxy6pa1ByfTl6rRixDE6AqvAK1wK139g8XrrH407byoWyw1L2UINvDfNMjZq?= =?us-ascii?Q?Duc39MZzrQuOJ+qMHWw5vjZQJta00e4OfuiBK5rqU54Bs0fFH+EubkWZrftz?= =?us-ascii?Q?YHv7hRv1BPpYgPxBLRh+mLNWvEpvhdtt6Ph54u2uIy4de/TO6ch2YZLRuqTI?= =?us-ascii?Q?Pj8PA6EscfyRfiJyxRPHnzypA7yE26pojQGYrNLo0rPm8FUaRw=3D=3D?= 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:(13230038)(36860700011)(82310400024)(1800799022)(376012); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: AangIp8QlgTQnJXGGFIUDku9ZW2djZlhmCFLVXNZYaDueF5eJgtBsrky1VZ2dHEzR3jYjKh16huqQndD8mSJzObKEL/4GBlF+8KqduwcSAqbtXC0uCv2Q6Kkdg6Alh7DIb2Ns9oxo+P4brxbZXd4c2COBA4OW8howCK3HcK0h6x6v2UmKbUNIRKNc+j1AP15e3h57Pk5Q7K4nI42+2HRUFWUOulyhCOffDh/2KBc+vJfezmOPdiNSTPJsbshZxC6RorHYI3oz0VoDR6Aon6lyuTioUPDc73AtEXj16RcmBXn1Ljap3Vs3l9m+Cv5+p2PqCIz9ok0OnHW+jmDquMASGyYozV4KJAnAvrxuoG3nRmRxqG8Z0MT1rYb5Wxyg5Y0GT84hDzTGhjakz8F3Jgm2OqzsFDxe3D6gT8HC2YrYSzTzmve4Z6qdyL5QQQVnis07ROHfpqIVodteU+DutuLi3mJI56xd8dEn4VFPBRsTr/mrBakuG/gPT0BrNUAgohNhobvUj2R9KaKhKwGrxuTBh4LKD/+PM97XAwvnxMKO1hZFSNi/GyWjG9nru5ftSnhEowChRRlSQ84E4drjr15uEbnfAQzUf775QCxx5q1grzS8Y3t1pjQtB0cZ2fKMZMAOijVJkvFOxxn0NrAgWRRsA== X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jun 2024 19:56:13.9893 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: da57fc6f-8c2e-4ff3-96e7-08dc961a08d5 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: AMS0EPF000001AC.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8P190MB1126 X-BESS-ID: 1719431836-303687-6283-56922-1 X-BESS-VER: 2019.1_20240620.2317 X-BESS-Apparent-Source-IP: 104.47.17.104 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVobGhubGQGYGUDQtzTjF2MI41c DYLCXF2NzMzMg82TDRzNzM0NTYwDAtTak2FgAewNXkQgAAAA== X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.257218 [from cloudscan19-172.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 44805bc704..92ac3d0e6d 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 4831078a2c..10848029ee 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