diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index dca8742..89ac900 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -1242,7 +1242,9 @@ cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
 			ctx_len += sizeof(template->ip4);
 
 			ip4->version_ihl = RTE_IPV4_VHL_DEF;
-			ip4->time_to_live = ipsec->tunnel.ipv4.ttl;
+			ip4->time_to_live = ipsec->tunnel.ipv4.ttl ?
+						    ipsec->tunnel.ipv4.ttl :
+						    0x40;
 			ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
 			if (ipsec->tunnel.ipv4.df)
 				frag_off |= RTE_IPV4_HDR_DF_FLAG;
@@ -1275,7 +1277,9 @@ cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
 						 ((ipsec->tunnel.ipv6.flabel
 						   << RTE_IPV6_HDR_FL_SHIFT) &
 						  RTE_IPV6_HDR_FL_MASK));
-			ip6->hop_limits = ipsec->tunnel.ipv6.hlimit;
+			ip6->hop_limits = ipsec->tunnel.ipv6.hlimit ?
+						  ipsec->tunnel.ipv6.hlimit :
+						  0x40;
 			memcpy(&ip6->src_addr, &ipsec->tunnel.ipv6.src_addr,
 			       sizeof(struct in6_addr));
 			memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr,
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
index 6f0ee44..8fc072b 100644
--- a/drivers/common/cnxk/roc_cpt.c
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -277,7 +277,7 @@ roc_cpt_inline_ipsec_inb_cfg_read(struct roc_cpt *roc_cpt,
 
 int
 roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt, uint16_t param1,
-			     uint16_t param2)
+			     uint16_t param2, uint16_t opcode)
 {
 	struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
 	struct cpt_rx_inline_lf_cfg_msg *req;
@@ -292,6 +292,7 @@ roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt, uint16_t param1,
 	req->sso_pf_func = idev_sso_pffunc_get();
 	req->param1 = param1;
 	req->param2 = param2;
+	req->opcode = opcode;
 
 	return mbox_process(mbox);
 }
@@ -998,7 +999,7 @@ roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
 }
 
 int
-roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, uint8_t opcode,
+roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, bool inb,
 		     uint16_t ctx_len, uint8_t egrp)
 {
 	union cpt_res_s res, *hw_res;
@@ -1014,7 +1015,9 @@ roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, uint8_t opcode,
 
 	hw_res->cn9k.compcode = CPT_COMP_NOT_DONE;
 
-	inst.w4.s.opcode_major = opcode;
+	inst.w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND;
+	if (inb)
+		inst.w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND;
 	inst.w4.s.opcode_minor = ctx_len >> 3;
 	inst.w4.s.param1 = 0;
 	inst.w4.s.param2 = 0;
diff --git a/drivers/common/cnxk/roc_cpt.h b/drivers/common/cnxk/roc_cpt.h
index 6953f2b..9a79998 100644
--- a/drivers/common/cnxk/roc_cpt.h
+++ b/drivers/common/cnxk/roc_cpt.h
@@ -161,7 +161,8 @@ int __roc_api roc_cpt_inline_ipsec_cfg(struct dev *dev, uint8_t slot,
 int __roc_api roc_cpt_inline_ipsec_inb_cfg_read(
 	struct roc_cpt *roc_cpt, struct nix_inline_ipsec_cfg *inb_cfg);
 int __roc_api roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt,
-					   uint16_t param1, uint16_t param2);
+					   uint16_t param1, uint16_t param2,
+					   uint16_t opcode);
 int __roc_api roc_cpt_afs_print(struct roc_cpt *roc_cpt);
 int __roc_api roc_cpt_lfs_print(struct roc_cpt *roc_cpt);
 void __roc_api roc_cpt_iq_disable(struct roc_cpt_lf *lf);
@@ -173,7 +174,6 @@ void __roc_api roc_cpt_parse_hdr_dump(const struct cpt_parse_hdr_s *cpth);
 int __roc_api roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr,
 				void *sa_cptr, uint16_t sa_len);
 
-int __roc_api roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa,
-				   uint8_t opcode, uint16_t ctx_len,
-				   uint8_t egrp);
+int __roc_api roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, uint64_t sa, bool inb,
+				   uint16_t ctx_len, uint8_t egrp);
 #endif /* _ROC_CPT_H_ */
diff --git a/drivers/common/cnxk/roc_ie_on.h b/drivers/common/cnxk/roc_ie_on.h
index 2d93cb6..961d5fc 100644
--- a/drivers/common/cnxk/roc_ie_on.h
+++ b/drivers/common/cnxk/roc_ie_on.h
@@ -13,6 +13,12 @@
 #define ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC 0x23
 #define ROC_IE_ON_MAJOR_OP_PROCESS_INBOUND_IPSEC  0x24
 
+#define ROC_IE_ON_INB_MAX_CTX_LEN	       34UL
+#define ROC_IE_ON_INB_IKEV2_SINGLE_SA_SUPPORT  (1 << 12)
+#define ROC_IE_ON_OUTB_MAX_CTX_LEN	       31UL
+#define ROC_IE_ON_OUTB_IKEV2_SINGLE_SA_SUPPORT (1 << 9)
+#define ROC_IE_ON_OUTB_PER_PKT_IV	       (1 << 11)
+
 /* Ucode completion codes */
 enum roc_ie_on_ucc_ipsec {
 	ROC_IE_ON_UCC_SUCCESS = 0,
diff --git a/drivers/common/cnxk/roc_nix_inl.c b/drivers/common/cnxk/roc_nix_inl.c
index 507a153..be0b806 100644
--- a/drivers/common/cnxk/roc_nix_inl.c
+++ b/drivers/common/cnxk/roc_nix_inl.c
@@ -8,11 +8,11 @@
 uint32_t soft_exp_consumer_cnt;
 roc_nix_inl_meta_pool_cb_t meta_pool_cb;
 
-PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ ==
-		  1UL << ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ_LOG2);
-PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ == 512);
-PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ ==
-		  1UL << ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ_LOG2);
+PLT_STATIC_ASSERT(ROC_NIX_INL_ON_IPSEC_INB_SA_SZ ==
+		  1UL << ROC_NIX_INL_ON_IPSEC_INB_SA_SZ_LOG2);
+PLT_STATIC_ASSERT(ROC_NIX_INL_ON_IPSEC_INB_SA_SZ == 1024);
+PLT_STATIC_ASSERT(ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ ==
+		  1UL << ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ_LOG2);
 PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_INB_SA_SZ ==
 		  1UL << ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
 PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_INB_SA_SZ == 1024);
@@ -184,7 +184,7 @@ nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
 
 	/* CN9K SA size is different */
 	if (roc_model_is_cn9k())
-		inb_sa_sz = ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ;
+		inb_sa_sz = ROC_NIX_INL_ON_IPSEC_INB_SA_SZ;
 	else
 		inb_sa_sz = ROC_NIX_INL_OT_IPSEC_INB_SA_SZ;
 
@@ -422,7 +422,9 @@ roc_nix_inl_inb_init(struct roc_nix *roc_nix)
 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
 	struct idev_cfg *idev = idev_get_cfg();
 	struct roc_cpt *roc_cpt;
+	uint16_t opcode;
 	uint16_t param1;
+	uint16_t param2;
 	int rc;
 
 	if (idev == NULL)
@@ -439,17 +441,23 @@ roc_nix_inl_inb_init(struct roc_nix *roc_nix)
 	}
 
 	if (roc_model_is_cn9k()) {
-		param1 = ROC_ONF_IPSEC_INB_MAX_L2_SZ;
+		param1 = (ROC_ONF_IPSEC_INB_MAX_L2_SZ >> 3) & 0xf;
+		param2 = ROC_IE_ON_INB_IKEV2_SINGLE_SA_SUPPORT;
+		opcode =
+			((ROC_IE_ON_INB_MAX_CTX_LEN << 8) |
+			 (ROC_IE_ON_MAJOR_OP_PROCESS_INBOUND_IPSEC | (1 << 6)));
 	} else {
 		union roc_ot_ipsec_inb_param1 u;
 
 		u.u16 = 0;
 		u.s.esp_trailer_disable = 1;
 		param1 = u.u16;
+		param2 = 0;
+		opcode = (ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC | (1 << 6));
 	}
 
 	/* Do onetime Inbound Inline config in CPTPF */
-	rc = roc_cpt_inline_ipsec_inb_cfg(roc_cpt, param1, 0);
+	rc = roc_cpt_inline_ipsec_inb_cfg(roc_cpt, param1, param2, opcode);
 	if (rc && rc != -EEXIST) {
 		plt_err("Failed to setup inbound lf, rc=%d", rc);
 		return rc;
@@ -605,7 +613,7 @@ roc_nix_inl_outb_init(struct roc_nix *roc_nix)
 
 	/* CN9K SA size is different */
 	if (roc_model_is_cn9k())
-		sa_sz = ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ;
+		sa_sz = ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ;
 	else
 		sa_sz = ROC_NIX_INL_OT_IPSEC_OUTB_SA_SZ;
 	/* Alloc contiguous memory of outbound SA */
@@ -1212,7 +1220,12 @@ roc_nix_inl_ctx_write(struct roc_nix *roc_nix, void *sa_dptr, void *sa_cptr,
 
 	/* Nothing much to do on cn9k */
 	if (roc_model_is_cn9k()) {
-		plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
+		nix = roc_nix_to_nix_priv(roc_nix);
+		outb_lf = nix->cpt_lf_base;
+		rc = roc_on_cpt_ctx_write(outb_lf, (uint64_t)sa_dptr, inb,
+					  sa_len, ROC_CPT_DFLT_ENG_GRP_SE_IE);
+		if (rc)
+			return rc;
 		return 0;
 	}
 
diff --git a/drivers/common/cnxk/roc_nix_inl.h b/drivers/common/cnxk/roc_nix_inl.h
index 9911a48..555cb28 100644
--- a/drivers/common/cnxk/roc_nix_inl.h
+++ b/drivers/common/cnxk/roc_nix_inl.h
@@ -22,6 +22,24 @@
 	(ROC_NIX_INL_ONF_IPSEC_OUTB_HW_SZ + ROC_NIX_INL_ONF_IPSEC_OUTB_SW_RSVD)
 #define ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ_LOG2 8
 
+/* ON INB HW area */
+#define ROC_NIX_INL_ON_IPSEC_INB_HW_SZ                                         \
+	PLT_ALIGN(sizeof(struct roc_ie_on_inb_sa), ROC_ALIGN)
+/* ON INB SW reserved area */
+#define ROC_NIX_INL_ON_IPSEC_INB_SW_RSVD 640
+#define ROC_NIX_INL_ON_IPSEC_INB_SA_SZ                                         \
+	(ROC_NIX_INL_ON_IPSEC_INB_HW_SZ + ROC_NIX_INL_ON_IPSEC_INB_SW_RSVD)
+#define ROC_NIX_INL_ON_IPSEC_INB_SA_SZ_LOG2 10
+
+/* ONF OUTB HW area */
+#define ROC_NIX_INL_ON_IPSEC_OUTB_HW_SZ                                        \
+	PLT_ALIGN(sizeof(struct roc_ie_on_outb_sa), ROC_ALIGN)
+/* ONF OUTB SW reserved area */
+#define ROC_NIX_INL_ON_IPSEC_OUTB_SW_RSVD 256
+#define ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ                                        \
+	(ROC_NIX_INL_ON_IPSEC_OUTB_HW_SZ + ROC_NIX_INL_ON_IPSEC_OUTB_SW_RSVD)
+#define ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ_LOG2 9
+
 /* OT INB HW area */
 #define ROC_NIX_INL_OT_IPSEC_INB_HW_SZ                                         \
 	PLT_ALIGN(sizeof(struct roc_ot_ipsec_inb_sa), ROC_ALIGN)
@@ -61,6 +79,34 @@
 #define ROC_NIX_INL_REAS_ZOMBIE_LIMIT	  0xFFF
 #define ROC_NIX_INL_REAS_ZOMBIE_THRESHOLD 10
 
+static inline struct roc_ie_on_inb_sa *
+roc_nix_inl_on_ipsec_inb_sa(uintptr_t base, uint64_t idx)
+{
+	uint64_t off = idx << ROC_NIX_INL_ON_IPSEC_INB_SA_SZ_LOG2;
+
+	return PLT_PTR_ADD(base, off);
+}
+
+static inline struct roc_ie_on_outb_sa *
+roc_nix_inl_on_ipsec_outb_sa(uintptr_t base, uint64_t idx)
+{
+	uint64_t off = idx << ROC_NIX_INL_ON_IPSEC_OUTB_SA_SZ_LOG2;
+
+	return PLT_PTR_ADD(base, off);
+}
+
+static inline void *
+roc_nix_inl_on_ipsec_inb_sa_sw_rsvd(void *sa)
+{
+	return PLT_PTR_ADD(sa, ROC_NIX_INL_ON_IPSEC_INB_HW_SZ);
+}
+
+static inline void *
+roc_nix_inl_on_ipsec_outb_sa_sw_rsvd(void *sa)
+{
+	return PLT_PTR_ADD(sa, ROC_NIX_INL_ON_IPSEC_OUTB_HW_SZ);
+}
+
 static inline struct roc_onf_ipsec_inb_sa *
 roc_nix_inl_onf_ipsec_inb_sa(uintptr_t base, uint64_t idx)
 {
diff --git a/drivers/common/cnxk/roc_nix_inl_dev.c b/drivers/common/cnxk/roc_nix_inl_dev.c
index 1e9b2b9..4fe7b51 100644
--- a/drivers/common/cnxk/roc_nix_inl_dev.c
+++ b/drivers/common/cnxk/roc_nix_inl_dev.c
@@ -394,7 +394,7 @@ nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
 
 	/* CN9K SA is different */
 	if (roc_model_is_cn9k())
-		inb_sa_sz = ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ;
+		inb_sa_sz = ROC_NIX_INL_ON_IPSEC_INB_SA_SZ;
 	else
 		inb_sa_sz = ROC_NIX_INL_OT_IPSEC_INB_SA_SZ;
 
diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c
index 78c181b..8491558 100644
--- a/drivers/crypto/cnxk/cn9k_ipsec.c
+++ b/drivers/crypto/cnxk/cn9k_ipsec.c
@@ -29,7 +29,6 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
 	union cpt_inst_w4 w4;
 	union cpt_inst_w7 w7;
 	size_t ctx_len;
-	uint8_t opcode;
 	uint8_t egrp;
 	int ret;
 
@@ -80,10 +79,9 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
 		return ret;
 
 	ctx_len = ret;
-	opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND;
 	egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
 	ret = roc_on_cpt_ctx_write(&qp->lf, rte_mempool_virt2iova(&sa->out_sa),
-				   opcode, ctx_len, egrp);
+				   false, ctx_len, egrp);
 
 	if (ret)
 		return ret;
@@ -133,7 +131,6 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
 	union cpt_inst_w4 w4;
 	union cpt_inst_w7 w7;
 	size_t ctx_len = 0;
-	uint8_t opcode;
 	uint8_t egrp;
 	int ret = 0;
 
@@ -172,10 +169,9 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
 		sa->esn_en = 1;
 
 	ctx_len = ret;
-	opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND;
 	egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
 	ret = roc_on_cpt_ctx_write(&qp->lf, rte_mempool_virt2iova(&sa->in_sa),
-				   opcode, ctx_len, egrp);
+				   true, ctx_len, egrp);
 	if (ret)
 		return ret;
 
diff --git a/drivers/event/cnxk/cn9k_worker.h b/drivers/event/cnxk/cn9k_worker.h
index b087255..881861f 100644
--- a/drivers/event/cnxk/cn9k_worker.h
+++ b/drivers/event/cnxk/cn9k_worker.h
@@ -626,12 +626,14 @@ cn9k_sso_hws_xmit_sec_one(const struct cn9k_eth_txq *txq, uint64_t base,
 	struct nix_send_hdr_s *send_hdr;
 	uint64_t sa_base = txq->sa_base;
 	uint32_t pkt_len, dlen_adj, rlen;
+	struct roc_ie_on_outb_hdr *hdr;
 	uint64x2_t cmd01, cmd23;
 	uint64_t lmt_status, sa;
 	union nix_send_sg_s *sg;
+	uint32_t esn_lo, esn_hi;
 	uintptr_t dptr, nixtx;
 	uint64_t ucode_cmd[4];
-	uint64_t esn, *iv;
+	uint64_t esn;
 	uint8_t l2_len;
 
 	mdata.u64 = *rte_security_dynfield(m);
@@ -670,14 +672,19 @@ cn9k_sso_hws_xmit_sec_one(const struct cn9k_eth_txq *txq, uint64_t base,
 
 	/* Load opcode and cptr already prepared at pkt metadata set */
 	pkt_len -= l2_len;
-	pkt_len += sizeof(struct roc_onf_ipsec_outb_hdr) +
-		    ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ;
+	pkt_len += (sizeof(struct roc_ie_on_outb_hdr) - ROC_IE_ON_MAX_IV_LEN) +
+		   ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ;
 	sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
 
-	sa = (uintptr_t)roc_nix_inl_onf_ipsec_outb_sa(sa_base, mdata.sa_idx);
+	sa = (uintptr_t)roc_nix_inl_on_ipsec_outb_sa(sa_base, mdata.sa_idx);
 	ucode_cmd[3] = (ROC_CPT_DFLT_ENG_GRP_SE_IE << 61 | sa);
-	ucode_cmd[0] = (ROC_IE_ONF_MAJOR_OP_PROCESS_OUTBOUND_IPSEC << 48 |
-			0x40UL << 48 | pkt_len);
+	ucode_cmd[0] = (((ROC_IE_ON_OUTB_MAX_CTX_LEN << 8) |
+			 ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC)
+				<< 48 |
+			(ROC_IE_ON_OUTB_IKEV2_SINGLE_SA_SUPPORT |
+			 (ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ >>
+			  3)) << 32 |
+			pkt_len);
 
 	/* CPT Word 0 and Word 1 */
 	cmd01 = vdupq_n_u64((nixtx + 16) | (cn9k_nix_tx_ext_subs(flags) + 1));
@@ -687,35 +694,40 @@ cn9k_sso_hws_xmit_sec_one(const struct cn9k_eth_txq *txq, uint64_t base,
 	/* CPT word 2 and 3 */
 	cmd23 = vdupq_n_u64(0);
 	cmd23 = vsetq_lane_u64((((uint64_t)RTE_EVENT_TYPE_CPU << 28) |
-				CNXK_ETHDEV_SEC_OUTB_EV_SUB << 20), cmd23, 0);
-	cmd23 = vsetq_lane_u64((uintptr_t)m | 1, cmd23, 1);
+				CNXK_ETHDEV_SEC_OUTB_EV_SUB << 20),
+			       cmd23, 0);
+	cmd23 = vsetq_lane_u64(((uintptr_t)m + sizeof(struct rte_mbuf)) | 1,
+			       cmd23, 1);
 
 	dptr += l2_len - ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ -
-		sizeof(struct roc_onf_ipsec_outb_hdr);
+		(sizeof(struct roc_ie_on_outb_hdr) - ROC_IE_ON_MAX_IV_LEN);
 	ucode_cmd[1] = dptr;
 	ucode_cmd[2] = dptr;
 
-	/* Update IV to zero and l2 sz */
-	*(uint16_t *)(dptr + sizeof(struct roc_onf_ipsec_outb_hdr)) =
+	/* Update l2 sz */
+	*(uint16_t *)(dptr + (sizeof(struct roc_ie_on_outb_hdr) -
+			      ROC_IE_ON_MAX_IV_LEN)) =
 		rte_cpu_to_be_16(ROC_ONF_IPSEC_OUTB_MAX_L2_INFO_SZ);
-	iv = (uint64_t *)(dptr + 8);
-	iv[0] = 0;
-	iv[1] = 0;
 
 	/* Head wait if needed */
 	if (base)
 		roc_sso_hws_head_wait(base);
 
 	/* ESN */
-	outb_priv = roc_nix_inl_onf_ipsec_outb_sa_sw_rsvd((void *)sa);
+	outb_priv = roc_nix_inl_on_ipsec_outb_sa_sw_rsvd((void *)sa);
 	esn = outb_priv->esn;
 	outb_priv->esn = esn + 1;
 
 	ucode_cmd[0] |= (esn >> 32) << 16;
-	esn = rte_cpu_to_be_32(esn & (BIT_ULL(32) - 1));
+	esn_lo = rte_cpu_to_be_32(esn & (BIT_ULL(32) - 1));
+	esn_hi = rte_cpu_to_be_32(esn >> 32);
 
-	/* Update ESN and IPID and IV */
-	*(uint64_t *)dptr = esn << 32 | esn;
+	/* Update ESN, IPID and IV */
+	hdr = (struct roc_ie_on_outb_hdr *)dptr;
+	hdr->ip_id = esn_lo;
+	hdr->seq = esn_lo;
+	hdr->esn = esn_hi;
+	hdr->df_tos = 0;
 
 	rte_io_wmb();
 	cn9k_sso_txq_fc_wait(txq);
diff --git a/drivers/net/cnxk/cn9k_ethdev.h b/drivers/net/cnxk/cn9k_ethdev.h
index 449729f..472a4b0 100644
--- a/drivers/net/cnxk/cn9k_ethdev.h
+++ b/drivers/net/cnxk/cn9k_ethdev.h
@@ -79,6 +79,9 @@ struct cn9k_outb_priv_data {
 
 	/* Back pointer to eth sec session */
 	struct cnxk_eth_sec_sess *eth_sec;
+
+	/* IV in DBG mode */
+	uint8_t iv_dbg[ROC_IE_ON_MAX_IV_LEN];
 };
 
 struct cn9k_sec_sess_priv {
diff --git a/drivers/net/cnxk/cn9k_ethdev_sec.c b/drivers/net/cnxk/cn9k_ethdev_sec.c
index 4dd0b61..88b95fb 100644
--- a/drivers/net/cnxk/cn9k_ethdev_sec.c
+++ b/drivers/net/cnxk/cn9k_ethdev_sec.c
@@ -134,6 +134,37 @@ ar_window_init(struct cn9k_inb_priv_data *inb_priv)
 	return 0;
 }
 
+static void
+outb_dbg_iv_update(struct roc_ie_on_common_sa *common_sa, const char *__iv_str)
+{
+	uint8_t *iv_dbg = common_sa->iv.aes_iv;
+	char *iv_str = strdup(__iv_str);
+	char *iv_b = NULL;
+	char *save;
+	int i, iv_len = ROC_IE_ON_MAX_IV_LEN;
+
+	if (!iv_str)
+		return;
+
+	if (common_sa->ctl.enc_type == ROC_IE_OT_SA_ENC_AES_GCM ||
+	    common_sa->ctl.enc_type == ROC_IE_OT_SA_ENC_AES_CTR ||
+	    common_sa->ctl.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
+	    common_sa->ctl.auth_type == ROC_IE_OT_SA_AUTH_AES_GMAC) {
+		iv_dbg = common_sa->iv.gcm.iv;
+		iv_len = 8;
+	}
+
+	memset(iv_dbg, 0, iv_len);
+	for (i = 0; i < iv_len; i++) {
+		iv_b = strtok_r(i ? NULL : iv_str, ",", &save);
+		if (!iv_b)
+			break;
+		iv_dbg[i] = strtoul(iv_b, NULL, 0);
+	}
+
+	free(iv_str);
+}
+
 static int
 cn9k_eth_sec_session_create(void *device,
 			    struct rte_security_session_conf *conf,
@@ -150,6 +181,7 @@ cn9k_eth_sec_session_create(void *device,
 	rte_spinlock_t *lock;
 	char tbuf[128] = {0};
 	bool inbound;
+	int ctx_len;
 	int rc = 0;
 
 	if (conf->action_type != RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
@@ -183,21 +215,26 @@ cn9k_eth_sec_session_create(void *device,
 	memset(eth_sec, 0, sizeof(struct cnxk_eth_sec_sess));
 	sess_priv.u64 = 0;
 
+	if (!dev->outb.lf_base) {
+		plt_err("Could not allocate security session private data");
+		return -ENOMEM;
+	}
+
 	if (inbound) {
 		struct cn9k_inb_priv_data *inb_priv;
-		struct roc_onf_ipsec_inb_sa *inb_sa;
+		struct roc_ie_on_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);
+				  ROC_NIX_INL_ON_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(nix, false, ipsec->spi);
+		inb_sa = (struct roc_ie_on_inb_sa *)roc_nix_inl_inb_sa_get(
+			nix, false, ipsec->spi);
 		if (!inb_sa) {
 			snprintf(tbuf, sizeof(tbuf),
 				 "Failed to create ingress sa");
@@ -206,7 +243,7 @@ cn9k_eth_sec_session_create(void *device,
 		}
 
 		/* Check if SA is already in use */
-		if (inb_sa->ctl.valid) {
+		if (inb_sa->common_sa.ctl.valid) {
 			snprintf(tbuf, sizeof(tbuf),
 				 "Inbound SA with SPI %u already in use",
 				 ipsec->spi);
@@ -214,17 +251,26 @@ cn9k_eth_sec_session_create(void *device,
 			goto mempool_put;
 		}
 
-		memset(inb_sa, 0, sizeof(struct roc_onf_ipsec_inb_sa));
+		memset(inb_sa, 0, sizeof(struct roc_ie_on_inb_sa));
 
 		/* Fill inbound sa params */
-		rc = cnxk_onf_ipsec_inb_sa_fill(inb_sa, ipsec, crypto);
-		if (rc) {
+		rc = cnxk_on_ipsec_inb_sa_create(ipsec, crypto, inb_sa);
+		if (rc < 0) {
 			snprintf(tbuf, sizeof(tbuf),
 				 "Failed to init inbound sa, rc=%d", rc);
 			goto mempool_put;
 		}
 
-		inb_priv = roc_nix_inl_onf_ipsec_inb_sa_sw_rsvd(inb_sa);
+		ctx_len = rc;
+		rc = roc_nix_inl_ctx_write(&dev->nix, inb_sa, inb_sa, inbound,
+					   ctx_len);
+		if (rc) {
+			snprintf(tbuf, sizeof(tbuf),
+				 "Failed to create inbound sa, rc=%d", rc);
+			goto mempool_put;
+		}
+
+		inb_priv = roc_nix_inl_on_ipsec_inb_sa_sw_rsvd(inb_sa);
 		/* Back pointer to get eth_sec */
 		inb_priv->eth_sec = eth_sec;
 
@@ -253,27 +299,38 @@ cn9k_eth_sec_session_create(void *device,
 		dev->inb.nb_sess++;
 	} else {
 		struct cn9k_outb_priv_data *outb_priv;
-		struct roc_onf_ipsec_outb_sa *outb_sa;
 		uintptr_t sa_base = dev->outb.sa_base;
 		struct cnxk_ipsec_outb_rlens *rlens;
+		struct roc_ie_on_outb_sa *outb_sa;
+		const char *iv_str;
 		uint32_t sa_idx;
 
 		PLT_STATIC_ASSERT(sizeof(struct cn9k_outb_priv_data) <
-				  ROC_NIX_INL_ONF_IPSEC_OUTB_SW_RSVD);
+				  ROC_NIX_INL_ON_IPSEC_OUTB_SW_RSVD);
 
 		/* Alloc an sa index */
 		rc = cnxk_eth_outb_sa_idx_get(dev, &sa_idx, 0);
 		if (rc)
 			goto mempool_put;
 
-		outb_sa = roc_nix_inl_onf_ipsec_outb_sa(sa_base, sa_idx);
-		outb_priv = roc_nix_inl_onf_ipsec_outb_sa_sw_rsvd(outb_sa);
+		outb_sa = roc_nix_inl_on_ipsec_outb_sa(sa_base, sa_idx);
+		outb_priv = roc_nix_inl_on_ipsec_outb_sa_sw_rsvd(outb_sa);
 		rlens = &outb_priv->rlens;
 
-		memset(outb_sa, 0, sizeof(struct roc_onf_ipsec_outb_sa));
+		memset(outb_sa, 0, sizeof(struct roc_ie_on_outb_sa));
 
 		/* Fill outbound sa params */
-		rc = cnxk_onf_ipsec_outb_sa_fill(outb_sa, ipsec, crypto);
+		rc = cnxk_on_ipsec_outb_sa_create(ipsec, crypto, outb_sa);
+		if (rc < 0) {
+			snprintf(tbuf, sizeof(tbuf),
+				 "Failed to init outbound sa, rc=%d", rc);
+			rc |= cnxk_eth_outb_sa_idx_put(dev, sa_idx);
+			goto mempool_put;
+		}
+
+		ctx_len = rc;
+		rc = roc_nix_inl_ctx_write(&dev->nix, outb_sa, outb_sa, inbound,
+					   ctx_len);
 		if (rc) {
 			snprintf(tbuf, sizeof(tbuf),
 				 "Failed to init outbound sa, rc=%d", rc);
@@ -281,6 +338,18 @@ cn9k_eth_sec_session_create(void *device,
 			goto mempool_put;
 		}
 
+		/* Always enable explicit IV.
+		 * Copy the IV from application only when iv_gen_disable flag is
+		 * set
+		 */
+		outb_sa->common_sa.ctl.explicit_iv_en = 1;
+
+		if (conf->ipsec.options.iv_gen_disable == 1) {
+			iv_str = getenv("ETH_SEC_IV_OVR");
+			if (iv_str)
+				outb_dbg_iv_update(&outb_sa->common_sa, iv_str);
+		}
+
 		/* Save userdata */
 		outb_priv->userdata = conf->userdata;
 		outb_priv->sa_idx = sa_idx;
@@ -288,8 +357,8 @@ cn9k_eth_sec_session_create(void *device,
 		/* Start sequence number with 1 */
 		outb_priv->seq = 1;
 
-		memcpy(&outb_priv->nonce, outb_sa->nonce, 4);
-		if (outb_sa->ctl.enc_type == ROC_IE_ON_SA_ENC_AES_GCM)
+		memcpy(&outb_priv->nonce, outb_sa->common_sa.iv.gcm.nonce, 4);
+		if (outb_sa->common_sa.ctl.enc_type == ROC_IE_ON_SA_ENC_AES_GCM)
 			outb_priv->copy_salt = 1;
 
 		/* Save rlen info */
@@ -337,9 +406,9 @@ cn9k_eth_sec_session_destroy(void *device, struct rte_security_session *sess)
 {
 	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
 	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
-	struct roc_onf_ipsec_outb_sa *outb_sa;
-	struct roc_onf_ipsec_inb_sa *inb_sa;
 	struct cnxk_eth_sec_sess *eth_sec;
+	struct roc_ie_on_outb_sa *outb_sa;
+	struct roc_ie_on_inb_sa *inb_sa;
 	struct rte_mempool *mp;
 	rte_spinlock_t *lock;
 
@@ -353,14 +422,14 @@ cn9k_eth_sec_session_destroy(void *device, struct rte_security_session *sess)
 	if (eth_sec->inb) {
 		inb_sa = eth_sec->sa;
 		/* Disable SA */
-		inb_sa->ctl.valid = 0;
+		inb_sa->common_sa.ctl.valid = 0;
 
 		TAILQ_REMOVE(&dev->inb.list, eth_sec, entry);
 		dev->inb.nb_sess--;
 	} else {
 		outb_sa = eth_sec->sa;
 		/* Disable SA */
-		outb_sa->ctl.valid = 0;
+		outb_sa->common_sa.ctl.valid = 0;
 
 		/* Release Outbound SA index */
 		cnxk_eth_outb_sa_idx_put(dev, eth_sec->sa_idx);
diff --git a/drivers/net/cnxk/cn9k_rx.h b/drivers/net/cnxk/cn9k_rx.h
index 25a4927..1a9f920 100644
--- a/drivers/net/cnxk/cn9k_rx.h
+++ b/drivers/net/cnxk/cn9k_rx.h
@@ -171,7 +171,7 @@ nix_cqe_xtract_mseg(const union nix_rx_parse_u *rx, struct rte_mbuf *mbuf,
 }
 
 static inline int
-ipsec_antireplay_check(struct roc_onf_ipsec_inb_sa *sa,
+ipsec_antireplay_check(struct roc_ie_on_inb_sa *sa,
 		       struct cn9k_inb_priv_data *priv, uintptr_t data,
 		       uint32_t win_sz)
 {
@@ -183,7 +183,7 @@ ipsec_antireplay_check(struct roc_onf_ipsec_inb_sa *sa,
 	uint8_t esn;
 	int rc;
 
-	esn = sa->ctl.esn_en;
+	esn = sa->common_sa.ctl.esn_en;
 	seql = rte_be_to_cpu_32(*((uint32_t *)(data + IPSEC_SQ_LO_IDX)));
 
 	if (!esn) {
@@ -200,11 +200,12 @@ ipsec_antireplay_check(struct roc_onf_ipsec_inb_sa *sa,
 	rte_spinlock_lock(&ar->lock);
 	rc = cnxk_on_anti_replay_check(seq, ar, win_sz);
 	if (esn && !rc) {
-		seq_in_sa = ((uint64_t)rte_be_to_cpu_32(sa->esn_hi) << 32) |
-			    rte_be_to_cpu_32(sa->esn_low);
+		seq_in_sa = ((uint64_t)rte_be_to_cpu_32(sa->common_sa.seq_t.th)
+			     << 32) |
+			    rte_be_to_cpu_32(sa->common_sa.seq_t.tl);
 		if (seq > seq_in_sa) {
-			sa->esn_low = rte_cpu_to_be_32(seql);
-			sa->esn_hi = rte_cpu_to_be_32(seqh);
+			sa->common_sa.seq_t.tl = rte_cpu_to_be_32(seql);
+			sa->common_sa.seq_t.th = rte_cpu_to_be_32(seqh);
 		}
 	}
 	rte_spinlock_unlock(&ar->lock);
@@ -266,9 +267,10 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
 	const union nix_rx_parse_u *rx =
 		(const union nix_rx_parse_u *)((const uint64_t *)cq + 1);
 	struct cn9k_inb_priv_data *sa_priv;
-	struct roc_onf_ipsec_inb_sa *sa;
+	struct roc_ie_on_inb_sa *sa;
 	uint8_t lcptr = rx->lcptr;
-	struct rte_ipv4_hdr *ipv4;
+	struct rte_ipv4_hdr *ip;
+	struct rte_ipv6_hdr *ip6;
 	uint16_t data_off, res;
 	uint32_t spi, win_sz;
 	uint32_t spi_mask;
@@ -279,6 +281,7 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
 	res = *(uint64_t *)(res_sg0 + 8);
 	data_off = *rearm_val & (BIT_ULL(16) - 1);
 	data = (uintptr_t)m->buf_addr;
+
 	data += data_off;
 
 	rte_prefetch0((void *)data);
@@ -294,10 +297,10 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
 	sa_w = sa_base & (ROC_NIX_INL_SA_BASE_ALIGN - 1);
 	sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
 	spi_mask = (1ULL << sa_w) - 1;
-	sa = roc_nix_inl_onf_ipsec_inb_sa(sa_base, spi & spi_mask);
+	sa = roc_nix_inl_on_ipsec_inb_sa(sa_base, spi & spi_mask);
 
 	/* Update dynamic field with userdata */
-	sa_priv = roc_nix_inl_onf_ipsec_inb_sa_sw_rsvd(sa);
+	sa_priv = roc_nix_inl_on_ipsec_inb_sa_sw_rsvd(sa);
 	dw = *(__uint128_t *)sa_priv;
 	*rte_security_dynfield(m) = (uint64_t)dw;
 
@@ -309,16 +312,26 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
 	}
 
 	/* Get total length from IPv4 header. We can assume only IPv4 */
-	ipv4 = (struct rte_ipv4_hdr *)(data + ROC_ONF_IPSEC_INB_SPI_SEQ_SZ +
-				       ROC_ONF_IPSEC_INB_MAX_L2_SZ);
+	ip = (struct rte_ipv4_hdr *)(data + ROC_ONF_IPSEC_INB_SPI_SEQ_SZ +
+				     ROC_ONF_IPSEC_INB_MAX_L2_SZ);
+
+	if (((ip->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER) ==
+	    IPVERSION) {
+		*len = rte_be_to_cpu_16(ip->total_length) + lcptr;
+	} else {
+		PLT_ASSERT(((ip->version_ihl & 0xf0) >>
+			    RTE_IPV4_IHL_MULTIPLIER) == 6);
+		ip6 = (struct rte_ipv6_hdr *)ip;
+		*len = rte_be_to_cpu_16(ip6->payload_len) +
+		       sizeof(struct rte_ipv6_hdr) + lcptr;
+	}
 
 	/* Update data offset */
-	data_off += (ROC_ONF_IPSEC_INB_SPI_SEQ_SZ +
-		     ROC_ONF_IPSEC_INB_MAX_L2_SZ);
+	data_off +=
+		(ROC_ONF_IPSEC_INB_SPI_SEQ_SZ + ROC_ONF_IPSEC_INB_MAX_L2_SZ);
 	*rearm_val = *rearm_val & ~(BIT_ULL(16) - 1);
 	*rearm_val |= data_off;
 
-	*len = rte_be_to_cpu_16(ipv4->total_length) + lcptr;
 	return RTE_MBUF_F_RX_SEC_OFFLOAD;
 }
 
diff --git a/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c b/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c
index bfdbd1e..dd8b7a5 100644
--- a/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c
+++ b/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c
@@ -14,59 +14,47 @@
 static int
 copy_outb_sa_9k(struct rte_tel_data *d, uint32_t i, void *sa)
 {
-	struct roc_onf_ipsec_outb_sa *out_sa;
 	union {
-		struct roc_ie_onf_sa_ctl ctl;
+		struct roc_ie_on_sa_ctl ctl;
 		uint64_t u64;
 	} w0;
+	struct roc_ie_on_outb_sa *out_sa;
 	char strw0[W0_MAXLEN];
 	char str[STR_MAXLEN];
 
-	out_sa = (struct roc_onf_ipsec_outb_sa *)sa;
-	w0.ctl = out_sa->ctl;
+	out_sa = (struct roc_ie_on_outb_sa *)sa;
+	w0.ctl = out_sa->common_sa.ctl;
 
 	snprintf(str, sizeof(str), "outsa_w0_%u", i);
 	snprintf(strw0, sizeof(strw0), "%" PRIu64, w0.u64);
 	rte_tel_data_add_dict_string(d, str, strw0);
 
-	snprintf(str, sizeof(str), "outsa_src_%u", i);
-	rte_tel_data_add_dict_u64(d, str, out_sa->udp_src);
-
-	snprintf(str, sizeof(str), "outsa_dst_%u", i);
-	rte_tel_data_add_dict_u64(d, str, out_sa->udp_dst);
-
-	snprintf(str, sizeof(str), "outsa_isrc_%u", i);
-	rte_tel_data_add_dict_u64(d, str, out_sa->ip_src);
-
-	snprintf(str, sizeof(str), "outsa_idst_%u", i);
-	rte_tel_data_add_dict_u64(d, str, out_sa->ip_dst);
-
 	return 0;
 }
 
 static int
 copy_inb_sa_9k(struct rte_tel_data *d, uint32_t i, void *sa)
 {
-	struct roc_onf_ipsec_inb_sa *in_sa;
 	union {
-		struct roc_ie_onf_sa_ctl ctl;
+		struct roc_ie_on_sa_ctl ctl;
 		uint64_t u64;
 	} w0;
+	struct roc_ie_on_inb_sa *in_sa;
 	char strw0[W0_MAXLEN];
 	char str[STR_MAXLEN];
 
-	in_sa = (struct roc_onf_ipsec_inb_sa *)sa;
-	w0.ctl = in_sa->ctl;
+	in_sa = (struct roc_ie_on_inb_sa *)sa;
+	w0.ctl = in_sa->common_sa.ctl;
 
 	snprintf(str, sizeof(str), "insa_w0_%u", i);
 	snprintf(strw0, sizeof(strw0), "%" PRIu64, w0.u64);
 	rte_tel_data_add_dict_string(d, str, strw0);
 
 	snprintf(str, sizeof(str), "insa_esnh_%u", i);
-	rte_tel_data_add_dict_u64(d, str, in_sa->esn_hi);
+	rte_tel_data_add_dict_u64(d, str, in_sa->common_sa.seq_t.th);
 
 	snprintf(str, sizeof(str), "insa_esnl_%u", i);
-	rte_tel_data_add_dict_u64(d, str, in_sa->esn_low);
+	rte_tel_data_add_dict_u64(d, str, in_sa->common_sa.seq_t.tl);
 
 	return 0;
 }
