Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2022 Intel Corporation
3 : : */
4 : :
5 : : #include "gve_ethdev.h"
6 : : #include "base/gve_adminq.h"
7 : :
8 : : #define GVE_PKT_CONT_BIT_IS_SET(x) (GVE_RXF_PKT_CONT & (x))
9 : :
10 : : static inline void
11 : 0 : gve_rx_refill(struct gve_rx_queue *rxq)
12 : : {
13 : 0 : uint16_t mask = rxq->nb_rx_desc - 1;
14 : 0 : uint16_t idx = rxq->next_avail & mask;
15 : : uint32_t next_avail = rxq->next_avail;
16 : : uint16_t nb_alloc, i;
17 : : struct rte_mbuf *nmb;
18 : : int diag;
19 : :
20 : : /* wrap around */
21 : 0 : nb_alloc = rxq->nb_rx_desc - idx;
22 [ # # ]: 0 : if (nb_alloc <= rxq->nb_avail) {
23 : 0 : diag = rte_pktmbuf_alloc_bulk(rxq->mpool, &rxq->sw_ring[idx], nb_alloc);
24 [ # # ]: 0 : if (diag < 0) {
25 : 0 : rxq->stats.no_mbufs_bulk++;
26 [ # # ]: 0 : for (i = 0; i < nb_alloc; i++) {
27 : 0 : nmb = rte_pktmbuf_alloc(rxq->mpool);
28 [ # # ]: 0 : if (!nmb)
29 : : break;
30 : 0 : rxq->sw_ring[idx + i] = nmb;
31 : : }
32 [ # # ]: 0 : if (i != nb_alloc) {
33 : 0 : rxq->stats.no_mbufs += nb_alloc - i;
34 : : nb_alloc = i;
35 : : }
36 : : }
37 : 0 : rxq->nb_avail -= nb_alloc;
38 : 0 : next_avail += nb_alloc;
39 : :
40 : : /* queue page list mode doesn't need real refill. */
41 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
42 : 0 : idx += nb_alloc;
43 : : } else {
44 [ # # ]: 0 : for (i = 0; i < nb_alloc; i++) {
45 : 0 : nmb = rxq->sw_ring[idx];
46 : 0 : rxq->rx_data_ring[idx].addr =
47 : : rte_cpu_to_be_64(rte_mbuf_data_iova(nmb));
48 : 0 : idx++;
49 : : }
50 : : }
51 [ # # ]: 0 : if (idx == rxq->nb_rx_desc)
52 : : idx = 0;
53 : : }
54 : :
55 [ # # ]: 0 : if (rxq->nb_avail > 0) {
56 : 0 : nb_alloc = rxq->nb_avail;
57 [ # # ]: 0 : if (rxq->nb_rx_desc < idx + rxq->nb_avail)
58 : 0 : nb_alloc = rxq->nb_rx_desc - idx;
59 : 0 : diag = rte_pktmbuf_alloc_bulk(rxq->mpool, &rxq->sw_ring[idx], nb_alloc);
60 [ # # ]: 0 : if (diag < 0) {
61 : 0 : rxq->stats.no_mbufs_bulk++;
62 [ # # ]: 0 : for (i = 0; i < nb_alloc; i++) {
63 : 0 : nmb = rte_pktmbuf_alloc(rxq->mpool);
64 [ # # ]: 0 : if (!nmb)
65 : : break;
66 : 0 : rxq->sw_ring[idx + i] = nmb;
67 : : }
68 [ # # ]: 0 : if (i != nb_alloc) {
69 : 0 : rxq->stats.no_mbufs += nb_alloc - i;
70 : : nb_alloc = i;
71 : : }
72 : : }
73 : 0 : rxq->nb_avail -= nb_alloc;
74 : 0 : next_avail += nb_alloc;
75 : :
76 [ # # ]: 0 : if (!rxq->is_gqi_qpl) {
77 [ # # ]: 0 : for (i = 0; i < nb_alloc; i++) {
78 : 0 : nmb = rxq->sw_ring[idx];
79 : 0 : rxq->rx_data_ring[idx].addr =
80 : : rte_cpu_to_be_64(rte_mbuf_data_iova(nmb));
81 : 0 : idx++;
82 : : }
83 : : }
84 : : }
85 : :
86 [ # # ]: 0 : if (next_avail != rxq->next_avail) {
87 [ # # ]: 0 : rte_write32(rte_cpu_to_be_32(next_avail), rxq->qrx_tail);
88 : 0 : rxq->next_avail = next_avail;
89 : : }
90 : 0 : }
91 : :
92 : : /*
93 : : * This method processes a single rte_mbuf and handles packet segmentation
94 : : * In QPL mode it copies data from the mbuf to the gve_rx_queue.
95 : : */
96 : : static void
97 : 0 : gve_rx_mbuf(struct gve_rx_queue *rxq, struct rte_mbuf *rxe, uint16_t len,
98 : : uint16_t rx_id)
99 : : {
100 : : uint16_t padding = 0;
101 : : uint64_t addr;
102 : :
103 : 0 : rxe->data_len = len;
104 [ # # ]: 0 : if (!rxq->ctx.mbuf_head) {
105 : 0 : rxq->ctx.mbuf_head = rxe;
106 : 0 : rxq->ctx.mbuf_tail = rxe;
107 : 0 : rxe->nb_segs = 1;
108 : 0 : rxe->pkt_len = len;
109 : 0 : rxe->data_len = len;
110 : 0 : rxe->port = rxq->port_id;
111 : 0 : rxe->ol_flags = 0;
112 : : padding = GVE_RX_PAD;
113 : : } else {
114 : 0 : rxq->ctx.mbuf_head->pkt_len += len;
115 : 0 : rxq->ctx.mbuf_head->nb_segs += 1;
116 : 0 : rxq->ctx.mbuf_tail->next = rxe;
117 : 0 : rxq->ctx.mbuf_tail = rxe;
118 : : }
119 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
120 : 0 : addr = (uint64_t)rxq->qpl->qpl_bufs[rx_id] + padding;
121 [ # # ]: 0 : rte_memcpy((void *)((size_t)rxe->buf_addr + rxe->data_off),
122 : : (void *)(size_t)addr, len);
123 : : }
124 : 0 : }
125 : :
126 : : /*
127 : : * This method processes a single packet fragment associated with the
128 : : * passed packet descriptor.
129 : : * This methods returns whether the fragment is the last fragment
130 : : * of a packet.
131 : : */
132 : : static bool
133 : 0 : gve_rx(struct gve_rx_queue *rxq, volatile struct gve_rx_desc *rxd, uint16_t rx_id)
134 : : {
135 : 0 : bool is_last_frag = !GVE_PKT_CONT_BIT_IS_SET(rxd->flags_seq);
136 : 0 : uint16_t frag_size = rte_be_to_cpu_16(rxd->len);
137 : : struct gve_rx_ctx *ctx = &rxq->ctx;
138 : 0 : bool is_first_frag = ctx->total_frags == 0;
139 : : struct rte_mbuf *rxe;
140 : :
141 [ # # ]: 0 : if (ctx->drop_pkt)
142 : 0 : goto finish_frag;
143 : :
144 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_ERR) {
145 : 0 : ctx->drop_pkt = true;
146 : 0 : rxq->stats.errors++;
147 : 0 : goto finish_frag;
148 : : }
149 : :
150 [ # # ]: 0 : if (is_first_frag)
151 : 0 : frag_size -= GVE_RX_PAD;
152 : :
153 : 0 : rxe = rxq->sw_ring[rx_id];
154 : 0 : gve_rx_mbuf(rxq, rxe, frag_size, rx_id);
155 : 0 : rxq->sw_ring[rx_id] = NULL;
156 : 0 : rxq->stats.bytes += frag_size;
157 : :
158 [ # # ]: 0 : if (is_first_frag) {
159 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_TCP)
160 : 0 : rxe->packet_type |= RTE_PTYPE_L4_TCP;
161 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_UDP)
162 : 0 : rxe->packet_type |= RTE_PTYPE_L4_UDP;
163 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_IPV4)
164 : 0 : rxe->packet_type |= RTE_PTYPE_L3_IPV4;
165 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_IPV6)
166 : 0 : rxe->packet_type |= RTE_PTYPE_L3_IPV6;
167 : :
168 [ # # ]: 0 : if (gve_needs_rss(rxd->flags_seq)) {
169 : 0 : rxe->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
170 : 0 : rxe->hash.rss = rte_be_to_cpu_32(rxd->rss_hash);
171 : : }
172 : : }
173 : :
174 : 0 : finish_frag:
175 : 0 : ctx->total_frags++;
176 : 0 : return is_last_frag;
177 : : }
178 : :
179 : : static void
180 : : gve_rx_ctx_clear(struct gve_rx_ctx *ctx)
181 : : {
182 : 0 : ctx->mbuf_head = NULL;
183 : 0 : ctx->mbuf_tail = NULL;
184 : 0 : ctx->drop_pkt = false;
185 : 0 : ctx->total_frags = 0;
186 : 0 : }
187 : :
188 : : uint16_t
189 : 0 : gve_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
190 : : {
191 : : volatile struct gve_rx_desc *rxr, *rxd;
192 : : struct gve_rx_queue *rxq = rx_queue;
193 : : struct gve_rx_ctx *ctx = &rxq->ctx;
194 : 0 : uint16_t rx_id = rxq->rx_tail;
195 : : uint16_t nb_rx;
196 : :
197 : 0 : rxr = rxq->rx_desc_ring;
198 : : nb_rx = 0;
199 : :
200 [ # # ]: 0 : while (nb_rx < nb_pkts) {
201 : 0 : rxd = &rxr[rx_id];
202 [ # # ]: 0 : if (GVE_SEQNO(rxd->flags_seq) != rxq->expected_seqno)
203 : : break;
204 : :
205 [ # # ]: 0 : if (gve_rx(rxq, rxd, rx_id)) {
206 [ # # ]: 0 : if (!ctx->drop_pkt)
207 : 0 : rx_pkts[nb_rx++] = ctx->mbuf_head;
208 [ # # ]: 0 : else if (ctx->mbuf_head != NULL)
209 : 0 : rte_pktmbuf_free(ctx->mbuf_head);
210 : 0 : rxq->nb_avail += ctx->total_frags;
211 : : gve_rx_ctx_clear(ctx);
212 : : }
213 : :
214 : 0 : rx_id++;
215 [ # # ]: 0 : if (rx_id == rxq->nb_rx_desc)
216 : : rx_id = 0;
217 : :
218 [ # # ]: 0 : rxq->expected_seqno = gve_next_seqno(rxq->expected_seqno);
219 : : }
220 : :
221 : 0 : rxq->rx_tail = rx_id;
222 : :
223 [ # # ]: 0 : if (rxq->nb_avail > rxq->free_thresh)
224 : 0 : gve_rx_refill(rxq);
225 : :
226 [ # # ]: 0 : if (nb_rx)
227 : 0 : rxq->stats.packets += nb_rx;
228 : :
229 : 0 : return nb_rx;
230 : : }
231 : :
232 : : static inline void
233 : 0 : gve_reset_rxq(struct gve_rx_queue *rxq)
234 : : {
235 : : struct rte_mbuf **sw_ring;
236 : : uint32_t size, i;
237 : :
238 [ # # ]: 0 : if (rxq == NULL) {
239 : 0 : PMD_DRV_LOG(ERR, "pointer to rxq is NULL");
240 : 0 : return;
241 : : }
242 : :
243 : 0 : size = rxq->nb_rx_desc * sizeof(struct gve_rx_desc);
244 [ # # ]: 0 : for (i = 0; i < size; i++)
245 : 0 : ((volatile char *)rxq->rx_desc_ring)[i] = 0;
246 : :
247 : 0 : size = rxq->nb_rx_desc * sizeof(union gve_rx_data_slot);
248 [ # # ]: 0 : for (i = 0; i < size; i++)
249 : 0 : ((volatile char *)rxq->rx_data_ring)[i] = 0;
250 : :
251 : 0 : sw_ring = rxq->sw_ring;
252 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++)
253 : 0 : sw_ring[i] = NULL;
254 : :
255 : 0 : rxq->rx_tail = 0;
256 : 0 : rxq->next_avail = 0;
257 : 0 : rxq->nb_avail = rxq->nb_rx_desc;
258 : 0 : rxq->expected_seqno = 1;
259 : : }
260 : :
261 : : static inline void
262 : 0 : gve_release_rxq_mbufs(struct gve_rx_queue *rxq)
263 : : {
264 : : uint16_t i;
265 : :
266 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
267 [ # # ]: 0 : if (rxq->sw_ring[i]) {
268 : : rte_pktmbuf_free_seg(rxq->sw_ring[i]);
269 : 0 : rxq->sw_ring[i] = NULL;
270 : : }
271 : : }
272 : :
273 : 0 : rxq->nb_avail = rxq->nb_rx_desc;
274 : 0 : }
275 : :
276 : : void
277 : 0 : gve_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
278 : : {
279 : 0 : struct gve_rx_queue *q = dev->data->rx_queues[qid];
280 : :
281 [ # # ]: 0 : if (!q)
282 : : return;
283 : :
284 [ # # ]: 0 : if (q->is_gqi_qpl) {
285 : 0 : gve_teardown_queue_page_list(q->hw, q->qpl);
286 : 0 : q->qpl = NULL;
287 : : }
288 : :
289 : 0 : gve_release_rxq_mbufs(q);
290 : 0 : rte_free(q->sw_ring);
291 : 0 : rte_memzone_free(q->data_mz);
292 : 0 : rte_memzone_free(q->mz);
293 : 0 : rte_memzone_free(q->qres_mz);
294 : 0 : q->qres = NULL;
295 : 0 : rte_free(q);
296 : :
297 : 0 : dev->data->rx_queues[qid] = NULL;
298 : : }
299 : :
300 : : int
301 : 0 : gve_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
302 : : uint16_t nb_desc, unsigned int socket_id,
303 : : const struct rte_eth_rxconf *conf, struct rte_mempool *pool)
304 : : {
305 : 0 : struct gve_priv *hw = dev->data->dev_private;
306 : : const struct rte_memzone *mz;
307 : : struct gve_rx_queue *rxq;
308 : : uint16_t free_thresh;
309 : : uint32_t mbuf_len;
310 : : int err = 0;
311 : :
312 : : /* Ring size is required to be a power of two. */
313 [ # # ]: 0 : if (!rte_is_power_of_2(nb_desc)) {
314 : 0 : PMD_DRV_LOG(ERR, "Invalid ring size %u. GVE ring size must be a power of 2.",
315 : : nb_desc);
316 : 0 : return -EINVAL;
317 : : }
318 : :
319 : : /* Free memory if needed. */
320 [ # # ]: 0 : if (dev->data->rx_queues[queue_id]) {
321 : 0 : gve_rx_queue_release(dev, queue_id);
322 : 0 : dev->data->rx_queues[queue_id] = NULL;
323 : : }
324 : :
325 : : /* Allocate the RX queue data structure. */
326 : 0 : rxq = rte_zmalloc_socket("gve rxq",
327 : : sizeof(struct gve_rx_queue),
328 : : RTE_CACHE_LINE_SIZE,
329 : : socket_id);
330 [ # # ]: 0 : if (!rxq) {
331 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for rx queue structure");
332 : : err = -ENOMEM;
333 : 0 : goto err_rxq;
334 : : }
335 : :
336 [ # # ]: 0 : free_thresh = conf->rx_free_thresh ? conf->rx_free_thresh : GVE_DEFAULT_RX_FREE_THRESH;
337 [ # # ]: 0 : if (free_thresh >= nb_desc) {
338 : 0 : PMD_DRV_LOG(ERR, "rx_free_thresh (%u) must be less than nb_desc (%u) minus 3.",
339 : : free_thresh, rxq->nb_rx_desc);
340 : : err = -EINVAL;
341 : 0 : goto err_rxq;
342 : : }
343 : :
344 : 0 : rxq->nb_rx_desc = nb_desc;
345 : 0 : rxq->free_thresh = free_thresh;
346 : 0 : rxq->queue_id = queue_id;
347 : 0 : rxq->port_id = dev->data->port_id;
348 : 0 : rxq->ntfy_id = hw->num_ntfy_blks / 2 + queue_id;
349 : 0 : rxq->is_gqi_qpl = hw->queue_format == GVE_GQI_QPL_FORMAT;
350 : 0 : rxq->mpool = pool;
351 : 0 : rxq->hw = hw;
352 [ # # # # ]: 0 : rxq->ntfy_addr = &hw->db_bar2[rte_be_to_cpu_32(hw->irq_dbs[rxq->ntfy_id].id)];
353 : :
354 : 0 : mbuf_len =
355 : 0 : rte_pktmbuf_data_room_size(rxq->mpool) - RTE_PKTMBUF_HEADROOM;
356 : 0 : rxq->rx_buf_len =
357 : 0 : RTE_MIN((uint16_t)GVE_RX_MAX_BUF_SIZE_GQI,
358 : : RTE_ALIGN_FLOOR(mbuf_len, GVE_RX_BUF_ALIGN_GQI));
359 : :
360 : : /* Allocate software ring */
361 : 0 : rxq->sw_ring = rte_zmalloc_socket("gve rx sw ring", sizeof(struct rte_mbuf *) * nb_desc,
362 : : RTE_CACHE_LINE_SIZE, socket_id);
363 [ # # ]: 0 : if (!rxq->sw_ring) {
364 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for SW RX ring");
365 : : err = -ENOMEM;
366 : 0 : goto err_rxq;
367 : : }
368 : :
369 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
370 : : nb_desc * sizeof(struct gve_rx_desc),
371 : : PAGE_SIZE, socket_id);
372 [ # # ]: 0 : if (mz == NULL) {
373 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX");
374 : : err = -ENOMEM;
375 : 0 : goto err_sw_ring;
376 : : }
377 : 0 : rxq->rx_desc_ring = (struct gve_rx_desc *)mz->addr;
378 : 0 : rxq->rx_ring_phys_addr = mz->iova;
379 : 0 : rxq->mz = mz;
380 : :
381 : 0 : mz = rte_eth_dma_zone_reserve(dev, "gve rx data ring", queue_id,
382 : : sizeof(union gve_rx_data_slot) * nb_desc,
383 : : PAGE_SIZE, socket_id);
384 [ # # ]: 0 : if (mz == NULL) {
385 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for RX data ring");
386 : : err = -ENOMEM;
387 : 0 : goto err_rx_ring;
388 : : }
389 : 0 : rxq->rx_data_ring = (union gve_rx_data_slot *)mz->addr;
390 : 0 : rxq->data_mz = mz;
391 : :
392 : : /* Allocate and register QPL for the queue. */
393 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
394 : 0 : rxq->qpl = gve_setup_queue_page_list(hw, queue_id, true,
395 : : nb_desc);
396 [ # # ]: 0 : if (!rxq->qpl) {
397 : : err = -ENOMEM;
398 : 0 : PMD_DRV_LOG(ERR,
399 : : "Failed to alloc rx qpl for queue %hu.",
400 : : queue_id);
401 : 0 : goto err_data_ring;
402 : : }
403 : : }
404 : :
405 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rxq_res", queue_id,
406 : : sizeof(struct gve_queue_resources),
407 : : PAGE_SIZE, socket_id);
408 [ # # ]: 0 : if (mz == NULL) {
409 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX resource");
410 : : err = -ENOMEM;
411 : 0 : goto err_qpl;
412 : : }
413 : 0 : rxq->qres = (struct gve_queue_resources *)mz->addr;
414 : 0 : rxq->qres_mz = mz;
415 : :
416 : 0 : gve_reset_rxq(rxq);
417 : :
418 : 0 : dev->data->rx_queues[queue_id] = rxq;
419 : :
420 : 0 : return 0;
421 : : err_qpl:
422 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
423 : 0 : gve_teardown_queue_page_list(hw, rxq->qpl);
424 : 0 : rxq->qpl = NULL;
425 : : }
426 : 0 : err_data_ring:
427 : 0 : rte_memzone_free(rxq->data_mz);
428 : 0 : err_rx_ring:
429 : 0 : rte_memzone_free(rxq->mz);
430 : 0 : err_sw_ring:
431 : 0 : rte_free(rxq->sw_ring);
432 : 0 : err_rxq:
433 : 0 : rte_free(rxq);
434 : 0 : return err;
435 : : }
436 : :
437 : : static int
438 : 0 : gve_rxq_mbufs_alloc(struct gve_rx_queue *rxq)
439 : : {
440 : : struct rte_mbuf *nmb;
441 : : uint16_t i;
442 : : int diag;
443 : :
444 : 0 : diag = rte_pktmbuf_alloc_bulk(rxq->mpool, &rxq->sw_ring[0], rxq->nb_rx_desc);
445 [ # # ]: 0 : if (diag < 0) {
446 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc - 1; i++) {
447 : 0 : nmb = rte_pktmbuf_alloc(rxq->mpool);
448 [ # # ]: 0 : if (!nmb)
449 : : break;
450 : 0 : rxq->sw_ring[i] = nmb;
451 : : }
452 [ # # ]: 0 : if (i < rxq->nb_rx_desc - 1)
453 : : return -ENOMEM;
454 : : }
455 : 0 : rxq->nb_avail = 0;
456 : 0 : rxq->next_avail = rxq->nb_rx_desc - 1;
457 : :
458 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
459 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
460 [ # # ]: 0 : rxq->rx_data_ring[i].addr = rte_cpu_to_be_64(i * PAGE_SIZE);
461 : : } else {
462 [ # # ]: 0 : if (i == rxq->nb_rx_desc - 1)
463 : : break;
464 : 0 : nmb = rxq->sw_ring[i];
465 : 0 : rxq->rx_data_ring[i].addr = rte_cpu_to_be_64(rte_mbuf_data_iova(nmb));
466 : : }
467 : : }
468 : :
469 [ # # ]: 0 : rte_write32(rte_cpu_to_be_32(rxq->next_avail), rxq->qrx_tail);
470 : :
471 : 0 : return 0;
472 : : }
473 : :
474 : : int
475 : 0 : gve_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
476 : : {
477 : 0 : struct gve_priv *hw = dev->data->dev_private;
478 : : struct gve_rx_queue *rxq;
479 : : int ret;
480 : :
481 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
482 : : return -EINVAL;
483 : :
484 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
485 : :
486 [ # # ]: 0 : rxq->qrx_tail = &hw->db_bar2[rte_be_to_cpu_32(rxq->qres->db_index)];
487 : :
488 : 0 : rte_write32(rte_cpu_to_be_32(GVE_IRQ_MASK), rxq->ntfy_addr);
489 : :
490 : 0 : ret = gve_rxq_mbufs_alloc(rxq);
491 [ # # ]: 0 : if (ret != 0) {
492 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc Rx queue mbuf");
493 : 0 : return ret;
494 : : }
495 : :
496 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
497 : :
498 : 0 : return 0;
499 : : }
500 : :
501 : : int
502 : 0 : gve_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
503 : : {
504 : : struct gve_rx_queue *rxq;
505 : :
506 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
507 : : return -EINVAL;
508 : :
509 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
510 : 0 : gve_release_rxq_mbufs(rxq);
511 : 0 : gve_reset_rxq(rxq);
512 : :
513 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
514 : :
515 : 0 : return 0;
516 : : }
517 : :
518 : : void
519 : 0 : gve_stop_rx_queues(struct rte_eth_dev *dev)
520 : : {
521 [ # # ]: 0 : struct gve_priv *hw = dev->data->dev_private;
522 : : uint16_t i;
523 : : int err;
524 : :
525 [ # # ]: 0 : if (!gve_is_gqi(hw))
526 : 0 : return gve_stop_rx_queues_dqo(dev);
527 : :
528 : 0 : err = gve_adminq_destroy_rx_queues(hw, dev->data->nb_rx_queues);
529 [ # # ]: 0 : if (err != 0)
530 : 0 : PMD_DRV_LOG(WARNING, "failed to destroy rxqs");
531 : :
532 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
533 [ # # ]: 0 : if (gve_rx_queue_stop(dev, i) != 0)
534 : 0 : PMD_DRV_LOG(WARNING, "Fail to stop Rx queue %d", i);
535 : : }
536 : :
537 : : void
538 : 0 : gve_set_rx_function(struct rte_eth_dev *dev)
539 : : {
540 : 0 : dev->rx_pkt_burst = gve_rx_burst;
541 : 0 : }
|