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 900E04411D; Fri, 31 May 2024 17:49:52 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 77FBC42E01; Fri, 31 May 2024 17:48:06 +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 1F77242D9D for ; Fri, 31 May 2024 17:47:51 +0200 (CEST) Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05lp2110.outbound.protection.outlook.com [104.47.18.110]) by mx-outbound13-64.eu-central-1a.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 31 May 2024 15:47:48 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OxcZlFycLIbwh9aY3GsBrB5AhgcVOrXxY9GoblSuSO5D8K3EXzi7wS+QeVB2R87+zcPT7tQ/xudTKwvXUKaik7RbmWtZV3DG5CXCO5LPvIXX4Vc5tO3don86ofj6htkleC2xCBnEKBtYYbbIDJy5SYNOBfbTN/YR59TywIBp50X23l4PnRNp8XFgpcQS+tRQ18XgSIcm1Nkotn6CHa0IV6sSaciYpvD6HdQ30/oBklPiUmygf/L/HvaGvCFMMREFkru+UhnbvwIdBJdyDXr6/4ARv47y2BRXHA5V2CDieGSu7ZpluEWd8D93rRiSLE3f8XRuk9Pc7X+QeA/59i2e3Q== 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=eWASIxqgsZ0cggrX6evmLLICr2wgk5vlS1D7iov/w6Q=; b=lRh+tu8Ojs/1WuSJ7QUOVXB7s8Bl20gdPHMq7HbFKx8SG2h3D90P7495ZqeGaa6ra5RE0PsTdMJCtbAHu+KXV/G6vPoa0N9R01S/qq1rWd0wBR28+WKO2zAyp+TEWmWfbu9CEqjYdIqrUpINvUBpx4cdD1AXm6w8DvBikWe4rYLFQKwEkJf1Tz+vTVOnfWu/uilZs3g9r2jr/KEMHvSzEosQ7mob10n9eTfAVhzy5oT+kXIa/srBAAHyFCDgQU6xyIgDlF6S1bLCjIs1Jtr+0QmlU5OiVIu/C0ZhKyHvpCEyxdm8jcjuHpyBD4egPAkJ7my0AhGPjfTejtnT+wmU9g== 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=eWASIxqgsZ0cggrX6evmLLICr2wgk5vlS1D7iov/w6Q=; b=dgmer18a12au9pzwTkXrIxuzgqQBuIa7F+v3KijXbd6UqJFzOSXJM/xo/SbouvXmcd3o+wS+QHMT7Ik1uRC5xvlpk+ALslzledYMPH6N735gkexx6FaYJXcECSxo2W5VVdQYyj/pnL9wnvnraD2MwbwEVwmLbQW5I3BQB1yQJ+c= Received: from AS4P251CA0017.EURP251.PROD.OUTLOOK.COM (2603:10a6:20b:5d3::6) by AM7P190MB0599.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:120::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7633.23; Fri, 31 May 2024 15:47:45 +0000 Received: from AMS1EPF00000047.eurprd04.prod.outlook.com (2603:10a6:20b:5d3:cafe::f) by AS4P251CA0017.outlook.office365.com (2603:10a6:20b:5d3::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7633.24 via Frontend Transport; Fri, 31 May 2024 15:47:45 +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 AMS1EPF00000047.mail.protection.outlook.com (10.167.16.135) with Microsoft SMTP Server id 15.20.7633.15 via Frontend Transport; Fri, 31 May 2024 15:47:45 +0000 From: Serhii Iliushyk To: dev@dpdk.org Cc: mko-plv@napatech.com, ckm@napatech.com, andrew.rybchenko@oktetlabs.ru, ferruh.yigit@amd.com Subject: [PATCH v2 13/17] net/ntnic: add adapter initialization Date: Fri, 31 May 2024 17:47:17 +0200 Message-ID: <20240531154731.1856874-13-sil-plv@napatech.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240531154731.1856874-1-sil-plv@napatech.com> References: <20240530144929.4127931-1-sil-plv@napatech.com> <20240531154731.1856874-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AMS1EPF00000047:EE_|AM7P190MB0599:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 8bf4b541-18b5-40b0-575f-08dc818903e3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|82310400017|1800799015|376005|36860700004; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?3j4aUlAGs1SxE6zmTuaA73xFQPciPALJJnj1KRUpXtrq/3tl4txGxOoV6kQ5?= =?us-ascii?Q?kRjnElG0tZv8Ti0uIHCSK6aLCoaa355f2xVvKsagOPDouQCh3KkhvlQq6qPZ?= =?us-ascii?Q?eZ8Aw1BCML9540V9xggRTTyDiZJ62JNfurHrIghDtA8WOLJRxQ327cYspT7M?= =?us-ascii?Q?hisSUP/pPZcc5e45plZr9fUsjO73YlUTDJ+MFBeEKy1Ikrlakdprjx5BwMAV?= =?us-ascii?Q?bNESvhk5iSEW9lxnh1nyQdAsC71cr5xvMWzwxxy1/BUjSI98bfbK+Y9dC0QI?= =?us-ascii?Q?myMXJddUMipOKjBI1wVqCzNWU/1NXul4XlrFHu++/+69w16I9386AYq1U34h?= =?us-ascii?Q?RtWbQcd9qmuztgNNgDc0+iUt63fDFtoBUrXfwHGv4Hp4w2MRAGdc4SpQb+fF?= =?us-ascii?Q?n7tWKIrHoH2Fm/S3X4Xx2MZ1+JIk+sjh3DMkRXyG0cDyWMowZiZK06GQ3CdO?= =?us-ascii?Q?HseCW7VSk6O8Qwg4o48fOBa71/kOYyPM4zcVFQ5LILrkOWE/0rNGJUQRC65I?= =?us-ascii?Q?SqR1gL4Vcrka39OaPEH31soH06aujCJcUdXVfllezaX7GQjNXQkubAfMOoAr?= =?us-ascii?Q?fye9VlOeUQSfj6w13gAbNw5J2dLvAgvczWWtF+LzlJ/n7dlKihGgtqpTCiPI?= =?us-ascii?Q?WF9iJkx4wtuR/3QYvJMzubGzjs+NQtXJw5IKvxSNvA4PqIzkY1LPhUMnJHan?= =?us-ascii?Q?vc9TwJe0PL5rRg/SnMCNpNtnUEl9Av9eQot8+Pb5zCqrlnSdiAxl40a2OLKy?= =?us-ascii?Q?7IY3Hh3Tlkr/nWGD866Pw1CUalI+NrhUho8Ek58MRUGirW8irJ1Y6Bp712fi?= =?us-ascii?Q?VbKtFiNqTyuVP0KYAXwBR4iuMMlWLx2O+w2OwY3N8fU/NTpV4C4Hp5EIYgKH?= =?us-ascii?Q?curskvIYwQZudQR71B3GGKaOTagXezLCfNMSsViWyFSfUpHFT23Hh0b8aeod?= =?us-ascii?Q?JtT6Zirq0AF6Z6tODH8Qw1Rdhfrm6rFmmCJfGgeFUBNV4AYP6VHYTr6y6jXJ?= =?us-ascii?Q?fVJEq64DjWD8wGGJ/Kx6/5e5fjayaUODEsZAUOkzVfsJvmj1N6uIN+/zZ7MJ?= =?us-ascii?Q?D+rycBXVXIut/r42xS2D4CdcU56jNvsF2Ag+mq5UsgvVt4a+30x4wp+OSdSy?= =?us-ascii?Q?VJEXwvOFBalUMrYfbAlxSRkvWUpI+/v7a9UBl24rjswfnuztsG4lh0pVJkfr?= =?us-ascii?Q?/6P7zjph8KUThJfHRkKOybCvd9e/FAJumrkH7X7cGoZGmyJx025+TSMjo/Yw?= =?us-ascii?Q?2NqwFaGkY8hdPfZ8V5XW/QF5GSUWyKX+Cg5welph65A1I/+8OcuXOTXZ40Y9?= =?us-ascii?Q?Ex3alWEWvP0ZbrP+DbEn3Tti5ZJkRwXhNDnjqQflCEj5jUHh1nKIRecTNEJU?= =?us-ascii?Q?0H5FAMnj3oCEshARV3myR4lOa2VD?= 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:(13230031)(82310400017)(1800799015)(376005)(36860700004); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: AsWMU3yVAWHmFEIjUb0g6QJJfpvSH65abAi/G/sU+axGYy0jeJoGGL6BcDw037R+qF9/8H5qndhsIUiYEAyBgs5/ZQ2t3pAAZldHe/MuYU7gbsgtA+6B9nk8ssZzutBBSnmLVC4n2DfJT5qBi2nnYjl1XQ17L1YaRIdE/tsQP9/94cxVm8OhjI5gaFW9vxrsUQkvBh3iKISsesMlKBbe4GycqaVg0qjWXuznp3wsGk7ONXVokrxOb5nXB4eJDMlaU/7SoFfBjJENmLftRNPDjpHN7jM+8kk4Z5FnQU/ACA8XH2xm2ZFCg+PDMROY7jdwlfNbDdWJHcTmqpsVYNVnWtXL4bsWhSus1K93h5NbSB0NzKnnwSJQUJmnZb+Dh+uYiDCNqBPRnaESKxFHjHE3U4ajHwP6sIiJfZI8n4TFJvRThqa8Bwe+RdxxENRaUHYpkPM4VIhepvyIj3vJjyCIqFLw9IhbMPDHV3A8mUBrIBQa2oa2ropZgLr5tUG9L6th6+qbL9NgFaxswmTZGJgA9+s7XBq4r/afnOVmiiIkrXwsjNcRCFjQBN4qPf64E0CuHfQsRHbS0S257Bka0Gerr1BaSbHQOiNbDeg10BF+AFRAM34TdVTFgNa8pT8PwWjw9zDY1r8ASvTJTz2vyt4fPg== X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 May 2024 15:47:45.4251 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8bf4b541-18b5-40b0-575f-08dc818903e3 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: AMS1EPF00000047.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM7P190MB0599 X-BESS-ID: 1717170468-303392-12651-39858-1 X-BESS-VER: 2019.1_20240530.1612 X-BESS-Apparent-Source-IP: 104.47.18.110 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVmYW5gYmQGYGUNQoOdHQItXY2N DCyNjMMtHYxMjSxMzSNNEsydAixcAiTak2FgAeKXeyQgAAAA== X-BESS-Outbound-Spam-Score: 0.00 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.256627 [from cloudscan15-157.eu-central-1a.ess.aws.cudaops.com] Rule breakdown below pts rule name description ---- ---------------------- -------------------------------- 0.00 BSF_BESS_OUTBOUND META: BESS Outbound X-BESS-Outbound-Spam-Status: SCORE=0.00 using account:ESS113687 scores of KILL_LEVEL=7.0 tests=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 Add ntnic HW interfaces (PCIe, I2C) API. Signed-off-by: Serhii Iliushyk --- v2: * Fixed WARNING:TYPO_SPELLING --- drivers/net/ntnic/adapter/nt4ga_pci_ta_tg.c | 550 ++++++++++++++++++ drivers/net/ntnic/adapter/nt4ga_tfg.c | 69 +++ drivers/net/ntnic/include/nt4ga_tfg.h | 2 + drivers/net/ntnic/include/ntnic_nim.h | 1 + drivers/net/ntnic/meson.build | 8 + .../net/ntnic/nthw/core/include/nthw_core.h | 6 + .../net/ntnic/nthw/core/include/nthw_gfg.h | 40 ++ .../net/ntnic/nthw/core/include/nthw_gmf.h | 75 +++ .../net/ntnic/nthw/core/include/nthw_i2cm.h | 51 ++ .../ntnic/nthw/core/include/nthw_pci_rd_tg.h | 50 ++ .../net/ntnic/nthw/core/include/nthw_pci_ta.h | 40 ++ .../ntnic/nthw/core/include/nthw_pci_wr_tg.h | 55 ++ drivers/net/ntnic/nthw/core/nthw_gfg.c | 365 ++++++++++++ drivers/net/ntnic/nthw/core/nthw_gmf.c | 176 ++++++ drivers/net/ntnic/nthw/core/nthw_i2cm.c | 197 +++++++ drivers/net/ntnic/nthw/core/nthw_pci_rd_tg.c | 115 ++++ drivers/net/ntnic/nthw/core/nthw_pci_ta.c | 94 +++ drivers/net/ntnic/nthw/core/nthw_pci_wr_tg.c | 122 ++++ 18 files changed, 2016 insertions(+) create mode 100644 drivers/net/ntnic/adapter/nt4ga_pci_ta_tg.c create mode 100644 drivers/net/ntnic/adapter/nt4ga_tfg.c create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_gfg.h create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_gmf.h create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_i2cm.h create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pci_rd_tg.h create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pci_ta.h create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pci_wr_tg.h create mode 100644 drivers/net/ntnic/nthw/core/nthw_gfg.c create mode 100644 drivers/net/ntnic/nthw/core/nthw_gmf.c create mode 100644 drivers/net/ntnic/nthw/core/nthw_i2cm.c create mode 100644 drivers/net/ntnic/nthw/core/nthw_pci_rd_tg.c create mode 100644 drivers/net/ntnic/nthw/core/nthw_pci_ta.c create mode 100644 drivers/net/ntnic/nthw/core/nthw_pci_wr_tg.c diff --git a/drivers/net/ntnic/adapter/nt4ga_pci_ta_tg.c b/drivers/net/ntnic/adapter/nt4ga_pci_ta_tg.c new file mode 100644 index 0000000000..b7a9ca2fbe --- /dev/null +++ b/drivers/net/ntnic/adapter/nt4ga_pci_ta_tg.c @@ -0,0 +1,550 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "ntlog.h" +#include "nt_util.h" +#include "nthw_drv.h" +#include "nt4ga_adapter.h" +#include "nt4ga_pci_ta_tg.h" +#include "nthw_pci_ta.h" +#include "nthw_pci_rd_tg.h" +#include "nthw_pci_wr_tg.h" + +int nt4ga_pci_ta_tg_init(struct adapter_info_s *p_adapter_info) +{ + const char *const p_adapter_id_str = p_adapter_info->mp_adapter_id_str; + fpga_info_t *fpga_info = &p_adapter_info->fpga_info; + nthw_fpga_t *p_fpga = fpga_info->mp_fpga; + nt4ga_pci_ta_tg_t *p = &p_adapter_info->nt4ga_pci_ta_tg; + int res; + int n_err_cnt = 0; + + if (p) { + memset(p, 0, sizeof(nt4ga_pci_ta_tg_t)); + + } else { + NT_LOG(ERR, NTHW, "%s: %s: null ptr\n", p_adapter_id_str, __func__); + return -1; + } + + assert(p_fpga); + + p->mp_nthw_pci_rd_tg = nthw_pci_rd_tg_new(); + assert(p->mp_nthw_pci_rd_tg); + res = nthw_pci_rd_tg_init(p->mp_nthw_pci_rd_tg, p_fpga, 0); + + if (res) { + n_err_cnt++; + NT_LOG(WRN, NTHW, "%s: module PCI_RD_TG not found\n", p_adapter_id_str); + } + + p->mp_nthw_pci_wr_tg = nthw_pci_wr_tg_new(); + assert(p->mp_nthw_pci_wr_tg); + res = nthw_pci_wr_tg_init(p->mp_nthw_pci_wr_tg, p_fpga, 0); + + if (res) { + n_err_cnt++; + NT_LOG(WRN, NTHW, "%s: module PCI_WR_TG not found\n", p_adapter_id_str); + } + + p->mp_nthw_pci_ta = nthw_pci_ta_new(); + assert(p->mp_nthw_pci_ta); + res = nthw_pci_ta_init(p->mp_nthw_pci_ta, p_fpga, 0); + + if (res) { + n_err_cnt++; + NT_LOG(WRN, NTHW, "%s: module PCI_TA not found\n", p_adapter_id_str); + } + + return n_err_cnt; +} + +static int nt4ga_pci_ta_tg_ta_write_control_enable(nt4ga_pci_ta_tg_t *p, uint32_t enable) +{ + nthw_pci_ta_set_control_enable(p->mp_nthw_pci_ta, enable); + return 0; +} + +static int nt4ga_pci_ta_tg_ta_read_length_error(nt4ga_pci_ta_tg_t *p, uint32_t *p_data) +{ + nthw_pci_ta_get_length_error(p->mp_nthw_pci_ta, p_data); + return 0; +} + +static int nt4ga_pci_ta_tg_ta_read_packet_bad(nt4ga_pci_ta_tg_t *p, uint32_t *p_data) +{ + nthw_pci_ta_get_packet_bad(p->mp_nthw_pci_ta, p_data); + return 0; +} + +static int nt4ga_pci_ta_tg_ta_read_packet_good(nt4ga_pci_ta_tg_t *p, uint32_t *p_data) +{ + nthw_pci_ta_get_packet_good(p->mp_nthw_pci_ta, p_data); + return 0; +} + +static int nt4ga_pci_ta_tg_ta_read_payload_error(nt4ga_pci_ta_tg_t *p, uint32_t *p_data) +{ + nthw_pci_ta_get_payload_error(p->mp_nthw_pci_ta, p_data); + return 0; +} + +static int nt4ga_pci_ta_tg_rd_tg_setup(nt4ga_pci_ta_tg_t *p, uint64_t iova, int slot_addr, + uint32_t req_size, bool wait, bool wrap) +{ + const uint64_t n_phys_addr = (iova + (unsigned long)(slot_addr * req_size)); + nthw_pci_rd_tg_set_ram_addr(p->mp_nthw_pci_rd_tg, slot_addr); + nthw_pci_rd_tg_set_phys_addr(p->mp_nthw_pci_rd_tg, n_phys_addr); + nthw_pci_rd_tg_set_ram_data(p->mp_nthw_pci_rd_tg, req_size, wait, wrap); + return 0; +} + +static int nt4ga_pci_ta_tg_rd_tg_run(nt4ga_pci_ta_tg_t *p, uint32_t num_iterations) +{ + nthw_pci_rd_tg_set_run(p->mp_nthw_pci_rd_tg, num_iterations); + return 0; +} + +static int nt4ga_pci_ta_tg_rd_tg_wait_ready(nt4ga_pci_ta_tg_t *p) +{ + int poll = 0; + uint32_t data = 0; + + while (data == 0) { + /* NOTE: Deliberately start with a sleep - ensures that the FPGA pipe is empty */ + nt_os_wait_usec(1000); + data = nthw_pci_rd_tg_get_ctrl_rdy(p->mp_nthw_pci_rd_tg); + poll++; + + if (poll >= 1000) { + NT_LOG(ERR, NTHW, "%s: FAILED waiting PCI RD TG ready: poll=%d\n", + __func__, poll); + return -1; + } + } + + return 0; +} + +static int nt4ga_pci_ta_tg_wr_tg_setup(nt4ga_pci_ta_tg_t *p, uint64_t iova, int slot_addr, + uint32_t req_size, bool wait, bool wrap, bool inc) +{ + const uint64_t n_phys_addr = (iova + (unsigned long)(slot_addr * req_size)); + + nthw_pci_wr_tg_set_ram_addr(p->mp_nthw_pci_wr_tg, slot_addr); + nthw_pci_wr_tg_set_phys_addr(p->mp_nthw_pci_wr_tg, n_phys_addr); + nthw_pci_wr_tg_set_ram_data(p->mp_nthw_pci_wr_tg, req_size, wait, wrap, inc); + + return 0; +} + +static int nt4ga_pci_ta_tg_wr_tg_run(nt4ga_pci_ta_tg_t *p, uint32_t num_iterations) +{ + nthw_pci_wr_tg_set_run(p->mp_nthw_pci_wr_tg, num_iterations); + return 0; +} + +static int nt4ga_pci_ta_tg_wr_tg_wait_ready(nt4ga_pci_ta_tg_t *p) +{ + int poll = 0; + uint32_t data = 0; + + while (data == 0) { + /* NOTE: Deliberately start with a sleep - ensures that the FPGA pipe is empty */ + nt_os_wait_usec(1000); + data = nthw_pci_wr_tg_get_ctrl_rdy(p->mp_nthw_pci_wr_tg); + poll++; + + if (poll >= 1000) { + NT_LOG(ERR, NTHW, "%s: FAILED waiting PCI WR TG ready: poll=%d\n", + __func__, poll); + return -1; + } + } + + return 0; +} + +int nt4ga_pci_ta_tg_measure_throughput_run(struct adapter_info_s *p_adapter_info, + struct nthw_hif_end_point_counters *pri, + struct nthw_hif_end_point_counters *sla) +{ + nt4ga_pci_ta_tg_t *p = &p_adapter_info->nt4ga_pci_ta_tg; + + const int delay = pri->n_tg_delay; + const int pkt_size = pri->n_tg_pkt_size; + const int num_pkts = pri->n_tg_num_pkts; + const int n_direction = pri->n_tg_direction; + const uint8_t n_numa_node = (uint8_t)pri->n_numa_node; + const int dma_buf_size = (4 * 1024 * 1024); + + const size_t align_size = nt_util_align_size(dma_buf_size); + uint32_t *mem_addr; + uint64_t iova; + + int bo_error = 0; + + nthw_hif *p_primary_instance = p_adapter_info->fpga_info.mp_nthw_hif; + nthw_hif *p_secondary_instance = NULL; + + nthw_pcie3 *p_pci_primary = p_adapter_info->fpga_info.mp_nthw_pcie3; + nthw_pcie3 *p_pci_secondary = NULL; + + assert(p_primary_instance || p_pci_primary); + + struct nt_dma_s *p_dma; + /* FPGA needs a Page alignment (4K on Intel) */ + p_dma = nt_dma_alloc(align_size, 0x1000, n_numa_node); + + if (p_dma == NULL) { + NT_LOG(DBG, ETHDEV, "%s: vfio_dma_alloc failed\n", __func__); + return 0; + } + + mem_addr = (uint32_t *)p_dma->addr; + iova = p_dma->iova; + + NT_LOG(DBG, NTHW, "%s: Running HIF bandwidth measurements on NUMA node %d\n", __func__, + n_numa_node); + + bo_error = 0; + { + int wrap; + + /* Stop any existing running test */ + bo_error |= nt4ga_pci_ta_tg_rd_tg_run(p, 0); + bo_error |= nt4ga_pci_ta_tg_rd_tg_wait_ready(p); + + bo_error |= nt4ga_pci_ta_tg_wr_tg_run(p, 0); + bo_error |= nt4ga_pci_ta_tg_wr_tg_wait_ready(p); + + bo_error |= nt4ga_pci_ta_tg_ta_write_control_enable(p, 0); + + /* Prepare the HIF Traffic generator */ + bo_error |= nt4ga_pci_ta_tg_ta_write_control_enable(p, 1); + bo_error |= nt4ga_pci_ta_tg_rd_tg_wait_ready(p); + bo_error |= nt4ga_pci_ta_tg_wr_tg_wait_ready(p); + + /* + * Ensure that the hostbuffer memory contain data that can be read - + * For this we will ask the FPGA to write data to it. The last wrap packet + * does not generate any data it only wraps (unlike the PCIe2 TG) + */ + { + int pkt; + + for (pkt = 0; pkt < num_pkts; pkt++) { + if (pkt >= (num_pkts - 1)) + wrap = 1; + + else + wrap = 0; + + bo_error |= nt4ga_pci_ta_tg_wr_tg_setup(p, iova, pkt, pkt_size, 0, + wrap, 1); + bo_error |= nt4ga_pci_ta_tg_rd_tg_setup(p, iova, pkt, pkt_size, 0, + wrap); + } + } + + bo_error |= nt4ga_pci_ta_tg_wr_tg_run(p, 1); + bo_error |= nt4ga_pci_ta_tg_wr_tg_wait_ready(p); + + /* Start WR TG Write once */ + bo_error |= nt4ga_pci_ta_tg_wr_tg_run(p, 1); + /* Wait until WR TG ready */ + bo_error |= nt4ga_pci_ta_tg_wr_tg_wait_ready(p); + + /* Verify that we have a packet */ + { + int pkt; + + for (pkt = 0; pkt < num_pkts; pkt++) { + uint32_t value = 0; + int poll; + + for (poll = 8; poll < pkt_size; poll += 4, value++) { + if (*(uint32_t *)((uint8_t *)mem_addr + (pkt * pkt_size) + + poll) != value) { + NT_LOG(ERR, NTHW, + "HIF TG: Prepare failed. Data write failed: #%d.%d: %016X:%08X\n", + pkt, poll, + *(uint32_t *)((uint8_t *)mem_addr + + (pkt * pkt_size) + poll), + value); + + /* + * Break out of the verification loop on first + * compare error + */ + bo_error |= 1; + break; + } + } + } + } + + switch (n_direction) { + case 1: /* Read only test */ + nt4ga_pci_ta_tg_wr_tg_run(p, 0xffff); + break; + + case 2: /* Write only test */ + nt4ga_pci_ta_tg_rd_tg_run(p, 0xffff); + break; + + case 3: /* Combined read/write test */ + nt4ga_pci_ta_tg_wr_tg_run(p, 0xffff); + nt4ga_pci_ta_tg_rd_tg_run(p, 0xffff); + break; + + default:/* stop tests */ + nt4ga_pci_ta_tg_wr_tg_run(p, 0); + nt4ga_pci_ta_tg_rd_tg_run(p, 0); + break; + } + + do { + /* prep */ + if (p_pci_primary) + nthw_pcie3_end_point_counters_sample_pre(p_pci_primary, pri); + + if (p_pci_secondary) + nthw_pcie3_end_point_counters_sample_pre(p_pci_secondary, sla); + + /* start measure */ + if (p_primary_instance) + nthw_hif_stat_req_enable(p_primary_instance); + + if (p_pci_primary) + nthw_pcie3_stat_req_enable(p_pci_primary); + + if (p_secondary_instance) + nthw_hif_stat_req_enable(p_secondary_instance); + + if (p_pci_secondary) + nthw_pcie3_stat_req_enable(p_pci_secondary); + + /* Wait */ + nt_os_wait_usec(delay); + + /* Stop measure */ + if (p_primary_instance) + nthw_hif_stat_req_disable(p_primary_instance); + + if (p_pci_primary) + nthw_pcie3_stat_req_disable(p_pci_primary); + + if (p_secondary_instance) + nthw_hif_stat_req_disable(p_secondary_instance); + + if (p_pci_secondary) + nthw_pcie3_stat_req_disable(p_pci_secondary); + + /* Post process primary */ + if (p_primary_instance) + nthw_hif_end_point_counters_sample(p_primary_instance, pri); + + if (p_pci_primary) + nthw_pcie3_end_point_counters_sample_post(p_pci_primary, pri); + + /* Post process secondary */ + if (p_secondary_instance) + nthw_hif_end_point_counters_sample(p_secondary_instance, sla); + + if (p_pci_secondary) + nthw_pcie3_end_point_counters_sample_post(p_pci_secondary, sla); + + { + /* Check for TA transmit errors */ + uint32_t dw_good_pkts, dw_bad_pkts, dw_bad_length, dw_bad_payload; + nt4ga_pci_ta_tg_ta_read_packet_good(p, &dw_good_pkts); + nt4ga_pci_ta_tg_ta_read_packet_bad(p, &dw_bad_pkts); + nt4ga_pci_ta_tg_ta_read_length_error(p, &dw_bad_length); + nt4ga_pci_ta_tg_ta_read_payload_error(p, &dw_bad_payload); + + NT_LOG(DBG, NTHW, + "%s: NUMA node %u: HIF: TA: Good pkts, Bad pkts, Bad length, Bad payload\n", + __func__, n_numa_node); + NT_LOG(DBG, NTHW, + "%s: NUMA node %u: HIF: TA: 0x%08x 0x%08x 0x%08x 0x%08x\n", + __func__, n_numa_node, dw_good_pkts, dw_bad_pkts, + dw_bad_length, dw_bad_payload); + + if (dw_bad_pkts | dw_bad_length | dw_bad_payload) { + bo_error |= 1; + NT_LOG(ERR, NTHW, + "%s: NUMA node %u: HIF: TA: error detected\n", + __func__, n_numa_node); + NT_LOG(ERR, NTHW, + "%s: NUMA node %u: HIF: TA: Good packets received: %u\n", + __func__, n_numa_node, dw_good_pkts); + NT_LOG(ERR, NTHW, + "%s: NUMA node %u: HIF: TA: Bad packets received : %u\n", + __func__, n_numa_node, dw_bad_pkts); + NT_LOG(ERR, NTHW, + "%s: NUMA node %u: HIF: TA: Bad length received : %u\n", + __func__, n_numa_node, dw_bad_length); + NT_LOG(ERR, NTHW, + "%s: NUMA node %u: HIF: TA: Bad payload received : %u\n", + __func__, n_numa_node, dw_bad_payload); + } + } + + if (bo_error != 0) + break; + + break; /* for now only loop once */ + + /* + * Only do "signalstop" looping if a specific numa node and direction is to + * be tested. + */ + } while ((bo_error == 0) && (n_numa_node != UINT8_MAX) && (n_direction != -1)); + + /* Stop the test */ + bo_error |= nt4ga_pci_ta_tg_wr_tg_run(p, 0); + bo_error |= nt4ga_pci_ta_tg_wr_tg_wait_ready(p); + + bo_error |= nt4ga_pci_ta_tg_rd_tg_run(p, 0); + bo_error |= nt4ga_pci_ta_tg_rd_tg_wait_ready(p); + + bo_error |= nt4ga_pci_ta_tg_ta_write_control_enable(p, 0); + + /* PCIe3 sanity checks */ + { +#if defined(DEBUG) + int do_loop = 1; +#else + int do_loop = 0; +#endif + + while (do_loop) { + do_loop = 0; + + if (p_primary_instance) { + nthw_hif_stat_req_enable(p_primary_instance); + nt_os_wait_usec(100); + nthw_hif_stat_req_disable(p_primary_instance); + } + + if (do_loop == 0) + break; + + NT_LOG(DBG, NTHW, "%s: WARNING this is wrong - wait again\n", + __func__); + nt_os_wait_usec(200 * 1000); + } + } + } + + /* Stop the test */ + + bo_error |= nt4ga_pci_ta_tg_wr_tg_run(p, 0); + bo_error |= nt4ga_pci_ta_tg_wr_tg_wait_ready(p); + + bo_error |= nt4ga_pci_ta_tg_rd_tg_run(p, 0); + bo_error |= nt4ga_pci_ta_tg_rd_tg_wait_ready(p); + + bo_error |= nt4ga_pci_ta_tg_ta_write_control_enable(p, 0); + + nt_dma_free(p_dma); + + return bo_error; +} + +int nt4ga_pci_ta_tg_measure_throughput_main(struct adapter_info_s *p_adapter_info, + const uint8_t numa_node, const int direction, + const int n_pkt_size, const int n_batch_count, + const int n_delay) +{ + /* All numa nodes is indicated by UINT8_MAX */ + const uint8_t numa_begin = (numa_node == UINT8_MAX ? 0 : numa_node); + const uint8_t numa_end = numa_begin; + + /* sanity check direction param */ + const int dir_begin = (direction <= 0 ? 1 : direction); + const int dir_end = (direction <= 0 ? 3 : direction); + + int bo_error = 0; + struct nthw_hif_end_points eps; + + if (n_delay == 0) + return -1; + + NT_LOG(DBG, NTHW, "HIF adapter throughput:\n"); + + /* Only do "signalstop"-looping if a specific numa node is to be tested. */ + { + uint8_t numa; + + for (numa = numa_begin; numa <= numa_end; numa++) { + int by_loop; + + for (by_loop = dir_begin; by_loop <= dir_end; by_loop++) { + struct nthw_hif_end_point_counters *pri = &eps.pri; + struct nthw_hif_end_point_counters *sla = &eps.sla; + + pri->n_numa_node = numa; + pri->n_tg_direction = by_loop; + pri->n_tg_pkt_size = (n_pkt_size > 0 ? n_pkt_size : TG_PKT_SIZE); + pri->n_tg_num_pkts = + (n_batch_count > 0 ? n_batch_count : TG_NUM_PACKETS); + pri->n_tg_delay = (n_delay > 0 ? n_delay : TG_DELAY); + pri->cur_rx = 0; + pri->cur_tx = 0; + pri->n_ref_clk_cnt = -1; + pri->bo_error = 0; + + sla->n_numa_node = numa; + sla->n_tg_direction = by_loop; + sla->n_tg_pkt_size = (n_pkt_size > 0 ? n_pkt_size : TG_PKT_SIZE); + sla->n_tg_num_pkts = + (n_batch_count > 0 ? n_batch_count : TG_NUM_PACKETS); + sla->n_tg_delay = (n_delay > 0 ? n_delay : TG_DELAY); + sla->cur_rx = 0; + sla->cur_tx = 0; + pri->n_ref_clk_cnt = -1; + sla->bo_error = 0; + + bo_error += nt4ga_pci_ta_tg_measure_throughput_run(p_adapter_info, + pri, sla); +#if defined(DEBUG) && (1) + { + NT_LOG(DBG, NTHW, + "%s: @ %d: %d %d %d %d: %016lX %016lX : %6ld Mbps %6ld Mbps\n", + __func__, pri->n_numa_node, pri->n_tg_direction, + pri->n_tg_num_pkts, pri->n_tg_pkt_size, + pri->n_tg_delay, pri->cur_rx, pri->cur_tx, + (pri->cur_rx * 8UL / 1000000UL), + (pri->cur_tx * 8UL / 1000000UL)); + } + { + NT_LOG(DBG, NTHW, + "%s: @ %d: %d %d %d %d: %016lX %016lX : %6ld Mbps %6ld Mbps\n", + __func__, sla->n_numa_node, sla->n_tg_direction, + sla->n_tg_num_pkts, sla->n_tg_pkt_size, + sla->n_tg_delay, sla->cur_rx, sla->cur_tx, + (sla->cur_rx * 8UL / 1000000UL), + (sla->cur_tx * 8UL / 1000000UL)); + } +#endif + + if (pri->bo_error != 0 || sla->bo_error != 0) + bo_error++; + + if (bo_error) + break; + } + } + } + + if (bo_error != 0) + NT_LOG(ERR, NTHW, "%s: error during bandwidth measurement\n", __func__); + + NT_LOG(DBG, NTHW, "HIF adapter throughput: done %s\n", __func__); + + return 0; +} diff --git a/drivers/net/ntnic/adapter/nt4ga_tfg.c b/drivers/net/ntnic/adapter/nt4ga_tfg.c new file mode 100644 index 0000000000..be1b2a55ad --- /dev/null +++ b/drivers/net/ntnic/adapter/nt4ga_tfg.c @@ -0,0 +1,69 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "ntlog.h" +#include "nthw_drv.h" +#include "nt4ga_adapter.h" +#include "nthw_fpga.h" +#include "nt4ga_tfg.h" + +int nt4ga_tfg_init(struct adapter_info_s *p_adapter_info) +{ + const char *const p_adapter_id_str = p_adapter_info->mp_adapter_id_str; + + fpga_info_t *fpga_info = &p_adapter_info->fpga_info; + nthw_fpga_t *p_fpga = fpga_info->mp_fpga; + nt4ga_tfg_t *p_nt4ga_tfg = &p_adapter_info->nt4ga_tfg; + + nthw_gfg_t *p_nthw_gfg = nthw_gfg_new(); + + if (p_nthw_gfg) { + int res = nthw_gfg_init(p_nthw_gfg, p_fpga, 0); + + if (res) { + NT_LOG(WRN, ETHDEV, "%s: TFG/GFG capability is not available\n", + p_adapter_id_str); + free(p_nthw_gfg); + p_nthw_gfg = NULL; + } + } + + p_nt4ga_tfg->mp_nthw_gfg = p_nthw_gfg; + + return p_nthw_gfg ? 0 : -1; +} + +int nt4ga_tfg_setup(struct adapter_info_s *p_adapter_info, const int n_intf_no, + const int n_cmd_start_stop, const int n_frame_count, const int n_frame_size, + const int n_frame_fill_mode, const int n_frame_stream_id) +{ + fpga_info_t *fpga_info = &p_adapter_info->fpga_info; + nt4ga_tfg_t *p_nt4ga_tfg = &p_adapter_info->nt4ga_tfg; + + nthw_gfg_t *p_nthw_gfg = p_nt4ga_tfg->mp_nthw_gfg; + + if (p_nthw_gfg) { + nthw_fpga_t *p_fpga = fpga_info->mp_fpga; + + /* Does FPGA have GMF module? */ + if (nthw_gmf_init(NULL, p_fpga, n_intf_no) == 0) { + /* Yes, FPGA has GMF module */ + nthw_gmf_t gmf; + + if (nthw_gmf_init(&gmf, p_fpga, n_intf_no) == 0) + nthw_gmf_set_ifg_speed_percent(&gmf, n_cmd_start_stop); + } + + if (n_cmd_start_stop) { + nthw_gfg_start(p_nthw_gfg, n_intf_no, n_frame_count, n_frame_size, + n_frame_fill_mode, n_frame_stream_id); + + } else { + nthw_gfg_stop(p_nthw_gfg, n_intf_no); + } + } + + return 0; +} diff --git a/drivers/net/ntnic/include/nt4ga_tfg.h b/drivers/net/ntnic/include/nt4ga_tfg.h index 9797403dec..db2f42b215 100644 --- a/drivers/net/ntnic/include/nt4ga_tfg.h +++ b/drivers/net/ntnic/include/nt4ga_tfg.h @@ -7,6 +7,8 @@ #define NT4GA_TFG_H_ typedef struct nt4ga_tfg_s { + nthw_gfg_t *mp_nthw_gfg; + nthw_gmf_t *mp_nthw_gmf; nthw_mac_tfg_t *mp_nthw_mac_tfg; } nt4ga_tfg_t; diff --git a/drivers/net/ntnic/include/ntnic_nim.h b/drivers/net/ntnic/include/ntnic_nim.h index 41457b7a07..fc9b2a2b23 100644 --- a/drivers/net/ntnic/include/ntnic_nim.h +++ b/drivers/net/ntnic/include/ntnic_nim.h @@ -93,6 +93,7 @@ typedef struct nim_i2c_ctx { union { nthw_iic_t hwiic; /* depends on *Fpga_t, instance number, and cycle time */ struct { + nthw_i2cm_t *p_nt_i2cm; int mux_channel; } hwagx; }; diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build index 0205d7de8e..1a56a0f6c4 100644 --- a/drivers/net/ntnic/meson.build +++ b/drivers/net/ntnic/meson.build @@ -77,6 +77,8 @@ headers = files('rte_pmd_ntnic.h') # all sources sources = files( 'dpdk_mod_reg.c', + 'drivers/net/ntnic/driver/modules/adapter/nt4ga_pci_ta_tg.c', + 'drivers/net/ntnic/driver/modules/adapter/nt4ga_tfg.c', 'nthw/supported/nthw_fpga_9563_055_039_0000.c', 'nthw/supported/nthw_fpga_instances.c', 'nthw/supported/nthw_fpga_mod_str_map.c', @@ -86,10 +88,16 @@ sources = files( 'nthw/core/nt200a0x/reset/nthw_fpga_rst_nt200a0x.c', 'nthw/core/nthw_fpga.c', 'nthw/core/nthw_fpga_rst.c', + 'nthw/core/nthw_gfg.c', + 'nthw/core/nthw_gmf.c', 'nthw/core/nthw_hif.c', + 'nthw/core/nthw_i2cm.c', 'nthw/core/nthw_iic.c', 'nthw/core/nthw_mac_pcs_xxv.c', 'nthw/core/nthw_pcie3.c', + 'nthw/core/nthw_pci_rd_tg.c', + 'nthw/core/nthw_pci_ta.c', + 'nthw/core/nthw_pci_wr_tg.c', 'nthw/core/nthw_sdc.c', 'nthw/core/nthw_si5340.c', 'nthw/core/nthw_spim.c', diff --git a/drivers/net/ntnic/nthw/core/include/nthw_core.h b/drivers/net/ntnic/nthw/core/include/nthw_core.h index f2d56a41f9..b72766cc5c 100644 --- a/drivers/net/ntnic/nthw/core/include/nthw_core.h +++ b/drivers/net/ntnic/nthw/core/include/nthw_core.h @@ -13,8 +13,14 @@ #include "nthw_fpga_model.h" #include "nthw_hif.h" #include "nthw_pcie3.h" +#include "nthw_pci_rd_tg.h" +#include "nthw_pci_wr_tg.h" +#include "nthw_pci_ta.h" #include "nthw_iic.h" +#include "nthw_i2cm.h" +#include "nthw_gfg.h" +#include "nthw_gmf.h" #include "nthw_mac_pcs_xxv.h" #include "nthw_mac_tfg.h" #include "nthw_sdc.h" diff --git a/drivers/net/ntnic/nthw/core/include/nthw_gfg.h b/drivers/net/ntnic/nthw/core/include/nthw_gfg.h new file mode 100644 index 0000000000..fd477775d5 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/include/nthw_gfg.h @@ -0,0 +1,40 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef NTHW_GFG_H_ +#define NTHW_GFG_H_ + +struct nthw_gfg { + nthw_fpga_t *mp_fpga; + nthw_module_t *mp_mod_gfg; + int mn_instance; + + int mn_param_gfg_present; + + nthw_field_t *mpa_fld_ctrl_enable[8]; + nthw_field_t *mpa_fld_ctrl_mode[8]; + nthw_field_t *mpa_fld_ctrl_prbs_en[8]; + nthw_field_t *mpa_fld_ctrl_size[8]; + nthw_field_t *mpa_fld_stream_id_val[8]; + nthw_field_t *mpa_fld_run_run[8]; + nthw_field_t *mpa_fld_size_mask[8]; + nthw_field_t *mpa_fld_burst_size_val[8]; +}; + +typedef struct nthw_gfg nthw_gfg_t; +typedef struct nthw_gfg nthw_gfg; + +nthw_gfg_t *nthw_gfg_new(void); +int nthw_gfg_init(nthw_gfg_t *p, nthw_fpga_t *p_fpga, int n_instance); + +int nthw_gfg_start(nthw_gfg_t *p, const int n_intf_no, const int n_frame_count, + const int n_frame_size, const int n_frame_fill_mode, + const int n_frame_stream_id); +int nthw_gfg_stop(nthw_gfg_t *p, const int n_intf_no); +int nthw_gfg_setup(nthw_gfg_t *p, const size_t n_intf_no, const int n_enable, + const int n_frame_count, const int n_frame_size, const int n_frame_fill_mode, + const int n_frame_stream_id); + +#endif /* NTHW_GFG_H_ */ diff --git a/drivers/net/ntnic/nthw/core/include/nthw_gmf.h b/drivers/net/ntnic/nthw/core/include/nthw_gmf.h new file mode 100644 index 0000000000..b9907a9285 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/include/nthw_gmf.h @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef __NTHW_GMF_H__ +#define __NTHW_GMF_H__ + +enum GMF_STATUS_MASK { + GMF_STATUS_MASK_DATA_UNDERFLOWED = 1, + GMF_STATUS_MASK_IFG_ADJUSTED +}; + +struct nthw_gmf { + nthw_fpga_t *mp_fpga; + nthw_module_t *mp_mod_gmf; + int mn_instance; + + nthw_register_t *mp_ctrl; + nthw_field_t *mp_ctrl_enable; + nthw_field_t *mp_ctrl_ifg_enable; + nthw_field_t *mp_ctrl_ifg_tx_now_always; + nthw_field_t *mp_ctrl_ifg_tx_on_ts_always; + nthw_field_t *mp_ctrl_ifg_tx_on_ts_adjust_on_set_clock; + nthw_field_t *mp_ctrl_ifg_auto_adjust_enable; + nthw_field_t *mp_ctrl_ts_inject_always; + nthw_field_t *mp_ctrl_fcs_always; + + nthw_register_t *mp_speed; + nthw_field_t *mp_speed_ifg_speed; + + nthw_register_t *mp_ifg_clock_delta; + nthw_field_t *mp_ifg_clock_delta_delta; + + nthw_register_t *mp_ifg_clock_delta_adjust; + nthw_field_t *mp_ifg_clock_delta_adjust_delta; + + nthw_register_t *mp_ifg_max_adjust_slack; + nthw_field_t *mp_ifg_max_adjust_slack_slack; + + nthw_register_t *mp_debug_lane_marker; + nthw_field_t *mp_debug_lane_marker_compensation; + + nthw_register_t *mp_stat_sticky; + nthw_field_t *mp_stat_sticky_data_underflowed; + nthw_field_t *mp_stat_sticky_ifg_adjusted; + + nthw_register_t *mp_stat_next_pkt; + nthw_field_t *mp_stat_next_pkt_ns; + + nthw_register_t *mp_stat_max_delayed_pkt; + nthw_field_t *mp_stat_max_delayed_pkt_ns; + + nthw_register_t *mp_ts_inject; + nthw_field_t *mp_ts_inject_offset; + nthw_field_t *mp_ts_inject_pos; + int mn_param_gmf_ifg_speed_mul; + int mn_param_gmf_ifg_speed_div; + + bool m_administrative_block; /* Used to enforce license expiry */ +}; + +typedef struct nthw_gmf nthw_gmf_t; +typedef struct nthw_gmf nthw_gmf; + +int nthw_gmf_init(nthw_gmf_t *p, nthw_fpga_t *p_fpga, int n_instance); + +void nthw_gmf_set_enable(nthw_gmf_t *p, bool enable); + +int nthw_gmf_get_ifg_speed_bit_width(nthw_gmf_t *p); + +int nthw_gmf_set_ifg_speed_raw(nthw_gmf_t *p, uint64_t n_speed_val); +int nthw_gmf_set_ifg_speed_percent(nthw_gmf_t *p, const double f_rate_limit_percent); + +#endif /* __NTHW_GMF_H__ */ diff --git a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h new file mode 100644 index 0000000000..9d08da07ee --- /dev/null +++ b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h @@ -0,0 +1,51 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef __NTHW_II2CM_H__ +#define __NTHW_II2CM_H__ + +#include "nthw_fpga_model.h" +#include "pthread.h" + +struct nt_i2cm { + nthw_fpga_t *mp_fpga; + + nthw_module_t *m_mod_i2cm; + + int mn_i2c_instance; + + nthw_register_t *mp_reg_prer_low; + nthw_field_t *mp_fld_prer_low_prer_low; + + nthw_register_t *mp_reg_prer_high; + nthw_field_t *mp_fld_prer_high_prer_high; + + nthw_register_t *mp_reg_ctrl; + nthw_field_t *mp_fld_ctrl_ien; + nthw_field_t *mp_fld_ctrl_en; + + nthw_register_t *mp_reg_data; + nthw_field_t *mp_fld_data_data; + + nthw_register_t *mp_reg_cmd_status; + nthw_field_t *mp_fld_cmd_status_cmd_status; + + nthw_register_t *mp_reg_select; + nthw_field_t *mp_fld_select_select; + + nthw_register_t *mp_reg_io_exp; + nthw_field_t *mp_fld_io_exp_rst; + nthw_field_t *mp_fld_io_exp_int_b; + + pthread_mutex_t i2cmmutex; +}; + +typedef struct nt_i2cm nthw_i2cm_t; +typedef struct nt_i2cm nt_i2cm; + +int nthw_i2cm_read(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t *value); +int nthw_i2cm_write(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t value); + +#endif /* __NTHW_II2CM_H__ */ diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pci_rd_tg.h b/drivers/net/ntnic/nthw/core/include/nthw_pci_rd_tg.h new file mode 100644 index 0000000000..3cef7809ea --- /dev/null +++ b/drivers/net/ntnic/nthw/core/include/nthw_pci_rd_tg.h @@ -0,0 +1,50 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef __NTHW_PCI_RD_TG_H__ +#define __NTHW_PCI_RD_TG_H__ + +struct nthw_pci_rd_tg { + nthw_fpga_t *mp_fpga; + nthw_module_t *mp_mod_pci_rd_tg; + int mn_instance; + + int mn_param_pci_ta_tg_present; + + nthw_register_t *mp_reg_pci_rd_tg_rd_data0; + nthw_field_t *mp_fld_pci_rd_tg_phys_addr_low; + + nthw_register_t *mp_reg_pci_rd_tg_rd_data1; + nthw_field_t *mp_fld_pci_rd_tg_phys_addr_high; + + nthw_register_t *mp_reg_pci_rd_tg_rd_data2; + nthw_field_t *mp_fld_pci_rd_tg_req_size; + nthw_field_t *mp_fld_pci_rd_tg_req_hid; + nthw_field_t *mp_fld_pci_rd_tg_wait; + nthw_field_t *mp_fld_pci_rd_tg_wrap; + + nthw_register_t *mp_reg_pci_rd_tg_rd_addr; + nthw_field_t *mp_fld_pci_rd_tg_ram_addr; + + nthw_register_t *mp_reg_pci_rd_tg_rd_run; + nthw_field_t *mp_fld_pci_rd_tg_run_iteration; + + nthw_register_t *mp_reg_pci_rd_tg_rd_ctrl; + nthw_field_t *mp_fld_pci_rd_tg_ctrl_rdy; +}; + +typedef struct nthw_pci_rd_tg nthw_pci_rd_tg_t; +typedef struct nthw_pci_rd_tg nthw_pci_rd_tg; + +nthw_pci_rd_tg_t *nthw_pci_rd_tg_new(void); +int nthw_pci_rd_tg_init(nthw_pci_rd_tg_t *p, nthw_fpga_t *p_fpga, int n_instance); + +void nthw_pci_rd_tg_set_phys_addr(nthw_pci_rd_tg_t *p, uint64_t n_phys_addr); +void nthw_pci_rd_tg_set_ram_addr(nthw_pci_rd_tg_t *p, int n_ram_addr); +void nthw_pci_rd_tg_set_ram_data(nthw_pci_rd_tg_t *p, uint32_t req_size, bool wait, bool wrap); +void nthw_pci_rd_tg_set_run(nthw_pci_rd_tg_t *p, int n_iterations); +uint32_t nthw_pci_rd_tg_get_ctrl_rdy(nthw_pci_rd_tg_t *p); + +#endif /* __NTHW_PCI_RD_TG_H__ */ diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pci_ta.h b/drivers/net/ntnic/nthw/core/include/nthw_pci_ta.h new file mode 100644 index 0000000000..56892d25d2 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/include/nthw_pci_ta.h @@ -0,0 +1,40 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef __NTHW_PCI_TA_H__ +#define __NTHW_PCI_TA_H__ + +struct nthw_pci_ta { + nthw_fpga_t *mp_fpga; + nthw_module_t *mp_mod_pci_ta; + int mn_instance; + + int mn_param_pci_ta_tg_present; + + nthw_register_t *mp_reg_pci_ta_ctrl; + nthw_field_t *mp_fld_pci_ta_ctrl_enable; + nthw_register_t *mp_reg_pci_ta_packet_good; + nthw_field_t *mp_fld_pci_ta_packet_good_amount; + nthw_register_t *mp_reg_pci_ta_packet_bad; + nthw_field_t *mp_fld_pci_ta_packet_bad_amount; + nthw_register_t *mp_reg_pci_ta_length_error; + nthw_field_t *mp_fld_pci_ta_length_error_amount; + nthw_register_t *mp_reg_pci_ta_payload_error; + nthw_field_t *mp_fld_pci_ta_payload_error_amount; +}; + +typedef struct nthw_pci_ta nthw_pci_ta_t; +typedef struct nthw_pci_ta nthw_pci_ta; + +nthw_pci_ta_t *nthw_pci_ta_new(void); +int nthw_pci_ta_init(nthw_pci_ta_t *p, nthw_fpga_t *p_fpga, int n_instance); + +void nthw_pci_ta_set_control_enable(nthw_pci_ta_t *p, uint32_t val); +void nthw_pci_ta_get_packet_good(nthw_pci_ta_t *p, uint32_t *val); +void nthw_pci_ta_get_packet_bad(nthw_pci_ta_t *p, uint32_t *val); +void nthw_pci_ta_get_length_error(nthw_pci_ta_t *p, uint32_t *val); +void nthw_pci_ta_get_payload_error(nthw_pci_ta_t *p, uint32_t *val); + +#endif /* __NTHW_PCI_TA_H__ */ diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pci_wr_tg.h b/drivers/net/ntnic/nthw/core/include/nthw_pci_wr_tg.h new file mode 100644 index 0000000000..e0323d1d24 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/include/nthw_pci_wr_tg.h @@ -0,0 +1,55 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef __NTHW_PCI_WR_TG_H__ +#define __NTHW_PCI_WR_TG_H__ + +struct nthw_pci_wr_tg { + nthw_fpga_t *mp_fpga; + nthw_module_t *mp_mod_pci_wr_tg; + int mn_instance; + + int mn_param_pci_ta_tg_present; + + nthw_register_t *mp_reg_pci_wr_tg_data0; + nthw_field_t *mp_fld_pci_wr_tg_phys_addr_low; + + nthw_register_t *mp_reg_pci_wr_tg_data1; + nthw_field_t *mp_fld_pci_wr_tg_phys_addr_high; + + nthw_register_t *mp_reg_pci_wr_tg_data2; + nthw_field_t *mp_fld_pci_wr_tg_req_size; + nthw_field_t *mp_fld_pci_wr_tg_req_hid; + nthw_field_t *mp_fld_pci_wr_tg_inc_mode; + nthw_field_t *mp_fld_pci_wr_tg_wait; + nthw_field_t *mp_fld_pci_wr_tg_wrap; + + nthw_register_t *mp_reg_pci_wr_tg_addr; + nthw_field_t *mp_fld_pci_wr_tg_ram_addr; + + nthw_register_t *mp_reg_pci_wr_tg_run; + nthw_field_t *mp_fld_pci_wr_tg_run_iteration; + + nthw_register_t *mp_reg_pci_wr_tg_ctrl; + nthw_field_t *mp_fld_pci_wr_tg_ctrl_rdy; + + nthw_register_t *mp_reg_pci_wr_tg_seq; + nthw_field_t *mp_fld_pci_wr_tg_seq_sequence; +}; + +typedef struct nthw_pci_wr_tg nthw_pci_wr_tg_t; +typedef struct nthw_pci_wr_tg nthw_pci_wr_tg; + +nthw_pci_wr_tg_t *nthw_pci_wr_tg_new(void); +int nthw_pci_wr_tg_init(nthw_pci_wr_tg_t *p, nthw_fpga_t *p_fpga, int n_instance); + +void nthw_pci_wr_tg_set_phys_addr(nthw_pci_wr_tg_t *p, uint64_t n_phys_addr); +void nthw_pci_wr_tg_set_ram_addr(nthw_pci_wr_tg_t *p, int n_ram_addr); +void nthw_pci_wr_tg_set_ram_data(nthw_pci_wr_tg_t *p, uint32_t req_size, bool wait, bool wrap, + bool inc); +void nthw_pci_wr_tg_set_run(nthw_pci_wr_tg_t *p, int n_iterations); +uint32_t nthw_pci_wr_tg_get_ctrl_rdy(nthw_pci_wr_tg_t *p); + +#endif /* __NTHW_PCI_WR_TG_H__ */ diff --git a/drivers/net/ntnic/nthw/core/nthw_gfg.c b/drivers/net/ntnic/nthw/core/nthw_gfg.c new file mode 100644 index 0000000000..88f349eae3 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/nthw_gfg.c @@ -0,0 +1,365 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "ntlog.h" + +#include "nthw_drv.h" +#include "nthw_register.h" + +#include "nthw_gfg.h" + +nthw_gfg_t *nthw_gfg_new(void) +{ + nthw_gfg_t *p = malloc(sizeof(nthw_gfg_t)); + + if (p) + memset(p, 0, sizeof(nthw_gfg_t)); + + return p; +} + +int nthw_gfg_init(nthw_gfg_t *p, nthw_fpga_t *p_fpga, int n_instance) +{ + nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_GFG, n_instance); + const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str; + nthw_register_t *p_reg; + + if (p == NULL) + return mod == NULL ? -1 : 0; + + if (mod == NULL) { + NT_LOG(ERR, NTHW, "%s: GFG %d: no such instance\n", p_adapter_id_str, n_instance); + return -1; + } + + p->mp_fpga = p_fpga; + p->mn_instance = n_instance; + p->mp_mod_gfg = mod; + + p->mn_param_gfg_present = nthw_fpga_get_product_param(p_fpga, NT_GFG_PRESENT, 0); + + if (!p->mn_param_gfg_present) { + NT_LOG(ERR, + NTHW, + "%s: %s: GFG %d module found - but logically not present - failing", + __func__, + p_adapter_id_str, + p->mn_instance); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL0); + + if (p_reg) { + p->mpa_fld_ctrl_enable[0] = nthw_register_query_field(p_reg, GFG_CTRL0_ENABLE); + p->mpa_fld_ctrl_mode[0] = nthw_register_query_field(p_reg, GFG_CTRL0_MODE); + p->mpa_fld_ctrl_prbs_en[0] = nthw_register_query_field(p_reg, GFG_CTRL0_PRBS_EN); + p->mpa_fld_ctrl_size[0] = nthw_register_query_field(p_reg, GFG_CTRL0_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL1); + + if (p_reg) { + p->mpa_fld_ctrl_enable[1] = nthw_register_query_field(p_reg, GFG_CTRL1_ENABLE); + p->mpa_fld_ctrl_mode[1] = nthw_register_query_field(p_reg, GFG_CTRL1_MODE); + p->mpa_fld_ctrl_prbs_en[1] = nthw_register_query_field(p_reg, GFG_CTRL1_PRBS_EN); + p->mpa_fld_ctrl_size[1] = nthw_register_query_field(p_reg, GFG_CTRL1_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL2); + + if (p_reg) { + p->mpa_fld_ctrl_enable[2] = nthw_register_query_field(p_reg, GFG_CTRL2_ENABLE); + p->mpa_fld_ctrl_mode[2] = nthw_register_query_field(p_reg, GFG_CTRL2_MODE); + p->mpa_fld_ctrl_prbs_en[2] = nthw_register_query_field(p_reg, GFG_CTRL2_PRBS_EN); + p->mpa_fld_ctrl_size[2] = nthw_register_query_field(p_reg, GFG_CTRL2_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL3); + + if (p_reg) { + p->mpa_fld_ctrl_enable[3] = nthw_register_query_field(p_reg, GFG_CTRL3_ENABLE); + p->mpa_fld_ctrl_mode[3] = nthw_register_query_field(p_reg, GFG_CTRL3_MODE); + p->mpa_fld_ctrl_prbs_en[3] = nthw_register_query_field(p_reg, GFG_CTRL3_PRBS_EN); + p->mpa_fld_ctrl_size[3] = nthw_register_query_field(p_reg, GFG_CTRL3_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL4); + + if (p_reg) { + p->mpa_fld_ctrl_enable[4] = nthw_register_query_field(p_reg, GFG_CTRL4_ENABLE); + p->mpa_fld_ctrl_mode[4] = nthw_register_query_field(p_reg, GFG_CTRL4_MODE); + p->mpa_fld_ctrl_prbs_en[4] = nthw_register_query_field(p_reg, GFG_CTRL4_PRBS_EN); + p->mpa_fld_ctrl_size[4] = nthw_register_query_field(p_reg, GFG_CTRL4_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL5); + + if (p_reg) { + p->mpa_fld_ctrl_enable[5] = nthw_register_query_field(p_reg, GFG_CTRL5_ENABLE); + p->mpa_fld_ctrl_mode[5] = nthw_register_query_field(p_reg, GFG_CTRL5_MODE); + p->mpa_fld_ctrl_prbs_en[5] = nthw_register_query_field(p_reg, GFG_CTRL5_PRBS_EN); + p->mpa_fld_ctrl_size[5] = nthw_register_query_field(p_reg, GFG_CTRL5_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL6); + + if (p_reg) { + p->mpa_fld_ctrl_enable[6] = nthw_register_query_field(p_reg, GFG_CTRL6_ENABLE); + p->mpa_fld_ctrl_mode[6] = nthw_register_query_field(p_reg, GFG_CTRL6_MODE); + p->mpa_fld_ctrl_prbs_en[6] = nthw_register_query_field(p_reg, GFG_CTRL6_PRBS_EN); + p->mpa_fld_ctrl_size[6] = nthw_register_query_field(p_reg, GFG_CTRL6_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_CTRL7); + + if (p_reg) { + p->mpa_fld_ctrl_enable[7] = nthw_register_query_field(p_reg, GFG_CTRL7_ENABLE); + p->mpa_fld_ctrl_mode[7] = nthw_register_query_field(p_reg, GFG_CTRL7_MODE); + p->mpa_fld_ctrl_prbs_en[7] = nthw_register_query_field(p_reg, GFG_CTRL7_PRBS_EN); + p->mpa_fld_ctrl_size[7] = nthw_register_query_field(p_reg, GFG_CTRL7_SIZE); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN0); + + if (p_reg) + p->mpa_fld_run_run[0] = nthw_register_query_field(p_reg, GFG_RUN0_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN1); + + if (p_reg) + p->mpa_fld_run_run[1] = nthw_register_query_field(p_reg, GFG_RUN1_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN2); + + if (p_reg) + p->mpa_fld_run_run[2] = nthw_register_query_field(p_reg, GFG_RUN2_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN3); + + if (p_reg) + p->mpa_fld_run_run[3] = nthw_register_query_field(p_reg, GFG_RUN3_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN4); + + if (p_reg) + p->mpa_fld_run_run[4] = nthw_register_query_field(p_reg, GFG_RUN4_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN5); + + if (p_reg) + p->mpa_fld_run_run[5] = nthw_register_query_field(p_reg, GFG_RUN5_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN6); + + if (p_reg) + p->mpa_fld_run_run[6] = nthw_register_query_field(p_reg, GFG_RUN6_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_RUN7); + + if (p_reg) + p->mpa_fld_run_run[7] = nthw_register_query_field(p_reg, GFG_RUN7_RUN); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID0); + + if (p_reg) + p->mpa_fld_stream_id_val[0] = nthw_register_query_field(p_reg, GFG_STREAMID0_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID1); + + if (p_reg) + p->mpa_fld_stream_id_val[1] = nthw_register_query_field(p_reg, GFG_STREAMID1_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID2); + + if (p_reg) + p->mpa_fld_stream_id_val[2] = nthw_register_query_field(p_reg, GFG_STREAMID2_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID3); + + if (p_reg) + p->mpa_fld_stream_id_val[3] = nthw_register_query_field(p_reg, GFG_STREAMID3_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID4); + + if (p_reg) + p->mpa_fld_stream_id_val[4] = nthw_register_query_field(p_reg, GFG_STREAMID4_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID5); + + if (p_reg) + p->mpa_fld_stream_id_val[5] = nthw_register_query_field(p_reg, GFG_STREAMID5_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID6); + + if (p_reg) + p->mpa_fld_stream_id_val[6] = nthw_register_query_field(p_reg, GFG_STREAMID6_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_STREAMID7); + + if (p_reg) + p->mpa_fld_stream_id_val[7] = nthw_register_query_field(p_reg, GFG_STREAMID7_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK0); + + if (p_reg) + p->mpa_fld_size_mask[0] = nthw_register_query_field(p_reg, GFG_SIZEMASK0_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK1); + + if (p_reg) + p->mpa_fld_size_mask[1] = nthw_register_query_field(p_reg, GFG_SIZEMASK1_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK2); + + if (p_reg) + p->mpa_fld_size_mask[2] = nthw_register_query_field(p_reg, GFG_SIZEMASK2_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK3); + + if (p_reg) + p->mpa_fld_size_mask[3] = nthw_register_query_field(p_reg, GFG_SIZEMASK3_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK4); + + if (p_reg) + p->mpa_fld_size_mask[4] = nthw_register_query_field(p_reg, GFG_SIZEMASK4_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK5); + + if (p_reg) + p->mpa_fld_size_mask[5] = nthw_register_query_field(p_reg, GFG_SIZEMASK5_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK6); + + if (p_reg) + p->mpa_fld_size_mask[6] = nthw_register_query_field(p_reg, GFG_SIZEMASK6_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_SIZEMASK7); + + if (p_reg) + p->mpa_fld_size_mask[7] = nthw_register_query_field(p_reg, GFG_SIZEMASK7_VAL); + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE0); + + if (p_reg) { + p->mpa_fld_burst_size_val[0] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE0_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE1); + + if (p_reg) { + p->mpa_fld_burst_size_val[1] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE1_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE2); + + if (p_reg) { + p->mpa_fld_burst_size_val[2] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE2_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE3); + + if (p_reg) { + p->mpa_fld_burst_size_val[3] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE3_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE4); + + if (p_reg) { + p->mpa_fld_burst_size_val[4] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE4_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE5); + + if (p_reg) { + p->mpa_fld_burst_size_val[5] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE5_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE6); + + if (p_reg) { + p->mpa_fld_burst_size_val[6] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE6_VAL); + } + + p_reg = nthw_module_query_register(p->mp_mod_gfg, GFG_BURSTSIZE7); + + if (p_reg) { + p->mpa_fld_burst_size_val[7] = + nthw_register_query_field(p_reg, GFG_BURSTSIZE7_VAL); + } + + return 0; +} + +int nthw_gfg_setup(nthw_gfg_t *p, + const size_t n_intf_no, + const int n_enable, + const int n_frame_count, + const int n_frame_size, + const int n_frame_fill_mode, + const int n_frame_stream_id) +{ + if ((size_t)n_intf_no >= ARRAY_SIZE(p->mpa_fld_ctrl_enable) || + n_intf_no >= ARRAY_SIZE(p->mpa_fld_ctrl_mode) || + (size_t)n_intf_no >= ARRAY_SIZE(p->mpa_fld_ctrl_size) || + n_intf_no >= ARRAY_SIZE(p->mpa_fld_stream_id_val) || + (size_t)n_intf_no >= ARRAY_SIZE(p->mpa_fld_burst_size_val)) { + assert(false); + return -1; + } + + if (p->mpa_fld_ctrl_enable[n_intf_no] == NULL || p->mpa_fld_ctrl_mode[n_intf_no] == NULL || + p->mpa_fld_ctrl_size[n_intf_no] == NULL || + p->mpa_fld_stream_id_val[n_intf_no] == NULL || + p->mpa_fld_burst_size_val[n_intf_no] == NULL) { + assert(false); + return -1; + } + + nthw_field_set_val_flush32(p->mpa_fld_stream_id_val[n_intf_no], n_frame_stream_id); + nthw_field_set_val_flush32(p->mpa_fld_burst_size_val[n_intf_no], n_frame_count); + + if (p->mpa_fld_size_mask[n_intf_no]) + nthw_field_set_val_flush32(p->mpa_fld_size_mask[n_intf_no], 0); + + nthw_field_set_val32(p->mpa_fld_ctrl_mode[n_intf_no], n_frame_fill_mode); + nthw_field_set_val32(p->mpa_fld_ctrl_size[n_intf_no], n_frame_size); + + if (p->mpa_fld_ctrl_prbs_en[n_intf_no]) + nthw_field_set_val32(p->mpa_fld_ctrl_prbs_en[n_intf_no], 0); + + nthw_field_set_val_flush32(p->mpa_fld_ctrl_enable[n_intf_no], + n_enable); /* write enable and flush */ + + return 0; +} + +int nthw_gfg_start(nthw_gfg_t *p, + const int n_intf_no, + const int n_frame_count, + const int n_frame_size, + const int n_frame_fill_mode, + const int n_frame_stream_id) +{ + return nthw_gfg_setup(p, + n_intf_no, + 1, + n_frame_count, + n_frame_size, + n_frame_fill_mode, + n_frame_stream_id); +} + +int nthw_gfg_stop(nthw_gfg_t *p, const int n_intf_no) +{ + return nthw_gfg_setup(p, n_intf_no, 0, 1, 0x666, 0, n_intf_no); +} diff --git a/drivers/net/ntnic/nthw/core/nthw_gmf.c b/drivers/net/ntnic/nthw/core/nthw_gmf.c new file mode 100644 index 0000000000..3a54138578 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/nthw_gmf.c @@ -0,0 +1,176 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include +#include +#include "ntlog.h" + +#include "nthw_drv.h" +#include "nthw_register.h" + +#include "nthw_gmf.h" + +int nthw_gmf_init(nthw_gmf_t *p, nthw_fpga_t *p_fpga, int n_instance) +{ + nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_GMF, n_instance); + + if (p == NULL) + return mod == NULL ? -1 : 0; + + if (mod == NULL) { + NT_LOG(ERR, NTHW, "%s: GMF %d: no such instance\n", + p_fpga->p_fpga_info->mp_adapter_id_str, n_instance); + return -1; + } + + p->mp_fpga = p_fpga; + p->mn_instance = n_instance; + p->mp_mod_gmf = mod; + + p->mp_ctrl = nthw_module_get_register(p->mp_mod_gmf, GMF_CTRL); + p->mp_ctrl_enable = nthw_register_get_field(p->mp_ctrl, GMF_CTRL_ENABLE); + p->mp_ctrl_ifg_enable = nthw_register_get_field(p->mp_ctrl, GMF_CTRL_IFG_ENABLE); + p->mp_ctrl_ifg_auto_adjust_enable = + nthw_register_get_field(p->mp_ctrl, GMF_CTRL_IFG_AUTO_ADJUST_ENABLE); + p->mp_ctrl_ts_inject_always = + nthw_register_query_field(p->mp_ctrl, GMF_CTRL_TS_INJECT_ALWAYS); + p->mp_ctrl_fcs_always = nthw_register_query_field(p->mp_ctrl, GMF_CTRL_FCS_ALWAYS); + + p->mp_speed = nthw_module_get_register(p->mp_mod_gmf, GMF_SPEED); + p->mp_speed_ifg_speed = nthw_register_get_field(p->mp_speed, GMF_SPEED_IFG_SPEED); + + p->mp_ifg_clock_delta = nthw_module_get_register(p->mp_mod_gmf, GMF_IFG_SET_CLOCK_DELTA); + p->mp_ifg_clock_delta_delta = + nthw_register_get_field(p->mp_ifg_clock_delta, GMF_IFG_SET_CLOCK_DELTA_DELTA); + + p->mp_ifg_max_adjust_slack = + nthw_module_get_register(p->mp_mod_gmf, GMF_IFG_MAX_ADJUST_SLACK); + p->mp_ifg_max_adjust_slack_slack = nthw_register_get_field(p->mp_ifg_max_adjust_slack, + GMF_IFG_MAX_ADJUST_SLACK_SLACK); + + p->mp_debug_lane_marker = nthw_module_get_register(p->mp_mod_gmf, GMF_DEBUG_LANE_MARKER); + p->mp_debug_lane_marker_compensation = + nthw_register_get_field(p->mp_debug_lane_marker, + GMF_DEBUG_LANE_MARKER_COMPENSATION); + + p->mp_stat_sticky = nthw_module_get_register(p->mp_mod_gmf, GMF_STAT_STICKY); + p->mp_stat_sticky_data_underflowed = + nthw_register_get_field(p->mp_stat_sticky, GMF_STAT_STICKY_DATA_UNDERFLOWED); + p->mp_stat_sticky_ifg_adjusted = + nthw_register_get_field(p->mp_stat_sticky, GMF_STAT_STICKY_IFG_ADJUSTED); + + p->mn_param_gmf_ifg_speed_mul = + nthw_fpga_get_product_param(p_fpga, NT_GMF_IFG_SPEED_MUL, 1); + p->mn_param_gmf_ifg_speed_div = + nthw_fpga_get_product_param(p_fpga, NT_GMF_IFG_SPEED_DIV, 1); + + p->m_administrative_block = false; + + p->mp_stat_next_pkt = nthw_module_query_register(p->mp_mod_gmf, GMF_STAT_NEXT_PKT); + + if (p->mp_stat_next_pkt) { + p->mp_stat_next_pkt_ns = + nthw_register_query_field(p->mp_stat_next_pkt, GMF_STAT_NEXT_PKT_NS); + + } else { + p->mp_stat_next_pkt_ns = NULL; + } + + p->mp_stat_max_delayed_pkt = + nthw_module_query_register(p->mp_mod_gmf, GMF_STAT_MAX_DELAYED_PKT); + + if (p->mp_stat_max_delayed_pkt) { + p->mp_stat_max_delayed_pkt_ns = + nthw_register_query_field(p->mp_stat_max_delayed_pkt, + GMF_STAT_MAX_DELAYED_PKT_NS); + + } else { + p->mp_stat_max_delayed_pkt_ns = NULL; + } + + p->mp_ctrl_ifg_tx_now_always = + nthw_register_query_field(p->mp_ctrl, GMF_CTRL_IFG_TX_NOW_ALWAYS); + p->mp_ctrl_ifg_tx_on_ts_always = + nthw_register_query_field(p->mp_ctrl, GMF_CTRL_IFG_TX_ON_TS_ALWAYS); + + p->mp_ctrl_ifg_tx_on_ts_adjust_on_set_clock = + nthw_register_query_field(p->mp_ctrl, GMF_CTRL_IFG_TX_ON_TS_ADJUST_ON_SET_CLOCK); + + p->mp_ifg_clock_delta_adjust = + nthw_module_query_register(p->mp_mod_gmf, GMF_IFG_SET_CLOCK_DELTA_ADJUST); + + if (p->mp_ifg_clock_delta_adjust) { + p->mp_ifg_clock_delta_adjust_delta = + nthw_register_query_field(p->mp_ifg_clock_delta_adjust, + GMF_IFG_SET_CLOCK_DELTA_ADJUST_DELTA); + + } else { + p->mp_ifg_clock_delta_adjust_delta = NULL; + } + + p->mp_ts_inject = nthw_module_query_register(p->mp_mod_gmf, GMF_TS_INJECT); + + if (p->mp_ts_inject) { + p->mp_ts_inject_offset = + nthw_register_query_field(p->mp_ts_inject, GMF_TS_INJECT_OFFSET); + p->mp_ts_inject_pos = + nthw_register_query_field(p->mp_ts_inject, GMF_TS_INJECT_POS); + + } else { + p->mp_ts_inject_offset = NULL; + p->mp_ts_inject_pos = NULL; + } + + return 0; +} + +void nthw_gmf_set_enable(nthw_gmf_t *p, bool enable) +{ + if (!p->m_administrative_block) + nthw_field_set_val_flush32(p->mp_ctrl_enable, enable ? 1 : 0); +} + +int nthw_gmf_set_ifg_speed_raw(nthw_gmf_t *p, uint64_t n_speed_val) +{ + if (n_speed_val <= (1ULL << (nthw_field_get_bit_width(p->mp_speed_ifg_speed) - 1))) { + nthw_field_set_val(p->mp_speed_ifg_speed, (uint32_t *)&n_speed_val, + (nthw_field_get_bit_width(p->mp_speed_ifg_speed) <= 32 ? 1 + : 2)); + nthw_field_flush_register(p->mp_speed_ifg_speed); + return 0; + } + + return -1; +} + +int nthw_gmf_get_ifg_speed_bit_width(nthw_gmf_t *p) +{ + const int n_bit_width = nthw_field_get_bit_width(p->mp_speed_ifg_speed); + /* Sanity check: GMF ver 1.2 is bw 22 - GMF ver 1.3 is bw 64 */ + assert(n_bit_width >= 22); + return n_bit_width; +} + +int nthw_gmf_set_ifg_speed_percent(nthw_gmf_t *p, const double f_rate_limit_percent) +{ + uint64_t n_speed_val; + + if (f_rate_limit_percent == 0.0 || f_rate_limit_percent == 100.0) { + n_speed_val = 0; + + } else if (f_rate_limit_percent <= 99) { + const int n_bit_width = (nthw_gmf_get_ifg_speed_bit_width(p) / 2); + const double f_adj_rate = + ((double)(f_rate_limit_percent * (double)p->mn_param_gmf_ifg_speed_mul) / + p->mn_param_gmf_ifg_speed_div / 100); + const double f_speed = ((1UL / f_adj_rate) - 1) * exp2(n_bit_width); + n_speed_val = (uint64_t)f_speed; + + } else { + return -1; + } + + return nthw_gmf_set_ifg_speed_raw(p, n_speed_val); +} diff --git a/drivers/net/ntnic/nthw/core/nthw_i2cm.c b/drivers/net/ntnic/nthw/core/nthw_i2cm.c new file mode 100644 index 0000000000..f76fab5783 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/nthw_i2cm.c @@ -0,0 +1,197 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "nt_util.h" +#include "ntlog.h" + +#include "nthw_drv.h" +#include "nthw_register.h" + +#include "nthw_i2cm.h" + +#define NT_I2C_CMD_START 0x80 +#define NT_I2C_CMD_STOP 0x40 +#define NT_I2C_CMD_RD 0x20 +#define NT_I2C_CMD_WR 0x10 +#define NT_I2C_CMD_NACK 0x08 +#define NT_I2C_CMD_IRQ_ACK 0x01 + +#define NT_I2C_STATUS_NACK 0x80 +#define NT_I2C_STATUS_BUSY 0x40 +#define NT_I2C_STATUS_AL 0x20 +#define NT_I2C_STATUS_TIP 0x02 +#define NT_I2C_STATUS_IRQ 0x01 + +#define NT_I2C_TRANSMIT_WR 0x00 +#define NT_I2C_TRANSMIT_RD 0x01 + +#define NUM_RETRIES 50U +#define SLEEP_USECS 100U/* 0.1 ms */ + +#define I2C_TRANSMIT_WR (0x00) +#define I2C_TRANSMIT_RD (0x01) + +static bool nthw_i2cm_ready(nthw_i2cm_t *p, bool wait_for_ack) +{ + uint32_t flags = NT_I2C_STATUS_TIP | (wait_for_ack ? NT_I2C_STATUS_NACK : 0U); + + for (uint32_t i = 0U; i < NUM_RETRIES; i++) { + uint32_t status = nthw_field_get_updated(p->mp_fld_cmd_status_cmd_status); + uint32_t ready = (status & flags) == 0U; + /* MUST have a short break to avoid time-outs, even if ready == true */ + nt_os_wait_usec(SLEEP_USECS); + + if (ready) + return true; + } + + return false; +} + +static int nthw_i2cm_write_internal(nthw_i2cm_t *p, uint8_t value) +{ + /* Write data to data register */ + nthw_field_set_val_flush32(p->mp_fld_data_data, value); + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK); + + if (!nthw_i2cm_ready(p, true)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out writing data %u", __PRETTY_FUNCTION__, value); + return 1; + } + + /* Generate stop condition and clear interrupt */ + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + + if (!nthw_i2cm_ready(p, true)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out sending stop condition", __PRETTY_FUNCTION__); + return 1; + } + + return 0; +} + +static int nthw_i2cm_write_reg_addr_internal(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, + bool send_stop) +{ + /* Write device address to data register */ + nthw_field_set_val_flush32(p->mp_fld_data_data, + (uint8_t)(dev_addr << 1 | NT_I2C_TRANSMIT_WR)); + + /* #Set start condition along with secondary I2C dev_addr */ + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_START | NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK); + + if (!nthw_i2cm_ready(p, true)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out writing device address %u, reg_addr=%u", + __PRETTY_FUNCTION__, dev_addr, reg_addr); + return 1; + } + + /* Writing I2C register address */ + nthw_field_set_val_flush32(p->mp_fld_data_data, reg_addr); + + if (send_stop) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK | NT_I2C_CMD_STOP); + + } else { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK); + } + + if (!nthw_i2cm_ready(p, true)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out writing register address %u", __PRETTY_FUNCTION__, + reg_addr); + return 1; + } + + return 0; +} + +static int nthw_i2cm_read_internal(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t *value) +{ + /* Write I2C device address - with LSBit set to READ */ + + nthw_field_set_val_flush32(p->mp_fld_data_data, + (uint8_t)(dev_addr << 1 | NT_I2C_TRANSMIT_RD)); + /* #Send START condition along with secondary I2C dev_addr */ + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_START | NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK); + + if (!nthw_i2cm_ready(p, true)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out rewriting device address %u", __PRETTY_FUNCTION__, + dev_addr); + return 1; + } + + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_RD | NT_I2C_CMD_NACK | NT_I2C_CMD_IRQ_ACK); + + if (!nthw_i2cm_ready(p, false)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out during read operation", __PRETTY_FUNCTION__); + return 1; + } + + *value = (uint8_t)nthw_field_get_updated(p->mp_fld_data_data); + + /* Generate stop condition and clear interrupt */ + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + + if (!nthw_i2cm_ready(p, false)) { + nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, + NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK); + NT_LOG(ERR, NTHW, "%s: Time-out sending stop condition", __PRETTY_FUNCTION__); + return 1; + } + + return 0; +} + +int nthw_i2cm_read(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t *value) +{ + int status; + status = nthw_i2cm_write_reg_addr_internal(p, dev_addr, reg_addr, false); + + if (status != 0) + return status; + + status = nthw_i2cm_read_internal(p, dev_addr, value); + + if (status != 0) + return status; + + return 0; +} + +int nthw_i2cm_write(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t value) +{ + int status; + status = nthw_i2cm_write_reg_addr_internal(p, dev_addr, reg_addr, false); + + if (status != 0) + return status; + + status = nthw_i2cm_write_internal(p, value); + + if (status != 0) + return status; + + return 0; +} diff --git a/drivers/net/ntnic/nthw/core/nthw_pci_rd_tg.c b/drivers/net/ntnic/nthw/core/nthw_pci_rd_tg.c new file mode 100644 index 0000000000..5648a09853 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/nthw_pci_rd_tg.c @@ -0,0 +1,115 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "ntlog.h" + +#include "nthw_drv.h" +#include "nthw_register.h" + +#include "nthw_pci_rd_tg.h" + +nthw_pci_rd_tg_t *nthw_pci_rd_tg_new(void) +{ + nthw_pci_rd_tg_t *p = malloc(sizeof(nthw_pci_rd_tg_t)); + + if (p) + memset(p, 0, sizeof(nthw_pci_rd_tg_t)); + + return p; +} + +int nthw_pci_rd_tg_init(nthw_pci_rd_tg_t *p, nthw_fpga_t *p_fpga, int n_instance) +{ + nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_PCI_RD_TG, n_instance); + + if (p == NULL) + return mod == NULL ? -1 : 0; + + if (mod == NULL) { + NT_LOG(ERR, NTHW, "%s: PCI_RD_TG %d: no such instance\n", + p_fpga->p_fpga_info->mp_adapter_id_str, n_instance); + return -1; + } + + p->mp_fpga = p_fpga; + p->mn_instance = n_instance; + p->mp_mod_pci_rd_tg = mod; + + p->mn_param_pci_ta_tg_present = + nthw_fpga_get_product_param(p_fpga, NT_PCI_TA_TG_PRESENT, 1); + + p->mp_reg_pci_rd_tg_rd_data0 = + nthw_module_get_register(p->mp_mod_pci_rd_tg, PCI_RD_TG_TG_RDDATA0); + p->mp_fld_pci_rd_tg_phys_addr_low = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_data0, + PCI_RD_TG_TG_RDDATA0_PHYS_ADDR_LOW); + + p->mp_reg_pci_rd_tg_rd_data1 = + nthw_module_get_register(p->mp_mod_pci_rd_tg, PCI_RD_TG_TG_RDDATA1); + p->mp_fld_pci_rd_tg_phys_addr_high = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_data1, + PCI_RD_TG_TG_RDDATA1_PHYS_ADDR_HIGH); + + p->mp_reg_pci_rd_tg_rd_data2 = + nthw_module_get_register(p->mp_mod_pci_rd_tg, PCI_RD_TG_TG_RDDATA2); + p->mp_fld_pci_rd_tg_req_size = nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_data2, + PCI_RD_TG_TG_RDDATA2_REQ_SIZE); + p->mp_fld_pci_rd_tg_wait = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_data2, PCI_RD_TG_TG_RDDATA2_WAIT); + p->mp_fld_pci_rd_tg_wrap = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_data2, PCI_RD_TG_TG_RDDATA2_WRAP); + /* optional VF host id */ + p->mp_fld_pci_rd_tg_req_hid = nthw_register_query_field(p->mp_reg_pci_rd_tg_rd_data2, + PCI_RD_TG_TG_RDDATA2_REQ_HID); + + p->mp_reg_pci_rd_tg_rd_addr = + nthw_module_get_register(p->mp_mod_pci_rd_tg, PCI_RD_TG_TG_RDADDR); + p->mp_fld_pci_rd_tg_ram_addr = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_addr, PCI_RD_TG_TG_RDADDR_RAM_ADDR); + + p->mp_reg_pci_rd_tg_rd_run = + nthw_module_get_register(p->mp_mod_pci_rd_tg, PCI_RD_TG_TG_RD_RUN); + p->mp_fld_pci_rd_tg_run_iteration = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_run, + PCI_RD_TG_TG_RD_RUN_RD_ITERATION); + + p->mp_reg_pci_rd_tg_rd_ctrl = + nthw_module_get_register(p->mp_mod_pci_rd_tg, PCI_RD_TG_TG_CTRL); + p->mp_fld_pci_rd_tg_ctrl_rdy = + nthw_register_get_field(p->mp_reg_pci_rd_tg_rd_ctrl, PCI_RD_TG_TG_CTRL_TG_RD_RDY); + + return 0; +} + +void nthw_pci_rd_tg_set_phys_addr(nthw_pci_rd_tg_t *p, uint64_t n_phys_addr) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_rd_tg_phys_addr_low, + (uint32_t)(n_phys_addr & ((1UL << 32) - 1))); + nthw_field_set_val_flush32(p->mp_fld_pci_rd_tg_phys_addr_high, + (uint32_t)((n_phys_addr >> 32) & ((1UL << 32) - 1))); +} + +void nthw_pci_rd_tg_set_ram_addr(nthw_pci_rd_tg_t *p, int n_ram_addr) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_rd_tg_ram_addr, n_ram_addr); +} + +void nthw_pci_rd_tg_set_ram_data(nthw_pci_rd_tg_t *p, uint32_t req_size, bool wait, bool wrap) +{ + nthw_field_set_val32(p->mp_fld_pci_rd_tg_req_size, req_size); + nthw_field_set_val32(p->mp_fld_pci_rd_tg_wait, wait); + nthw_field_set_val32(p->mp_fld_pci_rd_tg_wrap, wrap); + nthw_field_flush_register(p->mp_fld_pci_rd_tg_wrap); +} + +void nthw_pci_rd_tg_set_run(nthw_pci_rd_tg_t *p, int n_iterations) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_rd_tg_run_iteration, n_iterations); +} + +uint32_t nthw_pci_rd_tg_get_ctrl_rdy(nthw_pci_rd_tg_t *p) +{ + return nthw_field_get_updated(p->mp_fld_pci_rd_tg_ctrl_rdy); +} diff --git a/drivers/net/ntnic/nthw/core/nthw_pci_ta.c b/drivers/net/ntnic/nthw/core/nthw_pci_ta.c new file mode 100644 index 0000000000..e23d9b7c7b --- /dev/null +++ b/drivers/net/ntnic/nthw/core/nthw_pci_ta.c @@ -0,0 +1,94 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "ntlog.h" + +#include "nthw_drv.h" +#include "nthw_register.h" + +#include "nthw_pci_ta.h" + +nthw_pci_ta_t *nthw_pci_ta_new(void) +{ + nthw_pci_ta_t *p = malloc(sizeof(nthw_pci_ta_t)); + + if (p) + memset(p, 0, sizeof(nthw_pci_ta_t)); + + return p; +} + +int nthw_pci_ta_init(nthw_pci_ta_t *p, nthw_fpga_t *p_fpga, int n_instance) +{ + nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_PCI_TA, n_instance); + + if (p == NULL) + return mod == NULL ? -1 : 0; + + if (mod == NULL) { + NT_LOG(ERR, NTHW, "%s: PCI_TA %d: no such instance\n", + p_fpga->p_fpga_info->mp_adapter_id_str, n_instance); + return -1; + } + + p->mp_fpga = p_fpga; + p->mn_instance = n_instance; + p->mp_mod_pci_ta = mod; + + p->mn_param_pci_ta_tg_present = + nthw_fpga_get_product_param(p_fpga, NT_PCI_TA_TG_PRESENT, 1); + + p->mp_reg_pci_ta_ctrl = nthw_module_get_register(p->mp_mod_pci_ta, PCI_TA_CONTROL); + p->mp_fld_pci_ta_ctrl_enable = + nthw_register_get_field(p->mp_reg_pci_ta_ctrl, PCI_TA_CONTROL_ENABLE); + + p->mp_reg_pci_ta_packet_good = + nthw_module_get_register(p->mp_mod_pci_ta, PCI_TA_PACKET_GOOD); + p->mp_fld_pci_ta_packet_good_amount = + nthw_register_get_field(p->mp_reg_pci_ta_packet_good, PCI_TA_PACKET_GOOD_AMOUNT); + + p->mp_reg_pci_ta_packet_bad = + nthw_module_get_register(p->mp_mod_pci_ta, PCI_TA_PACKET_BAD); + p->mp_fld_pci_ta_packet_bad_amount = + nthw_register_get_field(p->mp_reg_pci_ta_packet_bad, PCI_TA_PACKET_BAD_AMOUNT); + + p->mp_reg_pci_ta_length_error = + nthw_module_get_register(p->mp_mod_pci_ta, PCI_TA_LENGTH_ERROR); + p->mp_fld_pci_ta_length_error_amount = + nthw_register_get_field(p->mp_reg_pci_ta_length_error, PCI_TA_LENGTH_ERROR_AMOUNT); + + p->mp_reg_pci_ta_payload_error = + nthw_module_get_register(p->mp_mod_pci_ta, PCI_TA_PAYLOAD_ERROR); + p->mp_fld_pci_ta_payload_error_amount = + nthw_register_get_field(p->mp_reg_pci_ta_payload_error, + PCI_TA_PAYLOAD_ERROR_AMOUNT); + + return 0; +} + +void nthw_pci_ta_set_control_enable(nthw_pci_ta_t *p, uint32_t val) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_ta_ctrl_enable, val); +} + +void nthw_pci_ta_get_packet_good(nthw_pci_ta_t *p, uint32_t *val) +{ + *val = nthw_field_get_updated(p->mp_fld_pci_ta_packet_good_amount); +} + +void nthw_pci_ta_get_packet_bad(nthw_pci_ta_t *p, uint32_t *val) +{ + *val = nthw_field_get_updated(p->mp_fld_pci_ta_packet_bad_amount); +} + +void nthw_pci_ta_get_length_error(nthw_pci_ta_t *p, uint32_t *val) +{ + *val = nthw_field_get_updated(p->mp_fld_pci_ta_length_error_amount); +} + +void nthw_pci_ta_get_payload_error(nthw_pci_ta_t *p, uint32_t *val) +{ + *val = nthw_field_get_updated(p->mp_fld_pci_ta_payload_error_amount); +} diff --git a/drivers/net/ntnic/nthw/core/nthw_pci_wr_tg.c b/drivers/net/ntnic/nthw/core/nthw_pci_wr_tg.c new file mode 100644 index 0000000000..dfcfe7b1d2 --- /dev/null +++ b/drivers/net/ntnic/nthw/core/nthw_pci_wr_tg.c @@ -0,0 +1,122 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#include "ntlog.h" + +#include "nthw_drv.h" +#include "nthw_register.h" + +#include "nthw_pci_wr_tg.h" + +nthw_pci_wr_tg_t *nthw_pci_wr_tg_new(void) +{ + nthw_pci_wr_tg_t *p = malloc(sizeof(nthw_pci_wr_tg_t)); + + if (p) + memset(p, 0, sizeof(nthw_pci_wr_tg_t)); + + return p; +} + +int nthw_pci_wr_tg_init(nthw_pci_wr_tg_t *p, nthw_fpga_t *p_fpga, int n_instance) +{ + nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_PCI_WR_TG, n_instance); + + if (p == NULL) + return mod == NULL ? -1 : 0; + + if (mod == NULL) { + NT_LOG(ERR, NTHW, "%s: PCI_WR_TG %d: no such instance\n", + p_fpga->p_fpga_info->mp_adapter_id_str, n_instance); + return -1; + } + + p->mp_fpga = p_fpga; + p->mn_instance = n_instance; + p->mp_mod_pci_wr_tg = mod; + + p->mn_param_pci_ta_tg_present = + nthw_fpga_get_product_param(p_fpga, NT_PCI_TA_TG_PRESENT, 1); + + p->mp_reg_pci_wr_tg_data0 = + nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_WRDATA0); + p->mp_fld_pci_wr_tg_phys_addr_low = + nthw_register_get_field(p->mp_reg_pci_wr_tg_data0, + PCI_WR_TG_TG_WRDATA0_PHYS_ADDR_LOW); + + p->mp_reg_pci_wr_tg_data1 = + nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_WRDATA1); + p->mp_fld_pci_wr_tg_phys_addr_high = + nthw_register_get_field(p->mp_reg_pci_wr_tg_data1, + PCI_WR_TG_TG_WRDATA1_PHYS_ADDR_HIGH); + + p->mp_reg_pci_wr_tg_data2 = + nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_WRDATA2); + p->mp_fld_pci_wr_tg_req_size = + nthw_register_get_field(p->mp_reg_pci_wr_tg_data2, PCI_WR_TG_TG_WRDATA2_REQ_SIZE); + p->mp_fld_pci_wr_tg_inc_mode = + nthw_register_get_field(p->mp_reg_pci_wr_tg_data2, PCI_WR_TG_TG_WRDATA2_INC_MODE); + p->mp_fld_pci_wr_tg_wait = + nthw_register_get_field(p->mp_reg_pci_wr_tg_data2, PCI_WR_TG_TG_WRDATA2_WAIT); + p->mp_fld_pci_wr_tg_wrap = + nthw_register_get_field(p->mp_reg_pci_wr_tg_data2, PCI_WR_TG_TG_WRDATA2_WRAP); + /* optional VF host id */ + p->mp_fld_pci_wr_tg_req_hid = + nthw_register_query_field(p->mp_reg_pci_wr_tg_data2, PCI_WR_TG_TG_WRDATA2_REQ_HID); + + p->mp_reg_pci_wr_tg_addr = + nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_WRADDR); + p->mp_fld_pci_wr_tg_ram_addr = + nthw_register_get_field(p->mp_reg_pci_wr_tg_addr, PCI_WR_TG_TG_WRADDR_RAM_ADDR); + + p->mp_reg_pci_wr_tg_run = + nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_WR_RUN); + p->mp_fld_pci_wr_tg_run_iteration = + nthw_register_get_field(p->mp_reg_pci_wr_tg_run, PCI_WR_TG_TG_WR_RUN_WR_ITERATION); + + p->mp_reg_pci_wr_tg_ctrl = + nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_CTRL); + p->mp_fld_pci_wr_tg_ctrl_rdy = + nthw_register_get_field(p->mp_reg_pci_wr_tg_ctrl, PCI_WR_TG_TG_CTRL_TG_WR_RDY); + + p->mp_reg_pci_wr_tg_seq = nthw_module_get_register(p->mp_mod_pci_wr_tg, PCI_WR_TG_TG_SEQ); + p->mp_fld_pci_wr_tg_seq_sequence = + nthw_register_get_field(p->mp_reg_pci_wr_tg_seq, PCI_WR_TG_TG_SEQ_SEQUENCE); + + return 0; +} + +void nthw_pci_wr_tg_set_phys_addr(nthw_pci_wr_tg_t *p, uint64_t n_phys_addr) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_wr_tg_phys_addr_low, + (uint32_t)(n_phys_addr & ((1UL << 32) - 1))); + nthw_field_set_val_flush32(p->mp_fld_pci_wr_tg_phys_addr_high, + (uint32_t)((n_phys_addr >> 32) & ((1UL << 32) - 1))); +} + +void nthw_pci_wr_tg_set_ram_addr(nthw_pci_wr_tg_t *p, int n_ram_addr) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_wr_tg_ram_addr, n_ram_addr); +} + +void nthw_pci_wr_tg_set_ram_data(nthw_pci_wr_tg_t *p, uint32_t req_size, bool wait, bool wrap, + bool inc) +{ + nthw_field_set_val32(p->mp_fld_pci_wr_tg_req_size, req_size); + nthw_field_set_val32(p->mp_fld_pci_wr_tg_wait, wait); + nthw_field_set_val32(p->mp_fld_pci_wr_tg_wrap, wrap); + nthw_field_set_val32(p->mp_fld_pci_wr_tg_inc_mode, inc); + nthw_field_flush_register(p->mp_fld_pci_wr_tg_inc_mode); +} + +void nthw_pci_wr_tg_set_run(nthw_pci_wr_tg_t *p, int n_iterations) +{ + nthw_field_set_val_flush32(p->mp_fld_pci_wr_tg_run_iteration, n_iterations); +} + +uint32_t nthw_pci_wr_tg_get_ctrl_rdy(nthw_pci_wr_tg_t *p) +{ + return nthw_field_get_updated(p->mp_fld_pci_wr_tg_ctrl_rdy); +} -- 2.44.0