diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini
index 0d76540..24803da 100644
--- a/doc/guides/nics/features/cnxk.ini
+++ b/doc/guides/nics/features/cnxk.ini
@@ -23,6 +23,8 @@ Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
 RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 Inner RSS            = Y
 Flow control         = Y
 Jumbo frame          = Y
diff --git a/doc/guides/nics/features/cnxk_vec.ini b/doc/guides/nics/features/cnxk_vec.ini
index 65ee8ba..b4b1169 100644
--- a/doc/guides/nics/features/cnxk_vec.ini
+++ b/doc/guides/nics/features/cnxk_vec.ini
@@ -22,6 +22,8 @@ Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
 RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 Inner RSS            = Y
 Flow control         = Y
 Jumbo frame          = Y
diff --git a/doc/guides/nics/features/cnxk_vf.ini b/doc/guides/nics/features/cnxk_vf.ini
index 00bde9b..fbc50a8 100644
--- a/doc/guides/nics/features/cnxk_vf.ini
+++ b/doc/guides/nics/features/cnxk_vf.ini
@@ -19,6 +19,8 @@ Queue start/stop     = Y
 MTU update           = Y
 TSO                  = Y
 RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 Inner RSS            = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 06cc039..a250cff 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1237,6 +1237,10 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.timesync_write_time = cnxk_nix_timesync_write_time,
 	.timesync_adjust_time = cnxk_nix_timesync_adjust_time,
 	.read_clock = cnxk_nix_read_clock,
+	.reta_update = cnxk_nix_reta_update,
+	.reta_query = cnxk_nix_reta_query,
+	.rss_hash_update = cnxk_nix_rss_hash_update,
+	.rss_hash_conf_get = cnxk_nix_rss_hash_conf_get,
 };
 
 static int
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index 9b96904..62c88e6 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -314,6 +314,16 @@ uint64_t cnxk_nix_rxq_mbuf_setup(struct cnxk_eth_dev *dev);
 /* RSS */
 uint32_t cnxk_rss_ethdev_to_nix(struct cnxk_eth_dev *dev, uint64_t ethdev_rss,
 				uint8_t rss_level);
+int cnxk_nix_reta_update(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_rss_reta_entry64 *reta_conf,
+			 uint16_t reta_size);
+int cnxk_nix_reta_query(struct rte_eth_dev *eth_dev,
+			struct rte_eth_rss_reta_entry64 *reta_conf,
+			uint16_t reta_size);
+int cnxk_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
+			     struct rte_eth_rss_conf *rss_conf);
+int cnxk_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
+			       struct rte_eth_rss_conf *rss_conf);
 
 /* Link */
 void cnxk_nix_toggle_flag_link_cfg(struct cnxk_eth_dev *dev, bool set);
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index 7fd06eb..c76b628 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -109,6 +109,7 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
 #define CNXK_FLOW_MAX_PRIORITY	"flow_max_priority"
 #define CNXK_SWITCH_HEADER_TYPE "switch_header"
 #define CNXK_RSS_TAG_AS_XOR	"tag_as_xor"
+#define CNXK_LOCK_RX_CTX	"lock_rx_ctx"
 
 int
 cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
@@ -120,6 +121,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	uint16_t flow_max_priority = 3;
 	uint16_t rss_tag_as_xor = 0;
 	uint16_t scalar_enable = 0;
+	uint8_t lock_rx_ctx = 0;
 	struct rte_kvargs *kvlist;
 
 	if (devargs == NULL)
@@ -143,6 +145,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 			   &parse_switch_header_type, &switch_header_type);
 	rte_kvargs_process(kvlist, CNXK_RSS_TAG_AS_XOR, &parse_flag,
 			   &rss_tag_as_xor);
+	rte_kvargs_process(kvlist, CNXK_LOCK_RX_CTX, &parse_flag, &lock_rx_ctx);
 	rte_kvargs_free(kvlist);
 
 null_devargs:
@@ -150,6 +153,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	dev->nix.rss_tag_as_xor = !!rss_tag_as_xor;
 	dev->nix.max_sqb_count = sqb_count;
 	dev->nix.reta_sz = reta_sz;
+	dev->nix.lock_rx_ctx = lock_rx_ctx;
 	dev->npc.flow_prealloc_size = flow_prealloc_size;
 	dev->npc.flow_max_priority = flow_max_priority;
 	dev->npc.switch_header_type = switch_header_type;
diff --git a/drivers/net/cnxk/cnxk_ethdev_ops.c b/drivers/net/cnxk/cnxk_ethdev_ops.c
index d437e2c..c28512a 100644
--- a/drivers/net/cnxk/cnxk_ethdev_ops.c
+++ b/drivers/net/cnxk/cnxk_ethdev_ops.c
@@ -718,3 +718,124 @@ cnxk_nix_dev_get_reg(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 
 	return rc;
 }
+
+int
+cnxk_nix_reta_update(struct rte_eth_dev *eth_dev,
+		     struct rte_eth_rss_reta_entry64 *reta_conf,
+		     uint16_t reta_size)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	uint16_t reta[ROC_NIX_RSS_RETA_MAX];
+	struct roc_nix *nix = &dev->nix;
+	int i, j, rc = -EINVAL, idx = 0;
+
+	if (reta_size != dev->nix.reta_sz) {
+		plt_err("Size of hash lookup table configured (%d) does not "
+			"match the number hardware can supported (%d)",
+			reta_size, dev->nix.reta_sz);
+		goto fail;
+	}
+
+	/* Copy RETA table */
+	for (i = 0; i < (int)(dev->nix.reta_sz / RTE_RETA_GROUP_SIZE); i++) {
+		for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
+			if ((reta_conf[i].mask >> j) & 0x01)
+				reta[idx] = reta_conf[i].reta[j];
+			idx++;
+		}
+	}
+
+	return roc_nix_rss_reta_set(nix, 0, reta);
+
+fail:
+	return rc;
+}
+
+int
+cnxk_nix_reta_query(struct rte_eth_dev *eth_dev,
+		    struct rte_eth_rss_reta_entry64 *reta_conf,
+		    uint16_t reta_size)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	uint16_t reta[ROC_NIX_RSS_RETA_MAX];
+	struct roc_nix *nix = &dev->nix;
+	int rc = -EINVAL, i, j, idx = 0;
+
+	if (reta_size != dev->nix.reta_sz) {
+		plt_err("Size of hash lookup table configured (%d) does not "
+			"match the number hardware can supported (%d)",
+			reta_size, dev->nix.reta_sz);
+		goto fail;
+	}
+
+	rc = roc_nix_rss_reta_get(nix, 0, reta);
+	if (rc)
+		goto fail;
+
+	/* Copy RETA table */
+	for (i = 0; i < (int)(dev->nix.reta_sz / RTE_RETA_GROUP_SIZE); i++) {
+		for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
+			if ((reta_conf[i].mask >> j) & 0x01)
+				reta_conf[i].reta[j] = reta[idx];
+			idx++;
+		}
+	}
+
+	return 0;
+
+fail:
+	return rc;
+}
+
+int
+cnxk_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_rss_conf *rss_conf)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	uint8_t rss_hash_level;
+	uint32_t flowkey_cfg;
+	int rc = -EINVAL;
+	uint8_t alg_idx;
+
+	if (rss_conf->rss_key && rss_conf->rss_key_len != ROC_NIX_RSS_KEY_LEN) {
+		plt_err("Hash key size mismatch %d vs %d",
+			rss_conf->rss_key_len, ROC_NIX_RSS_KEY_LEN);
+		goto fail;
+	}
+
+	if (rss_conf->rss_key)
+		roc_nix_rss_key_set(nix, rss_conf->rss_key);
+
+	rss_hash_level = ETH_RSS_LEVEL(rss_conf->rss_hf);
+	if (rss_hash_level)
+		rss_hash_level -= 1;
+	flowkey_cfg =
+		cnxk_rss_ethdev_to_nix(dev, rss_conf->rss_hf, rss_hash_level);
+
+	rc = roc_nix_rss_flowkey_set(nix, &alg_idx, flowkey_cfg,
+				     ROC_NIX_RSS_GROUP_DEFAULT,
+				     ROC_NIX_RSS_MCAM_IDX_DEFAULT);
+	if (rc) {
+		plt_err("Failed to set RSS hash function rc=%d", rc);
+		return rc;
+	}
+
+fail:
+	return rc;
+}
+
+int
+cnxk_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_rss_conf *rss_conf)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+	if (rss_conf->rss_key)
+		roc_nix_rss_key_get(&dev->nix, rss_conf->rss_key);
+
+	rss_conf->rss_key_len = ROC_NIX_RSS_KEY_LEN;
+	rss_conf->rss_hf = dev->ethdev_rss_hf;
+
+	return 0;
+}
