*
  * @ivlen: length of the IV to be read from the input frame, before any data
  *         to be processed
- * @auth_only_len: length of the data to be authenticated-only (commonly IP
- *                 header, IV, Sequence number and SPI)
- * Note: Extended Sequence Number processing is NOT supported
  *
  * @trunc_len: the length of the ICV to be written to the output frame. If 0,
  *             then the corresponding length of the digest, according to the
  *       will be done correctly:
  * For encapsulation:
  *     Input:
- * +----+----------------+---------------------------------------------+
- * | IV | Auth-only data | Padded data to be authenticated & Encrypted |
- * +----+----------------+---------------------------------------------+
+ * +----+----------------+-----------------------------------------------+
+ * | IV | Auth-only head | Padded data to be auth & Enc | Auth-only tail |
+ * +----+----------------+-----------------------------------------------+
  *     Output:
  * +--------------------------------------+
  * | Authenticated & Encrypted data | ICV |
  * +--------------------------------+-----+
-
+ *
  * For decapsulation:
  *     Input:
- * +----+----------------+--------------------------------+-----+
- * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
- * +----+----------------+--------------------------------+-----+
+ * +----+----------------+-----------------+----------------------+
+ * | IV | Auth-only head | Auth & Enc data | Auth-only tail | ICV |
+ * +----+----------------+-----------------+----------------------+
  *     Output:
- * +----+--------------------------+
+ * +----+---------------------------+
  * | Decrypted & authenticated data |
- * +----+--------------------------+
+ * +----+---------------------------+
  *
  * Note: This descriptor can use per-packet commands, encoded as below in the
  *       DPOVRD register:
- * 32    24    16               0
- * +------+---------------------+
- * | 0x80 | 0x00| auth_only_len |
- * +------+---------------------+
+ * 32    28               16            1
+ * +------+------------------------------+
+ * | 0x8  | auth_tail_len | auth_hdr_len |
+ * +------+------------------------------+
  *
  * This mechanism is available only for SoCs having SEC ERA >= 3. In other
  * words, this will not work for P4080TO2
                    enum rta_share_type share,
                    struct alginfo *cipherdata,
                    struct alginfo *authdata,
-                   uint16_t ivlen, uint16_t auth_only_len,
+                   uint16_t ivlen,
                    uint8_t trunc_len, uint8_t dir)
 {
        struct program prg;
        const bool need_dk = (dir == DIR_DEC) &&
                             (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
                             (cipherdata->algmode == OP_ALG_AAI_CBC);
+       int data_type;
 
-       LABEL(skip_patch_len);
        LABEL(keyjmp);
        LABEL(skipkeys);
-       LABEL(aonly_len_offset);
-       REFERENCE(pskip_patch_len);
+       LABEL(proc_icv);
+       LABEL(no_auth_tail);
        REFERENCE(pkeyjmp);
        REFERENCE(pskipkeys);
-       REFERENCE(read_len);
-       REFERENCE(write_len);
+       REFERENCE(p_proc_icv);
+       REFERENCE(p_no_auth_tail);
 
        PROGRAM_CNTXT_INIT(p, descbuf, 0);
 
 
        SHR_HDR(p, share, 1, SC);
 
-       /*
-        * M0 will contain the value provided by the user when creating
-        * the shared descriptor. If the user provided an override in
-        * DPOVRD, then M0 will contain that value
-        */
-       MATHB(p, MATH0, ADD, auth_only_len, MATH0, 4, IMMED2);
-
-       if (rta_sec_era >= RTA_SEC_ERA_3) {
-               /*
-                * Check if the user wants to override the auth-only len
-                */
-               MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
-
-               /*
-                * No need to patch the length of the auth-only data read if
-                * the user did not override it
-                */
-               pskip_patch_len = JUMP(p, skip_patch_len, LOCAL_JUMP, ALL_TRUE,
-                                 MATH_N);
-
-               /* Get auth-only len in M0 */
-               MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
-
-               /*
-                * Since M0 is used in calculations, don't mangle it, copy
-                * its content to M1 and use this for patching.
-                */
-               MATHB(p, MATH0, ADD, MATH1, MATH1, 4, 0);
-
-               read_len = MOVE(p, DESCBUF, 0, MATH1, 0, 6, WAITCOMP | IMMED);
-               write_len = MOVE(p, MATH1, 0, DESCBUF, 0, 8, WAITCOMP | IMMED);
-
-               SET_LABEL(p, skip_patch_len);
-       }
-       /*
-        * MATH0 contains the value in DPOVRD w/o the MSB, or the initial
-        * value, as provided by the user at descriptor creation time
-        */
-       if (dir == DIR_ENC)
-               MATHB(p, MATH0, ADD, ivlen, MATH0, 4, IMMED2);
-       else
-               MATHB(p, MATH0, ADD, ivlen + trunc_len, MATH0, 4, IMMED2);
+       /* Collect the (auth_tail || auth_hdr) len from DPOVRD */
+       MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
+
+       /* Get auth_hdr len in MATH0 */
+       MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
+
+       /* Get auth_tail len in MATH2 */
+       MATHB(p, MATH2, AND, 0xFFF0000, MATH2, 4, IMMED2);
+       MATHI(p, MATH2, RSHIFT, 16, MATH2, 4, IMMED2);
 
        pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
 
                              OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
        }
 
+       /* Read IV */
+       if (cipherdata->algmode == OP_ALG_AAI_CTR)
+               SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
+       else
+               SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
+
+       /*
+        * authenticate auth_hdr data
+        */
+       MATHB(p, MATH0, ADD, ZERO, VSEQINSZ, 4, 0);
+       SEQFIFOLOAD(p, MSG2, 0, VLF);
+
        /*
         * Prepare the length of the data to be both encrypted/decrypted
         * and authenticated/checked
         */
-       MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);
+       MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
+       if (dir == DIR_DEC) {
+               MATHB(p, VSEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
+               data_type = MSGINSNOOP;
+       } else {
+               data_type = MSGOUTSNOOP;
+       }
 
-       MATHB(p, VSEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
+       MATHB(p, VSEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
 
        /* Prepare for writing the output frame */
        SEQFIFOSTORE(p, MSG, 0, 0, VLF);
 
-       SET_LABEL(p, aonly_len_offset);
 
-       /* Read IV */
-       if (cipherdata->algmode == OP_ALG_AAI_CTR)
-               SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
-       else
-               SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
+       /* Check if there is no auth-tail */
+       MATHB(p, MATH2, ADD, ZERO, MATH2, 4, 0);
+       p_no_auth_tail = JUMP(p, no_auth_tail, LOCAL_JUMP, ALL_TRUE, MATH_Z);
 
        /*
-        * Read data needed only for authentication. This is overwritten above
-        * if the user requested it.
+        * Read input plain/cipher text, encrypt/decrypt & auth & write
+        * to output
         */
-       SEQFIFOLOAD(p, MSG2, auth_only_len, 0);
+       SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | FLUSH1);
+
+       /* Authenticate auth tail */
+       MATHB(p, MATH2, ADD, ZERO, VSEQINSZ, 4, 0);
+       SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
+
+       /* Jump to process icv */
+       p_proc_icv = JUMP(p, proc_icv, LOCAL_JUMP, ALL_FALSE, MATH_Z);
+
+       SET_LABEL(p, no_auth_tail);
 
-       if (dir == DIR_ENC) {
-               /*
-                * Read input plaintext, encrypt and authenticate & write to
-                * output
-                */
-               SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
+       SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | LAST2 | FLUSH1);
 
+       SET_LABEL(p, proc_icv);
+
+       if (dir == DIR_ENC)
                /* Finally, write the ICV */
                SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
-       } else {
-               /*
-                * Read input ciphertext, decrypt and authenticate & write to
-                * output
-                */
-               SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
-
+       else
                /* Read the ICV to check */
                SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
-       }
 
        PATCH_JUMP(p, pkeyjmp, keyjmp);
        PATCH_JUMP(p, pskipkeys, skipkeys);
-       PATCH_JUMP(p, pskipkeys, skipkeys);
-
-       if (rta_sec_era >= RTA_SEC_ERA_3) {
-               PATCH_JUMP(p, pskip_patch_len, skip_patch_len);
-               PATCH_MOVE(p, read_len, aonly_len_offset);
-               PATCH_MOVE(p, write_len, aonly_len_offset);
-       }
-
+       PATCH_JUMP(p, p_no_auth_tail, no_auth_tail);
+       PATCH_JUMP(p, p_proc_icv, proc_icv);
        return PROGRAM_FINALIZE(p);
 }
 
 
                 */
                shared_desc_len = cnstr_shdsc_authenc(cdb->sh_desc,
                                true, swap, SHR_SERIAL, &alginfo_c, &alginfo_a,
-                               ses->iv.length, 0,
+                               ses->iv.length,
                                ses->digest_length, ses->dir);
        }
 
        struct rte_crypto_op *op;
        struct dpaa_sec_job *cf;
        dpaa_sec_session *ses;
-       uint32_t auth_only_len, index, flags[DPAA_SEC_BURST] = {0};
+       uint16_t auth_hdr_len, auth_tail_len;
+       uint32_t index, flags[DPAA_SEC_BURST] = {0};
        struct qman_fq *inq[DPAA_SEC_BURST];
 
        while (nb_ops) {
                                goto send_pkts;
                        }
 
-                       auth_only_len = op->sym->auth.data.length -
+                       auth_hdr_len = op->sym->auth.data.length -
                                                op->sym->cipher.data.length;
+                       auth_tail_len = 0;
+
                        if (rte_pktmbuf_is_contiguous(op->sym->m_src) &&
                                  ((op->sym->m_dst == NULL) ||
                                   rte_pktmbuf_is_contiguous(op->sym->m_dst))) {
                                        cf = build_cipher_only(op, ses);
                                } else if (is_aead(ses)) {
                                        cf = build_cipher_auth_gcm(op, ses);
-                                       auth_only_len = ses->auth_only_len;
+                                       auth_hdr_len = ses->auth_only_len;
                                } else if (is_auth_cipher(ses)) {
+                                       auth_hdr_len =
+                                               op->sym->cipher.data.offset
+                                               - op->sym->auth.data.offset;
+                                       auth_tail_len =
+                                               op->sym->auth.data.length
+                                               - op->sym->cipher.data.length
+                                               - auth_hdr_len;
                                        cf = build_cipher_auth(op, ses);
                                } else {
                                        DPAA_SEC_DP_ERR("not supported ops");
                                        cf = build_cipher_only_sg(op, ses);
                                } else if (is_aead(ses)) {
                                        cf = build_cipher_auth_gcm_sg(op, ses);
-                                       auth_only_len = ses->auth_only_len;
+                                       auth_hdr_len = ses->auth_only_len;
                                } else if (is_auth_cipher(ses)) {
+                                       auth_hdr_len =
+                                               op->sym->cipher.data.offset
+                                               - op->sym->auth.data.offset;
+                                       auth_tail_len =
+                                               op->sym->auth.data.length
+                                               - op->sym->cipher.data.length
+                                               - auth_hdr_len;
                                        cf = build_cipher_auth_sg(op, ses);
                                } else {
                                        DPAA_SEC_DP_ERR("not supported ops");
                        qm_fd_addr_set64(fd, dpaa_mem_vtop(cf->sg));
                        fd->_format1 = qm_fd_compound;
                        fd->length29 = 2 * sizeof(struct qm_sg_entry);
+
                        /* Auth_only_len is set as 0 in descriptor and it is
                         * overwritten here in the fd.cmd which will update
                         * the DPOVRD reg.
                         */
-                       if (auth_only_len)
-                               fd->cmd = 0x80000000 | auth_only_len;
+                       if (auth_hdr_len || auth_tail_len) {
+                               fd->cmd = 0x80000000;
+                               fd->cmd |=
+                                       ((auth_tail_len << 16) | auth_hdr_len);
+                       }
 
                        /* In case of PDCP, per packet HFN is stored in
                         * mbuf priv after sym_op.