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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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; 73+ 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] 73+ 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
  2025-02-07 11:03       ` Serhii Iliushyk
  34 siblings, 1 reply; 73+ 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] 73+ messages in thread

* Re: [PATCH v2 00/34] net/ntnic: bugfixes and refactoring
  2025-02-05 16:51     ` [PATCH v2 00/34] net/ntnic: bugfixes and refactoring Stephen Hemminger
@ 2025-02-07 11:03       ` Serhii Iliushyk
  0 siblings, 0 replies; 73+ messages in thread
From: Serhii Iliushyk @ 2025-02-07 11:03 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Mykola Kostenok, Christian Koue Muf

[-- Attachment #1: Type: text/plain, Size: 1040 bytes --]

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://linkprotect.cudasvc.com/url?a=https%3a%2f%2fbugs.dpdk.org%2fshow_bug.cgi%3fid%3d1622&c=E,1,6udE5Jl1KN1y6YarjUq8xAU2C_RnMxvCsO4FC_7QGgRwCOMRCfX-0jEcl4wPapW-A2poKdj_W5XNKd_SMg4ohWp5E3FgSkpTr8VsSWWoOlne_dqw77o,&typo=1.
>   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?

Hi Stephen,

We do not need to backport these patches to the stable version.
Please keep them only for the latest DPDK.

Thanks,
Serhii


[-- Attachment #2: Type: text/html, Size: 4168 bytes --]

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

end of thread, other threads:[~2025-02-07 11:03 UTC | newest]

Thread overview: 73+ 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-02-07 11:03       ` Serhii Iliushyk
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).