examples/l3fwd: share queue size variables
[dpdk.git] / drivers / net / cnxk / cn10k_tx.h
index fc1f6ce..de88a21 100644 (file)
@@ -186,23 +186,26 @@ cn10k_cpt_tx_steor_data(void)
 }
 
 static __rte_always_inline void
-cn10k_nix_tx_skeleton(const struct cn10k_eth_txq *txq, uint64_t *cmd,
-                     const uint16_t flags)
+cn10k_nix_tx_skeleton(struct cn10k_eth_txq *txq, uint64_t *cmd,
+                     const uint16_t flags, const uint16_t static_sz)
 {
-       /* Send hdr */
-       cmd[0] = txq->send_hdr_w0;
+       if (static_sz)
+               cmd[0] = txq->send_hdr_w0;
+       else
+               cmd[0] = (txq->send_hdr_w0 & 0xFFFFF00000000000) |
+                        ((uint64_t)(cn10k_nix_tx_ext_subs(flags) + 1) << 40);
        cmd[1] = 0;
-       cmd += 2;
 
-       /* Send ext if present */
        if (flags & NIX_TX_NEED_EXT_HDR) {
-               *(__uint128_t *)cmd = *(const __uint128_t *)txq->cmd;
-               cmd += 2;
+               if (flags & NIX_TX_OFFLOAD_TSTAMP_F)
+                       cmd[2] = (NIX_SUBDC_EXT << 60) | BIT_ULL(15);
+               else
+                       cmd[2] = NIX_SUBDC_EXT << 60;
+               cmd[3] = 0;
+               cmd[4] = (NIX_SUBDC_SG << 60) | BIT_ULL(48);
+       } else {
+               cmd[2] = (NIX_SUBDC_SG << 60) | BIT_ULL(48);
        }
-
-       /* Send sg */
-       cmd[0] = txq->sg_w0;
-       cmd[1] = 0;
 }
 
 static __rte_always_inline void
@@ -508,13 +511,16 @@ cn10k_nix_xmit_prepare_tso(struct rte_mbuf *m, const uint64_t flags)
 
 static __rte_always_inline void
 cn10k_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags,
-                      const uint64_t lso_tun_fmt, bool *sec)
+                      const uint64_t lso_tun_fmt, bool *sec, uint8_t mark_flag,
+                      uint64_t mark_fmt)
 {
+       uint8_t mark_off = 0, mark_vlan = 0, markptr = 0;
        struct nix_send_ext_s *send_hdr_ext;
        struct nix_send_hdr_s *send_hdr;
        uint64_t ol_flags = 0, mask;
        union nix_send_hdr_w1_u w1;
        union nix_send_sg_s *sg;
+       uint16_t mark_form = 0;
 
        send_hdr = (struct nix_send_hdr_s *)cmd;
        if (flags & NIX_TX_NEED_EXT_HDR) {
@@ -522,7 +528,9 @@ cn10k_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags,
                sg = (union nix_send_sg_s *)(cmd + 4);
                /* Clear previous markings */
                send_hdr_ext->w0.lso = 0;
+               send_hdr_ext->w0.mark_en = 0;
                send_hdr_ext->w1.u = 0;
+               ol_flags = m->ol_flags;
        } else {
                sg = (union nix_send_sg_s *)(cmd + 2);
        }
@@ -618,6 +626,10 @@ cn10k_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags,
        }
 
        if (flags & NIX_TX_NEED_EXT_HDR && flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
+               const uint8_t ipv6 = !!(ol_flags & RTE_MBUF_F_TX_IPV6);
+               const uint8_t ip = !!(ol_flags & (RTE_MBUF_F_TX_IPV4 |
+                                                 RTE_MBUF_F_TX_IPV6));
+
                send_hdr_ext->w1.vlan1_ins_ena = !!(ol_flags & RTE_MBUF_F_TX_VLAN);
                /* HW will update ptr after vlan0 update */
                send_hdr_ext->w1.vlan1_ins_ptr = 12;
@@ -627,6 +639,22 @@ cn10k_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags,
                /* 2B before end of l2 header */
                send_hdr_ext->w1.vlan0_ins_ptr = 12;
                send_hdr_ext->w1.vlan0_ins_tci = m->vlan_tci_outer;
+               /* Fill for VLAN marking only when VLAN insertion enabled */
+               mark_vlan = ((mark_flag & CNXK_TM_MARK_VLAN_DEI) &
+                            (send_hdr_ext->w1.vlan1_ins_ena ||
+                             send_hdr_ext->w1.vlan0_ins_ena));
+
+               /* Mask requested flags with packet data information */
+               mark_off = mark_flag & ((ip << 2) | (ip << 1) | mark_vlan);
+               mark_off = ffs(mark_off & CNXK_TM_MARK_MASK);
+
+               mark_form = (mark_fmt >> ((mark_off - !!mark_off) << 4));
+               mark_form = (mark_form >> (ipv6 << 3)) & 0xFF;
+               markptr = m->l2_len + (mark_form >> 7) - (mark_vlan << 2);
+
+               send_hdr_ext->w0.mark_en = !!mark_off;
+               send_hdr_ext->w0.markform = mark_form & 0x7F;
+               send_hdr_ext->w0.markptr = markptr;
        }
 
        if (flags & NIX_TX_OFFLOAD_TSO_F && (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
@@ -718,41 +746,29 @@ cn10k_nix_xmit_mv_lmt_base(uintptr_t lmt_addr, uint64_t *cmd,
 }
 
 static __rte_always_inline void
-cn10k_nix_xmit_prepare_tstamp(uintptr_t lmt_addr, const uint64_t *cmd,
+cn10k_nix_xmit_prepare_tstamp(struct cn10k_eth_txq *txq, uintptr_t lmt_addr,
                              const uint64_t ol_flags, const uint16_t no_segdw,
                              const uint16_t flags)
 {
        if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
-               const uint8_t is_ol_tstamp = !(ol_flags & RTE_MBUF_F_TX_IEEE1588_TMST);
-               struct nix_send_ext_s *send_hdr_ext =
-                       (struct nix_send_ext_s *)lmt_addr + 16;
+               const uint8_t is_ol_tstamp =
+                       !(ol_flags & RTE_MBUF_F_TX_IEEE1588_TMST);
                uint64_t *lmt = (uint64_t *)lmt_addr;
                uint16_t off = (no_segdw - 1) << 1;
                struct nix_send_mem_s *send_mem;
 
                send_mem = (struct nix_send_mem_s *)(lmt + off);
-               send_hdr_ext->w0.subdc = NIX_SUBDC_EXT;
-               send_hdr_ext->w0.tstmp = 1;
-               if (flags & NIX_TX_MULTI_SEG_F) {
-                       /* Retrieving the default desc values */
-                       lmt[off] = cmd[2];
-
-                       /* Using compiler barrier to avoid violation of C
-                        * aliasing rules.
-                        */
-                       rte_compiler_barrier();
-               }
-
-               /* Packets for which RTE_MBUF_F_TX_IEEE1588_TMST is not set, tx tstamp
+               /* Packets for which PKT_TX_IEEE1588_TMST is not set, tx tstamp
                 * should not be recorded, hence changing the alg type to
-                * NIX_SENDMEMALG_SET and also changing send mem addr field to
+                * NIX_SENDMEMALG_SUB and also changing send mem addr field to
                 * next 8 bytes as it corrupts the actual Tx tstamp registered
                 * address.
                 */
                send_mem->w0.subdc = NIX_SUBDC_MEM;
-               send_mem->w0.alg = NIX_SENDMEMALG_SETTSTMP - (is_ol_tstamp);
+               send_mem->w0.alg =
+                       NIX_SENDMEMALG_SETTSTMP + (is_ol_tstamp << 3);
                send_mem->addr =
-                       (rte_iova_t)(((uint64_t *)cmd[3]) + is_ol_tstamp);
+                       (rte_iova_t)(((uint64_t *)txq->ts_mem) + is_ol_tstamp);
        }
 }
 
@@ -841,8 +857,8 @@ done:
 }
 
 static __rte_always_inline uint16_t
-cn10k_nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts,
-                   uint64_t *cmd, uintptr_t base, const uint16_t flags)
+cn10k_nix_xmit_pkts(void *tx_queue, uint64_t *ws, struct rte_mbuf **tx_pkts,
+                   uint16_t pkts, uint64_t *cmd, const uint16_t flags)
 {
        struct cn10k_eth_txq *txq = tx_queue;
        const rte_iova_t io_addr = txq->io_addr;
@@ -850,6 +866,8 @@ cn10k_nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts,
        uintptr_t pa, lbase = txq->lmt_base;
        uint16_t lmt_id, burst, left, i;
        uintptr_t c_lbase = lbase;
+       uint64_t mark_fmt = 0;
+       uint8_t mark_flag = 0;
        rte_iova_t c_io_addr;
        uint64_t lso_tun_fmt;
        uint16_t c_lmt_id;
@@ -863,13 +881,17 @@ cn10k_nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts,
                /* Reduce the cached count */
                txq->fc_cache_pkts -= pkts;
        }
-
        /* Get cmd skeleton */
-       cn10k_nix_tx_skeleton(txq, cmd, flags);
+       cn10k_nix_tx_skeleton(txq, cmd, flags, !(flags & NIX_TX_VWQE_F));
 
        if (flags & NIX_TX_OFFLOAD_TSO_F)
                lso_tun_fmt = txq->lso_tun_fmt;
 
+       if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
+               mark_fmt = txq->mark_fmt;
+               mark_flag = txq->mark_flag;
+       }
+
        /* Get LMT base address and LMT ID as lcore id */
        ROC_LMT_BASE_ID_GET(lbase, lmt_id);
        if (flags & NIX_TX_OFFLOAD_SECURITY_F) {
@@ -897,7 +919,7 @@ again:
                        cn10k_nix_xmit_prepare_tso(tx_pkts[i], flags);
 
                cn10k_nix_xmit_prepare(tx_pkts[i], cmd, flags, lso_tun_fmt,
-                                      &sec);
+                                      &sec, mark_flag, mark_fmt);
 
                laddr = (uintptr_t)LMT_OFF(lbase, lnum, 0);
 
@@ -909,14 +931,14 @@ again:
 
                /* Move NIX desc to LMT/NIXTX area */
                cn10k_nix_xmit_mv_lmt_base(laddr, cmd, flags);
-               cn10k_nix_xmit_prepare_tstamp(laddr, &txq->cmd[0],
-                                             tx_pkts[i]->ol_flags, 4, flags);
+               cn10k_nix_xmit_prepare_tstamp(txq, laddr, tx_pkts[i]->ol_flags,
+                                             4, flags);
                if (!(flags & NIX_TX_OFFLOAD_SECURITY_F) || !sec)
                        lnum++;
        }
 
-       if (flags & NIX_TX_VWQE_F)
-               roc_sso_hws_head_wait(base);
+       if ((flags & NIX_TX_VWQE_F) && !(ws[1] & BIT_ULL(35)))
+               ws[1] = roc_sso_hws_head_wait(ws[0]);
 
        left -= burst;
        tx_pkts += burst;
@@ -967,9 +989,9 @@ again:
 }
 
 static __rte_always_inline uint16_t
-cn10k_nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
-                        uint16_t pkts, uint64_t *cmd, uintptr_t base,
-                        const uint16_t flags)
+cn10k_nix_xmit_pkts_mseg(void *tx_queue, uint64_t *ws,
+                        struct rte_mbuf **tx_pkts, uint16_t pkts,
+                        uint64_t *cmd, const uint16_t flags)
 {
        struct cn10k_eth_txq *txq = tx_queue;
        uintptr_t pa0, pa1, lbase = txq->lmt_base;
@@ -977,6 +999,8 @@ cn10k_nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
        uint16_t segdw, lmt_id, burst, left, i;
        uint8_t lnum, c_lnum, c_loff;
        uintptr_t c_lbase = lbase;
+       uint64_t mark_fmt = 0;
+       uint8_t mark_flag = 0;
        uint64_t data0, data1;
        rte_iova_t c_io_addr;
        uint64_t lso_tun_fmt;
@@ -987,16 +1011,22 @@ cn10k_nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
        uintptr_t laddr;
        bool sec;
 
-       NIX_XMIT_FC_OR_RETURN(txq, pkts);
-
-       cn10k_nix_tx_skeleton(txq, cmd, flags);
-
-       /* Reduce the cached count */
-       txq->fc_cache_pkts -= pkts;
+       if (!(flags & NIX_TX_VWQE_F)) {
+               NIX_XMIT_FC_OR_RETURN(txq, pkts);
+               /* Reduce the cached count */
+               txq->fc_cache_pkts -= pkts;
+       }
+       /* Get cmd skeleton */
+       cn10k_nix_tx_skeleton(txq, cmd, flags, !(flags & NIX_TX_VWQE_F));
 
        if (flags & NIX_TX_OFFLOAD_TSO_F)
                lso_tun_fmt = txq->lso_tun_fmt;
 
+       if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
+               mark_fmt = txq->mark_fmt;
+               mark_flag = txq->mark_flag;
+       }
+
        /* Get LMT base address and LMT ID as lcore id */
        ROC_LMT_BASE_ID_GET(lbase, lmt_id);
        if (flags & NIX_TX_OFFLOAD_SECURITY_F) {
@@ -1026,7 +1056,7 @@ again:
                        cn10k_nix_xmit_prepare_tso(tx_pkts[i], flags);
 
                cn10k_nix_xmit_prepare(tx_pkts[i], cmd, flags, lso_tun_fmt,
-                                      &sec);
+                                      &sec, mark_flag, mark_fmt);
 
                laddr = (uintptr_t)LMT_OFF(lbase, lnum, 0);
 
@@ -1038,13 +1068,11 @@ again:
 
                /* Move NIX desc to LMT/NIXTX area */
                cn10k_nix_xmit_mv_lmt_base(laddr, cmd, flags);
-
                /* Store sg list directly on lmt line */
                segdw = cn10k_nix_prepare_mseg(tx_pkts[i], (uint64_t *)laddr,
                                               flags);
-               cn10k_nix_xmit_prepare_tstamp(laddr, &txq->cmd[0],
-                                             tx_pkts[i]->ol_flags, segdw,
-                                             flags);
+               cn10k_nix_xmit_prepare_tstamp(txq, laddr, tx_pkts[i]->ol_flags,
+                                             segdw, flags);
                if (!(flags & NIX_TX_OFFLOAD_SECURITY_F) || !sec) {
                        lnum++;
                        data128 |= (((__uint128_t)(segdw - 1)) << shft);
@@ -1052,8 +1080,8 @@ again:
                }
        }
 
-       if (flags & NIX_TX_VWQE_F)
-               roc_sso_hws_head_wait(base);
+       if ((flags & NIX_TX_VWQE_F) && !(ws[1] & BIT_ULL(35)))
+               ws[1] = roc_sso_hws_head_wait(ws[0]);
 
        left -= burst;
        tx_pkts += burst;
@@ -1474,9 +1502,9 @@ cn10k_nix_xmit_store(struct rte_mbuf *mbuf, uint8_t segdw, uintptr_t laddr,
 }
 
 static __rte_always_inline uint16_t
-cn10k_nix_xmit_pkts_vector(void *tx_queue, struct rte_mbuf **tx_pkts,
-                          uint16_t pkts, uint64_t *cmd, uintptr_t base,
-                          const uint16_t flags)
+cn10k_nix_xmit_pkts_vector(void *tx_queue, uint64_t *ws,
+                          struct rte_mbuf **tx_pkts, uint16_t pkts,
+                          uint64_t *cmd, const uint16_t flags)
 {
        uint64x2_t dataoff_iova0, dataoff_iova1, dataoff_iova2, dataoff_iova3;
        uint64x2_t len_olflags0, len_olflags1, len_olflags2, len_olflags3;
@@ -1526,25 +1554,42 @@ cn10k_nix_xmit_pkts_vector(void *tx_queue, struct rte_mbuf **tx_pkts,
                        cn10k_nix_xmit_prepare_tso(tx_pkts[i], flags);
        }
 
-       senddesc01_w0 = vld1q_dup_u64(&txq->send_hdr_w0);
+       if (!(flags & NIX_TX_VWQE_F)) {
+               senddesc01_w0 = vld1q_dup_u64(&txq->send_hdr_w0);
+       } else {
+               uint64_t w0 =
+                       (txq->send_hdr_w0 & 0xFFFFF00000000000) |
+                       ((uint64_t)(cn10k_nix_tx_ext_subs(flags) + 1) << 40);
+
+               senddesc01_w0 = vdupq_n_u64(w0);
+       }
        senddesc23_w0 = senddesc01_w0;
+
        senddesc01_w1 = vdupq_n_u64(0);
        senddesc23_w1 = senddesc01_w1;
-       sgdesc01_w0 = vld1q_dup_u64(&txq->sg_w0);
+       sgdesc01_w0 = vdupq_n_u64((NIX_SUBDC_SG << 60) | BIT_ULL(48));
        sgdesc23_w0 = sgdesc01_w0;
 
-       /* Load command defaults into vector variables. */
        if (flags & NIX_TX_NEED_EXT_HDR) {
-               sendext01_w0 = vld1q_dup_u64(&txq->cmd[0]);
-               sendext23_w0 = sendext01_w0;
-               sendext01_w1 = vdupq_n_u64(12 | 12U << 24);
-               sendext23_w1 = sendext01_w1;
                if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
-                       sendmem01_w0 = vld1q_dup_u64(&txq->cmd[2]);
+                       sendext01_w0 = vdupq_n_u64((NIX_SUBDC_EXT << 60) |
+                                                  BIT_ULL(15));
+                       sendmem01_w0 =
+                               vdupq_n_u64((NIX_SUBDC_MEM << 60) |
+                                           (NIX_SENDMEMALG_SETTSTMP << 56));
                        sendmem23_w0 = sendmem01_w0;
-                       sendmem01_w1 = vld1q_dup_u64(&txq->cmd[3]);
+                       sendmem01_w1 = vdupq_n_u64(txq->ts_mem);
                        sendmem23_w1 = sendmem01_w1;
+               } else {
+                       sendext01_w0 = vdupq_n_u64((NIX_SUBDC_EXT << 60));
                }
+               sendext23_w0 = sendext01_w0;
+
+               if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F)
+                       sendext01_w1 = vdupq_n_u64(12 | 12U << 24);
+               else
+                       sendext01_w1 = vdupq_n_u64(0);
+               sendext23_w1 = sendext01_w1;
        }
 
        /* Get LMT base address and LMT ID as lcore id */
@@ -2563,6 +2608,13 @@ again:
                        lnum += 1;
                }
 
+               if (flags & NIX_TX_MULTI_SEG_F) {
+                       tx_pkts[0]->next = NULL;
+                       tx_pkts[1]->next = NULL;
+                       tx_pkts[2]->next = NULL;
+                       tx_pkts[3]->next = NULL;
+               }
+
                tx_pkts = tx_pkts + NIX_DESCS_PER_LOOP;
        }
 
@@ -2576,8 +2628,8 @@ again:
        if (flags & (NIX_TX_MULTI_SEG_F | NIX_TX_OFFLOAD_SECURITY_F))
                wd.data[0] >>= 16;
 
-       if (flags & NIX_TX_VWQE_F)
-               roc_sso_hws_head_wait(base);
+       if ((flags & NIX_TX_VWQE_F) && !(ws[1] & BIT_ULL(35)))
+               ws[1] = roc_sso_hws_head_wait(ws[0]);
 
        left -= burst;
 
@@ -2640,12 +2692,11 @@ again:
 
        if (unlikely(scalar)) {
                if (flags & NIX_TX_MULTI_SEG_F)
-                       pkts += cn10k_nix_xmit_pkts_mseg(tx_queue, tx_pkts,
-                                                        scalar, cmd, base,
-                                                        flags);
+                       pkts += cn10k_nix_xmit_pkts_mseg(tx_queue, ws, tx_pkts,
+                                                        scalar, cmd, flags);
                else
-                       pkts += cn10k_nix_xmit_pkts(tx_queue, tx_pkts, scalar,
-                                                   cmd, base, flags);
+                       pkts += cn10k_nix_xmit_pkts(tx_queue, ws, tx_pkts,
+                                                   scalar, cmd, flags);
        }
 
        return pkts;
@@ -2653,16 +2704,16 @@ again:
 
 #else
 static __rte_always_inline uint16_t
-cn10k_nix_xmit_pkts_vector(void *tx_queue, struct rte_mbuf **tx_pkts,
-                          uint16_t pkts, uint64_t *cmd, uintptr_t base,
-                          const uint16_t flags)
+cn10k_nix_xmit_pkts_vector(void *tx_queue, uint64_t *ws,
+                          struct rte_mbuf **tx_pkts, uint16_t pkts,
+                          uint64_t *cmd, const uint16_t flags)
 {
+       RTE_SET_USED(ws);
        RTE_SET_USED(tx_queue);
        RTE_SET_USED(tx_pkts);
        RTE_SET_USED(pkts);
        RTE_SET_USED(cmd);
        RTE_SET_USED(flags);
-       RTE_SET_USED(base);
        return 0;
 }
 #endif
@@ -2892,7 +2943,7 @@ NIX_TX_FASTPATH_MODES
                if (((flags) & NIX_TX_OFFLOAD_TSO_F) &&                        \
                    !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F))                  \
                        return 0;                                              \
-               return cn10k_nix_xmit_pkts(tx_queue, tx_pkts, pkts, cmd, 0,    \
+               return cn10k_nix_xmit_pkts(tx_queue, NULL, tx_pkts, pkts, cmd, \
                                           flags);                             \
        }
 
@@ -2905,8 +2956,8 @@ NIX_TX_FASTPATH_MODES
                if (((flags) & NIX_TX_OFFLOAD_TSO_F) &&                        \
                    !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F))                  \
                        return 0;                                              \
-               return cn10k_nix_xmit_pkts_mseg(tx_queue, tx_pkts, pkts, cmd,  \
-                                               0,                             \
+               return cn10k_nix_xmit_pkts_mseg(tx_queue, NULL, tx_pkts, pkts, \
+                                               cmd,                           \
                                                flags | NIX_TX_MULTI_SEG_F);   \
        }
 
@@ -2919,8 +2970,8 @@ NIX_TX_FASTPATH_MODES
                if (((flags) & NIX_TX_OFFLOAD_TSO_F) &&                        \
                    !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F))                  \
                        return 0;                                              \
-               return cn10k_nix_xmit_pkts_vector(tx_queue, tx_pkts, pkts,     \
-                                                 cmd, 0, (flags));            \
+               return cn10k_nix_xmit_pkts_vector(tx_queue, NULL, tx_pkts,     \
+                                                 pkts, cmd, (flags));         \
        }
 
 #define NIX_TX_XMIT_VEC_MSEG(fn, sz, flags)                                    \
@@ -2933,7 +2984,7 @@ NIX_TX_FASTPATH_MODES
                    !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F))                  \
                        return 0;                                              \
                return cn10k_nix_xmit_pkts_vector(                             \
-                       tx_queue, tx_pkts, pkts, cmd, 0,                       \
+                       tx_queue, NULL, tx_pkts, pkts, cmd,                    \
                        (flags) | NIX_TX_MULTI_SEG_F);                         \
        }