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