Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2022-2023 Google LLC
3 : : * Copyright (c) 2022-2023 Intel Corporation
4 : : */
5 : :
6 : :
7 : : #include "gve_ethdev.h"
8 : : #include "base/gve_adminq.h"
9 : : #include "rte_mbuf_ptype.h"
10 : : #include "rte_atomic.h"
11 : :
12 : : static inline void
13 : : gve_completed_buf_list_init(struct gve_rx_queue *rxq)
14 : : {
15 [ # # ]: 0 : for (int i = 0; i < rxq->nb_rx_desc; i++)
16 : 0 : rxq->completed_buf_list[i] = -1;
17 : :
18 : 0 : rxq->completed_buf_list_head = -1;
19 : : }
20 : :
21 : : /* Assumes buf_id < nb_rx_desc */
22 : : static inline void
23 : : gve_completed_buf_list_push(struct gve_rx_queue *rxq, uint16_t buf_id)
24 : : {
25 : 0 : rxq->completed_buf_list[buf_id] = rxq->completed_buf_list_head;
26 : 0 : rxq->completed_buf_list_head = buf_id;
27 : : }
28 : :
29 : : static inline int16_t
30 : : gve_completed_buf_list_pop(struct gve_rx_queue *rxq)
31 : : {
32 : 0 : int16_t head = rxq->completed_buf_list_head;
33 : 0 : if (head != -1)
34 : 0 : rxq->completed_buf_list_head = rxq->completed_buf_list[head];
35 : :
36 : : return head;
37 : : }
38 : :
39 : : static inline void
40 : 0 : gve_rx_refill_dqo(struct gve_rx_queue *rxq)
41 : : {
42 : : volatile struct gve_rx_desc_dqo *rx_buf_desc;
43 : 0 : uint16_t rx_mask = rxq->nb_rx_desc - 1;
44 : 0 : uint16_t next_avail = rxq->bufq_tail;
45 : : struct rte_eth_dev *dev;
46 : : uint16_t nb_refill;
47 : : uint64_t dma_addr;
48 : : rte_iova_t iova;
49 : : int16_t buf_id;
50 : : int diag;
51 : : int i;
52 : :
53 : 0 : nb_refill = rxq->nb_rx_hold;
54 [ # # ]: 0 : if (nb_refill < rxq->free_thresh)
55 : : return;
56 : :
57 : 0 : diag = rte_pktmbuf_alloc_bulk(rxq->mpool, rxq->refill_bufs, nb_refill);
58 [ # # ]: 0 : if (unlikely(diag < 0)) {
59 : 0 : rxq->stats.no_mbufs_bulk++;
60 : 0 : rxq->stats.no_mbufs += nb_refill;
61 : 0 : dev = &rte_eth_devices[rxq->port_id];
62 : 0 : dev->data->rx_mbuf_alloc_failed += nb_refill;
63 : : PMD_DRV_DP_LOG(DEBUG,
64 : : "RX mbuf alloc failed port_id=%u queue_id=%u",
65 : : rxq->port_id, rxq->queue_id);
66 : 0 : return;
67 : : }
68 : :
69 : : /* Mbuf allocation succeeded, so refill buffers. */
70 [ # # ]: 0 : for (i = 0; i < nb_refill; i++) {
71 [ # # ]: 0 : rx_buf_desc = &rxq->rx_ring[next_avail];
72 : : buf_id = gve_completed_buf_list_pop(rxq);
73 : :
74 : : /* Out of buffers. Free remaining mbufs and return. */
75 [ # # ]: 0 : if (unlikely(buf_id == -1)) {
76 : 0 : PMD_DRV_DP_LOG(ERR,
77 : : "No free entries in sw_ring for port %d, queue %d.",
78 : : rxq->port_id, rxq->queue_id);
79 : 0 : rte_pktmbuf_free_bulk(rxq->refill_bufs + i,
80 : 0 : nb_refill - i);
81 : 0 : nb_refill = i;
82 : 0 : break;
83 : : }
84 : 0 : rxq->sw_ring[buf_id] = rxq->refill_bufs[i];
85 : 0 : iova = rte_mbuf_data_iova_default(rxq->refill_bufs[i]);
86 : : dma_addr = rte_cpu_to_le_64(iova);
87 : 0 : rx_buf_desc->buf_id = buf_id;
88 : 0 : rx_buf_desc->header_buf_addr = 0;
89 : 0 : rx_buf_desc->buf_addr = dma_addr;
90 : :
91 : 0 : next_avail = (next_avail + 1) & rx_mask;
92 : : }
93 : :
94 : 0 : rxq->nb_rx_hold -= nb_refill;
95 : 0 : rte_write32(next_avail, rxq->qrx_tail);
96 : 0 : rxq->bufq_tail = next_avail;
97 : : }
98 : :
99 : : static inline void
100 : 0 : gve_parse_csum_ol_flags(struct rte_mbuf *rx_mbuf,
101 : : volatile struct gve_rx_compl_desc_dqo *rx_desc)
102 : : {
103 [ # # ]: 0 : if (!rx_desc->l3_l4_processed)
104 : : return;
105 : :
106 [ # # ]: 0 : if (rx_mbuf->packet_type & RTE_PTYPE_L3_IPV4) {
107 [ # # ]: 0 : if (rx_desc->csum_ip_err)
108 : 0 : rx_mbuf->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
109 : : else
110 : 0 : rx_mbuf->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
111 : : }
112 : :
113 [ # # ]: 0 : if (rx_desc->csum_l4_err) {
114 : 0 : rx_mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
115 : 0 : return;
116 : : }
117 [ # # ]: 0 : if (rx_mbuf->packet_type & RTE_PTYPE_L4_MASK)
118 : 0 : rx_mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
119 : : }
120 : :
121 : : static inline void
122 : 0 : gve_rx_set_mbuf_ptype(struct gve_priv *priv, struct rte_mbuf *rx_mbuf,
123 : : volatile struct gve_rx_compl_desc_dqo *rx_desc)
124 : : {
125 : 0 : struct gve_ptype ptype =
126 : 0 : priv->ptype_lut_dqo->ptypes[rx_desc->packet_type];
127 : 0 : rx_mbuf->packet_type = 0;
128 : :
129 [ # # # ]: 0 : switch (ptype.l3_type) {
130 : 0 : case GVE_L3_TYPE_IPV4:
131 : 0 : rx_mbuf->packet_type |= RTE_PTYPE_L3_IPV4;
132 : 0 : break;
133 : 0 : case GVE_L3_TYPE_IPV6:
134 : 0 : rx_mbuf->packet_type |= RTE_PTYPE_L3_IPV6;
135 : 0 : break;
136 : : default:
137 : : break;
138 : : }
139 : :
140 [ # # # # : 0 : switch (ptype.l4_type) {
# ]
141 : 0 : case GVE_L4_TYPE_TCP:
142 : 0 : rx_mbuf->packet_type |= RTE_PTYPE_L4_TCP;
143 : 0 : break;
144 : 0 : case GVE_L4_TYPE_UDP:
145 : 0 : rx_mbuf->packet_type |= RTE_PTYPE_L4_UDP;
146 : 0 : break;
147 : 0 : case GVE_L4_TYPE_ICMP:
148 : 0 : rx_mbuf->packet_type |= RTE_PTYPE_L4_ICMP;
149 : 0 : break;
150 : 0 : case GVE_L4_TYPE_SCTP:
151 : 0 : rx_mbuf->packet_type |= RTE_PTYPE_L4_SCTP;
152 : 0 : break;
153 : : default:
154 : : break;
155 : : }
156 : 0 : }
157 : :
158 : : uint16_t
159 : 0 : gve_rx_burst_dqo(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
160 : : {
161 : : volatile struct gve_rx_compl_desc_dqo *rx_desc;
162 : : struct gve_rx_queue *rxq;
163 : : uint64_t last_sync = 0;
164 : : struct gve_priv *priv;
165 : : struct rte_mbuf *rxm;
166 : : uint16_t rx_buf_id;
167 : : uint16_t pkt_len;
168 : : uint16_t rx_id;
169 : : uint16_t nb_rx;
170 : : uint64_t bytes;
171 : :
172 : : bytes = 0;
173 : : nb_rx = 0;
174 : : rxq = rx_queue;
175 : 0 : rx_id = rxq->rx_tail;
176 : 0 : priv = rxq->hw;
177 : :
178 [ # # ]: 0 : if (rxq->timestamp_enabled &&
179 [ # # ]: 0 : !rte_atomic_load_explicit(&priv->nic_ts_stale,
180 : : rte_memory_order_acquire)) {
181 : : last_sync =
182 : 0 : rte_atomic_load_explicit(&priv->last_read_nic_timestamp,
183 : : rte_memory_order_relaxed);
184 : : }
185 : :
186 [ # # ]: 0 : while (nb_rx < nb_pkts) {
187 : 0 : rx_desc = &rxq->compl_ring[rx_id];
188 : :
189 : : /* check status */
190 [ # # ]: 0 : if (rx_desc->generation != rxq->cur_gen_bit)
191 : : break;
192 : :
193 : 0 : rte_io_rmb();
194 : :
195 : 0 : rxq->nb_rx_hold++;
196 : 0 : rx_id++;
197 [ # # ]: 0 : if (rx_id == rxq->nb_rx_desc) {
198 : : rx_id = 0;
199 : 0 : rxq->cur_gen_bit ^= 1;
200 : : }
201 : :
202 : 0 : rx_buf_id = rte_le_to_cpu_16(rx_desc->buf_id);
203 [ # # ]: 0 : if (unlikely(rx_buf_id >= rxq->nb_rx_desc)) {
204 : 0 : PMD_DRV_DP_LOG(ERR, "Invalid buf_id %d", rx_buf_id);
205 : 0 : continue;
206 : : }
207 : :
208 : 0 : rxm = rxq->sw_ring[rx_buf_id];
209 : : gve_completed_buf_list_push(rxq, rx_buf_id);
210 : 0 : rxq->sw_ring[rx_buf_id] = NULL;
211 : :
212 : : /* Free buffer and report error. */
213 [ # # ]: 0 : if (unlikely(rx_desc->rx_error)) {
214 : 0 : rxq->stats.errors++;
215 : 0 : rte_pktmbuf_free(rxm);
216 : 0 : continue;
217 : : }
218 : :
219 : 0 : pkt_len = rte_le_to_cpu_16(rx_desc->packet_len);
220 : 0 : rxm->pkt_len = pkt_len;
221 : 0 : rxm->data_len = pkt_len;
222 : 0 : rxm->port = rxq->port_id;
223 : 0 : gve_rx_set_mbuf_ptype(rxq->hw, rxm, rx_desc);
224 : 0 : rxm->ol_flags = RTE_MBUF_F_RX_RSS_HASH;
225 : 0 : gve_parse_csum_ol_flags(rxm, rx_desc);
226 : 0 : rxm->hash.rss = rte_le_to_cpu_32(rx_desc->hash);
227 : :
228 [ # # ]: 0 : if (last_sync != 0 &&
229 [ # # ]: 0 : (rx_desc->ts_sub_nsecs_low & GVE_DQO_RX_HWTSTAMP_VALID) &&
230 [ # # ]: 0 : priv->mbuf_timestamp_offset >= 0) {
231 : 0 : uint32_t ts = rte_le_to_cpu_32(rx_desc->ts);
232 : : uint64_t full_ts = gve_reconstruct_ts(last_sync, ts);
233 : :
234 : 0 : *RTE_MBUF_DYNFIELD(rxm, priv->mbuf_timestamp_offset, uint64_t *) = full_ts;
235 : 0 : rxm->ol_flags |= priv->mbuf_timestamp_mask;
236 : : }
237 : :
238 : 0 : rx_pkts[nb_rx++] = rxm;
239 : 0 : bytes += pkt_len;
240 : : }
241 : :
242 [ # # ]: 0 : if (nb_rx > 0) {
243 : 0 : rxq->rx_tail = rx_id;
244 : :
245 : 0 : rxq->stats.packets += nb_rx;
246 : 0 : rxq->stats.bytes += bytes;
247 : : }
248 : 0 : gve_rx_refill_dqo(rxq);
249 : :
250 : 0 : return nb_rx;
251 : : }
252 : :
253 : : static inline void
254 : 0 : gve_release_rxq_mbufs_dqo(struct gve_rx_queue *rxq)
255 : : {
256 : : uint16_t i;
257 : :
258 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
259 [ # # ]: 0 : if (rxq->sw_ring[i]) {
260 : : rte_pktmbuf_free_seg(rxq->sw_ring[i]);
261 : 0 : rxq->sw_ring[i] = NULL;
262 : : }
263 : : }
264 : :
265 : 0 : rxq->nb_avail = rxq->nb_rx_desc;
266 : 0 : }
267 : :
268 : : void
269 : 0 : gve_rx_queue_release_dqo(struct rte_eth_dev *dev, uint16_t qid)
270 : : {
271 : 0 : struct gve_rx_queue *q = dev->data->rx_queues[qid];
272 : :
273 [ # # ]: 0 : if (q == NULL)
274 : : return;
275 : :
276 : 0 : gve_release_rxq_mbufs_dqo(q);
277 : 0 : rte_free(q->sw_ring);
278 : 0 : rte_free(q->completed_buf_list);
279 : 0 : rte_free(q->refill_bufs);
280 : 0 : rte_memzone_free(q->compl_ring_mz);
281 : 0 : rte_memzone_free(q->mz);
282 : 0 : rte_memzone_free(q->qres_mz);
283 : 0 : q->qres = NULL;
284 : 0 : rte_free(q);
285 : :
286 : 0 : dev->data->rx_queues[qid] = NULL;
287 : : }
288 : :
289 : : static void
290 : 0 : gve_reset_rx_ring_state_dqo(struct gve_rx_queue *rxq)
291 : : {
292 : : struct rte_mbuf **sw_ring;
293 : : uint32_t size, i;
294 : :
295 [ # # ]: 0 : if (rxq == NULL) {
296 : 0 : PMD_DRV_LOG(ERR, "pointer to rxq is NULL");
297 : 0 : return;
298 : : }
299 : :
300 : 0 : size = rxq->nb_rx_desc * sizeof(struct gve_rx_desc_dqo);
301 [ # # ]: 0 : for (i = 0; i < size; i++)
302 : 0 : ((volatile char *)rxq->rx_ring)[i] = 0;
303 : :
304 : 0 : size = rxq->nb_rx_desc * sizeof(struct gve_rx_compl_desc_dqo);
305 [ # # ]: 0 : for (i = 0; i < size; i++)
306 : 0 : ((volatile char *)rxq->compl_ring)[i] = 0;
307 : :
308 : 0 : sw_ring = rxq->sw_ring;
309 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++)
310 : 0 : sw_ring[i] = NULL;
311 : :
312 : : gve_completed_buf_list_init(rxq);
313 : :
314 : 0 : rxq->bufq_tail = 0;
315 : 0 : rxq->nb_rx_hold = rxq->nb_rx_desc - 1;
316 : :
317 : 0 : rxq->rx_tail = 0;
318 : 0 : rxq->cur_gen_bit = 1;
319 : : }
320 : :
321 : : int
322 : 0 : gve_rx_queue_setup_dqo(struct rte_eth_dev *dev, uint16_t queue_id,
323 : : uint16_t nb_desc, unsigned int socket_id,
324 : : const struct rte_eth_rxconf *conf,
325 : : struct rte_mempool *pool)
326 : : {
327 : 0 : struct gve_priv *hw = dev->data->dev_private;
328 : : const struct rte_memzone *mz;
329 : : struct gve_rx_queue *rxq;
330 : : uint16_t free_thresh;
331 : : uint32_t mbuf_len;
332 : : int err = 0;
333 : :
334 : : /* Free memory if needed */
335 [ # # ]: 0 : if (dev->data->rx_queues[queue_id]) {
336 : 0 : gve_rx_queue_release_dqo(dev, queue_id);
337 : 0 : dev->data->rx_queues[queue_id] = NULL;
338 : : }
339 : :
340 : : /* Allocate the RX queue data structure. */
341 : 0 : rxq = rte_zmalloc_socket("gve rxq",
342 : : sizeof(struct gve_rx_queue),
343 : : RTE_CACHE_LINE_SIZE,
344 : : socket_id);
345 [ # # ]: 0 : if (rxq == NULL) {
346 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for rx queue structure");
347 : 0 : return -ENOMEM;
348 : : }
349 : :
350 : : /* Setup hardware timestamping if enabled */
351 [ # # ]: 0 : if ((conf->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) ||
352 [ # # ]: 0 : (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP))
353 : 0 : rxq->timestamp_enabled = true;
354 : :
355 : : /* check free_thresh here */
356 [ # # ]: 0 : free_thresh = conf->rx_free_thresh ?
357 : : conf->rx_free_thresh : GVE_DEFAULT_RX_FREE_THRESH;
358 [ # # ]: 0 : if (free_thresh >= nb_desc) {
359 : 0 : PMD_DRV_LOG(ERR, "rx_free_thresh (%u) must be less than nb_desc (%u).",
360 : : free_thresh, rxq->nb_rx_desc);
361 : : err = -EINVAL;
362 : 0 : goto free_rxq;
363 : : }
364 : :
365 : 0 : rxq->nb_rx_desc = nb_desc;
366 : 0 : rxq->free_thresh = free_thresh;
367 : 0 : rxq->queue_id = queue_id;
368 : 0 : rxq->port_id = dev->data->port_id;
369 : 0 : rxq->ntfy_id = hw->num_ntfy_blks / 2 + queue_id;
370 : :
371 : 0 : rxq->mpool = pool;
372 : 0 : rxq->hw = hw;
373 [ # # # # ]: 0 : rxq->ntfy_addr = &hw->db_bar2[rte_be_to_cpu_32(hw->irq_dbs[rxq->ntfy_id].id)];
374 : :
375 : 0 : mbuf_len =
376 : 0 : rte_pktmbuf_data_room_size(rxq->mpool) - RTE_PKTMBUF_HEADROOM;
377 : 0 : rxq->rx_buf_len =
378 : 0 : RTE_MIN((uint16_t)GVE_RX_MAX_BUF_SIZE_DQO,
379 : : RTE_ALIGN_FLOOR(mbuf_len, GVE_RX_BUF_ALIGN_DQO));
380 : :
381 : : /* Allocate software ring */
382 : 0 : rxq->sw_ring = rte_zmalloc_socket("gve rx sw ring",
383 : : nb_desc * sizeof(struct rte_mbuf *),
384 : : RTE_CACHE_LINE_SIZE, socket_id);
385 [ # # ]: 0 : if (rxq->sw_ring == NULL) {
386 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for SW RX ring");
387 : : err = -ENOMEM;
388 : 0 : goto free_rxq;
389 : : }
390 : :
391 : : /* Allocate completed bufs list */
392 : 0 : rxq->completed_buf_list = rte_zmalloc_socket("gve completed buf list",
393 : : nb_desc * sizeof(*rxq->completed_buf_list), RTE_CACHE_LINE_SIZE,
394 : : socket_id);
395 [ # # ]: 0 : if (rxq->completed_buf_list == NULL) {
396 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate completed buffer list.");
397 : : err = -ENOMEM;
398 : 0 : goto free_rxq_sw_ring;
399 : : }
400 : :
401 : : /* Allocate buffer for reallocating mbufs */
402 : 0 : rxq->refill_bufs = rte_zmalloc_socket("gve rx refill bufs",
403 : : nb_desc * sizeof(*rxq->refill_bufs), RTE_CACHE_LINE_SIZE,
404 : : socket_id);
405 [ # # ]: 0 : if (rxq->refill_bufs == NULL) {
406 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate rx refill bufs.");
407 : : err = -ENOMEM;
408 : 0 : goto free_rxq_completed_buf_list;
409 : : }
410 : :
411 : : /* Allocate RX buffer queue */
412 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
413 : : nb_desc * sizeof(struct gve_rx_desc_dqo),
414 : : PAGE_SIZE, socket_id);
415 [ # # ]: 0 : if (mz == NULL) {
416 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX buffer queue");
417 : : err = -ENOMEM;
418 : 0 : goto free_rxq_refill_bufs;
419 : : }
420 : 0 : rxq->rx_ring = (struct gve_rx_desc_dqo *)mz->addr;
421 : 0 : rxq->rx_ring_phys_addr = mz->iova;
422 : 0 : rxq->mz = mz;
423 : :
424 : : /* Allocate RX completion queue */
425 : 0 : mz = rte_eth_dma_zone_reserve(dev, "compl_ring", queue_id,
426 : : nb_desc * sizeof(struct gve_rx_compl_desc_dqo),
427 : : PAGE_SIZE, socket_id);
428 [ # # ]: 0 : if (mz == NULL) {
429 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX completion queue");
430 : : err = -ENOMEM;
431 : 0 : goto free_rxq_mz;
432 : : }
433 : : /* Zero all the descriptors in the ring */
434 : 0 : memset(mz->addr, 0, nb_desc * sizeof(struct gve_rx_compl_desc_dqo));
435 : 0 : rxq->compl_ring = (struct gve_rx_compl_desc_dqo *)mz->addr;
436 : 0 : rxq->compl_ring_phys_addr = mz->iova;
437 : 0 : rxq->compl_ring_mz = mz;
438 : :
439 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rxq_res", queue_id,
440 : : sizeof(struct gve_queue_resources),
441 : : PAGE_SIZE, socket_id);
442 [ # # ]: 0 : if (mz == NULL) {
443 : 0 : PMD_DRV_LOG(ERR, "Failed to reserve DMA memory for RX resource");
444 : : err = -ENOMEM;
445 : 0 : goto free_rxq_cq_mz;
446 : : }
447 : 0 : rxq->qres = (struct gve_queue_resources *)mz->addr;
448 : 0 : rxq->qres_mz = mz;
449 : :
450 : 0 : gve_reset_rx_ring_state_dqo(rxq);
451 : :
452 : 0 : dev->data->rx_queues[queue_id] = rxq;
453 : :
454 : 0 : return 0;
455 : :
456 : : free_rxq_cq_mz:
457 : 0 : rte_memzone_free(rxq->compl_ring_mz);
458 : 0 : free_rxq_mz:
459 : 0 : rte_memzone_free(rxq->mz);
460 : 0 : free_rxq_refill_bufs:
461 : 0 : rte_free(rxq->refill_bufs);
462 : 0 : free_rxq_completed_buf_list:
463 : 0 : rte_free(rxq->completed_buf_list);
464 : 0 : free_rxq_sw_ring:
465 : 0 : rte_free(rxq->sw_ring);
466 : 0 : free_rxq:
467 : 0 : rte_free(rxq);
468 : 0 : return err;
469 : : }
470 : :
471 : : static int
472 : 0 : gve_rxq_mbufs_alloc_dqo(struct gve_rx_queue *rxq)
473 : : {
474 : : struct rte_mbuf *nmb;
475 : : uint16_t rx_mask;
476 : : uint16_t i;
477 : : int diag;
478 : :
479 : 0 : rx_mask = rxq->nb_rx_desc - 1;
480 : 0 : diag = rte_pktmbuf_alloc_bulk(rxq->mpool, &rxq->sw_ring[0],
481 : : rx_mask);
482 [ # # ]: 0 : if (diag < 0) {
483 : 0 : rxq->stats.no_mbufs_bulk++;
484 [ # # ]: 0 : for (i = 0; i < rx_mask; i++) {
485 : 0 : nmb = rte_pktmbuf_alloc(rxq->mpool);
486 [ # # ]: 0 : if (!nmb) {
487 : 0 : rxq->stats.no_mbufs++;
488 : 0 : gve_release_rxq_mbufs_dqo(rxq);
489 : 0 : return -ENOMEM;
490 : : }
491 : 0 : rxq->sw_ring[i] = nmb;
492 : : }
493 : : }
494 : :
495 [ # # ]: 0 : for (i = 0; i < rx_mask; i++) {
496 : 0 : nmb = rxq->sw_ring[i];
497 : 0 : rxq->rx_ring[i].buf_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(nmb));
498 : 0 : rxq->rx_ring[i].buf_id = rte_cpu_to_le_16(i);
499 : : }
500 : 0 : rxq->rx_ring[rx_mask].buf_id = rte_cpu_to_le_16(rx_mask);
501 : :
502 : 0 : rxq->nb_rx_hold = 0;
503 : 0 : rxq->bufq_tail = rx_mask;
504 : :
505 : 0 : rte_write32(rxq->bufq_tail, rxq->qrx_tail);
506 : :
507 : 0 : return 0;
508 : : }
509 : :
510 : : int
511 : 0 : gve_rx_queue_start_dqo(struct rte_eth_dev *dev, uint16_t rx_queue_id)
512 : : {
513 : 0 : struct gve_priv *hw = dev->data->dev_private;
514 : : struct gve_rx_queue *rxq;
515 : : int ret;
516 : :
517 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
518 : : return -EINVAL;
519 : :
520 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
521 : :
522 [ # # ]: 0 : rxq->qrx_tail = &hw->db_bar2[rte_be_to_cpu_32(rxq->qres->db_index)];
523 : :
524 : : rte_write32(rte_cpu_to_le_32(GVE_NO_INT_MODE_DQO |
525 : : GVE_ITR_NO_UPDATE_DQO),
526 : 0 : rxq->ntfy_addr);
527 : :
528 : 0 : ret = gve_rxq_mbufs_alloc_dqo(rxq);
529 [ # # ]: 0 : if (ret != 0) {
530 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc Rx queue mbuf");
531 : 0 : return ret;
532 : : }
533 : :
534 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
535 : :
536 : 0 : return 0;
537 : : }
538 : :
539 : : int
540 : 0 : gve_rx_queue_stop_dqo(struct rte_eth_dev *dev, uint16_t rx_queue_id)
541 : : {
542 : : struct gve_rx_queue *rxq;
543 : :
544 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
545 : : return -EINVAL;
546 : :
547 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
548 : 0 : gve_release_rxq_mbufs_dqo(rxq);
549 : 0 : gve_reset_rx_ring_state_dqo(rxq);
550 : :
551 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
552 : :
553 : 0 : return 0;
554 : : }
555 : :
556 : : void
557 : 0 : gve_stop_rx_queues_dqo(struct rte_eth_dev *dev)
558 : : {
559 : 0 : struct gve_priv *hw = dev->data->dev_private;
560 : : uint16_t i;
561 : : int err;
562 : :
563 : 0 : err = gve_adminq_destroy_rx_queues(hw, dev->data->nb_rx_queues);
564 [ # # ]: 0 : if (err != 0)
565 : 0 : PMD_DRV_LOG(WARNING, "failed to destroy rxqs");
566 : :
567 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
568 [ # # ]: 0 : if (gve_rx_queue_stop_dqo(dev, i) != 0)
569 : 0 : PMD_DRV_LOG(WARNING, "Fail to stop Rx queue %d", i);
570 : 0 : }
571 : :
572 : : void
573 : 0 : gve_set_rx_function_dqo(struct rte_eth_dev *dev)
574 : : {
575 : 0 : dev->rx_pkt_burst = gve_rx_burst_dqo;
576 : 0 : }
|