DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 00/31] net/ntnic: bugfixes and refactoring
@ 2025-01-21 17:07 Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 01/31] net/ntnic: fix index verification Serhii Iliushyk
                   ` (31 more replies)
  0 siblings, 32 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

These patches include fixes for issues detected by the Coverity Scan tool and internal tests.

Danylo Vodopianov (26):
  net/ntnic: fix index verification
  net/ntnic: add thread check return code
  net/ntnic: add return code handling
  net/ntnic: add array index verification
  net/ntnic: fix realloc memory leak
  net/ntnic: fix array index verification
  net/ntnic: add var definition transparently
  net/ntnic: add proper var freed
  net/ntnic: remove deadcode
  net/ntnic: fix potentially overflow
  net/ntnic: add null checking
  net/ntnic: fix overflow issue
  net/ntnic: fix untrusted loop bound
  net/ntnic: add null checking
  net/ntnic: move null checking
  net/ntnic: fix var size
  net/ntnic: fix var overflow
  net/ntnic: remove dead code
  net/ntnic: remove convert error func
  net/ntnic: fix array verification
  net/ntnic: fix memory leak
  net/ntnic: remove unused code
  net/ntnic: refactor RSS implementation
  net/ntnic: fix age timeout recalculation into fpga unit
  net/ntnic: rework age event generation
  net/ntnic: fix group print

Oleksandr Kolomeiets (2):
  net/ntnic: remove extra address-of operator
  net/ntnic: remove extra check for null

Serhii Iliushyk (3):
  net/ntnic: extend module mapping
  net/ntnic: refactoring of the FPGA initialization
  net/ntnic: remove tag EXPERIMENTAL

 MAINTAINERS                                   |   2 +-
 .../net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c |   9 -
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c |  10 +-
 drivers/net/ntnic/include/create_elements.h   |   1 -
 drivers/net/ntnic/include/flow_api.h          |   9 -
 drivers/net/ntnic/include/flow_api_engine.h   |   2 +
 drivers/net/ntnic/include/hw_mod_backend.h    |  16 +-
 .../link_mgmt/link_100g/nt4ga_link_100g.c     |   2 +-
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nthw/core/nthw_fpga.c       |  14 +-
 drivers/net/ntnic/nthw/flow_api/flow_api.c    |  67 +-
 drivers/net/ntnic/nthw/flow_api/flow_group.c  |  26 +
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.c    | 661 ++++++++++++++
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.h    |  17 +
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c   |  14 +-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c   |  19 +-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c   |  18 +-
 .../profile_inline/flow_api_hw_db_inline.c    |  29 +-
 .../profile_inline/flow_api_profile_inline.c  | 817 +-----------------
 .../profile_inline/flow_api_profile_inline.h  |   4 -
 .../ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c |  10 +-
 .../nthw/supported/nthw_fpga_mod_str_map.c    |  24 +
 drivers/net/ntnic/ntnic_ethdev.c              |  16 +-
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 155 ++--
 drivers/net/ntnic/ntnic_mod_reg.h             |   6 -
 drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c |  10 +-
 26 files changed, 915 insertions(+), 1044 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h

-- 
2.45.0


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

* [PATCH v1 01/31] net/ntnic: fix index verification
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 02/31] net/ntnic: add thread check return code Serhii Iliushyk
                   ` (30 subsequent siblings)
  31 siblings, 1 reply; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

CI found couple coverity problems which were fixed in this commit.

CID: 448974, 448977, 448978 (OVERRUN).

These issues were fixed with updating index verification statement.

Coverity issue: 448974
Fixes: effa04693274 ("net/ntnic: add statistics")

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

diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index 4c8503f689..e00b10ff82 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -1201,7 +1201,7 @@ static int poll_statistics(struct pmd_internals *internals)
 	const int if_index = internals->n_intf_no;
 	uint64_t last_stat_rtc = 0;
 
-	if (!p_nt4ga_stat || if_index < 0 || if_index > NUM_ADAPTER_PORTS_MAX)
+	if (!p_nt4ga_stat || if_index < 0 || if_index >= NUM_ADAPTER_PORTS_MAX)
 		return -1;
 
 	assert(rte_tsc_freq > 0);
-- 
2.45.0


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

* [PATCH v1 02/31] net/ntnic: add thread check return code
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 01/31] net/ntnic: fix index verification Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 18:24   ` Stephen Hemminger
  2025-01-28 18:54   ` Stephen Hemminger
  2025-01-21 17:07 ` [PATCH v1 03/31] net/ntnic: add return code handling Serhii Iliushyk
                   ` (29 subsequent siblings)
  31 siblings, 2 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

CI found couple coverity problems which were fixed in this commit.

CID: 448965 Error handling issues (CHECKED_RETURN).

Thread return code check was added.

Coverity issue: 448965
Fixes: a1ba8c473f5c ("net/ntnic: add statistics poll")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 2a2643a106..620d023a71 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -2516,8 +2516,11 @@ static int init_shutdown(void)
 	NT_LOG(DBG, NTNIC, "Starting shutdown handler");
 	kill_pmd = 0;
 	previous_handler = signal(SIGINT, signal_handler_func_int);
-	THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
-
+	int ret = THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
+	if (ret != 0) {
+		NT_LOG(ERR, NTNIC, "Failed to create shutdown thread, error code: %d", ret);
+		return -1;
+	}
 	/*
 	 * 1 time calculation of 1 sec stat update rtc cycles to prevent stat poll
 	 * flooding by OVS from multiple virtual port threads - no need to be precise
-- 
2.45.0


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

* [PATCH v1 03/31] net/ntnic: add return code handling
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 01/31] net/ntnic: fix index verification Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 02/31] net/ntnic: add thread check return code Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 18:30   ` Stephen Hemminger
  2025-01-21 17:07 ` [PATCH v1 04/31] net/ntnic: add array index verification Serhii Iliushyk
                   ` (28 subsequent siblings)
  31 siblings, 1 reply; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

CI found couple coverity problems which were fixed in this commit.

CID: 448984, 448982, 448975, 448969, 448968, 448967
API usage errors  (BAD_COMPARE).

Add memcmp return value checking.

Coverity issue: 448984
Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/hw_mod_backend.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index f91a3ed058..40002f3343 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -114,10 +114,10 @@ enum {
 		typeof(be_module_reg) *temp_be_module = &(be_module_reg);                     \
 		typeof(idx) tmp_idx = (idx);                                                  \
 		typeof(cmp_idx) tmp_cmp_idx = (cmp_idx);                                      \
-		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx)) {                     \
-			(void)memcmp(temp_be_module + tmp_idx, &temp_be_module[tmp_cmp_idx],      \
-				     sizeof(type));                                               \
-		}                                                                                 \
+		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx))                     \
+			if (memcmp(temp_be_module + tmp_idx, &temp_be_module[tmp_cmp_idx], \
+				sizeof(type)) == 0) \
+				return 1;                                              \
 	} while (0)
 
 static inline int is_non_zero(const void *addr, size_t n)
-- 
2.45.0


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

* [PATCH v1 04/31] net/ntnic: add array index verification
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (2 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 03/31] net/ntnic: add return code handling Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 05/31] net/ntnic: fix realloc memory leak Serhii Iliushyk
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

CI found couple coverity problems which were fixed in this commit.

CID: 448983, 448980
Memory - corruptions  (OVERRUN)

Add check both indices within bounds before calling the macro

Coverity issue: 448983
Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c    | 17 ++++++++++++++++-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c    | 18 ++++++++++++++++--
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
index 1750d09afb..cc8db2fae5 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
@@ -121,8 +121,23 @@ static int hw_mod_hsh_rcp_mod(struct flow_api_backend_s *be, enum hw_hsh_e field
 				INDEX_TOO_LARGE_LOG;
 				return INDEX_TOO_LARGE;
 			}
+			/* Size of the structure */
+			size_t element_size = sizeof(struct hsh_v5_rcp_s);
+			/* Size of the buffer */
+			size_t buffer_size = sizeof(be->hsh.v5.rcp);
 
-			DO_COMPARE_INDEXS(be->hsh.v5.rcp, struct hsh_v5_rcp_s, index, word_off);
+			/* Calculate the maximum valid index (number of elements in the buffer) */
+			size_t max_idx = buffer_size / element_size;
+
+			/* Check that both indices are within bounds before calling the macro */
+			if (index < max_idx && word_off < max_idx) {
+				DO_COMPARE_INDEXS(be->hsh.v5.rcp, struct hsh_v5_rcp_s, index,
+					word_off);
+
+			} else {
+				INDEX_TOO_LARGE_LOG;
+				return INDEX_TOO_LARGE;
+			}
 			break;
 
 		case HW_HSH_RCP_FIND:
diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c
index 59285405ba..147a06ac2b 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c
@@ -131,8 +131,22 @@ static int hw_mod_pdb_rcp_mod(struct flow_api_backend_s *be, enum hw_pdb_e field
 				INDEX_TOO_LARGE_LOG;
 				return INDEX_TOO_LARGE;
 			}
-
-			DO_COMPARE_INDEXS(be->pdb.v9.rcp, struct pdb_v9_rcp_s, index, *value);
+			/* Size of the structure */
+			size_t element_size = sizeof(struct pdb_v9_rcp_s);
+			/* Size of the buffer */
+			size_t buffer_size = sizeof(be->pdb.v9.rcp);
+
+			/* Calculate the maximum valid index (number of elements in the buffer) */
+			size_t max_idx = buffer_size / element_size;
+
+			/* Check that both indices are within bounds before calling the macro */
+			if (index < max_idx && *value < max_idx) {
+				DO_COMPARE_INDEXS(be->pdb.v9.rcp, struct pdb_v9_rcp_s, index,
+					*value);
+			} else {
+				INDEX_TOO_LARGE_LOG;
+				return INDEX_TOO_LARGE;
+			}
 			break;
 
 		case HW_PDB_RCP_DESCRIPTOR:
-- 
2.45.0


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

* [PATCH v1 05/31] net/ntnic: fix realloc memory leak
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (3 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 04/31] net/ntnic: add array index verification Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 06/31] net/ntnic: fix array index verification Serhii Iliushyk
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Issue was fixed with verification in case of the
successful memory re-allocation.

Coverity issue: 448959
Fixes: 4033e0539435 ("net/ntnic: add flow meter")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../profile_inline/flow_api_profile_inline.c      | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index ff8eb502f4..1c7d5cac3e 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -5523,11 +5523,16 @@ int flow_configure_profile_inline(struct flow_eth_dev *dev, uint8_t caller_id,
 		struct flm_flow_mtr_handle_s *mtr_handle = dev->ndev->flm_mtr_handle;
 
 		if (mtr_handle->port_stats[caller_id]->shared == 1) {
-			res = realloc(mtr_handle->port_stats[caller_id]->stats,
-					port_attr->nb_meters) == NULL
-				? -1
-				: 0;
-			mtr_handle->port_stats[caller_id]->size = port_attr->nb_meters;
+			struct flm_mtr_stat_s *temp_stats =
+				realloc(mtr_handle->port_stats[caller_id]->stats,
+					port_attr->nb_meters);
+			if (temp_stats == NULL) {
+				res = -1;
+			} else {
+				res = 0;
+				mtr_handle->port_stats[caller_id]->stats = temp_stats;
+				mtr_handle->port_stats[caller_id]->size = port_attr->nb_meters;
+			}
 
 		} else {
 			mtr_handle->port_stats[caller_id] =
-- 
2.45.0


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

* [PATCH v1 06/31] net/ntnic: fix array index verification
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (4 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 05/31] net/ntnic: fix realloc memory leak Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 07/31] net/ntnic: add var definition transparently Serhii Iliushyk
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

CI found couple coverity problems which were fixed in this commit.

CID: 448983 Out-of-bounds write (OVERRUN).

These issues were fixed with updating index verification statement.

Coverity issue: 448983
Fixes: 96c8249be53e ("net/ntnic: learn flow queue handling")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 620d023a71..28b086c009 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -140,7 +140,7 @@ store_pdrv(struct drv_s *p_drv)
 
 static void clear_pdrv(struct drv_s *p_drv)
 {
-	if (p_drv->adapter_no > NUM_ADAPTER_MAX)
+	if (p_drv->adapter_no >= NUM_ADAPTER_MAX)
 		return;
 
 	rte_spinlock_lock(&hwlock);
-- 
2.45.0


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

* [PATCH v1 07/31] net/ntnic: add var definition transparently
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (5 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 06/31] net/ntnic: fix array index verification Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 08/31] net/ntnic: add proper var freed Serhii Iliushyk
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

set eth_base to NULL after freeing to prevent
use-after-free

CID: 446746 Use after free (USE_AFTER_FREE)

Coverity issue: 446746
Fixes: 1d3f62a0c4f1 ("net/ntnic: add base init and deinit of flow API")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_api/flow_api.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index 82d4e34ae9..d25d1a3dd1 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -385,8 +385,10 @@ static void flow_ndev_reset(struct flow_nic_dev *ndev)
 	}
 
 	/* Delete all eth-port devices created on this NIC device */
-	while (ndev->eth_base)
+	while (ndev->eth_base) {
 		flow_delete_eth_dev(ndev->eth_base);
+		ndev->eth_base = NULL;
+	}
 
 	/* Error check */
 	while (ndev->flow_base) {
-- 
2.45.0


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

* [PATCH v1 08/31] net/ntnic: add proper var freed
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (6 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 07/31] net/ntnic: add var definition transparently Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 09/31] net/ntnic: remove deadcode Serhii Iliushyk
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Ferruh Yigit

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

p_fpga_mgr is properly freed when it's no longer needed

CID 440546: Resource leak (RESOURCE_LEAK)
Fixes: ddf184d0b6c2 ("net/ntnic: add FPGA initialization")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/core/nthw_fpga.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/nthw_fpga.c b/drivers/net/ntnic/nthw/core/nthw_fpga.c
index ca69a9d5b1..88641145ec 100644
--- a/drivers/net/ntnic/nthw/core/nthw_fpga.c
+++ b/drivers/net/ntnic/nthw/core/nthw_fpga.c
@@ -230,6 +230,8 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 		if (p_fpga == NULL) {
 			NT_LOG(ERR, NTHW, "%s: Unsupported FPGA: %s (%08X)", p_adapter_id_str,
 				s_fpga_prod_ver_rev_str, p_fpga_info->n_fpga_build_time);
+			nthw_fpga_mgr_delete(p_fpga_mgr);
+			p_fpga_mgr = NULL;
 			return -1;
 		}
 
-- 
2.45.0


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

* [PATCH v1 09/31] net/ntnic: remove deadcode
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (7 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 08/31] net/ntnic: add proper var freed Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 10/31] net/ntnic: fix potentially overflow Serhii Iliushyk
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Deadcode was removed.

CID: 448981 Logically dead code (DEADCODE)

Coverity issue: 448981
Fixes: e02fdb65c2a8 ("net/ntnic: add flow create/destroy")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../flow_api/profile_inline/flow_api_profile_inline.c    | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 1c7d5cac3e..535047d246 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -4268,13 +4268,8 @@ struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev __rte_un
 
 err_exit:
 
-	if (fh) {
-		flow_destroy_locked_profile_inline(dev, fh, NULL);
-		fh = NULL;
-	} else {
-		free(fd);
-		fd = NULL;
-	}
+	free(fd);
+	fd = NULL;
 
 	rte_spinlock_unlock(&dev->ndev->mtx);
 
-- 
2.45.0


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

* [PATCH v1 10/31] net/ntnic: fix potentially overflow
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (8 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 09/31] net/ntnic: remove deadcode Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 11/31] net/ntnic: add null checking Serhii Iliushyk
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Issue with potentially overflow was fixed.

CID 448944: Unintentional integer overflow (OVERFLOW_BEFORE_WIDEN)

Coverity issue: 448944
Fixes: 339ca124e659 ("net/ntnic: add flow action modify field")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 535047d246..a68c3ea702 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -1632,7 +1632,7 @@ static int interpret_flow_actions(const struct flow_eth_dev *dev,
 						return -1;
 					}
 
-					modify_field_use_flag = 1
+					modify_field_use_flag = (uint64_t)1
 						<< fd->modify_field[fd->modify_field_count].select;
 
 					if (modify_field_use_flag & modify_field_use_flags) {
-- 
2.45.0


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

* [PATCH v1 11/31] net/ntnic: add null checking
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (9 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 10/31] net/ntnic: fix potentially overflow Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 12/31] net/ntnic: fix overflow issue Serhii Iliushyk
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

Fix issue with potential rereferencing a pointer
that might be NULL p->m_rpp_lr when calling
nthw_module_query_register

CID 448923:  Dereference null return value (NULL_RETURNS)

Coverity issue: 448923
Fixes: f543ca6b9ab2 ("net/ntnic: add RPP local retransmit (RPP LR) flow module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c
index 28c7a05fe2..e69a1ca823 100644
--- a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c
+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c
@@ -54,18 +54,20 @@ int rpp_lr_nthw_init(struct rpp_lr_nthw *p, nthw_fpga_t *p_fpga, int n_instance)
 	p->mp_fpga = p_fpga;
 	p->m_physical_adapter_no = (uint8_t)n_instance;
 	p->m_rpp_lr = nthw_fpga_query_module(p_fpga, MOD_RPP_LR, n_instance);
-
-	p->mp_rcp_ctrl = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_CTRL);
+	if (p->m_rpp_lr)
+		p->mp_rcp_ctrl = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_CTRL);
 	p->mp_rcp_addr = nthw_register_get_field(p->mp_rcp_ctrl, RPP_LR_RCP_CTRL_ADR);
 	p->mp_rcp_cnt = nthw_register_get_field(p->mp_rcp_ctrl, RPP_LR_RCP_CTRL_CNT);
-	p->mp_rcp_data = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_DATA);
+	if (p->m_rpp_lr)
+		p->mp_rcp_data = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_DATA);
 	p->mp_rcp_data_exp = nthw_register_get_field(p->mp_rcp_data, RPP_LR_RCP_DATA_EXP);
 
 	p->mp_ifr_rcp_ctrl = nthw_module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_CTRL);
 	p->mp_ifr_rcp_addr =
 		nthw_register_query_field(p->mp_ifr_rcp_ctrl, RPP_LR_IFR_RCP_CTRL_ADR);
 	p->mp_ifr_rcp_cnt = nthw_register_query_field(p->mp_ifr_rcp_ctrl, RPP_LR_IFR_RCP_CTRL_CNT);
-	p->mp_ifr_rcp_data = nthw_module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_DATA);
+	if (p->m_rpp_lr)
+		p->mp_ifr_rcp_data = nthw_module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_DATA);
 	p->mp_ifr_rcp_data_ipv4_en =
 		nthw_register_query_field(p->mp_ifr_rcp_data, RPP_LR_IFR_RCP_DATA_IPV4_EN);
 	p->mp_ifr_rcp_data_ipv6_en =
-- 
2.45.0


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

* [PATCH v1 12/31] net/ntnic: fix overflow issue
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (10 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 11/31] net/ntnic: add null checking Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 13/31] net/ntnic: fix untrusted loop bound Serhii Iliushyk
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Fix overflow issue with checking max bit shifting value.

Coverity issue: 448921
Fixes: 833962ebb893 ("net/ntnic: add CAT module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index a68c3ea702..574e51c2fa 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -3605,7 +3605,7 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n
 			.err_mask_ttl = (fd->ttl_sub_enable &&
 				fd->ttl_sub_outer) ? -1 : 0x1,
 			.ptc_mask_tunnel = fd->tunnel_prot !=
-				-1 ? (1 << fd->tunnel_prot) : -1,
+			-1 ? (1 << (fd->tunnel_prot > 10 ? 10 : fd->tunnel_prot)) : -1,
 			.ptc_mask_l3_tunnel =
 				fd->tunnel_l3_prot != -1 ? (1 << fd->tunnel_l3_prot) : -1,
 			.ptc_mask_l4_tunnel =
-- 
2.45.0


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

* [PATCH v1 13/31] net/ntnic: fix untrusted loop bound
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (11 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 12/31] net/ntnic: fix overflow issue Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 14/31] net/ntnic: add null checking Serhii Iliushyk
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Replace while with if statement to avoid infinite loop
in case ther_type will be modified with extenral source.

Coverity issue: 448917
Fixes: c6821abf58e8 ("net/ntnic: add flow items GTP and actions raw encap/decap")

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

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


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

* [PATCH v1 14/31] net/ntnic: add null checking
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (12 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 13/31] net/ntnic: fix untrusted loop bound Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 15/31] net/ntnic: move " Serhii Iliushyk
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Add null checking for fpga var.

Coverity issue: 448916
Fixes: 30b2f87ac650 ("net/ntnic: add GMF module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 d8e0cad7cd..67dc0d01f6 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
@@ -405,7 +405,7 @@ static int _port_init(adapter_info_t *drv, nthw_fpga_t *fpga, int port)
 	_reset_rx(drv, mac_pcs);
 
 	/* 2.2) Nt4gaPort::setup() */
-	if (nthw_gmf_init(NULL, fpga, port) == 0) {
+	if (fpga && nthw_gmf_init(NULL, fpga, port) == 0) {
 		nthw_gmf_t gmf;
 
 		if (nthw_gmf_init(&gmf, fpga, port) == 0)
-- 
2.45.0


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

* [PATCH v1 15/31] net/ntnic: move null checking
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (13 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 14/31] net/ntnic: add null checking Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 16/31] net/ntnic: fix var size Serhii Iliushyk
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Move null checking before using

Coverity issue: 446759
Fixes: f0fe222ea9cf ("net/ntnic: add releasing virtqueues")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
index c178144d42..279a852a1c 100644
--- a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
+++ b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
@@ -510,11 +510,11 @@ static int dbs_wait_hw_queue_shutdown(struct nthw_virt_queue *vq, int rx)
 
 static int dbs_internal_release_rx_virt_queue(struct nthw_virt_queue *rxvq)
 {
-	nthw_dbs_t *p_nthw_dbs = rxvq->mp_nthw_dbs;
-
 	if (rxvq == NULL)
 		return -1;
 
+	nthw_dbs_t *p_nthw_dbs = rxvq->mp_nthw_dbs;
+
 	/* Clear UW */
 	rxvq->used_struct_phys_addr = NULL;
 
-- 
2.45.0


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

* [PATCH v1 16/31] net/ntnic: fix var size
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (14 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 15/31] net/ntnic: move " Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 17/31] net/ntnic: fix var overflow Serhii Iliushyk
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Function operate with uint16_r value, meanwhile return value with
uint32_t size.
This conversion was aligned to the uint8_t as far as max value of the
return value could be equal 16.

Coverity issue: 446747
Fixes: 67aee0a69665 ("net/ntnic: add used writer data handling")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
index 279a852a1c..a2c9ef27f0 100644
--- a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
+++ b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
@@ -345,9 +345,9 @@ dbs_initialize_virt_queue_structs(void *avail_struct_addr, void *used_struct_add
 		flgs);
 }
 
-static uint16_t dbs_qsize_log2(uint16_t qsize)
+static uint8_t dbs_qsize_log2(uint16_t qsize)
 {
-	uint32_t qs = 0;
+	uint8_t qs = 0;
 
 	while (qsize) {
 		qsize = qsize >> 1;
-- 
2.45.0


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

* [PATCH v1 17/31] net/ntnic: fix var overflow
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (15 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 16/31] net/ntnic: fix var size Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 18/31] net/ntnic: remove dead code Serhii Iliushyk
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Casting either buf_size and num_descr to uint64_t before performing the
multiplication was done.

Coverity issue: 446740
Fixes: 6b0047fadf41 ("net/ntnic: add queue setup operations")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 28b086c009..6fcbb8fa9b 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -790,7 +790,7 @@ static int allocate_hw_virtio_queues(struct rte_eth_dev *eth_dev, int vf_num, st
 	NT_LOG(DBG, NTNIC, "***** Configure IOMMU for HW queues on VF %i *****", vf_num);
 
 	/* Just allocate 1MB to hold all combined descr rings */
-	uint64_t tot_alloc_size = 0x100000 + buf_size * num_descr;
+	uint64_t tot_alloc_size = 0x100000 + (uint64_t)buf_size * (uint64_t)num_descr;
 
 	void *virt =
 		rte_malloc_socket("VirtQDescr", tot_alloc_size, nt_util_align_size(tot_alloc_size),
-- 
2.45.0


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

* [PATCH v1 18/31] net/ntnic: remove dead code
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (16 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 17/31] net/ntnic: fix var overflow Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 19/31] net/ntnic: remove convert error func Serhii Iliushyk
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Dead code path in the condition irq_vector >= 0
because the condition irq_vector < 0 is already
established

Coverity issue: 446745
Fixes: 01e34ed9c756 ("net/ntnic: add availability monitor management")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
index a2c9ef27f0..e1eccb647c 100644
--- a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
+++ b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
@@ -415,7 +415,7 @@ static struct nthw_virt_queue *nthw_setup_rx_virt_queue(nthw_dbs_t *p_nthw_dbs,
 	if (irq_vector < 0) {
 		if (set_rx_am_data(p_nthw_dbs, index, (uint64_t)avail_struct_phys_addr,
 				RX_AM_DISABLE, host_id, 0,
-				irq_vector >= 0 ? 1 : 0) != 0) {
+				0) != 0) {
 			return NULL;
 		}
 	}
-- 
2.45.0


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

* [PATCH v1 19/31] net/ntnic: remove convert error func
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (17 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 18/31] net/ntnic: remove dead code Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 20/31] net/ntnic: fix array verification Serhii Iliushyk
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

convert_error func was removed as far as this approach was deprecated.

Coverity issue: 448973
Fixes: e526adf1fdef ("net/ntnic: add minimal create/destroy flow operations")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/create_elements.h   |   1 -
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 151 ++++++------------
 2 files changed, 53 insertions(+), 99 deletions(-)

diff --git a/drivers/net/ntnic/include/create_elements.h b/drivers/net/ntnic/include/create_elements.h
index 1456977837..f0b9410cb9 100644
--- a/drivers/net/ntnic/include/create_elements.h
+++ b/drivers/net/ntnic/include/create_elements.h
@@ -61,7 +61,6 @@ enum nt_rte_flow_item_type {
 extern rte_spinlock_t flow_lock;
 
 int interpret_raw_data(uint8_t *data, uint8_t *preserve, int size, struct rte_flow_item *out);
-int convert_error(struct rte_flow_error *error, struct rte_flow_error *rte_flow_error);
 int create_attr(struct cnv_attr_s *attribute, const struct rte_flow_attr *attr);
 int create_match_elements(struct cnv_match_s *match, const struct rte_flow_item items[],
 	int max_elem);
diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index b07e16c1d3..70bff776be 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -246,23 +246,6 @@ int interpret_raw_data(uint8_t *data, uint8_t *preserve, int size, struct rte_fl
 	return hdri + 1;
 }
 
-int convert_error(struct rte_flow_error *error, struct rte_flow_error *rte_flow_error)
-{
-	if (error) {
-		error->cause = NULL;
-		error->message = rte_flow_error->message;
-
-		if (rte_flow_error->type == RTE_FLOW_ERROR_TYPE_NONE ||
-			rte_flow_error->type == RTE_FLOW_ERROR_TYPE_NONE)
-			error->type = RTE_FLOW_ERROR_TYPE_NONE;
-
-		else
-			error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
-	}
-
-	return 0;
-}
-
 int create_attr(struct cnv_attr_s *attribute, const struct rte_flow_attr *attr)
 {
 	memset(&attribute->attr, 0x0, sizeof(struct rte_flow_attr));
@@ -497,13 +480,10 @@ static int convert_flow(struct rte_eth_dev *eth_dev,
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	uint32_t queue_offset = 0;
 
-	/* Set initial error */
-	convert_error(error, &flow_error);
-
 	if (!internals) {
 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 			"Missing eth_dev");
@@ -559,23 +539,19 @@ eth_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *flow, struct rte_
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	int res = 0;
-	/* Set initial error */
-	convert_error(error, &flow_error);
 
 	if (!flow)
 		return 0;
 
 	if (is_flow_handle_typecast(flow)) {
-		res = flow_filter_ops->flow_destroy(internals->flw_dev, (void *)flow, &flow_error);
-		convert_error(error, &flow_error);
+		res = flow_filter_ops->flow_destroy(internals->flw_dev, (void *)flow, error);
 
 	} else {
 		res = flow_filter_ops->flow_destroy(internals->flw_dev, flow->flw_hdl,
-			&flow_error);
-		convert_error(error, &flow_error);
+			error);
 
 		rte_spinlock_lock(&flow_lock);
 		flow->used = 0;
@@ -606,8 +582,8 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 	struct cnv_match_s match = { 0 };
 	struct cnv_action_s action = { 0 };
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	uint32_t flow_stat_id = 0;
 
 	if (convert_flow(eth_dev, attr, items, actions, &attribute, &match, &action, error) < 0)
@@ -620,8 +596,7 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 		void *flw_hdl = flow_filter_ops->flow_create(internals->flw_dev, &attribute.attr,
 			attribute.forced_vlan_vid, attribute.caller_id,
 			match.rte_flow_item, action.flow_actions,
-			&flow_error);
-		convert_error(error, &flow_error);
+			error);
 		return (struct rte_flow *)flw_hdl;
 	}
 
@@ -648,8 +623,7 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 		flow->flw_hdl = flow_filter_ops->flow_create(internals->flw_dev, &attribute.attr,
 			attribute.forced_vlan_vid, attribute.caller_id,
 			match.rte_flow_item, action.flow_actions,
-			&flow_error);
-		convert_error(error, &flow_error);
+			error);
 
 		if (!flow->flw_hdl) {
 			rte_spinlock_lock(&flow_lock);
@@ -678,14 +652,14 @@ static int eth_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *er
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	int res = 0;
 	/* Main application caller_id is port_id shifted above VDPA ports */
 	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
 
 	if (internals->flw_dev) {
-		res = flow_filter_ops->flow_flush(internals->flw_dev, caller_id, &flow_error);
+		res = flow_filter_ops->flow_flush(internals->flw_dev, caller_id, error);
 		rte_spinlock_lock(&flow_lock);
 
 		for (int flow = 0; flow < MAX_RTE_FLOWS; flow++) {
@@ -702,8 +676,6 @@ static int eth_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *er
 		rte_spinlock_unlock(&flow_lock);
 	}
 
-	convert_error(error, &flow_error);
-
 	return res;
 }
 
@@ -721,8 +693,8 @@ static int eth_flow_actions_update(struct rte_eth_dev *eth_dev,
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	int res = -1;
 
 	if (internals->flw_dev) {
@@ -756,18 +728,16 @@ static int eth_flow_actions_update(struct rte_eth_dev *eth_dev,
 			res = flow_filter_ops->flow_actions_update(internals->flw_dev,
 					(void *)flow,
 					action.flow_actions,
-					&flow_error);
+					error);
 
 		} else {
 			res = flow_filter_ops->flow_actions_update(internals->flw_dev,
 					flow->flw_hdl,
 					action.flow_actions,
-					&flow_error);
+					error);
 		}
 	}
 
-	convert_error(error, &flow_error);
-
 	return res;
 }
 
@@ -785,17 +755,16 @@ static int eth_flow_dev_dump(struct rte_eth_dev *eth_dev,
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
 
 	int res = flow_filter_ops->flow_dev_dump(internals->flw_dev,
 			is_flow_handle_typecast(flow) ? (void *)flow
 			: flow->flw_hdl,
-			caller_id, file, &flow_error);
+			caller_id, file, error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -813,16 +782,14 @@ static int eth_flow_get_aged_flows(struct rte_eth_dev *eth_dev,
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
 
 	int res = flow_filter_ops->flow_get_aged_flows(internals->flw_dev, caller_id, context,
-			nb_contexts, &flow_error);
+			nb_contexts, error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -842,17 +809,15 @@ static int eth_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_info_get(internals->flw_dev,
 			get_caller_id(dev->data->port_id),
 			(struct rte_flow_port_info *)port_info,
 			(struct rte_flow_queue_info *)queue_info,
-			&flow_error);
+			error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -869,18 +834,16 @@ static int eth_flow_configure(struct rte_eth_dev *dev, const struct rte_flow_por
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_configure(internals->flw_dev,
 			get_caller_id(dev->data->port_id),
 			(const struct rte_flow_port_attr *)port_attr,
 			nb_queue,
 			(const struct rte_flow_queue_attr **)queue_attr,
-			&flow_error);
+			error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -897,8 +860,8 @@ static struct rte_flow_pattern_template *eth_flow_pattern_template_create(struct
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct cnv_match_s match = { 0 };
 	struct rte_flow_pattern_template_attr attr = {
@@ -918,9 +881,8 @@ static struct rte_flow_pattern_template *eth_flow_pattern_template_create(struct
 
 	struct flow_pattern_template *res =
 		flow_filter_ops->flow_pattern_template_create(internals->flw_dev, &attr, caller_id,
-			match.rte_flow_item, &flow_error);
+			match.rte_flow_item, error);
 
-	convert_error(error, &flow_error);
 	return (struct rte_flow_pattern_template *)res;
 }
 
@@ -937,15 +899,14 @@ static int eth_flow_pattern_template_destroy(struct rte_eth_dev *dev,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_pattern_template_destroy(internals->flw_dev,
 			(struct flow_pattern_template *)
 			pattern_template,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
@@ -964,8 +925,8 @@ static struct rte_flow_actions_template *eth_flow_actions_template_create(struct
 	struct pmd_internals *internals = dev->data->dev_private;
 
 	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct cnv_action_s action = { 0 };
 	struct cnv_action_s mask = { 0 };
@@ -1004,9 +965,8 @@ static struct rte_flow_actions_template *eth_flow_actions_template_create(struct
 	struct flow_actions_template *res =
 		flow_filter_ops->flow_actions_template_create(internals->flw_dev, &attr, caller_id,
 			action.flow_actions,
-			mask.flow_actions, &rte_flow_error);
+			mask.flow_actions, error);
 
-	convert_error(error, &rte_flow_error);
 	return (struct rte_flow_actions_template *)res;
 }
 
@@ -1023,15 +983,14 @@ static int eth_flow_actions_template_destroy(struct rte_eth_dev *dev,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_actions_template_destroy(internals->flw_dev,
 			(struct flow_actions_template *)
 			actions_template,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
@@ -1050,8 +1009,8 @@ static struct rte_flow_template_table *eth_flow_template_table_create(struct rte
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct rte_flow_template_table_attr attr = {
 		.flow_attr = {
@@ -1071,9 +1030,8 @@ static struct rte_flow_template_table *eth_flow_template_table_create(struct rte
 			forced_vlan_vid, caller_id,
 			(struct flow_pattern_template **)pattern_templates,
 			nb_pattern_templates, (struct flow_actions_template **)actions_templates,
-			nb_actions_templates, &rte_flow_error);
+			nb_actions_templates, error);
 
-	convert_error(error, &rte_flow_error);
 	return (struct rte_flow_template_table *)res;
 }
 
@@ -1090,15 +1048,14 @@ static int eth_flow_template_table_destroy(struct rte_eth_dev *dev,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_template_table_destroy(internals->flw_dev,
 			(struct flow_template_table *)
 			template_table,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
@@ -1118,8 +1075,8 @@ static struct rte_flow *eth_flow_async_create(struct rte_eth_dev *dev, uint32_t
 	struct pmd_internals *internals = dev->data->dev_private;
 
 	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct cnv_action_s action = { 0 };
 	struct cnv_match_s match = { 0 };
@@ -1159,9 +1116,8 @@ static struct rte_flow *eth_flow_async_create(struct rte_eth_dev *dev, uint32_t
 			action.flow_actions,
 			actions_template_index,
 			user_data,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return (struct rte_flow *)res;
 }
 
@@ -1178,17 +1134,16 @@ static int eth_flow_async_destroy(struct rte_eth_dev *dev, uint32_t queue_id,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_async_destroy(internals->flw_dev,
 			queue_id,
 			(const struct rte_flow_op_attr *)op_attr,
 			(struct flow_handle *)flow,
 			user_data,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
-- 
2.45.0


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

* [PATCH v1 20/31] net/ntnic: fix array verification
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (18 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 19/31] net/ntnic: remove convert error func Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:07 ` [PATCH v1 21/31] net/ntnic: fix memory leak Serhii Iliushyk
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

if statement was modify to ensure that word_off
doesn't exceed the size of the array

Coverity issue: 448958
Fixes: 7fa0bf29e667 ("net/ntnic: add hash module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
index cc8db2fae5..d19e72e323 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
@@ -221,7 +221,7 @@ static int hw_mod_hsh_rcp_mod(struct flow_api_backend_s *be, enum hw_hsh_e field
 			break;
 
 		case HW_HSH_RCP_WORD_MASK:
-			if (word_off > HSH_RCP_WORD_MASK_SIZE) {
+			if (word_off >= HSH_RCP_WORD_MASK_SIZE) {
 				WORD_OFF_TOO_LARGE_LOG;
 				return WORD_OFF_TOO_LARGE;
 			}
-- 
2.45.0


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

* [PATCH v1 21/31] net/ntnic: fix memory leak
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (19 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 20/31] net/ntnic: fix array verification Serhii Iliushyk
@ 2025-01-21 17:07 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 22/31] net/ntnic: remove extra address-of operator Serhii Iliushyk
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:07 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

free for kvlist was added before return to avoid memory leak.

Coveriry issue: 446751
Fixes: fe91ade9f5db ("net/ntnic: add basic queue operations")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 6fcbb8fa9b..d1360cc925 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -2089,6 +2089,7 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
 				NT_LOG_DBGX(ERR, NTNIC,
 					"problem with command line arguments: res=%d",
 					res);
+				free(kvlist);
 				return -1;
 			}
 
@@ -2112,6 +2113,7 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
 				NT_LOG_DBGX(ERR, NTNIC,
 					"problem with command line arguments: res=%d",
 					res);
+				free(kvlist);
 				return -1;
 			}
 
-- 
2.45.0


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

* [PATCH v1 22/31] net/ntnic: remove extra address-of operator
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (20 preceding siblings ...)
  2025-01-21 17:07 ` [PATCH v1 21/31] net/ntnic: fix memory leak Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 23/31] net/ntnic: remove extra check for null Serhii Iliushyk
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Oleksandr Kolomeiets

From: Oleksandr Kolomeiets <okl-plv@napatech.com>

Macro DO_COMPARE_INDEXS expects pointer to array.
If condition is true, one of array's elements get overwritten.
Misinterpreting pointer to pointer as pointer to array
may result in out-of-bounds access.

Coverity issue: 448966, 448970, 448971, 448972
Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")

Signed-off-by: Oleksandr Kolomeiets <okl-plv@napatech.com>
---
 drivers/net/ntnic/include/hw_mod_backend.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index 40002f3343..7bb39e37eb 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -111,7 +111,7 @@ enum {
 
 #define DO_COMPARE_INDEXS(be_module_reg, type, idx, cmp_idx)                                      \
 	do {                                                                                      \
-		typeof(be_module_reg) *temp_be_module = &(be_module_reg);                     \
+		typeof(be_module_reg) temp_be_module = (be_module_reg);                     \
 		typeof(idx) tmp_idx = (idx);                                                  \
 		typeof(cmp_idx) tmp_cmp_idx = (cmp_idx);                                      \
 		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx))                     \
-- 
2.45.0


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

* [PATCH v1 23/31] net/ntnic: remove extra check for null
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (21 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 22/31] net/ntnic: remove extra address-of operator Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 24/31] net/ntnic: remove unused code Serhii Iliushyk
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Oleksandr Kolomeiets, Danylo Vodopianov

From: Oleksandr Kolomeiets <okl-plv@napatech.com>

pld_ptr points to mp_port_load's element,
which is initialized during driver's probe,
otherwise probe fails and xstats_get_by_id is not called.

Coverity issue: 448945
Fixes: cf6007eac498 ("net/ntnic: add xstats")

Signed-off-by: Oleksandr Kolomeiets <okl-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c b/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c
index 7604afe6a0..cf3271d5de 100644
--- a/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c
+++ b/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c
@@ -645,16 +645,8 @@ static int nthw_xstats_get_by_id(nt4ga_stat_t *p_nt4ga_stat,
 				break;
 
 			case 4:
-
 				/* Port Load stat */
-				if (pld_ptr) {
-					/* No reset */
-					values[i] = *((uint64_t *)&pld_ptr[names[i].offset]);
-
-				} else {
-					values[i] = 0;
-				}
-
+				values[i] = *((uint64_t *)&pld_ptr[names[i].offset]);
 				break;
 
 			default:
-- 
2.45.0


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

* [PATCH v1 24/31] net/ntnic: remove unused code
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (22 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 23/31] net/ntnic: remove extra check for null Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 25/31] net/ntnic: refactor RSS implementation Serhii Iliushyk
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

NTNIC currently cupport only 100G link.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
index 8fedfdcd04..2add43639a 100644
--- a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
+++ b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
@@ -215,16 +215,7 @@ static int nt4ga_stat_setup(struct adapter_info_s *p_adapter_info)
 		return -1;
 	}
 
-#ifdef NIM_TRIGGER
-	uint64_t max_bps_speed = nt_get_max_link_speed(p_adapter_info->nt4ga_link.speed_capa);
-
-	if (max_bps_speed == 0)
-		max_bps_speed = DEFAULT_MAX_BPS_SPEED;
-
-#else
 	uint64_t max_bps_speed = DEFAULT_MAX_BPS_SPEED;
-	NT_LOG(ERR, NTNIC, "NIM module not included");
-#endif
 
 	for (int p = 0; p < NUM_ADAPTER_PORTS_MAX; p++) {
 		p_nt4ga_stat->mp_port_load[p].rx_bps_max = max_bps_speed;
-- 
2.45.0


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

* [PATCH v1 25/31] net/ntnic: refactor RSS implementation
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (23 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 24/31] net/ntnic: remove unused code Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 26/31] net/ntnic: fix age timeout recalculation into fpga unit Serhii Iliushyk
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Virtualization backward compatible RSS implementation is no longer
needed, thus RSS was refactored as follows:
* conversion of RTE_ETH_RSS fields into HSH registers was moved to
  separate files
* profile wrapper for RSS configuration was removed
* flow_nic_set_hasher(), to configure default 5-tuple hash, was
  replaced by call of hsh_set() with proper RTE_ETH_RSS*
  fields

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api.h          |   9 -
 drivers/net/ntnic/include/hw_mod_backend.h    |   6 -
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nthw/flow_api/flow_api.c    |  63 --
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.c    | 661 +++++++++++++++
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.h    |  17 +
 .../profile_inline/flow_api_hw_db_inline.c    |   5 +-
 .../profile_inline/flow_api_profile_inline.c  | 782 +-----------------
 .../profile_inline/flow_api_profile_inline.h  |   4 -
 drivers/net/ntnic/ntnic_ethdev.c              |   3 +-
 drivers/net/ntnic/ntnic_mod_reg.h             |   6 -
 11 files changed, 695 insertions(+), 862 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h

diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
index 0af766fe5b..9201b8a3ae 100644
--- a/drivers/net/ntnic/include/flow_api.h
+++ b/drivers/net/ntnic/include/flow_api.h
@@ -83,11 +83,6 @@ struct flow_eth_dev {
 	struct flow_eth_dev *next;
 };
 
-enum flow_nic_hash_e {
-	HASH_ALGO_ROUND_ROBIN = 0,
-	HASH_ALGO_5TUPLE,
-};
-
 /* registered NIC backends */
 struct flow_nic_dev {
 	uint8_t adapter_no;     /* physical adapter no in the host system */
@@ -234,10 +229,6 @@ void flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type,
 int flow_nic_ref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);
 int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);
 
-int flow_nic_set_hasher(struct flow_nic_dev *ndev, int hsh_idx, enum flow_nic_hash_e algorithm);
-int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx,
-	struct nt_eth_rss_conf rss_conf);
-
 int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
 
 #endif
diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index 7bb39e37eb..28980b727b 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -239,12 +239,6 @@ enum {
 	PROT_TUN_L4_ICMP = 4
 };
 
-
-enum {
-	HASH_HASH_NONE = 0,
-	HASH_5TUPLE = 8,
-};
-
 enum {
 	CPY_SELECT_DSCP_IPV4 = 0,
 	CPY_SELECT_DSCP_IPV6 = 1,
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 3c05ad1d87..bfc5ae5aa8 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -70,6 +70,7 @@ sources = files(
         'nthw/flow_api/flow_backend/flow_backend.c',
         'nthw/flow_api/flow_filter.c',
         'nthw/flow_api/flow_hasher.c',
+        'nthw/flow_api/flow_hsh_cfg.c',
         'nthw/flow_api/flow_kcc.c',
         'nthw/flow_api/flow_km.c',
         'nthw/flow_api/hw_mod/hw_mod_backend.c',
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index d25d1a3dd1..857051fe14 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -1009,55 +1009,6 @@ int sprint_nt_rss_mask(char *str, uint16_t str_len, const char *prefix, uint64_t
 	return 0;
 }
 
-/*
- * Hash
- */
-
-int flow_nic_set_hasher(struct flow_nic_dev *ndev, int hsh_idx, enum flow_nic_hash_e algorithm)
-{
-	hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
-
-	switch (algorithm) {
-	case HASH_ALGO_5TUPLE:
-		/* need to create an IPv6 hashing and enable the adaptive ip mask bit */
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_LOAD_DIST_TYPE, hsh_idx, 0, 2);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW0_PE, hsh_idx, 0, DYN_FINAL_IP_DST);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW0_OFS, hsh_idx, 0, -16);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW4_PE, hsh_idx, 0, DYN_FINAL_IP_DST);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW4_OFS, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W8_PE, hsh_idx, 0, DYN_L4);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W8_OFS, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W9_PE, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W9_OFS, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W9_P, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK, hsh_idx, 0, 1);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 0, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 1, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 2, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 3, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 4, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 5, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 6, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 7, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 8, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 9, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_SEED, hsh_idx, 0, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_HSH_VALID, hsh_idx, 0, 1);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_HSH_TYPE, hsh_idx, 0, HASH_5TUPLE);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_AUTO_IPV4_MASK, hsh_idx, 0, 1);
-
-		NT_LOG(DBG, FILTER, "Set IPv6 5-tuple hasher with adaptive IPv4 hashing");
-		break;
-
-	default:
-	case HASH_ALGO_ROUND_ROBIN:
-		/* zero is round-robin */
-		break;
-	}
-
-	return 0;
-}
-
 static int flow_dev_dump(struct flow_eth_dev *dev,
 	struct flow_handle *flow,
 	uint16_t caller_id,
@@ -1074,19 +1025,6 @@ static int flow_dev_dump(struct flow_eth_dev *dev,
 	return profile_inline_ops->flow_dev_dump_profile_inline(dev, flow, caller_id, file, error);
 }
 
-int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx,
-	struct nt_eth_rss_conf rss_conf)
-{
-	const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
-
-	if (profile_inline_ops == NULL) {
-		NT_LOG(ERR, FILTER, "%s: profile_inline module uninitialized", __func__);
-		return -1;
-	}
-
-	return profile_inline_ops->flow_nic_set_hasher_fields_inline(ndev, hsh_idx, rss_conf);
-}
-
 static int flow_get_aged_flows(struct flow_eth_dev *dev,
 	uint16_t caller_id,
 	void **context,
@@ -1324,7 +1262,6 @@ static const struct flow_filter_ops ops = {
 	 * Other
 	 */
 	 .hw_mod_hsh_rcp_flush = hw_mod_hsh_rcp_flush,
-	 .flow_nic_set_hasher_fields = flow_nic_set_hasher_fields,
 };
 
 void init_flow_filter(void)
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
new file mode 100644
index 0000000000..624d1a26d1
--- /dev/null
+++ b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
@@ -0,0 +1,661 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#include "flow_hsh_cfg.h"
+
+#define RTE_ETH_RSS_UDP_COMBINED (RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
+								  RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
+								  RTE_ETH_RSS_IPV6_UDP_EX)
+
+#define RTE_ETH_RSS_TCP_COMBINED (RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
+								  RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
+								  RTE_ETH_RSS_IPV6_TCP_EX)
+
+#define TOEPLITS_HSH_SIZE 9
+/*
+ * FPGA uses up to 10 32-bit words (320 bits) for hash calculation + 8 bits for L4 protocol number.
+ * Hashed data are split between two 128-bit Quad Words (QW)
+ * and two 32-bit Words (W), which can refer to different header parts.
+ */
+enum hsh_words_id {
+	HSH_WORDS_QW0     = 0,
+	HSH_WORDS_QW4,
+	HSH_WORDS_W8,
+	HSH_WORDS_W9,
+	HSH_WORDS_SIZE,
+};
+
+/* struct with details about hash QWs & Ws */
+struct hsh_words {
+	/*
+	 * index of W (word) or index of 1st word of QW (quad word)
+	 * is used for hash mask calculation
+	 */
+	uint8_t index;
+	enum hw_hsh_e pe;           /* offset to header part, e.g. beginning of L4 */
+	enum hw_hsh_e ofs;          /* relative offset in BYTES to 'pe' header offset above */
+	uint16_t bit_len;           /* max length of header part in bits to fit into QW/W */
+	bool free;                  /* only free words can be used for hsh calculation */
+};
+
+static enum hsh_words_id get_free_word(struct hsh_words *words, uint16_t bit_len)
+{
+	enum hsh_words_id ret = HSH_WORDS_SIZE;
+	uint16_t ret_bit_len = UINT16_MAX;
+	for (enum hsh_words_id i = HSH_WORDS_QW0; i < HSH_WORDS_SIZE; i++) {
+		if (words[i].free && bit_len <=
+			words[i].bit_len && words[i].bit_len <
+			ret_bit_len) {
+			ret = i;
+			ret_bit_len = words[i].bit_len;
+		}
+	}
+	return ret;
+}
+
+static int hsh_set_part(struct flow_nic_dev *ndev, int hsh_idx, struct hsh_words *words,
+	uint32_t pe, uint32_t ofs, int bit_len, bool toeplitz)
+{
+	int res = 0;
+
+	/* check if there is any free word, which can accommodate header part of given 'bit_len' */
+	enum hsh_words_id word = get_free_word(words, bit_len);
+
+	if (word == HSH_WORDS_SIZE) {
+		NT_LOG(ERR, FILTER, "Cannot add additional %d bits into hash", bit_len);
+		return -1;
+	}
+
+	words[word].free = false;
+
+	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].pe, hsh_idx, 0, pe);
+	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].pe,
+		hsh_idx, pe);
+	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].ofs, hsh_idx, 0, ofs);
+	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].ofs,
+		hsh_idx, ofs);
+
+
+	/* set HW_HSH_RCP_WORD_MASK based on used QW/W and given 'bit_len' */
+	int mask_bit_len = bit_len;
+	uint32_t mask = 0x0;
+	uint32_t toeplitz_mask[TOEPLITS_HSH_SIZE] = {0x0};
+	/* iterate through all words of QW */
+	uint16_t words_count = words[word].bit_len / 32;
+	for (uint16_t mask_off = 1; mask_off <= words_count; mask_off++) {
+		if (mask_bit_len >= 32) {
+			mask_bit_len -= 32;
+			mask = 0xffffffff;
+		} else if (mask_bit_len > 0) {
+			mask = 0xffffffff >> (32 - mask_bit_len) << (32 - mask_bit_len);
+			mask_bit_len = 0;
+		} else {
+			mask = 0x0;
+		}
+		/* reorder QW words mask from little to big endian */
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx,
+			words[word].index + words_count - mask_off, mask);
+		NT_LOG(DBG, FILTER,
+			"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, %d, %d, 0x%08" PRIX32 ")",
+				hsh_idx, words[word].index + words_count - mask_off, mask);
+		toeplitz_mask[words[word].index + mask_off - 1] = mask;
+	}
+	if (toeplitz) {
+		NT_LOG(DBG, FILTER,
+			"Partial Toeplitz RSS key mask: %08" PRIX32 " %08" PRIX32 " %08" PRIX32
+			" %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32
+			" %08" PRIX32 "",
+			toeplitz_mask[0], toeplitz_mask[1], toeplitz_mask[2], toeplitz_mask[3],
+			toeplitz_mask[4], toeplitz_mask[5], toeplitz_mask[6], toeplitz_mask[7],
+			toeplitz_mask[8]);
+		NT_LOG(DBG, FILTER, "                               MSB                                                                          LSB");
+	}
+	return res;
+}
+
+static __rte_always_inline bool all_bits_enabled(uint64_t hash_mask, uint64_t hash_bits)
+{
+	return (hash_mask & hash_bits) == hash_bits;
+}
+
+static __rte_always_inline void unset_bits(uint64_t *hash_mask, uint64_t hash_bits)
+{
+	*hash_mask &= ~hash_bits;
+}
+
+static __rte_always_inline void unset_bits_and_log(uint64_t *hash_mask, uint64_t hash_bits)
+{
+	char rss_buffer[4096];
+	uint16_t rss_buffer_len = sizeof(rss_buffer);
+
+	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", *hash_mask & hash_bits) == 0)
+		NT_LOG(DBG, FILTER, "Configured RSS types:%s", rss_buffer);
+	unset_bits(hash_mask, hash_bits);
+}
+
+static __rte_always_inline void unset_bits_if_all_enabled(uint64_t *hash_mask, uint64_t hash_bits)
+{
+	if (all_bits_enabled(*hash_mask, hash_bits))
+		unset_bits(hash_mask, hash_bits);
+}
+
+int hsh_set(struct flow_nic_dev *ndev, int hsh_idx, struct nt_eth_rss_conf rss_conf)
+{
+	uint64_t fields = rss_conf.rss_hf;
+
+	char rss_buffer[4096];
+	uint16_t rss_buffer_len = sizeof(rss_buffer);
+
+	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", fields) == 0)
+		NT_LOG(DBG, FILTER, "Requested RSS types:%s", rss_buffer);
+
+	/*
+	 * configure all (Q)Words usable for hash calculation
+	 * Hash can be calculated from 4 independent header parts:
+	 *      | QW0           | Qw4           | W8| W9|
+	 * word | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+	 */
+	struct hsh_words words[HSH_WORDS_SIZE] = {
+		{ 0, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
+		{ 4, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
+		{ 8, HW_HSH_RCP_W8_PE,  HW_HSH_RCP_W8_OFS,   32, true },
+		 /* not supported for Toeplitz */
+		{ 9, HW_HSH_RCP_W9_PE,  HW_HSH_RCP_W9_OFS,   32, true },
+	};
+
+	int res = 0;
+	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
+	/* enable hashing */
+	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_LOAD_DIST_TYPE, hsh_idx, 0, 2);
+
+	/* configure selected hash function and its key */
+	bool toeplitz = false;
+	switch (rss_conf.algorithm) {
+	case RTE_ETH_HASH_FUNCTION_DEFAULT:
+		/* Use default NTH10 hashing algorithm */
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 0);
+		/* Use 1st 32-bits from rss_key to configure NTH10 SEED */
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_SEED, hsh_idx, 0,
+			rss_conf.rss_key[0] << 24 | rss_conf.rss_key[1] << 16 |
+				rss_conf.rss_key[2] << 8 | rss_conf.rss_key[3]);
+		break;
+	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
+		toeplitz = true;
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 1);
+		uint8_t empty_key = 0;
+
+		/* Toeplitz key (always 40B) words have to be programmed in reverse order */
+		for (uint8_t i = 0; i <= (MAX_RSS_KEY_LEN - 4); i += 4) {
+			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, hsh_idx, 9 - i / 4,
+				rss_conf.rss_key[i] << 24 | rss_conf.rss_key[i + 1] << 16 |
+				rss_conf.rss_key[i + 2] << 8 | rss_conf.rss_key[i + 3]);
+			NT_LOG(DBG, FILTER,
+				"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, %d, %d, 0x%" PRIX32 ")",
+				hsh_idx, 9 - i / 4, rss_conf.rss_key[i] << 24 |
+				rss_conf.rss_key[i + 1] << 16 | rss_conf.rss_key[i + 2] << 8 |
+				rss_conf.rss_key[i + 3]);
+			empty_key |= rss_conf.rss_key[i] | rss_conf.rss_key[i + 1] |
+				rss_conf.rss_key[i + 2] | rss_conf.rss_key[i + 3];
+		}
+
+		if (empty_key == 0) {
+			NT_LOG(ERR, FILTER, "Toeplitz key must be configured. Key with all bytes set to zero is not allowed.");
+			return -1;
+		}
+		words[HSH_WORDS_W9].free = false;
+		NT_LOG(DBG, FILTER, "Toeplitz hashing is enabled thus W9 and P_MASK cannot be used.");
+		break;
+	default:
+		NT_LOG(ERR, FILTER, "Unknown hashing function %d requested", rss_conf.algorithm);
+		return -1;
+	}
+
+	/* indication that some IPv6 flag is present */
+	bool ipv6 = fields & (NT_ETH_RSS_IPV6_MASK);
+	/* store proto mask for later use at IP and L4 checksum handling */
+	uint64_t l4_proto_mask = fields &
+				(RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV4_UDP |
+				RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
+				RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
+				RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
+				RTE_ETH_RSS_IPV6_TCP_EX | RTE_ETH_RSS_IPV6_UDP_EX);
+
+	/* outermost headers are used by default, so innermost bit takes precedence if detected */
+	bool outer = (fields & RTE_ETH_RSS_LEVEL_INNERMOST) ? false : true;
+	unset_bits(&fields, RTE_ETH_RSS_LEVEL_MASK);
+
+	if (fields == 0) {
+		NT_LOG(ERR, FILTER, "RSS hash configuration 0x%" PRIX64 " is not valid.",
+			rss_conf.rss_hf);
+		return -1;
+	}
+
+	/* indication that IPv4 `protocol` or IPv6 `next header` fields shall be part of the hash */
+	bool l4_proto_hash = false;
+
+	/*
+	 * check if SRC_ONLY & DST_ONLY are used simultaneously;
+	 * According to DPDK, we shall behave like none of these bits is set
+	 */
+	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY);
+	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY);
+	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY);
+
+	/* L2 */
+	if (fields & (RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY)) {
+		if (outer) {
+			if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer src MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L2,
+					6, 48, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L2,
+					0, 48, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set outer src & dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L2,
+					0, 96, toeplitz);
+			}
+		} else {
+			if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner src MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L2,
+					6, 48, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L2,
+					0, 48, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner src & dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L2,
+					0, 96, toeplitz);
+			}
+		}
+		unset_bits_and_log(&fields, RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY |
+			RTE_ETH_RSS_L2_DST_ONLY);
+	}
+
+	/*
+	 * VLAN support of multiple VLAN headers,
+	 * where S-VLAN is the first and C-VLAN the last VLAN header
+	 */
+	if (fields & RTE_ETH_RSS_C_VLAN) {
+		/*
+		 * use MPLS protocol offset, which points
+		 * just after ethertype with relative
+		 * offset -6 (i.e. 2 bytes
+		 * of ethertype & size + 4 bytes of VLAN header field)
+		 * to access last vlan header
+		 */
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer C-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_MPLS,
+				-6, 32, toeplitz);
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner C-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_MPLS,
+				-6, 32, toeplitz);
+		}
+		unset_bits_and_log(&fields, RTE_ETH_RSS_C_VLAN);
+	}
+
+	if (fields & RTE_ETH_RSS_S_VLAN) {
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer S-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_FIRST_VLAN,
+				0, 32, toeplitz);
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner S-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_VLAN,
+				0, 32, toeplitz);
+		}
+		unset_bits_and_log(&fields, RTE_ETH_RSS_S_VLAN);
+	}
+
+	/* L2 payload */
+	/* calculate hash of 128-bits of l2 payload;
+	 * Use MPLS protocol offset to address the beginning
+	 * of L2 payload even if MPLS header is not present
+	 */
+	if (fields & RTE_ETH_RSS_L2_PAYLOAD) {
+		uint64_t outer_fields_enabled = 0;
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer L2 payload hasher.");
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_MPLS,
+				0, 128, toeplitz);
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner L2 payload hasher.");
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_MPLS,
+				0, 128, toeplitz);
+			outer_fields_enabled = fields & RTE_ETH_RSS_GTPU;
+		}
+		/*
+		 * L2 PAYLOAD hashing overrides all L3 & L4 RSS flags.
+		 * Thus we can clear all remaining (supported)
+		 * RSS flags...
+		 */
+		unset_bits_and_log(&fields, NT_ETH_RSS_OFFLOAD_MASK);
+		/*
+		 * ...but in case of INNER L2 PAYLOAD we must process
+		 * "always outer" GTPU field if enabled
+		 */
+		fields |= outer_fields_enabled;
+	}
+
+	/* L3 + L4 protocol number */
+	if (fields & RTE_ETH_RSS_IPV4_CHKSUM) {
+		/* only IPv4 checksum is supported by DPDK RTE_ETH_RSS_* types */
+		if (ipv6) {
+			NT_LOG(ERR, FILTER, "RSS: IPv4 checksum requested with IPv6 header hashing!");
+			res = 1;
+		} else {
+			if (outer) {
+				NT_LOG(DBG, FILTER, "Set outer IPv4 checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+					10, 16, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner IPv4 checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+					10, 16, toeplitz);
+			}
+		}
+		/*
+		 * L3 checksum is made from whole L3 header, i.e. no need to process other
+		 * L3 hashing flags
+		 */
+		unset_bits_and_log(&fields, RTE_ETH_RSS_IPV4_CHKSUM | NT_ETH_RSS_IP_MASK);
+	}
+
+	if (fields & NT_ETH_RSS_IP_MASK) {
+		if (ipv6) {
+			if (outer) {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 src hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						-16, 128, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						0, 128, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						-16, 128, toeplitz);
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						0, 128, toeplitz);
+				}
+			} else {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, -16, 128, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, 0, 128, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, -16, 128, toeplitz);
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, 0, 128, toeplitz);
+				}
+			}
+			/* check if fragment ID shall be part of hash */
+			if (fields & (RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6)) {
+				if (outer) {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_ID_IPV4_6,
+						0, 32, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_ID_IPV4_6,
+						0, 32, toeplitz);
+				}
+			}
+			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_AUTO_IPV4_MASK,
+				hsh_idx, 0, 1);
+		} else {
+			/* IPv4 */
+			if (outer) {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 src only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+						12, 32, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 dst only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+						16, 32, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+						12, 64, toeplitz);
+				}
+			} else {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 src only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+						12, 32, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 dst only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+						16, 32, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+						12, 64, toeplitz);
+				}
+			}
+			/* check if fragment ID shall be part of hash */
+			if (fields & RTE_ETH_RSS_FRAG_IPV4) {
+				if (outer) {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_ID_IPV4_6,
+						0, 16, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_ID_IPV4_6,
+						0, 16, toeplitz);
+				}
+			}
+		}
+
+		/* check if L4 protocol type shall be part of hash */
+		if (l4_proto_mask)
+			l4_proto_hash = true;
+		unset_bits_and_log(&fields, NT_ETH_RSS_IP_MASK);
+	}
+
+	/* L4 */
+	if (fields & (RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY |
+		RTE_ETH_RSS_L4_DST_ONLY)) {
+		if (outer) {
+			if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer L4 src hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4,
+					0, 16, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer L4 dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4,
+					2, 16, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set outer L4 src & dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4,
+					0, 32, toeplitz);
+			}
+		} else {
+			if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner L4 src hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4,
+					0, 16, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner L4 dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4,
+					2, 16, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner L4 src & dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4,
+					0, 32, toeplitz);
+			}
+		}
+		l4_proto_hash = true;
+		unset_bits_and_log(&fields, RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY |
+			RTE_ETH_RSS_L4_DST_ONLY);
+	}
+
+	/* IPv4 protocol / IPv6 next header fields */
+	if (l4_proto_hash) {
+		/* NOTE: HW_HSH_RCP_P_MASK is not supported for
+		 *Toeplitz and thus one of SW0, SW4 or W8
+		 * must be used to hash on `protocol` field of IPv4 or
+		 * `next header` field of IPv6 header.
+		 */
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer L4 protocol type / next header hasher.");
+			if (toeplitz) {
+				if (ipv6)
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3, 6, 8,
+						toeplitz);
+				else
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3, 9, 8,
+						toeplitz);
+			} else {
+				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK,
+					hsh_idx, 0, 1);
+				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TNL_P,
+					hsh_idx, 0, 0);
+			}
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner L4 protocol type / next header hasher.");
+			if (toeplitz) {
+				if (ipv6) {
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3, 6, 8,
+						toeplitz);
+				} else {
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3, 9, 8,
+						toeplitz);
+				}
+			} else {
+				res |= hw_mod_hsh_rcp_set(&ndev->be,
+					HW_HSH_RCP_P_MASK, hsh_idx, 0, 1);
+				res |= hw_mod_hsh_rcp_set(&ndev->be,
+					HW_HSH_RCP_TNL_P, hsh_idx, 0, 1);
+			}
+		}
+		l4_proto_hash = false;
+	}
+
+	/*
+	 * GTPU - for UPF use cases we always use TEID from outermost GTPU header
+	 * even if other headers are innermost
+	 */
+	if (fields & RTE_ETH_RSS_GTPU) {
+		NT_LOG(DBG, FILTER, "Set outer GTPU TEID hasher.");
+		res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4_PAYLOAD, 4, 32, toeplitz);
+		unset_bits_and_log(&fields, RTE_ETH_RSS_GTPU);
+	}
+
+	/* Checksums */
+	/* only UDP, TCP and SCTP checksums are supported */
+	if (fields & RTE_ETH_RSS_L4_CHKSUM) {
+		switch (l4_proto_mask) {
+		case RTE_ETH_RSS_NONFRAG_IPV4_UDP:
+		case RTE_ETH_RSS_NONFRAG_IPV6_UDP:
+		case RTE_ETH_RSS_IPV6_UDP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP:
+		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
+		case RTE_ETH_RSS_UDP_COMBINED:
+			if (outer) {
+				NT_LOG(DBG, FILTER, "Set outer UDP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4, 6, 16,
+					toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner UDP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4, 6, 16,
+					toeplitz);
+			}
+			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
+			break;
+		case RTE_ETH_RSS_NONFRAG_IPV4_TCP:
+		case RTE_ETH_RSS_NONFRAG_IPV6_TCP:
+		case RTE_ETH_RSS_IPV6_TCP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP:
+		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
+		case RTE_ETH_RSS_TCP_COMBINED:
+				if (outer) {
+					NT_LOG(DBG, FILTER, "Set outer TCP checksum hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_L4, 16, 16, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner TCP checksum hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_L4, 16, 16, toeplitz);
+				}
+				unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
+				break;
+		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP:
+		case RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
+		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
+			if (outer) {
+				NT_LOG(DBG, FILTER, "Set outer SCTP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4, 8, 32,
+					toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner SCTP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4, 8, 32,
+					toeplitz);
+			}
+			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
+			break;
+		case RTE_ETH_RSS_NONFRAG_IPV4_OTHER:
+		case RTE_ETH_RSS_NONFRAG_IPV6_OTHER:
+		/* none or unsupported protocol was chosen */
+		case 0:
+			NT_LOG(ERR, FILTER, "L4 checksum hashing is supported only for UDP, TCP and SCTP protocols");
+			res = -1;
+			break;
+		/* multiple L4 protocols were selected */
+		default:
+			NT_LOG(ERR, FILTER, "L4 checksum hashing can be enabled just for one of UDP, TCP or SCTP protocols");
+			res = -1;
+			break;
+		}
+	}
+
+	if (fields || res != 0) {
+		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
+		if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", rss_conf.rss_hf) == 0) {
+			NT_LOG(ERR, FILTER, "RSS configuration%s is not supported for hash func %s.",
+				rss_buffer, (enum rte_eth_hash_function)toeplitz ?
+					"Toeplitz" : "NTH10");
+		} else {
+			NT_LOG(ERR, FILTER, "RSS configuration 0x%" PRIX64 " is not supported for hash func %s.",
+				rss_conf.rss_hf, (enum rte_eth_hash_function)toeplitz ?
+					"Toeplitz" : "NTH10");
+		}
+		return -1;
+	}
+
+	return res;
+}
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h
new file mode 100644
index 0000000000..38901b3e8a
--- /dev/null
+++ b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h
@@ -0,0 +1,17 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#ifndef _FLOW_HSH_CFG_H_
+#define _FLOW_HSH_CFG_H_
+
+#include <rte_ethdev.h>
+
+#include "hw_mod_backend.h"
+#include "flow_api.h"
+
+int hsh_set(struct flow_nic_dev *ndev, int hsh_idx,
+	struct nt_eth_rss_conf rss_conf);
+
+#endif /* _FLOW_HSH_CFG_H_ */
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
index ffab643f56..22cbf61b60 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
@@ -2,13 +2,14 @@
  * Copyright(c) 2023 Napatech A/S
  */
 
+#include "rte_common.h"
 
 #include "hw_mod_backend.h"
 #include "flow_api_engine.h"
 
 #include "flow_api_hw_db_inline.h"
 #include "flow_api_profile_inline_config.h"
-#include "rte_common.h"
+#include "flow_hsh_cfg.h"
 
 #define HW_DB_INLINE_ACTION_SET_NB 512
 #define HW_DB_INLINE_MATCH_SET_NB 512
@@ -2844,7 +2845,7 @@ struct hw_db_hsh_idx hw_db_inline_hsh_add(struct flow_nic_dev *ndev, void *db_ha
 	tmp_rss_conf.rss_hf = data->hash_mask;
 	memcpy(tmp_rss_conf.rss_key, data->key, MAX_RSS_KEY_LEN);
 	tmp_rss_conf.algorithm = data->func;
-	int res = flow_nic_set_hasher_fields(ndev, idx.ids, tmp_rss_conf);
+	int res = hsh_set(ndev, idx.ids, tmp_rss_conf);
 
 	if (res != 0) {
 		idx.error = 1;
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 574e51c2fa..e5abd372bc 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -20,6 +20,7 @@
 
 #include "flow_api_profile_inline.h"
 #include "ntnic_mod_reg.h"
+#include "flow_hsh_cfg.h"
 #include <rte_spinlock.h>
 #include <rte_common.h>
 
@@ -44,12 +45,6 @@
 #define NT_VIOLATING_MBR_CFN 0
 #define NT_VIOLATING_MBR_QSL 1
 
-#define RTE_ETH_RSS_UDP_COMBINED                                                                  \
-	(RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_IPV6_UDP_EX)
-
-#define RTE_ETH_RSS_TCP_COMBINED                                                                  \
-	(RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_IPV6_TCP_EX)
-
 #define NT_FLM_OP_UNLEARN 0
 #define NT_FLM_OP_LEARN 1
 
@@ -3809,116 +3804,6 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n
 	return NULL;
 }
 
-/*
- * FPGA uses up to 10 32-bit words (320 bits) for hash calculation + 8 bits for L4 protocol number.
- * Hashed data are split between two 128-bit Quad Words (QW)
- * and two 32-bit Words (W), which can refer to different header parts.
- */
-enum hsh_words_id {
-	HSH_WORDS_QW0 = 0,
-	HSH_WORDS_QW4,
-	HSH_WORDS_W8,
-	HSH_WORDS_W9,
-	HSH_WORDS_SIZE,
-};
-
-/* struct with details about hash QWs & Ws */
-struct hsh_words {
-	/*
-	 * index of W (word) or index of 1st word of QW (quad word)
-	 * is used for hash mask calculation
-	 */
-	uint8_t index;
-	enum hw_hsh_e pe;	/* offset to header part, e.g. beginning of L4 */
-	enum hw_hsh_e ofs;	/* relative offset in BYTES to 'pe' header offset above */
-	uint16_t bit_len;	/* max length of header part in bits to fit into QW/W */
-	bool free;	/* only free words can be used for hsh calculation */
-};
-
-static enum hsh_words_id get_free_word(struct hsh_words *words, uint16_t bit_len)
-{
-	enum hsh_words_id ret = HSH_WORDS_SIZE;
-	uint16_t ret_bit_len = UINT16_MAX;
-
-	for (enum hsh_words_id i = HSH_WORDS_QW0; i < HSH_WORDS_SIZE; i++) {
-		if (words[i].free && bit_len <= words[i].bit_len &&
-			words[i].bit_len < ret_bit_len) {
-			ret = i;
-			ret_bit_len = words[i].bit_len;
-		}
-	}
-
-	return ret;
-}
-
-static int flow_nic_set_hasher_part_inline(struct flow_nic_dev *ndev, int hsh_idx,
-	struct hsh_words *words, uint32_t pe, uint32_t ofs,
-	int bit_len, bool toeplitz)
-{
-	int res = 0;
-
-	/* check if there is any free word, which can accommodate header part of given 'bit_len' */
-	enum hsh_words_id word = get_free_word(words, bit_len);
-
-	if (word == HSH_WORDS_SIZE) {
-		NT_LOG(ERR, FILTER, "Cannot add additional %d bits into hash", bit_len);
-		return -1;
-	}
-
-	words[word].free = false;
-
-	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].pe, hsh_idx, 0, pe);
-	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].pe,
-		hsh_idx, pe);
-	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].ofs, hsh_idx, 0, ofs);
-	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].ofs,
-		hsh_idx, ofs);
-
-	/* set HW_HSH_RCP_WORD_MASK based on used QW/W and given 'bit_len' */
-	int mask_bit_len = bit_len;
-	uint32_t mask = 0x0;
-	uint32_t toeplitz_mask[9] = { 0x0 };
-	/* iterate through all words of QW */
-	uint16_t words_count = words[word].bit_len / 32;
-
-	for (uint16_t mask_off = 1; mask_off <= words_count; mask_off++) {
-		if (mask_bit_len >= 32) {
-			mask_bit_len -= 32;
-			mask = 0xffffffff;
-
-		} else if (mask_bit_len > 0) {
-			mask = 0xffffffff >> (32 - mask_bit_len) << (32 - mask_bit_len);
-			mask_bit_len = 0;
-
-		} else {
-			mask = 0x0;
-		}
-
-		/* reorder QW words mask from little to big endian */
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx,
-			words[word].index + words_count - mask_off, mask);
-		NT_LOG_DBGX(DBG, FILTER,
-			"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, %d, %d, 0x%08" PRIX32
-			")",
-			hsh_idx, words[word].index + words_count - mask_off, mask);
-		toeplitz_mask[words[word].index + mask_off - 1] = mask;
-	}
-
-	if (toeplitz) {
-		NT_LOG(DBG, FILTER,
-			"Partial Toeplitz RSS key mask: %08" PRIX32 " %08" PRIX32 " %08" PRIX32
-			" %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32
-			" %08" PRIX32 "",
-			toeplitz_mask[0], toeplitz_mask[1], toeplitz_mask[2], toeplitz_mask[3],
-			toeplitz_mask[4], toeplitz_mask[5], toeplitz_mask[6], toeplitz_mask[7],
-			toeplitz_mask[8]);
-		NT_LOG(DBG, FILTER,
-			"                               MSB                                                                          LSB");
-	}
-
-	return res;
-}
-
 /*
  * Public functions
  */
@@ -3982,8 +3867,16 @@ int initialize_flow_management_of_ndev_profile_inline(struct flow_nic_dev *ndev)
 
 		flow_nic_mark_resource_used(ndev, RES_PDB_RCP, 0);
 
-		/* Set default hasher recipe to 5-tuple */
-		flow_nic_set_hasher(ndev, 0, HASH_ALGO_5TUPLE);
+		/* Set default hasher recipe to 5-tuple:
+		 * RTE_ETH_RSS_IPV6 - enables hashing on both IPv4/IPv6 SA and DA
+		 * RTE_ETH_RSS_PORT - enables hashing on both L4 SP and DP and L4 protocol type
+		 */
+		struct nt_eth_rss_conf hsh_5_tuple = {
+			.rss_key = {},
+			.rss_hf = RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_PORT,
+			.algorithm = 0,
+		};
+		hsh_set(ndev, 0, hsh_5_tuple);
 		hw_mod_hsh_rcp_flush(&ndev->be, 0, 1);
 
 		flow_nic_mark_resource_used(ndev, RES_HSH_RCP, 0);
@@ -4580,658 +4473,6 @@ int flow_actions_update_profile_inline(struct flow_eth_dev *dev,
 	return -1;
 }
 
-static __rte_always_inline bool all_bits_enabled(uint64_t hash_mask, uint64_t hash_bits)
-{
-	return (hash_mask & hash_bits) == hash_bits;
-}
-
-static __rte_always_inline void unset_bits(uint64_t *hash_mask, uint64_t hash_bits)
-{
-	*hash_mask &= ~hash_bits;
-}
-
-static __rte_always_inline void unset_bits_and_log(uint64_t *hash_mask, uint64_t hash_bits)
-{
-	char rss_buffer[4096];
-	uint16_t rss_buffer_len = sizeof(rss_buffer);
-
-	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", *hash_mask & hash_bits) == 0)
-		NT_LOG(DBG, FILTER, "Configured RSS types:%s", rss_buffer);
-
-	unset_bits(hash_mask, hash_bits);
-}
-
-static __rte_always_inline void unset_bits_if_all_enabled(uint64_t *hash_mask, uint64_t hash_bits)
-{
-	if (all_bits_enabled(*hash_mask, hash_bits))
-		unset_bits(hash_mask, hash_bits);
-}
-
-int flow_nic_set_hasher_fields_inline(struct flow_nic_dev *ndev, int hsh_idx,
-	struct nt_eth_rss_conf rss_conf)
-{
-	uint64_t fields = rss_conf.rss_hf;
-
-	char rss_buffer[4096];
-	uint16_t rss_buffer_len = sizeof(rss_buffer);
-
-	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", fields) == 0)
-		NT_LOG(DBG, FILTER, "Requested RSS types:%s", rss_buffer);
-
-	/*
-	 * configure all (Q)Words usable for hash calculation
-	 * Hash can be calculated from 4 independent header parts:
-	 *      | QW0           | Qw4           | W8| W9|
-	 * word | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
-	 */
-	struct hsh_words words[HSH_WORDS_SIZE] = {
-		{ 0, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
-		{ 4, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
-		{ 8, HW_HSH_RCP_W8_PE, HW_HSH_RCP_W8_OFS, 32, true },
-		{
-			9, HW_HSH_RCP_W9_PE, HW_HSH_RCP_W9_OFS, 32,
-			true
-		},	/* not supported for Toeplitz */
-	};
-
-	int res = 0;
-	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
-	/* enable hashing */
-	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_LOAD_DIST_TYPE, hsh_idx, 0, 2);
-
-	/* configure selected hash function and its key */
-	bool toeplitz = false;
-
-	switch (rss_conf.algorithm) {
-	case RTE_ETH_HASH_FUNCTION_DEFAULT:
-		/* Use default NTH10 hashing algorithm */
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 0);
-		/* Use 1st 32-bits from rss_key to configure NTH10 SEED */
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_SEED, hsh_idx, 0,
-			rss_conf.rss_key[0] << 24 | rss_conf.rss_key[1] << 16 |
-			rss_conf.rss_key[2] << 8 | rss_conf.rss_key[3]);
-		break;
-
-	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
-		toeplitz = true;
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 1);
-		uint8_t empty_key = 0;
-
-		/* Toeplitz key (always 40B) words have to be programmed in reverse order */
-		for (uint8_t i = 0; i <= (MAX_RSS_KEY_LEN - 4); i += 4) {
-			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, hsh_idx, 9 - i / 4,
-					rss_conf.rss_key[i] << 24 |
-					rss_conf.rss_key[i + 1] << 16 |
-					rss_conf.rss_key[i + 2] << 8 |
-					rss_conf.rss_key[i + 3]);
-			NT_LOG_DBG(DBG, FILTER,
-				"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, %d, %d, 0x%" PRIX32
-				")",
-				hsh_idx, 9 - i / 4,
-				rss_conf.rss_key[i] << 24 | rss_conf.rss_key[i + 1] << 16 |
-				rss_conf.rss_key[i + 2] << 8 | rss_conf.rss_key[i + 3]);
-			empty_key |= rss_conf.rss_key[i] | rss_conf.rss_key[i + 1] |
-				rss_conf.rss_key[i + 2] | rss_conf.rss_key[i + 3];
-		}
-
-		if (empty_key == 0) {
-			NT_LOG(ERR, FILTER,
-				"Toeplitz key must be configured. Key with all bytes set to zero is not allowed.");
-			return -1;
-		}
-
-		words[HSH_WORDS_W9].free = false;
-		NT_LOG(DBG, FILTER,
-			"Toeplitz hashing is enabled thus W9 and P_MASK cannot be used.");
-		break;
-
-	default:
-		NT_LOG(ERR, FILTER, "Unknown hashing function %d requested", rss_conf.algorithm);
-		return -1;
-	}
-
-	/* indication that some IPv6 flag is present */
-	bool ipv6 = fields & (NT_ETH_RSS_IPV6_MASK);
-	/* store proto mask for later use at IP and L4 checksum handling */
-	uint64_t l4_proto_mask = fields &
-		(RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV4_UDP |
-		RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
-		RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
-		RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
-		RTE_ETH_RSS_IPV6_TCP_EX | RTE_ETH_RSS_IPV6_UDP_EX);
-
-	/* outermost headers are used by default, so innermost bit takes precedence if detected */
-	bool outer = (fields & RTE_ETH_RSS_LEVEL_INNERMOST) ? false : true;
-	unset_bits(&fields, RTE_ETH_RSS_LEVEL_MASK);
-
-	if (fields == 0) {
-		NT_LOG(ERR, FILTER, "RSS hash configuration 0x%" PRIX64 " is not valid.",
-			rss_conf.rss_hf);
-		return -1;
-	}
-
-	/* indication that IPv4 `protocol` or IPv6 `next header` fields shall be part of the hash
-	 */
-	bool l4_proto_hash = false;
-
-	/*
-	 * check if SRC_ONLY & DST_ONLY are used simultaneously;
-	 * According to DPDK, we shall behave like none of these bits is set
-	 */
-	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY);
-	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY);
-	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY);
-
-	/* L2 */
-	if (fields & (RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY)) {
-		if (outer) {
-			if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer src MAC hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L2, 6, 48, toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer dst MAC hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L2, 0, 48, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set outer src & dst MAC hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L2, 0, 96, toeplitz);
-			}
-
-		} else if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner src MAC hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L2, 6,
-				48, toeplitz);
-
-		} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner dst MAC hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L2, 0,
-				48, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner src & dst MAC hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L2, 0,
-				96, toeplitz);
-		}
-
-		unset_bits_and_log(&fields,
-			RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY |
-			RTE_ETH_RSS_L2_DST_ONLY);
-	}
-
-	/*
-	 * VLAN support of multiple VLAN headers,
-	 * where S-VLAN is the first and C-VLAN the last VLAN header
-	 */
-	if (fields & RTE_ETH_RSS_C_VLAN) {
-		/*
-		 * use MPLS protocol offset, which points just after ethertype with relative
-		 * offset -6 (i.e. 2 bytes
-		 * of ethertype & size + 4 bytes of VLAN header field) to access last vlan header
-		 */
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer C-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_MPLS, -6,
-				32, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner C-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_MPLS,
-				-6, 32, toeplitz);
-		}
-
-		unset_bits_and_log(&fields, RTE_ETH_RSS_C_VLAN);
-	}
-
-	if (fields & RTE_ETH_RSS_S_VLAN) {
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer S-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-				DYN_FIRST_VLAN, 0, 32, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner S-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_VLAN,
-				0, 32, toeplitz);
-		}
-
-		unset_bits_and_log(&fields, RTE_ETH_RSS_S_VLAN);
-	}
-	/* L2 payload */
-	/* calculate hash of 128-bits of l2 payload; Use MPLS protocol offset to address the
-	 * beginning of L2 payload even if MPLS header is not present
-	 */
-	if (fields & RTE_ETH_RSS_L2_PAYLOAD) {
-		uint64_t outer_fields_enabled = 0;
-
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer L2 payload hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_MPLS, 0,
-				128, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner L2 payload hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_MPLS,
-				0, 128, toeplitz);
-			outer_fields_enabled = fields & RTE_ETH_RSS_GTPU;
-		}
-
-		/*
-		 * L2 PAYLOAD hashing overrides all L3 & L4 RSS flags.
-		 * Thus we can clear all remaining (supported)
-		 * RSS flags...
-		 */
-		unset_bits_and_log(&fields, NT_ETH_RSS_OFFLOAD_MASK);
-		/*
-		 * ...but in case of INNER L2 PAYLOAD we must process
-		 * "always outer" GTPU field if enabled
-		 */
-		fields |= outer_fields_enabled;
-	}
-
-	/* L3 + L4 protocol number */
-	if (fields & RTE_ETH_RSS_IPV4_CHKSUM) {
-		/* only IPv4 checksum is supported by DPDK RTE_ETH_RSS_* types */
-		if (ipv6) {
-			NT_LOG(ERR, FILTER,
-				"RSS: IPv4 checksum requested with IPv6 header hashing!");
-			res = 1;
-
-		} else if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer IPv4 checksum hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_L3, 10,
-				16, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner IPv4 checksum hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L3,
-				10, 16, toeplitz);
-		}
-
-		/*
-		 * L3 checksum is made from whole L3 header, i.e. no need to process other
-		 * L3 hashing flags
-		 */
-		unset_bits_and_log(&fields, RTE_ETH_RSS_IPV4_CHKSUM | NT_ETH_RSS_IP_MASK);
-	}
-
-	if (fields & NT_ETH_RSS_IP_MASK) {
-		if (ipv6) {
-			if (outer) {
-				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 src hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST,
-						-16, 128, toeplitz);
-
-				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 dst hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST, 0,
-						128, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER,
-						"Set outer IPv6/IPv4 src & dst hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST,
-						-16, 128, toeplitz);
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST, 0,
-						128, toeplitz);
-				}
-
-			} else if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, -16,
-					128, toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, 0,
-					128, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src & dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, -16,
-					128, toeplitz);
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, 0,
-					128, toeplitz);
-			}
-
-			/* check if fragment ID shall be part of hash */
-			if (fields & (RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6)) {
-				if (outer) {
-					NT_LOG(DBG, FILTER,
-						"Set outer IPv6/IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_ID_IPV4_6, 0,
-						32, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER,
-						"Set inner IPv6/IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_TUN_ID_IPV4_6,
-						0, 32, toeplitz);
-				}
-			}
-
-			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_AUTO_IPV4_MASK, hsh_idx, 0,
-				1);
-
-		} else {
-			/* IPv4 */
-			if (outer) {
-				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv4 src only hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 12,
-						32, toeplitz);
-
-				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv4 dst only hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 16,
-						32, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER, "Set outer IPv4 src & dst hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 12,
-						64, toeplitz);
-				}
-
-			} else if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv4 src only hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L3, 12, 32,
-					toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv4 dst only hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L3, 16, 32,
-					toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner IPv4 src & dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L3, 12, 64,
-					toeplitz);
-			}
-
-			/* check if fragment ID shall be part of hash */
-			if (fields & RTE_ETH_RSS_FRAG_IPV4) {
-				if (outer) {
-					NT_LOG(DBG, FILTER,
-						"Set outer IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_ID_IPV4_6, 0,
-						16, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER,
-						"Set inner IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_TUN_ID_IPV4_6,
-						0, 16, toeplitz);
-				}
-			}
-		}
-
-		/* check if L4 protocol type shall be part of hash */
-		if (l4_proto_mask)
-			l4_proto_hash = true;
-
-		unset_bits_and_log(&fields, NT_ETH_RSS_IP_MASK);
-	}
-
-	/* L4 */
-	if (fields & (RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY)) {
-		if (outer) {
-			if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer L4 src hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 0, 16, toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer L4 dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 2, 16, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set outer L4 src & dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 0, 32, toeplitz);
-			}
-
-		} else if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner L4 src hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L4, 0,
-				16, toeplitz);
-
-		} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner L4 dst hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L4, 2,
-				16, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner L4 src & dst hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L4, 0,
-				32, toeplitz);
-		}
-
-		l4_proto_hash = true;
-		unset_bits_and_log(&fields,
-			RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY |
-			RTE_ETH_RSS_L4_DST_ONLY);
-	}
-
-	/* IPv4 protocol / IPv6 next header fields */
-	if (l4_proto_hash) {
-		/* NOTE: HW_HSH_RCP_P_MASK is not supported for Toeplitz and thus one of SW0, SW4
-		 * or W8 must be used to hash on `protocol` field of IPv4 or `next header` field of
-		 * IPv6 header.
-		 */
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer L4 protocol type / next header hasher.");
-
-			if (toeplitz) {
-				if (ipv6) {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 6, 8,
-						toeplitz);
-
-				} else {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 9, 8,
-						toeplitz);
-				}
-
-			} else {
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK, hsh_idx, 0,
-					1);
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TNL_P, hsh_idx, 0,
-					0);
-			}
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner L4 protocol type / next header hasher.");
-
-			if (toeplitz) {
-				if (ipv6) {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_TUN_L3,
-						6, 8, toeplitz);
-
-				} else {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_TUN_L3,
-						9, 8, toeplitz);
-				}
-
-			} else {
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK, hsh_idx, 0,
-					1);
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TNL_P, hsh_idx, 0,
-					1);
-			}
-		}
-
-		l4_proto_hash = false;
-	}
-
-	/*
-	 * GTPU - for UPF use cases we always use TEID from outermost GTPU header
-	 * even if other headers are innermost
-	 */
-	if (fields & RTE_ETH_RSS_GTPU) {
-		NT_LOG(DBG, FILTER, "Set outer GTPU TEID hasher.");
-		res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_L4_PAYLOAD, 4, 32,
-			toeplitz);
-		unset_bits_and_log(&fields, RTE_ETH_RSS_GTPU);
-	}
-
-	/* Checksums */
-	/* only UDP, TCP and SCTP checksums are supported */
-	if (fields & RTE_ETH_RSS_L4_CHKSUM) {
-		switch (l4_proto_mask) {
-		case RTE_ETH_RSS_NONFRAG_IPV4_UDP:
-		case RTE_ETH_RSS_NONFRAG_IPV6_UDP:
-		case RTE_ETH_RSS_IPV6_UDP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP:
-		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
-		case RTE_ETH_RSS_UDP_COMBINED:
-			if (outer) {
-				NT_LOG(DBG, FILTER, "Set outer UDP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 6, 16, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner UDP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L4, 6, 16,
-					toeplitz);
-			}
-
-			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
-			break;
-
-		case RTE_ETH_RSS_NONFRAG_IPV4_TCP:
-		case RTE_ETH_RSS_NONFRAG_IPV6_TCP:
-		case RTE_ETH_RSS_IPV6_TCP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP:
-		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
-		case RTE_ETH_RSS_TCP_COMBINED:
-			if (outer) {
-				NT_LOG(DBG, FILTER, "Set outer TCP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 16, 16, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner TCP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L4, 16, 16,
-					toeplitz);
-			}
-
-			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
-			break;
-
-		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP:
-		case RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
-		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
-			if (outer) {
-				NT_LOG(DBG, FILTER, "Set outer SCTP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 8, 32, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner SCTP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L4, 8, 32,
-					toeplitz);
-			}
-
-			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
-			break;
-
-		case RTE_ETH_RSS_NONFRAG_IPV4_OTHER:
-		case RTE_ETH_RSS_NONFRAG_IPV6_OTHER:
-
-		/* none or unsupported protocol was chosen */
-		case 0:
-			NT_LOG(ERR, FILTER,
-				"L4 checksum hashing is supported only for UDP, TCP and SCTP protocols");
-			res = -1;
-			break;
-
-		/* multiple L4 protocols were selected */
-		default:
-			NT_LOG(ERR, FILTER,
-				"L4 checksum hashing can be enabled just for one of UDP, TCP or SCTP protocols");
-			res = -1;
-			break;
-		}
-	}
-
-	if (fields || res != 0) {
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
-
-		if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", rss_conf.rss_hf) == 0) {
-			NT_LOG(ERR, FILTER,
-				"RSS configuration%s is not supported for hash func %s.",
-				rss_buffer,
-				(enum rte_eth_hash_function)toeplitz ? "Toeplitz" : "NTH10");
-
-		} else {
-			NT_LOG(ERR, FILTER,
-				"RSS configuration 0x%" PRIX64
-				" is not supported for hash func %s.",
-				rss_conf.rss_hf,
-				(enum rte_eth_hash_function)toeplitz ? "Toeplitz" : "NTH10");
-		}
-
-		return -1;
-	}
-
-	return res;
-}
-
 static void dump_flm_data(const uint32_t *data, FILE *file)
 {
 	for (unsigned int i = 0; i < 10; ++i) {
@@ -6020,7 +5261,6 @@ static const struct profile_inline_ops ops = {
 	.flow_destroy_profile_inline = flow_destroy_profile_inline,
 	.flow_flush_profile_inline = flow_flush_profile_inline,
 	.flow_actions_update_profile_inline = flow_actions_update_profile_inline,
-	.flow_nic_set_hasher_fields_inline = flow_nic_set_hasher_fields_inline,
 	.flow_get_aged_flows_profile_inline = flow_get_aged_flows_profile_inline,
 	/*
 	 * Stats
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
index 169f71ee68..be22c9bcd1 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
@@ -66,10 +66,6 @@ int flow_get_aged_flows_profile_inline(struct flow_eth_dev *dev,
 	uint32_t nb_contexts,
 	struct rte_flow_error *error);
 
-int flow_nic_set_hasher_fields_inline(struct flow_nic_dev *ndev,
-	int hsh_idx,
-	struct nt_eth_rss_conf rss_conf);
-
 /*
  * Stats
  */
diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index d1360cc925..9000264804 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -27,6 +27,7 @@
 #include "ntnic_vfio.h"
 #include "ntnic_mod_reg.h"
 #include "nt_util.h"
+#include "flow_hsh_cfg.h"
 #include "profile_inline/flm_age_queue.h"
 #include "profile_inline/flm_evt_queue.h"
 #include "rte_pmd_ntnic.h"
@@ -1672,7 +1673,7 @@ static int eth_dev_rss_hash_update(struct rte_eth_dev *eth_dev, struct rte_eth_r
 	tmp_rss_conf.algorithm = rss_conf->algorithm;
 
 	tmp_rss_conf.rss_hf = rss_conf->rss_hf;
-	int res = flow_filter_ops->flow_nic_set_hasher_fields(ndev, hsh_idx, tmp_rss_conf);
+	int res = hsh_set(ndev, hsh_idx, tmp_rss_conf);
 
 	if (res == 0) {
 		flow_filter_ops->hw_mod_hsh_rcp_flush(&ndev->be, hsh_idx, 1);
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index 71861c6dea..8db4911262 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -355,10 +355,6 @@ struct profile_inline_ops {
 		struct flow_handle *flow, void *user_data,
 		struct rte_flow_error *error);
 
-	int (*flow_nic_set_hasher_fields_inline)(struct flow_nic_dev *ndev,
-		int hsh_idx,
-		struct nt_eth_rss_conf rss_conf);
-
 	/*
 	 * Stats
 	 */
@@ -467,8 +463,6 @@ struct flow_filter_ops {
 	/*
 	 * Other
 	 */
-	int (*flow_nic_set_hasher_fields)(struct flow_nic_dev *ndev, int hsh_idx,
-		struct nt_eth_rss_conf rss_conf);
 	int (*hw_mod_hsh_rcp_flush)(struct flow_api_backend_s *be, int start_idx, int count);
 
 	int (*flow_get_aged_flows)(struct flow_eth_dev *dev,
-- 
2.45.0


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

* [PATCH v1 26/31] net/ntnic: fix age timeout recalculation into fpga unit
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (24 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 25/31] net/ntnic: refactor RSS implementation Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 27/31] net/ntnic: rework age event generation Serhii Iliushyk
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

The FPGA scrub T parameter shall be encoded timeout using internal unit,
which is measured in 2^30 nanoseconds. It is approx 1.074 times longer
than age timeout specified in seconds. Internal method
hw_mod_flm_inf_sta_data_update_get() was updated to perform conversion
between age time and internal FPGA scrub T time unit.

Fixes: c0d44442b831 ("net/ntnic: add flow aging event")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c    | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c
index 14dd95a150..5cf8264909 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c
@@ -969,16 +969,22 @@ int hw_mod_flm_inf_sta_data_update_get(struct flow_api_backend_s *be, enum hw_fl
  *
  * (T[7:3] != 0) ? ((8 + T[2:0]) shift-left (T[7:3] - 1)) : T[2:0]
  *
- * The maximum allowed value is 0xEF (127 years).
+ * The maximum allowed value is 0xEF (137 years).
  *
  * Note that this represents a lower bound on the timeout, depending on the flow
  * scanner interval and overall load, the timeout can be substantially longer.
  */
 uint32_t hw_mod_flm_scrub_timeout_decode(uint32_t t_enc)
 {
-	uint8_t t_bits_2_0 = t_enc & 0x07;
-	uint8_t t_bits_7_3 = (t_enc >> 3) & 0x1F;
-	return t_bits_7_3 != 0 ? ((8 + t_bits_2_0) << (t_bits_7_3 - 1)) : t_bits_2_0;
+	uint32_t t_bits_2_0 = t_enc & 0x07;
+	uint32_t t_bits_7_3 = (t_enc >> 3) & 0x1F;
+	uint32_t t_dec = t_bits_7_3 != 0 ? ((8U + t_bits_2_0) << (t_bits_7_3 - 1U))
+		: t_bits_2_0;
+	/* convert internal FPGA scrub time unit into seconds, i.e. 2^30/1e9 is
+	 * approx 1.074 sec per internal unit
+	 */
+	uint64_t t_sec = (uint64_t)t_dec * 1074UL / 1000UL;
+	return t_sec > UINT32_MAX ? UINT32_MAX : (uint32_t)t_sec;
 }
 
 uint32_t hw_mod_flm_scrub_timeout_encode(uint32_t t)
-- 
2.45.0


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

* [PATCH v1 27/31] net/ntnic: rework age event generation
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (25 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 26/31] net/ntnic: fix age timeout recalculation into fpga unit Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 28/31] net/ntnic: fix group print Serhii Iliushyk
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Add age event generating only for physical ports.

Fixes: 4033e0539435 ("net/ntnic: add flow meter")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index e5abd372bc..e911860c38 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -479,13 +479,16 @@ static void flm_mtr_read_inf_records(struct flow_eth_dev *dev, uint32_t *data, u
 				struct flow_handle *fh = (struct flow_handle *)flm_h.p;
 				struct flm_age_event_s age_event;
 				uint8_t port;
+				bool is_remote;
 
 				age_event.context = fh->context;
 
-				is_remote_caller(caller_id, &port);
+				is_remote = is_remote_caller(caller_id, &port);
 
 				flm_age_queue_put(caller_id, &age_event);
-				flm_age_event_set(port);
+				/* age events are supported only for physical ports */
+				if (!is_remote)
+					flm_age_event_set(port);
 			}
 			break;
 
-- 
2.45.0


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

* [PATCH v1 28/31] net/ntnic: fix group print
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (26 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 27/31] net/ntnic: rework age event generation Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 29/31] net/ntnic: extend module mapping Serhii Iliushyk
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

Flow dump output was fixed to show original group
number for `jumps` stored in action and match sets.

Fixes: 6f0fe142caed ("net/ntnic: add flow dump")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api_engine.h   |  2 ++
 drivers/net/ntnic/nthw/flow_api/flow_group.c  | 26 +++++++++++++++++++
 .../profile_inline/flow_api_hw_db_inline.c    | 24 ++++++++++++-----
 3 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h
index 636c53b260..262317002f 100644
--- a/drivers/net/ntnic/include/flow_api_engine.h
+++ b/drivers/net/ntnic/include/flow_api_engine.h
@@ -425,5 +425,7 @@ int flow_group_handle_destroy(void **handle);
 
 int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, uint32_t group_in,
 	uint32_t *group_out);
+int flow_group_translate_get_orig_group(void *handle, uint32_t translated_group,
+	uint32_t *group_orig);
 
 #endif  /* _FLOW_API_ENGINE_H_ */
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_group.c b/drivers/net/ntnic/nthw/flow_api/flow_group.c
index f76986b178..d1fa0193e1 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_group.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_group.c
@@ -14,6 +14,7 @@
 struct group_lookup_entry_s {
 	uint64_t ref_counter;
 	uint32_t *reverse_lookup;
+	uint32_t group_orig;
 };
 
 struct group_handle_s {
@@ -83,6 +84,7 @@ int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, ui
 		if (lookup < group_handle->group_count) {
 			group_handle->lookup_entries[lookup].reverse_lookup = table_ptr;
 			group_handle->lookup_entries[lookup].ref_counter += 1;
+			group_handle->lookup_entries[lookup].group_orig = group_in;
 
 			*table_ptr = lookup;
 
@@ -97,3 +99,27 @@ int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, ui
 	*group_out = lookup;
 	return 0;
 }
+
+int flow_group_translate_get_orig_group(void *handle, uint32_t translated_group,
+	uint32_t *group_orig)
+{
+	struct group_handle_s *group_handle = (struct group_handle_s *)handle;
+	struct group_lookup_entry_s *lookup;
+
+	if (group_handle == NULL || translated_group >= group_handle->group_count)
+		return -1;
+
+	/* Don't translate group 0 */
+	if (translated_group == 0) {
+		*group_orig = 0;
+		return 0;
+	}
+
+	lookup = &group_handle->lookup_entries[translated_group];
+
+	if (lookup->reverse_lookup && lookup->ref_counter > 0) {
+		*group_orig = lookup->group_orig;
+		return 0;
+	}
+	return -1;
+}
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
index 22cbf61b60..278be8b180 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
@@ -429,9 +429,14 @@ void hw_db_inline_dump(struct flow_nic_dev *ndev, void *db_handle, const struct
 				data->cat.ids, data->km.id1, data->km_ft.id1,
 				data->action_set.ids);
 
-			if (data->jump)
-				fprintf(file, "    Jumps to %d\n", data->jump);
-
+			if (data->jump) {
+				uint32_t group_orig = 0;
+				if (flow_group_translate_get_orig_group(ndev->group_handle,
+					data->jump, &group_orig) < 0)
+					fprintf(file, "    Jumps to %d (encoded)\n", data->jump);
+				else
+					fprintf(file, "    Jumps to %d\n", group_orig);
+			}
 			break;
 		}
 
@@ -440,15 +445,20 @@ void hw_db_inline_dump(struct flow_nic_dev *ndev, void *db_handle, const struct
 					&db->action_set[idxs[i].ids].data;
 			fprintf(file, "  ACTION_SET %d\n", idxs[i].ids);
 
-			if (data->contains_jump)
-				fprintf(file, "    Jumps to %d\n", data->jump);
+			if (data->contains_jump) {
+				uint32_t group_orig = 0;
+				if (flow_group_translate_get_orig_group(ndev->group_handle,
+					data->jump, &group_orig) < 0)
+					fprintf(file, "    Jumps to %d (encoded)\n", data->jump);
 
-			else
+				else
+					fprintf(file, "    Jumps to %d\n", group_orig);
+			} else {
 				fprintf(file,
 					"    COT id %d, QSL id %d, SLC_LR id %d, TPE id %d, HSH id %d, SCRUB id %d\n",
 					data->cot.ids, data->qsl.ids, data->slc_lr.ids,
 					data->tpe.ids, data->hsh.ids, data->scrub.ids);
-
+			}
 			break;
 		}
 
-- 
2.45.0


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

* [PATCH v1 29/31] net/ntnic: extend module mapping
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (27 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 28/31] net/ntnic: fix group print Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 30/31] net/ntnic: refactoring of the FPGA initialization Serhii Iliushyk
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

FPGA module mapping(to string) was extended with new fpga's modules.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../nthw/supported/nthw_fpga_mod_str_map.c    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
index e8ed7faf0d..459cc724c2 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
@@ -6,20 +6,44 @@
 
 #include "nthw_fpga_mod_str_map.h"
 const struct nthw_fpga_mod_str_s sa_nthw_fpga_mod_str_map[] = {
+	{ MOD_CAT, "CAT" },
+	{ MOD_CPY, "CPY" },
+	{ MOD_CSU, "CSU" },
+	{ MOD_DBS, "DBS" },
+	{ MOD_FLM, "FLM" },
 	{ MOD_GFG, "GFG" },
 	{ MOD_GMF, "GMF" },
 	{ MOD_GPIO_PHY, "GPIO_PHY" },
+	{ MOD_HFU, "HFU" },
 	{ MOD_HIF, "HIF" },
+	{ MOD_HSH, "HSH" },
 	{ MOD_I2CM, "I2CM" },
+	{ MOD_IFR, "IFR" },
 	{ MOD_IIC, "IIC" },
+	{ MOD_INS, "INS" },
+	{ MOD_KM, "KM" },
 	{ MOD_MAC_PCS, "MAC_PCS" },
 	{ MOD_PCIE3, "PCIE3" },
+	{ MOD_MAC_RX, "MAC_RX" },
+	{ MOD_MAC_TX, "MAC_TX" },
 	{ MOD_PCI_RD_TG, "PCI_RD_TG" },
 	{ MOD_PCI_WR_TG, "PCI_WR_TG" },
+	{ MOD_PCIE3, "PCIE3" },
+	{ MOD_PDB, "PDB" },
+	{ MOD_QSL, "QSL" },
 	{ MOD_RAC, "RAC" },
+	{ MOD_RMC, "RMC" },
+	{ MOD_RPF, "RPF" },
+	{ MOD_RPL, "RPL" },
+	{ MOD_RPP_LR, "RPP_LR" },
 	{ MOD_RST9563, "RST9563" },
 	{ MOD_SDC, "SDC" },
+	{ MOD_SLC_LR, "SLC_LR" },
+	{ MOD_SLC, "SLC" },
 	{ MOD_STA, "STA" },
 	{ MOD_TSM, "TSM" },
+	{ MOD_TX_CPY, "TX_CPY" },
+	{ MOD_TX_INS, "TX_INS" },
+	{ MOD_TX_RPL, "TX_RPL" },
 	{ 0UL, NULL }
 };
-- 
2.45.0


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

* [PATCH v1 30/31] net/ntnic: refactoring of the FPGA initialization
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (28 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 29/31] net/ntnic: extend module mapping Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-21 17:08 ` [PATCH v1 31/31] net/ntnic: remove tag EXPERIMENTAL Serhii Iliushyk
  2025-01-28 18:51 ` [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Stephen Hemminger
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Remove unnecessary checks and logs.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/nthw/core/nthw_fpga.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/net/ntnic/nthw/core/nthw_fpga.c b/drivers/net/ntnic/nthw/core/nthw_fpga.c
index 88641145ec..5ca186209a 100644
--- a/drivers/net/ntnic/nthw/core/nthw_fpga.c
+++ b/drivers/net/ntnic/nthw/core/nthw_fpga.c
@@ -265,18 +265,14 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 	nthw_rac_rab_flush(p_nthw_rac);
 	p_fpga_info->mp_nthw_rac = p_nthw_rac;
 
-	bool included = true;
 	struct nt200a0x_ops *nt200a0x_ops = get_nt200a0x_ops();
 
 	switch (p_fpga_info->n_nthw_adapter_id) {
 	case NT_HW_ADAPTER_ID_NT200A02:
 		if (nt200a0x_ops != NULL)
 			res = nt200a0x_ops->nthw_fpga_nt200a0x_init(p_fpga_info);
-
-		else
-			included = false;
-
 		break;
+
 	default:
 		NT_LOG(ERR, NTHW, "%s: Unsupported HW product id: %d", p_adapter_id_str,
 			p_fpga_info->n_nthw_adapter_id);
@@ -284,12 +280,6 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 		break;
 	}
 
-	if (!included) {
-		NT_LOG(ERR, NTHW, "%s: NOT INCLUDED HW product: %d", p_adapter_id_str,
-			p_fpga_info->n_nthw_adapter_id);
-		res = -1;
-	}
-
 	if (res) {
 		NT_LOG(ERR, NTHW, "%s: status: 0x%08X", p_adapter_id_str, res);
 		return res;
-- 
2.45.0


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

* [PATCH v1 31/31] net/ntnic: remove tag EXPERIMENTAL
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (29 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 30/31] net/ntnic: refactoring of the FPGA initialization Serhii Iliushyk
@ 2025-01-21 17:08 ` Serhii Iliushyk
  2025-01-28 18:51 ` [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Stephen Hemminger
  31 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-01-21 17:08 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Thomas Monjalon

Since nitnic PMD driver for is fully added and verified,
the tag EXPERIMENTAL may be removed

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index b86cdd266b..b04951de85 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -890,7 +890,7 @@ F: drivers/net/octeon_ep/
 F: doc/guides/nics/features/octeon_ep.ini
 F: doc/guides/nics/octeon_ep.rst
 
-Napatech ntnic - EXPERIMENTAL
+Napatech ntnic
 M: Christian Koue Muf <ckm@napatech.com>
 M: Serhii Iliushyk <sil-plv@napatech.com>
 F: drivers/net/ntnic/
-- 
2.45.0


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

* Re: [PATCH v1 02/31] net/ntnic: add thread check return code
  2025-01-21 17:07 ` [PATCH v1 02/31] net/ntnic: add thread check return code Serhii Iliushyk
@ 2025-01-21 18:24   ` Stephen Hemminger
  2025-01-28 18:54   ` Stephen Hemminger
  1 sibling, 0 replies; 72+ messages in thread
From: Stephen Hemminger @ 2025-01-21 18:24 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm, Danylo Vodopianov

On Tue, 21 Jan 2025 18:07:40 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> From: Danylo Vodopianov <dvo-plv@napatech.com>
> 
> CI found couple coverity problems which were fixed in this commit.
> 
> CID: 448965 Error handling issues (CHECKED_RETURN).
> 
> Thread return code check was added.
> 
> Coverity issue: 448965
> Fixes: a1ba8c473f5c ("net/ntnic: add statistics poll")
> 
> Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
> ---
>  drivers/net/ntnic/ntnic_ethdev.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
> index 2a2643a106..620d023a71 100644
> --- a/drivers/net/ntnic/ntnic_ethdev.c
> +++ b/drivers/net/ntnic/ntnic_ethdev.c
> @@ -2516,8 +2516,11 @@ static int init_shutdown(void)
>  	NT_LOG(DBG, NTNIC, "Starting shutdown handler");
>  	kill_pmd = 0;
>  	previous_handler = signal(SIGINT, signal_handler_func_int);
> -	THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
> -
> +	int ret = THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
> +	if (ret != 0) {
> +		NT_LOG(ERR, NTNIC, "Failed to create shutdown thread, error code: %d", ret);
> +		return -1;
> +	}
>  	/*
>  	 * 1 time calculation of 1 sec stat update rtc cycles to prevent stat poll
>  	 * flooding by OVS from multiple virtual port threads - no need to be precise
> -- 

The whole thread, SIGINT stuff is a big mistake.
You are making all sorts of assumptions about application environment
such as SIGINT won't be used by other things, drivers creating internal threads
is a bad idea.

Also access to the flag kill_pmd is not being done in a thread safe manner.

What is it really trying to do?

IMHO, The driver should have never been merged with this stuff.



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

* Re: [PATCH v1 03/31] net/ntnic: add return code handling
  2025-01-21 17:07 ` [PATCH v1 03/31] net/ntnic: add return code handling Serhii Iliushyk
@ 2025-01-21 18:30   ` Stephen Hemminger
  0 siblings, 0 replies; 72+ messages in thread
From: Stephen Hemminger @ 2025-01-21 18:30 UTC (permalink / raw)
  To: Serhii Iliushyk
  Cc: dev, mko-plv, ckm, Danylo Vodopianov, Oleksandr Kolomeiets

On Tue, 21 Jan 2025 18:07:41 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> From: Danylo Vodopianov <dvo-plv@napatech.com>
> 
> CI found couple coverity problems which were fixed in this commit.
> 
> CID: 448984, 448982, 448975, 448969, 448968, 448967
> API usage errors  (BAD_COMPARE).
> 
> Add memcmp return value checking.
> 
> Coverity issue: 448984
> Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")
> 
> Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
> ---
>  drivers/net/ntnic/include/hw_mod_backend.h | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
> index f91a3ed058..40002f3343 100644
> --- a/drivers/net/ntnic/include/hw_mod_backend.h
> +++ b/drivers/net/ntnic/include/hw_mod_backend.h
> @@ -114,10 +114,10 @@ enum {
>  		typeof(be_module_reg) *temp_be_module = &(be_module_reg);                     \
>  		typeof(idx) tmp_idx = (idx);                                                  \
>  		typeof(cmp_idx) tmp_cmp_idx = (cmp_idx);                                      \
> -		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx)) {                     \
> -			(void)memcmp(temp_be_module + tmp_idx, &temp_be_module[tmp_cmp_idx],      \
> -				     sizeof(type));                                               \
> -		}                                                                                 \
> +		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx))                     \
> +			if (memcmp(temp_be_module + tmp_idx, &temp_be_module[tmp_cmp_idx], \
> +				sizeof(type)) == 0) \
> +				return 1;                                              \
>  	} while (0)
>  

Complex generic macros like this are brittle.
Adding a return in the middle of a loop means it will do unexpected exit of function??

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

* Re: [PATCH v1 00/31] net/ntnic: bugfixes and refactoring
  2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                   ` (30 preceding siblings ...)
  2025-01-21 17:08 ` [PATCH v1 31/31] net/ntnic: remove tag EXPERIMENTAL Serhii Iliushyk
@ 2025-01-28 18:51 ` Stephen Hemminger
  31 siblings, 0 replies; 72+ messages in thread
From: Stephen Hemminger @ 2025-01-28 18:51 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm

On Tue, 21 Jan 2025 18:07:38 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> These patches include fixes for issues detected by the Coverity Scan tool and internal tests.
> 
> Danylo Vodopianov (26):
>   net/ntnic: fix index verification
>   net/ntnic: add thread check return code
>   net/ntnic: add return code handling
>   net/ntnic: add array index verification
>   net/ntnic: fix realloc memory leak
>   net/ntnic: fix array index verification
>   net/ntnic: add var definition transparently
>   net/ntnic: add proper var freed
>   net/ntnic: remove deadcode
>   net/ntnic: fix potentially overflow
>   net/ntnic: add null checking
>   net/ntnic: fix overflow issue
>   net/ntnic: fix untrusted loop bound
>   net/ntnic: add null checking
>   net/ntnic: move null checking
>   net/ntnic: fix var size
>   net/ntnic: fix var overflow
>   net/ntnic: remove dead code
>   net/ntnic: remove convert error func
>   net/ntnic: fix array verification
>   net/ntnic: fix memory leak
>   net/ntnic: remove unused code
>   net/ntnic: refactor RSS implementation
>   net/ntnic: fix age timeout recalculation into fpga unit
>   net/ntnic: rework age event generation
>   net/ntnic: fix group print
> 
> Oleksandr Kolomeiets (2):
>   net/ntnic: remove extra address-of operator
>   net/ntnic: remove extra check for null
> 
> Serhii Iliushyk (3):
>   net/ntnic: extend module mapping
>   net/ntnic: refactoring of the FPGA initialization
>   net/ntnic: remove tag EXPERIMENTAL
> 
>  MAINTAINERS                                   |   2 +-
>  .../net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c |   9 -
>  drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c |  10 +-
>  drivers/net/ntnic/include/create_elements.h   |   1 -
>  drivers/net/ntnic/include/flow_api.h          |   9 -
>  drivers/net/ntnic/include/flow_api_engine.h   |   2 +
>  drivers/net/ntnic/include/hw_mod_backend.h    |  16 +-
>  .../link_mgmt/link_100g/nt4ga_link_100g.c     |   2 +-
>  drivers/net/ntnic/meson.build                 |   1 +
>  drivers/net/ntnic/nthw/core/nthw_fpga.c       |  14 +-
>  drivers/net/ntnic/nthw/flow_api/flow_api.c    |  67 +-
>  drivers/net/ntnic/nthw/flow_api/flow_group.c  |  26 +
>  .../net/ntnic/nthw/flow_api/flow_hsh_cfg.c    | 661 ++++++++++++++
>  .../net/ntnic/nthw/flow_api/flow_hsh_cfg.h    |  17 +
>  .../ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c   |  14 +-
>  .../ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c   |  19 +-
>  .../ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c   |  18 +-
>  .../profile_inline/flow_api_hw_db_inline.c    |  29 +-
>  .../profile_inline/flow_api_profile_inline.c  | 817 +-----------------
>  .../profile_inline/flow_api_profile_inline.h  |   4 -
>  .../ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c |  10 +-
>  .../nthw/supported/nthw_fpga_mod_str_map.c    |  24 +
>  drivers/net/ntnic/ntnic_ethdev.c              |  16 +-
>  drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 155 ++--
>  drivers/net/ntnic/ntnic_mod_reg.h             |   6 -
>  drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c |  10 +-
>  26 files changed, 915 insertions(+), 1044 deletions(-)
>  create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
>  create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h
> 


I assume that since driver was experimental, there is no point in backporting
any of this to stable.

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

* Re: [PATCH v1 02/31] net/ntnic: add thread check return code
  2025-01-21 17:07 ` [PATCH v1 02/31] net/ntnic: add thread check return code Serhii Iliushyk
  2025-01-21 18:24   ` Stephen Hemminger
@ 2025-01-28 18:54   ` Stephen Hemminger
  1 sibling, 0 replies; 72+ messages in thread
From: Stephen Hemminger @ 2025-01-28 18:54 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm, Danylo Vodopianov

On Tue, 21 Jan 2025 18:07:40 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> From: Danylo Vodopianov <dvo-plv@napatech.com>
> 
> CI found couple coverity problems which were fixed in this commit.
> 
> CID: 448965 Error handling issues (CHECKED_RETURN).
> 
> Thread return code check was added.
> 
> Coverity issue: 448965
> Fixes: a1ba8c473f5c ("net/ntnic: add statistics poll")
> 
> Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
> ---
>  drivers/net/ntnic/ntnic_ethdev.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
> index 2a2643a106..620d023a71 100644
> --- a/drivers/net/ntnic/ntnic_ethdev.c
> +++ b/drivers/net/ntnic/ntnic_ethdev.c
> @@ -2516,8 +2516,11 @@ static int init_shutdown(void)
>  	NT_LOG(DBG, NTNIC, "Starting shutdown handler");
>  	kill_pmd = 0;
>  	previous_handler = signal(SIGINT, signal_handler_func_int);
> -	THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
> -
> +	int ret = THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
> +	if (ret != 0) {
> +		NT_LOG(ERR, NTNIC, "Failed to create shutdown thread, error code: %d", ret);
> +		return -1;
> +	}
>  	/*
>  	 * 1 time calculation of 1 sec stat update rtc cycles to prevent stat poll
>  	 * flooding by OVS from multiple virtual port threads - no need to be precise

This whole init thread and shutdown logic is broken.
There are vendor NFV applications that expect to be able to do.
  
         rte_eal_init()
         signal(SIGINT, my_shutdown_func)

This kind of problem was reported years ago with the TAP device, and it
had to change to use a different signal.


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

* [PATCH v2 00/34] net/ntnic: bugfixes and refactoring
  2025-01-21 17:07 ` [PATCH v1 01/31] net/ntnic: fix index verification Serhii Iliushyk
@ 2025-02-05 10:45   ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 01/34] net/ntnic: fix index verification Serhii Iliushyk
                       ` (34 more replies)
  0 siblings, 35 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

This patch set addresses fixing issues in the ntnic PMD driver.

Changes in this patch:

The issues detected by the Coverity Scan tool.
The problems that were detected by the internal tests.
Fix for Bug 1622: ntnic: using signals and threads:
https://bugs.dpdk.org/show_bug.cgi?id=1622.
  The handling of signals within the PMD driver was removed.
  For manipulation with all threads dedicated EAL API
    (rte_thread_create_internal_control) is used.
  Product by design requires usage of threads inside PMD driver.

Danylo Vodopianov (26):
  net/ntnic: fix index verification
  net/ntnic: add thread check return code
  net/ntnic: add return code handling
  net/ntnic: add array index verification
  net/ntnic: fix realloc memory leak
  net/ntnic: fix array index verification
  net/ntnic: add var definition transparently
  net/ntnic: add proper var freed
  net/ntnic: remove unused code
  net/ntnic: fix potentially overflow
  net/ntnic: add null checking
  net/ntnic: fix overflow issue
  net/ntnic: fix untrusted loop bound
  net/ntnic: add null checking
  net/ntnic: move null checking
  net/ntnic: fix var size
  net/ntnic: fix var overflow
  net/ntnic: remove unused code
  net/ntnic: remove convert error func
  net/ntnic: fix array verification
  net/ntnic: fix memory leak
  net/ntnic: remove unused code
  net/ntnic: refactor RSS implementation
  net/ntnic: fix age timeout recalculation into fpga unit
  net/ntnic: rework age event generation
  net/ntnic: fix group print

Oleksandr Kolomeiets (2):
  net/ntnic: remove extra address-of operator
  net/ntnic: remove extra check for null

Serhii Iliushyk (6):
  net/ntnic: extend module mapping
  net/ntnic: refactoring of the FPGA initialization
  net/ntnic: remove shutdown thread
  net/ntnic: add checks for action modify
  net/ntnic: add IFR DROP counter
  net/ntnic: remove tag EXPERIMENTAL

 MAINTAINERS                                   |   2 +-
 .../net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c |  18 +-
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c |  10 +-
 drivers/net/ntnic/include/create_elements.h   |   1 -
 drivers/net/ntnic/include/flow_api.h          |  10 +-
 drivers/net/ntnic/include/flow_api_engine.h   |   2 +
 drivers/net/ntnic/include/hw_mod_backend.h    |  24 +-
 drivers/net/ntnic/include/hw_mod_tpe_v3.h     |   5 +
 drivers/net/ntnic/include/ntnic_stat.h        |   9 +
 .../link_mgmt/link_100g/nt4ga_link_100g.c     |   2 +-
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nthw/core/nthw_fpga.c       |  14 +-
 drivers/net/ntnic/nthw/flow_api/flow_api.c    |  83 +-
 .../nthw/flow_api/flow_backend/flow_backend.c |  28 +-
 drivers/net/ntnic/nthw/flow_api/flow_group.c  |  26 +
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.c    | 661 +++++++++++++
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.h    |  17 +
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c   |  14 +-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c   |  19 +-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c   |  18 +-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_tpe.c   |  58 +-
 .../profile_inline/flow_api_hw_db_inline.c    |  29 +-
 .../profile_inline/flow_api_profile_inline.c  | 925 +++---------------
 .../profile_inline/flow_api_profile_inline.h  |   8 +-
 .../ntnic/nthw/flow_filter/flow_nthw_ifr.c    |  32 +
 .../ntnic/nthw/flow_filter/flow_nthw_ifr.h    |  15 +-
 .../ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c |  10 +-
 drivers/net/ntnic/nthw/stat/nthw_stat.c       |   2 +
 .../nthw/supported/nthw_fpga_mod_str_map.c    |  24 +
 drivers/net/ntnic/ntnic_ethdev.c              |  69 +-
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 155 ++-
 drivers/net/ntnic/ntnic_mod_reg.h             |  11 +-
 drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c |  10 +-
 33 files changed, 1204 insertions(+), 1108 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h

-- 
2.45.0


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

* [PATCH v2 01/34] net/ntnic: fix index verification
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 02/34] net/ntnic: add thread check return code Serhii Iliushyk
                       ` (33 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

CI found couple coverity problems which were fixed in this commit.

CID: 448974, 448977, 448978 (OVERRUN).

These issues were fixed with updating index verification statement.

Coverity issue: 448974
Fixes: effa04693274 ("net/ntnic: add statistics")

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

diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index 4c8503f689..e00b10ff82 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -1201,7 +1201,7 @@ static int poll_statistics(struct pmd_internals *internals)
 	const int if_index = internals->n_intf_no;
 	uint64_t last_stat_rtc = 0;
 
-	if (!p_nt4ga_stat || if_index < 0 || if_index > NUM_ADAPTER_PORTS_MAX)
+	if (!p_nt4ga_stat || if_index < 0 || if_index >= NUM_ADAPTER_PORTS_MAX)
 		return -1;
 
 	assert(rte_tsc_freq > 0);
-- 
2.45.0


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

* [PATCH v2 02/34] net/ntnic: add thread check return code
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 01/34] net/ntnic: fix index verification Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 03/34] net/ntnic: add return code handling Serhii Iliushyk
                       ` (32 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

CI found couple coverity problems which were fixed in this commit.

CID: 448965 Error handling issues (CHECKED_RETURN).

Thread return code check was added.

Coverity issue: 448965
Fixes: a1ba8c473f5c ("net/ntnic: add statistics poll")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 2a2643a106..620d023a71 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -2516,8 +2516,11 @@ static int init_shutdown(void)
 	NT_LOG(DBG, NTNIC, "Starting shutdown handler");
 	kill_pmd = 0;
 	previous_handler = signal(SIGINT, signal_handler_func_int);
-	THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
-
+	int ret = THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
+	if (ret != 0) {
+		NT_LOG(ERR, NTNIC, "Failed to create shutdown thread, error code: %d", ret);
+		return -1;
+	}
 	/*
 	 * 1 time calculation of 1 sec stat update rtc cycles to prevent stat poll
 	 * flooding by OVS from multiple virtual port threads - no need to be precise
-- 
2.45.0


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

* [PATCH v2 03/34] net/ntnic: add return code handling
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 01/34] net/ntnic: fix index verification Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 02/34] net/ntnic: add thread check return code Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 04/34] net/ntnic: add array index verification Serhii Iliushyk
                       ` (31 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

CI found couple coverity problems which were fixed in this commit.

CID: 448984, 448982, 448975, 448969, 448968, 448967
API usage errors  (BAD_COMPARE).

Add memcmp return value checking.

Coverity issue: 448984
Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
v2
* replace return with break for macro DO_COMPARE_INDEXS
---
 drivers/net/ntnic/include/hw_mod_backend.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index f91a3ed058..544962751a 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -114,10 +114,10 @@ enum {
 		typeof(be_module_reg) *temp_be_module = &(be_module_reg);                     \
 		typeof(idx) tmp_idx = (idx);                                                  \
 		typeof(cmp_idx) tmp_cmp_idx = (cmp_idx);                                      \
-		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx)) {                     \
-			(void)memcmp(temp_be_module + tmp_idx, &temp_be_module[tmp_cmp_idx],      \
-				     sizeof(type));                                               \
-		}                                                                                 \
+		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx))                     \
+			if (memcmp(temp_be_module + tmp_idx, &temp_be_module[tmp_cmp_idx], \
+				sizeof(type)) == 0) \
+				break;                                              \
 	} while (0)
 
 static inline int is_non_zero(const void *addr, size_t n)
-- 
2.45.0


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

* [PATCH v2 04/34] net/ntnic: add array index verification
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (2 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 03/34] net/ntnic: add return code handling Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 05/34] net/ntnic: fix realloc memory leak Serhii Iliushyk
                       ` (30 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

CI found couple coverity problems which were fixed in this commit.

CID: 448983, 448980
Memory - corruptions  (OVERRUN)

Add check both indices within bounds before calling the macro

Coverity issue: 448983
Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c    | 17 ++++++++++++++++-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c    | 18 ++++++++++++++++--
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
index 1750d09afb..cc8db2fae5 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
@@ -121,8 +121,23 @@ static int hw_mod_hsh_rcp_mod(struct flow_api_backend_s *be, enum hw_hsh_e field
 				INDEX_TOO_LARGE_LOG;
 				return INDEX_TOO_LARGE;
 			}
+			/* Size of the structure */
+			size_t element_size = sizeof(struct hsh_v5_rcp_s);
+			/* Size of the buffer */
+			size_t buffer_size = sizeof(be->hsh.v5.rcp);
 
-			DO_COMPARE_INDEXS(be->hsh.v5.rcp, struct hsh_v5_rcp_s, index, word_off);
+			/* Calculate the maximum valid index (number of elements in the buffer) */
+			size_t max_idx = buffer_size / element_size;
+
+			/* Check that both indices are within bounds before calling the macro */
+			if (index < max_idx && word_off < max_idx) {
+				DO_COMPARE_INDEXS(be->hsh.v5.rcp, struct hsh_v5_rcp_s, index,
+					word_off);
+
+			} else {
+				INDEX_TOO_LARGE_LOG;
+				return INDEX_TOO_LARGE;
+			}
 			break;
 
 		case HW_HSH_RCP_FIND:
diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c
index 59285405ba..147a06ac2b 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_pdb.c
@@ -131,8 +131,22 @@ static int hw_mod_pdb_rcp_mod(struct flow_api_backend_s *be, enum hw_pdb_e field
 				INDEX_TOO_LARGE_LOG;
 				return INDEX_TOO_LARGE;
 			}
-
-			DO_COMPARE_INDEXS(be->pdb.v9.rcp, struct pdb_v9_rcp_s, index, *value);
+			/* Size of the structure */
+			size_t element_size = sizeof(struct pdb_v9_rcp_s);
+			/* Size of the buffer */
+			size_t buffer_size = sizeof(be->pdb.v9.rcp);
+
+			/* Calculate the maximum valid index (number of elements in the buffer) */
+			size_t max_idx = buffer_size / element_size;
+
+			/* Check that both indices are within bounds before calling the macro */
+			if (index < max_idx && *value < max_idx) {
+				DO_COMPARE_INDEXS(be->pdb.v9.rcp, struct pdb_v9_rcp_s, index,
+					*value);
+			} else {
+				INDEX_TOO_LARGE_LOG;
+				return INDEX_TOO_LARGE;
+			}
 			break;
 
 		case HW_PDB_RCP_DESCRIPTOR:
-- 
2.45.0


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

* [PATCH v2 05/34] net/ntnic: fix realloc memory leak
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (3 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 04/34] net/ntnic: add array index verification Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 06/34] net/ntnic: fix array index verification Serhii Iliushyk
                       ` (29 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Issue was fixed with verification in case of the
successful memory re-allocation.

Coverity issue: 448959
Fixes: 4033e0539435 ("net/ntnic: add flow meter")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../profile_inline/flow_api_profile_inline.c      | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index ff8eb502f4..1c7d5cac3e 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -5523,11 +5523,16 @@ int flow_configure_profile_inline(struct flow_eth_dev *dev, uint8_t caller_id,
 		struct flm_flow_mtr_handle_s *mtr_handle = dev->ndev->flm_mtr_handle;
 
 		if (mtr_handle->port_stats[caller_id]->shared == 1) {
-			res = realloc(mtr_handle->port_stats[caller_id]->stats,
-					port_attr->nb_meters) == NULL
-				? -1
-				: 0;
-			mtr_handle->port_stats[caller_id]->size = port_attr->nb_meters;
+			struct flm_mtr_stat_s *temp_stats =
+				realloc(mtr_handle->port_stats[caller_id]->stats,
+					port_attr->nb_meters);
+			if (temp_stats == NULL) {
+				res = -1;
+			} else {
+				res = 0;
+				mtr_handle->port_stats[caller_id]->stats = temp_stats;
+				mtr_handle->port_stats[caller_id]->size = port_attr->nb_meters;
+			}
 
 		} else {
 			mtr_handle->port_stats[caller_id] =
-- 
2.45.0


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

* [PATCH v2 06/34] net/ntnic: fix array index verification
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (4 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 05/34] net/ntnic: fix realloc memory leak Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 07/34] net/ntnic: add var definition transparently Serhii Iliushyk
                       ` (28 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

CI found couple coverity problems which were fixed in this commit.

CID: 448983 Out-of-bounds write (OVERRUN).

These issues were fixed with updating index verification statement.

Coverity issue: 448983
Fixes: 96c8249be53e ("net/ntnic: learn flow queue handling")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 620d023a71..28b086c009 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -140,7 +140,7 @@ store_pdrv(struct drv_s *p_drv)
 
 static void clear_pdrv(struct drv_s *p_drv)
 {
-	if (p_drv->adapter_no > NUM_ADAPTER_MAX)
+	if (p_drv->adapter_no >= NUM_ADAPTER_MAX)
 		return;
 
 	rte_spinlock_lock(&hwlock);
-- 
2.45.0


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

* [PATCH v2 07/34] net/ntnic: add var definition transparently
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (5 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 06/34] net/ntnic: fix array index verification Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 08/34] net/ntnic: add proper var freed Serhii Iliushyk
                       ` (27 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

set eth_base to NULL after freeing to prevent
use-after-free

CID: 446746 Use after free (USE_AFTER_FREE)

Coverity issue: 446746
Fixes: 1d3f62a0c4f1 ("net/ntnic: add base init and deinit of flow API")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_api/flow_api.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index 82d4e34ae9..d25d1a3dd1 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -385,8 +385,10 @@ static void flow_ndev_reset(struct flow_nic_dev *ndev)
 	}
 
 	/* Delete all eth-port devices created on this NIC device */
-	while (ndev->eth_base)
+	while (ndev->eth_base) {
 		flow_delete_eth_dev(ndev->eth_base);
+		ndev->eth_base = NULL;
+	}
 
 	/* Error check */
 	while (ndev->flow_base) {
-- 
2.45.0


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

* [PATCH v2 08/34] net/ntnic: add proper var freed
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (6 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 07/34] net/ntnic: add var definition transparently Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 09/34] net/ntnic: remove unused code Serhii Iliushyk
                       ` (26 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Ferruh Yigit

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

p_fpga_mgr is properly freed when it's no longer needed

CID 440546: Resource leak (RESOURCE_LEAK)
Fixes: ddf184d0b6c2 ("net/ntnic: add FPGA initialization")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/core/nthw_fpga.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ntnic/nthw/core/nthw_fpga.c b/drivers/net/ntnic/nthw/core/nthw_fpga.c
index ca69a9d5b1..88641145ec 100644
--- a/drivers/net/ntnic/nthw/core/nthw_fpga.c
+++ b/drivers/net/ntnic/nthw/core/nthw_fpga.c
@@ -230,6 +230,8 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 		if (p_fpga == NULL) {
 			NT_LOG(ERR, NTHW, "%s: Unsupported FPGA: %s (%08X)", p_adapter_id_str,
 				s_fpga_prod_ver_rev_str, p_fpga_info->n_fpga_build_time);
+			nthw_fpga_mgr_delete(p_fpga_mgr);
+			p_fpga_mgr = NULL;
 			return -1;
 		}
 
-- 
2.45.0


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

* [PATCH v2 09/34] net/ntnic: remove unused code
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (7 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 08/34] net/ntnic: add proper var freed Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 10/34] net/ntnic: fix potentially overflow Serhii Iliushyk
                       ` (25 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Unused code was removed.

CID: 448981 Logically dead code (DEADCODE)

Coverity issue: 448981
Fixes: e02fdb65c2a8 ("net/ntnic: add flow create/destroy")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../flow_api/profile_inline/flow_api_profile_inline.c    | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 1c7d5cac3e..535047d246 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -4268,13 +4268,8 @@ struct flow_handle *flow_create_profile_inline(struct flow_eth_dev *dev __rte_un
 
 err_exit:
 
-	if (fh) {
-		flow_destroy_locked_profile_inline(dev, fh, NULL);
-		fh = NULL;
-	} else {
-		free(fd);
-		fd = NULL;
-	}
+	free(fd);
+	fd = NULL;
 
 	rte_spinlock_unlock(&dev->ndev->mtx);
 
-- 
2.45.0


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

* [PATCH v2 10/34] net/ntnic: fix potentially overflow
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (8 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 09/34] net/ntnic: remove unused code Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 11/34] net/ntnic: add null checking Serhii Iliushyk
                       ` (24 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Issue with potentially overflow was fixed.

CID 448944: Unintentional integer overflow (OVERFLOW_BEFORE_WIDEN)

Coverity issue: 448944
Fixes: 339ca124e659 ("net/ntnic: add flow action modify field")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 535047d246..a68c3ea702 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -1632,7 +1632,7 @@ static int interpret_flow_actions(const struct flow_eth_dev *dev,
 						return -1;
 					}
 
-					modify_field_use_flag = 1
+					modify_field_use_flag = (uint64_t)1
 						<< fd->modify_field[fd->modify_field_count].select;
 
 					if (modify_field_use_flag & modify_field_use_flags) {
-- 
2.45.0


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

* [PATCH v2 11/34] net/ntnic: add null checking
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (9 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 10/34] net/ntnic: fix potentially overflow Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 12/34] net/ntnic: fix overflow issue Serhii Iliushyk
                       ` (23 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

Fix issue with potential rereferencing a pointer
that might be NULL p->m_rpp_lr when calling
nthw_module_query_register

CID 448923:  Dereference null return value (NULL_RETURNS)

Coverity issue: 448923
Fixes: f543ca6b9ab2 ("net/ntnic: add RPP local retransmit (RPP LR) flow module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c
index 28c7a05fe2..e69a1ca823 100644
--- a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c
+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c
@@ -54,18 +54,20 @@ int rpp_lr_nthw_init(struct rpp_lr_nthw *p, nthw_fpga_t *p_fpga, int n_instance)
 	p->mp_fpga = p_fpga;
 	p->m_physical_adapter_no = (uint8_t)n_instance;
 	p->m_rpp_lr = nthw_fpga_query_module(p_fpga, MOD_RPP_LR, n_instance);
-
-	p->mp_rcp_ctrl = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_CTRL);
+	if (p->m_rpp_lr)
+		p->mp_rcp_ctrl = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_CTRL);
 	p->mp_rcp_addr = nthw_register_get_field(p->mp_rcp_ctrl, RPP_LR_RCP_CTRL_ADR);
 	p->mp_rcp_cnt = nthw_register_get_field(p->mp_rcp_ctrl, RPP_LR_RCP_CTRL_CNT);
-	p->mp_rcp_data = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_DATA);
+	if (p->m_rpp_lr)
+		p->mp_rcp_data = nthw_module_get_register(p->m_rpp_lr, RPP_LR_RCP_DATA);
 	p->mp_rcp_data_exp = nthw_register_get_field(p->mp_rcp_data, RPP_LR_RCP_DATA_EXP);
 
 	p->mp_ifr_rcp_ctrl = nthw_module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_CTRL);
 	p->mp_ifr_rcp_addr =
 		nthw_register_query_field(p->mp_ifr_rcp_ctrl, RPP_LR_IFR_RCP_CTRL_ADR);
 	p->mp_ifr_rcp_cnt = nthw_register_query_field(p->mp_ifr_rcp_ctrl, RPP_LR_IFR_RCP_CTRL_CNT);
-	p->mp_ifr_rcp_data = nthw_module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_DATA);
+	if (p->m_rpp_lr)
+		p->mp_ifr_rcp_data = nthw_module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_DATA);
 	p->mp_ifr_rcp_data_ipv4_en =
 		nthw_register_query_field(p->mp_ifr_rcp_data, RPP_LR_IFR_RCP_DATA_IPV4_EN);
 	p->mp_ifr_rcp_data_ipv6_en =
-- 
2.45.0


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

* [PATCH v2 12/34] net/ntnic: fix overflow issue
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (10 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 11/34] net/ntnic: add null checking Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 13/34] net/ntnic: fix untrusted loop bound Serhii Iliushyk
                       ` (22 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Fix overflow issue with checking max bit shifting value.

Coverity issue: 448921
Fixes: 833962ebb893 ("net/ntnic: add CAT module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index a68c3ea702..574e51c2fa 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -3605,7 +3605,7 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n
 			.err_mask_ttl = (fd->ttl_sub_enable &&
 				fd->ttl_sub_outer) ? -1 : 0x1,
 			.ptc_mask_tunnel = fd->tunnel_prot !=
-				-1 ? (1 << fd->tunnel_prot) : -1,
+			-1 ? (1 << (fd->tunnel_prot > 10 ? 10 : fd->tunnel_prot)) : -1,
 			.ptc_mask_l3_tunnel =
 				fd->tunnel_l3_prot != -1 ? (1 << fd->tunnel_l3_prot) : -1,
 			.ptc_mask_l4_tunnel =
-- 
2.45.0


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

* [PATCH v2 13/34] net/ntnic: fix untrusted loop bound
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (11 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 12/34] net/ntnic: fix overflow issue Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 14/34] net/ntnic: add null checking Serhii Iliushyk
                       ` (21 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Replace while with if statement to avoid infinite loop
in case ther_type will be modified with extenral source.

Coverity issue: 448917
Fixes: c6821abf58e8 ("net/ntnic: add flow items GTP and actions raw encap/decap")

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

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


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

* [PATCH v2 14/34] net/ntnic: add null checking
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (12 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 13/34] net/ntnic: fix untrusted loop bound Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 15/34] net/ntnic: move " Serhii Iliushyk
                       ` (20 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Add null checking for fpga var.

Coverity issue: 448916
Fixes: 30b2f87ac650 ("net/ntnic: add GMF module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/link_mgmt/link_100g/nt4ga_link_100g.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 d8e0cad7cd..67dc0d01f6 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
@@ -405,7 +405,7 @@ static int _port_init(adapter_info_t *drv, nthw_fpga_t *fpga, int port)
 	_reset_rx(drv, mac_pcs);
 
 	/* 2.2) Nt4gaPort::setup() */
-	if (nthw_gmf_init(NULL, fpga, port) == 0) {
+	if (fpga && nthw_gmf_init(NULL, fpga, port) == 0) {
 		nthw_gmf_t gmf;
 
 		if (nthw_gmf_init(&gmf, fpga, port) == 0)
-- 
2.45.0


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

* [PATCH v2 15/34] net/ntnic: move null checking
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (13 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 14/34] net/ntnic: add null checking Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 16/34] net/ntnic: fix var size Serhii Iliushyk
                       ` (19 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Move null checking before using

Coverity issue: 446759
Fixes: f0fe222ea9cf ("net/ntnic: add releasing virtqueues")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
index c178144d42..279a852a1c 100644
--- a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
+++ b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
@@ -510,11 +510,11 @@ static int dbs_wait_hw_queue_shutdown(struct nthw_virt_queue *vq, int rx)
 
 static int dbs_internal_release_rx_virt_queue(struct nthw_virt_queue *rxvq)
 {
-	nthw_dbs_t *p_nthw_dbs = rxvq->mp_nthw_dbs;
-
 	if (rxvq == NULL)
 		return -1;
 
+	nthw_dbs_t *p_nthw_dbs = rxvq->mp_nthw_dbs;
+
 	/* Clear UW */
 	rxvq->used_struct_phys_addr = NULL;
 
-- 
2.45.0


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

* [PATCH v2 16/34] net/ntnic: fix var size
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (14 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 15/34] net/ntnic: move " Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 17/34] net/ntnic: fix var overflow Serhii Iliushyk
                       ` (18 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Function operate with uint16_r value, meanwhile return value with
uint32_t size.
This conversion was aligned to the uint8_t as far as max value of the
return value could be equal 16.

Coverity issue: 446747
Fixes: 67aee0a69665 ("net/ntnic: add used writer data handling")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
index 279a852a1c..a2c9ef27f0 100644
--- a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
+++ b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
@@ -345,9 +345,9 @@ dbs_initialize_virt_queue_structs(void *avail_struct_addr, void *used_struct_add
 		flgs);
 }
 
-static uint16_t dbs_qsize_log2(uint16_t qsize)
+static uint8_t dbs_qsize_log2(uint16_t qsize)
 {
-	uint32_t qs = 0;
+	uint8_t qs = 0;
 
 	while (qsize) {
 		qsize = qsize >> 1;
-- 
2.45.0


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

* [PATCH v2 17/34] net/ntnic: fix var overflow
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (15 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 16/34] net/ntnic: fix var size Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 18/34] net/ntnic: remove unused code Serhii Iliushyk
                       ` (17 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Casting either buf_size and num_descr to uint64_t before performing the
multiplication was done.

Coverity issue: 446740
Fixes: 6b0047fadf41 ("net/ntnic: add queue setup operations")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 28b086c009..6fcbb8fa9b 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -790,7 +790,7 @@ static int allocate_hw_virtio_queues(struct rte_eth_dev *eth_dev, int vf_num, st
 	NT_LOG(DBG, NTNIC, "***** Configure IOMMU for HW queues on VF %i *****", vf_num);
 
 	/* Just allocate 1MB to hold all combined descr rings */
-	uint64_t tot_alloc_size = 0x100000 + buf_size * num_descr;
+	uint64_t tot_alloc_size = 0x100000 + (uint64_t)buf_size * (uint64_t)num_descr;
 
 	void *virt =
 		rte_malloc_socket("VirtQDescr", tot_alloc_size, nt_util_align_size(tot_alloc_size),
-- 
2.45.0


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

* [PATCH v2 18/34] net/ntnic: remove unused code
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (16 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 17/34] net/ntnic: fix var overflow Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 19/34] net/ntnic: remove convert error func Serhii Iliushyk
                       ` (16 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Unused code path in the condition irq_vector >= 0
because the condition irq_vector < 0 is already
established

Coverity issue: 446745
Fixes: 01e34ed9c756 ("net/ntnic: add availability monitor management")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
index a2c9ef27f0..e1eccb647c 100644
--- a/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
+++ b/drivers/net/ntnic/dbsconfig/ntnic_dbsconfig.c
@@ -415,7 +415,7 @@ static struct nthw_virt_queue *nthw_setup_rx_virt_queue(nthw_dbs_t *p_nthw_dbs,
 	if (irq_vector < 0) {
 		if (set_rx_am_data(p_nthw_dbs, index, (uint64_t)avail_struct_phys_addr,
 				RX_AM_DISABLE, host_id, 0,
-				irq_vector >= 0 ? 1 : 0) != 0) {
+				0) != 0) {
 			return NULL;
 		}
 	}
-- 
2.45.0


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

* [PATCH v2 19/34] net/ntnic: remove convert error func
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (17 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 18/34] net/ntnic: remove unused code Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 20/34] net/ntnic: fix array verification Serhii Iliushyk
                       ` (15 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

convert_error func was removed as far as this approach was deprecated.

Coverity issue: 448973
Fixes: e526adf1fdef ("net/ntnic: add minimal create/destroy flow operations")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/create_elements.h   |   1 -
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 151 ++++++------------
 2 files changed, 53 insertions(+), 99 deletions(-)

diff --git a/drivers/net/ntnic/include/create_elements.h b/drivers/net/ntnic/include/create_elements.h
index 1456977837..f0b9410cb9 100644
--- a/drivers/net/ntnic/include/create_elements.h
+++ b/drivers/net/ntnic/include/create_elements.h
@@ -61,7 +61,6 @@ enum nt_rte_flow_item_type {
 extern rte_spinlock_t flow_lock;
 
 int interpret_raw_data(uint8_t *data, uint8_t *preserve, int size, struct rte_flow_item *out);
-int convert_error(struct rte_flow_error *error, struct rte_flow_error *rte_flow_error);
 int create_attr(struct cnv_attr_s *attribute, const struct rte_flow_attr *attr);
 int create_match_elements(struct cnv_match_s *match, const struct rte_flow_item items[],
 	int max_elem);
diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index b07e16c1d3..70bff776be 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -246,23 +246,6 @@ int interpret_raw_data(uint8_t *data, uint8_t *preserve, int size, struct rte_fl
 	return hdri + 1;
 }
 
-int convert_error(struct rte_flow_error *error, struct rte_flow_error *rte_flow_error)
-{
-	if (error) {
-		error->cause = NULL;
-		error->message = rte_flow_error->message;
-
-		if (rte_flow_error->type == RTE_FLOW_ERROR_TYPE_NONE ||
-			rte_flow_error->type == RTE_FLOW_ERROR_TYPE_NONE)
-			error->type = RTE_FLOW_ERROR_TYPE_NONE;
-
-		else
-			error->type = RTE_FLOW_ERROR_TYPE_UNSPECIFIED;
-	}
-
-	return 0;
-}
-
 int create_attr(struct cnv_attr_s *attribute, const struct rte_flow_attr *attr)
 {
 	memset(&attribute->attr, 0x0, sizeof(struct rte_flow_attr));
@@ -497,13 +480,10 @@ static int convert_flow(struct rte_eth_dev *eth_dev,
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	uint32_t queue_offset = 0;
 
-	/* Set initial error */
-	convert_error(error, &flow_error);
-
 	if (!internals) {
 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 			"Missing eth_dev");
@@ -559,23 +539,19 @@ eth_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *flow, struct rte_
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	int res = 0;
-	/* Set initial error */
-	convert_error(error, &flow_error);
 
 	if (!flow)
 		return 0;
 
 	if (is_flow_handle_typecast(flow)) {
-		res = flow_filter_ops->flow_destroy(internals->flw_dev, (void *)flow, &flow_error);
-		convert_error(error, &flow_error);
+		res = flow_filter_ops->flow_destroy(internals->flw_dev, (void *)flow, error);
 
 	} else {
 		res = flow_filter_ops->flow_destroy(internals->flw_dev, flow->flw_hdl,
-			&flow_error);
-		convert_error(error, &flow_error);
+			error);
 
 		rte_spinlock_lock(&flow_lock);
 		flow->used = 0;
@@ -606,8 +582,8 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 	struct cnv_match_s match = { 0 };
 	struct cnv_action_s action = { 0 };
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	uint32_t flow_stat_id = 0;
 
 	if (convert_flow(eth_dev, attr, items, actions, &attribute, &match, &action, error) < 0)
@@ -620,8 +596,7 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 		void *flw_hdl = flow_filter_ops->flow_create(internals->flw_dev, &attribute.attr,
 			attribute.forced_vlan_vid, attribute.caller_id,
 			match.rte_flow_item, action.flow_actions,
-			&flow_error);
-		convert_error(error, &flow_error);
+			error);
 		return (struct rte_flow *)flw_hdl;
 	}
 
@@ -648,8 +623,7 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 		flow->flw_hdl = flow_filter_ops->flow_create(internals->flw_dev, &attribute.attr,
 			attribute.forced_vlan_vid, attribute.caller_id,
 			match.rte_flow_item, action.flow_actions,
-			&flow_error);
-		convert_error(error, &flow_error);
+			error);
 
 		if (!flow->flw_hdl) {
 			rte_spinlock_lock(&flow_lock);
@@ -678,14 +652,14 @@ static int eth_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *er
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	int res = 0;
 	/* Main application caller_id is port_id shifted above VDPA ports */
 	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
 
 	if (internals->flw_dev) {
-		res = flow_filter_ops->flow_flush(internals->flw_dev, caller_id, &flow_error);
+		res = flow_filter_ops->flow_flush(internals->flw_dev, caller_id, error);
 		rte_spinlock_lock(&flow_lock);
 
 		for (int flow = 0; flow < MAX_RTE_FLOWS; flow++) {
@@ -702,8 +676,6 @@ static int eth_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *er
 		rte_spinlock_unlock(&flow_lock);
 	}
 
-	convert_error(error, &flow_error);
-
 	return res;
 }
 
@@ -721,8 +693,8 @@ static int eth_flow_actions_update(struct rte_eth_dev *eth_dev,
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 	int res = -1;
 
 	if (internals->flw_dev) {
@@ -756,18 +728,16 @@ static int eth_flow_actions_update(struct rte_eth_dev *eth_dev,
 			res = flow_filter_ops->flow_actions_update(internals->flw_dev,
 					(void *)flow,
 					action.flow_actions,
-					&flow_error);
+					error);
 
 		} else {
 			res = flow_filter_ops->flow_actions_update(internals->flw_dev,
 					flow->flw_hdl,
 					action.flow_actions,
-					&flow_error);
+					error);
 		}
 	}
 
-	convert_error(error, &flow_error);
-
 	return res;
 }
 
@@ -785,17 +755,16 @@ static int eth_flow_dev_dump(struct rte_eth_dev *eth_dev,
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
 
 	int res = flow_filter_ops->flow_dev_dump(internals->flw_dev,
 			is_flow_handle_typecast(flow) ? (void *)flow
 			: flow->flw_hdl,
-			caller_id, file, &flow_error);
+			caller_id, file, error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -813,16 +782,14 @@ static int eth_flow_get_aged_flows(struct rte_eth_dev *eth_dev,
 
 	struct pmd_internals *internals = eth_dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
 
 	int res = flow_filter_ops->flow_get_aged_flows(internals->flw_dev, caller_id, context,
-			nb_contexts, &flow_error);
+			nb_contexts, error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -842,17 +809,15 @@ static int eth_flow_info_get(struct rte_eth_dev *dev, struct rte_flow_port_info
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_info_get(internals->flw_dev,
 			get_caller_id(dev->data->port_id),
 			(struct rte_flow_port_info *)port_info,
 			(struct rte_flow_queue_info *)queue_info,
-			&flow_error);
+			error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -869,18 +834,16 @@ static int eth_flow_configure(struct rte_eth_dev *dev, const struct rte_flow_por
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = {
-		.type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_configure(internals->flw_dev,
 			get_caller_id(dev->data->port_id),
 			(const struct rte_flow_port_attr *)port_attr,
 			nb_queue,
 			(const struct rte_flow_queue_attr **)queue_attr,
-			&flow_error);
+			error);
 
-	convert_error(error, &flow_error);
 	return res;
 }
 
@@ -897,8 +860,8 @@ static struct rte_flow_pattern_template *eth_flow_pattern_template_create(struct
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct cnv_match_s match = { 0 };
 	struct rte_flow_pattern_template_attr attr = {
@@ -918,9 +881,8 @@ static struct rte_flow_pattern_template *eth_flow_pattern_template_create(struct
 
 	struct flow_pattern_template *res =
 		flow_filter_ops->flow_pattern_template_create(internals->flw_dev, &attr, caller_id,
-			match.rte_flow_item, &flow_error);
+			match.rte_flow_item, error);
 
-	convert_error(error, &flow_error);
 	return (struct rte_flow_pattern_template *)res;
 }
 
@@ -937,15 +899,14 @@ static int eth_flow_pattern_template_destroy(struct rte_eth_dev *dev,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_pattern_template_destroy(internals->flw_dev,
 			(struct flow_pattern_template *)
 			pattern_template,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
@@ -964,8 +925,8 @@ static struct rte_flow_actions_template *eth_flow_actions_template_create(struct
 	struct pmd_internals *internals = dev->data->dev_private;
 
 	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct cnv_action_s action = { 0 };
 	struct cnv_action_s mask = { 0 };
@@ -1004,9 +965,8 @@ static struct rte_flow_actions_template *eth_flow_actions_template_create(struct
 	struct flow_actions_template *res =
 		flow_filter_ops->flow_actions_template_create(internals->flw_dev, &attr, caller_id,
 			action.flow_actions,
-			mask.flow_actions, &rte_flow_error);
+			mask.flow_actions, error);
 
-	convert_error(error, &rte_flow_error);
 	return (struct rte_flow_actions_template *)res;
 }
 
@@ -1023,15 +983,14 @@ static int eth_flow_actions_template_destroy(struct rte_eth_dev *dev,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_actions_template_destroy(internals->flw_dev,
 			(struct flow_actions_template *)
 			actions_template,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
@@ -1050,8 +1009,8 @@ static struct rte_flow_template_table *eth_flow_template_table_create(struct rte
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct rte_flow_template_table_attr attr = {
 		.flow_attr = {
@@ -1071,9 +1030,8 @@ static struct rte_flow_template_table *eth_flow_template_table_create(struct rte
 			forced_vlan_vid, caller_id,
 			(struct flow_pattern_template **)pattern_templates,
 			nb_pattern_templates, (struct flow_actions_template **)actions_templates,
-			nb_actions_templates, &rte_flow_error);
+			nb_actions_templates, error);
 
-	convert_error(error, &rte_flow_error);
 	return (struct rte_flow_template_table *)res;
 }
 
@@ -1090,15 +1048,14 @@ static int eth_flow_template_table_destroy(struct rte_eth_dev *dev,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_template_table_destroy(internals->flw_dev,
 			(struct flow_template_table *)
 			template_table,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
@@ -1118,8 +1075,8 @@ static struct rte_flow *eth_flow_async_create(struct rte_eth_dev *dev, uint32_t
 	struct pmd_internals *internals = dev->data->dev_private;
 
 	struct fpga_info_s *fpga_info = &internals->p_drv->ntdrv.adapter_info.fpga_info;
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	struct cnv_action_s action = { 0 };
 	struct cnv_match_s match = { 0 };
@@ -1159,9 +1116,8 @@ static struct rte_flow *eth_flow_async_create(struct rte_eth_dev *dev, uint32_t
 			action.flow_actions,
 			actions_template_index,
 			user_data,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return (struct rte_flow *)res;
 }
 
@@ -1178,17 +1134,16 @@ static int eth_flow_async_destroy(struct rte_eth_dev *dev, uint32_t queue_id,
 
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	static struct rte_flow_error rte_flow_error = { .type = RTE_FLOW_ERROR_TYPE_NONE,
-		.message = "none" };
+	error->type = RTE_FLOW_ERROR_TYPE_NONE;
+	error->message = "none";
 
 	int res = flow_filter_ops->flow_async_destroy(internals->flw_dev,
 			queue_id,
 			(const struct rte_flow_op_attr *)op_attr,
 			(struct flow_handle *)flow,
 			user_data,
-			&rte_flow_error);
+			error);
 
-	convert_error(error, &rte_flow_error);
 	return res;
 }
 
-- 
2.45.0


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

* [PATCH v2 20/34] net/ntnic: fix array verification
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (18 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 19/34] net/ntnic: remove convert error func Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 21/34] net/ntnic: fix memory leak Serhii Iliushyk
                       ` (14 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

if statement was modify to ensure that word_off
doesn't exceed the size of the array

Coverity issue: 448958
Fixes: 7fa0bf29e667 ("net/ntnic: add hash module")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
index cc8db2fae5..d19e72e323 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_hsh.c
@@ -221,7 +221,7 @@ static int hw_mod_hsh_rcp_mod(struct flow_api_backend_s *be, enum hw_hsh_e field
 			break;
 
 		case HW_HSH_RCP_WORD_MASK:
-			if (word_off > HSH_RCP_WORD_MASK_SIZE) {
+			if (word_off >= HSH_RCP_WORD_MASK_SIZE) {
 				WORD_OFF_TOO_LARGE_LOG;
 				return WORD_OFF_TOO_LARGE;
 			}
-- 
2.45.0


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

* [PATCH v2 21/34] net/ntnic: fix memory leak
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (19 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 20/34] net/ntnic: fix array verification Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 22/34] net/ntnic: remove extra address-of operator Serhii Iliushyk
                       ` (13 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

free for kvlist was added before return to avoid memory leak.

Coveriry issue: 446751
Fixes: fe91ade9f5db ("net/ntnic: add basic queue operations")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 6fcbb8fa9b..d1360cc925 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -2089,6 +2089,7 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
 				NT_LOG_DBGX(ERR, NTNIC,
 					"problem with command line arguments: res=%d",
 					res);
+				free(kvlist);
 				return -1;
 			}
 
@@ -2112,6 +2113,7 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
 				NT_LOG_DBGX(ERR, NTNIC,
 					"problem with command line arguments: res=%d",
 					res);
+				free(kvlist);
 				return -1;
 			}
 
-- 
2.45.0


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

* [PATCH v2 22/34] net/ntnic: remove extra address-of operator
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (20 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 21/34] net/ntnic: fix memory leak Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 23/34] net/ntnic: remove extra check for null Serhii Iliushyk
                       ` (12 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Oleksandr Kolomeiets

From: Oleksandr Kolomeiets <okl-plv@napatech.com>

Macro DO_COMPARE_INDEXS expects pointer to array.
If condition is true, one of array's elements get overwritten.
Misinterpreting pointer to pointer as pointer to array
may result in out-of-bounds access.

Coverity issue: 448966, 448970, 448971, 448972
Fixes: 6e8b7f11205f ("net/ntnic: add categorizer (CAT) FPGA module")

Signed-off-by: Oleksandr Kolomeiets <okl-plv@napatech.com>
---
 drivers/net/ntnic/include/hw_mod_backend.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index 544962751a..1941692ddf 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -111,7 +111,7 @@ enum {
 
 #define DO_COMPARE_INDEXS(be_module_reg, type, idx, cmp_idx)                                      \
 	do {                                                                                      \
-		typeof(be_module_reg) *temp_be_module = &(be_module_reg);                     \
+		typeof(be_module_reg) temp_be_module = (be_module_reg);                     \
 		typeof(idx) tmp_idx = (idx);                                                  \
 		typeof(cmp_idx) tmp_cmp_idx = (cmp_idx);                                      \
 		if ((unsigned int)(tmp_idx) != (unsigned int)(tmp_cmp_idx))                     \
-- 
2.45.0


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

* [PATCH v2 23/34] net/ntnic: remove extra check for null
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (21 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 22/34] net/ntnic: remove extra address-of operator Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 24/34] net/ntnic: remove unused code Serhii Iliushyk
                       ` (11 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Oleksandr Kolomeiets, Danylo Vodopianov

From: Oleksandr Kolomeiets <okl-plv@napatech.com>

pld_ptr points to mp_port_load's element,
which is initialized during driver's probe,
otherwise probe fails and xstats_get_by_id is not called.

Coverity issue: 448945
Fixes: cf6007eac498 ("net/ntnic: add xstats")

Signed-off-by: Oleksandr Kolomeiets <okl-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c b/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c
index 7604afe6a0..cf3271d5de 100644
--- a/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c
+++ b/drivers/net/ntnic/ntnic_xstats/ntnic_xstats.c
@@ -645,16 +645,8 @@ static int nthw_xstats_get_by_id(nt4ga_stat_t *p_nt4ga_stat,
 				break;
 
 			case 4:
-
 				/* Port Load stat */
-				if (pld_ptr) {
-					/* No reset */
-					values[i] = *((uint64_t *)&pld_ptr[names[i].offset]);
-
-				} else {
-					values[i] = 0;
-				}
-
+				values[i] = *((uint64_t *)&pld_ptr[names[i].offset]);
 				break;
 
 			default:
-- 
2.45.0


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

* [PATCH v2 24/34] net/ntnic: remove unused code
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (22 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 23/34] net/ntnic: remove extra check for null Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 25/34] net/ntnic: refactor RSS implementation Serhii Iliushyk
                       ` (10 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

NTNIC currently cupport only 100G link.

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
index 8fedfdcd04..2add43639a 100644
--- a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
+++ b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
@@ -215,16 +215,7 @@ static int nt4ga_stat_setup(struct adapter_info_s *p_adapter_info)
 		return -1;
 	}
 
-#ifdef NIM_TRIGGER
-	uint64_t max_bps_speed = nt_get_max_link_speed(p_adapter_info->nt4ga_link.speed_capa);
-
-	if (max_bps_speed == 0)
-		max_bps_speed = DEFAULT_MAX_BPS_SPEED;
-
-#else
 	uint64_t max_bps_speed = DEFAULT_MAX_BPS_SPEED;
-	NT_LOG(ERR, NTNIC, "NIM module not included");
-#endif
 
 	for (int p = 0; p < NUM_ADAPTER_PORTS_MAX; p++) {
 		p_nt4ga_stat->mp_port_load[p].rx_bps_max = max_bps_speed;
-- 
2.45.0


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

* [PATCH v2 25/34] net/ntnic: refactor RSS implementation
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (23 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 24/34] net/ntnic: remove unused code Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 26/34] net/ntnic: fix age timeout recalculation into fpga unit Serhii Iliushyk
                       ` (9 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Virtualization backward compatible RSS implementation is no longer
needed, thus RSS was refactored as follows:
* conversion of RTE_ETH_RSS fields into HSH registers was moved to
  separate files
* profile wrapper for RSS configuration was removed
* flow_nic_set_hasher(), to configure default 5-tuple hash, was
  replaced by call of hsh_set() with proper RTE_ETH_RSS*
  fields

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api.h          |   9 -
 drivers/net/ntnic/include/hw_mod_backend.h    |   6 -
 drivers/net/ntnic/meson.build                 |   1 +
 drivers/net/ntnic/nthw/flow_api/flow_api.c    |  63 --
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.c    | 661 +++++++++++++++
 .../net/ntnic/nthw/flow_api/flow_hsh_cfg.h    |  17 +
 .../profile_inline/flow_api_hw_db_inline.c    |   5 +-
 .../profile_inline/flow_api_profile_inline.c  | 782 +-----------------
 .../profile_inline/flow_api_profile_inline.h  |   4 -
 drivers/net/ntnic/ntnic_ethdev.c              |   3 +-
 drivers/net/ntnic/ntnic_mod_reg.h             |   6 -
 11 files changed, 695 insertions(+), 862 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
 create mode 100644 drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h

diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
index 0af766fe5b..9201b8a3ae 100644
--- a/drivers/net/ntnic/include/flow_api.h
+++ b/drivers/net/ntnic/include/flow_api.h
@@ -83,11 +83,6 @@ struct flow_eth_dev {
 	struct flow_eth_dev *next;
 };
 
-enum flow_nic_hash_e {
-	HASH_ALGO_ROUND_ROBIN = 0,
-	HASH_ALGO_5TUPLE,
-};
-
 /* registered NIC backends */
 struct flow_nic_dev {
 	uint8_t adapter_no;     /* physical adapter no in the host system */
@@ -234,10 +229,6 @@ void flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type,
 int flow_nic_ref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);
 int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);
 
-int flow_nic_set_hasher(struct flow_nic_dev *ndev, int hsh_idx, enum flow_nic_hash_e algorithm);
-int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx,
-	struct nt_eth_rss_conf rss_conf);
-
 int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
 
 #endif
diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index 1941692ddf..4061d3f9e5 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -239,12 +239,6 @@ enum {
 	PROT_TUN_L4_ICMP = 4
 };
 
-
-enum {
-	HASH_HASH_NONE = 0,
-	HASH_5TUPLE = 8,
-};
-
 enum {
 	CPY_SELECT_DSCP_IPV4 = 0,
 	CPY_SELECT_DSCP_IPV6 = 1,
diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build
index 3c05ad1d87..bfc5ae5aa8 100644
--- a/drivers/net/ntnic/meson.build
+++ b/drivers/net/ntnic/meson.build
@@ -70,6 +70,7 @@ sources = files(
         'nthw/flow_api/flow_backend/flow_backend.c',
         'nthw/flow_api/flow_filter.c',
         'nthw/flow_api/flow_hasher.c',
+        'nthw/flow_api/flow_hsh_cfg.c',
         'nthw/flow_api/flow_kcc.c',
         'nthw/flow_api/flow_km.c',
         'nthw/flow_api/hw_mod/hw_mod_backend.c',
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index d25d1a3dd1..857051fe14 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -1009,55 +1009,6 @@ int sprint_nt_rss_mask(char *str, uint16_t str_len, const char *prefix, uint64_t
 	return 0;
 }
 
-/*
- * Hash
- */
-
-int flow_nic_set_hasher(struct flow_nic_dev *ndev, int hsh_idx, enum flow_nic_hash_e algorithm)
-{
-	hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
-
-	switch (algorithm) {
-	case HASH_ALGO_5TUPLE:
-		/* need to create an IPv6 hashing and enable the adaptive ip mask bit */
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_LOAD_DIST_TYPE, hsh_idx, 0, 2);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW0_PE, hsh_idx, 0, DYN_FINAL_IP_DST);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW0_OFS, hsh_idx, 0, -16);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW4_PE, hsh_idx, 0, DYN_FINAL_IP_DST);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_QW4_OFS, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W8_PE, hsh_idx, 0, DYN_L4);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W8_OFS, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W9_PE, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W9_OFS, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_W9_P, hsh_idx, 0, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK, hsh_idx, 0, 1);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 0, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 1, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 2, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 3, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 4, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 5, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 6, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 7, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 8, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx, 9, 0);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_SEED, hsh_idx, 0, 0xffffffff);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_HSH_VALID, hsh_idx, 0, 1);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_HSH_TYPE, hsh_idx, 0, HASH_5TUPLE);
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_AUTO_IPV4_MASK, hsh_idx, 0, 1);
-
-		NT_LOG(DBG, FILTER, "Set IPv6 5-tuple hasher with adaptive IPv4 hashing");
-		break;
-
-	default:
-	case HASH_ALGO_ROUND_ROBIN:
-		/* zero is round-robin */
-		break;
-	}
-
-	return 0;
-}
-
 static int flow_dev_dump(struct flow_eth_dev *dev,
 	struct flow_handle *flow,
 	uint16_t caller_id,
@@ -1074,19 +1025,6 @@ static int flow_dev_dump(struct flow_eth_dev *dev,
 	return profile_inline_ops->flow_dev_dump_profile_inline(dev, flow, caller_id, file, error);
 }
 
-int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx,
-	struct nt_eth_rss_conf rss_conf)
-{
-	const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
-
-	if (profile_inline_ops == NULL) {
-		NT_LOG(ERR, FILTER, "%s: profile_inline module uninitialized", __func__);
-		return -1;
-	}
-
-	return profile_inline_ops->flow_nic_set_hasher_fields_inline(ndev, hsh_idx, rss_conf);
-}
-
 static int flow_get_aged_flows(struct flow_eth_dev *dev,
 	uint16_t caller_id,
 	void **context,
@@ -1324,7 +1262,6 @@ static const struct flow_filter_ops ops = {
 	 * Other
 	 */
 	 .hw_mod_hsh_rcp_flush = hw_mod_hsh_rcp_flush,
-	 .flow_nic_set_hasher_fields = flow_nic_set_hasher_fields,
 };
 
 void init_flow_filter(void)
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
new file mode 100644
index 0000000000..624d1a26d1
--- /dev/null
+++ b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.c
@@ -0,0 +1,661 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#include "flow_hsh_cfg.h"
+
+#define RTE_ETH_RSS_UDP_COMBINED (RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
+								  RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
+								  RTE_ETH_RSS_IPV6_UDP_EX)
+
+#define RTE_ETH_RSS_TCP_COMBINED (RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
+								  RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
+								  RTE_ETH_RSS_IPV6_TCP_EX)
+
+#define TOEPLITS_HSH_SIZE 9
+/*
+ * FPGA uses up to 10 32-bit words (320 bits) for hash calculation + 8 bits for L4 protocol number.
+ * Hashed data are split between two 128-bit Quad Words (QW)
+ * and two 32-bit Words (W), which can refer to different header parts.
+ */
+enum hsh_words_id {
+	HSH_WORDS_QW0     = 0,
+	HSH_WORDS_QW4,
+	HSH_WORDS_W8,
+	HSH_WORDS_W9,
+	HSH_WORDS_SIZE,
+};
+
+/* struct with details about hash QWs & Ws */
+struct hsh_words {
+	/*
+	 * index of W (word) or index of 1st word of QW (quad word)
+	 * is used for hash mask calculation
+	 */
+	uint8_t index;
+	enum hw_hsh_e pe;           /* offset to header part, e.g. beginning of L4 */
+	enum hw_hsh_e ofs;          /* relative offset in BYTES to 'pe' header offset above */
+	uint16_t bit_len;           /* max length of header part in bits to fit into QW/W */
+	bool free;                  /* only free words can be used for hsh calculation */
+};
+
+static enum hsh_words_id get_free_word(struct hsh_words *words, uint16_t bit_len)
+{
+	enum hsh_words_id ret = HSH_WORDS_SIZE;
+	uint16_t ret_bit_len = UINT16_MAX;
+	for (enum hsh_words_id i = HSH_WORDS_QW0; i < HSH_WORDS_SIZE; i++) {
+		if (words[i].free && bit_len <=
+			words[i].bit_len && words[i].bit_len <
+			ret_bit_len) {
+			ret = i;
+			ret_bit_len = words[i].bit_len;
+		}
+	}
+	return ret;
+}
+
+static int hsh_set_part(struct flow_nic_dev *ndev, int hsh_idx, struct hsh_words *words,
+	uint32_t pe, uint32_t ofs, int bit_len, bool toeplitz)
+{
+	int res = 0;
+
+	/* check if there is any free word, which can accommodate header part of given 'bit_len' */
+	enum hsh_words_id word = get_free_word(words, bit_len);
+
+	if (word == HSH_WORDS_SIZE) {
+		NT_LOG(ERR, FILTER, "Cannot add additional %d bits into hash", bit_len);
+		return -1;
+	}
+
+	words[word].free = false;
+
+	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].pe, hsh_idx, 0, pe);
+	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].pe,
+		hsh_idx, pe);
+	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].ofs, hsh_idx, 0, ofs);
+	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].ofs,
+		hsh_idx, ofs);
+
+
+	/* set HW_HSH_RCP_WORD_MASK based on used QW/W and given 'bit_len' */
+	int mask_bit_len = bit_len;
+	uint32_t mask = 0x0;
+	uint32_t toeplitz_mask[TOEPLITS_HSH_SIZE] = {0x0};
+	/* iterate through all words of QW */
+	uint16_t words_count = words[word].bit_len / 32;
+	for (uint16_t mask_off = 1; mask_off <= words_count; mask_off++) {
+		if (mask_bit_len >= 32) {
+			mask_bit_len -= 32;
+			mask = 0xffffffff;
+		} else if (mask_bit_len > 0) {
+			mask = 0xffffffff >> (32 - mask_bit_len) << (32 - mask_bit_len);
+			mask_bit_len = 0;
+		} else {
+			mask = 0x0;
+		}
+		/* reorder QW words mask from little to big endian */
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx,
+			words[word].index + words_count - mask_off, mask);
+		NT_LOG(DBG, FILTER,
+			"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, %d, %d, 0x%08" PRIX32 ")",
+				hsh_idx, words[word].index + words_count - mask_off, mask);
+		toeplitz_mask[words[word].index + mask_off - 1] = mask;
+	}
+	if (toeplitz) {
+		NT_LOG(DBG, FILTER,
+			"Partial Toeplitz RSS key mask: %08" PRIX32 " %08" PRIX32 " %08" PRIX32
+			" %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32
+			" %08" PRIX32 "",
+			toeplitz_mask[0], toeplitz_mask[1], toeplitz_mask[2], toeplitz_mask[3],
+			toeplitz_mask[4], toeplitz_mask[5], toeplitz_mask[6], toeplitz_mask[7],
+			toeplitz_mask[8]);
+		NT_LOG(DBG, FILTER, "                               MSB                                                                          LSB");
+	}
+	return res;
+}
+
+static __rte_always_inline bool all_bits_enabled(uint64_t hash_mask, uint64_t hash_bits)
+{
+	return (hash_mask & hash_bits) == hash_bits;
+}
+
+static __rte_always_inline void unset_bits(uint64_t *hash_mask, uint64_t hash_bits)
+{
+	*hash_mask &= ~hash_bits;
+}
+
+static __rte_always_inline void unset_bits_and_log(uint64_t *hash_mask, uint64_t hash_bits)
+{
+	char rss_buffer[4096];
+	uint16_t rss_buffer_len = sizeof(rss_buffer);
+
+	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", *hash_mask & hash_bits) == 0)
+		NT_LOG(DBG, FILTER, "Configured RSS types:%s", rss_buffer);
+	unset_bits(hash_mask, hash_bits);
+}
+
+static __rte_always_inline void unset_bits_if_all_enabled(uint64_t *hash_mask, uint64_t hash_bits)
+{
+	if (all_bits_enabled(*hash_mask, hash_bits))
+		unset_bits(hash_mask, hash_bits);
+}
+
+int hsh_set(struct flow_nic_dev *ndev, int hsh_idx, struct nt_eth_rss_conf rss_conf)
+{
+	uint64_t fields = rss_conf.rss_hf;
+
+	char rss_buffer[4096];
+	uint16_t rss_buffer_len = sizeof(rss_buffer);
+
+	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", fields) == 0)
+		NT_LOG(DBG, FILTER, "Requested RSS types:%s", rss_buffer);
+
+	/*
+	 * configure all (Q)Words usable for hash calculation
+	 * Hash can be calculated from 4 independent header parts:
+	 *      | QW0           | Qw4           | W8| W9|
+	 * word | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+	 */
+	struct hsh_words words[HSH_WORDS_SIZE] = {
+		{ 0, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
+		{ 4, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
+		{ 8, HW_HSH_RCP_W8_PE,  HW_HSH_RCP_W8_OFS,   32, true },
+		 /* not supported for Toeplitz */
+		{ 9, HW_HSH_RCP_W9_PE,  HW_HSH_RCP_W9_OFS,   32, true },
+	};
+
+	int res = 0;
+	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
+	/* enable hashing */
+	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_LOAD_DIST_TYPE, hsh_idx, 0, 2);
+
+	/* configure selected hash function and its key */
+	bool toeplitz = false;
+	switch (rss_conf.algorithm) {
+	case RTE_ETH_HASH_FUNCTION_DEFAULT:
+		/* Use default NTH10 hashing algorithm */
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 0);
+		/* Use 1st 32-bits from rss_key to configure NTH10 SEED */
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_SEED, hsh_idx, 0,
+			rss_conf.rss_key[0] << 24 | rss_conf.rss_key[1] << 16 |
+				rss_conf.rss_key[2] << 8 | rss_conf.rss_key[3]);
+		break;
+	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
+		toeplitz = true;
+		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 1);
+		uint8_t empty_key = 0;
+
+		/* Toeplitz key (always 40B) words have to be programmed in reverse order */
+		for (uint8_t i = 0; i <= (MAX_RSS_KEY_LEN - 4); i += 4) {
+			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, hsh_idx, 9 - i / 4,
+				rss_conf.rss_key[i] << 24 | rss_conf.rss_key[i + 1] << 16 |
+				rss_conf.rss_key[i + 2] << 8 | rss_conf.rss_key[i + 3]);
+			NT_LOG(DBG, FILTER,
+				"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, %d, %d, 0x%" PRIX32 ")",
+				hsh_idx, 9 - i / 4, rss_conf.rss_key[i] << 24 |
+				rss_conf.rss_key[i + 1] << 16 | rss_conf.rss_key[i + 2] << 8 |
+				rss_conf.rss_key[i + 3]);
+			empty_key |= rss_conf.rss_key[i] | rss_conf.rss_key[i + 1] |
+				rss_conf.rss_key[i + 2] | rss_conf.rss_key[i + 3];
+		}
+
+		if (empty_key == 0) {
+			NT_LOG(ERR, FILTER, "Toeplitz key must be configured. Key with all bytes set to zero is not allowed.");
+			return -1;
+		}
+		words[HSH_WORDS_W9].free = false;
+		NT_LOG(DBG, FILTER, "Toeplitz hashing is enabled thus W9 and P_MASK cannot be used.");
+		break;
+	default:
+		NT_LOG(ERR, FILTER, "Unknown hashing function %d requested", rss_conf.algorithm);
+		return -1;
+	}
+
+	/* indication that some IPv6 flag is present */
+	bool ipv6 = fields & (NT_ETH_RSS_IPV6_MASK);
+	/* store proto mask for later use at IP and L4 checksum handling */
+	uint64_t l4_proto_mask = fields &
+				(RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV4_UDP |
+				RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
+				RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
+				RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
+				RTE_ETH_RSS_IPV6_TCP_EX | RTE_ETH_RSS_IPV6_UDP_EX);
+
+	/* outermost headers are used by default, so innermost bit takes precedence if detected */
+	bool outer = (fields & RTE_ETH_RSS_LEVEL_INNERMOST) ? false : true;
+	unset_bits(&fields, RTE_ETH_RSS_LEVEL_MASK);
+
+	if (fields == 0) {
+		NT_LOG(ERR, FILTER, "RSS hash configuration 0x%" PRIX64 " is not valid.",
+			rss_conf.rss_hf);
+		return -1;
+	}
+
+	/* indication that IPv4 `protocol` or IPv6 `next header` fields shall be part of the hash */
+	bool l4_proto_hash = false;
+
+	/*
+	 * check if SRC_ONLY & DST_ONLY are used simultaneously;
+	 * According to DPDK, we shall behave like none of these bits is set
+	 */
+	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY);
+	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY);
+	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY);
+
+	/* L2 */
+	if (fields & (RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY)) {
+		if (outer) {
+			if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer src MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L2,
+					6, 48, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L2,
+					0, 48, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set outer src & dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L2,
+					0, 96, toeplitz);
+			}
+		} else {
+			if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner src MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L2,
+					6, 48, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L2,
+					0, 48, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner src & dst MAC hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L2,
+					0, 96, toeplitz);
+			}
+		}
+		unset_bits_and_log(&fields, RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY |
+			RTE_ETH_RSS_L2_DST_ONLY);
+	}
+
+	/*
+	 * VLAN support of multiple VLAN headers,
+	 * where S-VLAN is the first and C-VLAN the last VLAN header
+	 */
+	if (fields & RTE_ETH_RSS_C_VLAN) {
+		/*
+		 * use MPLS protocol offset, which points
+		 * just after ethertype with relative
+		 * offset -6 (i.e. 2 bytes
+		 * of ethertype & size + 4 bytes of VLAN header field)
+		 * to access last vlan header
+		 */
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer C-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_MPLS,
+				-6, 32, toeplitz);
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner C-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_MPLS,
+				-6, 32, toeplitz);
+		}
+		unset_bits_and_log(&fields, RTE_ETH_RSS_C_VLAN);
+	}
+
+	if (fields & RTE_ETH_RSS_S_VLAN) {
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer S-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_FIRST_VLAN,
+				0, 32, toeplitz);
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner S-VLAN hasher.");
+			/*
+			 * use whole 32-bit 802.1a tag - backward compatible
+			 * with VSWITCH implementation
+			 */
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_VLAN,
+				0, 32, toeplitz);
+		}
+		unset_bits_and_log(&fields, RTE_ETH_RSS_S_VLAN);
+	}
+
+	/* L2 payload */
+	/* calculate hash of 128-bits of l2 payload;
+	 * Use MPLS protocol offset to address the beginning
+	 * of L2 payload even if MPLS header is not present
+	 */
+	if (fields & RTE_ETH_RSS_L2_PAYLOAD) {
+		uint64_t outer_fields_enabled = 0;
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer L2 payload hasher.");
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_MPLS,
+				0, 128, toeplitz);
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner L2 payload hasher.");
+			res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_MPLS,
+				0, 128, toeplitz);
+			outer_fields_enabled = fields & RTE_ETH_RSS_GTPU;
+		}
+		/*
+		 * L2 PAYLOAD hashing overrides all L3 & L4 RSS flags.
+		 * Thus we can clear all remaining (supported)
+		 * RSS flags...
+		 */
+		unset_bits_and_log(&fields, NT_ETH_RSS_OFFLOAD_MASK);
+		/*
+		 * ...but in case of INNER L2 PAYLOAD we must process
+		 * "always outer" GTPU field if enabled
+		 */
+		fields |= outer_fields_enabled;
+	}
+
+	/* L3 + L4 protocol number */
+	if (fields & RTE_ETH_RSS_IPV4_CHKSUM) {
+		/* only IPv4 checksum is supported by DPDK RTE_ETH_RSS_* types */
+		if (ipv6) {
+			NT_LOG(ERR, FILTER, "RSS: IPv4 checksum requested with IPv6 header hashing!");
+			res = 1;
+		} else {
+			if (outer) {
+				NT_LOG(DBG, FILTER, "Set outer IPv4 checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+					10, 16, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner IPv4 checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+					10, 16, toeplitz);
+			}
+		}
+		/*
+		 * L3 checksum is made from whole L3 header, i.e. no need to process other
+		 * L3 hashing flags
+		 */
+		unset_bits_and_log(&fields, RTE_ETH_RSS_IPV4_CHKSUM | NT_ETH_RSS_IP_MASK);
+	}
+
+	if (fields & NT_ETH_RSS_IP_MASK) {
+		if (ipv6) {
+			if (outer) {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 src hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						-16, 128, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						0, 128, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						-16, 128, toeplitz);
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_FINAL_IP_DST,
+						0, 128, toeplitz);
+				}
+			} else {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, -16, 128, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, 0, 128, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, -16, 128, toeplitz);
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_FINAL_IP_DST, 0, 128, toeplitz);
+				}
+			}
+			/* check if fragment ID shall be part of hash */
+			if (fields & (RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6)) {
+				if (outer) {
+					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_ID_IPV4_6,
+						0, 32, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_ID_IPV4_6,
+						0, 32, toeplitz);
+				}
+			}
+			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_AUTO_IPV4_MASK,
+				hsh_idx, 0, 1);
+		} else {
+			/* IPv4 */
+			if (outer) {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 src only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+						12, 32, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 dst only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+						16, 32, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3,
+						12, 64, toeplitz);
+				}
+			} else {
+				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 src only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+						12, 32, toeplitz);
+				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 dst only hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+						16, 32, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 src & dst hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3,
+						12, 64, toeplitz);
+				}
+			}
+			/* check if fragment ID shall be part of hash */
+			if (fields & RTE_ETH_RSS_FRAG_IPV4) {
+				if (outer) {
+					NT_LOG(DBG, FILTER, "Set outer IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_ID_IPV4_6,
+						0, 16, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner IPv4 fragment ID hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_ID_IPV4_6,
+						0, 16, toeplitz);
+				}
+			}
+		}
+
+		/* check if L4 protocol type shall be part of hash */
+		if (l4_proto_mask)
+			l4_proto_hash = true;
+		unset_bits_and_log(&fields, NT_ETH_RSS_IP_MASK);
+	}
+
+	/* L4 */
+	if (fields & (RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY |
+		RTE_ETH_RSS_L4_DST_ONLY)) {
+		if (outer) {
+			if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer L4 src hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4,
+					0, 16, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set outer L4 dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4,
+					2, 16, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set outer L4 src & dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4,
+					0, 32, toeplitz);
+			}
+		} else {
+			if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner L4 src hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4,
+					0, 16, toeplitz);
+			} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
+				NT_LOG(DBG, FILTER, "Set inner L4 dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4,
+					2, 16, toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner L4 src & dst hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4,
+					0, 32, toeplitz);
+			}
+		}
+		l4_proto_hash = true;
+		unset_bits_and_log(&fields, RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY |
+			RTE_ETH_RSS_L4_DST_ONLY);
+	}
+
+	/* IPv4 protocol / IPv6 next header fields */
+	if (l4_proto_hash) {
+		/* NOTE: HW_HSH_RCP_P_MASK is not supported for
+		 *Toeplitz and thus one of SW0, SW4 or W8
+		 * must be used to hash on `protocol` field of IPv4 or
+		 * `next header` field of IPv6 header.
+		 */
+		if (outer) {
+			NT_LOG(DBG, FILTER, "Set outer L4 protocol type / next header hasher.");
+			if (toeplitz) {
+				if (ipv6)
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3, 6, 8,
+						toeplitz);
+				else
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_L3, 9, 8,
+						toeplitz);
+			} else {
+				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK,
+					hsh_idx, 0, 1);
+				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TNL_P,
+					hsh_idx, 0, 0);
+			}
+		} else {
+			NT_LOG(DBG, FILTER, "Set inner L4 protocol type / next header hasher.");
+			if (toeplitz) {
+				if (ipv6) {
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3, 6, 8,
+						toeplitz);
+				} else {
+					res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L3, 9, 8,
+						toeplitz);
+				}
+			} else {
+				res |= hw_mod_hsh_rcp_set(&ndev->be,
+					HW_HSH_RCP_P_MASK, hsh_idx, 0, 1);
+				res |= hw_mod_hsh_rcp_set(&ndev->be,
+					HW_HSH_RCP_TNL_P, hsh_idx, 0, 1);
+			}
+		}
+		l4_proto_hash = false;
+	}
+
+	/*
+	 * GTPU - for UPF use cases we always use TEID from outermost GTPU header
+	 * even if other headers are innermost
+	 */
+	if (fields & RTE_ETH_RSS_GTPU) {
+		NT_LOG(DBG, FILTER, "Set outer GTPU TEID hasher.");
+		res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4_PAYLOAD, 4, 32, toeplitz);
+		unset_bits_and_log(&fields, RTE_ETH_RSS_GTPU);
+	}
+
+	/* Checksums */
+	/* only UDP, TCP and SCTP checksums are supported */
+	if (fields & RTE_ETH_RSS_L4_CHKSUM) {
+		switch (l4_proto_mask) {
+		case RTE_ETH_RSS_NONFRAG_IPV4_UDP:
+		case RTE_ETH_RSS_NONFRAG_IPV6_UDP:
+		case RTE_ETH_RSS_IPV6_UDP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP:
+		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
+		case RTE_ETH_RSS_UDP_COMBINED:
+			if (outer) {
+				NT_LOG(DBG, FILTER, "Set outer UDP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4, 6, 16,
+					toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner UDP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4, 6, 16,
+					toeplitz);
+			}
+			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
+			break;
+		case RTE_ETH_RSS_NONFRAG_IPV4_TCP:
+		case RTE_ETH_RSS_NONFRAG_IPV6_TCP:
+		case RTE_ETH_RSS_IPV6_TCP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP:
+		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
+		case RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
+		case RTE_ETH_RSS_TCP_COMBINED:
+				if (outer) {
+					NT_LOG(DBG, FILTER, "Set outer TCP checksum hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_L4, 16, 16, toeplitz);
+				} else {
+					NT_LOG(DBG, FILTER, "Set inner TCP checksum hasher.");
+					res |= hsh_set_part(ndev, hsh_idx, words,
+						DYN_TUN_L4, 16, 16, toeplitz);
+				}
+				unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
+				break;
+		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP:
+		case RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
+		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
+			if (outer) {
+				NT_LOG(DBG, FILTER, "Set outer SCTP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_L4, 8, 32,
+					toeplitz);
+			} else {
+				NT_LOG(DBG, FILTER, "Set inner SCTP checksum hasher.");
+				res |= hsh_set_part(ndev, hsh_idx, words, DYN_TUN_L4, 8, 32,
+					toeplitz);
+			}
+			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
+			break;
+		case RTE_ETH_RSS_NONFRAG_IPV4_OTHER:
+		case RTE_ETH_RSS_NONFRAG_IPV6_OTHER:
+		/* none or unsupported protocol was chosen */
+		case 0:
+			NT_LOG(ERR, FILTER, "L4 checksum hashing is supported only for UDP, TCP and SCTP protocols");
+			res = -1;
+			break;
+		/* multiple L4 protocols were selected */
+		default:
+			NT_LOG(ERR, FILTER, "L4 checksum hashing can be enabled just for one of UDP, TCP or SCTP protocols");
+			res = -1;
+			break;
+		}
+	}
+
+	if (fields || res != 0) {
+		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
+		if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", rss_conf.rss_hf) == 0) {
+			NT_LOG(ERR, FILTER, "RSS configuration%s is not supported for hash func %s.",
+				rss_buffer, (enum rte_eth_hash_function)toeplitz ?
+					"Toeplitz" : "NTH10");
+		} else {
+			NT_LOG(ERR, FILTER, "RSS configuration 0x%" PRIX64 " is not supported for hash func %s.",
+				rss_conf.rss_hf, (enum rte_eth_hash_function)toeplitz ?
+					"Toeplitz" : "NTH10");
+		}
+		return -1;
+	}
+
+	return res;
+}
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h
new file mode 100644
index 0000000000..38901b3e8a
--- /dev/null
+++ b/drivers/net/ntnic/nthw/flow_api/flow_hsh_cfg.h
@@ -0,0 +1,17 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#ifndef _FLOW_HSH_CFG_H_
+#define _FLOW_HSH_CFG_H_
+
+#include <rte_ethdev.h>
+
+#include "hw_mod_backend.h"
+#include "flow_api.h"
+
+int hsh_set(struct flow_nic_dev *ndev, int hsh_idx,
+	struct nt_eth_rss_conf rss_conf);
+
+#endif /* _FLOW_HSH_CFG_H_ */
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
index ffab643f56..22cbf61b60 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
@@ -2,13 +2,14 @@
  * Copyright(c) 2023 Napatech A/S
  */
 
+#include "rte_common.h"
 
 #include "hw_mod_backend.h"
 #include "flow_api_engine.h"
 
 #include "flow_api_hw_db_inline.h"
 #include "flow_api_profile_inline_config.h"
-#include "rte_common.h"
+#include "flow_hsh_cfg.h"
 
 #define HW_DB_INLINE_ACTION_SET_NB 512
 #define HW_DB_INLINE_MATCH_SET_NB 512
@@ -2844,7 +2845,7 @@ struct hw_db_hsh_idx hw_db_inline_hsh_add(struct flow_nic_dev *ndev, void *db_ha
 	tmp_rss_conf.rss_hf = data->hash_mask;
 	memcpy(tmp_rss_conf.rss_key, data->key, MAX_RSS_KEY_LEN);
 	tmp_rss_conf.algorithm = data->func;
-	int res = flow_nic_set_hasher_fields(ndev, idx.ids, tmp_rss_conf);
+	int res = hsh_set(ndev, idx.ids, tmp_rss_conf);
 
 	if (res != 0) {
 		idx.error = 1;
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 574e51c2fa..e5abd372bc 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -20,6 +20,7 @@
 
 #include "flow_api_profile_inline.h"
 #include "ntnic_mod_reg.h"
+#include "flow_hsh_cfg.h"
 #include <rte_spinlock.h>
 #include <rte_common.h>
 
@@ -44,12 +45,6 @@
 #define NT_VIOLATING_MBR_CFN 0
 #define NT_VIOLATING_MBR_QSL 1
 
-#define RTE_ETH_RSS_UDP_COMBINED                                                                  \
-	(RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_IPV6_UDP_EX)
-
-#define RTE_ETH_RSS_TCP_COMBINED                                                                  \
-	(RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_IPV6_TCP_EX)
-
 #define NT_FLM_OP_UNLEARN 0
 #define NT_FLM_OP_LEARN 1
 
@@ -3809,116 +3804,6 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n
 	return NULL;
 }
 
-/*
- * FPGA uses up to 10 32-bit words (320 bits) for hash calculation + 8 bits for L4 protocol number.
- * Hashed data are split between two 128-bit Quad Words (QW)
- * and two 32-bit Words (W), which can refer to different header parts.
- */
-enum hsh_words_id {
-	HSH_WORDS_QW0 = 0,
-	HSH_WORDS_QW4,
-	HSH_WORDS_W8,
-	HSH_WORDS_W9,
-	HSH_WORDS_SIZE,
-};
-
-/* struct with details about hash QWs & Ws */
-struct hsh_words {
-	/*
-	 * index of W (word) or index of 1st word of QW (quad word)
-	 * is used for hash mask calculation
-	 */
-	uint8_t index;
-	enum hw_hsh_e pe;	/* offset to header part, e.g. beginning of L4 */
-	enum hw_hsh_e ofs;	/* relative offset in BYTES to 'pe' header offset above */
-	uint16_t bit_len;	/* max length of header part in bits to fit into QW/W */
-	bool free;	/* only free words can be used for hsh calculation */
-};
-
-static enum hsh_words_id get_free_word(struct hsh_words *words, uint16_t bit_len)
-{
-	enum hsh_words_id ret = HSH_WORDS_SIZE;
-	uint16_t ret_bit_len = UINT16_MAX;
-
-	for (enum hsh_words_id i = HSH_WORDS_QW0; i < HSH_WORDS_SIZE; i++) {
-		if (words[i].free && bit_len <= words[i].bit_len &&
-			words[i].bit_len < ret_bit_len) {
-			ret = i;
-			ret_bit_len = words[i].bit_len;
-		}
-	}
-
-	return ret;
-}
-
-static int flow_nic_set_hasher_part_inline(struct flow_nic_dev *ndev, int hsh_idx,
-	struct hsh_words *words, uint32_t pe, uint32_t ofs,
-	int bit_len, bool toeplitz)
-{
-	int res = 0;
-
-	/* check if there is any free word, which can accommodate header part of given 'bit_len' */
-	enum hsh_words_id word = get_free_word(words, bit_len);
-
-	if (word == HSH_WORDS_SIZE) {
-		NT_LOG(ERR, FILTER, "Cannot add additional %d bits into hash", bit_len);
-		return -1;
-	}
-
-	words[word].free = false;
-
-	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].pe, hsh_idx, 0, pe);
-	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].pe,
-		hsh_idx, pe);
-	res |= hw_mod_hsh_rcp_set(&ndev->be, words[word].ofs, hsh_idx, 0, ofs);
-	NT_LOG(DBG, FILTER, "hw_mod_hsh_rcp_set(&ndev->be, %d, %d, 0, %d)", words[word].ofs,
-		hsh_idx, ofs);
-
-	/* set HW_HSH_RCP_WORD_MASK based on used QW/W and given 'bit_len' */
-	int mask_bit_len = bit_len;
-	uint32_t mask = 0x0;
-	uint32_t toeplitz_mask[9] = { 0x0 };
-	/* iterate through all words of QW */
-	uint16_t words_count = words[word].bit_len / 32;
-
-	for (uint16_t mask_off = 1; mask_off <= words_count; mask_off++) {
-		if (mask_bit_len >= 32) {
-			mask_bit_len -= 32;
-			mask = 0xffffffff;
-
-		} else if (mask_bit_len > 0) {
-			mask = 0xffffffff >> (32 - mask_bit_len) << (32 - mask_bit_len);
-			mask_bit_len = 0;
-
-		} else {
-			mask = 0x0;
-		}
-
-		/* reorder QW words mask from little to big endian */
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, hsh_idx,
-			words[word].index + words_count - mask_off, mask);
-		NT_LOG_DBGX(DBG, FILTER,
-			"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, %d, %d, 0x%08" PRIX32
-			")",
-			hsh_idx, words[word].index + words_count - mask_off, mask);
-		toeplitz_mask[words[word].index + mask_off - 1] = mask;
-	}
-
-	if (toeplitz) {
-		NT_LOG(DBG, FILTER,
-			"Partial Toeplitz RSS key mask: %08" PRIX32 " %08" PRIX32 " %08" PRIX32
-			" %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32
-			" %08" PRIX32 "",
-			toeplitz_mask[0], toeplitz_mask[1], toeplitz_mask[2], toeplitz_mask[3],
-			toeplitz_mask[4], toeplitz_mask[5], toeplitz_mask[6], toeplitz_mask[7],
-			toeplitz_mask[8]);
-		NT_LOG(DBG, FILTER,
-			"                               MSB                                                                          LSB");
-	}
-
-	return res;
-}
-
 /*
  * Public functions
  */
@@ -3982,8 +3867,16 @@ int initialize_flow_management_of_ndev_profile_inline(struct flow_nic_dev *ndev)
 
 		flow_nic_mark_resource_used(ndev, RES_PDB_RCP, 0);
 
-		/* Set default hasher recipe to 5-tuple */
-		flow_nic_set_hasher(ndev, 0, HASH_ALGO_5TUPLE);
+		/* Set default hasher recipe to 5-tuple:
+		 * RTE_ETH_RSS_IPV6 - enables hashing on both IPv4/IPv6 SA and DA
+		 * RTE_ETH_RSS_PORT - enables hashing on both L4 SP and DP and L4 protocol type
+		 */
+		struct nt_eth_rss_conf hsh_5_tuple = {
+			.rss_key = {},
+			.rss_hf = RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_PORT,
+			.algorithm = 0,
+		};
+		hsh_set(ndev, 0, hsh_5_tuple);
 		hw_mod_hsh_rcp_flush(&ndev->be, 0, 1);
 
 		flow_nic_mark_resource_used(ndev, RES_HSH_RCP, 0);
@@ -4580,658 +4473,6 @@ int flow_actions_update_profile_inline(struct flow_eth_dev *dev,
 	return -1;
 }
 
-static __rte_always_inline bool all_bits_enabled(uint64_t hash_mask, uint64_t hash_bits)
-{
-	return (hash_mask & hash_bits) == hash_bits;
-}
-
-static __rte_always_inline void unset_bits(uint64_t *hash_mask, uint64_t hash_bits)
-{
-	*hash_mask &= ~hash_bits;
-}
-
-static __rte_always_inline void unset_bits_and_log(uint64_t *hash_mask, uint64_t hash_bits)
-{
-	char rss_buffer[4096];
-	uint16_t rss_buffer_len = sizeof(rss_buffer);
-
-	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", *hash_mask & hash_bits) == 0)
-		NT_LOG(DBG, FILTER, "Configured RSS types:%s", rss_buffer);
-
-	unset_bits(hash_mask, hash_bits);
-}
-
-static __rte_always_inline void unset_bits_if_all_enabled(uint64_t *hash_mask, uint64_t hash_bits)
-{
-	if (all_bits_enabled(*hash_mask, hash_bits))
-		unset_bits(hash_mask, hash_bits);
-}
-
-int flow_nic_set_hasher_fields_inline(struct flow_nic_dev *ndev, int hsh_idx,
-	struct nt_eth_rss_conf rss_conf)
-{
-	uint64_t fields = rss_conf.rss_hf;
-
-	char rss_buffer[4096];
-	uint16_t rss_buffer_len = sizeof(rss_buffer);
-
-	if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", fields) == 0)
-		NT_LOG(DBG, FILTER, "Requested RSS types:%s", rss_buffer);
-
-	/*
-	 * configure all (Q)Words usable for hash calculation
-	 * Hash can be calculated from 4 independent header parts:
-	 *      | QW0           | Qw4           | W8| W9|
-	 * word | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
-	 */
-	struct hsh_words words[HSH_WORDS_SIZE] = {
-		{ 0, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
-		{ 4, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
-		{ 8, HW_HSH_RCP_W8_PE, HW_HSH_RCP_W8_OFS, 32, true },
-		{
-			9, HW_HSH_RCP_W9_PE, HW_HSH_RCP_W9_OFS, 32,
-			true
-		},	/* not supported for Toeplitz */
-	};
-
-	int res = 0;
-	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
-	/* enable hashing */
-	res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_LOAD_DIST_TYPE, hsh_idx, 0, 2);
-
-	/* configure selected hash function and its key */
-	bool toeplitz = false;
-
-	switch (rss_conf.algorithm) {
-	case RTE_ETH_HASH_FUNCTION_DEFAULT:
-		/* Use default NTH10 hashing algorithm */
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 0);
-		/* Use 1st 32-bits from rss_key to configure NTH10 SEED */
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_SEED, hsh_idx, 0,
-			rss_conf.rss_key[0] << 24 | rss_conf.rss_key[1] << 16 |
-			rss_conf.rss_key[2] << 8 | rss_conf.rss_key[3]);
-		break;
-
-	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
-		toeplitz = true;
-		res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TOEPLITZ, hsh_idx, 0, 1);
-		uint8_t empty_key = 0;
-
-		/* Toeplitz key (always 40B) words have to be programmed in reverse order */
-		for (uint8_t i = 0; i <= (MAX_RSS_KEY_LEN - 4); i += 4) {
-			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, hsh_idx, 9 - i / 4,
-					rss_conf.rss_key[i] << 24 |
-					rss_conf.rss_key[i + 1] << 16 |
-					rss_conf.rss_key[i + 2] << 8 |
-					rss_conf.rss_key[i + 3]);
-			NT_LOG_DBG(DBG, FILTER,
-				"hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_K, %d, %d, 0x%" PRIX32
-				")",
-				hsh_idx, 9 - i / 4,
-				rss_conf.rss_key[i] << 24 | rss_conf.rss_key[i + 1] << 16 |
-				rss_conf.rss_key[i + 2] << 8 | rss_conf.rss_key[i + 3]);
-			empty_key |= rss_conf.rss_key[i] | rss_conf.rss_key[i + 1] |
-				rss_conf.rss_key[i + 2] | rss_conf.rss_key[i + 3];
-		}
-
-		if (empty_key == 0) {
-			NT_LOG(ERR, FILTER,
-				"Toeplitz key must be configured. Key with all bytes set to zero is not allowed.");
-			return -1;
-		}
-
-		words[HSH_WORDS_W9].free = false;
-		NT_LOG(DBG, FILTER,
-			"Toeplitz hashing is enabled thus W9 and P_MASK cannot be used.");
-		break;
-
-	default:
-		NT_LOG(ERR, FILTER, "Unknown hashing function %d requested", rss_conf.algorithm);
-		return -1;
-	}
-
-	/* indication that some IPv6 flag is present */
-	bool ipv6 = fields & (NT_ETH_RSS_IPV6_MASK);
-	/* store proto mask for later use at IP and L4 checksum handling */
-	uint64_t l4_proto_mask = fields &
-		(RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV4_UDP |
-		RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
-		RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
-		RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
-		RTE_ETH_RSS_IPV6_TCP_EX | RTE_ETH_RSS_IPV6_UDP_EX);
-
-	/* outermost headers are used by default, so innermost bit takes precedence if detected */
-	bool outer = (fields & RTE_ETH_RSS_LEVEL_INNERMOST) ? false : true;
-	unset_bits(&fields, RTE_ETH_RSS_LEVEL_MASK);
-
-	if (fields == 0) {
-		NT_LOG(ERR, FILTER, "RSS hash configuration 0x%" PRIX64 " is not valid.",
-			rss_conf.rss_hf);
-		return -1;
-	}
-
-	/* indication that IPv4 `protocol` or IPv6 `next header` fields shall be part of the hash
-	 */
-	bool l4_proto_hash = false;
-
-	/*
-	 * check if SRC_ONLY & DST_ONLY are used simultaneously;
-	 * According to DPDK, we shall behave like none of these bits is set
-	 */
-	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY);
-	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY);
-	unset_bits_if_all_enabled(&fields, RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY);
-
-	/* L2 */
-	if (fields & (RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY)) {
-		if (outer) {
-			if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer src MAC hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L2, 6, 48, toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer dst MAC hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L2, 0, 48, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set outer src & dst MAC hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L2, 0, 96, toeplitz);
-			}
-
-		} else if (fields & RTE_ETH_RSS_L2_SRC_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner src MAC hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L2, 6,
-				48, toeplitz);
-
-		} else if (fields & RTE_ETH_RSS_L2_DST_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner dst MAC hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L2, 0,
-				48, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner src & dst MAC hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L2, 0,
-				96, toeplitz);
-		}
-
-		unset_bits_and_log(&fields,
-			RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2_SRC_ONLY |
-			RTE_ETH_RSS_L2_DST_ONLY);
-	}
-
-	/*
-	 * VLAN support of multiple VLAN headers,
-	 * where S-VLAN is the first and C-VLAN the last VLAN header
-	 */
-	if (fields & RTE_ETH_RSS_C_VLAN) {
-		/*
-		 * use MPLS protocol offset, which points just after ethertype with relative
-		 * offset -6 (i.e. 2 bytes
-		 * of ethertype & size + 4 bytes of VLAN header field) to access last vlan header
-		 */
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer C-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_MPLS, -6,
-				32, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner C-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_MPLS,
-				-6, 32, toeplitz);
-		}
-
-		unset_bits_and_log(&fields, RTE_ETH_RSS_C_VLAN);
-	}
-
-	if (fields & RTE_ETH_RSS_S_VLAN) {
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer S-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-				DYN_FIRST_VLAN, 0, 32, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner S-VLAN hasher.");
-			/*
-			 * use whole 32-bit 802.1a tag - backward compatible
-			 * with VSWITCH implementation
-			 */
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_VLAN,
-				0, 32, toeplitz);
-		}
-
-		unset_bits_and_log(&fields, RTE_ETH_RSS_S_VLAN);
-	}
-	/* L2 payload */
-	/* calculate hash of 128-bits of l2 payload; Use MPLS protocol offset to address the
-	 * beginning of L2 payload even if MPLS header is not present
-	 */
-	if (fields & RTE_ETH_RSS_L2_PAYLOAD) {
-		uint64_t outer_fields_enabled = 0;
-
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer L2 payload hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_MPLS, 0,
-				128, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner L2 payload hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_MPLS,
-				0, 128, toeplitz);
-			outer_fields_enabled = fields & RTE_ETH_RSS_GTPU;
-		}
-
-		/*
-		 * L2 PAYLOAD hashing overrides all L3 & L4 RSS flags.
-		 * Thus we can clear all remaining (supported)
-		 * RSS flags...
-		 */
-		unset_bits_and_log(&fields, NT_ETH_RSS_OFFLOAD_MASK);
-		/*
-		 * ...but in case of INNER L2 PAYLOAD we must process
-		 * "always outer" GTPU field if enabled
-		 */
-		fields |= outer_fields_enabled;
-	}
-
-	/* L3 + L4 protocol number */
-	if (fields & RTE_ETH_RSS_IPV4_CHKSUM) {
-		/* only IPv4 checksum is supported by DPDK RTE_ETH_RSS_* types */
-		if (ipv6) {
-			NT_LOG(ERR, FILTER,
-				"RSS: IPv4 checksum requested with IPv6 header hashing!");
-			res = 1;
-
-		} else if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer IPv4 checksum hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_L3, 10,
-				16, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner IPv4 checksum hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L3,
-				10, 16, toeplitz);
-		}
-
-		/*
-		 * L3 checksum is made from whole L3 header, i.e. no need to process other
-		 * L3 hashing flags
-		 */
-		unset_bits_and_log(&fields, RTE_ETH_RSS_IPV4_CHKSUM | NT_ETH_RSS_IP_MASK);
-	}
-
-	if (fields & NT_ETH_RSS_IP_MASK) {
-		if (ipv6) {
-			if (outer) {
-				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 src hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST,
-						-16, 128, toeplitz);
-
-				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv6/IPv4 dst hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST, 0,
-						128, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER,
-						"Set outer IPv6/IPv4 src & dst hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST,
-						-16, 128, toeplitz);
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_FINAL_IP_DST, 0,
-						128, toeplitz);
-				}
-
-			} else if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, -16,
-					128, toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, 0,
-					128, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner IPv6/IPv4 src & dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, -16,
-					128, toeplitz);
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_FINAL_IP_DST, 0,
-					128, toeplitz);
-			}
-
-			/* check if fragment ID shall be part of hash */
-			if (fields & (RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6)) {
-				if (outer) {
-					NT_LOG(DBG, FILTER,
-						"Set outer IPv6/IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_ID_IPV4_6, 0,
-						32, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER,
-						"Set inner IPv6/IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_TUN_ID_IPV4_6,
-						0, 32, toeplitz);
-				}
-			}
-
-			res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_AUTO_IPV4_MASK, hsh_idx, 0,
-				1);
-
-		} else {
-			/* IPv4 */
-			if (outer) {
-				if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv4 src only hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 12,
-						32, toeplitz);
-
-				} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-					NT_LOG(DBG, FILTER, "Set outer IPv4 dst only hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 16,
-						32, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER, "Set outer IPv4 src & dst hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 12,
-						64, toeplitz);
-				}
-
-			} else if (fields & RTE_ETH_RSS_L3_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv4 src only hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L3, 12, 32,
-					toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L3_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set inner IPv4 dst only hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L3, 16, 32,
-					toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner IPv4 src & dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L3, 12, 64,
-					toeplitz);
-			}
-
-			/* check if fragment ID shall be part of hash */
-			if (fields & RTE_ETH_RSS_FRAG_IPV4) {
-				if (outer) {
-					NT_LOG(DBG, FILTER,
-						"Set outer IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_ID_IPV4_6, 0,
-						16, toeplitz);
-
-				} else {
-					NT_LOG(DBG, FILTER,
-						"Set inner IPv4 fragment ID hasher.");
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words,
-						DYN_TUN_ID_IPV4_6,
-						0, 16, toeplitz);
-				}
-			}
-		}
-
-		/* check if L4 protocol type shall be part of hash */
-		if (l4_proto_mask)
-			l4_proto_hash = true;
-
-		unset_bits_and_log(&fields, NT_ETH_RSS_IP_MASK);
-	}
-
-	/* L4 */
-	if (fields & (RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY)) {
-		if (outer) {
-			if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer L4 src hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 0, 16, toeplitz);
-
-			} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
-				NT_LOG(DBG, FILTER, "Set outer L4 dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 2, 16, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set outer L4 src & dst hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 0, 32, toeplitz);
-			}
-
-		} else if (fields & RTE_ETH_RSS_L4_SRC_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner L4 src hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L4, 0,
-				16, toeplitz);
-
-		} else if (fields & RTE_ETH_RSS_L4_DST_ONLY) {
-			NT_LOG(DBG, FILTER, "Set inner L4 dst hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L4, 2,
-				16, toeplitz);
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner L4 src & dst hasher.");
-			res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_TUN_L4, 0,
-				32, toeplitz);
-		}
-
-		l4_proto_hash = true;
-		unset_bits_and_log(&fields,
-			RTE_ETH_RSS_PORT | RTE_ETH_RSS_L4_SRC_ONLY |
-			RTE_ETH_RSS_L4_DST_ONLY);
-	}
-
-	/* IPv4 protocol / IPv6 next header fields */
-	if (l4_proto_hash) {
-		/* NOTE: HW_HSH_RCP_P_MASK is not supported for Toeplitz and thus one of SW0, SW4
-		 * or W8 must be used to hash on `protocol` field of IPv4 or `next header` field of
-		 * IPv6 header.
-		 */
-		if (outer) {
-			NT_LOG(DBG, FILTER, "Set outer L4 protocol type / next header hasher.");
-
-			if (toeplitz) {
-				if (ipv6) {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 6, 8,
-						toeplitz);
-
-				} else {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_L3, 9, 8,
-						toeplitz);
-				}
-
-			} else {
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK, hsh_idx, 0,
-					1);
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TNL_P, hsh_idx, 0,
-					0);
-			}
-
-		} else {
-			NT_LOG(DBG, FILTER, "Set inner L4 protocol type / next header hasher.");
-
-			if (toeplitz) {
-				if (ipv6) {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_TUN_L3,
-						6, 8, toeplitz);
-
-				} else {
-					res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx,
-						words, DYN_TUN_L3,
-						9, 8, toeplitz);
-				}
-
-			} else {
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_P_MASK, hsh_idx, 0,
-					1);
-				res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_TNL_P, hsh_idx, 0,
-					1);
-			}
-		}
-
-		l4_proto_hash = false;
-	}
-
-	/*
-	 * GTPU - for UPF use cases we always use TEID from outermost GTPU header
-	 * even if other headers are innermost
-	 */
-	if (fields & RTE_ETH_RSS_GTPU) {
-		NT_LOG(DBG, FILTER, "Set outer GTPU TEID hasher.");
-		res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words, DYN_L4_PAYLOAD, 4, 32,
-			toeplitz);
-		unset_bits_and_log(&fields, RTE_ETH_RSS_GTPU);
-	}
-
-	/* Checksums */
-	/* only UDP, TCP and SCTP checksums are supported */
-	if (fields & RTE_ETH_RSS_L4_CHKSUM) {
-		switch (l4_proto_mask) {
-		case RTE_ETH_RSS_NONFRAG_IPV4_UDP:
-		case RTE_ETH_RSS_NONFRAG_IPV6_UDP:
-		case RTE_ETH_RSS_IPV6_UDP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP:
-		case RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_IPV6_UDP_EX:
-		case RTE_ETH_RSS_UDP_COMBINED:
-			if (outer) {
-				NT_LOG(DBG, FILTER, "Set outer UDP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 6, 16, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner UDP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L4, 6, 16,
-					toeplitz);
-			}
-
-			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
-			break;
-
-		case RTE_ETH_RSS_NONFRAG_IPV4_TCP:
-		case RTE_ETH_RSS_NONFRAG_IPV6_TCP:
-		case RTE_ETH_RSS_IPV6_TCP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP:
-		case RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
-		case RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_IPV6_TCP_EX:
-		case RTE_ETH_RSS_TCP_COMBINED:
-			if (outer) {
-				NT_LOG(DBG, FILTER, "Set outer TCP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 16, 16, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner TCP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L4, 16, 16,
-					toeplitz);
-			}
-
-			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
-			break;
-
-		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP:
-		case RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
-		case RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
-			if (outer) {
-				NT_LOG(DBG, FILTER, "Set outer SCTP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_L4, 8, 32, toeplitz);
-
-			} else {
-				NT_LOG(DBG, FILTER, "Set inner SCTP checksum hasher.");
-				res |= flow_nic_set_hasher_part_inline(ndev, hsh_idx, words,
-					DYN_TUN_L4, 8, 32,
-					toeplitz);
-			}
-
-			unset_bits_and_log(&fields, RTE_ETH_RSS_L4_CHKSUM | l4_proto_mask);
-			break;
-
-		case RTE_ETH_RSS_NONFRAG_IPV4_OTHER:
-		case RTE_ETH_RSS_NONFRAG_IPV6_OTHER:
-
-		/* none or unsupported protocol was chosen */
-		case 0:
-			NT_LOG(ERR, FILTER,
-				"L4 checksum hashing is supported only for UDP, TCP and SCTP protocols");
-			res = -1;
-			break;
-
-		/* multiple L4 protocols were selected */
-		default:
-			NT_LOG(ERR, FILTER,
-				"L4 checksum hashing can be enabled just for one of UDP, TCP or SCTP protocols");
-			res = -1;
-			break;
-		}
-	}
-
-	if (fields || res != 0) {
-		hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_PRESET_ALL, hsh_idx, 0, 0);
-
-		if (sprint_nt_rss_mask(rss_buffer, rss_buffer_len, " ", rss_conf.rss_hf) == 0) {
-			NT_LOG(ERR, FILTER,
-				"RSS configuration%s is not supported for hash func %s.",
-				rss_buffer,
-				(enum rte_eth_hash_function)toeplitz ? "Toeplitz" : "NTH10");
-
-		} else {
-			NT_LOG(ERR, FILTER,
-				"RSS configuration 0x%" PRIX64
-				" is not supported for hash func %s.",
-				rss_conf.rss_hf,
-				(enum rte_eth_hash_function)toeplitz ? "Toeplitz" : "NTH10");
-		}
-
-		return -1;
-	}
-
-	return res;
-}
-
 static void dump_flm_data(const uint32_t *data, FILE *file)
 {
 	for (unsigned int i = 0; i < 10; ++i) {
@@ -6020,7 +5261,6 @@ static const struct profile_inline_ops ops = {
 	.flow_destroy_profile_inline = flow_destroy_profile_inline,
 	.flow_flush_profile_inline = flow_flush_profile_inline,
 	.flow_actions_update_profile_inline = flow_actions_update_profile_inline,
-	.flow_nic_set_hasher_fields_inline = flow_nic_set_hasher_fields_inline,
 	.flow_get_aged_flows_profile_inline = flow_get_aged_flows_profile_inline,
 	/*
 	 * Stats
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
index 169f71ee68..be22c9bcd1 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
@@ -66,10 +66,6 @@ int flow_get_aged_flows_profile_inline(struct flow_eth_dev *dev,
 	uint32_t nb_contexts,
 	struct rte_flow_error *error);
 
-int flow_nic_set_hasher_fields_inline(struct flow_nic_dev *ndev,
-	int hsh_idx,
-	struct nt_eth_rss_conf rss_conf);
-
 /*
  * Stats
  */
diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index d1360cc925..9000264804 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -27,6 +27,7 @@
 #include "ntnic_vfio.h"
 #include "ntnic_mod_reg.h"
 #include "nt_util.h"
+#include "flow_hsh_cfg.h"
 #include "profile_inline/flm_age_queue.h"
 #include "profile_inline/flm_evt_queue.h"
 #include "rte_pmd_ntnic.h"
@@ -1672,7 +1673,7 @@ static int eth_dev_rss_hash_update(struct rte_eth_dev *eth_dev, struct rte_eth_r
 	tmp_rss_conf.algorithm = rss_conf->algorithm;
 
 	tmp_rss_conf.rss_hf = rss_conf->rss_hf;
-	int res = flow_filter_ops->flow_nic_set_hasher_fields(ndev, hsh_idx, tmp_rss_conf);
+	int res = hsh_set(ndev, hsh_idx, tmp_rss_conf);
 
 	if (res == 0) {
 		flow_filter_ops->hw_mod_hsh_rcp_flush(&ndev->be, hsh_idx, 1);
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index 71861c6dea..8db4911262 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -355,10 +355,6 @@ struct profile_inline_ops {
 		struct flow_handle *flow, void *user_data,
 		struct rte_flow_error *error);
 
-	int (*flow_nic_set_hasher_fields_inline)(struct flow_nic_dev *ndev,
-		int hsh_idx,
-		struct nt_eth_rss_conf rss_conf);
-
 	/*
 	 * Stats
 	 */
@@ -467,8 +463,6 @@ struct flow_filter_ops {
 	/*
 	 * Other
 	 */
-	int (*flow_nic_set_hasher_fields)(struct flow_nic_dev *ndev, int hsh_idx,
-		struct nt_eth_rss_conf rss_conf);
 	int (*hw_mod_hsh_rcp_flush)(struct flow_api_backend_s *be, int start_idx, int count);
 
 	int (*flow_get_aged_flows)(struct flow_eth_dev *dev,
-- 
2.45.0


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

* [PATCH v2 26/34] net/ntnic: fix age timeout recalculation into fpga unit
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (24 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 25/34] net/ntnic: refactor RSS implementation Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 27/34] net/ntnic: rework age event generation Serhii Iliushyk
                       ` (8 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

The FPGA scrub T parameter shall be encoded timeout using internal unit,
which is measured in 2^30 nanoseconds. It is approx 1.074 times longer
than age timeout specified in seconds. Internal method
hw_mod_flm_inf_sta_data_update_get() was updated to perform conversion
between age time and internal FPGA scrub T time unit.

Fixes: c0d44442b831 ("net/ntnic: add flow aging event")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c    | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c
index 14dd95a150..5cf8264909 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c
@@ -969,16 +969,22 @@ int hw_mod_flm_inf_sta_data_update_get(struct flow_api_backend_s *be, enum hw_fl
  *
  * (T[7:3] != 0) ? ((8 + T[2:0]) shift-left (T[7:3] - 1)) : T[2:0]
  *
- * The maximum allowed value is 0xEF (127 years).
+ * The maximum allowed value is 0xEF (137 years).
  *
  * Note that this represents a lower bound on the timeout, depending on the flow
  * scanner interval and overall load, the timeout can be substantially longer.
  */
 uint32_t hw_mod_flm_scrub_timeout_decode(uint32_t t_enc)
 {
-	uint8_t t_bits_2_0 = t_enc & 0x07;
-	uint8_t t_bits_7_3 = (t_enc >> 3) & 0x1F;
-	return t_bits_7_3 != 0 ? ((8 + t_bits_2_0) << (t_bits_7_3 - 1)) : t_bits_2_0;
+	uint32_t t_bits_2_0 = t_enc & 0x07;
+	uint32_t t_bits_7_3 = (t_enc >> 3) & 0x1F;
+	uint32_t t_dec = t_bits_7_3 != 0 ? ((8U + t_bits_2_0) << (t_bits_7_3 - 1U))
+		: t_bits_2_0;
+	/* convert internal FPGA scrub time unit into seconds, i.e. 2^30/1e9 is
+	 * approx 1.074 sec per internal unit
+	 */
+	uint64_t t_sec = (uint64_t)t_dec * 1074UL / 1000UL;
+	return t_sec > UINT32_MAX ? UINT32_MAX : (uint32_t)t_sec;
 }
 
 uint32_t hw_mod_flm_scrub_timeout_encode(uint32_t t)
-- 
2.45.0


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

* [PATCH v2 27/34] net/ntnic: rework age event generation
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (25 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 26/34] net/ntnic: fix age timeout recalculation into fpga unit Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 28/34] net/ntnic: fix group print Serhii Iliushyk
                       ` (7 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov

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

Add age event generating only for physical ports.

Fixes: 4033e0539435 ("net/ntnic: add flow meter")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 .../nthw/flow_api/profile_inline/flow_api_profile_inline.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index e5abd372bc..e911860c38 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -479,13 +479,16 @@ static void flm_mtr_read_inf_records(struct flow_eth_dev *dev, uint32_t *data, u
 				struct flow_handle *fh = (struct flow_handle *)flm_h.p;
 				struct flm_age_event_s age_event;
 				uint8_t port;
+				bool is_remote;
 
 				age_event.context = fh->context;
 
-				is_remote_caller(caller_id, &port);
+				is_remote = is_remote_caller(caller_id, &port);
 
 				flm_age_queue_put(caller_id, &age_event);
-				flm_age_event_set(port);
+				/* age events are supported only for physical ports */
+				if (!is_remote)
+					flm_age_event_set(port);
 			}
 			break;
 
-- 
2.45.0


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

* [PATCH v2 28/34] net/ntnic: fix group print
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (26 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 27/34] net/ntnic: rework age event generation Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 29/34] net/ntnic: extend module mapping Serhii Iliushyk
                       ` (6 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev
  Cc: mko-plv, sil-plv, ckm, stephen, Danylo Vodopianov, Oleksandr Kolomeiets

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

Flow dump output was fixed to show original group
number for `jumps` stored in action and match sets.

Fixes: 6f0fe142caed ("net/ntnic: add flow dump")

Signed-off-by: Danylo Vodopianov <dvo-plv@napatech.com>
---
 drivers/net/ntnic/include/flow_api_engine.h   |  2 ++
 drivers/net/ntnic/nthw/flow_api/flow_group.c  | 26 +++++++++++++++++++
 .../profile_inline/flow_api_hw_db_inline.c    | 24 ++++++++++++-----
 3 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h
index 636c53b260..262317002f 100644
--- a/drivers/net/ntnic/include/flow_api_engine.h
+++ b/drivers/net/ntnic/include/flow_api_engine.h
@@ -425,5 +425,7 @@ int flow_group_handle_destroy(void **handle);
 
 int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, uint32_t group_in,
 	uint32_t *group_out);
+int flow_group_translate_get_orig_group(void *handle, uint32_t translated_group,
+	uint32_t *group_orig);
 
 #endif  /* _FLOW_API_ENGINE_H_ */
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_group.c b/drivers/net/ntnic/nthw/flow_api/flow_group.c
index f76986b178..d1fa0193e1 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_group.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_group.c
@@ -14,6 +14,7 @@
 struct group_lookup_entry_s {
 	uint64_t ref_counter;
 	uint32_t *reverse_lookup;
+	uint32_t group_orig;
 };
 
 struct group_handle_s {
@@ -83,6 +84,7 @@ int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, ui
 		if (lookup < group_handle->group_count) {
 			group_handle->lookup_entries[lookup].reverse_lookup = table_ptr;
 			group_handle->lookup_entries[lookup].ref_counter += 1;
+			group_handle->lookup_entries[lookup].group_orig = group_in;
 
 			*table_ptr = lookup;
 
@@ -97,3 +99,27 @@ int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, ui
 	*group_out = lookup;
 	return 0;
 }
+
+int flow_group_translate_get_orig_group(void *handle, uint32_t translated_group,
+	uint32_t *group_orig)
+{
+	struct group_handle_s *group_handle = (struct group_handle_s *)handle;
+	struct group_lookup_entry_s *lookup;
+
+	if (group_handle == NULL || translated_group >= group_handle->group_count)
+		return -1;
+
+	/* Don't translate group 0 */
+	if (translated_group == 0) {
+		*group_orig = 0;
+		return 0;
+	}
+
+	lookup = &group_handle->lookup_entries[translated_group];
+
+	if (lookup->reverse_lookup && lookup->ref_counter > 0) {
+		*group_orig = lookup->group_orig;
+		return 0;
+	}
+	return -1;
+}
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
index 22cbf61b60..278be8b180 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c
@@ -429,9 +429,14 @@ void hw_db_inline_dump(struct flow_nic_dev *ndev, void *db_handle, const struct
 				data->cat.ids, data->km.id1, data->km_ft.id1,
 				data->action_set.ids);
 
-			if (data->jump)
-				fprintf(file, "    Jumps to %d\n", data->jump);
-
+			if (data->jump) {
+				uint32_t group_orig = 0;
+				if (flow_group_translate_get_orig_group(ndev->group_handle,
+					data->jump, &group_orig) < 0)
+					fprintf(file, "    Jumps to %d (encoded)\n", data->jump);
+				else
+					fprintf(file, "    Jumps to %d\n", group_orig);
+			}
 			break;
 		}
 
@@ -440,15 +445,20 @@ void hw_db_inline_dump(struct flow_nic_dev *ndev, void *db_handle, const struct
 					&db->action_set[idxs[i].ids].data;
 			fprintf(file, "  ACTION_SET %d\n", idxs[i].ids);
 
-			if (data->contains_jump)
-				fprintf(file, "    Jumps to %d\n", data->jump);
+			if (data->contains_jump) {
+				uint32_t group_orig = 0;
+				if (flow_group_translate_get_orig_group(ndev->group_handle,
+					data->jump, &group_orig) < 0)
+					fprintf(file, "    Jumps to %d (encoded)\n", data->jump);
 
-			else
+				else
+					fprintf(file, "    Jumps to %d\n", group_orig);
+			} else {
 				fprintf(file,
 					"    COT id %d, QSL id %d, SLC_LR id %d, TPE id %d, HSH id %d, SCRUB id %d\n",
 					data->cot.ids, data->qsl.ids, data->slc_lr.ids,
 					data->tpe.ids, data->hsh.ids, data->scrub.ids);
-
+			}
 			break;
 		}
 
-- 
2.45.0


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

* [PATCH v2 29/34] net/ntnic: extend module mapping
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (27 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 28/34] net/ntnic: fix group print Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 30/34] net/ntnic: refactoring of the FPGA initialization Serhii Iliushyk
                       ` (5 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

FPGA module mapping(to string) was extended with new fpga's modules.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../nthw/supported/nthw_fpga_mod_str_map.c    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
index e8ed7faf0d..459cc724c2 100644
--- a/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
+++ b/drivers/net/ntnic/nthw/supported/nthw_fpga_mod_str_map.c
@@ -6,20 +6,44 @@
 
 #include "nthw_fpga_mod_str_map.h"
 const struct nthw_fpga_mod_str_s sa_nthw_fpga_mod_str_map[] = {
+	{ MOD_CAT, "CAT" },
+	{ MOD_CPY, "CPY" },
+	{ MOD_CSU, "CSU" },
+	{ MOD_DBS, "DBS" },
+	{ MOD_FLM, "FLM" },
 	{ MOD_GFG, "GFG" },
 	{ MOD_GMF, "GMF" },
 	{ MOD_GPIO_PHY, "GPIO_PHY" },
+	{ MOD_HFU, "HFU" },
 	{ MOD_HIF, "HIF" },
+	{ MOD_HSH, "HSH" },
 	{ MOD_I2CM, "I2CM" },
+	{ MOD_IFR, "IFR" },
 	{ MOD_IIC, "IIC" },
+	{ MOD_INS, "INS" },
+	{ MOD_KM, "KM" },
 	{ MOD_MAC_PCS, "MAC_PCS" },
 	{ MOD_PCIE3, "PCIE3" },
+	{ MOD_MAC_RX, "MAC_RX" },
+	{ MOD_MAC_TX, "MAC_TX" },
 	{ MOD_PCI_RD_TG, "PCI_RD_TG" },
 	{ MOD_PCI_WR_TG, "PCI_WR_TG" },
+	{ MOD_PCIE3, "PCIE3" },
+	{ MOD_PDB, "PDB" },
+	{ MOD_QSL, "QSL" },
 	{ MOD_RAC, "RAC" },
+	{ MOD_RMC, "RMC" },
+	{ MOD_RPF, "RPF" },
+	{ MOD_RPL, "RPL" },
+	{ MOD_RPP_LR, "RPP_LR" },
 	{ MOD_RST9563, "RST9563" },
 	{ MOD_SDC, "SDC" },
+	{ MOD_SLC_LR, "SLC_LR" },
+	{ MOD_SLC, "SLC" },
 	{ MOD_STA, "STA" },
 	{ MOD_TSM, "TSM" },
+	{ MOD_TX_CPY, "TX_CPY" },
+	{ MOD_TX_INS, "TX_INS" },
+	{ MOD_TX_RPL, "TX_RPL" },
 	{ 0UL, NULL }
 };
-- 
2.45.0


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

* [PATCH v2 30/34] net/ntnic: refactoring of the FPGA initialization
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (28 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 29/34] net/ntnic: extend module mapping Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 31/34] net/ntnic: remove shutdown thread Serhii Iliushyk
                       ` (4 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Remove unnecessary checks and logs.

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/nthw/core/nthw_fpga.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/net/ntnic/nthw/core/nthw_fpga.c b/drivers/net/ntnic/nthw/core/nthw_fpga.c
index 88641145ec..5ca186209a 100644
--- a/drivers/net/ntnic/nthw/core/nthw_fpga.c
+++ b/drivers/net/ntnic/nthw/core/nthw_fpga.c
@@ -265,18 +265,14 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 	nthw_rac_rab_flush(p_nthw_rac);
 	p_fpga_info->mp_nthw_rac = p_nthw_rac;
 
-	bool included = true;
 	struct nt200a0x_ops *nt200a0x_ops = get_nt200a0x_ops();
 
 	switch (p_fpga_info->n_nthw_adapter_id) {
 	case NT_HW_ADAPTER_ID_NT200A02:
 		if (nt200a0x_ops != NULL)
 			res = nt200a0x_ops->nthw_fpga_nt200a0x_init(p_fpga_info);
-
-		else
-			included = false;
-
 		break;
+
 	default:
 		NT_LOG(ERR, NTHW, "%s: Unsupported HW product id: %d", p_adapter_id_str,
 			p_fpga_info->n_nthw_adapter_id);
@@ -284,12 +280,6 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
 		break;
 	}
 
-	if (!included) {
-		NT_LOG(ERR, NTHW, "%s: NOT INCLUDED HW product: %d", p_adapter_id_str,
-			p_fpga_info->n_nthw_adapter_id);
-		res = -1;
-	}
-
 	if (res) {
 		NT_LOG(ERR, NTHW, "%s: status: 0x%08X", p_adapter_id_str, res);
 		return res;
-- 
2.45.0


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

* [PATCH v2 31/34] net/ntnic: remove shutdown thread
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (29 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 30/34] net/ntnic: refactoring of the FPGA initialization Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 32/34] net/ntnic: add checks for action modify Serhii Iliushyk
                       ` (3 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Remove the shutdown thread and SIGINT handling on the level of PMD

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 drivers/net/ntnic/ntnic_ethdev.c | 63 ++++----------------------------
 1 file changed, 7 insertions(+), 56 deletions(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 9000264804..e65be67c44 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -76,10 +76,6 @@ const rte_thread_attr_t thread_attr = { .priority = RTE_THREAD_PRIORITY_NORMAL }
 
 uint64_t rte_tsc_freq;
 
-static void (*previous_handler)(int sig);
-static rte_thread_t shutdown_tid;
-
-int kill_pmd;
 
 #define ETH_DEV_NTNIC_HELP_ARG "help"
 #define ETH_DEV_NTHW_RXQUEUES_ARG "rxqs"
@@ -480,9 +476,6 @@ static uint16_t eth_dev_rx_scg(void *queue, struct rte_mbuf **bufs, uint16_t nb_
 
 	struct nthw_received_packets hw_recv[MAX_RX_PACKETS];
 
-	if (kill_pmd)
-		return 0;
-
 	if (unlikely(nb_pkts == 0))
 		return 0;
 
@@ -693,9 +686,6 @@ static uint16_t eth_dev_tx_scg(void *queue, struct rte_mbuf **bufs, uint16_t nb_
 	int pkts_sent = 0;
 	uint16_t nb_segs_arr[MAX_TX_PACKETS];
 
-	if (kill_pmd)
-		return 0;
-
 	if (nb_pkts > MAX_TX_PACKETS)
 		nb_pkts = MAX_TX_PACKETS;
 
@@ -2490,51 +2480,6 @@ nthw_pci_dev_deinit(struct rte_eth_dev *eth_dev __rte_unused)
 	return 0;
 }
 
-static void signal_handler_func_int(int sig)
-{
-	if (sig != SIGINT) {
-		signal(sig, previous_handler);
-		raise(sig);
-		return;
-	}
-
-	kill_pmd = 1;
-}
-
-THREAD_FUNC shutdown_thread(void *arg __rte_unused)
-{
-	while (!kill_pmd)
-		nt_os_wait_usec(100 * 1000);
-
-	NT_LOG_DBGX(DBG, NTNIC, "Shutting down because of ctrl+C");
-
-	signal(SIGINT, previous_handler);
-	raise(SIGINT);
-
-	return THREAD_RETURN;
-}
-
-static int init_shutdown(void)
-{
-	NT_LOG(DBG, NTNIC, "Starting shutdown handler");
-	kill_pmd = 0;
-	previous_handler = signal(SIGINT, signal_handler_func_int);
-	int ret = THREAD_CREATE(&shutdown_tid, shutdown_thread, NULL);
-	if (ret != 0) {
-		NT_LOG(ERR, NTNIC, "Failed to create shutdown thread, error code: %d", ret);
-		return -1;
-	}
-	/*
-	 * 1 time calculation of 1 sec stat update rtc cycles to prevent stat poll
-	 * flooding by OVS from multiple virtual port threads - no need to be precise
-	 */
-	uint64_t now_rtc = rte_get_tsc_cycles();
-	nt_os_wait_usec(10 * 1000);
-	rte_tsc_freq = 100 * (rte_get_tsc_cycles() - now_rtc);
-
-	return 0;
-}
-
 static int
 nthw_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
@@ -2577,7 +2522,13 @@ nthw_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 	ret = nthw_pci_dev_init(pci_dev);
 
-	init_shutdown();
+	/*
+	 * 1 time calculation of 1 sec stat update rtc cycles to prevent stat poll
+	 * flooding by OVS from multiple virtual port threads - no need to be precise
+	 */
+	uint64_t now_rtc = rte_get_tsc_cycles();
+	nt_os_wait_usec(10 * 1000);
+	rte_tsc_freq = 100 * (rte_get_tsc_cycles() - now_rtc);
 
 	NT_LOG_DBGX(DBG, NTNIC, "leave: ret=%d", ret);
 	return ret;
-- 
2.45.0


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

* [PATCH v2 32/34] net/ntnic: add checks for action modify
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (30 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 31/34] net/ntnic: remove shutdown thread Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 33/34] net/ntnic: add IFR DROP counter Serhii Iliushyk
                       ` (2 subsequent siblings)
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Following checks were added for `action modify`:
* range check to trigger an error in case that value is too large
* check for unsupported types of action modify for group 0

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../profile_inline/flow_api_profile_inline.c  | 89 ++++++++++++++++---
 1 file changed, 79 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index e911860c38..fe72865140 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -2990,7 +2990,36 @@ static int interpret_flow_elements(const struct flow_eth_dev *dev,
 	return 0;
 }
 
-static void copy_fd_to_fh_flm(struct flow_handle *fh, const struct nic_flow_def *fd,
+static bool has_only_valid_bits_set(const uint8_t *byte_array, const uint16_t byte_array_len,
+	uint16_t bit_len)
+{
+	if (byte_array_len * 8 < bit_len)
+		bit_len = byte_array_len * 8;
+
+	uint8_t mask;
+	uint16_t byte;
+
+	for (byte = 0; byte < byte_array_len; byte++) {
+		if (bit_len >= 8) {
+			bit_len -= 8;
+			mask = 0x00;
+
+		} else if (bit_len > 0) {
+			mask = 0xff >> bit_len << bit_len;
+			bit_len = 0;
+
+		} else {
+			mask = 0xFF;
+		}
+
+		if (byte_array[byte] & mask)
+			return false;
+	}
+
+	return true;
+}
+
+static int copy_fd_to_fh_flm(struct flow_handle *fh, const struct nic_flow_def *fd,
 	const uint32_t *packet_data, uint32_t flm_key_id, uint32_t flm_ft,
 	uint16_t rpl_ext_ptr, uint32_t flm_scrub __rte_unused, uint32_t priority)
 {
@@ -3056,23 +3085,47 @@ static void copy_fd_to_fh_flm(struct flow_handle *fh, const struct nic_flow_def
 		switch (fd->modify_field[i].select) {
 		case CPY_SELECT_DSCP_IPV4:
 		case CPY_SELECT_DSCP_IPV6:
+			if (!has_only_valid_bits_set(fd->modify_field[i].value8, 16, 8)) {
+				NT_LOG(ERR, FILTER, "IP DSCP value is out of the range");
+				return -1;
+			}
+
 			fh->flm_dscp = fd->modify_field[i].value8[0];
 			break;
 
 		case CPY_SELECT_RQI_QFI:
+			if (!has_only_valid_bits_set(fd->modify_field[i].value8, 16, 6)) {
+				NT_LOG(ERR, FILTER, "GTPU QFI value is out of the range");
+				return -1;
+			}
+
 			fh->flm_rqi = (fd->modify_field[i].value8[0] >> 6) & 0x1;
 			fh->flm_qfi = fd->modify_field[i].value8[0] & 0x3f;
 			break;
 
 		case CPY_SELECT_IPV4:
+			if (!has_only_valid_bits_set(fd->modify_field[i].value8, 16, 32)) {
+				NT_LOG(ERR, FILTER, "IPv4 address value is out of the range");
+				return -1;
+			}
+
 			fh->flm_nat_ipv4 = ntohl(fd->modify_field[i].value32[0]);
 			break;
 
 		case CPY_SELECT_PORT:
+			if (!has_only_valid_bits_set(fd->modify_field[i].value8, 16, 16)) {
+				NT_LOG(ERR, FILTER, "NAT port value is out of the range");
+				return -1;
+			}
+
 			fh->flm_nat_port = ntohs(fd->modify_field[i].value16[0]);
 			break;
 
 		case CPY_SELECT_TEID:
+			if (!has_only_valid_bits_set(fd->modify_field[i].value8, 16, 32)) {
+				NT_LOG(ERR, FILTER, "GTPU TEID value is out of the range");
+				return -1;
+			}
 			fh->flm_teid = ntohl(fd->modify_field[i].value32[0]);
 			break;
 
@@ -3085,6 +3138,8 @@ static void copy_fd_to_fh_flm(struct flow_handle *fh, const struct nic_flow_def
 
 	fh->flm_mtu_fragmentation_recipe = fd->flm_mtu_fragmentation_recipe;
 	fh->context = fd->age.context;
+
+	return 0;
 }
 
 static int convert_fh_to_fh_flm(struct flow_handle *fh, const uint32_t *packet_data,
@@ -3113,8 +3168,10 @@ static int convert_fh_to_fh_flm(struct flow_handle *fh, const uint32_t *packet_d
 	for (int i = 0; i < RES_COUNT; ++i)
 		fh->flm_db_idxs[i] = fh_copy.db_idxs[i];
 
-	copy_fd_to_fh_flm(fh, fd, packet_data, flm_key_id, flm_ft, rpl_ext_ptr, flm_scrub,
-		priority);
+	if (copy_fd_to_fh_flm(fh, fd, packet_data, flm_key_id, flm_ft, rpl_ext_ptr,
+		flm_scrub, priority) < 0) {
+		return -1;
+	}
 
 	free(fd);
 
@@ -3476,8 +3533,11 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n
 		}
 
 		/* Program flow */
-		convert_fh_to_fh_flm(fh, packet_data, flm_idx.id1 + 2, flm_ft, flm_rpl_ext_ptr,
-			flm_scrub, attr->priority & 0x3);
+		if (convert_fh_to_fh_flm(fh, packet_data, flm_idx.id1 + 2, flm_ft, flm_rpl_ext_ptr,
+				flm_scrub, attr->priority & 0x3) != 0) {
+			flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error);
+			goto error_out;
+		}
 		flm_flow_programming(fh, NT_FLM_OP_LEARN);
 
 		nic_insert_flow_flm(dev->ndev, fh);
@@ -3512,6 +3572,13 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n
 			/* Action Set doesn't contain jump */
 			action_set_data.contains_jump = 0;
 
+			/* Group 0 supports only modify action for TTL/Hop limit. */
+			if (fd->modify_field_count > 0) {
+				NT_LOG(ERR, FILTER, "Unsupported MODIFY ACTION for group 0");
+				flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error);
+				goto error_out;
+			}
+
 			/* Setup COT */
 			struct hw_db_inline_cot_data cot_data = {
 				.matcher_color_contrib = 0,
@@ -5179,11 +5246,13 @@ struct flow_handle *flow_async_create_profile_inline(struct flow_eth_dev *dev,
 		fh->caller_id = template_table->caller_id;
 		fh->user_data = user_data;
 
-		copy_fd_to_fh_flm(fh, fd, packet_data, pattern_action_pair->flm_key_id,
-			pattern_action_pair->flm_ft,
-			pattern_action_pair->flm_rpl_ext_ptr,
-			pattern_action_pair->flm_scrub_prof,
-			template_table->attr.priority & 0x3);
+		if (copy_fd_to_fh_flm(fh, fd, packet_data, pattern_action_pair->flm_key_id,
+				pattern_action_pair->flm_ft,
+				pattern_action_pair->flm_rpl_ext_ptr,
+				pattern_action_pair->flm_scrub_prof,
+				template_table->attr.priority & 0x3) != 0) {
+			goto err_exit;
+		}
 
 		free(fd);
 
-- 
2.45.0


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

* [PATCH v2 33/34] net/ntnic: add IFR DROP counter
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (31 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 32/34] net/ntnic: add checks for action modify Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 10:45     ` [PATCH v2 34/34] net/ntnic: remove tag EXPERIMENTAL Serhii Iliushyk
  2025-02-05 16:51     ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Stephen Hemminger
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen

Support for IP Fragmenter DROP counter to display number of packets
dropped due to size larger than MTU.
NOTE: Frames are dropped only in case that both IPV4_EN and IPV4_DF_DROP
are set to one (resp. their IPV6 counterparts).

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 .../net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c |  9 +++
 drivers/net/ntnic/include/flow_api.h          |  1 +
 drivers/net/ntnic/include/hw_mod_backend.h    |  8 +++
 drivers/net/ntnic/include/hw_mod_tpe_v3.h     |  5 ++
 drivers/net/ntnic/include/ntnic_stat.h        |  9 +++
 drivers/net/ntnic/nthw/flow_api/flow_api.c    | 16 +++++
 .../nthw/flow_api/flow_backend/flow_backend.c | 28 ++++++++-
 .../ntnic/nthw/flow_api/hw_mod/hw_mod_tpe.c   | 58 ++++++++++++++++++-
 .../profile_inline/flow_api_profile_inline.c  | 19 ++++++
 .../profile_inline/flow_api_profile_inline.h  |  4 ++
 .../ntnic/nthw/flow_filter/flow_nthw_ifr.c    | 32 ++++++++++
 .../ntnic/nthw/flow_filter/flow_nthw_ifr.h    | 15 ++++-
 drivers/net/ntnic/nthw/stat/nthw_stat.c       |  2 +
 drivers/net/ntnic/ntnic_mod_reg.h             |  5 ++
 14 files changed, 208 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
index 2add43639a..2f1e12f891 100644
--- a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
+++ b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c
@@ -100,6 +100,8 @@ static int nt4ga_stat_init(struct adapter_info_s *p_adapter_info)
 
 		p_nt4ga_stat->mn_rx_ports = p_nthw_stat->m_nb_rx_ports;
 		p_nt4ga_stat->mn_tx_ports = p_nthw_stat->m_nb_tx_ports;
+
+		p_nt4ga_stat->mn_ifr_counters = p_nthw_stat->m_nb_ifr_counters;
 	}
 
 	return 0;
@@ -205,6 +207,9 @@ static int nt4ga_stat_setup(struct adapter_info_s *p_adapter_info)
 		p_nt4ga_stat->mp_stat_structs_flm->max_lps =
 			nthw_fpga_get_product_param(p_adapter_info->fpga_info.mp_fpga,
 				NT_FLM_LOAD_LPS_MAX, 0);
+
+		p_nt4ga_stat->mp_stat_structs_ifr =
+			calloc(1, sizeof(struct ifr_counters) * p_nt4ga_stat->mn_ifr_counters);
 	}
 
 	p_nt4ga_stat->mp_port_load =
@@ -556,6 +561,10 @@ static int nt4ga_stat_collect_cap_v1_stats(struct adapter_info_s *p_adapter_info
 	flow_filter_ops->flow_get_flm_stats(ndev, (uint64_t *)p_nt4ga_stat->mp_stat_structs_flm,
 		sizeof(struct flm_counters_v1) / sizeof(uint64_t));
 
+	/* Update and get IFR stats */
+	flow_filter_ops->flow_get_ifr_stats(ndev, (uint64_t *)p_nt4ga_stat->mp_stat_structs_ifr,
+		p_nt4ga_stat->mn_ifr_counters - 1);
+
 	/*
 	 * Calculate correct load values:
 	 * rpp = nthw_fpga_get_product_param(p_fpga, NT_RPP_PER_PS, 0);
diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h
index 9201b8a3ae..7f6aa82ee0 100644
--- a/drivers/net/ntnic/include/flow_api.h
+++ b/drivers/net/ntnic/include/flow_api.h
@@ -230,5 +230,6 @@ int flow_nic_ref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, i
 int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);
 
 int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
+int flow_get_ifr_stats(struct flow_nic_dev *ndev, uint64_t *data, uint8_t port_count);
 
 #endif
diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h
index 4061d3f9e5..594bdab2a6 100644
--- a/drivers/net/ntnic/include/hw_mod_backend.h
+++ b/drivers/net/ntnic/include/hw_mod_backend.h
@@ -899,6 +899,7 @@ enum hw_tpe_e {
 	HW_TPE_IFR_RCP_IPV6_EN,
 	HW_TPE_IFR_RCP_IPV6_DROP,
 	HW_TPE_IFR_RCP_MTU,
+	HW_TPE_IFR_COUNTERS_DROP,
 	HW_TPE_INS_RCP_DYN,
 	HW_TPE_INS_RCP_OFS,
 	HW_TPE_INS_RCP_LEN,
@@ -959,6 +960,12 @@ int hw_mod_tpe_ifr_rcp_flush(struct flow_api_backend_s *be, int start_idx, int c
 int hw_mod_tpe_ifr_rcp_set(struct flow_api_backend_s *be, enum hw_tpe_e field, int index,
 	uint32_t value);
 
+int hw_mod_tpe_ifr_counters_update(struct flow_api_backend_s *be, int start_idx, int count);
+int hw_mod_tpe_ifr_counters_set(struct flow_api_backend_s *be, enum hw_tpe_e field, int index,
+	uint32_t value);
+int hw_mod_tpe_ifr_counters_get(struct flow_api_backend_s *be, enum hw_tpe_e field, int index,
+	uint32_t *value);
+
 int hw_mod_tpe_ins_rcp_flush(struct flow_api_backend_s *be, int start_idx, int count);
 int hw_mod_tpe_ins_rcp_set(struct flow_api_backend_s *be, enum hw_tpe_e field, int index,
 	uint32_t value);
@@ -1124,6 +1131,7 @@ struct flow_api_backend_ops {
 	int (*tpe_rpp_rcp_flush)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
 	int (*tpe_rpp_ifr_rcp_flush)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
 	int (*tpe_ifr_rcp_flush)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
+	int (*tpe_ifr_counters_update)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
 	int (*tpe_ins_rcp_flush)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
 	int (*tpe_rpl_rcp_flush)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
 	int (*tpe_rpl_ext_flush)(void *dev, const struct tpe_func_s *tpe, int index, int cnt);
diff --git a/drivers/net/ntnic/include/hw_mod_tpe_v3.h b/drivers/net/ntnic/include/hw_mod_tpe_v3.h
index 87710d8b35..9137e69256 100644
--- a/drivers/net/ntnic/include/hw_mod_tpe_v3.h
+++ b/drivers/net/ntnic/include/hw_mod_tpe_v3.h
@@ -104,6 +104,10 @@ struct tpe_v2_ifr_v1_rcp_s {
 	uint32_t mtu;
 };
 
+struct tpe_v2_ifr_v1_counters_s {
+	uint32_t drop;
+};
+
 struct hw_mod_tpe_v3_s {
 	struct tpe_v1_rpp_v0_rcp_s *rpp_rcp;
 
@@ -121,6 +125,7 @@ struct hw_mod_tpe_v3_s {
 
 	struct tpe_v2_rpp_v1_ifr_rcp_s *rpp_ifr_rcp;
 	struct tpe_v2_ifr_v1_rcp_s *ifr_rcp;
+	struct tpe_v2_ifr_v1_counters_s *ifr_counters;
 };
 
 #endif	/* _HW_MOD_TPE_V3_H_ */
diff --git a/drivers/net/ntnic/include/ntnic_stat.h b/drivers/net/ntnic/include/ntnic_stat.h
index 4d4affa3cf..1b53f6c347 100644
--- a/drivers/net/ntnic/include/ntnic_stat.h
+++ b/drivers/net/ntnic/include/ntnic_stat.h
@@ -46,6 +46,7 @@ struct nthw_stat {
 	int m_nb_counters;
 
 	int m_nb_rpp_per_ps;
+	int m_nb_ifr_counters;
 
 	nthw_field_t *mp_fld_dma_ena;
 	nthw_field_t *mp_fld_cnt_clear;
@@ -204,6 +205,10 @@ struct flm_counters_v1 {
 	uint64_t max_aps;
 };
 
+struct ifr_counters {
+	uint64_t drop;
+};
+
 struct nt4ga_stat_s {
 	nthw_stat_t *mp_nthw_stat;
 	nthw_rmc_t *mp_nthw_rmc;
@@ -220,6 +225,8 @@ struct nt4ga_stat_s {
 	int mn_rx_ports;
 	int mn_tx_ports;
 
+	int mn_ifr_counters;
+
 	struct color_counters *mp_stat_structs_color;
 	/* For calculating increments between stats polls */
 	struct color_counters a_stat_structs_color_base[NT_MAX_COLOR_FLOW_STATS];
@@ -236,6 +243,8 @@ struct nt4ga_stat_s {
 	int flm_stat_ver;
 	struct flm_counters_v1 *mp_stat_structs_flm;
 
+	struct ifr_counters *mp_stat_structs_ifr;
+
 	/* Rx/Tx totals: */
 	uint64_t n_totals_reset_timestamp;	/* timestamp for last totals reset */
 
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index 857051fe14..022d7a1c0e 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -1226,6 +1226,21 @@ int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size)
 	return -1;
 }
 
+int flow_get_ifr_stats(struct flow_nic_dev *ndev, uint64_t *data, uint8_t port_count)
+{
+	const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
+
+	if (profile_inline_ops == NULL)
+		return -1;
+
+	if (ndev->flow_profile == FLOW_ETH_DEV_PROFILE_INLINE) {
+		return profile_inline_ops->flow_get_ifr_stats_profile_inline(ndev, data,
+				port_count);
+	}
+
+	return -1;
+}
+
 static const struct flow_filter_ops ops = {
 	.flow_filter_init = flow_filter_init,
 	.flow_filter_done = flow_filter_done,
@@ -1242,6 +1257,7 @@ static const struct flow_filter_ops ops = {
 	.flow_actions_update = flow_actions_update,
 	.flow_dev_dump = flow_dev_dump,
 	.flow_get_flm_stats = flow_get_flm_stats,
+	.flow_get_ifr_stats = flow_get_ifr_stats,
 	.flow_get_aged_flows = flow_get_aged_flows,
 
 	/*
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_backend/flow_backend.c b/drivers/net/ntnic/nthw/flow_api/flow_backend/flow_backend.c
index a50055ce2b..9f7ee5decb 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_backend/flow_backend.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_backend/flow_backend.c
@@ -1584,7 +1584,7 @@ static bool tpe_get_present(void *be_dev)
 {
 	struct backend_dev_s *be = (struct backend_dev_s *)be_dev;
 	return be->p_csu_nthw != NULL && be->p_hfu_nthw != NULL && be->p_rpp_lr_nthw != NULL &&
-		be->p_tx_cpy_nthw != NULL && be->p_tx_ins_nthw != NULL &&
+		be->p_ifr_nthw != NULL && be->p_tx_cpy_nthw != NULL && be->p_tx_ins_nthw != NULL &&
 		be->p_tx_rpl_nthw != NULL;
 }
 
@@ -1717,6 +1717,31 @@ static int tpe_ifr_rcp_flush(void *be_dev, const struct tpe_func_s *ifr, int ind
 	return res;
 }
 
+static int tpe_ifr_counters_update(void *be_dev, const struct tpe_func_s *ifr, int index, int cnt)
+{
+	int res = 0;
+	int i = 0;
+	struct backend_dev_s *be = (struct backend_dev_s *)be_dev;
+	CHECK_DEBUG_ON(be, ifr, be->p_ifr_nthw);
+
+	if (ifr->ver >= 2) {
+		ifr_nthw_counters_cnt(be->p_ifr_nthw, 1);
+
+		for (i = 0; i < cnt; i++) {
+			ifr_nthw_counters_select(be->p_ifr_nthw, index + i);
+			ifr_nthw_counters_update(be->p_ifr_nthw);
+			ifr_nthw_counters_drop(be->p_ifr_nthw,
+				&ifr->v3.ifr_counters[index + i].drop, 1);
+		}
+
+	} else {
+		res = -1;
+	}
+
+	CHECK_DEBUG_OFF(ifr, be->p_ifr_nthw);
+	return res;
+}
+
 static int tpe_ins_rcp_flush(void *be_dev, const struct tpe_func_s *tx_ins, int index, int cnt)
 {
 	struct backend_dev_s *be = (struct backend_dev_s *)be_dev;
@@ -2062,6 +2087,7 @@ const struct flow_api_backend_ops flow_be_iface = {
 	tpe_rpp_rcp_flush,
 	tpe_rpp_ifr_rcp_flush,
 	tpe_ifr_rcp_flush,
+	tpe_ifr_counters_update,
 	tpe_ins_rcp_flush,
 	tpe_rpl_rcp_flush,
 	tpe_rpl_ext_flush,
diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_tpe.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_tpe.c
index 2c3ed2355b..0df5b9cf00 100644
--- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_tpe.c
+++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_tpe.c
@@ -69,11 +69,13 @@ int hw_mod_tpe_alloc(struct flow_api_backend_s *be)
 
 	switch (_VER_) {
 	case 3:
-		if (!callocate_mod((struct common_func_s *)&be->tpe, 10, &be->tpe.v3.rpp_rcp,
+		if (!callocate_mod((struct common_func_s *)&be->tpe, 11, &be->tpe.v3.rpp_rcp,
 				be->tpe.nb_rcp_categories, sizeof(struct tpe_v1_rpp_v0_rcp_s),
 				&be->tpe.v3.rpp_ifr_rcp, be->tpe.nb_ifr_categories,
 				sizeof(struct tpe_v2_rpp_v1_ifr_rcp_s), &be->tpe.v3.ifr_rcp,
 				be->tpe.nb_ifr_categories, sizeof(struct tpe_v2_ifr_v1_rcp_s),
+				&be->tpe.v3.ifr_counters, be->tpe.nb_ifr_categories,
+				sizeof(struct tpe_v2_ifr_v1_counters_s),
 
 				&be->tpe.v3.ins_rcp, be->tpe.nb_rcp_categories,
 				sizeof(struct tpe_v1_ins_v1_rcp_s),
@@ -131,6 +133,7 @@ int hw_mod_tpe_reset(struct flow_api_backend_s *be)
 	err |= hw_mod_tpe_csu_rcp_flush(be, 0, ALL_ENTRIES);
 	err |= hw_mod_tpe_rpp_ifr_rcp_flush(be, 0, ALL_ENTRIES);
 	err |= hw_mod_tpe_ifr_rcp_flush(be, 0, ALL_ENTRIES);
+	err |= hw_mod_tpe_ifr_counters_update(be, 0, ALL_ENTRIES);
 
 	return err;
 }
@@ -358,6 +361,59 @@ int hw_mod_tpe_ifr_rcp_set(struct flow_api_backend_s *be, enum hw_tpe_e field, i
 	return hw_mod_tpe_ifr_rcp_mod(be, field, index, &value, 0);
 }
 
+/*
+ * IFR_COUNTER
+ */
+
+int hw_mod_tpe_ifr_counters_update(struct flow_api_backend_s *be, int start_idx, int count)
+{
+	if (count == ALL_ENTRIES)
+		count = be->tpe.nb_ifr_categories;
+
+	if ((unsigned int)(start_idx + count) > be->tpe.nb_ifr_categories)
+		return INDEX_TOO_LARGE;
+
+	return be->iface->tpe_ifr_counters_update(be->be_dev, &be->tpe, start_idx, count);
+}
+
+static int hw_mod_tpe_ifr_counters_mod(struct flow_api_backend_s *be, enum hw_tpe_e field,
+	uint32_t index, uint32_t *value, int get)
+{
+	if (index >= be->tpe.nb_ifr_categories)
+		return INDEX_TOO_LARGE;
+
+	switch (_VER_) {
+	case 3:
+		switch (field) {
+		case HW_TPE_IFR_COUNTERS_DROP:
+			GET_SET(be->tpe.v3.ifr_counters[index].drop, value);
+			break;
+
+		default:
+			return UNSUP_FIELD;
+		}
+
+		break;
+
+	default:
+		return UNSUP_VER;
+	}
+
+	return 0;
+}
+
+int hw_mod_tpe_ifr_counters_set(struct flow_api_backend_s *be, enum hw_tpe_e field, int index,
+	uint32_t value)
+{
+	return hw_mod_tpe_ifr_counters_mod(be, field, index, &value, 0);
+}
+
+int hw_mod_tpe_ifr_counters_get(struct flow_api_backend_s *be, enum hw_tpe_e field, int index,
+	uint32_t *value)
+{
+	return hw_mod_tpe_ifr_counters_mod(be, field, index, value, 1);
+}
+
 /*
  * INS_RCP
  */
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index fe72865140..2cd2eab5cb 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -4715,6 +4715,24 @@ int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data,
 	return 0;
 }
 
+int flow_get_ifr_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data,
+	uint8_t port_count)
+{
+	/* IFR RCP 0 is reserved, port counters start from record 1 */
+	hw_mod_tpe_ifr_counters_update(&ndev->be, 1, port_count);
+	uint8_t i = 0;
+
+	for (i = 0; i < port_count; ++i) {
+		uint8_t ifr_mtu_recipe = convert_port_to_ifr_mtu_recipe(i);
+		uint32_t drop_cnt = 0;
+		hw_mod_tpe_ifr_counters_get(&ndev->be, HW_TPE_IFR_COUNTERS_DROP, ifr_mtu_recipe,
+			&drop_cnt);
+		data[i] = data[i] + drop_cnt;
+	}
+
+	return 0;
+}
+
 int flow_set_mtu_inline(struct flow_eth_dev *dev, uint32_t port, uint16_t mtu)
 {
 	if (port >= 255)
@@ -5338,6 +5356,7 @@ static const struct profile_inline_ops ops = {
 	 * Stats
 	 */
 	.flow_get_flm_stats_profile_inline = flow_get_flm_stats_profile_inline,
+	.flow_get_ifr_stats_profile_inline = flow_get_ifr_stats_profile_inline,
 	.flow_info_get_profile_inline = flow_info_get_profile_inline,
 	.flow_configure_profile_inline = flow_configure_profile_inline,
 	.flow_pattern_template_create_profile_inline = flow_pattern_template_create_profile_inline,
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
index be22c9bcd1..98aba07515 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
@@ -72,6 +72,10 @@ int flow_get_aged_flows_profile_inline(struct flow_eth_dev *dev,
 
 int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
 
+int flow_get_ifr_stats_profile_inline(struct flow_nic_dev *ndev,
+	uint64_t *data,
+	uint8_t port_count);
+
 /*
  * RTE flow asynchronous operations functions
  */
diff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c
index 11b6b5e5b8..45f2047916 100644
--- a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c
+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c
@@ -69,6 +69,13 @@ int ifr_nthw_init(struct ifr_nthw *p, nthw_fpga_t *p_fpga, int n_instance)
 	p->mp_df_buf_data_fifo_dat =
 		nthw_register_get_field(p->mp_df_buf_data, IFR_DF_BUF_DATA_FIFO_DAT);
 
+	p->mp_counters_ctrl = nthw_module_get_register(p->m_ifr, IFR_COUNTERS_CTRL);
+	p->mp_counters_addr = nthw_register_get_field(p->mp_counters_ctrl, IFR_COUNTERS_CTRL_ADR);
+	p->mp_counters_cnt = nthw_register_get_field(p->mp_counters_ctrl, IFR_COUNTERS_CTRL_CNT);
+
+	p->mp_counters_data = nthw_module_get_register(p->m_ifr, IFR_COUNTERS_DATA);
+	p->mp_counters_drop = nthw_register_get_field(p->mp_counters_data, IFR_COUNTERS_DATA_DROP);
+
 	return 0;
 }
 
@@ -121,3 +128,28 @@ void ifr_nthw_rcp_flush(const struct ifr_nthw *p)
 	nthw_register_flush(p->mp_rcp_ctrl, 1);
 	nthw_register_flush(p->mp_rcp_data, 1);
 }
+
+void ifr_nthw_counters_select(const struct ifr_nthw *p, uint32_t val)
+{
+	assert(p->mp_counters_addr);
+	nthw_field_set_val32(p->mp_counters_addr, val);
+}
+
+void ifr_nthw_counters_cnt(const struct ifr_nthw *p, uint32_t val)
+{
+	assert(p->mp_counters_cnt);
+	nthw_field_set_val32(p->mp_counters_cnt, val);
+}
+
+void ifr_nthw_counters_drop(const struct ifr_nthw *p, uint32_t *val, int get)
+{
+	if (get)
+		*val = nthw_field_get_val32(p->mp_counters_drop);
+}
+
+void ifr_nthw_counters_update(const struct ifr_nthw *p)
+{
+	assert(p->mp_counters_data);
+	nthw_register_flush(p->mp_counters_ctrl, 1);
+	nthw_register_update(p->mp_counters_data);
+}
diff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h
index 6751a599aa..4763333765 100644
--- a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h
+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h
@@ -33,6 +33,13 @@ struct ifr_nthw {
 
 	nthw_register_t *mp_df_buf_data;
 	nthw_field_t *mp_df_buf_data_fifo_dat;
+
+	nthw_register_t *mp_counters_ctrl;
+	nthw_field_t *mp_counters_addr;
+	nthw_field_t *mp_counters_cnt;
+
+	nthw_register_t *mp_counters_data;
+	nthw_field_t *mp_counters_drop;
 };
 
 struct ifr_nthw *ifr_nthw_new(void);
@@ -41,7 +48,7 @@ int ifr_nthw_init(struct ifr_nthw *p, nthw_fpga_t *p_fpga, int n_instance);
 int ifr_nthw_setup(struct ifr_nthw *p, int n_idx, int n_idx_cnt);
 void ifr_nthw_set_debug_mode(struct ifr_nthw *p, unsigned int n_debug_mode);
 
-/* IFR */
+/* IFR RCP */
 void ifr_nthw_rcp_select(const struct ifr_nthw *p, uint32_t val);
 void ifr_nthw_rcp_cnt(const struct ifr_nthw *p, uint32_t val);
 void ifr_nthw_rcp_ipv4_en(const struct ifr_nthw *p, uint32_t val);
@@ -51,4 +58,10 @@ void ifr_nthw_rcp_ipv6_drop(const struct ifr_nthw *p, uint32_t val);
 void ifr_nthw_rcp_mtu(const struct ifr_nthw *p, uint32_t val);
 void ifr_nthw_rcp_flush(const struct ifr_nthw *p);
 
+/* IFR Counters */
+void ifr_nthw_counters_select(const struct ifr_nthw *p, uint32_t val);
+void ifr_nthw_counters_cnt(const struct ifr_nthw *p, uint32_t val);
+void ifr_nthw_counters_drop(const struct ifr_nthw *p, uint32_t *val, int get);
+void ifr_nthw_counters_update(const struct ifr_nthw *p);
+
 #endif	/* __FLOW_NTHW_IFR_H__ */
diff --git a/drivers/net/ntnic/nthw/stat/nthw_stat.c b/drivers/net/ntnic/nthw/stat/nthw_stat.c
index b0db7b1984..afa24fd3a9 100644
--- a/drivers/net/ntnic/nthw/stat/nthw_stat.c
+++ b/drivers/net/ntnic/nthw/stat/nthw_stat.c
@@ -199,6 +199,8 @@ int nthw_stat_init(nthw_stat_t *p, nthw_fpga_t *p_fpga, int n_instance)
 
 	p->m_nb_rpp_per_ps = nthw_fpga_get_product_param(p_fpga, NT_RPP_PER_PS, 0);
 
+	p->m_nb_ifr_counters = nthw_fpga_get_product_param(p_fpga, NT_TX_MTU_PROFILE_IFR, 0);
+
 	p->m_nb_tx_ports = nthw_fpga_get_product_param(p_fpga, NT_TX_PORTS, 0);
 	p->m_rx_port_replicate = nthw_fpga_get_product_param(p_fpga, NT_RX_PORT_REPLICATE, 0);
 
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index 8db4911262..bddae823c8 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -362,6 +362,10 @@ struct profile_inline_ops {
 		uint64_t *data,
 		uint64_t size);
 
+	int (*flow_get_ifr_stats_profile_inline)(struct flow_nic_dev *ndev,
+		uint64_t *data,
+		uint8_t port_count);
+
 	/*
 	 * NT Flow FLM queue API
 	 */
@@ -459,6 +463,7 @@ struct flow_filter_ops {
 		struct rte_flow_error *error);
 
 	int (*flow_get_flm_stats)(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
+	int (*flow_get_ifr_stats)(struct flow_nic_dev *ndev, uint64_t *data, uint8_t port_count);
 
 	/*
 	 * Other
-- 
2.45.0


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

* [PATCH v2 34/34] net/ntnic: remove tag EXPERIMENTAL
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (32 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 33/34] net/ntnic: add IFR DROP counter Serhii Iliushyk
@ 2025-02-05 10:45     ` Serhii Iliushyk
  2025-02-05 16:51     ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Stephen Hemminger
  34 siblings, 0 replies; 72+ messages in thread
From: Serhii Iliushyk @ 2025-02-05 10:45 UTC (permalink / raw)
  To: dev; +Cc: mko-plv, sil-plv, ckm, stephen, Thomas Monjalon

Since nitnic PMD driver for is fully added and verified,
the tag EXPERIMENTAL may be removed

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index b86cdd266b..b04951de85 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -890,7 +890,7 @@ F: drivers/net/octeon_ep/
 F: doc/guides/nics/features/octeon_ep.ini
 F: doc/guides/nics/octeon_ep.rst
 
-Napatech ntnic - EXPERIMENTAL
+Napatech ntnic
 M: Christian Koue Muf <ckm@napatech.com>
 M: Serhii Iliushyk <sil-plv@napatech.com>
 F: drivers/net/ntnic/
-- 
2.45.0


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

* Re: [PATCH v2 00/34] net/ntnic: bugfixes and refactoring
  2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
                       ` (33 preceding siblings ...)
  2025-02-05 10:45     ` [PATCH v2 34/34] net/ntnic: remove tag EXPERIMENTAL Serhii Iliushyk
@ 2025-02-05 16:51     ` Stephen Hemminger
  34 siblings, 0 replies; 72+ messages in thread
From: Stephen Hemminger @ 2025-02-05 16:51 UTC (permalink / raw)
  To: Serhii Iliushyk; +Cc: dev, mko-plv, ckm

On Wed,  5 Feb 2025 11:45:09 +0100
Serhii Iliushyk <sil-plv@napatech.com> wrote:

> This patch set addresses fixing issues in the ntnic PMD driver.
> 
> Changes in this patch:
> 
> The issues detected by the Coverity Scan tool.
> The problems that were detected by the internal tests.
> Fix for Bug 1622: ntnic: using signals and threads:
> https://bugs.dpdk.org/show_bug.cgi?id=1622.
>   The handling of signals within the PMD driver was removed.
>   For manipulation with all threads dedicated EAL API
>     (rte_thread_create_internal_control) is used.
>   Product by design requires usage of threads inside PMD driver.

Do any of these patches need to be backported to stable versions of DPDK?

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

end of thread, other threads:[~2025-02-05 16:51 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-21 17:07 [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 01/31] net/ntnic: fix index verification Serhii Iliushyk
2025-02-05 10:45   ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 01/34] net/ntnic: fix index verification Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 02/34] net/ntnic: add thread check return code Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 03/34] net/ntnic: add return code handling Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 04/34] net/ntnic: add array index verification Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 05/34] net/ntnic: fix realloc memory leak Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 06/34] net/ntnic: fix array index verification Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 07/34] net/ntnic: add var definition transparently Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 08/34] net/ntnic: add proper var freed Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 09/34] net/ntnic: remove unused code Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 10/34] net/ntnic: fix potentially overflow Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 11/34] net/ntnic: add null checking Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 12/34] net/ntnic: fix overflow issue Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 13/34] net/ntnic: fix untrusted loop bound Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 14/34] net/ntnic: add null checking Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 15/34] net/ntnic: move " Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 16/34] net/ntnic: fix var size Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 17/34] net/ntnic: fix var overflow Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 18/34] net/ntnic: remove unused code Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 19/34] net/ntnic: remove convert error func Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 20/34] net/ntnic: fix array verification Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 21/34] net/ntnic: fix memory leak Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 22/34] net/ntnic: remove extra address-of operator Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 23/34] net/ntnic: remove extra check for null Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 24/34] net/ntnic: remove unused code Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 25/34] net/ntnic: refactor RSS implementation Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 26/34] net/ntnic: fix age timeout recalculation into fpga unit Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 27/34] net/ntnic: rework age event generation Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 28/34] net/ntnic: fix group print Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 29/34] net/ntnic: extend module mapping Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 30/34] net/ntnic: refactoring of the FPGA initialization Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 31/34] net/ntnic: remove shutdown thread Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 32/34] net/ntnic: add checks for action modify Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 33/34] net/ntnic: add IFR DROP counter Serhii Iliushyk
2025-02-05 10:45     ` [PATCH v2 34/34] net/ntnic: remove tag EXPERIMENTAL Serhii Iliushyk
2025-02-05 16:51     ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Stephen Hemminger
2025-01-21 17:07 ` [PATCH v1 02/31] net/ntnic: add thread check return code Serhii Iliushyk
2025-01-21 18:24   ` Stephen Hemminger
2025-01-28 18:54   ` Stephen Hemminger
2025-01-21 17:07 ` [PATCH v1 03/31] net/ntnic: add return code handling Serhii Iliushyk
2025-01-21 18:30   ` Stephen Hemminger
2025-01-21 17:07 ` [PATCH v1 04/31] net/ntnic: add array index verification Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 05/31] net/ntnic: fix realloc memory leak Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 06/31] net/ntnic: fix array index verification Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 07/31] net/ntnic: add var definition transparently Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 08/31] net/ntnic: add proper var freed Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 09/31] net/ntnic: remove deadcode Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 10/31] net/ntnic: fix potentially overflow Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 11/31] net/ntnic: add null checking Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 12/31] net/ntnic: fix overflow issue Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 13/31] net/ntnic: fix untrusted loop bound Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 14/31] net/ntnic: add null checking Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 15/31] net/ntnic: move " Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 16/31] net/ntnic: fix var size Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 17/31] net/ntnic: fix var overflow Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 18/31] net/ntnic: remove dead code Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 19/31] net/ntnic: remove convert error func Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 20/31] net/ntnic: fix array verification Serhii Iliushyk
2025-01-21 17:07 ` [PATCH v1 21/31] net/ntnic: fix memory leak Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 22/31] net/ntnic: remove extra address-of operator Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 23/31] net/ntnic: remove extra check for null Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 24/31] net/ntnic: remove unused code Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 25/31] net/ntnic: refactor RSS implementation Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 26/31] net/ntnic: fix age timeout recalculation into fpga unit Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 27/31] net/ntnic: rework age event generation Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 28/31] net/ntnic: fix group print Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 29/31] net/ntnic: extend module mapping Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 30/31] net/ntnic: refactoring of the FPGA initialization Serhii Iliushyk
2025-01-21 17:08 ` [PATCH v1 31/31] net/ntnic: remove tag EXPERIMENTAL Serhii Iliushyk
2025-01-28 18:51 ` [PATCH v1 00/31] net/ntnic: bugfixes and refactoring Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).