DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 00/32] add new adapter NT400D13
@ 2025-02-20 22:03 Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 01/32] net/ntnic: add link agx 100g Serhii Iliushyk
                   ` (33 more replies)
  0 siblings, 34 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

This patchset adds support for the new adapter NT400D13.

Danylo Vodopianov (23):
  net/ntnic: add link agx 100g
  net/ntnic: add link state machine
  net/ntnic: add rpf and gfg init
  net/ntnic: add agx setup for port
  net/ntnic: add host loopback init
  net/ntnic: add line loopback init
  net/ntnic: add 100 gbps port init
  net/ntnic: add port post init
  net/ntnic: add nim low power API
  net/ntnic: add link handling API
  net/ntnic: add port init to the state machine
  net/ntnic: add port disable API
  net/ntnic: add nt400d13 pcm init
  net/ntnic: add HIF clock test
  net/ntnic: add nt400d13 PRM module init
  net/ntnic: add nt400d13 PRM module reset
  net/ntnic: add SPI v3 support for FPGA
  net/ntnic: add i2cm init
  net/ntnic: add pca init
  net/ntnic: add pcal init
  net/ntnic: add reset PHY init
  net/ntnic: add igam module init
  net/ntnic: init IGAM and config PLL for FPGA

Serhii Iliushyk (9):
  net/ntnic: add minimal initialization new NIC NT400D13
  net/ntnic: add minimal reset FPGA
  net/ntnic: add FPGA modules and registers
  net/ntnic: add setup for fpga reset
  net/ntnic: add default reset setting for NT400D13
  net/ntnic: add DDR calibration to reset stage
  net/ntnic: add PHY ftile reset
  net/ntnic: add clock init
  net/ntnic: revert untrusted loop bound

 doc/guides/nics/ntnic.rst                     |    7 +-
 doc/guides/rel_notes/release_25_03.rst        |    4 +
 drivers/net/ntnic/adapter/nt4ga_adapter.c     |    9 +
 drivers/net/ntnic/include/nt4ga_link.h        |    7 +
 drivers/net/ntnic/include/nthw_gfg.h          |   33 +
 drivers/net/ntnic/include/ntnic_nim.h         |    5 +
 .../include/ntnic_nthw_fpga_rst_nt400dxx.h    |   34 +
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 1029 ++++++
 drivers/net/ntnic/meson.build                 |   16 +
 drivers/net/ntnic/nim/i2c_nim.c               |  158 +-
 drivers/net/ntnic/nim/i2c_nim.h               |    6 +
 ...00D13_U62_Si5332-GM2-RevD-1_V5-Registers.h |  425 +++
 .../net/ntnic/nthw/core/include/nthw_fpga.h   |   10 +
 .../net/ntnic/nthw/core/include/nthw_gmf.h    |    2 +
 .../net/ntnic/nthw/core/include/nthw_hif.h    |    4 +
 .../net/ntnic/nthw/core/include/nthw_i2cm.h   |    3 +
 .../net/ntnic/nthw/core/include/nthw_igam.h   |   40 +
 .../ntnic/nthw/core/include/nthw_pca9532.h    |   25 +
 .../ntnic/nthw/core/include/nthw_pcal6416a.h  |   33 +
 .../nthw/core/include/nthw_pcm_nt400dxx.h     |   40 +
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |  156 +
 .../nthw/core/include/nthw_prm_nt400dxx.h     |   32 +
 .../nthw/core/include/nthw_si5332_si5156.h    |   63 +
 .../net/ntnic/nthw/core/include/nthw_spi_v3.h |  107 +
 .../net/ntnic/nthw/core/include/nthw_spim.h   |   58 +
 .../net/ntnic/nthw/core/include/nthw_spis.h   |   63 +
 .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   |  220 ++
 .../core/nt400dxx/reset/nthw_fpga_rst9574.c   |  377 ++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |  427 +++
 drivers/net/ntnic/nthw/core/nthw_fpga.c       |  464 +++
 drivers/net/ntnic/nthw/core/nthw_gfg.c        |  340 ++
 drivers/net/ntnic/nthw/core/nthw_gmf.c        |   41 +
 drivers/net/ntnic/nthw/core/nthw_hif.c        |   92 +
 drivers/net/ntnic/nthw/core/nthw_i2cm.c       |  139 +
 drivers/net/ntnic/nthw/core/nthw_igam.c       |   93 +
 drivers/net/ntnic/nthw/core/nthw_pca9532.c    |   60 +
 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c  |  103 +
 .../net/ntnic/nthw/core/nthw_pcm_nt400dxx.c   |   80 +
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   | 1242 +++++++
 .../net/ntnic/nthw/core/nthw_prm_nt400dxx.c   |   55 +
 .../net/ntnic/nthw/core/nthw_si5332_si5156.c  |  142 +
 drivers/net/ntnic/nthw/core/nthw_spi_v3.c     |  358 ++
 drivers/net/ntnic/nthw/core/nthw_spim.c       |  113 +
 drivers/net/ntnic/nthw/core/nthw_spis.c       |  121 +
 drivers/net/ntnic/nthw/nthw_drv.h             |   31 +
 drivers/net/ntnic/nthw/nthw_platform.c        |    3 +
 drivers/net/ntnic/nthw/nthw_platform_drv.h    |    2 +
 .../supported/nthw_fpga_9574_055_049_0000.c   | 3124 +++++++++++++++++
 .../nthw/supported/nthw_fpga_instances.c      |    5 +-
 .../nthw/supported/nthw_fpga_instances.h      |    1 +
 .../ntnic/nthw/supported/nthw_fpga_mod_defs.h |   11 +
 .../nthw/supported/nthw_fpga_mod_str_map.c    |   11 +
 .../ntnic/nthw/supported/nthw_fpga_reg_defs.h |   11 +
 .../nthw/supported/nthw_fpga_reg_defs_igam.h  |   32 +
 .../supported/nthw_fpga_reg_defs_pci_ta.h     |   33 +
 .../nthw_fpga_reg_defs_pcm_nt400dxx.h         |   29 +
 .../nthw/supported/nthw_fpga_reg_defs_pdi.h   |   49 +
 .../supported/nthw_fpga_reg_defs_phy_tile.h   |  213 ++
 .../nthw_fpga_reg_defs_prm_nt400dxx.h         |   26 +
 .../nthw/supported/nthw_fpga_reg_defs_rfd.h   |   38 +
 .../supported/nthw_fpga_reg_defs_rst9574.h    |   35 +
 .../nthw/supported/nthw_fpga_reg_defs_spim.h  |   76 +
 .../nthw/supported/nthw_fpga_reg_defs_spis.h  |   51 +
 .../nthw/supported/nthw_fpga_reg_defs_tint.h  |   28 +
 drivers/net/ntnic/ntnic_ethdev.c              |    1 +
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c |    2 +-
 drivers/net/ntnic/ntnic_mod_reg.c             |   47 +
 drivers/net/ntnic/ntnic_mod_reg.h             |   25 +
 68 files changed, 10709 insertions(+), 11 deletions(-)
 create mode 100644 drivers/net/ntnic/include/nthw_gfg.h
 create mode 100644 drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h
 create mode 100644 drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
 create mode 100644 drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_igam.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spim.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spis.h
 create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
 create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
 create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_gfg.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_igam.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_pca9532.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_phy_tile.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_spi_v3.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_spim.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_spis.c
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h

-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 01/32] net/ntnic: add link agx 100g
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 02/32] net/ntnic: add link state machine Serhii Iliushyk
                   ` (32 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Minimal implementation for link agx 100g was added.
Add support for NT400D13 (Intel Agilex FPGA) link operations.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/adapter/nt4ga_adapter.c     |  9 ++++
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 42 +++++++++++++++++++
 drivers/net/ntnic/meson.build                 |  1 +
 drivers/net/ntnic/ntnic_mod_reg.c             | 17 ++++++++
 drivers/net/ntnic/ntnic_mod_reg.h             |  4 ++
 5 files changed, 73 insertions(+)
 create mode 100644 drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c

diff --git a/drivers/net/ntnic/adapter/nt4ga_adapter.c b/drivers/net/ntnic/adapter/nt4ga_adapter.c
index fa72dfda8d..fe9d397293 100644
--- a/drivers/net/ntnic/adapter/nt4ga_adapter.c
+++ b/drivers/net/ntnic/adapter/nt4ga_adapter.c
@@ -196,6 +196,15 @@ static int nt4ga_adapter_init(struct adapter_info_s *p_adapter_info)
 
 			res = link_ops->link_init(p_adapter_info, p_fpga);
 			break;
+		case 9574: /* NT400D13 (Intel Agilex FPGA) */
+			link_ops = get_agx_100g_link_ops();
+			if (link_ops == NULL) {
+				NT_LOG(ERR, NTNIC, "NT400D11 100G link module uninitialized");
+				res = -1;
+				break;
+			}
+			res = link_ops->link_init(p_adapter_info, p_fpga);
+			break;
 
 		default:
 			NT_LOG(ERR, NTNIC, "Unsupported FPGA product: %04d",
diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
new file mode 100644
index 0000000000..ad3398500f
--- /dev/null
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -0,0 +1,42 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "nt_util.h"
+#include "ntlog.h"
+#include "i2c_nim.h"
+#include "nt4ga_adapter.h"
+
+#include <string.h>
+#include "ntnic_mod_reg.h"
+#include "nim_defines.h"
+
+static int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info,
+	nthw_fpga_t *fpga);
+
+/*
+ * Init AGX 100G link ops variables
+ */
+static struct link_ops_s link_agx_100g_ops = {
+	.link_init = nt4ga_agx_link_100g_ports_init,
+};
+
+void link_agx_100g_init(void)
+{
+	register_agx_100g_link_ops(&link_agx_100g_ops);
+}
+
+/*
+ * Initialize all ports
+ * The driver calls this function during initialization (of the driver).
+ */
+int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nthw_fpga_t *fpga)
+{
+	(void)fpga;
+	int res = 0;
+
+	NT_LOG(DBG, NTNIC, "%s: Initializing ports", p_adapter_info->mp_adapter_id_str);
+
+	return res;
+}
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 8ae6817dea..7e4f47b1e6 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -32,6 +32,7 @@ sources = files(
         'adapter/nt4ga_stat/nt4ga_stat.c',
         'dbsconfig/ntnic_dbsconfig.c',
         'link_mgmt/link_100g/nt4ga_link_100g.c',
+        'link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c',
         'link_mgmt/nt4ga_link.c',
         'nim/i2c_nim.c',
         'ntnic_filter/ntnic_filter.c',
diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
index 658fac72c0..598df08fb7 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.c
+++ b/drivers/net/ntnic/ntnic_mod_reg.c
@@ -69,6 +69,23 @@ const struct link_ops_s *get_100g_link_ops(void)
 	return link_100g_ops;
 }
 
+/*
+ *
+ */
+static struct link_ops_s *link_agx_100g_ops;
+
+void register_agx_100g_link_ops(struct link_ops_s *ops)
+{
+	link_agx_100g_ops = ops;
+}
+
+const struct link_ops_s *get_agx_100g_link_ops(void)
+{
+	if (link_agx_100g_ops == NULL)
+		link_agx_100g_init();
+	return link_agx_100g_ops;
+}
+
 static const struct port_ops *port_ops;
 
 void register_port_ops(const struct port_ops *ops)
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index bddae823c8..3e84beaa62 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -144,6 +144,10 @@ void register_100g_link_ops(struct link_ops_s *ops);
 const struct link_ops_s *get_100g_link_ops(void);
 void link_100g_init(void);
 
+void register_agx_100g_link_ops(struct link_ops_s *ops);
+const struct link_ops_s *get_agx_100g_link_ops(void);
+void link_agx_100g_init(void);
+
 struct port_ops {
 	bool (*get_nim_present)(struct adapter_info_s *p, int port);
 
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 02/32] net/ntnic: add link state machine
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 01/32] net/ntnic: add link agx 100g Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 03/32] net/ntnic: add rpf and gfg init Serhii Iliushyk
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Minimal 100g agx link state machine implementation was added.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/nt4ga_link.h        |   5 +
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 111 ++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/drivers/net/ntnic/include/nt4ga_link.h b/drivers/net/ntnic/include/nt4ga_link.h
index 8366484830..af7ea4a9f2 100644
--- a/drivers/net/ntnic/include/nt4ga_link.h
+++ b/drivers/net/ntnic/include/nt4ga_link.h
@@ -82,9 +82,14 @@ typedef struct adapter_100g_s {
 	nthw_gpio_phy_t gpio_phy[NUM_ADAPTER_PORTS_MAX];
 } adapter_100g_t;
 
+typedef struct adapter_agx_100g_s {
+	nim_i2c_ctx_t nim_ctx[NUM_ADAPTER_PORTS_MAX];	/* should be the first field */
+} adapter_agx_100g_t;
+
 typedef union adapter_var_s {
 	nim_i2c_ctx_t nim_ctx[NUM_ADAPTER_PORTS_MAX];	/* First field in all the adapters type */
 	adapter_100g_t var100g;
+	adapter_agx_100g_t var_a100g;
 } adapter_var_u;
 
 typedef struct nt4ga_link_s {
diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index ad3398500f..369b9b601f 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -27,6 +27,106 @@ void link_agx_100g_init(void)
 	register_agx_100g_link_ops(&link_agx_100g_ops);
 }
 
+/*
+ * Link state machine
+ */
+static void *_common_ptp_nim_state_machine(void *data)
+{
+	adapter_info_t *drv = (adapter_info_t *)data;
+	fpga_info_t *fpga_info = &drv->fpga_info;
+	nt4ga_link_t *link_info = &drv->nt4ga_link;
+	nthw_fpga_t *fpga = fpga_info->mp_fpga;
+	const int adapter_no = drv->adapter_no;
+	const int nb_ports = fpga_info->n_phy_ports;
+	uint32_t last_lpbk_mode[NUM_ADAPTER_PORTS_MAX];
+	/* link_state_t new_link_state; */
+
+	link_state_t *link_state = link_info->link_state;
+
+	if (!fpga) {
+		NT_LOG(ERR, NTNIC, "%s: fpga is NULL", drv->mp_adapter_id_str);
+		goto NT4GA_LINK_100G_MON_EXIT;
+	}
+
+	assert(adapter_no >= 0 && adapter_no < NUM_ADAPTER_MAX);
+
+	monitor_task_is_running[adapter_no] = 1;
+	memset(last_lpbk_mode, 0, sizeof(last_lpbk_mode));
+
+	/* Initialize link state */
+	for (int i = 0; i < nb_ports; i++) {
+		link_state[i].link_disabled = true;
+		link_state[i].nim_present = false;
+		link_state[i].lh_nim_absent = true;
+		link_state[i].link_up = false;
+		link_state[i].link_state = NT_LINK_STATE_UNKNOWN;
+		link_state[i].link_state_latched = NT_LINK_STATE_UNKNOWN;
+	}
+
+	if (monitor_task_is_running[adapter_no])
+		NT_LOG(DBG, NTNIC, "%s: link state machine running...", drv->mp_adapter_id_str);
+
+	while (monitor_task_is_running[adapter_no]) {
+		int i;
+
+		for (i = 0; i < nb_ports; i++) {
+			const bool is_port_disabled = link_info->port_action[i].port_disable;
+			const bool was_port_disabled = link_state[i].link_disabled;
+			const bool disable_port = is_port_disabled && !was_port_disabled;
+			const bool enable_port = !is_port_disabled && was_port_disabled;
+
+			if (!monitor_task_is_running[adapter_no])
+				break;
+
+			/*
+			 * Has the administrative port state changed?
+			 */
+			assert(!(disable_port && enable_port));
+
+			if (enable_port) {
+				link_state[i].link_disabled = false;
+				NT_LOG(DBG, NTNIC, "%s: Port %i is enabled",
+					drv->mp_port_id_str[i], i);
+			}
+
+			if (is_port_disabled)
+				continue;
+
+			link_state[i].link_disabled = is_port_disabled;
+
+			if (!link_state[i].nim_present) {
+				if (!link_state[i].lh_nim_absent) {
+					NT_LOG(INF, NTNIC, "%s: NIM module removed",
+						drv->mp_port_id_str[i]);
+					link_state[i].link_up = false;
+					link_state[i].lh_nim_absent = true;
+
+				} else {
+					NT_LOG(DBG, NTNIC, "%s: No NIM module, skip",
+						drv->mp_port_id_str[i]);
+				}
+
+				continue;
+			}
+		}
+
+		if (monitor_task_is_running[adapter_no])
+			nt_os_wait_usec(5 * 100000U);	/*  5 x 0.1s = 0.5s */
+	}
+
+NT4GA_LINK_100G_MON_EXIT:
+	NT_LOG(DBG, NTNIC, "%s: Stopped NT4GA 100 Gbps link monitoring thread.",
+		drv->mp_adapter_id_str);
+	return NULL;
+}
+
+static uint32_t nt4ga_agx_link_100g_mon(void *data)
+{
+	(void)_common_ptp_nim_state_machine(data);
+
+	return 0;
+}
+
 /*
  * Initialize all ports
  * The driver calls this function during initialization (of the driver).
@@ -34,9 +134,20 @@ void link_agx_100g_init(void)
 int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nthw_fpga_t *fpga)
 {
 	(void)fpga;
+	const int adapter_no = p_adapter_info->adapter_no;
 	int res = 0;
 
 	NT_LOG(DBG, NTNIC, "%s: Initializing ports", p_adapter_info->mp_adapter_id_str);
 
+	/*
+	 * Create state-machine thread
+	 */
+	if (res == 0) {
+		if (!monitor_task_is_running[adapter_no]) {
+			res = rte_thread_create(&monitor_tasks[adapter_no], NULL,
+					nt4ga_agx_link_100g_mon, p_adapter_info);
+		}
+	}
+
 	return res;
 }
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 03/32] net/ntnic: add rpf and gfg init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 01/32] net/ntnic: add link agx 100g Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 02/32] net/ntnic: add link state machine Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 04/32] net/ntnic: add agx setup for port Serhii Iliushyk
                   ` (30 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

RPF and GFG modules initialization were added.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/nt4ga_link.h        |   2 +
 drivers/net/ntnic/include/nthw_gfg.h          |  33 ++
 .../link_agx_100g/nt4ga_agx_link_100g.c       |  24 ++
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nthw/core/nthw_gfg.c        | 340 ++++++++++++++++++
 drivers/net/ntnic/nthw/nthw_drv.h             |  10 +
 6 files changed, 410 insertions(+)
 create mode 100644 drivers/net/ntnic/include/nthw_gfg.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_gfg.c

diff --git a/drivers/net/ntnic/include/nt4ga_link.h b/drivers/net/ntnic/include/nt4ga_link.h
index af7ea4a9f2..e3dc3d4d5d 100644
--- a/drivers/net/ntnic/include/nt4ga_link.h
+++ b/drivers/net/ntnic/include/nt4ga_link.h
@@ -8,6 +8,7 @@
 
 #include "ntos_drv.h"
 #include "ntnic_nim.h"
+#include "nthw_gfg.h"
 
 enum nt_link_state_e {
 	NT_LINK_STATE_UNKNOWN = 0,	/* The link state has not been read yet */
@@ -84,6 +85,7 @@ typedef struct adapter_100g_s {
 
 typedef struct adapter_agx_100g_s {
 	nim_i2c_ctx_t nim_ctx[NUM_ADAPTER_PORTS_MAX];	/* should be the first field */
+	nthw_gfg_t gfg[NUM_ADAPTER_PORTS_MAX];
 } adapter_agx_100g_t;
 
 typedef union adapter_var_s {
diff --git a/drivers/net/ntnic/include/nthw_gfg.h b/drivers/net/ntnic/include/nthw_gfg.h
new file mode 100644
index 0000000000..4583fd9ebd
--- /dev/null
+++ b/drivers/net/ntnic/include/nthw_gfg.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef NTHW_GFG_H_
+#define NTHW_GFG_H_
+
+#include "nthw_fpga_model.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;
+
+int nthw_gfg_init(nthw_gfg_t *p, nthw_fpga_t *p_fpga, int n_instance);
+
+int nthw_gfg_stop(nthw_gfg_t *p, const int n_intf_no);
+
+#endif	/* NTHW_GFG_H_ */
diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 369b9b601f..9db32443fc 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -11,6 +11,7 @@
 #include <string.h>
 #include "ntnic_mod_reg.h"
 #include "nim_defines.h"
+#include "nthw_gfg.h"
 
 static int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info,
 	nthw_fpga_t *fpga);
@@ -134,11 +135,34 @@ static uint32_t nt4ga_agx_link_100g_mon(void *data)
 int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nthw_fpga_t *fpga)
 {
 	(void)fpga;
+	nt4ga_link_t *nt4ga_link = &p_adapter_info->nt4ga_link;
 	const int adapter_no = p_adapter_info->adapter_no;
 	int res = 0;
 
 	NT_LOG(DBG, NTNIC, "%s: Initializing ports", p_adapter_info->mp_adapter_id_str);
 
+	if (!nt4ga_link->variables_initialized) {
+		nthw_gfg_t *gfg_mod = p_adapter_info->nt4ga_link.u.var_a100g.gfg;
+		nthw_agx_t *p_nthw_agx = &p_adapter_info->fpga_info.mp_nthw_agx;
+
+		p_nthw_agx->p_rpf = nthw_rpf_new();
+		res = nthw_rpf_init(p_nthw_agx->p_rpf, fpga, adapter_no);
+
+		if (res != 0) {
+			NT_LOG(ERR, NTNIC, "%s: Failed to initialize RPF module (%u)",
+				p_adapter_info->mp_adapter_id_str, res);
+			return res;
+		}
+
+		res = nthw_gfg_init(&gfg_mod[adapter_no], fpga, 0 /* Only one instance */);
+
+		if (res != 0) {
+			NT_LOG(ERR, NTNIC, "%s: Failed to initialize GFG module (%u)",
+				p_adapter_info->mp_adapter_id_str, res);
+			return res;
+		}
+	}
+
 	/*
 	 * Create state-machine thread
 	 */
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 7e4f47b1e6..68d7fdafd4 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -47,6 +47,7 @@ sources = files(
         'nthw/core/nt200a0x/reset/nthw_fpga_rst_nt200a0x.c',
         'nthw/core/nthw_fpga.c',
         'nthw/core/nthw_gmf.c',
+        'nthw/core/nthw_gfg.c',
         'nthw/core/nthw_tsm.c',
         'nthw/core/nthw_gpio_phy.c',
         'nthw/core/nthw_hif.c',
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..aa71624457
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_gfg.c
@@ -0,0 +1,340 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "ntlog.h"
+
+#include "nthw_drv.h"
+#include "nthw_register.h"
+
+#include "nt_util.h"
+#include "nthw_gfg.h"
+
+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", 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;
+}
+
+static 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_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/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index 69e0360f5f..9dc839c83c 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -9,6 +9,15 @@
 #include "nthw_core.h"
 #include "ntnic_dbs.h"
 
+#include "nthw_rpf.h"
+
+/*
+ * Structs for controlling Agilex based NT400DXX adapter
+ */
+typedef struct nthw_agx_s {
+	nthw_rpf_t *p_rpf;
+} nthw_agx_t;
+
 typedef enum nt_meta_port_type_e {
 	PORT_TYPE_PHYSICAL,
 	PORT_TYPE_VIRTUAL,
@@ -88,6 +97,7 @@ typedef struct fpga_info_s {
 
 	nthw_adapter_id_t n_nthw_adapter_id;
 
+	nthw_agx_t mp_nthw_agx;	/* For the Agilex based NT400DXX */
 } fpga_info_t;
 
 
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 04/32] net/ntnic: add agx setup for port
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (2 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 03/32] net/ntnic: add rpf and gfg init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 05/32] net/ntnic: add host loopback init Serhii Iliushyk
                   ` (29 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Initialize NIM and PHY settings for Agilex FPGA ports

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/ntnic_nim.h         |   5 +
 .../link_agx_100g/nt4ga_agx_link_100g.c       |  86 ++++++++-
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nim/i2c_nim.c               |   8 +
 drivers/net/ntnic/nim/i2c_nim.h               |   3 +
 .../ntnic/nthw/core/include/nthw_pcal6416a.h  |  19 ++
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |  62 +++++++
 .../nthw/core/include/nthw_si5332_si5156.h    |  18 ++
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   | 173 ++++++++++++++++++
 drivers/net/ntnic/nthw/nthw_drv.h             |   8 +
 10 files changed, 382 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_phy_tile.c

diff --git a/drivers/net/ntnic/include/ntnic_nim.h b/drivers/net/ntnic/include/ntnic_nim.h
index 58daa8435f..3e97a9a8b2 100644
--- a/drivers/net/ntnic/include/ntnic_nim.h
+++ b/drivers/net/ntnic/include/ntnic_nim.h
@@ -7,9 +7,12 @@
 #define _NTNIC_NIM_H_
 
 #include <stdint.h>
+#include "nthw_pcal6416a.h"
+#include "nthw_i2cm.h"
 
 typedef enum i2c_type {
 	I2C_HWIIC,
+	I2C_HWAGX
 } i2c_type_e;
 
 enum nt_port_type_e {
@@ -38,7 +41,9 @@ typedef struct nim_i2c_ctx {
 	union {
 		nthw_iic_t hwiic;	/* depends on *Fpga_t, instance number, and cycle time */
 		struct {
+			nthw_pcal6416a_t *p_io_nim;
 			nthw_i2cm_t *p_nt_i2cm;
+			nthw_pca9849_t *p_ca9849;
 			int mux_channel;
 		} hwagx;
 	};
diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 9db32443fc..a6455ee598 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -12,6 +12,7 @@
 #include "ntnic_mod_reg.h"
 #include "nim_defines.h"
 #include "nthw_gfg.h"
+#include "nthw_phy_tile.h"
 
 static int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info,
 	nthw_fpga_t *fpga);
@@ -28,6 +29,58 @@ void link_agx_100g_init(void)
 	register_agx_100g_link_ops(&link_agx_100g_ops);
 }
 
+/*
+ * Utility functions
+ */
+
+static int swap_tx_rx_polarity(adapter_info_t *drv, int port, bool swap)
+{
+	/*
+	 * Mapping according to schematics
+	 * I: Inversion, N: Non-inversion
+	 *
+	 *  Port 0: PMA0/FGT0
+	 *  FPGA QSFP Tx Rx
+	 *  ---------------
+	 *  Q3C0 Ch4  I  I
+	 *  Q3C1 Ch2  I  I
+	 *  Q3C2 Ch1  I  N
+	 *  Q3C3 Ch3  I  I
+	 *
+	 *  Port 1: PMA1/FGT1
+	 *  FPGA QSFP Tx Rx
+	 *  ---------------
+	 *  Q2C0 Ch4  I  I
+	 *  Q2C1 Ch2  I  I
+	 *  Q2C2 Ch1  N  I
+	 *  Q2C3 Ch3  N  N
+	 */
+
+	bool rx_polarity_swap[2][4] = { { false, true, true, true }, { true, false, true, true } };
+	bool tx_polarity_swap[2][4] = { { false, false, true, true }, { true, true, true, true } };
+
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+
+	if (p) {
+		for (uint8_t lane = 0; lane < 4; lane++) {
+			if (swap) {
+				nthw_phy_tile_set_tx_pol_inv(p, port, lane,
+					tx_polarity_swap[port][lane]);
+				nthw_phy_tile_set_rx_pol_inv(p, port, lane,
+					rx_polarity_swap[port][lane]);
+
+			} else {
+				nthw_phy_tile_set_tx_pol_inv(p, port, lane, false);
+				nthw_phy_tile_set_rx_pol_inv(p, port, lane, false);
+			}
+		}
+
+		return 0;
+	}
+
+	return -1;
+}
+
 /*
  * Link state machine
  */
@@ -134,15 +187,18 @@ static uint32_t nt4ga_agx_link_100g_mon(void *data)
  */
 int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nthw_fpga_t *fpga)
 {
-	(void)fpga;
+	fpga_info_t *fpga_info = &p_adapter_info->fpga_info;
 	nt4ga_link_t *nt4ga_link = &p_adapter_info->nt4ga_link;
 	const int adapter_no = p_adapter_info->adapter_no;
+	const int nb_ports = fpga_info->n_phy_ports;
 	int res = 0;
+	int i;
 
 	NT_LOG(DBG, NTNIC, "%s: Initializing ports", p_adapter_info->mp_adapter_id_str);
 
 	if (!nt4ga_link->variables_initialized) {
 		nthw_gfg_t *gfg_mod = p_adapter_info->nt4ga_link.u.var_a100g.gfg;
+		nim_i2c_ctx_t *nim_ctx = p_adapter_info->nt4ga_link.u.var_a100g.nim_ctx;
 		nthw_agx_t *p_nthw_agx = &p_adapter_info->fpga_info.mp_nthw_agx;
 
 		p_nthw_agx->p_rpf = nthw_rpf_new();
@@ -161,6 +217,34 @@ int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nthw_f
 				p_adapter_info->mp_adapter_id_str, res);
 			return res;
 		}
+
+		for (i = 0; i < nb_ports; i++) {
+			/* 2 + adapter port number */
+			const uint8_t instance = (uint8_t)(2U + i);
+			nim_agx_setup(&nim_ctx[i], p_nthw_agx->p_io_nim, p_nthw_agx->p_i2cm,
+				p_nthw_agx->p_pca9849);
+			nim_ctx[i].hwagx.mux_channel = i;
+			nim_ctx[i].instance = instance;	/* not used */
+			nim_ctx[i].devaddr = 0;	/* not used */
+			nim_ctx[i].regaddr = 0;	/* not used */
+			nim_ctx[i].type = I2C_HWAGX;
+
+			nthw_gfg_stop(&gfg_mod[adapter_no], i);
+
+			for (uint8_t lane = 0; lane < 4; lane++) {
+				nthw_phy_tile_set_host_loopback(p_nthw_agx->p_phy_tile, i, lane,
+					false);
+			}
+
+			swap_tx_rx_polarity(p_adapter_info, i, true);
+		}
+
+		nthw_rpf_set_ts_at_eof(p_nthw_agx->p_rpf, true);
+
+		if (res == 0) {
+			p_adapter_info->nt4ga_link.speed_capa = NT_LINK_SPEED_100G;
+			p_adapter_info->nt4ga_link.variables_initialized = true;
+		}
 	}
 
 	/*
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 68d7fdafd4..4799ebfb8e 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -55,6 +55,7 @@ sources = files(
         'nthw/core/nthw_iic.c',
         'nthw/core/nthw_mac_pcs.c',
         'nthw/core/nthw_pcie3.c',
+        'nthw/core/nthw_phy_tile.c',
         'nthw/core/nthw_rpf.c',
         'nthw/core/nthw_rmc.c',
         'nthw/core/nthw_sdc.c',
diff --git a/drivers/net/ntnic/nim/i2c_nim.c b/drivers/net/ntnic/nim/i2c_nim.c
index e6f7755ded..7dbbdb8873 100644
--- a/drivers/net/ntnic/nim/i2c_nim.c
+++ b/drivers/net/ntnic/nim/i2c_nim.c
@@ -795,3 +795,11 @@ int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra)
 
 	return res;
 }
+
+void nim_agx_setup(struct nim_i2c_ctx *ctx, nthw_pcal6416a_t *p_io_nim, nthw_i2cm_t *p_nt_i2cm,
+	nthw_pca9849_t *p_ca9849)
+{
+	ctx->hwagx.p_nt_i2cm = p_nt_i2cm;
+	ctx->hwagx.p_ca9849 = p_ca9849;
+	ctx->hwagx.p_io_nim = p_io_nim;
+}
diff --git a/drivers/net/ntnic/nim/i2c_nim.h b/drivers/net/ntnic/nim/i2c_nim.h
index edb6dcf1b6..09837448c6 100644
--- a/drivers/net/ntnic/nim/i2c_nim.h
+++ b/drivers/net/ntnic/nim/i2c_nim.h
@@ -33,4 +33,7 @@ int nim_qsfp_plus_nim_set_tx_laser_disable(nim_i2c_ctx_t *ctx, bool disable, int
  */
 int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra);
 
+void nim_agx_setup(struct nim_i2c_ctx *ctx, nthw_pcal6416a_t *p_io_nim, nthw_i2cm_t *p_nt_i2cm,
+	nthw_pca9849_t *p_ca9849);
+
 #endif	/* I2C_NIM_H_ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
new file mode 100644
index 0000000000..636d2beb85
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+#ifndef __NTHW_PCAL6416A_H__
+#define __NTHW_PCAL6416A_H__
+
+#include <stdint.h>
+
+/*
+ * PCAL6416A I/O expander class
+ */
+
+struct nthw_pcal6416a {
+};
+
+typedef struct nthw_pcal6416a nthw_pcal6416a_t;
+
+#endif	/* __NTHW_PCAL6416A_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
new file mode 100644
index 0000000000..930c897046
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -0,0 +1,62 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_PHY_TILE_H__
+#define __NTHW_PHY_TILE_H__
+
+#include "nthw_fpga_model.h"
+
+struct nt_phy_tile {
+	nthw_fpga_t *mp_fpga;
+
+	int mn_phy_tile_instance;
+
+	int mn_fpga_version;
+	int mn_fpga_revision;
+
+	nthw_register_t *mp_reg_port_xcvr_base[2][4];
+	nthw_field_t *mp_fld_port_xcvr_base_ptr[2][4];
+	nthw_field_t *mp_fld_port_xcvr_base_busy[2][4];
+	nthw_field_t *mp_fld_port_xcvr_base_cmd[2][4];
+
+	nthw_field_t *mp_fld_port_xcvr_data_data[2][4];
+
+	nthw_register_t *mp_reg_port_eth_base[2];
+	nthw_field_t *mp_fld_port_eth_base_ptr[2];
+	nthw_field_t *mp_fld_port_eth_base_busy[2];
+	nthw_field_t *mp_fld_port_eth_base_cmd[2];
+
+	nthw_field_t *mp_fld_port_eth_data_data[2];
+
+	nthw_register_t *mp_reg_link_summary[2];
+	nthw_field_t *mp_fld_link_summary_nt_phy_link_state[2];
+	nthw_field_t *mp_fld_link_summary_ll_nt_phy_link_state[2];
+	nthw_field_t *mp_fld_link_summary_link_down_cnt[2];
+	nthw_field_t *mp_fld_link_summary_lh_remote_fault[2];
+
+	nthw_field_t *mp_fld_port_status_tx_reset_ackn[2];
+	nthw_field_t *mp_fld_port_status_rx_reset_ackn[2];
+
+	nthw_field_t *mp_fld_port_config_rx_reset[2];
+	nthw_field_t *mp_fld_port_config_tx_reset[2];
+
+	nthw_field_t *mp_fld_scratch_data;
+};
+
+typedef struct nt_phy_tile nthw_phy_tile_t;
+typedef struct nt_phy_tile nt_phy_tile;
+
+void nthw_phy_tile_set_tx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert);
+void nthw_phy_tile_set_rx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert);
+void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	bool enable);
+void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
+
+uint32_t nthw_phy_tile_read_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	uint32_t address);
+void nthw_phy_tile_write_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, uint32_t address,
+	uint32_t data);
+
+#endif	/* __NTHW_PHY_TILE_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
new file mode 100644
index 0000000000..fb44c62f12
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
@@ -0,0 +1,18 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_SI5332_SI5156_H__
+#define __NTHW_SI5332_SI5156_H__
+
+/*
+ * PCA9849 I2c mux class
+ */
+
+struct nthw_pca9849 {
+};
+
+typedef struct nthw_pca9849 nthw_pca9849_t;
+
+#endif	/* __NTHW_SI5332_SI5156_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
new file mode 100644
index 0000000000..fd7a1e1214
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -0,0 +1,173 @@
+/*
+ * 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_phy_tile.h"
+#include "nthw_helper.h"
+
+static const uint32_t link_addr = 0x9003C;
+static const uint32_t phy_addr = 0x90040;
+/* CPI option flags */
+static const uint32_t cpi_set = 0x2000;	/* 1 << 13 */
+static const uint32_t cpi_in_reset = 0x4000;	/* 1 << 14 */
+static const uint32_t bit_cpi_assert = 0x8000;	/* 1 << 15 */
+/*
+ * Base Addresses for Avalon MM Secondary Components
+ * static const uint32_t ADDR_AVMM_DR_CTRL_INT                  =  0x10035000 << 0;
+ * static const uint32_t ADDR_GDR_P0_XCVR_RECONFIG_INT          =  0x00800000 << 0;
+ * static const uint32_t ADDR_GDR_P1_XCVR_RECONFIG_INT          =  0x00900000 << 0;
+ * static const uint32_t ADDR_GDR_P2_XCVR_RECONFIG_INT          =  0x00A00000 << 0;
+ * static const uint32_t ADDR_GDR_P3_XCVR_RECONFIG_INT          =  0x00B00000 << 0;
+ * static const uint32_t ADDR_GDR_P0_ETH_RECONFIG_INT           =  0x00000000 << 0;
+ * static const uint32_t ADDR_GDR_P1_ETH_RECONFIG_INT           =  0x00010000 << 0;
+ * static const uint32_t ADDR_GDR_P2_ETH_RECONFIG_INT           =  0x00020000 << 0;
+ * static const uint32_t ADDR_GDR_P3_ETH_RECONFIG_INT           =  0x00030000 << 0;
+ * static const uint32_t ADDR_GDR_PKT_CLIENT_CONFIG_INT         =  0x000100000 << 0;
+ * static const uint32_t ADDR_GDR_P0_25G_PKT_CLIENT_CONFIG_INT  =  0x000200000 << 0;
+ * static const uint32_t ADDR_GDR_P0_50G_PKT_CLIENT_CONFIG_INT  =  0x000300000 << 0;
+ *
+ * ETH AVMM USER SPACE Registers Address Map
+ */
+
+void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset)
+{
+	/* Reset is active low */
+	nthw_field_get_updated(p->mp_fld_port_config_rx_reset[intf_no]);
+
+	if (reset) {
+		nthw_field_clr_flush(p->mp_fld_port_config_rx_reset[intf_no]);
+
+		/* Wait for ack */
+		if (p->mp_fld_port_status_rx_reset_ackn[intf_no]) {
+			int32_t count = 1000;
+
+			do {
+				nt_os_wait_usec(1000);	/* 1ms */
+			} while (nthw_field_get_updated(p->mp_fld_port_status_rx_reset_ackn
+				[intf_no]) && (--count > 0));
+
+			if (count <= 0) {
+				NT_LOG(ERR, NTHW, "intf_no %u: Time-out waiting for RxResetAck",
+					intf_no);
+			}
+		}
+
+	} else {
+		nthw_field_set_flush(p->mp_fld_port_config_rx_reset[intf_no]);
+	}
+}
+
+uint32_t nthw_phy_tile_read_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	uint32_t address)
+{
+	nthw_register_update(p->mp_reg_port_xcvr_base[intf_no][lane]);
+	nthw_field_set_val32(p->mp_fld_port_xcvr_base_cmd[intf_no][lane], 0);
+	nthw_field_set_val_flush32(p->mp_fld_port_xcvr_base_ptr[intf_no][lane], address);
+
+	while (nthw_field_get_updated(p->mp_fld_port_xcvr_base_busy[intf_no][lane]) == 1)
+		nt_os_wait_usec(100);
+
+	return nthw_field_get_updated(p->mp_fld_port_xcvr_data_data[intf_no][lane]);
+}
+
+void nthw_phy_tile_write_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, uint32_t address,
+	uint32_t data)
+{
+	nthw_field_set_val_flush32(p->mp_fld_port_xcvr_data_data[intf_no][lane], data);
+	nthw_register_update(p->mp_reg_port_xcvr_base[intf_no][lane]);
+	nthw_field_set_val32(p->mp_fld_port_xcvr_base_ptr[intf_no][lane], address);
+	nthw_field_set_val_flush32(p->mp_fld_port_xcvr_base_cmd[intf_no][lane], 1);
+
+	while (nthw_field_get_updated(p->mp_fld_port_xcvr_base_busy[intf_no][lane]) == 1)
+		/* NT_LOG(INF, NTHW, "busy"); */
+		nt_os_wait_usec(100);
+}
+
+static uint32_t nthw_phy_tile_cpi_request(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	uint32_t data, uint8_t op_code, uint32_t cpi_assert,
+	uint32_t cpi_set_get)
+{
+	uint32_t cpi_cmd;
+	uint32_t value = 0;
+	uint32_t xcvr_instance = lane;
+	uint32_t lane_offset = 0;
+	uint32_t quad_lane = 0;
+
+	/* Find quad lane */
+	quad_lane = nthw_phy_tile_read_xcvr(p, intf_no, lane, 0xFFFFC) & 0x3;
+
+	xcvr_instance = lane;
+	lane_offset = (uint32_t)(lane << 20);
+
+	cpi_cmd = (data << 16) | cpi_assert | cpi_set_get | (quad_lane << 8) | op_code;
+
+	nthw_phy_tile_write_xcvr(p, intf_no, lane, link_addr + lane_offset, cpi_cmd);
+
+	nt_os_wait_usec(10000);
+
+	for (int i = 20; i > 0; i--) {
+		data = nthw_phy_tile_read_xcvr(p, intf_no, lane, phy_addr + lane_offset);
+
+		value =
+			nthw_field_get_updated(p->mp_fld_port_xcvr_data_data
+				[intf_no][xcvr_instance]);
+
+		if (((value & bit_cpi_assert) == cpi_assert) && ((value & cpi_in_reset) == 0))
+			break;
+
+		nt_os_wait_usec(10000);
+
+		if (i == 0)
+			NT_LOG(ERR, NTHW, "Time out");
+	}
+
+	return value;
+}
+
+static void nthw_phy_tile_write_attribute(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	uint8_t op_code, uint8_t data)
+{
+	/*
+	 * p->cpi_set_get = 0x2000 #bit13: (1: set, 0: get)
+	 * cpi_assert = 0x0000 #bit15: (1: assert, 0: deassert)
+	 */
+	nthw_phy_tile_cpi_request(p, intf_no, lane, data, op_code, bit_cpi_assert, cpi_set);
+	nthw_phy_tile_cpi_request(p, intf_no, lane, data, op_code, 0x0000, cpi_set);
+}
+
+void nthw_phy_tile_set_tx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert)
+{
+	nthw_phy_tile_write_attribute(p, intf_no, lane, 0x65, invert ? 1 : 0);
+	/*
+	 * NT_LOG(INF, NTHW, "setTxPolInv intf_no %d, lane %d, inv %d ", intf_no, lane, invert);
+	 * nthw_phy_tile_get_tx_pol_inv(p, intf_no, lane);
+	 */
+}
+
+void nthw_phy_tile_set_rx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert)
+{
+	nthw_phy_tile_write_attribute(p, intf_no, lane, 0x66, invert ? 1 : 0);
+	/*
+	 * NT_LOG(INF, NTHW, "setRxPolInv intf_no %d, lane %d, inv %d ", intf_no, lane, invert);
+	 * nthw_phy_tile_get_rx_pol_inv(p, intf_no, lane);
+	 */
+}
+
+void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	bool enable)
+{
+	nthw_phy_tile_set_rx_reset(p, intf_no, true);
+	nthw_phy_tile_write_attribute(p, intf_no, lane, 0x40, enable ? 0x06 : 0);
+	nthw_phy_tile_set_rx_reset(p, intf_no, false);
+	/*
+	 * NT_LOG(INF, NTHW, "setLoopback intf_no %d, lane %d, enable %d ",
+	 * intf_no, lane, enable);
+	 */
+}
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index 9dc839c83c..1fc8df52ce 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -9,12 +9,20 @@
 #include "nthw_core.h"
 #include "ntnic_dbs.h"
 
+#include "nthw_si5332_si5156.h"
+#include "nthw_pcal6416a.h"
+#include "nthw_phy_tile.h"
 #include "nthw_rpf.h"
+#include "nthw_phy_tile.h"
 
 /*
  * Structs for controlling Agilex based NT400DXX adapter
  */
 typedef struct nthw_agx_s {
+	nthw_i2cm_t *p_i2cm;
+	nthw_pca9849_t *p_pca9849;
+	nthw_pcal6416a_t *p_io_nim;	/* PCAL6416A I/O expander for controlling TS */
+	nthw_phy_tile_t *p_phy_tile;
 	nthw_rpf_t *p_rpf;
 } nthw_agx_t;
 
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 05/32] net/ntnic: add host loopback init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (3 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 04/32] net/ntnic: add agx setup for port Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 06/32] net/ntnic: add line " Serhii Iliushyk
                   ` (28 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Implement PHY line loopback configuration for Agilex FPGA

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 111 ++++++++++++++++++
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |   1 +
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   |  28 +++++
 3 files changed, 140 insertions(+)

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index a6455ee598..f3862b7fe3 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -14,6 +14,11 @@
 #include "nthw_gfg.h"
 #include "nthw_phy_tile.h"
 
+typedef enum {
+	LOOPBACK_HOST_NONE,
+	LOOPBACK_HOST
+} loopback_host_t;
+
 static int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info,
 	nthw_fpga_t *fpga);
 
@@ -29,6 +34,65 @@ void link_agx_100g_init(void)
 	register_agx_100g_link_ops(&link_agx_100g_ops);
 }
 
+/*
+ * Phy handling
+ */
+
+static void phy_rx_path_rst(adapter_info_t *drv, int port, bool reset)
+{
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+	NT_LOG(DBG, NTNIC, "Port %d: %s", port, reset ? "assert" : "deassert");
+	nthw_phy_tile_set_rx_reset(p, port, reset);
+}
+
+static void phy_tx_path_rst(adapter_info_t *drv, int port, bool reset)
+{
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+	NT_LOG(DBG, NTNIC, "Port %d: %s", port, reset ? "assert" : "deassert");
+	nthw_phy_tile_set_tx_reset(p, port, reset);
+}
+
+static void phy_reset_rx(adapter_info_t *drv, int port)
+{
+	phy_rx_path_rst(drv, port, true);
+	nt_os_wait_usec(10000);	/* 10ms */
+	phy_rx_path_rst(drv, port, false);
+	nt_os_wait_usec(10000);	/* 10ms */
+}
+
+static void phy_reset_tx(adapter_info_t *drv, int port)
+{
+	phy_tx_path_rst(drv, port, true);
+	nt_os_wait_usec(10000);	/* 10ms */
+	phy_tx_path_rst(drv, port, false);
+	nt_os_wait_usec(10000);	/* 10ms */
+}
+
+static int phy_set_host_loopback(adapter_info_t *drv, int port, loopback_host_t loopback)
+{
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+
+	switch (loopback) {
+	case LOOPBACK_HOST_NONE:
+		for (uint8_t lane = 0; lane < 4; lane++)
+			nthw_phy_tile_set_host_loopback(p, port, lane, false);
+
+		break;
+
+	case LOOPBACK_HOST:
+		for (uint8_t lane = 0; lane < 4; lane++)
+			nthw_phy_tile_set_host_loopback(p, port, lane, true);
+
+		break;
+
+	default:
+		NT_LOG(ERR, NTNIC, "Port %d: Unhandled loopback value (%d)", port, loopback);
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  * Utility functions
  */
@@ -81,6 +145,40 @@ static int swap_tx_rx_polarity(adapter_info_t *drv, int port, bool swap)
 	return -1;
 }
 
+static void
+set_loopback(struct adapter_info_s *p_adapter_info, int port, uint32_t mode, uint32_t last_mode)
+{
+	switch (mode) {
+	case 1:
+		NT_LOG(INF, NTNIC, "%s: Applying host loopback",
+			p_adapter_info->mp_port_id_str[port]);
+		phy_set_host_loopback(p_adapter_info, port, LOOPBACK_HOST);
+		swap_tx_rx_polarity(p_adapter_info, port, false);
+		break;
+
+	default:
+		switch (last_mode) {
+		case 1:
+			NT_LOG(INF, NTNIC, "%s: Removing host loopback",
+				p_adapter_info->mp_port_id_str[port]);
+			phy_set_host_loopback(p_adapter_info, port, LOOPBACK_HOST_NONE);
+			swap_tx_rx_polarity(p_adapter_info, port, true);
+			break;
+
+		default:
+			/* do nothing */
+			break;
+		}
+
+		break;
+	}
+
+	/* After changing the loopback the system must be properly reset */
+	phy_reset_rx(p_adapter_info, port);
+	phy_reset_tx(p_adapter_info, port);
+	nt_os_wait_usec(10000);	/* 10ms - arbitrary choice */
+}
+
 /*
  * Link state machine
  */
@@ -146,6 +244,19 @@ static void *_common_ptp_nim_state_machine(void *data)
 			if (is_port_disabled)
 				continue;
 
+			if (link_info->port_action[i].port_lpbk_mode != last_lpbk_mode[i]) {
+				set_loopback(drv,
+					i,
+					link_info->port_action[i].port_lpbk_mode,
+					last_lpbk_mode[i]);
+
+				if (link_info->port_action[i].port_lpbk_mode == 1)
+					link_state[i].link_up = true;
+
+				last_lpbk_mode[i] = link_info->port_action[i].port_lpbk_mode;
+				continue;
+			}
+
 			link_state[i].link_disabled = is_port_disabled;
 
 			if (!link_state[i].nim_present) {
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
index 930c897046..5577f95944 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -52,6 +52,7 @@ void nthw_phy_tile_set_tx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t l
 void nthw_phy_tile_set_rx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert);
 void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	bool enable);
+void nthw_phy_tile_set_tx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
 void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
 
 uint32_t nthw_phy_tile_read_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
index fd7a1e1214..6402e5caf3 100644
--- a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -64,6 +64,34 @@ void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset)
 	}
 }
 
+void nthw_phy_tile_set_tx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset)
+{
+	/* Reset is active low */
+	nthw_field_get_updated(p->mp_fld_port_config_tx_reset[intf_no]);
+
+	if (reset) {
+		nthw_field_clr_flush(p->mp_fld_port_config_tx_reset[intf_no]);
+
+		/* Wait for ack */
+		if (p->mp_fld_port_status_tx_reset_ackn[intf_no]) {
+			int32_t count = 1000;
+
+			do {
+				nt_os_wait_usec(1000);	/* 1ms */
+			} while (nthw_field_get_updated(p->mp_fld_port_status_tx_reset_ackn
+				[intf_no]) && (--count > 0));
+
+			if (count <= 0) {
+				NT_LOG(ERR, NTHW, "intf_no %u: Time-out waiting for TxResetAck",
+					intf_no);
+			}
+		}
+
+	} else {
+		nthw_field_set_flush(p->mp_fld_port_config_tx_reset[intf_no]);
+	}
+}
+
 uint32_t nthw_phy_tile_read_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	uint32_t address)
 {
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 06/32] net/ntnic: add line loopback init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (4 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 05/32] net/ntnic: add host loopback init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 07/32] net/ntnic: add 100 gbps port init Serhii Iliushyk
                   ` (27 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Implement PHY host loopback configuration for Agilex FPGA

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 116 ++++++++++++++++++
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nim/i2c_nim.c               |  70 +++++++++--
 .../nthw/core/include/nthw_si5332_si5156.h    |   6 +
 .../net/ntnic/nthw/core/nthw_si5332_si5156.c  |  31 +++++
 5 files changed, 216 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index f3862b7fe3..9551dfdfdc 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -19,6 +19,11 @@ typedef enum {
 	LOOPBACK_HOST
 } loopback_host_t;
 
+typedef enum {
+	LOOPBACK_LINE_NONE,
+	LOOPBACK_LINE
+} loopback_line_t;
+
 static int nt4ga_agx_link_100g_ports_init(struct adapter_info_s *p_adapter_info,
 	nthw_fpga_t *fpga);
 
@@ -93,6 +98,105 @@ static int phy_set_host_loopback(adapter_info_t *drv, int port, loopback_host_t
 	return 0;
 }
 
+static int phy_set_line_loopback(adapter_info_t *drv, int port, loopback_line_t loopback)
+{
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+	uint32_t addr;
+
+	switch (loopback) {
+	case LOOPBACK_LINE_NONE:
+		for (uint8_t lane = 0; lane < 4; lane++) {
+			uint8_t quad_lane;
+
+			for (uint8_t fgt = 0; fgt < 4; fgt++) {
+				uint8_t quad_and_lane_no =
+					(uint8_t)nthw_phy_tile_read_xcvr(p, port, lane, 0xFFFFC);
+				quad_lane = quad_and_lane_no & 0x3;	/* bits[1:0] */
+
+				if (quad_lane == lane)
+					break;
+			}
+
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41830u + (0x8000u * quad_lane),
+				0x03);
+
+			addr = nthw_phy_tile_read_xcvr(p, 0, 0, 0x41768u + (0x8000u * quad_lane)) |
+				(1u << 24u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41768u + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, 0, 0, 0x41414u + (0x8000u * quad_lane)) &
+				~(1u << 29u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41414u + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, 0, 0, 0x4141Cu + (0x8000u * quad_lane)) &
+				~(1u << 30u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x4141Cu + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, 0, 0, 0x41418u + (0x8000u * quad_lane)) &
+				~(1u << 31u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41418u + (0x8000u * quad_lane),
+				addr);
+		}
+
+		break;
+
+	case LOOPBACK_LINE:
+		for (uint8_t lane = 0; lane < 4; lane++) {
+			uint8_t quad_lane;
+
+			for (uint8_t fgt = 0; fgt < 4; fgt++) {
+				uint8_t quad_and_lane_no =
+					(uint8_t)nthw_phy_tile_read_xcvr(p, port, lane, 0xFFFFC);
+				quad_lane = quad_and_lane_no & 0x3;	/* bits[1:0] */
+
+				if (quad_lane == lane)
+					break;
+			}
+
+			addr = nthw_phy_tile_read_xcvr(p, port, 0,
+					0x41830u + (0x8000u * quad_lane)) &
+				0u;
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41830u + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, port, 0,
+					0x41768u + (0x8000u * quad_lane)) &
+				~(1u << 24u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41768u + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, port, 0,
+					0x41414u + (0x8000u * quad_lane)) |
+				(1u << 29u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41414u + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, port, 0,
+					0x4141Cu + (0x8000u * quad_lane)) |
+				(1u << 30u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x4141Cu + (0x8000u * quad_lane),
+				addr);
+
+			addr = nthw_phy_tile_read_xcvr(p, port, 0,
+					0x41418u + (0x8000u * quad_lane)) |
+				(1u << 31u);
+			nthw_phy_tile_write_xcvr(p, port, 0, 0x41418u + (0x8000u * quad_lane),
+				addr);
+		}
+
+		break;
+
+	default:
+		NT_LOG(ERR, NTNIC, "Port %d: Unhandled loopback value (%d)", port, loopback);
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  * Utility functions
  */
@@ -156,6 +260,12 @@ set_loopback(struct adapter_info_s *p_adapter_info, int port, uint32_t mode, uin
 		swap_tx_rx_polarity(p_adapter_info, port, false);
 		break;
 
+	case 2:
+		NT_LOG(INF, NTNIC, "%s: Applying line loopback",
+			p_adapter_info->mp_port_id_str[port]);
+		phy_set_line_loopback(p_adapter_info, port, LOOPBACK_LINE);
+		break;
+
 	default:
 		switch (last_mode) {
 		case 1:
@@ -165,6 +275,12 @@ set_loopback(struct adapter_info_s *p_adapter_info, int port, uint32_t mode, uin
 			swap_tx_rx_polarity(p_adapter_info, port, true);
 			break;
 
+		case 2:
+			NT_LOG(INF, NTNIC, "%s: Removing line loopback",
+				p_adapter_info->mp_port_id_str[port]);
+			phy_set_line_loopback(p_adapter_info, port, LOOPBACK_LINE_NONE);
+			break;
+
 		default:
 			/* do nothing */
 			break;
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 4799ebfb8e..271115cdd3 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -56,6 +56,7 @@ sources = files(
         'nthw/core/nthw_mac_pcs.c',
         'nthw/core/nthw_pcie3.c',
         'nthw/core/nthw_phy_tile.c',
+        'nthw/core/nthw_si5332_si5156.c',
         'nthw/core/nthw_rpf.c',
         'nthw/core/nthw_rmc.c',
         'nthw/core/nthw_sdc.c',
diff --git a/drivers/net/ntnic/nim/i2c_nim.c b/drivers/net/ntnic/nim/i2c_nim.c
index 7dbbdb8873..f3cca9e555 100644
--- a/drivers/net/ntnic/nim/i2c_nim.c
+++ b/drivers/net/ntnic/nim/i2c_nim.c
@@ -13,6 +13,12 @@
 #include "qsfp_registers.h"
 #include "nim_defines.h"
 
+int nim_agx_read_id(struct nim_i2c_ctx *ctx);
+static void nim_agx_read(struct nim_i2c_ctx *ctx, uint8_t dev_addr, uint8_t reg_addr,
+	uint8_t data_len, void *p_data);
+static void nim_agx_write(struct nim_i2c_ctx *ctx, uint8_t dev_addr, uint8_t reg_addr,
+	uint8_t data_len, void *p_data);
+
 #define NIM_READ false
 #define NIM_WRITE true
 #define NIM_PAGE_SEL_REGISTER 127
@@ -50,17 +56,17 @@ static int nim_read_write_i2c_data(nim_i2c_ctx_p ctx, bool do_write, uint16_t li
 		if (ctx->type == I2C_HWIIC) {
 			return nthw_iic_write_data(&ctx->hwiic, i2c_devaddr, a_reg_addr, seq_cnt,
 					p_data);
-
-		} else {
-			return 0;
 		}
 
-	} else if (ctx->type == I2C_HWIIC) {
-		return nthw_iic_read_data(&ctx->hwiic, i2c_devaddr, a_reg_addr, seq_cnt, p_data);
-
-	} else {
+		nim_agx_write(ctx, i2c_addr, a_reg_addr, seq_cnt, p_data);
 		return 0;
 	}
+
+	if (ctx->type == I2C_HWIIC)
+		return nthw_iic_read_data(&ctx->hwiic, i2c_devaddr, a_reg_addr, seq_cnt, p_data);
+
+	nim_agx_read(ctx, i2c_addr, a_reg_addr, seq_cnt, p_data);
+	return 0;
 }
 
 /*
@@ -216,7 +222,7 @@ static int i2c_nim_common_construct(nim_i2c_ctx_p ctx)
 		res = nim_read_id(ctx);
 
 	else
-		res = -1;
+		res = nim_agx_read_id(ctx);
 
 	if (res) {
 		NT_LOG(ERR, NTNIC, "Can't read NIM id.");
@@ -803,3 +809,51 @@ void nim_agx_setup(struct nim_i2c_ctx *ctx, nthw_pcal6416a_t *p_io_nim, nthw_i2c
 	ctx->hwagx.p_ca9849 = p_ca9849;
 	ctx->hwagx.p_io_nim = p_io_nim;
 }
+
+static void nim_agx_read(struct nim_i2c_ctx *ctx,
+	uint8_t dev_addr,
+	uint8_t reg_addr,
+	uint8_t data_len,
+	void *p_data)
+{
+	nthw_i2cm_t *p_nt_i2cm = ctx->hwagx.p_nt_i2cm;
+	nthw_pca9849_t *p_ca9849 = ctx->hwagx.p_ca9849;
+	uint8_t *data = (uint8_t *)p_data;
+
+	rte_spinlock_lock(&p_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p_ca9849, ctx->hwagx.mux_channel);
+
+	for (uint8_t i = 0; i < data_len; i++) {
+		nthw_i2cm_read(p_nt_i2cm, (uint8_t)(dev_addr >> 1), (uint8_t)(reg_addr + i), data);
+		data++;
+	}
+
+	rte_spinlock_unlock(&p_nt_i2cm->i2cmmutex);
+}
+
+static void nim_agx_write(struct nim_i2c_ctx *ctx,
+	uint8_t dev_addr,
+	uint8_t reg_addr,
+	uint8_t data_len,
+	void *p_data)
+{
+	nthw_i2cm_t *p_nt_i2cm = ctx->hwagx.p_nt_i2cm;
+	nthw_pca9849_t *p_ca9849 = ctx->hwagx.p_ca9849;
+	uint8_t *data = (uint8_t *)p_data;
+
+	rte_spinlock_lock(&p_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p_ca9849, ctx->hwagx.mux_channel);
+
+	for (uint8_t i = 0; i < data_len; i++) {
+		nthw_i2cm_write(p_nt_i2cm, (uint8_t)(dev_addr >> 1), (uint8_t)(reg_addr + i),
+			*data++);
+	}
+
+	rte_spinlock_unlock(&p_nt_i2cm->i2cmmutex);
+}
+
+int nim_agx_read_id(struct nim_i2c_ctx *ctx)
+{
+	nim_agx_read(ctx, 0xA0, 0, sizeof(ctx->nim_id), &ctx->nim_id);
+	return 0;
+}
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
index fb44c62f12..968d7eb74a 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
@@ -6,13 +6,19 @@
 #ifndef __NTHW_SI5332_SI5156_H__
 #define __NTHW_SI5332_SI5156_H__
 
+#include "nthw_i2cm.h"
 /*
  * PCA9849 I2c mux class
  */
 
 struct nthw_pca9849 {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_current_channel;
+	uint8_t m_dev_address;
 };
 
 typedef struct nthw_pca9849 nthw_pca9849_t;
 
+int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel);
+
 #endif	/* __NTHW_SI5332_SI5156_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
new file mode 100644
index 0000000000..b5560e2990
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include <pthread.h>
+#include "nt_util.h"
+#include "ntlog.h"
+
+#include "nthw_drv.h"
+#include "nthw_register.h"
+
+#include "nthw_si5332_si5156.h"
+
+int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel)
+{
+	int res;
+
+	if (p->m_current_channel != channel) {
+		uint8_t data = channel + 4;
+		res = nthw_i2cm_write(p->mp_nt_i2cm, p->m_dev_address, 0, data);
+
+		if (res)
+			return res;
+
+		p->m_current_channel = channel;
+		nt_os_wait_usec(10000);
+	}
+
+	return 0;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 07/32] net/ntnic: add 100 gbps port init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (5 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 06/32] net/ntnic: add line " Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 08/32] net/ntnic: add port post init Serhii Iliushyk
                   ` (26 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Initialize NIM and 100G port for Agilex FPGA

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 143 ++++++++++++++++++
 drivers/net/ntnic/meson.build                 |   1 +
 .../net/ntnic/nthw/core/include/nthw_gmf.h    |   2 +
 .../ntnic/nthw/core/include/nthw_pcal6416a.h  |  10 ++
 drivers/net/ntnic/nthw/core/nthw_gmf.c        |  41 +++++
 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c  |  41 +++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 9551dfdfdc..6593c90ca5 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -197,6 +197,26 @@ static int phy_set_line_loopback(adapter_info_t *drv, int port, loopback_line_t
 	return 0;
 }
 
+/*
+ * Nim handling
+ */
+
+static bool nim_is_present(nim_i2c_ctx_p ctx, uint8_t nim_idx)
+{
+	assert(nim_idx < NUM_ADAPTER_PORTS_MAX);
+
+	nthw_pcal6416a_t *p = ctx->hwagx.p_io_nim;
+	uint8_t data = 0;
+
+	if (nim_idx == 0)
+		nthw_pcal6416a_read(p, 3, &data);
+
+	else if (nim_idx == 1)
+		nthw_pcal6416a_read(p, 7, &data);
+
+	return data == 0;
+}
+
 /*
  * Utility functions
  */
@@ -295,6 +315,119 @@ set_loopback(struct adapter_info_s *p_adapter_info, int port, uint32_t mode, uin
 	nt_os_wait_usec(10000);	/* 10ms - arbitrary choice */
 }
 
+/*
+ * Initialize NIM, Code based on nt400d1x.cpp: MyPort::createNim()
+ */
+
+static int create_nim(adapter_info_t *drv, int port, bool enable)
+{
+	int res = 0;
+	const uint8_t valid_nim_id = NT_NIM_QSFP28;
+	sfp_nim_state_t nim;
+	nt4ga_link_t *link_info = &drv->nt4ga_link;
+	nim_i2c_ctx_t *nim_ctx = &link_info->u.nim_ctx[port];
+
+	assert(port >= 0 && port < NUM_ADAPTER_PORTS_MAX);
+	assert(link_info->variables_initialized);
+
+	if (!enable) {
+		phy_reset_rx(drv, port);
+		phy_reset_tx(drv, port);
+	}
+
+	/*
+	 * Wait a little after a module has been inserted before trying to access I2C
+	 * data, otherwise the module will not respond correctly.
+	 */
+	nt_os_wait_usec(1000000);	/* pause 1.0s */
+
+	res = construct_and_preinit_nim(nim_ctx, NULL);
+
+	if (res)
+		return res;
+
+	res = nim_state_build(nim_ctx, &nim);
+
+	if (res)
+		return res;
+
+	/* Set FEC to be enabled by default */
+	nim_ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena = true;
+
+	NT_LOG(DBG, NTHW, "%s: NIM id = %u (%s), br = %u, vendor = '%s', pn = '%s', sn='%s'",
+		drv->mp_port_id_str[port], nim_ctx->nim_id, nim_id_to_text(nim_ctx->nim_id), nim.br,
+		nim_ctx->vendor_name, nim_ctx->prod_no, nim_ctx->serial_no);
+
+	/*
+	 * Does the driver support the NIM module type?
+	 */
+	if (nim_ctx->nim_id != valid_nim_id) {
+		NT_LOG(ERR, NTHW, "%s: The driver does not support the NIM module type %s",
+			drv->mp_port_id_str[port], nim_id_to_text(nim_ctx->nim_id));
+		NT_LOG(DBG, NTHW, "%s: The driver supports the NIM module type %s",
+			drv->mp_port_id_str[port], nim_id_to_text(valid_nim_id));
+		return -1;
+	}
+
+	return res;
+}
+
+/*
+ * Initialize one 100 Gbps port.
+ */
+static int _port_init(adapter_info_t *p_info, nthw_fpga_t *fpga, int port)
+{
+	uint8_t adapter_no = p_info->adapter_no;
+	int res;
+
+	nt4ga_link_t *link_info = &p_info->nt4ga_link;
+	nthw_gfg_t *p_gfg = &link_info->u.var_a100g.gfg[adapter_no];
+	nthw_phy_tile_t *p_phy_tile = p_info->fpga_info.mp_nthw_agx.p_phy_tile;
+	nthw_rpf_t *p_rpf = p_info->fpga_info.mp_nthw_agx.p_rpf;
+
+	assert(port >= 0 && port < NUM_ADAPTER_PORTS_MAX);
+	assert(link_info->variables_initialized);
+
+	link_info->link_info[port].link_speed = NT_LINK_SPEED_100G;
+	link_info->link_info[port].link_duplex = NT_LINK_DUPLEX_FULL;
+	link_info->link_info[port].link_auto_neg = NT_LINK_AUTONEG_OFF;
+	link_info->speed_capa |= NT_LINK_SPEED_100G;
+
+	nthw_gfg_stop(p_gfg, port);
+
+	for (uint8_t lane = 0; lane < 4; lane++)
+		nthw_phy_tile_set_host_loopback(p_phy_tile, port, lane, false);
+
+	swap_tx_rx_polarity(p_info, port, true);
+	nthw_rpf_set_ts_at_eof(p_rpf, true);
+
+	NT_LOG(DBG, NTNIC, "%s: Setting up port %d", p_info->mp_port_id_str[port], port);
+
+	phy_reset_rx(p_info, port);
+
+	if (nthw_gmf_init(NULL, fpga, port) == 0) {
+		nthw_gmf_t gmf;
+
+		if (nthw_gmf_init(&gmf, fpga, port) == 0)
+			nthw_gmf_set_enable_tsi(&gmf, true, 0, 0, false);
+	}
+
+	nthw_rpf_unblock(p_rpf);
+
+	res = create_nim(p_info, port, true);
+
+	if (res) {
+		NT_LOG(WRN, NTNIC, "%s: NIM initialization failed",
+			p_info->mp_port_id_str[port]);
+		return res;
+	}
+
+	NT_LOG(DBG, NTNIC, "%s: NIM initialized", p_info->mp_port_id_str[port]);
+
+	phy_reset_rx(p_info, port);
+	return res;
+}
+
 /*
  * Link state machine
  */
@@ -310,6 +443,7 @@ static void *_common_ptp_nim_state_machine(void *data)
 	/* link_state_t new_link_state; */
 
 	link_state_t *link_state = link_info->link_state;
+	nim_i2c_ctx_t *nim_ctx = link_info->u.var_a100g.nim_ctx;
 
 	if (!fpga) {
 		NT_LOG(ERR, NTNIC, "%s: fpga is NULL", drv->mp_adapter_id_str);
@@ -361,6 +495,15 @@ static void *_common_ptp_nim_state_machine(void *data)
 				continue;
 
 			if (link_info->port_action[i].port_lpbk_mode != last_lpbk_mode[i]) {
+				/* Loopback mode has changed. Do something */
+				if (!nim_is_present(&nim_ctx[i], i)) {
+					/*
+					 * If there is no Nim present, we need to initialize the
+					 * port  anyway
+					 */
+					_port_init(drv, fpga, i);
+				}
+
 				set_loopback(drv,
 					i,
 					link_info->port_action[i].port_lpbk_mode,
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 271115cdd3..b1505c5549 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -55,6 +55,7 @@ sources = files(
         'nthw/core/nthw_iic.c',
         'nthw/core/nthw_mac_pcs.c',
         'nthw/core/nthw_pcie3.c',
+        'nthw/core/nthw_pcal6416a.c',
         'nthw/core/nthw_phy_tile.c',
         'nthw/core/nthw_si5332_si5156.c',
         'nthw/core/nthw_rpf.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_gmf.h b/drivers/net/ntnic/nthw/core/include/nthw_gmf.h
index cc5be85154..c8beb2117c 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_gmf.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_gmf.h
@@ -58,6 +58,8 @@ struct nthw_gmf {
 typedef struct nthw_gmf nthw_gmf_t;
 
 int nthw_gmf_init(nthw_gmf_t *p, nthw_fpga_t *p_fpga, int n_instance);
+void nthw_gmf_set_enable_tsi(nthw_gmf_t *p, bool enable, int tsi_dynamic_offset,
+	int tsi_static_offset, bool tsi_always);
 
 void nthw_gmf_set_enable(nthw_gmf_t *p, bool enable);
 
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
index 636d2beb85..5ef14a0bc9 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
@@ -7,13 +7,23 @@
 
 #include <stdint.h>
 
+#include "nthw_i2cm.h"
+#include "nthw_si5332_si5156.h"
+
 /*
  * PCAL6416A I/O expander class
  */
 
 struct nthw_pcal6416a {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_dev_address;
+	nthw_pca9849_t *mp_ca9849;
+	uint8_t m_mux_channel;
+	uint8_t m_config_data[2];
 };
 
 typedef struct nthw_pcal6416a nthw_pcal6416a_t;
 
+void nthw_pcal6416a_read(nthw_pcal6416a_t *p, uint8_t pin, uint8_t *value);
+
 #endif	/* __NTHW_PCAL6416A_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nthw_gmf.c b/drivers/net/ntnic/nthw/core/nthw_gmf.c
index 16a4c288bd..9fb708bc50 100644
--- a/drivers/net/ntnic/nthw/core/nthw_gmf.c
+++ b/drivers/net/ntnic/nthw/core/nthw_gmf.c
@@ -131,3 +131,44 @@ 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);
 }
+
+void nthw_gmf_set_enable_tsi(nthw_gmf_t *p, bool enable, int tsi_dynamic_offset,
+	int tsi_static_offset, bool tsi_always)
+{
+	if (!p->m_administrative_block) {
+		nthw_field_update_register(p->mp_ctrl_enable);
+
+		if (p->mp_ctrl_ts_inject_always) {
+			/*
+			 * Do not force timestamp Inject- let the TBH control this now
+			 * Later we could consider an ini-setting for controlling this
+			 */
+			nthw_field_set_val_flush32(p->mp_ctrl_ts_inject_always,
+				tsi_always ? 1 : 0);
+		}
+
+		if (p->mp_ctrl_fcs_always) {
+			/*
+			 * Do not force FSC calculation - let the TBH control this
+			 * Later we could consider an ini-setting for controlling this
+			 */
+			nthw_field_set_val_flush32(p->mp_ctrl_fcs_always, 0);
+		}
+
+		if (p->mp_ts_inject) {
+			nthw_register_update(p->mp_ts_inject);
+
+			if (p->mp_ts_inject_pos) {
+				nthw_field_set_val_flush32(p->mp_ts_inject_pos,
+					(uint32_t)tsi_dynamic_offset);
+			}
+
+			if (p->mp_ts_inject_offset) {
+				nthw_field_set_val_flush32(p->mp_ts_inject_offset,
+					(uint32_t)tsi_static_offset);
+			}
+		}
+
+		nthw_field_set_val_flush32(p->mp_ctrl_enable, enable ? 1 : 0);
+	}
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c b/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
new file mode 100644
index 0000000000..37b6e7ec57
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+#include <pthread.h>
+
+#include "nt_util.h"
+#include "ntlog.h"
+
+#include "nthw_drv.h"
+#include "nthw_register.h"
+
+#include "nthw_pcal6416a.h"
+
+static const uint8_t read_port[2] = { 0x00, 0x01 };
+
+/*
+ * PCAL6416A I/O expander class
+ */
+
+void nthw_pcal6416a_read(nthw_pcal6416a_t *p, uint8_t pin, uint8_t *value)
+{
+	uint8_t port;
+	uint8_t data;
+
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_ca9849, p->m_mux_channel);
+
+	if (pin < 8) {
+		port = 0;
+
+	} else {
+		port = 1;
+		pin = (uint8_t)(pin - 8);
+	}
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, read_port[port], &data);
+
+	*value = (data >> pin) & 0x1;
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 08/32] net/ntnic: add port post init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (6 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 07/32] net/ntnic: add 100 gbps port init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 09/32] net/ntnic: add nim low power API Serhii Iliushyk
                   ` (25 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Configure FEC and TX equalization for 100G NIM on Agilex FPGA

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 122 ++++++++
 drivers/net/ntnic/nim/i2c_nim.c               |  80 +++++
 drivers/net/ntnic/nim/i2c_nim.h               |   3 +
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |  25 ++
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   | 295 ++++++++++++++++++
 5 files changed, 525 insertions(+)

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 6593c90ca5..fe2acef612 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -372,6 +372,121 @@ static int create_nim(adapter_info_t *drv, int port, bool enable)
 	return res;
 }
 
+static int nim_ready_100_gb(adapter_info_t *p_info, int port)
+{
+	nt4ga_link_t *link_info = &p_info->nt4ga_link;
+	nim_i2c_ctx_t *nim_ctx = &link_info->u.nim_ctx[port];
+	nthw_phy_tile_t *p_phy_tile = p_info->fpga_info.mp_nthw_agx.p_phy_tile;
+
+	bool disable_fec_by_port_type = (nim_ctx->port_type == NT_PORT_TYPE_QSFP28_LR4);
+	bool enable_fec = nim_ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena &&
+		!disable_fec_by_port_type;
+
+	NT_LOG(DBG, NTNIC, "Port %s: DisableFec = %d", p_info->mp_port_id_str[port], !enable_fec);
+	/*
+	 * FecAutonegotiation at 100G is not supported for Napatech adapters and therefore
+	 * not relevant at this speed
+	 */
+
+	/* Adjust NIM power level */
+	if (nim_ctx->pwr_level_req > 4) {
+		qsfp28_set_high_power(nim_ctx);
+		nim_ctx->pwr_level_cur = nim_ctx->pwr_level_req;
+	}
+
+	/* enable_fec is what the end result should be, now find out if it's possible */
+	if (enable_fec) {
+		if (qsfp28_set_fec_enable(nim_ctx, true, false)) {
+			/* Prefer NIM media FEC since the NIM is assumed to know the right FEC */
+			NT_LOG(DBG, NTNIC, "Port %s: NIM media FEC enabled",
+				p_info->mp_port_id_str[port]);
+
+			/* The NIM has been set to FEC on the media side so turn FPGA FEC off */
+			if (nthw_phy_tile_configure_fec(p_phy_tile, port, true)) {
+				NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC disabled",
+					p_info->mp_port_id_str[port]);
+
+			} else {
+				NT_LOG(DBG, NTNIC,
+					"Port %s: FPGA does not support disabling of FEC",
+					p_info->mp_port_id_str[port]);
+				return 1;
+			}
+
+		} else if (qsfp28_set_fec_enable(nim_ctx, false, false)) {
+			/* The NIM does not support FEC at all so turn FPGA FEC on instead */
+			/* This is relevant to SR4 modules */
+			NT_LOG(DBG, NTNIC, "Port %s: No NIM FEC", p_info->mp_port_id_str[port]);
+			nthw_phy_tile_configure_fec(p_phy_tile, port, false);
+			NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC enabled",
+				p_info->mp_port_id_str[port]);
+
+		} else if (qsfp28_set_fec_enable(nim_ctx, true, true)) {
+			/* This probably not a likely scenario */
+			nthw_phy_tile_configure_fec(p_phy_tile, port, false);
+			NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC enabled",
+				p_info->mp_port_id_str[port]);
+			NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC terminated, NIM media FEC enabled",
+				p_info->mp_port_id_str[port]);
+
+		} else {
+			NT_LOG(ERR, NTNIC, "Port %s: Could not enable FEC",
+				p_info->mp_port_id_str[port]);
+			return 1;
+		}
+
+	} else if (qsfp28_set_fec_enable(nim_ctx, false, false)) {
+		/* The NIM does not support FEC at all - this is relevant to LR4 modules */
+		NT_LOG(DBG, NTNIC, "Port %s: No NIM FEC", p_info->mp_port_id_str[port]);
+
+		if (nthw_phy_tile_configure_fec(p_phy_tile, port, true)) {
+			NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC disabled",
+				p_info->mp_port_id_str[port]);
+
+		} else {
+			NT_LOG(ERR, NTNIC, "Port %s: FPGA does not support disabling of FEC",
+				p_info->mp_port_id_str[port]);
+			return 1;
+		}
+
+	} else if (qsfp28_set_fec_enable(nim_ctx, false, true)) {
+		nthw_phy_tile_configure_fec(p_phy_tile, port, false);
+		/* This probably not a likely scenario */
+		NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC enabled", p_info->mp_port_id_str[port]);
+		NT_LOG(DBG, NTNIC, "Port %s: FPGA FEC terminated, NIM media FEC disabled",
+			p_info->mp_port_id_str[port]);
+
+	} else {
+		NT_LOG(ERR, NTNIC, "Port %s: Could not disable FEC",
+			p_info->mp_port_id_str[port]);
+		return 1;
+	}
+
+	if (port == 0) {
+		/* setTxEqualization(uint8_t intf_no, uint8_t lane, uint32_t pre_tap2,
+		 * uint32_t main_tap, uint32_t pre_tap1, uint32_t post_tap1)
+		 */
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 0, 0, 44, 2, 9);
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 1, 0, 44, 2, 9);
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 2, 0, 44, 2, 9);
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 3, 0, 44, 2, 9);
+
+	} else {
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 0, 0, 44, 2, 9);
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 1, 0, 44, 2, 9);
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 2, 0, 44, 2, 9);
+		nthw_phy_tile_set_tx_equalization(p_phy_tile, port, 3, 0, 44, 2, 9);
+	}
+
+	/*
+	 * Perform a full reset. If the RX is in reset from the start this sequence will
+	 * take it out of reset and this is necessary in order to read block/lane lock
+	 * in getLinkState()
+	 */
+	phy_reset_rx(p_info, port);
+	return 0;
+}
+
 /*
  * Initialize one 100 Gbps port.
  */
@@ -424,6 +539,13 @@ static int _port_init(adapter_info_t *p_info, nthw_fpga_t *fpga, int port)
 
 	NT_LOG(DBG, NTNIC, "%s: NIM initialized", p_info->mp_port_id_str[port]);
 
+	res = nim_ready_100_gb(p_info, port);
+
+	if (res) {
+		NT_LOG(WRN, NTNIC, "%s: NIM failed to get ready", p_info->mp_port_id_str[port]);
+		return res;
+	}
+
 	phy_reset_rx(p_info, port);
 	return res;
 }
diff --git a/drivers/net/ntnic/nim/i2c_nim.c b/drivers/net/ntnic/nim/i2c_nim.c
index f3cca9e555..892e1b58b7 100644
--- a/drivers/net/ntnic/nim/i2c_nim.c
+++ b/drivers/net/ntnic/nim/i2c_nim.c
@@ -192,6 +192,13 @@ static int read_data_lin(nim_i2c_ctx_p ctx, uint16_t lin_addr, uint16_t length,
 			NIM_READ);
 }
 
+static int write_data_lin(nim_i2c_ctx_p ctx, uint16_t lin_addr, uint16_t length, void *data)
+{
+	/* Wrapper for using Mutex for QSFP TODO */
+	return nim_read_write_data_lin(ctx, page_addressing(ctx->nim_id), lin_addr, length, data,
+		NIM_WRITE);
+}
+
 /* Read and return a single byte */
 static uint8_t read_byte(nim_i2c_ctx_p ctx, uint16_t addr)
 {
@@ -802,6 +809,79 @@ int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra)
 	return res;
 }
 
+/*
+ * Enables high power according to SFF-8636 Rev 2.7, Table 6-9, Page 35:
+ * When set (= 1b) enables Power Classes 5 to 7 in Byte 129 to exceed 3.5W.
+ * When cleared (= 0b), modules with power classes 5 to 7 must dissipate less
+ * than 3.5W (but are not required to be fully functional). Default 0.
+ */
+void qsfp28_set_high_power(nim_i2c_ctx_p ctx)
+{
+	const uint16_t addr = 93;
+	uint8_t data;
+
+	/* Enable high power class; Set Page 00h, Byte 93 bit 2 to 1 */
+	read_data_lin(ctx, addr, sizeof(data), &data);
+	data |= (1 << 2);
+	write_data_lin(ctx, addr, sizeof(data), &data);
+}
+
+/*
+ * Enable FEC on media and/or host side. If the operation could be carried out
+ * return true. For some modules media side FEC is enabled but cannot be changed
+ *  while others allow changing the FEC state.
+ * For LR4 modules write operations (which are also not necessary) to the control
+ *  register must be avoided as this introduces I2C errors on NT200A01.
+ */
+
+bool qsfp28_set_fec_enable(nim_i2c_ctx_p ctx, bool media_side_fec, bool host_side_fec)
+{
+	/*
+	 * If the current FEC state does not match the wanted and the FEC cannot be
+	 * controlled then the operation cannot be carried out
+	 */
+	if (ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena != media_side_fec &&
+		!ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ctrl)
+		return false;
+
+	if (ctx->specific_u.qsfp.specific_u.qsfp28.host_side_fec_ena != host_side_fec &&
+		!ctx->specific_u.qsfp.specific_u.qsfp28.host_side_fec_ctrl)
+		return false;
+
+	/*
+	 * If the current media and host side FEC state matches the wanted states then
+	 * no need to do more
+	 */
+	if (ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena == media_side_fec &&
+		ctx->specific_u.qsfp.specific_u.qsfp28.host_side_fec_ena == host_side_fec)
+		return true;
+
+	/*
+	 * SFF-8636, Rev 2.10a TABLE 6-29 Optional Channel Control)
+	 * (Page 03h, Bytes 230-241)
+	 */
+	const uint16_t addr = 230 + 3 * 128;
+	uint8_t data = 0;
+	read_data_lin(ctx, addr, sizeof(data), &data);
+
+	if (media_side_fec)
+		data &= (uint8_t)(~(1 << 6));
+
+	else
+		data |= (uint8_t)(1 << 6);
+
+	if (host_side_fec)
+		data |= (uint8_t)(1 << 7);
+
+	else
+		data &= (uint8_t)(~(1 << 7));
+
+	write_data_lin(ctx, addr, sizeof(data), &data);
+	ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena = media_side_fec;
+	ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena = host_side_fec;
+	return true;
+}
+
 void nim_agx_setup(struct nim_i2c_ctx *ctx, nthw_pcal6416a_t *p_io_nim, nthw_i2cm_t *p_nt_i2cm,
 	nthw_pca9849_t *p_ca9849)
 {
diff --git a/drivers/net/ntnic/nim/i2c_nim.h b/drivers/net/ntnic/nim/i2c_nim.h
index 09837448c6..888b709135 100644
--- a/drivers/net/ntnic/nim/i2c_nim.h
+++ b/drivers/net/ntnic/nim/i2c_nim.h
@@ -33,6 +33,9 @@ int nim_qsfp_plus_nim_set_tx_laser_disable(nim_i2c_ctx_t *ctx, bool disable, int
  */
 int construct_and_preinit_nim(nim_i2c_ctx_p ctx, void *extra);
 
+void qsfp28_set_high_power(nim_i2c_ctx_p ctx);
+bool qsfp28_set_fec_enable(nim_i2c_ctx_p ctx, bool media_side_fec, bool host_side_fec);
+
 void nim_agx_setup(struct nim_i2c_ctx *ctx, nthw_pcal6416a_t *p_io_nim, nthw_i2cm_t *p_nt_i2cm,
 	nthw_pca9849_t *p_ca9849);
 
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
index 5577f95944..c810f55c0d 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -34,15 +34,34 @@ struct nt_phy_tile {
 	nthw_field_t *mp_fld_link_summary_nt_phy_link_state[2];
 	nthw_field_t *mp_fld_link_summary_ll_nt_phy_link_state[2];
 	nthw_field_t *mp_fld_link_summary_link_down_cnt[2];
+	nthw_field_t *mp_fld_link_summary_lh_received_local_fault[2];
 	nthw_field_t *mp_fld_link_summary_lh_remote_fault[2];
 
+	nthw_field_t *mp_fld_port_status_rx_hi_ber[2];
+	nthw_field_t *mp_fld_port_status_rx_am_lock[2];
 	nthw_field_t *mp_fld_port_status_tx_reset_ackn[2];
 	nthw_field_t *mp_fld_port_status_rx_reset_ackn[2];
 
+	nthw_field_t *mp_fld_port_config_reset[2];
 	nthw_field_t *mp_fld_port_config_rx_reset[2];
 	nthw_field_t *mp_fld_port_config_tx_reset[2];
 
+	nthw_field_t *mp_fld_port_comp_rx_compensation[2];
+
+	nthw_register_t *mp_reg_dyn_reconfig_base;
+	nthw_field_t *mp_fld_dyn_reconfig_base_ptr;
+	nthw_field_t *mp_fld_dyn_reconfig_base_busy;
+	nthw_field_t *mp_fld_dyn_reconfig_base_cmd;
+
+	nthw_register_t *mp_reg_dyn_reconfig_data;
+	nthw_field_t *mp_fld_dyn_reconfig_data_data;
+
 	nthw_field_t *mp_fld_scratch_data;
+
+	nthw_register_t *mp_reg_dr_cfg_status;
+	nthw_field_t *mp_fld_dr_cfg_status_curr_profile_id;
+	nthw_field_t *mp_fld_dr_cfg_status_in_progress;
+	nthw_field_t *mp_fld_dr_cfg_status_error;
 };
 
 typedef struct nt_phy_tile nthw_phy_tile_t;
@@ -52,9 +71,15 @@ void nthw_phy_tile_set_tx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t l
 void nthw_phy_tile_set_rx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert);
 void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	bool enable);
+void nthw_phy_tile_set_tx_equalization(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	uint32_t pre_tap2, uint32_t main_tap, uint32_t pre_tap1,
+	uint32_t post_tap1);
 void nthw_phy_tile_set_tx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
 void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
 
+uint32_t nthw_phy_tile_read_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address);
+void nthw_phy_tile_write_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address, uint32_t data);
+bool nthw_phy_tile_configure_fec(nthw_phy_tile_t *p, uint8_t intf_no, bool enable);
 uint32_t nthw_phy_tile_read_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	uint32_t address);
 void nthw_phy_tile_write_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, uint32_t address,
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
index 6402e5caf3..42e2782f99 100644
--- a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -14,10 +14,15 @@
 
 static const uint32_t link_addr = 0x9003C;
 static const uint32_t phy_addr = 0x90040;
+static const uint32_t tx_eq_addr = 0x47830;
 /* CPI option flags */
 static const uint32_t cpi_set = 0x2000;	/* 1 << 13 */
 static const uint32_t cpi_in_reset = 0x4000;	/* 1 << 14 */
 static const uint32_t bit_cpi_assert = 0x8000;	/* 1 << 15 */
+static const uint32_t dyn_rcfg_dr_trigger_reg;
+static const uint32_t dyn_rcfg_dr_next_profile_0_reg = 0x4;
+static const uint32_t dyn_rcfg_dr_next_profile_1_reg = 0x8;
+static const uint32_t dyn_rcfg_dr_next_profile_2_reg = 0xc;
 /*
  * Base Addresses for Avalon MM Secondary Components
  * static const uint32_t ADDR_AVMM_DR_CTRL_INT                  =  0x10035000 << 0;
@@ -35,6 +40,21 @@ static const uint32_t bit_cpi_assert = 0x8000;	/* 1 << 15 */
  *
  * ETH AVMM USER SPACE Registers Address Map
  */
+static const uint32_t eth_soft_csr1 = 0x200;
+static const uint32_t eth_soft_csr2 = 0x204;
+static const uint32_t eth_soft_csr3 = 0x208;
+
+static void nthw_phy_tile_set_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset)
+{
+	/* Reset is active low */
+	nthw_field_get_updated(p->mp_fld_port_config_reset[intf_no]);
+
+	if (reset)
+		nthw_field_clr_flush(p->mp_fld_port_config_reset[intf_no]);
+
+	else
+		nthw_field_set_flush(p->mp_fld_port_config_reset[intf_no]);
+}
 
 void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset)
 {
@@ -118,6 +138,38 @@ void nthw_phy_tile_write_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 		nt_os_wait_usec(100);
 }
 
+static uint32_t nthw_phy_tile_read_dyn_reconfig(nthw_phy_tile_t *p, uint32_t address)
+{
+	nthw_register_update(p->mp_reg_dyn_reconfig_base);
+	nthw_field_set_val32(p->mp_fld_dyn_reconfig_base_cmd, 0);
+	nthw_field_set_val_flush32(p->mp_fld_dyn_reconfig_base_ptr, address);
+
+	while (nthw_field_get_updated(p->mp_fld_dyn_reconfig_base_busy) == 1)
+		nt_os_wait_usec(100);
+
+	uint32_t value = nthw_field_get_updated(p->mp_fld_dyn_reconfig_data_data);
+	/*
+	 * NT_LOG(INF, NTHW, "nthw_phy_tile_read_dyn_reconfig address %0x value,
+	 * %0x", address, value);
+	 */
+	return value;
+	/* return nthw_field_get_updated(p->mp_fld_dyn_reconfig_data_data); */
+}
+
+static void nthw_phy_tile_write_dyn_reconfig(nthw_phy_tile_t *p, uint32_t address, uint32_t data)
+{
+	nthw_register_update(p->mp_reg_dyn_reconfig_data);
+	nthw_field_set_val_flush32(p->mp_fld_dyn_reconfig_data_data, data);
+
+	nthw_register_update(p->mp_reg_dyn_reconfig_base);
+	nthw_field_set_val32(p->mp_fld_dyn_reconfig_base_ptr, address);
+	nthw_field_set_val_flush32(p->mp_fld_dyn_reconfig_base_cmd, 1);
+
+	while (nthw_field_get_updated(p->mp_fld_dyn_reconfig_base_busy) == 1)
+		/* NT_LOG(INF, NTHW, "busy"); */
+		nt_os_wait_usec(100);
+}
+
 static uint32_t nthw_phy_tile_cpi_request(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	uint32_t data, uint8_t op_code, uint32_t cpi_assert,
 	uint32_t cpi_set_get)
@@ -199,3 +251,246 @@ void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_
 	 * intf_no, lane, enable);
 	 */
 }
+
+void nthw_phy_tile_set_tx_equalization(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
+	uint32_t pre_tap2, uint32_t main_tap, uint32_t pre_tap1,
+	uint32_t post_tap1)
+{
+	uint32_t data = (pre_tap2 << 16) + (main_tap << 10) + (pre_tap1 << 5) + (post_tap1);
+	NT_LOG(DBG, NTHW,
+		"intf_no %u: setTxEq lane %u, pre_tap2 %u, main_tap %u, pre_tap1 %u, post_tap1 %u data %x",
+		intf_no, lane, pre_tap2, main_tap, pre_tap1, post_tap1, data);
+	nthw_phy_tile_write_xcvr(p, intf_no, lane, tx_eq_addr + 0x8000U * lane, data);
+}
+
+static bool nthw_phy_tile_read_fec_enabled_by_scratch(nthw_phy_tile_t *p, uint8_t intf_no)
+{
+	bool fec_enabled = false;
+
+	if (p->mp_fld_scratch_data) {
+		fec_enabled =
+			!((nthw_field_get_updated(p->mp_fld_scratch_data) >> (intf_no)) & 0x1);
+	}
+
+	/*
+	 * log(INF,"intf_no: %d FEC state read from inverted port specificscratch register
+	 * value %u ", intf_no,fec_enabled);
+	 */
+	return fec_enabled;
+}
+
+static void nthw_phy_tile_write_fec_enabled_by_scratch(nthw_phy_tile_t *p, uint8_t intf_no,
+	bool fec_enabled)
+{
+	const uint8_t mask = intf_no == 0U ? 0xf0U : 0xfU;
+	const uint8_t status_other_port =
+		(uint8_t)(nthw_field_get_updated(p->mp_fld_scratch_data) & mask);
+	const uint8_t disablebit = (uint8_t)(1U << (4 * intf_no));
+	const uint8_t val =
+		fec_enabled ? status_other_port : (uint8_t)(status_other_port | disablebit);
+	/*  NT_LOG(INF, NTHW, "intf_no: %u write ScratchFEC value %u", intf_no, val); */
+	nthw_field_set_val_flush32(p->mp_fld_scratch_data, val);
+}
+
+uint32_t nthw_phy_tile_read_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address)
+{
+	nthw_register_update(p->mp_reg_port_eth_base[intf_no]);
+	nthw_field_set_val32(p->mp_fld_port_eth_base_cmd[intf_no], 0);
+	nthw_field_set_val_flush32(p->mp_fld_port_eth_base_ptr[intf_no], address);
+
+	while (nthw_field_get_updated(p->mp_fld_port_eth_base_busy[intf_no]) == 1)
+		nt_os_wait_usec(100);
+
+	return nthw_field_get_updated(p->mp_fld_port_eth_data_data[intf_no]);
+}
+
+void nthw_phy_tile_write_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address, uint32_t data)
+{
+	nthw_field_set_val_flush32(p->mp_fld_port_eth_data_data[intf_no], data);
+	nthw_register_update(p->mp_reg_port_eth_base[intf_no]);
+	nthw_field_set_val32(p->mp_fld_port_eth_base_ptr[intf_no], address);
+	nthw_field_set_val_flush32(p->mp_fld_port_eth_base_cmd[intf_no], 1);
+
+	while (nthw_field_get_updated(p->mp_fld_port_eth_base_busy[intf_no]) == 1)
+		/* NT_LOG(INF, NTHW, "busy"); */
+		nt_os_wait_usec(100);
+}
+
+bool nthw_phy_tile_configure_fec(nthw_phy_tile_t *p, uint8_t intf_no, bool enable)
+{
+	/*
+	 * FPGA must have the Dynamic Reconfig register for FEC configuration to work.
+	 * Previous versions of the FPGA enable FEC statically.
+	 */
+	if (!p->mp_reg_dyn_reconfig_base)
+		return false;
+
+	/*
+	 * NT_LOG(INF, NTHW, "void nthw_phy_tile_configure_fec(intf_no %u, enable %u)",
+	 * intf_no, enable);
+	 */
+
+	/* Available DR profiles related to FEC */
+	/* Used as end symbol in profile sequence fed to NIOS processor - not really a profile. */
+	const uint32_t neutral_dr_profile = 0;
+
+	/* DR Fec profiles port 0*/
+	const uint32_t intf_no0_with_fec_dr_profile = 1;
+	const uint32_t intf_no0_no_fec_dr_profile = 2;
+
+	/* DR Fec profiles port 1 */
+	const uint32_t intf_no1_with_fec_dr_profile = 3;
+	const uint32_t intf_no1_no_fec_dr_profile = 4;
+
+	const uint32_t fec_profile_none = 0x00;
+	const uint32_t fec_profile_cl91 = 0x02;
+
+	uint32_t original_dr_profile_id = 0x00;
+	uint32_t destination_dr_profile_id = 0x00;
+	uint32_t final_fec_profile = 0x00;
+
+	if (intf_no == 0) {
+		original_dr_profile_id =
+			enable ? intf_no0_no_fec_dr_profile : intf_no0_with_fec_dr_profile;
+		destination_dr_profile_id =
+			enable ? intf_no0_with_fec_dr_profile : intf_no0_no_fec_dr_profile;
+
+	} else if (intf_no == 1) {
+		original_dr_profile_id =
+			enable ? intf_no1_no_fec_dr_profile : intf_no1_with_fec_dr_profile;
+		destination_dr_profile_id =
+			enable ? intf_no1_with_fec_dr_profile : intf_no1_no_fec_dr_profile;
+	}
+
+	final_fec_profile = enable ? fec_profile_cl91 : fec_profile_none;
+
+	/*
+	 * These steps are copied from a code example provided by Intel: ftile_eth_dr_test.tcl
+	 * Step 6: Program DUT soft CSR
+	 * The CSR registers are reset by the FPGA reset sequence so
+	 * they need to be set every time the driver is restarted.
+	 * This is why we perform step 6 first before step 1.
+	 */
+	uint32_t current_fec_profile = nthw_phy_tile_read_eth(p, intf_no, eth_soft_csr2);
+
+	if (current_fec_profile != final_fec_profile) {
+		nthw_phy_tile_set_reset(p, intf_no, true);
+		nthw_phy_tile_set_tx_reset(p, intf_no, true);
+		NT_LOG(DBG, NTHW, "intf_no %u: Program DUT soft CSR", intf_no);
+		/* Select profile */
+		nthw_phy_tile_write_eth(p, intf_no, eth_soft_csr1, 0x00);
+
+		/* Select FEC-Mode */
+		nthw_phy_tile_write_eth(p, intf_no, eth_soft_csr2,
+			(0 << 9) + (0 << 6) + (0 << 3) + (final_fec_profile << 0));
+
+		nt_os_wait_usec(10000);
+		nthw_phy_tile_set_reset(p, intf_no, false);
+		nthw_phy_tile_set_tx_reset(p, intf_no, false);
+
+		NT_LOG(DBG, NTHW, "intf_no %u: Register eth_soft_csr1 profile_sel: 0x%2.2x",
+			intf_no, nthw_phy_tile_read_eth(p, intf_no, eth_soft_csr1));
+		NT_LOG(DBG, NTHW, "intf_no %u: Register eth_soft_csr2 fec_mode:    0x%2.2x",
+			intf_no, nthw_phy_tile_read_eth(p, intf_no, eth_soft_csr2));
+		NT_LOG(DBG, NTHW, "intf_no %u: Register eth_soft_csr3 sel:         0x%2.2x",
+			intf_no, nthw_phy_tile_read_eth(p, intf_no, eth_soft_csr3));
+	}
+
+	/*
+	 * The FEC profile applied with Dynamic Reconfiguration is persistent through
+	 * a driver restart. Additionally, the operation is not idempotent, meaning that
+	 * the operations must only be performed when actual reconfiguration is necessary.
+	 * We use a persistent scratch register provided by the FPGA to store the FEC
+	 * state since we have not been able to get any of the methods suggested
+	 * by Intel to function properly.
+	 */
+	if (nthw_phy_tile_read_fec_enabled_by_scratch(p, intf_no) == enable)
+		return true;
+
+	/* Step 1: Wait for DR NIOS to be ready */
+	NT_LOG(DBG, NTHW, "intf_no %u: Step 1 Wait for DR NIOS", intf_no);
+
+	while ((nthw_phy_tile_read_dyn_reconfig(p, dyn_rcfg_dr_trigger_reg) & 0x02) != 0x02)
+		nt_os_wait_usec(10000);
+
+	/* Step 2: Triggering Reconfiguration */
+	NT_LOG(DBG, NTHW, "intf_no %u: Step 2: Triggering Reconfiguration", intf_no);
+
+	nthw_phy_tile_set_reset(p, intf_no, true);
+	nthw_phy_tile_set_rx_reset(p, intf_no, true);
+	nthw_phy_tile_set_tx_reset(p, intf_no, true);
+	nt_os_wait_usec(10000);
+
+	/* Disable original profile */
+	nthw_phy_tile_write_dyn_reconfig(p, dyn_rcfg_dr_next_profile_0_reg,
+		(1U << 18) + (0U << 15) + original_dr_profile_id);
+	nt_os_wait_usec(10000);
+	NT_LOG(DBG, NTHW, "intf_no %u: dyn_rcfg_dr_next_profile_0_reg: %#010x", intf_no,
+		nthw_phy_tile_read_dyn_reconfig(p, dyn_rcfg_dr_next_profile_0_reg));
+
+	nthw_phy_tile_write_dyn_reconfig(p, dyn_rcfg_dr_next_profile_1_reg,
+		(1U << 15) + destination_dr_profile_id + (0U << 31) +
+		(neutral_dr_profile << 16));
+	/*
+	 * Enable profile 2 and terminate dyn reconfig by
+	 * setting next profile to 0 and deactivate it
+	 */
+	nt_os_wait_usec(10000);
+	NT_LOG(DBG, NTHW, "intf_no %u: dyn_rcfg_dr_next_profile_1_reg: %#010x", intf_no,
+		nthw_phy_tile_read_dyn_reconfig(p, dyn_rcfg_dr_next_profile_1_reg));
+
+	/*
+	 * We do not know if this neutral profile is necessary.
+	 * It is done in the example design and INTEL has not
+	 * answered our question if it is necessary or not.
+	 */
+	nthw_phy_tile_write_dyn_reconfig(p, dyn_rcfg_dr_next_profile_2_reg,
+		(0U << 15) + neutral_dr_profile + (0U << 31) +
+		(neutral_dr_profile << 16));
+	nt_os_wait_usec(10000);
+	NT_LOG(DBG, NTHW, "intf_no %u: dyn_rcfg_dr_next_profile_2_reg: %#010x", intf_no,
+		nthw_phy_tile_read_dyn_reconfig(p, dyn_rcfg_dr_next_profile_2_reg));
+
+	nt_os_wait_usec(10000);
+
+	/* Step 3: Trigger DR interrupt */
+	NT_LOG(DBG, NTHW, "intf_no %u: Step 3: Trigger DR interrupt", intf_no);
+	nthw_phy_tile_write_dyn_reconfig(p, dyn_rcfg_dr_trigger_reg, 0x00000001);
+
+	nt_os_wait_usec(1000000);
+
+	/* Step 4: Wait for interrupt Acknowledge */
+	NT_LOG(DBG, NTHW, "intf_no %u: Step 4: Wait for interrupt Acknowledge", intf_no);
+
+	while ((nthw_phy_tile_read_dyn_reconfig(p, dyn_rcfg_dr_trigger_reg) & 0x01) != 0x00)
+		nt_os_wait_usec(10000);
+
+	nt_os_wait_usec(10000);
+
+	/* Step 5: Wait Until DR config is done */
+	NT_LOG(DBG, NTHW, "intf_no %u: Step 5: Wait Until DR config is done", intf_no);
+
+	while ((nthw_phy_tile_read_dyn_reconfig(p, dyn_rcfg_dr_trigger_reg) & 0x02) != 0x02)
+		nt_os_wait_usec(10000);
+
+	nt_os_wait_usec(1000000);
+
+	/* Write Fec status to scratch register */
+	nthw_phy_tile_write_fec_enabled_by_scratch(p, intf_no, enable);
+
+	nt_os_wait_usec(1000000);
+
+	nthw_phy_tile_set_reset(p, intf_no, false);
+	nthw_phy_tile_set_tx_reset(p, intf_no, false);
+	nthw_phy_tile_set_rx_reset(p, intf_no, false);
+
+	nthw_register_update(p->mp_reg_dr_cfg_status);
+	NT_LOG(DBG, NTHW, "intf_no %u: DrCfgStatusCurrPofileId: %u", intf_no,
+		nthw_field_get_val32(p->mp_fld_dr_cfg_status_curr_profile_id));
+	NT_LOG(DBG, NTHW, "intf_no %u: DrCfgStatusInProgress:  %u", intf_no,
+		nthw_field_get_val32(p->mp_fld_dr_cfg_status_in_progress));
+	NT_LOG(DBG, NTHW, "intf_no %u: DrCfgStatusError: %u", intf_no,
+		nthw_field_get_val32(p->mp_fld_dr_cfg_status_error));
+
+	return true;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 09/32] net/ntnic: add nim low power API
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (7 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 08/32] net/ntnic: add port post init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 10/32] net/ntnic: add link handling API Serhii Iliushyk
                   ` (24 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Add NIM reset and low power functions with presence check

- Implement nim_set_reset function to handle NIM reset.
- Implement set_nim_low_power function to manage
NIM power state.
- Add code to check NIM presence before performing reset.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 53 +++++++++++++++++++
 .../ntnic/nthw/core/include/nthw_pcal6416a.h  |  1 +
 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c  | 39 ++++++++++++++
 3 files changed, 93 insertions(+)

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index fe2acef612..9193f21f6f 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -201,6 +201,17 @@ static int phy_set_line_loopback(adapter_info_t *drv, int port, loopback_line_t
  * Nim handling
  */
 
+static void nim_set_reset(struct nim_i2c_ctx *ctx, uint8_t nim_idx, bool reset)
+{
+	nthw_pcal6416a_t *p = ctx->hwagx.p_io_nim;
+
+	if (nim_idx == 0)
+		nthw_pcal6416a_write(p, 0, reset ? 0 : 1);
+
+	else if (nim_idx == 1)
+		nthw_pcal6416a_write(p, 4, reset ? 0 : 1);
+}
+
 static bool nim_is_present(nim_i2c_ctx_p ctx, uint8_t nim_idx)
 {
 	assert(nim_idx < NUM_ADAPTER_PORTS_MAX);
@@ -217,6 +228,20 @@ static bool nim_is_present(nim_i2c_ctx_p ctx, uint8_t nim_idx)
 	return data == 0;
 }
 
+static void set_nim_low_power(nim_i2c_ctx_p ctx, uint8_t nim_idx, bool low_power)
+{
+	nthw_pcal6416a_t *p = ctx->hwagx.p_io_nim;
+
+	if (nim_idx == 0) {
+		/* De-asserting LP mode pin 1 */
+		nthw_pcal6416a_write(p, 1, low_power ? 1 : 0);
+
+	} else if (nim_idx == 1) {
+		/* De-asserting LP mode pin 5 */
+		nthw_pcal6416a_write(p, 5, low_power ? 1 : 0);
+	}
+}
+
 /*
  * Utility functions
  */
@@ -335,6 +360,25 @@ static int create_nim(adapter_info_t *drv, int port, bool enable)
 		phy_reset_tx(drv, port);
 	}
 
+	/*
+	 * Check NIM is present before doing reset.
+	 */
+
+	if (!nim_is_present(nim_ctx, port)) {
+		NT_LOG(DBG, NTNIC, "%s: NIM module is no longer absent!",
+			drv->mp_port_id_str[port]);
+		return -1;
+	}
+
+	/*
+	 * Reset NIM
+	 */
+
+	NT_LOG(DBG, NTNIC, "%s: Performing NIM reset", drv->mp_port_id_str[port]);
+	nim_set_reset(nim_ctx, (uint8_t)port, true);
+	nt_os_wait_usec(100000);/*  pause 0.1s */
+	nim_set_reset(nim_ctx, (uint8_t)port, false);
+
 	/*
 	 * Wait a little after a module has been inserted before trying to access I2C
 	 * data, otherwise the module will not respond correctly.
@@ -369,6 +413,15 @@ static int create_nim(adapter_info_t *drv, int port, bool enable)
 		return -1;
 	}
 
+	if (enable) {
+		NT_LOG(DBG, NTNIC, "%s: De-asserting low power", drv->mp_port_id_str[port]);
+		set_nim_low_power(nim_ctx, port, false);
+
+	} else {
+		NT_LOG(DBG, NTNIC, "%s: Asserting low power", drv->mp_port_id_str[port]);
+		set_nim_low_power(nim_ctx, port, true);
+	}
+
 	return res;
 }
 
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
index 5ef14a0bc9..a718b59a29 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
@@ -24,6 +24,7 @@ struct nthw_pcal6416a {
 
 typedef struct nthw_pcal6416a nthw_pcal6416a_t;
 
+void nthw_pcal6416a_write(nthw_pcal6416a_t *p, uint8_t pin, uint8_t value);
 void nthw_pcal6416a_read(nthw_pcal6416a_t *p, uint8_t pin, uint8_t *value);
 
 #endif	/* __NTHW_PCAL6416A_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c b/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
index 37b6e7ec57..dd803ac66d 100644
--- a/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
+++ b/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
@@ -13,11 +13,50 @@
 #include "nthw_pcal6416a.h"
 
 static const uint8_t read_port[2] = { 0x00, 0x01 };
+static const uint8_t write_port[2] = { 0x02, 0x03 };
+static const uint8_t config_port[2] = { 0x06, 0x07 };
 
 /*
  * PCAL6416A I/O expander class
  */
 
+void nthw_pcal6416a_write(nthw_pcal6416a_t *p, uint8_t pin, uint8_t value)
+{
+	uint8_t port;
+	uint8_t data;
+
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_ca9849, p->m_mux_channel);
+
+	if (pin < 8) {
+		port = 0;
+
+	} else {
+		port = 1;
+		pin = (uint8_t)(pin - 8);
+	}
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, write_port[port], &data);
+
+	if (value == 0)
+		data = (uint8_t)(data & (~(uint8_t)(1 << pin)));
+
+	else
+		data = (uint8_t)(data | (1 << pin));
+
+	nthw_i2cm_write(p->mp_nt_i2cm, p->m_dev_address, write_port[port], data);
+
+	/* Enable pin as output pin when writing to it first time */
+	data = (uint8_t)(p->m_config_data[port] & (~(uint8_t)(1 << pin)));
+
+	if (data != p->m_config_data[port]) {
+		nthw_i2cm_write(p->mp_nt_i2cm, p->m_dev_address, config_port[port], data);
+		p->m_config_data[port] = data;
+	}
+
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+}
+
 void nthw_pcal6416a_read(nthw_pcal6416a_t *p, uint8_t pin, uint8_t *value)
 {
 	uint8_t port;
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 10/32] net/ntnic: add link handling API
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (8 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 09/32] net/ntnic: add nim low power API Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 11/32] net/ntnic: add port init to the state machine Serhii Iliushyk
                   ` (23 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Add link state management and NIM reset functionality

- Implement phy_get_link_state to retrieve PHY link state.
- Implement adjust_maturing_delay to adjust link maturing delay.
- Implement get/set to operate current link state.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 171 ++++++++++++++++++
 drivers/net/ntnic/meson.build                 |   1 +
 .../ntnic/nthw/core/include/nthw_pca9532.h    |  22 +++
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |   9 +
 drivers/net/ntnic/nthw/core/nthw_pca9532.c    |  40 ++++
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   |  51 +++++-
 drivers/net/ntnic/nthw/nthw_drv.h             |   2 +
 7 files changed, 295 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_pca9532.c

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 9193f21f6f..00a30f24a5 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -43,6 +43,38 @@ void link_agx_100g_init(void)
  * Phy handling
  */
 
+static void phy_get_link_state(adapter_info_t *drv,
+	int port,
+	nt_link_state_p p_curr_link_state,
+	nt_link_state_p p_latched_links_state,
+	uint32_t *p_local_fault,
+	uint32_t *p_remote_fault)
+{
+	uint32_t status = 0;
+	uint32_t status_latch = 0;
+
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+
+	nthw_phy_tile_get_link_summary(p,
+		&status,
+		&status_latch,
+		p_local_fault,
+		p_remote_fault,
+		port);
+
+	if (status == 0x0)
+		*p_curr_link_state = NT_LINK_STATE_DOWN;
+
+	else
+		*p_curr_link_state = NT_LINK_STATE_UP;
+
+	if (status_latch == 0x0)
+		*p_latched_links_state = NT_LINK_STATE_DOWN;
+
+	else
+		*p_latched_links_state = NT_LINK_STATE_UP;
+}
+
 static void phy_rx_path_rst(adapter_info_t *drv, int port, bool reset)
 {
 	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
@@ -242,6 +274,135 @@ static void set_nim_low_power(nim_i2c_ctx_p ctx, uint8_t nim_idx, bool low_power
 	}
 }
 
+/*
+ * Link handling
+ */
+
+static void adjust_maturing_delay(adapter_info_t *drv, int port)
+{
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+	nthw_rpf_t *p_rpf = drv->fpga_info.mp_nthw_agx.p_rpf;
+	/*
+	 * Find the maximum of the absolute values of the RX componensation for all
+	 * ports (the RX componensation may not be set for some of the other ports).
+	 */
+	const int16_t unset_rx_compensation = -1;	/* 0xffff */
+	int16_t max_comp = 0;
+
+	for (int i = 0; i < drv->fpga_info.n_phy_ports; i++) {
+		int16_t comp = (int16_t)nthw_phy_tile_get_timestamp_comp_rx(p, i);
+
+		if (comp != unset_rx_compensation && abs(comp) > abs(max_comp))
+			max_comp = comp;
+	}
+
+	int delay = nthw_rpf_get_maturing_delay(p_rpf) - max_comp;
+
+	/*
+	 * For SOF time-stamping account for jumbo frame.
+	 * Frame size = 80000 b. divided by Gb link speed = processing time in ns.
+	 */
+	if (!nthw_rpf_get_ts_at_eof(p_rpf)) {
+		uint32_t jumbo_frame_processing_time_ns = 80000U / 100U;
+		delay -= (int)jumbo_frame_processing_time_ns;
+	}
+
+	const unsigned int delay_bit_width = 19;/* 19 bits maturing delay */
+	const int min_delay = -(1 << (delay_bit_width - 1));
+	const int max_delay = 0;
+
+	if (delay >= min_delay && delay <= max_delay) {
+		nthw_rpf_set_maturing_delay(p_rpf, delay);
+
+	} else {
+		NT_LOG(WRN, NTNIC,
+			"Port %u: Cannot set the RPF adjusted maturing delay to %i because "
+			"that value is outside the legal range [%i:%i]",
+			port, delay, min_delay, max_delay);
+	}
+}
+
+static void set_link_state(adapter_info_t *drv, nim_i2c_ctx_p ctx, link_state_t *state, int port)
+{
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+	/*
+	 * 100G: 4 LEDs per port
+	 */
+
+	bool led_on = state->nim_present && state->link_state == NT_LINK_STATE_UP;
+	uint8_t led_pos = (uint8_t)(port * ctx->lane_count);
+
+	for (uint8_t i = 0; i < ctx->lane_count; i++) {
+		nthw_pca9532_set_led_on(drv->fpga_info.mp_nthw_agx.p_pca9532_led, led_pos + 1,
+			led_on);
+	}
+
+	nthw_phy_tile_set_timestamp_comp_rx(p, port, 0);
+
+	if (ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena) {
+		/* Updated after mail from JKH 2023-02-07 */
+		nthw_phy_tile_set_timestamp_comp_rx(p, port, 0x9E);
+		/* TODO Hermosa Awaiting comp values to use */
+
+	} else {
+		/* TODO Hermosa Awaiting comp values to use */
+		nthw_phy_tile_set_timestamp_comp_rx(p, port, 0);
+	}
+
+	adjust_maturing_delay(drv, port);	/* MUST be called after timestampCompRx */
+}
+
+static void get_link_state(adapter_info_t *drv, nim_i2c_ctx_p ctx, link_state_t *state, int port)
+{
+	uint32_t local_fault;
+	uint32_t remote_fault;
+	nt_link_state_t curr_link_state;
+
+	nthw_phy_tile_t *p = drv->fpga_info.mp_nthw_agx.p_phy_tile;
+
+	/* Save the current state before reading the new */
+	curr_link_state = state->link_state;
+
+	phy_get_link_state(drv, port, &state->link_state, &state->link_state_latched, &local_fault,
+		&remote_fault);
+
+	if (curr_link_state != state->link_state)
+		NT_LOG(DBG, NTNIC, "Port %d: Faults(Local = %d, Remote = %d)", port, local_fault,
+			remote_fault);
+
+	state->nim_present = nim_is_present(ctx, port);
+
+	if (!state->nim_present)
+		return;	/* No nim so no need to do anything */
+
+	state->link_up = state->link_state == NT_LINK_STATE_UP ? true : false;
+
+	if (state->link_state == NT_LINK_STATE_UP)
+		return;	/* The link is up so no need to do anything else */
+
+	if (remote_fault == 0) {
+		phy_reset_rx(drv, port);
+		NT_LOG(DBG, NTNIC, "Port %u: resetRx due to local fault.", port);
+		return;
+	}
+
+	/* In case of too many errors perform a reset */
+	if (nthw_phy_tile_get_rx_hi_ber(p, port)) {
+		NT_LOG(INF, NTNIC, "Port %u: HiBer", port);
+		phy_reset_rx(drv, port);
+		return;
+	}
+
+	/* If FEC is not enabled then no reason to look at FEC state */
+	if (!ctx->specific_u.qsfp.specific_u.qsfp28.media_side_fec_ena ||
+		nthw_phy_tile_read_fec_enabled_by_scratch(p, port)) {
+		return;
+	}
+
+	if (!nthw_phy_tile_get_rx_am_lock(p, port))
+		phy_reset_rx(drv, port);
+}
+
 /*
  * Utility functions
  */
@@ -645,6 +806,7 @@ static void *_common_ptp_nim_state_machine(void *data)
 
 	while (monitor_task_is_running[adapter_no]) {
 		int i;
+		static bool reported_link[NUM_ADAPTER_PORTS_MAX] = { false };
 
 		for (i = 0; i < nb_ports; i++) {
 			const bool is_port_disabled = link_info->port_action[i].port_disable;
@@ -691,12 +853,14 @@ static void *_common_ptp_nim_state_machine(void *data)
 				continue;
 			}
 
+			get_link_state(drv, nim_ctx, &link_state[i], i);
 			link_state[i].link_disabled = is_port_disabled;
 
 			if (!link_state[i].nim_present) {
 				if (!link_state[i].lh_nim_absent) {
 					NT_LOG(INF, NTNIC, "%s: NIM module removed",
 						drv->mp_port_id_str[i]);
+					reported_link[i] = false;
 					link_state[i].link_up = false;
 					link_state[i].lh_nim_absent = true;
 
@@ -707,6 +871,13 @@ static void *_common_ptp_nim_state_machine(void *data)
 
 				continue;
 			}
+
+			if (reported_link[i] != link_state[i].link_up) {
+				NT_LOG(INF, NTNIC, "%s: link is %s", drv->mp_port_id_str[i],
+					(link_state[i].link_up ? "up" : "down"));
+				reported_link[i] = link_state[i].link_up;
+				set_link_state(drv, nim_ctx, &link_state[i], i);
+			}
 		}
 
 		if (monitor_task_is_running[adapter_no])
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index b1505c5549..92aad6f94d 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -55,6 +55,7 @@ sources = files(
         'nthw/core/nthw_iic.c',
         'nthw/core/nthw_mac_pcs.c',
         'nthw/core/nthw_pcie3.c',
+        'nthw/core/nthw_pca9532.c',
         'nthw/core/nthw_pcal6416a.c',
         'nthw/core/nthw_phy_tile.c',
         'nthw/core/nthw_si5332_si5156.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h b/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
new file mode 100644
index 0000000000..24da937a18
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_PCA9532_H__
+#define __NTHW_PCA9532_H__
+
+#include "nthw_si5332_si5156.h"
+
+struct nthw_pca9532 {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_dev_address;
+	nthw_pca9849_t *mp_ca9849;
+	uint8_t m_mux_channel;
+};
+
+typedef struct nthw_pca9532 nthw_pca9532_t;
+
+void nthw_pca9532_set_led_on(nthw_pca9532_t *p, uint8_t led_pos, bool state_on);
+
+#endif	/* __NTHW_PCA9532_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
index c810f55c0d..f84aef44a9 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -74,8 +74,17 @@ void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_
 void nthw_phy_tile_set_tx_equalization(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	uint32_t pre_tap2, uint32_t main_tap, uint32_t pre_tap1,
 	uint32_t post_tap1);
+void nthw_phy_tile_get_link_summary(nthw_phy_tile_t *p, uint32_t *p_nt_phy_link_state,
+	uint32_t *p_ll_nt_phy_link_state, uint32_t *p_lh_local_fault,
+	uint32_t *p_lh_remote_fault, uint8_t index);
 void nthw_phy_tile_set_tx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
 void nthw_phy_tile_set_rx_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset);
+bool nthw_phy_tile_read_fec_enabled_by_scratch(nthw_phy_tile_t *p, uint8_t intf_no);
+
+bool nthw_phy_tile_get_rx_hi_ber(nthw_phy_tile_t *p, uint8_t intf_no);
+bool nthw_phy_tile_get_rx_am_lock(nthw_phy_tile_t *p, uint8_t intf_no);
+void nthw_phy_tile_set_timestamp_comp_rx(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t value);
+uint32_t nthw_phy_tile_get_timestamp_comp_rx(nthw_phy_tile_t *p, uint8_t intf_no);
 
 uint32_t nthw_phy_tile_read_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address);
 void nthw_phy_tile_write_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address, uint32_t data);
diff --git a/drivers/net/ntnic/nthw/core/nthw_pca9532.c b/drivers/net/ntnic/nthw/core/nthw_pca9532.c
new file mode 100644
index 0000000000..fcf5463fcb
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_pca9532.c
@@ -0,0 +1,40 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include <pthread.h>
+
+#include "nt_util.h"
+#include "ntlog.h"
+
+#include "nthw_drv.h"
+#include "nthw_register.h"
+
+#include "nthw_pca9532.h"
+
+static const uint8_t led_sel_reg[4] = { 6, 7, 8, 9 };
+
+void nthw_pca9532_set_led_on(nthw_pca9532_t *p, uint8_t led_pos, bool state_on)
+{
+	if (led_pos >= 16) {
+		NT_LOG(ERR, NTHW, "Led pos (%u) out of range", led_pos);
+		return;
+	}
+
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_ca9849, p->m_mux_channel);
+
+	uint8_t reg_addr = led_sel_reg[led_pos / 4];
+	uint8_t bit_pos = (uint8_t)((led_pos % 4) * 2);
+	uint8_t data = 0U;
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, reg_addr, &data);
+	data = data & (uint8_t)(~(0b11 << bit_pos));	/* Set bits to "00" aka off */
+
+	if (state_on)
+		data = (uint8_t)(data | (0b01 << bit_pos));
+
+	nthw_i2cm_write(p->mp_nt_i2cm, p->m_dev_address, reg_addr, data);
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
index 42e2782f99..b057e9e88c 100644
--- a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -263,7 +263,34 @@ void nthw_phy_tile_set_tx_equalization(nthw_phy_tile_t *p, uint8_t intf_no, uint
 	nthw_phy_tile_write_xcvr(p, intf_no, lane, tx_eq_addr + 0x8000U * lane, data);
 }
 
-static bool nthw_phy_tile_read_fec_enabled_by_scratch(nthw_phy_tile_t *p, uint8_t intf_no)
+void nthw_phy_tile_get_link_summary(nthw_phy_tile_t *p, uint32_t *p_nt_phy_link_state,
+	uint32_t *p_ll_nt_phy_link_state, uint32_t *p_lh_local_fault,
+	uint32_t *p_lh_remote_fault, uint8_t index)
+{
+	nthw_register_update(p->mp_reg_link_summary[index]);
+
+	if (p_nt_phy_link_state) {
+		*p_nt_phy_link_state =
+			nthw_field_get_val32(p->mp_fld_link_summary_nt_phy_link_state[index]);
+	}
+
+	if (p_ll_nt_phy_link_state) {
+		*p_ll_nt_phy_link_state =
+			nthw_field_get_val32(p->mp_fld_link_summary_ll_nt_phy_link_state[index]);
+	}
+
+	if (p_lh_local_fault) {
+		*p_lh_local_fault =
+			nthw_field_get_val32(p->mp_fld_link_summary_lh_received_local_fault[index]);
+	}
+
+	if (p_lh_remote_fault) {
+		*p_lh_remote_fault =
+			nthw_field_get_val32(p->mp_fld_link_summary_lh_remote_fault[index]);
+	}
+}
+
+bool nthw_phy_tile_read_fec_enabled_by_scratch(nthw_phy_tile_t *p, uint8_t intf_no)
 {
 	bool fec_enabled = false;
 
@@ -292,6 +319,28 @@ static void nthw_phy_tile_write_fec_enabled_by_scratch(nthw_phy_tile_t *p, uint8
 	nthw_field_set_val_flush32(p->mp_fld_scratch_data, val);
 }
 
+bool nthw_phy_tile_get_rx_hi_ber(nthw_phy_tile_t *p, uint8_t intf_no)
+{
+	return nthw_field_get_updated(p->mp_fld_port_status_rx_hi_ber[intf_no]);
+}
+
+bool nthw_phy_tile_get_rx_am_lock(nthw_phy_tile_t *p, uint8_t intf_no)
+{
+	return nthw_field_get_updated(p->mp_fld_port_status_rx_am_lock[intf_no]);
+}
+
+void nthw_phy_tile_set_timestamp_comp_rx(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t value)
+{
+	nthw_field_get_updated(p->mp_fld_port_comp_rx_compensation[intf_no]);
+	nthw_field_set_val_flush32(p->mp_fld_port_comp_rx_compensation[intf_no], value);
+}
+
+uint32_t nthw_phy_tile_get_timestamp_comp_rx(nthw_phy_tile_t *p, uint8_t intf_no)
+{
+	nthw_field_get_updated(p->mp_fld_port_comp_rx_compensation[intf_no]);
+	return nthw_field_get_val32(p->mp_fld_port_comp_rx_compensation[intf_no]);
+}
+
 uint32_t nthw_phy_tile_read_eth(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t address)
 {
 	nthw_register_update(p->mp_reg_port_eth_base[intf_no]);
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index 1fc8df52ce..a3c54846f5 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -11,6 +11,7 @@
 
 #include "nthw_si5332_si5156.h"
 #include "nthw_pcal6416a.h"
+#include "nthw_pca9532.h"
 #include "nthw_phy_tile.h"
 #include "nthw_rpf.h"
 #include "nthw_phy_tile.h"
@@ -22,6 +23,7 @@ typedef struct nthw_agx_s {
 	nthw_i2cm_t *p_i2cm;
 	nthw_pca9849_t *p_pca9849;
 	nthw_pcal6416a_t *p_io_nim;	/* PCAL6416A I/O expander for controlling TS */
+	nthw_pca9532_t *p_pca9532_led;
 	nthw_phy_tile_t *p_phy_tile;
 	nthw_rpf_t *p_rpf;
 } nthw_agx_t;
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 11/32] net/ntnic: add port init to the state machine
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (9 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 10/32] net/ntnic: add link handling API Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 12/32] net/ntnic: add port disable API Serhii Iliushyk
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Handle NIM module insertion and initialization

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 00a30f24a5..33d39ce62f 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -872,6 +872,39 @@ static void *_common_ptp_nim_state_machine(void *data)
 				continue;
 			}
 
+			/*
+			 * NIM module is present
+			 */
+			if (link_state[i].lh_nim_absent && link_state[i].nim_present) {
+				sfp_nim_state_t new_state;
+				NT_LOG(INF, NTNIC, "%s: NIM module inserted",
+					drv->mp_port_id_str[i]);
+
+				if (_port_init(drv, fpga, i)) {
+					NT_LOG(ERR, NTNIC,
+						"%s: Failed to initialize NIM module",
+						drv->mp_port_id_str[i]);
+					continue;
+				}
+
+				if (nim_state_build(&nim_ctx[i], &new_state)) {
+					NT_LOG(ERR, NTNIC, "%s: Cannot read basic NIM data",
+						drv->mp_port_id_str[i]);
+					continue;
+				}
+
+				assert(new_state.br);	/* Cannot be zero if NIM is present */
+				NT_LOG(DBG, NTNIC,
+					"%s: NIM id = %u (%s), br = %u, vendor = '%s', pn = '%s', sn='%s'",
+					drv->mp_port_id_str[i], nim_ctx->nim_id,
+					nim_id_to_text(nim_ctx->nim_id), (unsigned int)new_state.br,
+					nim_ctx->vendor_name, nim_ctx->prod_no, nim_ctx->serial_no);
+				link_state[i].lh_nim_absent = false;
+				NT_LOG(DBG, NTNIC, "%s: NIM module initialized",
+					drv->mp_port_id_str[i]);
+				continue;
+			}
+
 			if (reported_link[i] != link_state[i].link_up) {
 				NT_LOG(INF, NTNIC, "%s: link is %s", drv->mp_port_id_str[i],
 					(link_state[i].link_up ? "up" : "down"));
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 12/32] net/ntnic: add port disable API
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (10 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 11/32] net/ntnic: add port init to the state machine Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 13/32] net/ntnic: add minimal initialization new NIC NT400D13 Serhii Iliushyk
                   ` (21 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Added logic to check if the administrative port state
has changed.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../link_agx_100g/nt4ga_agx_link_100g.c       | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
index 33d39ce62f..3f59c4a6b8 100644
--- a/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
@@ -501,6 +501,14 @@ set_loopback(struct adapter_info_s *p_adapter_info, int port, uint32_t mode, uin
 	nt_os_wait_usec(10000);	/* 10ms - arbitrary choice */
 }
 
+static void port_disable(adapter_info_t *drv, int port)
+{
+	nim_i2c_ctx_t *nim_ctx = &drv->nt4ga_link.u.nim_ctx[port];
+	phy_reset_rx(drv, port);
+	phy_reset_tx(drv, port);
+	set_nim_low_power(nim_ctx, port, true);
+}
+
 /*
  * Initialize NIM, Code based on nt400d1x.cpp: MyPort::createNim()
  */
@@ -822,6 +830,17 @@ static void *_common_ptp_nim_state_machine(void *data)
 			 */
 			assert(!(disable_port && enable_port));
 
+			if (disable_port) {
+				memset(&link_state[i], 0, sizeof(link_state[i]));
+				link_state[i].link_disabled = true;
+				link_state[i].lh_nim_absent = true;
+				reported_link[i] = false;
+				port_disable(drv, i);
+				NT_LOG(INF, NTNIC, "%s: Port %i is disabled",
+					drv->mp_port_id_str[i], i);
+				continue;
+			}
+
 			if (enable_port) {
 				link_state[i].link_disabled = false;
 				NT_LOG(DBG, NTNIC, "%s: Port %i is enabled",
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 13/32] net/ntnic: add minimal initialization new NIC NT400D13
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (11 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 12/32] net/ntnic: add port disable API Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 14/32] net/ntnic: add minimal reset FPGA Serhii Iliushyk
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Add function and structures required to init the new NIC NT400D13

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 doc/guides/nics/ntnic.rst                     |  7 +++++-
 doc/guides/rel_notes/release_25_03.rst        |  4 ++++
 drivers/net/ntnic/meson.build                 |  1 +
 .../net/ntnic/nthw/core/include/nthw_fpga.h   |  8 +++++++
 .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   | 23 +++++++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_fpga.c       | 20 ++++++++++++++++
 drivers/net/ntnic/nthw/nthw_platform.c        |  3 +++
 drivers/net/ntnic/nthw/nthw_platform_drv.h    |  2 ++
 drivers/net/ntnic/ntnic_ethdev.c              |  1 +
 9 files changed, 68 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c

diff --git a/doc/guides/nics/ntnic.rst b/doc/guides/nics/ntnic.rst
index f186822504..f519a9f083 100644
--- a/doc/guides/nics/ntnic.rst
+++ b/doc/guides/nics/ntnic.rst
@@ -27,8 +27,13 @@ Supported NICs
 
     - FPGA ID 9563 (Inline Flow Management)
 
-All information about NT200A02 can be found by link below:
+- NT400D13 2x100G SmartNIC
+
+    - FPGA ID 9574 (Inline Flow Management)
+
+All information about NT200A02 and NT400D13 can be found by links below:
 https://www.napatech.com/products/nt200a02-smartnic-inline/
+https://www.napatech.com/support/resources/data-sheets/link-inline-software-for-napatech/
 
 
 Features
diff --git a/doc/guides/rel_notes/release_25_03.rst b/doc/guides/rel_notes/release_25_03.rst
index 8867a4bd74..8064a2e688 100644
--- a/doc/guides/rel_notes/release_25_03.rst
+++ b/doc/guides/rel_notes/release_25_03.rst
@@ -123,6 +123,10 @@ New Features
     This feature enhances the efficiency of probing VF/SFs on a large scale
     by significantly reducing the probing time.
 
+* **Updated Napatech ntnic driver.**
+
+  * Added support for the NT400D13 adapter.
+
 * **Updated Wangxun ngbe driver.**
 
   * Added support for virtual function (VF).
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 92aad6f94d..d56e85dd66 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -43,6 +43,7 @@ sources = files(
         'nthw/supported/nthw_fpga_mod_str_map.c',
         'nthw/core/nt200a0x/clock_profiles/nthw_fpga_clk9563.c',
         'nthw/core/nt200a0x/nthw_fpga_nt200a0x.c',
+        'nthw/core/nt400dxx/nthw_fpga_nt400dxx.c',
         'nthw/core/nt200a0x/reset/nthw_fpga_rst9563.c',
         'nthw/core/nt200a0x/reset/nthw_fpga_rst_nt200a0x.c',
         'nthw/core/nthw_fpga.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_fpga.h b/drivers/net/ntnic/nthw/core/include/nthw_fpga.h
index cee1d23090..8b1d548a25 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_fpga.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_fpga.h
@@ -36,4 +36,12 @@ void register_nt200a0x_ops(struct nt200a0x_ops *ops);
 struct nt200a0x_ops *get_nt200a0x_ops(void);
 void nt200a0x_ops_init(void);
 
+struct nt400dxx_ops {
+	int (*nthw_fpga_nt400dxx_init)(struct fpga_info_s *p_fpga_info);
+};
+
+void register_nt400dxx_ops(struct nt400dxx_ops *ops);
+struct nt400dxx_ops *get_nt400dxx_ops(void);
+void nt400dxx_ops_init(void);
+
 #endif	/* __NTHW_FPGA_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
new file mode 100644
index 0000000000..3f86843ff3
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "nthw_fpga.h"
+#include "ntnic_mod_reg.h"
+
+
+static int nthw_fpga_nt400dxx_init(struct fpga_info_s *p_fpga_info)
+{
+	assert(p_fpga_info);
+	int res = -1;
+
+	return res;
+}
+
+static struct nt400dxx_ops nt400dxx_ops = { .nthw_fpga_nt400dxx_init = nthw_fpga_nt400dxx_init };
+
+void nt400dxx_ops_init(void)
+{
+	register_nt400dxx_ops(&nt400dxx_ops);
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_fpga.c b/drivers/net/ntnic/nthw/core/nthw_fpga.c
index 5ca186209a..e54a210c9f 100644
--- a/drivers/net/ntnic/nthw/core/nthw_fpga.c
+++ b/drivers/net/ntnic/nthw/core/nthw_fpga.c
@@ -266,6 +266,7 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 	p_fpga_info->mp_nthw_rac = p_nthw_rac;
 
 	struct nt200a0x_ops *nt200a0x_ops = get_nt200a0x_ops();
+	struct nt400dxx_ops *nt400dxx_ops = get_nt400dxx_ops();
 
 	switch (p_fpga_info->n_nthw_adapter_id) {
 	case NT_HW_ADAPTER_ID_NT200A02:
@@ -273,6 +274,11 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 			res = nt200a0x_ops->nthw_fpga_nt200a0x_init(p_fpga_info);
 		break;
 
+	case NT_HW_ADAPTER_ID_NT400D13:
+		if (nt400dxx_ops != NULL)
+			res = nt400dxx_ops->nthw_fpga_nt400dxx_init(p_fpga_info);
+		break;
+
 	default:
 		NT_LOG(ERR, NTHW, "%s: Unsupported HW product id: %d", p_adapter_id_str,
 			p_fpga_info->n_nthw_adapter_id);
@@ -398,3 +404,17 @@ struct nt200a0x_ops *get_nt200a0x_ops(void)
 		nt200a0x_ops_init();
 	return nt200a0x_ops;
 }
+
+static struct nt400dxx_ops *nt400dxx_ops;
+
+void register_nt400dxx_ops(struct nt400dxx_ops *ops)
+{
+	nt400dxx_ops = ops;
+}
+
+struct nt400dxx_ops *get_nt400dxx_ops(void)
+{
+	if (nt400dxx_ops == NULL)
+		nt400dxx_ops_init();
+	return nt400dxx_ops;
+}
diff --git a/drivers/net/ntnic/nthw/nthw_platform.c b/drivers/net/ntnic/nthw/nthw_platform.c
index 33e18e549f..80063c9d25 100644
--- a/drivers/net/ntnic/nthw/nthw_platform.c
+++ b/drivers/net/ntnic/nthw/nthw_platform.c
@@ -11,6 +11,9 @@ nthw_adapter_id_t nthw_platform_get_nthw_adapter_id(const uint16_t n_pci_device_
 	case NT_HW_PCI_DEVICE_ID_NT200A02:
 		return NT_HW_ADAPTER_ID_NT200A02;
 
+	case NT_HW_PCI_DEVICE_ID_NT400D13:
+		return NT_HW_ADAPTER_ID_NT400D13;
+
 	default:
 		return NT_HW_ADAPTER_ID_UNKNOWN;
 	}
diff --git a/drivers/net/ntnic/nthw/nthw_platform_drv.h b/drivers/net/ntnic/nthw/nthw_platform_drv.h
index 42eb0b8b05..df54dcead0 100644
--- a/drivers/net/ntnic/nthw/nthw_platform_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_platform_drv.h
@@ -10,10 +10,12 @@
 
 #define NT_HW_PCI_VENDOR_ID (0x18f4)
 #define NT_HW_PCI_DEVICE_ID_NT200A02 (0x1C5)
+#define NT_HW_PCI_DEVICE_ID_NT400D13 (0x295)
 
 enum nthw_adapter_id_e {
 	NT_HW_ADAPTER_ID_UNKNOWN = 0,
 	NT_HW_ADAPTER_ID_NT200A02,
+	NT_HW_ADAPTER_ID_NT400D13,
 };
 
 typedef enum nthw_adapter_id_e nthw_adapter_id_t;
diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 1b6b222c9d..88f6b6af6b 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -91,6 +91,7 @@ static const char *const valid_arguments[] = {
 
 static const struct rte_pci_id nthw_pci_id_map[] = {
 	{ RTE_PCI_DEVICE(NT_HW_PCI_VENDOR_ID, NT_HW_PCI_DEVICE_ID_NT200A02) },
+	{ RTE_PCI_DEVICE(NT_HW_PCI_VENDOR_ID, NT_HW_PCI_DEVICE_ID_NT400D13) },
 	{
 		.vendor_id = 0,
 	},	/* sentinel */
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 14/32] net/ntnic: add minimal reset FPGA
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (12 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 13/32] net/ntnic: add minimal initialization new NIC NT400D13 Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 15/32] net/ntnic: add FPGA modules and registers Serhii Iliushyk
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Define and register FPGA reset operations.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../include/ntnic_nthw_fpga_rst_nt400dxx.h    | 34 +++++++
 drivers/net/ntnic/meson.build                 |  2 +
 .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   | 88 ++++++++++++++++++-
 .../core/nt400dxx/reset/nthw_fpga_rst9574.c   | 40 +++++++++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 33 +++++++
 drivers/net/ntnic/ntnic_mod_reg.c             | 30 +++++++
 drivers/net/ntnic/ntnic_mod_reg.h             | 21 +++++
 7 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
 create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c

diff --git a/drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h b/drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h
new file mode 100644
index 0000000000..2f04907ac9
--- /dev/null
+++ b/drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h
@@ -0,0 +1,34 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#ifndef __NTNIC_NTHW_FPGA_RST_NT400DXX_H__
+#define __NTNIC_NTHW_FPGA_RST_NT400DXX_H__
+
+#include "nthw_drv.h"
+#include "nthw_fpga_model.h"
+
+struct nthw_fpga_rst_nt400dxx {
+	int n_fpga_product_id;
+	int n_fpga_version;
+	int n_fpga_revision;
+	int n_hw_id;
+	bool mb_is_nt400d11;
+
+	nthw_field_t *p_fld_rst_sys;
+	nthw_field_t *p_fld_rst_ddr4;
+	nthw_field_t *p_fld_rst_phy_ftile;
+
+	nthw_field_t *p_fld_stat_ddr4_calib_complete;
+	nthw_field_t *p_fld_stat_phy_ftile_rst_done;
+	nthw_field_t *p_fld_stat_phy_ftile_rdy;
+
+	nthw_field_t *p_fld_latch_ddr4_calib_complete;
+	nthw_field_t *p_fld_latch_phy_ftile_rst_done;
+	nthw_field_t *p_fld_latch_phy_ftile_rdy;
+};
+
+typedef struct nthw_fpga_rst_nt400dxx nthw_fpga_rst_nt400dxx_t;
+
+#endif	/* __NTHW_FPGA_RST_NT400DXX_H__ */
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index d56e85dd66..5a159f8bc6 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -45,7 +45,9 @@ sources = files(
         'nthw/core/nt200a0x/nthw_fpga_nt200a0x.c',
         'nthw/core/nt400dxx/nthw_fpga_nt400dxx.c',
         'nthw/core/nt200a0x/reset/nthw_fpga_rst9563.c',
+        'nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c',
         'nthw/core/nt200a0x/reset/nthw_fpga_rst_nt200a0x.c',
+        'nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c',
         'nthw/core/nthw_fpga.c',
         'nthw/core/nthw_gmf.c',
         'nthw/core/nthw_gfg.c',
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
index 3f86843ff3..0a5add60e0 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
@@ -5,13 +5,99 @@
 
 #include "nthw_fpga.h"
 #include "ntnic_mod_reg.h"
-
+#include "ntlog.h"
 
 static int nthw_fpga_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 {
 	assert(p_fpga_info);
+	struct rst9574_ops *rst9574_ops = NULL;
+
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	struct nthw_fpga_rst_nt400dxx rst;
 	int res = -1;
 
+	nthw_fpga_t *p_fpga = p_fpga_info->mp_fpga;
+	assert(p_fpga);
+
+	switch (p_fpga_info->n_fpga_prod_id) {
+	case 9574:
+		rst9574_ops = get_rst9574_ops();
+
+		if (rst9574_ops == NULL) {
+			NT_LOG(ERR, NTHW, "%s: RST 9574 NOT INCLUDED", p_adapter_id_str);
+			return -1;
+		}
+
+		res = rst9574_ops->nthw_fpga_rst9574_setup(p_fpga, &rst);
+
+		if (res) {
+			NT_LOG(ERR, NTHW,
+				"%s: %s: FPGA=%04d Failed to create reset module res=%d",
+				p_adapter_id_str, __func__, p_fpga_info->n_fpga_prod_id, res);
+			return res;
+		}
+
+		break;
+
+	default:
+		NT_LOG(ERR, NTHW, "%s: Unsupported FPGA product: %04d",
+			p_adapter_id_str, p_fpga_info->n_fpga_prod_id);
+		return -1;
+	}
+
+	struct rst_nt400dxx_ops *rst_nt400dxx_ops = get_rst_nt400dxx_ops();
+
+	if (rst_nt400dxx_ops == NULL) {
+		NT_LOG(ERR, NTHW, "RST NT400DXX NOT INCLUDED");
+		return -1;
+	}
+
+	/* reset common */
+	res = rst_nt400dxx_ops->nthw_fpga_rst_nt400dxx_init(p_fpga_info);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: FPGA=%04d - Failed to init common modules res=%d",
+			p_adapter_id_str, __func__, p_fpga_info->n_fpga_prod_id, res);
+		return res;
+	}
+
+	res = rst_nt400dxx_ops->nthw_fpga_rst_nt400dxx_reset(p_fpga_info);
+
+	if (res) {
+		NT_LOG(ERR, NTHW,
+			"%s: %s: FPGA=%04d - Failed to reset common modules res=%d",
+			p_adapter_id_str, __func__, p_fpga_info->n_fpga_prod_id, res);
+		return res;
+	}
+
+		/* reset specific */
+	switch (p_fpga_info->n_fpga_prod_id) {
+	case 9574:
+		if (rst9574_ops)
+			res = rst9574_ops->nthw_fpga_rst9574_init(p_fpga_info, &rst);
+
+		if (res) {
+			NT_LOG(ERR, NTHW,
+				"%s: %s: FPGA=%04d - Failed to reset 9574 modules res=%d",
+				p_adapter_id_str, __func__, p_fpga_info->n_fpga_prod_id, res);
+			return res;
+		}
+
+		break;
+
+	default:
+		NT_LOG(ERR, NTHW, "%s: Unsupported FPGA product: %04d",
+			p_adapter_id_str, p_fpga_info->n_fpga_prod_id);
+		res = -1;
+		break;
+	}
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: loc=%u: FPGA=%04d res=%d", p_adapter_id_str,
+			__func__, __LINE__, p_fpga_info->n_fpga_prod_id, res);
+		return res;
+	}
+
 	return res;
 }
 
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
new file mode 100644
index 0000000000..9ab26583df
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
@@ -0,0 +1,40 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+#include "nthw_drv.h"
+#include "nthw_register.h"
+#include "nthw_fpga.h"
+
+#include "ntnic_nthw_fpga_rst_nt400dxx.h"
+#include "ntnic_mod_reg.h"
+
+static int nthw_fpga_rst9574_setup(nthw_fpga_t *p_fpga, struct nthw_fpga_rst_nt400dxx *const p)
+{
+	assert(p_fpga);
+	assert(p);
+
+	return 0;
+};
+
+
+
+static int nthw_fpga_rst9574_init(struct fpga_info_s *p_fpga_info,
+	struct nthw_fpga_rst_nt400dxx *p_rst)
+{
+	assert(p_fpga_info);
+	assert(p_rst);
+	int res = -1;
+
+	return res;
+}
+
+static struct rst9574_ops rst9574_ops = {
+	.nthw_fpga_rst9574_init = nthw_fpga_rst9574_init,
+	.nthw_fpga_rst9574_setup = nthw_fpga_rst9574_setup,
+};
+
+void rst9574_ops_init(void)
+{
+	register_rst9574_ops(&rst9574_ops);
+}
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
new file mode 100644
index 0000000000..e0e4bc0861
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -0,0 +1,33 @@
+/*
+ * 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_fpga.h"
+#include "nthw_hif.h"
+#include "ntnic_mod_reg.h"
+
+static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
+{
+	assert(p_fpga_info);
+	return 0;
+}
+
+static int nthw_fpga_rst_nt400dxx_reset(struct fpga_info_s *p_fpga_info)
+{
+	assert(p_fpga_info);
+	return 0;
+}
+
+static struct rst_nt400dxx_ops rst_nt400dxx_ops = {
+	.nthw_fpga_rst_nt400dxx_init = nthw_fpga_rst_nt400dxx_init,
+	.nthw_fpga_rst_nt400dxx_reset = nthw_fpga_rst_nt400dxx_reset
+};
+
+void rst_nt400dxx_ops_init(void)
+{
+	register_rst_nt400dxx_ops(&rst_nt400dxx_ops);
+}
diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c
index 598df08fb7..054b343fe7 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.c
+++ b/drivers/net/ntnic/ntnic_mod_reg.c
@@ -178,6 +178,36 @@ void register_flow_backend_ops(const struct flow_backend_ops *ops)
 	flow_backend_ops = ops;
 }
 
+static struct rst9574_ops *rst9574_ops;
+
+void register_rst9574_ops(struct rst9574_ops *ops)
+{
+	rst9574_ops = ops;
+}
+
+struct rst9574_ops *get_rst9574_ops(void)
+{
+	if (rst9574_ops == NULL)
+		rst9574_ops_init();
+
+	return rst9574_ops;
+}
+
+static struct rst_nt400dxx_ops *rst_nt400dxx_ops;
+
+void register_rst_nt400dxx_ops(struct rst_nt400dxx_ops *ops)
+{
+	rst_nt400dxx_ops = ops;
+}
+
+struct rst_nt400dxx_ops *get_rst_nt400dxx_ops(void)
+{
+	if (rst_nt400dxx_ops == NULL)
+		rst_nt400dxx_ops_init();
+
+	return rst_nt400dxx_ops;
+}
+
 const struct flow_backend_ops *get_flow_backend_ops(void)
 {
 	if (flow_backend_ops == NULL)
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index 3e84beaa62..9b3650da89 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -19,6 +19,7 @@
 #include "nthw_drv.h"
 #include "nt4ga_adapter.h"
 #include "ntnic_nthw_fpga_rst_nt200a0x.h"
+#include "ntnic_nthw_fpga_rst_nt400dxx.h"
 #include "ntnic_virt_queue.h"
 #include "create_elements.h"
 
@@ -255,6 +256,26 @@ void register_rst9563_ops(struct rst9563_ops *ops);
 struct rst9563_ops *get_rst9563_ops(void);
 void rst9563_ops_init(void);
 
+struct rst9574_ops {
+	int (*nthw_fpga_rst9574_init)(struct fpga_info_s *p_fpga_info,
+		struct nthw_fpga_rst_nt400dxx *const p);
+	int (*nthw_fpga_rst9574_setup)(nthw_fpga_t *p_fpga,
+		struct nthw_fpga_rst_nt400dxx *const p);
+};
+
+void register_rst9574_ops(struct rst9574_ops *ops);
+struct rst9574_ops *get_rst9574_ops(void);
+void rst9574_ops_init(void);
+
+struct rst_nt400dxx_ops {
+	int (*nthw_fpga_rst_nt400dxx_init)(struct fpga_info_s *p_fpga_info);
+	int (*nthw_fpga_rst_nt400dxx_reset)(struct fpga_info_s *p_fpga_info);
+};
+
+void register_rst_nt400dxx_ops(struct rst_nt400dxx_ops *ops);
+struct rst_nt400dxx_ops *get_rst_nt400dxx_ops(void);
+void rst_nt400dxx_ops_init(void);
+
 struct flow_backend_ops {
 	const struct flow_api_backend_ops *(*bin_flow_backend_init)(nthw_fpga_t *p_fpga,
 		void **be_dev);
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 15/32] net/ntnic: add FPGA modules and registers
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (13 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 14/32] net/ntnic: add minimal reset FPGA Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 16/32] net/ntnic: add setup for fpga reset Serhii Iliushyk
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Extend driver with new fpga modules for NT400DXX card.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/meson.build                 |    1 +
 .../supported/nthw_fpga_9574_055_049_0000.c   | 3124 +++++++++++++++++
 .../nthw/supported/nthw_fpga_instances.c      |    5 +-
 .../nthw/supported/nthw_fpga_instances.h      |    1 +
 .../ntnic/nthw/supported/nthw_fpga_mod_defs.h |   11 +
 .../nthw/supported/nthw_fpga_mod_str_map.c    |   11 +
 .../ntnic/nthw/supported/nthw_fpga_reg_defs.h |   11 +
 .../nthw/supported/nthw_fpga_reg_defs_igam.h  |   32 +
 .../supported/nthw_fpga_reg_defs_pci_ta.h     |   33 +
 .../nthw_fpga_reg_defs_pcm_nt400dxx.h         |   29 +
 .../nthw/supported/nthw_fpga_reg_defs_pdi.h   |   49 +
 .../supported/nthw_fpga_reg_defs_phy_tile.h   |  213 ++
 .../nthw_fpga_reg_defs_prm_nt400dxx.h         |   26 +
 .../nthw/supported/nthw_fpga_reg_defs_rfd.h   |   38 +
 .../supported/nthw_fpga_reg_defs_rst9574.h    |   35 +
 .../nthw/supported/nthw_fpga_reg_defs_spim.h  |   76 +
 .../nthw/supported/nthw_fpga_reg_defs_spis.h  |   51 +
 .../nthw/supported/nthw_fpga_reg_defs_tint.h  |   28 +
 18 files changed, 3773 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h
 create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h

diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 5a159f8bc6..aec7b52714 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -39,6 +39,7 @@ sources = files(
         'ntnic_xstats/ntnic_xstats.c',
         'nthw/dbs/nthw_dbs.c',
         'nthw/supported/nthw_fpga_9563_055_049_0000.c',
+        'nthw/supported/nthw_fpga_9574_055_049_0000.c',
         'nthw/supported/nthw_fpga_instances.c',
         'nthw/supported/nthw_fpga_mod_str_map.c',
         'nthw/core/nt200a0x/clock_profiles/nthw_fpga_clk9563.c',
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c b/drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c
new file mode 100644
index 0000000000..700012ca06
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c
@@ -0,0 +1,3124 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#include "nthw_register.h"
+
+static nthw_fpga_field_init_s cat_cct_ctrl_fields[] = {
+	{ CAT_CCT_CTRL_ADR, 8, 0, 0x0000 },
+	{ CAT_CCT_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cct_data_fields[] = {
+	{ CAT_CCT_DATA_COLOR, 32, 0, 0x0000 },
+	{ CAT_CCT_DATA_KM, 4, 32, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cfn_ctrl_fields[] = {
+	{ CAT_CFN_CTRL_ADR, 6, 0, 0x0000 },
+	{ CAT_CFN_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cfn_data_fields[] = {
+	{ CAT_CFN_DATA_ENABLE, 1, 0, 0x0000 },
+	{ CAT_CFN_DATA_ERR_CV, 2, 99, 0x0000 },
+	{ CAT_CFN_DATA_ERR_FCS, 2, 101, 0x0000 },
+	{ CAT_CFN_DATA_ERR_INV, 1, 98, 0x0000 },
+	{ CAT_CFN_DATA_ERR_L3_CS, 2, 105, 0x0000 },
+	{ CAT_CFN_DATA_ERR_L4_CS, 2, 107, 0x0000 },
+	{ CAT_CFN_DATA_ERR_TNL_L3_CS, 2, 109, 0x0000 },
+	{ CAT_CFN_DATA_ERR_TNL_L4_CS, 2, 111, 0x0000 },
+	{ CAT_CFN_DATA_ERR_TNL_TTL_EXP, 2, 115, 0x0000 },
+	{ CAT_CFN_DATA_ERR_TRUNC, 2, 103, 0x0000 },
+	{ CAT_CFN_DATA_ERR_TTL_EXP, 2, 113, 0x0000 },
+	{ CAT_CFN_DATA_INV, 1, 1, 0x0000 },
+	{ CAT_CFN_DATA_KM0_OR, 3, 173, 0x0000 },
+	{ CAT_CFN_DATA_KM1_OR, 3, 176, 0x0000 },
+	{ CAT_CFN_DATA_LC, 8, 164, 0x0000 },
+	{ CAT_CFN_DATA_LC_INV, 1, 172, 0x0000 },
+	{ CAT_CFN_DATA_MAC_PORT, 2, 117, 0x0000 },
+	{ CAT_CFN_DATA_PM_AND_INV, 1, 161, 0x0000 },
+	{ CAT_CFN_DATA_PM_CMB, 4, 157, 0x0000 },
+	{ CAT_CFN_DATA_PM_CMP, 32, 119, 0x0000 },
+	{ CAT_CFN_DATA_PM_DCT, 2, 151, 0x0000 },
+	{ CAT_CFN_DATA_PM_EXT_INV, 4, 153, 0x0000 },
+	{ CAT_CFN_DATA_PM_INV, 1, 163, 0x0000 },
+	{ CAT_CFN_DATA_PM_OR_INV, 1, 162, 0x0000 },
+	{ CAT_CFN_DATA_PTC_CFP, 2, 5, 0x0000 },
+	{ CAT_CFN_DATA_PTC_FRAG, 4, 36, 0x0000 },
+	{ CAT_CFN_DATA_PTC_INV, 1, 2, 0x0000 },
+	{ CAT_CFN_DATA_PTC_IP_PROT, 8, 40, 0x0000 },
+	{ CAT_CFN_DATA_PTC_ISL, 2, 3, 0x0000 },
+	{ CAT_CFN_DATA_PTC_L2, 7, 12, 0x0000 },
+	{ CAT_CFN_DATA_PTC_L3, 3, 33, 0x0000 },
+	{ CAT_CFN_DATA_PTC_L4, 5, 48, 0x0000 },
+	{ CAT_CFN_DATA_PTC_MAC, 5, 7, 0x0000 },
+	{ CAT_CFN_DATA_PTC_MPLS, 8, 25, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_FRAG, 4, 81, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_IP_PROT, 8, 85, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_L2, 2, 64, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_L3, 3, 78, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_L4, 5, 93, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_MPLS, 8, 70, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TNL_VLAN, 4, 66, 0x0000 },
+	{ CAT_CFN_DATA_PTC_TUNNEL, 11, 53, 0x0000 },
+	{ CAT_CFN_DATA_PTC_VLAN, 4, 21, 0x0000 },
+	{ CAT_CFN_DATA_PTC_VNTAG, 2, 19, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cot_ctrl_fields[] = {
+	{ CAT_COT_CTRL_ADR, 6, 0, 0x0000 },
+	{ CAT_COT_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cot_data_fields[] = {
+	{ CAT_COT_DATA_COLOR, 32, 0, 0x0000 },
+	{ CAT_COT_DATA_KM, 4, 32, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cte_ctrl_fields[] = {
+	{ CAT_CTE_CTRL_ADR, 6, 0, 0x0000 },
+	{ CAT_CTE_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cte_data_fields[] = {
+	{ CAT_CTE_DATA_COL_ENABLE, 1, 0, 0x0000 }, { CAT_CTE_DATA_COR_ENABLE, 1, 1, 0x0000 },
+	{ CAT_CTE_DATA_EPP_ENABLE, 1, 9, 0x0000 }, { CAT_CTE_DATA_HSH_ENABLE, 1, 2, 0x0000 },
+	{ CAT_CTE_DATA_HST_ENABLE, 1, 8, 0x0000 }, { CAT_CTE_DATA_IPF_ENABLE, 1, 4, 0x0000 },
+	{ CAT_CTE_DATA_MSK_ENABLE, 1, 7, 0x0000 }, { CAT_CTE_DATA_PDB_ENABLE, 1, 6, 0x0000 },
+	{ CAT_CTE_DATA_QSL_ENABLE, 1, 3, 0x0000 }, { CAT_CTE_DATA_SLC_ENABLE, 1, 5, 0x0000 },
+	{ CAT_CTE_DATA_TPE_ENABLE, 1, 10, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cts_ctrl_fields[] = {
+	{ CAT_CTS_CTRL_ADR, 9, 0, 0x0000 },
+	{ CAT_CTS_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_cts_data_fields[] = {
+	{ CAT_CTS_DATA_CAT_A, 6, 0, 0x0000 },
+	{ CAT_CTS_DATA_CAT_B, 6, 6, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_dct_ctrl_fields[] = {
+	{ CAT_DCT_CTRL_ADR, 13, 0, 0x0000 },
+	{ CAT_DCT_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_dct_data_fields[] = {
+	{ CAT_DCT_DATA_RES, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_dct_sel_fields[] = {
+	{ CAT_DCT_SEL_LU, 2, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_exo_ctrl_fields[] = {
+	{ CAT_EXO_CTRL_ADR, 2, 0, 0x0000 },
+	{ CAT_EXO_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_exo_data_fields[] = {
+	{ CAT_EXO_DATA_DYN, 5, 0, 0x0000 },
+	{ CAT_EXO_DATA_OFS, 11, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_fte0_ctrl_fields[] = {
+	{ CAT_FTE0_CTRL_ADR, 9, 0, 0x0000 },
+	{ CAT_FTE0_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_fte0_data_fields[] = {
+	{ CAT_FTE0_DATA_ENABLE, 8, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_fte1_ctrl_fields[] = {
+	{ CAT_FTE1_CTRL_ADR, 9, 0, 0x0000 },
+	{ CAT_FTE1_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_fte1_data_fields[] = {
+	{ CAT_FTE1_DATA_ENABLE, 8, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_join_fields[] = {
+	{ CAT_JOIN_J1, 2, 0, 0x0000 },
+	{ CAT_JOIN_J2, 1, 8, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kcc_ctrl_fields[] = {
+	{ CAT_KCC_CTRL_ADR, 11, 0, 0x0000 },
+	{ CAT_KCC_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kcc_data_fields[] = {
+	{ CAT_KCC_DATA_CATEGORY, 8, 64, 0x0000 },
+	{ CAT_KCC_DATA_ID, 12, 72, 0x0000 },
+	{ CAT_KCC_DATA_KEY, 64, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kce0_ctrl_fields[] = {
+	{ CAT_KCE0_CTRL_ADR, 3, 0, 0x0000 },
+	{ CAT_KCE0_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kce0_data_fields[] = {
+	{ CAT_KCE0_DATA_ENABLE, 8, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kce1_ctrl_fields[] = {
+	{ CAT_KCE1_CTRL_ADR, 3, 0, 0x0000 },
+	{ CAT_KCE1_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kce1_data_fields[] = {
+	{ CAT_KCE1_DATA_ENABLE, 8, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kcs0_ctrl_fields[] = {
+	{ CAT_KCS0_CTRL_ADR, 6, 0, 0x0000 },
+	{ CAT_KCS0_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kcs0_data_fields[] = {
+	{ CAT_KCS0_DATA_CATEGORY, 6, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kcs1_ctrl_fields[] = {
+	{ CAT_KCS1_CTRL_ADR, 6, 0, 0x0000 },
+	{ CAT_KCS1_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_kcs1_data_fields[] = {
+	{ CAT_KCS1_DATA_CATEGORY, 6, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_len_ctrl_fields[] = {
+	{ CAT_LEN_CTRL_ADR, 3, 0, 0x0000 },
+	{ CAT_LEN_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_len_data_fields[] = {
+	{ CAT_LEN_DATA_DYN1, 5, 28, 0x0000 }, { CAT_LEN_DATA_DYN2, 5, 33, 0x0000 },
+	{ CAT_LEN_DATA_INV, 1, 38, 0x0000 }, { CAT_LEN_DATA_LOWER, 14, 0, 0x0000 },
+	{ CAT_LEN_DATA_UPPER, 14, 14, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_rck_ctrl_fields[] = {
+	{ CAT_RCK_CTRL_ADR, 8, 0, 0x0000 },
+	{ CAT_RCK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cat_rck_data_fields[] = {
+	{ CAT_RCK_DATA_CM0U, 1, 1, 0x0000 }, { CAT_RCK_DATA_CM1U, 1, 5, 0x0000 },
+	{ CAT_RCK_DATA_CM2U, 1, 9, 0x0000 }, { CAT_RCK_DATA_CM3U, 1, 13, 0x0000 },
+	{ CAT_RCK_DATA_CM4U, 1, 17, 0x0000 }, { CAT_RCK_DATA_CM5U, 1, 21, 0x0000 },
+	{ CAT_RCK_DATA_CM6U, 1, 25, 0x0000 }, { CAT_RCK_DATA_CM7U, 1, 29, 0x0000 },
+	{ CAT_RCK_DATA_CML0, 1, 0, 0x0000 }, { CAT_RCK_DATA_CML1, 1, 4, 0x0000 },
+	{ CAT_RCK_DATA_CML2, 1, 8, 0x0000 }, { CAT_RCK_DATA_CML3, 1, 12, 0x0000 },
+	{ CAT_RCK_DATA_CML4, 1, 16, 0x0000 }, { CAT_RCK_DATA_CML5, 1, 20, 0x0000 },
+	{ CAT_RCK_DATA_CML6, 1, 24, 0x0000 }, { CAT_RCK_DATA_CML7, 1, 28, 0x0000 },
+	{ CAT_RCK_DATA_SEL0, 1, 2, 0x0000 }, { CAT_RCK_DATA_SEL1, 1, 6, 0x0000 },
+	{ CAT_RCK_DATA_SEL2, 1, 10, 0x0000 }, { CAT_RCK_DATA_SEL3, 1, 14, 0x0000 },
+	{ CAT_RCK_DATA_SEL4, 1, 18, 0x0000 }, { CAT_RCK_DATA_SEL5, 1, 22, 0x0000 },
+	{ CAT_RCK_DATA_SEL6, 1, 26, 0x0000 }, { CAT_RCK_DATA_SEL7, 1, 30, 0x0000 },
+	{ CAT_RCK_DATA_SEU0, 1, 3, 0x0000 }, { CAT_RCK_DATA_SEU1, 1, 7, 0x0000 },
+	{ CAT_RCK_DATA_SEU2, 1, 11, 0x0000 }, { CAT_RCK_DATA_SEU3, 1, 15, 0x0000 },
+	{ CAT_RCK_DATA_SEU4, 1, 19, 0x0000 }, { CAT_RCK_DATA_SEU5, 1, 23, 0x0000 },
+	{ CAT_RCK_DATA_SEU6, 1, 27, 0x0000 }, { CAT_RCK_DATA_SEU7, 1, 31, 0x0000 },
+};
+
+static nthw_fpga_register_init_s cat_registers[] = {
+	{ CAT_CCT_CTRL, 30, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cct_ctrl_fields },
+	{ CAT_CCT_DATA, 31, 36, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cct_data_fields },
+	{ CAT_CFN_CTRL, 10, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cfn_ctrl_fields },
+	{ CAT_CFN_DATA, 11, 179, NTHW_FPGA_REG_TYPE_WO, 0, 44, cat_cfn_data_fields },
+	{ CAT_COT_CTRL, 28, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cot_ctrl_fields },
+	{ CAT_COT_DATA, 29, 36, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cot_data_fields },
+	{ CAT_CTE_CTRL, 24, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cte_ctrl_fields },
+	{ CAT_CTE_DATA, 25, 11, NTHW_FPGA_REG_TYPE_WO, 0, 11, cat_cte_data_fields },
+	{ CAT_CTS_CTRL, 26, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cts_ctrl_fields },
+	{ CAT_CTS_DATA, 27, 12, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_cts_data_fields },
+	{ CAT_DCT_CTRL, 6, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_dct_ctrl_fields },
+	{ CAT_DCT_DATA, 7, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_dct_data_fields },
+	{ CAT_DCT_SEL, 4, 2, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_dct_sel_fields },
+	{ CAT_EXO_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_exo_ctrl_fields },
+	{ CAT_EXO_DATA, 1, 27, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_exo_data_fields },
+	{ CAT_FTE0_CTRL, 16, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_fte0_ctrl_fields },
+	{ CAT_FTE0_DATA, 17, 8, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_fte0_data_fields },
+	{ CAT_FTE1_CTRL, 22, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_fte1_ctrl_fields },
+	{ CAT_FTE1_DATA, 23, 8, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_fte1_data_fields },
+	{ CAT_JOIN, 5, 9, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_join_fields },
+	{ CAT_KCC_CTRL, 32, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_kcc_ctrl_fields },
+	{ CAT_KCC_DATA, 33, 84, NTHW_FPGA_REG_TYPE_WO, 0, 3, cat_kcc_data_fields },
+	{ CAT_KCE0_CTRL, 12, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_kce0_ctrl_fields },
+	{ CAT_KCE0_DATA, 13, 8, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_kce0_data_fields },
+	{ CAT_KCE1_CTRL, 18, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_kce1_ctrl_fields },
+	{ CAT_KCE1_DATA, 19, 8, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_kce1_data_fields },
+	{ CAT_KCS0_CTRL, 14, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_kcs0_ctrl_fields },
+	{ CAT_KCS0_DATA, 15, 6, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_kcs0_data_fields },
+	{ CAT_KCS1_CTRL, 20, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_kcs1_ctrl_fields },
+	{ CAT_KCS1_DATA, 21, 6, NTHW_FPGA_REG_TYPE_WO, 0, 1, cat_kcs1_data_fields },
+	{ CAT_LEN_CTRL, 8, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_len_ctrl_fields },
+	{ CAT_LEN_DATA, 9, 39, NTHW_FPGA_REG_TYPE_WO, 0, 5, cat_len_data_fields },
+	{ CAT_RCK_CTRL, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cat_rck_ctrl_fields },
+	{ CAT_RCK_DATA, 3, 32, NTHW_FPGA_REG_TYPE_WO, 0, 32, cat_rck_data_fields },
+};
+
+static nthw_fpga_field_init_s cpy_packet_reader0_ctrl_fields[] = {
+	{ CPY_PACKET_READER0_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_PACKET_READER0_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_packet_reader0_data_fields[] = {
+	{ CPY_PACKET_READER0_DATA_DYN, 5, 10, 0x0000 },
+	{ CPY_PACKET_READER0_DATA_OFS, 10, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer0_ctrl_fields[] = {
+	{ CPY_WRITER0_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER0_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer0_data_fields[] = {
+	{ CPY_WRITER0_DATA_DYN, 5, 17, 0x0000 }, { CPY_WRITER0_DATA_LEN, 5, 22, 0x0000 },
+	{ CPY_WRITER0_DATA_MASK_POINTER, 4, 27, 0x0000 }, { CPY_WRITER0_DATA_OFS, 14, 3, 0x0000 },
+	{ CPY_WRITER0_DATA_READER_SELECT, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer0_mask_ctrl_fields[] = {
+	{ CPY_WRITER0_MASK_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER0_MASK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer0_mask_data_fields[] = {
+	{ CPY_WRITER0_MASK_DATA_BYTE_MASK, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer1_ctrl_fields[] = {
+	{ CPY_WRITER1_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER1_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer1_data_fields[] = {
+	{ CPY_WRITER1_DATA_DYN, 5, 17, 0x0000 }, { CPY_WRITER1_DATA_LEN, 5, 22, 0x0000 },
+	{ CPY_WRITER1_DATA_MASK_POINTER, 4, 27, 0x0000 }, { CPY_WRITER1_DATA_OFS, 14, 3, 0x0000 },
+	{ CPY_WRITER1_DATA_READER_SELECT, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer1_mask_ctrl_fields[] = {
+	{ CPY_WRITER1_MASK_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER1_MASK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer1_mask_data_fields[] = {
+	{ CPY_WRITER1_MASK_DATA_BYTE_MASK, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer2_ctrl_fields[] = {
+	{ CPY_WRITER2_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER2_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer2_data_fields[] = {
+	{ CPY_WRITER2_DATA_DYN, 5, 17, 0x0000 }, { CPY_WRITER2_DATA_LEN, 5, 22, 0x0000 },
+	{ CPY_WRITER2_DATA_MASK_POINTER, 4, 27, 0x0000 }, { CPY_WRITER2_DATA_OFS, 14, 3, 0x0000 },
+	{ CPY_WRITER2_DATA_READER_SELECT, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer2_mask_ctrl_fields[] = {
+	{ CPY_WRITER2_MASK_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER2_MASK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer2_mask_data_fields[] = {
+	{ CPY_WRITER2_MASK_DATA_BYTE_MASK, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer3_ctrl_fields[] = {
+	{ CPY_WRITER3_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER3_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer3_data_fields[] = {
+	{ CPY_WRITER3_DATA_DYN, 5, 17, 0x0000 }, { CPY_WRITER3_DATA_LEN, 5, 22, 0x0000 },
+	{ CPY_WRITER3_DATA_MASK_POINTER, 4, 27, 0x0000 }, { CPY_WRITER3_DATA_OFS, 14, 3, 0x0000 },
+	{ CPY_WRITER3_DATA_READER_SELECT, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer3_mask_ctrl_fields[] = {
+	{ CPY_WRITER3_MASK_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER3_MASK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer3_mask_data_fields[] = {
+	{ CPY_WRITER3_MASK_DATA_BYTE_MASK, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer4_ctrl_fields[] = {
+	{ CPY_WRITER4_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER4_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer4_data_fields[] = {
+	{ CPY_WRITER4_DATA_DYN, 5, 17, 0x0000 }, { CPY_WRITER4_DATA_LEN, 5, 22, 0x0000 },
+	{ CPY_WRITER4_DATA_MASK_POINTER, 4, 27, 0x0000 }, { CPY_WRITER4_DATA_OFS, 14, 3, 0x0000 },
+	{ CPY_WRITER4_DATA_READER_SELECT, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer4_mask_ctrl_fields[] = {
+	{ CPY_WRITER4_MASK_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER4_MASK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer4_mask_data_fields[] = {
+	{ CPY_WRITER4_MASK_DATA_BYTE_MASK, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer5_ctrl_fields[] = {
+	{ CPY_WRITER5_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER5_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer5_data_fields[] = {
+	{ CPY_WRITER5_DATA_DYN, 5, 17, 0x0000 }, { CPY_WRITER5_DATA_LEN, 5, 22, 0x0000 },
+	{ CPY_WRITER5_DATA_MASK_POINTER, 4, 27, 0x0000 }, { CPY_WRITER5_DATA_OFS, 14, 3, 0x0000 },
+	{ CPY_WRITER5_DATA_READER_SELECT, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer5_mask_ctrl_fields[] = {
+	{ CPY_WRITER5_MASK_CTRL_ADR, 4, 0, 0x0000 },
+	{ CPY_WRITER5_MASK_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s cpy_writer5_mask_data_fields[] = {
+	{ CPY_WRITER5_MASK_DATA_BYTE_MASK, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s cpy_registers[] = {
+	{
+		CPY_PACKET_READER0_CTRL, 24, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_packet_reader0_ctrl_fields
+	},
+	{
+		CPY_PACKET_READER0_DATA, 25, 15, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_packet_reader0_data_fields
+	},
+	{ CPY_WRITER0_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cpy_writer0_ctrl_fields },
+	{ CPY_WRITER0_DATA, 1, 31, NTHW_FPGA_REG_TYPE_WO, 0, 5, cpy_writer0_data_fields },
+	{
+		CPY_WRITER0_MASK_CTRL, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_writer0_mask_ctrl_fields
+	},
+	{
+		CPY_WRITER0_MASK_DATA, 3, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		cpy_writer0_mask_data_fields
+	},
+	{ CPY_WRITER1_CTRL, 4, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cpy_writer1_ctrl_fields },
+	{ CPY_WRITER1_DATA, 5, 31, NTHW_FPGA_REG_TYPE_WO, 0, 5, cpy_writer1_data_fields },
+	{
+		CPY_WRITER1_MASK_CTRL, 6, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_writer1_mask_ctrl_fields
+	},
+	{
+		CPY_WRITER1_MASK_DATA, 7, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		cpy_writer1_mask_data_fields
+	},
+	{ CPY_WRITER2_CTRL, 8, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cpy_writer2_ctrl_fields },
+	{ CPY_WRITER2_DATA, 9, 31, NTHW_FPGA_REG_TYPE_WO, 0, 5, cpy_writer2_data_fields },
+	{
+		CPY_WRITER2_MASK_CTRL, 10, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_writer2_mask_ctrl_fields
+	},
+	{
+		CPY_WRITER2_MASK_DATA, 11, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		cpy_writer2_mask_data_fields
+	},
+	{ CPY_WRITER3_CTRL, 12, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cpy_writer3_ctrl_fields },
+	{ CPY_WRITER3_DATA, 13, 31, NTHW_FPGA_REG_TYPE_WO, 0, 5, cpy_writer3_data_fields },
+	{
+		CPY_WRITER3_MASK_CTRL, 14, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_writer3_mask_ctrl_fields
+	},
+	{
+		CPY_WRITER3_MASK_DATA, 15, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		cpy_writer3_mask_data_fields
+	},
+	{ CPY_WRITER4_CTRL, 16, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cpy_writer4_ctrl_fields },
+	{ CPY_WRITER4_DATA, 17, 31, NTHW_FPGA_REG_TYPE_WO, 0, 5, cpy_writer4_data_fields },
+	{
+		CPY_WRITER4_MASK_CTRL, 18, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_writer4_mask_ctrl_fields
+	},
+	{
+		CPY_WRITER4_MASK_DATA, 19, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		cpy_writer4_mask_data_fields
+	},
+	{ CPY_WRITER5_CTRL, 20, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, cpy_writer5_ctrl_fields },
+	{ CPY_WRITER5_DATA, 21, 31, NTHW_FPGA_REG_TYPE_WO, 0, 5, cpy_writer5_data_fields },
+	{
+		CPY_WRITER5_MASK_CTRL, 22, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2,
+		cpy_writer5_mask_ctrl_fields
+	},
+	{
+		CPY_WRITER5_MASK_DATA, 23, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		cpy_writer5_mask_data_fields
+	},
+};
+
+static nthw_fpga_field_init_s csu_rcp_ctrl_fields[] = {
+	{ CSU_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ CSU_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s csu_rcp_data_fields[] = {
+	{ CSU_RCP_DATA_IL3_CMD, 2, 5, 0x0000 },
+	{ CSU_RCP_DATA_IL4_CMD, 3, 7, 0x0000 },
+	{ CSU_RCP_DATA_OL3_CMD, 2, 0, 0x0000 },
+	{ CSU_RCP_DATA_OL4_CMD, 3, 2, 0x0000 },
+};
+
+static nthw_fpga_register_init_s csu_registers[] = {
+	{ CSU_RCP_CTRL, 1, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, csu_rcp_ctrl_fields },
+	{ CSU_RCP_DATA, 2, 10, NTHW_FPGA_REG_TYPE_WO, 0, 4, csu_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s dbs_rx_am_ctrl_fields[] = {
+	{ DBS_RX_AM_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_RX_AM_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_am_data_fields[] = {
+	{ DBS_RX_AM_DATA_ENABLE, 1, 72, 0x0000 }, { DBS_RX_AM_DATA_GPA, 64, 0, 0x0000 },
+	{ DBS_RX_AM_DATA_HID, 8, 64, 0x0000 }, { DBS_RX_AM_DATA_INT, 1, 74, 0x0000 },
+	{ DBS_RX_AM_DATA_PCKED, 1, 73, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_control_fields[] = {
+	{ DBS_RX_CONTROL_AME, 1, 7, 0 }, { DBS_RX_CONTROL_AMS, 4, 8, 8 },
+	{ DBS_RX_CONTROL_LQ, 7, 0, 0 }, { DBS_RX_CONTROL_QE, 1, 17, 0 },
+	{ DBS_RX_CONTROL_UWE, 1, 12, 0 }, { DBS_RX_CONTROL_UWS, 4, 13, 5 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_dr_ctrl_fields[] = {
+	{ DBS_RX_DR_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_RX_DR_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_dr_data_fields[] = {
+	{ DBS_RX_DR_DATA_GPA, 64, 0, 0x0000 }, { DBS_RX_DR_DATA_HDR, 1, 88, 0x0000 },
+	{ DBS_RX_DR_DATA_HID, 8, 64, 0x0000 }, { DBS_RX_DR_DATA_PCKED, 1, 87, 0x0000 },
+	{ DBS_RX_DR_DATA_QS, 15, 72, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_idle_fields[] = {
+	{ DBS_RX_IDLE_BUSY, 1, 8, 0 },
+	{ DBS_RX_IDLE_IDLE, 1, 0, 0x0000 },
+	{ DBS_RX_IDLE_QUEUE, 7, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_init_fields[] = {
+	{ DBS_RX_INIT_BUSY, 1, 8, 0 },
+	{ DBS_RX_INIT_INIT, 1, 0, 0x0000 },
+	{ DBS_RX_INIT_QUEUE, 7, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_init_val_fields[] = {
+	{ DBS_RX_INIT_VAL_IDX, 16, 0, 0x0000 },
+	{ DBS_RX_INIT_VAL_PTR, 15, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_ptr_fields[] = {
+	{ DBS_RX_PTR_PTR, 16, 0, 0x0000 },
+	{ DBS_RX_PTR_QUEUE, 7, 16, 0x0000 },
+	{ DBS_RX_PTR_VALID, 1, 23, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_uw_ctrl_fields[] = {
+	{ DBS_RX_UW_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_RX_UW_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_rx_uw_data_fields[] = {
+	{ DBS_RX_UW_DATA_GPA, 64, 0, 0x0000 }, { DBS_RX_UW_DATA_HID, 8, 64, 0x0000 },
+	{ DBS_RX_UW_DATA_INT, 1, 88, 0x0000 }, { DBS_RX_UW_DATA_ISTK, 1, 92, 0x0000 },
+	{ DBS_RX_UW_DATA_PCKED, 1, 87, 0x0000 }, { DBS_RX_UW_DATA_QS, 15, 72, 0x0000 },
+	{ DBS_RX_UW_DATA_VEC, 3, 89, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_am_ctrl_fields[] = {
+	{ DBS_TX_AM_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_TX_AM_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_am_data_fields[] = {
+	{ DBS_TX_AM_DATA_ENABLE, 1, 72, 0x0000 }, { DBS_TX_AM_DATA_GPA, 64, 0, 0x0000 },
+	{ DBS_TX_AM_DATA_HID, 8, 64, 0x0000 }, { DBS_TX_AM_DATA_INT, 1, 74, 0x0000 },
+	{ DBS_TX_AM_DATA_PCKED, 1, 73, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_control_fields[] = {
+	{ DBS_TX_CONTROL_AME, 1, 7, 0 }, { DBS_TX_CONTROL_AMS, 4, 8, 5 },
+	{ DBS_TX_CONTROL_LQ, 7, 0, 0 }, { DBS_TX_CONTROL_QE, 1, 17, 0 },
+	{ DBS_TX_CONTROL_UWE, 1, 12, 0 }, { DBS_TX_CONTROL_UWS, 4, 13, 8 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_dr_ctrl_fields[] = {
+	{ DBS_TX_DR_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_TX_DR_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_dr_data_fields[] = {
+	{ DBS_TX_DR_DATA_GPA, 64, 0, 0x0000 }, { DBS_TX_DR_DATA_HDR, 1, 88, 0x0000 },
+	{ DBS_TX_DR_DATA_HID, 8, 64, 0x0000 }, { DBS_TX_DR_DATA_PCKED, 1, 87, 0x0000 },
+	{ DBS_TX_DR_DATA_PORT, 1, 89, 0x0000 }, { DBS_TX_DR_DATA_QS, 15, 72, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_idle_fields[] = {
+	{ DBS_TX_IDLE_BUSY, 1, 8, 0 },
+	{ DBS_TX_IDLE_IDLE, 1, 0, 0x0000 },
+	{ DBS_TX_IDLE_QUEUE, 7, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_init_fields[] = {
+	{ DBS_TX_INIT_BUSY, 1, 8, 0 },
+	{ DBS_TX_INIT_INIT, 1, 0, 0x0000 },
+	{ DBS_TX_INIT_QUEUE, 7, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_init_val_fields[] = {
+	{ DBS_TX_INIT_VAL_IDX, 16, 0, 0x0000 },
+	{ DBS_TX_INIT_VAL_PTR, 15, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_ptr_fields[] = {
+	{ DBS_TX_PTR_PTR, 16, 0, 0x0000 },
+	{ DBS_TX_PTR_QUEUE, 7, 16, 0x0000 },
+	{ DBS_TX_PTR_VALID, 1, 23, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_qos_ctrl_fields[] = {
+	{ DBS_TX_QOS_CTRL_ADR, 1, 0, 0x0000 },
+	{ DBS_TX_QOS_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_qos_data_fields[] = {
+	{ DBS_TX_QOS_DATA_BS, 27, 17, 0x0000 },
+	{ DBS_TX_QOS_DATA_EN, 1, 0, 0x0000 },
+	{ DBS_TX_QOS_DATA_IR, 16, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_qos_rate_fields[] = {
+	{ DBS_TX_QOS_RATE_DIV, 19, 16, 2 },
+	{ DBS_TX_QOS_RATE_MUL, 16, 0, 1 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_qp_ctrl_fields[] = {
+	{ DBS_TX_QP_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_TX_QP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_qp_data_fields[] = {
+	{ DBS_TX_QP_DATA_VPORT, 1, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_uw_ctrl_fields[] = {
+	{ DBS_TX_UW_CTRL_ADR, 7, 0, 0x0000 },
+	{ DBS_TX_UW_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s dbs_tx_uw_data_fields[] = {
+	{ DBS_TX_UW_DATA_GPA, 64, 0, 0x0000 }, { DBS_TX_UW_DATA_HID, 8, 64, 0x0000 },
+	{ DBS_TX_UW_DATA_INO, 1, 93, 0x0000 }, { DBS_TX_UW_DATA_INT, 1, 88, 0x0000 },
+	{ DBS_TX_UW_DATA_ISTK, 1, 92, 0x0000 }, { DBS_TX_UW_DATA_PCKED, 1, 87, 0x0000 },
+	{ DBS_TX_UW_DATA_QS, 15, 72, 0x0000 }, { DBS_TX_UW_DATA_VEC, 3, 89, 0x0000 },
+};
+
+static nthw_fpga_register_init_s dbs_registers[] = {
+	{ DBS_RX_AM_CTRL, 10, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_rx_am_ctrl_fields },
+	{ DBS_RX_AM_DATA, 11, 75, NTHW_FPGA_REG_TYPE_WO, 0, 5, dbs_rx_am_data_fields },
+	{ DBS_RX_CONTROL, 0, 18, NTHW_FPGA_REG_TYPE_RW, 43008, 6, dbs_rx_control_fields },
+	{ DBS_RX_DR_CTRL, 18, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_rx_dr_ctrl_fields },
+	{ DBS_RX_DR_DATA, 19, 89, NTHW_FPGA_REG_TYPE_WO, 0, 5, dbs_rx_dr_data_fields },
+	{ DBS_RX_IDLE, 8, 9, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, dbs_rx_idle_fields },
+	{ DBS_RX_INIT, 2, 9, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, dbs_rx_init_fields },
+	{ DBS_RX_INIT_VAL, 3, 31, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_rx_init_val_fields },
+	{ DBS_RX_PTR, 4, 24, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, dbs_rx_ptr_fields },
+	{ DBS_RX_UW_CTRL, 14, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_rx_uw_ctrl_fields },
+	{ DBS_RX_UW_DATA, 15, 93, NTHW_FPGA_REG_TYPE_WO, 0, 7, dbs_rx_uw_data_fields },
+	{ DBS_TX_AM_CTRL, 12, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_tx_am_ctrl_fields },
+	{ DBS_TX_AM_DATA, 13, 75, NTHW_FPGA_REG_TYPE_WO, 0, 5, dbs_tx_am_data_fields },
+	{ DBS_TX_CONTROL, 1, 18, NTHW_FPGA_REG_TYPE_RW, 66816, 6, dbs_tx_control_fields },
+	{ DBS_TX_DR_CTRL, 20, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_tx_dr_ctrl_fields },
+	{ DBS_TX_DR_DATA, 21, 90, NTHW_FPGA_REG_TYPE_WO, 0, 6, dbs_tx_dr_data_fields },
+	{ DBS_TX_IDLE, 9, 9, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, dbs_tx_idle_fields },
+	{ DBS_TX_INIT, 5, 9, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, dbs_tx_init_fields },
+	{ DBS_TX_INIT_VAL, 6, 31, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_tx_init_val_fields },
+	{ DBS_TX_PTR, 7, 24, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, dbs_tx_ptr_fields },
+	{ DBS_TX_QOS_CTRL, 24, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_tx_qos_ctrl_fields },
+	{ DBS_TX_QOS_DATA, 25, 44, NTHW_FPGA_REG_TYPE_WO, 0, 3, dbs_tx_qos_data_fields },
+	{ DBS_TX_QOS_RATE, 26, 35, NTHW_FPGA_REG_TYPE_RW, 131073, 2, dbs_tx_qos_rate_fields },
+	{ DBS_TX_QP_CTRL, 22, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_tx_qp_ctrl_fields },
+	{ DBS_TX_QP_DATA, 23, 1, NTHW_FPGA_REG_TYPE_WO, 0, 1, dbs_tx_qp_data_fields },
+	{ DBS_TX_UW_CTRL, 16, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, dbs_tx_uw_ctrl_fields },
+	{ DBS_TX_UW_DATA, 17, 94, NTHW_FPGA_REG_TYPE_WO, 0, 8, dbs_tx_uw_data_fields },
+};
+
+static nthw_fpga_field_init_s flm_buf_ctrl_fields[] = {
+	{ FLM_BUF_CTRL_INF_AVAIL, 16, 16, 0x0000 },
+	{ FLM_BUF_CTRL_LRN_FREE, 16, 0, 0x0000 },
+	{ FLM_BUF_CTRL_STA_AVAIL, 16, 32, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_control_fields[] = {
+	{ FLM_CONTROL_CALIB_RECALIBRATE, 4, 28, 0 },
+	{ FLM_CONTROL_CRCRD, 1, 12, 0x0000 },
+	{ FLM_CONTROL_CRCWR, 1, 11, 0x0000 },
+	{ FLM_CONTROL_EAB, 5, 18, 0 },
+	{ FLM_CONTROL_ENABLE, 1, 0, 0 },
+	{ FLM_CONTROL_INIT, 1, 1, 0x0000 },
+	{ FLM_CONTROL_LDS, 1, 2, 0x0000 },
+	{ FLM_CONTROL_LFS, 1, 3, 0x0000 },
+	{ FLM_CONTROL_LIS, 1, 4, 0x0000 },
+	{ FLM_CONTROL_PDS, 1, 9, 0x0000 },
+	{ FLM_CONTROL_PIS, 1, 10, 0x0000 },
+	{ FLM_CONTROL_RBL, 4, 13, 0 },
+	{ FLM_CONTROL_RDS, 1, 7, 0x0000 },
+	{ FLM_CONTROL_RIS, 1, 8, 0x0000 },
+	{ FLM_CONTROL_SPLIT_SDRAM_USAGE, 5, 23, 16 },
+	{ FLM_CONTROL_UDS, 1, 5, 0x0000 },
+	{ FLM_CONTROL_UIS, 1, 6, 0x0000 },
+	{ FLM_CONTROL_WPD, 1, 17, 0 },
+};
+
+static nthw_fpga_field_init_s flm_inf_data_fields[] = {
+	{ FLM_INF_DATA_BYTES, 64, 0, 0x0000 }, { FLM_INF_DATA_CAUSE, 3, 224, 0x0000 },
+	{ FLM_INF_DATA_EOR, 1, 287, 0x0000 }, { FLM_INF_DATA_ID, 32, 192, 0x0000 },
+	{ FLM_INF_DATA_PACKETS, 64, 64, 0x0000 }, { FLM_INF_DATA_TS, 64, 128, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_load_aps_fields[] = {
+	{ FLM_LOAD_APS_APS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_load_bin_fields[] = {
+	{ FLM_LOAD_BIN_BIN, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_load_lps_fields[] = {
+	{ FLM_LOAD_LPS_LPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_lrn_data_fields[] = {
+	{ FLM_LRN_DATA_ADJ, 32, 480, 0x0000 }, { FLM_LRN_DATA_COLOR, 32, 448, 0x0000 },
+	{ FLM_LRN_DATA_DSCP, 6, 698, 0x0000 }, { FLM_LRN_DATA_ENT, 1, 693, 0x0000 },
+	{ FLM_LRN_DATA_EOR, 1, 767, 0x0000 }, { FLM_LRN_DATA_FILL, 16, 544, 0x0000 },
+	{ FLM_LRN_DATA_FT, 4, 560, 0x0000 }, { FLM_LRN_DATA_FT_MBR, 4, 564, 0x0000 },
+	{ FLM_LRN_DATA_FT_MISS, 4, 568, 0x0000 }, { FLM_LRN_DATA_ID, 32, 512, 0x0000 },
+	{ FLM_LRN_DATA_KID, 8, 328, 0x0000 }, { FLM_LRN_DATA_MBR_ID1, 28, 572, 0x0000 },
+	{ FLM_LRN_DATA_MBR_ID2, 28, 600, 0x0000 }, { FLM_LRN_DATA_MBR_ID3, 28, 628, 0x0000 },
+	{ FLM_LRN_DATA_MBR_ID4, 28, 656, 0x0000 }, { FLM_LRN_DATA_NAT_EN, 1, 711, 0x0000 },
+	{ FLM_LRN_DATA_NAT_IP, 32, 336, 0x0000 }, { FLM_LRN_DATA_NAT_PORT, 16, 400, 0x0000 },
+	{ FLM_LRN_DATA_NOFI, 1, 716, 0x0000 }, { FLM_LRN_DATA_OP, 4, 694, 0x0000 },
+	{ FLM_LRN_DATA_PRIO, 2, 691, 0x0000 }, { FLM_LRN_DATA_PROT, 8, 320, 0x0000 },
+	{ FLM_LRN_DATA_QFI, 6, 704, 0x0000 }, { FLM_LRN_DATA_QW0, 128, 192, 0x0000 },
+	{ FLM_LRN_DATA_QW4, 128, 64, 0x0000 }, { FLM_LRN_DATA_RATE, 16, 416, 0x0000 },
+	{ FLM_LRN_DATA_RQI, 1, 710, 0x0000 }, { FLM_LRN_DATA_SCRUB_PROF, 4, 712, 0x0000 },
+	{ FLM_LRN_DATA_SIZE, 16, 432, 0x0000 }, { FLM_LRN_DATA_STAT_PROF, 4, 687, 0x0000 },
+	{ FLM_LRN_DATA_SW8, 32, 32, 0x0000 }, { FLM_LRN_DATA_SW9, 32, 0, 0x0000 },
+	{ FLM_LRN_DATA_TEID, 32, 368, 0x0000 }, { FLM_LRN_DATA_VOL_IDX, 3, 684, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_prio_fields[] = {
+	{ FLM_PRIO_FT0, 4, 4, 1 }, { FLM_PRIO_FT1, 4, 12, 1 }, { FLM_PRIO_FT2, 4, 20, 1 },
+	{ FLM_PRIO_FT3, 4, 28, 1 }, { FLM_PRIO_LIMIT0, 4, 0, 0 }, { FLM_PRIO_LIMIT1, 4, 8, 0 },
+	{ FLM_PRIO_LIMIT2, 4, 16, 0 }, { FLM_PRIO_LIMIT3, 4, 24, 0 },
+};
+
+static nthw_fpga_field_init_s flm_pst_ctrl_fields[] = {
+	{ FLM_PST_CTRL_ADR, 4, 0, 0x0000 },
+	{ FLM_PST_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_pst_data_fields[] = {
+	{ FLM_PST_DATA_BP, 5, 0, 0x0000 },
+	{ FLM_PST_DATA_PP, 5, 5, 0x0000 },
+	{ FLM_PST_DATA_TP, 5, 10, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_rcp_ctrl_fields[] = {
+	{ FLM_RCP_CTRL_ADR, 5, 0, 0x0000 },
+	{ FLM_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_rcp_data_fields[] = {
+	{ FLM_RCP_DATA_AUTO_IPV4_MASK, 1, 402, 0x0000 },
+	{ FLM_RCP_DATA_BYT_DYN, 5, 387, 0x0000 },
+	{ FLM_RCP_DATA_BYT_OFS, 8, 392, 0x0000 },
+	{ FLM_RCP_DATA_IPN, 1, 386, 0x0000 },
+	{ FLM_RCP_DATA_KID, 8, 377, 0x0000 },
+	{ FLM_RCP_DATA_LOOKUP, 1, 0, 0x0000 },
+	{ FLM_RCP_DATA_MASK, 320, 57, 0x0000 },
+	{ FLM_RCP_DATA_OPN, 1, 385, 0x0000 },
+	{ FLM_RCP_DATA_QW0_DYN, 5, 1, 0x0000 },
+	{ FLM_RCP_DATA_QW0_OFS, 8, 6, 0x0000 },
+	{ FLM_RCP_DATA_QW0_SEL, 2, 14, 0x0000 },
+	{ FLM_RCP_DATA_QW4_DYN, 5, 16, 0x0000 },
+	{ FLM_RCP_DATA_QW4_OFS, 8, 21, 0x0000 },
+	{ FLM_RCP_DATA_SW8_DYN, 5, 29, 0x0000 },
+	{ FLM_RCP_DATA_SW8_OFS, 8, 34, 0x0000 },
+	{ FLM_RCP_DATA_SW8_SEL, 2, 42, 0x0000 },
+	{ FLM_RCP_DATA_SW9_DYN, 5, 44, 0x0000 },
+	{ FLM_RCP_DATA_SW9_OFS, 8, 49, 0x0000 },
+	{ FLM_RCP_DATA_TXPLM, 2, 400, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_scan_fields[] = {
+	{ FLM_SCAN_I, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s flm_scrub_ctrl_fields[] = {
+	{ FLM_SCRUB_CTRL_ADR, 4, 0, 0x0000 },
+	{ FLM_SCRUB_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_scrub_data_fields[] = {
+	{ FLM_SCRUB_DATA_DEL, 1, 12, 0 },
+	{ FLM_SCRUB_DATA_INF, 1, 13, 0 },
+	{ FLM_SCRUB_DATA_R, 4, 8, 0 },
+	{ FLM_SCRUB_DATA_T, 8, 0, 0 },
+};
+
+static nthw_fpga_field_init_s flm_status_fields[] = {
+	{ FLM_STATUS_CACHE_BUFFER_CRITICAL, 1, 14, 0x0000 },
+	{ FLM_STATUS_CALIB_FAIL, 4, 4, 0 },
+	{ FLM_STATUS_CALIB_SUCCESS, 4, 0, 0 },
+	{ FLM_STATUS_CRCERR, 1, 12, 0x0000 },
+	{ FLM_STATUS_CRITICAL, 1, 10, 0x0000 },
+	{ FLM_STATUS_EFT_BP, 1, 13, 0x0000 },
+	{ FLM_STATUS_IDLE, 1, 9, 0x0000 },
+	{ FLM_STATUS_INITDONE, 1, 8, 0x0000 },
+	{ FLM_STATUS_PANIC, 1, 11, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_aul_done_fields[] = {
+	{ FLM_STAT_AUL_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_aul_fail_fields[] = {
+	{ FLM_STAT_AUL_FAIL_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_aul_ignore_fields[] = {
+	{ FLM_STAT_AUL_IGNORE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_csh_hit_fields[] = {
+	{ FLM_STAT_CSH_HIT_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_csh_miss_fields[] = {
+	{ FLM_STAT_CSH_MISS_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_csh_unh_fields[] = {
+	{ FLM_STAT_CSH_UNH_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_cuc_move_fields[] = {
+	{ FLM_STAT_CUC_MOVE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_cuc_start_fields[] = {
+	{ FLM_STAT_CUC_START_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_flows_fields[] = {
+	{ FLM_STAT_FLOWS_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_inf_done_fields[] = {
+	{ FLM_STAT_INF_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_inf_skip_fields[] = {
+	{ FLM_STAT_INF_SKIP_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_lrn_done_fields[] = {
+	{ FLM_STAT_LRN_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_lrn_fail_fields[] = {
+	{ FLM_STAT_LRN_FAIL_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_lrn_ignore_fields[] = {
+	{ FLM_STAT_LRN_IGNORE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_pck_dis_fields[] = {
+	{ FLM_STAT_PCK_DIS_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_pck_hit_fields[] = {
+	{ FLM_STAT_PCK_HIT_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_pck_miss_fields[] = {
+	{ FLM_STAT_PCK_MISS_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_pck_unh_fields[] = {
+	{ FLM_STAT_PCK_UNH_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_prb_done_fields[] = {
+	{ FLM_STAT_PRB_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_prb_ignore_fields[] = {
+	{ FLM_STAT_PRB_IGNORE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_rel_done_fields[] = {
+	{ FLM_STAT_REL_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_rel_ignore_fields[] = {
+	{ FLM_STAT_REL_IGNORE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_sta_done_fields[] = {
+	{ FLM_STAT_STA_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_tul_done_fields[] = {
+	{ FLM_STAT_TUL_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_unl_done_fields[] = {
+	{ FLM_STAT_UNL_DONE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_stat_unl_ignore_fields[] = {
+	{ FLM_STAT_UNL_IGNORE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s flm_sta_data_fields[] = {
+	{ FLM_STA_DATA_EOR, 1, 95, 0x0000 }, { FLM_STA_DATA_ID, 32, 0, 0x0000 },
+	{ FLM_STA_DATA_LDS, 1, 32, 0x0000 }, { FLM_STA_DATA_LFS, 1, 33, 0x0000 },
+	{ FLM_STA_DATA_LIS, 1, 34, 0x0000 }, { FLM_STA_DATA_PDS, 1, 39, 0x0000 },
+	{ FLM_STA_DATA_PIS, 1, 40, 0x0000 }, { FLM_STA_DATA_RDS, 1, 37, 0x0000 },
+	{ FLM_STA_DATA_RIS, 1, 38, 0x0000 }, { FLM_STA_DATA_UDS, 1, 35, 0x0000 },
+	{ FLM_STA_DATA_UIS, 1, 36, 0x0000 },
+};
+
+static nthw_fpga_register_init_s flm_registers[] = {
+	{ FLM_BUF_CTRL, 14, 48, NTHW_FPGA_REG_TYPE_RW, 0, 3, flm_buf_ctrl_fields },
+	{ FLM_CONTROL, 0, 32, NTHW_FPGA_REG_TYPE_MIXED, 134217728, 18, flm_control_fields },
+	{ FLM_INF_DATA, 16, 288, NTHW_FPGA_REG_TYPE_RO, 0, 6, flm_inf_data_fields },
+	{ FLM_LOAD_APS, 5, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_load_aps_fields },
+	{ FLM_LOAD_BIN, 3, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, flm_load_bin_fields },
+	{ FLM_LOAD_LPS, 4, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_load_lps_fields },
+	{ FLM_LRN_DATA, 15, 768, NTHW_FPGA_REG_TYPE_WO, 0, 34, flm_lrn_data_fields },
+	{ FLM_PRIO, 6, 32, NTHW_FPGA_REG_TYPE_WO, 269488144, 8, flm_prio_fields },
+	{ FLM_PST_CTRL, 12, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, flm_pst_ctrl_fields },
+	{ FLM_PST_DATA, 13, 15, NTHW_FPGA_REG_TYPE_WO, 0, 3, flm_pst_data_fields },
+	{ FLM_RCP_CTRL, 8, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, flm_rcp_ctrl_fields },
+	{ FLM_RCP_DATA, 9, 403, NTHW_FPGA_REG_TYPE_WO, 0, 19, flm_rcp_data_fields },
+	{ FLM_SCAN, 2, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1, flm_scan_fields },
+	{ FLM_SCRUB_CTRL, 10, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, flm_scrub_ctrl_fields },
+	{ FLM_SCRUB_DATA, 11, 14, NTHW_FPGA_REG_TYPE_WO, 0, 4, flm_scrub_data_fields },
+	{ FLM_STATUS, 1, 19, NTHW_FPGA_REG_TYPE_MIXED, 0, 9, flm_status_fields },
+	{ FLM_STAT_AUL_DONE, 41, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_aul_done_fields },
+	{ FLM_STAT_AUL_FAIL, 43, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_aul_fail_fields },
+	{ FLM_STAT_AUL_IGNORE, 42, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_aul_ignore_fields },
+	{ FLM_STAT_CSH_HIT, 52, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_csh_hit_fields },
+	{ FLM_STAT_CSH_MISS, 53, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_csh_miss_fields },
+	{ FLM_STAT_CSH_UNH, 54, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_csh_unh_fields },
+	{ FLM_STAT_CUC_MOVE, 56, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_cuc_move_fields },
+	{ FLM_STAT_CUC_START, 55, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_cuc_start_fields },
+	{ FLM_STAT_FLOWS, 18, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_flows_fields },
+	{ FLM_STAT_INF_DONE, 46, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_inf_done_fields },
+	{ FLM_STAT_INF_SKIP, 47, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_inf_skip_fields },
+	{ FLM_STAT_LRN_DONE, 32, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_lrn_done_fields },
+	{ FLM_STAT_LRN_FAIL, 34, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_lrn_fail_fields },
+	{ FLM_STAT_LRN_IGNORE, 33, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_lrn_ignore_fields },
+	{ FLM_STAT_PCK_DIS, 51, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_pck_dis_fields },
+	{ FLM_STAT_PCK_HIT, 48, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_pck_hit_fields },
+	{ FLM_STAT_PCK_MISS, 49, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_pck_miss_fields },
+	{ FLM_STAT_PCK_UNH, 50, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_pck_unh_fields },
+	{ FLM_STAT_PRB_DONE, 39, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_prb_done_fields },
+	{ FLM_STAT_PRB_IGNORE, 40, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_prb_ignore_fields },
+	{ FLM_STAT_REL_DONE, 37, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_rel_done_fields },
+	{ FLM_STAT_REL_IGNORE, 38, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_rel_ignore_fields },
+	{ FLM_STAT_STA_DONE, 45, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_sta_done_fields },
+	{ FLM_STAT_TUL_DONE, 44, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_tul_done_fields },
+	{ FLM_STAT_UNL_DONE, 35, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_unl_done_fields },
+	{ FLM_STAT_UNL_IGNORE, 36, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, flm_stat_unl_ignore_fields },
+	{ FLM_STA_DATA, 17, 96, NTHW_FPGA_REG_TYPE_RO, 0, 11, flm_sta_data_fields },
+};
+
+static nthw_fpga_field_init_s gfg_burstsize0_fields[] = {
+	{ GFG_BURSTSIZE0_VAL, 24, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_burstsize1_fields[] = {
+	{ GFG_BURSTSIZE1_VAL, 24, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_ctrl0_fields[] = {
+	{ GFG_CTRL0_ENABLE, 1, 0, 0 },
+	{ GFG_CTRL0_MODE, 3, 1, 0 },
+	{ GFG_CTRL0_PRBS_EN, 1, 4, 0 },
+	{ GFG_CTRL0_SIZE, 14, 16, 64 },
+};
+
+static nthw_fpga_field_init_s gfg_ctrl1_fields[] = {
+	{ GFG_CTRL1_ENABLE, 1, 0, 0 },
+	{ GFG_CTRL1_MODE, 3, 1, 0 },
+	{ GFG_CTRL1_PRBS_EN, 1, 4, 0 },
+	{ GFG_CTRL1_SIZE, 14, 16, 64 },
+};
+
+static nthw_fpga_field_init_s gfg_run0_fields[] = {
+	{ GFG_RUN0_RUN, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_run1_fields[] = {
+	{ GFG_RUN1_RUN, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_sizemask0_fields[] = {
+	{ GFG_SIZEMASK0_VAL, 14, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_sizemask1_fields[] = {
+	{ GFG_SIZEMASK1_VAL, 14, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_streamid0_fields[] = {
+	{ GFG_STREAMID0_VAL, 8, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gfg_streamid1_fields[] = {
+	{ GFG_STREAMID1_VAL, 8, 0, 1 },
+};
+
+static nthw_fpga_register_init_s gfg_registers[] = {
+	{ GFG_BURSTSIZE0, 3, 24, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_burstsize0_fields },
+	{ GFG_BURSTSIZE1, 8, 24, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_burstsize1_fields },
+	{ GFG_CTRL0, 0, 30, NTHW_FPGA_REG_TYPE_WO, 4194304, 4, gfg_ctrl0_fields },
+	{ GFG_CTRL1, 5, 30, NTHW_FPGA_REG_TYPE_WO, 4194304, 4, gfg_ctrl1_fields },
+	{ GFG_RUN0, 1, 1, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_run0_fields },
+	{ GFG_RUN1, 6, 1, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_run1_fields },
+	{ GFG_SIZEMASK0, 4, 14, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_sizemask0_fields },
+	{ GFG_SIZEMASK1, 9, 14, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_sizemask1_fields },
+	{ GFG_STREAMID0, 2, 8, NTHW_FPGA_REG_TYPE_WO, 0, 1, gfg_streamid0_fields },
+	{ GFG_STREAMID1, 7, 8, NTHW_FPGA_REG_TYPE_WO, 1, 1, gfg_streamid1_fields },
+};
+
+static nthw_fpga_field_init_s gmf_ctrl_fields[] = {
+	{ GMF_CTRL_ENABLE, 1, 0, 0 },
+	{ GMF_CTRL_FCS_ALWAYS, 1, 1, 0 },
+	{ GMF_CTRL_IFG_AUTO_ADJUST_ENABLE, 1, 7, 0 },
+	{ GMF_CTRL_IFG_ENABLE, 1, 2, 0 },
+	{ GMF_CTRL_IFG_TX_NOW_ALWAYS, 1, 3, 0 },
+	{ GMF_CTRL_IFG_TX_NOW_ON_TS_ENABLE, 1, 5, 0 },
+	{ GMF_CTRL_IFG_TX_ON_TS_ADJUST_ON_SET_CLOCK, 1, 6, 0 },
+	{ GMF_CTRL_IFG_TX_ON_TS_ALWAYS, 1, 4, 0 },
+	{ GMF_CTRL_TS_INJECT_ALWAYS, 1, 8, 0 },
+	{ GMF_CTRL_TS_INJECT_DUAL_STEP, 1, 9, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_debug_lane_marker_fields[] = {
+	{ GMF_DEBUG_LANE_MARKER_COMPENSATION, 16, 0, 16384 },
+};
+
+static nthw_fpga_field_init_s gmf_ifg_max_adjust_slack_fields[] = {
+	{ GMF_IFG_MAX_ADJUST_SLACK_SLACK, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_ifg_set_clock_delta_fields[] = {
+	{ GMF_IFG_SET_CLOCK_DELTA_DELTA, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_ifg_set_clock_delta_adjust_fields[] = {
+	{ GMF_IFG_SET_CLOCK_DELTA_ADJUST_DELTA, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_ifg_tx_now_on_ts_fields[] = {
+	{ GMF_IFG_TX_NOW_ON_TS_TS, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_speed_fields[] = {
+	{ GMF_SPEED_IFG_SPEED, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_stat_data_buffer_fields[] = {
+	{ GMF_STAT_DATA_BUFFER_USED, 15, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s gmf_stat_max_delayed_pkt_fields[] = {
+	{ GMF_STAT_MAX_DELAYED_PKT_NS, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_stat_next_pkt_fields[] = {
+	{ GMF_STAT_NEXT_PKT_NS, 64, 0, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_stat_sticky_fields[] = {
+	{ GMF_STAT_STICKY_DATA_UNDERFLOWED, 1, 0, 0 },
+	{ GMF_STAT_STICKY_IFG_ADJUSTED, 1, 1, 0 },
+};
+
+static nthw_fpga_field_init_s gmf_ts_inject_fields[] = {
+	{ GMF_TS_INJECT_OFFSET, 14, 0, 0 },
+	{ GMF_TS_INJECT_POS, 2, 14, 0 },
+};
+
+static nthw_fpga_register_init_s gmf_registers[] = {
+	{ GMF_CTRL, 0, 10, NTHW_FPGA_REG_TYPE_WO, 0, 10, gmf_ctrl_fields },
+	{
+		GMF_DEBUG_LANE_MARKER, 7, 16, NTHW_FPGA_REG_TYPE_WO, 16384, 1,
+		gmf_debug_lane_marker_fields
+	},
+	{
+		GMF_IFG_MAX_ADJUST_SLACK, 4, 64, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		gmf_ifg_max_adjust_slack_fields
+	},
+	{
+		GMF_IFG_SET_CLOCK_DELTA, 2, 64, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		gmf_ifg_set_clock_delta_fields
+	},
+	{
+		GMF_IFG_SET_CLOCK_DELTA_ADJUST, 3, 64, NTHW_FPGA_REG_TYPE_WO, 0, 1,
+		gmf_ifg_set_clock_delta_adjust_fields
+	},
+	{ GMF_IFG_TX_NOW_ON_TS, 5, 64, NTHW_FPGA_REG_TYPE_WO, 0, 1, gmf_ifg_tx_now_on_ts_fields },
+	{ GMF_SPEED, 1, 64, NTHW_FPGA_REG_TYPE_WO, 0, 1, gmf_speed_fields },
+	{ GMF_STAT_DATA_BUFFER, 9, 15, NTHW_FPGA_REG_TYPE_RO, 0, 1, gmf_stat_data_buffer_fields },
+	{
+		GMF_STAT_MAX_DELAYED_PKT, 11, 64, NTHW_FPGA_REG_TYPE_RC1, 0, 1,
+		gmf_stat_max_delayed_pkt_fields
+	},
+	{ GMF_STAT_NEXT_PKT, 10, 64, NTHW_FPGA_REG_TYPE_RO, 0, 1, gmf_stat_next_pkt_fields },
+	{ GMF_STAT_STICKY, 8, 2, NTHW_FPGA_REG_TYPE_RC1, 0, 2, gmf_stat_sticky_fields },
+	{ GMF_TS_INJECT, 6, 16, NTHW_FPGA_REG_TYPE_WO, 0, 2, gmf_ts_inject_fields },
+};
+
+static nthw_fpga_field_init_s hfu_rcp_ctrl_fields[] = {
+	{ HFU_RCP_CTRL_ADR, 6, 0, 0x0000 },
+	{ HFU_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s hfu_rcp_data_fields[] = {
+	{ HFU_RCP_DATA_LEN_A_ADD_DYN, 5, 15, 0x0000 },
+	{ HFU_RCP_DATA_LEN_A_ADD_OFS, 8, 20, 0x0000 },
+	{ HFU_RCP_DATA_LEN_A_OL4LEN, 1, 1, 0x0000 },
+	{ HFU_RCP_DATA_LEN_A_POS_DYN, 5, 2, 0x0000 },
+	{ HFU_RCP_DATA_LEN_A_POS_OFS, 8, 7, 0x0000 },
+	{ HFU_RCP_DATA_LEN_A_SUB_DYN, 5, 28, 0x0000 },
+	{ HFU_RCP_DATA_LEN_A_WR, 1, 0, 0x0000 },
+	{ HFU_RCP_DATA_LEN_B_ADD_DYN, 5, 47, 0x0000 },
+	{ HFU_RCP_DATA_LEN_B_ADD_OFS, 8, 52, 0x0000 },
+	{ HFU_RCP_DATA_LEN_B_POS_DYN, 5, 34, 0x0000 },
+	{ HFU_RCP_DATA_LEN_B_POS_OFS, 8, 39, 0x0000 },
+	{ HFU_RCP_DATA_LEN_B_SUB_DYN, 5, 60, 0x0000 },
+	{ HFU_RCP_DATA_LEN_B_WR, 1, 33, 0x0000 },
+	{ HFU_RCP_DATA_LEN_C_ADD_DYN, 5, 79, 0x0000 },
+	{ HFU_RCP_DATA_LEN_C_ADD_OFS, 8, 84, 0x0000 },
+	{ HFU_RCP_DATA_LEN_C_POS_DYN, 5, 66, 0x0000 },
+	{ HFU_RCP_DATA_LEN_C_POS_OFS, 8, 71, 0x0000 },
+	{ HFU_RCP_DATA_LEN_C_SUB_DYN, 5, 92, 0x0000 },
+	{ HFU_RCP_DATA_LEN_C_WR, 1, 65, 0x0000 },
+	{ HFU_RCP_DATA_TTL_POS_DYN, 5, 98, 0x0000 },
+	{ HFU_RCP_DATA_TTL_POS_OFS, 8, 103, 0x0000 },
+	{ HFU_RCP_DATA_TTL_WR, 1, 97, 0x0000 },
+};
+
+static nthw_fpga_register_init_s hfu_registers[] = {
+	{ HFU_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, hfu_rcp_ctrl_fields },
+	{ HFU_RCP_DATA, 1, 111, NTHW_FPGA_REG_TYPE_WO, 0, 22, hfu_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s hif_build_time_fields[] = {
+	{ HIF_BUILD_TIME_TIME, 32, 0, 1726786851 },
+};
+
+static nthw_fpga_field_init_s hif_config_fields[] = {
+	{ HIF_CONFIG_EXT_TAG, 1, 6, 0x0000 },
+	{ HIF_CONFIG_MAX_READ, 3, 3, 0x0000 },
+	{ HIF_CONFIG_MAX_TLP, 3, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s hif_control_fields[] = {
+	{ HIF_CONTROL_BLESSED, 8, 4, 0 },
+	{ HIF_CONTROL_FSR, 1, 12, 1 },
+	{ HIF_CONTROL_WRAW, 4, 0, 1 },
+};
+
+static nthw_fpga_field_init_s hif_prod_id_ex_fields[] = {
+	{ HIF_PROD_ID_EX_LAYOUT, 1, 31, 0 },
+	{ HIF_PROD_ID_EX_LAYOUT_VERSION, 8, 0, 1 },
+	{ HIF_PROD_ID_EX_RESERVED, 23, 8, 0 },
+};
+
+static nthw_fpga_field_init_s hif_prod_id_lsb_fields[] = {
+	{ HIF_PROD_ID_LSB_GROUP_ID, 16, 16, 9574 },
+	{ HIF_PROD_ID_LSB_REV_ID, 8, 0, 49 },
+	{ HIF_PROD_ID_LSB_VER_ID, 8, 8, 55 },
+};
+
+static nthw_fpga_field_init_s hif_prod_id_msb_fields[] = {
+	{ HIF_PROD_ID_MSB_BUILD_NO, 10, 12, 0 },
+	{ HIF_PROD_ID_MSB_TYPE_ID, 12, 0, 200 },
+};
+
+static nthw_fpga_field_init_s hif_sample_time_fields[] = {
+	{ HIF_SAMPLE_TIME_SAMPLE_TIME, 1, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s hif_status_fields[] = {
+	{ HIF_STATUS_RD_ERR, 1, 9, 0 },
+	{ HIF_STATUS_TAGS_IN_USE, 8, 0, 0 },
+	{ HIF_STATUS_WR_ERR, 1, 8, 0 },
+};
+
+static nthw_fpga_field_init_s hif_stat_ctrl_fields[] = {
+	{ HIF_STAT_CTRL_STAT_ENA, 1, 1, 0 },
+	{ HIF_STAT_CTRL_STAT_REQ, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s hif_stat_refclk_fields[] = {
+	{ HIF_STAT_REFCLK_REFCLK250, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s hif_stat_rx_fields[] = {
+	{ HIF_STAT_RX_COUNTER, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s hif_stat_tx_fields[] = {
+	{ HIF_STAT_TX_COUNTER, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s hif_test0_fields[] = {
+	{ HIF_TEST0_DATA, 32, 0, 287454020 },
+};
+
+static nthw_fpga_field_init_s hif_test1_fields[] = {
+	{ HIF_TEST1_DATA, 32, 0, 2864434397 },
+};
+
+static nthw_fpga_field_init_s hif_uuid0_fields[] = {
+	{ HIF_UUID0_UUID0, 32, 0, 3012419783 },
+};
+
+static nthw_fpga_field_init_s hif_uuid1_fields[] = {
+	{ HIF_UUID1_UUID1, 32, 0, 2520748366 },
+};
+
+static nthw_fpga_field_init_s hif_uuid2_fields[] = {
+	{ HIF_UUID2_UUID2, 32, 0, 2554609223 },
+};
+
+static nthw_fpga_field_init_s hif_uuid3_fields[] = {
+	{ HIF_UUID3_UUID3, 32, 0, 3614884744 },
+};
+
+static nthw_fpga_register_init_s hif_registers[] = {
+	{ HIF_BUILD_TIME, 16, 32, NTHW_FPGA_REG_TYPE_RO, 1726786851, 1, hif_build_time_fields },
+	{ HIF_CONFIG, 24, 7, NTHW_FPGA_REG_TYPE_RW, 0, 3, hif_config_fields },
+	{ HIF_CONTROL, 40, 13, NTHW_FPGA_REG_TYPE_MIXED, 4097, 3, hif_control_fields },
+	{ HIF_PROD_ID_EX, 112, 32, NTHW_FPGA_REG_TYPE_RO, 1, 3, hif_prod_id_ex_fields },
+	{ HIF_PROD_ID_LSB, 0, 32, NTHW_FPGA_REG_TYPE_RO, 627455793, 3, hif_prod_id_lsb_fields },
+	{ HIF_PROD_ID_MSB, 8, 22, NTHW_FPGA_REG_TYPE_RO, 200, 2, hif_prod_id_msb_fields },
+	{ HIF_SAMPLE_TIME, 96, 1, NTHW_FPGA_REG_TYPE_WO, 0, 1, hif_sample_time_fields },
+	{ HIF_STATUS, 32, 10, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, hif_status_fields },
+	{ HIF_STAT_CTRL, 64, 2, NTHW_FPGA_REG_TYPE_WO, 0, 2, hif_stat_ctrl_fields },
+	{ HIF_STAT_REFCLK, 72, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, hif_stat_refclk_fields },
+	{ HIF_STAT_RX, 88, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, hif_stat_rx_fields },
+	{ HIF_STAT_TX, 80, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, hif_stat_tx_fields },
+	{ HIF_TEST0, 48, 32, NTHW_FPGA_REG_TYPE_RW, 287454020, 1, hif_test0_fields },
+	{ HIF_TEST1, 56, 32, NTHW_FPGA_REG_TYPE_RW, 2864434397, 1, hif_test1_fields },
+	{ HIF_UUID0, 128, 32, NTHW_FPGA_REG_TYPE_RO, 3012419783, 1, hif_uuid0_fields },
+	{ HIF_UUID1, 144, 32, NTHW_FPGA_REG_TYPE_RO, 2520748366, 1, hif_uuid1_fields },
+	{ HIF_UUID2, 160, 32, NTHW_FPGA_REG_TYPE_RO, 2554609223, 1, hif_uuid2_fields },
+	{ HIF_UUID3, 176, 32, NTHW_FPGA_REG_TYPE_RO, 3614884744, 1, hif_uuid3_fields },
+};
+
+static nthw_fpga_field_init_s hsh_rcp_ctrl_fields[] = {
+	{ HSH_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ HSH_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s hsh_rcp_data_fields[] = {
+	{ HSH_RCP_DATA_AUTO_IPV4_MASK, 1, 742, 0x0000 },
+	{ HSH_RCP_DATA_HSH_TYPE, 5, 416, 0x0000 },
+	{ HSH_RCP_DATA_HSH_VALID, 1, 415, 0x0000 },
+	{ HSH_RCP_DATA_K, 320, 422, 0x0000 },
+	{ HSH_RCP_DATA_LOAD_DIST_TYPE, 2, 0, 0x0000 },
+	{ HSH_RCP_DATA_MAC_PORT_MASK, 2, 2, 0x0000 },
+	{ HSH_RCP_DATA_P_MASK, 1, 61, 0x0000 },
+	{ HSH_RCP_DATA_QW0_OFS, 8, 11, 0x0000 },
+	{ HSH_RCP_DATA_QW0_PE, 5, 6, 0x0000 },
+	{ HSH_RCP_DATA_QW4_OFS, 8, 24, 0x0000 },
+	{ HSH_RCP_DATA_QW4_PE, 5, 19, 0x0000 },
+	{ HSH_RCP_DATA_SEED, 32, 382, 0x0000 },
+	{ HSH_RCP_DATA_SORT, 2, 4, 0x0000 },
+	{ HSH_RCP_DATA_TNL_P, 1, 414, 0x0000 },
+	{ HSH_RCP_DATA_TOEPLITZ, 1, 421, 0x0000 },
+	{ HSH_RCP_DATA_W8_OFS, 8, 37, 0x0000 },
+	{ HSH_RCP_DATA_W8_PE, 5, 32, 0x0000 },
+	{ HSH_RCP_DATA_W8_SORT, 1, 45, 0x0000 },
+	{ HSH_RCP_DATA_W9_OFS, 8, 51, 0x0000 },
+	{ HSH_RCP_DATA_W9_P, 1, 60, 0x0000 },
+	{ HSH_RCP_DATA_W9_PE, 5, 46, 0x0000 },
+	{ HSH_RCP_DATA_W9_SORT, 1, 59, 0x0000 },
+	{ HSH_RCP_DATA_WORD_MASK, 320, 62, 0x0000 },
+};
+
+static nthw_fpga_register_init_s hsh_registers[] = {
+	{ HSH_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, hsh_rcp_ctrl_fields },
+	{ HSH_RCP_DATA, 1, 743, NTHW_FPGA_REG_TYPE_WO, 0, 23, hsh_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s i2cm_cmd_status_fields[] = {
+	{ I2CM_CMD_STATUS_CMD_STATUS, 8, 0, 0 },
+};
+
+static nthw_fpga_field_init_s i2cm_ctrl_fields[] = {
+	{ I2CM_CTRL_EN, 1, 7, 0 },
+	{ I2CM_CTRL_IEN, 1, 6, 0 },
+};
+
+static nthw_fpga_field_init_s i2cm_data_fields[] = {
+	{ I2CM_DATA_DATA, 8, 0, 0 },
+};
+
+static nthw_fpga_field_init_s i2cm_io_exp_fields[] = {
+	{ I2CM_IO_EXP_INT_B, 1, 1, 0 },
+	{ I2CM_IO_EXP_RST, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s i2cm_prer_high_fields[] = {
+	{ I2CM_PRER_HIGH_PRER_HIGH, 8, 0, 255 },
+};
+
+static nthw_fpga_field_init_s i2cm_prer_low_fields[] = {
+	{ I2CM_PRER_LOW_PRER_LOW, 8, 0, 255 },
+};
+
+static nthw_fpga_field_init_s i2cm_select_fields[] = {
+	{ I2CM_SELECT_SELECT, 2, 0, 0 },
+};
+
+static nthw_fpga_register_init_s i2cm_registers[] = {
+	{ I2CM_CMD_STATUS, 4, 8, NTHW_FPGA_REG_TYPE_RW, 0, 1, i2cm_cmd_status_fields },
+	{ I2CM_CTRL, 2, 8, NTHW_FPGA_REG_TYPE_RW, 0, 2, i2cm_ctrl_fields },
+	{ I2CM_DATA, 3, 8, NTHW_FPGA_REG_TYPE_RW, 0, 1, i2cm_data_fields },
+	{ I2CM_IO_EXP, 6, 2, NTHW_FPGA_REG_TYPE_MIXED, 0, 2, i2cm_io_exp_fields },
+	{ I2CM_PRER_HIGH, 1, 8, NTHW_FPGA_REG_TYPE_RW, 255, 1, i2cm_prer_high_fields },
+	{ I2CM_PRER_LOW, 0, 8, NTHW_FPGA_REG_TYPE_RW, 255, 1, i2cm_prer_low_fields },
+	{ I2CM_SELECT, 5, 2, NTHW_FPGA_REG_TYPE_RW, 0, 1, i2cm_select_fields },
+};
+
+static nthw_fpga_field_init_s ifr_counters_ctrl_fields[] = {
+	{ IFR_COUNTERS_CTRL_ADR, 4, 0, 0x0000 },
+	{ IFR_COUNTERS_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s ifr_counters_data_fields[] = {
+	{ IFR_COUNTERS_DATA_DROP, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s ifr_df_buf_ctrl_fields[] = {
+	{ IFR_DF_BUF_CTRL_AVAILABLE, 11, 0, 0x0000 },
+	{ IFR_DF_BUF_CTRL_MTU_PROFILE, 16, 11, 0x0000 },
+};
+
+static nthw_fpga_field_init_s ifr_df_buf_data_fields[] = {
+	{ IFR_DF_BUF_DATA_FIFO_DAT, 128, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s ifr_rcp_ctrl_fields[] = {
+	{ IFR_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ IFR_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s ifr_rcp_data_fields[] = {
+	{ IFR_RCP_DATA_IPV4_DF_DROP, 1, 17, 0x0000 }, { IFR_RCP_DATA_IPV4_EN, 1, 0, 0x0000 },
+	{ IFR_RCP_DATA_IPV6_DROP, 1, 16, 0x0000 }, { IFR_RCP_DATA_IPV6_EN, 1, 1, 0x0000 },
+	{ IFR_RCP_DATA_MTU, 14, 2, 0x0000 },
+};
+
+static nthw_fpga_register_init_s ifr_registers[] = {
+	{ IFR_COUNTERS_CTRL, 4, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, ifr_counters_ctrl_fields },
+	{ IFR_COUNTERS_DATA, 5, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, ifr_counters_data_fields },
+	{ IFR_DF_BUF_CTRL, 2, 27, NTHW_FPGA_REG_TYPE_RO, 0, 2, ifr_df_buf_ctrl_fields },
+	{ IFR_DF_BUF_DATA, 3, 128, NTHW_FPGA_REG_TYPE_RO, 0, 1, ifr_df_buf_data_fields },
+	{ IFR_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, ifr_rcp_ctrl_fields },
+	{ IFR_RCP_DATA, 1, 18, NTHW_FPGA_REG_TYPE_WO, 0, 5, ifr_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s igam_base_fields[] = {
+	{ IGAM_BASE_BUSY, 1, 30, 0x0000 },
+	{ IGAM_BASE_CMD, 1, 31, 0x0000 },
+	{ IGAM_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s igam_ctrl_fields[] = {
+	{ IGAM_CTRL_FORCE_RST, 1, 0, 0 },
+	{ IGAM_CTRL_FORWARD_RST, 1, 1, 1 },
+};
+
+static nthw_fpga_field_init_s igam_data_fields[] = {
+	{ IGAM_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s igam_registers[] = {
+	{ IGAM_BASE, 0, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, igam_base_fields },
+	{ IGAM_CTRL, 2, 2, NTHW_FPGA_REG_TYPE_RW, 2, 2, igam_ctrl_fields },
+	{ IGAM_DATA, 1, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1, igam_data_fields },
+};
+
+static nthw_fpga_field_init_s ins_rcp_ctrl_fields[] = {
+	{ INS_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ INS_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s ins_rcp_data_fields[] = {
+	{ INS_RCP_DATA_DYN, 5, 0, 0x0000 },
+	{ INS_RCP_DATA_LEN, 8, 15, 0x0000 },
+	{ INS_RCP_DATA_OFS, 10, 5, 0x0000 },
+};
+
+static nthw_fpga_register_init_s ins_registers[] = {
+	{ INS_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, ins_rcp_ctrl_fields },
+	{ INS_RCP_DATA, 1, 23, NTHW_FPGA_REG_TYPE_WO, 0, 3, ins_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s km_cam_ctrl_fields[] = {
+	{ KM_CAM_CTRL_ADR, 13, 0, 0x0000 },
+	{ KM_CAM_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_cam_data_fields[] = {
+	{ KM_CAM_DATA_FT0, 4, 192, 0x0000 }, { KM_CAM_DATA_FT1, 4, 196, 0x0000 },
+	{ KM_CAM_DATA_FT2, 4, 200, 0x0000 }, { KM_CAM_DATA_FT3, 4, 204, 0x0000 },
+	{ KM_CAM_DATA_FT4, 4, 208, 0x0000 }, { KM_CAM_DATA_FT5, 4, 212, 0x0000 },
+	{ KM_CAM_DATA_W0, 32, 0, 0x0000 }, { KM_CAM_DATA_W1, 32, 32, 0x0000 },
+	{ KM_CAM_DATA_W2, 32, 64, 0x0000 }, { KM_CAM_DATA_W3, 32, 96, 0x0000 },
+	{ KM_CAM_DATA_W4, 32, 128, 0x0000 }, { KM_CAM_DATA_W5, 32, 160, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_rcp_ctrl_fields[] = {
+	{ KM_RCP_CTRL_ADR, 5, 0, 0x0000 },
+	{ KM_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_rcp_data_fields[] = {
+	{ KM_RCP_DATA_BANK_A, 12, 694, 0x0000 }, { KM_RCP_DATA_BANK_B, 12, 706, 0x0000 },
+	{ KM_RCP_DATA_DUAL, 1, 651, 0x0000 }, { KM_RCP_DATA_DW0_B_DYN, 5, 729, 0x0000 },
+	{ KM_RCP_DATA_DW0_B_OFS, 8, 734, 0x0000 }, { KM_RCP_DATA_DW10_DYN, 5, 55, 0x0000 },
+	{ KM_RCP_DATA_DW10_OFS, 8, 60, 0x0000 }, { KM_RCP_DATA_DW10_SEL_A, 2, 68, 0x0000 },
+	{ KM_RCP_DATA_DW10_SEL_B, 2, 70, 0x0000 }, { KM_RCP_DATA_DW2_B_DYN, 5, 742, 0x0000 },
+	{ KM_RCP_DATA_DW2_B_OFS, 8, 747, 0x0000 }, { KM_RCP_DATA_DW8_DYN, 5, 36, 0x0000 },
+	{ KM_RCP_DATA_DW8_OFS, 8, 41, 0x0000 }, { KM_RCP_DATA_DW8_SEL_A, 3, 49, 0x0000 },
+	{ KM_RCP_DATA_DW8_SEL_B, 3, 52, 0x0000 }, { KM_RCP_DATA_EL_A, 4, 653, 0x0000 },
+	{ KM_RCP_DATA_EL_B, 3, 657, 0x0000 }, { KM_RCP_DATA_FTM_A, 16, 662, 0x0000 },
+	{ KM_RCP_DATA_FTM_B, 16, 678, 0x0000 }, { KM_RCP_DATA_INFO_A, 1, 660, 0x0000 },
+	{ KM_RCP_DATA_INFO_B, 1, 661, 0x0000 }, { KM_RCP_DATA_KEYWAY_A, 1, 725, 0x0000 },
+	{ KM_RCP_DATA_KEYWAY_B, 1, 726, 0x0000 }, { KM_RCP_DATA_KL_A, 4, 718, 0x0000 },
+	{ KM_RCP_DATA_KL_B, 3, 722, 0x0000 }, { KM_RCP_DATA_MASK_A, 384, 75, 0x0000 },
+	{ KM_RCP_DATA_MASK_B, 192, 459, 0x0000 }, { KM_RCP_DATA_PAIRED, 1, 652, 0x0000 },
+	{ KM_RCP_DATA_QW0_DYN, 5, 0, 0x0000 }, { KM_RCP_DATA_QW0_OFS, 8, 5, 0x0000 },
+	{ KM_RCP_DATA_QW0_SEL_A, 3, 13, 0x0000 }, { KM_RCP_DATA_QW0_SEL_B, 3, 16, 0x0000 },
+	{ KM_RCP_DATA_QW4_DYN, 5, 19, 0x0000 }, { KM_RCP_DATA_QW4_OFS, 8, 24, 0x0000 },
+	{ KM_RCP_DATA_QW4_SEL_A, 2, 32, 0x0000 }, { KM_RCP_DATA_QW4_SEL_B, 2, 34, 0x0000 },
+	{ KM_RCP_DATA_SW4_B_DYN, 5, 755, 0x0000 }, { KM_RCP_DATA_SW4_B_OFS, 8, 760, 0x0000 },
+	{ KM_RCP_DATA_SW5_B_DYN, 5, 768, 0x0000 }, { KM_RCP_DATA_SW5_B_OFS, 8, 773, 0x0000 },
+	{ KM_RCP_DATA_SWX_CCH, 1, 72, 0x0000 }, { KM_RCP_DATA_SWX_SEL_A, 1, 73, 0x0000 },
+	{ KM_RCP_DATA_SWX_SEL_B, 1, 74, 0x0000 }, { KM_RCP_DATA_SYNERGY_MODE, 2, 727, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_status_fields[] = {
+	{ KM_STATUS_TCQ_RDY, 1, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_tcam_ctrl_fields[] = {
+	{ KM_TCAM_CTRL_ADR, 14, 0, 0x0000 },
+	{ KM_TCAM_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_tcam_data_fields[] = {
+	{ KM_TCAM_DATA_T, 72, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_tci_ctrl_fields[] = {
+	{ KM_TCI_CTRL_ADR, 10, 0, 0x0000 },
+	{ KM_TCI_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_tci_data_fields[] = {
+	{ KM_TCI_DATA_COLOR, 32, 0, 0x0000 },
+	{ KM_TCI_DATA_FT, 4, 32, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_tcq_ctrl_fields[] = {
+	{ KM_TCQ_CTRL_ADR, 7, 0, 0x0000 },
+	{ KM_TCQ_CTRL_CNT, 5, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s km_tcq_data_fields[] = {
+	{ KM_TCQ_DATA_BANK_MASK, 12, 0, 0x0000 },
+	{ KM_TCQ_DATA_QUAL, 3, 12, 0x0000 },
+};
+
+static nthw_fpga_register_init_s km_registers[] = {
+	{ KM_CAM_CTRL, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_cam_ctrl_fields },
+	{ KM_CAM_DATA, 3, 216, NTHW_FPGA_REG_TYPE_WO, 0, 12, km_cam_data_fields },
+	{ KM_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_rcp_ctrl_fields },
+	{ KM_RCP_DATA, 1, 781, NTHW_FPGA_REG_TYPE_WO, 0, 44, km_rcp_data_fields },
+	{ KM_STATUS, 10, 1, NTHW_FPGA_REG_TYPE_RO, 0, 1, km_status_fields },
+	{ KM_TCAM_CTRL, 4, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_tcam_ctrl_fields },
+	{ KM_TCAM_DATA, 5, 72, NTHW_FPGA_REG_TYPE_WO, 0, 1, km_tcam_data_fields },
+	{ KM_TCI_CTRL, 6, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_tci_ctrl_fields },
+	{ KM_TCI_DATA, 7, 36, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_tci_data_fields },
+	{ KM_TCQ_CTRL, 8, 21, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_tcq_ctrl_fields },
+	{ KM_TCQ_DATA, 9, 15, NTHW_FPGA_REG_TYPE_WO, 0, 2, km_tcq_data_fields },
+};
+
+static nthw_fpga_field_init_s pci_rd_tg_tg_ctrl_fields[] = {
+	{ PCI_RD_TG_TG_CTRL_TG_RD_RDY, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_rd_tg_tg_rdaddr_fields[] = {
+	{ PCI_RD_TG_TG_RDADDR_RAM_ADDR, 9, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_rd_tg_tg_rddata0_fields[] = {
+	{ PCI_RD_TG_TG_RDDATA0_PHYS_ADDR_LOW, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_rd_tg_tg_rddata1_fields[] = {
+	{ PCI_RD_TG_TG_RDDATA1_PHYS_ADDR_HIGH, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_rd_tg_tg_rddata2_fields[] = {
+	{ PCI_RD_TG_TG_RDDATA2_REQ_HID, 6, 22, 0 },
+	{ PCI_RD_TG_TG_RDDATA2_REQ_SIZE, 22, 0, 0 },
+	{ PCI_RD_TG_TG_RDDATA2_WAIT, 1, 30, 0 },
+	{ PCI_RD_TG_TG_RDDATA2_WRAP, 1, 31, 0 },
+};
+
+static nthw_fpga_field_init_s pci_rd_tg_tg_rd_run_fields[] = {
+	{ PCI_RD_TG_TG_RD_RUN_RD_ITERATION, 16, 0, 0 },
+};
+
+static nthw_fpga_register_init_s pci_rd_tg_registers[] = {
+	{ PCI_RD_TG_TG_CTRL, 5, 1, NTHW_FPGA_REG_TYPE_RO, 0, 1, pci_rd_tg_tg_ctrl_fields },
+	{ PCI_RD_TG_TG_RDADDR, 3, 9, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_rd_tg_tg_rdaddr_fields },
+	{ PCI_RD_TG_TG_RDDATA0, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_rd_tg_tg_rddata0_fields },
+	{ PCI_RD_TG_TG_RDDATA1, 1, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_rd_tg_tg_rddata1_fields },
+	{ PCI_RD_TG_TG_RDDATA2, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 4, pci_rd_tg_tg_rddata2_fields },
+	{ PCI_RD_TG_TG_RD_RUN, 4, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_rd_tg_tg_rd_run_fields },
+};
+
+static nthw_fpga_field_init_s pci_ta_control_fields[] = {
+	{ PCI_TA_CONTROL_ENABLE, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_ta_length_error_fields[] = {
+	{ PCI_TA_LENGTH_ERROR_AMOUNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s pci_ta_packet_bad_fields[] = {
+	{ PCI_TA_PACKET_BAD_AMOUNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s pci_ta_packet_good_fields[] = {
+	{ PCI_TA_PACKET_GOOD_AMOUNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s pci_ta_payload_error_fields[] = {
+	{ PCI_TA_PAYLOAD_ERROR_AMOUNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s pci_ta_registers[] = {
+	{ PCI_TA_CONTROL, 0, 1, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_ta_control_fields },
+	{ PCI_TA_LENGTH_ERROR, 3, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, pci_ta_length_error_fields },
+	{ PCI_TA_PACKET_BAD, 2, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, pci_ta_packet_bad_fields },
+	{ PCI_TA_PACKET_GOOD, 1, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, pci_ta_packet_good_fields },
+	{ PCI_TA_PAYLOAD_ERROR, 4, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, pci_ta_payload_error_fields },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_ctrl_fields[] = {
+	{ PCI_WR_TG_TG_CTRL_TG_WR_RDY, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_seq_fields[] = {
+	{ PCI_WR_TG_TG_SEQ_SEQUENCE, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_wraddr_fields[] = {
+	{ PCI_WR_TG_TG_WRADDR_RAM_ADDR, 9, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_wrdata0_fields[] = {
+	{ PCI_WR_TG_TG_WRDATA0_PHYS_ADDR_LOW, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_wrdata1_fields[] = {
+	{ PCI_WR_TG_TG_WRDATA1_PHYS_ADDR_HIGH, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_wrdata2_fields[] = {
+	{ PCI_WR_TG_TG_WRDATA2_INC_MODE, 1, 29, 0 }, { PCI_WR_TG_TG_WRDATA2_REQ_HID, 6, 22, 0 },
+	{ PCI_WR_TG_TG_WRDATA2_REQ_SIZE, 22, 0, 0 }, { PCI_WR_TG_TG_WRDATA2_WAIT, 1, 30, 0 },
+	{ PCI_WR_TG_TG_WRDATA2_WRAP, 1, 31, 0 },
+};
+
+static nthw_fpga_field_init_s pci_wr_tg_tg_wr_run_fields[] = {
+	{ PCI_WR_TG_TG_WR_RUN_WR_ITERATION, 16, 0, 0 },
+};
+
+static nthw_fpga_register_init_s pci_wr_tg_registers[] = {
+	{ PCI_WR_TG_TG_CTRL, 5, 1, NTHW_FPGA_REG_TYPE_RO, 0, 1, pci_wr_tg_tg_ctrl_fields },
+	{ PCI_WR_TG_TG_SEQ, 6, 16, NTHW_FPGA_REG_TYPE_RW, 0, 1, pci_wr_tg_tg_seq_fields },
+	{ PCI_WR_TG_TG_WRADDR, 3, 9, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_wr_tg_tg_wraddr_fields },
+	{ PCI_WR_TG_TG_WRDATA0, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_wr_tg_tg_wrdata0_fields },
+	{ PCI_WR_TG_TG_WRDATA1, 1, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_wr_tg_tg_wrdata1_fields },
+	{ PCI_WR_TG_TG_WRDATA2, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 5, pci_wr_tg_tg_wrdata2_fields },
+	{ PCI_WR_TG_TG_WR_RUN, 4, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1, pci_wr_tg_tg_wr_run_fields },
+};
+
+static nthw_fpga_field_init_s pcm_nt400dxx_ctrl_fields[] = {
+	{ PCM_NT400DXX_CTRL_TS_PLL_RECAL, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pcm_nt400dxx_latch_fields[] = {
+	{ PCM_NT400DXX_LATCH_TS_PLL_LOCKED, 1, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s pcm_nt400dxx_stat_fields[] = {
+	{ PCM_NT400DXX_STAT_TS_PLL_LOCKED, 1, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s pcm_nt400dxx_registers[] = {
+	{ PCM_NT400DXX_CTRL, 0, 1, NTHW_FPGA_REG_TYPE_RW, 0, 1, pcm_nt400dxx_ctrl_fields },
+	{ PCM_NT400DXX_LATCH, 2, 1, NTHW_FPGA_REG_TYPE_RW, 0, 1, pcm_nt400dxx_latch_fields },
+	{ PCM_NT400DXX_STAT, 1, 1, NTHW_FPGA_REG_TYPE_RO, 0, 1, pcm_nt400dxx_stat_fields },
+};
+
+static nthw_fpga_field_init_s pdb_config_fields[] = {
+	{ PDB_CONFIG_PORT_OFS, 6, 3, 0 },
+	{ PDB_CONFIG_TS_FORMAT, 3, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pdb_rcp_ctrl_fields[] = {
+	{ PDB_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ PDB_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s pdb_rcp_data_fields[] = {
+	{ PDB_RCP_DATA_ALIGN, 1, 17, 0x0000 },
+	{ PDB_RCP_DATA_CRC_OVERWRITE, 1, 16, 0x0000 },
+	{ PDB_RCP_DATA_DESCRIPTOR, 4, 0, 0x0000 },
+	{ PDB_RCP_DATA_DESC_LEN, 5, 4, 0 },
+	{ PDB_RCP_DATA_DUPLICATE_BIT, 5, 61, 0x0000 },
+	{ PDB_RCP_DATA_DUPLICATE_EN, 1, 60, 0x0000 },
+	{ PDB_RCP_DATA_IP_PROT_TNL, 1, 57, 0x0000 },
+	{ PDB_RCP_DATA_OFS0_DYN, 5, 18, 0x0000 },
+	{ PDB_RCP_DATA_OFS0_REL, 8, 23, 0x0000 },
+	{ PDB_RCP_DATA_OFS1_DYN, 5, 31, 0x0000 },
+	{ PDB_RCP_DATA_OFS1_REL, 8, 36, 0x0000 },
+	{ PDB_RCP_DATA_OFS2_DYN, 5, 44, 0x0000 },
+	{ PDB_RCP_DATA_OFS2_REL, 8, 49, 0x0000 },
+	{ PDB_RCP_DATA_PCAP_KEEP_FCS, 1, 66, 0x0000 },
+	{ PDB_RCP_DATA_PPC_HSH, 2, 58, 0x0000 },
+	{ PDB_RCP_DATA_TX_IGNORE, 1, 14, 0x0000 },
+	{ PDB_RCP_DATA_TX_NOW, 1, 15, 0x0000 },
+	{ PDB_RCP_DATA_TX_PORT, 5, 9, 0x0000 },
+};
+
+static nthw_fpga_register_init_s pdb_registers[] = {
+	{ PDB_CONFIG, 2, 10, NTHW_FPGA_REG_TYPE_WO, 0, 2, pdb_config_fields },
+	{ PDB_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, pdb_rcp_ctrl_fields },
+	{ PDB_RCP_DATA, 1, 67, NTHW_FPGA_REG_TYPE_WO, 0, 18, pdb_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s pdi_cr_fields[] = {
+	{ PDI_CR_EN, 1, 0, 0 }, { PDI_CR_PARITY, 1, 4, 0 }, { PDI_CR_RST, 1, 1, 0 },
+	{ PDI_CR_RXRST, 1, 2, 0 }, { PDI_CR_STOP, 1, 5, 0 }, { PDI_CR_TXRST, 1, 3, 0 },
+};
+
+static nthw_fpga_field_init_s pdi_drr_fields[] = {
+	{ PDI_DRR_DRR, 8, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pdi_dtr_fields[] = {
+	{ PDI_DTR_DTR, 8, 0, 0 },
+};
+
+static nthw_fpga_field_init_s pdi_pre_fields[] = {
+	{ PDI_PRE_PRE, 7, 0, 3 },
+};
+
+static nthw_fpga_field_init_s pdi_sr_fields[] = {
+	{ PDI_SR_DISABLE_BUSY, 1, 2, 0 }, { PDI_SR_DONE, 1, 0, 0 },
+	{ PDI_SR_ENABLE_BUSY, 1, 1, 0 }, { PDI_SR_FRAME_ERR, 1, 5, 0 },
+	{ PDI_SR_OVERRUN_ERR, 1, 7, 0 }, { PDI_SR_PARITY_ERR, 1, 6, 0 },
+	{ PDI_SR_RXLVL, 7, 8, 0 }, { PDI_SR_RX_BUSY, 1, 4, 0 },
+	{ PDI_SR_TXLVL, 7, 15, 0 }, { PDI_SR_TX_BUSY, 1, 3, 0 },
+};
+
+static nthw_fpga_field_init_s pdi_srr_fields[] = {
+	{ PDI_SRR_RST, 4, 0, 0 },
+};
+
+static nthw_fpga_register_init_s pdi_registers[] = {
+	{ PDI_CR, 1, 6, NTHW_FPGA_REG_TYPE_WO, 0, 6, pdi_cr_fields },
+	{ PDI_DRR, 4, 8, NTHW_FPGA_REG_TYPE_RO, 0, 1, pdi_drr_fields },
+	{ PDI_DTR, 3, 8, NTHW_FPGA_REG_TYPE_WO, 0, 1, pdi_dtr_fields },
+	{ PDI_PRE, 5, 7, NTHW_FPGA_REG_TYPE_WO, 3, 1, pdi_pre_fields },
+	{ PDI_SR, 2, 22, NTHW_FPGA_REG_TYPE_RO, 0, 10, pdi_sr_fields },
+	{ PDI_SRR, 0, 4, NTHW_FPGA_REG_TYPE_WO, 0, 1, pdi_srr_fields },
+};
+
+static nthw_fpga_field_init_s phy_tile_dr_cfg_fields[] = {
+	{ PHY_TILE_DR_CFG_DYN_RST, 1, 0, 0 },
+	{ PHY_TILE_DR_CFG_FEATURES, 7, 9, 0x0000 },
+	{ PHY_TILE_DR_CFG_SCRATCH, 8, 1, 0x0000 },
+	{ PHY_TILE_DR_CFG_TX_FLUSH_LEVEL, 6, 16, 23 },
+};
+
+static nthw_fpga_field_init_s phy_tile_dr_cfg_status_fields[] = {
+	{ PHY_TILE_DR_CFG_STATUS_CURR_PROFILE_ID, 15, 0, 0x0000 },
+	{ PHY_TILE_DR_CFG_STATUS_ERROR, 1, 16, 0x0000 },
+	{ PHY_TILE_DR_CFG_STATUS_IN_PROGRESS, 1, 15, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_dyn_reconfig_base_fields[] = {
+	{ PHY_TILE_DYN_RECONFIG_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_DYN_RECONFIG_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_DYN_RECONFIG_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_dyn_reconfig_data_fields[] = {
+	{ PHY_TILE_DYN_RECONFIG_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_link_summary_0_fields[] = {
+	{ PHY_TILE_LINK_SUMMARY_0_LH_RECEIVED_LOCAL_FAULT, 1, 14, 0 },
+	{ PHY_TILE_LINK_SUMMARY_0_LH_REMOTE_FAULT, 1, 15, 0 },
+	{ PHY_TILE_LINK_SUMMARY_0_LH_RX_HIGH_BIT_ERROR_RATE, 1, 13, 0 },
+	{ PHY_TILE_LINK_SUMMARY_0_LINK_DOWN_CNT, 8, 2, 0 },
+	{ PHY_TILE_LINK_SUMMARY_0_LL_PHY_LINK_STATE, 1, 1, 1 },
+	{ PHY_TILE_LINK_SUMMARY_0_LL_RX_AM_LOCK, 1, 11, 1 },
+	{ PHY_TILE_LINK_SUMMARY_0_LL_RX_BLOCK_LOCK, 1, 10, 1 },
+	{ PHY_TILE_LINK_SUMMARY_0_NT_PHY_LINK_STATE, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s phy_tile_link_summary_1_fields[] = {
+	{ PHY_TILE_LINK_SUMMARY_1_LH_RECEIVED_LOCAL_FAULT, 1, 14, 0 },
+	{ PHY_TILE_LINK_SUMMARY_1_LH_REMOTE_FAULT, 1, 15, 0 },
+	{ PHY_TILE_LINK_SUMMARY_1_LH_RX_HIGH_BIT_ERROR_RATE, 1, 13, 0 },
+	{ PHY_TILE_LINK_SUMMARY_1_LINK_DOWN_CNT, 8, 2, 0 },
+	{ PHY_TILE_LINK_SUMMARY_1_LL_PHY_LINK_STATE, 1, 1, 1 },
+	{ PHY_TILE_LINK_SUMMARY_1_LL_RX_AM_LOCK, 1, 11, 1 },
+	{ PHY_TILE_LINK_SUMMARY_1_LL_RX_BLOCK_LOCK, 1, 10, 1 },
+	{ PHY_TILE_LINK_SUMMARY_1_NT_PHY_LINK_STATE, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_eth_0_base_fields[] = {
+	{ PHY_TILE_PORT_0_ETH_0_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_0_ETH_0_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_0_ETH_0_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_eth_0_data_fields[] = {
+	{ PHY_TILE_PORT_0_ETH_0_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_0_base_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_0_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_0_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_0_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_0_data_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_0_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_1_base_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_1_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_1_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_1_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_1_data_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_1_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_2_base_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_2_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_2_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_2_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_2_data_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_2_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_3_base_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_3_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_3_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_0_XCVR_3_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_0_xcvr_3_data_fields[] = {
+	{ PHY_TILE_PORT_0_XCVR_3_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_eth_0_base_fields[] = {
+	{ PHY_TILE_PORT_1_ETH_0_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_1_ETH_0_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_1_ETH_0_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_eth_0_data_fields[] = {
+	{ PHY_TILE_PORT_1_ETH_0_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_0_base_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_0_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_0_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_0_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_0_data_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_0_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_1_base_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_1_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_1_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_1_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_1_data_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_1_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_2_base_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_2_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_2_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_2_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_2_data_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_2_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_3_base_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_3_BASE_BUSY, 1, 30, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_3_BASE_CMD, 1, 31, 0x0000 },
+	{ PHY_TILE_PORT_1_XCVR_3_BASE_PTR, 30, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_1_xcvr_3_data_fields[] = {
+	{ PHY_TILE_PORT_1_XCVR_3_DATA_DATA, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_comp_0_fields[] = {
+	{ PHY_TILE_PORT_COMP_0_RX_COMPENSATION, 16, 0, 0 },
+	{ PHY_TILE_PORT_COMP_0_TX_COMPENSATION, 16, 16, 0 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_comp_1_fields[] = {
+	{ PHY_TILE_PORT_COMP_1_RX_COMPENSATION, 16, 0, 0 },
+	{ PHY_TILE_PORT_COMP_1_TX_COMPENSATION, 16, 16, 0 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_config_0_fields[] = {
+	{ PHY_TILE_PORT_CONFIG_0_NT_AUTO_FORCE_LINK_DOWN, 1, 12, 0 },
+	{ PHY_TILE_PORT_CONFIG_0_NT_FORCE_LINK_DOWN, 1, 11, 0 },
+	{ PHY_TILE_PORT_CONFIG_0_NT_LINKUP_LATENCY, 8, 3, 10 },
+	{ PHY_TILE_PORT_CONFIG_0_RST, 1, 0, 1 },
+	{ PHY_TILE_PORT_CONFIG_0_RX_RST, 1, 1, 1 },
+	{ PHY_TILE_PORT_CONFIG_0_TX_RST, 1, 2, 1 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_config_1_fields[] = {
+	{ PHY_TILE_PORT_CONFIG_1_NT_AUTO_FORCE_LINK_DOWN, 1, 12, 0 },
+	{ PHY_TILE_PORT_CONFIG_1_NT_FORCE_LINK_DOWN, 1, 11, 0 },
+	{ PHY_TILE_PORT_CONFIG_1_NT_LINKUP_LATENCY, 8, 3, 10 },
+	{ PHY_TILE_PORT_CONFIG_1_RST, 1, 0, 1 },
+	{ PHY_TILE_PORT_CONFIG_1_RX_RST, 1, 1, 1 },
+	{ PHY_TILE_PORT_CONFIG_1_TX_RST, 1, 2, 1 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_status_0_fields[] = {
+	{ PHY_TILE_PORT_STATUS_0_RESET_ACK_N, 1, 0, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_RX_AM_LOCK, 1, 10, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_RX_HI_BER, 1, 7, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_RX_LOCAL_FAULT, 1, 9, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_RX_PCS_FULLY_ALIGNED, 1, 6, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_RX_REMOTE_FAULT, 1, 8, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_RX_RESET_ACK_N, 1, 2, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_SYS_PLL_LOCKED, 1, 5, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_TX_LANES_STABLE, 1, 3, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_TX_PLL_LOCKED, 1, 4, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_0_TX_RESET_ACK_N, 1, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_port_status_1_fields[] = {
+	{ PHY_TILE_PORT_STATUS_1_RESET_ACK_N, 1, 0, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_RX_AM_LOCK, 1, 10, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_RX_HI_BER, 1, 7, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_RX_LOCAL_FAULT, 1, 9, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_RX_PCS_FULLY_ALIGNED, 1, 6, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_RX_REMOTE_FAULT, 1, 8, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_RX_RESET_ACK_N, 1, 2, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_SYS_PLL_LOCKED, 1, 5, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_TX_LANES_STABLE, 1, 3, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_TX_PLL_LOCKED, 1, 4, 0x0000 },
+	{ PHY_TILE_PORT_STATUS_1_TX_RESET_ACK_N, 1, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s phy_tile_sys_pll_fields[] = {
+	{ PHY_TILE_SYS_PLL_DISABLE_REFCLK_MONITOR, 8, 13, 0 },
+	{ PHY_TILE_SYS_PLL_EN_REFCLK_FGT, 8, 5, 0 },
+	{ PHY_TILE_SYS_PLL_FORCE_RST, 1, 29, 0 },
+	{ PHY_TILE_SYS_PLL_FORWARD_RST, 1, 30, 1 },
+	{ PHY_TILE_SYS_PLL_GET_RDY, 1, 3, 0x0000 },
+	{ PHY_TILE_SYS_PLL_REFCLK_FGT_ENABLED, 8, 21, 0 },
+	{ PHY_TILE_SYS_PLL_SET_RDY, 3, 0, 0 },
+	{ PHY_TILE_SYS_PLL_SYSTEMPLL_LOCK, 1, 4, 0x0000 },
+};
+
+static nthw_fpga_register_init_s phy_tile_registers[] = {
+	{ PHY_TILE_DR_CFG, 32, 22, NTHW_FPGA_REG_TYPE_MIXED, 1507328, 4, phy_tile_dr_cfg_fields },
+	{
+		PHY_TILE_DR_CFG_STATUS, 31, 19, NTHW_FPGA_REG_TYPE_RO, 0, 3,
+		phy_tile_dr_cfg_status_fields
+	},
+	{
+		PHY_TILE_DYN_RECONFIG_BASE, 20, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_dyn_reconfig_base_fields
+	},
+	{
+		PHY_TILE_DYN_RECONFIG_DATA, 21, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_dyn_reconfig_data_fields
+	},
+	{
+		PHY_TILE_LINK_SUMMARY_0, 27, 16, NTHW_FPGA_REG_TYPE_RO, 7170, 8,
+		phy_tile_link_summary_0_fields
+	},
+	{
+		PHY_TILE_LINK_SUMMARY_1, 28, 16, NTHW_FPGA_REG_TYPE_RO, 7170, 8,
+		phy_tile_link_summary_1_fields
+	},
+	{
+		PHY_TILE_PORT_0_ETH_0_BASE, 8, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_0_eth_0_base_fields
+	},
+	{
+		PHY_TILE_PORT_0_ETH_0_DATA, 9, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_0_eth_0_data_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_0_BASE, 0, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_0_xcvr_0_base_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_0_DATA, 1, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_0_xcvr_0_data_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_1_BASE, 2, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_0_xcvr_1_base_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_1_DATA, 3, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_0_xcvr_1_data_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_2_BASE, 4, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_0_xcvr_2_base_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_2_DATA, 5, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_0_xcvr_2_data_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_3_BASE, 6, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_0_xcvr_3_base_fields
+	},
+	{
+		PHY_TILE_PORT_0_XCVR_3_DATA, 7, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_0_xcvr_3_data_fields
+	},
+	{
+		PHY_TILE_PORT_1_ETH_0_BASE, 18, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_1_eth_0_base_fields
+	},
+	{
+		PHY_TILE_PORT_1_ETH_0_DATA, 19, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_1_eth_0_data_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_0_BASE, 10, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_1_xcvr_0_base_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_0_DATA, 11, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_1_xcvr_0_data_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_1_BASE, 12, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_1_xcvr_1_base_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_1_DATA, 13, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_1_xcvr_1_data_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_2_BASE, 14, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_1_xcvr_2_base_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_2_DATA, 15, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_1_xcvr_2_data_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_3_BASE, 16, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3,
+		phy_tile_port_1_xcvr_3_base_fields
+	},
+	{
+		PHY_TILE_PORT_1_XCVR_3_DATA, 17, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1,
+		phy_tile_port_1_xcvr_3_data_fields
+	},
+	{ PHY_TILE_PORT_COMP_0, 35, 32, NTHW_FPGA_REG_TYPE_RW, 0, 2, phy_tile_port_comp_0_fields },
+	{ PHY_TILE_PORT_COMP_1, 36, 32, NTHW_FPGA_REG_TYPE_RW, 0, 2, phy_tile_port_comp_1_fields },
+	{
+		PHY_TILE_PORT_CONFIG_0, 33, 13, NTHW_FPGA_REG_TYPE_RW, 87, 6,
+		phy_tile_port_config_0_fields
+	},
+	{
+		PHY_TILE_PORT_CONFIG_1, 34, 13, NTHW_FPGA_REG_TYPE_RW, 87, 6,
+		phy_tile_port_config_1_fields
+	},
+	{
+		PHY_TILE_PORT_STATUS_0, 29, 16, NTHW_FPGA_REG_TYPE_RO, 0, 11,
+		phy_tile_port_status_0_fields
+	},
+	{
+		PHY_TILE_PORT_STATUS_1, 30, 16, NTHW_FPGA_REG_TYPE_RO, 0, 11,
+		phy_tile_port_status_1_fields
+	},
+	{
+		PHY_TILE_SYS_PLL, 26, 31, NTHW_FPGA_REG_TYPE_MIXED, 1073741824, 8,
+		phy_tile_sys_pll_fields
+	},
+};
+
+static nthw_fpga_field_init_s prm_nt400dxx_rst_fields[] = {
+	{ PRM_NT400DXX_RST_PERIPH, 1, 0, 0 },
+	{ PRM_NT400DXX_RST_PLATFORM, 1, 1, 1 },
+};
+
+static nthw_fpga_register_init_s prm_nt400dxx_registers[] = {
+	{ PRM_NT400DXX_RST, 0, 2, NTHW_FPGA_REG_TYPE_RW, 2, 2, prm_nt400dxx_rst_fields },
+};
+
+static nthw_fpga_field_init_s qsl_qen_ctrl_fields[] = {
+	{ QSL_QEN_CTRL_ADR, 5, 0, 0x0000 },
+	{ QSL_QEN_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_qen_data_fields[] = {
+	{ QSL_QEN_DATA_EN, 4, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_qst_ctrl_fields[] = {
+	{ QSL_QST_CTRL_ADR, 12, 0, 0x0000 },
+	{ QSL_QST_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_qst_data_fields[] = {
+	{ QSL_QST_DATA_LRE, 1, 9, 0x0000 }, { QSL_QST_DATA_QEN, 1, 7, 0x0000 },
+	{ QSL_QST_DATA_QUEUE, 7, 0, 0x0000 }, { QSL_QST_DATA_TCI, 16, 10, 0x0000 },
+	{ QSL_QST_DATA_TX_PORT, 1, 8, 0x0000 }, { QSL_QST_DATA_VEN, 1, 26, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_rcp_ctrl_fields[] = {
+	{ QSL_RCP_CTRL_ADR, 5, 0, 0x0000 },
+	{ QSL_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_rcp_data_fields[] = {
+	{ QSL_RCP_DATA_DISCARD, 1, 0, 0x0000 }, { QSL_RCP_DATA_DROP, 2, 1, 0x0000 },
+	{ QSL_RCP_DATA_LR, 2, 51, 0x0000 }, { QSL_RCP_DATA_TBL_HI, 12, 15, 0x0000 },
+	{ QSL_RCP_DATA_TBL_IDX, 12, 27, 0x0000 }, { QSL_RCP_DATA_TBL_LO, 12, 3, 0x0000 },
+	{ QSL_RCP_DATA_TBL_MSK, 12, 39, 0x0000 }, { QSL_RCP_DATA_TSA, 1, 53, 0x0000 },
+	{ QSL_RCP_DATA_VLI, 2, 54, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_unmq_ctrl_fields[] = {
+	{ QSL_UNMQ_CTRL_ADR, 1, 0, 0x0000 },
+	{ QSL_UNMQ_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s qsl_unmq_data_fields[] = {
+	{ QSL_UNMQ_DATA_DEST_QUEUE, 7, 0, 0x0000 },
+	{ QSL_UNMQ_DATA_EN, 1, 7, 0x0000 },
+};
+
+static nthw_fpga_register_init_s qsl_registers[] = {
+	{ QSL_QEN_CTRL, 4, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, qsl_qen_ctrl_fields },
+	{ QSL_QEN_DATA, 5, 4, NTHW_FPGA_REG_TYPE_WO, 0, 1, qsl_qen_data_fields },
+	{ QSL_QST_CTRL, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, qsl_qst_ctrl_fields },
+	{ QSL_QST_DATA, 3, 27, NTHW_FPGA_REG_TYPE_WO, 0, 6, qsl_qst_data_fields },
+	{ QSL_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, qsl_rcp_ctrl_fields },
+	{ QSL_RCP_DATA, 1, 56, NTHW_FPGA_REG_TYPE_WO, 0, 9, qsl_rcp_data_fields },
+	{ QSL_UNMQ_CTRL, 6, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, qsl_unmq_ctrl_fields },
+	{ QSL_UNMQ_DATA, 7, 8, NTHW_FPGA_REG_TYPE_WO, 0, 2, qsl_unmq_data_fields },
+};
+
+static nthw_fpga_field_init_s rac_dbg_ctrl_fields[] = {
+	{ RAC_DBG_CTRL_C, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rac_dbg_data_fields[] = {
+	{ RAC_DBG_DATA_D, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rac_rab_buf_free_fields[] = {
+	{ RAC_RAB_BUF_FREE_IB_FREE, 9, 0, 511 }, { RAC_RAB_BUF_FREE_IB_OVF, 1, 12, 0 },
+	{ RAC_RAB_BUF_FREE_OB_FREE, 9, 16, 511 }, { RAC_RAB_BUF_FREE_OB_OVF, 1, 28, 0 },
+	{ RAC_RAB_BUF_FREE_TIMEOUT, 1, 31, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_buf_used_fields[] = {
+	{ RAC_RAB_BUF_USED_FLUSH, 1, 31, 0 },
+	{ RAC_RAB_BUF_USED_IB_USED, 9, 0, 0 },
+	{ RAC_RAB_BUF_USED_OB_USED, 9, 16, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ib_hi_fields[] = {
+	{ RAC_RAB_DMA_IB_HI_PHYADDR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ib_lo_fields[] = {
+	{ RAC_RAB_DMA_IB_LO_PHYADDR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ib_rd_fields[] = {
+	{ RAC_RAB_DMA_IB_RD_PTR, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ib_wr_fields[] = {
+	{ RAC_RAB_DMA_IB_WR_PTR, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ob_hi_fields[] = {
+	{ RAC_RAB_DMA_OB_HI_PHYADDR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ob_lo_fields[] = {
+	{ RAC_RAB_DMA_OB_LO_PHYADDR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_dma_ob_wr_fields[] = {
+	{ RAC_RAB_DMA_OB_WR_PTR, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s rac_rab_ib_data_fields[] = {
+	{ RAC_RAB_IB_DATA_D, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rac_rab_init_fields[] = {
+	{ RAC_RAB_INIT_RAB, 3, 0, 7 },
+};
+
+static nthw_fpga_field_init_s rac_rab_ob_data_fields[] = {
+	{ RAC_RAB_OB_DATA_D, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s rac_registers[] = {
+	{ RAC_DBG_CTRL, 4200, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1, rac_dbg_ctrl_fields },
+	{ RAC_DBG_DATA, 4208, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1, rac_dbg_data_fields },
+	{
+		RAC_RAB_BUF_FREE, 4176, 32, NTHW_FPGA_REG_TYPE_MIXED, 33489407, 5,
+		rac_rab_buf_free_fields
+	},
+	{ RAC_RAB_BUF_USED, 4184, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, rac_rab_buf_used_fields },
+	{ RAC_RAB_DMA_IB_HI, 4360, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, rac_rab_dma_ib_hi_fields },
+	{ RAC_RAB_DMA_IB_LO, 4352, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, rac_rab_dma_ib_lo_fields },
+	{ RAC_RAB_DMA_IB_RD, 4424, 16, NTHW_FPGA_REG_TYPE_RO, 0, 1, rac_rab_dma_ib_rd_fields },
+	{ RAC_RAB_DMA_IB_WR, 4416, 16, NTHW_FPGA_REG_TYPE_WO, 0, 1, rac_rab_dma_ib_wr_fields },
+	{ RAC_RAB_DMA_OB_HI, 4376, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, rac_rab_dma_ob_hi_fields },
+	{ RAC_RAB_DMA_OB_LO, 4368, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, rac_rab_dma_ob_lo_fields },
+	{ RAC_RAB_DMA_OB_WR, 4480, 16, NTHW_FPGA_REG_TYPE_RO, 0, 1, rac_rab_dma_ob_wr_fields },
+	{ RAC_RAB_IB_DATA, 4160, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, rac_rab_ib_data_fields },
+	{ RAC_RAB_INIT, 4192, 3, NTHW_FPGA_REG_TYPE_RW, 7, 1, rac_rab_init_fields },
+	{ RAC_RAB_OB_DATA, 4168, 32, NTHW_FPGA_REG_TYPE_RC1, 0, 1, rac_rab_ob_data_fields },
+};
+
+static nthw_fpga_field_init_s rfd_ctrl_fields[] = {
+	{ RFD_CTRL_CFP, 1, 2, 1 },
+	{ RFD_CTRL_ISL, 1, 0, 1 },
+	{ RFD_CTRL_PWMCW, 1, 1, 1 },
+};
+
+static nthw_fpga_field_init_s rfd_max_frame_size_fields[] = {
+	{ RFD_MAX_FRAME_SIZE_MAX, 14, 0, 9018 },
+};
+
+static nthw_fpga_field_init_s rfd_tnl_vlan_fields[] = {
+	{ RFD_TNL_VLAN_TPID0, 16, 0, 33024 },
+	{ RFD_TNL_VLAN_TPID1, 16, 16, 33024 },
+};
+
+static nthw_fpga_field_init_s rfd_vlan_fields[] = {
+	{ RFD_VLAN_TPID0, 16, 0, 33024 },
+	{ RFD_VLAN_TPID1, 16, 16, 33024 },
+};
+
+static nthw_fpga_field_init_s rfd_vxlan_fields[] = {
+	{ RFD_VXLAN_DP0, 16, 0, 4789 },
+	{ RFD_VXLAN_DP1, 16, 16, 4789 },
+};
+
+static nthw_fpga_register_init_s rfd_registers[] = {
+	{ RFD_CTRL, 0, 3, NTHW_FPGA_REG_TYPE_WO, 7, 3, rfd_ctrl_fields },
+	{ RFD_MAX_FRAME_SIZE, 1, 14, NTHW_FPGA_REG_TYPE_WO, 9018, 1, rfd_max_frame_size_fields },
+	{ RFD_TNL_VLAN, 3, 32, NTHW_FPGA_REG_TYPE_WO, 2164293888, 2, rfd_tnl_vlan_fields },
+	{ RFD_VLAN, 2, 32, NTHW_FPGA_REG_TYPE_WO, 2164293888, 2, rfd_vlan_fields },
+	{ RFD_VXLAN, 4, 32, NTHW_FPGA_REG_TYPE_WO, 313856693, 2, rfd_vxlan_fields },
+};
+
+static nthw_fpga_field_init_s rpf_control_fields[] = {
+	{ RPF_CONTROL_KEEP_ALIVE_EN, 1, 7, 0 },
+	{ RPF_CONTROL_PEN, 2, 0, 0 },
+	{ RPF_CONTROL_RPP_EN, 4, 2, 0 },
+	{ RPF_CONTROL_ST_TGL_EN, 1, 6, 0 },
+};
+
+static nthw_fpga_field_init_s rpf_ts_sort_prg_fields[] = {
+	{ RPF_TS_SORT_PRG_MATURING_DELAY, 19, 0, 524163 },
+	{ RPF_TS_SORT_PRG_TS_AT_EOF, 1, 19, 1 },
+};
+
+static nthw_fpga_register_init_s rpf_registers[] = {
+	{ RPF_CONTROL, 0, 8, NTHW_FPGA_REG_TYPE_RW, 0, 4, rpf_control_fields },
+	{ RPF_TS_SORT_PRG, 1, 20, NTHW_FPGA_REG_TYPE_RW, 1048451, 2, rpf_ts_sort_prg_fields },
+};
+
+static nthw_fpga_field_init_s rpl_ext_ctrl_fields[] = {
+	{ RPL_EXT_CTRL_ADR, 10, 0, 0x0000 },
+	{ RPL_EXT_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpl_ext_data_fields[] = {
+	{ RPL_EXT_DATA_RPL_PTR, 12, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpl_rcp_ctrl_fields[] = {
+	{ RPL_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ RPL_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpl_rcp_data_fields[] = {
+	{ RPL_RCP_DATA_DYN, 5, 0, 0x0000 }, { RPL_RCP_DATA_ETH_TYPE_WR, 1, 36, 0x0000 },
+	{ RPL_RCP_DATA_EXT_PRIO, 1, 35, 0x0000 }, { RPL_RCP_DATA_LEN, 8, 15, 0x0000 },
+	{ RPL_RCP_DATA_OFS, 10, 5, 0x0000 }, { RPL_RCP_DATA_RPL_PTR, 12, 23, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpl_rpl_ctrl_fields[] = {
+	{ RPL_RPL_CTRL_ADR, 12, 0, 0x0000 },
+	{ RPL_RPL_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpl_rpl_data_fields[] = {
+	{ RPL_RPL_DATA_VALUE, 128, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s rpl_registers[] = {
+	{ RPL_EXT_CTRL, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, rpl_ext_ctrl_fields },
+	{ RPL_EXT_DATA, 3, 12, NTHW_FPGA_REG_TYPE_WO, 0, 1, rpl_ext_data_fields },
+	{ RPL_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, rpl_rcp_ctrl_fields },
+	{ RPL_RCP_DATA, 1, 37, NTHW_FPGA_REG_TYPE_WO, 0, 6, rpl_rcp_data_fields },
+	{ RPL_RPL_CTRL, 4, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, rpl_rpl_ctrl_fields },
+	{ RPL_RPL_DATA, 5, 128, NTHW_FPGA_REG_TYPE_WO, 0, 1, rpl_rpl_data_fields },
+};
+
+static nthw_fpga_field_init_s rpp_lr_ifr_rcp_ctrl_fields[] = {
+	{ RPP_LR_IFR_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ RPP_LR_IFR_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpp_lr_ifr_rcp_data_fields[] = {
+	{ RPP_LR_IFR_RCP_DATA_IPV4_DF_DROP, 1, 17, 0x0000 },
+	{ RPP_LR_IFR_RCP_DATA_IPV4_EN, 1, 0, 0x0000 },
+	{ RPP_LR_IFR_RCP_DATA_IPV6_DROP, 1, 16, 0x0000 },
+	{ RPP_LR_IFR_RCP_DATA_IPV6_EN, 1, 1, 0x0000 },
+	{ RPP_LR_IFR_RCP_DATA_MTU, 14, 2, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpp_lr_rcp_ctrl_fields[] = {
+	{ RPP_LR_RCP_CTRL_ADR, 4, 0, 0x0000 },
+	{ RPP_LR_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rpp_lr_rcp_data_fields[] = {
+	{ RPP_LR_RCP_DATA_EXP, 14, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s rpp_lr_registers[] = {
+	{ RPP_LR_IFR_RCP_CTRL, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, rpp_lr_ifr_rcp_ctrl_fields },
+	{ RPP_LR_IFR_RCP_DATA, 3, 18, NTHW_FPGA_REG_TYPE_WO, 0, 5, rpp_lr_ifr_rcp_data_fields },
+	{ RPP_LR_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, rpp_lr_rcp_ctrl_fields },
+	{ RPP_LR_RCP_DATA, 1, 14, NTHW_FPGA_REG_TYPE_WO, 0, 1, rpp_lr_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s rst9574_latch_fields[] = {
+	{ RST9574_LATCH_DDR4_CALIB_COMPLETE, 1, 0, 0x0000 },
+	{ RST9574_LATCH_PHY_FTILE_RDY, 1, 2, 0x0000 },
+	{ RST9574_LATCH_PHY_FTILE_RST_DONE, 1, 1, 0x0000 },
+};
+
+static nthw_fpga_field_init_s rst9574_rst_fields[] = {
+	{ RST9574_RST_DDR4, 1, 1, 1 },
+	{ RST9574_RST_PHY_FTILE, 1, 2, 1 },
+	{ RST9574_RST_SYS, 1, 0, 1 },
+};
+
+static nthw_fpga_field_init_s rst9574_stat_fields[] = {
+	{ RST9574_STAT_DDR4_CALIB_COMPLETE, 1, 0, 0x0000 },
+	{ RST9574_STAT_PHY_FTILE_RDY, 1, 2, 0x0000 },
+	{ RST9574_STAT_PHY_FTILE_RST_DONE, 1, 1, 0x0000 },
+};
+
+static nthw_fpga_register_init_s rst9574_registers[] = {
+	{ RST9574_LATCH, 2, 3, NTHW_FPGA_REG_TYPE_RW, 0, 3, rst9574_latch_fields },
+	{ RST9574_RST, 0, 3, NTHW_FPGA_REG_TYPE_RW, 7, 3, rst9574_rst_fields },
+	{ RST9574_STAT, 1, 3, NTHW_FPGA_REG_TYPE_RO, 0, 3, rst9574_stat_fields },
+};
+
+static nthw_fpga_field_init_s slc_rcp_ctrl_fields[] = {
+	{ SLC_RCP_CTRL_ADR, 6, 0, 0x0000 },
+	{ SLC_RCP_CTRL_CNT, 16, 16, 0x0000 },
+};
+
+static nthw_fpga_field_init_s slc_rcp_data_fields[] = {
+	{ SLC_RCP_DATA_HEAD_DYN, 5, 1, 0x0000 }, { SLC_RCP_DATA_HEAD_OFS, 8, 6, 0x0000 },
+	{ SLC_RCP_DATA_HEAD_SLC_EN, 1, 0, 0x0000 }, { SLC_RCP_DATA_PCAP, 1, 35, 0x0000 },
+	{ SLC_RCP_DATA_TAIL_DYN, 5, 15, 0x0000 }, { SLC_RCP_DATA_TAIL_OFS, 15, 20, 0x0000 },
+	{ SLC_RCP_DATA_TAIL_SLC_EN, 1, 14, 0x0000 },
+};
+
+static nthw_fpga_register_init_s slc_registers[] = {
+	{ SLC_RCP_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, slc_rcp_ctrl_fields },
+	{ SLC_RCP_DATA, 1, 36, NTHW_FPGA_REG_TYPE_WO, 0, 7, slc_rcp_data_fields },
+};
+
+static nthw_fpga_field_init_s spim_cfg_fields[] = {
+	{ SPIM_CFG_PRE, 3, 0, 5 },
+};
+
+static nthw_fpga_field_init_s spim_cfg_clk_fields[] = {
+	{ SPIM_CFG_CLK_MODE, 2, 0, 0 },
+};
+
+static nthw_fpga_field_init_s spim_cr_fields[] = {
+	{ SPIM_CR_EN, 1, 1, 0 },
+	{ SPIM_CR_LOOP, 1, 0, 0 },
+	{ SPIM_CR_RXRST, 1, 3, 0 },
+	{ SPIM_CR_TXRST, 1, 2, 0 },
+};
+
+static nthw_fpga_field_init_s spim_drr_fields[] = {
+	{ SPIM_DRR_DRR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s spim_dtr_fields[] = {
+	{ SPIM_DTR_DTR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s spim_sr_fields[] = {
+	{ SPIM_SR_DONE, 1, 0, 0 }, { SPIM_SR_RXEMPTY, 1, 2, 1 }, { SPIM_SR_RXFULL, 1, 4, 0 },
+	{ SPIM_SR_RXLVL, 8, 16, 0 }, { SPIM_SR_TXEMPTY, 1, 1, 1 }, { SPIM_SR_TXFULL, 1, 3, 0 },
+	{ SPIM_SR_TXLVL, 8, 8, 0 },
+};
+
+static nthw_fpga_field_init_s spim_srr_fields[] = {
+	{ SPIM_SRR_RST, 4, 0, 0 },
+};
+
+static nthw_fpga_register_init_s spim_registers[] = {
+	{ SPIM_CFG, 5, 3, NTHW_FPGA_REG_TYPE_WO, 5, 1, spim_cfg_fields },
+	{ SPIM_CFG_CLK, 6, 2, NTHW_FPGA_REG_TYPE_WO, 0, 1, spim_cfg_clk_fields },
+	{ SPIM_CR, 1, 4, NTHW_FPGA_REG_TYPE_WO, 0, 4, spim_cr_fields },
+	{ SPIM_DRR, 4, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, spim_drr_fields },
+	{ SPIM_DTR, 3, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, spim_dtr_fields },
+	{ SPIM_SR, 2, 24, NTHW_FPGA_REG_TYPE_MIXED, 6, 7, spim_sr_fields },
+	{ SPIM_SRR, 0, 4, NTHW_FPGA_REG_TYPE_WO, 0, 1, spim_srr_fields },
+};
+
+static nthw_fpga_field_init_s spis_cr_fields[] = {
+	{ SPIS_CR_DEBUG, 1, 4, 0 }, { SPIS_CR_EN, 1, 1, 0 }, { SPIS_CR_LOOP, 1, 0, 0 },
+	{ SPIS_CR_RXRST, 1, 3, 0 }, { SPIS_CR_TXRST, 1, 2, 0 },
+};
+
+static nthw_fpga_field_init_s spis_drr_fields[] = {
+	{ SPIS_DRR_DRR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s spis_dtr_fields[] = {
+	{ SPIS_DTR_DTR, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s spis_ram_ctrl_fields[] = {
+	{ SPIS_RAM_CTRL_ADR, 6, 0, 0 },
+	{ SPIS_RAM_CTRL_CNT, 6, 6, 0 },
+};
+
+static nthw_fpga_field_init_s spis_ram_data_fields[] = {
+	{ SPIS_RAM_DATA_DATA, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s spis_sr_fields[] = {
+	{ SPIS_SR_DONE, 1, 0, 0 }, { SPIS_SR_FRAME_ERR, 1, 24, 0 },
+	{ SPIS_SR_READ_ERR, 1, 25, 0 }, { SPIS_SR_RXEMPTY, 1, 2, 1 },
+	{ SPIS_SR_RXFULL, 1, 4, 0 }, { SPIS_SR_RXLVL, 8, 16, 0 },
+	{ SPIS_SR_TXEMPTY, 1, 1, 1 }, { SPIS_SR_TXFULL, 1, 3, 0 },
+	{ SPIS_SR_TXLVL, 8, 8, 0 }, { SPIS_SR_WRITE_ERR, 1, 26, 0 },
+};
+
+static nthw_fpga_field_init_s spis_srr_fields[] = {
+	{ SPIS_SRR_RST, 4, 0, 0 },
+};
+
+static nthw_fpga_register_init_s spis_registers[] = {
+	{ SPIS_CR, 1, 5, NTHW_FPGA_REG_TYPE_WO, 0, 5, spis_cr_fields },
+	{ SPIS_DRR, 4, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, spis_drr_fields },
+	{ SPIS_DTR, 3, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, spis_dtr_fields },
+	{ SPIS_RAM_CTRL, 5, 12, NTHW_FPGA_REG_TYPE_RW, 0, 2, spis_ram_ctrl_fields },
+	{ SPIS_RAM_DATA, 6, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1, spis_ram_data_fields },
+	{ SPIS_SR, 2, 27, NTHW_FPGA_REG_TYPE_RO, 6, 10, spis_sr_fields },
+	{ SPIS_SRR, 0, 4, NTHW_FPGA_REG_TYPE_WO, 0, 1, spis_srr_fields },
+};
+
+static nthw_fpga_field_init_s sta_byte_fields[] = {
+	{ STA_BYTE_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_cfg_fields[] = {
+	{ STA_CFG_CNT_CLEAR, 1, 1, 0 },
+	{ STA_CFG_DMA_ENA, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s sta_cv_err_fields[] = {
+	{ STA_CV_ERR_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_fcs_err_fields[] = {
+	{ STA_FCS_ERR_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_host_adr_lsb_fields[] = {
+	{ STA_HOST_ADR_LSB_LSB, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s sta_host_adr_msb_fields[] = {
+	{ STA_HOST_ADR_MSB_MSB, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s sta_load_bin_fields[] = {
+	{ STA_LOAD_BIN_BIN, 32, 0, 8388607 },
+};
+
+static nthw_fpga_field_init_s sta_load_bps_rx_0_fields[] = {
+	{ STA_LOAD_BPS_RX_0_BPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_bps_rx_1_fields[] = {
+	{ STA_LOAD_BPS_RX_1_BPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_bps_tx_0_fields[] = {
+	{ STA_LOAD_BPS_TX_0_BPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_bps_tx_1_fields[] = {
+	{ STA_LOAD_BPS_TX_1_BPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_pps_rx_0_fields[] = {
+	{ STA_LOAD_PPS_RX_0_PPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_pps_rx_1_fields[] = {
+	{ STA_LOAD_PPS_RX_1_PPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_pps_tx_0_fields[] = {
+	{ STA_LOAD_PPS_TX_0_PPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_load_pps_tx_1_fields[] = {
+	{ STA_LOAD_PPS_TX_1_PPS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_pckt_fields[] = {
+	{ STA_PCKT_CNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s sta_status_fields[] = {
+	{ STA_STATUS_STAT_TOGGLE_MISSED, 1, 0, 0x0000 },
+};
+
+static nthw_fpga_register_init_s sta_registers[] = {
+	{ STA_BYTE, 4, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_byte_fields },
+	{ STA_CFG, 0, 2, NTHW_FPGA_REG_TYPE_RW, 0, 2, sta_cfg_fields },
+	{ STA_CV_ERR, 5, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_cv_err_fields },
+	{ STA_FCS_ERR, 6, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_fcs_err_fields },
+	{ STA_HOST_ADR_LSB, 1, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, sta_host_adr_lsb_fields },
+	{ STA_HOST_ADR_MSB, 2, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, sta_host_adr_msb_fields },
+	{ STA_LOAD_BIN, 8, 32, NTHW_FPGA_REG_TYPE_WO, 8388607, 1, sta_load_bin_fields },
+	{ STA_LOAD_BPS_RX_0, 11, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_bps_rx_0_fields },
+	{ STA_LOAD_BPS_RX_1, 13, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_bps_rx_1_fields },
+	{ STA_LOAD_BPS_TX_0, 15, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_bps_tx_0_fields },
+	{ STA_LOAD_BPS_TX_1, 17, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_bps_tx_1_fields },
+	{ STA_LOAD_PPS_RX_0, 10, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_pps_rx_0_fields },
+	{ STA_LOAD_PPS_RX_1, 12, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_pps_rx_1_fields },
+	{ STA_LOAD_PPS_TX_0, 14, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_pps_tx_0_fields },
+	{ STA_LOAD_PPS_TX_1, 16, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_load_pps_tx_1_fields },
+	{ STA_PCKT, 3, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, sta_pckt_fields },
+	{ STA_STATUS, 7, 1, NTHW_FPGA_REG_TYPE_RC1, 0, 1, sta_status_fields },
+};
+
+static nthw_fpga_field_init_s tint_ctrl_fields[] = {
+	{ TINT_CTRL_INTERVAL, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tint_status_fields[] = {
+	{ TINT_STATUS_DELAYED, 8, 8, 0 },
+	{ TINT_STATUS_SKIPPED, 8, 0, 0 },
+};
+
+static nthw_fpga_register_init_s tint_registers[] = {
+	{ TINT_CTRL, 0, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, tint_ctrl_fields },
+	{ TINT_STATUS, 1, 16, NTHW_FPGA_REG_TYPE_RC1, 0, 2, tint_status_fields },
+};
+
+static nthw_fpga_field_init_s tsm_con0_config_fields[] = {
+	{ TSM_CON0_CONFIG_BLIND, 5, 8, 9 }, { TSM_CON0_CONFIG_DC_SRC, 3, 5, 0 },
+	{ TSM_CON0_CONFIG_PORT, 3, 0, 0 }, { TSM_CON0_CONFIG_PPSIN_2_5V, 1, 13, 0 },
+	{ TSM_CON0_CONFIG_SAMPLE_EDGE, 2, 3, 2 },
+};
+
+static nthw_fpga_field_init_s tsm_con0_interface_fields[] = {
+	{ TSM_CON0_INTERFACE_EX_TERM, 2, 0, 3 }, { TSM_CON0_INTERFACE_IN_REF_PWM, 8, 12, 128 },
+	{ TSM_CON0_INTERFACE_PWM_ENA, 1, 2, 0 }, { TSM_CON0_INTERFACE_RESERVED, 1, 3, 0 },
+	{ TSM_CON0_INTERFACE_VTERM_PWM, 8, 4, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_con0_sample_hi_fields[] = {
+	{ TSM_CON0_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con0_sample_lo_fields[] = {
+	{ TSM_CON0_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con1_config_fields[] = {
+	{ TSM_CON1_CONFIG_BLIND, 5, 8, 9 }, { TSM_CON1_CONFIG_DC_SRC, 3, 5, 0 },
+	{ TSM_CON1_CONFIG_PORT, 3, 0, 0 }, { TSM_CON1_CONFIG_PPSIN_2_5V, 1, 13, 0 },
+	{ TSM_CON1_CONFIG_SAMPLE_EDGE, 2, 3, 2 },
+};
+
+static nthw_fpga_field_init_s tsm_con1_sample_hi_fields[] = {
+	{ TSM_CON1_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con1_sample_lo_fields[] = {
+	{ TSM_CON1_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con2_config_fields[] = {
+	{ TSM_CON2_CONFIG_BLIND, 5, 8, 9 }, { TSM_CON2_CONFIG_DC_SRC, 3, 5, 0 },
+	{ TSM_CON2_CONFIG_PORT, 3, 0, 0 }, { TSM_CON2_CONFIG_PPSIN_2_5V, 1, 13, 0 },
+	{ TSM_CON2_CONFIG_SAMPLE_EDGE, 2, 3, 2 },
+};
+
+static nthw_fpga_field_init_s tsm_con2_sample_hi_fields[] = {
+	{ TSM_CON2_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con2_sample_lo_fields[] = {
+	{ TSM_CON2_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con3_config_fields[] = {
+	{ TSM_CON3_CONFIG_BLIND, 5, 5, 26 },
+	{ TSM_CON3_CONFIG_PORT, 3, 0, 1 },
+	{ TSM_CON3_CONFIG_SAMPLE_EDGE, 2, 3, 1 },
+};
+
+static nthw_fpga_field_init_s tsm_con3_sample_hi_fields[] = {
+	{ TSM_CON3_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con3_sample_lo_fields[] = {
+	{ TSM_CON3_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con4_config_fields[] = {
+	{ TSM_CON4_CONFIG_BLIND, 5, 5, 26 },
+	{ TSM_CON4_CONFIG_PORT, 3, 0, 1 },
+	{ TSM_CON4_CONFIG_SAMPLE_EDGE, 2, 3, 1 },
+};
+
+static nthw_fpga_field_init_s tsm_con4_sample_hi_fields[] = {
+	{ TSM_CON4_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con4_sample_lo_fields[] = {
+	{ TSM_CON4_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con5_config_fields[] = {
+	{ TSM_CON5_CONFIG_BLIND, 5, 5, 26 },
+	{ TSM_CON5_CONFIG_PORT, 3, 0, 1 },
+	{ TSM_CON5_CONFIG_SAMPLE_EDGE, 2, 3, 1 },
+};
+
+static nthw_fpga_field_init_s tsm_con5_sample_hi_fields[] = {
+	{ TSM_CON5_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con5_sample_lo_fields[] = {
+	{ TSM_CON5_SAMPLE_LO_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con6_config_fields[] = {
+	{ TSM_CON6_CONFIG_BLIND, 5, 5, 26 },
+	{ TSM_CON6_CONFIG_PORT, 3, 0, 1 },
+	{ TSM_CON6_CONFIG_SAMPLE_EDGE, 2, 3, 1 },
+};
+
+static nthw_fpga_field_init_s tsm_con6_sample_hi_fields[] = {
+	{ TSM_CON6_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con6_sample_lo_fields[] = {
+	{ TSM_CON6_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con7_host_sample_hi_fields[] = {
+	{ TSM_CON7_HOST_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_con7_host_sample_lo_fields[] = {
+	{ TSM_CON7_HOST_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_config_fields[] = {
+	{ TSM_CONFIG_NTTS_SRC, 2, 5, 0 }, { TSM_CONFIG_NTTS_SYNC, 1, 4, 0 },
+	{ TSM_CONFIG_TIMESET_EDGE, 2, 8, 1 }, { TSM_CONFIG_TIMESET_SRC, 3, 10, 0 },
+	{ TSM_CONFIG_TIMESET_UP, 1, 7, 0 }, { TSM_CONFIG_TS_FORMAT, 4, 0, 1 },
+};
+
+static nthw_fpga_field_init_s tsm_int_config_fields[] = {
+	{ TSM_INT_CONFIG_AUTO_DISABLE, 1, 0, 0 },
+	{ TSM_INT_CONFIG_MASK, 19, 1, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_int_stat_fields[] = {
+	{ TSM_INT_STAT_CAUSE, 19, 1, 0 },
+	{ TSM_INT_STAT_ENABLE, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_led_fields[] = {
+	{ TSM_LED_LED0_BG_COLOR, 2, 3, 0 }, { TSM_LED_LED0_COLOR, 2, 1, 0 },
+	{ TSM_LED_LED0_MODE, 1, 0, 0 }, { TSM_LED_LED0_SRC, 4, 5, 0 },
+	{ TSM_LED_LED1_BG_COLOR, 2, 12, 0 }, { TSM_LED_LED1_COLOR, 2, 10, 0 },
+	{ TSM_LED_LED1_MODE, 1, 9, 0 }, { TSM_LED_LED1_SRC, 4, 14, 1 },
+	{ TSM_LED_LED2_BG_COLOR, 2, 21, 0 }, { TSM_LED_LED2_COLOR, 2, 19, 0 },
+	{ TSM_LED_LED2_MODE, 1, 18, 0 }, { TSM_LED_LED2_SRC, 4, 23, 2 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_config_fields[] = {
+	{ TSM_NTTS_CONFIG_AUTO_HARDSET, 1, 5, 1 },
+	{ TSM_NTTS_CONFIG_EXT_CLK_ADJ, 1, 6, 0 },
+	{ TSM_NTTS_CONFIG_HIGH_SAMPLE, 1, 4, 0 },
+	{ TSM_NTTS_CONFIG_TS_SRC_FORMAT, 4, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_ext_stat_fields[] = {
+	{ TSM_NTTS_EXT_STAT_MASTER_ID, 8, 16, 0x0000 },
+	{ TSM_NTTS_EXT_STAT_MASTER_REV, 8, 24, 0x0000 },
+	{ TSM_NTTS_EXT_STAT_MASTER_STAT, 16, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_limit_hi_fields[] = {
+	{ TSM_NTTS_LIMIT_HI_SEC, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_limit_lo_fields[] = {
+	{ TSM_NTTS_LIMIT_LO_NS, 32, 0, 100000 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_offset_fields[] = {
+	{ TSM_NTTS_OFFSET_NS, 30, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_sample_hi_fields[] = {
+	{ TSM_NTTS_SAMPLE_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_sample_lo_fields[] = {
+	{ TSM_NTTS_SAMPLE_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_stat_fields[] = {
+	{ TSM_NTTS_STAT_NTTS_VALID, 1, 0, 0 },
+	{ TSM_NTTS_STAT_SIGNAL_LOST, 8, 1, 0 },
+	{ TSM_NTTS_STAT_SYNC_LOST, 8, 9, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_ts_t0_hi_fields[] = {
+	{ TSM_NTTS_TS_T0_HI_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_ts_t0_lo_fields[] = {
+	{ TSM_NTTS_TS_T0_LO_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ntts_ts_t0_offset_fields[] = {
+	{ TSM_NTTS_TS_T0_OFFSET_COUNT, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_pb_ctrl_fields[] = {
+	{ TSM_PB_CTRL_INSTMEM_WR, 1, 1, 0 },
+	{ TSM_PB_CTRL_RST, 1, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_pb_instmem_fields[] = {
+	{ TSM_PB_INSTMEM_MEM_ADDR, 14, 0, 0 },
+	{ TSM_PB_INSTMEM_MEM_DATA, 18, 14, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_pi_ctrl_i_fields[] = {
+	{ TSM_PI_CTRL_I_VAL, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_pi_ctrl_ki_fields[] = {
+	{ TSM_PI_CTRL_KI_GAIN, 24, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_pi_ctrl_kp_fields[] = {
+	{ TSM_PI_CTRL_KP_GAIN, 24, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_pi_ctrl_shl_fields[] = {
+	{ TSM_PI_CTRL_SHL_VAL, 4, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_stat_fields[] = {
+	{ TSM_STAT_HARD_SYNC, 8, 8, 0 }, { TSM_STAT_LINK_CON0, 1, 0, 0 },
+	{ TSM_STAT_LINK_CON1, 1, 1, 0 }, { TSM_STAT_LINK_CON2, 1, 2, 0 },
+	{ TSM_STAT_LINK_CON3, 1, 3, 0 }, { TSM_STAT_LINK_CON4, 1, 4, 0 },
+	{ TSM_STAT_LINK_CON5, 1, 5, 0 }, { TSM_STAT_NTTS_INSYNC, 1, 6, 0 },
+	{ TSM_STAT_PTP_MI_PRESENT, 1, 7, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_timer_ctrl_fields[] = {
+	{ TSM_TIMER_CTRL_TIMER_EN_T0, 1, 0, 0 },
+	{ TSM_TIMER_CTRL_TIMER_EN_T1, 1, 1, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_timer_t0_fields[] = {
+	{ TSM_TIMER_T0_MAX_COUNT, 30, 0, 50000 },
+};
+
+static nthw_fpga_field_init_s tsm_timer_t1_fields[] = {
+	{ TSM_TIMER_T1_MAX_COUNT, 30, 0, 50000 },
+};
+
+static nthw_fpga_field_init_s tsm_time_hardset_hi_fields[] = {
+	{ TSM_TIME_HARDSET_HI_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_time_hardset_lo_fields[] = {
+	{ TSM_TIME_HARDSET_LO_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_time_hi_fields[] = {
+	{ TSM_TIME_HI_SEC, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_time_lo_fields[] = {
+	{ TSM_TIME_LO_NS, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_time_rate_adj_fields[] = {
+	{ TSM_TIME_RATE_ADJ_FRACTION, 29, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_hi_fields[] = {
+	{ TSM_TS_HI_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_lo_fields[] = {
+	{ TSM_TS_LO_TIME, 32, 0, 0x0000 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_offset_fields[] = {
+	{ TSM_TS_OFFSET_NS, 30, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_fields[] = {
+	{ TSM_TS_STAT_OVERRUN, 1, 16, 0 },
+	{ TSM_TS_STAT_SAMPLES, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_hi_offset_fields[] = {
+	{ TSM_TS_STAT_HI_OFFSET_NS, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_lo_offset_fields[] = {
+	{ TSM_TS_STAT_LO_OFFSET_NS, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_tar_hi_fields[] = {
+	{ TSM_TS_STAT_TAR_HI_SEC, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_tar_lo_fields[] = {
+	{ TSM_TS_STAT_TAR_LO_NS, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_x_fields[] = {
+	{ TSM_TS_STAT_X_NS, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_x2_hi_fields[] = {
+	{ TSM_TS_STAT_X2_HI_NS, 16, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_ts_stat_x2_lo_fields[] = {
+	{ TSM_TS_STAT_X2_LO_NS, 32, 0, 0 },
+};
+
+static nthw_fpga_field_init_s tsm_utc_offset_fields[] = {
+	{ TSM_UTC_OFFSET_SEC, 8, 0, 0 },
+};
+
+static nthw_fpga_register_init_s tsm_registers[] = {
+	{ TSM_CON0_CONFIG, 24, 14, NTHW_FPGA_REG_TYPE_RW, 2320, 5, tsm_con0_config_fields },
+	{
+		TSM_CON0_INTERFACE, 25, 20, NTHW_FPGA_REG_TYPE_RW, 524291, 5,
+		tsm_con0_interface_fields
+	},
+	{ TSM_CON0_SAMPLE_HI, 27, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con0_sample_hi_fields },
+	{ TSM_CON0_SAMPLE_LO, 26, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con0_sample_lo_fields },
+	{ TSM_CON1_CONFIG, 28, 14, NTHW_FPGA_REG_TYPE_RW, 2320, 5, tsm_con1_config_fields },
+	{ TSM_CON1_SAMPLE_HI, 30, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con1_sample_hi_fields },
+	{ TSM_CON1_SAMPLE_LO, 29, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con1_sample_lo_fields },
+	{ TSM_CON2_CONFIG, 31, 14, NTHW_FPGA_REG_TYPE_RW, 2320, 5, tsm_con2_config_fields },
+	{ TSM_CON2_SAMPLE_HI, 33, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con2_sample_hi_fields },
+	{ TSM_CON2_SAMPLE_LO, 32, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con2_sample_lo_fields },
+	{ TSM_CON3_CONFIG, 34, 10, NTHW_FPGA_REG_TYPE_RW, 841, 3, tsm_con3_config_fields },
+	{ TSM_CON3_SAMPLE_HI, 36, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con3_sample_hi_fields },
+	{ TSM_CON3_SAMPLE_LO, 35, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con3_sample_lo_fields },
+	{ TSM_CON4_CONFIG, 37, 10, NTHW_FPGA_REG_TYPE_RW, 841, 3, tsm_con4_config_fields },
+	{ TSM_CON4_SAMPLE_HI, 39, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con4_sample_hi_fields },
+	{ TSM_CON4_SAMPLE_LO, 38, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con4_sample_lo_fields },
+	{ TSM_CON5_CONFIG, 40, 10, NTHW_FPGA_REG_TYPE_RW, 841, 3, tsm_con5_config_fields },
+	{ TSM_CON5_SAMPLE_HI, 42, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con5_sample_hi_fields },
+	{ TSM_CON5_SAMPLE_LO, 41, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con5_sample_lo_fields },
+	{ TSM_CON6_CONFIG, 43, 10, NTHW_FPGA_REG_TYPE_RW, 841, 3, tsm_con6_config_fields },
+	{ TSM_CON6_SAMPLE_HI, 45, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con6_sample_hi_fields },
+	{ TSM_CON6_SAMPLE_LO, 44, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_con6_sample_lo_fields },
+	{
+		TSM_CON7_HOST_SAMPLE_HI, 47, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1,
+		tsm_con7_host_sample_hi_fields
+	},
+	{
+		TSM_CON7_HOST_SAMPLE_LO, 46, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1,
+		tsm_con7_host_sample_lo_fields
+	},
+	{ TSM_CONFIG, 0, 13, NTHW_FPGA_REG_TYPE_RW, 257, 6, tsm_config_fields },
+	{ TSM_INT_CONFIG, 2, 20, NTHW_FPGA_REG_TYPE_RW, 0, 2, tsm_int_config_fields },
+	{ TSM_INT_STAT, 3, 20, NTHW_FPGA_REG_TYPE_MIXED, 0, 2, tsm_int_stat_fields },
+	{ TSM_LED, 4, 27, NTHW_FPGA_REG_TYPE_RW, 16793600, 12, tsm_led_fields },
+	{ TSM_NTTS_CONFIG, 13, 7, NTHW_FPGA_REG_TYPE_RW, 32, 4, tsm_ntts_config_fields },
+	{ TSM_NTTS_EXT_STAT, 15, 32, NTHW_FPGA_REG_TYPE_MIXED, 0, 3, tsm_ntts_ext_stat_fields },
+	{ TSM_NTTS_LIMIT_HI, 23, 16, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_ntts_limit_hi_fields },
+	{ TSM_NTTS_LIMIT_LO, 22, 32, NTHW_FPGA_REG_TYPE_RW, 100000, 1, tsm_ntts_limit_lo_fields },
+	{ TSM_NTTS_OFFSET, 21, 30, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_ntts_offset_fields },
+	{ TSM_NTTS_SAMPLE_HI, 19, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ntts_sample_hi_fields },
+	{ TSM_NTTS_SAMPLE_LO, 18, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ntts_sample_lo_fields },
+	{ TSM_NTTS_STAT, 14, 17, NTHW_FPGA_REG_TYPE_RO, 0, 3, tsm_ntts_stat_fields },
+	{ TSM_NTTS_TS_T0_HI, 17, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ntts_ts_t0_hi_fields },
+	{ TSM_NTTS_TS_T0_LO, 16, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ntts_ts_t0_lo_fields },
+	{
+		TSM_NTTS_TS_T0_OFFSET, 20, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1,
+		tsm_ntts_ts_t0_offset_fields
+	},
+	{ TSM_PB_CTRL, 63, 2, NTHW_FPGA_REG_TYPE_WO, 0, 2, tsm_pb_ctrl_fields },
+	{ TSM_PB_INSTMEM, 64, 32, NTHW_FPGA_REG_TYPE_WO, 0, 2, tsm_pb_instmem_fields },
+	{ TSM_PI_CTRL_I, 54, 32, NTHW_FPGA_REG_TYPE_WO, 0, 1, tsm_pi_ctrl_i_fields },
+	{ TSM_PI_CTRL_KI, 52, 24, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_pi_ctrl_ki_fields },
+	{ TSM_PI_CTRL_KP, 51, 24, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_pi_ctrl_kp_fields },
+	{ TSM_PI_CTRL_SHL, 53, 4, NTHW_FPGA_REG_TYPE_WO, 0, 1, tsm_pi_ctrl_shl_fields },
+	{ TSM_STAT, 1, 16, NTHW_FPGA_REG_TYPE_RO, 0, 9, tsm_stat_fields },
+	{ TSM_TIMER_CTRL, 48, 2, NTHW_FPGA_REG_TYPE_RW, 0, 2, tsm_timer_ctrl_fields },
+	{ TSM_TIMER_T0, 49, 30, NTHW_FPGA_REG_TYPE_RW, 50000, 1, tsm_timer_t0_fields },
+	{ TSM_TIMER_T1, 50, 30, NTHW_FPGA_REG_TYPE_RW, 50000, 1, tsm_timer_t1_fields },
+	{ TSM_TIME_HARDSET_HI, 12, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_time_hardset_hi_fields },
+	{ TSM_TIME_HARDSET_LO, 11, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_time_hardset_lo_fields },
+	{ TSM_TIME_HI, 9, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_time_hi_fields },
+	{ TSM_TIME_LO, 8, 32, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_time_lo_fields },
+	{ TSM_TIME_RATE_ADJ, 10, 29, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_time_rate_adj_fields },
+	{ TSM_TS_HI, 6, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_hi_fields },
+	{ TSM_TS_LO, 5, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_lo_fields },
+	{ TSM_TS_OFFSET, 7, 30, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_ts_offset_fields },
+	{ TSM_TS_STAT, 55, 17, NTHW_FPGA_REG_TYPE_RO, 0, 2, tsm_ts_stat_fields },
+	{
+		TSM_TS_STAT_HI_OFFSET, 62, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1,
+		tsm_ts_stat_hi_offset_fields
+	},
+	{
+		TSM_TS_STAT_LO_OFFSET, 61, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1,
+		tsm_ts_stat_lo_offset_fields
+	},
+	{ TSM_TS_STAT_TAR_HI, 57, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_stat_tar_hi_fields },
+	{ TSM_TS_STAT_TAR_LO, 56, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_stat_tar_lo_fields },
+	{ TSM_TS_STAT_X, 58, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_stat_x_fields },
+	{ TSM_TS_STAT_X2_HI, 60, 16, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_stat_x2_hi_fields },
+	{ TSM_TS_STAT_X2_LO, 59, 32, NTHW_FPGA_REG_TYPE_RO, 0, 1, tsm_ts_stat_x2_lo_fields },
+	{ TSM_UTC_OFFSET, 65, 8, NTHW_FPGA_REG_TYPE_RW, 0, 1, tsm_utc_offset_fields },
+};
+
+static nthw_fpga_module_init_s fpga_modules[] = {
+	{ MOD_CAT, 0, MOD_CAT, 0, 21, NTHW_FPGA_BUS_TYPE_RAB1, 768, 34, cat_registers },
+	{ MOD_CSU, 0, MOD_CSU, 0, 0, NTHW_FPGA_BUS_TYPE_RAB1, 9728, 2, csu_registers },
+	{ MOD_DBS, 0, MOD_DBS, 0, 11, NTHW_FPGA_BUS_TYPE_RAB2, 1568, 27, dbs_registers },
+	{ MOD_FLM, 0, MOD_FLM, 0, 25, NTHW_FPGA_BUS_TYPE_RAB1, 1280, 43, flm_registers },
+	{ MOD_GFG, 0, MOD_GFG, 1, 1, NTHW_FPGA_BUS_TYPE_RAB2, 5120, 10, gfg_registers },
+	{ MOD_GMF, 0, MOD_GMF, 2, 5, NTHW_FPGA_BUS_TYPE_RAB2, 5632, 12, gmf_registers },
+	{ MOD_GMF, 1, MOD_GMF, 2, 5, NTHW_FPGA_BUS_TYPE_RAB2, 6144, 12, gmf_registers },
+	{ MOD_HFU, 0, MOD_HFU, 0, 2, NTHW_FPGA_BUS_TYPE_RAB1, 9472, 2, hfu_registers },
+	{ MOD_HIF, 0, MOD_HIF, 0, 0, NTHW_FPGA_BUS_TYPE_PCI, 0, 18, hif_registers },
+	{ MOD_HSH, 0, MOD_HSH, 0, 5, NTHW_FPGA_BUS_TYPE_RAB1, 1536, 2, hsh_registers },
+	{ MOD_I2CM, 0, MOD_I2CM, 0, 1, NTHW_FPGA_BUS_TYPE_RAB0, 640, 7, i2cm_registers },
+	{ MOD_IFR, 0, MOD_IFR, 0, 7, NTHW_FPGA_BUS_TYPE_RAB1, 9984, 6, ifr_registers },
+	{ MOD_IGAM, 0, MOD_IGAM, 0, 1, NTHW_FPGA_BUS_TYPE_RAB0, 1040, 3, igam_registers },
+	{ MOD_KM, 0, MOD_KM, 0, 7, NTHW_FPGA_BUS_TYPE_RAB1, 1024, 11, km_registers },
+	{
+		MOD_PCI_RD_TG, 0, MOD_PCI_RD_TG, 0, 1, NTHW_FPGA_BUS_TYPE_RAB0, 1312, 6,
+		pci_rd_tg_registers
+	},
+	{ MOD_PCI_TA, 0, MOD_PCI_TA, 0, 0, NTHW_FPGA_BUS_TYPE_RAB0, 1328, 5, pci_ta_registers },
+	{
+		MOD_PCI_WR_TG, 0, MOD_PCI_WR_TG, 0, 1, NTHW_FPGA_BUS_TYPE_RAB0, 1296, 7,
+		pci_wr_tg_registers
+	},
+	{
+		MOD_PCM_NT400DXX, 0, MOD_PCM_NT400DXX, 0, 3, NTHW_FPGA_BUS_TYPE_RAB0, 1024, 3,
+		pcm_nt400dxx_registers
+	},
+	{ MOD_PDB, 0, MOD_PDB, 0, 9, NTHW_FPGA_BUS_TYPE_RAB1, 2560, 3, pdb_registers },
+	{ MOD_PDI, 0, MOD_PDI, 1, 1, NTHW_FPGA_BUS_TYPE_RAB0, 64, 6, pdi_registers },
+	{
+		MOD_PHY_TILE, 0, MOD_PHY_TILE, 0, 10, NTHW_FPGA_BUS_TYPE_RAB2, 7168, 33,
+		phy_tile_registers
+	},
+	{
+		MOD_PRM_NT400DXX, 0, MOD_PRM_NT400DXX, 0, 0, NTHW_FPGA_BUS_TYPE_RAB0, 1032, 1,
+		prm_nt400dxx_registers
+	},
+	{ MOD_QSL, 0, MOD_QSL, 0, 7, NTHW_FPGA_BUS_TYPE_RAB1, 1792, 8, qsl_registers },
+	{ MOD_RAC, 0, MOD_RAC, 3, 0, NTHW_FPGA_BUS_TYPE_PCI, 8192, 14, rac_registers },
+	{ MOD_RFD, 0, MOD_RFD, 0, 4, NTHW_FPGA_BUS_TYPE_RAB1, 256, 5, rfd_registers },
+	{ MOD_RPF, 0, MOD_RPF, 0, 2, NTHW_FPGA_BUS_TYPE_RAB2, 4096, 2, rpf_registers },
+	{ MOD_RPP_LR, 0, MOD_RPP_LR, 0, 2, NTHW_FPGA_BUS_TYPE_RAB1, 2304, 4, rpp_lr_registers },
+	{ MOD_RST9574, 0, MOD_RST9574, 0, 2, NTHW_FPGA_BUS_TYPE_RAB2, 0, 3, rst9574_registers },
+	{ MOD_SLC_LR, 0, MOD_SLC, 0, 2, NTHW_FPGA_BUS_TYPE_RAB1, 2048, 2, slc_registers },
+	{ MOD_SPIM, 0, MOD_SPIM, 1, 1, NTHW_FPGA_BUS_TYPE_RAB0, 80, 7, spim_registers },
+	{ MOD_SPIS, 0, MOD_SPIS, 1, 0, NTHW_FPGA_BUS_TYPE_RAB0, 256, 7, spis_registers },
+	{ MOD_STA, 0, MOD_STA, 0, 9, NTHW_FPGA_BUS_TYPE_RAB2, 1536, 17, sta_registers },
+	{ MOD_TINT, 0, MOD_TINT, 0, 0, NTHW_FPGA_BUS_TYPE_RAB2, 1024, 2, tint_registers },
+	{ MOD_TSM, 0, MOD_TSM, 0, 8, NTHW_FPGA_BUS_TYPE_RAB2, 512, 66, tsm_registers },
+	{ MOD_TX_CPY, 0, MOD_CPY, 0, 4, NTHW_FPGA_BUS_TYPE_RAB1, 9216, 26, cpy_registers },
+	{ MOD_TX_INS, 0, MOD_INS, 0, 2, NTHW_FPGA_BUS_TYPE_RAB1, 8704, 2, ins_registers },
+	{ MOD_TX_RPL, 0, MOD_RPL, 0, 4, NTHW_FPGA_BUS_TYPE_RAB1, 8960, 6, rpl_registers },
+};
+
+static nthw_fpga_prod_param_s product_parameters[] = {
+	{ NT_BUILD_NUMBER, 0 },
+	{ NT_BUILD_TIME, 1726786851 },
+	{ NT_CATEGORIES, 64 },
+	{ NT_CAT_DCT_PRESENT, 0 },
+	{ NT_CAT_END_OFS_SUPPORT, 0 },
+	{ NT_CAT_FUNCS, 64 },
+	{ NT_CAT_KCC_BANKS, 3 },
+	{ NT_CAT_KCC_PRESENT, 0 },
+	{ NT_CAT_KCC_SIZE, 1536 },
+	{ NT_CAT_KM_IF_CNT, 2 },
+	{ NT_CAT_KM_IF_M0, 0 },
+	{ NT_CAT_KM_IF_M1, 1 },
+	{ NT_CAT_N_CMP, 8 },
+	{ NT_CAT_N_EXT, 4 },
+	{ NT_CAT_N_LEN, 8 },
+	{ NT_CB_DEBUG, 0 },
+	{ NT_COR_CATEGORIES, 16 },
+	{ NT_COR_PRESENT, 0 },
+	{ NT_CSU_PRESENT, 1 },
+	{ NT_DBS_PRESENT, 1 },
+	{ NT_DBS_RX_QUEUES, 128 },
+	{ NT_DBS_TX_PORTS, 2 },
+	{ NT_DBS_TX_QUEUES, 128 },
+	{ NT_DDP_PRESENT, 0 },
+	{ NT_DDP_TBL_DEPTH, 1024 },
+	{ NT_EMI_SPLIT_STEPS, 16 },
+	{ NT_EOF_TIMESTAMP_ONLY, 1 },
+	{ NT_EPP_CATEGORIES, 32 },
+	{ NT_FLM_CACHE, 1 },
+	{ NT_FLM_CATEGORIES, 32 },
+	{ NT_FLM_ENTRY_SIZE, 64 },
+	{ NT_FLM_LOAD_APS_MAX, 360000000 },
+	{ NT_FLM_LOAD_LPS_MAX, 600000000 },
+	{ NT_FLM_PRESENT, 1 },
+	{ NT_FLM_PRIOS, 4 },
+	{ NT_FLM_PST_PROFILES, 16 },
+	{ NT_FLM_SCRUB_PROFILES, 16 },
+	{ NT_FLM_SIZE_MB, 16384 },
+	{ NT_FLM_STATEFUL, 1 },
+	{ NT_FLM_VARIANT, 2 },
+	{ NT_GFG_PRESENT, 1 },
+	{ NT_GFG_TX_LIVE_RECONFIG_SUPPORT, 1 },
+	{ NT_GMF_FCS_PRESENT, 0 },
+	{ NT_GMF_IFG_SPEED_DIV, 34 },
+	{ NT_GMF_IFG_SPEED_DIV100G, 34 },
+	{ NT_GMF_IFG_SPEED_MUL, 16 },
+	{ NT_GMF_IFG_SPEED_MUL100G, 16 },
+	{ NT_GROUP_ID, 9574 },
+	{ NT_HFU_PRESENT, 1 },
+	{ NT_HIF_MSIX_BAR, 1 },
+	{ NT_HIF_MSIX_PBA_OFS, 8192 },
+	{ NT_HIF_MSIX_PRESENT, 1 },
+	{ NT_HIF_MSIX_TBL_OFS, 0 },
+	{ NT_HIF_MSIX_TBL_SIZE, 8 },
+	{ NT_HIF_PER_PS, 2222 },
+	{ NT_HIF_SRIOV_PRESENT, 1 },
+	{ NT_HIF_VF_OFFSET, 1 },
+	{ NT_HSH_CATEGORIES, 16 },
+	{ NT_HSH_TOEPLITZ, 1 },
+	{ NT_HST_CATEGORIES, 32 },
+	{ NT_HST_PRESENT, 0 },
+	{ NT_IOA_CATEGORIES, 1024 },
+	{ NT_IOA_PRESENT, 0 },
+	{ NT_IPF_PRESENT, 0 },
+	{ NT_KM_CAM_BANKS, 3 },
+	{ NT_KM_CAM_RECORDS, 2048 },
+	{ NT_KM_CAM_REC_WORDS, 6 },
+	{ NT_KM_CATEGORIES, 32 },
+	{ NT_KM_END_OFS_SUPPORT, 0 },
+	{ NT_KM_EXT_EXTRACTORS, 1 },
+	{ NT_KM_FLOW_TYPES, 16 },
+	{ NT_KM_PRESENT, 1 },
+	{ NT_KM_SWX_PRESENT, 0 },
+	{ NT_KM_SYNERGY_MATCH, 0 },
+	{ NT_KM_TCAM_BANKS, 12 },
+	{ NT_KM_TCAM_BANK_WIDTH, 72 },
+	{ NT_KM_TCAM_HIT_QUAL, 0 },
+	{ NT_KM_TCAM_KEYWAY, 1 },
+	{ NT_KM_WIDE, 0 },
+	{ NT_LR_PRESENT, 1 },
+	{ NT_MCU_PRESENT, 0 },
+	{ NT_MDG_DEBUG_FLOW_CONTROL, 0 },
+	{ NT_MDG_DEBUG_REG_READ_BACK, 0 },
+	{ NT_MSK_CATEGORIES, 32 },
+	{ NT_MSK_PRESENT, 0 },
+	{ NT_NFV_OVS_PRODUCT, 0 },
+	{ NT_NIMS, 2 },
+	{ NT_PCI_DEVICE_ID, 661 },
+	{ NT_PCI_TA_TG_PRESENT, 1 },
+	{ NT_PCI_VENDOR_ID, 6388 },
+	{ NT_PDB_CATEGORIES, 16 },
+	{ NT_PHY_ANEG_PRESENT, 0 },
+	{ NT_PHY_KRFEC_PRESENT, 0 },
+	{ NT_PHY_PORTS, 2 },
+	{ NT_PHY_PORTS_PER_QUAD, 1 },
+	{ NT_PHY_QUADS, 2 },
+	{ NT_PHY_RSFEC_PRESENT, 0 },
+	{ NT_QM_CELLS, 4194304 },
+	{ NT_QM_CELL_SIZE, 4096 },
+	{ NT_QM_PRESENT, 0 },
+	{ NT_QSL_CATEGORIES, 32 },
+	{ NT_QSL_COLOR_SEL_BW, 7 },
+	{ NT_QSL_QST_SIZE, 4096 },
+	{ NT_QUEUES, 128 },
+	{ NT_RAC_RAB_INTERFACES, 3 },
+	{ NT_RAC_RAB_OB_UPDATE, 0 },
+	{ NT_REVISION_ID, 49 },
+	{ NT_RMC_LAG_GROUPS, 1 },
+	{ NT_RMC_PRESENT, 0 },
+	{ NT_ROA_CATEGORIES, 1024 },
+	{ NT_ROA_PRESENT, 0 },
+	{ NT_RPF_MATURING_DEL_DEFAULT, -125 },
+	{ NT_RPF_PRESENT, 1 },
+	{ NT_RPP_PER_PS, 1666 },
+	{ NT_RTX_PRESENT, 0 },
+	{ NT_RX_HOST_BUFFERS, 128 },
+	{ NT_RX_PORTS, 2 },
+	{ NT_RX_PORT_REPLICATE, 0 },
+	{ NT_SLB_PRESENT, 0 },
+	{ NT_SLC_LR_PRESENT, 1 },
+	{ NT_SLC_PRESENT, 0 },
+	{ NT_STA_COLORS, 64 },
+	{ NT_STA_LOAD_AVG_RX, 1 },
+	{ NT_STA_LOAD_AVG_TX, 1 },
+	{ NT_STA_RX_PORTS, 2 },
+	{ NT_TBH_DEBUG_DLN, 1 },
+	{ NT_TBH_PRESENT, 0 },
+	{ NT_TFD_PRESENT, 1 },
+	{ NT_TPE_CATEGORIES, 16 },
+	{ NT_TSM_OST_ONLY, 1 },
+	{ NT_TS_APPEND, 0 },
+	{ NT_TS_INJECT_PRESENT, 0 },
+	{ NT_TX_CPY_PACKET_READERS, 0 },
+	{ NT_TX_CPY_PRESENT, 1 },
+	{ NT_TX_CPY_SIDEBAND_READERS, 7 },
+	{ NT_TX_CPY_VARIANT, 0 },
+	{ NT_TX_CPY_WRITERS, 6 },
+	{ NT_TX_HOST_BUFFERS, 128 },
+	{ NT_TX_INS_OFS_ZERO, 1 },
+	{ NT_TX_INS_PRESENT, 1 },
+	{ NT_TX_MTU_PROFILE_IFR, 16 },
+	{ NT_TX_ON_TIMESTAMP, 1 },
+	{ NT_TX_PORTS, 2 },
+	{ NT_TX_PORT_REPLICATE, 1 },
+	{ NT_TX_RPL_DEPTH, 4096 },
+	{ NT_TX_RPL_EXT_CATEGORIES, 1024 },
+	{ NT_TX_RPL_OFS_ZERO, 1 },
+	{ NT_TX_RPL_PRESENT, 1 },
+	{ NT_TYPE_ID, 200 },
+	{ NT_USE_TRIPLE_SPEED, 0 },
+	{ NT_VERSION_ID, 55 },
+	{ NT_VLI_PRESENT, 0 },
+	{ 0, -1 },	/* END */
+};
+
+nthw_fpga_prod_init_s nthw_fpga_9574_055_049_0000 = {
+	200, 9574, 55, 49, 0, 0, 1726786851, 152, product_parameters, 37, fpga_modules,
+};
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.c b/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.c
index c8a310c415..634095646c 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.c
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.c
@@ -5,4 +5,7 @@
 
 
 #include "nthw_fpga_instances.h"
-nthw_fpga_prod_init_s *nthw_fpga_instances[] = { &nthw_fpga_9563_055_049_0000, NULL };
+nthw_fpga_prod_init_s *nthw_fpga_instances[] = {
+	 &nthw_fpga_9563_055_049_0000,
+	&nthw_fpga_9574_055_049_0000,
+	NULL  };
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.h
index 3e5983f763..ad0e700bfd 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.h
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_instances.h
@@ -7,3 +7,4 @@
 #include "fpga_model.h"
 extern nthw_fpga_prod_init_s *nthw_fpga_instances[];
 extern nthw_fpga_prod_init_s nthw_fpga_9563_055_049_0000;
+extern nthw_fpga_prod_init_s nthw_fpga_9574_055_049_0000;
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_defs.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_defs.h
index e6ed9e714b..e2a98a737a 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_defs.h
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_defs.h
@@ -27,6 +27,7 @@
 #define MOD_HSH (0x501484bfUL)
 #define MOD_I2CM (0x93bc7780UL)
 #define MOD_IFR (0x9b01f1e6UL)
+#define MOD_IGAM (0xf3b0bfb9UL)
 #define MOD_IIC (0x7629cddbUL)
 #define MOD_INS (0x24df4b78UL)
 #define MOD_KM (0xcfbd9dbeUL)
@@ -35,19 +36,29 @@
 #define MOD_MAC_TX (0x351d1316UL)
 #define MOD_PCIE3 (0xfbc48c18UL)
 #define MOD_PCI_RD_TG (0x9ad9eed2UL)
+#define MOD_PCI_TA (0xfb431997UL)
 #define MOD_PCI_WR_TG (0x274b69e1UL)
+#define MOD_PCM_NT400DXX (0x93b709a3UL)
 #define MOD_PDB (0xa7771bffUL)
+#define MOD_PDI (0x30a5c277UL)
+#define MOD_PHY_TILE (0x4e0aef6eUL)
+#define MOD_PRM_NT400DXX (0xfccf12a8UL)
 #define MOD_QSL (0x448ed859UL)
 #define MOD_RAC (0xae830b42UL)
+#define MOD_RFD (0x7fa60826UL)
 #define MOD_RMC (0x236444eUL)
 #define MOD_RPL (0x6de535c3UL)
 #define MOD_RPF (0x8d30dcddUL)
 #define MOD_RPP_LR (0xba7f945cUL)
 #define MOD_RST9563 (0x385d6d1dUL)
+#define MOD_RST9574 (0xbf22c9ffUL)
 #define MOD_SDC (0xd2369530UL)
 #define MOD_SLC (0x1aef1f38UL)
 #define MOD_SLC_LR (0x969fc50bUL)
+#define MOD_SPIM (0x1da437bfUL)
+#define MOD_SPIS (0xe7ab0adcUL)
 #define MOD_STA (0x76fae64dUL)
+#define MOD_TINT (0xb8aea9feUL)
 #define MOD_TSM (0x35422a24UL)
 #define MOD_TX_CPY (0x60acf217UL)
 #define MOD_TX_INS (0x59afa100UL)
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
index 459cc724c2..a0afa22579 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
@@ -19,6 +19,7 @@ const struct nthw_fpga_mod_str_s sa_nthw_fpga_mod_str_map[] = {
 	{ MOD_HSH, "HSH" },
 	{ MOD_I2CM, "I2CM" },
 	{ MOD_IFR, "IFR" },
+	{ MOD_IGAM, "IGAM" },
 	{ MOD_IIC, "IIC" },
 	{ MOD_INS, "INS" },
 	{ MOD_KM, "KM" },
@@ -27,20 +28,30 @@ const struct nthw_fpga_mod_str_s sa_nthw_fpga_mod_str_map[] = {
 	{ MOD_MAC_RX, "MAC_RX" },
 	{ MOD_MAC_TX, "MAC_TX" },
 	{ MOD_PCI_RD_TG, "PCI_RD_TG" },
+	{ MOD_PCI_TA, "PCI_TA" },
 	{ MOD_PCI_WR_TG, "PCI_WR_TG" },
 	{ MOD_PCIE3, "PCIE3" },
+	{ MOD_PCM_NT400DXX, "PCM_NT400DXX" },
 	{ MOD_PDB, "PDB" },
+	{ MOD_PDI, "PDI" },
+	{ MOD_PHY_TILE, "PHY_TILE" },
+	{ MOD_PRM_NT400DXX, "PRM_NT400DXX" },
 	{ MOD_QSL, "QSL" },
 	{ MOD_RAC, "RAC" },
+	{ MOD_RFD, "RFD" },
 	{ MOD_RMC, "RMC" },
 	{ MOD_RPF, "RPF" },
 	{ MOD_RPL, "RPL" },
 	{ MOD_RPP_LR, "RPP_LR" },
 	{ MOD_RST9563, "RST9563" },
+	{ MOD_RST9574, "RST9574" },
 	{ MOD_SDC, "SDC" },
 	{ MOD_SLC_LR, "SLC_LR" },
 	{ MOD_SLC, "SLC" },
+	{ MOD_SPIM, "SPIM" },
+	{ MOD_SPIS, "SPIS" },
 	{ MOD_STA, "STA" },
+	{ MOD_TINT, "TINT" },
 	{ MOD_TSM, "TSM" },
 	{ MOD_TX_CPY, "TX_CPY" },
 	{ MOD_TX_INS, "TX_INS" },
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs.h
index 4d299c6aa8..5b824ef3e5 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs.h
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs.h
@@ -26,6 +26,7 @@
 #include "nthw_fpga_reg_defs_hsh.h"
 #include "nthw_fpga_reg_defs_i2cm.h"
 #include "nthw_fpga_reg_defs_ifr.h"
+#include "nthw_fpga_reg_defs_igam.h"
 #include "nthw_fpga_reg_defs_iic.h"
 #include "nthw_fpga_reg_defs_ins.h"
 #include "nthw_fpga_reg_defs_km.h"
@@ -34,20 +35,30 @@
 #include "nthw_fpga_reg_defs_mac_tx.h"
 #include "nthw_fpga_reg_defs_pcie3.h"
 #include "nthw_fpga_reg_defs_pci_rd_tg.h"
+#include "nthw_fpga_reg_defs_pci_ta.h"
 #include "nthw_fpga_reg_defs_pci_wr_tg.h"
+#include "nthw_fpga_reg_defs_pcm_nt400dxx.h"
 #include "nthw_fpga_reg_defs_pdb.h"
+#include "nthw_fpga_reg_defs_pdi.h"
+#include "nthw_fpga_reg_defs_phy_tile.h"
+#include "nthw_fpga_reg_defs_prm_nt400dxx.h"
 #include "nthw_fpga_reg_defs_qsl.h"
 #include "nthw_fpga_reg_defs_rac.h"
+#include "nthw_fpga_reg_defs_rfd.h"
 #include "nthw_fpga_reg_defs_rmc.h"
 #include "nthw_fpga_reg_defs_rpf.h"
 #include "nthw_fpga_reg_defs_rpl.h"
 #include "nthw_fpga_reg_defs_rpp_lr.h"
 #include "nthw_fpga_reg_defs_rst9563.h"
+#include "nthw_fpga_reg_defs_rst9574.h"
 #include "nthw_fpga_reg_defs_sdc.h"
 #include "nthw_fpga_reg_defs_tsm.h"
 #include "nthw_fpga_reg_defs_slc.h"
 #include "nthw_fpga_reg_defs_slc_lr.h"
+#include "nthw_fpga_reg_defs_spim.h"
+#include "nthw_fpga_reg_defs_spis.h"
 #include "nthw_fpga_reg_defs_sta.h"
+#include "nthw_fpga_reg_defs_tint.h"
 #include "nthw_fpga_reg_defs_tx_cpy.h"
 #include "nthw_fpga_reg_defs_tx_ins.h"
 #include "nthw_fpga_reg_defs_tx_rpl.h"
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h
new file mode 100644
index 0000000000..dd247ef0dd
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_igam.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_IGAM_
+#define _NTHW_FPGA_REG_DEFS_IGAM_
+
+/* IGAM */
+#define NTHW_MOD_IGAM (0xf3b0bfb9UL)
+#define IGAM_BASE (0xcdbfd276UL)
+#define IGAM_BASE_BUSY (0x2a018901UL)
+#define IGAM_BASE_CMD (0x61c2922dUL)
+#define IGAM_BASE_PTR (0x1076934dUL)
+#define IGAM_CTRL (0xf295d6dUL)
+#define IGAM_CTRL_FORCE_RST (0xf40df899UL)
+#define IGAM_CTRL_FORWARD_RST (0xbe779fc1UL)
+#define IGAM_DATA (0xa0f8df74UL)
+#define IGAM_DATA_DATA (0x6544d6f2UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_IGAM_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h
new file mode 100644
index 0000000000..d9a0b4f381
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_pci_ta.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_PCI_TA_
+#define _NTHW_FPGA_REG_DEFS_PCI_TA_
+
+/* PCI_TA */
+#define NTHW_MOD_PCI_TA (0xfb431997UL)
+#define PCI_TA_CONTROL (0xa707df59UL)
+#define PCI_TA_CONTROL_ENABLE (0x87cdcc9aUL)
+#define PCI_TA_LENGTH_ERROR (0x8648b862UL)
+#define PCI_TA_LENGTH_ERROR_AMOUNT (0x8774bd63UL)
+#define PCI_TA_PACKET_BAD (0xaaa256d4UL)
+#define PCI_TA_PACKET_BAD_AMOUNT (0x601f72f3UL)
+#define PCI_TA_PACKET_GOOD (0xfc13da6cUL)
+#define PCI_TA_PACKET_GOOD_AMOUNT (0xd936d64dUL)
+#define PCI_TA_PAYLOAD_ERROR (0x69d7a09bUL)
+#define PCI_TA_PAYLOAD_ERROR_AMOUNT (0x445da330UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_PCI_TA_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h
new file mode 100644
index 0000000000..fadb8c17e8
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h
@@ -0,0 +1,29 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_pcm_nt400dxx.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_PCM_NT400DXX_
+#define _NTHW_FPGA_REG_DEFS_PCM_NT400DXX_
+
+/* PCM_NT400DXX */
+#define NTHW_MOD_PCM_NT400DXX (0x93b709a3UL)
+#define PCM_NT400DXX_CTRL (0x7dd2be2aUL)
+#define PCM_NT400DXX_CTRL_TS_PLL_RECAL (0xe876b916UL)
+#define PCM_NT400DXX_LATCH (0x17416d46UL)
+#define PCM_NT400DXX_LATCH_TS_PLL_LOCKED (0xe38e12c5UL)
+#define PCM_NT400DXX_STAT (0x5f483071UL)
+#define PCM_NT400DXX_STAT_TS_PLL_LOCKED (0x92116985UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_PCM_NT400DXX_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h
new file mode 100644
index 0000000000..67177ca288
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_pdi.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_PDI_
+#define _NTHW_FPGA_REG_DEFS_PDI_
+
+/* PDI */
+#define NTHW_MOD_PDI (0x30a5c277UL)
+#define PDI_CR (0x9d6d02a8UL)
+#define PDI_CR_EN (0x7a6160dUL)
+#define PDI_CR_PARITY (0xaed85250UL)
+#define PDI_CR_RST (0x26b77922UL)
+#define PDI_CR_RXRST (0xe1aedb39UL)
+#define PDI_CR_STOP (0x78eaf29eUL)
+#define PDI_CR_TXRST (0x6eee2e99UL)
+#define PDI_DRR (0x8ab88f08UL)
+#define PDI_DRR_DRR (0x157e17dfUL)
+#define PDI_DTR (0xdce2288eUL)
+#define PDI_DTR_DTR (0x957d5344UL)
+#define PDI_PRE (0x12440163UL)
+#define PDI_PRE_PRE (0xccd36afbUL)
+#define PDI_SR (0xd7af10f9UL)
+#define PDI_SR_DISABLE_BUSY (0xd8936666UL)
+#define PDI_SR_DONE (0xb64f984dUL)
+#define PDI_SR_ENABLE_BUSY (0xee39b4e3UL)
+#define PDI_SR_FRAME_ERR (0x7c7b177dUL)
+#define PDI_SR_OVERRUN_ERR (0x4093d29dUL)
+#define PDI_SR_PARITY_ERR (0xa12e1293UL)
+#define PDI_SR_RXLVL (0xe5b6087bUL)
+#define PDI_SR_RX_BUSY (0xeb248de4UL)
+#define PDI_SR_TXLVL (0x6af6fddbUL)
+#define PDI_SR_TX_BUSY (0x88f4b8deUL)
+#define PDI_SRR (0x93d13afdUL)
+#define PDI_SRR_RST (0x5fd4fe29UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_PDI_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h
new file mode 100644
index 0000000000..99ef0e21fc
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h
@@ -0,0 +1,213 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_phy_tile.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_PHY_TILE_
+#define _NTHW_FPGA_REG_DEFS_PHY_TILE_
+
+/* PHY_TILE */
+#define NTHW_MOD_PHY_TILE (0x4e0aef6eUL)
+#define PHY_TILE_DR_CFG (0x763df0f3UL)
+#define PHY_TILE_DR_CFG_DYN_RST (0x2ff2174cUL)
+#define PHY_TILE_DR_CFG_FEATURES (0xf43413f2UL)
+#define PHY_TILE_DR_CFG_SCRATCH (0x605efc72UL)
+#define PHY_TILE_DR_CFG_TX_FLUSH_LEVEL (0x528b497bUL)
+#define PHY_TILE_DR_CFG_STATUS (0x252aff33UL)
+#define PHY_TILE_DR_CFG_STATUS_CURR_PROFILE_ID (0x98db7e13UL)
+#define PHY_TILE_DR_CFG_STATUS_ERROR (0x594c35e7UL)
+#define PHY_TILE_DR_CFG_STATUS_IN_PROGRESS (0x62cdc29fUL)
+#define PHY_TILE_DYN_RECONFIG_BASE (0xda7abd93UL)
+#define PHY_TILE_DYN_RECONFIG_BASE_BUSY (0x3b97f6c6UL)
+#define PHY_TILE_DYN_RECONFIG_BASE_CMD (0xf6b609f6UL)
+#define PHY_TILE_DYN_RECONFIG_BASE_PTR (0x87020896UL)
+#define PHY_TILE_DYN_RECONFIG_DATA (0xb73db091UL)
+#define PHY_TILE_DYN_RECONFIG_DATA_DATA (0x74d2a935UL)
+#define PHY_TILE_LINK_SUMMARY_0 (0x2e6c2bb2UL)
+#define PHY_TILE_LINK_SUMMARY_0_LH_RECEIVED_LOCAL_FAULT (0x658fa4f2UL)
+#define PHY_TILE_LINK_SUMMARY_0_LH_REMOTE_FAULT (0x12c794faUL)
+#define PHY_TILE_LINK_SUMMARY_0_LH_RX_HIGH_BIT_ERROR_RATE (0x99e0ad8bUL)
+#define PHY_TILE_LINK_SUMMARY_0_LINK_DOWN_CNT (0x7c6a63a9UL)
+#define PHY_TILE_LINK_SUMMARY_0_LL_PHY_LINK_STATE (0x694563dcUL)
+#define PHY_TILE_LINK_SUMMARY_0_LL_RX_AM_LOCK (0xc958731bUL)
+#define PHY_TILE_LINK_SUMMARY_0_LL_RX_BLOCK_LOCK (0x1ae5c634UL)
+#define PHY_TILE_LINK_SUMMARY_0_NT_PHY_LINK_STATE (0x284d52caUL)
+#define PHY_TILE_LINK_SUMMARY_1 (0x596b1b24UL)
+#define PHY_TILE_LINK_SUMMARY_1_LH_RECEIVED_LOCAL_FAULT (0xc00434fcUL)
+#define PHY_TILE_LINK_SUMMARY_1_LH_REMOTE_FAULT (0x95615fb9UL)
+#define PHY_TILE_LINK_SUMMARY_1_LH_RX_HIGH_BIT_ERROR_RATE (0xf76cb6caUL)
+#define PHY_TILE_LINK_SUMMARY_1_LINK_DOWN_CNT (0xc591b841UL)
+#define PHY_TILE_LINK_SUMMARY_1_LL_PHY_LINK_STATE (0xbea7e384UL)
+#define PHY_TILE_LINK_SUMMARY_1_LL_RX_AM_LOCK (0x70a3a8f3UL)
+#define PHY_TILE_LINK_SUMMARY_1_LL_RX_BLOCK_LOCK (0xf5b770d5UL)
+#define PHY_TILE_LINK_SUMMARY_1_NT_PHY_LINK_STATE (0xffafd292UL)
+#define PHY_TILE_PORT_0_ETH_0_BASE (0x337c4712UL)
+#define PHY_TILE_PORT_0_ETH_0_BASE_BUSY (0xd5fbad30UL)
+#define PHY_TILE_PORT_0_ETH_0_BASE_CMD (0x948cd3f4UL)
+#define PHY_TILE_PORT_0_ETH_0_BASE_PTR (0xe538d294UL)
+#define PHY_TILE_PORT_0_ETH_0_DATA (0x5e3b4a10UL)
+#define PHY_TILE_PORT_0_ETH_0_DATA_DATA (0x9abef2c3UL)
+#define PHY_TILE_PORT_0_XCVR_0_BASE (0x758a7765UL)
+#define PHY_TILE_PORT_0_XCVR_0_BASE_BUSY (0x79488eafUL)
+#define PHY_TILE_PORT_0_XCVR_0_BASE_CMD (0x9b560cdfUL)
+#define PHY_TILE_PORT_0_XCVR_0_BASE_PTR (0xeae20dbfUL)
+#define PHY_TILE_PORT_0_XCVR_0_DATA (0x18cd7a67UL)
+#define PHY_TILE_PORT_0_XCVR_0_DATA_DATA (0x360dd15cUL)
+#define PHY_TILE_PORT_0_XCVR_1_BASE (0xbed6a4c0UL)
+#define PHY_TILE_PORT_0_XCVR_1_BASE_BUSY (0xb8c6516fUL)
+#define PHY_TILE_PORT_0_XCVR_1_BASE_CMD (0x749467e1UL)
+#define PHY_TILE_PORT_0_XCVR_1_BASE_PTR (0x5206681UL)
+#define PHY_TILE_PORT_0_XCVR_1_DATA (0xd391a9c2UL)
+#define PHY_TILE_PORT_0_XCVR_1_DATA_DATA (0xf7830e9cUL)
+#define PHY_TILE_PORT_0_XCVR_2_BASE (0x3842d66eUL)
+#define PHY_TILE_PORT_0_XCVR_2_BASE_BUSY (0x2124376eUL)
+#define PHY_TILE_PORT_0_XCVR_2_BASE_CMD (0x9fa3dce2UL)
+#define PHY_TILE_PORT_0_XCVR_2_BASE_PTR (0xee17dd82UL)
+#define PHY_TILE_PORT_0_XCVR_2_DATA (0x5505db6cUL)
+#define PHY_TILE_PORT_0_XCVR_2_DATA_DATA (0x6e61689dUL)
+#define PHY_TILE_PORT_0_XCVR_3_BASE (0xf31e05cbUL)
+#define PHY_TILE_PORT_0_XCVR_3_BASE_BUSY (0xe0aae8aeUL)
+#define PHY_TILE_PORT_0_XCVR_3_BASE_CMD (0x7061b7dcUL)
+#define PHY_TILE_PORT_0_XCVR_3_BASE_PTR (0x1d5b6bcUL)
+#define PHY_TILE_PORT_0_XCVR_3_DATA (0x9e5908c9UL)
+#define PHY_TILE_PORT_0_XCVR_3_DATA_DATA (0xafefb75dUL)
+#define PHY_TILE_PORT_1_ETH_0_BASE (0xa8d90b7dUL)
+#define PHY_TILE_PORT_1_ETH_0_BASE_BUSY (0x525d6673UL)
+#define PHY_TILE_PORT_1_ETH_0_BASE_CMD (0x3ae44265UL)
+#define PHY_TILE_PORT_1_ETH_0_BASE_PTR (0x4b504305UL)
+#define PHY_TILE_PORT_1_ETH_0_DATA (0xc59e067fUL)
+#define PHY_TILE_PORT_1_ETH_0_DATA_DATA (0x1d183980UL)
+#define PHY_TILE_PORT_1_XCVR_0_BASE (0xa81caee0UL)
+#define PHY_TILE_PORT_1_XCVR_0_BASE_BUSY (0x961a384eUL)
+#define PHY_TILE_PORT_1_XCVR_0_BASE_CMD (0x1cf0c79cUL)
+#define PHY_TILE_PORT_1_XCVR_0_BASE_PTR (0x6d44c6fcUL)
+#define PHY_TILE_PORT_1_XCVR_0_DATA (0xc55ba3e2UL)
+#define PHY_TILE_PORT_1_XCVR_0_DATA_DATA (0xd95f67bdUL)
+#define PHY_TILE_PORT_1_XCVR_1_BASE (0x63407d45UL)
+#define PHY_TILE_PORT_1_XCVR_1_BASE_BUSY (0x5794e78eUL)
+#define PHY_TILE_PORT_1_XCVR_1_BASE_CMD (0xf332aca2UL)
+#define PHY_TILE_PORT_1_XCVR_1_BASE_PTR (0x8286adc2UL)
+#define PHY_TILE_PORT_1_XCVR_1_DATA (0xe077047UL)
+#define PHY_TILE_PORT_1_XCVR_1_DATA_DATA (0x18d1b87dUL)
+#define PHY_TILE_PORT_1_XCVR_2_BASE (0xe5d40febUL)
+#define PHY_TILE_PORT_1_XCVR_2_BASE_BUSY (0xce76818fUL)
+#define PHY_TILE_PORT_1_XCVR_2_BASE_CMD (0x180517a1UL)
+#define PHY_TILE_PORT_1_XCVR_2_BASE_PTR (0x69b116c1UL)
+#define PHY_TILE_PORT_1_XCVR_2_DATA (0x889302e9UL)
+#define PHY_TILE_PORT_1_XCVR_2_DATA_DATA (0x8133de7cUL)
+#define PHY_TILE_PORT_1_XCVR_3_BASE (0x2e88dc4eUL)
+#define PHY_TILE_PORT_1_XCVR_3_BASE_BUSY (0xff85e4fUL)
+#define PHY_TILE_PORT_1_XCVR_3_BASE_CMD (0xf7c77c9fUL)
+#define PHY_TILE_PORT_1_XCVR_3_BASE_PTR (0x86737dffUL)
+#define PHY_TILE_PORT_1_XCVR_3_DATA (0x43cfd14cUL)
+#define PHY_TILE_PORT_1_XCVR_3_DATA_DATA (0x40bd01bcUL)
+#define PHY_TILE_PORT_COMP_0 (0xfc048a04UL)
+#define PHY_TILE_PORT_COMP_0_RX_COMPENSATION (0xffba9733UL)
+#define PHY_TILE_PORT_COMP_0_TX_COMPENSATION (0xdd4043c1UL)
+#define PHY_TILE_PORT_COMP_1 (0x8b03ba92UL)
+#define PHY_TILE_PORT_COMP_1_RX_COMPENSATION (0x781c5c70UL)
+#define PHY_TILE_PORT_COMP_1_TX_COMPENSATION (0x5ae68882UL)
+#define PHY_TILE_PORT_CONFIG (0x24e3ab60UL)
+#define PHY_TILE_PORT_CONFIG_DYN_RESET (0x72b5f859UL)
+#define PHY_TILE_PORT_CONFIG_NT_FORCE_LINK_DOWN_0 (0x7e66781UL)
+#define PHY_TILE_PORT_CONFIG_NT_FORCE_LINK_DOWN_1 (0x70e15717UL)
+#define PHY_TILE_PORT_CONFIG_NT_LINKUP_LATENCY_0 (0x33fd94c2UL)
+#define PHY_TILE_PORT_CONFIG_NT_LINKUP_LATENCY_1 (0x44faa454UL)
+#define PHY_TILE_PORT_CONFIG_RESET_0 (0xf0e1e1c4UL)
+#define PHY_TILE_PORT_CONFIG_RESET_1 (0x87e6d152UL)
+#define PHY_TILE_PORT_CONFIG_RX_RESET_0 (0x70027edeUL)
+#define PHY_TILE_PORT_CONFIG_RX_RESET_1 (0x7054e48UL)
+#define PHY_TILE_PORT_CONFIG_TX_RESET_0 (0x7d1c0e99UL)
+#define PHY_TILE_PORT_CONFIG_TX_RESET_1 (0xa1b3e0fUL)
+#define PHY_TILE_PORT_CONFIG_0 (0x7eda56ecUL)
+#define PHY_TILE_PORT_CONFIG_0_NT_AUTO_FORCE_LINK_DOWN (0x1e02d057UL)
+#define PHY_TILE_PORT_CONFIG_0_NT_FORCE_LINK_DOWN (0xf21d946dUL)
+#define PHY_TILE_PORT_CONFIG_0_NT_LINKUP_LATENCY (0x833ea2b3UL)
+#define PHY_TILE_PORT_CONFIG_0_RST (0xcbf3bb99UL)
+#define PHY_TILE_PORT_CONFIG_0_RX_RST (0x1c7f59c7UL)
+#define PHY_TILE_PORT_CONFIG_0_TX_RST (0xca26badaUL)
+#define PHY_TILE_PORT_CONFIG_1 (0x9dd667aUL)
+#define PHY_TILE_PORT_CONFIG_1_NT_AUTO_FORCE_LINK_DOWN (0xbb894059UL)
+#define PHY_TILE_PORT_CONFIG_1_NT_FORCE_LINK_DOWN (0x977aaf2bUL)
+#define PHY_TILE_PORT_CONFIG_1_NT_LINKUP_LATENCY (0x54dc22ebUL)
+#define PHY_TILE_PORT_CONFIG_1_RST (0xf6939229UL)
+#define PHY_TILE_PORT_CONFIG_1_RX_RST (0xd0d55959UL)
+#define PHY_TILE_PORT_CONFIG_1_TX_RST (0x68cba44UL)
+#define PHY_TILE_PORT_STATUS (0x8b69e100UL)
+#define PHY_TILE_PORT_STATUS_RESET_ACK_N_0 (0x812f344UL)
+#define PHY_TILE_PORT_STATUS_RESET_ACK_N_1 (0x7f15c3d2UL)
+#define PHY_TILE_PORT_STATUS_RX_AM_LOCK_0 (0x18c38950UL)
+#define PHY_TILE_PORT_STATUS_RX_AM_LOCK_1 (0x6fc4b9c6UL)
+#define PHY_TILE_PORT_STATUS_RX_BLOCK_LOCK_0 (0x72b847a5UL)
+#define PHY_TILE_PORT_STATUS_RX_BLOCK_LOCK_1 (0x5bf7733UL)
+#define PHY_TILE_PORT_STATUS_RX_CDR_LOCK_0 (0x8557733cUL)
+#define PHY_TILE_PORT_STATUS_RX_CDR_LOCK_1 (0xf25043aaUL)
+#define PHY_TILE_PORT_STATUS_RX_HI_BER_0 (0xae6e5427UL)
+#define PHY_TILE_PORT_STATUS_RX_HI_BER_1 (0xd96964b1UL)
+#define PHY_TILE_PORT_STATUS_RX_LOCAL_FAULT_0 (0xb7de3d5eUL)
+#define PHY_TILE_PORT_STATUS_RX_LOCAL_FAULT_1 (0xc0d90dc8UL)
+#define PHY_TILE_PORT_STATUS_RX_PCS_FULLY_ALIGNED_0 (0x690e7dbcUL)
+#define PHY_TILE_PORT_STATUS_RX_PCS_FULLY_ALIGNED_1 (0x1e094d2aUL)
+#define PHY_TILE_PORT_STATUS_RX_PCS_READY_0 (0x4bb3d53cUL)
+#define PHY_TILE_PORT_STATUS_RX_PCS_READY_1 (0x3cb4e5aaUL)
+#define PHY_TILE_PORT_STATUS_RX_PTP_OFFSET_DATA_VALID_0 (0x4a8305e7UL)
+#define PHY_TILE_PORT_STATUS_RX_PTP_OFFSET_DATA_VALID_1 (0x3d843571UL)
+#define PHY_TILE_PORT_STATUS_RX_PTP_READY_0 (0xb74c7368UL)
+#define PHY_TILE_PORT_STATUS_RX_PTP_READY_1 (0xc04b43feUL)
+#define PHY_TILE_PORT_STATUS_RX_REMOTE_FAULT_0 (0x7160c5c7UL)
+#define PHY_TILE_PORT_STATUS_RX_REMOTE_FAULT_1 (0x667f551UL)
+#define PHY_TILE_PORT_STATUS_SYSTEMPLL_LOCK (0x3d44b5b8UL)
+#define PHY_TILE_PORT_STATUS_SYS_PLL_LOCKED_0 (0x9a284858UL)
+#define PHY_TILE_PORT_STATUS_SYS_PLL_LOCKED_1 (0xed2f78ceUL)
+#define PHY_TILE_PORT_STATUS_TX_LANES_STABLE_0 (0x9d0d322aUL)
+#define PHY_TILE_PORT_STATUS_TX_LANES_STABLE_1 (0xea0a02bcUL)
+#define PHY_TILE_PORT_STATUS_TX_PLL_LOCKED_0 (0x56587371UL)
+#define PHY_TILE_PORT_STATUS_TX_PLL_LOCKED_1 (0x215f43e7UL)
+#define PHY_TILE_PORT_STATUS_0 (0x8d2e3a4fUL)
+#define PHY_TILE_PORT_STATUS_0_RESET_ACK_N (0xa0728651UL)
+#define PHY_TILE_PORT_STATUS_0_RX_AM_LOCK (0x84cbe16dUL)
+#define PHY_TILE_PORT_STATUS_0_RX_HI_BER (0x3284d104UL)
+#define PHY_TILE_PORT_STATUS_0_RX_LOCAL_FAULT (0x581a604cUL)
+#define PHY_TILE_PORT_STATUS_0_RX_PCS_FULLY_ALIGNED (0x8a9f2523UL)
+#define PHY_TILE_PORT_STATUS_0_RX_REMOTE_FAULT (0xa42546cfUL)
+#define PHY_TILE_PORT_STATUS_0_RX_RESET_ACK_N (0x5d1fa363UL)
+#define PHY_TILE_PORT_STATUS_0_SYS_PLL_LOCKED (0x1624ce5aUL)
+#define PHY_TILE_PORT_STATUS_0_TX_LANES_STABLE (0x7a66b5c7UL)
+#define PHY_TILE_PORT_STATUS_0_TX_PLL_LOCKED (0x29cd220bUL)
+#define PHY_TILE_PORT_STATUS_0_TX_RESET_ACK_N (0xa5dde8d5UL)
+#define PHY_TILE_PORT_STATUS_1 (0xfa290ad9UL)
+#define PHY_TILE_PORT_STATUS_1_RESET_ACK_N (0x7de45fd4UL)
+#define PHY_TILE_PORT_STATUS_1_RX_AM_LOCK (0x1f6ead02UL)
+#define PHY_TILE_PORT_STATUS_1_RX_HI_BER (0xf30a0ec4UL)
+#define PHY_TILE_PORT_STATUS_1_RX_LOCAL_FAULT (0xf672f1ddUL)
+#define PHY_TILE_PORT_STATUS_1_RX_PCS_FULLY_ALIGNED (0x9db741e3UL)
+#define PHY_TILE_PORT_STATUS_1_RX_REMOTE_FAULT (0x23838d8cUL)
+#define PHY_TILE_PORT_STATUS_1_RX_RESET_ACK_N (0xf37732f2UL)
+#define PHY_TILE_PORT_STATUS_1_SYS_PLL_LOCKED (0xb84c5fcbUL)
+#define PHY_TILE_PORT_STATUS_1_TX_LANES_STABLE (0xfdc07e84UL)
+#define PHY_TILE_PORT_STATUS_1_TX_PLL_LOCKED (0x9036f9e3UL)
+#define PHY_TILE_PORT_STATUS_1_TX_RESET_ACK_N (0xbb57944UL)
+#define PHY_TILE_SCRATCH (0xcd637527UL)
+#define PHY_TILE_SCRATCH_DATA (0x1934d873UL)
+#define PHY_TILE_SYS_PLL (0x65742dccUL)
+#define PHY_TILE_SYS_PLL_DISABLE_REFCLK_MONITOR (0xf740e941UL)
+#define PHY_TILE_SYS_PLL_EN_REFCLK_FGT (0x8f5bac3aUL)
+#define PHY_TILE_SYS_PLL_FORCE_RST (0xa3d1af1fUL)
+#define PHY_TILE_SYS_PLL_FORWARD_RST (0x26a13387UL)
+#define PHY_TILE_SYS_PLL_GET_RDY (0xa2822d9bUL)
+#define PHY_TILE_SYS_PLL_REFCLK_FGT_ENABLED (0x57072ab1UL)
+#define PHY_TILE_SYS_PLL_SET_RDY (0x31139546UL)
+#define PHY_TILE_SYS_PLL_SYSTEMPLL_LOCK (0x467d08f6UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_PHY_TILE_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h
new file mode 100644
index 0000000000..7855c9cab5
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h
@@ -0,0 +1,26 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_prm_nt400dxx.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_PRM_NT400DXX_
+#define _NTHW_FPGA_REG_DEFS_PRM_NT400DXX_
+
+/* PRM_NT400DXX */
+#define NTHW_MOD_PRM_NT400DXX (0xfccf12a8UL)
+#define PRM_NT400DXX_RST (0x9c1555f7UL)
+#define PRM_NT400DXX_RST_PERIPH (0xe08c7c1cUL)
+#define PRM_NT400DXX_RST_PLATFORM (0x866ae8d1UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_PRM_NT400DXX_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h
new file mode 100644
index 0000000000..18b67f4032
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h
@@ -0,0 +1,38 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_rfd.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_RFD_
+#define _NTHW_FPGA_REG_DEFS_RFD_
+
+/* RFD */
+#define NTHW_MOD_RFD (0x7fa60826UL)
+#define RFD_CTRL (0x5347930aUL)
+#define RFD_CTRL_CFP (0x38fb2beUL)
+#define RFD_CTRL_ISL (0x2dac8d33UL)
+#define RFD_CTRL_PWMCW (0xebb075fcUL)
+#define RFD_MAX_FRAME_SIZE (0x8369a9a2UL)
+#define RFD_MAX_FRAME_SIZE_MAX (0x647c0b15UL)
+#define RFD_TNL_VLAN (0xb85aa35fUL)
+#define RFD_TNL_VLAN_TPID0 (0xe2dfb0a4UL)
+#define RFD_TNL_VLAN_TPID1 (0x95d88032UL)
+#define RFD_VLAN (0xa954e6d1UL)
+#define RFD_VLAN_TPID0 (0xab4dac41UL)
+#define RFD_VLAN_TPID1 (0xdc4a9cd7UL)
+#define RFD_VXLAN (0xe2207aeaUL)
+#define RFD_VXLAN_DP0 (0xb17ca4d9UL)
+#define RFD_VXLAN_DP1 (0xc67b944fUL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_RFD_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h
new file mode 100644
index 0000000000..90aeaec3a4
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_rst9574.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_RST9574_
+#define _NTHW_FPGA_REG_DEFS_RST9574_
+
+/* RST9574 */
+#define NTHW_MOD_RST9574 (0xbf22c9ffUL)
+#define RST9574_LATCH (0x3ed1e303UL)
+#define RST9574_LATCH_DDR4_CALIB_COMPLETE (0x3b59afedUL)
+#define RST9574_LATCH_PHY_FTILE_RDY (0x4e701f0fUL)
+#define RST9574_LATCH_PHY_FTILE_RST_DONE (0xd55b1659UL)
+#define RST9574_RST (0x4f1625b6UL)
+#define RST9574_RST_DDR4 (0x152e69ddUL)
+#define RST9574_RST_PHY_FTILE (0x8455e296UL)
+#define RST9574_RST_SYS (0x6a2c0d30UL)
+#define RST9574_STAT (0x160fed08UL)
+#define RST9574_STAT_DDR4_CALIB_COMPLETE (0x768d8717UL)
+#define RST9574_STAT_PHY_FTILE_RDY (0x727ca032UL)
+#define RST9574_STAT_PHY_FTILE_RST_DONE (0xb312b439UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_RST9574_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h
new file mode 100644
index 0000000000..5adeaea1ec
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h
@@ -0,0 +1,76 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_spim.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_SPIM_
+#define _NTHW_FPGA_REG_DEFS_SPIM_
+
+/* SPIM */
+#define NTHW_MOD_SPIM (0x1da437bfUL)
+#define SPIM_CFG (0x90b6b0d5UL)
+#define SPIM_CFG_PRE (0x156a8ea9UL)
+#define SPIM_CFG_CLK (0xeb7046a1UL)
+#define SPIM_CFG_CLK_MODE (0x228be0cbUL)
+#define SPIM_CMD (0xea4b38a4UL)
+#define SPIM_CMD_ADDR (0x95fe56baUL)
+#define SPIM_CMD_CMD (0x9c30279bUL)
+#define SPIM_CMD_DATA (0x6a9737ecUL)
+#define SPIM_CONF0 (0x84d4acb5UL)
+#define SPIM_CONF0_BYTE_PACE (0xc9a95016UL)
+#define SPIM_CONF0_MIRROR_EN (0xa710688UL)
+#define SPIM_CONF0_MSB_FIRST (0x5f60c96aUL)
+#define SPIM_CONF0_PRESCAL_CLK (0xadb38a7UL)
+#define SPIM_CONF0_RESTART (0x1fda85dcUL)
+#define SPIM_CONF0_RST (0x64e3b3bUL)
+#define SPIM_CONF0_SYNC_MON_EN (0x591a639eUL)
+#define SPIM_CONF1 (0xf3d39c23UL)
+#define SPIM_CONF1_MIRROR_PACE (0x370f3f34UL)
+#define SPIM_CONF1_MIRROR_SCAN (0x83daffbeUL)
+#define SPIM_CONF1_SYNCTIMEOUT (0x1b5d30cdUL)
+#define SPIM_CONF2 (0x6adacd99UL)
+#define SPIM_CONF2_MIRROR_PRESC (0x3a8c10e2UL)
+#define SPIM_CONF2_OPCODE_RD (0x3eb6084fUL)
+#define SPIM_CONF2_OPCODE_WR (0xb715495bUL)
+#define SPIM_CONF3 (0x1dddfd0fUL)
+#define SPIM_CONF3_MIRROR_RDADR (0xc00ba60fUL)
+#define SPIM_CONF3_MIRROR_WRADR (0x7d99213cUL)
+#define SPIM_CR (0x1c1de013UL)
+#define SPIM_CR_EN (0xf2e0e72fUL)
+#define SPIM_CR_LOOP (0xdeb882aUL)
+#define SPIM_CR_RXRST (0x487f7d1bUL)
+#define SPIM_CR_TXRST (0xc73f88bbUL)
+#define SPIM_DRR (0xd68a95eeUL)
+#define SPIM_DRR_DRR (0x78766633UL)
+#define SPIM_DTR (0x80d03268UL)
+#define SPIM_DTR_DTR (0xf87522a8UL)
+#define SPIM_REPLY (0x6ed04defUL)
+#define SPIM_REPLY_RDDATA (0x40db3b24UL)
+#define SPIM_SR (0x56dff242UL)
+#define SPIM_SR_DONE (0xdb47e9a1UL)
+#define SPIM_SR_RXEMPTY (0x489aaf91UL)
+#define SPIM_SR_RXFULL (0xd26832f5UL)
+#define SPIM_SR_RXLVL (0x4c67ae59UL)
+#define SPIM_SR_TXEMPTY (0x2b4a9aabUL)
+#define SPIM_SR_TXFULL (0x431d1e8UL)
+#define SPIM_SR_TXLVL (0xc3275bf9UL)
+#define SPIM_SRR (0xcfe3201bUL)
+#define SPIM_SRR_RST (0x32dc8fc5UL)
+#define SPIM_STATUS (0xd04220ceUL)
+#define SPIM_STATUS_CMDPENDING (0x74ed833fUL)
+#define SPIM_STATUS_RESERVED (0xa50278bUL)
+#define SPIM_STATUS_RESYNCDETECT (0x5b268881UL)
+#define SPIM_STATUS_RESYNCING (0x5ec3f11UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_SPIM_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h
new file mode 100644
index 0000000000..11785d74b7
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h
@@ -0,0 +1,51 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_spis.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_SPIS_
+#define _NTHW_FPGA_REG_DEFS_SPIS_
+
+/* SPIS */
+#define NTHW_MOD_SPIS (0xe7ab0adcUL)
+#define SPIS_CR (0xacdbc0bfUL)
+#define SPIS_CR_DEBUG (0xf2096408UL)
+#define SPIS_CR_EN (0xc50100bcUL)
+#define SPIS_CR_LOOP (0x69e911c9UL)
+#define SPIS_CR_RXRST (0x7118cc40UL)
+#define SPIS_CR_TXRST (0xfe5839e0UL)
+#define SPIS_DRR (0x95abc0dUL)
+#define SPIS_DRR_DRR (0x1c74ffd0UL)
+#define SPIS_DTR (0x5f001b8bUL)
+#define SPIS_DTR_DTR (0x9c77bb4bUL)
+#define SPIS_RAM_CTRL (0x682dc7d8UL)
+#define SPIS_RAM_CTRL_ADR (0x15c2f809UL)
+#define SPIS_RAM_CTRL_CNT (0x5ca61d8UL)
+#define SPIS_RAM_DATA (0xc7fc45c1UL)
+#define SPIS_RAM_DATA_DATA (0x422b05eaUL)
+#define SPIS_SR (0xe619d2eeUL)
+#define SPIS_SR_DONE (0xbf457042UL)
+#define SPIS_SR_FRAME_ERR (0x31b5d7e4UL)
+#define SPIS_SR_READ_ERR (0xa83d91f1UL)
+#define SPIS_SR_RXEMPTY (0xadb39173UL)
+#define SPIS_SR_RXFULL (0x2ee8dd38UL)
+#define SPIS_SR_RXLVL (0x75001f02UL)
+#define SPIS_SR_TXEMPTY (0xce63a449UL)
+#define SPIS_SR_TXFULL (0xf8b13e25UL)
+#define SPIS_SR_TXLVL (0xfa40eaa2UL)
+#define SPIS_SR_WRITE_ERR (0x9d389ce2UL)
+#define SPIS_SRR (0x103309f8UL)
+#define SPIS_SRR_RST (0x56de1626UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_SPIS_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h
new file mode 100644
index 0000000000..acfc07a1b6
--- /dev/null
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h
@@ -0,0 +1,28 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+/*
+ * nthw_fpga_reg_defs_tint.h
+ *
+ * Auto-generated file - do *NOT* edit
+ *
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_TINT_
+#define _NTHW_FPGA_REG_DEFS_TINT_
+
+/* TINT */
+#define NTHW_MOD_TINT (0xb8aea9feUL)
+#define TINT_CTRL (0x95bdc9c3UL)
+#define TINT_CTRL_INTERVAL (0xfe472b70UL)
+#define TINT_STATUS (0x2557d8a6UL)
+#define TINT_STATUS_DELAYED (0xabd2ff4cUL)
+#define TINT_STATUS_SKIPPED (0x1c35b879UL)
+
+#endif	/* _NTHW_FPGA_REG_DEFS_TINT_ */
+
+/*
+ * Auto-generated file - do *NOT* edit
+ */
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 16/32] net/ntnic: add setup for fpga reset
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (14 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 15/32] net/ntnic: add FPGA modules and registers Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 17/32] net/ntnic: add default reset setting for NT400D13 Serhii Iliushyk
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Initialize FPGA reset module and register fields.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../core/nt400dxx/reset/nthw_fpga_rst9574.c   | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
index 9ab26583df..bd38d6b8c8 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
@@ -14,6 +14,60 @@ static int nthw_fpga_rst9574_setup(nthw_fpga_t *p_fpga, struct nthw_fpga_rst_nt4
 	assert(p_fpga);
 	assert(p);
 
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	const int n_fpga_product_id = p_fpga->mn_product_id;
+	const int n_fpga_version = p_fpga->mn_fpga_version;
+	const int n_fpga_revision = p_fpga->mn_fpga_revision;
+
+	nthw_module_t *p_mod_rst;
+	nthw_register_t *p_curr_reg;
+
+	p->n_fpga_product_id = n_fpga_product_id;
+	p->n_fpga_version = n_fpga_version;
+	p->n_fpga_revision = n_fpga_revision;
+
+	NT_LOG(DBG, NTHW, "%s: %s: FPGA reset setup: FPGA %04d-%02d-%02d", p_adapter_id_str,
+		__func__, n_fpga_product_id, n_fpga_version, n_fpga_revision);
+
+	p_mod_rst = nthw_fpga_query_module(p_fpga, MOD_RST9574, 0);
+
+	if (p_mod_rst == NULL) {
+		NT_LOG(ERR, NTHW, "%s: RST %d: no such instance", p_adapter_id_str, 0);
+		return -1;
+	}
+
+	p_mod_rst = nthw_fpga_query_module(p_fpga, MOD_RST9574, 0);
+
+	if (p_mod_rst == NULL) {
+		NT_LOG(ERR, NTHW, "%s: RST %d: no such instance", p_adapter_id_str, 0);
+		return -1;
+	}
+
+	/* RST register field pointers */
+	p_curr_reg = nthw_module_get_register(p_mod_rst, RST9574_RST);
+	p->p_fld_rst_sys = nthw_register_get_field(p_curr_reg, RST9574_RST_SYS);
+	p->p_fld_rst_ddr4 = nthw_register_get_field(p_curr_reg, RST9574_RST_DDR4);
+	p->p_fld_rst_phy_ftile = nthw_register_get_field(p_curr_reg, RST9574_RST_PHY_FTILE);
+	nthw_register_update(p_curr_reg);
+
+	p_curr_reg = nthw_module_get_register(p_mod_rst, RST9574_STAT);
+	p->p_fld_stat_ddr4_calib_complete =
+		nthw_register_get_field(p_curr_reg, RST9574_STAT_DDR4_CALIB_COMPLETE);
+	p->p_fld_stat_phy_ftile_rst_done =
+		nthw_register_get_field(p_curr_reg, RST9574_STAT_PHY_FTILE_RST_DONE);
+	p->p_fld_stat_phy_ftile_rdy =
+		nthw_register_get_field(p_curr_reg, RST9574_STAT_PHY_FTILE_RDY);
+	nthw_register_update(p_curr_reg);
+
+	p_curr_reg = nthw_module_get_register(p_mod_rst, RST9574_LATCH);
+	p->p_fld_latch_ddr4_calib_complete =
+		nthw_register_get_field(p_curr_reg, RST9574_LATCH_DDR4_CALIB_COMPLETE);
+	p->p_fld_latch_phy_ftile_rst_done =
+		nthw_register_get_field(p_curr_reg, RST9574_LATCH_PHY_FTILE_RST_DONE);
+	p->p_fld_latch_phy_ftile_rdy =
+		nthw_register_get_field(p_curr_reg, RST9574_LATCH_PHY_FTILE_RDY);
+	nthw_register_update(p_curr_reg);
+
 	return 0;
 };
 
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 17/32] net/ntnic: add default reset setting for NT400D13
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (15 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 16/32] net/ntnic: add setup for fpga reset Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 18/32] net/ntnic: add DDR calibration to reset stage Serhii Iliushyk
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Add DDR4 reset and calibration completion handling.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../core/nt400dxx/reset/nthw_fpga_rst9574.c   | 29 ++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
index bd38d6b8c8..757ec1b4c6 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
@@ -71,14 +71,41 @@ static int nthw_fpga_rst9574_setup(nthw_fpga_t *p_fpga, struct nthw_fpga_rst_nt4
 	return 0;
 };
 
+static void nthw_fpga_rst9574_set_default_rst_values(struct nthw_fpga_rst_nt400dxx *const p)
+{
+	nthw_field_update_register(p->p_fld_rst_sys);
+	nthw_field_set_all(p->p_fld_rst_sys);
+	nthw_field_set_val32(p->p_fld_rst_ddr4, 1);
+	nthw_field_set_val_flush32(p->p_fld_rst_phy_ftile, 1);
+}
+
+static int nthw_fpga_rst9574_product_reset(struct fpga_info_s *p_fpga_info,
+	struct nthw_fpga_rst_nt400dxx *p_rst)
+{
+	assert(p_fpga_info);
+	assert(p_rst);
 
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+
+	/* (0) Reset all domains / modules except peripherals: */
+	NT_LOG(DBG, NTHW, "%s: %s: RST defaults", p_adapter_id_str, __func__);
+	nthw_fpga_rst9574_set_default_rst_values(p_rst);
+
+	/*
+	 * Wait a while before waiting for deasserting ddr4 reset
+	 */
+	nt_os_wait_usec(2000);
+
+
+	return 0;
+}
 
 static int nthw_fpga_rst9574_init(struct fpga_info_s *p_fpga_info,
 	struct nthw_fpga_rst_nt400dxx *p_rst)
 {
 	assert(p_fpga_info);
 	assert(p_rst);
-	int res = -1;
+	int res = nthw_fpga_rst9574_product_reset(p_fpga_info, p_rst);
 
 	return res;
 }
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 18/32] net/ntnic: add DDR calibration to reset stage
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (16 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 17/32] net/ntnic: add default reset setting for NT400D13 Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 19/32] net/ntnic: add PHY ftile reset Serhii Iliushyk
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Add DDR4 reset and calibration functions for FPGA.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../core/nt400dxx/reset/nthw_fpga_rst9574.c   | 95 +++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
index 757ec1b4c6..27d60d1448 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
@@ -79,6 +79,72 @@ static void nthw_fpga_rst9574_set_default_rst_values(struct nthw_fpga_rst_nt400d
 	nthw_field_set_val_flush32(p->p_fld_rst_phy_ftile, 1);
 }
 
+static void nthw_fpga_rst9574_ddr4_rst(struct nthw_fpga_rst_nt400dxx *const p, uint32_t val)
+{
+	nthw_field_update_register(p->p_fld_rst_ddr4);
+	nthw_field_set_val_flush32(p->p_fld_rst_ddr4, val);
+}
+
+static bool nthw_fpga_rst9574_get_ddr4_calib_complete_stat(struct nthw_fpga_rst_nt400dxx *const p)
+{
+	return nthw_field_get_updated(p->p_fld_stat_ddr4_calib_complete) != 0;
+}
+
+static bool nthw_fpga_rst9574_get_ddr4_calib_complete_latch(struct nthw_fpga_rst_nt400dxx *const p)
+{
+	return nthw_field_get_updated(p->p_fld_latch_ddr4_calib_complete) != 0;
+}
+
+static void nthw_fpga_rst9574_set_ddr4_calib_complete_latch(struct nthw_fpga_rst_nt400dxx *const p,
+	uint32_t val)
+{
+	nthw_field_update_register(p->p_fld_latch_ddr4_calib_complete);
+	nthw_field_set_val_flush32(p->p_fld_latch_ddr4_calib_complete, val);
+}
+
+static int nthw_fpga_rst9574_wait_ddr4_calibration_complete(struct fpga_info_s *p_fpga_info,
+	struct nthw_fpga_rst_nt400dxx *p_rst)
+{
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	uint32_t complete;
+	uint32_t retrycount;
+	uint32_t timeout;
+
+	/* 3: wait until DDR4 CALIB COMPLETE */
+	NT_LOG(DBG, NTHW, "%s: %s: DDR4 CALIB COMPLETE wait complete", p_adapter_id_str, __func__);
+	/*
+	 * The following retry count gives a total timeout of 1 * 5 + 5 * 8 = 45sec
+	 * It has been observed that at least 21sec can be necessary
+	 */
+	retrycount = 1;
+	timeout = 50000;/* initial timeout must be set to 5 sec. */
+
+	do {
+		complete = nthw_fpga_rst9574_get_ddr4_calib_complete_stat(p_rst);
+
+		if (!complete)
+			nt_os_wait_usec(100);
+
+		timeout--;
+
+		if (timeout == 0) {
+			if (retrycount == 0) {
+				NT_LOG(ERR, NTHW,
+					"%s: %s: Timeout waiting for DDR4 CALIB COMPLETE to be complete",
+					p_adapter_id_str, __func__);
+				return -1;
+			}
+
+			nthw_fpga_rst9574_ddr4_rst(p_rst, 1);	/* Reset DDR4 */
+			nthw_fpga_rst9574_ddr4_rst(p_rst, 0);
+			retrycount--;
+			timeout = 90000;/* Increase timeout for second attempt to 8 sec. */
+		}
+	} while (!complete);
+
+	return 0;
+}
+
 static int nthw_fpga_rst9574_product_reset(struct fpga_info_s *p_fpga_info,
 	struct nthw_fpga_rst_nt400dxx *p_rst)
 {
@@ -86,6 +152,7 @@ static int nthw_fpga_rst9574_product_reset(struct fpga_info_s *p_fpga_info,
 	assert(p_rst);
 
 	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	int res = -1;
 
 	/* (0) Reset all domains / modules except peripherals: */
 	NT_LOG(DBG, NTHW, "%s: %s: RST defaults", p_adapter_id_str, __func__);
@@ -96,6 +163,34 @@ static int nthw_fpga_rst9574_product_reset(struct fpga_info_s *p_fpga_info,
 	 */
 	nt_os_wait_usec(2000);
 
+	/* (1) De-assert DDR4 reset: */
+	NT_LOG(DBG, NTHW, "%s: %s: De-asserting DDR4 reset", p_adapter_id_str, __func__);
+	nthw_fpga_rst9574_ddr4_rst(p_rst, 0);
+
+	/*
+	 * Wait a while before waiting for calibration complete, since calibration complete
+	 * is true while ddr4 is in reset
+	 */
+	nt_os_wait_usec(2000);
+
+	/* (2) Wait until DDR4 calibration complete */
+	res = nthw_fpga_rst9574_wait_ddr4_calibration_complete(p_fpga_info, p_rst);
+
+	if (res)
+		return res;
+
+	/* (3) Set DDR4 calib complete latched bits: */
+	nthw_fpga_rst9574_set_ddr4_calib_complete_latch(p_rst, 1);
+
+	/* Wait for phy to settle.*/
+	nt_os_wait_usec(20000);
+
+	/* (4) Ensure all latched status bits are still set: */
+	if (!nthw_fpga_rst9574_get_ddr4_calib_complete_latch(p_rst)) {
+		NT_LOG(ERR, NTHW, "%s: %s: DDR4 calibration complete has toggled",
+			p_adapter_id_str, __func__);
+	}
+
 
 	return 0;
 }
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 19/32] net/ntnic: add PHY ftile reset
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (17 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 18/32] net/ntnic: add DDR calibration to reset stage Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 20/32] net/ntnic: add clock init Serhii Iliushyk
                   ` (14 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Add reset functions and reset procedure for module PHY FTILE

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |  12 ++
 .../core/nt400dxx/reset/nthw_fpga_rst9574.c   | 161 ++++++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   |  38 +++++
 3 files changed, 211 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
index f84aef44a9..68d8455b8d 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -8,6 +8,10 @@
 
 #include "nthw_fpga_model.h"
 
+enum mac_pcs_mode_e {
+	MAC_PCS_MODE_2X100
+};
+
 struct nt_phy_tile {
 	nthw_fpga_t *mp_fpga;
 
@@ -16,6 +20,8 @@ struct nt_phy_tile {
 	int mn_fpga_version;
 	int mn_fpga_revision;
 
+	enum mac_pcs_mode_e mac_pcs_mode;
+
 	nthw_register_t *mp_reg_port_xcvr_base[2][4];
 	nthw_field_t *mp_fld_port_xcvr_base_ptr[2][4];
 	nthw_field_t *mp_fld_port_xcvr_base_busy[2][4];
@@ -39,6 +45,8 @@ struct nt_phy_tile {
 
 	nthw_field_t *mp_fld_port_status_rx_hi_ber[2];
 	nthw_field_t *mp_fld_port_status_rx_am_lock[2];
+	nthw_field_t *mp_fld_port_status_reset_ackn[2];
+	nthw_field_t *mp_fld_port_status_tx_lanes_stable[2];
 	nthw_field_t *mp_fld_port_status_tx_reset_ackn[2];
 	nthw_field_t *mp_fld_port_status_rx_reset_ackn[2];
 
@@ -93,5 +101,9 @@ uint32_t nthw_phy_tile_read_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t la
 	uint32_t address);
 void nthw_phy_tile_write_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, uint32_t address,
 	uint32_t data);
+uint32_t nthw_phy_tile_get_port_status_reset_ack(nthw_phy_tile_t *p, uint8_t intf_no);
+uint32_t nthw_phy_tile_get_port_status_tx_lanes_stable(nthw_phy_tile_t *p, uint8_t intf_no);
+uint8_t nthw_phy_tile_get_no_intfs(nthw_phy_tile_t *p);
+void nthw_phy_tile_set_port_config_rst(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t value);
 
 #endif	/* __NTHW_PHY_TILE_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
index 27d60d1448..b1bbe28709 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
@@ -79,17 +79,44 @@ static void nthw_fpga_rst9574_set_default_rst_values(struct nthw_fpga_rst_nt400d
 	nthw_field_set_val_flush32(p->p_fld_rst_phy_ftile, 1);
 }
 
+static void nthw_fpga_rst9574_sys_rst(struct nthw_fpga_rst_nt400dxx *const p, uint32_t val)
+{
+	nthw_field_update_register(p->p_fld_rst_sys);
+	nthw_field_set_val_flush32(p->p_fld_rst_sys, val);
+}
+
 static void nthw_fpga_rst9574_ddr4_rst(struct nthw_fpga_rst_nt400dxx *const p, uint32_t val)
 {
 	nthw_field_update_register(p->p_fld_rst_ddr4);
 	nthw_field_set_val_flush32(p->p_fld_rst_ddr4, val);
 }
 
+static void nthw_fpga_rst9574_phy_ftile_rst(struct nthw_fpga_rst_nt400dxx *const p, uint32_t val)
+{
+	nthw_field_update_register(p->p_fld_rst_phy_ftile);
+	nthw_field_set_val_flush32(p->p_fld_rst_phy_ftile, val);
+}
+
+static bool nthw_fpga_rst9574_get_phy_ftile_rst(struct nthw_fpga_rst_nt400dxx *const p)
+{
+	return nthw_field_get_updated(p->p_fld_rst_phy_ftile) != 0;
+}
+
 static bool nthw_fpga_rst9574_get_ddr4_calib_complete_stat(struct nthw_fpga_rst_nt400dxx *const p)
 {
 	return nthw_field_get_updated(p->p_fld_stat_ddr4_calib_complete) != 0;
 }
 
+static bool nthw_fpga_rst9574_get_phy_ftile_rst_done_stat(struct nthw_fpga_rst_nt400dxx *const p)
+{
+	return nthw_field_get_updated(p->p_fld_stat_phy_ftile_rst_done) != 0;
+}
+
+static bool nthw_fpga_rst9574_get_phy_ftile_rdy_stat(struct nthw_fpga_rst_nt400dxx *const p)
+{
+	return nthw_field_get_updated(p->p_fld_stat_phy_ftile_rdy) != 0;
+}
+
 static bool nthw_fpga_rst9574_get_ddr4_calib_complete_latch(struct nthw_fpga_rst_nt400dxx *const p)
 {
 	return nthw_field_get_updated(p->p_fld_latch_ddr4_calib_complete) != 0;
@@ -145,6 +172,69 @@ static int nthw_fpga_rst9574_wait_ddr4_calibration_complete(struct fpga_info_s *
 	return 0;
 }
 
+static int nthw_fpga_rst9574_wait_phy_ftile_rdy(struct fpga_info_s *p_fpga_info,
+	struct nthw_fpga_rst_nt400dxx *p_rst)
+{
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	uint32_t complete;
+	uint32_t timeout;
+
+	/* 5: wait until PHY_FTILE reset done */
+	NT_LOG(DBG, NTHW, "%s: %s: PHY FTILE ready", p_adapter_id_str, __func__);
+	timeout = 50000;/* initial timeout must be set to 5 sec. */
+
+	do {
+		complete = nthw_fpga_rst9574_get_phy_ftile_rdy_stat(p_rst);
+
+		if (!complete) {
+			nt_os_wait_usec(100);
+
+		} else {
+			NT_LOG(DBG, NTHW, "%s: PHY FTILE ready, margin to timeout %u",
+				p_adapter_id_str, timeout);
+		}
+
+		timeout--;
+
+		if (timeout == 0) {
+			NT_LOG(ERR, NTHW, "%s: %s: Timeout waiting for PHY FTILE ready",
+				p_adapter_id_str, __func__);
+			return -1;
+		}
+	} while (!complete);
+
+	return 0;
+}
+
+static int nthw_fpga_rst9574_wait_phy_ftile_rst_done(struct fpga_info_s *p_fpga_info,
+	struct nthw_fpga_rst_nt400dxx *p_rst)
+{
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	uint32_t complete;
+	uint32_t timeout;
+
+	/* 5: wait until PHY_FTILE reset done */
+	NT_LOG(DBG, NTHW, "%s: %s: PHY FTILE RESET done", p_adapter_id_str, __func__);
+	timeout = 50000;/* initial timeout must be set to 5 sec. */
+
+	do {
+		complete = nthw_fpga_rst9574_get_phy_ftile_rst_done_stat(p_rst);
+
+		if (!complete)
+			nt_os_wait_usec(100);
+
+		timeout--;
+
+		if (timeout == 0) {
+			NT_LOG(ERR, NTHW, "%s: %s: Timeout waiting for PHY FTILE RESET to be done",
+				p_adapter_id_str, __func__);
+			return -1;
+		}
+	} while (!complete);
+
+	return 0;
+}
+
 static int nthw_fpga_rst9574_product_reset(struct fpga_info_s *p_fpga_info,
 	struct nthw_fpga_rst_nt400dxx *p_rst)
 {
@@ -191,6 +281,77 @@ static int nthw_fpga_rst9574_product_reset(struct fpga_info_s *p_fpga_info,
 			p_adapter_id_str, __func__);
 	}
 
+	int32_t tries = 0;
+	bool success = false;
+
+	do {
+		/* Only wait for ftile rst done if ftile is indeed in reset. */
+		if (nthw_fpga_rst9574_get_phy_ftile_rst(p_rst)) {
+			/* (5) Wait until PHY_FTILE reset done */
+			NT_LOG(DBG, NTHW, "%s: %s: Wait until PHY_FTILE reset done",
+				p_adapter_id_str, __func__);
+			res = nthw_fpga_rst9574_wait_phy_ftile_rst_done(p_fpga_info, p_rst);
+
+			if (res)
+				return res;
+		}
+
+		/* (6) De-assert PHY_FTILE reset: */
+		NT_LOG(DBG, NTHW, "%s: %s: De-asserting PHY_FTILE reset", p_adapter_id_str,
+			__func__);
+		nthw_fpga_rst9574_phy_ftile_rst(p_rst, 0);
+
+		nt_os_wait_usec(10000);
+		/* (7) Wait until PHY_FTILE ready */
+		if (nthw_fpga_rst9574_wait_phy_ftile_rdy(p_fpga_info, p_rst) != -1) {
+			success = true;
+			continue;
+		}
+
+		if (++tries >= 5) {
+			/* Give up */
+			NT_LOG(ERR, NTHW, "%s: %s: PHY_TILE not ready after %u attempts",
+				p_adapter_id_str, __func__, tries);
+			return res;
+		}
+
+		/* Try to recover with as little effort as possible */
+		nthw_phy_tile_t *p_phy_tile = p_fpga_info->mp_nthw_agx.p_phy_tile;
+
+		for (uint8_t i = 0; i < nthw_phy_tile_get_no_intfs(p_phy_tile); i++) {
+			/* Also consider TX_PLL_LOCKED == 0 */
+			if (!nthw_phy_tile_get_port_status_tx_lanes_stable(p_phy_tile, i)) {
+				success = false;
+				NT_LOG(WRN, NTHW,
+					"%s: %s: PHY_TILE Intf %u TX_LANES_STABLE == FALSE",
+					p_adapter_id_str, __func__, i);
+
+				/* Active low */
+				nthw_phy_tile_set_port_config_rst(p_phy_tile, i, 0);
+				int32_t count = 1000;
+
+				do {
+					nt_os_wait_usec(1000);
+				} while (!nthw_phy_tile_get_port_status_reset_ack(p_phy_tile, i) &&
+					(--count > 0));
+
+				if (count <= 0) {
+					NT_LOG(ERR, NTHW, "%s: %s: IntfNo %u: "
+					"Time-out waiting for PortStatusResetAck",
+					p_adapter_id_str, __func__, i);
+				}
+
+				/* Active low */
+				nthw_phy_tile_set_port_config_rst(p_phy_tile, i, 1);
+				nt_os_wait_usec(20000);
+			}
+		}
+
+	} while (!success);
+
+	/* (8) De-assert SYS reset: */
+	NT_LOG(DBG, NTHW, "%s: %s: De-asserting SYS reset", p_adapter_id_str, __func__);
+	nthw_fpga_rst9574_sys_rst(p_rst, 0);
 
 	return 0;
 }
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
index b057e9e88c..a8c2d03be9 100644
--- a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -44,6 +44,17 @@ static const uint32_t eth_soft_csr1 = 0x200;
 static const uint32_t eth_soft_csr2 = 0x204;
 static const uint32_t eth_soft_csr3 = 0x208;
 
+uint8_t nthw_phy_tile_get_no_intfs(nthw_phy_tile_t *p)
+{
+	switch (p->mac_pcs_mode) {
+	case MAC_PCS_MODE_2X100:
+		return 2;
+
+	default:
+		return 0;
+	}
+}
+
 static void nthw_phy_tile_set_reset(nthw_phy_tile_t *p, uint8_t intf_no, bool reset)
 {
 	/* Reset is active low */
@@ -543,3 +554,30 @@ bool nthw_phy_tile_configure_fec(nthw_phy_tile_t *p, uint8_t intf_no, bool enabl
 
 	return true;
 }
+
+uint32_t nthw_phy_tile_get_port_status_reset_ack(nthw_phy_tile_t *p, uint8_t intf_no)
+{
+	if (p->mp_fld_port_status_reset_ackn[intf_no]) {
+		return nthw_field_get_updated(p->mp_fld_port_status_reset_ackn[intf_no]) == 0
+			? 1
+			: 0;    /* Inverted */
+	}
+
+	return 1;
+}
+
+uint32_t nthw_phy_tile_get_port_status_tx_lanes_stable(nthw_phy_tile_t *p, uint8_t intf_no)
+{
+	if (p->mp_fld_port_status_tx_lanes_stable[intf_no])
+		return nthw_field_get_updated(p->mp_fld_port_status_tx_lanes_stable[intf_no]);
+
+	return 1;
+}
+
+void nthw_phy_tile_set_port_config_rst(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t value)
+{
+	if (p->mp_fld_port_config_reset[intf_no]) {
+		nthw_field_get_updated(p->mp_fld_port_config_reset[intf_no]);
+		nthw_field_set_val_flush32(p->mp_fld_port_config_reset[intf_no], value);
+	}
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 20/32] net/ntnic: add clock init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (18 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 19/32] net/ntnic: add PHY ftile reset Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-03-05 17:03   ` David Marchand
  2025-02-20 22:03 ` [PATCH v1 21/32] net/ntnic: add nt400d13 pcm init Serhii Iliushyk
                   ` (13 subsequent siblings)
  33 siblings, 1 reply; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Add initialization for the clock subsystem

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 ...00D13_U62_Si5332-GM2-RevD-1_V5-Registers.h | 425 ++++++++++++++++++
 .../net/ntnic/nthw/core/include/nthw_i2cm.h   |   1 +
 .../nthw/core/include/nthw_pcm_nt400dxx.h     |  14 +
 .../nthw/core/include/nthw_si5332_si5156.h    |  36 ++
 .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   | 115 ++++-
 drivers/net/ntnic/nthw/core/nthw_i2cm.c       |  57 +++
 .../net/ntnic/nthw/core/nthw_si5332_si5156.c  |  93 ++++
 drivers/net/ntnic/nthw/nthw_drv.h             |   7 +-
 8 files changed, 745 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h

diff --git a/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
new file mode 100644
index 0000000000..f87828fcfe
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
@@ -0,0 +1,425 @@
+/*
+ * Si5332-GM2 Rev D Configuration Register Export Header File
+ *
+ * This file represents a series of Skyworks Si5332-GM2 Rev D
+ * register writes that can be performed to load a single configuration
+ * on a device. It was created by a Skyworks ClockBuilder Pro
+ * export tool.
+ *
+ * Part:		                                       Si5332-GM2 Rev D
+ * Design ID:                                          1
+ * Includes Pre/Post Download Control Register Writes: Yes
+ * Created By:                                         ClockBuilder Pro v4.5 [2022-08-23]
+ * Timestamp:                                          2022-10-11 15:44:24 GMT+02:00
+ *
+ * A complete design report corresponding to this export is included at the end
+ * of this header file.
+ *
+ */
+
+#ifndef SI5332_GM2_REVD_REG_CONFIG_HEADER
+#define SI5332_GM2_REVD_REG_CONFIG_HEADER
+
+#define SI5332_GM2_REVD_REG_CONFIG_NUM_REGS 76
+
+typedef struct {
+	unsigned int address;	/* 8-bit register address */
+	unsigned char value;	/* 8-bit register data */
+
+} si5332_gm2_revd_register_t;
+
+si5332_gm2_revd_register_t const si5332_gm2_revd_registers[SI5332_GM2_REVD_REG_CONFIG_NUM_REGS] = {
+	/* Start configuration preamble */
+	/*    Set device in Ready mode */
+	{ 0x0006, 0x01 },
+	/* End configuration preamble */
+
+	/* Start configuration registers */
+	{ 0x0017, 0x31 },
+	{ 0x0018, 0x00 },
+	{ 0x0019, 0x00 },
+	{ 0x001A, 0x00 },
+	{ 0x001B, 0x00 },
+	{ 0x001C, 0x00 },
+	{ 0x0021, 0x6A },
+	{ 0x0024, 0x01 },
+	{ 0x0025, 0x00 },
+	{ 0x0026, 0x00 },
+	{ 0x0027, 0x50 },
+	{ 0x0028, 0x50 },
+	{ 0x0029, 0x00 },
+	{ 0x002A, 0x00 },
+	{ 0x002B, 0x10 },
+	{ 0x0036, 0x07 },
+	{ 0x0037, 0x80 },
+	{ 0x0038, 0x02 },
+	{ 0x0039, 0x80 },
+	{ 0x003A, 0x05 },
+	{ 0x003B, 0x35 },
+	{ 0x003C, 0x00 },
+	{ 0x0048, 0x00 },
+	{ 0x0054, 0x00 },
+	{ 0x0060, 0x00 },
+	{ 0x0067, 0x19 },
+	{ 0x0068, 0x00 },
+	{ 0x0069, 0x00 },
+	{ 0x006A, 0x00 },
+	{ 0x006B, 0x00 },
+	{ 0x006C, 0x01 },
+	{ 0x0073, 0x00 },
+	{ 0x0074, 0x00 },
+	{ 0x0075, 0x01 },
+	{ 0x007A, 0x07 },
+	{ 0x007B, 0x01 },
+	{ 0x007C, 0x00 },
+	{ 0x007D, 0x00 },
+	{ 0x007F, 0x07 },
+	{ 0x0080, 0x01 },
+	{ 0x0081, 0x00 },
+	{ 0x0082, 0x00 },
+	{ 0x0089, 0x07 },
+	{ 0x008A, 0x01 },
+	{ 0x008B, 0x00 },
+	{ 0x008C, 0x00 },
+	{ 0x008E, 0x07 },
+	{ 0x008F, 0x01 },
+	{ 0x0090, 0x00 },
+	{ 0x0091, 0x00 },
+	{ 0x0098, 0x07 },
+	{ 0x0099, 0x01 },
+	{ 0x009A, 0x00 },
+	{ 0x009B, 0x00 },
+	{ 0x009D, 0x07 },
+	{ 0x009E, 0x01 },
+	{ 0x009F, 0x00 },
+	{ 0x00A0, 0x00 },
+	{ 0x00A7, 0x07 },
+	{ 0x00A8, 0x01 },
+	{ 0x00A9, 0x00 },
+	{ 0x00AA, 0x00 },
+	{ 0x00AC, 0x07 },
+	{ 0x00AD, 0x01 },
+	{ 0x00AE, 0x00 },
+	{ 0x00AF, 0x00 },
+	{ 0x00B6, 0xDB },
+	{ 0x00B7, 0x06 },
+	{ 0x00B9, 0x06 },
+	{ 0x00BA, 0x5E },
+	{ 0x00BB, 0x00 },
+	{ 0x00BC, 0x00 },
+	{ 0x00BD, 0x00 },
+	{ 0x00BE, 0x20 },
+	/* End configuration registers */
+
+	/* Start configuration postamble */
+	/*    Set device in Active mode */
+	{ 0x0006, 0x02 },
+	/* End configuration postamble */
+};
+
+/*
+ * Design Report
+ *
+ * Overview
+ * ========
+ * Part:               Si5332EFL Rev D
+ * Project File:       P:\Hardware\NT
+ * Adapters\NT400D13\design\Clock_syn_design\Si5332-GM2-RevD-1-Project_V5.slabtimeproj Design ID: 1
+ * Created By:         ClockBuilder Pro v4.5 [2022-08-23]
+ * Timestamp:          2022-10-11 15:44:24 GMT+02:00
+ *
+ * Design Rule Check
+ * =================
+ * Errors:
+ * - No errors
+ *
+ * Warnings:
+ * - OUT1 [156.25 MHz] and OUT2 [166.625 MHz] may have coupling [1]
+ * - OUT5 [166.625 MHz] and OUT6 [156.25 MHz] may have coupling [1]
+ *
+ * Footnotes:
+ * [1] To avoid coupling in outputs, Skyworks recommends the following:
+ *
+ * - Avoid adjacent frequency values that are close. CBPro uses an output's integration bandwidth
+ *   (IBW) to determine whether two adjacent frequencies are too close. An IBW of 20 MHz is used
+ *   for frequencies 80 MHz and larger. Lower frequencies will use IBW of OUT/4. CBPro will flag
+ *   fundamental coupling and coupling up to the fourth harmonic, where coupling
+ *   frequency = Absolute(OUTa*x - OUTb*y) for all combinations of x and y 1 through 4. If any one
+ *   of these values is less than or equal to the IBW, the output is flagged as having possible
+ *   coupling.
+ * - Adjacent frequency values that are integer multiples of one another are okay and these
+ *   outputs should be grouped accordingly.
+ * - Unused outputs can be used to separate clock outputs that might otherwise interfere
+ *   with one another.
+ *
+ * Skyworks recommends you validate your design's jitter performance using an Evaluation Board.
+ * You can request a custom phase noise report for your design from CBPro's design dashboard.
+ *
+ * Device Grade
+ * ============
+ * Maximum Output Frequency: 166.625 MHz
+ * Frequency Synthesis Mode: Fractional
+ * Frequency Plan Grade:     F
+ * Minimum Base OPN:         Si5332F*
+ *
+ * Base       Output Clock         Supported Frequency Synthesis Modes
+ * OPN Grade  Frequency Range      (Typical Jitter)
+ * ---------  ------------------  --------------------------------------------
+ * Si5332E    5 MHz to 334 MHz    Integer (~230 fs) and fractional (~500 fs)
+ * Si5332F*   5 MHz to 200 MHz    "
+ * Si5332G    5 MHz to 334 MHz    Integer only (~230 fs)
+ * Si5332H    5 MHz to 200 MHz    "
+ * Si5332L*   5 MHz to 334 MHz    Integer (~230 fs) and fractional (~500 fs)
+ *
+ * * Based on your calculated frequency plan, a Si5332F grade device is
+ * sufficient for your design. For more in-system configuration flexibility
+ * (higher frequencies and/or to enable fractional synthesis), consider
+ * selecting device grade Si5332E when specifying an ordering part number (OPN)
+ * for your application. See the datasheet Ordering Guide for more information.
+ *
+ * Design
+ * ======
+ * Base I2C Address: 0x6A
+ *
+ * Universal Hardware Input Pins:
+ *    INPUT1 (P10): None
+ *    INPUT2 (P19): None
+ *    INPUT3 (P20): None
+ *    INPUT4 (P31): None
+ *    INPUT5 (P32): None
+ *    INPUT6 (P36): None
+ *    INPUT7 (P37): None
+ *
+ * Inputs:
+ *    XAXB: 50 MHz
+ *          Crystal Mode
+ *  CLKIN2: Unused
+ *  CLKIN3: Unused
+ *
+ * Outputs:
+ *    OUT0: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT1: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT2: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT3: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT4: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT5: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT6: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT7: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *
+ * Frequency Plan
+ * ==============
+ * Fpfd = 50 MHz
+ * Fvco = 2.5 GHz
+ *
+ * P divider = 1
+ * M = 50
+ * N dividers:
+ *    N0:
+ *       Value: 15.0037509377344336... [ 15 + 5/1333 ]
+ *       OUT2: 166.625 MHz, Error: 0 ppm
+ *       OUT3: 166.625 MHz, Error: 0 ppm
+ *       OUT4: 166.625 MHz, Error: 0 ppm
+ *       OUT5: 166.625 MHz, Error: 0 ppm
+ *    N1:
+ *       Unused
+ *
+ * O dividers:
+ *    O0:
+ *       Value: 16
+ *       OUT0: 156.25 MHz, Error: 0 ppm
+ *       OUT1: 156.25 MHz, Error: 0 ppm
+ *       OUT6: 156.25 MHz, Error: 0 ppm
+ *       OUT7: 156.25 MHz, Error: 0 ppm
+ *    O1:
+ *       Unused
+ *    O2:
+ *       Unused
+ *    O3:
+ *       Unused
+ *    O4:
+ *       Unused
+ *
+ * R dividers:
+ *    R0 = 1
+ *    R1 = 1
+ *    R2 = 1
+ *    R3 = 1
+ *    R4 = 1
+ *    R5 = 1
+ *    R6 = 1
+ *    R7 = 1
+ *
+ * Estimated Power
+ * ===============
+ * Total Power: 233 mW, On Chip Power: 220 mW, Tj: 31 °C
+ *
+ *                    Frequency    Format   Voltage   Current     Power
+ *                  -----------  --------  --------  --------  --------
+ * VDD                                        1.8 V   30.7 mA     55 mW
+ * VDD Dig                                    1.8 V    7.0 mA     13 mW
+ * VDD Xtal                                   1.8 V    2.3 mA      4 mW
+ * VDDO0
+ *            OUT0   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ * VDDO1
+ *            OUT1   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ * VDDO2
+ *            OUT2  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ *            OUT3  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ * VDDO3
+ *            OUT4  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ *            OUT5  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ * VDDO4
+ *            OUT6   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ * VDDO5
+ *            OUT7   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ *                                                   --------  --------
+ *                                            Total  129.4 mA    233 mW
+ *
+ * Note:
+ *
+ * -Tj is junction temperature. Tj must be less than 125 °C (on Si5332-GM2 Revision D) for device
+ *  to comply with datasheet specifications. Tj = Ta + Theta_JA*On_Chip_Power.
+ * -Overall power includes on-chip power dissipation and adds differential load power dissipation
+ *  to estimate total power requirements.
+ * -Above are estimates only: power and temperature should be measured on your PCB.
+ *
+ * Settings
+ * ========
+ *
+ * Location    Setting Name     Decimal Value      Hex Value
+ * ----------  ---------------  -----------------  -----------------
+ * 0x17[7:0]   DESIGN_ID0       49                 0x31
+ * 0x18[7:0]   DESIGN_ID1       0                  0x00
+ * 0x19[7:0]   DESIGN_ID2       0                  0x00
+ * 0x1A[7:0]   DESIGN_ID3       0                  0x00
+ * 0x1B[7:0]   DESIGN_ID4       0                  0x00
+ * 0x1C[7:0]   DESIGN_ID5       0                  0x00
+ * 0x21[6:0]   I2C_ADDR         106                0x6A
+ * 0x24[1:0]   IMUX_SEL         1                  0x1
+ * 0x25[1:0]   OMUX0_SEL0       0                  0x0
+ * 0x25[6:4]   OMUX0_SEL1       0                  0x0
+ * 0x26[1:0]   OMUX1_SEL0       0                  0x0
+ * 0x26[6:4]   OMUX1_SEL1       0                  0x0
+ * 0x27[1:0]   OMUX2_SEL0       0                  0x0
+ * 0x27[6:4]   OMUX2_SEL1       5                  0x5
+ * 0x28[1:0]   OMUX3_SEL0       0                  0x0
+ * 0x28[6:4]   OMUX3_SEL1       5                  0x5
+ * 0x29[1:0]   OMUX4_SEL0       0                  0x0
+ * 0x29[6:4]   OMUX4_SEL1       0                  0x0
+ * 0x2A[1:0]   OMUX5_SEL0       0                  0x0
+ * 0x2A[6:4]   OMUX5_SEL1       0                  0x0
+ * 0x2B[7:0]   HSDIV0A_DIV      16                 0x10
+ * 0x36[14:0]  ID0A_INTG        1920               0x0780
+ * 0x38[14:0]  ID0A_RES         640                0x0280
+ * 0x3A[14:0]  ID0A_DEN         1333               0x0535
+ * 0x3C[0]     ID0A_SS_ENA      0                  0x0
+ * 0x3C[2:1]   ID0A_SS_MODE     0                  0x0
+ * 0x48[0]     ID0B_SS_ENA      0                  0x0
+ * 0x48[2:1]   ID0B_SS_MODE     0                  0x0
+ * 0x54[0]     ID1A_SS_ENA      0                  0x0
+ * 0x54[2:1]   ID1A_SS_MODE     0                  0x0
+ * 0x60[0]     ID1B_SS_ENA      0                  0x0
+ * 0x60[2:1]   ID1B_SS_MODE     0                  0x0
+ * 0x67[14:0]  IDPA_INTG        6400               0x1900
+ * 0x69[14:0]  IDPA_RES         0                  0x0000
+ * 0x6B[14:0]  IDPA_DEN         1                  0x0001
+ * 0x73[1:0]   CLKIN_2_CLK_SEL  0                  0x0
+ * 0x74[1:0]   CLKIN_3_CLK_SEL  0                  0x0
+ * 0x75[4:0]   P_VAL            1                  0x01
+ * 0x7A[3:0]   OUT0_MODE        7                  0x7
+ * 0x7B[5:0]   OUT0_DIV         1                  0x01
+ * 0x7C[2:0]   OUT0_SKEW        0                  0x0
+ * 0x7D[0]     OUT0_STOP_HIGHZ  0                  0x0
+ * 0x7D[5:4]   OUT0_CMOS_INV    0                  0x0
+ * 0x7D[6]     OUT0_DIFF_INV    0                  0x0
+ * 0x7F[3:0]   OUT1_MODE        7                  0x7
+ * 0x80[5:0]   OUT1_DIV         1                  0x01
+ * 0x81[2:0]   OUT1_SKEW        0                  0x0
+ * 0x82[0]     OUT1_STOP_HIGHZ  0                  0x0
+ * 0x82[5:4]   OUT1_CMOS_INV    0                  0x0
+ * 0x82[6]     OUT1_DIFF_INV    0                  0x0
+ * 0x89[3:0]   OUT2_MODE        7                  0x7
+ * 0x8A[5:0]   OUT2_DIV         1                  0x01
+ * 0x8B[2:0]   OUT2_SKEW        0                  0x0
+ * 0x8C[0]     OUT2_STOP_HIGHZ  0                  0x0
+ * 0x8C[5:4]   OUT2_CMOS_INV    0                  0x0
+ * 0x8C[6]     OUT2_DIFF_INV    0                  0x0
+ * 0x8E[3:0]   OUT3_MODE        7                  0x7
+ * 0x8F[5:0]   OUT3_DIV         1                  0x01
+ * 0x90[2:0]   OUT3_SKEW        0                  0x0
+ * 0x91[0]     OUT3_STOP_HIGHZ  0                  0x0
+ * 0x91[5:4]   OUT3_CMOS_INV    0                  0x0
+ * 0x91[6]     OUT3_DIFF_INV    0                  0x0
+ * 0x98[3:0]   OUT4_MODE        7                  0x7
+ * 0x99[5:0]   OUT4_DIV         1                  0x01
+ * 0x9A[2:0]   OUT4_SKEW        0                  0x0
+ * 0x9B[0]     OUT4_STOP_HIGHZ  0                  0x0
+ * 0x9B[5:4]   OUT4_CMOS_INV    0                  0x0
+ * 0x9B[6]     OUT4_DIFF_INV    0                  0x0
+ * 0x9D[3:0]   OUT5_MODE        7                  0x7
+ * 0x9E[5:0]   OUT5_DIV         1                  0x01
+ * 0x9F[2:0]   OUT5_SKEW        0                  0x0
+ * 0xA0[0]     OUT5_STOP_HIGHZ  0                  0x0
+ * 0xA0[5:4]   OUT5_CMOS_INV    0                  0x0
+ * 0xA0[6]     OUT5_DIFF_INV    0                  0x0
+ * 0xA7[3:0]   OUT6_MODE        7                  0x7
+ * 0xA8[5:0]   OUT6_DIV         1                  0x01
+ * 0xA9[2:0]   OUT6_SKEW        0                  0x0
+ * 0xAA[0]     OUT6_STOP_HIGHZ  0                  0x0
+ * 0xAA[5:4]   OUT6_CMOS_INV    0                  0x0
+ * 0xAA[6]     OUT6_DIFF_INV    0                  0x0
+ * 0xAC[3:0]   OUT7_MODE        7                  0x7
+ * 0xAD[5:0]   OUT7_DIV         1                  0x01
+ * 0xAE[2:0]   OUT7_SKEW        0                  0x0
+ * 0xAF[0]     OUT7_STOP_HIGHZ  0                  0x0
+ * 0xAF[5:4]   OUT7_CMOS_INV    0                  0x0
+ * 0xAF[6]     OUT7_DIFF_INV    0                  0x0
+ * 0xB6[0]     OUT0_OE          1                  0x1
+ * 0xB6[1]     OUT1_OE          1                  0x1
+ * 0xB6[3]     OUT2_OE          1                  0x1
+ * 0xB6[4]     OUT3_OE          1                  0x1
+ * 0xB6[6]     OUT4_OE          1                  0x1
+ * 0xB6[7]     OUT5_OE          1                  0x1
+ * 0xB7[1]     OUT6_OE          1                  0x1
+ * 0xB7[2]     OUT7_OE          1                  0x1
+ * 0xB9[0]     XOSC_DIS         0                  0x0
+ * 0xB9[1]     IBUF0_DIS        1                  0x1
+ * 0xB9[2]     IBUF1_DIS        1                  0x1
+ * 0xB9[3]     IMUX_DIS         0                  0x0
+ * 0xB9[4]     PDIV_DIS         0                  0x0
+ * 0xB9[5]     PLL_DIS          0                  0x0
+ * 0xBA[5]     ID0_DIS          0                  0x0
+ * 0xBA[6]     ID1_DIS          1                  0x1
+ * 0xBA[0]     HSDIV0_DIS       0                  0x0
+ * 0xBA[1]     HSDIV1_DIS       1                  0x1
+ * 0xBA[2]     HSDIV2_DIS       1                  0x1
+ * 0xBA[3]     HSDIV3_DIS       1                  0x1
+ * 0xBA[4]     HSDIV4_DIS       1                  0x1
+ * 0xBB[0]     OMUX0_DIS        0                  0x0
+ * 0xBB[1]     OMUX1_DIS        0                  0x0
+ * 0xBB[2]     OMUX2_DIS        0                  0x0
+ * 0xBB[3]     OMUX3_DIS        0                  0x0
+ * 0xBB[4]     OMUX4_DIS        0                  0x0
+ * 0xBB[5]     OMUX5_DIS        0                  0x0
+ * 0xBC[0]     OUT0_DIS         0                  0x0
+ * 0xBC[1]     OUT1_DIS         0                  0x0
+ * 0xBC[3]     OUT2_DIS         0                  0x0
+ * 0xBC[4]     OUT3_DIS         0                  0x0
+ * 0xBC[6]     OUT4_DIS         0                  0x0
+ * 0xBC[7]     OUT5_DIS         0                  0x0
+ * 0xBD[1]     OUT6_DIS         0                  0x0
+ * 0xBD[2]     OUT7_DIS         0                  0x0
+ * 0xBE[7:0]   PLL_MODE         32                 0x20
+ *
+ *
+ */
+
+#endif
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
index eeb4dffe25..53aa3c018e 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
@@ -46,5 +46,6 @@ typedef struct nt_i2cm nthw_i2cm_t;
 
 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);
+int nthw_i2cm_write16(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint16_t value);
 
 #endif	/* __NTHW_II2CM_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
new file mode 100644
index 0000000000..1e114886ca
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+#ifndef __NTHW_PCM_NT400DXX_H__
+#define __NTHW_PCM_NT400DXX_H__
+
+struct nthw_pcm_nt400_dxx {
+	int mn_module_minor_version;
+};
+
+typedef struct nthw_pcm_nt400_dxx nthw_pcm_nt400dxx_t;
+
+#endif  /* __NTHW_PCM_NT400DXX_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
index 968d7eb74a..753717ba8a 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
@@ -21,4 +21,40 @@ typedef struct nthw_pca9849 nthw_pca9849_t;
 
 int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel);
 
+/*
+ * Si5332 clock synthesizer
+ */
+
+struct nthw_si5332 {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_dev_address;
+	nthw_pca9849_t *mp_pca9849;
+	uint8_t m_mux_channel;
+};
+
+typedef struct nthw_si5332 nthw_si5332_t;
+
+nthw_si5332_t *nthw_si5332_new(void);
+int nthw_si5332_init(nthw_si5332_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel);
+bool nthw_si5332_clock_active(nthw_si5332_t *p);
+void nthw_si5332_write(nthw_si5332_t *p, uint8_t address, uint8_t value);
+
+/*
+ * Si5156 MEMS Super TCXO
+ */
+struct nthw_si5156 {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_dev_address;
+	nthw_pca9849_t *mp_pca9849;
+	uint8_t m_mux_channel;
+};
+
+typedef struct nthw_si5156 nthw_si5156_t;
+
+nthw_si5156_t *nthw_si5156_new(void);
+int nthw_si5156_init(nthw_si5156_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel);
+int nthw_si5156_write16(nthw_si5156_t *p, uint8_t address, uint16_t value);
+
 #endif	/* __NTHW_SI5332_SI5156_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
index 0a5add60e0..24118822c4 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
@@ -2,10 +2,113 @@
  * SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2023 Napatech A/S
  */
-
+#include "ntlog.h"
 #include "nthw_fpga.h"
 #include "ntnic_mod_reg.h"
-#include "ntlog.h"
+#include "NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h"
+
+static int nthw_fpga_nt400dxx_init_clock_synthesizers(struct fpga_info_s *p_fpga_info)
+{
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	int res = -1;
+
+	/* Clock synthesizer on address 0x6a on channel 2 */
+	p_fpga_info->mp_nthw_agx.p_si5332 = nthw_si5332_new();
+	res = nthw_si5332_init(p_fpga_info->mp_nthw_agx.p_si5332,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x6A,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			2);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: Failed to initialize Si5332 clock - res=%d",
+			p_adapter_id_str, __func__, res);
+		return res;
+	}
+
+	p_fpga_info->mp_nthw_agx.p_si5156 = nthw_si5156_new();
+	res = nthw_si5156_init(p_fpga_info->mp_nthw_agx.p_si5156,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x60,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			2);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: Failed to initialize Si5156 clock - res=%d",
+			p_adapter_id_str, __func__, res);
+		return res;
+	}
+
+	if (nthw_si5332_clock_active(p_fpga_info->mp_nthw_agx.p_si5332)) {
+		NT_LOG(INF,
+			NTHW,
+			"%s: Fpga clock already active, skipping clock initialisation.",
+			p_adapter_id_str);
+
+	} else {
+		NT_LOG(INF, NTHW,
+			"%s: Fpga clock not active, performing full clock initialisation.",
+			p_adapter_id_str);
+
+		for (int i = 0; i < SI5332_GM2_REVD_REG_CONFIG_NUM_REGS; i++) {
+			nthw_si5332_write(p_fpga_info->mp_nthw_agx.p_si5332,
+				(uint8_t)si5332_gm2_revd_registers[i].address,
+				(uint8_t)si5332_gm2_revd_registers[i].value);
+		}
+	}
+
+	/*
+	 * TCXO capable PCM version if minor version >= 3
+	 * Unfortunately, the module version is not readily
+	 * available in the FPGA_400D1x class.
+	 */
+	bool tcxo_capable = p_fpga_info->mp_nthw_agx.p_pcm->mn_module_minor_version >= 3;
+
+	/*
+	 * This method of determining the presence of a TCXO
+	 *  will only work until non SI5156 equipped boards
+	 *  use the vacant I2C address for something else...
+	 *
+	 * There's no other way, there's no other way
+	 * All that you can do is watch them play
+	 * Clean-up when GA HW is readily available
+	 */
+	if (nthw_si5156_write16(p_fpga_info->mp_nthw_agx.p_si5156, 0x1, 0x0400) != 0) {
+		p_fpga_info->mp_nthw_agx.tcxo_capable = false;
+		p_fpga_info->mp_nthw_agx.tcxo_present = false;
+
+	} else {
+		p_fpga_info->mp_nthw_agx.tcxo_capable = tcxo_capable;
+		p_fpga_info->mp_nthw_agx.tcxo_present = true;
+	}
+
+	return 0;
+}
+
+static int nthw_fpga_nt400dxx_init_sub_systems(struct fpga_info_s *p_fpga_info)
+{
+	int res;
+	NT_LOG(INF, NTHW, "%s: Initializing NT4GA subsystems...", p_fpga_info->mp_adapter_id_str);
+
+	/* RAB subsystem */
+	NT_LOG(DBG, NTHW, "%s: Initializing RAB subsystem: flush", p_fpga_info->mp_adapter_id_str);
+	res = nthw_rac_rab_flush(p_fpga_info->mp_nthw_rac);
+
+	if (res)
+		return res;
+
+	/* clock synthesizer subsystem */
+	NT_LOG(DBG,
+		NTHW,
+		"%s: Initializing clock synthesizer subsystem",
+		p_fpga_info->mp_adapter_id_str);
+	res = nthw_fpga_nt400dxx_init_clock_synthesizers(p_fpga_info);
+
+	if (res)
+		return res;
+
+	return 0;
+}
 
 static int nthw_fpga_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 {
@@ -61,6 +164,14 @@ static int nthw_fpga_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 		return res;
 	}
 
+	res = nthw_fpga_nt400dxx_init_sub_systems(p_fpga_info);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: FPGA=%04d Failed to init subsystems res=%d",
+		p_adapter_id_str, __func__, p_fpga_info->n_fpga_prod_id, res);
+		return res;
+	}
+
 	res = rst_nt400dxx_ops->nthw_fpga_rst_nt400dxx_reset(p_fpga_info);
 
 	if (res) {
diff --git a/drivers/net/ntnic/nthw/core/nthw_i2cm.c b/drivers/net/ntnic/nthw/core/nthw_i2cm.c
index b5f8e299ff..f7500b2e93 100644
--- a/drivers/net/ntnic/nthw/core/nthw_i2cm.c
+++ b/drivers/net/ntnic/nthw/core/nthw_i2cm.c
@@ -73,6 +73,47 @@ static int nthw_i2cm_write_internal(nthw_i2cm_t *p, uint8_t value)
 	return 0;
 }
 
+static int nthw_i2cm_write16_internal(nthw_i2cm_t *p, uint16_t value)
+{
+	const uint8_t count = 1;
+
+	for (int8_t i = count; i >= 0; i--) {
+		uint8_t byte_value = (uint8_t)(value >> ((uint8_t)i * 8)) & 0xffU;
+
+		/* Write data to data register */
+		nthw_field_set_val_flush32(p->mp_fld_data_data, byte_value);
+
+		if (i == 0) {
+			nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status,
+				NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK);
+
+		} else {
+			nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, NT_I2C_CMD_WR);
+		}
+
+		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)
 {
@@ -190,3 +231,19 @@ int nthw_i2cm_write(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t
 
 	return 0;
 }
+
+int nthw_i2cm_write16(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint16_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_write16_internal(p, value);
+
+	if (status != 0)
+		return status;
+
+	return 0;
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
index b5560e2990..b4a7b57bcb 100644
--- a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
+++ b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
@@ -4,6 +4,7 @@
  */
 
 #include <pthread.h>
+#include "generic/rte_spinlock.h"
 #include "nt_util.h"
 #include "ntlog.h"
 
@@ -29,3 +30,95 @@ int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel)
 
 	return 0;
 }
+
+/*
+ * Si5332 clock synthesizer
+ */
+
+nthw_si5332_t *nthw_si5332_new(void)
+{
+	nthw_si5332_t *p = malloc(sizeof(nthw_si5332_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_si5332_t));
+
+	return p;
+}
+
+int nthw_si5332_init(nthw_si5332_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->m_mux_channel = mux_channel;
+	p->mp_pca9849 = pca9849;
+	return 0;
+}
+
+bool nthw_si5332_clock_active(nthw_si5332_t *p)
+{
+	uint8_t ena1, ena2;
+
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_pca9849, p->m_mux_channel);
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, 0xB6, &ena1);
+	NT_LOG(DBG, NTHW, "Read %x from i2c dev 0x6A, reg 0xB6", ena1);
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, 0xB7, &ena2);
+	NT_LOG(DBG, NTHW, "Read %x from i2c dev 0x6A, reg 0xB7", ena2);
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+
+	return ((ena1 & 0xDB) != 0) || ((ena2 & 0x06) != 0);
+}
+
+void nthw_si5332_write(nthw_si5332_t *p, uint8_t address, uint8_t value)
+{
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_pca9849, p->m_mux_channel);
+	nthw_i2cm_write(p->mp_nt_i2cm, p->m_dev_address, address, value);
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+}
+
+/*
+ * Si5156 MEMS Super TCXO
+ */
+
+nthw_si5156_t *nthw_si5156_new(void)
+{
+	nthw_si5156_t *p = malloc(sizeof(nthw_si5156_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_si5156_t));
+
+	return p;
+}
+
+int nthw_si5156_init(nthw_si5156_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->m_mux_channel = mux_channel;
+	p->mp_pca9849 = pca9849;
+	return 0;
+}
+
+int nthw_si5156_write16(nthw_si5156_t *p, uint8_t address, uint16_t value)
+{
+	int res = 0;
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	res = nthw_pca9849_set_channel(p->mp_pca9849, p->m_mux_channel);
+
+	if (res)
+		goto ERROR;
+
+	res = nthw_i2cm_write16(p->mp_nt_i2cm, p->m_dev_address, address, value);
+
+	if (res)
+		goto ERROR;
+
+ERROR:
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+	return res;
+}
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index a3c54846f5..1d5b750db9 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -12,8 +12,8 @@
 #include "nthw_si5332_si5156.h"
 #include "nthw_pcal6416a.h"
 #include "nthw_pca9532.h"
-#include "nthw_phy_tile.h"
 #include "nthw_rpf.h"
+#include "nthw_pcm_nt400dxx.h"
 #include "nthw_phy_tile.h"
 
 /*
@@ -24,8 +24,13 @@ typedef struct nthw_agx_s {
 	nthw_pca9849_t *p_pca9849;
 	nthw_pcal6416a_t *p_io_nim;	/* PCAL6416A I/O expander for controlling TS */
 	nthw_pca9532_t *p_pca9532_led;
+	nthw_si5332_t *p_si5332;
+	nthw_si5156_t *p_si5156;
+	nthw_pcm_nt400dxx_t *p_pcm;
 	nthw_phy_tile_t *p_phy_tile;
 	nthw_rpf_t *p_rpf;
+	bool tcxo_present;
+	bool tcxo_capable;
 } nthw_agx_t;
 
 typedef enum nt_meta_port_type_e {
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 21/32] net/ntnic: add nt400d13 pcm init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (19 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 20/32] net/ntnic: add clock init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 22/32] net/ntnic: add HIF clock test Serhii Iliushyk
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Initialize and create PCM for FPGA and HIF modules

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/meson.build                 |  1 +
 .../nthw/core/include/nthw_pcm_nt400dxx.h     | 24 +++++++-
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 18 ++++++
 .../net/ntnic/nthw/core/nthw_pcm_nt400dxx.c   | 56 +++++++++++++++++++
 drivers/net/ntnic/nthw/nthw_drv.h             |  1 +
 5 files changed, 99 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c

diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index aec7b52714..b9ac069bcc 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -61,6 +61,7 @@ sources = files(
         'nthw/core/nthw_pcie3.c',
         'nthw/core/nthw_pca9532.c',
         'nthw/core/nthw_pcal6416a.c',
+        'nthw/core/nthw_pcm_nt400dxx.c',
         'nthw/core/nthw_phy_tile.c',
         'nthw/core/nthw_si5332_si5156.c',
         'nthw/core/nthw_rpf.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
index 1e114886ca..23865f466b 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
@@ -5,10 +5,32 @@
 #ifndef __NTHW_PCM_NT400DXX_H__
 #define __NTHW_PCM_NT400DXX_H__
 
+#include "nthw_fpga_model.h"
+
 struct nthw_pcm_nt400_dxx {
+	nthw_fpga_t *mp_fpga;
+	nthw_module_t *mp_mod_pcm;
+	int mn_instance;
+
+	int mn_module_major_version;
 	int mn_module_minor_version;
+
+	nthw_register_t *mp_reg_ctrl;
+	nthw_field_t *mp_fld_ctrl_ts_pll_recal;	/* Dunite HW version 3 */
+	nthw_field_t *mp_fld_ctrl_ts_clksel;
+	nthw_field_t *mp_fld_ctrl_ts_pll_rst;
+
+	nthw_register_t *mp_reg_stat;
+	nthw_field_t *mp_fld_stat_ts_pll_locked;
+
+	nthw_register_t *mp_reg_latch;
+	nthw_field_t *mp_fld_latch_ts_pll_locked;
 };
 
 typedef struct nthw_pcm_nt400_dxx nthw_pcm_nt400dxx_t;
+typedef struct nthw_pcm_nt400_dxx nthw_pcm_nt400_dxx;
+
+nthw_pcm_nt400dxx_t *nthw_pcm_nt400dxx_new(void);
+int nthw_pcm_nt400dxx_init(nthw_pcm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_instance);
 
-#endif  /* __NTHW_PCM_NT400DXX_H__ */
+#endif	/* __NTHW_PCM_NT400DXX_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index e0e4bc0861..1d93474cff 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -13,6 +13,24 @@
 static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 {
 	assert(p_fpga_info);
+	int res = -1;
+	nthw_fpga_t *p_fpga = NULL;
+
+	p_fpga = p_fpga_info->mp_fpga;
+
+	nthw_hif_t *p_nthw_hif = nthw_hif_new();
+	res = nthw_hif_init(p_nthw_hif, p_fpga, 0);
+
+	if (res == 0)
+		NT_LOG(DBG, NTHW, "%s: Hif module found", p_fpga_info->mp_adapter_id_str);
+
+	/* Create PCM */
+	p_fpga_info->mp_nthw_agx.p_pcm = nthw_pcm_nt400dxx_new();
+	res = nthw_pcm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_pcm, p_fpga, 0);
+
+	if (res != 0)
+		return res;
+
 	return 0;
 }
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c b/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
new file mode 100644
index 0000000000..f32a277e86
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
@@ -0,0 +1,56 @@
+/*
+ * 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_fpga.h"
+
+#include "nthw_pcm_nt400dxx.h"
+
+nthw_pcm_nt400dxx_t *nthw_pcm_nt400dxx_new(void)
+{
+	nthw_pcm_nt400dxx_t *p = malloc(sizeof(nthw_pcm_nt400dxx_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_pcm_nt400dxx_t));
+
+	return p;
+}
+
+int nthw_pcm_nt400dxx_init(nthw_pcm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_instance)
+{
+	nthw_module_t *p_mod = nthw_fpga_query_module(p_fpga, MOD_PCM_NT400DXX, n_instance);
+
+	if (p == NULL)
+		return p_mod == NULL ? -1 : 0;
+
+	if (p_mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: PCM_NT400DXX %d: no such instance",
+			p->mp_fpga->p_fpga_info->mp_adapter_id_str, p->mn_instance);
+		return -1;
+	}
+
+	p->mp_mod_pcm = p_mod;
+
+	p->mp_fpga = p_fpga;
+	p->mn_instance = n_instance;
+
+	p->mn_module_major_version = nthw_module_get_major_version(p->mp_mod_pcm);
+	p->mn_module_minor_version = nthw_module_get_minor_version(p->mp_mod_pcm);
+
+	p->mp_reg_ctrl = nthw_module_get_register(p->mp_mod_pcm, PCM_NT400DXX_CTRL);
+	p->mp_fld_ctrl_ts_pll_recal =
+		nthw_register_query_field(p->mp_reg_ctrl, PCM_NT400DXX_CTRL_TS_PLL_RECAL);
+
+	p->mp_reg_stat = nthw_module_get_register(p->mp_mod_pcm, PCM_NT400DXX_STAT);
+	p->mp_fld_stat_ts_pll_locked =
+		nthw_register_get_field(p->mp_reg_stat, PCM_NT400DXX_STAT_TS_PLL_LOCKED);
+
+	p->mp_reg_latch = nthw_module_get_register(p->mp_mod_pcm, PCM_NT400DXX_LATCH);
+	p->mp_fld_latch_ts_pll_locked =
+		nthw_register_get_field(p->mp_reg_latch, PCM_NT400DXX_LATCH_TS_PLL_LOCKED);
+
+	return 0;
+}
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index 1d5b750db9..955d0a37b0 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -15,6 +15,7 @@
 #include "nthw_rpf.h"
 #include "nthw_pcm_nt400dxx.h"
 #include "nthw_phy_tile.h"
+#include "nthw_pcm_nt400dxx.h"
 
 /*
  * Structs for controlling Agilex based NT400DXX adapter
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 22/32] net/ntnic: add HIF clock test
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (20 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 21/32] net/ntnic: add nt400d13 pcm init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 23/32] net/ntnic: add nt400d13 PRM module init Serhii Iliushyk
                   ` (11 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Add HIF clock test with write/read verification.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../net/ntnic/nthw/core/include/nthw_hif.h    |  3 +
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 20 +++++
 drivers/net/ntnic/nthw/core/nthw_hif.c        | 82 +++++++++++++++++++
 3 files changed, 105 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_hif.h b/drivers/net/ntnic/nthw/core/include/nthw_hif.h
index c8f4669f83..deb9ed04e8 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_hif.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_hif.h
@@ -148,4 +148,7 @@ int nthw_hif_get_stat_rate(nthw_hif_t *p, uint64_t *p_pci_rx_rate, uint64_t *p_p
 
 int nthw_hif_end_point_counters_sample(nthw_hif_t *p, struct nthw_hif_end_point_counters *epc);
 
+int nthw_hif_read_test_reg(nthw_hif_t *p, uint8_t test_reg, uint32_t *p_value);
+int nthw_hif_write_test_reg(nthw_hif_t *p, uint8_t test_reg, uint32_t value);
+
 #endif	/* __NTHW_HIF_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 1d93474cff..60e7714283 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -24,6 +24,26 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 	if (res == 0)
 		NT_LOG(DBG, NTHW, "%s: Hif module found", p_fpga_info->mp_adapter_id_str);
 
+	/* (A) Test HIF clock is running by performing simple write/read test of HIF registers */
+	const uint32_t test_pattern[2] = { 0x11223344, 0x55667788 };
+
+	for (uint8_t i = 0; i < 2; ++i) {
+		uint32_t test_data = 0;
+		nthw_hif_write_test_reg(p_nthw_hif, i, test_pattern[i]);
+		nthw_hif_read_test_reg(p_nthw_hif, i, &test_data);
+
+		if (test_data != test_pattern[i]) {
+			NT_LOG(ERR,
+				NTHW,
+				"%s: %s: Test sys 250 clock failed",
+				p_fpga_info->mp_adapter_id_str,
+				__func__);
+			return -1;
+		}
+	}
+
+	nthw_hif_delete(p_nthw_hif);
+
 	/* Create PCM */
 	p_fpga_info->mp_nthw_agx.p_pcm = nthw_pcm_nt400dxx_new();
 	res = nthw_pcm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_pcm, p_fpga, 0);
diff --git a/drivers/net/ntnic/nthw/core/nthw_hif.c b/drivers/net/ntnic/nthw/core/nthw_hif.c
index 9f699e4f94..92a2348bbb 100644
--- a/drivers/net/ntnic/nthw/core/nthw_hif.c
+++ b/drivers/net/ntnic/nthw/core/nthw_hif.c
@@ -298,3 +298,85 @@ int nthw_hif_end_point_counters_sample(nthw_hif_t *p, struct nthw_hif_end_point_
 
 	return 0;
 }
+
+int nthw_hif_read_test_reg(nthw_hif_t *p, uint8_t test_reg, uint32_t *p_value)
+{
+	uint32_t data;
+
+	switch (test_reg) {
+	case 0:
+		data = nthw_field_get_updated(p->mp_fld_pci_test0);
+		break;
+
+	case 1:
+		data = nthw_field_get_updated(p->mp_fld_pci_test1);
+		break;
+
+	case 2:
+		if (p->mp_fld_pci_test2)
+			data = nthw_field_get_updated(p->mp_fld_pci_test2);
+
+		else
+			return -1;
+
+		break;
+
+	case 3:
+		if (p->mp_fld_pci_test3)
+			data = nthw_field_get_updated(p->mp_fld_pci_test3);
+
+		else
+			return -1;
+
+		break;
+
+	default:
+		assert(false);
+		return -1;
+	}
+
+	if (p_value)
+		*p_value = data;
+
+	else
+		return -1;
+
+	return 0;
+}
+
+int nthw_hif_write_test_reg(nthw_hif_t *p, uint8_t test_reg, uint32_t value)
+{
+	switch (test_reg) {
+	case 0:
+		nthw_field_set_val_flush32(p->mp_fld_pci_test0, value);
+		break;
+
+	case 1:
+		nthw_field_set_val_flush32(p->mp_fld_pci_test1, value);
+		break;
+
+	case 2:
+		if (p->mp_fld_pci_test2)
+			nthw_field_set_val_flush32(p->mp_fld_pci_test2, value);
+
+		else
+			return -1;
+
+		break;
+
+	case 3:
+		if (p->mp_fld_pci_test3)
+			nthw_field_set_val_flush32(p->mp_fld_pci_test3, value);
+
+		else
+			return -1;
+
+		break;
+
+	default:
+		assert(false);
+		return -1;
+	}
+
+	return 0;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 23/32] net/ntnic: add nt400d13 PRM module init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (21 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 22/32] net/ntnic: add HIF clock test Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 24/32] net/ntnic: add nt400d13 PRM module reset Serhii Iliushyk
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Initialize RAB0 and create PRM for FPGA.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/meson.build                 |  1 +
 .../nthw/core/include/nthw_prm_nt400dxx.h     | 30 +++++++++++++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 11 +++++
 .../net/ntnic/nthw/core/nthw_prm_nt400dxx.c   | 43 +++++++++++++++++++
 drivers/net/ntnic/nthw/nthw_drv.h             |  2 +
 5 files changed, 87 insertions(+)
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c

diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index b9ac069bcc..9885d4efbf 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -63,6 +63,7 @@ sources = files(
         'nthw/core/nthw_pcal6416a.c',
         'nthw/core/nthw_pcm_nt400dxx.c',
         'nthw/core/nthw_phy_tile.c',
+        'nthw/core/nthw_prm_nt400dxx.c',
         'nthw/core/nthw_si5332_si5156.c',
         'nthw/core/nthw_rpf.c',
         'nthw/core/nthw_rmc.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h b/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
new file mode 100644
index 0000000000..09bfd79249
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef NTHW_PRM_NT400DXX_H_
+#define NTHW_PRM_NT400DXX_H_
+
+#include <stdint.h>
+
+#include "nthw_fpga_model.h"
+
+struct nt_prm_nt400dxx {
+	nthw_fpga_t *mp_fpga;
+	nthw_module_t *mp_mod_prm;
+
+	int mn_instance;
+
+	nthw_register_t *mp_reg_rst;
+	nthw_field_t *mp_fld_rst_periph;
+	nthw_field_t *mp_fld_rst_platform;
+};
+
+typedef struct nt_prm_nt400dxx nthw_prm_nt400dxx_t;
+typedef struct nt_prm_nt400dxx nt_prm_nt400dxx;
+
+nthw_prm_nt400dxx_t *nthw_prm_nt400dxx_new(void);
+int nthw_prm_nt400dxx_init(nthw_prm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_instance);
+
+#endif	/* NTHW_PRM_NT400DXX_H_ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 60e7714283..4d74db88de 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -44,6 +44,17 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 
 	nthw_hif_delete(p_nthw_hif);
 
+	/* (b) Init RAB0 */
+	nthw_rac_rab_init(p_fpga_info->mp_nthw_rac, 0x7);
+	nthw_rac_rab_init(p_fpga_info->mp_nthw_rac, 0x6);
+
+	/* Create PRM */
+	p_fpga_info->mp_nthw_agx.p_prm = nthw_prm_nt400dxx_new();
+	res = nthw_prm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_prm, p_fpga, 0);
+
+	if (res != 0)
+		return res;
+
 	/* Create PCM */
 	p_fpga_info->mp_nthw_agx.p_pcm = nthw_pcm_nt400dxx_new();
 	res = nthw_pcm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_pcm, p_fpga, 0);
diff --git a/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c b/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
new file mode 100644
index 0000000000..b1910fdbd5
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
@@ -0,0 +1,43 @@
+/*
+ * 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_prm_nt400dxx.h"
+
+nthw_prm_nt400dxx_t *nthw_prm_nt400dxx_new(void)
+{
+	nthw_prm_nt400dxx_t *p = malloc(sizeof(nthw_prm_nt400dxx_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_prm_nt400dxx_t));
+
+	return p;
+}
+
+int nthw_prm_nt400dxx_init(nthw_prm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_instance)
+{
+	nthw_module_t *p_mod = nthw_fpga_query_module(p_fpga, MOD_PRM_NT400DXX, n_instance);
+
+	if (p == NULL)
+		return p_mod == NULL ? -1 : 0;
+
+	if (p_mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: PRM_NT400DXX %d: no such instance",
+			p->mp_fpga->p_fpga_info->mp_adapter_id_str, p->mn_instance);
+		return -1;
+	}
+
+	p->mp_mod_prm = p_mod;
+
+	p->mp_fpga = p_fpga;
+	p->mn_instance = n_instance;
+
+	p->mp_reg_rst = nthw_module_get_register(p->mp_mod_prm, PRM_NT400DXX_RST);
+	p->mp_fld_rst_periph = nthw_register_get_field(p->mp_reg_rst, PRM_NT400DXX_RST_PERIPH);
+	p->mp_fld_rst_platform = nthw_register_get_field(p->mp_reg_rst, PRM_NT400DXX_RST_PLATFORM);
+	return 0;
+}
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index 955d0a37b0..ecd3bb9cc4 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -15,6 +15,7 @@
 #include "nthw_rpf.h"
 #include "nthw_pcm_nt400dxx.h"
 #include "nthw_phy_tile.h"
+#include "nthw_prm_nt400dxx.h"
 #include "nthw_pcm_nt400dxx.h"
 
 /*
@@ -27,6 +28,7 @@ typedef struct nthw_agx_s {
 	nthw_pca9532_t *p_pca9532_led;
 	nthw_si5332_t *p_si5332;
 	nthw_si5156_t *p_si5156;
+	nthw_prm_nt400dxx_t *p_prm;
 	nthw_pcm_nt400dxx_t *p_pcm;
 	nthw_phy_tile_t *p_phy_tile;
 	nthw_rpf_t *p_rpf;
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 24/32] net/ntnic: add nt400d13 PRM module reset
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (22 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 23/32] net/ntnic: add nt400d13 PRM module init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA Serhii Iliushyk
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Reset platform and peripherals for PRM initialization.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h |  2 ++
 .../core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c    | 13 +++++++++++++
 drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c     | 12 ++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h b/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
index 09bfd79249..53692145b7 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
@@ -26,5 +26,7 @@ typedef struct nt_prm_nt400dxx nt_prm_nt400dxx;
 
 nthw_prm_nt400dxx_t *nthw_prm_nt400dxx_new(void);
 int nthw_prm_nt400dxx_init(nthw_prm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_instance);
+void nthw_prm_nt400dxx_periph_rst(nthw_prm_nt400dxx_t *p, uint32_t val);
+void nthw_prm_nt400dxx_platform_rst(nthw_prm_nt400dxx_t *p, uint32_t val);
 
 #endif	/* NTHW_PRM_NT400DXX_H_ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 4d74db88de..ff29101e61 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -52,6 +52,19 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 	p_fpga_info->mp_nthw_agx.p_prm = nthw_prm_nt400dxx_new();
 	res = nthw_prm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_prm, p_fpga, 0);
 
+	if (res != 0)
+		return res;
+
+	/* (b1) Reset platform. It is released later */
+	nthw_prm_nt400dxx_platform_rst(p_fpga_info->mp_nthw_agx.p_prm, 1);
+	nt_os_wait_usec(10000);
+
+	/* (C) Reset peripherals and release the reset */
+	nthw_prm_nt400dxx_periph_rst(p_fpga_info->mp_nthw_agx.p_prm, 1);
+	nt_os_wait_usec(10000);
+	nthw_prm_nt400dxx_periph_rst(p_fpga_info->mp_nthw_agx.p_prm, 0);
+	nt_os_wait_usec(10000);
+
 	if (res != 0)
 		return res;
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c b/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
index b1910fdbd5..286bda43f8 100644
--- a/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
@@ -41,3 +41,15 @@ int nthw_prm_nt400dxx_init(nthw_prm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_in
 	p->mp_fld_rst_platform = nthw_register_get_field(p->mp_reg_rst, PRM_NT400DXX_RST_PLATFORM);
 	return 0;
 }
+
+void nthw_prm_nt400dxx_periph_rst(nthw_prm_nt400dxx_t *p, uint32_t val)
+{
+	nthw_field_update_register(p->mp_fld_rst_periph);
+	nthw_field_set_val_flush32(p->mp_fld_rst_periph, val);
+}
+
+void nthw_prm_nt400dxx_platform_rst(nthw_prm_nt400dxx_t *p, uint32_t val)
+{
+	nthw_field_update_register(p->mp_fld_rst_platform);
+	nthw_field_set_val_flush32(p->mp_fld_rst_platform, val);
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (23 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 24/32] net/ntnic: add nt400d13 PRM module reset Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-22 19:21   ` Stephen Hemminger
  2025-02-20 22:03 ` [PATCH v1 26/32] net/ntnic: add i2cm init Serhii Iliushyk
                   ` (8 subsequent siblings)
  33 siblings, 1 reply; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

- Implement nthw_spi_v3 module with initialization, transfer, and
utility functions.
- Add nthw_spim and nthw_spis modules for SPI primary and secondary
interfaces.
- Include SPI v3 header files and update meson build configuration.
- Implement AVR probe function to retrieve and log AVR information.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/meson.build                 |   3 +
 .../net/ntnic/nthw/core/include/nthw_fpga.h   |   2 +
 .../net/ntnic/nthw/core/include/nthw_spi_v3.h | 107 +++++
 .../net/ntnic/nthw/core/include/nthw_spim.h   |  58 +++
 .../net/ntnic/nthw/core/include/nthw_spis.h   |  63 +++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |   2 +
 drivers/net/ntnic/nthw/core/nthw_fpga.c       | 444 ++++++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_spi_v3.c     | 358 ++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_spim.c       | 113 +++++
 drivers/net/ntnic/nthw/core/nthw_spis.c       | 121 +++++
 10 files changed, 1271 insertions(+)
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spim.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spis.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_spi_v3.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_spim.c
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_spis.c

diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 9885d4efbf..7e326a3e1d 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -69,6 +69,9 @@ sources = files(
         'nthw/core/nthw_rmc.c',
         'nthw/core/nthw_sdc.c',
         'nthw/core/nthw_si5340.c',
+        'nthw/core/nthw_spim.c',
+        'nthw/core/nthw_spis.c',
+        'nthw/core/nthw_spi_v3.c',
         'nthw/stat/nthw_stat.c',
         'nthw/flow_api/flow_api.c',
         'nthw/flow_api/flow_group.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_fpga.h b/drivers/net/ntnic/nthw/core/include/nthw_fpga.h
index 8b1d548a25..418aea8277 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_fpga.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_fpga.h
@@ -18,6 +18,8 @@ int nthw_fpga_shutdown(struct fpga_info_s *p_fpga_info);
 
 int nthw_fpga_get_param_info(struct fpga_info_s *p_fpga_info, nthw_fpga_t *p_fpga);
 
+int nthw_fpga_avr_probe(nthw_fpga_t *p_fpga, const int n_instance_no);
+
 int nthw_fpga_iic_scan(nthw_fpga_t *p_fpga, const int n_instance_no_begin,
 	const int n_instance_no_end);
 
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h b/drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h
new file mode 100644
index 0000000000..66b1f7f45d
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h
@@ -0,0 +1,107 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NT4GA_SPI_V3__
+#define __NT4GA_SPI_V3__
+
+#include "nthw_spis.h"
+#include "nthw_spim.h"
+
+/* Must include v1.x series. The first v1.0a only had 248 bytes of storage. v2.0x have 255 */
+#define MAX_AVR_CONTAINER_SIZE (248)
+
+enum avr_opcodes {
+	__AVR_OP_NOP = 0,	/* v2 NOP command */
+	/* version handlers */
+	AVR_OP_VERSION = 1,
+	AVR_OP_SPI_VERSION = 2,	/* v2.0+ command Get protocol version */
+	AVR_OP_SYSINFO = 3,
+	/* Ping handlers */
+	AVR_OP_PING = 4,
+	AVR_OP_PING_DELAY = 5,
+	/* i2c handlers */
+	AVR_OP_I2C_READ = 9,
+	AVR_OP_I2C_WRITE = 10,
+	AVR_OP_I2C_RANDOM_READ = 11,
+	/* VPD handlers */
+	AVR_OP_VPD_READ = 19,
+	AVR_OP_VPD_WRITE = 20,
+	/* SENSOR handlers */
+	AVR_OP_SENSOR_FETCH = 28,
+	/* The following command are only relevant to V3 */
+	AVR_OP_SENSOR_MON_CONTROL = 42,
+	AVR_OP_SENSOR_MON_SETUP = 43,
+	/* special version handler */
+	AVR_OP_SYSINFO_2 = 62,
+};
+
+#define GEN2_AVR_IDENT_SIZE (20)
+#define GEN2_AVR_VERSION_SIZE (50)
+
+#define GEN2_PN_SIZE (13)
+#define GEN2_PBA_SIZE (16)
+#define GEN2_SN_SIZE (10)
+#define GEN2_BNAME_SIZE (14)
+#define GEN2_PLATFORM_SIZE (72)
+#define GEN2_VPD_SIZE_TOTAL                                                                       \
+	(1 + GEN2_PN_SIZE + GEN2_PBA_SIZE + GEN2_SN_SIZE + GEN2_BNAME_SIZE + GEN2_PLATFORM_SIZE + \
+	 2)
+
+typedef struct vpd_eeprom_s {
+	uint8_t psu_hw_version;	/* Hw revision - MUST NEVER ne overwritten. */
+	/* Vital Product Data: P/N   (13bytes ascii 0-9) */
+	uint8_t vpd_pn[GEN2_PN_SIZE];
+	/* Vital Product Data: PBA   (16bytes ascii 0-9) */
+	uint8_t vpd_pba[GEN2_PBA_SIZE];
+	/* Vital Product Data: S/N   (10bytes ascii 0-9) */
+	uint8_t vpd_sn[GEN2_SN_SIZE];
+	/* Vital Product Data: Board Name (10bytes ascii) (e.g. "ntmainb1e2" or "ntfront20b1") */
+	uint8_t vpd_board_name[GEN2_BNAME_SIZE];
+	/*
+	 * Vital Product Data: Other (72bytes of MAC addresses or other stuff.. (gives up to 12 mac
+	 * addresses)
+	 */
+	uint8_t vpd_platform_section[GEN2_PLATFORM_SIZE];
+	/* CRC16 checksum of all of above. This field is not included in the checksum */
+	uint16_t crc16;
+} vpd_eeprom_t;
+
+typedef struct {
+	uint8_t psu_hw_revision;
+	char board_type[GEN2_BNAME_SIZE + 1];
+	char product_id[GEN2_PN_SIZE + 1];
+	char pba_id[GEN2_PBA_SIZE + 1];
+	char serial_number[GEN2_SN_SIZE + 1];
+	uint8_t product_family;
+	uint32_t feature_mask;
+	uint32_t invfeature_mask;
+	uint8_t no_of_macs;
+	uint8_t mac_address[6];
+	uint16_t custom_id;
+	uint8_t user_id[8];
+} board_info_t;
+
+struct tx_rx_buf {
+	uint16_t size;
+	void *p_buf;
+};
+
+struct nthw_spi_v3 {
+	int m_time_out;
+	int mn_instance_no;
+	nthw_spim_t *mp_spim_mod;
+	nthw_spis_t *mp_spis_mod;
+};
+
+typedef struct nthw_spi_v3 nthw_spi_v3_t;
+typedef struct nthw_spi_v3 nthw_spi_v3;
+
+nthw_spi_v3_t *nthw_spi_v3_new(void);
+int nthw_spi_v3_init(nthw_spi_v3_t *p, nthw_fpga_t *p_fpga, int n_instance_no);
+
+int nthw_spi_v3_transfer(nthw_spi_v3_t *p, uint16_t opcode, struct tx_rx_buf *tx_buf,
+	struct tx_rx_buf *rx_buf);
+
+#endif	/* __NT4GA_SPI_V3__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_spim.h b/drivers/net/ntnic/nthw/core/include/nthw_spim.h
new file mode 100644
index 0000000000..70a49ab627
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_spim.h
@@ -0,0 +1,58 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_SPIM_H__
+#define __NTHW_SPIM_H__
+
+#include "nthw_fpga.h"
+
+struct nthw_spim {
+	nthw_fpga_t *mp_fpga;
+	nthw_module_t *mp_mod_spim;
+	int mn_instance;
+
+	nthw_register_t *mp_reg_srr;
+	nthw_field_t *mp_fld_srr_rst;
+
+	nthw_register_t *mp_reg_cr;
+	nthw_field_t *mp_fld_cr_loop;
+	nthw_field_t *mp_fld_cr_en;
+	nthw_field_t *mp_fld_cr_txrst;
+	nthw_field_t *mp_fld_cr_rxrst;
+
+	nthw_register_t *mp_reg_sr;
+	nthw_field_t *mp_fld_sr_done;
+	nthw_field_t *mp_fld_sr_txempty;
+	nthw_field_t *mp_fld_sr_rxempty;
+	nthw_field_t *mp_fld_sr_txfull;
+	nthw_field_t *mp_fld_sr_rxfull;
+	nthw_field_t *mp_fld_sr_txlvl;
+	nthw_field_t *mp_fld_sr_rxlvl;
+
+	nthw_register_t *mp_reg_dtr;
+	nthw_field_t *mp_fld_dtr_dtr;
+
+	nthw_register_t *mp_reg_drr;
+	nthw_field_t *mp_fld_drr_drr;
+
+	nthw_register_t *mp_reg_cfg;
+	nthw_field_t *mp_fld_cfg_pre;
+
+	nthw_register_t *mp_reg_cfg_clk;
+	nthw_field_t *mp_fld_cfg_clk_mode;
+};
+
+typedef struct nthw_spim nthw_spim_t;
+typedef struct nthw_spim nthw_spim;
+
+nthw_spim_t *nthw_spim_new(void);
+int nthw_spim_init(nthw_spim_t *p, nthw_fpga_t *p_fpga, int n_instance);
+
+uint32_t nthw_spim_reset(nthw_spim_t *p);
+uint32_t nthw_spim_enable(nthw_spim_t *p, bool b_enable);
+uint32_t nthw_spim_get_tx_fifo_empty(nthw_spim_t *p, bool *pb_empty);
+uint32_t nthw_spim_write_tx_fifo(nthw_spim_t *p, uint32_t n_data);
+
+#endif	/* __NTHW_SPIM_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_spis.h b/drivers/net/ntnic/nthw/core/include/nthw_spis.h
new file mode 100644
index 0000000000..978f239dd0
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_spis.h
@@ -0,0 +1,63 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_SPIS_H__
+#define __NTHW_SPIS_H__
+
+#include "nthw_fpga.h"
+
+struct nthw_spis {
+	nthw_fpga_t *mp_fpga;
+	nthw_module_t *mp_mod_spis;
+	int mn_instance;
+
+	nthw_register_t *mp_reg_srr;
+	nthw_field_t *mp_fld_srr_rst;
+
+	nthw_register_t *mp_reg_cr;
+	nthw_field_t *mp_fld_cr_loop;
+	nthw_field_t *mp_fld_cr_en;
+	nthw_field_t *mp_fld_cr_txrst;
+	nthw_field_t *mp_fld_cr_rxrst;
+	nthw_field_t *mp_fld_cr_debug;
+
+	nthw_register_t *mp_reg_sr;
+	nthw_field_t *mp_fld_sr_done;
+	nthw_field_t *mp_fld_sr_txempty;
+	nthw_field_t *mp_fld_sr_rxempty;
+	nthw_field_t *mp_fld_sr_txfull;
+	nthw_field_t *mp_fld_sr_rxfull;
+	nthw_field_t *mp_fld_sr_txlvl;
+	nthw_field_t *mp_fld_sr_rxlvl;
+	nthw_field_t *mp_fld_sr_frame_err;
+	nthw_field_t *mp_fld_sr_read_err;
+	nthw_field_t *mp_fld_sr_write_err;
+
+	nthw_register_t *mp_reg_dtr;
+	nthw_field_t *mp_fld_dtr_dtr;
+
+	nthw_register_t *mp_reg_drr;
+	nthw_field_t *mp_fld_drr_drr;
+
+	nthw_register_t *mp_reg_ram_ctrl;
+	nthw_field_t *mp_fld_ram_ctrl_adr;
+	nthw_field_t *mp_fld_ram_ctrl_cnt;
+
+	nthw_register_t *mp_reg_ram_data;
+	nthw_field_t *mp_fld_ram_data_data;
+};
+
+typedef struct nthw_spis nthw_spis_t;
+typedef struct nthw_spis nthw_spis;
+
+nthw_spis_t *nthw_spis_new(void);
+int nthw_spis_init(nthw_spis_t *p, nthw_fpga_t *p_fpga, int n_instance);
+
+uint32_t nthw_spis_reset(nthw_spis_t *p);
+uint32_t nthw_spis_enable(nthw_spis_t *p, bool b_enable);
+uint32_t nthw_spis_get_rx_fifo_empty(nthw_spis_t *p, bool *pb_empty);
+uint32_t nthw_spis_read_rx_fifo(nthw_spis_t *p, uint32_t *p_data);
+
+#endif	/* __NTHW_SPIS_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index ff29101e61..73feaa4ebd 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -65,6 +65,8 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 	nthw_prm_nt400dxx_periph_rst(p_fpga_info->mp_nthw_agx.p_prm, 0);
 	nt_os_wait_usec(10000);
 
+	res = nthw_fpga_avr_probe(p_fpga, 0);
+
 	if (res != 0)
 		return res;
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_fpga.c b/drivers/net/ntnic/nthw/core/nthw_fpga.c
index e54a210c9f..3166a2ba51 100644
--- a/drivers/net/ntnic/nthw/core/nthw_fpga.c
+++ b/drivers/net/ntnic/nthw/core/nthw_fpga.c
@@ -14,6 +14,7 @@
 #include "nthw_fpga_mod_str_map.h"
 
 #include "nthw_tsm.h"
+#include "nthw_spi_v3.h"
 
 #include <arpa/inet.h>
 
@@ -151,6 +152,449 @@ int nthw_fpga_silabs_detect(nthw_fpga_t *p_fpga, const int n_instance_no, const
 	return res;
 }
 
+/*
+ * Calculate CRC-16-CCITT of passed data
+ * CRC-16-CCITT ^16 + ^12 + ^5 + 1 (0x1021) (X.25, HDLC, XMODEM, Bluetooth,
+ *   SD, many others; known as CRC-CCITT)
+ */
+static uint16_t crc16(uint8_t *buffer, size_t length)
+{
+	uint16_t seed = 0;
+
+	while (length--) {
+		seed = (uint16_t)(seed >> 8 | seed << 8);
+		seed = (uint16_t)(seed ^ *buffer++);
+		seed = (uint16_t)(seed ^ (seed & 0xff) >> 4);
+		seed = (uint16_t)(seed ^ seed << 8 << 4);
+		seed = (uint16_t)(seed ^ (seed & 0xff) << 4 << 1);
+	}
+
+	return seed;
+}
+
+int nthw_fpga_avr_probe(nthw_fpga_t *p_fpga, const int n_instance_no)
+{
+	struct fpga_info_s *p_fpga_info = p_fpga->p_fpga_info;
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	nthw_spi_v3_t *p_avr_spi;
+	int res = -1;
+
+	p_avr_spi = nthw_spi_v3_new();
+
+	if (p_avr_spi) {
+		struct avr_vpd_info_s {
+			/* avr info */
+			uint32_t n_avr_spi_version;
+			uint8_t n_avr_fw_ver_major;
+			uint8_t n_avr_fw_ver_minor;
+			uint8_t n_avr_fw_ver_micro;
+			uint8_t a_avr_fw_ver_str[50];
+			uint8_t a_avr_fw_plat_id_str[20];
+
+			/* vpd_eeprom_t */
+			uint8_t psu_hw_version;
+			uint8_t vpd_pn[GEN2_PN_SIZE];
+			uint8_t vpd_pba[GEN2_PBA_SIZE];
+			uint8_t vpd_sn[GEN2_SN_SIZE];
+			uint8_t vpd_board_name[GEN2_BNAME_SIZE];
+			uint8_t vpd_platform_section[GEN2_PLATFORM_SIZE];
+
+			/* board_info_t aka vpd_platform_section: */
+			uint32_t product_family;/* uint8_t 1: capture, 2: Inline, 3: analysis */
+			uint32_t feature_mask;	/* Bit 0: OC192 capable */
+			uint32_t invfeature_mask;
+			uint8_t no_of_macs;
+			uint8_t mac_address[6];
+			uint16_t custom_id;
+			uint8_t user_id[8];
+			/*
+			 * Reserved NT operations to monitor the reprogram count of user_id with
+			 * vpduser
+			 */
+			uint16_t user_id_erase_write_count;
+
+			/*
+			 * AVR_OP_SYSINFO: struct version_sysinfo_request_container
+			 * Which version of the sysinfo container to retrieve. Set to zero to fetch
+			 * latest. Offset zero of latest always contain an uint8_t version info
+			 */
+			uint8_t sysinfo_container_version;
+
+			/* AVR_OP_SYSINFO: struct AvrLibcVersion */
+			/* The constant __AVR_LIBC_VERSION__ */
+			uint32_t sysinfo_avr_libc_version;
+
+			/* AVR_OP_SYSINFO: struct AvrLibcSignature */
+			uint8_t sysinfo_signature_0;	/* The constant SIGNATURE_0 */
+			uint8_t sysinfo_signature_1;	/* The constant SIGNATURE_1 */
+			uint8_t sysinfo_signature_2;	/* The constant SIGNATURE_2 */
+
+			/* AVR_OP_SYSINFO: struct AvrOs */
+			uint8_t sysinfo_spi_version;	/* SPI command layer version */
+			/*
+			 * Hardware revision. Locked to eeprom address zero. Is also available via
+			 * VPD read opcode (prior to v1.4b, this is required)
+			 */
+			uint8_t sysinfo_hw_revision;
+			/*
+			 * Number of ticks/second (Note: Be aware this may become zero if timer
+			 * module is rewritten to a tickles system!)
+			 */
+			uint8_t sysinfo_ticks_per_second;
+			uint32_t sysinfo_uptime;/* Uptime in seconds since last AVR reset */
+			uint8_t sysinfo_osccal;	/* OSCCAL value */
+
+			/*
+			 * Meta data concluded/calculated from req/reply
+			 */
+			bool b_feature_mask_valid;
+			bool b_crc16_valid;
+			uint16_t n_crc16_stored;
+			uint16_t n_crc16_calced;
+			uint64_t n_mac_val;
+		};
+
+		struct avr_vpd_info_s avr_vpd_info;
+		struct tx_rx_buf tx_buf;
+		struct tx_rx_buf rx_buf;
+		char rx_data[MAX_AVR_CONTAINER_SIZE];
+		uint32_t u32;
+
+		memset(&avr_vpd_info, 0, sizeof(avr_vpd_info));
+
+		nthw_spi_v3_init(p_avr_spi, p_fpga, n_instance_no);
+
+		/* AVR_OP_SPI_VERSION */
+		tx_buf.size = 0;
+		tx_buf.p_buf = NULL;
+		rx_buf.size = sizeof(u32);
+		rx_buf.p_buf = &u32;
+		u32 = 0;
+		res = nthw_spi_v3_transfer(p_avr_spi, AVR_OP_SPI_VERSION, &tx_buf, &rx_buf);
+		avr_vpd_info.n_avr_spi_version = u32;
+		NT_LOG(DBG, NTHW, "%s: AVR%d: SPI_VER: %d", p_adapter_id_str, n_instance_no,
+			avr_vpd_info.n_avr_spi_version);
+
+		/* AVR_OP_VERSION */
+		tx_buf.size = 0;
+		tx_buf.p_buf = NULL;
+		rx_buf.size = sizeof(rx_data);
+		rx_buf.p_buf = &rx_data;
+		res = nthw_spi_v3_transfer(p_avr_spi, AVR_OP_VERSION, &tx_buf, &rx_buf);
+
+		avr_vpd_info.n_avr_fw_ver_major = rx_data[0];
+		avr_vpd_info.n_avr_fw_ver_minor = rx_data[1];
+		avr_vpd_info.n_avr_fw_ver_micro = rx_data[2];
+		NT_LOG(DBG, NTHW, "%s: AVR%d: FW_VER: %c.%c.%c", p_adapter_id_str, n_instance_no,
+			avr_vpd_info.n_avr_fw_ver_major, avr_vpd_info.n_avr_fw_ver_minor,
+			avr_vpd_info.n_avr_fw_ver_micro);
+
+		memcpy(avr_vpd_info.a_avr_fw_ver_str, &rx_data[0 + 3],
+			sizeof(avr_vpd_info.a_avr_fw_ver_str));
+		NT_LOG(DBG, NTHW, "%s: AVR%d: FW_VER_STR: '%.*s'", p_adapter_id_str,
+			n_instance_no, (int)sizeof(avr_vpd_info.a_avr_fw_ver_str),
+			avr_vpd_info.a_avr_fw_ver_str);
+
+		memcpy(avr_vpd_info.a_avr_fw_plat_id_str, &rx_data[0 + 3 + 50],
+			sizeof(avr_vpd_info.a_avr_fw_plat_id_str));
+		NT_LOG(DBG, NTHW, "%s: AVR%d: FW_HW_ID_STR: '%.*s'", p_adapter_id_str,
+			n_instance_no, (int)sizeof(avr_vpd_info.a_avr_fw_plat_id_str),
+			avr_vpd_info.a_avr_fw_plat_id_str);
+
+		snprintf(p_fpga_info->nthw_hw_info.hw_plat_id_str,
+			sizeof(p_fpga_info->nthw_hw_info.hw_plat_id_str), "%s",
+			(char *)avr_vpd_info.a_avr_fw_plat_id_str);
+		p_fpga_info->nthw_hw_info
+		.hw_plat_id_str[sizeof(p_fpga_info->nthw_hw_info.hw_plat_id_str) - 1] = 0;
+
+		/* AVR_OP_SYSINFO_2 */
+		tx_buf.size = 0;
+		tx_buf.p_buf = NULL;
+		rx_buf.size = sizeof(rx_data);
+		rx_buf.p_buf = &rx_data;
+		res = nthw_spi_v3_transfer(p_avr_spi, AVR_OP_SYSINFO_2, &tx_buf, &rx_buf);
+
+		if (res == 0 && avr_vpd_info.n_avr_spi_version >= 3 && rx_buf.size >= 16) {
+			if (rx_buf.size != 16) {
+				NT_LOG(WRN, NTHW,
+					"%s: AVR%d: SYSINFO2: reply is larger than expected: %04X %04X",
+					p_adapter_id_str, n_instance_no, rx_buf.size, 16);
+
+			} else {
+				NT_LOG(DBG, NTHW, "%s: AVR%d: SYSINFO2: OK: res=%d sz=%d",
+					p_adapter_id_str, n_instance_no, res, rx_buf.size);
+			}
+
+			avr_vpd_info.sysinfo_container_version = rx_data[0];
+			NT_LOG(DBG, NTHW, "%s: AVR%d: SYSINFO_REQ_VER: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_container_version);
+
+			memcpy(&avr_vpd_info.sysinfo_avr_libc_version, &rx_data[0 + 1],
+				sizeof(avr_vpd_info.sysinfo_avr_libc_version));
+			NT_LOG(DBG, NTHW, "%s: AVR%d: LIBC_VER: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_avr_libc_version);
+
+			avr_vpd_info.sysinfo_signature_0 = rx_data[5];
+			avr_vpd_info.sysinfo_signature_1 = rx_data[6];
+			avr_vpd_info.sysinfo_signature_2 = rx_data[7];
+			NT_LOG(DBG, NTHW, "%s: AVR%d: SIGNATURE: %02x%02x%02x", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_signature_0,
+				avr_vpd_info.sysinfo_signature_1, avr_vpd_info.sysinfo_signature_2);
+
+			avr_vpd_info.sysinfo_spi_version = rx_data[8];
+			NT_LOG(DBG, NTHW, "%s: AVR%d: SPI_VER: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_spi_version);
+
+			avr_vpd_info.sysinfo_hw_revision = rx_data[9];
+			NT_LOG(DBG, NTHW, "%s: AVR%d: HW_REV: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_hw_revision);
+
+			avr_vpd_info.sysinfo_ticks_per_second = rx_data[10];
+			NT_LOG(DBG, NTHW, "%s: AVR%d: TICKS_PER_SEC: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_ticks_per_second);
+
+			memcpy(&avr_vpd_info.sysinfo_uptime, &rx_data[11],
+				sizeof(avr_vpd_info.sysinfo_uptime));
+			NT_LOG(DBG, NTHW, "%s: AVR%d: UPTIME: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_uptime);
+
+			avr_vpd_info.sysinfo_osccal = rx_data[15];
+			NT_LOG(DBG, NTHW, "%s: AVR%d: OSCCAL: %d", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.sysinfo_osccal);
+
+			{
+				bool b_spi_ver_match = (avr_vpd_info.n_avr_spi_version ==
+						avr_vpd_info.sysinfo_spi_version);
+				(void)b_spi_ver_match;
+				NT_LOG(DBG, NTHW, "%s: AVR%d: SPI_VER_TST: %s (%d %d)",
+					p_adapter_id_str, n_instance_no,
+					(b_spi_ver_match ? "OK" : "MISMATCH"),
+					avr_vpd_info.n_avr_spi_version,
+					avr_vpd_info.sysinfo_spi_version);
+			}
+
+			/* SYSINFO2: if response: only populate hw_id not hw_id_emulated */
+			p_fpga_info->nthw_hw_info.hw_id = avr_vpd_info.sysinfo_hw_revision;
+
+		} else {
+			/* AVR_OP_SYSINFO */
+			tx_buf.size = 0;
+			tx_buf.p_buf = NULL;
+			rx_buf.size = sizeof(rx_data);
+			rx_buf.p_buf = &rx_data;
+			res = nthw_spi_v3_transfer(p_avr_spi, AVR_OP_SYSINFO, &tx_buf, &rx_buf);
+
+			if (res == 0 && avr_vpd_info.n_avr_spi_version >= 3 && rx_buf.size >= 16) {
+				if (rx_buf.size != 16) {
+					NT_LOG(WRN, NTHW,
+						"%s: AVR%d: SYSINFO: reply is larger than expected: %04X %04X",
+						p_adapter_id_str, n_instance_no, rx_buf.size, 16);
+
+				} else {
+					NT_LOG(DBG, NTHW, "%s: AVR%d: SYSINFO: OK: res=%d sz=%d",
+						p_adapter_id_str, n_instance_no, res, rx_buf.size);
+				}
+
+				avr_vpd_info.sysinfo_container_version = rx_data[0];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: SYSINFO_REQ_VER: %d",
+					p_adapter_id_str, n_instance_no,
+					avr_vpd_info.sysinfo_container_version);
+
+				memcpy(&avr_vpd_info.sysinfo_avr_libc_version, &rx_data[0 + 1],
+					sizeof(avr_vpd_info.sysinfo_avr_libc_version));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: LIBC_VER: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.sysinfo_avr_libc_version);
+
+				avr_vpd_info.sysinfo_signature_0 = rx_data[5];
+				avr_vpd_info.sysinfo_signature_1 = rx_data[6];
+				avr_vpd_info.sysinfo_signature_2 = rx_data[7];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: SIGNATURE: %02x%02x%02x",
+					p_adapter_id_str, n_instance_no,
+					avr_vpd_info.sysinfo_signature_0,
+					avr_vpd_info.sysinfo_signature_1,
+					avr_vpd_info.sysinfo_signature_2);
+
+				avr_vpd_info.sysinfo_spi_version = rx_data[8];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: SPI_VER: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.sysinfo_spi_version);
+
+				avr_vpd_info.sysinfo_hw_revision = rx_data[9];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: HW_REV: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.sysinfo_hw_revision);
+				NT_LOG(INF, NTHW, "%s: AVR%d: HW_REV: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.sysinfo_hw_revision);
+
+				avr_vpd_info.sysinfo_ticks_per_second = rx_data[10];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: TICKS_PER_SEC: %d",
+					p_adapter_id_str, n_instance_no,
+					avr_vpd_info.sysinfo_ticks_per_second);
+
+				memcpy(&avr_vpd_info.sysinfo_uptime, &rx_data[11],
+					sizeof(avr_vpd_info.sysinfo_uptime));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: UPTIME: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.sysinfo_uptime);
+
+				avr_vpd_info.sysinfo_osccal = rx_data[15];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: OSCCAL: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.sysinfo_osccal);
+
+				{
+					bool b_spi_ver_match = (avr_vpd_info.n_avr_spi_version ==
+							avr_vpd_info.sysinfo_spi_version);
+					(void)b_spi_ver_match;
+					NT_LOG(DBG, NTHW, "%s: AVR%d: SPI_VER_TST: %s (%d %d)",
+						p_adapter_id_str, n_instance_no,
+						(b_spi_ver_match ? "OK" : "MISMATCH"),
+						avr_vpd_info.n_avr_spi_version,
+						avr_vpd_info.sysinfo_spi_version);
+				}
+
+				p_fpga_info->nthw_hw_info.hw_id = avr_vpd_info.sysinfo_hw_revision;
+				p_fpga_info->nthw_hw_info.hw_id_emulated =
+					avr_vpd_info.sysinfo_hw_revision;
+
+			} else {
+				NT_LOG(ERR, NTHW, "%s: AVR%d: SYSINFO: NA: res=%d sz=%d",
+					p_adapter_id_str, n_instance_no, res, rx_buf.size);
+			}
+		}
+
+		/* AVR_OP_VPD_READ */
+		tx_buf.size = 0;
+		tx_buf.p_buf = NULL;
+		rx_buf.size = sizeof(rx_data);
+		rx_buf.p_buf = &rx_data;
+		res = nthw_spi_v3_transfer(p_avr_spi, AVR_OP_VPD_READ, &tx_buf, &rx_buf);
+
+		if (res == 0 && avr_vpd_info.n_avr_spi_version >= 3 &&
+			rx_buf.size >= GEN2_VPD_SIZE_TOTAL) {
+			avr_vpd_info.n_crc16_calced = crc16(rx_buf.p_buf, rx_buf.size - 2);
+			memcpy(&avr_vpd_info.n_crc16_stored, &rx_data[rx_buf.size - 2],
+				sizeof(avr_vpd_info.n_crc16_stored));
+			NT_LOG(DBG, NTHW, "%s: AVR%d: VPD_CRC: %04X %04X", p_adapter_id_str,
+				n_instance_no, avr_vpd_info.n_crc16_stored,
+				avr_vpd_info.n_crc16_calced);
+
+			avr_vpd_info.b_crc16_valid =
+				(avr_vpd_info.n_crc16_stored == avr_vpd_info.n_crc16_calced);
+			NT_LOG(DBG, NTHW, "%s: AVR%d: CRC_TST: %s", p_adapter_id_str,
+				n_instance_no, (avr_vpd_info.b_crc16_valid ? "OK" : "ERROR"));
+
+			if (avr_vpd_info.b_crc16_valid) {
+				memcpy(&avr_vpd_info.psu_hw_version, &rx_data[0],
+					sizeof(avr_vpd_info.psu_hw_version));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: PSU_HW_VER: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.psu_hw_version);
+
+				memcpy(&avr_vpd_info.vpd_pn, &rx_data[0 + 1],
+					sizeof(avr_vpd_info.vpd_pn));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: PN: '%.*s'", p_adapter_id_str,
+					n_instance_no, GEN2_PN_SIZE, avr_vpd_info.vpd_pn);
+
+				memcpy(&avr_vpd_info.vpd_pba, &rx_data[0 + 1 + GEN2_PN_SIZE],
+					sizeof(avr_vpd_info.vpd_pba));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: PBA: '%.*s'", p_adapter_id_str,
+					n_instance_no, GEN2_PBA_SIZE, avr_vpd_info.vpd_pba);
+
+				memcpy(&avr_vpd_info.vpd_sn,
+					&rx_data[0 + 1 + GEN2_PN_SIZE + GEN2_PBA_SIZE],
+					sizeof(avr_vpd_info.vpd_sn));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: SN: '%.*s", p_adapter_id_str,
+					n_instance_no, GEN2_SN_SIZE, avr_vpd_info.vpd_sn);
+
+				memcpy(&avr_vpd_info.vpd_board_name,
+					&rx_data[0 + 1 + GEN2_PN_SIZE + GEN2_PBA_SIZE +
+						GEN2_SN_SIZE],
+					sizeof(avr_vpd_info.vpd_board_name));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: BN: '%.*s'", p_adapter_id_str,
+					n_instance_no, GEN2_BNAME_SIZE,
+					avr_vpd_info.vpd_board_name);
+
+				union mac_u {
+					uint8_t a_u8[8];
+					uint16_t a_u16[4];
+					uint32_t a_u32[2];
+					uint64_t a_u64[1];
+				} mac;
+
+				/* vpd_platform_section */
+				uint8_t *p_vpd_board_info =
+					(uint8_t *)(&rx_data[1 + GEN2_PN_SIZE + GEN2_PBA_SIZE +
+					GEN2_SN_SIZE + GEN2_BNAME_SIZE]);
+				memcpy(&avr_vpd_info.product_family, &p_vpd_board_info[0],
+					sizeof(avr_vpd_info.product_family));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: PROD_FAM: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.product_family);
+
+				memcpy(&avr_vpd_info.feature_mask, &p_vpd_board_info[0 + 4],
+					sizeof(avr_vpd_info.feature_mask));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: FMSK_VAL: 0x%08X",
+					p_adapter_id_str, n_instance_no, avr_vpd_info.feature_mask);
+
+				memcpy(&avr_vpd_info.invfeature_mask, &p_vpd_board_info[0 + 4 + 4],
+					sizeof(avr_vpd_info.invfeature_mask));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: FMSK_INV: 0x%08X",
+					p_adapter_id_str, n_instance_no,
+					avr_vpd_info.invfeature_mask);
+
+				avr_vpd_info.b_feature_mask_valid =
+					(avr_vpd_info.feature_mask ==
+						~avr_vpd_info.invfeature_mask);
+				NT_LOG(DBG, NTHW, "%s: AVR%d: FMSK_TST: %s", p_adapter_id_str,
+					n_instance_no,
+					(avr_vpd_info.b_feature_mask_valid ? "OK" : "ERROR"));
+
+				memcpy(&avr_vpd_info.no_of_macs, &p_vpd_board_info[0 + 4 + 4 + 4],
+					sizeof(avr_vpd_info.no_of_macs));
+				NT_LOG(DBG, NTHW, "%s: AVR%d: NUM_MACS: %d", p_adapter_id_str,
+					n_instance_no, avr_vpd_info.no_of_macs);
+
+				memcpy(&avr_vpd_info.mac_address,
+					&p_vpd_board_info[0 + 4 + 4 + 4 + 1],
+					sizeof(avr_vpd_info.mac_address));
+				NT_LOG(DBG, NTHW,
+					"%s: AVR%d: MAC_ADDR: %02x:%02x:%02x:%02x:%02x:%02x",
+					p_adapter_id_str, n_instance_no,
+					avr_vpd_info.mac_address[0], avr_vpd_info.mac_address[1],
+					avr_vpd_info.mac_address[2], avr_vpd_info.mac_address[3],
+					avr_vpd_info.mac_address[4], avr_vpd_info.mac_address[5]);
+
+				mac.a_u64[0] = 0;
+				memcpy(&mac.a_u8[2], &avr_vpd_info.mac_address,
+					sizeof(avr_vpd_info.mac_address));
+				{
+					const uint32_t u1 = ntohl(mac.a_u32[0]);
+
+					if (u1 != mac.a_u32[0]) {
+						const uint32_t u0 = ntohl(mac.a_u32[1]);
+						mac.a_u32[0] = u0;
+						mac.a_u32[1] = u1;
+					}
+				}
+
+				avr_vpd_info.n_mac_val = mac.a_u64[0];
+				NT_LOG(DBG, NTHW, "%s: AVR%d: MAC_U64: %012" PRIX64 "",
+					p_adapter_id_str, n_instance_no, avr_vpd_info.n_mac_val);
+			}
+
+			p_fpga_info->nthw_hw_info.vpd_info.mn_mac_addr_count =
+				avr_vpd_info.no_of_macs;
+			p_fpga_info->nthw_hw_info.vpd_info.mn_mac_addr_value =
+				avr_vpd_info.n_mac_val;
+			memcpy(p_fpga_info->nthw_hw_info.vpd_info.ma_mac_addr_octets,
+				avr_vpd_info.mac_address,
+				ARRAY_SIZE(p_fpga_info->nthw_hw_info.vpd_info.ma_mac_addr_octets));
+
+		} else {
+			NT_LOG(ERR, NTHW, "%s:%u: res=%d", __func__, __LINE__, res);
+			NT_LOG(ERR, NTHW, "%s: AVR%d: SYSINFO2: NA: res=%d sz=%d",
+				p_adapter_id_str, n_instance_no, res, rx_buf.size);
+		}
+	}
+
+	return res;
+}
+
 /*
  * NT200A02, NT200A01-HWbuild2
  */
diff --git a/drivers/net/ntnic/nthw/core/nthw_spi_v3.c b/drivers/net/ntnic/nthw/core/nthw_spi_v3.c
new file mode 100644
index 0000000000..0b611462a0
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_spi_v3.c
@@ -0,0 +1,358 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "ntlog.h"
+
+#include "nthw_drv.h"
+#include "nthw_fpga.h"
+
+#include "nthw_spi_v3.h"
+
+#include <arpa/inet.h>
+
+#undef SPI_V3_DEBUG_PRINT
+
+nthw_spi_v3_t *nthw_spi_v3_new(void)
+{
+	nthw_spi_v3_t *p = malloc(sizeof(nthw_spi_v3_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_spi_v3_t));
+
+	return p;
+}
+
+static int nthw_spi_v3_set_timeout(nthw_spi_v3_t *p, int time_out)
+{
+	p->m_time_out = time_out;
+	return 0;
+}
+
+/*
+ * Wait until Tx data have been sent after they have been placed in the Tx FIFO.
+ */
+static int wait_for_tx_data_sent(nthw_spim_t *p_spim_mod, uint64_t time_out)
+{
+	int result;
+	bool empty;
+	uint64_t start_time;
+	uint64_t cur_time;
+	start_time = nt_os_get_time_monotonic_counter();
+
+	while (true) {
+		nt_os_wait_usec(1000);	/* Every 1ms */
+
+		result = nthw_spim_get_tx_fifo_empty(p_spim_mod, &empty);
+
+		if (result != 0) {
+			NT_LOG(WRN, NTHW, "nthw_spim_get_tx_fifo_empty failed");
+			return result;
+		}
+
+		if (empty)
+			break;
+
+		cur_time = nt_os_get_time_monotonic_counter();
+
+		if ((cur_time - start_time) > time_out) {
+			NT_LOG(WRN, NTHW, "%s: Timed out", __func__);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Wait until Rx data have been received.
+ */
+static int wait_for_rx_data_ready(nthw_spis_t *p_spis_mod, uint64_t time_out)
+{
+	int result;
+	bool empty;
+	uint64_t start_time;
+	uint64_t cur_time;
+	start_time = nt_os_get_time_monotonic_counter();
+
+	/* Wait for data to become ready in the Rx FIFO */
+	while (true) {
+		nt_os_wait_usec(10000);	/* Every 10ms */
+
+		result = nthw_spis_get_rx_fifo_empty(p_spis_mod, &empty);
+
+		if (result != 0) {
+			NT_LOG(WRN, NTHW, "nthw_spis_get_rx_empty failed");
+			return result;
+		}
+
+		if (!empty)
+			break;
+
+		cur_time = nt_os_get_time_monotonic_counter();
+
+		if ((cur_time - start_time) > time_out) {
+			NT_LOG(WRN, NTHW, "%s: Timed out", __func__);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+#ifdef SPI_V3_DEBUG_PRINT
+static void dump_hex(uint8_t *p_data, uint16_t count)
+{
+	int i;
+	int j = 0;
+	char tmp_str[128];
+
+	for (i = 0; i < count; i++) {
+		sprintf(&tmp_str[j * 3], "%02X ", *(p_data++));
+		j++;
+
+		if (j == 16 || i == count - 1) {
+			tmp_str[j * 3 - 1] = '\0';
+			NT_LOG(DBG, NTHW, "    %s", tmp_str);
+			j = 0;
+		}
+	}
+}
+
+#endif
+
+int nthw_spi_v3_init(nthw_spi_v3_t *p, nthw_fpga_t *p_fpga, int n_instance_no)
+{
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	uint32_t result;
+
+	p->mn_instance_no = n_instance_no;
+
+	nthw_spi_v3_set_timeout(p, 1);
+
+	/* Initialize SPIM module */
+	p->mp_spim_mod = nthw_spim_new();
+
+	result = nthw_spim_init(p->mp_spim_mod, p_fpga, n_instance_no);
+
+	if (result != 0)
+		NT_LOG(ERR, NTHW, "%s: nthw_spis_init failed: %d", p_adapter_id_str, result);
+
+	/* Initialize SPIS module */
+	p->mp_spis_mod = nthw_spis_new();
+
+	result = nthw_spis_init(p->mp_spis_mod, p_fpga, n_instance_no);
+
+	if (result != 0)
+		NT_LOG(ERR, NTHW, "%s: nthw_spim_init failed: %d", p_adapter_id_str, result);
+
+	/* Reset SPIM and SPIS modules */
+	result = nthw_spim_reset(p->mp_spim_mod);
+
+	if (result != 0)
+		NT_LOG(ERR, NTHW, "%s: nthw_spim_reset failed: %d", p_adapter_id_str, result);
+
+	result = nthw_spis_reset(p->mp_spis_mod);
+
+	if (result != 0)
+		NT_LOG(ERR, NTHW, "%s: nthw_spis_reset failed: %d", p_adapter_id_str, result);
+
+	return result;
+}
+
+/*
+ * Send Tx data using the SPIM module and receive any data using the SPIS module.
+ * The data are sent and received being wrapped into a SPI v3 container.
+ */
+int nthw_spi_v3_transfer(nthw_spi_v3_t *p, uint16_t opcode, struct tx_rx_buf *tx_buf,
+	struct tx_rx_buf *rx_buf)
+{
+	const uint16_t max_payload_rx_size = rx_buf->size;
+	int result = 0;
+
+#pragma pack(push, 1)
+	union {
+		uint32_t raw;
+
+		struct {
+			uint16_t opcode;
+			uint16_t size;
+		};
+	} spi_tx_hdr;
+
+	union {
+		uint32_t raw;
+
+		struct {
+			uint16_t error_code;
+			uint16_t size;
+		};
+	} spi_rx_hdr;
+
+#pragma pack(pop)
+
+#ifdef SPI_V3_DEBUG_PRINT
+	NT_LOG_DBG(DBG, NTHW, "Started");
+#endif
+
+	/* Disable transmission from Tx FIFO */
+	result = nthw_spim_enable(p->mp_spim_mod, false);
+
+	if (result != 0) {
+		NT_LOG(WRN, NTHW, "nthw_spim_enable failed");
+		return result;
+	}
+
+	/* Enable SPIS module */
+	result = nthw_spis_enable(p->mp_spis_mod, true);
+
+	if (result != 0) {
+		NT_LOG(WRN, NTHW, "nthw_spis_enable failed");
+		return result;
+	}
+
+	/* Put data into Tx FIFO */
+	spi_tx_hdr.opcode = opcode;
+	spi_tx_hdr.size = tx_buf->size;
+
+#ifdef SPI_V3_DEBUG_PRINT
+	NT_LOG(DBG, NTHW, "Opcode=0x%04X tx_bufSize=0x%04X rx_bufSize=0x%04X", opcode,
+		tx_buf->size, rx_buf->size);
+
+#endif	/* SPI_V3_DEBUG_PRINT */
+
+	result = nthw_spim_write_tx_fifo(p->mp_spim_mod, htonl(spi_tx_hdr.raw));
+
+	if (result != 0) {
+		NT_LOG(WRN, NTHW, "nthw_spim_write_tx_fifo failed");
+		return result;
+	}
+
+	{
+		uint8_t *tx_data = (uint8_t *)tx_buf->p_buf;
+		uint16_t tx_size = tx_buf->size;
+		uint16_t count;
+		uint32_t value;
+
+		while (tx_size > 0) {
+			if (tx_size > 4) {
+				count = 4;
+
+			} else {
+				count = tx_size;
+				value = 0;
+			}
+
+			memcpy(&value, tx_data, count);
+
+			result = nthw_spim_write_tx_fifo(p->mp_spim_mod, htonl(value));
+
+			if (result != 0) {
+				NT_LOG(WRN, NTHW, "nthw_spim_write_tx_fifo failed");
+				return result;
+			}
+
+			tx_size = (uint16_t)(tx_size - count);
+			tx_data += count;
+		}
+	}
+
+	/* Enable Tx FIFO */
+	result = nthw_spim_enable(p->mp_spim_mod, true);
+
+	if (result != 0) {
+		NT_LOG(WRN, NTHW, "nthw_spim_enable failed");
+		return result;
+	}
+
+	result = wait_for_tx_data_sent(p->mp_spim_mod, p->m_time_out);
+
+	if (result != 0)
+		return result;
+
+#ifdef SPI_V3_DEBUG_PRINT
+	NT_LOG(DBG, NTHW, "%s: SPI header and payload data have been sent", __func__);
+#endif
+
+	{
+		/* Start receiving data */
+		uint16_t rx_size =
+			sizeof(spi_rx_hdr.raw);	/* The first data to read is the header */
+		uint8_t *rx_data = (uint8_t *)rx_buf->p_buf;
+		bool rx_hdr_read = false;
+
+		rx_buf->size = 0;
+
+		while (true) {
+			uint16_t count;
+			uint32_t value;
+
+			if (!rx_hdr_read) {	/* Read the header */
+				result = wait_for_rx_data_ready(p->mp_spis_mod, p->m_time_out);
+
+				if (result != 0)
+					return result;
+
+				result = nthw_spis_read_rx_fifo(p->mp_spis_mod, &spi_rx_hdr.raw);
+
+				if (result != 0) {
+					NT_LOG(WRN, NTHW, "nthw_spis_read_rx_fifo failed");
+					return result;
+				}
+
+				spi_rx_hdr.raw = ntohl(spi_rx_hdr.raw);
+				rx_size = spi_rx_hdr.size;
+				rx_hdr_read = true;	/* Next time read payload */
+
+#ifdef SPI_V3_DEBUG_PRINT
+				NT_LOG(DBG, NTHW,
+					"  spi_rx_hdr.error_code = 0x%04X, spi_rx_hdr.size = 0x%04X",
+					spi_rx_hdr.error_code, spi_rx_hdr.size);
+#endif
+
+				if (spi_rx_hdr.error_code != 0) {
+					result = -1;	/* NT_ERROR_AVR_OPCODE_RETURNED_ERROR; */
+					break;
+				}
+
+				if (rx_size > max_payload_rx_size) {
+					result = 1;	/* NT_ERROR_AVR_RX_BUFFER_TOO_SMALL; */
+					break;
+				}
+
+			} else {/* Read the payload */
+				count = (uint16_t)(rx_size < 4U ? rx_size : 4U);
+
+				if (count == 0)
+					break;
+
+				result = wait_for_rx_data_ready(p->mp_spis_mod, p->m_time_out);
+
+				if (result != 0)
+					return result;
+
+				result = nthw_spis_read_rx_fifo(p->mp_spis_mod, &value);
+
+				if (result != 0) {
+					NT_LOG(WRN, NTHW, "nthw_spis_read_rx_fifo failed");
+					return result;
+				}
+
+				value = ntohl(value);	/* Convert to host endian */
+				memcpy(rx_data, &value, count);
+				rx_buf->size = (uint16_t)(rx_buf->size + count);
+				rx_size = (uint16_t)(rx_size - count);
+				rx_data += count;
+			}
+		}
+	}
+
+#ifdef SPI_V3_DEBUG_PRINT
+	NT_LOG(DBG, NTHW, "  RxData: %d", rx_buf->size);
+	dump_hex(rx_buf->p_buf, rx_buf->size);
+	NT_LOG(DBG, NTHW, "%s:  Ended: %d", __func__, result);
+#endif
+
+	return result;
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_spim.c b/drivers/net/ntnic/nthw/core/nthw_spim.c
new file mode 100644
index 0000000000..d30c11d0ff
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_spim.c
@@ -0,0 +1,113 @@
+/*
+ * 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_spim.h"
+
+nthw_spim_t *nthw_spim_new(void)
+{
+	nthw_spim_t *p = malloc(sizeof(nthw_spim_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_spim_t));
+
+	return p;
+}
+
+int nthw_spim_init(nthw_spim_t *p, nthw_fpga_t *p_fpga, int n_instance)
+{
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_SPIM, n_instance);
+
+	if (p == NULL)
+		return mod == NULL ? -1 : 0;
+
+	if (mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: SPIM %d: no such instance", p_adapter_id_str, n_instance);
+		return -1;
+	}
+
+	p->mp_fpga = p_fpga;
+	p->mn_instance = n_instance;
+	p->mp_mod_spim = mod;
+
+	/* SPIM is a primary communication channel - turn off debug by default */
+	nthw_module_set_debug_mode(p->mp_mod_spim, 0x00);
+
+	p->mp_reg_srr = nthw_module_get_register(p->mp_mod_spim, SPIM_SRR);
+	p->mp_fld_srr_rst = nthw_register_get_field(p->mp_reg_srr, SPIM_SRR_RST);
+
+	p->mp_reg_cr = nthw_module_get_register(p->mp_mod_spim, SPIM_CR);
+	p->mp_fld_cr_loop = nthw_register_get_field(p->mp_reg_cr, SPIM_CR_LOOP);
+	p->mp_fld_cr_en = nthw_register_get_field(p->mp_reg_cr, SPIM_CR_EN);
+	p->mp_fld_cr_txrst = nthw_register_get_field(p->mp_reg_cr, SPIM_CR_TXRST);
+	p->mp_fld_cr_rxrst = nthw_register_get_field(p->mp_reg_cr, SPIM_CR_RXRST);
+
+	p->mp_reg_sr = nthw_module_get_register(p->mp_mod_spim, SPIM_SR);
+	p->mp_fld_sr_done = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_DONE);
+	p->mp_fld_sr_txempty = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_TXEMPTY);
+	p->mp_fld_sr_rxempty = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_RXEMPTY);
+	p->mp_fld_sr_txfull = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_TXFULL);
+	p->mp_fld_sr_rxfull = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_RXFULL);
+	p->mp_fld_sr_txlvl = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_TXLVL);
+	p->mp_fld_sr_rxlvl = nthw_register_get_field(p->mp_reg_sr, SPIM_SR_RXLVL);
+
+	p->mp_reg_dtr = nthw_module_get_register(p->mp_mod_spim, SPIM_DTR);
+	p->mp_fld_dtr_dtr = nthw_register_get_field(p->mp_reg_dtr, SPIM_DTR_DTR);
+
+	p->mp_reg_drr = nthw_module_get_register(p->mp_mod_spim, SPIM_DRR);
+	p->mp_fld_drr_drr = nthw_register_get_field(p->mp_reg_drr, SPIM_DRR_DRR);
+
+	p->mp_reg_cfg = nthw_module_get_register(p->mp_mod_spim, SPIM_CFG);
+	p->mp_fld_cfg_pre = nthw_register_get_field(p->mp_reg_cfg, SPIM_CFG_PRE);
+
+	p->mp_reg_cfg_clk = nthw_module_query_register(p->mp_mod_spim, SPIM_CFG_CLK);
+	p->mp_fld_cfg_clk_mode = nthw_register_query_field(p->mp_reg_cfg, SPIM_CFG_CLK_MODE);
+
+	return 0;
+}
+
+uint32_t nthw_spim_reset(nthw_spim_t *p)
+{
+	nthw_register_update(p->mp_reg_srr);
+	nthw_field_set_val32(p->mp_fld_srr_rst, 0x0A);	/* 0x0A hardcoded value - see doc */
+	nthw_register_flush(p->mp_reg_srr, 1);
+
+	return 0;
+}
+
+uint32_t nthw_spim_enable(nthw_spim_t *p, bool b_enable)
+{
+	nthw_field_update_register(p->mp_fld_cr_en);
+
+	if (b_enable)
+		nthw_field_set_all(p->mp_fld_cr_en);
+
+	else
+		nthw_field_clr_all(p->mp_fld_cr_en);
+
+	nthw_field_flush_register(p->mp_fld_cr_en);
+
+	return 0;
+}
+
+uint32_t nthw_spim_write_tx_fifo(nthw_spim_t *p, uint32_t n_data)
+{
+	nthw_field_set_val_flush32(p->mp_fld_dtr_dtr, n_data);
+	return 0;
+}
+
+uint32_t nthw_spim_get_tx_fifo_empty(nthw_spim_t *p, bool *pb_empty)
+{
+	assert(pb_empty);
+
+	*pb_empty = nthw_field_get_updated(p->mp_fld_sr_txempty) ? true : false;
+
+	return 0;
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_spis.c b/drivers/net/ntnic/nthw/core/nthw_spis.c
new file mode 100644
index 0000000000..3c34dec936
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_spis.c
@@ -0,0 +1,121 @@
+/*
+ * 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_spis.h"
+
+nthw_spis_t *nthw_spis_new(void)
+{
+	nthw_spis_t *p = malloc(sizeof(nthw_spis_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_spis_t));
+
+	return p;
+}
+
+int nthw_spis_init(nthw_spis_t *p, nthw_fpga_t *p_fpga, int n_instance)
+{
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_SPIS, n_instance);
+
+	if (p == NULL)
+		return mod == NULL ? -1 : 0;
+
+	if (mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: SPIS %d: no such instance", p_adapter_id_str, n_instance);
+		return -1;
+	}
+
+	p->mp_fpga = p_fpga;
+	p->mn_instance = n_instance;
+	p->mp_mod_spis = mod;
+
+	/* SPIS is a primary communication channel - turn off debug by default */
+	nthw_module_set_debug_mode(p->mp_mod_spis, 0x00);
+
+	p->mp_reg_srr = nthw_module_get_register(p->mp_mod_spis, SPIS_SRR);
+	p->mp_fld_srr_rst = nthw_register_get_field(p->mp_reg_srr, SPIS_SRR_RST);
+
+	p->mp_reg_cr = nthw_module_get_register(p->mp_mod_spis, SPIS_CR);
+	p->mp_fld_cr_loop = nthw_register_get_field(p->mp_reg_cr, SPIS_CR_LOOP);
+	p->mp_fld_cr_en = nthw_register_get_field(p->mp_reg_cr, SPIS_CR_EN);
+	p->mp_fld_cr_txrst = nthw_register_get_field(p->mp_reg_cr, SPIS_CR_TXRST);
+	p->mp_fld_cr_rxrst = nthw_register_get_field(p->mp_reg_cr, SPIS_CR_RXRST);
+	p->mp_fld_cr_debug = nthw_register_get_field(p->mp_reg_cr, SPIS_CR_DEBUG);
+
+	p->mp_reg_sr = nthw_module_get_register(p->mp_mod_spis, SPIS_SR);
+	p->mp_fld_sr_done = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_DONE);
+	p->mp_fld_sr_txempty = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_TXEMPTY);
+	p->mp_fld_sr_rxempty = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_RXEMPTY);
+	p->mp_fld_sr_txfull = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_TXFULL);
+	p->mp_fld_sr_rxfull = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_RXFULL);
+	p->mp_fld_sr_txlvl = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_TXLVL);
+	p->mp_fld_sr_rxlvl = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_RXLVL);
+	p->mp_fld_sr_frame_err = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_FRAME_ERR);
+	p->mp_fld_sr_read_err = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_READ_ERR);
+	p->mp_fld_sr_write_err = nthw_register_get_field(p->mp_reg_sr, SPIS_SR_WRITE_ERR);
+
+	p->mp_reg_dtr = nthw_module_get_register(p->mp_mod_spis, SPIS_DTR);
+	p->mp_fld_dtr_dtr = nthw_register_get_field(p->mp_reg_dtr, SPIS_DTR_DTR);
+
+	p->mp_reg_drr = nthw_module_get_register(p->mp_mod_spis, SPIS_DRR);
+	p->mp_fld_drr_drr = nthw_register_get_field(p->mp_reg_drr, SPIS_DRR_DRR);
+
+	p->mp_reg_ram_ctrl = nthw_module_get_register(p->mp_mod_spis, SPIS_RAM_CTRL);
+	p->mp_fld_ram_ctrl_adr = nthw_register_get_field(p->mp_reg_ram_ctrl, SPIS_RAM_CTRL_ADR);
+	p->mp_fld_ram_ctrl_cnt = nthw_register_get_field(p->mp_reg_ram_ctrl, SPIS_RAM_CTRL_CNT);
+
+	p->mp_reg_ram_data = nthw_module_get_register(p->mp_mod_spis, SPIS_RAM_DATA);
+	p->mp_fld_ram_data_data = nthw_register_get_field(p->mp_reg_ram_data, SPIS_RAM_DATA_DATA);
+
+	return 0;
+}
+
+uint32_t nthw_spis_reset(nthw_spis_t *p)
+{
+	nthw_register_update(p->mp_reg_srr);
+	nthw_field_set_val32(p->mp_fld_srr_rst, 0x0A);	/* 0x0A hardcoded value - see doc */
+	nthw_register_flush(p->mp_reg_srr, 1);
+
+	return 0;
+}
+
+uint32_t nthw_spis_enable(nthw_spis_t *p, bool b_enable)
+{
+	nthw_field_update_register(p->mp_fld_cr_en);
+
+	if (b_enable)
+		nthw_field_set_all(p->mp_fld_cr_en);
+
+	else
+		nthw_field_clr_all(p->mp_fld_cr_en);
+
+	nthw_field_flush_register(p->mp_fld_cr_en);
+
+	return 0;
+}
+
+uint32_t nthw_spis_get_rx_fifo_empty(nthw_spis_t *p, bool *pb_empty)
+{
+	assert(pb_empty);
+
+	*pb_empty = nthw_field_get_updated(p->mp_fld_sr_rxempty) ? true : false;
+
+	return 0;
+}
+
+uint32_t nthw_spis_read_rx_fifo(nthw_spis_t *p, uint32_t *p_data)
+{
+	assert(p_data);
+
+	*p_data = nthw_field_get_updated(p->mp_fld_drr_drr);
+
+	return 0;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 26/32] net/ntnic: add i2cm init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (24 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 27/32] net/ntnic: add pca init Serhii Iliushyk
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Create and initialize I2C for FPGA.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../net/ntnic/nthw/core/include/nthw_i2cm.h   |  2 +
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |  7 ++
 drivers/net/ntnic/nthw/core/nthw_i2cm.c       | 82 +++++++++++++++++++
 3 files changed, 91 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
index 53aa3c018e..1bf780d714 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
@@ -44,6 +44,8 @@ struct nt_i2cm {
 
 typedef struct nt_i2cm nthw_i2cm_t;
 
+nthw_i2cm_t *nthw_i2cm_new(void);
+int nthw_i2cm_init(nthw_i2cm_t *p, nthw_fpga_t *p_fpga, int n_i2c_instance);
 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);
 int nthw_i2cm_write16(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint16_t value);
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 73feaa4ebd..bfc66a97d1 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -67,6 +67,13 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 
 	res = nthw_fpga_avr_probe(p_fpga, 0);
 
+	if (res != 0)
+		return res;
+
+	/* Create I2C */
+	p_fpga_info->mp_nthw_agx.p_i2cm = nthw_i2cm_new();
+	res = nthw_i2cm_init(p_fpga_info->mp_nthw_agx.p_i2cm, p_fpga, 0);
+
 	if (res != 0)
 		return res;
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_i2cm.c b/drivers/net/ntnic/nthw/core/nthw_i2cm.c
index f7500b2e93..353fb3f82a 100644
--- a/drivers/net/ntnic/nthw/core/nthw_i2cm.c
+++ b/drivers/net/ntnic/nthw/core/nthw_i2cm.c
@@ -27,6 +27,88 @@
 #define NUM_RETRIES 50U
 #define SLEEP_USECS 100U/* 0.1 ms */
 
+nthw_i2cm_t *nthw_i2cm_new(void)
+{
+	nthw_i2cm_t *p = malloc(sizeof(nthw_i2cm_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_i2cm_t));
+
+	return p;
+}
+
+int nthw_i2cm_init(nthw_i2cm_t *p, nthw_fpga_t *p_fpga, int n_i2c_instance)
+{
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_I2CM, n_i2c_instance);
+
+	if (p == NULL)
+		return mod == NULL ? -1 : 0;
+
+	if (mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: I2C %d: no such instance", p_adapter_id_str,
+			n_i2c_instance);
+		return -1;
+	}
+
+	p->mp_fpga = p_fpga;
+	p->mn_i2c_instance = n_i2c_instance;
+	p->m_mod_i2cm = mod;
+
+	p->mp_reg_prer_low = nthw_module_get_register(p->m_mod_i2cm, I2CM_PRER_LOW);
+	p->mp_fld_prer_low_prer_low =
+		nthw_register_get_field(p->mp_reg_prer_low, I2CM_PRER_LOW_PRER_LOW);
+
+	p->mp_reg_prer_high = nthw_module_get_register(p->m_mod_i2cm, I2CM_PRER_HIGH);
+	p->mp_fld_prer_high_prer_high =
+		nthw_register_get_field(p->mp_reg_prer_high, I2CM_PRER_HIGH_PRER_HIGH);
+
+	p->mp_reg_ctrl = nthw_module_get_register(p->m_mod_i2cm, I2CM_CTRL);
+	p->mp_fld_ctrl_ien = nthw_register_get_field(p->mp_reg_ctrl, I2CM_CTRL_IEN);
+	p->mp_fld_ctrl_en = nthw_register_get_field(p->mp_reg_ctrl, I2CM_CTRL_EN);
+
+	p->mp_reg_data = nthw_module_get_register(p->m_mod_i2cm, I2CM_DATA);
+	p->mp_fld_data_data = nthw_register_get_field(p->mp_reg_data, I2CM_DATA_DATA);
+
+	p->mp_reg_cmd_status = nthw_module_get_register(p->m_mod_i2cm, I2CM_CMD_STATUS);
+	p->mp_fld_cmd_status_cmd_status =
+		nthw_register_get_field(p->mp_reg_cmd_status, I2CM_CMD_STATUS_CMD_STATUS);
+
+	p->mp_reg_select = nthw_module_get_register(p->m_mod_i2cm, I2CM_SELECT);
+	p->mp_fld_select_select = nthw_register_get_field(p->mp_reg_select, I2CM_SELECT_SELECT);
+
+	p->mp_reg_io_exp = nthw_module_get_register(p->m_mod_i2cm, I2CM_IO_EXP);
+	p->mp_fld_io_exp_rst = nthw_register_get_field(p->mp_reg_io_exp, I2CM_IO_EXP_RST);
+	p->mp_fld_io_exp_int_b = nthw_register_get_field(p->mp_reg_io_exp, I2CM_IO_EXP_INT_B);
+
+	nthw_field_get_updated(p->mp_fld_io_exp_rst);
+	nthw_field_set_val_flush32(p->mp_fld_io_exp_rst, 1);
+	nthw_field_set_val_flush32(p->mp_fld_io_exp_rst, 0);
+
+	/* disable interrupt and core */
+	nthw_field_get_updated(p->mp_fld_ctrl_ien);
+	nthw_field_set_val_flush32(p->mp_fld_ctrl_ien, 0);
+	nthw_field_get_updated(p->mp_fld_ctrl_en);
+	nthw_field_set_val_flush32(p->mp_fld_ctrl_en, 0);
+
+	nthw_field_set_val_flush32(p->mp_fld_prer_high_prer_high, 0);
+	nthw_field_set_val_flush32(p->mp_fld_prer_low_prer_low, 225);
+
+	/* Enable interrupt and core */
+	nthw_field_set_val_flush32(p->mp_fld_ctrl_ien, 1);
+	nthw_field_set_val_flush32(p->mp_fld_ctrl_en, 1);
+
+	nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status,
+		NT_I2C_CMD_STOP | NT_I2C_CMD_NACK);
+
+	NT_LOG(INF, NTHW, "%s: %s  init done", p_adapter_id_str, __PRETTY_FUNCTION__);
+	nt_os_wait_usec(10000);
+
+	/* Initialize mutex */
+	rte_spinlock_init(&p->i2cmmutex);
+
+	return 0;
+}
 
 static bool nthw_i2cm_ready(nthw_i2cm_t *p, bool wait_for_ack)
 {
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 27/32] net/ntnic: add pca init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (25 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 26/32] net/ntnic: add i2cm init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 28/32] net/ntnic: add pcal init Serhii Iliushyk
                   ` (6 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Add initialization for I2C mux and LED driver.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../ntnic/nthw/core/include/nthw_pca9532.h    |  3 +++
 .../nthw/core/include/nthw_si5332_si5156.h    |  3 +++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 23 +++++++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_pca9532.c    | 20 ++++++++++++++++
 .../net/ntnic/nthw/core/nthw_si5332_si5156.c  | 18 +++++++++++++++
 5 files changed, 67 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h b/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
index 24da937a18..7cc0008dcb 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
@@ -17,6 +17,9 @@ struct nthw_pca9532 {
 
 typedef struct nthw_pca9532 nthw_pca9532_t;
 
+nthw_pca9532_t *nthw_pca9532_new(void);
+int nthw_pca9532_init(nthw_pca9532_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel);
 void nthw_pca9532_set_led_on(nthw_pca9532_t *p, uint8_t led_pos, bool state_on);
 
 #endif	/* __NTHW_PCA9532_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
index 753717ba8a..9eaf8872e3 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
@@ -19,6 +19,9 @@ struct nthw_pca9849 {
 
 typedef struct nthw_pca9849 nthw_pca9849_t;
 
+nthw_pca9849_t *nthw_pca9849_new(void);
+int nthw_pca9849_init(nthw_pca9849_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address);
+
 int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel);
 
 /*
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index bfc66a97d1..6c5c1cd51e 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -77,6 +77,29 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 	if (res != 0)
 		return res;
 
+	/* Create pca9849 i2c mux */
+	p_fpga_info->mp_nthw_agx.p_pca9849 = nthw_pca9849_new();
+	res = nthw_pca9849_init(p_fpga_info->mp_nthw_agx.p_pca9849,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x71);
+
+	if (res != 0)
+		return res;
+
+	/* Create LED driver */
+	p_fpga_info->mp_nthw_agx.p_pca9532_led = nthw_pca9532_new();
+	res = nthw_pca9532_init(p_fpga_info->mp_nthw_agx.p_pca9532_led,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x60,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			3);
+
+	if (res != 0)
+		return res;
+
+	for (uint8_t i = 0; i < 16; i++)
+		nthw_pca9532_set_led_on(p_fpga_info->mp_nthw_agx.p_pca9532_led, i, false);
+
 	/* Create PCM */
 	p_fpga_info->mp_nthw_agx.p_pcm = nthw_pcm_nt400dxx_new();
 	res = nthw_pcm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_pcm, p_fpga, 0);
diff --git a/drivers/net/ntnic/nthw/core/nthw_pca9532.c b/drivers/net/ntnic/nthw/core/nthw_pca9532.c
index fcf5463fcb..af14cd6d06 100644
--- a/drivers/net/ntnic/nthw/core/nthw_pca9532.c
+++ b/drivers/net/ntnic/nthw/core/nthw_pca9532.c
@@ -15,6 +15,26 @@
 
 static const uint8_t led_sel_reg[4] = { 6, 7, 8, 9 };
 
+nthw_pca9532_t *nthw_pca9532_new(void)
+{
+	nthw_pca9532_t *p = malloc(sizeof(nthw_pca9532_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_pca9532_t));
+
+	return p;
+}
+
+int nthw_pca9532_init(nthw_pca9532_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->mp_ca9849 = pca9849;
+	p->m_mux_channel = mux_channel;
+	return 0;
+}
+
 void nthw_pca9532_set_led_on(nthw_pca9532_t *p, uint8_t led_pos, bool state_on)
 {
 	if (led_pos >= 16) {
diff --git a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
index b4a7b57bcb..eb11ebc67a 100644
--- a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
+++ b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
@@ -13,6 +13,24 @@
 
 #include "nthw_si5332_si5156.h"
 
+nthw_pca9849_t *nthw_pca9849_new(void)
+{
+	nthw_pca9849_t *p = malloc(sizeof(nthw_pca9849_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_pca9849_t));
+
+	return p;
+}
+
+int nthw_pca9849_init(nthw_pca9849_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->m_current_channel = 0;
+	return 0;
+}
+
 int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel)
 {
 	int res;
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 28/32] net/ntnic: add pcal init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (26 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 27/32] net/ntnic: add pca init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 29/32] net/ntnic: add reset PHY init Serhii Iliushyk
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Add initialization for I/O expanders and configure TS settings.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../ntnic/nthw/core/include/nthw_pcal6416a.h  |  3 +
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 69 +++++++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c  | 23 +++++++
 drivers/net/ntnic/nthw/nthw_drv.h             |  1 +
 4 files changed, 96 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
index a718b59a29..e3dadcc8e3 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
@@ -24,6 +24,9 @@ struct nthw_pcal6416a {
 
 typedef struct nthw_pcal6416a nthw_pcal6416a_t;
 
+nthw_pcal6416a_t *nthw_pcal6416a_new(void);
+int nthw_pcal6416a_init(nthw_pcal6416a_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel);
 void nthw_pcal6416a_write(nthw_pcal6416a_t *p, uint8_t pin, uint8_t value);
 void nthw_pcal6416a_read(nthw_pcal6416a_t *p, uint8_t pin, uint8_t *value);
 
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 6c5c1cd51e..c8fd37d0ff 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -86,6 +86,58 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 	if (res != 0)
 		return res;
 
+	/* Create PCAL6416A I/O expander for controlling Nim */
+	p_fpga_info->mp_nthw_agx.p_io_nim = nthw_pcal6416a_new();
+	res = nthw_pcal6416a_init(p_fpga_info->mp_nthw_agx.p_io_nim,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x20,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			3);
+
+	if (res != 0)
+		return res;
+
+	/* Create PCAL6416A I/O expander for controlling TS */
+	p_fpga_info->mp_nthw_agx.p_io_ts = nthw_pcal6416a_new();
+	res = nthw_pcal6416a_init(p_fpga_info->mp_nthw_agx.p_io_ts,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x20,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			2);
+
+	if (res != 0)
+		return res;
+
+	/*
+	 * disable pps out
+	 * TS_EXT1_OUT_EN : Low
+	 */
+	nthw_pcal6416a_write(p_fpga_info->mp_nthw_agx.p_io_ts, 0, 0);
+
+	/*
+	 * Enable DC termination
+	 * TS_EXT1_TERM_DC_E : High
+	 */
+	nthw_pcal6416a_write(p_fpga_info->mp_nthw_agx.p_io_ts, 3, 1);
+
+	/*
+	 * enable 50 ohm termination
+	 * TS_EXT1_TERM50_DIS : low
+	 */
+	nthw_pcal6416a_write(p_fpga_info->mp_nthw_agx.p_io_ts, 2, 0);
+
+	/*
+	 * Normal Threshold
+	 * TS_EXT1_LOW_THRESHOLD: Low
+	 */
+	nthw_pcal6416a_write(p_fpga_info->mp_nthw_agx.p_io_ts, 1, 0);
+
+	/*
+	 * Select FPGA I/O - we want to use TSM Bresenham for time adjustments against PPS time
+	 * reference TS_EXT_ZL30733_EnB: High
+	 */
+	nthw_pcal6416a_write(p_fpga_info->mp_nthw_agx.p_io_ts, 8, 1);
+
 	/* Create LED driver */
 	p_fpga_info->mp_nthw_agx.p_pca9532_led = nthw_pca9532_new();
 	res = nthw_pca9532_init(p_fpga_info->mp_nthw_agx.p_pca9532_led,
@@ -100,6 +152,23 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 	for (uint8_t i = 0; i < 16; i++)
 		nthw_pca9532_set_led_on(p_fpga_info->mp_nthw_agx.p_pca9532_led, i, false);
 
+	/* Enable power supply to NIMs */
+	nthw_pcal6416a_write(p_fpga_info->mp_nthw_agx.p_io_nim, 8, 1);
+	nt_os_wait_usec(100000);/* 100ms */
+
+	/* Check that power supply turned on. Warn if it didn't. */
+	uint8_t port_power_ok;
+	nthw_pcal6416a_read(p_fpga_info->mp_nthw_agx.p_io_nim, 9, &port_power_ok);
+
+	if (port_power_ok != 1) {
+		NT_LOG(ERR,
+			NTHW,
+			"Warning: Power supply for QSFP modules did not turn on - Fuse might be blown.");
+		return -1;
+	}
+
+	NT_LOG(INF, NTHW, "Status of power supply for QSFP modules %u", port_power_ok);
+
 	/* Create PCM */
 	p_fpga_info->mp_nthw_agx.p_pcm = nthw_pcm_nt400dxx_new();
 	res = nthw_pcm_nt400dxx_init(p_fpga_info->mp_nthw_agx.p_pcm, p_fpga, 0);
diff --git a/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c b/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
index dd803ac66d..2fca469497 100644
--- a/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
+++ b/drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
@@ -20,6 +20,29 @@ static const uint8_t config_port[2] = { 0x06, 0x07 };
  * PCAL6416A I/O expander class
  */
 
+nthw_pcal6416a_t *nthw_pcal6416a_new(void)
+{
+	nthw_pcal6416a_t *p = malloc(sizeof(nthw_pcal6416a_t));
+
+	if (p) {
+		memset(p, 0, sizeof(nthw_pcal6416a_t));
+		p->m_config_data[0] = 0xFF;
+		p->m_config_data[1] = 0xFF;
+	}
+
+	return p;
+}
+
+int nthw_pcal6416a_init(nthw_pcal6416a_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->mp_ca9849 = pca9849;
+	p->m_mux_channel = mux_channel;
+	return 0;
+}
+
 void nthw_pcal6416a_write(nthw_pcal6416a_t *p, uint8_t pin, uint8_t value)
 {
 	uint8_t port;
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index ecd3bb9cc4..574dd663ea 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -24,6 +24,7 @@
 typedef struct nthw_agx_s {
 	nthw_i2cm_t *p_i2cm;
 	nthw_pca9849_t *p_pca9849;
+	nthw_pcal6416a_t *p_io_ts;	/* PCAL6416A I/O expander for controlling TS */
 	nthw_pcal6416a_t *p_io_nim;	/* PCAL6416A I/O expander for controlling TS */
 	nthw_pca9532_t *p_pca9532_led;
 	nthw_si5332_t *p_si5332;
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 29/32] net/ntnic: add reset PHY init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (27 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 28/32] net/ntnic: add pcal init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 30/32] net/ntnic: add igam module init Serhii Iliushyk
                   ` (4 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Add initialization and logging for Phy Tile module.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |  39 ++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |  16 +
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   | 598 ++++++++++++++++++
 3 files changed, 653 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
index 68d8455b8d..ba044a5091 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -9,12 +9,16 @@
 #include "nthw_fpga_model.h"
 
 enum mac_pcs_mode_e {
+	MAC_PCS_MODE_8x10_25,
+	MAC_PCS_MODE_2X40,
 	MAC_PCS_MODE_2X100
 };
 
 struct nt_phy_tile {
 	nthw_fpga_t *mp_fpga;
 
+	nthw_module_t *m_mod_phy_tile;
+
 	int mn_phy_tile_instance;
 
 	int mn_fpga_version;
@@ -27,6 +31,7 @@ struct nt_phy_tile {
 	nthw_field_t *mp_fld_port_xcvr_base_busy[2][4];
 	nthw_field_t *mp_fld_port_xcvr_base_cmd[2][4];
 
+	nthw_register_t *mp_reg_port_xcvr_data[2][4];
 	nthw_field_t *mp_fld_port_xcvr_data_data[2][4];
 
 	nthw_register_t *mp_reg_port_eth_base[2];
@@ -34,27 +39,44 @@ struct nt_phy_tile {
 	nthw_field_t *mp_fld_port_eth_base_busy[2];
 	nthw_field_t *mp_fld_port_eth_base_cmd[2];
 
+	nthw_register_t *mp_reg_port_eth_data[2];
 	nthw_field_t *mp_fld_port_eth_data_data[2];
 
 	nthw_register_t *mp_reg_link_summary[2];
 	nthw_field_t *mp_fld_link_summary_nt_phy_link_state[2];
 	nthw_field_t *mp_fld_link_summary_ll_nt_phy_link_state[2];
 	nthw_field_t *mp_fld_link_summary_link_down_cnt[2];
+	nthw_field_t *mp_fld_link_summary_ll_rx_block_lock[2];
+	nthw_field_t *mp_fld_link_summary_ll_rx_am_lock[2];
+	nthw_field_t *mp_fld_link_summary_lh_rx_high_bit_error_rate[2];
 	nthw_field_t *mp_fld_link_summary_lh_received_local_fault[2];
 	nthw_field_t *mp_fld_link_summary_lh_remote_fault[2];
 
+	nthw_register_t *mp_reg_port_status[2];
+	nthw_field_t *mp_fld_port_status_rx_pcs_fully_aligned[2];
 	nthw_field_t *mp_fld_port_status_rx_hi_ber[2];
+	nthw_field_t *mp_fld_port_status_rx_remote_fault[2];
+	nthw_field_t *mp_fld_port_status_rx_local_fault[2];
 	nthw_field_t *mp_fld_port_status_rx_am_lock[2];
 	nthw_field_t *mp_fld_port_status_reset_ackn[2];
 	nthw_field_t *mp_fld_port_status_tx_lanes_stable[2];
+	nthw_field_t *mp_fld_port_status_tx_pll_locked[2];
+	nthw_field_t *mp_fld_port_status_sys_pll_locked[2];
 	nthw_field_t *mp_fld_port_status_tx_reset_ackn[2];
 	nthw_field_t *mp_fld_port_status_rx_reset_ackn[2];
 
+	nthw_register_t *mp_reg_port_config[2];
+	nthw_field_t *mp_fld_port_config_dyn_reset;
 	nthw_field_t *mp_fld_port_config_reset[2];
 	nthw_field_t *mp_fld_port_config_rx_reset[2];
 	nthw_field_t *mp_fld_port_config_tx_reset[2];
+	nthw_field_t *mp_fld_port_config_nt_linkup_latency[2];
+	nthw_field_t *mp_fld_port_config_nt_force_linkdown[2];
+	nthw_field_t *mp_fld_port_config_nt_auto_force_linkdown[2];
 
+	nthw_register_t *mp_reg_port_comp[2];
 	nthw_field_t *mp_fld_port_comp_rx_compensation[2];
+	nthw_field_t *mp_fld_port_comp_tx_compensation[2];
 
 	nthw_register_t *mp_reg_dyn_reconfig_base;
 	nthw_field_t *mp_fld_dyn_reconfig_base_ptr;
@@ -64,17 +86,34 @@ struct nt_phy_tile {
 	nthw_register_t *mp_reg_dyn_reconfig_data;
 	nthw_field_t *mp_fld_dyn_reconfig_data_data;
 
+	nthw_register_t *mp_reg_scratch;
 	nthw_field_t *mp_fld_scratch_data;
 
+	nthw_register_t *mp_reg_dr_cfg;
+	nthw_field_t *mp_fld_reg_dr_cfg_features;
+	nthw_field_t *mp_fld_reg_dr_cfg_tx_flush_level;
+
 	nthw_register_t *mp_reg_dr_cfg_status;
 	nthw_field_t *mp_fld_dr_cfg_status_curr_profile_id;
 	nthw_field_t *mp_fld_dr_cfg_status_in_progress;
 	nthw_field_t *mp_fld_dr_cfg_status_error;
+
+	nthw_register_t *mp_reg_sys_pll;
+	nthw_field_t *mp_fld_sys_pll_set_rdy;
+	nthw_field_t *mp_fld_sys_pll_get_rdy;
+	nthw_field_t *mp_fld_sys_pll_system_pll_lock;
+	nthw_field_t *mp_fld_sys_pll_en_ref_clk_fgt;
+	nthw_field_t *mp_fld_sys_pll_disable_ref_clk_monitor;
+	nthw_field_t *mp_fld_sys_pll_ref_clk_fgt_enabled;
+	nthw_field_t *mp_fld_sys_pll_forward_rst;
+	nthw_field_t *mp_fld_sys_pll_force_rst;
 };
 
 typedef struct nt_phy_tile nthw_phy_tile_t;
 typedef struct nt_phy_tile nt_phy_tile;
 
+nthw_phy_tile_t *nthw_phy_tile_new(void);
+int nthw_phy_tile_init(nthw_phy_tile_t *p, nthw_fpga_t *p_fpga, int mn_phy_tile_instance);
 void nthw_phy_tile_set_tx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert);
 void nthw_phy_tile_set_rx_pol_inv(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane, bool invert);
 void nthw_phy_tile_set_host_loopback(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index c8fd37d0ff..35cbaea81e 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -181,7 +181,23 @@ static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 
 static int nthw_fpga_rst_nt400dxx_reset(struct fpga_info_s *p_fpga_info)
 {
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	nthw_fpga_t *p_fpga = NULL;
+
+	p_fpga = p_fpga_info->mp_fpga;
+
 	assert(p_fpga_info);
+
+	NT_LOG(DBG, NTHW, "%s: %s: BEGIN", p_adapter_id_str, __PRETTY_FUNCTION__);
+
+	/* Create Phy Tile module */
+	p_fpga_info->mp_nthw_agx.p_phy_tile = nthw_phy_tile_new();
+
+	if (nthw_phy_tile_init(p_fpga_info->mp_nthw_agx.p_phy_tile, p_fpga, 0)) {
+		NT_LOG(ERR, NTHW, "%s: Failed to create Phy Tile Module", p_adapter_id_str);
+		return -1;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
index a8c2d03be9..f78d8263f5 100644
--- a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -44,6 +44,604 @@ static const uint32_t eth_soft_csr1 = 0x200;
 static const uint32_t eth_soft_csr2 = 0x204;
 static const uint32_t eth_soft_csr3 = 0x208;
 
+nthw_phy_tile_t *nthw_phy_tile_new(void)
+{
+	nthw_phy_tile_t *p = malloc(sizeof(nthw_phy_tile_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_phy_tile_t));
+
+	return p;
+}
+
+int nthw_phy_tile_init(nthw_phy_tile_t *p, nthw_fpga_t *p_fpga, int mn_phy_tile_instance)
+{
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_PHY_TILE, mn_phy_tile_instance);
+
+	if (p == NULL)
+		return mod == NULL ? -1 : 0;
+
+	if (mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: PHY_TILE %d: no such instance", p_adapter_id_str,
+			mn_phy_tile_instance);
+		return -1;
+	}
+
+	p->mp_fpga = p_fpga;
+	p->mn_phy_tile_instance = mn_phy_tile_instance;
+
+	p->m_mod_phy_tile = mod;
+
+	p->mn_fpga_revision = p_fpga->mn_fpga_revision;
+	p->mn_fpga_version = p_fpga->mn_fpga_version;
+
+	switch (p_fpga->mn_product_id) {
+	case 9569:
+	case 9574:
+		p->mac_pcs_mode = MAC_PCS_MODE_2X100;
+		break;
+
+	default:
+		NT_LOG_DBG(DBG, NTHW, "unknown product ID: %u", p_fpga->mn_product_id);
+		break;
+	}
+
+	/* Port 0 Base 0..3 */
+	p->mp_reg_port_xcvr_base[0][0] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_0_BASE);
+	p->mp_fld_port_xcvr_base_ptr[0][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][0],
+			PHY_TILE_PORT_0_XCVR_0_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[0][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][0],
+			PHY_TILE_PORT_0_XCVR_0_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[0][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][0],
+			PHY_TILE_PORT_0_XCVR_0_BASE_CMD);
+
+	p->mp_reg_port_xcvr_base[0][1] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_1_BASE);
+	p->mp_fld_port_xcvr_base_ptr[0][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][1],
+			PHY_TILE_PORT_0_XCVR_1_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[0][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][1],
+			PHY_TILE_PORT_0_XCVR_1_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[0][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][1],
+			PHY_TILE_PORT_0_XCVR_1_BASE_CMD);
+
+	p->mp_reg_port_xcvr_base[0][2] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_2_BASE);
+	p->mp_fld_port_xcvr_base_ptr[0][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][2],
+			PHY_TILE_PORT_0_XCVR_2_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[0][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][2],
+			PHY_TILE_PORT_0_XCVR_2_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[0][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][2],
+			PHY_TILE_PORT_0_XCVR_2_BASE_CMD);
+
+	p->mp_reg_port_xcvr_base[0][3] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_3_BASE);
+	p->mp_fld_port_xcvr_base_ptr[0][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][3],
+			PHY_TILE_PORT_0_XCVR_3_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[0][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][3],
+			PHY_TILE_PORT_0_XCVR_3_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[0][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[0][3],
+			PHY_TILE_PORT_0_XCVR_3_BASE_CMD);
+
+	/* Port 0 Data 0..3 */
+	p->mp_reg_port_xcvr_data[0][0] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_0_DATA);
+	p->mp_fld_port_xcvr_data_data[0][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[0][0],
+			PHY_TILE_PORT_0_XCVR_0_DATA_DATA);
+
+	p->mp_reg_port_xcvr_data[0][1] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_1_DATA);
+	p->mp_fld_port_xcvr_data_data[0][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[0][1],
+			PHY_TILE_PORT_0_XCVR_1_DATA_DATA);
+
+	p->mp_reg_port_xcvr_data[0][2] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_2_DATA);
+	p->mp_fld_port_xcvr_data_data[0][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[0][2],
+			PHY_TILE_PORT_0_XCVR_2_DATA_DATA);
+
+	p->mp_reg_port_xcvr_data[0][3] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_XCVR_3_DATA);
+	p->mp_fld_port_xcvr_data_data[0][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[0][3],
+			PHY_TILE_PORT_0_XCVR_3_DATA_DATA);
+
+	/* Port 1 Base 0..3 */
+	p->mp_reg_port_xcvr_base[1][0] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_0_BASE);
+	p->mp_fld_port_xcvr_base_ptr[1][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][0],
+			PHY_TILE_PORT_1_XCVR_0_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[1][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][0],
+			PHY_TILE_PORT_1_XCVR_0_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[1][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][0],
+			PHY_TILE_PORT_1_XCVR_0_BASE_CMD);
+
+	p->mp_reg_port_xcvr_base[1][1] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_1_BASE);
+	p->mp_fld_port_xcvr_base_ptr[1][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][1],
+			PHY_TILE_PORT_1_XCVR_1_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[1][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][1],
+			PHY_TILE_PORT_1_XCVR_1_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[1][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][1],
+			PHY_TILE_PORT_1_XCVR_1_BASE_CMD);
+
+	p->mp_reg_port_xcvr_base[1][2] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_2_BASE);
+	p->mp_fld_port_xcvr_base_ptr[1][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][2],
+			PHY_TILE_PORT_1_XCVR_2_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[1][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][2],
+			PHY_TILE_PORT_1_XCVR_2_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[1][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][2],
+			PHY_TILE_PORT_1_XCVR_2_BASE_CMD);
+
+	p->mp_reg_port_xcvr_base[1][3] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_3_BASE);
+	p->mp_fld_port_xcvr_base_ptr[1][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][3],
+			PHY_TILE_PORT_1_XCVR_3_BASE_PTR);
+	p->mp_fld_port_xcvr_base_busy[1][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][3],
+			PHY_TILE_PORT_1_XCVR_3_BASE_BUSY);
+	p->mp_fld_port_xcvr_base_cmd[1][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_base[1][3],
+			PHY_TILE_PORT_1_XCVR_3_BASE_CMD);
+
+	/* Port 1 Data 0..3 */
+	p->mp_reg_port_xcvr_data[1][0] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_0_DATA);
+	p->mp_fld_port_xcvr_data_data[1][0] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[1][0],
+			PHY_TILE_PORT_1_XCVR_0_DATA_DATA);
+
+	p->mp_reg_port_xcvr_data[1][1] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_1_DATA);
+	p->mp_fld_port_xcvr_data_data[1][1] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[1][1],
+			PHY_TILE_PORT_1_XCVR_1_DATA_DATA);
+
+	p->mp_reg_port_xcvr_data[1][2] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_2_DATA);
+	p->mp_fld_port_xcvr_data_data[1][2] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[1][2],
+			PHY_TILE_PORT_1_XCVR_2_DATA_DATA);
+
+	p->mp_reg_port_xcvr_data[1][3] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_XCVR_3_DATA);
+	p->mp_fld_port_xcvr_data_data[1][3] =
+		nthw_register_get_field(p->mp_reg_port_xcvr_data[1][3],
+			PHY_TILE_PORT_1_XCVR_3_DATA_DATA);
+
+	if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 3)) {
+		if (p->mac_pcs_mode == MAC_PCS_MODE_2X100 ||
+			p->mac_pcs_mode == MAC_PCS_MODE_8x10_25) {
+			/* DYN_RECONFIG */
+			p->mp_reg_dyn_reconfig_base =
+				nthw_module_get_register(p->m_mod_phy_tile,
+					PHY_TILE_DYN_RECONFIG_BASE);
+			p->mp_fld_dyn_reconfig_base_ptr =
+				nthw_register_get_field(p->mp_reg_dyn_reconfig_base,
+					PHY_TILE_DYN_RECONFIG_BASE_PTR);
+			p->mp_fld_dyn_reconfig_base_busy =
+				nthw_register_get_field(p->mp_reg_dyn_reconfig_base,
+					PHY_TILE_DYN_RECONFIG_BASE_BUSY);
+			p->mp_fld_dyn_reconfig_base_cmd =
+				nthw_register_get_field(p->mp_reg_dyn_reconfig_base,
+					PHY_TILE_DYN_RECONFIG_BASE_CMD);
+
+			p->mp_reg_dyn_reconfig_data =
+				nthw_module_get_register(p->m_mod_phy_tile,
+					PHY_TILE_DYN_RECONFIG_DATA);
+			p->mp_fld_dyn_reconfig_data_data =
+				nthw_register_get_field(p->mp_reg_dyn_reconfig_data,
+					PHY_TILE_DYN_RECONFIG_DATA_DATA);
+		}
+
+		/* Port 0 Eth Base */
+		p->mp_reg_port_eth_base[0] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_ETH_0_BASE);
+		p->mp_fld_port_eth_base_ptr[0] =
+			nthw_register_get_field(p->mp_reg_port_eth_base[0],
+				PHY_TILE_PORT_0_ETH_0_BASE_PTR);
+		p->mp_fld_port_eth_base_busy[0] =
+			nthw_register_get_field(p->mp_reg_port_eth_base[0],
+				PHY_TILE_PORT_0_ETH_0_BASE_BUSY);
+		p->mp_fld_port_eth_base_cmd[0] =
+			nthw_register_get_field(p->mp_reg_port_eth_base[0],
+				PHY_TILE_PORT_0_ETH_0_BASE_CMD);
+
+		/* Port 1 Eth Base */
+		p->mp_reg_port_eth_base[1] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_ETH_0_BASE);
+		p->mp_fld_port_eth_base_ptr[1] =
+			nthw_register_get_field(p->mp_reg_port_eth_base[1],
+				PHY_TILE_PORT_1_ETH_0_BASE_PTR);
+		p->mp_fld_port_eth_base_busy[1] =
+			nthw_register_get_field(p->mp_reg_port_eth_base[1],
+				PHY_TILE_PORT_1_ETH_0_BASE_BUSY);
+		p->mp_fld_port_eth_base_cmd[1] =
+			nthw_register_get_field(p->mp_reg_port_eth_base[1],
+				PHY_TILE_PORT_1_ETH_0_BASE_CMD);
+
+		/* Port 0 Eth Data */
+		p->mp_reg_port_eth_data[0] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_0_ETH_0_DATA);
+		p->mp_fld_port_eth_data_data[0] =
+			nthw_register_get_field(p->mp_reg_port_eth_data[0],
+				PHY_TILE_PORT_0_ETH_0_DATA_DATA);
+
+		/* Port 1 Eth Data 0..3 */
+		p->mp_reg_port_eth_data[1] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_1_ETH_0_DATA);
+		p->mp_fld_port_eth_data_data[1] =
+			nthw_register_get_field(p->mp_reg_port_eth_data[1],
+				PHY_TILE_PORT_1_ETH_0_DATA_DATA);
+	}
+
+	p->mp_reg_link_summary[0] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_LINK_SUMMARY_0);
+	p->mp_fld_link_summary_nt_phy_link_state[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_NT_PHY_LINK_STATE);
+	p->mp_fld_link_summary_ll_nt_phy_link_state[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LL_PHY_LINK_STATE);
+	p->mp_fld_link_summary_link_down_cnt[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LINK_DOWN_CNT);
+	p->mp_fld_link_summary_ll_rx_block_lock[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LL_RX_BLOCK_LOCK);
+	p->mp_fld_link_summary_ll_rx_am_lock[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LL_RX_AM_LOCK);
+	p->mp_fld_link_summary_lh_rx_high_bit_error_rate[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LH_RX_HIGH_BIT_ERROR_RATE);
+	p->mp_fld_link_summary_lh_received_local_fault[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LH_RECEIVED_LOCAL_FAULT);
+	p->mp_fld_link_summary_lh_remote_fault[0] =
+		nthw_register_get_field(p->mp_reg_link_summary[0],
+			PHY_TILE_LINK_SUMMARY_0_LH_REMOTE_FAULT);
+
+	p->mp_reg_link_summary[1] =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_LINK_SUMMARY_1);
+	p->mp_fld_link_summary_nt_phy_link_state[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_NT_PHY_LINK_STATE);
+	p->mp_fld_link_summary_ll_nt_phy_link_state[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LL_PHY_LINK_STATE);
+	p->mp_fld_link_summary_link_down_cnt[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LINK_DOWN_CNT);
+	p->mp_fld_link_summary_ll_rx_block_lock[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LL_RX_BLOCK_LOCK);
+	p->mp_fld_link_summary_ll_rx_am_lock[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LL_RX_AM_LOCK);
+	p->mp_fld_link_summary_lh_rx_high_bit_error_rate[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LH_RX_HIGH_BIT_ERROR_RATE);
+	p->mp_fld_link_summary_lh_received_local_fault[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LH_RECEIVED_LOCAL_FAULT);
+	p->mp_fld_link_summary_lh_remote_fault[1] =
+		nthw_register_get_field(p->mp_reg_link_summary[1],
+			PHY_TILE_LINK_SUMMARY_1_LH_REMOTE_FAULT);
+
+	if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 4)) {
+		p->mp_reg_port_status[0] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_STATUS_0);
+		p->mp_fld_port_status_rx_pcs_fully_aligned[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RX_PCS_FULLY_ALIGNED);
+		p->mp_fld_port_status_rx_hi_ber[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RX_HI_BER);
+		p->mp_fld_port_status_rx_remote_fault[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RX_REMOTE_FAULT);
+		p->mp_fld_port_status_rx_local_fault[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RX_LOCAL_FAULT);
+		p->mp_fld_port_status_rx_am_lock[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RX_AM_LOCK);
+		p->mp_fld_port_status_reset_ackn[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RESET_ACK_N);
+		p->mp_fld_port_status_tx_lanes_stable[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_TX_LANES_STABLE);
+		p->mp_fld_port_status_tx_pll_locked[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_TX_PLL_LOCKED);
+		p->mp_fld_port_status_sys_pll_locked[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_SYS_PLL_LOCKED);
+		p->mp_fld_port_status_tx_reset_ackn[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_TX_RESET_ACK_N);
+		p->mp_fld_port_status_rx_reset_ackn[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_0_RX_RESET_ACK_N);
+
+		p->mp_reg_port_status[1] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_STATUS_1);
+		p->mp_fld_port_status_rx_pcs_fully_aligned[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RX_PCS_FULLY_ALIGNED);
+		p->mp_fld_port_status_rx_hi_ber[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RX_HI_BER);
+		p->mp_fld_port_status_rx_remote_fault[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RX_REMOTE_FAULT);
+		p->mp_fld_port_status_rx_local_fault[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RX_LOCAL_FAULT);
+		p->mp_fld_port_status_rx_am_lock[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RX_AM_LOCK);
+		p->mp_fld_port_status_reset_ackn[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RESET_ACK_N);
+		p->mp_fld_port_status_tx_lanes_stable[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_TX_LANES_STABLE);
+		p->mp_fld_port_status_tx_pll_locked[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_TX_PLL_LOCKED);
+		p->mp_fld_port_status_sys_pll_locked[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_SYS_PLL_LOCKED);
+		p->mp_fld_port_status_tx_reset_ackn[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_TX_RESET_ACK_N);
+		p->mp_fld_port_status_rx_reset_ackn[1] =
+			nthw_register_get_field(p->mp_reg_port_status[1],
+				PHY_TILE_PORT_STATUS_1_RX_RESET_ACK_N);
+
+	} else {
+		p->mp_reg_port_status[0] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_STATUS);
+		p->mp_fld_port_status_rx_pcs_fully_aligned[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_PCS_FULLY_ALIGNED_0);
+		p->mp_fld_port_status_rx_hi_ber[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_HI_BER_0);
+		p->mp_fld_port_status_rx_remote_fault[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_REMOTE_FAULT_0);
+		p->mp_fld_port_status_rx_local_fault[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_LOCAL_FAULT_0);
+		p->mp_fld_port_status_rx_am_lock[0] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_AM_LOCK_0);
+
+		p->mp_fld_port_status_rx_pcs_fully_aligned[1] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_PCS_FULLY_ALIGNED_1);
+		p->mp_fld_port_status_rx_hi_ber[1] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_HI_BER_1);
+		p->mp_fld_port_status_rx_remote_fault[1] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_REMOTE_FAULT_1);
+		p->mp_fld_port_status_rx_local_fault[1] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_LOCAL_FAULT_1);
+		p->mp_fld_port_status_rx_am_lock[1] =
+			nthw_register_get_field(p->mp_reg_port_status[0],
+				PHY_TILE_PORT_STATUS_RX_AM_LOCK_1);
+
+		p->mp_fld_port_status_reset_ackn[0] = NULL;
+		p->mp_fld_port_status_tx_lanes_stable[0] = NULL;
+		p->mp_fld_port_status_tx_pll_locked[0] = NULL;
+		p->mp_fld_port_status_sys_pll_locked[0] = NULL;
+		p->mp_fld_port_status_tx_reset_ackn[0] = NULL;
+		p->mp_fld_port_status_rx_reset_ackn[0] = NULL;
+
+		p->mp_fld_port_status_reset_ackn[1] = NULL;
+		p->mp_fld_port_status_tx_lanes_stable[1] = NULL;
+		p->mp_fld_port_status_tx_pll_locked[1] = NULL;
+		p->mp_fld_port_status_sys_pll_locked[1] = NULL;
+		p->mp_fld_port_status_tx_reset_ackn[1] = NULL;
+		p->mp_fld_port_status_rx_reset_ackn[1] = NULL;
+	}
+
+	if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 4)) {
+		p->mp_reg_port_config[0] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_CONFIG_0);
+		p->mp_fld_port_config_reset[0] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_0_RST);
+		p->mp_fld_port_config_rx_reset[0] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_0_RX_RST);
+		p->mp_fld_port_config_tx_reset[0] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_0_TX_RST);
+		p->mp_fld_port_config_nt_linkup_latency[0] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_0_NT_LINKUP_LATENCY);
+		p->mp_fld_port_config_nt_force_linkdown[0] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_0_NT_FORCE_LINK_DOWN);
+
+		if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 10)) {
+			p->mp_fld_port_config_nt_auto_force_linkdown[0] =
+				nthw_register_query_field(p->mp_reg_port_config[0],
+					PHY_TILE_PORT_CONFIG_0_NT_AUTO_FORCE_LINK_DOWN);
+		}
+
+		p->mp_reg_port_config[1] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_CONFIG_1);
+		p->mp_fld_port_config_reset[1] =
+			nthw_register_query_field(p->mp_reg_port_config[1],
+				PHY_TILE_PORT_CONFIG_1_RST);
+		p->mp_fld_port_config_rx_reset[1] =
+			nthw_register_query_field(p->mp_reg_port_config[1],
+				PHY_TILE_PORT_CONFIG_1_RX_RST);
+		p->mp_fld_port_config_tx_reset[1] =
+			nthw_register_query_field(p->mp_reg_port_config[1],
+				PHY_TILE_PORT_CONFIG_1_TX_RST);
+		p->mp_fld_port_config_nt_linkup_latency[1] =
+			nthw_register_query_field(p->mp_reg_port_config[1],
+				PHY_TILE_PORT_CONFIG_1_NT_LINKUP_LATENCY);
+		p->mp_fld_port_config_nt_force_linkdown[1] =
+			nthw_register_query_field(p->mp_reg_port_config[1],
+				PHY_TILE_PORT_CONFIG_1_NT_FORCE_LINK_DOWN);
+
+		if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 10)) {
+			p->mp_fld_port_config_nt_auto_force_linkdown[1] =
+				nthw_register_query_field(p->mp_reg_port_config[1],
+					PHY_TILE_PORT_CONFIG_1_NT_AUTO_FORCE_LINK_DOWN);
+		}
+
+	} else {
+		p->mp_reg_port_config[0] =
+			nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_CONFIG);
+		p->mp_fld_port_config_dyn_reset =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_DYN_RESET);
+		p->mp_fld_port_config_reset[0] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_RESET_0);
+		p->mp_fld_port_config_rx_reset[0] =
+			nthw_register_get_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_RX_RESET_0);
+		p->mp_fld_port_config_tx_reset[0] =
+			nthw_register_get_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_TX_RESET_0);
+		p->mp_fld_port_config_reset[1] =
+			nthw_register_query_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_RESET_1);
+		p->mp_fld_port_config_rx_reset[1] =
+			nthw_register_get_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_RX_RESET_1);
+		p->mp_fld_port_config_tx_reset[1] =
+			nthw_register_get_field(p->mp_reg_port_config[0],
+				PHY_TILE_PORT_CONFIG_TX_RESET_1);
+	}
+
+	p->mp_reg_port_comp[0] = nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_COMP_0);
+	p->mp_fld_port_comp_rx_compensation[0] =
+		nthw_register_get_field(p->mp_reg_port_comp[0],
+			PHY_TILE_PORT_COMP_0_RX_COMPENSATION);
+	p->mp_fld_port_comp_tx_compensation[0] =
+		nthw_register_get_field(p->mp_reg_port_comp[0],
+			PHY_TILE_PORT_COMP_0_TX_COMPENSATION);
+	p->mp_reg_port_comp[1] = nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_PORT_COMP_1);
+	p->mp_fld_port_comp_rx_compensation[1] =
+		nthw_register_get_field(p->mp_reg_port_comp[1],
+			PHY_TILE_PORT_COMP_1_RX_COMPENSATION);
+	p->mp_fld_port_comp_tx_compensation[1] =
+		nthw_register_get_field(p->mp_reg_port_comp[1],
+			PHY_TILE_PORT_COMP_1_TX_COMPENSATION);
+
+	p->mp_reg_scratch = nthw_module_query_register(p->m_mod_phy_tile, PHY_TILE_SCRATCH);
+
+	if (p->mp_reg_scratch) {
+		p->mp_fld_scratch_data =
+			nthw_register_query_field(p->mp_reg_scratch, PHY_TILE_SCRATCH_DATA);
+	}
+
+	if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 4)) {
+		p->mp_reg_dr_cfg = nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_DR_CFG);
+		p->mp_fld_port_config_dyn_reset =
+			nthw_register_get_field(p->mp_reg_dr_cfg, PHY_TILE_DR_CFG_DYN_RST);
+
+		if (!p->mp_reg_scratch) {
+			p->mp_fld_scratch_data =
+				nthw_register_get_field(p->mp_reg_dr_cfg, PHY_TILE_DR_CFG_SCRATCH);
+		}
+
+		p->mp_fld_reg_dr_cfg_features =
+			nthw_register_get_field(p->mp_reg_dr_cfg, PHY_TILE_DR_CFG_FEATURES);
+
+		if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 10)) {
+			p->mp_fld_reg_dr_cfg_tx_flush_level =
+				nthw_register_get_field(p->mp_reg_dr_cfg,
+					PHY_TILE_DR_CFG_TX_FLUSH_LEVEL);
+		}
+	}
+
+	p->mp_reg_dr_cfg_status =
+		nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_DR_CFG_STATUS);
+	p->mp_fld_dr_cfg_status_curr_profile_id =
+		nthw_register_get_field(p->mp_reg_dr_cfg_status,
+			PHY_TILE_DR_CFG_STATUS_CURR_PROFILE_ID);
+	p->mp_fld_dr_cfg_status_in_progress =
+		nthw_register_get_field(p->mp_reg_dr_cfg_status,
+			PHY_TILE_DR_CFG_STATUS_IN_PROGRESS);
+	p->mp_fld_dr_cfg_status_error =
+		nthw_register_get_field(p->mp_reg_dr_cfg_status, PHY_TILE_DR_CFG_STATUS_ERROR);
+
+	if (nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 7)) {
+		p->mp_reg_sys_pll = nthw_module_get_register(p->m_mod_phy_tile, PHY_TILE_SYS_PLL);
+		p->mp_fld_sys_pll_set_rdy =
+			nthw_register_get_field(p->mp_reg_sys_pll, PHY_TILE_SYS_PLL_SET_RDY);
+		p->mp_fld_sys_pll_get_rdy =
+			nthw_register_get_field(p->mp_reg_sys_pll, PHY_TILE_SYS_PLL_GET_RDY);
+		p->mp_fld_sys_pll_system_pll_lock =
+			nthw_register_get_field(p->mp_reg_sys_pll,
+				PHY_TILE_SYS_PLL_SYSTEMPLL_LOCK);
+		p->mp_fld_sys_pll_en_ref_clk_fgt =
+			nthw_register_get_field(p->mp_reg_sys_pll, PHY_TILE_SYS_PLL_EN_REFCLK_FGT);
+		p->mp_fld_sys_pll_disable_ref_clk_monitor =
+			nthw_register_get_field(p->mp_reg_sys_pll,
+				PHY_TILE_SYS_PLL_DISABLE_REFCLK_MONITOR);
+		p->mp_fld_sys_pll_ref_clk_fgt_enabled =
+			nthw_register_get_field(p->mp_reg_sys_pll,
+				PHY_TILE_SYS_PLL_REFCLK_FGT_ENABLED);
+		p->mp_fld_sys_pll_forward_rst =
+			nthw_register_get_field(p->mp_reg_sys_pll, PHY_TILE_SYS_PLL_FORWARD_RST);
+		p->mp_fld_sys_pll_force_rst =
+			nthw_register_get_field(p->mp_reg_sys_pll, PHY_TILE_SYS_PLL_FORCE_RST);
+
+	} else {
+		p->mp_fld_sys_pll_set_rdy = NULL;
+		p->mp_fld_sys_pll_get_rdy = NULL;
+		p->mp_fld_sys_pll_system_pll_lock = NULL;
+		p->mp_fld_sys_pll_en_ref_clk_fgt = NULL;
+		p->mp_fld_sys_pll_disable_ref_clk_monitor = NULL;
+		p->mp_fld_sys_pll_ref_clk_fgt_enabled = NULL;
+		p->mp_fld_sys_pll_forward_rst = NULL;
+		p->mp_fld_sys_pll_force_rst = NULL;
+	}
+
+	return 0;
+}
+
 uint8_t nthw_phy_tile_get_no_intfs(nthw_phy_tile_t *p)
 {
 	switch (p->mac_pcs_mode) {
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 30/32] net/ntnic: add igam module init
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (28 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 29/32] net/ntnic: add reset PHY init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 31/32] net/ntnic: init IGAM and config PLL for FPGA Serhii Iliushyk
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

Create and initialize IGAM module.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/meson.build                 |  1 +
 .../net/ntnic/nthw/core/include/nthw_igam.h   | 37 +++++++++++
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |  4 ++
 drivers/net/ntnic/nthw/core/nthw_igam.c       | 62 +++++++++++++++++++
 4 files changed, 104 insertions(+)
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_igam.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_igam.c

diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 7e326a3e1d..30a92130b5 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -56,6 +56,7 @@ sources = files(
         'nthw/core/nthw_gpio_phy.c',
         'nthw/core/nthw_hif.c',
         'nthw/core/nthw_i2cm.c',
+        'nthw/core/nthw_igam.c',
         'nthw/core/nthw_iic.c',
         'nthw/core/nthw_mac_pcs.c',
         'nthw/core/nthw_pcie3.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_igam.h b/drivers/net/ntnic/nthw/core/include/nthw_igam.h
new file mode 100644
index 0000000000..e78637a331
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_igam.h
@@ -0,0 +1,37 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_IGAM_H__
+#define __NTHW_IGAM_H__
+
+#include "nthw_fpga_model.h"
+
+struct nt_igam {
+	nthw_fpga_t *mp_fpga;
+
+	nthw_module_t *mp_mod_igam;
+
+	int mn_igam_instance;
+
+	nthw_register_t *mp_reg_base;
+	nthw_field_t *mp_fld_base_ptr;
+	nthw_field_t *mp_fld_base_busy;
+	nthw_field_t *mp_fld_base_cmd;
+
+	nthw_register_t *mp_reg_data;
+	nthw_field_t *mp_fld_data_data;
+
+	/* CTRL From version 0.1 */
+	nthw_register_t *mp_reg_ctrl;
+	nthw_field_t *mp_fld_ctrl_forward_rst;
+};
+
+typedef struct nt_igam nthw_igam_t;
+typedef struct nt_igam nthw_igam;
+
+nthw_igam_t *nthw_igam_new(void);
+int nthw_igam_init(nthw_igam_t *p, nthw_fpga_t *p_fpga, int mn_igam_instance);
+
+#endif	/*  __NTHW_IGAM_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 35cbaea81e..95394b9c8f 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -9,6 +9,7 @@
 #include "nthw_fpga.h"
 #include "nthw_hif.h"
 #include "ntnic_mod_reg.h"
+#include "nthw_igam.h"
 
 static int nthw_fpga_rst_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 {
@@ -198,6 +199,9 @@ static int nthw_fpga_rst_nt400dxx_reset(struct fpga_info_s *p_fpga_info)
 		return -1;
 	}
 
+	nthw_igam_t *p_igam = nthw_igam_new();
+	nthw_igam_init(p_igam, p_fpga, 0);
+
 	return 0;
 }
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_igam.c b/drivers/net/ntnic/nthw/core/nthw_igam.c
new file mode 100644
index 0000000000..5dc7e36c7b
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_igam.c
@@ -0,0 +1,62 @@
+/*
+ * 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_igam.h"
+
+nthw_igam_t *nthw_igam_new(void)
+{
+	nthw_igam_t *p = malloc(sizeof(nthw_igam_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_igam_t));
+
+	return p;
+}
+
+int nthw_igam_init(nthw_igam_t *p, nthw_fpga_t *p_fpga, int mn_igam_instance)
+{
+	const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+	nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_IGAM, mn_igam_instance);
+
+	if (p == NULL)
+		return mod == NULL ? -1 : 0;
+
+	if (mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: IGAM %d: no such instance", p_adapter_id_str,
+			mn_igam_instance);
+		return -1;
+	}
+
+	p->mp_fpga = p_fpga;
+	p->mn_igam_instance = mn_igam_instance;
+
+	p->mp_mod_igam = mod;
+
+	p->mp_reg_base = nthw_module_get_register(p->mp_mod_igam, IGAM_BASE);
+	p->mp_fld_base_ptr = nthw_register_get_field(p->mp_reg_base, IGAM_BASE_PTR);
+	p->mp_fld_base_busy = nthw_register_get_field(p->mp_reg_base, IGAM_BASE_BUSY);
+	p->mp_fld_base_cmd = nthw_register_get_field(p->mp_reg_base, IGAM_BASE_CMD);
+
+	p->mp_reg_data = nthw_module_get_register(p->mp_mod_igam, IGAM_DATA);
+	p->mp_fld_data_data = nthw_register_get_field(p->mp_reg_data, IGAM_DATA_DATA);
+
+	p->mp_reg_ctrl = nthw_module_query_register(p->mp_mod_igam, IGAM_CTRL);
+
+	if (p->mp_reg_ctrl) {
+		p->mp_fld_ctrl_forward_rst =
+			nthw_register_get_field(p->mp_reg_ctrl, IGAM_CTRL_FORWARD_RST);
+
+	} else {
+		p->mp_fld_ctrl_forward_rst = NULL;
+	}
+
+	return 0;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 31/32] net/ntnic: init IGAM and config PLL for FPGA
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (29 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 30/32] net/ntnic: add igam module init Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:03 ` [PATCH v1 32/32] net/ntnic: revert untrusted loop bound Serhii Iliushyk
                   ` (2 subsequent siblings)
  33 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

From: Danylo Vodopianov <dvo-plv@napatech.com>

- Initialize IGAM module and check for its presence.
- Enable system PLL using IGAM and check for PLL lock status.
- Reset and configure TS PLL and check for lock status.
- Force HIF soft reset and de-assert platform reset.
- Enable RAB1 and RAB2 and perform RAB initialization and flush.
- Check system PLL readiness using PHY_TILE and handle PLL lock status.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../net/ntnic/nthw/core/include/nthw_hif.h    |   1 +
 .../net/ntnic/nthw/core/include/nthw_igam.h   |   3 +
 .../nthw/core/include/nthw_pcm_nt400dxx.h     |   4 +
 .../ntnic/nthw/core/include/nthw_phy_tile.h   |   8 +
 .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   | 211 ++++++++++++++++++
 drivers/net/ntnic/nthw/core/nthw_hif.c        |  10 +
 drivers/net/ntnic/nthw/core/nthw_igam.c       |  31 +++
 .../net/ntnic/nthw/core/nthw_pcm_nt400dxx.c   |  24 ++
 drivers/net/ntnic/nthw/core/nthw_phy_tile.c   |  61 +++++
 drivers/net/ntnic/nthw/nthw_drv.h             |   2 +
 10 files changed, 355 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/include/nthw_hif.h b/drivers/net/ntnic/nthw/core/include/nthw_hif.h
index deb9ed04e8..7d5e1f1310 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_hif.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_hif.h
@@ -135,6 +135,7 @@ void nthw_hif_delete(nthw_hif_t *p);
 int nthw_hif_init(nthw_hif_t *p, nthw_fpga_t *p_fpga, int n_instance);
 
 int nthw_hif_trigger_sample_time(nthw_hif_t *p);
+int nthw_hif_force_soft_reset(nthw_hif_t *p);
 
 int nthw_hif_stat_req_enable(nthw_hif_t *p);
 int nthw_hif_stat_req_disable(nthw_hif_t *p);
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_igam.h b/drivers/net/ntnic/nthw/core/include/nthw_igam.h
index e78637a331..fed462cd34 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_igam.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_igam.h
@@ -33,5 +33,8 @@ typedef struct nt_igam nthw_igam;
 
 nthw_igam_t *nthw_igam_new(void);
 int nthw_igam_init(nthw_igam_t *p, nthw_fpga_t *p_fpga, int mn_igam_instance);
+uint32_t nthw_igam_read(nthw_igam_t *p, uint32_t address);
+void nthw_igam_write(nthw_igam_t *p, uint32_t address, uint32_t data);
+void nthw_igam_set_ctrl_forward_rst(nthw_igam_t *p, uint32_t value);
 
 #endif	/*  __NTHW_IGAM_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
index 23865f466b..47d2670cf5 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
@@ -32,5 +32,9 @@ typedef struct nthw_pcm_nt400_dxx nthw_pcm_nt400_dxx;
 
 nthw_pcm_nt400dxx_t *nthw_pcm_nt400dxx_new(void);
 int nthw_pcm_nt400dxx_init(nthw_pcm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_instance);
+void nthw_pcm_nt400dxx_set_ts_pll_recal(nthw_pcm_nt400dxx_t *p, uint32_t val);
+bool nthw_pcm_nt400dxx_get_ts_pll_locked_stat(nthw_pcm_nt400dxx_t *p);
+bool nthw_pcm_nt400dxx_get_ts_pll_locked_latch(nthw_pcm_nt400dxx_t *p);
+void nthw_pcm_nt400dxx_set_ts_pll_locked_latch(nthw_pcm_nt400dxx_t *p, uint32_t val);
 
 #endif	/* __NTHW_PCM_NT400DXX_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
index ba044a5091..c4ec100c23 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
@@ -142,7 +142,15 @@ void nthw_phy_tile_write_xcvr(nthw_phy_tile_t *p, uint8_t intf_no, uint8_t lane,
 	uint32_t data);
 uint32_t nthw_phy_tile_get_port_status_reset_ack(nthw_phy_tile_t *p, uint8_t intf_no);
 uint32_t nthw_phy_tile_get_port_status_tx_lanes_stable(nthw_phy_tile_t *p, uint8_t intf_no);
+void nthw_phy_tile_set_sys_pll_set_rdy(nthw_phy_tile_t *p, uint32_t value);
+uint32_t nthw_phy_tile_get_sys_pll_get_rdy(nthw_phy_tile_t *p);
+uint32_t nthw_phy_tile_get_sys_pll_system_pll_lock(nthw_phy_tile_t *p);
+void nthw_phy_tile_set_sys_pll_en_ref_clk_fgt(nthw_phy_tile_t *p, uint32_t value);
+uint32_t nthw_phy_tile_get_sys_pll_ref_clk_fgt_enabled(nthw_phy_tile_t *p);
+void nthw_phy_tile_set_sys_pll_forward_rst(nthw_phy_tile_t *p, uint32_t value);
+void nthw_phy_tile_set_sys_pll_force_rst(nthw_phy_tile_t *p, uint32_t value);
 uint8_t nthw_phy_tile_get_no_intfs(nthw_phy_tile_t *p);
 void nthw_phy_tile_set_port_config_rst(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t value);
+bool nthw_phy_tile_use_phy_tile_pll_check(nthw_phy_tile_t *p);
 
 #endif	/* __NTHW_PHY_TILE_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
index 95394b9c8f..b93b0a829a 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
@@ -184,9 +184,13 @@ static int nthw_fpga_rst_nt400dxx_reset(struct fpga_info_s *p_fpga_info)
 {
 	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
 	nthw_fpga_t *p_fpga = NULL;
+	int res = -1;
 
 	p_fpga = p_fpga_info->mp_fpga;
 
+	nthw_pcm_nt400dxx_t *p_pcm = p_fpga_info->mp_nthw_agx.p_pcm;
+	nthw_prm_nt400dxx_t *p_prm = p_fpga_info->mp_nthw_agx.p_prm;
+
 	assert(p_fpga_info);
 
 	NT_LOG(DBG, NTHW, "%s: %s: BEGIN", p_adapter_id_str, __PRETTY_FUNCTION__);
@@ -199,9 +203,216 @@ static int nthw_fpga_rst_nt400dxx_reset(struct fpga_info_s *p_fpga_info)
 		return -1;
 	}
 
+	nthw_phy_tile_t *p_phy_tile = p_fpga_info->mp_nthw_agx.p_phy_tile;
+
 	nthw_igam_t *p_igam = nthw_igam_new();
 	nthw_igam_init(p_igam, p_fpga, 0);
 
+	if (p_igam) {
+		if (!nthw_phy_tile_use_phy_tile_pll_check(p_fpga_info->mp_nthw_agx.p_phy_tile)) {
+			NT_LOG(DBG, NTHW, "%s: IGAM module present.", p_adapter_id_str);
+			uint32_t data;
+
+			p_fpga_info->mp_nthw_agx.p_igam = p_igam;
+
+			/*
+			 * (E) When the reference clock for the F-tile system PLL is started (and
+			 * stable) it must be enabled using the Intel Global Avalon Memory-Mapped
+			 * Mailbox (IGAM) module.
+			 */
+
+			nthw_igam_write(p_igam, 0xffff8, 0x90000000);
+
+			/* (F) Check that the system PLL is ready. */
+			for (int i = 1000; i >= 0; i--) {
+				nt_os_wait_usec(1000);
+				data = nthw_igam_read(p_igam, 0xffff4);
+
+				if (data == 0x80000000 || data == 0xA0000000) {
+					NT_LOG(INF,
+						NTHW,
+						"%s: All enabled system PLLs are locked. Response: %#08x",
+						p_adapter_id_str,
+						data);
+					break;
+				}
+
+				if (i == 0) {
+					NT_LOG(ERR,
+						NTHW,
+						"%s: Timeout waiting for all system PLLs to lock. Response: %#08x",
+						p_adapter_id_str,
+						data);
+					return -1;
+				}
+			}
+
+		} else {
+			nthw_igam_set_ctrl_forward_rst(p_igam,
+				0);	/* Ensure that the Avalon bus is not */
+			/* reset at every driver re-load. */
+			nt_os_wait_usec(1000000);
+			NT_LOG(DBG, NTHW, "%s: IGAM module not used.", p_adapter_id_str);
+		}
+
+	} else {
+		NT_LOG(DBG, NTHW, "%s: No IGAM module present.", p_adapter_id_str);
+	}
+
+	/*
+	 * (G) Reset TS PLL and select Time-of-Day clock (tod_fpga_clk). Source is either
+	 * from ZL clock device or SiTime tunable XO. NOTE that the PLL must be held in
+	 * RESET during clock switchover.
+	 */
+
+	if (p_fpga_info->mp_nthw_agx.tcxo_present && p_fpga_info->mp_nthw_agx.tcxo_capable) {
+		nthw_pcm_nt400dxx_set_ts_pll_recal(p_pcm, 1);
+		nt_os_wait_usec(1000);
+		nthw_pcm_nt400dxx_set_ts_pll_recal(p_pcm, 0);
+		nt_os_wait_usec(1000);
+	}
+
+	/* (I) Wait for TS PLL locked. */
+	for (int i = 1000; i >= 0; i--) {
+		nt_os_wait_usec(1000);
+
+		if (nthw_pcm_nt400dxx_get_ts_pll_locked_stat(p_pcm))
+			break;
+
+		if (i == 0) {
+			NT_LOG(ERR,
+				NTHW,
+				"%s: %s: Time out waiting for TS PLL locked",
+				p_adapter_id_str,
+				__func__);
+			return -1;
+		}
+	}
+
+	/* NT_RAB0_REG.PCM_NT400D1X.STAT.TS_PLL_LOCKED==1 */
+
+	/* (J) Set latched TS PLL locked. */
+	nthw_pcm_nt400dxx_set_ts_pll_locked_latch(p_pcm, 1);
+	/* NT_RAB0_REG.PCM_NT400D1X.LATCH.TS_PLL_LOCKED=1 */
+
+	/* (K) Ensure TS latched status bit is still set. */
+	if (!nthw_pcm_nt400dxx_get_ts_pll_locked_stat(p_pcm)) {
+		NT_LOG(ERR,
+			NTHW,
+			"%s: %s: TS latched status bit toggled",
+			p_adapter_id_str,
+			__func__);
+		return -1;
+	}
+
+	/* NT_RAB0_REG.PCM_NT400D1X.LATCH.TS_PLL_LOCKED==1 */
+
+	/*
+	 * At this point all system clocks and TS clocks are running.
+	 * Last thing to do before proceeding to product reset is to
+	 * de-assert the platform reset and enable the RAB buses.
+	 */
+
+	/* (K1) Force HIF soft reset. */
+	nthw_hif_t *p_nthw_hif = nthw_hif_new();
+	res = nthw_hif_init(p_nthw_hif, p_fpga, 0);
+
+	if (res == 0)
+		NT_LOG(DBG, NTHW, "%s: Hif module found", p_fpga_info->mp_adapter_id_str);
+
+	nt_os_wait_usec(1000);
+	nthw_hif_force_soft_reset(p_nthw_hif);
+	nt_os_wait_usec(1000);
+	nthw_hif_delete(p_nthw_hif);
+
+	/* (L) De-assert platform reset. */
+	nthw_prm_nt400dxx_platform_rst(p_prm, 0);
+
+	/*
+	 * (M) Enable RAB1 and RAB2.
+	 * NT_BAR_REG.RAC.RAB_INIT.RAB=0
+	 */
+	NT_LOG_DBGX(DBG, NTHW, "%s: RAB Init", p_adapter_id_str);
+	nthw_rac_rab_init(p_fpga_info->mp_nthw_rac, 0);
+	nthw_rac_rab_setup(p_fpga_info->mp_nthw_rac);
+
+	NT_LOG_DBGX(DBG, NTHW, "%s: RAB Flush", p_adapter_id_str);
+	nthw_rac_rab_flush(p_fpga_info->mp_nthw_rac);
+
+	/*
+	 * FPGAs with newer PHY_TILE versions must use PhyTile to check that system PLL is ready.
+	 * It has been added here after consultations with ORA since the test must be performed
+	 * after de-assertion of platform reset.
+	 */
+
+	if (nthw_phy_tile_use_phy_tile_pll_check(p_phy_tile)) {
+		/* Ensure that the Avalon bus is not reset at every driver re-load. */
+		nthw_phy_tile_set_sys_pll_forward_rst(p_phy_tile, 0);
+
+		nthw_phy_tile_set_sys_pll_set_rdy(p_phy_tile, 0x07);
+		NT_LOG_DBGX(DBG, NTHW, "%s: setSysPllSetRdy.", p_adapter_id_str);
+
+		/* (F) Check that the system PLL is ready. */
+		for (int i = 1000; i >= 0; i--) {
+			nt_os_wait_usec(1000);
+
+			if (nthw_phy_tile_get_sys_pll_get_rdy(p_phy_tile) &&
+				nthw_phy_tile_get_sys_pll_system_pll_lock(p_phy_tile)) {
+				break;
+			}
+
+			if (i == 500) {
+				nthw_phy_tile_set_sys_pll_force_rst(p_phy_tile, 1);
+				nt_os_wait_usec(1000);
+				nthw_phy_tile_set_sys_pll_force_rst(p_phy_tile, 0);
+				NT_LOG_DBGX(DBG,
+					NTHW,
+					"%s: setSysPllForceRst due to system PLL not ready.",
+					p_adapter_id_str);
+			}
+
+			if (i == 0) {
+				NT_LOG_DBGX(DBG,
+					NTHW,
+					"%s: Timeout waiting for all system PLLs to lock",
+					p_adapter_id_str);
+				return -1;
+			}
+		}
+
+		nt_os_wait_usec(100000);/* 100 ms */
+
+		uint32_t fgt_enable = 0x0d;	/* FGT 0, 2 & 3 */
+		nthw_phy_tile_set_sys_pll_en_ref_clk_fgt(p_phy_tile, fgt_enable);
+
+		for (int i = 1000; i >= 0; i--) {
+			nt_os_wait_usec(1000);
+
+			if (nthw_phy_tile_get_sys_pll_ref_clk_fgt_enabled(p_phy_tile) ==
+				fgt_enable) {
+				break;
+			}
+
+			if (i == 500) {
+				nthw_phy_tile_set_sys_pll_force_rst(p_phy_tile, 1);
+				nt_os_wait_usec(1000);
+				nthw_phy_tile_set_sys_pll_force_rst(p_phy_tile, 0);
+				NT_LOG_DBGX(DBG,
+					NTHW,
+					"%s: setSysPllForceRst due to FGTs not ready.",
+					p_adapter_id_str);
+			}
+
+			if (i == 0) {
+				NT_LOG_DBGX(DBG,
+					NTHW,
+					"%s: Timeout waiting for FGTs to lock",
+					p_adapter_id_str);
+				return -1;
+			}
+		}
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/ntnic/nthw/core/nthw_hif.c b/drivers/net/ntnic/nthw/core/nthw_hif.c
index 92a2348bbb..630262a7fc 100644
--- a/drivers/net/ntnic/nthw/core/nthw_hif.c
+++ b/drivers/net/ntnic/nthw/core/nthw_hif.c
@@ -202,6 +202,16 @@ int nthw_hif_init(nthw_hif_t *p, nthw_fpga_t *p_fpga, int n_instance)
 	return 0;
 }
 
+int nthw_hif_force_soft_reset(nthw_hif_t *p)
+{
+	if (p->mp_fld_ctrl_fsr) {
+		nthw_field_update_register(p->mp_fld_ctrl_fsr);
+		nthw_field_set_flush(p->mp_fld_ctrl_fsr);
+	}
+
+	return 0;
+}
+
 int nthw_hif_trigger_sample_time(nthw_hif_t *p)
 {
 	nthw_field_set_val_flush32(p->mp_fld_sample_time, 0xfee1dead);
diff --git a/drivers/net/ntnic/nthw/core/nthw_igam.c b/drivers/net/ntnic/nthw/core/nthw_igam.c
index 5dc7e36c7b..385282298a 100644
--- a/drivers/net/ntnic/nthw/core/nthw_igam.c
+++ b/drivers/net/ntnic/nthw/core/nthw_igam.c
@@ -60,3 +60,34 @@ int nthw_igam_init(nthw_igam_t *p, nthw_fpga_t *p_fpga, int mn_igam_instance)
 
 	return 0;
 }
+
+uint32_t nthw_igam_read(nthw_igam_t *p, uint32_t address)
+{
+	nthw_register_update(p->mp_reg_base);
+	nthw_field_set_val32(p->mp_fld_base_cmd, 0);
+	nthw_field_set_val_flush32(p->mp_fld_base_ptr, address);
+
+	while (nthw_field_get_updated(p->mp_fld_base_busy) == 1)
+		nt_os_wait_usec(100);
+
+	return nthw_field_get_updated(p->mp_fld_data_data);
+}
+
+void nthw_igam_write(nthw_igam_t *p, uint32_t address, uint32_t data)
+{
+	nthw_field_set_val_flush32(p->mp_fld_data_data, data);
+	nthw_register_update(p->mp_reg_base);
+	nthw_field_set_val32(p->mp_fld_base_ptr, address);
+	nthw_field_set_val_flush32(p->mp_fld_base_cmd, 1);
+
+	while (nthw_field_get_updated(p->mp_fld_base_busy) == 1)
+		nt_os_wait_usec(100);
+}
+
+void nthw_igam_set_ctrl_forward_rst(nthw_igam_t *p, uint32_t value)
+{
+	if (p->mp_fld_ctrl_forward_rst) {
+		nthw_field_get_updated(p->mp_fld_ctrl_forward_rst);
+		nthw_field_set_val_flush32(p->mp_fld_ctrl_forward_rst, value);
+	}
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c b/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
index f32a277e86..e7be634a83 100644
--- a/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
@@ -54,3 +54,27 @@ int nthw_pcm_nt400dxx_init(nthw_pcm_nt400dxx_t *p, nthw_fpga_t *p_fpga, int n_in
 
 	return 0;
 }
+
+void nthw_pcm_nt400dxx_set_ts_pll_recal(nthw_pcm_nt400dxx_t *p, uint32_t val)
+{
+	if (p->mp_fld_ctrl_ts_pll_recal) {
+		nthw_field_update_register(p->mp_fld_ctrl_ts_pll_recal);
+		nthw_field_set_val_flush32(p->mp_fld_ctrl_ts_pll_recal, val);
+	}
+}
+
+bool nthw_pcm_nt400dxx_get_ts_pll_locked_stat(nthw_pcm_nt400dxx_t *p)
+{
+	return nthw_field_get_updated(p->mp_fld_stat_ts_pll_locked) != 0;
+}
+
+bool nthw_pcm_nt400dxx_get_ts_pll_locked_latch(nthw_pcm_nt400dxx_t *p)
+{
+	return nthw_field_get_updated(p->mp_fld_latch_ts_pll_locked) != 0;
+}
+
+void nthw_pcm_nt400dxx_set_ts_pll_locked_latch(nthw_pcm_nt400dxx_t *p, uint32_t val)
+{
+	nthw_field_update_register(p->mp_fld_latch_ts_pll_locked);
+	nthw_field_set_val_flush32(p->mp_fld_latch_ts_pll_locked, val);
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
index f78d8263f5..0dc2784034 100644
--- a/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
+++ b/drivers/net/ntnic/nthw/core/nthw_phy_tile.c
@@ -642,6 +642,11 @@ int nthw_phy_tile_init(nthw_phy_tile_t *p, nthw_fpga_t *p_fpga, int mn_phy_tile_
 	return 0;
 }
 
+bool nthw_phy_tile_use_phy_tile_pll_check(nthw_phy_tile_t *p)
+{
+	return nthw_module_is_version_newer(p->m_mod_phy_tile, 0, 8);
+}
+
 uint8_t nthw_phy_tile_get_no_intfs(nthw_phy_tile_t *p)
 {
 	switch (p->mac_pcs_mode) {
@@ -1172,6 +1177,62 @@ uint32_t nthw_phy_tile_get_port_status_tx_lanes_stable(nthw_phy_tile_t *p, uint8
 	return 1;
 }
 
+void nthw_phy_tile_set_sys_pll_set_rdy(nthw_phy_tile_t *p, uint32_t value)
+{
+	if (p->mp_fld_sys_pll_set_rdy) {
+		nthw_field_get_updated(p->mp_fld_sys_pll_set_rdy);
+		nthw_field_set_val_flush32(p->mp_fld_sys_pll_set_rdy, value);
+	}
+}
+
+uint32_t nthw_phy_tile_get_sys_pll_get_rdy(nthw_phy_tile_t *p)
+{
+	if (p->mp_fld_sys_pll_get_rdy)
+		return nthw_field_get_updated(p->mp_fld_sys_pll_get_rdy);
+
+	return 0;
+}
+
+uint32_t nthw_phy_tile_get_sys_pll_system_pll_lock(nthw_phy_tile_t *p)
+{
+	if (p->mp_fld_sys_pll_system_pll_lock)
+		return nthw_field_get_updated(p->mp_fld_sys_pll_system_pll_lock);
+
+	return 0;
+}
+
+void nthw_phy_tile_set_sys_pll_en_ref_clk_fgt(nthw_phy_tile_t *p, uint32_t value)
+{
+	if (p->mp_fld_sys_pll_en_ref_clk_fgt) {
+		nthw_field_get_updated(p->mp_fld_sys_pll_en_ref_clk_fgt);
+		nthw_field_set_val_flush32(p->mp_fld_sys_pll_en_ref_clk_fgt, value);
+	}
+}
+
+uint32_t nthw_phy_tile_get_sys_pll_ref_clk_fgt_enabled(nthw_phy_tile_t *p)
+{
+	if (p->mp_fld_sys_pll_ref_clk_fgt_enabled)
+		return nthw_field_get_updated(p->mp_fld_sys_pll_ref_clk_fgt_enabled);
+
+	return 0;
+}
+
+void nthw_phy_tile_set_sys_pll_forward_rst(nthw_phy_tile_t *p, uint32_t value)
+{
+	if (p->mp_fld_sys_pll_forward_rst) {
+		nthw_field_get_updated(p->mp_fld_sys_pll_forward_rst);
+		nthw_field_set_val_flush32(p->mp_fld_sys_pll_forward_rst, value);
+	}
+}
+
+void nthw_phy_tile_set_sys_pll_force_rst(nthw_phy_tile_t *p, uint32_t value)
+{
+	if (p->mp_fld_sys_pll_force_rst) {
+		nthw_field_get_updated(p->mp_fld_sys_pll_force_rst);
+		nthw_field_set_val_flush32(p->mp_fld_sys_pll_force_rst, value);
+	}
+}
+
 void nthw_phy_tile_set_port_config_rst(nthw_phy_tile_t *p, uint8_t intf_no, uint32_t value)
 {
 	if (p->mp_fld_port_config_reset[intf_no]) {
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index 574dd663ea..e1a00c5ea5 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -17,6 +17,7 @@
 #include "nthw_phy_tile.h"
 #include "nthw_prm_nt400dxx.h"
 #include "nthw_pcm_nt400dxx.h"
+#include "nthw_igam.h"
 
 /*
  * Structs for controlling Agilex based NT400DXX adapter
@@ -31,6 +32,7 @@ typedef struct nthw_agx_s {
 	nthw_si5156_t *p_si5156;
 	nthw_prm_nt400dxx_t *p_prm;
 	nthw_pcm_nt400dxx_t *p_pcm;
+	nthw_igam_t *p_igam;
 	nthw_phy_tile_t *p_phy_tile;
 	nthw_rpf_t *p_rpf;
 	bool tcxo_present;
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 32/32] net/ntnic: revert untrusted loop bound
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (30 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 31/32] net/ntnic: init IGAM and config PLL for FPGA Serhii Iliushyk
@ 2025-02-20 22:03 ` Serhii Iliushyk
  2025-02-20 22:31   ` Stephen Hemminger
  2025-02-20 23:49 ` [PATCH v1 00/32] add new adapter NT400D13 Stephen Hemminger
  2025-02-22 21:41 ` Stephen Hemminger
  33 siblings, 1 reply; 39+ messages in thread
From: Serhii Iliushyk @ 2025-02-20 22:03 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

The changes for untrusted loop bound breaks VLAN processing

This reverts commit 36cd2cb0eea49813dd59ee1df2eb592e8ae5b6b4.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index 70bff776be..43f45ebe34 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -53,7 +53,7 @@ int interpret_raw_data(uint8_t *data, uint8_t *preserve, int size, struct rte_fl
 		goto interpret_end;
 
 	/* VLAN */
-	if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ||
+	while (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ||
 		ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ) ||
 		ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ1)) {
 		if (size - pkti == 0)
-- 
2.45.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 32/32] net/ntnic: revert untrusted loop bound
  2025-02-20 22:03 ` [PATCH v1 32/32] net/ntnic: revert untrusted loop bound Serhii Iliushyk
@ 2025-02-20 22:31   ` Stephen Hemminger
  0 siblings, 0 replies; 39+ messages in thread
From: Stephen Hemminger @ 2025-02-20 22:31 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm

On Thu, 20 Feb 2025 23:03:56 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> The changes for untrusted loop bound breaks VLAN processing
> 
> This reverts commit 36cd2cb0eea49813dd59ee1df2eb592e8ae5b6b4.
> 
> Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>

This will bring back the Coverity bug and potential for VLAN "packet of doom" bugs.
Any loop iterating over VLAN's needs to limit depth

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 00/32] add new adapter NT400D13
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (31 preceding siblings ...)
  2025-02-20 22:03 ` [PATCH v1 32/32] net/ntnic: revert untrusted loop bound Serhii Iliushyk
@ 2025-02-20 23:49 ` Stephen Hemminger
  2025-02-22 21:41 ` Stephen Hemminger
  33 siblings, 0 replies; 39+ messages in thread
From: Stephen Hemminger @ 2025-02-20 23:49 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm

[-- Attachment #1: Type: text/plain, Size: 52726 bytes --]

Ok, scan of ntnic with PVS studio after this bundle.
Similar to Coverity it is a good automated tool for finding bugs.

MESSAGES
LocationCodeMessage
Fails/Info

nt4ga_adapter.c (129)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function.
Under certain conditions the pointer can be null.

nt4ga_adapter.c (150)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function.
Under certain conditions the pointer can be null.

nt4ga_stat.c (252)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'p_nt4ga_stat'
pointer was utilized before it was verified against nullptr. Check lines:
252, 259.

nt4ga_stat.c (47)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression
'p_nt4ga_stat' is always true.

ntnic_dbsconfig.c (595)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'txvq' pointer was
utilized before it was verified against nullptr. Check lines: 595, 597.

ntnic_dbsconfig.c (765)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'irq_vector
>= 0' is always false.

ntnic_dbsconfig.c (400)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

hw_mod_backend.h (750)
V1071 <https://pvs-studio.com/en/docs/warnings/v1071/> Consider inspecting
the 'hw_mod_hsh_rcp_set' function. The return value is not always used.
Total calls: 15, discarded results: 1.

nt4ga_link_100g.c (259)
V781 <https://pvs-studio.com/en/docs/warnings/v781/> The value of the
'port' variable is checked after it was used. Perhaps there is a mistake in
program logic. Check lines: 259, 261.

nt4ga_link_100g.c (674)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always true: res == 0.

nt4ga_agx_link_100g.c (696)
V523 <https://pvs-studio.com/en/docs/warnings/v523/> The 'then' statement
is equivalent to the 'else' statement.

nt4ga_agx_link_100g.c (1012)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'res == 0'
is always true.

nt4ga_agx_link_100g.c (1021)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'res == 0'
is always true.

nt4ga_agx_link_100g.c (522)
V781 <https://pvs-studio.com/en/docs/warnings/v781/> The value of the
'port' variable is checked after it was used. Perhaps there is a mistake in
program logic. Check lines: 522, 524.

nt4ga_agx_link_100g.c (916)
V619 <https://pvs-studio.com/en/docs/warnings/v619/> The array 'nim_ctx' is
being utilized as a pointer to single object.

nt4ga_agx_link_100g.c (318)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (370)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (370)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (385)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (391)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (976)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (984)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

nt4ga_agx_link_100g.c (380)
V1051 <https://pvs-studio.com/en/docs/warnings/v1051/> Consider checking
for misprints. It's possible that the 'state->link_up' should be checked
here.

i2c_nim.c (126)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'multi_byte
== 1' is always true.

i2c_nim.c (881)
V519 <https://pvs-studio.com/en/docs/warnings/v519/> The variable is
assigned values twice successively. Perhaps this is a mistake. Check lines:
880, 881.

nthw_fpga_rst9563.c (62)
V519 <https://pvs-studio.com/en/docs/warnings/v519/> The
'p->mp_fld_rst_ptp' variable is assigned values twice successively. Perhaps
this is a mistake. Check lines: 61, 62.

nthw_fpga_rst9563.c (107)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression
'!p->mp_fld_stat_tsm_ref_mmcm_locked' is always true.

nthw_fpga_rst9563.c (129)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression
'!p->mp_fld_sticky_tsm_ref_mmcm_unlocked' is always true.

nthw_fpga_rst_nt200a0x.c (531)
V519 <https://pvs-studio.com/en/docs/warnings/v519/> The 'res' variable is
assigned values twice successively. Perhaps this is a mistake. Check lines:
530, 531.

nthw_fpga_rst_nt200a0x.c (62)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_fpga_rst_nt200a0x.c (72)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_fpga_nt400dxx.c (187)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression
'rst9574_ops' is always true.

nthw_fpga_rst_nt400dxx.c (185)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'p_fpga_info'
pointer was utilized before it was verified against nullptr. Check lines:
185, 194.

nthw_fpga_rst_nt400dxx.c (60)
V525 <https://pvs-studio.com/en/docs/warnings/v525/> The code contains the
collection of similar blocks. Check items 'nthw_prm_nt400dxx_platform_rst',
'nthw_prm_nt400dxx_periph_rst', 'nthw_prm_nt400dxx_periph_rst' in lines 60,
64, 66.

nthw_fpga_rst_nt400dxx.c (116)
V525 <https://pvs-studio.com/en/docs/warnings/v525/> The code contains the
collection of similar blocks. Check items '0', '1', '0', '0', '1' in lines
116, 122, 128, 134, 140.

nthw_fpga.c (623)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'p_fpga_info'
pointer was utilized before it was verified against nullptr. Check lines:
623, 639.

nthw_fpga.c (317)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: avr_vpd_info.n_avr_spi_version >= 3.

nthw_fpga.c (387)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: avr_vpd_info.n_avr_spi_version >= 3.

nthw_fpga.c (469)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: avr_vpd_info.n_avr_spi_version >= 3.

nthw_fpga.c (831)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always true: p_fpga_info.

nthw_fpga.c (831)
V571 <https://pvs-studio.com/en/docs/warnings/v571/> Recurring check. The
'p_fpga_info' condition was already verified in line 830.

nthw_fpga.c (524)
V1086 <https://pvs-studio.com/en/docs/warnings/v1086/> A call of the
'memcpy' function will lead to underflow of the buffer '&
p_vpd_board_info[0]'.

nthw_hif.c (27)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_hif.c (82)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

nthw_iic.c (257)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_iic.c (242)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

nthw_pcie3.c (28)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_pcm_nt400dxx.c (45)
V525 <https://pvs-studio.com/en/docs/warnings/v525/> The code contains the
collection of similar blocks. Check items 'nthw_register_query_field',
'nthw_register_get_field', 'nthw_register_get_field' in lines 45, 49, 53.

nthw_phy_tile.c (821)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'i == 0' is
always false.

nthw_phy_tile.c (800)
V1048 <https://pvs-studio.com/en/docs/warnings/v1048/> The 'xcvr_instance'
variable was assigned the same value.

nthw_phy_tile.c (86)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

nthw_rpf.c (26)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_sdc.c (26)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_sdc.c (135)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression
'pn_result_mask' is always true.

nthw_si5340.c (48)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_spi_v3.c (140)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_spi_v3.c (148)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_spi_v3.c (154)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_spi_v3.c (159)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_tsm.c (92)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'p_ts' is
always true.

nthw_tsm.c (111)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'p_time' is
always true.

flow_api.c (833)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'ndev' is
always true.

flow_api.c (999)
V1029 <https://pvs-studio.com/en/docs/warnings/v1029/> Numeric Truncation
Error. Return value of the 'strlen' function is written to the 16-bit
variable.

flow_api.c (1001)
V1029 <https://pvs-studio.com/en/docs/warnings/v1029/> Numeric Truncation
Error. Return value of the 'strlen' function is written to the 16-bit
variable.

flow_api.c (214)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

flow_api.c (227)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

flow_api.c (428)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

flow_group.c (35)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> There might be
dereferencing of a potential null pointer 'group_handle'. Check lines: 35,
32.

flow_hsh_cfg.c (74)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

flow_hsh_cfg.c (77)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

flow_id_table.c (71)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> There might be
dereferencing of a potential null pointer 'handle'. Check lines: 71, 69.

flow_km.c (583)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

flow_km.c (614)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The SIGNED integer type argument is expected.

flow_km.c (791)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

flow_km.c (92)
V769 <https://pvs-studio.com/en/docs/warnings/v769/> The '(char *)
km->cam_dist' pointer in the expression could be nullptr. In such case,
resulting value of arithmetic operations on this pointer will be senseless
and it should not be used. Check lines: 92, 85.

hw_mod_flm.c (836)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression
'be->flm.ver < 18' is always false.

hw_mod_hsh.c (127)
V568 <https://pvs-studio.com/en/docs/warnings/v568/> It's odd that
'sizeof()' operator evaluates the size of a pointer to a class, but not the
size of the 'be->hsh.v5.rcp' class object.

hw_mod_hsh.c (130)
V1064 <https://pvs-studio.com/en/docs/warnings/v1064/> The 'buffer_size'
operand of integer division is less than the 'element_size' one. The result
will always be zero.

hw_mod_hsh.c (133)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: index < max_idx. Unsigned type value is never <
0.

hw_mod_hsh.c (133)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: word_off < max_idx. Unsigned type value is
never < 0.

hw_mod_pdb.c (137)
V568 <https://pvs-studio.com/en/docs/warnings/v568/> It's odd that
'sizeof()' operator evaluates the size of a pointer to a class, but not the
size of the 'be->pdb.v9.rcp' class object.

hw_mod_pdb.c (140)
V1064 <https://pvs-studio.com/en/docs/warnings/v1064/> The 'buffer_size'
operand of integer division is less than the 'element_size' one. The result
will always be zero.

hw_mod_pdb.c (143)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: * value < max_idx. Unsigned type value is never
< 0.

hw_mod_pdb.c (143)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: index < max_idx. Unsigned type value is never <
0.

flm_evt_queue.c (194)
V557 <https://pvs-studio.com/en/docs/warnings/v557/> Array overrun is
possible. The value of 'port' index could reach 127.

flm_evt_queue.c (202)
V557 <https://pvs-studio.com/en/docs/warnings/v557/> Array overrun is
possible. The value of 'port' index could reach 127.

flm_evt_queue.c (80)
V1037 <https://pvs-studio.com/en/docs/warnings/v1037/> Two or more
case-branches perform the same actions. Check lines: 80, 88

flm_evt_queue.c (84)
V1037 <https://pvs-studio.com/en/docs/warnings/v1037/> Two or more
case-branches perform the same actions. Check lines: 84, 92

flow_api_hw_db_inline.c (2461)
V1086 <https://pvs-studio.com/en/docs/warnings/v1086/> A call of the
'memset' function will lead to underflow of the buffer '&
db->flm[idx.id1].data'.

flow_api_hw_db_inline.c (426)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (428)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (428)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fourth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (428)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (428)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (438)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (446)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (455)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (457)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the eighth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (457)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (457)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fourth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (457)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'fprintf' function.
The SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (457)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (457)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (467)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (482)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (494)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (509)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (518)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (526)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (560)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (578)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (579)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (579)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fourth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (579)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (579)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (581)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (581)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fourth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (581)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (581)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (583)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fourth actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (583)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
integer argument of 32-bit size is expected.

flow_api_hw_db_inline.c (596)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (604)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (610)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (618)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (619)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (620)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (621)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (627)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (628)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (629)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fourth actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (629)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (636)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the third actual argument of the 'fprintf' function. The
SIGNED integer type argument is expected.

flow_api_hw_db_inline.c (706)
V1037 <https://pvs-studio.com/en/docs/warnings/v1037/> Two or more
case-branches perform the same actions. Check lines: 706, 736, 742

flow_api_profile_inline.c (117)
V629 <https://pvs-studio.com/en/docs/warnings/v629/> Consider inspecting
the '1 << (shift - 1)' expression. Bit shifting of the 32-bit value with a
subsequent expansion to the 64-bit type.

flow_api_profile_inline.c (738)
V674 <https://pvs-studio.com/en/docs/warnings/v674/> The '0.01' literal of
the 'double' type is compared to a value of the 'int' type. Consider
inspecting the '0.01 > 0' expression.

flow_api_profile_inline.c (3469)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> There might be
dereferencing of a potential null pointer 'fh'. Check lines: 3469, 3467.

flow_api_profile_inline.c (4925)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> There might be
dereferencing of a potential null pointer 'template'. Check lines: 4925,
4923.

flow_api_profile_inline.c (4990)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> There might be
dereferencing of a potential null pointer 'template'. Check lines: 4990,
4988.

flow_api_profile_inline.c (5262)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> There might be
dereferencing of a potential null pointer 'fh'. Check lines: 5262, 5260.

flow_api_profile_inline.c (4307)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'err' is
always false.

flow_api_profile_inline.c (2040)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always true: match_cnt == 1.

flow_api_profile_inline.c (196)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer is cast
to a more strictly aligned pointer type

flow_api_profile_inline.c (254)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer is cast
to a more strictly aligned pointer type

flow_api_profile_inline.c (294)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer is cast
to a more strictly aligned pointer type

flow_api_profile_inline.c (347)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer is cast
to a more strictly aligned pointer type

flow_api_profile_inline.c (434)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer 'data'
is cast to a more strictly aligned pointer type.

flow_api_profile_inline.c (510)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer 'data'
is cast to a more strictly aligned pointer type.

flow_api_profile_inline.c (980)
V1032 <https://pvs-studio.com/en/docs/warnings/v1032/> The pointer is cast
to a more strictly aligned pointer type

flow_api_profile_inline.c (4758)
V523 <https://pvs-studio.com/en/docs/warnings/v523/> The 'then' statement
is equivalent to the 'else' statement.

flow_api_profile_inline.c (2272)
V525 <https://pvs-studio.com/en/docs/warnings/v525/> The code contains the
collection of similar blocks. Check items 'qw_data', 'qw_data', 'qw_mask'
in lines 2272, 2273, 2275.

flow_api_profile_inline.c (1160)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the eighth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

flow_api_profile_inline.c (1224)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

flow_api_profile_inline.c (3133)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

flow_api_profile_inline.c (4507)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

flow_api_profile_inline.c (3573)
V1048 <https://pvs-studio.com/en/docs/warnings/v1048/> The
'action_set_data.contains_jump' variable was assigned the same value.

flow_api_profile_inline.c (972)
V1051 <https://pvs-studio.com/en/docs/warnings/v1051/> Consider checking
for misprints. It's possible that the 'flm_id' should be checked here.

flow_nthw_cat.c (29)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_csu.c (33)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_flm.c (30)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_flm.c (736)
V1020 <https://pvs-studio.com/en/docs/warnings/v1020/> The function exited
without calling the 'rte_spinlock_unlock' function. Check lines: 736, 729.

flow_nthw_hfu.c (33)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_hsh.c (34)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_info.c (34)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_km.c (43)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_pdb.c (34)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_qsl.c (34)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_rpp_lr.c (33)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_rpp_lr.c (65)
V1004 <https://pvs-studio.com/en/docs/warnings/v1004/> The 'p->m_rpp_lr'
pointer was used unsafely after it was verified against nullptr. Check
lines: 57, 65.

flow_nthw_slc_lr.c (34)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_tx_cpy.c (34)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_tx_ins.c (33)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

flow_nthw_tx_rpl.c (33)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_fpga_model.c (491)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'p->m_rpp_lr'
pointer was utilized before it was verified against nullptr. Check lines:
'nthw_fpga_model.c:479', 'nthw_fpga_model.c:491', 'flow_nthw_rpp_lr.c:65',
'flow_nthw_rpp_lr.c:69'.

nthw_fpga_model.c (186)
V597 <https://pvs-studio.com/en/docs/warnings/v597/> The compiler could
delete the 'memset' function call, which is used to flush 'p' object. The
memset_s() function should be used to erase the private data.

nthw_fpga_model.c (365)
V522 <https://pvs-studio.com/en/docs/warnings/v522/> Dereferencing of the
null pointer might take place. The potential null pointer is passed into
'nthw_fpga_get_param_info' function. Inspect the second argument. Check
lines: 'nthw_fpga_model.c:365', 'nthw_fpga.c:25', 'nthw_fpga.c:687'.

nthw_fpga_model.c (906)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the 14th actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_fpga_model.c (906)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (515)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression '(word_cnt
+ 3) > (0x4000)' is always false.

nthw_rac.c (34)
V575 <https://pvs-studio.com/en/docs/warnings/v575/> The potential null
pointer is passed into 'memset' function. Inspect the first argument. Check
lines: 34, 33.

nthw_rac.c (265)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the eighth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (469)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the eighth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (508)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the eighth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (560)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (578)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (747)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (768)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

nthw_rac.c (94)
V1048 <https://pvs-studio.com/en/docs/warnings/v1048/> The
'p->mp_reg_dbg_data' variable was assigned the same value.

ntnic_meter.c (89)
V525 <https://pvs-studio.com/en/docs/warnings/v525/> The code contains the
collection of similar blocks. Check items '0', '1', '0', '0', '0', '0' in
lines 89, 90, 91, 94, 95, 96.

nthw_stat.c (257)
V1048 <https://pvs-studio.com/en/docs/warnings/v1048/> The
'p->mn_stat_layout_version' variable was assigned the same value.

ntnic_ethdev.c (2194)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'err == 0'
is always true.

ntnic_ethdev.c (334)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'internals->p_drv'
pointer was utilized before it was verified against nullptr. Check lines:
334, 350.

ntnic_ethdev.c (2268)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression '(1 <<
n_intf_no) & ~n_port_mask' is always false.

ntnic_ethdev.c (191)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: !p_nt4ga_stat.

ntnic_ethdev.c (238)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: !p_nt4ga_stat.

ntnic_ethdev.c (1763)
V1044 <https://pvs-studio.com/en/docs/warnings/v1044/> Loop break
conditions do not depend on the number of iterations.

ntnic_ethdev.c (1900)
V1044 <https://pvs-studio.com/en/docs/warnings/v1044/> Loop break
conditions do not depend on the number of iterations.

ntnic_ethdev.c (1935)
V1044 <https://pvs-studio.com/en/docs/warnings/v1044/> Loop break
conditions do not depend on the number of iterations.

ntnic_ethdev.c (1942)
V1044 <https://pvs-studio.com/en/docs/warnings/v1044/> Loop break
conditions do not depend on the number of iterations.

ntnic_ethdev.c (1370)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'port ==
internals->n_intf_no' is always true.

ntnic_ethdev.c (1396)
V547 <https://pvs-studio.com/en/docs/warnings/v547/> Expression 'port ==
internals->n_intf_no' is always true.

ntnic_ethdev.c (375)
V574 <https://pvs-studio.com/en/docs/warnings/v574/> The 'hw_recv' pointer
is used simultaneously as an array and as a pointer to single object. Check
lines: 375, 457.

ntnic_ethdev.c (844)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (866)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the tenth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (907)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (974)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the seventh actual argument of the 'rte_log' function.
The UNSIGNED integer type argument is expected.

ntnic_ethdev.c (974)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

ntnic_ethdev.c (1012)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (1042)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (1076)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (1136)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (1277)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

ntnic_ethdev.c (1335)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

ntnic_ethdev.c (2302)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_ethdev.c (2308)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the sixth actual argument of the 'rte_log' function. The
SIGNED integer type argument is expected.

ntnic_filter.c (481)
V595 <https://pvs-studio.com/en/docs/warnings/v595/> The 'internals'
pointer was utilized before it was verified against nullptr. Check lines:
481, 487.

ntnic_filter.c (1159)
V560 <https://pvs-studio.com/en/docs/warnings/v560/> A part of conditional
expression is always false: !p_nt4ga_stat.

ntnic_filter.c (357)
V576 <https://pvs-studio.com/en/docs/warnings/v576/> Incorrect format.
Consider checking the fifth actual argument of the 'rte_log' function. The
UNSIGNED integer type argument is expected.

ntnic_filter.c (1121)
V1027 <https://pvs-studio.com/en/docs/warnings/v1027/> Pointer to an object
of the 'flow_handle' class is cast to unrelated 'rte_flow' class.

ntnic_filter.c (1143)
V1027 <https://pvs-studio.com/en/docs/warnings/v1027/> Pointer to an object
of the 'rte_flow' class is cast to unrelated 'flow_handle' class.

ntnic_vfio.c (81)
V1048 <https://pvs-studio.com/en/docs/warnings/v1048/> The
'vfio->container_fd' variable was assigned the same value.

On Thu, Feb 20, 2025 at 2:04 PM Serhii Iliushyk <sil-plv@napatech.com>
wrote:

> This patchset adds support for the new adapter NT400D13.
>
> Danylo Vodopianov (23):
>   net/ntnic: add link agx 100g
>   net/ntnic: add link state machine
>   net/ntnic: add rpf and gfg init
>   net/ntnic: add agx setup for port
>   net/ntnic: add host loopback init
>   net/ntnic: add line loopback init
>   net/ntnic: add 100 gbps port init
>   net/ntnic: add port post init
>   net/ntnic: add nim low power API
>   net/ntnic: add link handling API
>   net/ntnic: add port init to the state machine
>   net/ntnic: add port disable API
>   net/ntnic: add nt400d13 pcm init
>   net/ntnic: add HIF clock test
>   net/ntnic: add nt400d13 PRM module init
>   net/ntnic: add nt400d13 PRM module reset
>   net/ntnic: add SPI v3 support for FPGA
>   net/ntnic: add i2cm init
>   net/ntnic: add pca init
>   net/ntnic: add pcal init
>   net/ntnic: add reset PHY init
>   net/ntnic: add igam module init
>   net/ntnic: init IGAM and config PLL for FPGA
>
> Serhii Iliushyk (9):
>   net/ntnic: add minimal initialization new NIC NT400D13
>   net/ntnic: add minimal reset FPGA
>   net/ntnic: add FPGA modules and registers
>   net/ntnic: add setup for fpga reset
>   net/ntnic: add default reset setting for NT400D13
>   net/ntnic: add DDR calibration to reset stage
>   net/ntnic: add PHY ftile reset
>   net/ntnic: add clock init
>   net/ntnic: revert untrusted loop bound
>
>  doc/guides/nics/ntnic.rst                     |    7 +-
>  doc/guides/rel_notes/release_25_03.rst        |    4 +
>  drivers/net/ntnic/adapter/nt4ga_adapter.c     |    9 +
>  drivers/net/ntnic/include/nt4ga_link.h        |    7 +
>  drivers/net/ntnic/include/nthw_gfg.h          |   33 +
>  drivers/net/ntnic/include/ntnic_nim.h         |    5 +
>  .../include/ntnic_nthw_fpga_rst_nt400dxx.h    |   34 +
>  .../link_agx_100g/nt4ga_agx_link_100g.c       | 1029 ++++++
>  drivers/net/ntnic/meson.build                 |   16 +
>  drivers/net/ntnic/nim/i2c_nim.c               |  158 +-
>  drivers/net/ntnic/nim/i2c_nim.h               |    6 +
>  ...00D13_U62_Si5332-GM2-RevD-1_V5-Registers.h |  425 +++
>  .../net/ntnic/nthw/core/include/nthw_fpga.h   |   10 +
>  .../net/ntnic/nthw/core/include/nthw_gmf.h    |    2 +
>  .../net/ntnic/nthw/core/include/nthw_hif.h    |    4 +
>  .../net/ntnic/nthw/core/include/nthw_i2cm.h   |    3 +
>  .../net/ntnic/nthw/core/include/nthw_igam.h   |   40 +
>  .../ntnic/nthw/core/include/nthw_pca9532.h    |   25 +
>  .../ntnic/nthw/core/include/nthw_pcal6416a.h  |   33 +
>  .../nthw/core/include/nthw_pcm_nt400dxx.h     |   40 +
>  .../ntnic/nthw/core/include/nthw_phy_tile.h   |  156 +
>  .../nthw/core/include/nthw_prm_nt400dxx.h     |   32 +
>  .../nthw/core/include/nthw_si5332_si5156.h    |   63 +
>  .../net/ntnic/nthw/core/include/nthw_spi_v3.h |  107 +
>  .../net/ntnic/nthw/core/include/nthw_spim.h   |   58 +
>  .../net/ntnic/nthw/core/include/nthw_spis.h   |   63 +
>  .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   |  220 ++
>  .../core/nt400dxx/reset/nthw_fpga_rst9574.c   |  377 ++
>  .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |  427 +++
>  drivers/net/ntnic/nthw/core/nthw_fpga.c       |  464 +++
>  drivers/net/ntnic/nthw/core/nthw_gfg.c        |  340 ++
>  drivers/net/ntnic/nthw/core/nthw_gmf.c        |   41 +
>  drivers/net/ntnic/nthw/core/nthw_hif.c        |   92 +
>  drivers/net/ntnic/nthw/core/nthw_i2cm.c       |  139 +
>  drivers/net/ntnic/nthw/core/nthw_igam.c       |   93 +
>  drivers/net/ntnic/nthw/core/nthw_pca9532.c    |   60 +
>  drivers/net/ntnic/nthw/core/nthw_pcal6416a.c  |  103 +
>  .../net/ntnic/nthw/core/nthw_pcm_nt400dxx.c   |   80 +
>  drivers/net/ntnic/nthw/core/nthw_phy_tile.c   | 1242 +++++++
>  .../net/ntnic/nthw/core/nthw_prm_nt400dxx.c   |   55 +
>  .../net/ntnic/nthw/core/nthw_si5332_si5156.c  |  142 +
>  drivers/net/ntnic/nthw/core/nthw_spi_v3.c     |  358 ++
>  drivers/net/ntnic/nthw/core/nthw_spim.c       |  113 +
>  drivers/net/ntnic/nthw/core/nthw_spis.c       |  121 +
>  drivers/net/ntnic/nthw/nthw_drv.h             |   31 +
>  drivers/net/ntnic/nthw/nthw_platform.c        |    3 +
>  drivers/net/ntnic/nthw/nthw_platform_drv.h    |    2 +
>  .../supported/nthw_fpga_9574_055_049_0000.c   | 3124 +++++++++++++++++
>  .../nthw/supported/nthw_fpga_instances.c      |    5 +-
>  .../nthw/supported/nthw_fpga_instances.h      |    1 +
>  .../ntnic/nthw/supported/nthw_fpga_mod_defs.h |   11 +
>  .../nthw/supported/nthw_fpga_mod_str_map.c    |   11 +
>  .../ntnic/nthw/supported/nthw_fpga_reg_defs.h |   11 +
>  .../nthw/supported/nthw_fpga_reg_defs_igam.h  |   32 +
>  .../supported/nthw_fpga_reg_defs_pci_ta.h     |   33 +
>  .../nthw_fpga_reg_defs_pcm_nt400dxx.h         |   29 +
>  .../nthw/supported/nthw_fpga_reg_defs_pdi.h   |   49 +
>  .../supported/nthw_fpga_reg_defs_phy_tile.h   |  213 ++
>  .../nthw_fpga_reg_defs_prm_nt400dxx.h         |   26 +
>  .../nthw/supported/nthw_fpga_reg_defs_rfd.h   |   38 +
>  .../supported/nthw_fpga_reg_defs_rst9574.h    |   35 +
>  .../nthw/supported/nthw_fpga_reg_defs_spim.h  |   76 +
>  .../nthw/supported/nthw_fpga_reg_defs_spis.h  |   51 +
>  .../nthw/supported/nthw_fpga_reg_defs_tint.h  |   28 +
>  drivers/net/ntnic/ntnic_ethdev.c              |    1 +
>  drivers/net/ntnic/ntnic_filter/ntnic_filter.c |    2 +-
>  drivers/net/ntnic/ntnic_mod_reg.c             |   47 +
>  drivers/net/ntnic/ntnic_mod_reg.h             |   25 +
>  68 files changed, 10709 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/net/ntnic/include/nthw_gfg.h
>  create mode 100644
> drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h
>  create mode 100644
> drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
>  create mode 100644
> drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_igam.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
>  create mode 100644
> drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spim.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spis.h
>  create mode 100644
> drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
>  create mode 100644
> drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
>  create mode 100644
> drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_gfg.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_igam.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_pca9532.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_phy_tile.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_spi_v3.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_spim.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_spis.c
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h
>  create mode 100644
> drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h
>
> --
> 2.45.0
>
>

[-- Attachment #2: Type: text/html, Size: 127854 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA
  2025-02-20 22:03 ` [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA Serhii Iliushyk
@ 2025-02-22 19:21   ` Stephen Hemminger
  0 siblings, 0 replies; 39+ messages in thread
From: Stephen Hemminger @ 2025-02-22 19:21 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm, Danylo Vodopianov

On Thu, 20 Feb 2025 23:03:49 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> +/*
> + * Send Tx data using the SPIM module and receive any data using the SPIS module.
> + * The data are sent and received being wrapped into a SPI v3 container.
> + */
> +int nthw_spi_v3_transfer(nthw_spi_v3_t *p, uint16_t opcode, struct tx_rx_buf *tx_buf,
> +	struct tx_rx_buf *rx_buf)
> +{
> +	const uint16_t max_payload_rx_size = rx_buf->size;
> +	int result = 0;
> +
> +#pragma pack(push, 1)
> +	union {
> +		uint32_t raw;
> +
> +		struct {
> +			uint16_t opcode;
> +			uint16_t size;
> +		};
> +	} spi_tx_hdr;
> +
> +	union {
> +		uint32_t raw;
> +
> +		struct {
> +			uint16_t error_code;
> +			uint16_t size;
> +		};
> +	} spi_rx_hdr;
> +
> +#pragma pack(pop)

Use of pragma's is strongly discouraged. For packed data use __rte_packed_begin, __rte_packed_end.
Not sure why packing is needed here at all. The union will result in the same

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 00/32] add new adapter NT400D13
  2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
                   ` (32 preceding siblings ...)
  2025-02-20 23:49 ` [PATCH v1 00/32] add new adapter NT400D13 Stephen Hemminger
@ 2025-02-22 21:41 ` Stephen Hemminger
  33 siblings, 0 replies; 39+ messages in thread
From: Stephen Hemminger @ 2025-02-22 21:41 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm

On Thu, 20 Feb 2025 23:03:24 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> This patchset adds support for the new adapter NT400D13.
> 
> Danylo Vodopianov (23):
>   net/ntnic: add link agx 100g
>   net/ntnic: add link state machine
>   net/ntnic: add rpf and gfg init
>   net/ntnic: add agx setup for port
>   net/ntnic: add host loopback init
>   net/ntnic: add line loopback init
>   net/ntnic: add 100 gbps port init
>   net/ntnic: add port post init
>   net/ntnic: add nim low power API
>   net/ntnic: add link handling API
>   net/ntnic: add port init to the state machine
>   net/ntnic: add port disable API
>   net/ntnic: add nt400d13 pcm init
>   net/ntnic: add HIF clock test
>   net/ntnic: add nt400d13 PRM module init
>   net/ntnic: add nt400d13 PRM module reset
>   net/ntnic: add SPI v3 support for FPGA
>   net/ntnic: add i2cm init
>   net/ntnic: add pca init
>   net/ntnic: add pcal init
>   net/ntnic: add reset PHY init
>   net/ntnic: add igam module init
>   net/ntnic: init IGAM and config PLL for FPGA
> 
> Serhii Iliushyk (9):
>   net/ntnic: add minimal initialization new NIC NT400D13
>   net/ntnic: add minimal reset FPGA
>   net/ntnic: add FPGA modules and registers
>   net/ntnic: add setup for fpga reset
>   net/ntnic: add default reset setting for NT400D13
>   net/ntnic: add DDR calibration to reset stage
>   net/ntnic: add PHY ftile reset
>   net/ntnic: add clock init
>   net/ntnic: revert untrusted loop bound
> 
>  doc/guides/nics/ntnic.rst                     |    7 +-
>  doc/guides/rel_notes/release_25_03.rst        |    4 +
>  drivers/net/ntnic/adapter/nt4ga_adapter.c     |    9 +
>  drivers/net/ntnic/include/nt4ga_link.h        |    7 +
>  drivers/net/ntnic/include/nthw_gfg.h          |   33 +
>  drivers/net/ntnic/include/ntnic_nim.h         |    5 +
>  .../include/ntnic_nthw_fpga_rst_nt400dxx.h    |   34 +
>  .../link_agx_100g/nt4ga_agx_link_100g.c       | 1029 ++++++
>  drivers/net/ntnic/meson.build                 |   16 +
>  drivers/net/ntnic/nim/i2c_nim.c               |  158 +-
>  drivers/net/ntnic/nim/i2c_nim.h               |    6 +
>  ...00D13_U62_Si5332-GM2-RevD-1_V5-Registers.h |  425 +++
>  .../net/ntnic/nthw/core/include/nthw_fpga.h   |   10 +
>  .../net/ntnic/nthw/core/include/nthw_gmf.h    |    2 +
>  .../net/ntnic/nthw/core/include/nthw_hif.h    |    4 +
>  .../net/ntnic/nthw/core/include/nthw_i2cm.h   |    3 +
>  .../net/ntnic/nthw/core/include/nthw_igam.h   |   40 +
>  .../ntnic/nthw/core/include/nthw_pca9532.h    |   25 +
>  .../ntnic/nthw/core/include/nthw_pcal6416a.h  |   33 +
>  .../nthw/core/include/nthw_pcm_nt400dxx.h     |   40 +
>  .../ntnic/nthw/core/include/nthw_phy_tile.h   |  156 +
>  .../nthw/core/include/nthw_prm_nt400dxx.h     |   32 +
>  .../nthw/core/include/nthw_si5332_si5156.h    |   63 +
>  .../net/ntnic/nthw/core/include/nthw_spi_v3.h |  107 +
>  .../net/ntnic/nthw/core/include/nthw_spim.h   |   58 +
>  .../net/ntnic/nthw/core/include/nthw_spis.h   |   63 +
>  .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   |  220 ++
>  .../core/nt400dxx/reset/nthw_fpga_rst9574.c   |  377 ++
>  .../nt400dxx/reset/nthw_fpga_rst_nt400dxx.c   |  427 +++
>  drivers/net/ntnic/nthw/core/nthw_fpga.c       |  464 +++
>  drivers/net/ntnic/nthw/core/nthw_gfg.c        |  340 ++
>  drivers/net/ntnic/nthw/core/nthw_gmf.c        |   41 +
>  drivers/net/ntnic/nthw/core/nthw_hif.c        |   92 +
>  drivers/net/ntnic/nthw/core/nthw_i2cm.c       |  139 +
>  drivers/net/ntnic/nthw/core/nthw_igam.c       |   93 +
>  drivers/net/ntnic/nthw/core/nthw_pca9532.c    |   60 +
>  drivers/net/ntnic/nthw/core/nthw_pcal6416a.c  |  103 +
>  .../net/ntnic/nthw/core/nthw_pcm_nt400dxx.c   |   80 +
>  drivers/net/ntnic/nthw/core/nthw_phy_tile.c   | 1242 +++++++
>  .../net/ntnic/nthw/core/nthw_prm_nt400dxx.c   |   55 +
>  .../net/ntnic/nthw/core/nthw_si5332_si5156.c  |  142 +
>  drivers/net/ntnic/nthw/core/nthw_spi_v3.c     |  358 ++
>  drivers/net/ntnic/nthw/core/nthw_spim.c       |  113 +
>  drivers/net/ntnic/nthw/core/nthw_spis.c       |  121 +
>  drivers/net/ntnic/nthw/nthw_drv.h             |   31 +
>  drivers/net/ntnic/nthw/nthw_platform.c        |    3 +
>  drivers/net/ntnic/nthw/nthw_platform_drv.h    |    2 +
>  .../supported/nthw_fpga_9574_055_049_0000.c   | 3124 +++++++++++++++++
>  .../nthw/supported/nthw_fpga_instances.c      |    5 +-
>  .../nthw/supported/nthw_fpga_instances.h      |    1 +
>  .../ntnic/nthw/supported/nthw_fpga_mod_defs.h |   11 +
>  .../nthw/supported/nthw_fpga_mod_str_map.c    |   11 +
>  .../ntnic/nthw/supported/nthw_fpga_reg_defs.h |   11 +
>  .../nthw/supported/nthw_fpga_reg_defs_igam.h  |   32 +
>  .../supported/nthw_fpga_reg_defs_pci_ta.h     |   33 +
>  .../nthw_fpga_reg_defs_pcm_nt400dxx.h         |   29 +
>  .../nthw/supported/nthw_fpga_reg_defs_pdi.h   |   49 +
>  .../supported/nthw_fpga_reg_defs_phy_tile.h   |  213 ++
>  .../nthw_fpga_reg_defs_prm_nt400dxx.h         |   26 +
>  .../nthw/supported/nthw_fpga_reg_defs_rfd.h   |   38 +
>  .../supported/nthw_fpga_reg_defs_rst9574.h    |   35 +
>  .../nthw/supported/nthw_fpga_reg_defs_spim.h  |   76 +
>  .../nthw/supported/nthw_fpga_reg_defs_spis.h  |   51 +
>  .../nthw/supported/nthw_fpga_reg_defs_tint.h  |   28 +
>  drivers/net/ntnic/ntnic_ethdev.c              |    1 +
>  drivers/net/ntnic/ntnic_filter/ntnic_filter.c |    2 +-
>  drivers/net/ntnic/ntnic_mod_reg.c             |   47 +
>  drivers/net/ntnic/ntnic_mod_reg.h             |   25 +
>  68 files changed, 10709 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/net/ntnic/include/nthw_gfg.h
>  create mode 100644 drivers/net/ntnic/include/ntnic_nthw_fpga_rst_nt400dxx.h
>  create mode 100644 drivers/net/ntnic/link_mgmt/link_agx_100g/nt4ga_agx_link_100g.c
>  create mode 100644 drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_igam.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pca9532.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcal6416a.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_phy_tile.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_prm_nt400dxx.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spi_v3.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spim.h
>  create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_spis.h
>  create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst9574.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nt400dxx/reset/nthw_fpga_rst_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_gfg.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_igam.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_pca9532.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcal6416a.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_pcm_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_phy_tile.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_prm_nt400dxx.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_spi_v3.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_spim.c
>  create mode 100644 drivers/net/ntnic/nthw/core/nthw_spis.c
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_9574_055_049_0000.c
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_igam.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pci_ta.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pcm_nt400dxx.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_pdi.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_phy_tile.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_prm_nt400dxx.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rfd.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_rst9574.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spim.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_spis.h
>  create mode 100644 drivers/net/ntnic/nthw/supported/nthw_fpga_reg_defs_tint.h
> 

I will merge this for next-net BUT
The driver is better after this patch series, but still low quality.

Several pre-existing issues in this driver; looks like it did not get enough
review during 24.11 release when it was merged.

    ✔ passed
    ✘ Failed

Basic hygiene
    ✔ Look at CI results in patchwork
    ✔ Merge cleanly with git am
    ✔ Run checkpatches
    ✔ Run check-git-log
    ✔ Run check-symbol-maps.sh
    ✔ Run check-doc-vs-code
    ✔ Run check-spdk-tag

Builds
    ✔ Normal Gcc build; make sure driver is built!
    ✔ Use latest experimental Gcc 15
    ✔ Clang build using current version (clang-19)
    ✔ Doc build
    o Build for 32 bit x86
    o Cross build for Windows (if applicable)
    ✔ Debug build
    ✔ Enable asserts
    ✔ Test meson builds

Experimental builds:
    ✔ Enable address sanitizer

    ✘ Enable extra warnings (edit meson.build) for
        -Wvla, -Wformat-truncation, -Waddress-of-packed-member

    Let's not add more VLA's, these could be arrays with a fixed size.

[1470/3259] Compiling C object drivers...ofile_inline_flow_api_hw_db_inline.c.o
../drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c: In function ‘hw_db_inline_alloc_prioritized_cfn’:
../drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c:1346:9: warning: ISO C90 forbids variable length array ‘sorted_priority’ [-Wvla]
 1346 |         } sorted_priority[db->nb_cat];
      |         ^

[1479/3259] Compiling C object drivers...ile_inline_flow_api_profile_inline.c.o
../drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c: In function ‘setup_db_qsl_data’:
../drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c:3193:17: warning: ISO C90 forbids variable length array ‘ports’ [-Wvla]
 3193 |                 uint32_t ports[fd->dst_num_avail];
      |                 ^~~~~~~~
../drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c:3194:17: warning: ISO C90 forbids variable length array ‘queues’ [-Wvla]
 3194 |                 uint32_t queues[fd->dst_num_avail];
      |                 ^~~~~~~~

This is not doing what you expect, ports is uint32_t array

		uint32_t ports[fd->dst_num_avail];
		uint32_t queues[fd->dst_num_avail];

		memset(ports, 0, fd->dst_num_avail);
		memset(queues, 0, fd->dst_num_avail);

Instead use HW_DB_INLINE_MAX_QST_PER_QSL


Look for anti-patterns:
    ✘ Driver must not disable warnings with compiler flags or pragma's
      Using pragma pack()

    ✘ Driver must not use thread and signal
      Using thread to monitor, should not be done by PMD specific thread.

    ✘ Driver should not call abort() or assert() directly
      Is using assert() when should be using RTE_ASSERT()

    ✘ Review exposed symbol names
      The driver exposes lots of global symbols (when statically linked)
      that do not have a consistent prefix of nthw_...
      Examples: get_rx_idle(), set_rx_idle(), dev_flow_init()


    ✔ Apply coccinelle scripts

    ✘ Review use of malloc
      Several places call malloc but do not check return value

    ✘ Review use of memset

The code related to stats has several issues:
   - function returns -1 but never checked by callers
   - stats structure is already zero'd by ethdev
   - if queue is greater than RTE_ETHDEV_QUEUE_STAT_CNTRS the statistics should
     still be counted for that queue, just no per-queue stats
   - the use of term if_index is potentially confusing; normally if_index refers to the interface
     index assigned by the OS used for ioctl's etc. In this driver it appears to be the index
     of the phy.

static int dpdk_stats_collect(struct pmd_internals *internals, struct rte_eth_stats *stats)
{
	const struct ntnic_filter_ops *ntnic_filter_ops = get_ntnic_filter_ops();

	if (ntnic_filter_ops == NULL) {
		NT_LOG_DBGX(ERR, NTNIC, "ntnic_filter_ops uninitialized");
		return -1;
	}
...
	ntnic_filter_ops->poll_statistics(internals);
	memset(stats, 0, sizeof(*stats));

	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && i < internals->nb_rx_queues; i++) {
		stats->q_ipackets[i] = internals->rxq_scg[i].rx_pkts;
		stats->q_ibytes[i] = internals->rxq_scg[i].rx_bytes;
		rx_total += stats->q_ipackets[i];
		rx_total_b += stats->q_ibytes[i];
	}

	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && i < internals->nb_tx_queues; i++) {
		stats->q_opackets[i] = internals->txq_scg[i].tx_pkts;
		stats->q_obytes[i] = internals->txq_scg[i].tx_bytes;
		stats->q_errors[i] = internals->txq_scg[i].err_pkts;
		tx_total += stats->q_opackets[i];
		tx_total_b += stats->q_obytes[i];
		tx_err_total += stats->q_errors[i];
	}

Other:
    The handling of queue start/stop in this device is odd.
    Doesn't do deferred start.
    When Rx is stopped most drivers do some action to stop the hardware.

    Given the use of thread, driver should *not* have been merged in 24.11.
    The DPDK has a set of assumptions about thread and process model, and
    drivers making their own threads can cause problems in applications.
    (Other drivers use alarm for this type of port monitor function).

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 20/32] net/ntnic: add clock init
  2025-02-20 22:03 ` [PATCH v1 20/32] net/ntnic: add clock init Serhii Iliushyk
@ 2025-03-05 17:03   ` David Marchand
  2025-03-07 10:20     ` Serhii Iliushyk
  0 siblings, 1 reply; 39+ messages in thread
From: David Marchand @ 2025-03-05 17:03 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm, stephen, Thomas Monjalon

On Thu, Feb 20, 2025 at 11:06 PM Serhii Iliushyk <sil-plv@napatech.com> wrote:
> diff --git a/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
> new file mode 100644
> index 0000000000..f87828fcfe
> --- /dev/null
> +++ b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
> @@ -0,0 +1,425 @@
> +/*
> + * Si5332-GM2 Rev D Configuration Register Export Header File
> + *
> + * This file represents a series of Skyworks Si5332-GM2 Rev D
> + * register writes that can be performed to load a single configuration
> + * on a device. It was created by a Skyworks ClockBuilder Pro
> + * export tool.
> + *

This file is missing a SPDX tag.
Please send a fix or we will have to revert this change.

The filename also looks strange, as it does not follow some kind of
implicit convention (when I compare to other files in this driver).
Could it be renamed?


-- 
David Marchand


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 20/32] net/ntnic: add clock init
  2025-03-05 17:03   ` David Marchand
@ 2025-03-07 10:20     ` Serhii Iliushyk
  0 siblings, 0 replies; 39+ messages in thread
From: Serhii Iliushyk @ 2025-03-07 10:20 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Mykola Kostenok, Christian Koue Muf, stephen,
	Thomas Monjalon, Uffe Jakobsen

[-- Attachment #1: Type: text/plain, Size: 1679 bytes --]

On 05.03.2025, 19:03, "David Marchand" <david.marchand@redhat.com> wrote:

On Thu, Feb 20, 2025 at 11:06 PM Serhii Iliushyk <sil-plv@napatech.com> wrote:
> diff --git a/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
> new file mode 100644
> index 0000000000..f87828fcfe
> --- /dev/null
> +++ b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
> @@ -0,0 +1,425 @@
> +/*
> + * Si5332-GM2 Rev D Configuration Register Export Header File
> + *
> + * This file represents a series of Skyworks Si5332-GM2 Rev D
> + * register writes that can be performed to load a single configuration
> + * on a device. It was created by a Skyworks ClockBuilder Pro
> + * export tool.
> + *

This file is missing a SPDX tag.
Please send a fix or we will have to revert this change.

The filename also looks strange, as it does not follow some kind of
implicit convention (when I compare to other files in this driver).
Could it be renamed?


--
David Marchand
Hi David,
We will add the SDPX to the current file. Thanks for noticing it.

The clock profiles are named according to our internal documentation on the PCB (board) design - the "Uxx" is actually the component number on the board design - the versioning ensures that we can support multiple versions of the clock profile for different PCB revisions.
Is it suitable for you to change the name of the file to all lowercase and remove dashes:
NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h ---> nt400d13_u62_si5332_gm2_revd_1_v5_registers.h

BR,
Serhii

[-- Attachment #2: Type: text/html, Size: 4809 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2025-03-07 10:20 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 01/32] net/ntnic: add link agx 100g Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 02/32] net/ntnic: add link state machine Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 03/32] net/ntnic: add rpf and gfg init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 04/32] net/ntnic: add agx setup for port Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 05/32] net/ntnic: add host loopback init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 06/32] net/ntnic: add line " Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 07/32] net/ntnic: add 100 gbps port init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 08/32] net/ntnic: add port post init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 09/32] net/ntnic: add nim low power API Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 10/32] net/ntnic: add link handling API Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 11/32] net/ntnic: add port init to the state machine Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 12/32] net/ntnic: add port disable API Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 13/32] net/ntnic: add minimal initialization new NIC NT400D13 Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 14/32] net/ntnic: add minimal reset FPGA Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 15/32] net/ntnic: add FPGA modules and registers Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 16/32] net/ntnic: add setup for fpga reset Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 17/32] net/ntnic: add default reset setting for NT400D13 Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 18/32] net/ntnic: add DDR calibration to reset stage Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 19/32] net/ntnic: add PHY ftile reset Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 20/32] net/ntnic: add clock init Serhii Iliushyk
2025-03-05 17:03   ` David Marchand
2025-03-07 10:20     ` Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 21/32] net/ntnic: add nt400d13 pcm init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 22/32] net/ntnic: add HIF clock test Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 23/32] net/ntnic: add nt400d13 PRM module init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 24/32] net/ntnic: add nt400d13 PRM module reset Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA Serhii Iliushyk
2025-02-22 19:21   ` Stephen Hemminger
2025-02-20 22:03 ` [PATCH v1 26/32] net/ntnic: add i2cm init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 27/32] net/ntnic: add pca init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 28/32] net/ntnic: add pcal init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 29/32] net/ntnic: add reset PHY init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 30/32] net/ntnic: add igam module init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 31/32] net/ntnic: init IGAM and config PLL for FPGA Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 32/32] net/ntnic: revert untrusted loop bound Serhii Iliushyk
2025-02-20 22:31   ` Stephen Hemminger
2025-02-20 23:49 ` [PATCH v1 00/32] add new adapter NT400D13 Stephen Hemminger
2025-02-22 21:41 ` Stephen Hemminger

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).