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->mz->addr) + rx_id * PAGE_SIZE + 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->stats.bytes += frag_size;
156 : :
157 [ # # ]: 0 : if (is_first_frag) {
158 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_TCP)
159 : 0 : rxe->packet_type |= RTE_PTYPE_L4_TCP;
160 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_UDP)
161 : 0 : rxe->packet_type |= RTE_PTYPE_L4_UDP;
162 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_IPV4)
163 : 0 : rxe->packet_type |= RTE_PTYPE_L3_IPV4;
164 [ # # ]: 0 : if (rxd->flags_seq & GVE_RXF_IPV6)
165 : 0 : rxe->packet_type |= RTE_PTYPE_L3_IPV6;
166 : :
167 [ # # ]: 0 : if (gve_needs_rss(rxd->flags_seq)) {
168 : 0 : rxe->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
169 : 0 : rxe->hash.rss = rte_be_to_cpu_32(rxd->rss_hash);
170 : : }
171 : : }
172 : :
173 : 0 : finish_frag:
174 : 0 : ctx->total_frags++;
175 : 0 : return is_last_frag;
176 : : }
177 : :
178 : : static void
179 : : gve_rx_ctx_clear(struct gve_rx_ctx *ctx)
180 : : {
181 : 0 : ctx->mbuf_head = NULL;
182 : 0 : ctx->mbuf_tail = NULL;
183 : 0 : ctx->drop_pkt = false;
184 : 0 : ctx->total_frags = 0;
185 : 0 : }
186 : :
187 : : uint16_t
188 : 0 : gve_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
189 : : {
190 : : volatile struct gve_rx_desc *rxr, *rxd;
191 : : struct gve_rx_queue *rxq = rx_queue;
192 : : struct gve_rx_ctx *ctx = &rxq->ctx;
193 : 0 : uint16_t rx_id = rxq->rx_tail;
194 : : uint16_t nb_rx;
195 : :
196 : 0 : rxr = rxq->rx_desc_ring;
197 : : nb_rx = 0;
198 : :
199 [ # # ]: 0 : while (nb_rx < nb_pkts) {
200 : 0 : rxd = &rxr[rx_id];
201 [ # # ]: 0 : if (GVE_SEQNO(rxd->flags_seq) != rxq->expected_seqno)
202 : : break;
203 : :
204 [ # # ]: 0 : if (gve_rx(rxq, rxd, rx_id)) {
205 [ # # ]: 0 : if (!ctx->drop_pkt)
206 : 0 : rx_pkts[nb_rx++] = ctx->mbuf_head;
207 : 0 : rxq->nb_avail += ctx->total_frags;
208 : : gve_rx_ctx_clear(ctx);
209 : : }
210 : :
211 : 0 : rx_id++;
212 [ # # ]: 0 : if (rx_id == rxq->nb_rx_desc)
213 : : rx_id = 0;
214 : :
215 [ # # ]: 0 : rxq->expected_seqno = gve_next_seqno(rxq->expected_seqno);
216 : : }
217 : :
218 : 0 : rxq->rx_tail = rx_id;
219 : :
220 [ # # ]: 0 : if (rxq->nb_avail > rxq->free_thresh)
221 : 0 : gve_rx_refill(rxq);
222 : :
223 [ # # ]: 0 : if (nb_rx)
224 : 0 : rxq->stats.packets += nb_rx;
225 : :
226 : 0 : return nb_rx;
227 : : }
228 : :
229 : : static inline void
230 : 0 : gve_reset_rxq(struct gve_rx_queue *rxq)
231 : : {
232 : : struct rte_mbuf **sw_ring;
233 : : uint32_t size, i;
234 : :
235 [ # # ]: 0 : if (rxq == NULL) {
236 : 0 : PMD_DRV_LOG(ERR, "pointer to rxq is NULL");
237 : 0 : return;
238 : : }
239 : :
240 : 0 : size = rxq->nb_rx_desc * sizeof(struct gve_rx_desc);
241 [ # # ]: 0 : for (i = 0; i < size; i++)
242 : 0 : ((volatile char *)rxq->rx_desc_ring)[i] = 0;
243 : :
244 : 0 : size = rxq->nb_rx_desc * sizeof(union gve_rx_data_slot);
245 [ # # ]: 0 : for (i = 0; i < size; i++)
246 : 0 : ((volatile char *)rxq->rx_data_ring)[i] = 0;
247 : :
248 : 0 : sw_ring = rxq->sw_ring;
249 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++)
250 : 0 : sw_ring[i] = NULL;
251 : :
252 : 0 : rxq->rx_tail = 0;
253 : 0 : rxq->next_avail = 0;
254 : 0 : rxq->nb_avail = rxq->nb_rx_desc;
255 : 0 : rxq->expected_seqno = 1;
256 : : }
257 : :
258 : : static inline void
259 : 0 : gve_release_rxq_mbufs(struct gve_rx_queue *rxq)
260 : : {
261 : : uint16_t i;
262 : :
263 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
264 [ # # ]: 0 : if (rxq->sw_ring[i]) {
265 : : rte_pktmbuf_free_seg(rxq->sw_ring[i]);
266 : 0 : rxq->sw_ring[i] = NULL;
267 : : }
268 : : }
269 : :
270 : 0 : rxq->nb_avail = rxq->nb_rx_desc;
271 : 0 : }
272 : :
273 : : void
274 : 0 : gve_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
275 : : {
276 : 0 : struct gve_rx_queue *q = dev->data->rx_queues[qid];
277 : :
278 [ # # ]: 0 : if (!q)
279 : : return;
280 : :
281 [ # # ]: 0 : if (q->is_gqi_qpl) {
282 : 0 : gve_adminq_unregister_page_list(q->hw, q->qpl->id);
283 : 0 : q->qpl = NULL;
284 : : }
285 : :
286 : 0 : gve_release_rxq_mbufs(q);
287 : 0 : rte_free(q->sw_ring);
288 : 0 : rte_memzone_free(q->data_mz);
289 : 0 : rte_memzone_free(q->mz);
290 : 0 : rte_memzone_free(q->qres_mz);
291 : 0 : q->qres = NULL;
292 : 0 : rte_free(q);
293 : : }
294 : :
295 : : int
296 : 0 : gve_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
297 : : uint16_t nb_desc, unsigned int socket_id,
298 : : const struct rte_eth_rxconf *conf, struct rte_mempool *pool)
299 : : {
300 : 0 : struct gve_priv *hw = dev->data->dev_private;
301 : : const struct rte_memzone *mz;
302 : : struct gve_rx_queue *rxq;
303 : : uint16_t free_thresh;
304 : : uint32_t mbuf_len;
305 : : int err = 0;
306 : :
307 [ # # ]: 0 : if (nb_desc != hw->rx_desc_cnt) {
308 : 0 : PMD_DRV_LOG(WARNING, "gve doesn't support nb_desc config, use hw nb_desc %u.",
309 : : hw->rx_desc_cnt);
310 : : }
311 : 0 : nb_desc = hw->rx_desc_cnt;
312 : :
313 : : /* Free memory if needed. */
314 [ # # ]: 0 : if (dev->data->rx_queues[queue_id]) {
315 : 0 : gve_rx_queue_release(dev, queue_id);
316 : 0 : dev->data->rx_queues[queue_id] = NULL;
317 : : }
318 : :
319 : : /* Allocate the RX queue data structure. */
320 : 0 : rxq = rte_zmalloc_socket("gve rxq",
321 : : sizeof(struct gve_rx_queue),
322 : : RTE_CACHE_LINE_SIZE,
323 : : socket_id);
324 [ # # ]: 0 : if (!rxq) {
325 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for rx queue structure");
326 : : err = -ENOMEM;
327 : 0 : goto err_rxq;
328 : : }
329 : :
330 [ # # ]: 0 : free_thresh = conf->rx_free_thresh ? conf->rx_free_thresh : GVE_DEFAULT_RX_FREE_THRESH;
331 [ # # ]: 0 : if (free_thresh >= nb_desc) {
332 : 0 : PMD_DRV_LOG(ERR, "rx_free_thresh (%u) must be less than nb_desc (%u) minus 3.",
333 : : free_thresh, rxq->nb_rx_desc);
334 : : err = -EINVAL;
335 : 0 : goto err_rxq;
336 : : }
337 : :
338 : 0 : rxq->nb_rx_desc = nb_desc;
339 : 0 : rxq->free_thresh = free_thresh;
340 : 0 : rxq->queue_id = queue_id;
341 : 0 : rxq->port_id = dev->data->port_id;
342 : 0 : rxq->ntfy_id = hw->num_ntfy_blks / 2 + queue_id;
343 : 0 : rxq->is_gqi_qpl = hw->queue_format == GVE_GQI_QPL_FORMAT;
344 : 0 : rxq->mpool = pool;
345 : 0 : rxq->hw = hw;
346 [ # # # # ]: 0 : rxq->ntfy_addr = &hw->db_bar2[rte_be_to_cpu_32(hw->irq_dbs[rxq->ntfy_id].id)];
347 : :
348 : 0 : mbuf_len =
349 : 0 : rte_pktmbuf_data_room_size(rxq->mpool) - RTE_PKTMBUF_HEADROOM;
350 : 0 : rxq->rx_buf_len =
351 : 0 : RTE_MIN((uint16_t)GVE_RX_MAX_BUF_SIZE_GQI,
352 : : RTE_ALIGN_FLOOR(mbuf_len, GVE_RX_BUF_ALIGN_GQI));
353 : :
354 : : /* Allocate software ring */
355 : 0 : rxq->sw_ring = rte_zmalloc_socket("gve rx sw ring", sizeof(struct rte_mbuf *) * nb_desc,
356 : : RTE_CACHE_LINE_SIZE, socket_id);
357 [ # # ]: 0 : if (!rxq->sw_ring) {
358 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for SW RX ring");
359 : : err = -ENOMEM;
360 : 0 : goto err_rxq;
361 : : }
362 : :
363 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
364 : : nb_desc * sizeof(struct gve_rx_desc),
365 : : PAGE_SIZE, socket_id);
366 [ # # ]: 0 : if (mz == NULL) {
367 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX");
368 : : err = -ENOMEM;
369 : 0 : goto err_sw_ring;
370 : : }
371 : 0 : rxq->rx_desc_ring = (struct gve_rx_desc *)mz->addr;
372 : 0 : rxq->rx_ring_phys_addr = mz->iova;
373 : 0 : rxq->mz = mz;
374 : :
375 : 0 : mz = rte_eth_dma_zone_reserve(dev, "gve rx data ring", queue_id,
376 : : sizeof(union gve_rx_data_slot) * nb_desc,
377 : : PAGE_SIZE, socket_id);
378 [ # # ]: 0 : if (mz == NULL) {
379 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for RX data ring");
380 : : err = -ENOMEM;
381 : 0 : goto err_rx_ring;
382 : : }
383 : 0 : rxq->rx_data_ring = (union gve_rx_data_slot *)mz->addr;
384 : 0 : rxq->data_mz = mz;
385 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
386 : 0 : rxq->qpl = &hw->qpl[rxq->ntfy_id];
387 : 0 : err = gve_adminq_register_page_list(hw, rxq->qpl);
388 [ # # ]: 0 : if (err != 0) {
389 : 0 : PMD_DRV_LOG(ERR, "Failed to register qpl %u", queue_id);
390 : 0 : goto err_data_ring;
391 : : }
392 : : }
393 : :
394 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rxq_res", queue_id,
395 : : sizeof(struct gve_queue_resources),
396 : : PAGE_SIZE, socket_id);
397 [ # # ]: 0 : if (mz == NULL) {
398 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX resource");
399 : : err = -ENOMEM;
400 : 0 : goto err_data_ring;
401 : : }
402 : 0 : rxq->qres = (struct gve_queue_resources *)mz->addr;
403 : 0 : rxq->qres_mz = mz;
404 : :
405 : 0 : gve_reset_rxq(rxq);
406 : :
407 : 0 : dev->data->rx_queues[queue_id] = rxq;
408 : :
409 : 0 : return 0;
410 : :
411 : 0 : err_data_ring:
412 : 0 : rte_memzone_free(rxq->data_mz);
413 : 0 : err_rx_ring:
414 : 0 : rte_memzone_free(rxq->mz);
415 : 0 : err_sw_ring:
416 : 0 : rte_free(rxq->sw_ring);
417 : 0 : err_rxq:
418 : 0 : rte_free(rxq);
419 : 0 : return err;
420 : : }
421 : :
422 : : static int
423 : 0 : gve_rxq_mbufs_alloc(struct gve_rx_queue *rxq)
424 : : {
425 : : struct rte_mbuf *nmb;
426 : : uint16_t i;
427 : : int diag;
428 : :
429 : 0 : diag = rte_pktmbuf_alloc_bulk(rxq->mpool, &rxq->sw_ring[0], rxq->nb_rx_desc);
430 [ # # ]: 0 : if (diag < 0) {
431 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc - 1; i++) {
432 : 0 : nmb = rte_pktmbuf_alloc(rxq->mpool);
433 [ # # ]: 0 : if (!nmb)
434 : : break;
435 : 0 : rxq->sw_ring[i] = nmb;
436 : : }
437 [ # # ]: 0 : if (i < rxq->nb_rx_desc - 1)
438 : : return -ENOMEM;
439 : : }
440 : 0 : rxq->nb_avail = 0;
441 : 0 : rxq->next_avail = rxq->nb_rx_desc - 1;
442 : :
443 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
444 [ # # ]: 0 : if (rxq->is_gqi_qpl) {
445 [ # # ]: 0 : rxq->rx_data_ring[i].addr = rte_cpu_to_be_64(i * PAGE_SIZE);
446 : : } else {
447 [ # # ]: 0 : if (i == rxq->nb_rx_desc - 1)
448 : : break;
449 : 0 : nmb = rxq->sw_ring[i];
450 : 0 : rxq->rx_data_ring[i].addr = rte_cpu_to_be_64(rte_mbuf_data_iova(nmb));
451 : : }
452 : : }
453 : :
454 [ # # ]: 0 : rte_write32(rte_cpu_to_be_32(rxq->next_avail), rxq->qrx_tail);
455 : :
456 : 0 : return 0;
457 : : }
458 : :
459 : : int
460 : 0 : gve_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
461 : : {
462 : 0 : struct gve_priv *hw = dev->data->dev_private;
463 : : struct gve_rx_queue *rxq;
464 : : int ret;
465 : :
466 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
467 : : return -EINVAL;
468 : :
469 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
470 : :
471 [ # # ]: 0 : rxq->qrx_tail = &hw->db_bar2[rte_be_to_cpu_32(rxq->qres->db_index)];
472 : :
473 : 0 : rte_write32(rte_cpu_to_be_32(GVE_IRQ_MASK), rxq->ntfy_addr);
474 : :
475 : 0 : ret = gve_rxq_mbufs_alloc(rxq);
476 [ # # ]: 0 : if (ret != 0) {
477 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc Rx queue mbuf");
478 : 0 : return ret;
479 : : }
480 : :
481 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
482 : :
483 : 0 : return 0;
484 : : }
485 : :
486 : : int
487 : 0 : gve_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
488 : : {
489 : : struct gve_rx_queue *rxq;
490 : :
491 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
492 : : return -EINVAL;
493 : :
494 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
495 : 0 : gve_release_rxq_mbufs(rxq);
496 : 0 : gve_reset_rxq(rxq);
497 : :
498 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
499 : :
500 : 0 : return 0;
501 : : }
502 : :
503 : : void
504 : 0 : gve_stop_rx_queues(struct rte_eth_dev *dev)
505 : : {
506 [ # # ]: 0 : struct gve_priv *hw = dev->data->dev_private;
507 : : uint16_t i;
508 : : int err;
509 : :
510 [ # # ]: 0 : if (!gve_is_gqi(hw))
511 : 0 : return gve_stop_rx_queues_dqo(dev);
512 : :
513 : 0 : err = gve_adminq_destroy_rx_queues(hw, dev->data->nb_rx_queues);
514 [ # # ]: 0 : if (err != 0)
515 : 0 : PMD_DRV_LOG(WARNING, "failed to destroy rxqs");
516 : :
517 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
518 [ # # ]: 0 : if (gve_rx_queue_stop(dev, i) != 0)
519 : 0 : PMD_DRV_LOG(WARNING, "Fail to stop Rx queue %d", i);
520 : : }
521 : :
522 : : void
523 : 0 : gve_set_rx_function(struct rte_eth_dev *dev)
524 : : {
525 : 0 : dev->rx_pkt_burst = gve_rx_burst;
526 : 0 : }
|