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