diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index ca21842..6652e17 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -27,3 +27,97 @@ Driver compilation and testing
 
 Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
 for details.
+
+Runtime Config Options
+----------------------
+
+- ``Rx&Tx scalar mode enable`` (default ``0``)
+
+   PMD supports both scalar and vector mode, it may be selected at runtime
+   using ``scalar_enable`` ``devargs`` parameter.
+
+- ``RSS reta size`` (default ``64``)
+
+   RSS redirection table size may be configured during runtime using ``reta_size``
+   ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,reta_size=256
+
+   With the above configuration, reta table of size 256 is populated.
+
+- ``Flow priority levels`` (default ``3``)
+
+   RTE Flow priority levels can be configured during runtime using
+   ``flow_max_priority`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,flow_max_priority=10
+
+   With the above configuration, priority level was set to 10 (0-9). Max
+   priority level supported is 32.
+
+- ``Reserve Flow entries`` (default ``8``)
+
+   RTE flow entries can be pre allocated and the size of pre allocation can be
+   selected runtime using ``flow_prealloc_size`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,flow_prealloc_size=4
+
+   With the above configuration, pre alloc size was set to 4. Max pre alloc
+   size supported is 32.
+
+- ``Max SQB buffer count`` (default ``512``)
+
+   Send queue descriptor buffer count may be limited during runtime using
+   ``max_sqb_count`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,max_sqb_count=64
+
+   With the above configuration, each send queue's descriptor buffer count is
+   limited to a maximum of 64 buffers.
+
+- ``Switch header enable`` (default ``none``)
+
+   A port can be configured to a specific switch header type by using
+   ``switch_header`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,switch_header="higig2"
+
+   With the above configuration, higig2 will be enabled on that port and the
+   traffic on this port should be higig2 traffic only. Supported switch header
+   types are "higig2", "dsa", "chlen90b" and "chlen24b".
+
+- ``RSS tag as XOR`` (default ``0``)
+
+   The HW gives two options to configure the RSS adder i.e
+
+   * ``rss_adder<7:0> = flow_tag<7:0> ^ flow_tag<15:8> ^ flow_tag<23:16> ^ flow_tag<31:24>``
+
+   * ``rss_adder<7:0> = flow_tag<7:0>``
+
+   Latter one aligns with standard NIC behavior vs former one is a legacy
+   RSS adder scheme used in OCTEON TX2 products.
+
+   By default, the driver runs in the latter mode.
+   Setting this flag to 1 to select the legacy mode.
+
+   For example to select the legacy mode(RSS tag adder as XOR)::
+
+      -a 0002:02:00.0,tag_as_xor=1
+
+
+
+.. note::
+
+   Above devarg parameters are configurable per device, user needs to pass the
+   parameters to all the PCIe devices if application requires to configure on
+   all the ethdev ports.
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 526c19b..109fd35 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -57,6 +57,13 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
 	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
+	/* Parse devargs string */
+	rc = cnxk_ethdev_parse_devargs(eth_dev->device->devargs, dev);
+	if (rc) {
+		plt_err("Failed to parse devargs rc=%d", rc);
+		goto error;
+	}
+
 	/* Initialize base roc nix */
 	nix->pci_dev = pci_dev;
 	rc = roc_nix_dev_init(nix);
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index ba2bfcd..97e3a15 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -9,11 +9,15 @@
 
 #include <ethdev_driver.h>
 #include <ethdev_pci.h>
+#include <rte_kvargs.h>
 
 #include "roc_api.h"
 
 #define CNXK_ETH_DEV_PMD_VERSION "1.0"
 
+/* Max supported SQB count */
+#define CNXK_NIX_TX_MAX_SQB 512
+
 #define CNXK_NIX_TX_OFFLOAD_CAPA                                               \
 	(DEV_TX_OFFLOAD_MBUF_FAST_FREE | DEV_TX_OFFLOAD_MT_LOCKFREE |          \
 	 DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT |             \
@@ -38,6 +42,7 @@ struct cnxk_eth_dev {
 	uint8_t max_mac_entries;
 
 	uint16_t flags;
+	bool scalar_ena;
 
 	/* Pointer back to rte */
 	struct rte_eth_dev *eth_dev;
@@ -73,4 +78,8 @@ int cnxk_nix_probe(struct rte_pci_driver *pci_drv,
 		   struct rte_pci_device *pci_dev);
 int cnxk_nix_remove(struct rte_pci_device *pci_dev);
 
+/* Devargs */
+int cnxk_ethdev_parse_devargs(struct rte_devargs *devargs,
+			      struct cnxk_eth_dev *dev);
+
 #endif /* __CNXK_ETHDEV_H__ */
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
new file mode 100644
index 0000000..4af2803
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include <inttypes.h>
+#include <math.h>
+
+#include "cnxk_ethdev.h"
+
+static int
+parse_flow_max_priority(const char *key, const char *value, void *extra_args)
+{
+	RTE_SET_USED(key);
+	uint16_t val;
+
+	val = atoi(value);
+
+	/* Limit the max priority to 32 */
+	if (val < 1 || val > 32)
+		return -EINVAL;
+
+	*(uint16_t *)extra_args = val;
+
+	return 0;
+}
+
+static int
+parse_flow_prealloc_size(const char *key, const char *value, void *extra_args)
+{
+	RTE_SET_USED(key);
+	uint16_t val;
+
+	val = atoi(value);
+
+	/* Limit the prealloc size to 32 */
+	if (val < 1 || val > 32)
+		return -EINVAL;
+
+	*(uint16_t *)extra_args = val;
+
+	return 0;
+}
+
+static int
+parse_reta_size(const char *key, const char *value, void *extra_args)
+{
+	RTE_SET_USED(key);
+	uint32_t val;
+
+	val = atoi(value);
+
+	if (val <= ETH_RSS_RETA_SIZE_64)
+		val = ROC_NIX_RSS_RETA_SZ_64;
+	else if (val > ETH_RSS_RETA_SIZE_64 && val <= ETH_RSS_RETA_SIZE_128)
+		val = ROC_NIX_RSS_RETA_SZ_128;
+	else if (val > ETH_RSS_RETA_SIZE_128 && val <= ETH_RSS_RETA_SIZE_256)
+		val = ROC_NIX_RSS_RETA_SZ_256;
+	else
+		val = ROC_NIX_RSS_RETA_SZ_64;
+
+	*(uint16_t *)extra_args = val;
+
+	return 0;
+}
+
+static int
+parse_flag(const char *key, const char *value, void *extra_args)
+{
+	RTE_SET_USED(key);
+
+	*(uint16_t *)extra_args = atoi(value);
+
+	return 0;
+}
+
+static int
+parse_sqb_count(const char *key, const char *value, void *extra_args)
+{
+	RTE_SET_USED(key);
+	uint32_t val;
+
+	val = atoi(value);
+
+	*(uint16_t *)extra_args = val;
+
+	return 0;
+}
+
+static int
+parse_switch_header_type(const char *key, const char *value, void *extra_args)
+{
+	RTE_SET_USED(key);
+
+	if (strcmp(value, "higig2") == 0)
+		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_HIGIG;
+
+	if (strcmp(value, "dsa") == 0)
+		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_EDSA;
+
+	if (strcmp(value, "chlen90b") == 0)
+		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_LEN_90B;
+	return 0;
+}
+
+#define CNXK_RSS_RETA_SIZE	"reta_size"
+#define CNXK_SCL_ENABLE		"scalar_enable"
+#define CNXK_MAX_SQB_COUNT	"max_sqb_count"
+#define CNXK_FLOW_PREALLOC_SIZE "flow_prealloc_size"
+#define CNXK_FLOW_MAX_PRIORITY	"flow_max_priority"
+#define CNXK_SWITCH_HEADER_TYPE "switch_header"
+#define CNXK_RSS_TAG_AS_XOR	"tag_as_xor"
+
+int
+cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
+{
+	uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64;
+	uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB;
+	uint16_t flow_prealloc_size = 8;
+	uint16_t switch_header_type = 0;
+	uint16_t flow_max_priority = 3;
+	uint16_t rss_tag_as_xor = 0;
+	uint16_t scalar_enable = 0;
+	struct rte_kvargs *kvlist;
+
+	if (devargs == NULL)
+		goto null_devargs;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		goto exit;
+
+	rte_kvargs_process(kvlist, CNXK_RSS_RETA_SIZE, &parse_reta_size,
+			   &reta_sz);
+	rte_kvargs_process(kvlist, CNXK_SCL_ENABLE, &parse_flag,
+			   &scalar_enable);
+	rte_kvargs_process(kvlist, CNXK_MAX_SQB_COUNT, &parse_sqb_count,
+			   &sqb_count);
+	rte_kvargs_process(kvlist, CNXK_FLOW_PREALLOC_SIZE,
+			   &parse_flow_prealloc_size, &flow_prealloc_size);
+	rte_kvargs_process(kvlist, CNXK_FLOW_MAX_PRIORITY,
+			   &parse_flow_max_priority, &flow_max_priority);
+	rte_kvargs_process(kvlist, CNXK_SWITCH_HEADER_TYPE,
+			   &parse_switch_header_type, &switch_header_type);
+	rte_kvargs_process(kvlist, CNXK_RSS_TAG_AS_XOR, &parse_flag,
+			   &rss_tag_as_xor);
+	rte_kvargs_free(kvlist);
+
+null_devargs:
+	dev->scalar_ena = !!scalar_enable;
+	dev->nix.rss_tag_as_xor = !!rss_tag_as_xor;
+	dev->nix.max_sqb_count = sqb_count;
+	dev->nix.reta_sz = reta_sz;
+	return 0;
+
+exit:
+	return -EINVAL;
+}
+
+RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
+			      CNXK_RSS_RETA_SIZE "=<64|128|256>"
+			      CNXK_SCL_ENABLE "=1"
+			      CNXK_MAX_SQB_COUNT "=<8-512>"
+			      CNXK_FLOW_PREALLOC_SIZE "=<1-32>"
+			      CNXK_FLOW_MAX_PRIORITY "=<1-32>"
+			      CNXK_SWITCH_HEADER_TYPE "=<higig2|dsa|chlen90b>"
+			      CNXK_RSS_TAG_AS_XOR "=1");
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index 089e4fc..e7e43f0 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -8,7 +8,8 @@ if not dpdk_conf.get('RTE_ARCH_64')
 	subdir_done()
 endif
 
-sources = files('cnxk_ethdev.c')
+sources = files('cnxk_ethdev.c',
+		'cnxk_ethdev_devargs.c')
 
 # CN9K
 sources += files('cn9k_ethdev.c')
