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 v4 22/23] net/ntnic: add MAC PCS register interface module
Date: Wed, 26 Jun 2024 21:55:32 +0200	[thread overview]
Message-ID: <20240626195545.1793419-22-sil-plv@napatech.com> (raw)
In-Reply-To: <20240626195545.1793419-1-sil-plv@napatech.com>

Add API for MAC and PCS(Physical Coding Sublayer)

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 499f5de8eb..9d55733ddc 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 /* timing */);
 
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index eb0ead4835..77f87ffa8e 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -43,6 +43,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-06-26 19:58 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-30 14:48 [PATCH v1 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-05-30 14:48 ` [PATCH v1 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 07/17] net/ntnic: add API " Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 13/17] net/ntnic: add adapter initialization Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 14/17] net/ntnic: add adapter initialization API Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 15/17] net/ntnic: add link management module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 16/17] net/ntnic: add link 100G module Serhii Iliushyk
2024-05-30 14:49 ` [PATCH v1 17/17] net/ntnic: add NIM module Serhii Iliushyk
2024-05-31 15:47 ` [PATCH v2 01/17] net/ntnic: Add registers for NapaTech SmartNiC Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 02/17] net/ntnic: add core platform functionality Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 03/17] net/ntnic: add interfaces for " Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 04/17] net/ntnic: add FPGA model implementation Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 05/17] net/ntnic: add NTNIC adapter interfaces Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 06/17] net/ntnic: add interfaces for PMD driver modules Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 07/17] net/ntnic: add API " Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 08/17] net/ntnic: add interfaces for flow API engine Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 09/17] net/ntnic: add VFIO module Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 10/17] net/ntnic: add Logs and utilities implementation Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 11/17] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-05-31 15:47   ` [PATCH v2 12/17] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-05-31 15:47   ` [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   ` Serhii Iliushyk [this message]
2024-06-26 19:55   ` [PATCH v4 23/23] net/ntnic: add GMF (Generic MAC Feeder) module Serhii Iliushyk
2024-06-27  7:38 ` [PATCH v5 01/23] net/ntnic: add ethdev and makes PMD available Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 02/23] net/ntnic: add logging implementation Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 03/23] net/ntnic: add minimal initialization for PCI device Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 04/23] net/ntnic: add NT utilities implementation Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 05/23] net/ntnic: add VFIO module Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 06/23] net/ntnic: add NT NIC driver dependencies Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 07/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 08/23] net/ntnic: add adapter initialization Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 09/23] net/ntnic: add registers and FPGA model for NapaTech NIC Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 10/23] net/ntnic: add core platform functionality Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 11/23] net/ntnic: add FPGA initialization functionality Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 12/23] net/ntnic: add support of the NT200A0X smartNIC Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 13/23] net/ntnic: add reset module for " Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 14/23] net/ntnic: add clock profiles " Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 15/23] net/ntnic: add MAC and packet features Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 16/23] net/ntnic: add link management module Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 17/23] net/ntnic: add link 100G module Serhii Iliushyk
2024-06-27  7:38   ` [PATCH v5 18/23] net/ntnic: add NIM module Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 19/23] net/ntnic: add QSFP support Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 20/23] net/ntnic: add QSFP28 support Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 21/23] net/ntnic: add GPIO PHY module Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 22/23] net/ntnic: add MAC PCS register interface module Serhii Iliushyk
2024-06-27  7:39   ` [PATCH v5 23/23] net/ntnic: add GMF (Generic MAC Feeder) module Serhii Iliushyk

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20240626195545.1793419-22-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).