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 <ethdev_driver.h>
6 : : #include <rte_net.h>
7 : : #include <rte_vect.h>
8 : : #include <rte_malloc.h>
9 : : #include <rte_memzone.h>
10 : :
11 : : #include "sxe2_ethdev.h"
12 : : #include "sxe2_queue.h"
13 : : #include "sxe2_rx.h"
14 : : #include "sxe2_cmd_chnl.h"
15 : :
16 : : #include "sxe2_osal.h"
17 : : #include "sxe2_common_log.h"
18 : :
19 : 0 : static void *sxe2_rx_doorbell_tail_addr_get(struct sxe2_adapter *adapter, uint16_t queue_id)
20 : : {
21 : 0 : return sxe2_pci_map_addr_get(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL,
22 : : queue_id);
23 : : }
24 : :
25 : 0 : static void sxe2_rx_head_tail_init(struct sxe2_adapter *adapter, struct sxe2_rx_queue *rxq)
26 : : {
27 : 0 : rxq->rdt_reg_addr = sxe2_rx_doorbell_tail_addr_get(adapter, rxq->queue_id);
28 : 0 : SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, 0);
29 : 0 : }
30 : :
31 : 0 : static void __rte_cold sxe2_rx_queue_reset(struct sxe2_rx_queue *rxq)
32 : : {
33 : 0 : uint16_t i = 0;
34 : 0 : uint16_t len = 0;
35 : 0 : static const union sxe2_rx_desc zeroed_desc = {{0}};
36 : :
37 : 0 : len = rxq->ring_depth + SXE2_RX_PKTS_BURST_BATCH_NUM;
38 [ # # ]: 0 : for (i = 0; i < len; ++i)
39 : 0 : rxq->desc_ring[i] = zeroed_desc;
40 : :
41 : 0 : memset(&rxq->fake_mbuf, 0, sizeof(rxq->fake_mbuf));
42 [ # # ]: 0 : for (i = rxq->ring_depth; i < len; i++)
43 : 0 : rxq->buffer_ring[i] = &rxq->fake_mbuf;
44 : :
45 : 0 : rxq->hold_num = 0;
46 : 0 : rxq->next_ret_pkt = 0;
47 : 0 : rxq->processing_idx = 0;
48 : 0 : rxq->completed_pkts_num = 0;
49 : 0 : rxq->batch_alloc_trigger = rxq->rx_free_thresh - 1;
50 : :
51 : 0 : rxq->pkt_first_seg = NULL;
52 : 0 : rxq->pkt_last_seg = NULL;
53 : :
54 : 0 : rxq->realloc_num = 0;
55 : 0 : rxq->realloc_start = 0;
56 : 0 : }
57 : :
58 : 0 : void __rte_cold sxe2_rx_queue_mbufs_release(struct sxe2_rx_queue *rxq)
59 : : {
60 : 0 : uint16_t i;
61 : :
62 [ # # ]: 0 : if (rxq->buffer_ring != NULL) {
63 [ # # ]: 0 : for (i = 0; i < rxq->ring_depth; i++) {
64 [ # # ]: 0 : if (rxq->buffer_ring[i] != NULL) {
65 : 0 : rte_pktmbuf_free(rxq->buffer_ring[i]);
66 : 0 : rxq->buffer_ring[i] = NULL;
67 : : }
68 : : }
69 : : }
70 : :
71 [ # # ]: 0 : if (rxq->completed_pkts_num) {
72 [ # # ]: 0 : for (i = 0; i < rxq->completed_pkts_num; ++i) {
73 [ # # ]: 0 : if (rxq->completed_buf[rxq->next_ret_pkt + i] != NULL) {
74 : 0 : rte_pktmbuf_free(rxq->completed_buf[rxq->next_ret_pkt + i]);
75 : 0 : rxq->completed_buf[rxq->next_ret_pkt + i] = NULL;
76 : : }
77 : : }
78 : 0 : rxq->completed_pkts_num = 0;
79 : : }
80 : 0 : }
81 : :
82 : : const struct sxe2_rxq_ops sxe2_default_rxq_ops = {
83 : : .queue_reset = sxe2_rx_queue_reset,
84 : : .mbufs_release = sxe2_rx_queue_mbufs_release,
85 : : };
86 : :
87 : 0 : static struct sxe2_rxq_ops sxe2_rx_default_ops_get(void)
88 : : {
89 : 0 : return sxe2_default_rxq_ops;
90 : : }
91 : :
92 : 0 : void __rte_cold sxe2_rx_queue_info_get(struct rte_eth_dev *dev,
93 : : uint16_t queue_id, struct rte_eth_rxq_info *qinfo)
94 : : {
95 : 0 : struct sxe2_rx_queue *rxq = NULL;
96 : :
97 [ # # ]: 0 : if (queue_id >= dev->data->nb_rx_queues) {
98 : 0 : PMD_LOG_ERR(RX, "rx queue:%u is out of range:%u",
99 : : queue_id, dev->data->nb_rx_queues);
100 : 0 : goto end;
101 : : }
102 : :
103 : 0 : rxq = dev->data->rx_queues[queue_id];
104 [ # # ]: 0 : if (rxq == NULL) {
105 : 0 : PMD_LOG_ERR(RX, "rx queue:%u is NULL", queue_id);
106 : 0 : goto end;
107 : : }
108 : :
109 : 0 : qinfo->mp = rxq->mb_pool;
110 : 0 : qinfo->nb_desc = rxq->ring_depth;
111 : 0 : qinfo->scattered_rx = dev->data->scattered_rx;
112 : 0 : qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
113 : 0 : qinfo->conf.rx_drop_en = rxq->drop_en;
114 : 0 : qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
115 : :
116 : 0 : end:
117 : 0 : return;
118 : : }
119 : :
120 : 0 : int32_t __rte_cold sxe2_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
121 : : {
122 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
123 : 0 : struct sxe2_rx_queue *rxq;
124 : 0 : int32_t ret;
125 : 0 : PMD_INIT_FUNC_TRACE();
126 : :
127 [ # # ]: 0 : if (dev->data->rx_queue_state[rx_queue_id] ==
128 : : RTE_ETH_QUEUE_STATE_STOPPED) {
129 : 0 : ret = 0;
130 : 0 : goto l_end;
131 : : }
132 : :
133 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
134 [ # # ]: 0 : if (rxq == NULL) {
135 : 0 : ret = 0;
136 : 0 : goto l_end;
137 : : }
138 : 0 : ret = sxe2_drv_rxq_switch(adapter, rxq, false);
139 [ # # ]: 0 : if (ret) {
140 : 0 : PMD_LOG_ERR(RX, "Failed to switch rx queue %u off, ret = %d",
141 : : rx_queue_id, ret);
142 [ # # ]: 0 : if (ret == -EPERM)
143 : 0 : goto l_free;
144 : 0 : goto l_end;
145 : : }
146 : :
147 : 0 : l_free:
148 : 0 : rxq->ops.mbufs_release(rxq);
149 : 0 : rxq->ops.queue_reset(rxq);
150 : 0 : dev->data->rx_queue_state[rx_queue_id] =
151 : : RTE_ETH_QUEUE_STATE_STOPPED;
152 : 0 : l_end:
153 : 0 : return ret;
154 : : }
155 : :
156 : 0 : static void __rte_cold sxe2_rx_queue_free(struct sxe2_rx_queue *rxq)
157 : : {
158 [ # # ]: 0 : if (rxq != NULL) {
159 : 0 : rxq->ops.mbufs_release(rxq);
160 [ # # ]: 0 : if (rxq->buffer_ring != NULL) {
161 : 0 : rte_free(rxq->buffer_ring);
162 : 0 : rxq->buffer_ring = NULL;
163 : : }
164 : 0 : rte_memzone_free(rxq->mz);
165 : 0 : rte_free(rxq);
166 : : }
167 : 0 : }
168 : :
169 : 0 : void __rte_cold sxe2_rx_queue_release(struct rte_eth_dev *dev,
170 : : uint16_t queue_idx)
171 : : {
172 : 0 : (void)sxe2_rx_queue_stop(dev, queue_idx);
173 : 0 : sxe2_rx_queue_free(dev->data->rx_queues[queue_idx]);
174 : 0 : dev->data->rx_queues[queue_idx] = NULL;
175 : 0 : }
176 : :
177 : 0 : void __rte_cold sxe2_all_rxqs_release(struct rte_eth_dev *dev)
178 : : {
179 : 0 : struct rte_eth_dev_data *data = dev->data;
180 : 0 : uint16_t nb_rxq;
181 : :
182 [ # # ]: 0 : for (nb_rxq = 0; nb_rxq < data->nb_rx_queues; nb_rxq++) {
183 [ # # ]: 0 : if (data->rx_queues[nb_rxq] == NULL)
184 : 0 : continue;
185 : 0 : sxe2_rx_queue_release(dev, nb_rxq);
186 : 0 : data->rx_queues[nb_rxq] = NULL;
187 : : }
188 : 0 : data->nb_rx_queues = 0;
189 : 0 : }
190 : :
191 : 0 : static struct sxe2_rx_queue *sxe2_rx_queue_alloc(struct rte_eth_dev *dev, uint16_t queue_idx,
192 : : uint16_t ring_depth, uint32_t socket_id)
193 : : {
194 : 0 : struct sxe2_rx_queue *rxq;
195 : 0 : const struct rte_memzone *tz;
196 : 0 : uint16_t len;
197 : :
198 [ # # ]: 0 : if (dev->data->rx_queues[queue_idx] != NULL) {
199 : 0 : sxe2_rx_queue_release(dev, queue_idx);
200 : 0 : dev->data->rx_queues[queue_idx] = NULL;
201 : : }
202 : :
203 : 0 : rxq = rte_zmalloc_socket("rx_queue", sizeof(*rxq),
204 : : RTE_CACHE_LINE_SIZE, socket_id);
205 : :
206 [ # # ]: 0 : if (rxq == NULL) {
207 : 0 : PMD_LOG_ERR(RX, "rx queue[%d] alloc failed", queue_idx);
208 : 0 : goto l_end;
209 : : }
210 : :
211 : 0 : rxq->ring_depth = ring_depth;
212 : 0 : len = rxq->ring_depth + SXE2_RX_PKTS_BURST_BATCH_NUM;
213 : :
214 : 0 : rxq->buffer_ring = rte_zmalloc_socket("rx_buffer_ring",
215 : : sizeof(struct rte_mbuf *) * len,
216 : : RTE_CACHE_LINE_SIZE, socket_id);
217 : :
218 [ # # ]: 0 : if (!rxq->buffer_ring) {
219 : 0 : PMD_LOG_ERR(RX, "Rxq malloc mbuf mem failed");
220 : 0 : rte_free(rxq);
221 : 0 : rxq = NULL;
222 : 0 : goto l_end;
223 : : }
224 : :
225 : 0 : tz = rte_eth_dma_zone_reserve(dev, "rx_dma", queue_idx,
226 : : SXE2_RX_RING_SIZE, SXE2_DESC_ADDR_ALIGN, socket_id);
227 [ # # ]: 0 : if (tz == NULL) {
228 : 0 : PMD_LOG_ERR(RX, "Rxq malloc desc mem failed");
229 : 0 : rte_free(rxq->buffer_ring);
230 : 0 : rxq->buffer_ring = NULL;
231 : 0 : rte_free(rxq);
232 : 0 : rxq = NULL;
233 : 0 : goto l_end;
234 : : }
235 : :
236 : 0 : rxq->mz = tz;
237 : 0 : memset(tz->addr, 0, SXE2_RX_RING_SIZE);
238 : 0 : rxq->base_addr = tz->iova;
239 : 0 : rxq->desc_ring = (union sxe2_rx_desc *)tz->addr;
240 : :
241 : 0 : l_end:
242 : 0 : return rxq;
243 : : }
244 : :
245 : 0 : int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
246 : : uint16_t queue_idx, uint16_t nb_desc, uint32_t socket_id,
247 : : const struct rte_eth_rxconf *rx_conf,
248 : : struct rte_mempool *mp)
249 : : {
250 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
251 : 0 : struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
252 : 0 : struct sxe2_rx_queue *rxq;
253 : 0 : uint64_t offloads;
254 : 0 : int32_t ret;
255 : 0 : uint16_t rx_nseg;
256 : 0 : uint16_t i;
257 : :
258 : 0 : PMD_INIT_FUNC_TRACE();
259 : :
260 : 0 : if (nb_desc % SXE2_RX_DESC_RING_ALIGN != 0 ||
261 [ # # ]: 0 : nb_desc > SXE2_MAX_RING_DESC ||
262 : : nb_desc < SXE2_MIN_RING_DESC) {
263 : 0 : PMD_LOG_ERR(RX, "param desc num:%u is invalid", nb_desc);
264 : 0 : ret = -EINVAL;
265 : 0 : goto l_end;
266 : : }
267 : :
268 [ # # ]: 0 : if (mp != NULL)
269 : : rx_nseg = 1;
270 : : else
271 : 0 : rx_nseg = rx_conf->rx_nseg;
272 : :
273 : 0 : offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
274 : :
275 [ # # # # ]: 0 : if (rx_nseg > 1 && !(offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
276 : 0 : PMD_LOG_ERR(RX, "Port %u queue %u Buffer split offload not configured, but rx_nseg is %u",
277 : : dev->data->port_id, queue_idx, rx_nseg);
278 : 0 : ret = -EINVAL;
279 : 0 : goto l_end;
280 : : }
281 : :
282 [ # # # # ]: 0 : if ((offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) && !(rx_nseg > 1)) {
283 : 0 : PMD_LOG_ERR(RX, "Port %u queue %u Buffer split offload configured, but rx_nseg is %u",
284 : : dev->data->port_id, queue_idx, rx_nseg);
285 : 0 : ret = -EINVAL;
286 : 0 : goto l_end;
287 : : }
288 : :
289 [ # # ]: 0 : if ((offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) &&
290 : : (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)) {
291 : 0 : PMD_LOG_ERR(RX, "port_id %u queue %u, LRO can't be configure with Keep crc.",
292 : : dev->data->port_id, queue_idx);
293 : 0 : ret = -EINVAL;
294 : 0 : goto l_end;
295 : : }
296 : :
297 [ # # ]: 0 : if (!sxe2_ipsec_valid_rx_offloads(offloads)) {
298 : 0 : ret = -EINVAL;
299 : 0 : goto l_end;
300 : : }
301 : :
302 : 0 : rxq = sxe2_rx_queue_alloc(dev, queue_idx, nb_desc, socket_id);
303 [ # # ]: 0 : if (rxq == NULL) {
304 : 0 : PMD_LOG_ERR(RX, "rx queue[%d] resource alloc failed", queue_idx);
305 : 0 : ret = -ENOMEM;
306 : 0 : goto l_end;
307 : : }
308 : :
309 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
310 : 0 : dev->data->lro = 1;
311 : :
312 [ # # ]: 0 : if (rx_nseg > 1) {
313 [ # # ]: 0 : for (i = 0; i < rx_nseg; i++) {
314 : 0 : rte_memcpy(&rxq->rx_seg[i], &rx_conf->rx_seg[i].split,
315 : : sizeof(struct rte_eth_rxseg_split));
316 : : }
317 : 0 : rxq->mb_pool = rxq->rx_seg[0].mp;
318 : : } else {
319 : 0 : rxq->mb_pool = mp;
320 : : }
321 : :
322 : 0 : rxq->rx_free_thresh = rx_conf->rx_free_thresh;
323 : 0 : rxq->port_id = dev->data->port_id;
324 : 0 : rxq->offloads = offloads;
325 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
326 : 0 : rxq->crc_len = RTE_ETHER_CRC_LEN;
327 : : else
328 : 0 : rxq->crc_len = 0;
329 : :
330 : 0 : rxq->queue_id = queue_idx;
331 : 0 : rxq->idx_in_func = vsi->rxqs.base_idx_in_func + queue_idx;
332 : 0 : rxq->drop_en = rx_conf->rx_drop_en;
333 : 0 : rxq->rx_deferred_start = rx_conf->rx_deferred_start;
334 : 0 : rxq->vsi = vsi;
335 : 0 : rxq->ops = sxe2_rx_default_ops_get();
336 : 0 : rxq->ops.queue_reset(rxq);
337 : 0 : dev->data->rx_queues[queue_idx] = rxq;
338 : :
339 : 0 : ret = 0;
340 : 0 : l_end:
341 : 0 : return ret;
342 : : }
343 : :
344 : 0 : static int32_t __rte_cold sxe2_rx_queue_mbufs_alloc(struct sxe2_rx_queue *rxq)
345 : : {
346 : 0 : struct rte_mbuf **buf_ring = rxq->buffer_ring;
347 : 0 : struct rte_mbuf *mbuf = NULL;
348 : 0 : struct rte_mbuf *mbuf_pay;
349 : 0 : volatile union sxe2_rx_desc *desc;
350 : 0 : uint64_t dma_addr;
351 : 0 : int32_t ret;
352 : 0 : uint16_t i, j;
353 : :
354 [ # # ]: 0 : for (i = 0; i < rxq->ring_depth; i++) {
355 : 0 : mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
356 [ # # ]: 0 : if (mbuf == NULL) {
357 : 0 : PMD_LOG_ERR(RX, "Rx queue is not available or setup");
358 : 0 : ret = -ENOMEM;
359 : 0 : goto l_err_free_mbuf;
360 : : }
361 : :
362 : 0 : buf_ring[i] = mbuf;
363 : 0 : mbuf->data_off = RTE_PKTMBUF_HEADROOM;
364 : 0 : mbuf->nb_segs = 1;
365 : 0 : mbuf->port = rxq->port_id;
366 : :
367 [ # # ]: 0 : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
368 : 0 : desc = &rxq->desc_ring[i];
369 [ # # ]: 0 : if (!(rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
370 : 0 : mbuf->next = NULL;
371 : 0 : desc->read.hdr_addr = 0;
372 : 0 : desc->read.pkt_addr = dma_addr;
373 : : } else {
374 : 0 : mbuf_pay = rte_mbuf_raw_alloc(rxq->rx_seg[1].mp);
375 [ # # ]: 0 : if (unlikely(!mbuf_pay)) {
376 : 0 : PMD_LOG_ERR(RX, "Failed to allocate payload mbuf for RX");
377 : 0 : ret = -ENOMEM;
378 : 0 : goto l_err_free_mbuf;
379 : : }
380 : :
381 : 0 : mbuf_pay->next = NULL;
382 : 0 : mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
383 : 0 : mbuf_pay->nb_segs = 1;
384 : 0 : mbuf_pay->port = rxq->port_id;
385 : 0 : mbuf->next = mbuf_pay;
386 : :
387 : 0 : desc->read.hdr_addr = dma_addr;
388 : 0 : desc->read.pkt_addr =
389 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf_pay));
390 : : }
391 : :
392 : : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
393 : 0 : desc->read.rsvd1 = 0;
394 : 0 : desc->read.rsvd2 = 0;
395 : : #endif
396 : : }
397 : :
398 : 0 : ret = 0;
399 : 0 : goto l_end;
400 : :
401 : 0 : l_err_free_mbuf:
402 [ # # ]: 0 : for (j = 0; j <= i; j++) {
403 [ # # # # ]: 0 : if (buf_ring[j] != NULL && buf_ring[j]->next != NULL) {
404 : 0 : rte_pktmbuf_free(buf_ring[j]->next);
405 : 0 : buf_ring[j]->next = NULL;
406 : : }
407 : :
408 [ # # ]: 0 : if (buf_ring[j] != NULL) {
409 : 0 : rte_pktmbuf_free(buf_ring[j]);
410 : 0 : buf_ring[j] = NULL;
411 : : }
412 : : }
413 : :
414 : 0 : l_end:
415 : 0 : return ret;
416 : : }
417 : :
418 : 0 : int32_t __rte_cold sxe2_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
419 : : {
420 : 0 : struct sxe2_rx_queue *rxq;
421 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
422 : 0 : int32_t ret;
423 : 0 : PMD_INIT_FUNC_TRACE();
424 : :
425 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
426 [ # # ]: 0 : if (rxq == NULL) {
427 : 0 : PMD_LOG_ERR(RX, "Rx queue %u is not available or setup",
428 : : rx_queue_id);
429 : 0 : ret = -EINVAL;
430 : 0 : goto l_end;
431 : : }
432 : :
433 [ # # ]: 0 : if (dev->data->rx_queue_state[rx_queue_id] ==
434 : : RTE_ETH_QUEUE_STATE_STARTED) {
435 : 0 : ret = 0;
436 : 0 : goto l_end;
437 : : }
438 : :
439 : 0 : ret = sxe2_rx_queue_mbufs_alloc(rxq);
440 [ # # ]: 0 : if (ret) {
441 : 0 : PMD_LOG_ERR(RX, "Rx queue %u apply desc ring fail",
442 : : rx_queue_id);
443 : 0 : ret = -ENOMEM;
444 : 0 : goto l_end;
445 : : }
446 : :
447 : 0 : sxe2_rx_head_tail_init(adapter, rxq);
448 : :
449 : 0 : ret = sxe2_drv_rxq_ctxt_cfg(adapter, rxq, 1);
450 [ # # ]: 0 : if (ret) {
451 : 0 : PMD_LOG_ERR(RX, "Rx queue %u config ctxt fail, ret=%d",
452 : : rx_queue_id, ret);
453 : :
454 : 0 : (void)sxe2_drv_rxq_switch(adapter, rxq, false);
455 : 0 : rxq->ops.mbufs_release(rxq);
456 : 0 : rxq->ops.queue_reset(rxq);
457 : 0 : goto l_end;
458 : : }
459 : :
460 : 0 : SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, rxq->ring_depth - 1);
461 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
462 : :
463 : 0 : l_end:
464 : 0 : return ret;
465 : : }
466 : :
467 : 0 : int32_t __rte_cold sxe2_rxqs_all_start(struct rte_eth_dev *dev)
468 : : {
469 : 0 : struct rte_eth_dev_data *data = dev->data;
470 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
471 : 0 : struct sxe2_drv_vsi_fc_get_resp fc_resp = {0};
472 : 0 : struct sxe2_rx_queue *rxq;
473 : 0 : uint16_t nb_rxq;
474 : 0 : uint16_t nb_started_rxq;
475 : 0 : int32_t ret;
476 : 0 : PMD_INIT_FUNC_TRACE();
477 : :
478 [ # # ]: 0 : if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE) {
479 : 0 : ret = sxe2_drv_fc_state_get(adapter, &fc_resp);
480 [ # # ]: 0 : if (ret) {
481 : 0 : PMD_LOG_ERR(RX, "Failed to get fc state, ret=[%d]", ret);
482 : 0 : goto l_end;
483 : : }
484 : 0 : adapter->fc_state_ctx.cfg_state = fc_resp.fc_enable;
485 : 0 : adapter->fc_state_ctx.curr_state = adapter->fc_state_ctx.cfg_state;
486 : : }
487 : :
488 [ # # ]: 0 : for (nb_rxq = 0; nb_rxq < data->nb_rx_queues; nb_rxq++) {
489 : 0 : rxq = dev->data->rx_queues[nb_rxq];
490 [ # # # # ]: 0 : if (!rxq || rxq->rx_deferred_start)
491 : 0 : continue;
492 : :
493 : 0 : ret = sxe2_rx_queue_start(dev, nb_rxq);
494 [ # # ]: 0 : if (ret) {
495 : 0 : PMD_LOG_ERR(RX, "Fail to start rx queue %u", nb_rxq);
496 : 0 : goto l_free_started_queue;
497 : : }
498 : :
499 : 0 : rxq->sw_stats.pkts = 0;
500 : 0 : rxq->sw_stats.bytes = 0;
501 : 0 : rxq->sw_stats.drop_pkts = 0;
502 : 0 : rxq->sw_stats.drop_bytes = 0;
503 : 0 : rxq->sw_stats.unicast_pkts = 0;
504 : 0 : rxq->sw_stats.broadcast_pkts = 0;
505 : 0 : rxq->sw_stats.multicast_pkts = 0;
506 : : }
507 : 0 : ret = 0;
508 : 0 : goto l_end;
509 : :
510 : 0 : l_free_started_queue:
511 [ # # ]: 0 : for (nb_started_rxq = 0; nb_started_rxq <= nb_rxq; nb_started_rxq++)
512 : 0 : (void)sxe2_rx_queue_stop(dev, nb_started_rxq);
513 : 0 : l_end:
514 : 0 : return ret;
515 : : }
516 : :
517 : 0 : void __rte_cold sxe2_rxqs_all_stop(struct rte_eth_dev *dev)
518 : : {
519 : 0 : struct rte_eth_dev_data *data = dev->data;
520 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
521 : 0 : struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
522 : 0 : struct sxe2_stats *sw_stats_prev = &vsi->vsi_stats.vsi_sw_stats_prev;
523 : 0 : struct sxe2_rx_queue *rxq = NULL;
524 : 0 : int32_t ret;
525 : 0 : uint16_t nb_rxq;
526 : 0 : PMD_INIT_FUNC_TRACE();
527 : :
528 [ # # ]: 0 : for (nb_rxq = 0; nb_rxq < data->nb_rx_queues; nb_rxq++) {
529 : 0 : ret = sxe2_rx_queue_stop(dev, nb_rxq);
530 [ # # ]: 0 : if (ret) {
531 : 0 : PMD_LOG_ERR(RX, "Fail to stop rx queue %u", nb_rxq);
532 : 0 : continue;
533 : : }
534 : :
535 : 0 : rxq = dev->data->rx_queues[nb_rxq];
536 [ # # ]: 0 : if (rxq) {
537 : 0 : sw_stats_prev->ipackets += rxq->sw_stats.pkts;
538 : 0 : sw_stats_prev->ierrors += rxq->sw_stats.drop_pkts;
539 : 0 : sw_stats_prev->ibytes += rxq->sw_stats.bytes;
540 : :
541 : 0 : sw_stats_prev->rx_sw_unicast_packets += rxq->sw_stats.unicast_pkts;
542 : 0 : sw_stats_prev->rx_sw_broadcast_packets += rxq->sw_stats.broadcast_pkts;
543 : 0 : sw_stats_prev->rx_sw_multicast_packets += rxq->sw_stats.multicast_pkts;
544 : 0 : sw_stats_prev->rx_sw_drop_packets += rxq->sw_stats.drop_pkts;
545 : 0 : sw_stats_prev->rx_sw_drop_bytes += rxq->sw_stats.drop_bytes;
546 : : }
547 : : }
548 : 0 : }
549 : :
550 : 0 : static int32_t sxe2_monitor_callback(const uint64_t value,
551 : : const uint64_t arg[RTE_POWER_MONITOR_OPAQUE_SZ] __rte_unused)
552 : : {
553 : 0 : const uint64_t dd_state = rte_cpu_to_le_64(SXE2_RX_DESC_STATUS_DD_MASK);
554 [ # # ]: 0 : return (value & dd_state) == dd_state ? -1 : 0;
555 : : }
556 : :
557 : 0 : int32_t sxe2_get_monitor_addr(void *rx_queue, struct rte_power_monitor_cond *pmc)
558 : : {
559 : 0 : volatile union sxe2_rx_desc *rxdp;
560 : 0 : struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
561 : :
562 : 0 : rxdp = &rxq->desc_ring[rxq->processing_idx];
563 : :
564 : 0 : pmc->addr = &rxdp->wb.status_err_ptype_len;
565 : 0 : pmc->fn = sxe2_monitor_callback;
566 : 0 : pmc->size = sizeof(uint16_t);
567 : :
568 : 0 : return 0;
569 : : }
|