Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd. 3 : : */ 4 : : 5 : : #include "sxe2_txrx_vec.h" 6 : : #include "sxe2_txrx_vec_common.h" 7 : : #include "sxe2_queue.h" 8 : : #include "sxe2_ethdev.h" 9 : : #include "sxe2_common_log.h" 10 : : 11 : : static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq); 12 : : 13 : : static const struct sxe2_txq_ops sxe2_tx_vec_ops = { 14 : : .queue_reset = sxe2_tx_queue_reset_vec, 15 : : .mbufs_release = sxe2_tx_queue_mbufs_release_vec, 16 : : .buffer_ring_free = sxe2_tx_buffer_ring_free, 17 : : }; 18 : : 19 : 0 : int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags) 20 : : { 21 : 0 : struct sxe2_rx_queue *rxq; 22 : 0 : int32_t ret = 0; 23 : 0 : uint16_t i; 24 : : 25 : 0 : *vec_flags = SXE2_RX_MODE_VEC_SIMPLE; 26 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; ++i) { 27 : 0 : rxq = (struct sxe2_rx_queue *)dev->data->rx_queues[i]; 28 [ # # ]: 0 : if (rxq == NULL) { 29 : 0 : ret = -EINVAL; 30 : 0 : goto l_end; 31 : : } 32 [ # # ]: 0 : if (!rte_is_power_of_2(rxq->ring_depth)) { 33 : 0 : ret = -ENOTSUP; 34 : 0 : goto l_end; 35 : : } 36 [ # # ]: 0 : if (rxq->rx_free_thresh < SXE2_RX_PKTS_BURST_BATCH_NUM_VEC && 37 [ # # ]: 0 : (rxq->ring_depth % rxq->rx_free_thresh) != 0) { 38 : 0 : ret = -ENOTSUP; 39 : 0 : goto l_end; 40 : : } 41 [ # # ]: 0 : if ((rxq->offloads & SXE2_RX_VEC_NO_SUPPORT_OFFLOAD) != 0) { 42 : 0 : ret = -ENOTSUP; 43 : 0 : goto l_end; 44 : : } 45 [ # # ]: 0 : if ((rxq->offloads & SXE2_RX_VEC_SUPPORT_OFFLOAD) != 0) 46 : 0 : *vec_flags = SXE2_RX_MODE_VEC_OFFLOAD; 47 : : } 48 : 0 : l_end: 49 : 0 : return ret; 50 : : } 51 : : 52 : 0 : bool __rte_cold sxe2_rx_offload_en_check(struct rte_eth_dev *dev, uint64_t offload) 53 : : { 54 : 0 : struct sxe2_rx_queue *rxq; 55 : 0 : bool en = false; 56 : 0 : uint16_t i; 57 : : 58 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; ++i) { 59 : 0 : rxq = (struct sxe2_rx_queue *)dev->data->rx_queues[i]; 60 [ # # ]: 0 : if (rxq == NULL) 61 : 0 : continue; 62 [ # # ]: 0 : if ((rxq->offloads & offload) != 0) { 63 : 0 : en = true; 64 : 0 : goto l_end; 65 : : } 66 : : } 67 : 0 : l_end: 68 : 0 : return en; 69 : : } 70 : : 71 : 0 : static inline void sxe2_rx_queue_mbufs_release_vec(struct sxe2_rx_queue *rxq) 72 : : { 73 : 0 : const uint16_t mask = rxq->ring_depth - 1; 74 : 0 : uint16_t i; 75 : : 76 [ # # ]: 0 : if (unlikely(!rxq->buffer_ring)) { 77 : 0 : PMD_LOG_DEBUG(RX, "Rx queue release mbufs vec, buffer_ring if NULL." 78 : : "port_id:%u queue_id:%u", rxq->port_id, rxq->queue_id); 79 : 0 : return; 80 : : } 81 [ # # ]: 0 : if (rxq->realloc_num >= rxq->ring_depth) 82 : : return; 83 [ # # ]: 0 : if (rxq->realloc_num == 0) { 84 [ # # ]: 0 : for (i = 0; i < rxq->ring_depth; ++i) { 85 [ # # ]: 0 : if (rxq->buffer_ring[i]) { 86 : 0 : rte_pktmbuf_free_seg(rxq->buffer_ring[i]); 87 : 0 : rxq->buffer_ring[i] = NULL; 88 : : } 89 : : } 90 : : } else { 91 : 0 : for (i = rxq->processing_idx; 92 [ # # ]: 0 : i != rxq->realloc_start; 93 : 0 : i = (i + 1) & mask) { 94 [ # # ]: 0 : if (rxq->buffer_ring[i]) { 95 : 0 : rte_pktmbuf_free_seg(rxq->buffer_ring[i]); 96 : 0 : rxq->buffer_ring[i] = NULL; 97 : : } 98 : : } 99 : : } 100 : 0 : rxq->realloc_num = rxq->ring_depth; 101 : 0 : memset(rxq->buffer_ring, 0, rxq->ring_depth * sizeof(rxq->buffer_ring[0])); 102 : : } 103 : : 104 : 0 : static inline void sxe2_rx_queue_vec_init(struct sxe2_rx_queue *rxq) 105 : : { 106 : 0 : uintptr_t data; 107 : 0 : struct rte_mbuf mbuf_def; 108 : : 109 : 0 : memset(&mbuf_def, 0, sizeof(mbuf_def)); 110 : 0 : mbuf_def.buf_addr = 0; 111 : 0 : mbuf_def.nb_segs = 1; 112 : 0 : mbuf_def.data_off = RTE_PKTMBUF_HEADROOM; 113 : 0 : mbuf_def.port = rxq->port_id; 114 : 0 : rte_mbuf_refcnt_set(&mbuf_def, 1); 115 : 0 : rte_compiler_barrier(); 116 : 0 : data = (uintptr_t)&mbuf_def.rearm_data; 117 : 0 : rxq->mbuf_init_value = *(uint64_t *)data; 118 : 0 : } 119 : : 120 : 0 : int32_t __rte_cold sxe2_rx_queues_vec_prepare(struct rte_eth_dev *dev) 121 : : { 122 : 0 : struct sxe2_rx_queue *rxq = NULL; 123 : 0 : int32_t ret = 0; 124 : 0 : uint16_t i; 125 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; ++i) { 126 : 0 : rxq = (struct sxe2_rx_queue *)dev->data->rx_queues[i]; 127 [ # # ]: 0 : if (rxq == NULL) { 128 : 0 : PMD_LOG_INFO(RX, "Failed to prepare rx queue, rxq[%d] is NULL", i); 129 : 0 : continue; 130 : : } 131 : 0 : rxq->ops.mbufs_release = sxe2_rx_queue_mbufs_release_vec; 132 : 0 : sxe2_rx_queue_vec_init(rxq); 133 : : } 134 : 0 : return ret; 135 : : } 136 : : 137 : 0 : int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags) 138 : : { 139 : 0 : struct sxe2_tx_queue *txq; 140 : 0 : int32_t ret = 0; 141 : 0 : uint32_t i; 142 : : 143 : 0 : *vec_flags = SXE2_TX_MODE_VEC_SIMPLE; 144 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; ++i) { 145 : 0 : txq = (struct sxe2_tx_queue *)dev->data->tx_queues[i]; 146 [ # # ]: 0 : if (txq == NULL) { 147 : 0 : ret = -EINVAL; 148 : 0 : goto l_end; 149 : : } 150 [ # # ]: 0 : if (txq->rs_thresh < SXE2_TX_RS_THRESH_MIN_VEC || 151 : : txq->rs_thresh > SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC) { 152 : 0 : ret = -ENOTSUP; 153 : 0 : goto l_end; 154 : : } 155 [ # # ]: 0 : if ((txq->offloads & SXE2_TX_VEC_NO_SUPPORT_OFFLOAD) != 0) { 156 : 0 : ret = -ENOTSUP; 157 : 0 : goto l_end; 158 : : } 159 [ # # ]: 0 : if ((txq->offloads & SXE2_TX_VEC_SUPPORT_OFFLOAD) != 0) 160 : 0 : *vec_flags = SXE2_TX_MODE_VEC_OFFLOAD; 161 : : } 162 : 0 : l_end: 163 : 0 : return ret; 164 : : } 165 : : 166 : 0 : static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq) 167 : : { 168 : 0 : struct sxe2_tx_buffer_vec *buffer_vec; 169 : 0 : uint16_t i; 170 : : 171 [ # # # # ]: 0 : if (unlikely(txq == NULL || txq->buffer_ring_vec == NULL)) { 172 : 0 : PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params."); 173 : 0 : return; 174 : : } 175 : : 176 : 0 : i = txq->next_dd - (txq->rs_thresh - 1); 177 : 0 : buffer_vec = txq->buffer_ring_vec; 178 : : 179 [ # # ]: 0 : if (txq->next_use < i) { 180 [ # # ]: 0 : for ( ; i < txq->ring_depth; ++i) { 181 [ # # ]: 0 : if (buffer_vec[i].mbuf != NULL) { 182 : 0 : rte_pktmbuf_free_seg(buffer_vec[i].mbuf); 183 : 0 : buffer_vec[i].mbuf = NULL; 184 : : } 185 : : } 186 : : i = 0; 187 : : } 188 : : 189 [ # # ]: 0 : for ( ; i < txq->next_use; ++i) { 190 [ # # ]: 0 : if (buffer_vec[i].mbuf != NULL) { 191 : 0 : rte_pktmbuf_free_seg(buffer_vec[i].mbuf); 192 : 0 : buffer_vec[i].mbuf = NULL; 193 : : } 194 : : } 195 : : } 196 : : 197 : 0 : int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev) 198 : : { 199 : 0 : struct sxe2_tx_queue *txq = NULL; 200 : 0 : int32_t ret = 0; 201 : 0 : uint16_t i; 202 : : 203 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; ++i) { 204 : 0 : txq = dev->data->tx_queues[i]; 205 [ # # ]: 0 : if (txq == NULL) { 206 : 0 : PMD_LOG_ERR(TX, "Failed to prepare tx queue, txq[%d] is NULL", i); 207 : 0 : ret = -EINVAL; 208 : 0 : goto l_end; 209 : : } 210 : 0 : txq->ops = sxe2_tx_vec_ops; 211 : 0 : txq->ops.queue_reset(txq); 212 : : } 213 : 0 : l_end: 214 : 0 : return ret; 215 : : }