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,
	stephen@networkplumber.org,
	Danylo Vodopianov <dvo-plv@napatech.com>
Subject: [PATCH v1 07/32] net/ntnic: add 100 gbps port init
Date: Thu, 20 Feb 2025 23:03:31 +0100	[thread overview]
Message-ID: <20250220220406.3925597-8-sil-plv@napatech.com> (raw)
In-Reply-To: <20250220220406.3925597-1-sil-plv@napatech.com>

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

Initialize NIM and 100G port for Agilex FPGA

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

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


  parent reply	other threads:[~2025-02-20 22:04 UTC|newest]

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

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=20250220220406.3925597-8-sil-plv@napatech.com \
    --to=sil-plv@napatech.com \
    --cc=ckm@napatech.com \
    --cc=dev@dpdk.org \
    --cc=dvo-plv@napatech.com \
    --cc=mko-plv@napatech.com \
    --cc=stephen@networkplumber.org \
    /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).