+static __rte_always_inline void
+nix_sec_flush_meta_burst(uint16_t lmt_id, uint64_t data, uint16_t lnum,
+ uintptr_t aura_handle)
+{
+ uint64_t pa;
+
+ /* Prepare PA and Data */
+ pa = roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_BATCH_FREE0;
+ pa |= ((data & 0x7) << 4);
+
+ data >>= 3;
+ data <<= 19;
+ data |= (uint64_t)lmt_id;
+ data |= (uint64_t)(lnum - 1) << 12;
+
+ roc_lmt_submit_steorl(data, pa);
+}
+
+static __rte_always_inline void
+nix_sec_flush_meta(uintptr_t laddr, uint16_t lmt_id, uint8_t loff,
+ uintptr_t aura_handle)
+{
+ uint64_t pa;
+
+ /* laddr is pointing to first pointer */
+ laddr -= 8;
+
+ /* Trigger free either on lmtline full or different aura handle */
+ pa = roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_BATCH_FREE0;
+
+ /* Update aura handle */
+ *(uint64_t *)laddr = (((uint64_t)(loff & 0x1) << 32) |
+ roc_npa_aura_handle_to_aura(aura_handle));
+
+ pa |= ((uint64_t)(loff >> 1) << 4);
+ roc_lmt_submit_steorl(lmt_id, pa);
+}
+
+static struct rte_mbuf *
+nix_sec_attach_frags(const struct cpt_parse_hdr_s *hdr,
+ struct cn10k_inb_priv_data *inb_priv,
+ const uint64_t mbuf_init)
+{
+ struct rte_mbuf *head, *mbuf, *mbuf_prev;
+ uint32_t offset = hdr->w2.fi_offset;
+ union nix_rx_parse_u *frag_rx;
+ struct cpt_frag_info_s *finfo;
+ uint64_t *frag_ptr = NULL;
+ uint64_t ol_flags;
+ uint16_t frag_size;
+ uint16_t rlen;
+ uint64_t *wqe;
+ int off;
+
+ off = inb_priv->reass_dynfield_off;
+ ol_flags = BIT_ULL(inb_priv->reass_dynflag_bit);
+ ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
+
+ /* offset of 0 implies 256B, otherwise it implies offset*8B */
+ offset = (((offset - 1) & 0x1f) + 1) * 8;
+ finfo = RTE_PTR_ADD(hdr, offset + hdr->w2.fi_pad);
+
+ /* Frag-0: */
+ wqe = (uint64_t *)(rte_be_to_cpu_64(hdr->wqe_ptr));
+ rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
+
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+ frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
+ frag_rx->pkt_lenm1 = frag_size - 1;
+
+ mbuf = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
+ mbuf->data_len = frag_size;
+ mbuf->pkt_len = frag_size;
+ mbuf->ol_flags = ol_flags;
+ mbuf->next = NULL;
+ head = mbuf;
+ mbuf_prev = mbuf;
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
+
+ cnxk_ip_reassembly_dynfield(head, off)->nb_frags = hdr->w0.num_frags - 1;
+ cnxk_ip_reassembly_dynfield(head, off)->next_frag = NULL;
+
+ /* Frag-1: */
+ if (hdr->w0.num_frags > 1) {
+ wqe = (uint64_t *)(rte_be_to_cpu_64(hdr->frag1_wqe_ptr));
+ rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
+
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+ frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
+ frag_rx->pkt_lenm1 = frag_size - 1;
+
+ mbuf = (struct rte_mbuf *)((uintptr_t)wqe -
+ sizeof(struct rte_mbuf));
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
+ mbuf->data_len = frag_size;
+ mbuf->pkt_len = frag_size;
+ mbuf->ol_flags = ol_flags;
+ mbuf->next = NULL;
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
+
+ cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags =
+ hdr->w0.num_frags - 2;
+ cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
+ cnxk_ip_reassembly_dynfield(mbuf_prev, off)->next_frag = mbuf;
+ mbuf_prev = mbuf;
+ }
+
+ /* Frag-2: */
+ if (hdr->w0.num_frags > 2) {
+ frag_ptr = (uint64_t *)(finfo + 1);
+ wqe = (uint64_t *)(rte_be_to_cpu_64(*frag_ptr));
+ rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
+
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+ frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
+ frag_rx->pkt_lenm1 = frag_size - 1;
+
+ mbuf = (struct rte_mbuf *)((uintptr_t)wqe -
+ sizeof(struct rte_mbuf));
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
+ mbuf->data_len = frag_size;
+ mbuf->pkt_len = frag_size;
+ mbuf->ol_flags = ol_flags;
+ mbuf->next = NULL;
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
+
+ cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags =
+ hdr->w0.num_frags - 3;
+ cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
+ cnxk_ip_reassembly_dynfield(mbuf_prev, off)->next_frag = mbuf;
+ mbuf_prev = mbuf;
+ }
+
+ /* Frag-3: */
+ if (hdr->w0.num_frags > 3) {
+ wqe = (uint64_t *)(rte_be_to_cpu_64(*(frag_ptr + 1)));
+ rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
+
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+ frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
+ frag_rx->pkt_lenm1 = frag_size - 1;
+
+ mbuf = (struct rte_mbuf *)((uintptr_t)wqe -
+ sizeof(struct rte_mbuf));
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
+ mbuf->data_len = frag_size;
+ mbuf->pkt_len = frag_size;
+ mbuf->ol_flags = ol_flags;
+ mbuf->next = NULL;
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
+
+ cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags =
+ hdr->w0.num_frags - 4;
+ cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
+ cnxk_ip_reassembly_dynfield(mbuf_prev, off)->next_frag = mbuf;
+ }
+ return head;
+}
+
+static struct rte_mbuf *
+nix_sec_reassemble_frags(const struct cpt_parse_hdr_s *hdr, uint64_t cq_w1,
+ uint64_t cq_w5, uint64_t mbuf_init)
+{
+ uint32_t fragx_sum, pkt_hdr_len, l3_hdr_size;
+ uint32_t offset = hdr->w2.fi_offset;
+ union nix_rx_parse_u *inner_rx;
+ uint16_t rlen, data_off, b_off;
+ union nix_rx_parse_u *frag_rx;
+ struct cpt_frag_info_s *finfo;
+ struct rte_mbuf *head, *mbuf;
+ uint64_t *frag_ptr = NULL;
+ rte_iova_t *inner_iova;
+ uint16_t frag_size;
+ uint64_t *wqe;
+
+ /* Base data offset */
+ b_off = mbuf_init & 0xFFFFUL;
+ mbuf_init &= ~0xFFFFUL;
+
+ /* offset of 0 implies 256B, otherwise it implies offset*8B */
+ offset = (((offset - 1) & 0x1f) + 1) * 8;
+ finfo = RTE_PTR_ADD(hdr, offset + hdr->w2.fi_pad);
+
+ /* Frag-0: */
+ wqe = (uint64_t *)rte_be_to_cpu_64(hdr->wqe_ptr);
+ inner_rx = (union nix_rx_parse_u *)(wqe + 1);
+ inner_iova = (rte_iova_t *)*(wqe + 9);
+
+ /* Update only the upper 28-bits from meta pkt parse info */
+ *((uint64_t *)inner_rx) = ((*((uint64_t *)inner_rx) & ((1ULL << 36) - 1)) |
+ (cq_w1 & ~((1ULL << 36) - 1)));
+
+ rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
+ frag_size = rlen + ((cq_w5 >> 16) & 0xFF) - (cq_w5 & 0xFF);
+ fragx_sum = rte_be_to_cpu_16(finfo->w1.frag_size0);
+ pkt_hdr_len = frag_size - fragx_sum;
+
+ mbuf = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | b_off;
+ mbuf->data_len = frag_size;
+ head = mbuf;
+
+ if (inner_rx->lctype == NPC_LT_LC_IP) {
+ struct rte_ipv4_hdr *hdr = (struct rte_ipv4_hdr *)
+ RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
+
+ l3_hdr_size = (hdr->version_ihl & 0xf) << 2;
+ } else {
+ struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)
+ RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
+ size_t ext_len = sizeof(struct rte_ipv6_hdr);
+ uint8_t *nxt_hdr = (uint8_t *)hdr;
+ int nh = hdr->proto;
+
+ l3_hdr_size = 0;
+ while (nh != -EINVAL) {
+ nxt_hdr += ext_len;
+ l3_hdr_size += ext_len;
+ nh = rte_ipv6_get_next_ext(nxt_hdr, nh, &ext_len);
+ }
+ }
+
+ /* Frag-1: */
+ wqe = (uint64_t *)(rte_be_to_cpu_64(hdr->frag1_wqe_ptr));
+ frag_size = rte_be_to_cpu_16(finfo->w1.frag_size1);
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+
+ mbuf->next = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
+ mbuf = mbuf->next;
+ data_off = b_off + frag_rx->lcptr + l3_hdr_size;
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
+ mbuf->data_len = frag_size;
+ fragx_sum += frag_size;
+
+ /* Frag-2: */
+ if (hdr->w0.num_frags > 2) {
+ frag_ptr = (uint64_t *)(finfo + 1);
+ wqe = (uint64_t *)(rte_be_to_cpu_64(*frag_ptr));
+ frag_size = rte_be_to_cpu_16(finfo->w1.frag_size2);
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+
+ mbuf->next = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
+ mbuf = mbuf->next;
+ data_off = b_off + frag_rx->lcptr + l3_hdr_size;
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
+ mbuf->data_len = frag_size;
+ fragx_sum += frag_size;
+ }
+
+ /* Frag-3: */
+ if (hdr->w0.num_frags > 3) {
+ wqe = (uint64_t *)(rte_be_to_cpu_64(*(frag_ptr + 1)));
+ frag_size = rte_be_to_cpu_16(finfo->w1.frag_size3);
+ frag_rx = (union nix_rx_parse_u *)(wqe + 1);
+
+ mbuf->next = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
+ mbuf = mbuf->next;
+ data_off = b_off + frag_rx->lcptr + l3_hdr_size;
+ *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
+ mbuf->data_len = frag_size;
+ fragx_sum += frag_size;
+ }
+
+ if (inner_rx->lctype == NPC_LT_LC_IP) {
+ struct rte_ipv4_hdr *hdr = (struct rte_ipv4_hdr *)
+ RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
+
+ hdr->fragment_offset = 0;
+ hdr->total_length = rte_cpu_to_be_16(fragx_sum + l3_hdr_size);
+ hdr->hdr_checksum = 0;
+ hdr->hdr_checksum = rte_ipv4_cksum(hdr);
+
+ inner_rx->pkt_lenm1 = pkt_hdr_len + fragx_sum - 1;
+ } else {
+ /* Remove the frag header by moving header 8 bytes forward */
+ struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)
+ RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
+
+ hdr->payload_len = rte_cpu_to_be_16(fragx_sum + l3_hdr_size -
+ 8 - sizeof(struct rte_ipv6_hdr));
+
+ rte_memcpy(rte_pktmbuf_mtod_offset(head, void *, 8),
+ rte_pktmbuf_mtod(head, void *),
+ inner_rx->lcptr + sizeof(struct rte_ipv6_hdr));
+
+ inner_rx->pkt_lenm1 = pkt_hdr_len + fragx_sum - 8 - 1;
+ head->data_len -= 8;
+ head->data_off += 8;
+ }
+ mbuf->next = NULL;
+ head->pkt_len = inner_rx->pkt_lenm1 + 1;
+ head->nb_segs = hdr->w0.num_frags;
+
+ return head;
+}
+
+static __rte_always_inline struct rte_mbuf *
+nix_sec_meta_to_mbuf_sc(uint64_t cq_w1, uint64_t cq_w5, const uint64_t sa_base,
+ uintptr_t laddr, uint8_t *loff, struct rte_mbuf *mbuf,
+ uint16_t data_off, const uint16_t flags,
+ const uint64_t mbuf_init)
+{
+ const void *__p = (void *)((uintptr_t)mbuf + (uint16_t)data_off);
+ const struct cpt_parse_hdr_s *hdr = (const struct cpt_parse_hdr_s *)__p;
+ struct cn10k_inb_priv_data *inb_priv;
+ struct rte_mbuf *inner = NULL;
+ uint64_t res_w1;
+ uint32_t sa_idx;
+ uint16_t uc_cc;
+ uint32_t len;
+ void *inb_sa;
+ uint64_t w0;
+
+ if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11))) {
+ /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
+ w0 = hdr->w0.u64;
+ sa_idx = w0 >> 32;
+
+ inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
+ inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
+
+ if (!hdr->w0.num_frags) {
+ /* No Reassembly or inbound error */
+ inner = (struct rte_mbuf *)
+ (rte_be_to_cpu_64(hdr->wqe_ptr) -
+ sizeof(struct rte_mbuf));
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(inner) =
+ (uint64_t)inb_priv->userdata;
+
+ /* CPT result(struct cpt_cn10k_res_s) is at
+ * after first IOVA in meta
+ */
+ res_w1 = *((uint64_t *)(&inner[1]) + 10);
+ uc_cc = res_w1 & 0xFF;
+
+ /* Calculate inner packet length */
+ len = ((res_w1 >> 16) & 0xFFFF) + hdr->w2.il3_off -
+ sizeof(struct cpt_parse_hdr_s) - (w0 & 0x7);
+ inner->pkt_len = len;
+ inner->data_len = len;
+ *(uint64_t *)(&inner->rearm_data) = mbuf_init;
+
+ inner->ol_flags = ((uc_cc == CPT_COMP_WARN) ?
+ RTE_MBUF_F_RX_SEC_OFFLOAD :
+ (RTE_MBUF_F_RX_SEC_OFFLOAD |
+ RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
+ } else if (!(hdr->w0.err_sum) && !(hdr->w0.reas_sts)) {
+ /* Reassembly success */
+ inner = nix_sec_reassemble_frags(hdr, cq_w1, cq_w5,
+ mbuf_init);
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(inner) =
+ (uint64_t)inb_priv->userdata;
+
+ /* Assume success */
+ inner->ol_flags = RTE_MBUF_F_RX_SEC_OFFLOAD;
+ } else {
+ /* Reassembly failure */
+ inner = nix_sec_attach_frags(hdr, inb_priv, mbuf_init);
+ }
+
+ /* Store meta in lmtline to free
+ * Assume all meta's from same aura.
+ */
+ *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
+ *loff = *loff + 1;
+
+ return inner;
+ } else if (cq_w1 & BIT(11)) {
+ inner = (struct rte_mbuf *)(rte_be_to_cpu_64(hdr->wqe_ptr) -
+ sizeof(struct rte_mbuf));
+
+ /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
+ w0 = hdr->w0.u64;
+ sa_idx = w0 >> 32;
+
+ inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
+ inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
+
+ /* Update l2 hdr length first */
+
+ /* CPT result(struct cpt_cn10k_res_s) is at
+ * after first IOVA in meta
+ */
+ res_w1 = *((uint64_t *)(&inner[1]) + 10);
+ uc_cc = res_w1 & 0xFF;
+
+ /* Calculate inner packet length */
+ len = ((res_w1 >> 16) & 0xFFFF) + hdr->w2.il3_off -
+ sizeof(struct cpt_parse_hdr_s) - (w0 & 0x7);
+ inner->pkt_len = len;
+ inner->data_len = len;
+ *(uint64_t *)(&inner->rearm_data) = mbuf_init;
+
+ inner->ol_flags = ((uc_cc == CPT_COMP_WARN) ?
+ RTE_MBUF_F_RX_SEC_OFFLOAD :
+ (RTE_MBUF_F_RX_SEC_OFFLOAD |
+ RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
+
+ /* Store meta in lmtline to free
+ * Assume all meta's from same aura.
+ */
+ *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
+ *loff = *loff + 1;
+
+ /* Mark meta mbuf as put */
+ RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 0);
+
+ /* Mark inner mbuf as get */
+ RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
+
+ return inner;
+ }
+
+ return mbuf;
+}
+
+#if defined(RTE_ARCH_ARM64)
+
+static __rte_always_inline struct rte_mbuf *
+nix_sec_meta_to_mbuf(uint64_t cq_w1, uint64_t cq_w5, uintptr_t sa_base,
+ uintptr_t laddr, uint8_t *loff, struct rte_mbuf *mbuf,
+ uint16_t data_off, uint8x16_t *rx_desc_field1,
+ uint64_t *ol_flags, const uint16_t flags,
+ uint64x2_t *rearm)
+{
+ const void *__p = (void *)((uintptr_t)mbuf + (uint16_t)data_off);
+ const struct cpt_parse_hdr_s *hdr = (const struct cpt_parse_hdr_s *)__p;
+ uint64_t mbuf_init = vgetq_lane_u64(*rearm, 0);
+ struct cn10k_inb_priv_data *inb_priv;
+ struct rte_mbuf *inner;
+ uint64_t *sg, res_w1;
+ uint32_t sa_idx;
+ void *inb_sa;
+ uint16_t len;
+ uint64_t w0;
+
+ if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11))) {
+ w0 = hdr->w0.u64;
+ sa_idx = w0 >> 32;
+
+ /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
+ w0 = hdr->w0.u64;
+ sa_idx = w0 >> 32;
+
+ inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
+ inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
+
+ /* Clear checksum flags */
+ *ol_flags &= ~(RTE_MBUF_F_RX_L4_CKSUM_MASK |
+ RTE_MBUF_F_RX_IP_CKSUM_MASK);
+
+ if (!hdr->w0.num_frags) {
+ /* No Reassembly or inbound error */
+ inner = (struct rte_mbuf *)
+ (rte_be_to_cpu_64(hdr->wqe_ptr) -
+ sizeof(struct rte_mbuf));
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(inner) =
+ (uint64_t)inb_priv->userdata;
+
+ /* CPT result(struct cpt_cn10k_res_s) is at
+ * after first IOVA in meta
+ */
+ sg = (uint64_t *)(inner + 1);
+ res_w1 = sg[10];
+
+ /* Clear checksum flags and update security flag */
+ *ol_flags &= ~(RTE_MBUF_F_RX_L4_CKSUM_MASK |
+ RTE_MBUF_F_RX_IP_CKSUM_MASK);
+ *ol_flags |=
+ (((res_w1 & 0xFF) == CPT_COMP_WARN) ?
+ RTE_MBUF_F_RX_SEC_OFFLOAD :
+ (RTE_MBUF_F_RX_SEC_OFFLOAD |
+ RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
+ /* Calculate inner packet length */
+ len = ((res_w1 >> 16) & 0xFFFF) +
+ hdr->w2.il3_off -
+ sizeof(struct cpt_parse_hdr_s) -
+ (w0 & 0x7);
+ /* Update pkt_len and data_len */
+ *rx_desc_field1 =
+ vsetq_lane_u16(len, *rx_desc_field1, 2);
+ *rx_desc_field1 =
+ vsetq_lane_u16(len, *rx_desc_field1, 4);
+
+ } else if (!(hdr->w0.err_sum) && !(hdr->w0.reas_sts)) {
+ /* Reassembly success */
+ inner = nix_sec_reassemble_frags(hdr, cq_w1, cq_w5,
+ mbuf_init);
+ sg = (uint64_t *)(inner + 1);
+ res_w1 = sg[10];
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(inner) =
+ (uint64_t)inb_priv->userdata;
+
+ /* Assume success */
+ *ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
+
+ /* Update pkt_len and data_len */
+ *rx_desc_field1 = vsetq_lane_u16(inner->pkt_len,
+ *rx_desc_field1, 2);
+ *rx_desc_field1 = vsetq_lane_u16(inner->data_len,
+ *rx_desc_field1, 4);
+
+ /* Data offset might be updated */
+ mbuf_init = *(uint64_t *)(&inner->rearm_data);
+ *rearm = vsetq_lane_u64(mbuf_init, *rearm, 0);
+ } else {
+ /* Reassembly failure */
+ inner = nix_sec_attach_frags(hdr, inb_priv, mbuf_init);
+ *ol_flags |= inner->ol_flags;
+
+ /* Update pkt_len and data_len */
+ *rx_desc_field1 = vsetq_lane_u16(inner->pkt_len,
+ *rx_desc_field1, 2);
+ *rx_desc_field1 = vsetq_lane_u16(inner->data_len,
+ *rx_desc_field1, 4);
+ }
+
+ /* Store meta in lmtline to free
+ * Assume all meta's from same aura.
+ */
+ *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
+ *loff = *loff + 1;
+
+ /* Return inner mbuf */
+ return inner;
+
+ } else if (cq_w1 & BIT(11)) {
+ inner = (struct rte_mbuf *)(rte_be_to_cpu_64(hdr->wqe_ptr) -
+ sizeof(struct rte_mbuf));
+ /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
+ w0 = hdr->w0.u64;
+ sa_idx = w0 >> 32;
+
+ inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
+ inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
+
+ /* Update dynamic field with userdata */
+ *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
+
+ /* CPT result(struct cpt_cn10k_res_s) is at
+ * after first IOVA in meta
+ */
+ sg = (uint64_t *)(inner + 1);
+ res_w1 = sg[10];
+
+ /* Clear checksum flags and update security flag */
+ *ol_flags &= ~(RTE_MBUF_F_RX_L4_CKSUM_MASK | RTE_MBUF_F_RX_IP_CKSUM_MASK);
+ *ol_flags |= (((res_w1 & 0xFF) == CPT_COMP_WARN) ?
+ RTE_MBUF_F_RX_SEC_OFFLOAD :
+ (RTE_MBUF_F_RX_SEC_OFFLOAD | RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
+ /* Calculate inner packet length */
+ len = ((res_w1 >> 16) & 0xFFFF) + hdr->w2.il3_off -
+ sizeof(struct cpt_parse_hdr_s) - (w0 & 0x7);
+ /* Update pkt_len and data_len */
+ *rx_desc_field1 = vsetq_lane_u16(len, *rx_desc_field1, 2);
+ *rx_desc_field1 = vsetq_lane_u16(len, *rx_desc_field1, 4);
+
+ /* Store meta in lmtline to free
+ * Assume all meta's from same aura.
+ */
+ *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
+ *loff = *loff + 1;
+
+ /* Mark meta mbuf as put */
+ RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 0);
+
+ /* Mark inner mbuf as get */
+ RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
+
+ /* Return inner mbuf */
+ return inner;
+ }
+
+ /* Return same mbuf as it is not a decrypted pkt */
+ return mbuf;
+}
+#endif
+