diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index 4f7fd1b..215d9fd 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -161,6 +161,26 @@ ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 		return -EINVAL;
 	}
 
+	if (ipsec_xfrm->life.packets_soft_limit != 0 ||
+	    ipsec_xfrm->life.packets_hard_limit != 0) {
+		if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
+		    ipsec_xfrm->life.bytes_hard_limit != 0) {
+			plt_err("Expiry tracking with both packets & bytes is not supported");
+			return -EINVAL;
+		}
+		w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS;
+	}
+
+	if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
+	    ipsec_xfrm->life.bytes_hard_limit != 0) {
+		if (ipsec_xfrm->life.packets_soft_limit != 0 ||
+		    ipsec_xfrm->life.packets_hard_limit != 0) {
+			plt_err("Expiry tracking with both packets & bytes is not supported");
+			return -EINVAL;
+		}
+		w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS;
+	}
+
 	return 0;
 }
 
@@ -236,6 +256,31 @@ cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa,
 		 ROC_CTX_UNIT_128B) -
 		1;
 
+	/**
+	 * CPT MC triggers expiry when counter value changes from 2 to 1. To
+	 * mitigate this behaviour add 1 to the life counter values provided.
+	 */
+
+	if (ipsec_xfrm->life.bytes_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.bytes_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
 	/* There are two words of CPT_CTX_HW_S for ucode to skip */
 	sa->w0.s.ctx_hdr_size = 1;
 	sa->w0.s.aop_valid = 1;
@@ -360,6 +405,31 @@ cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa,
 	/* IPID gen */
 	sa->w2.s.ipid_gen = 1;
 
+	/**
+	 * CPT MC triggers expiry when counter value changes from 2 to 1. To
+	 * mitigate this behaviour add 1 to the life counter values provided.
+	 */
+
+	if (ipsec_xfrm->life.bytes_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.bytes_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
 	/* There are two words of CPT_CTX_HW_S for ucode to skip */
 	sa->w0.s.ctx_hdr_size = 1;
 	sa->w0.s.aop_valid = 1;
diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index cccca77..e6ed733 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -348,12 +348,44 @@ cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
 			       struct cpt_inflight_req *infl_req)
 {
 	struct cpt_cn10k_res_s *res = (struct cpt_cn10k_res_s *)&infl_req->res;
+	const uint8_t uc_compcode = res->uc_compcode;
+	const uint8_t compcode = res->compcode;
 	unsigned int sz;
 
-	if (likely(res->compcode == CPT_COMP_GOOD ||
-		   res->compcode == CPT_COMP_WARN)) {
-		if (unlikely(res->uc_compcode)) {
-			if (res->uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+
+	if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
+	    cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
+		if (likely(compcode == CPT_COMP_WARN)) {
+			if (unlikely(uc_compcode != ROC_IE_OT_UCC_SUCCESS)) {
+				/* Success with additional info */
+				switch (uc_compcode) {
+				case ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_FIRST:
+					cop->aux_flags =
+						RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY;
+					break;
+				default:
+					break;
+				}
+			}
+			cn10k_cpt_sec_post_process(cop, res);
+		} else {
+			cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+			plt_dp_info("HW completion code 0x%x", res->compcode);
+			if (compcode == CPT_COMP_GOOD) {
+				plt_dp_info(
+					"Request failed with microcode error");
+				plt_dp_info("MC completion code 0x%x",
+					    uc_compcode);
+			}
+		}
+
+		return;
+	}
+
+	if (likely(compcode == CPT_COMP_GOOD || compcode == CPT_COMP_WARN)) {
+		if (unlikely(uc_compcode)) {
+			if (uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
 				cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
 			else
 				cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
@@ -364,13 +396,7 @@ cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
 			goto temp_sess_free;
 		}
 
-		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
 		if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
-			if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
-				cn10k_cpt_sec_post_process(cop, res);
-				return;
-			}
-
 			/* Verify authentication data if required */
 			if (unlikely(infl_req->op_flags &
 				     CPT_OP_FLAGS_AUTH_VERIFY)) {
@@ -392,7 +418,7 @@ cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
 		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
 		plt_dp_info("HW completion code 0x%x", res->compcode);
 
-		switch (res->compcode) {
+		switch (compcode) {
 		case CPT_COMP_INSTERR:
 			plt_dp_err("Request failed with instruction error");
 			break;
diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c
index 0b63cc4..63ae025 100644
--- a/drivers/crypto/cnxk/cn9k_ipsec.c
+++ b/drivers/crypto/cnxk/cn9k_ipsec.c
@@ -485,7 +485,11 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
 static inline int
 cn9k_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec)
 {
-	RTE_SET_USED(ipsec);
+	if (ipsec->life.bytes_hard_limit != 0 ||
+	    ipsec->life.bytes_soft_limit != 0 ||
+	    ipsec->life.packets_hard_limit != 0 ||
+	    ipsec->life.packets_soft_limit != 0)
+		return -ENOTSUP;
 
 	return 0;
 }
