DPDK patches and discussions
 help / color / mirror / Atom feed
From: Serhii Iliushyk <sil-plv@napatech.com>
To: dev@dpdk.org
Cc: mko-plv@napatech.com, sil-plv@napatech.com, ckm@napatech.com,
	andrew.rybchenko@oktetlabs.ru, ferruh.yigit@amd.com
Subject: [PATCH v9 21/21] net/ntnic: add physical layer control module
Date: Tue, 16 Jul 2024 14:02:10 +0200	[thread overview]
Message-ID: <20240716120216.3032484-21-sil-plv@napatech.com> (raw)
In-Reply-To: <20240716120216.3032484-1-sil-plv@napatech.com>

Adds functionality to control the physical layer of the OSI model.
This takes the form of the module
MAC PCS (Media Access Control Physical Coding Sublayer).
The functionality is used by the 100G link functionality to establish link.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/include/nt4ga_link.h        |   1 +
 .../link_mgmt/link_100g/nt4ga_link_100g.c     | 393 +++++++-
 drivers/net/ntnic/meson.build                 |   1 +
 .../net/ntnic/nthw/core/include/nthw_core.h   |   1 +
 .../ntnic/nthw/core/include/nthw_mac_pcs.h    | 250 +++++
 drivers/net/ntnic/nthw/core/nthw_mac_pcs.c    | 894 ++++++++++++++++++
 6 files changed, 1538 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_mac_pcs.h
 create mode 100644 drivers/net/ntnic/nthw/core/nthw_mac_pcs.c

diff --git a/drivers/net/ntnic/include/nt4ga_link.h b/drivers/net/ntnic/include/nt4ga_link.h
index 5a16afea2a..8366484830 100644
--- a/drivers/net/ntnic/include/nt4ga_link.h
+++ b/drivers/net/ntnic/include/nt4ga_link.h
@@ -78,6 +78,7 @@ typedef struct port_action_s {
 
 typedef struct adapter_100g_s {
 	nim_i2c_ctx_t nim_ctx[NUM_ADAPTER_PORTS_MAX];	/* Should be the first field */
+	nthw_mac_pcs_t mac_pcs100g[NUM_ADAPTER_PORTS_MAX];
 	nthw_gpio_phy_t gpio_phy[NUM_ADAPTER_PORTS_MAX];
 } adapter_100g_t;
 
diff --git a/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c b/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c
index ed0b89d417..8f0afa1f60 100644
--- a/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c
+++ b/drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c
@@ -10,6 +10,168 @@
 #include "i2c_nim.h"
 #include "ntnic_mod_reg.h"
 
+/*
+ * Swap tx/rx polarity
+ */
+static int _swap_tx_rx_polarity(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs, int port, bool swap)
+{
+	const bool tx_polarity_swap[2][4] = { { true, true, false, false },
+		{ false, true, false, false }
+	};
+	const bool rx_polarity_swap[2][4] = { { false, true, true, true },
+		{ false, true, true, false }
+	};
+	uint8_t lane;
+
+	(void)drv;
+
+	for (lane = 0U; lane < 4U; lane++) {
+		if (swap) {
+			nthw_mac_pcs_swap_gty_tx_polarity(mac_pcs, lane,
+				tx_polarity_swap[port][lane]);
+			nthw_mac_pcs_swap_gty_rx_polarity(mac_pcs, lane,
+				rx_polarity_swap[port][lane]);
+
+		} else {
+			nthw_mac_pcs_swap_gty_tx_polarity(mac_pcs, lane, false);
+			nthw_mac_pcs_swap_gty_rx_polarity(mac_pcs, lane, false);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Reset RX
+ */
+static int _reset_rx(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs)
+{
+	(void)drv;
+
+	nthw_mac_pcs_rx_path_rst(mac_pcs, true);
+	nt_os_wait_usec(10000);	/* 10ms */
+	nthw_mac_pcs_rx_path_rst(mac_pcs, false);
+	nt_os_wait_usec(10000);	/* 10ms */
+
+	return 0;
+}
+
+static void _set_loopback(struct adapter_info_s *p_adapter_info,
+	nthw_mac_pcs_t *mac_pcs,
+	int intf_no,
+	uint32_t mode,
+	uint32_t last_mode)
+{
+	bool swap_polerity = true;
+
+	switch (mode) {
+	case 1:
+		NT_LOG(INF, NTNIC, "%s: Applying host loopback\n",
+			p_adapter_info->mp_port_id_str[intf_no]);
+		nthw_mac_pcs_set_fec(mac_pcs, true);
+		nthw_mac_pcs_set_host_loopback(mac_pcs, true);
+		swap_polerity = false;
+		break;
+
+	case 2:
+		NT_LOG(INF, NTNIC, "%s: Applying line loopback\n",
+			p_adapter_info->mp_port_id_str[intf_no]);
+		nthw_mac_pcs_set_line_loopback(mac_pcs, true);
+		break;
+
+	default:
+		switch (last_mode) {
+		case 1:
+			NT_LOG(INF, NTNIC, "%s: Removing host loopback\n",
+				p_adapter_info->mp_port_id_str[intf_no]);
+			nthw_mac_pcs_set_host_loopback(mac_pcs, false);
+			break;
+
+		case 2:
+			NT_LOG(INF, NTNIC, "%s: Removing line loopback\n",
+				p_adapter_info->mp_port_id_str[intf_no]);
+			nthw_mac_pcs_set_line_loopback(mac_pcs, false);
+			break;
+
+		default:
+			/* Do nothing */
+			break;
+		}
+
+		break;
+	}
+
+	if (p_adapter_info->fpga_info.nthw_hw_info.hw_id == 2 ||
+		p_adapter_info->hw_info.n_nthw_adapter_id == NT_HW_ADAPTER_ID_NT200A02) {
+		(void)_swap_tx_rx_polarity(p_adapter_info, mac_pcs, intf_no, swap_polerity);
+	}
+
+	/* After changing the loopback the system must be properly reset */
+	_reset_rx(p_adapter_info, mac_pcs);
+
+	nt_os_wait_usec(10000);	/* 10ms - arbitrary choice */
+
+	if (!nthw_mac_pcs_is_rx_path_rst(mac_pcs)) {
+		nthw_mac_pcs_reset_bip_counters(mac_pcs);
+
+		if (!nthw_mac_pcs_get_fec_bypass(mac_pcs))
+			nthw_mac_pcs_reset_fec_counters(mac_pcs);
+	}
+}
+
+/*
+ * Function to retrieve the current state of a link (for one port)
+ */
+static int _link_state_build(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs,
+	nthw_gpio_phy_t *gpio_phy, int port, link_state_t *state,
+	bool is_port_disabled)
+{
+	uint32_t abs;
+	uint32_t phy_link_state;
+	uint32_t lh_abs;
+	uint32_t ll_phy_link_state;
+	uint32_t link_down_cnt;
+	uint32_t nim_interr;
+	uint32_t lh_local_fault;
+	uint32_t lh_remote_fault;
+	uint32_t lh_internal_local_fault;
+	uint32_t lh_received_local_fault;
+
+	memset(state, 0, sizeof(*state));
+	state->link_disabled = is_port_disabled;
+	nthw_mac_pcs_get_link_summary(mac_pcs, &abs, &phy_link_state, &lh_abs, &ll_phy_link_state,
+		&link_down_cnt, &nim_interr, &lh_local_fault,
+		&lh_remote_fault, &lh_internal_local_fault,
+		&lh_received_local_fault);
+
+	assert(port >= 0 && port < NUM_ADAPTER_PORTS_MAX);
+	state->nim_present = nthw_gpio_phy_is_module_present(gpio_phy, (uint8_t)port);
+	state->lh_nim_absent = !state->nim_present;
+	state->link_up = phy_link_state ? true : false;
+
+	{
+		static char lsbuf[NUM_ADAPTER_MAX][NUM_ADAPTER_PORTS_MAX][256];
+		char buf[255];
+		const int adapter_no = drv->adapter_no;
+		snprintf(buf, sizeof(buf),
+			"%s: Port = %d: abs = %u, phy_link_state = %u, lh_abs = %u, "
+			"ll_phy_link_state = %u, "
+			"link_down_cnt = %u, nim_interr = %u, lh_local_fault = %u, lh_remote_fault = "
+			"%u, lh_internal_local_fault = %u, lh_received_local_fault = %u",
+			drv->mp_adapter_id_str, mac_pcs->mn_instance, abs, phy_link_state, lh_abs,
+			ll_phy_link_state, link_down_cnt, nim_interr, lh_local_fault,
+			lh_remote_fault, lh_internal_local_fault, lh_received_local_fault);
+
+		if (strcmp(lsbuf[adapter_no][port], buf) != 0) {
+			snprintf(lsbuf[adapter_no][port], sizeof(lsbuf[adapter_no][port]), "%s",
+				buf);
+			lsbuf[adapter_no][port][sizeof(lsbuf[adapter_no][port]) - 1U] = '\0';
+			NT_LOG(DBG, NTNIC, "%s\n", lsbuf[adapter_no][port]);
+		}
+	}
+	return 0;
+}
+
 /*
  * Check whether a NIM module is present
  */
@@ -20,6 +182,69 @@ static bool _nim_is_present(nthw_gpio_phy_t *gpio_phy, uint8_t if_no)
 	return nthw_gpio_phy_is_module_present(gpio_phy, if_no);
 }
 
+/*
+ * Enable RX
+ */
+static int _enable_rx(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs)
+{
+	(void)drv;	/* unused */
+	nthw_mac_pcs_set_rx_enable(mac_pcs, true);
+	return 0;
+}
+
+/*
+ * Enable TX
+ */
+static int _enable_tx(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs)
+{
+	(void)drv;	/* unused */
+	nthw_mac_pcs_set_tx_enable(mac_pcs, true);
+	nthw_mac_pcs_set_tx_sel_host(mac_pcs, true);
+	return 0;
+}
+
+/*
+ * Disable RX
+ */
+static int _disable_rx(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs)
+{
+	(void)drv;	/* unused */
+	nthw_mac_pcs_set_rx_enable(mac_pcs, false);
+	return 0;
+}
+
+/*
+ * Disable TX
+ */
+static int _disable_tx(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs)
+{
+	(void)drv;	/* unused */
+	nthw_mac_pcs_set_tx_enable(mac_pcs, false);
+	nthw_mac_pcs_set_tx_sel_host(mac_pcs, false);
+	return 0;
+}
+
+/*
+ * Check link once NIM is installed and link can be expected.
+ */
+static int check_link_state(adapter_info_t *drv, nthw_mac_pcs_t *mac_pcs)
+{
+	bool rst_required;
+	bool ber;
+	bool fec_all_locked;
+
+	rst_required = nthw_mac_pcs_reset_required(mac_pcs);
+
+	ber = nthw_mac_pcs_get_hi_ber(mac_pcs);
+
+	fec_all_locked = nthw_mac_pcs_get_fec_stat_all_am_locked(mac_pcs);
+
+	if (rst_required || ber || !fec_all_locked)
+		_reset_rx(drv, mac_pcs);
+
+	return 0;
+}
+
 /*
  * Initialize NIM, Code based on nt200e3_2_ptp.cpp: MyPort::createNim()
  */
@@ -31,6 +256,7 @@ static int _create_nim(adapter_info_t *drv, int port, bool enable)
 	nim_i2c_ctx_t *nim_ctx;
 	sfp_nim_state_t nim;
 	nt4ga_link_t *link_info = &drv->nt4ga_link;
+	nthw_mac_pcs_t *mac_pcs = &link_info->u.var100g.mac_pcs100g[port];
 
 	assert(port >= 0 && port < NUM_ADAPTER_PORTS_MAX);
 	assert(link_info->variables_initialized);
@@ -46,6 +272,12 @@ static int _create_nim(adapter_info_t *drv, int port, bool enable)
 		return 0;
 	}
 
+	if (!enable) {
+		_disable_rx(drv, mac_pcs);
+		_disable_tx(drv, mac_pcs);
+		_reset_rx(drv, mac_pcs);
+	}
+
 	/*
 	 * Perform PHY reset.
 	 */
@@ -114,14 +346,29 @@ static int _create_nim(adapter_info_t *drv, int port, bool enable)
  * The function shall not assume anything about the state of the adapter
  * and/or port.
  */
-static int _port_init(adapter_info_t *drv, int port)
+static int _port_init(adapter_info_t *drv, nthw_fpga_t *fpga, int port)
 {
+	int adapter_id;
+	int hw_id;
 	int res;
 	nt4ga_link_t *link_info = &drv->nt4ga_link;
 
+	nthw_mac_pcs_t *mac_pcs;
+
 	assert(port >= 0 && port < NUM_ADAPTER_PORTS_MAX);
 	assert(link_info->variables_initialized);
 
+	if (fpga && fpga->p_fpga_info) {
+		adapter_id = fpga->p_fpga_info->n_nthw_adapter_id;
+		hw_id = fpga->p_fpga_info->nthw_hw_info.hw_id;
+
+	} else {
+		adapter_id = -1;
+		hw_id = -1;
+	}
+
+	mac_pcs = &link_info->u.var100g.mac_pcs100g[port];
+
 	/*
 	 * Phase 1. Pre-state machine (`port init` functions)
 	 * 1.1) nt4ga_adapter::port_init()
@@ -134,6 +381,28 @@ static int _port_init(adapter_info_t *drv, int port)
 	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_mac_pcs_set_led_mode(mac_pcs, NTHW_MAC_PCS_LED_AUTO);
+	nthw_mac_pcs_set_receiver_equalization_mode(mac_pcs, nthw_mac_pcs_receiver_mode_lpm);
+
+	/*
+	 * NT200A01 build 2 HW and NT200A02 that require GTY polarity swap
+	 * if (adapter is `NT200A01 build 2 HW or NT200A02`)
+	 */
+	if (adapter_id == NT_HW_ADAPTER_ID_NT200A02 || hw_id == 2)
+		(void)_swap_tx_rx_polarity(drv, mac_pcs, port, true);
+
+	nthw_mac_pcs_set_ts_eop(mac_pcs, true);	/* end-of-frame timestamping */
+
+	/* Work in ABSOLUTE timing mode, don't set IFG mode. */
+
+	/* Phase 2. Pre-state machine (`setup` functions) */
+
+	/* 2.1) nt200a0x.cpp:Myport::setup() */
+	NT_LOG(DBG, NTNIC, "%s: Setting up port %d\n", drv->mp_port_id_str[port], port);
+
+	NT_LOG(DBG, NTNIC, "%s: Port %d: PHY TX enable\n", drv->mp_port_id_str[port], port);
+	_enable_tx(drv, mac_pcs);
+	_reset_rx(drv, mac_pcs);
 
 	/* Phase 3. Link state machine steps */
 
@@ -147,6 +416,50 @@ static int _port_init(adapter_info_t *drv, int port)
 
 	NT_LOG(DBG, NTNIC, "%s: NIM initialized\n", drv->mp_port_id_str[port]);
 
+	/* 3.2) MyPort::nimReady() */
+
+	/* 3.3) MyPort::nimReady100Gb() */
+
+	/* Setting FEC resets the lane counter in one half of the GMF */
+	nthw_mac_pcs_set_fec(mac_pcs, true);
+	NT_LOG(DBG, NTNIC, "%s: Port %d: HOST FEC enabled\n", drv->mp_port_id_str[port], port);
+
+	if (adapter_id == NT_HW_ADAPTER_ID_NT200A02 || hw_id == 2) {
+		const uint8_t pre = 5;
+		const uint8_t diff = 25;
+		const uint8_t post = 12;
+
+		uint8_t lane = 0;
+
+		for (lane = 0; lane < 4; lane++)
+			nthw_mac_pcs_set_gty_tx_tuning(mac_pcs, lane, pre, diff, post);
+
+	} else {
+		NT_LOG(ERR, NTNIC, "Unhandled AdapterId/HwId: %02x_hwid%d\n", adapter_id, hw_id);
+		assert(0);
+	}
+
+	_reset_rx(drv, mac_pcs);
+
+	/*
+	 * 3.4) MyPort::setLinkState()
+	 *
+	 * Compensation = 1640 - dly
+	 * CMAC-core dly 188 ns
+	 * FEC no correction 87 ns
+	 * FEC active correction 211
+	 */
+	if (nthw_mac_pcs_get_fec_valid(mac_pcs))
+		nthw_mac_pcs_set_timestamp_comp_rx(mac_pcs, (1640 - 188 - 211));
+
+	else
+		nthw_mac_pcs_set_timestamp_comp_rx(mac_pcs, (1640 - 188 - 87));
+
+	/* 3.5) uint32_t MyPort::macConfig(nt_link_state_t link_state) */
+	_enable_rx(drv, mac_pcs);
+
+	nthw_mac_pcs_set_host_loopback(mac_pcs, false);
+
 	return res;
 }
 
@@ -163,7 +476,9 @@ static int _common_ptp_nim_state_machine(void *data)
 	const int nb_ports = fpga_info->n_phy_ports;
 	uint32_t last_lpbk_mode[NUM_ADAPTER_PORTS_MAX];
 
+	nim_i2c_ctx_t *nim_ctx;
 	link_state_t *link_state;
+	nthw_mac_pcs_t *mac_pcs;
 	nthw_gpio_phy_t *gpio_phy;
 
 	if (!fpga) {
@@ -172,7 +487,9 @@ static int _common_ptp_nim_state_machine(void *data)
 	}
 
 	assert(adapter_no >= 0 && adapter_no < NUM_ADAPTER_MAX);
+	nim_ctx = link_info->u.var100g.nim_ctx;
 	link_state = link_info->link_state;
+	mac_pcs = link_info->u.var100g.mac_pcs100g;
 	gpio_phy = link_info->u.var100g.gpio_phy;
 
 	monitor_task_is_running[adapter_no] = 1;
@@ -183,8 +500,10 @@ static int _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++) {
+			link_state_t new_link_state;
 			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;
@@ -200,6 +519,7 @@ static int _common_ptp_nim_state_machine(void *data)
 				memset(&link_state[i], 0, sizeof(link_state[i]));
 				link_info->link_info[i].link_speed = NT_LINK_SPEED_UNKNOWN;
 				link_state[i].link_disabled = true;
+				reported_link[i] = false;
 				/* Turn off laser and LED, etc. */
 				(void)_create_nim(drv, i, false);
 				NT_LOG(DBG, NTNIC, "%s: Port %i is disabled\n",
@@ -223,12 +543,17 @@ static int _common_ptp_nim_state_machine(void *data)
 					 * If there is no Nim present, we need to initialize the
 					 * port anyway
 					 */
-					_port_init(drv, i);
+					_port_init(drv, fpga, i);
 				}
 
 				NT_LOG(INF, NTNIC, "%s: Loopback mode changed=%u\n",
 					drv->mp_port_id_str[i],
 					link_info->port_action[i].port_lpbk_mode);
+				_set_loopback(drv,
+					&mac_pcs[i],
+					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;
@@ -237,6 +562,65 @@ static int _common_ptp_nim_state_machine(void *data)
 				continue;
 			}
 
+			(void)_link_state_build(drv, &mac_pcs[i], &gpio_phy[i], i, &new_link_state,
+				is_port_disabled);
+
+			if (!new_link_state.nim_present) {
+				if (link_state[i].nim_present) {
+					NT_LOG(INF, NTNIC, "%s: NIM module removed\n",
+						drv->mp_port_id_str[i]);
+				}
+
+				link_state[i] = new_link_state;
+				continue;
+			}
+
+			/* NIM module is present */
+			if (new_link_state.lh_nim_absent || !link_state[i].nim_present) {
+				sfp_nim_state_t new_state;
+
+				NT_LOG(DBG, NTNIC, "%s: NIM module inserted\n",
+					drv->mp_port_id_str[i]);
+
+				if (_port_init(drv, fpga, i)) {
+					NT_LOG(ERR, NTNIC,
+						"%s: Failed to initialize NIM module\n",
+						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\n",
+						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'\n",
+					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);
+
+				(void)_link_state_build(drv, &mac_pcs[i], &gpio_phy[i], i,
+					&link_state[i], is_port_disabled);
+
+				NT_LOG(DBG, NTNIC, "%s: NIM module initialized\n",
+					drv->mp_port_id_str[i]);
+				continue;
+			}
+
+			if (reported_link[i] != new_link_state.link_up) {
+				NT_LOG(INF, NTNIC, "%s: link is %s\n", drv->mp_port_id_str[i],
+					(new_link_state.link_up ? "up" : "down"));
+				link_info->link_info[i].link_speed =
+					(new_link_state.link_up ? NT_LINK_SPEED_100G
+						: NT_LINK_SPEED_UNKNOWN);
+				link_state[i].link_up = new_link_state.link_up;
+				reported_link[i] = new_link_state.link_up;
+			}
+
+			check_link_state(drv, &mac_pcs[i]);
 		}	/* end-for */
 
 		if (monitor_task_is_running[adapter_no])
@@ -280,6 +664,7 @@ static int nt4ga_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nth
 	assert(adapter_no >= 0 && adapter_no < NUM_ADAPTER_MAX);
 
 	if (res == 0 && !p_adapter_info->nt4ga_link.variables_initialized) {
+		nthw_mac_pcs_t *mac_pcs = p_adapter_info->nt4ga_link.u.var100g.mac_pcs100g;
 		nim_i2c_ctx_t *nim_ctx = p_adapter_info->nt4ga_link.u.var100g.nim_ctx;
 		nthw_gpio_phy_t *gpio_phy = p_adapter_info->nt4ga_link.u.var100g.gpio_phy;
 		int i;
@@ -287,6 +672,10 @@ static int nt4ga_link_100g_ports_init(struct adapter_info_s *p_adapter_info, nth
 		for (i = 0; i < nb_ports; i++) {
 			/* 2 + adapter port number */
 			const uint8_t instance = (uint8_t)(2U + i);
+			res = nthw_mac_pcs_init(&mac_pcs[i], fpga, i /* int n_instance */);
+
+			if (res != 0)
+				break;
 
 			res = nthw_iic_init(&nim_ctx[i].hwiic, fpga, instance, 8);
 
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index e995ed75b0..0a6308f6bb 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -38,6 +38,7 @@ sources = files(
     'nthw/core/nthw_hif.c',
     'nthw/core/nthw_i2cm.c',
     'nthw/core/nthw_iic.c',
+    'nthw/core/nthw_mac_pcs.c',
     'nthw/core/nthw_pcie3.c',
     'nthw/core/nthw_sdc.c',
     'nthw/core/nthw_si5340.c',
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_core.h b/drivers/net/ntnic/nthw/core/include/nthw_core.h
index 5cce56e13f..fe32891712 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_core.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_core.h
@@ -18,6 +18,7 @@
 #include "nthw_i2cm.h"
 
 #include "nthw_gpio_phy.h"
+#include "nthw_mac_pcs.h"
 #include "nthw_sdc.h"
 
 #include "nthw_si5340.h"
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_mac_pcs.h b/drivers/net/ntnic/nthw/core/include/nthw_mac_pcs.h
new file mode 100644
index 0000000000..8d0e81bd73
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_mac_pcs.h
@@ -0,0 +1,250 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef NTHW_MAC_PCS_H_
+#define NTHW_MAC_PCS_H_
+
+enum nthw_mac_pcs_led_mode_e {
+	NTHW_MAC_PCS_LED_AUTO = 0x00,
+	NTHW_MAC_PCS_LED_ON = 0x01,
+	NTHW_MAC_PCS_LED_OFF = 0x02,
+	NTHW_MAC_PCS_LED_PORTID = 0x03,
+};
+
+#define nthw_mac_pcs_receiver_mode_dfe (0)
+#define nthw_mac_pcs_receiver_mode_lpm (1)
+
+struct nthw_mac_pcs {
+	uint8_t m_port_no;
+
+	nthw_fpga_t *mp_fpga;
+	nthw_module_t *mp_mod_mac_pcs;
+	int mn_instance;
+
+	/* Block lock status */
+	nthw_field_t *mp_fld_block_lock_lock;
+	uint32_t m_fld_block_lock_lock_mask;
+
+	/* Lane lock status */
+	nthw_field_t *mp_fld_vl_demuxed_lock;
+	uint32_t m_fld_vl_demuxed_lock_mask;
+
+	/* GTY_STAT */
+	nthw_field_t *mp_fld_gty_stat_rx_rst_done0;
+	nthw_field_t *mp_fld_gty_stat_rx_rst_done1;
+	nthw_field_t *mp_fld_gty_stat_rx_rst_done2;
+	nthw_field_t *mp_fld_gty_stat_rx_rst_done3;
+	nthw_field_t *mp_fld_gty_stat_tx_rst_done0;
+	nthw_field_t *mp_fld_gty_stat_tx_rst_done1;
+	nthw_field_t *mp_fld_gty_stat_tx_rst_done2;
+	nthw_field_t *mp_fld_gty_stat_tx_rst_done3;
+	uint32_t m_fld_gty_stat_rx_rst_done_mask;
+	uint32_t m_fld_gty_stat_tx_rst_done_mask;
+
+	/* GTY_LOOP */
+	nthw_register_t *mp_reg_gty_loop;
+	nthw_field_t *mp_fld_gty_loop_gt_loop0;
+	nthw_field_t *mp_fld_gty_loop_gt_loop1;
+	nthw_field_t *mp_fld_gty_loop_gt_loop2;
+	nthw_field_t *mp_fld_gty_loop_gt_loop3;
+
+	/* MAC_PCS_CONFIG */
+	nthw_field_t *mp_fld_pcs_config_tx_path_rst;
+	nthw_field_t *mp_fld_pcs_config_rx_path_rst;
+	nthw_field_t *mp_fld_pcs_config_rx_enable;
+	nthw_field_t *mp_fld_pcs_config_rx_force_resync;
+	nthw_field_t *mp_fld_pcs_config_rx_test_pattern;
+	nthw_field_t *mp_fld_pcs_config_tx_enable;
+	nthw_field_t *mp_fld_pcs_config_tx_send_idle;
+	nthw_field_t *mp_fld_pcs_config_tx_send_rfi;
+	nthw_field_t *mp_fld_pcs_config_tx_test_pattern;
+
+	/* STAT PCS */
+	nthw_field_t *mp_fld_stat_pcs_rx_status;
+	nthw_field_t *mp_fld_stat_pcs_rx_aligned;
+	nthw_field_t *mp_fld_stat_pcs_rx_aligned_err;
+	nthw_field_t *mp_fld_stat_pcs_rx_misaligned;
+	nthw_field_t *mp_fld_stat_pcs_rx_internal_local_fault;
+	nthw_field_t *mp_fld_stat_pcs_rx_received_local_fault;
+	nthw_field_t *mp_fld_stat_pcs_rx_local_fault;
+	nthw_field_t *mp_fld_stat_pcs_rx_remote_fault;
+	nthw_field_t *mp_fld_stat_pcs_rx_hi_ber;
+
+	/* STAT_PCS_RX_LATCH */
+	nthw_field_t *mp_fld_stat_pcs_rx_latch_status;
+
+	/* PHYMAC_MISC */
+	nthw_field_t *mp_fld_phymac_misc_tx_sel_host;
+	nthw_field_t *mp_fld_phymac_misc_tx_sel_tfg;
+	nthw_field_t *mp_fld_phymac_misc_tx_sel_rx_loop;
+	nthw_field_t *mp_fld_phymac_misc_ts_eop;
+
+	/* LINK_SUMMARY */
+	nthw_register_t *mp_reg_link_summary;
+	nthw_field_t *mp_fld_link_summary_abs;
+	nthw_field_t *mp_fld_link_summary_nt_phy_link_state;
+	nthw_field_t *mp_fld_link_summary_lh_abs;
+	nthw_field_t *mp_fld_link_summary_ll_nt_phy_link_state;
+	nthw_field_t *mp_fld_link_summary_link_down_cnt;
+	nthw_field_t *mp_fld_link_summary_nim_interr;
+	nthw_field_t *mp_fld_link_summary_lh_local_fault;
+	nthw_field_t *mp_fld_link_summary_lh_remote_fault;
+	nthw_field_t *mp_fld_link_summary_local_fault;
+	nthw_field_t *mp_fld_link_summary_remote_fault;
+
+	/* BIP_ERR */
+	nthw_register_t *mp_reg_bip_err;
+	nthw_field_t *mp_fld_reg_bip_err_bip_err;
+
+	/* FEC_CTRL */
+	nthw_register_t *mp_reg_fec_ctrl;
+	nthw_field_t *mp_field_fec_ctrl_reg_rs_fec_ctrl_in;
+
+	/* FEC_STAT */
+	nthw_register_t *mp_reg_fec_stat;
+	nthw_field_t *mp_field_fec_stat_bypass;
+	nthw_field_t *mp_field_fec_stat_valid;
+	nthw_field_t *mp_field_fec_stat_am_lock0;
+	nthw_field_t *mp_field_fec_stat_am_lock1;
+	nthw_field_t *mp_field_fec_stat_am_lock2;
+	nthw_field_t *mp_field_fec_stat_am_lock3;
+	nthw_field_t *mp_field_fec_stat_fec_lane_algn;
+
+	/* FEC Corrected code word count */
+	nthw_register_t *mp_reg_fec_cw_cnt;
+	nthw_field_t *mp_field_fec_cw_cnt_cw_cnt;
+
+	/* FEC Uncorrected code word count */
+	nthw_register_t *mp_reg_fec_ucw_cnt;
+	nthw_field_t *mp_field_fec_ucw_cnt_ucw_cnt;
+
+	/* GTY_RX_BUF_STAT */
+	nthw_register_t *mp_reg_gty_rx_buf_stat;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat0;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat1;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat2;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat3;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat_changed0;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat_changed1;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat_changed2;
+	nthw_field_t *mp_field_gty_rx_buf_stat_rx_buf_stat_changed3;
+
+	/* GTY_PRE_CURSOR */
+	nthw_register_t *mp_reg_gty_pre_cursor;
+	nthw_field_t *mp_field_gty_pre_cursor_tx_pre_csr0;
+	nthw_field_t *mp_field_gty_pre_cursor_tx_pre_csr1;
+	nthw_field_t *mp_field_gty_pre_cursor_tx_pre_csr2;
+	nthw_field_t *mp_field_gty_pre_cursor_tx_pre_csr3;
+
+	/* GTY_DIFF_CTL */
+	nthw_register_t *mp_reg_gty_diff_ctl;
+	nthw_field_t *mp_field_gty_gty_diff_ctl_tx_diff_ctl0;
+	nthw_field_t *mp_field_gty_gty_diff_ctl_tx_diff_ctl1;
+	nthw_field_t *mp_field_gty_gty_diff_ctl_tx_diff_ctl2;
+	nthw_field_t *mp_field_gty_gty_diff_ctl_tx_diff_ctl3;
+
+	/* GTY_POST_CURSOR */
+	nthw_register_t *mp_reg_gty_post_cursor;
+	nthw_field_t *mp_field_gty_post_cursor_tx_post_csr0;
+	nthw_field_t *mp_field_gty_post_cursor_tx_post_csr1;
+	nthw_field_t *mp_field_gty_post_cursor_tx_post_csr2;
+	nthw_field_t *mp_field_gty_post_cursor_tx_post_csr3;
+
+	/* GTY_CTL */
+	nthw_register_t *mp_reg_gty_ctl;
+	nthw_register_t *mp_reg_gty_ctl_tx;
+	nthw_field_t *mp_field_gty_ctl_tx_pol0;
+	nthw_field_t *mp_field_gty_ctl_tx_pol1;
+	nthw_field_t *mp_field_gty_ctl_tx_pol2;
+	nthw_field_t *mp_field_gty_ctl_tx_pol3;
+	nthw_field_t *mp_field_gty_ctl_rx_pol0;
+	nthw_field_t *mp_field_gty_ctl_rx_pol1;
+	nthw_field_t *mp_field_gty_ctl_rx_pol2;
+	nthw_field_t *mp_field_gty_ctl_rx_pol3;
+	nthw_field_t *mp_field_gty_ctl_rx_lpm_en0;
+	nthw_field_t *mp_field_gty_ctl_rx_lpm_en1;
+	nthw_field_t *mp_field_gty_ctl_rx_lpm_en2;
+	nthw_field_t *mp_field_gty_ctl_rx_lpm_en3;
+	nthw_field_t *mp_field_gty_ctl_rx_equa_rst0;
+	nthw_field_t *mp_field_gty_ctl_rx_equa_rst1;
+	nthw_field_t *mp_field_gty_ctl_rx_equa_rst2;
+	nthw_field_t *mp_field_gty_ctl_rx_equa_rst3;
+
+	/* DEBOUNCE_CTRL */
+	nthw_register_t *mp_reg_debounce_ctrl;
+	nthw_field_t *mp_field_debounce_ctrl_nt_port_ctrl;
+
+	/* TIMESTAMP_COMP */
+	nthw_register_t *mp_reg_time_stamp_comp;
+	nthw_field_t *mp_field_time_stamp_comp_rx_dly;
+	nthw_field_t *mp_field_time_stamp_comp_tx_dly;
+
+	/* STAT_PCS_RX */
+	nthw_register_t *mp_reg_stat_pcs_rx;
+
+	/* STAT_PCS_RX */
+	nthw_register_t *mp_reg_stat_pcs_rx_latch;
+
+	/* PHYMAC_MISC */
+	nthw_register_t *mp_reg_phymac_misc;
+
+	/* BLOCK_LOCK */
+	nthw_register_t *mp_reg_block_lock;
+};
+
+typedef struct nthw_mac_pcs nthw_mac_pcs_t;
+
+int nthw_mac_pcs_init(nthw_mac_pcs_t *p, nthw_fpga_t *p_fpga, int n_instance);
+
+void nthw_mac_pcs_tx_path_rst(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_rx_path_rst(nthw_mac_pcs_t *p, bool enable);
+bool nthw_mac_pcs_is_rx_path_rst(nthw_mac_pcs_t *p);
+/* wrapper - for ease of use */
+void nthw_mac_pcs_set_rx_enable(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_set_tx_enable(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_set_tx_sel_host(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_set_tx_sel_tfg(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_set_ts_eop(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_set_host_loopback(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_set_line_loopback(nthw_mac_pcs_t *p, bool enable);
+void nthw_mac_pcs_reset_bip_counters(nthw_mac_pcs_t *p);
+bool nthw_mac_pcs_get_hi_ber(nthw_mac_pcs_t *p);
+
+void nthw_mac_pcs_get_link_summary(nthw_mac_pcs_t *p,
+	uint32_t *p_abs,
+	uint32_t *p_nt_phy_link_state,
+	uint32_t *p_lh_abs,
+	uint32_t *p_ll_nt_phy_link_state,
+	uint32_t *p_link_down_cnt,
+	uint32_t *p_nim_interr,
+	uint32_t *p_lh_local_fault,
+	uint32_t *p_lh_remote_fault,
+	uint32_t *p_local_fault,
+	uint32_t *p_remote_fault);
+
+bool nthw_mac_pcs_reset_required(nthw_mac_pcs_t *p);
+void nthw_mac_pcs_set_fec(nthw_mac_pcs_t *p, bool enable);
+bool nthw_mac_pcs_get_fec_bypass(nthw_mac_pcs_t *p);
+bool nthw_mac_pcs_get_fec_valid(nthw_mac_pcs_t *p);
+bool nthw_mac_pcs_get_fec_stat_all_am_locked(nthw_mac_pcs_t *p);
+void nthw_mac_pcs_reset_fec_counters(nthw_mac_pcs_t *p);
+void nthw_mac_pcs_set_gty_tx_tuning(nthw_mac_pcs_t *p,
+	uint8_t lane,
+	uint8_t tx_pre_csr,
+	uint8_t tx_diff_ctl,
+	uint8_t tx_post_csr);
+void nthw_mac_pcs_swap_gty_tx_polarity(nthw_mac_pcs_t *p, uint8_t lane, bool swap);
+void nthw_mac_pcs_swap_gty_rx_polarity(nthw_mac_pcs_t *p, uint8_t lane, bool swap);
+void nthw_mac_pcs_set_receiver_equalization_mode(nthw_mac_pcs_t *p, uint8_t mode);
+void nthw_mac_pcs_set_led_mode(nthw_mac_pcs_t *p, uint8_t mode);
+void nthw_mac_pcs_set_timestamp_comp_rx(nthw_mac_pcs_t *p, uint16_t rx_dly);
+void nthw_mac_pcs_set_port_no(nthw_mac_pcs_t *p, uint8_t port_no);
+
+uint32_t nthw_mac_pcs_get_fld_block_lock_lock(nthw_mac_pcs_t *p);
+uint32_t nthw_mac_pcs_get_fld_block_lock_lock_mask(nthw_mac_pcs_t *p);
+uint32_t nthw_mac_pcs_get_fld_lane_lock_lock(nthw_mac_pcs_t *p);
+uint32_t nthw_mac_pcs_get_fld_lane_lock_lock_mask(nthw_mac_pcs_t *p);
+
+#endif	/* NTHW_MAC_PCS_H_ */
diff --git a/drivers/net/ntnic/nthw/core/nthw_mac_pcs.c b/drivers/net/ntnic/nthw/core/nthw_mac_pcs.c
new file mode 100644
index 0000000000..76040ec9c0
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/nthw_mac_pcs.c
@@ -0,0 +1,894 @@
+/*
+ * 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_mac_pcs.h"
+
+#define NTHW_MAC_PCS_LANES (20)
+
+static const uint8_t c_pcs_lanes = NTHW_MAC_PCS_LANES;
+static const uint8_t c_mac_pcs_receiver_mode_dfe;
+
+/*
+ * Parameters:
+ *   p != NULL: init struct pointed to by p
+ *   p == NULL: check fpga module(s) presence (but no struct to init)
+ *
+ * Return value:
+ *  <0: if p == NULL then fpga module(s) is/are not present.
+ *      if p != NULL then fpga module(s) is/are not present, struct undefined
+ * ==0: if p == NULL then fpga module(s) is/are present (no struct to init)
+ *    : if p != NULL then fpga module(s) is/are present and struct initialized
+ */
+int nthw_mac_pcs_init(nthw_mac_pcs_t *p, nthw_fpga_t *p_fpga, int n_instance)
+{
+	nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_MAC_PCS, n_instance);
+
+	if (p == NULL)
+		return mod == NULL ? -1 : 0;
+
+	if (mod == NULL) {
+		NT_LOG(ERR, NTHW, "%s: MAC_PCS %d: no such instance\n",
+			p_fpga->p_fpga_info->mp_adapter_id_str, n_instance);
+		return -1;
+	}
+
+	p->mp_fpga = p_fpga;
+	p->mn_instance = n_instance;
+	p->mp_mod_mac_pcs = mod;
+
+	assert(n_instance >= 0 && n_instance <= 255);
+	nthw_mac_pcs_set_port_no(p, (uint8_t)n_instance);
+
+	{
+		nthw_register_t *p_reg_block_lock, *p_reg_stat_pcs_rx, *p_reg_stat_pcs_rx_latch;
+		nthw_register_t *p_reg_vl_demuxed, *p_reg_gty_stat, *p_reg_pcs_config,
+				*p_reg_phymac_misc;
+		const int product_id = nthw_fpga_get_product_id(p_fpga);
+
+		p_reg_block_lock = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_BLOCK_LOCK);
+		p->mp_reg_block_lock = p_reg_block_lock;
+		p->mp_fld_block_lock_lock =
+			nthw_register_get_field(p_reg_block_lock, MAC_PCS_BLOCK_LOCK_LOCK);
+
+		p_reg_stat_pcs_rx =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_STAT_PCS_RX);
+		p->mp_reg_stat_pcs_rx = p_reg_stat_pcs_rx;
+		p->mp_fld_stat_pcs_rx_status =
+			nthw_register_get_field(p_reg_stat_pcs_rx, MAC_PCS_STAT_PCS_RX_STATUS);
+		p->mp_fld_stat_pcs_rx_aligned =
+			nthw_register_get_field(p_reg_stat_pcs_rx, MAC_PCS_STAT_PCS_RX_ALIGNED);
+		p->mp_fld_stat_pcs_rx_aligned_err =
+			nthw_register_get_field(p_reg_stat_pcs_rx,
+				MAC_PCS_STAT_PCS_RX_ALIGNED_ERR);
+		p->mp_fld_stat_pcs_rx_misaligned =
+			nthw_register_get_field(p_reg_stat_pcs_rx, MAC_PCS_STAT_PCS_RX_MISALIGNED);
+		p->mp_fld_stat_pcs_rx_internal_local_fault =
+			nthw_register_get_field(p_reg_stat_pcs_rx,
+				MAC_PCS_STAT_PCS_RX_INTERNAL_LOCAL_FAULT);
+		p->mp_fld_stat_pcs_rx_received_local_fault =
+			nthw_register_get_field(p_reg_stat_pcs_rx,
+				MAC_PCS_STAT_PCS_RX_RECEIVED_LOCAL_FAULT);
+		p->mp_fld_stat_pcs_rx_local_fault =
+			nthw_register_get_field(p_reg_stat_pcs_rx,
+				MAC_PCS_STAT_PCS_RX_LOCAL_FAULT);
+		p->mp_fld_stat_pcs_rx_remote_fault =
+			nthw_register_get_field(p_reg_stat_pcs_rx,
+				MAC_PCS_STAT_PCS_RX_REMOTE_FAULT);
+		p->mp_fld_stat_pcs_rx_hi_ber =
+			nthw_register_get_field(p_reg_stat_pcs_rx, MAC_PCS_STAT_PCS_RX_HI_BER);
+
+		p_reg_stat_pcs_rx_latch =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_STAT_PCS_RX_LATCH);
+		p->mp_reg_stat_pcs_rx_latch = p_reg_stat_pcs_rx_latch;
+		p->mp_fld_stat_pcs_rx_latch_status =
+			nthw_register_get_field(p_reg_stat_pcs_rx_latch,
+				MAC_PCS_STAT_PCS_RX_LATCH_STATUS);
+
+		p_reg_vl_demuxed = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_VL_DEMUXED);
+		p->mp_fld_vl_demuxed_lock =
+			nthw_register_get_field(p_reg_vl_demuxed, MAC_PCS_VL_DEMUXED_LOCK);
+
+		p_reg_gty_stat = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_STAT);
+		p->mp_fld_gty_stat_tx_rst_done0 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_TX_RST_DONE_0);
+		p->mp_fld_gty_stat_tx_rst_done1 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_TX_RST_DONE_1);
+		p->mp_fld_gty_stat_tx_rst_done2 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_TX_RST_DONE_2);
+		p->mp_fld_gty_stat_tx_rst_done3 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_TX_RST_DONE_3);
+		p->mp_fld_gty_stat_rx_rst_done0 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_RX_RST_DONE_0);
+		p->mp_fld_gty_stat_rx_rst_done1 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_RX_RST_DONE_1);
+		p->mp_fld_gty_stat_rx_rst_done2 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_RX_RST_DONE_2);
+		p->mp_fld_gty_stat_rx_rst_done3 =
+			nthw_register_get_field(p_reg_gty_stat, MAC_PCS_GTY_STAT_RX_RST_DONE_3);
+
+		p->m_fld_block_lock_lock_mask = 0;
+		p->m_fld_vl_demuxed_lock_mask = 0;
+		p->m_fld_gty_stat_tx_rst_done_mask = 0;
+		p->m_fld_gty_stat_rx_rst_done_mask = 0;
+
+		if (product_id == 9563) {
+			/* NT200A01_2X100 implements 20 virtual lanes */
+			p->m_fld_block_lock_lock_mask = (1 << 20) - 1;
+			/* NT200A01_2X100 implements 20 virtual lanes */
+			p->m_fld_vl_demuxed_lock_mask = (1 << 20) - 1;
+			p->m_fld_gty_stat_tx_rst_done_mask =
+				1;	/* NT200A01_2X100 implements 4 GTY */
+			p->m_fld_gty_stat_rx_rst_done_mask =
+				1;	/* NT200A01_2X100 implements 4 GTY */
+
+		} else {
+			/* Remember to add new product_ids */
+			assert(0);
+		}
+
+		p_reg_pcs_config =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_MAC_PCS_CONFIG);
+		p->mp_fld_pcs_config_tx_path_rst =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_TX_PATH_RST);
+		p->mp_fld_pcs_config_rx_path_rst =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_RX_PATH_RST);
+		p->mp_fld_pcs_config_rx_enable =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_RX_ENABLE);
+		p->mp_fld_pcs_config_rx_force_resync =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_RX_FORCE_RESYNC);
+		p->mp_fld_pcs_config_rx_test_pattern =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_RX_TEST_PATTERN);
+		p->mp_fld_pcs_config_tx_enable =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_TX_ENABLE);
+		p->mp_fld_pcs_config_tx_send_idle =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_TX_SEND_IDLE);
+		p->mp_fld_pcs_config_tx_send_rfi =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_TX_SEND_RFI);
+		p->mp_fld_pcs_config_tx_test_pattern =
+			nthw_register_get_field(p_reg_pcs_config,
+				MAC_PCS_MAC_PCS_CONFIG_TX_TEST_PATTERN);
+
+		p->mp_reg_gty_loop = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_LOOP);
+		p->mp_fld_gty_loop_gt_loop0 =
+			nthw_register_get_field(p->mp_reg_gty_loop, MAC_PCS_GTY_LOOP_GT_LOOP_0);
+		p->mp_fld_gty_loop_gt_loop1 =
+			nthw_register_get_field(p->mp_reg_gty_loop, MAC_PCS_GTY_LOOP_GT_LOOP_1);
+		p->mp_fld_gty_loop_gt_loop2 =
+			nthw_register_get_field(p->mp_reg_gty_loop, MAC_PCS_GTY_LOOP_GT_LOOP_2);
+		p->mp_fld_gty_loop_gt_loop3 =
+			nthw_register_get_field(p->mp_reg_gty_loop, MAC_PCS_GTY_LOOP_GT_LOOP_3);
+
+		p_reg_phymac_misc =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_PHYMAC_MISC);
+		p->mp_reg_phymac_misc = p_reg_phymac_misc;
+		p->mp_fld_phymac_misc_tx_sel_host =
+			nthw_register_get_field(p_reg_phymac_misc,
+				MAC_PCS_PHYMAC_MISC_TX_SEL_HOST);
+		p->mp_fld_phymac_misc_tx_sel_tfg =
+			nthw_register_get_field(p_reg_phymac_misc, MAC_PCS_PHYMAC_MISC_TX_SEL_TFG);
+		p->mp_fld_phymac_misc_tx_sel_rx_loop =
+			nthw_register_get_field(p_reg_phymac_misc,
+				MAC_PCS_PHYMAC_MISC_TX_SEL_RX_LOOP);
+
+		/* SOP or EOP TIMESTAMP */
+		p->mp_fld_phymac_misc_ts_eop =
+			nthw_register_query_field(p_reg_phymac_misc, MAC_PCS_PHYMAC_MISC_TS_EOP);
+
+		p->mp_reg_link_summary =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_LINK_SUMMARY);
+		p->mp_fld_link_summary_abs =
+			nthw_register_get_field(p->mp_reg_link_summary, MAC_PCS_LINK_SUMMARY_ABS);
+		p->mp_fld_link_summary_nt_phy_link_state =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_NT_PHY_LINK_STATE);
+		p->mp_fld_link_summary_lh_abs =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_LH_ABS);
+		p->mp_fld_link_summary_ll_nt_phy_link_state =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_LL_PHY_LINK_STATE);
+		p->mp_fld_link_summary_link_down_cnt =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_LINK_DOWN_CNT);
+		p->mp_fld_link_summary_nim_interr =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_NIM_INTERR);
+		p->mp_fld_link_summary_lh_local_fault =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_LH_LOCAL_FAULT);
+		p->mp_fld_link_summary_lh_remote_fault =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_LH_REMOTE_FAULT);
+		p->mp_fld_link_summary_local_fault =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_LOCAL_FAULT);
+		p->mp_fld_link_summary_remote_fault =
+			nthw_register_get_field(p->mp_reg_link_summary,
+				MAC_PCS_LINK_SUMMARY_REMOTE_FAULT);
+
+		p->mp_reg_bip_err = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_BIP_ERR);
+		p->mp_fld_reg_bip_err_bip_err =
+			nthw_register_get_field(p->mp_reg_bip_err, MAC_PCS_BIP_ERR_BIP_ERR);
+
+		p->mp_reg_fec_ctrl = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_FEC_CTRL);
+		p->mp_field_fec_ctrl_reg_rs_fec_ctrl_in =
+			nthw_register_get_field(p->mp_reg_fec_ctrl,
+				MAC_PCS_FEC_CTRL_RS_FEC_CTRL_IN);
+
+		p->mp_reg_fec_stat = nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_FEC_STAT);
+		p->mp_field_fec_stat_bypass =
+			nthw_register_get_field(p->mp_reg_fec_stat, MAC_PCS_FEC_STAT_BYPASS);
+		p->mp_field_fec_stat_valid =
+			nthw_register_get_field(p->mp_reg_fec_stat, MAC_PCS_FEC_STAT_VALID);
+		p->mp_field_fec_stat_am_lock0 =
+			nthw_register_get_field(p->mp_reg_fec_stat, MAC_PCS_FEC_STAT_AM_LOCK_0);
+		p->mp_field_fec_stat_am_lock1 =
+			nthw_register_get_field(p->mp_reg_fec_stat, MAC_PCS_FEC_STAT_AM_LOCK_1);
+		p->mp_field_fec_stat_am_lock2 =
+			nthw_register_get_field(p->mp_reg_fec_stat, MAC_PCS_FEC_STAT_AM_LOCK_2);
+		p->mp_field_fec_stat_am_lock3 =
+			nthw_register_get_field(p->mp_reg_fec_stat, MAC_PCS_FEC_STAT_AM_LOCK_3);
+		p->mp_field_fec_stat_fec_lane_algn =
+			nthw_register_get_field(p->mp_reg_fec_stat,
+				MAC_PCS_FEC_STAT_FEC_LANE_ALGN);
+
+		p->mp_reg_fec_cw_cnt =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_FEC_CW_CNT);
+		p->mp_field_fec_cw_cnt_cw_cnt =
+			nthw_register_get_field(p->mp_reg_fec_cw_cnt, MAC_PCS_FEC_CW_CNT_CW_CNT);
+
+		p->mp_reg_fec_ucw_cnt =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_FEC_UCW_CNT);
+		p->mp_field_fec_ucw_cnt_ucw_cnt =
+			nthw_register_get_field(p->mp_reg_fec_ucw_cnt,
+				MAC_PCS_FEC_UCW_CNT_UCW_CNT);
+
+		/* GTY_RX_BUF_STAT */
+#ifdef RXBUFSTAT
+		p->mp_reg_gty_rx_buf_stat =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_RX_BUF_STAT);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat0 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_0);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat1 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_1);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat2 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_2);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat3 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_3);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat_changed0 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_CHANGED_0);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat_changed1 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_CHANGED_1);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat_changed2 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_CHANGED_2);
+		p->mp_field_gty_rx_buf_stat_rx_buf_stat_changed3 =
+			nthw_register_get_field(p->mp_reg_gty_rx_buf_stat,
+				MAC_PCS_GTY_RX_BUF_STAT_RX_BUF_STAT_CHANGED_3);
+#endif
+
+		/* GTY_PRE_CURSOR */
+		p->mp_reg_gty_pre_cursor =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_PRE_CURSOR);
+		p->mp_field_gty_pre_cursor_tx_pre_csr0 =
+			nthw_register_get_field(p->mp_reg_gty_pre_cursor,
+				MAC_PCS_GTY_PRE_CURSOR_TX_PRE_CSR_0);
+		p->mp_field_gty_pre_cursor_tx_pre_csr1 =
+			nthw_register_get_field(p->mp_reg_gty_pre_cursor,
+				MAC_PCS_GTY_PRE_CURSOR_TX_PRE_CSR_1);
+		p->mp_field_gty_pre_cursor_tx_pre_csr2 =
+			nthw_register_get_field(p->mp_reg_gty_pre_cursor,
+				MAC_PCS_GTY_PRE_CURSOR_TX_PRE_CSR_2);
+		p->mp_field_gty_pre_cursor_tx_pre_csr3 =
+			nthw_register_get_field(p->mp_reg_gty_pre_cursor,
+				MAC_PCS_GTY_PRE_CURSOR_TX_PRE_CSR_3);
+
+		/* GTY_DIFF_CTL */
+		p->mp_reg_gty_diff_ctl =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_DIFF_CTL);
+		p->mp_field_gty_gty_diff_ctl_tx_diff_ctl0 =
+			nthw_register_get_field(p->mp_reg_gty_diff_ctl,
+				MAC_PCS_GTY_DIFF_CTL_TX_DIFF_CTL_0);
+		p->mp_field_gty_gty_diff_ctl_tx_diff_ctl1 =
+			nthw_register_get_field(p->mp_reg_gty_diff_ctl,
+				MAC_PCS_GTY_DIFF_CTL_TX_DIFF_CTL_1);
+		p->mp_field_gty_gty_diff_ctl_tx_diff_ctl2 =
+			nthw_register_get_field(p->mp_reg_gty_diff_ctl,
+				MAC_PCS_GTY_DIFF_CTL_TX_DIFF_CTL_2);
+		p->mp_field_gty_gty_diff_ctl_tx_diff_ctl3 =
+			nthw_register_get_field(p->mp_reg_gty_diff_ctl,
+				MAC_PCS_GTY_DIFF_CTL_TX_DIFF_CTL_3);
+
+		/* GTY_POST_CURSOR */
+		p->mp_reg_gty_post_cursor =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_POST_CURSOR);
+		p->mp_field_gty_post_cursor_tx_post_csr0 =
+			nthw_register_get_field(p->mp_reg_gty_post_cursor,
+				MAC_PCS_GTY_POST_CURSOR_TX_POST_CSR_0);
+		p->mp_field_gty_post_cursor_tx_post_csr1 =
+			nthw_register_get_field(p->mp_reg_gty_post_cursor,
+				MAC_PCS_GTY_POST_CURSOR_TX_POST_CSR_1);
+		p->mp_field_gty_post_cursor_tx_post_csr2 =
+			nthw_register_get_field(p->mp_reg_gty_post_cursor,
+				MAC_PCS_GTY_POST_CURSOR_TX_POST_CSR_2);
+		p->mp_field_gty_post_cursor_tx_post_csr3 =
+			nthw_register_get_field(p->mp_reg_gty_post_cursor,
+				MAC_PCS_GTY_POST_CURSOR_TX_POST_CSR_3);
+
+		/* GTY_CTL */
+		p->mp_reg_gty_ctl = nthw_module_query_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_CTL);
+
+		if (p->mp_reg_gty_ctl) {
+			p->mp_field_gty_ctl_tx_pol0 =
+				nthw_register_get_field(p->mp_reg_gty_ctl,
+					MAC_PCS_GTY_CTL_TX_POLARITY_0);
+			p->mp_field_gty_ctl_tx_pol1 =
+				nthw_register_get_field(p->mp_reg_gty_ctl,
+					MAC_PCS_GTY_CTL_TX_POLARITY_1);
+			p->mp_field_gty_ctl_tx_pol2 =
+				nthw_register_get_field(p->mp_reg_gty_ctl,
+					MAC_PCS_GTY_CTL_TX_POLARITY_2);
+			p->mp_field_gty_ctl_tx_pol3 =
+				nthw_register_get_field(p->mp_reg_gty_ctl,
+					MAC_PCS_GTY_CTL_TX_POLARITY_3);
+
+		} else {
+			p->mp_reg_gty_ctl =
+				nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_CTL_RX);
+			p->mp_reg_gty_ctl_tx =
+				nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_GTY_CTL_TX);
+			p->mp_field_gty_ctl_tx_pol0 =
+				nthw_register_get_field(p->mp_reg_gty_ctl_tx,
+					MAC_PCS_GTY_CTL_TX_POLARITY_0);
+			p->mp_field_gty_ctl_tx_pol1 =
+				nthw_register_get_field(p->mp_reg_gty_ctl_tx,
+					MAC_PCS_GTY_CTL_TX_POLARITY_1);
+			p->mp_field_gty_ctl_tx_pol2 =
+				nthw_register_get_field(p->mp_reg_gty_ctl_tx,
+					MAC_PCS_GTY_CTL_TX_POLARITY_2);
+			p->mp_field_gty_ctl_tx_pol3 =
+				nthw_register_get_field(p->mp_reg_gty_ctl_tx,
+					MAC_PCS_GTY_CTL_TX_POLARITY_3);
+		}
+
+		p->mp_field_gty_ctl_rx_pol0 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_POLARITY_0);
+		p->mp_field_gty_ctl_rx_pol1 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_POLARITY_1);
+		p->mp_field_gty_ctl_rx_pol2 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_POLARITY_2);
+		p->mp_field_gty_ctl_rx_pol3 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_POLARITY_3);
+		p->mp_field_gty_ctl_rx_lpm_en0 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_LPM_EN_0);
+		p->mp_field_gty_ctl_rx_lpm_en1 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_LPM_EN_1);
+		p->mp_field_gty_ctl_rx_lpm_en2 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_LPM_EN_2);
+		p->mp_field_gty_ctl_rx_lpm_en3 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_LPM_EN_3);
+		p->mp_field_gty_ctl_rx_equa_rst0 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_EQUA_RST_0);
+		p->mp_field_gty_ctl_rx_equa_rst1 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_EQUA_RST_1);
+		p->mp_field_gty_ctl_rx_equa_rst2 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_EQUA_RST_2);
+		p->mp_field_gty_ctl_rx_equa_rst3 =
+			nthw_register_get_field(p->mp_reg_gty_ctl, MAC_PCS_GTY_CTL_RX_EQUA_RST_3);
+
+		/* DEBOUNCE_CTRL */
+		p->mp_reg_debounce_ctrl =
+			nthw_module_get_register(p->mp_mod_mac_pcs, MAC_PCS_DEBOUNCE_CTRL);
+		p->mp_field_debounce_ctrl_nt_port_ctrl =
+			nthw_register_get_field(p->mp_reg_debounce_ctrl,
+				MAC_PCS_DEBOUNCE_CTRL_NT_PORT_CTRL);
+
+		p->mp_reg_time_stamp_comp =
+			nthw_module_query_register(p->mp_mod_mac_pcs, MAC_PCS_TIMESTAMP_COMP);
+
+		if (p->mp_reg_time_stamp_comp) {
+			/* TIMESTAMP_COMP */
+			p->mp_field_time_stamp_comp_rx_dly =
+				nthw_register_get_field(p->mp_reg_time_stamp_comp,
+					MAC_PCS_TIMESTAMP_COMP_RX_DLY);
+			p->mp_field_time_stamp_comp_tx_dly =
+				nthw_register_get_field(p->mp_reg_time_stamp_comp,
+					MAC_PCS_TIMESTAMP_COMP_TX_DLY);
+		}
+	}
+	return 0;
+}
+
+void nthw_mac_pcs_set_rx_enable(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_field_get_updated(p->mp_fld_pcs_config_rx_enable);
+
+	if (enable)
+		nthw_field_set_flush(p->mp_fld_pcs_config_rx_enable);
+
+	else
+		nthw_field_clr_flush(p->mp_fld_pcs_config_rx_enable);
+}
+
+void nthw_mac_pcs_set_tx_enable(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_field_get_updated(p->mp_fld_pcs_config_tx_enable);
+
+	if (enable)
+		nthw_field_set_flush(p->mp_fld_pcs_config_tx_enable);
+
+	else
+		nthw_field_clr_flush(p->mp_fld_pcs_config_tx_enable);
+}
+
+void nthw_mac_pcs_set_tx_sel_host(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_field_get_updated(p->mp_fld_phymac_misc_tx_sel_host);
+
+	if (enable)
+		nthw_field_set_flush(p->mp_fld_phymac_misc_tx_sel_host);
+
+	else
+		nthw_field_clr_flush(p->mp_fld_phymac_misc_tx_sel_host);
+}
+
+void nthw_mac_pcs_set_tx_sel_tfg(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_field_get_updated(p->mp_fld_phymac_misc_tx_sel_tfg);
+
+	if (enable)
+		nthw_field_set_flush(p->mp_fld_phymac_misc_tx_sel_tfg);
+
+	else
+		nthw_field_clr_flush(p->mp_fld_phymac_misc_tx_sel_tfg);
+}
+
+void nthw_mac_pcs_set_ts_eop(nthw_mac_pcs_t *p, bool enable)
+{
+	if (p->mp_fld_phymac_misc_ts_eop) {
+		nthw_field_get_updated(p->mp_fld_phymac_misc_ts_eop);
+
+		if (enable)
+			nthw_field_set_flush(p->mp_fld_phymac_misc_ts_eop);
+
+		else
+			nthw_field_clr_flush(p->mp_fld_phymac_misc_ts_eop);
+	}
+}
+
+void nthw_mac_pcs_tx_path_rst(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_field_get_updated(p->mp_fld_pcs_config_tx_path_rst);
+
+	if (enable)
+		nthw_field_set_flush(p->mp_fld_pcs_config_tx_path_rst);
+
+	else
+		nthw_field_clr_flush(p->mp_fld_pcs_config_tx_path_rst);
+}
+
+void nthw_mac_pcs_rx_path_rst(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_field_get_updated(p->mp_fld_pcs_config_rx_path_rst);
+
+	if (enable)
+		nthw_field_set_flush(p->mp_fld_pcs_config_rx_path_rst);
+
+	else
+		nthw_field_clr_flush(p->mp_fld_pcs_config_rx_path_rst);
+}
+
+bool nthw_mac_pcs_is_rx_path_rst(nthw_mac_pcs_t *p)
+{
+	return nthw_field_get_updated(p->mp_fld_pcs_config_rx_path_rst);
+}
+
+void nthw_mac_pcs_set_host_loopback(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_register_update(p->mp_reg_gty_loop);
+
+	if (enable) {
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop0, 2);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop1, 2);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop2, 2);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop3, 2);
+
+	} else {
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop0, 0);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop1, 0);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop2, 0);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop3, 0);
+	}
+
+	nthw_register_flush(p->mp_reg_gty_loop, 1);
+}
+
+void nthw_mac_pcs_set_line_loopback(nthw_mac_pcs_t *p, bool enable)
+{
+	nthw_register_update(p->mp_reg_gty_loop);
+
+	if (enable) {
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop0, 4);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop1, 4);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop2, 4);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop3, 4);
+
+	} else {
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop0, 0);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop1, 0);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop2, 0);
+		nthw_field_set_val32(p->mp_fld_gty_loop_gt_loop3, 0);
+	}
+
+	nthw_register_flush(p->mp_reg_gty_loop, 1);
+}
+
+void nthw_mac_pcs_reset_bip_counters(nthw_mac_pcs_t *p)
+{
+	uint32_t lane_bit_errors[NTHW_MAC_PCS_LANES];
+	nthw_register_update(p->mp_reg_bip_err);
+	nthw_field_get_val(p->mp_fld_reg_bip_err_bip_err, (uint32_t *)lane_bit_errors,
+		ARRAY_SIZE(lane_bit_errors));
+
+	(void)c_pcs_lanes;	/* unused - kill warning */
+}
+
+bool nthw_mac_pcs_get_hi_ber(nthw_mac_pcs_t *p)
+{
+	return nthw_field_get_updated(p->mp_fld_stat_pcs_rx_hi_ber);
+}
+
+void nthw_mac_pcs_get_link_summary(nthw_mac_pcs_t *p,
+	uint32_t *p_abs,
+	uint32_t *p_nt_phy_link_state,
+	uint32_t *p_lh_abs,
+	uint32_t *p_ll_nt_phy_link_state,
+	uint32_t *p_link_down_cnt,
+	uint32_t *p_nim_interr,
+	uint32_t *p_lh_local_fault,
+	uint32_t *p_lh_remote_fault,
+	uint32_t *p_local_fault,
+	uint32_t *p_remote_fault)
+{
+	nthw_register_update(p->mp_reg_link_summary);
+
+	if (p_abs)
+		*p_abs = nthw_field_get_val32(p->mp_fld_link_summary_abs);
+
+	if (p_nt_phy_link_state) {
+		*p_nt_phy_link_state =
+			nthw_field_get_val32(p->mp_fld_link_summary_nt_phy_link_state);
+	}
+
+	if (p_lh_abs)
+		*p_lh_abs = nthw_field_get_val32(p->mp_fld_link_summary_lh_abs);
+
+	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);
+	}
+
+	if (p_link_down_cnt)
+		*p_link_down_cnt = nthw_field_get_val32(p->mp_fld_link_summary_link_down_cnt);
+
+	if (p_nim_interr)
+		*p_nim_interr = nthw_field_get_val32(p->mp_fld_link_summary_nim_interr);
+
+	if (p_lh_local_fault)
+		*p_lh_local_fault = nthw_field_get_val32(p->mp_fld_link_summary_lh_local_fault);
+
+	if (p_lh_remote_fault)
+		*p_lh_remote_fault = nthw_field_get_val32(p->mp_fld_link_summary_lh_remote_fault);
+
+	if (p_local_fault)
+		*p_local_fault = nthw_field_get_val32(p->mp_fld_link_summary_local_fault);
+
+	if (p_remote_fault)
+		*p_remote_fault = nthw_field_get_val32(p->mp_fld_link_summary_remote_fault);
+}
+
+/*
+ * Returns true if the lane/block lock bits indicate that a reset is required.
+ * This is the case if Block/Lane lock is not all zero but not all set either.
+ */
+bool nthw_mac_pcs_reset_required(nthw_mac_pcs_t *p)
+{
+	uint32_t block_lock = nthw_mac_pcs_get_fld_block_lock_lock(p);
+	uint32_t lane_lock = nthw_mac_pcs_get_fld_lane_lock_lock(p);
+	uint32_t block_lock_mask = nthw_mac_pcs_get_fld_block_lock_lock_mask(p);
+	uint32_t lane_lock_mask = nthw_mac_pcs_get_fld_lane_lock_lock_mask(p);
+
+	return ((block_lock != 0) && (block_lock != block_lock_mask)) ||
+		((lane_lock != 0) && (lane_lock != lane_lock_mask));
+}
+
+void nthw_mac_pcs_set_fec(nthw_mac_pcs_t *p, bool enable)
+{
+	NT_LOG(DBG, NTHW, "Port %u: Set FEC: %u\n", p->m_port_no, enable);
+
+	nthw_field_get_updated(p->mp_field_fec_ctrl_reg_rs_fec_ctrl_in);
+
+	if (enable)
+		nthw_field_set_val_flush32(p->mp_field_fec_ctrl_reg_rs_fec_ctrl_in, 0);
+
+	else
+		nthw_field_set_val_flush32(p->mp_field_fec_ctrl_reg_rs_fec_ctrl_in, (1 << 5) - 1);
+
+	/* Both Rx and Tx must be reset for new FEC state to become active */
+	nthw_mac_pcs_rx_path_rst(p, true);
+	nthw_mac_pcs_tx_path_rst(p, true);
+	nt_os_wait_usec(10000);	/* 10ms */
+
+	nthw_mac_pcs_rx_path_rst(p, false);
+	nthw_mac_pcs_tx_path_rst(p, false);
+	nt_os_wait_usec(10000);	/* 10ms */
+}
+
+bool nthw_mac_pcs_get_fec_bypass(nthw_mac_pcs_t *p)
+{
+	return nthw_field_get_updated(p->mp_field_fec_stat_bypass);
+}
+
+bool nthw_mac_pcs_get_fec_valid(nthw_mac_pcs_t *p)
+{
+	return nthw_field_get_updated(p->mp_field_fec_stat_valid);
+}
+
+bool nthw_mac_pcs_get_fec_stat_all_am_locked(nthw_mac_pcs_t *p)
+{
+	nthw_register_update(p->mp_reg_fec_stat);
+
+	if ((nthw_field_get_val32(p->mp_field_fec_stat_am_lock0)) &&
+		(nthw_field_get_val32(p->mp_field_fec_stat_am_lock1)) &&
+		(nthw_field_get_val32(p->mp_field_fec_stat_am_lock2)) &&
+		(nthw_field_get_val32(p->mp_field_fec_stat_am_lock3))) {
+		return true;
+	}
+
+	return false;
+}
+
+void nthw_mac_pcs_reset_fec_counters(nthw_mac_pcs_t *p)
+{
+	nthw_register_update(p->mp_reg_fec_cw_cnt);
+	nthw_register_update(p->mp_reg_fec_ucw_cnt);
+
+	if (nthw_field_get_val32(p->mp_field_fec_cw_cnt_cw_cnt)) {
+		NT_LOG(DBG, NTHW, "Port %u: FEC_CW_CNT: %u\n", p->m_port_no,
+			nthw_field_get_val32(p->mp_field_fec_cw_cnt_cw_cnt));
+	}
+
+	if (nthw_field_get_val32(p->mp_field_fec_ucw_cnt_ucw_cnt)) {
+		NT_LOG(DBG, NTHW, "Port %u: FEC_UCW_CNT: %u\n", p->m_port_no,
+			nthw_field_get_val32(p->mp_field_fec_ucw_cnt_ucw_cnt));
+	}
+}
+
+void nthw_mac_pcs_set_gty_tx_tuning(nthw_mac_pcs_t *p, uint8_t lane, uint8_t tx_pre_csr,
+	uint8_t tx_diff_ctl, uint8_t tx_post_csr)
+{
+	/* GTY_PRE_CURSOR */
+	nthw_register_update(p->mp_reg_gty_pre_cursor);
+
+	switch (lane) {
+	case 0:
+		nthw_field_set_val_flush32(p->mp_field_gty_pre_cursor_tx_pre_csr0,
+			tx_pre_csr & 0x1F);
+		break;
+
+	case 1:
+		nthw_field_set_val_flush32(p->mp_field_gty_pre_cursor_tx_pre_csr1,
+			tx_pre_csr & 0x1F);
+		break;
+
+	case 2:
+		nthw_field_set_val_flush32(p->mp_field_gty_pre_cursor_tx_pre_csr2,
+			tx_pre_csr & 0x1F);
+		break;
+
+	case 3:
+		nthw_field_set_val_flush32(p->mp_field_gty_pre_cursor_tx_pre_csr3,
+			tx_pre_csr & 0x1F);
+		break;
+	}
+
+	/* GTY_DIFF_CTL */
+	nthw_register_update(p->mp_reg_gty_diff_ctl);
+
+	switch (lane) {
+	case 0:
+		nthw_field_set_val_flush32(p->mp_field_gty_gty_diff_ctl_tx_diff_ctl0,
+			tx_diff_ctl & 0x1F);
+		break;
+
+	case 1:
+		nthw_field_set_val_flush32(p->mp_field_gty_gty_diff_ctl_tx_diff_ctl1,
+			tx_diff_ctl & 0x1F);
+		break;
+
+	case 2:
+		nthw_field_set_val_flush32(p->mp_field_gty_gty_diff_ctl_tx_diff_ctl2,
+			tx_diff_ctl & 0x1F);
+		break;
+
+	case 3:
+		nthw_field_set_val_flush32(p->mp_field_gty_gty_diff_ctl_tx_diff_ctl3,
+			tx_diff_ctl & 0x1F);
+		break;
+	}
+
+	/* GTY_POST_CURSOR */
+	nthw_register_update(p->mp_reg_gty_post_cursor);
+
+	switch (lane) {
+	case 0:
+		nthw_field_set_val_flush32(p->mp_field_gty_post_cursor_tx_post_csr0,
+			tx_post_csr & 0x1F);
+		break;
+
+	case 1:
+		nthw_field_set_val_flush32(p->mp_field_gty_post_cursor_tx_post_csr1,
+			tx_post_csr & 0x1F);
+		break;
+
+	case 2:
+		nthw_field_set_val_flush32(p->mp_field_gty_post_cursor_tx_post_csr2,
+			tx_post_csr & 0x1F);
+		break;
+
+	case 3:
+		nthw_field_set_val_flush32(p->mp_field_gty_post_cursor_tx_post_csr3,
+			tx_post_csr & 0x1F);
+		break;
+	}
+
+	NT_LOG(DBG, NTHW,
+		"Port %u, lane %u: GTY tx_pre_csr: %d, tx_diff_ctl: %d, tx_post_csr: %d\n",
+		p->m_port_no, lane, tx_pre_csr, tx_diff_ctl, tx_post_csr);
+}
+
+/*
+ * Set receiver equalization mode
+ *  0: enable DFE
+ *  1: enable LPM
+ *
+ * See UltraScale Architecture GTY Transceivers www.xilinx.com page 181,
+ * UG578 (v1.1) November 24, 2015
+ */
+void nthw_mac_pcs_set_receiver_equalization_mode(nthw_mac_pcs_t *p, uint8_t mode)
+{
+	nthw_register_update(p->mp_reg_gty_ctl);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_lpm_en0, mode & 0x1);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_lpm_en1, mode & 0x1);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_lpm_en2, mode & 0x1);
+	nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_lpm_en3, mode & 0x1);
+
+	/* Toggle reset */
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_equa_rst0, 1);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_equa_rst1, 1);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_equa_rst2, 1);
+	nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_equa_rst3, 1);
+
+	nt_os_wait_usec(1000);	/* 1ms */
+
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_equa_rst0, 0);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_equa_rst1, 0);
+	nthw_field_set_val32(p->mp_field_gty_ctl_rx_equa_rst2, 0);
+	nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_equa_rst3, 0);
+
+	NT_LOG(DBG, NTHW, "Port %u: GTY receiver mode: %s\n", p->m_port_no,
+		(mode == c_mac_pcs_receiver_mode_dfe ? "DFE" : "LPM"));
+}
+
+void nthw_mac_pcs_swap_gty_tx_polarity(nthw_mac_pcs_t *p, uint8_t lane, bool swap)
+{
+	nthw_register_update(p->mp_reg_gty_ctl);
+
+	switch (lane) {
+	case 0:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_tx_pol0, swap);
+		break;
+
+	case 1:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_tx_pol1, swap);
+		break;
+
+	case 2:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_tx_pol2, swap);
+		break;
+
+	case 3:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_tx_pol3, swap);
+		break;
+	}
+
+	NT_LOG(DBG, NTHW, "Port %u: set GTY Tx lane (%d) polarity: %d\n", p->m_port_no, lane,
+		swap);
+}
+
+void nthw_mac_pcs_swap_gty_rx_polarity(nthw_mac_pcs_t *p, uint8_t lane, bool swap)
+{
+	nthw_register_update(p->mp_reg_gty_ctl);
+
+	switch (lane) {
+	case 0:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_pol0, swap);
+		break;
+
+	case 1:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_pol1, swap);
+		break;
+
+	case 2:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_pol2, swap);
+		break;
+
+	case 3:
+		nthw_field_set_val_flush32(p->mp_field_gty_ctl_rx_pol3, swap);
+		break;
+	}
+
+	NT_LOG(DBG, NTHW, "Port %u: set GTY Rx lane (%d) polarity: %d\n", p->m_port_no, lane,
+		swap);
+}
+
+void nthw_mac_pcs_set_led_mode(nthw_mac_pcs_t *p, uint8_t mode)
+{
+	nthw_field_get_updated(p->mp_field_debounce_ctrl_nt_port_ctrl);
+	nthw_field_set_val_flush32(p->mp_field_debounce_ctrl_nt_port_ctrl, mode);
+}
+
+void nthw_mac_pcs_set_timestamp_comp_rx(nthw_mac_pcs_t *p, uint16_t rx_dly)
+{
+	if (p->mp_field_time_stamp_comp_rx_dly) {
+		nthw_field_get_updated(p->mp_field_time_stamp_comp_rx_dly);
+		nthw_field_set_val_flush32(p->mp_field_time_stamp_comp_rx_dly, rx_dly);
+	}
+}
+
+void nthw_mac_pcs_set_port_no(nthw_mac_pcs_t *p, uint8_t port_no)
+{
+	p->m_port_no = port_no;
+}
+
+uint32_t nthw_mac_pcs_get_fld_block_lock_lock(nthw_mac_pcs_t *p)
+{
+	return nthw_field_get_updated(p->mp_fld_block_lock_lock);
+}
+
+uint32_t nthw_mac_pcs_get_fld_block_lock_lock_mask(nthw_mac_pcs_t *p)
+{
+	return p->m_fld_block_lock_lock_mask;
+}
+
+uint32_t nthw_mac_pcs_get_fld_lane_lock_lock(nthw_mac_pcs_t *p)
+{
+	return nthw_field_get_updated(p->mp_fld_vl_demuxed_lock);
+}
+
+uint32_t nthw_mac_pcs_get_fld_lane_lock_lock_mask(nthw_mac_pcs_t *p)
+{
+	return p->m_fld_vl_demuxed_lock_mask;
+}
-- 
2.45.0


  parent reply	other threads:[~2024-07-16 12:05 UTC|newest]

Thread overview: 238+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-30 14:48 [PATCH v1 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-05-30 14:48 ` [PATCH v1 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 07/17] net/ntnic: add API " Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 13/17] net/ntnic: add adapter initialization Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 07/17] net/ntnic: add API " Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 13/17] net/ntnic: add adapter initialization Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-06-03 16:17 ` [PATCH v3 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-06-03 16:17   ` [PATCH v3 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 07/17] net/ntnic: add API " Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 13/17] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-03 16:18   ` [PATCH v3 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-06-04 10:29   ` [PATCH v3 01/17] net/ntnic: Add registers for NapaTech SmartNiC Mykola Kostenok
2024-06-07 13:03     ` Serhii Iliushyk
2024-06-12  8:50       ` Ferruh Yigit
2024-06-12  8:55         ` Ferruh Yigit
2024-06-26 19:55 ` [PATCH v4 01/23] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 02/23] net/ntnic: add logging implementation Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 03/23] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 04/23] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 05/23] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 06/23] net/ntnic: add NT NIC driver dependencies Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 07/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 08/23] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 09/23] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 10/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 11/23] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 12/23] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 13/23] net/ntnic: add reset module for " Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 14/23] net/ntnic: add clock profiles " Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 15/23] net/ntnic: add MAC and packet features Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 16/23] net/ntnic: add link management module Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 17/23] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 18/23] net/ntnic: add NIM module Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 19/23] net/ntnic: add QSFP support Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 20/23] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 21/23] net/ntnic: add GPIO PHY module Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 22/23] net/ntnic: add MAC PCS register interface module Serhii Iliushyk
2024-06-26 19:55   ` [PATCH v4 23/23] net/ntnic: add GMF (Generic MAC Feeder) module Serhii Iliushyk
2024-06-27  7:38 ` [PATCH v5 01/23] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 02/23] net/ntnic: add logging implementation Serhii Iliushyk
2024-07-04 22:43     ` Ferruh Yigit
2024-06-27  7:38   ` [PATCH v5 03/23] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-07-04 22:44     ` Ferruh Yigit
2024-07-10 14:30       ` Serhii Iliushyk
2024-07-10 14:58         ` Ferruh Yigit
2024-06-27  7:38   ` [PATCH v5 04/23] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-07-04 22:44     ` Ferruh Yigit
2024-06-27  7:38   ` [PATCH v5 05/23] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 06/23] net/ntnic: add NT NIC driver dependencies Serhii Iliushyk
2024-07-04 22:46     ` Ferruh Yigit
2024-06-27  7:38   ` [PATCH v5 07/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 08/23] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 09/23] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 10/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 11/23] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-07-04 22:46     ` Ferruh Yigit
2024-06-27  7:38   ` [PATCH v5 12/23] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 13/23] net/ntnic: add reset module for " Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 14/23] net/ntnic: add clock profiles " Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 15/23] net/ntnic: add MAC and packet features Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 16/23] net/ntnic: add link management module Serhii Iliushyk
2024-07-04 22:47     ` Ferruh Yigit
2024-06-27  7:38   ` [PATCH v5 17/23] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 18/23] net/ntnic: add NIM module Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 19/23] net/ntnic: add QSFP support Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 20/23] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 21/23] net/ntnic: add GPIO PHY module Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 22/23] net/ntnic: add MAC PCS register interface module Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 23/23] net/ntnic: add GMF (Generic MAC Feeder) module Serhii Iliushyk
2024-07-04 22:50     ` Ferruh Yigit
2024-07-04 22:43   ` [PATCH v5 01/23] net/ntnic: add ethdev and makes PMD available Ferruh Yigit
2024-07-11 12:07 ` [PATCH v6 01/21] " Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 02/21] net/ntnic: add logging implementation Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 03/21] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 04/21] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 05/21] net/ntnic: add VFIO module Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 06/21] net/ntnic: add basic eth dev ops to ntnic Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 07/21] net/ntnic: add core platform structures Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 08/21] net/ntnic: add adapter initialization Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 09/21] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 10/21] net/ntnic: add FPGA modules for initialization Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 11/21] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 12/21] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 13/21] net/ntnic: add startup and reset sequence for NT200A0X Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 14/21] net/ntnic: add clock profile for the NT200A0X smartNIC Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 15/21] net/ntnic: add link management skeleton Serhii Iliushyk
     [not found]     ` <9f13294e-4169-483c-bee4-8ea4c2db8070@amd.com>
2024-07-11 16:51       ` Ferruh Yigit
2024-07-11 12:07   ` [PATCH v6 16/21] net/ntnic: add link 100G module ops Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 17/21] net/ntnic: add generic NIM and I2C modules Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 18/21] net/ntnic: add QSFP support Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 19/21] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 20/21] net/ntnic: add GPIO communication for NIMs Serhii Iliushyk
2024-07-11 12:07   ` [PATCH v6 21/21] net/ntnic: add physical layer control module Serhii Iliushyk
     [not found]   ` <3f90331f-9ba9-4590-b83f-dd33f25c92a0@amd.com>
2024-07-11 16:53     ` [PATCH v6 01/21] net/ntnic: add ethdev and makes PMD available Ferruh Yigit
     [not found]   ` <0bfefc75-c57e-4510-9c9f-15f8fb277718@amd.com>
2024-07-11 16:54     ` Ferruh Yigit
2024-07-12  9:48 ` [PATCH v7 " Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 02/21] net/ntnic: add logging implementation Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 03/21] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 04/21] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 05/21] net/ntnic: add VFIO module Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 06/21] net/ntnic: add basic eth dev ops to ntnic Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 07/21] net/ntnic: add core platform structures Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 08/21] net/ntnic: add adapter initialization Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 09/21] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 10/21] net/ntnic: add FPGA modules for initialization Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 11/21] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 12/21] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 13/21] net/ntnic: add startup and reset sequence for NT200A0X Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 14/21] net/ntnic: add clock profile for the NT200A0X smartNIC Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 15/21] net/ntnic: add link management skeleton Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 16/21] net/ntnic: add link 100G module ops Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 17/21] net/ntnic: add generic NIM and I2C modules Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 18/21] net/ntnic: add QSFP support Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 19/21] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 20/21] net/ntnic: add GPIO communication for NIMs Serhii Iliushyk
2024-07-12  9:48   ` [PATCH v7 21/21] net/ntnic: add physical layer control module Serhii Iliushyk
2024-07-12 13:54   ` [PATCH v7 01/21] net/ntnic: add ethdev and makes PMD available Patrick Robb
2024-07-13  2:45     ` zhoumin
2024-07-15 15:39       ` Patrick Robb
2024-07-16  2:36         ` zhoumin
2024-07-17 13:44           ` Patrick Robb
2024-07-19  7:54             ` Ferruh Yigit
2024-07-12 15:47 ` [PATCH v8 " Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 02/21] net/ntnic: add logging implementation Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 03/21] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-07-13  0:16     ` Ferruh Yigit
2024-07-12 15:47   ` [PATCH v8 04/21] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 05/21] net/ntnic: add VFIO module Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 06/21] net/ntnic: add basic eth dev ops to ntnic Serhii Iliushyk
2024-07-13  0:17     ` Ferruh Yigit
2024-07-12 15:47   ` [PATCH v8 07/21] net/ntnic: add core platform structures Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 08/21] net/ntnic: add adapter initialization Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 09/21] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 10/21] net/ntnic: add FPGA modules for initialization Serhii Iliushyk
2024-07-13  0:18     ` Ferruh Yigit
2024-07-12 15:47   ` [PATCH v8 11/21] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 12/21] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 13/21] net/ntnic: add startup and reset sequence for NT200A0X Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 14/21] net/ntnic: add clock profile for the NT200A0X smartNIC Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 15/21] net/ntnic: add link management skeleton Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 16/21] net/ntnic: add link 100G module ops Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 17/21] net/ntnic: add generic NIM and I2C modules Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 18/21] net/ntnic: add QSFP support Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 19/21] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 20/21] net/ntnic: add GPIO communication for NIMs Serhii Iliushyk
2024-07-12 15:47   ` [PATCH v8 21/21] net/ntnic: add physical layer control module Serhii Iliushyk
2024-07-13  0:15   ` [PATCH v8 01/21] net/ntnic: add ethdev and makes PMD available Ferruh Yigit
2024-07-13  0:21   ` Ferruh Yigit
2024-07-16 12:01 ` [PATCH v9 " Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 02/21] net/ntnic: add logging implementation Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 03/21] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 04/21] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 05/21] net/ntnic: add VFIO module Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 06/21] net/ntnic: add basic eth dev ops to ntnic Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 07/21] net/ntnic: add core platform structures Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 08/21] net/ntnic: add adapter initialization Serhii Iliushyk
2024-07-16 12:01   ` [PATCH v9 09/21] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-07-16 17:33     ` Ferruh Yigit
2024-07-16 12:01   ` [PATCH v9 10/21] net/ntnic: add FPGA modules for initialization Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 11/21] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 12/21] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 13/21] net/ntnic: add startup and reset sequence for NT200A0X Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 14/21] net/ntnic: add clock profile for the NT200A0X smartNIC Serhii Iliushyk
2024-07-16 17:33     ` Ferruh Yigit
2024-07-16 12:02   ` [PATCH v9 15/21] net/ntnic: add link management skeleton Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 16/21] net/ntnic: add link 100G module ops Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 17/21] net/ntnic: add generic NIM and I2C modules Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 18/21] net/ntnic: add QSFP support Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 19/21] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-07-16 12:02   ` [PATCH v9 20/21] net/ntnic: add GPIO communication for NIMs Serhii Iliushyk
2024-07-16 12:02   ` Serhii Iliushyk [this message]
2024-07-16 17:33     ` [PATCH v9 21/21] net/ntnic: add physical layer control module Ferruh Yigit
2024-07-16 17:33   ` [PATCH v9 01/21] net/ntnic: add ethdev and makes PMD available Ferruh Yigit
2024-07-17 13:32 ` [PATCH v10 " Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 02/21] net/ntnic: add logging implementation Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 03/21] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 04/21] net/ntnic: add utilities implementation Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 05/21] net/ntnic: add VFIO module Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 06/21] net/ntnic: add basic eth dev ops Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 07/21] net/ntnic: add core platform structures Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 08/21] net/ntnic: add adapter initialization Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 09/21] net/ntnic: add registers and FPGA model Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 10/21] net/ntnic: add FPGA modules for initialization Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 11/21] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-07-17 13:32   ` [PATCH v10 12/21] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 13/21] net/ntnic: add startup and reset sequence for NT200A0X Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 14/21] net/ntnic: add clock profile for the NT200A0X smartNIC Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 15/21] net/ntnic: add link management skeleton Serhii Iliushyk
2024-07-18 21:42     ` Ferruh Yigit
2024-07-17 13:33   ` [PATCH v10 16/21] net/ntnic: add link 100G module ops Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 17/21] net/ntnic: add generic NIM and I2C modules Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 18/21] net/ntnic: add QSFP support Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 19/21] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 20/21] net/ntnic: add GPIO communication for NIMs Serhii Iliushyk
2024-07-17 13:33   ` [PATCH v10 21/21] net/ntnic: add physical layer control module Serhii Iliushyk
2024-07-18 21:43   ` [PATCH v10 01/21] net/ntnic: add ethdev and makes PMD available Ferruh Yigit
2024-07-23  7:49     ` Ferruh Yigit
2024-07-23  9:32       ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240716120216.3032484-21-sil-plv@napatech.com \
    --to=sil-plv@napatech.com \
    --cc=andrew.rybchenko@oktetlabs.ru \
    --cc=ckm@napatech.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=mko-plv@napatech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).