Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2010-2015 Intel Corporation 3 : : */ 4 : : 5 : : #ifndef _IXGBE_RXTX_VEC_COMMON_H_ 6 : : #define _IXGBE_RXTX_VEC_COMMON_H_ 7 : : #include <stdint.h> 8 : : #include <ethdev_driver.h> 9 : : 10 : : #include "ixgbe_ethdev.h" 11 : : #include "ixgbe_rxtx.h" 12 : : 13 : : static inline uint16_t 14 : 0 : reassemble_packets(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_bufs, 15 : : uint16_t nb_bufs, uint8_t *split_flags) 16 : 0 : { 17 : 0 : struct rte_mbuf *pkts[nb_bufs]; /*finished pkts*/ 18 : 0 : struct rte_mbuf *start = rxq->pkt_first_seg; 19 : 0 : struct rte_mbuf *end = rxq->pkt_last_seg; 20 : : unsigned int pkt_idx, buf_idx; 21 : : 22 [ # # ]: 0 : for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) { 23 [ # # ]: 0 : if (end != NULL) { 24 : : /* processing a split packet */ 25 : 0 : end->next = rx_bufs[buf_idx]; 26 : 0 : rx_bufs[buf_idx]->data_len += rxq->crc_len; 27 : : 28 : 0 : start->nb_segs++; 29 : 0 : start->pkt_len += rx_bufs[buf_idx]->data_len; 30 : : end = end->next; 31 : : 32 [ # # ]: 0 : if (!split_flags[buf_idx]) { 33 : : /* it's the last packet of the set */ 34 : 0 : start->hash = end->hash; 35 : 0 : start->ol_flags = end->ol_flags; 36 : : /* we need to strip crc for the whole packet */ 37 : 0 : start->pkt_len -= rxq->crc_len; 38 [ # # ]: 0 : if (end->data_len > rxq->crc_len) 39 : 0 : end->data_len -= rxq->crc_len; 40 : : else { 41 : : /* free up last mbuf */ 42 : : struct rte_mbuf *secondlast = start; 43 : : 44 : 0 : start->nb_segs--; 45 [ # # ]: 0 : while (secondlast->next != end) 46 : : secondlast = secondlast->next; 47 : 0 : secondlast->data_len -= (rxq->crc_len - 48 : : end->data_len); 49 : 0 : secondlast->next = NULL; 50 : : rte_pktmbuf_free_seg(end); 51 : : } 52 : 0 : pkts[pkt_idx++] = start; 53 : : start = end = NULL; 54 : : } 55 : : } else { 56 : : /* not processing a split packet */ 57 [ # # ]: 0 : if (!split_flags[buf_idx]) { 58 : : /* not a split packet, save and skip */ 59 : 0 : pkts[pkt_idx++] = rx_bufs[buf_idx]; 60 : 0 : continue; 61 : : } 62 : 0 : end = start = rx_bufs[buf_idx]; 63 : 0 : rx_bufs[buf_idx]->data_len += rxq->crc_len; 64 : 0 : rx_bufs[buf_idx]->pkt_len += rxq->crc_len; 65 : : } 66 : : } 67 : : 68 : : /* save the partial packet for next time */ 69 : 0 : rxq->pkt_first_seg = start; 70 : 0 : rxq->pkt_last_seg = end; 71 : 0 : memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts))); 72 : 0 : return pkt_idx; 73 : : } 74 : : 75 : : static __rte_always_inline int 76 : : ixgbe_tx_free_bufs(struct ixgbe_tx_queue *txq) 77 : : { 78 : : struct ixgbe_tx_entry_v *txep; 79 : : uint32_t status; 80 : : uint32_t n; 81 : : uint32_t i; 82 : : int nb_free = 0; 83 : : struct rte_mbuf *m, *free[RTE_IXGBE_TX_MAX_FREE_BUF_SZ]; 84 : : 85 : : /* check DD bit on threshold descriptor */ 86 : 0 : status = txq->tx_ring[txq->tx_next_dd].wb.status; 87 [ # # ]: 0 : if (!(status & IXGBE_ADVTXD_STAT_DD)) 88 : : return 0; 89 : : 90 : 0 : n = txq->tx_rs_thresh; 91 : : 92 : : /* 93 : : * first buffer to free from S/W ring is at index 94 : : * tx_next_dd - (tx_rs_thresh-1) 95 : : */ 96 : 0 : txep = &txq->sw_ring_v[txq->tx_next_dd - (n - 1)]; 97 [ # # ]: 0 : m = rte_pktmbuf_prefree_seg(txep[0].mbuf); 98 [ # # ]: 0 : if (likely(m != NULL)) { 99 : 0 : free[0] = m; 100 : : nb_free = 1; 101 [ # # ]: 0 : for (i = 1; i < n; i++) { 102 [ # # ]: 0 : m = rte_pktmbuf_prefree_seg(txep[i].mbuf); 103 [ # # ]: 0 : if (likely(m != NULL)) { 104 [ # # ]: 0 : if (likely(m->pool == free[0]->pool)) 105 : 0 : free[nb_free++] = m; 106 : : else { 107 [ # # ]: 0 : rte_mempool_put_bulk(free[0]->pool, 108 : : (void *)free, nb_free); 109 : 0 : free[0] = m; 110 : : nb_free = 1; 111 : : } 112 : : } 113 : : } 114 [ # # ]: 0 : rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free); 115 : : } else { 116 [ # # ]: 0 : for (i = 1; i < n; i++) { 117 [ # # ]: 0 : m = rte_pktmbuf_prefree_seg(txep[i].mbuf); 118 [ # # ]: 0 : if (m != NULL) 119 [ # # ]: 0 : rte_mempool_put(m->pool, m); 120 : : } 121 : : } 122 : : 123 : : /* buffers were freed, update counters */ 124 : 0 : txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh); 125 : 0 : txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh); 126 [ # # ]: 0 : if (txq->tx_next_dd >= txq->nb_tx_desc) 127 : 0 : txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1); 128 : : 129 : 0 : return txq->tx_rs_thresh; 130 : : } 131 : : 132 : : static __rte_always_inline void 133 : : tx_backlog_entry(struct ixgbe_tx_entry_v *txep, 134 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 135 : : { 136 : : int i; 137 : : 138 [ # # # # ]: 0 : for (i = 0; i < (int)nb_pkts; ++i) 139 : 0 : txep[i].mbuf = tx_pkts[i]; 140 : : } 141 : : 142 : : static inline void 143 : 0 : _ixgbe_tx_queue_release_mbufs_vec(struct ixgbe_tx_queue *txq) 144 : : { 145 : : unsigned int i; 146 : : struct ixgbe_tx_entry_v *txe; 147 : 0 : const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1); 148 : : 149 [ # # # # ]: 0 : if (txq->sw_ring == NULL || txq->nb_tx_free == max_desc) 150 : : return; 151 : : 152 : : /* release the used mbufs in sw_ring */ 153 : 0 : for (i = txq->tx_next_dd - (txq->tx_rs_thresh - 1); 154 [ # # ]: 0 : i != txq->tx_tail; 155 : 0 : i = (i + 1) % txq->nb_tx_desc) { 156 : 0 : txe = &txq->sw_ring_v[i]; 157 : 0 : rte_pktmbuf_free_seg(txe->mbuf); 158 : : } 159 : 0 : txq->nb_tx_free = max_desc; 160 : : 161 : : /* reset tx_entry */ 162 [ # # ]: 0 : for (i = 0; i < txq->nb_tx_desc; i++) { 163 : 0 : txe = &txq->sw_ring_v[i]; 164 : 0 : txe->mbuf = NULL; 165 : : } 166 : : } 167 : : 168 : : static inline void 169 : 0 : _ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq) 170 : : { 171 : : unsigned int i; 172 : : 173 [ # # # # ]: 0 : if (rxq->sw_ring == NULL || rxq->rxrearm_nb >= rxq->nb_rx_desc) 174 : : return; 175 : : 176 : : /* free all mbufs that are valid in the ring */ 177 [ # # ]: 0 : if (rxq->rxrearm_nb == 0) { 178 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) { 179 [ # # ]: 0 : if (rxq->sw_ring[i].mbuf != NULL) 180 : : rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf); 181 : : } 182 : : } else { 183 : 0 : for (i = rxq->rx_tail; 184 [ # # ]: 0 : i != rxq->rxrearm_start; 185 : 0 : i = (i + 1) % rxq->nb_rx_desc) { 186 [ # # ]: 0 : if (rxq->sw_ring[i].mbuf != NULL) 187 : : rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf); 188 : : } 189 : : } 190 : : 191 : 0 : rxq->rxrearm_nb = rxq->nb_rx_desc; 192 : : 193 : : /* set all entries to NULL */ 194 : 0 : memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc); 195 : : } 196 : : 197 : : static inline void 198 : : _ixgbe_tx_free_swring_vec(struct ixgbe_tx_queue *txq) 199 : : { 200 [ # # ]: 0 : if (txq == NULL) 201 : : return; 202 : : 203 [ # # ]: 0 : if (txq->sw_ring != NULL) { 204 : 0 : rte_free(txq->sw_ring_v - 1); 205 : 0 : txq->sw_ring_v = NULL; 206 : : } 207 : : } 208 : : 209 : : static inline void 210 : 0 : _ixgbe_reset_tx_queue_vec(struct ixgbe_tx_queue *txq) 211 : : { 212 : : static const union ixgbe_adv_tx_desc zeroed_desc = { { 0 } }; 213 : 0 : struct ixgbe_tx_entry_v *txe = txq->sw_ring_v; 214 : : uint16_t i; 215 : : 216 : : /* Zero out HW ring memory */ 217 [ # # ]: 0 : for (i = 0; i < txq->nb_tx_desc; i++) 218 : 0 : txq->tx_ring[i] = zeroed_desc; 219 : : 220 : : /* Initialize SW ring entries */ 221 [ # # ]: 0 : for (i = 0; i < txq->nb_tx_desc; i++) { 222 : 0 : volatile union ixgbe_adv_tx_desc *txd = &txq->tx_ring[i]; 223 : : 224 : 0 : txd->wb.status = IXGBE_TXD_STAT_DD; 225 : 0 : txe[i].mbuf = NULL; 226 : : } 227 : : 228 : 0 : txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1); 229 : 0 : txq->tx_next_rs = (uint16_t)(txq->tx_rs_thresh - 1); 230 : : 231 : 0 : txq->tx_tail = 0; 232 : 0 : txq->nb_tx_used = 0; 233 : : /* 234 : : * Always allow 1 descriptor to be un-allocated to avoid 235 : : * a H/W race condition 236 : : */ 237 : 0 : txq->last_desc_cleaned = (uint16_t)(txq->nb_tx_desc - 1); 238 : 0 : txq->nb_tx_free = (uint16_t)(txq->nb_tx_desc - 1); 239 : 0 : txq->ctx_curr = 0; 240 : 0 : memset((void *)&txq->ctx_cache, 0, 241 : : IXGBE_CTX_NUM * sizeof(struct ixgbe_advctx_info)); 242 : 0 : } 243 : : 244 : : static inline int 245 : 0 : ixgbe_rxq_vec_setup_default(struct ixgbe_rx_queue *rxq) 246 : : { 247 : : uintptr_t p; 248 : 0 : struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */ 249 : : 250 : 0 : mb_def.nb_segs = 1; 251 : 0 : mb_def.data_off = RTE_PKTMBUF_HEADROOM; 252 : 0 : mb_def.port = rxq->port_id; 253 : : rte_mbuf_refcnt_set(&mb_def, 1); 254 : : 255 : : /* prevent compiler reordering: rearm_data covers previous fields */ 256 : 0 : rte_compiler_barrier(); 257 : : p = (uintptr_t)&mb_def.rearm_data; 258 : 0 : rxq->mbuf_initializer = *(uint64_t *)p; 259 : 0 : return 0; 260 : : } 261 : : 262 : : static inline int 263 : : ixgbe_txq_vec_setup_default(struct ixgbe_tx_queue *txq, 264 : : const struct ixgbe_txq_ops *txq_ops) 265 : : { 266 [ # # ]: 0 : if (txq->sw_ring_v == NULL) 267 : : return -1; 268 : : 269 : : /* leave the first one for overflow */ 270 : 0 : txq->sw_ring_v = txq->sw_ring_v + 1; 271 : 0 : txq->ops = txq_ops; 272 : : 273 : 0 : return 0; 274 : : } 275 : : 276 : : static inline int 277 : : ixgbe_rx_vec_dev_conf_condition_check_default(struct rte_eth_dev *dev) 278 : : { 279 : : #ifndef RTE_LIBRTE_IEEE1588 280 : 0 : struct rte_eth_fdir_conf *fconf = IXGBE_DEV_FDIR_CONF(dev); 281 : : 282 : : /* no fdir support */ 283 [ # # ]: 0 : if (fconf->mode != RTE_FDIR_MODE_NONE) 284 : 0 : return -1; 285 : : 286 : : return 0; 287 : : #else 288 : : RTE_SET_USED(dev); 289 : : return -1; 290 : : #endif 291 : : } 292 : : #endif