16d69b74fc3c249cacba39749edddab4fa9a0c85
[dpdk.git] / drivers / net / octeontx2 / otx2_tx.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_vect.h>
6
7 #include "otx2_ethdev.h"
8
9 #define NIX_XMIT_FC_OR_RETURN(txq, pkts) do {                           \
10         /* Cached value is low, Update the fc_cache_pkts */             \
11         if (unlikely((txq)->fc_cache_pkts < (pkts))) {                  \
12                 /* Multiply with sqe_per_sqb to express in pkts */      \
13                 (txq)->fc_cache_pkts =                                  \
14                         ((txq)->nb_sqb_bufs_adj - *(txq)->fc_mem) <<    \
15                                 (txq)->sqes_per_sqb_log2;               \
16                 /* Check it again for the room */                       \
17                 if (unlikely((txq)->fc_cache_pkts < (pkts)))            \
18                         return 0;                                       \
19         }                                                               \
20 } while (0)
21
22
23 static __rte_always_inline uint16_t
24 nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
25               uint16_t pkts, uint64_t *cmd, const uint16_t flags)
26 {
27         struct otx2_eth_txq *txq = tx_queue; uint16_t i;
28         const rte_iova_t io_addr = txq->io_addr;
29         void *lmt_addr = txq->lmt_addr;
30
31         NIX_XMIT_FC_OR_RETURN(txq, pkts);
32
33         otx2_lmt_mov(cmd, &txq->cmd[0], otx2_nix_tx_ext_subs(flags));
34
35         /* Lets commit any changes in the packet */
36         rte_cio_wmb();
37
38         for (i = 0; i < pkts; i++) {
39                 otx2_nix_xmit_prepare(tx_pkts[i], cmd, flags);
40                 /* Passing no of segdw as 4: HDR + EXT + SG + SMEM */
41                 otx2_nix_xmit_prepare_tstamp(cmd, &txq->cmd[0],
42                                              tx_pkts[i]->ol_flags, 4, flags);
43                 otx2_nix_xmit_one(cmd, lmt_addr, io_addr, flags);
44         }
45
46         /* Reduce the cached count */
47         txq->fc_cache_pkts -= pkts;
48
49         return pkts;
50 }
51
52 #define T(name, f4, f3, f2, f1, f0, sz, flags)                          \
53 static uint16_t __rte_noinline  __hot                                   \
54 otx2_nix_xmit_pkts_ ## name(void *tx_queue,                             \
55                         struct rte_mbuf **tx_pkts, uint16_t pkts)       \
56 {                                                                       \
57         uint64_t cmd[sz];                                               \
58                                                                         \
59         return nix_xmit_pkts(tx_queue, tx_pkts, pkts, cmd, flags);      \
60 }
61
62 NIX_TX_FASTPATH_MODES
63 #undef T
64
65 static inline void
66 pick_tx_func(struct rte_eth_dev *eth_dev,
67              const eth_tx_burst_t tx_burst[2][2][2][2][2])
68 {
69         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
70
71         /* [TSTMP] [NOFF] [VLAN] [OL3_OL4_CSUM] [IL3_IL4_CSUM] */
72         eth_dev->tx_pkt_burst = tx_burst
73                 [!!(dev->tx_offload_flags & NIX_TX_OFFLOAD_TSTAMP_F)]
74                 [!!(dev->tx_offload_flags & NIX_TX_OFFLOAD_MBUF_NOFF_F)]
75                 [!!(dev->tx_offload_flags & NIX_TX_OFFLOAD_VLAN_QINQ_F)]
76                 [!!(dev->tx_offload_flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F)]
77                 [!!(dev->tx_offload_flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F)];
78 }
79
80 void
81 otx2_eth_set_tx_function(struct rte_eth_dev *eth_dev)
82 {
83         const eth_tx_burst_t nix_eth_tx_burst[2][2][2][2][2] = {
84 #define T(name, f4, f3, f2, f1, f0, sz, flags)                          \
85         [f4][f3][f2][f1][f0] =  otx2_nix_xmit_pkts_ ## name,
86
87 NIX_TX_FASTPATH_MODES
88 #undef T
89         };
90
91         pick_tx_func(eth_dev, nix_eth_tx_burst);
92
93         rte_mb();
94 }