diff mbox series

[v2,3/4] net/cnxk: add dev args for min-max spi

Message ID 20220120165310.4165567-4-gakhil@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Jerin Jacob
Headers show
Series net/cnxk: support IP reassembly offload | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Akhil Goyal Jan. 20, 2022, 4:53 p.m. UTC
From: Nithin Dabilpuram <ndabilpuram@marvell.com>

Add support for inline inbound SPI range via devargs
instead of just max SPI value and range being 0..max.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
---
 doc/guides/nics/cnxk.rst               | 28 ++++++++++-
 drivers/common/cnxk/roc_nix.h          |  5 +-
 drivers/common/cnxk/roc_nix_inl.c      | 65 +++++++++++++++-----------
 drivers/common/cnxk/roc_nix_inl.h      |  8 ++--
 drivers/common/cnxk/roc_nix_inl_dev.c  | 22 ++++++---
 drivers/common/cnxk/roc_nix_inl_priv.h |  4 +-
 drivers/common/cnxk/roc_nix_priv.h     |  1 +
 drivers/common/cnxk/version.map        |  2 +-
 drivers/net/cnxk/cn10k_ethdev_sec.c    | 13 ++++--
 drivers/net/cnxk/cn9k_ethdev_sec.c     | 10 ++--
 drivers/net/cnxk/cnxk_ethdev_devargs.c | 25 +++++++---
 drivers/net/cnxk/cnxk_ethdev_sec.c     | 16 +++++--
 drivers/net/cnxk/cnxk_lookup.c         |  3 +-
 13 files changed, 141 insertions(+), 61 deletions(-)
diff mbox series

Patch

diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index 2119ba51c8..e90a7d166b 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -187,6 +187,18 @@  Runtime Config Options
 
       -a 0002:02:00.0,tag_as_xor=1
 
+- ``Min SPI for inbound inline IPsec`` (default ``0``)
+
+   Min SPI supported for inbound inline IPsec processing can be specified by
+   ``ipsec_in_min_spi`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,ipsec_in_min_spi=6
+
+   With the above configuration, application can enable inline IPsec processing
+   for inbound SA with min SPI of 6.
+
 - ``Max SPI for inbound inline IPsec`` (default ``255``)
 
    Max SPI supported for inbound inline IPsec processing can be specified by
@@ -197,7 +209,7 @@  Runtime Config Options
       -a 0002:02:00.0,ipsec_in_max_spi=128
 
    With the above configuration, application can enable inline IPsec processing
-   for 128 inbound SAs (SPI 0-127).
+   with max SPI of 128.
 
 - ``Max SA's for outbound inline IPsec`` (default ``4096``)
 
@@ -365,6 +377,18 @@  VF ``177D:A0F1``.
 Runtime Config Options for inline device
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+- ``Min SPI for inbound inline IPsec`` (default ``0``)
+
+   Min SPI supported for inbound inline IPsec processing can be specified by
+   ``ipsec_in_min_spi`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:1d:00.0,ipsec_in_min_spi=6
+
+   With the above configuration, application can enable inline IPsec processing
+   for inbound SA with min SPI of 6 for traffic aggregated on inline device.
+
 - ``Max SPI for inbound inline IPsec`` (default ``255``)
 
    Max SPI supported for inbound inline IPsec processing can be specified by
@@ -375,7 +399,7 @@  Runtime Config Options for inline device
       -a 0002:1d:00.0,ipsec_in_max_spi=128
 
    With the above configuration, application can enable inline IPsec processing
-   for 128 inbound SAs (SPI 0-127) for traffic aggregated on inline device.
+   for inbound SA with max SPI of 128 for traffic aggregated on inline device.
 
 
 Debugging Options
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 69a5e8e7b4..ae42690470 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -380,8 +380,9 @@  struct roc_nix {
 	uint8_t lock_rx_ctx;
 	uint32_t outb_nb_desc;
 	uint16_t outb_nb_crypto_qs;
-	uint16_t ipsec_in_max_spi;
-	uint16_t ipsec_out_max_sa;
+	uint32_t ipsec_in_min_spi;
+	uint32_t ipsec_in_max_spi;
+	uint32_t ipsec_out_max_sa;
 	/* End of input parameters */
 	/* LMT line base for "Per Core Tx LMT line" mode*/
 	uintptr_t lmt_base;
diff --git a/drivers/common/cnxk/roc_nix_inl.c b/drivers/common/cnxk/roc_nix_inl.c
index 5251b51f9e..849473063f 100644
--- a/drivers/common/cnxk/roc_nix_inl.c
+++ b/drivers/common/cnxk/roc_nix_inl.c
@@ -19,12 +19,16 @@  PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_OUTB_SA_SZ ==
 static int
 nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
 {
-	uint16_t ipsec_in_max_spi = roc_nix->ipsec_in_max_spi;
+	uint32_t ipsec_in_min_spi = roc_nix->ipsec_in_min_spi;
+	uint32_t ipsec_in_max_spi = roc_nix->ipsec_in_max_spi;
 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
 	struct roc_nix_ipsec_cfg cfg;
+	uint64_t max_sa, i;
 	size_t inb_sa_sz;
-	int rc, i;
 	void *sa;
+	int rc;
+
+	max_sa = plt_align32pow2(ipsec_in_max_spi - ipsec_in_min_spi + 1);
 
 	/* CN9K SA size is different */
 	if (roc_model_is_cn9k())
@@ -34,14 +38,15 @@  nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
 
 	/* Alloc contiguous memory for Inbound SA's */
 	nix->inb_sa_sz = inb_sa_sz;
-	nix->inb_sa_base = plt_zmalloc(inb_sa_sz * ipsec_in_max_spi,
+	nix->inb_spi_mask = max_sa - 1;
+	nix->inb_sa_base = plt_zmalloc(inb_sa_sz * max_sa,
 				       ROC_NIX_INL_SA_BASE_ALIGN);
 	if (!nix->inb_sa_base) {
 		plt_err("Failed to allocate memory for Inbound SA");
 		return -ENOMEM;
 	}
 	if (roc_model_is_cn10k()) {
-		for (i = 0; i < ipsec_in_max_spi; i++) {
+		for (i = 0; i < max_sa; i++) {
 			sa = ((uint8_t *)nix->inb_sa_base) + (i * inb_sa_sz);
 			roc_nix_inl_inb_sa_init(sa);
 		}
@@ -50,7 +55,7 @@  nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
 	memset(&cfg, 0, sizeof(cfg));
 	cfg.sa_size = inb_sa_sz;
 	cfg.iova = (uintptr_t)nix->inb_sa_base;
-	cfg.max_sa = ipsec_in_max_spi + 1;
+	cfg.max_sa = max_sa;
 	cfg.tt = SSO_TT_ORDERED;
 
 	/* Setup device specific inb SA table */
@@ -129,26 +134,34 @@  roc_nix_inl_inb_sa_base_get(struct roc_nix *roc_nix, bool inb_inl_dev)
 }
 
 uint32_t
-roc_nix_inl_inb_sa_max_spi(struct roc_nix *roc_nix, bool inb_inl_dev)
+roc_nix_inl_inb_spi_range(struct roc_nix *roc_nix, bool inb_inl_dev,
+			  uint32_t *min_spi, uint32_t *max_spi)
 {
 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
 	struct idev_cfg *idev = idev_get_cfg();
+	uint32_t min = 0, max = 0, mask = 0;
 	struct nix_inl_dev *inl_dev;
 
-	if (idev == NULL)
-		return 0;
-
-	if (!nix->inl_inb_ena)
-		return 0;
+	if (idev == NULL || !nix->inl_inb_ena)
+		goto exit;
 
 	inl_dev = idev->nix_inl_dev;
-	if (inb_inl_dev) {
-		if (inl_dev)
-			return inl_dev->ipsec_in_max_spi;
-		return 0;
+	if (inb_inl_dev && inl_dev) {
+		min = inl_dev->ipsec_in_min_spi;
+		max = inl_dev->ipsec_in_max_spi;
+		mask = inl_dev->inb_spi_mask;
+	} else if (!inb_inl_dev) {
+		min = roc_nix->ipsec_in_min_spi;
+		max = roc_nix->ipsec_in_max_spi;
+		mask = nix->inb_spi_mask;
 	}
 
-	return roc_nix->ipsec_in_max_spi;
+exit:
+	if (min_spi)
+		*min_spi = min;
+	if (max_spi)
+		*max_spi = max;
+	return mask;
 }
 
 uint32_t
@@ -175,8 +188,8 @@  roc_nix_inl_inb_sa_sz(struct roc_nix *roc_nix, bool inl_dev_sa)
 uintptr_t
 roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix, bool inb_inl_dev, uint32_t spi)
 {
+	uint32_t max_spi, min_spi, mask;
 	uintptr_t sa_base;
-	uint32_t max_spi;
 	uint64_t sz;
 
 	sa_base = roc_nix_inl_inb_sa_base_get(roc_nix, inb_inl_dev);
@@ -185,11 +198,11 @@  roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix, bool inb_inl_dev, uint32_t spi)
 		return 0;
 
 	/* Check if SPI is in range */
-	max_spi = roc_nix_inl_inb_sa_max_spi(roc_nix, inb_inl_dev);
-	if (spi > max_spi) {
-		plt_err("Inbound SA SPI %u exceeds max %u", spi, max_spi);
-		return 0;
-	}
+	mask = roc_nix_inl_inb_spi_range(roc_nix, inb_inl_dev, &min_spi,
+					 &max_spi);
+	if (spi > max_spi || spi < min_spi)
+		plt_warn("Inbound SA SPI %u not in range (%u..%u)", spi,
+			 min_spi, max_spi);
 
 	/* Get SA size */
 	sz = roc_nix_inl_inb_sa_sz(roc_nix, inb_inl_dev);
@@ -197,7 +210,7 @@  roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix, bool inb_inl_dev, uint32_t spi)
 		return 0;
 
 	/* Basic logic of SPI->SA for now */
-	return (sa_base + (spi * sz));
+	return (sa_base + ((spi & mask) * sz));
 }
 
 int
@@ -300,11 +313,11 @@  roc_nix_inl_outb_init(struct roc_nix *roc_nix)
 	struct nix_inl_dev *inl_dev;
 	uint16_t sso_pffunc;
 	uint8_t eng_grpmask;
-	uint64_t blkaddr;
+	uint64_t blkaddr, i;
 	uint16_t nb_lf;
 	void *sa_base;
 	size_t sa_sz;
-	int i, j, rc;
+	int j, rc;
 	void *sa;
 
 	if (idev == NULL)
@@ -745,7 +758,7 @@  roc_nix_inl_inb_tag_update(struct roc_nix *roc_nix, uint32_t tag_const,
 	memset(&cfg, 0, sizeof(cfg));
 	cfg.sa_size = nix->inb_sa_sz;
 	cfg.iova = (uintptr_t)nix->inb_sa_base;
-	cfg.max_sa = roc_nix->ipsec_in_max_spi + 1;
+	cfg.max_sa = nix->inb_spi_mask + 1;
 	cfg.tt = tt;
 	cfg.tag_const = tag_const;
 
diff --git a/drivers/common/cnxk/roc_nix_inl.h b/drivers/common/cnxk/roc_nix_inl.h
index 73a17276c4..280ea7cb80 100644
--- a/drivers/common/cnxk/roc_nix_inl.h
+++ b/drivers/common/cnxk/roc_nix_inl.h
@@ -110,7 +110,8 @@  typedef void (*roc_nix_inl_sso_work_cb_t)(uint64_t *gw, void *args);
 struct roc_nix_inl_dev {
 	/* Input parameters */
 	struct plt_pci_device *pci_dev;
-	uint16_t ipsec_in_max_spi;
+	uint32_t ipsec_in_min_spi;
+	uint32_t ipsec_in_max_spi;
 	bool selftest;
 	bool is_multi_channel;
 	uint16_t channel;
@@ -138,8 +139,9 @@  int __roc_api roc_nix_inl_inb_fini(struct roc_nix *roc_nix);
 bool __roc_api roc_nix_inl_inb_is_enabled(struct roc_nix *roc_nix);
 uintptr_t __roc_api roc_nix_inl_inb_sa_base_get(struct roc_nix *roc_nix,
 						bool inl_dev_sa);
-uint32_t __roc_api roc_nix_inl_inb_sa_max_spi(struct roc_nix *roc_nix,
-					      bool inl_dev_sa);
+uint32_t __roc_api roc_nix_inl_inb_spi_range(struct roc_nix *roc_nix,
+					     bool inl_dev_sa, uint32_t *min,
+					     uint32_t *max);
 uint32_t __roc_api roc_nix_inl_inb_sa_sz(struct roc_nix *roc_nix,
 					 bool inl_dev_sa);
 uintptr_t __roc_api roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix,
diff --git a/drivers/common/cnxk/roc_nix_inl_dev.c b/drivers/common/cnxk/roc_nix_inl_dev.c
index a0fe6ecd82..f75d14ba8b 100644
--- a/drivers/common/cnxk/roc_nix_inl_dev.c
+++ b/drivers/common/cnxk/roc_nix_inl_dev.c
@@ -114,6 +114,7 @@  nix_inl_nix_ipsec_cfg(struct nix_inl_dev *inl_dev, bool ena)
 {
 	struct nix_inline_ipsec_lf_cfg *lf_cfg;
 	struct mbox *mbox = (&inl_dev->dev)->mbox;
+	uint64_t max_sa;
 	uint32_t sa_w;
 
 	lf_cfg = mbox_alloc_msg_nix_inline_ipsec_lf_cfg(mbox);
@@ -121,8 +122,9 @@  nix_inl_nix_ipsec_cfg(struct nix_inl_dev *inl_dev, bool ena)
 		return -ENOSPC;
 
 	if (ena) {
-		sa_w = plt_align32pow2(inl_dev->ipsec_in_max_spi + 1);
-		sa_w = plt_log2_u32(sa_w);
+
+		max_sa = inl_dev->inb_spi_mask + 1;
+		sa_w = plt_log2_u32(max_sa);
 
 		lf_cfg->enable = 1;
 		lf_cfg->sa_base_addr = (uintptr_t)inl_dev->inb_sa_base;
@@ -132,7 +134,7 @@  nix_inl_nix_ipsec_cfg(struct nix_inl_dev *inl_dev, bool ena)
 			lf_cfg->ipsec_cfg0.lenm1_max = NIX_CN9K_MAX_HW_FRS - 1;
 		else
 			lf_cfg->ipsec_cfg0.lenm1_max = NIX_RPM_MAX_HW_FRS - 1;
-		lf_cfg->ipsec_cfg1.sa_idx_max = inl_dev->ipsec_in_max_spi;
+		lf_cfg->ipsec_cfg1.sa_idx_max = max_sa - 1;
 		lf_cfg->ipsec_cfg0.sa_pow2_size =
 			plt_log2_u32(inl_dev->inb_sa_sz);
 
@@ -341,15 +343,19 @@  nix_inl_sso_release(struct nix_inl_dev *inl_dev)
 static int
 nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
 {
-	uint16_t ipsec_in_max_spi = inl_dev->ipsec_in_max_spi;
+	uint32_t ipsec_in_min_spi = inl_dev->ipsec_in_min_spi;
+	uint32_t ipsec_in_max_spi = inl_dev->ipsec_in_max_spi;
 	struct dev *dev = &inl_dev->dev;
 	struct mbox *mbox = dev->mbox;
 	struct nix_lf_alloc_rsp *rsp;
 	struct nix_lf_alloc_req *req;
+	uint64_t max_sa, i;
 	size_t inb_sa_sz;
-	int i, rc = -ENOSPC;
+	int rc = -ENOSPC;
 	void *sa;
 
+	max_sa = plt_align32pow2(ipsec_in_max_spi - ipsec_in_min_spi + 1);
+
 	/* Alloc NIX LF needed for single RQ */
 	req = mbox_alloc_msg_nix_lf_alloc(mbox);
 	if (req == NULL)
@@ -397,7 +403,8 @@  nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
 
 	/* Alloc contiguous memory for Inbound SA's */
 	inl_dev->inb_sa_sz = inb_sa_sz;
-	inl_dev->inb_sa_base = plt_zmalloc(inb_sa_sz * ipsec_in_max_spi,
+	inl_dev->inb_spi_mask = max_sa - 1;
+	inl_dev->inb_sa_base = plt_zmalloc(inb_sa_sz * max_sa,
 					   ROC_NIX_INL_SA_BASE_ALIGN);
 	if (!inl_dev->inb_sa_base) {
 		plt_err("Failed to allocate memory for Inbound SA");
@@ -406,7 +413,7 @@  nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
 	}
 
 	if (roc_model_is_cn10k()) {
-		for (i = 0; i < ipsec_in_max_spi; i++) {
+		for (i = 0; i < max_sa; i++) {
 			sa = ((uint8_t *)inl_dev->inb_sa_base) +
 			     (i * inb_sa_sz);
 			roc_nix_inl_inb_sa_init(sa);
@@ -562,6 +569,7 @@  roc_nix_inl_dev_init(struct roc_nix_inl_dev *roc_inl_dev)
 	memset(inl_dev, 0, sizeof(*inl_dev));
 
 	inl_dev->pci_dev = pci_dev;
+	inl_dev->ipsec_in_min_spi = roc_inl_dev->ipsec_in_min_spi;
 	inl_dev->ipsec_in_max_spi = roc_inl_dev->ipsec_in_max_spi;
 	inl_dev->selftest = roc_inl_dev->selftest;
 	inl_dev->is_multi_channel = roc_inl_dev->is_multi_channel;
diff --git a/drivers/common/cnxk/roc_nix_inl_priv.h b/drivers/common/cnxk/roc_nix_inl_priv.h
index 3dc526f929..71bfd50c75 100644
--- a/drivers/common/cnxk/roc_nix_inl_priv.h
+++ b/drivers/common/cnxk/roc_nix_inl_priv.h
@@ -53,7 +53,9 @@  struct nix_inl_dev {
 	uint16_t channel;
 	uint16_t chan_mask;
 	bool is_multi_channel;
-	uint16_t ipsec_in_max_spi;
+	uint32_t ipsec_in_min_spi;
+	uint32_t ipsec_in_max_spi;
+	uint32_t inb_spi_mask;
 	bool attach_cptlf;
 };
 
diff --git a/drivers/common/cnxk/roc_nix_priv.h b/drivers/common/cnxk/roc_nix_priv.h
index 04575af295..4bd69cbec5 100644
--- a/drivers/common/cnxk/roc_nix_priv.h
+++ b/drivers/common/cnxk/roc_nix_priv.h
@@ -173,6 +173,7 @@  struct nix {
 	bool inl_outb_ena;
 	void *inb_sa_base;
 	size_t inb_sa_sz;
+	uint32_t inb_spi_mask;
 	void *outb_sa_base;
 	size_t outb_sa_sz;
 	uint16_t outb_err_sso_pffunc;
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index eab6e6a432..26ea18527d 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -140,7 +140,7 @@  INTERNAL {
 	roc_nix_inl_inb_init;
 	roc_nix_inl_inb_sa_base_get;
 	roc_nix_inl_inb_sa_get;
-	roc_nix_inl_inb_sa_max_spi;
+	roc_nix_inl_inb_spi_range;
 	roc_nix_inl_inb_sa_sz;
 	roc_nix_inl_inb_tag_update;
 	roc_nix_inl_inb_fini;
diff --git a/drivers/net/cnxk/cn10k_ethdev_sec.c b/drivers/net/cnxk/cn10k_ethdev_sec.c
index c332d59012..59c7befb8e 100644
--- a/drivers/net/cnxk/cn10k_ethdev_sec.c
+++ b/drivers/net/cnxk/cn10k_ethdev_sec.c
@@ -237,6 +237,7 @@  cn10k_eth_sec_session_create(void *device,
 	struct cn10k_sec_sess_priv sess_priv;
 	struct rte_crypto_sym_xform *crypto;
 	struct cnxk_eth_sec_sess *eth_sec;
+	struct roc_nix *nix = &dev->nix;
 	bool inbound, inl_dev;
 	int rc = 0;
 
@@ -287,13 +288,16 @@  cn10k_eth_sec_session_create(void *device,
 	if (inbound) {
 		struct roc_ot_ipsec_inb_sa *inb_sa, *inb_sa_dptr;
 		struct cn10k_inb_priv_data *inb_priv;
+		uint32_t spi_mask;
 		uintptr_t sa;
 
 		PLT_STATIC_ASSERT(sizeof(struct cn10k_inb_priv_data) <
 				  ROC_NIX_INL_OT_IPSEC_INB_SW_RSVD);
 
+		spi_mask = roc_nix_inl_inb_spi_range(nix, inl_dev, NULL, NULL);
+
 		/* Get Inbound SA from NIX_RX_IPSEC_SA_BASE */
-		sa = roc_nix_inl_inb_sa_get(&dev->nix, inl_dev, ipsec->spi);
+		sa = roc_nix_inl_inb_sa_get(nix, inl_dev, ipsec->spi);
 		if (!sa && dev->inb.inl_dev) {
 			plt_err("Failed to create ingress sa, inline dev "
 				"not found or spi not in range");
@@ -332,16 +336,17 @@  cn10k_eth_sec_session_create(void *device,
 		inb_priv->userdata = conf->userdata;
 
 		/* Save SA index/SPI in cookie for now */
-		inb_sa_dptr->w1.s.cookie = rte_cpu_to_be_32(ipsec->spi);
+		inb_sa_dptr->w1.s.cookie =
+			rte_cpu_to_be_32(ipsec->spi & spi_mask);
 
 		/* Prepare session priv */
 		sess_priv.inb_sa = 1;
-		sess_priv.sa_idx = ipsec->spi;
+		sess_priv.sa_idx = ipsec->spi & spi_mask;
 
 		/* Pointer from eth_sec -> inb_sa */
 		eth_sec->sa = inb_sa;
 		eth_sec->sess = sess;
-		eth_sec->sa_idx = ipsec->spi;
+		eth_sec->sa_idx = ipsec->spi & spi_mask;
 		eth_sec->spi = ipsec->spi;
 		eth_sec->inl_dev = !!dev->inb.inl_dev;
 		eth_sec->inb = true;
diff --git a/drivers/net/cnxk/cn9k_ethdev_sec.c b/drivers/net/cnxk/cn9k_ethdev_sec.c
index b070ad57fc..cf0431184a 100644
--- a/drivers/net/cnxk/cn9k_ethdev_sec.c
+++ b/drivers/net/cnxk/cn9k_ethdev_sec.c
@@ -146,6 +146,7 @@  cn9k_eth_sec_session_create(void *device,
 	struct cn9k_sec_sess_priv sess_priv;
 	struct rte_crypto_sym_xform *crypto;
 	struct cnxk_eth_sec_sess *eth_sec;
+	struct roc_nix *nix = &dev->nix;
 	bool inbound;
 	int rc = 0;
 
@@ -180,15 +181,18 @@  cn9k_eth_sec_session_create(void *device,
 	if (inbound) {
 		struct cn9k_inb_priv_data *inb_priv;
 		struct roc_onf_ipsec_inb_sa *inb_sa;
+		uint32_t spi_mask;
 
 		PLT_STATIC_ASSERT(sizeof(struct cn9k_inb_priv_data) <
 				  ROC_NIX_INL_ONF_IPSEC_INB_SW_RSVD);
 
+		spi_mask = roc_nix_inl_inb_spi_range(nix, false, NULL, NULL);
+
 		/* Get Inbound SA from NIX_RX_IPSEC_SA_BASE. Assume no inline
 		 * device always for CN9K.
 		 */
 		inb_sa = (struct roc_onf_ipsec_inb_sa *)
-			roc_nix_inl_inb_sa_get(&dev->nix, false, ipsec->spi);
+			roc_nix_inl_inb_sa_get(nix, false, ipsec->spi);
 		if (!inb_sa) {
 			plt_err("Failed to create ingress sa");
 			rc = -EFAULT;
@@ -228,12 +232,12 @@  cn9k_eth_sec_session_create(void *device,
 
 		/* Prepare session priv */
 		sess_priv.inb_sa = 1;
-		sess_priv.sa_idx = ipsec->spi;
+		sess_priv.sa_idx = ipsec->spi & spi_mask;
 
 		/* Pointer from eth_sec -> inb_sa */
 		eth_sec->sa = inb_sa;
 		eth_sec->sess = sess;
-		eth_sec->sa_idx = ipsec->spi;
+		eth_sec->sa_idx = ipsec->spi & spi_mask;
 		eth_sec->spi = ipsec->spi;
 		eth_sec->inb = true;
 
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index e068f55349..2923d2b18b 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -37,14 +37,17 @@  parse_outb_nb_crypto_qs(const char *key, const char *value, void *extra_args)
 }
 
 static int
-parse_ipsec_in_max_spi(const char *key, const char *value, void *extra_args)
+parse_ipsec_in_spi_range(const char *key, const char *value, void *extra_args)
 {
 	RTE_SET_USED(key);
 	uint32_t val;
 
-	val = atoi(value);
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	if (errno)
+		val = 0;
 
-	*(uint16_t *)extra_args = val;
+	*(uint32_t *)extra_args = val;
 
 	return 0;
 }
@@ -55,7 +58,10 @@  parse_ipsec_out_max_sa(const char *key, const char *value, void *extra_args)
 	RTE_SET_USED(key);
 	uint32_t val;
 
-	val = atoi(value);
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	if (errno)
+		val = 0;
 
 	*(uint16_t *)extra_args = val;
 
@@ -172,6 +178,7 @@  parse_switch_header_type(const char *key, const char *value, void *extra_args)
 #define CNXK_SWITCH_HEADER_TYPE "switch_header"
 #define CNXK_RSS_TAG_AS_XOR	"tag_as_xor"
 #define CNXK_LOCK_RX_CTX	"lock_rx_ctx"
+#define CNXK_IPSEC_IN_MIN_SPI	"ipsec_in_min_spi"
 #define CNXK_IPSEC_IN_MAX_SPI	"ipsec_in_max_spi"
 #define CNXK_IPSEC_OUT_MAX_SA	"ipsec_out_max_sa"
 #define CNXK_OUTB_NB_DESC	"outb_nb_desc"
@@ -183,13 +190,14 @@  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 ipsec_in_max_spi = BIT(8) - 1;
-	uint16_t ipsec_out_max_sa = BIT(12);
+	uint32_t ipsec_in_max_spi = BIT(8) - 1;
+	uint32_t ipsec_out_max_sa = BIT(12);
 	uint16_t flow_prealloc_size = 1;
 	uint16_t switch_header_type = 0;
 	uint16_t flow_max_priority = 3;
 	uint16_t force_inb_inl_dev = 0;
 	uint16_t outb_nb_crypto_qs = 1;
+	uint32_t ipsec_in_min_spi = 0;
 	uint16_t outb_nb_desc = 8200;
 	uint16_t rss_tag_as_xor = 0;
 	uint16_t scalar_enable = 0;
@@ -218,8 +226,10 @@  cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	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_process(kvlist, CNXK_IPSEC_IN_MIN_SPI,
+			   &parse_ipsec_in_spi_range, &ipsec_in_min_spi);
 	rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MAX_SPI,
-			   &parse_ipsec_in_max_spi, &ipsec_in_max_spi);
+			   &parse_ipsec_in_spi_range, &ipsec_in_max_spi);
 	rte_kvargs_process(kvlist, CNXK_IPSEC_OUT_MAX_SA,
 			   &parse_ipsec_out_max_sa, &ipsec_out_max_sa);
 	rte_kvargs_process(kvlist, CNXK_OUTB_NB_DESC, &parse_outb_nb_desc,
@@ -237,6 +247,7 @@  cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	dev->outb.max_sa = ipsec_out_max_sa;
 	dev->outb.nb_desc = outb_nb_desc;
 	dev->outb.nb_crypto_qs = outb_nb_crypto_qs;
+	dev->nix.ipsec_in_min_spi = ipsec_in_min_spi;
 	dev->nix.ipsec_in_max_spi = ipsec_in_max_spi;
 	dev->nix.ipsec_out_max_sa = ipsec_out_max_sa;
 	dev->nix.rss_tag_as_xor = !!rss_tag_as_xor;
diff --git a/drivers/net/cnxk/cnxk_ethdev_sec.c b/drivers/net/cnxk/cnxk_ethdev_sec.c
index 3fef0562ea..a20203501a 100644
--- a/drivers/net/cnxk/cnxk_ethdev_sec.c
+++ b/drivers/net/cnxk/cnxk_ethdev_sec.c
@@ -5,6 +5,7 @@ 
 #include <cnxk_ethdev.h>
 
 #define CNXK_NIX_INL_SELFTEST	      "selftest"
+#define CNXK_NIX_INL_IPSEC_IN_MIN_SPI "ipsec_in_min_spi"
 #define CNXK_NIX_INL_IPSEC_IN_MAX_SPI "ipsec_in_max_spi"
 #define CNXK_INL_CPT_CHANNEL	      "inl_cpt_channel"
 
@@ -119,14 +120,17 @@  struct rte_security_ops cnxk_eth_sec_ops = {
 };
 
 static int
-parse_ipsec_in_max_spi(const char *key, const char *value, void *extra_args)
+parse_ipsec_in_spi_range(const char *key, const char *value, void *extra_args)
 {
 	RTE_SET_USED(key);
 	uint32_t val;
 
-	val = atoi(value);
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	if (errno)
+		val = 0;
 
-	*(uint16_t *)extra_args = val;
+	*(uint32_t *)extra_args = val;
 
 	return 0;
 }
@@ -169,6 +173,7 @@  nix_inl_parse_devargs(struct rte_devargs *devargs,
 		      struct roc_nix_inl_dev *inl_dev)
 {
 	uint32_t ipsec_in_max_spi = BIT(8) - 1;
+	uint32_t ipsec_in_min_spi = 0;
 	struct inl_cpt_channel cpt_channel;
 	struct rte_kvargs *kvlist;
 	uint8_t selftest = 0;
@@ -184,13 +189,16 @@  nix_inl_parse_devargs(struct rte_devargs *devargs,
 
 	rte_kvargs_process(kvlist, CNXK_NIX_INL_SELFTEST, &parse_selftest,
 			   &selftest);
+	rte_kvargs_process(kvlist, CNXK_NIX_INL_IPSEC_IN_MIN_SPI,
+			   &parse_ipsec_in_spi_range, &ipsec_in_min_spi);
 	rte_kvargs_process(kvlist, CNXK_NIX_INL_IPSEC_IN_MAX_SPI,
-			   &parse_ipsec_in_max_spi, &ipsec_in_max_spi);
+			   &parse_ipsec_in_spi_range, &ipsec_in_max_spi);
 	rte_kvargs_process(kvlist, CNXK_INL_CPT_CHANNEL, &parse_inl_cpt_channel,
 			   &cpt_channel);
 	rte_kvargs_free(kvlist);
 
 null_devargs:
+	inl_dev->ipsec_in_min_spi = ipsec_in_min_spi;
 	inl_dev->ipsec_in_max_spi = ipsec_in_max_spi;
 	inl_dev->selftest = selftest;
 	inl_dev->channel = cpt_channel.channel;
diff --git a/drivers/net/cnxk/cnxk_lookup.c b/drivers/net/cnxk/cnxk_lookup.c
index 4eb1ecf17d..f36fb8f27a 100644
--- a/drivers/net/cnxk/cnxk_lookup.c
+++ b/drivers/net/cnxk/cnxk_lookup.c
@@ -337,7 +337,8 @@  cnxk_nix_lookup_mem_sa_base_set(struct cnxk_eth_dev *dev)
 	if (!sa_base)
 		return -ENOTSUP;
 
-	sa_w = plt_log2_u32(dev->nix.ipsec_in_max_spi + 1);
+	sa_w = plt_log2_u32(dev->nix.ipsec_in_max_spi + 1 -
+			    dev->nix.ipsec_in_min_spi);
 
 	/* Set SA Base in lookup mem */
 	sa_base_tbl = (uintptr_t)lookup_mem;