Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(C) 2024 Marvell. 3 : : */ 4 : : 5 : : #ifndef __CN20K_RXTX_H__ 6 : : #define __CN20K_RXTX_H__ 7 : : 8 : : #include <rte_security.h> 9 : : 10 : : /* ROC Constants */ 11 : : #include "roc_constants.h" 12 : : 13 : : /* Platform definition */ 14 : : #include "roc_platform.h" 15 : : 16 : : /* IO */ 17 : : #if defined(__aarch64__) 18 : : #include "roc_io.h" 19 : : #else 20 : : #include "roc_io_generic.h" 21 : : #endif 22 : : 23 : : /* HW structure definition */ 24 : : #include "hw/cpt.h" 25 : : #include "hw/nix.h" 26 : : #include "hw/npa.h" 27 : : #include "hw/npc.h" 28 : : #include "hw/ssow.h" 29 : : 30 : : /* NPA */ 31 : : #include "roc_npa_dp.h" 32 : : 33 : : /* SSO */ 34 : : #include "roc_sso_dp.h" 35 : : 36 : : /* CPT */ 37 : : #include "roc_cpt.h" 38 : : 39 : : #include "roc_ie_ot.h" 40 : : 41 : : #include "roc_ie_ow.h" 42 : : 43 : : /* NIX Inline dev */ 44 : : #include "roc_nix_inl_dp.h" 45 : : 46 : : #include "cnxk_ethdev_dp.h" 47 : : 48 : : struct cn20k_eth_txq { 49 : : uint64_t send_hdr_w0; 50 : : int64_t fc_cache_pkts; 51 : : uint64_t *fc_mem; 52 : : uintptr_t lmt_base; 53 : : rte_iova_t io_addr; 54 : : uint16_t sqes_per_sqb_log2; 55 : : int16_t nb_sqb_bufs_adj; 56 : : uint8_t flag; 57 : : rte_iova_t cpt_io_addr; 58 : : uint64_t sa_base; 59 : : uint64_t *cpt_fc; 60 : : uint16_t cpt_desc; 61 : : int32_t *cpt_fc_sw; 62 : : uint64_t lso_tun_fmt; 63 : : uint64_t ts_mem; 64 : : uint64_t mark_flag : 8; 65 : : uint64_t mark_fmt : 48; 66 : : struct cnxk_eth_txq_comp tx_compl; 67 : : } __plt_cache_aligned; 68 : : 69 : : struct cn20k_eth_rxq { 70 : : uint64_t mbuf_initializer; 71 : : uintptr_t desc; 72 : : void *lookup_mem; 73 : : uintptr_t cq_door; 74 : : uint64_t wdata; 75 : : int64_t *cq_status; 76 : : uint32_t head; 77 : : uint32_t qmask; 78 : : uint32_t available; 79 : : uint16_t data_off; 80 : : uint64_t sa_base; 81 : : uint64_t lmt_base; 82 : : uint64_t meta_aura; 83 : : uintptr_t meta_pool; 84 : : uint16_t rq; 85 : : uint64_t mp_buf_sz; 86 : : struct cnxk_timesync_info *tstamp; 87 : : } __plt_cache_aligned; 88 : : 89 : : /* Private data in sw rsvd area of struct roc_ot_ipsec_inb_sa */ 90 : : struct cn20k_inb_priv_data { 91 : : void *userdata; 92 : : int reass_dynfield_off; 93 : : int reass_dynflag_bit; 94 : : struct cnxk_eth_sec_sess *eth_sec; 95 : : }; 96 : : 97 : : struct __rte_packed_begin cn20k_sec_sess_priv { 98 : : union { 99 : : struct { 100 : : uint32_t sa_idx; 101 : : uint8_t inb_sa : 1; 102 : : uint8_t outer_ip_ver : 1; 103 : : uint8_t mode : 1; 104 : : uint8_t roundup_byte : 5; 105 : : uint8_t roundup_len; 106 : : uint16_t partial_len : 10; 107 : : uint16_t chksum : 2; 108 : : uint16_t dec_ttl : 1; 109 : : uint16_t nixtx_off : 1; 110 : : uint16_t rsvd : 2; 111 : : }; 112 : : 113 : : uint64_t u64; 114 : : }; 115 : : } __rte_packed_end; 116 : : 117 : : #define LMT_OFF(lmt_addr, lmt_num, offset) \ 118 : : (void *)((uintptr_t)(lmt_addr) + ((uint64_t)(lmt_num) << ROC_LMT_LINE_SIZE_LOG2) + (offset)) 119 : : 120 : : static inline uint16_t 121 : : nix_tx_compl_nb_pkts(struct cn20k_eth_txq *txq, const uint64_t wdata, const uint32_t qmask) 122 : : { 123 : 0 : uint16_t available = txq->tx_compl.available; 124 : : 125 : : /* Update the available count if cached value is not enough */ 126 [ # # ]: 0 : if (!unlikely(available)) { 127 : : uint64_t reg, head, tail; 128 : : 129 : : /* Use LDADDA version to avoid reorder */ 130 : : reg = roc_atomic64_add_sync(wdata, txq->tx_compl.cq_status); 131 : : /* CQ_OP_STATUS operation error */ 132 : : if (reg & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) || reg & BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR)) 133 : : return 0; 134 : : 135 : : tail = reg & 0xFFFFF; 136 : : head = (reg >> 20) & 0xFFFFF; 137 : : if (tail < head) 138 : : available = tail - head + qmask + 1; 139 : : else 140 : : available = tail - head; 141 : : 142 : 0 : txq->tx_compl.available = available; 143 : : } 144 : : return available; 145 : : } 146 : : 147 : : static inline void 148 : 0 : handle_tx_completion_pkts(struct cn20k_eth_txq *txq, uint8_t mt_safe) 149 : : { 150 : : #define CNXK_NIX_CQ_ENTRY_SZ 128 151 : : #define CQE_SZ(x) ((x) * CNXK_NIX_CQ_ENTRY_SZ) 152 : : 153 : : uint16_t tx_pkts = 0, nb_pkts; 154 : 0 : const uintptr_t desc = txq->tx_compl.desc_base; 155 : 0 : const uint64_t wdata = txq->tx_compl.wdata; 156 : 0 : const uint32_t qmask = txq->tx_compl.qmask; 157 : 0 : uint32_t head = txq->tx_compl.head; 158 : : struct nix_cqe_hdr_s *tx_compl_cq; 159 : : struct nix_send_comp_s *tx_compl_s0; 160 : : struct rte_mbuf *m_next, *m; 161 : : 162 [ # # ]: 0 : if (mt_safe) 163 : 0 : rte_spinlock_lock(&txq->tx_compl.ext_buf_lock); 164 : : 165 : : nb_pkts = nix_tx_compl_nb_pkts(txq, wdata, qmask); 166 [ # # ]: 0 : while (tx_pkts < nb_pkts) { 167 : 0 : rte_prefetch_non_temporal((void *)(desc + (CQE_SZ((head + 2) & qmask)))); 168 : 0 : tx_compl_cq = (struct nix_cqe_hdr_s *)(desc + CQE_SZ(head)); 169 : : tx_compl_s0 = (struct nix_send_comp_s *)((uint64_t *)tx_compl_cq + 1); 170 : 0 : m = txq->tx_compl.ptr[tx_compl_s0->sqe_id]; 171 [ # # ]: 0 : while (m->next != NULL) { 172 : : m_next = m->next; 173 : : rte_pktmbuf_free_seg(m); 174 : : m = m_next; 175 : : } 176 : : rte_pktmbuf_free_seg(m); 177 : 0 : txq->tx_compl.ptr[tx_compl_s0->sqe_id] = NULL; 178 : : 179 : 0 : head++; 180 : 0 : head &= qmask; 181 : 0 : tx_pkts++; 182 : : } 183 : 0 : txq->tx_compl.head = head; 184 : 0 : txq->tx_compl.available -= nb_pkts; 185 : : 186 [ # # ]: 0 : plt_write64((wdata | nb_pkts), txq->tx_compl.cq_door); 187 : : 188 [ # # ]: 0 : if (mt_safe) 189 : 0 : rte_spinlock_unlock(&txq->tx_compl.ext_buf_lock); 190 : 0 : } 191 : : 192 : : static __rte_always_inline uint64_t 193 : : cn20k_cpt_tx_steor_data(void) 194 : : { 195 : : /* We have two CPT instructions per LMTLine TODO */ 196 : : const uint64_t dw_m1 = ROC_CN10K_TWO_CPT_INST_DW_M1; 197 : : uint64_t data; 198 : : 199 : : /* This will be moved to addr area */ 200 : : data = dw_m1 << 16; 201 : : data |= dw_m1 << 19; 202 : : data |= dw_m1 << 22; 203 : : data |= dw_m1 << 25; 204 : : data |= dw_m1 << 28; 205 : : data |= dw_m1 << 31; 206 : : data |= dw_m1 << 34; 207 : : data |= dw_m1 << 37; 208 : : data |= dw_m1 << 40; 209 : : data |= dw_m1 << 43; 210 : : data |= dw_m1 << 46; 211 : : data |= dw_m1 << 49; 212 : : data |= dw_m1 << 52; 213 : : data |= dw_m1 << 55; 214 : : data |= dw_m1 << 58; 215 : : data |= dw_m1 << 61; 216 : : 217 : : return data; 218 : : } 219 : : 220 : : static __rte_always_inline void 221 : : cn20k_nix_sec_steorl(uintptr_t io_addr, uint32_t lmt_id, uint8_t lnum, uint8_t loff, uint8_t shft) 222 : : { 223 : : uint64_t data; 224 : : uintptr_t pa; 225 : : 226 : : /* Check if there is any CPT instruction to submit */ 227 : : if (!lnum && !loff) 228 : : return; 229 : : 230 : : data = cn20k_cpt_tx_steor_data(); 231 : : /* Update lmtline use for partial end line */ 232 : : if (loff) { 233 : : data &= ~(0x7ULL << shft); 234 : : /* Update it to half full i.e 64B */ 235 : : data |= (0x3UL << shft); 236 : : } 237 : : 238 : : pa = io_addr | ((data >> 16) & 0x7) << 4; 239 : : data &= ~(0x7ULL << 16); 240 : : /* Update lines - 1 that contain valid data */ 241 : : data |= ((uint64_t)(lnum + loff - 1)) << 12; 242 : : data |= (uint64_t)lmt_id; 243 : : 244 : : /* STEOR */ 245 : : roc_lmt_submit_steorl(data, pa); 246 : : } 247 : : 248 : : #endif /* __CN20K_RXTX_H__ */