Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include <stdint.h>
6 : : #include <rte_malloc.h>
7 : : #include <rte_mbuf.h>
8 : :
9 : : #include "zxdh_queue.h"
10 : : #include "zxdh_logs.h"
11 : : #include "zxdh_pci.h"
12 : : #include "zxdh_common.h"
13 : : #include "zxdh_msg.h"
14 : :
15 : : #define ZXDH_MBUF_MIN_SIZE sizeof(struct zxdh_net_hdr_dl)
16 : : #define ZXDH_MBUF_SIZE_4K 4096
17 : : #define ZXDH_RX_FREE_THRESH 32
18 : : #define ZXDH_TX_FREE_THRESH 32
19 : :
20 : : struct rte_mbuf *
21 : 0 : zxdh_queue_detach_unused(struct zxdh_virtqueue *vq)
22 : : {
23 : : struct rte_mbuf *cookie = NULL;
24 : : int32_t idx = 0;
25 : :
26 [ # # ]: 0 : if (vq == NULL)
27 : : return NULL;
28 : :
29 [ # # ]: 0 : for (idx = 0; idx < vq->vq_nentries; idx++) {
30 : 0 : cookie = vq->vq_descx[idx].cookie;
31 [ # # ]: 0 : if (cookie != NULL) {
32 : 0 : vq->vq_descx[idx].cookie = NULL;
33 : 0 : return cookie;
34 : : }
35 : : }
36 : : return NULL;
37 : : }
38 : :
39 : : static void
40 : 0 : zxdh_clear_channel(struct rte_eth_dev *dev, uint16_t lch)
41 : : {
42 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
43 : : uint16_t pch;
44 : : uint32_t var, addr, widx, bidx;
45 : :
46 [ # # ]: 0 : if (hw->channel_context[lch].valid == 0)
47 : : return;
48 : : /* get coi table offset and index */
49 : 0 : pch = hw->channel_context[lch].ph_chno;
50 : 0 : widx = pch / 32;
51 : 0 : bidx = pch % 32;
52 : 0 : addr = ZXDH_QUERES_SHARE_BASE + (widx * sizeof(uint32_t));
53 : 0 : var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr);
54 : 0 : var &= ~(1 << bidx);
55 : 0 : zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var);
56 : 0 : hw->channel_context[lch].valid = 0;
57 : 0 : hw->channel_context[lch].ph_chno = 0;
58 : 0 : PMD_DRV_LOG(DEBUG, " phyque %d release end ", pch);
59 : : }
60 : :
61 : : static int32_t
62 : 0 : zxdh_release_channel(struct rte_eth_dev *dev)
63 : : {
64 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
65 : 0 : u_int16_t rxq_num = hw->rx_qnum;
66 : 0 : u_int16_t txq_num = hw->tx_qnum;
67 : : uint16_t lch, i;
68 : : int32_t ret = 0;
69 : :
70 [ # # ]: 0 : if (hw->queue_set_flag == 1) {
71 [ # # ]: 0 : for (i = 0; i < rxq_num; i++) {
72 : 0 : lch = i * 2;
73 : 0 : PMD_DRV_LOG(DEBUG, "free success!");
74 [ # # ]: 0 : if (hw->channel_context[lch].valid == 0)
75 : 0 : continue;
76 : 0 : PMD_DRV_LOG(DEBUG, "phyque %d no need to release backend do it",
77 : : hw->channel_context[lch].ph_chno);
78 : 0 : hw->channel_context[lch].valid = 0;
79 : 0 : hw->channel_context[lch].ph_chno = 0;
80 : : }
81 [ # # ]: 0 : for (i = 0; i < txq_num; i++) {
82 : 0 : lch = i * 2 + 1;
83 : 0 : PMD_DRV_LOG(DEBUG, "free success!");
84 [ # # ]: 0 : if (hw->channel_context[lch].valid == 0)
85 : 0 : continue;
86 : 0 : PMD_DRV_LOG(DEBUG, "phyque %d no need to release backend do it",
87 : : hw->channel_context[lch].ph_chno);
88 : 0 : hw->channel_context[lch].valid = 0;
89 : 0 : hw->channel_context[lch].ph_chno = 0;
90 : : }
91 : 0 : hw->queue_set_flag = 0;
92 : 0 : return 0;
93 : : }
94 : 0 : ret = zxdh_timedlock(hw, 1000);
95 [ # # ]: 0 : if (ret) {
96 : 0 : PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout");
97 : 0 : return -1;
98 : : }
99 : :
100 [ # # ]: 0 : for (i = 0 ; i < rxq_num ; i++) {
101 : 0 : lch = i * 2;
102 : 0 : zxdh_clear_channel(dev, lch);
103 : : }
104 [ # # ]: 0 : for (i = 0; i < txq_num ; i++) {
105 : 0 : lch = i * 2 + 1;
106 : 0 : zxdh_clear_channel(dev, lch);
107 : : }
108 : 0 : zxdh_release_lock(hw);
109 : :
110 : 0 : return 0;
111 : : }
112 : :
113 : : int32_t
114 : 0 : zxdh_get_queue_type(uint16_t vtpci_queue_idx)
115 : : {
116 [ # # ]: 0 : if (vtpci_queue_idx % 2 == 0)
117 : : return ZXDH_VTNET_RQ;
118 : : else
119 : 0 : return ZXDH_VTNET_TQ;
120 : : }
121 : :
122 : : int32_t
123 : 0 : zxdh_free_queues(struct rte_eth_dev *dev)
124 : : {
125 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
126 : : struct zxdh_virtqueue *vq = NULL;
127 : 0 : u_int16_t rxq_num = hw->rx_qnum;
128 : 0 : u_int16_t txq_num = hw->tx_qnum;
129 : : uint16_t i = 0;
130 : :
131 [ # # ]: 0 : if (hw->vqs == NULL)
132 : : return 0;
133 : :
134 [ # # ]: 0 : for (i = 0; i < rxq_num; i++) {
135 : 0 : vq = hw->vqs[i * 2];
136 [ # # ]: 0 : if (vq == NULL)
137 : 0 : continue;
138 : :
139 : 0 : ZXDH_VTPCI_OPS(hw)->del_queue(hw, vq);
140 : 0 : rte_memzone_free(vq->rxq.mz);
141 : 0 : rte_free(vq);
142 : 0 : hw->vqs[i * 2] = NULL;
143 : 0 : PMD_MSG_LOG(DEBUG, "Release to queue %d success!", i * 2);
144 : : }
145 [ # # ]: 0 : for (i = 0; i < txq_num; i++) {
146 : 0 : vq = hw->vqs[i * 2 + 1];
147 [ # # ]: 0 : if (vq == NULL)
148 : 0 : continue;
149 : :
150 : 0 : ZXDH_VTPCI_OPS(hw)->del_queue(hw, vq);
151 : 0 : rte_memzone_free(vq->txq.mz);
152 : 0 : rte_memzone_free(vq->txq.zxdh_net_hdr_mz);
153 : 0 : rte_free(vq);
154 : 0 : hw->vqs[i * 2 + 1] = NULL;
155 : 0 : PMD_DRV_LOG(DEBUG, "Release to queue %d success!", i * 2 + 1);
156 : : }
157 : :
158 [ # # ]: 0 : if (zxdh_release_channel(dev) < 0) {
159 : 0 : PMD_DRV_LOG(ERR, "Failed to clear coi table");
160 : 0 : return -1;
161 : : }
162 : :
163 : 0 : rte_free(hw->vqs);
164 : 0 : hw->vqs = NULL;
165 : :
166 : 0 : return 0;
167 : : }
168 : :
169 : : static int
170 : 0 : zxdh_check_mempool(struct rte_mempool *mp, uint16_t offset, uint16_t min_length)
171 : : {
172 : : uint16_t data_room_size;
173 : :
174 [ # # ]: 0 : if (mp == NULL)
175 : : return -EINVAL;
176 : : data_room_size = rte_pktmbuf_data_room_size(mp);
177 [ # # ]: 0 : if (data_room_size < offset + min_length) {
178 : 0 : PMD_RX_LOG(ERR,
179 : : "%s mbuf_data_room_size %u < %u (%u + %u)",
180 : : mp->name, data_room_size,
181 : : offset + min_length, offset, min_length);
182 : 0 : return -EINVAL;
183 : : }
184 : : return 0;
185 : : }
186 : :
187 : : static unsigned int
188 : : log2above(unsigned int v)
189 : : {
190 [ # # ]: 0 : if (v <= 1)
191 : : return 0;
192 : 0 : return 32 - rte_clz32(v - 1);
193 : : }
194 : :
195 : 0 : static uint16_t zxdh_queue_desc_pre_setup(uint16_t desc)
196 : : {
197 : 0 : uint32_t nb_desc = desc;
198 : :
199 [ # # ]: 0 : if (desc < ZXDH_MIN_QUEUE_DEPTH) {
200 : 0 : PMD_DRV_LOG(WARNING, "nb_desc(%u) < min queue depth (%u), turn to min queue depth",
201 : : desc, ZXDH_MIN_QUEUE_DEPTH);
202 : 0 : return ZXDH_MIN_QUEUE_DEPTH;
203 : : }
204 : :
205 [ # # ]: 0 : if (desc > ZXDH_MAX_QUEUE_DEPTH) {
206 : 0 : PMD_DRV_LOG(WARNING, "nb_desc(%u) > max queue depth (%d), turn to max queue depth",
207 : : desc, ZXDH_MAX_QUEUE_DEPTH);
208 : 0 : return ZXDH_MAX_QUEUE_DEPTH;
209 : : }
210 : :
211 : : if (!rte_is_power_of_2(desc)) {
212 : 0 : nb_desc = 1 << log2above(desc);
213 : : if (nb_desc > ZXDH_MAX_QUEUE_DEPTH)
214 : : nb_desc = ZXDH_MAX_QUEUE_DEPTH;
215 : 0 : PMD_DRV_LOG(WARNING, "nb_desc(%u) turn to the next power of two (%u)",
216 : : desc, nb_desc);
217 : : }
218 : :
219 : 0 : return nb_desc;
220 : : }
221 : :
222 : : int32_t
223 : 0 : zxdh_dev_rx_queue_setup(struct rte_eth_dev *dev,
224 : : uint16_t queue_idx,
225 : : uint16_t nb_desc,
226 : : uint32_t socket_id __rte_unused,
227 : : const struct rte_eth_rxconf *rx_conf,
228 : : struct rte_mempool *mp)
229 : : {
230 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
231 : : uint16_t valid_nb_desc = 0;
232 : :
233 [ # # ]: 0 : if (rx_conf->rx_deferred_start) {
234 : 0 : PMD_RX_LOG(ERR, "Rx deferred start is not supported");
235 : 0 : return -EINVAL;
236 : : }
237 : :
238 : 0 : valid_nb_desc = zxdh_queue_desc_pre_setup(nb_desc);
239 [ # # ]: 0 : if (dev->data->nb_rx_queues != hw->rx_qnum ||
240 [ # # ]: 0 : valid_nb_desc != hw->queue_conf->conf[queue_idx].rx_nb_desc) {
241 : 0 : PMD_RX_LOG(DEBUG, "rx queue changed. rxq:[%d], hw->rxq:[%d], nb_desc:%d, hw->nb_desc:%d",
242 : : dev->data->nb_rx_queues, hw->rx_qnum, valid_nb_desc,
243 : : hw->queue_conf->conf[queue_idx].rx_nb_desc);
244 : 0 : hw->queue_conf->queue_changed = 1;
245 : : }
246 : :
247 [ # # ]: 0 : rte_memcpy(&hw->queue_conf->conf[queue_idx].zxdh_rx_conf,
248 : : rx_conf, sizeof(struct rte_eth_rxconf));
249 : 0 : hw->queue_conf->conf[queue_idx].rx_nb_desc = valid_nb_desc;
250 : 0 : hw->queue_conf->conf[queue_idx].queue_mp = mp;
251 : :
252 : 0 : return 0;
253 : : }
254 : :
255 : : int32_t
256 : 0 : zxdh_rx_queue_config(struct rte_eth_dev *dev, uint16_t queue_idx)
257 : : {
258 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
259 : 0 : uint16_t vtpci_logic_qidx = 2 * queue_idx + ZXDH_RQ_QUEUE_IDX;
260 : 0 : struct zxdh_virtqueue *vq = hw->vqs[vtpci_logic_qidx];
261 : : struct rte_eth_rxconf *rx_conf;
262 : : uint16_t rx_free_thresh;
263 : : int32_t ret = 0;
264 : :
265 [ # # ]: 0 : if (!hw->queue_conf) {
266 : 0 : PMD_RX_LOG(ERR, "rx queue config failed queue_conf is NULL, queue-idx:%d",
267 : : queue_idx);
268 : 0 : return -EINVAL;
269 : : }
270 : :
271 : 0 : rx_conf = &hw->queue_conf->conf[queue_idx].zxdh_rx_conf;
272 : 0 : rx_free_thresh = rx_conf->rx_free_thresh;
273 : :
274 [ # # ]: 0 : if (rx_free_thresh == 0)
275 : 0 : rx_free_thresh = RTE_MIN(vq->vq_nentries / 4, ZXDH_RX_FREE_THRESH);
276 : :
277 [ # # ]: 0 : if (rx_free_thresh & 0x3) {
278 : 0 : PMD_RX_LOG(ERR, "(rx_free_thresh=%u port=%u queue=%u)",
279 : : rx_free_thresh, dev->data->port_id, queue_idx);
280 : 0 : return -EINVAL;
281 : : }
282 [ # # ]: 0 : if (rx_free_thresh >= vq->vq_nentries) {
283 : 0 : PMD_RX_LOG(ERR, "RX entries (%u). (rx_free_thresh=%u port=%u queue=%u)",
284 : : vq->vq_nentries, rx_free_thresh, dev->data->port_id, queue_idx);
285 : 0 : return -EINVAL;
286 : : }
287 : :
288 : 0 : vq->vq_free_thresh = rx_free_thresh;
289 : :
290 : 0 : vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, hw->queue_conf->conf[queue_idx].rx_nb_desc);
291 : 0 : struct zxdh_virtnet_rx *rxvq = &vq->rxq;
292 : :
293 : 0 : rxvq->queue_id = vtpci_logic_qidx;
294 : :
295 : : int mbuf_min_size = ZXDH_MBUF_MIN_SIZE;
296 : :
297 [ # # ]: 0 : if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
298 : : mbuf_min_size = ZXDH_MBUF_SIZE_4K;
299 : :
300 : 0 : struct rte_mempool *mp = hw->queue_conf->conf[queue_idx].queue_mp;
301 : 0 : ret = zxdh_check_mempool(mp, RTE_PKTMBUF_HEADROOM, mbuf_min_size);
302 [ # # ]: 0 : if (ret != 0) {
303 : 0 : PMD_RX_LOG(ERR,
304 : : "rxq setup but mpool size too small(<%d) failed", mbuf_min_size);
305 : 0 : return -EINVAL;
306 : : }
307 : 0 : rxvq->mpool = mp;
308 : :
309 [ # # ]: 0 : if (queue_idx < dev->data->nb_rx_queues)
310 : 0 : dev->data->rx_queues[queue_idx] = rxvq;
311 : :
312 : : return 0;
313 : : }
314 : :
315 : : int32_t
316 : 0 : zxdh_dev_tx_queue_setup(struct rte_eth_dev *dev,
317 : : uint16_t queue_idx,
318 : : uint16_t nb_desc,
319 : : uint32_t socket_id __rte_unused,
320 : : const struct rte_eth_txconf *tx_conf)
321 : : {
322 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
323 : : uint16_t valid_nb_desc = 0;
324 : :
325 [ # # ]: 0 : if (tx_conf->tx_deferred_start) {
326 : 0 : PMD_TX_LOG(ERR, "Tx deferred start is not supported");
327 : 0 : return -EINVAL;
328 : : }
329 : :
330 : 0 : valid_nb_desc = zxdh_queue_desc_pre_setup(nb_desc);
331 [ # # ]: 0 : if (dev->data->nb_tx_queues != hw->tx_qnum ||
332 [ # # ]: 0 : valid_nb_desc != hw->queue_conf->conf[queue_idx].tx_nb_desc) {
333 : 0 : PMD_TX_LOG(DEBUG, "tx queue changed. txq:[%d], hw->txq:[%d], nb_desc:%d, hw->nb_desc:%d",
334 : : dev->data->nb_tx_queues, hw->tx_qnum, valid_nb_desc,
335 : : hw->queue_conf->conf[queue_idx].tx_nb_desc);
336 : 0 : hw->queue_conf->queue_changed = 1;
337 : : }
338 : :
339 [ # # ]: 0 : rte_memcpy(&hw->queue_conf->conf[queue_idx].zxdh_tx_conf,
340 : : tx_conf, sizeof(struct rte_eth_txconf));
341 : 0 : hw->queue_conf->conf[queue_idx].tx_nb_desc = valid_nb_desc;
342 : :
343 : 0 : return 0;
344 : : }
345 : :
346 : : int32_t
347 : 0 : zxdh_tx_queue_config(struct rte_eth_dev *dev, uint16_t queue_idx)
348 : : {
349 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
350 : : struct zxdh_virtnet_tx *txvq = NULL;
351 : 0 : uint16_t vtpci_logic_qidx = 2 * queue_idx + ZXDH_TQ_QUEUE_IDX;
352 : 0 : struct zxdh_virtqueue *vq = hw->vqs[vtpci_logic_qidx];
353 : : uint16_t tx_free_thresh = 0;
354 : :
355 [ # # ]: 0 : if (!hw->queue_conf) {
356 : 0 : PMD_TX_LOG(ERR, "tx queue config failed queue_conf is NULL, queue_idx:%d",
357 : : queue_idx);
358 : 0 : return -EINVAL;
359 : : }
360 : :
361 : 0 : struct rte_eth_txconf *tx_conf = &hw->queue_conf->conf[queue_idx].zxdh_tx_conf;
362 : :
363 : 0 : vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, hw->queue_conf->conf[queue_idx].tx_nb_desc);
364 : 0 : txvq = &vq->txq;
365 : 0 : txvq->queue_id = vtpci_logic_qidx;
366 : :
367 : 0 : tx_free_thresh = tx_conf->tx_free_thresh;
368 [ # # ]: 0 : if (tx_free_thresh == 0)
369 : 0 : tx_free_thresh = RTE_MIN(vq->vq_nentries / 4, ZXDH_TX_FREE_THRESH);
370 : :
371 [ # # ]: 0 : if (tx_free_thresh >= (vq->vq_nentries - 3)) {
372 : 0 : PMD_TX_LOG(ERR, "tx_free_thresh must be less than the number of TX entries minus 3 (%u). (tx_free_thresh=%u port=%u queue=%u)",
373 : : vq->vq_nentries - 3,
374 : : tx_free_thresh, dev->data->port_id, queue_idx);
375 : 0 : return -EINVAL;
376 : : }
377 : :
378 : 0 : vq->vq_free_thresh = tx_free_thresh;
379 [ # # ]: 0 : if (queue_idx < dev->data->nb_tx_queues)
380 : 0 : dev->data->tx_queues[queue_idx] = txvq;
381 : :
382 : : return 0;
383 : : }
384 : :
385 : : int32_t
386 : 0 : zxdh_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
387 : : {
388 : 0 : struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
389 [ # # ]: 0 : struct zxdh_virtqueue *vq = rxvq->vq;
390 : :
391 : : zxdh_queue_enable_intr(vq);
392 : 0 : return 0;
393 : : }
394 : :
395 : : int32_t
396 : 0 : zxdh_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
397 : : {
398 : 0 : struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
399 [ # # ]: 0 : struct zxdh_virtqueue *vq = rxvq->vq;
400 : :
401 : : zxdh_queue_disable_intr(vq);
402 : 0 : return 0;
403 : : }
404 : :
405 : 0 : int32_t zxdh_enqueue_recv_refill_packed(struct zxdh_virtqueue *vq,
406 : : struct rte_mbuf **cookie, uint16_t num)
407 : : {
408 : 0 : struct zxdh_vring_packed_desc *start_dp = vq->vq_packed.ring.desc;
409 : : struct zxdh_vq_desc_extra *dxp;
410 : 0 : uint16_t flags = vq->vq_packed.cached_flags;
411 : : int32_t i;
412 : : uint16_t idx;
413 : :
414 [ # # ]: 0 : for (i = 0; i < num; i++) {
415 : 0 : idx = vq->vq_avail_idx;
416 : 0 : dxp = &vq->vq_descx[idx];
417 : 0 : dxp->cookie = (void *)cookie[i];
418 : 0 : dxp->ndescs = 1;
419 : : /* rx pkt fill in data_off */
420 : 0 : start_dp[idx].addr = rte_mbuf_iova_get(cookie[i]) + RTE_PKTMBUF_HEADROOM;
421 : 0 : start_dp[idx].len = cookie[i]->buf_len - RTE_PKTMBUF_HEADROOM;
422 : :
423 : : zxdh_queue_store_flags_packed(&start_dp[idx], flags);
424 [ # # ]: 0 : if (++vq->vq_avail_idx >= vq->vq_nentries) {
425 : 0 : vq->vq_avail_idx -= vq->vq_nentries;
426 : 0 : vq->vq_packed.cached_flags ^= ZXDH_VRING_PACKED_DESC_F_AVAIL_USED;
427 : : flags = vq->vq_packed.cached_flags;
428 : : }
429 : : }
430 : 0 : vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - num);
431 : 0 : return 0;
432 : : }
433 : :
434 : 0 : int32_t zxdh_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
435 : : {
436 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
437 : 0 : uint16_t logic_qidx = ((queue_idx << 1) + ZXDH_RQ_QUEUE_IDX) % ZXDH_QUEUES_NUM_MAX;
438 : 0 : struct zxdh_virtqueue *vq = hw->vqs[logic_qidx];
439 : : struct zxdh_virtnet_rx *rxvq = &vq->rxq;
440 : : int32_t error = 0;
441 : :
442 [ # # ]: 0 : while (!zxdh_queue_full(vq)) {
443 : : struct rte_mbuf *new_pkts[ZXDH_MBUF_BURST_SZ];
444 : 0 : uint16_t free_cnt = RTE_MIN(ZXDH_MBUF_BURST_SZ, vq->vq_free_cnt);
445 : :
446 [ # # ]: 0 : if (likely(rte_pktmbuf_alloc_bulk(rxvq->mpool, new_pkts, free_cnt) == 0)) {
447 : 0 : error = zxdh_enqueue_recv_refill_packed(vq, new_pkts, free_cnt);
448 [ # # ]: 0 : if (unlikely(error)) {
449 : : int32_t i;
450 [ # # ]: 0 : for (i = 0; i < free_cnt; i++)
451 : 0 : rte_pktmbuf_free(new_pkts[i]);
452 : : }
453 : : } else {
454 : 0 : PMD_DRV_LOG(ERR, "port %d rxq %d allocated bufs from %s failed",
455 : : hw->port_id, logic_qidx, rxvq->mpool->name);
456 : 0 : break;
457 : : }
458 : : }
459 : 0 : return 0;
460 : : }
461 : :
462 : 0 : void zxdh_queue_rxvq_flush(struct zxdh_virtqueue *vq)
463 : : {
464 : : struct zxdh_vq_desc_extra *dxp = NULL;
465 : : uint16_t i = 0;
466 : 0 : struct zxdh_vring_packed_desc *descs = vq->vq_packed.ring.desc;
467 : : int32_t cnt = 0;
468 : :
469 : 0 : i = vq->vq_used_cons_idx;
470 [ # # ]: 0 : while (zxdh_desc_used(&descs[i], vq) && cnt++ < vq->vq_nentries) {
471 : 0 : dxp = &vq->vq_descx[descs[i].id];
472 [ # # ]: 0 : if (dxp->cookie != NULL) {
473 : 0 : rte_pktmbuf_free(dxp->cookie);
474 : 0 : dxp->cookie = NULL;
475 : : }
476 : 0 : vq->vq_free_cnt++;
477 : 0 : vq->vq_used_cons_idx++;
478 [ # # ]: 0 : if (vq->vq_used_cons_idx >= vq->vq_nentries) {
479 : 0 : vq->vq_used_cons_idx -= vq->vq_nentries;
480 : 0 : vq->vq_packed.used_wrap_counter ^= 1;
481 : : }
482 : 0 : i = vq->vq_used_cons_idx;
483 : : }
484 : 0 : }
|