From: Serhii Iliushyk <sil-plv@napatech.com>
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 [thread overview]
Message-ID: <20240531154731.1856874-13-sil-plv@napatech.com> (raw)
In-Reply-To: <20240531154731.1856874-1-sil-plv@napatech.com>
Add ntnic HW interfaces (PCIe, I2C) API.
Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
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 <limits.h>
+#include <math.h>
+#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
next prev parent reply other threads:[~2024-05-31 15:49 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-30 14:48 [PATCH v1 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-05-30 14:48 ` [PATCH v1 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 07/17] net/ntnic: add API " Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 13/17] net/ntnic: add adapter initialization Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 07/17] net/ntnic: add API " Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-05-31 15:47 ` Serhii Iliushyk [this message]
2024-05-31 15:47 ` [PATCH v2 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-06-03 16:17 ` [PATCH v3 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-06-03 16:17 ` [PATCH v3 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 07/17] net/ntnic: add API " Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 13/17] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-03 16:18 ` [PATCH v3 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-06-04 10:29 ` [PATCH v3 01/17] net/ntnic: Add registers for NapaTech SmartNiC Mykola Kostenok
2024-06-07 13:03 ` Serhii Iliushyk
2024-06-12 8:50 ` Ferruh Yigit
2024-06-12 8:55 ` Ferruh Yigit
2024-06-26 19:55 ` [PATCH v4 01/23] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 02/23] net/ntnic: add logging implementation Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 03/23] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 04/23] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 05/23] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 06/23] net/ntnic: add NT NIC driver dependencies Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 07/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 08/23] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 09/23] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 10/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 11/23] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 12/23] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 13/23] net/ntnic: add reset module for " Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 14/23] net/ntnic: add clock profiles " Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 15/23] net/ntnic: add MAC and packet features Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 16/23] net/ntnic: add link management module Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 17/23] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 18/23] net/ntnic: add NIM module Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 19/23] net/ntnic: add QSFP support Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 20/23] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 21/23] net/ntnic: add GPIO PHY module Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 22/23] net/ntnic: add MAC PCS register interface module Serhii Iliushyk
2024-06-26 19:55 ` [PATCH v4 23/23] net/ntnic: add GMF (Generic MAC Feeder) module Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 01/23] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 02/23] net/ntnic: add logging implementation Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 03/23] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 04/23] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 05/23] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 06/23] net/ntnic: add NT NIC driver dependencies Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 07/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 08/23] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 09/23] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 10/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 11/23] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 12/23] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 13/23] net/ntnic: add reset module for " Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 14/23] net/ntnic: add clock profiles " Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 15/23] net/ntnic: add MAC and packet features Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 16/23] net/ntnic: add link management module Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 17/23] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-27 7:38 ` [PATCH v5 18/23] net/ntnic: add NIM module Serhii Iliushyk
2024-06-27 7:39 ` [PATCH v5 19/23] net/ntnic: add QSFP support Serhii Iliushyk
2024-06-27 7:39 ` [PATCH v5 20/23] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-06-27 7:39 ` [PATCH v5 21/23] net/ntnic: add GPIO PHY module Serhii Iliushyk
2024-06-27 7:39 ` [PATCH v5 22/23] net/ntnic: add MAC PCS register interface module Serhii Iliushyk
2024-06-27 7:39 ` [PATCH v5 23/23] net/ntnic: add GMF (Generic MAC Feeder) module Serhii Iliushyk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240531154731.1856874-13-sil-plv@napatech.com \
--to=sil-plv@napatech.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=ckm@napatech.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=mko-plv@napatech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).