1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
6 #include <vnet/dev/dev.h>
7 #include <vnet/dev/pci.h>
8 #include <vnet/dev/counters.h>
9 #include <vppinfra/ring.h>
10 #include <dev_iavf/iavf.h>
11 #include <dev_iavf/virtchnl.h>
12 #include <dev_iavf/virtchnl_funcs.h>
13 #include <vnet/ethernet/ethernet.h>
14 #include <vnet/plugin/plugin.h>
15 #include <vpp/app/version.h>
17 VLIB_REGISTER_LOG_CLASS (iavf_log, static) = {
19 .subclass_name = "queue",
23 iavf_rx_queue_alloc (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq)
25 vnet_dev_port_t *port = rxq->port;
26 vnet_dev_t *dev = port->dev;
27 iavf_device_t *ad = vnet_dev_get_data (dev);
28 iavf_rxq_t *arq = vnet_dev_get_rx_queue_data (rxq);
31 arq->buffer_indices = clib_mem_alloc_aligned (
32 rxq->size * sizeof (arq->buffer_indices[0]), CLIB_CACHE_LINE_BYTES);
35 vnet_dev_dma_mem_alloc (vm, dev, sizeof (iavf_rx_desc_t) * rxq->size,
36 0, (void **) &arq->descs)))
39 arq->qrx_tail = ad->bar0 + IAVF_QRX_TAIL (rxq->queue_id);
41 log_debug (dev, "queue %u alocated", rxq->queue_id);
46 iavf_rx_queue_free (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq)
48 vnet_dev_t *dev = rxq->port->dev;
49 iavf_rxq_t *aq = vnet_dev_get_rx_queue_data (rxq);
51 log_debug (dev, "queue %u", rxq->queue_id);
53 vnet_dev_dma_mem_free (vm, dev, aq->descs);
55 foreach_pointer (p, aq->buffer_indices)
61 iavf_tx_queue_alloc (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
63 vnet_dev_t *dev = txq->port->dev;
64 iavf_device_t *ad = vnet_dev_get_data (dev);
65 iavf_txq_t *atq = vnet_dev_get_tx_queue_data (txq);
69 vnet_dev_dma_mem_alloc (vm, dev, sizeof (iavf_tx_desc_t) * txq->size,
70 0, (void **) &atq->descs)))
73 clib_ring_new_aligned (atq->rs_slots, 32, CLIB_CACHE_LINE_BYTES);
74 atq->buffer_indices = clib_mem_alloc_aligned (
75 txq->size * sizeof (atq->buffer_indices[0]), CLIB_CACHE_LINE_BYTES);
76 atq->tmp_descs = clib_mem_alloc_aligned (
77 sizeof (atq->tmp_descs[0]) * txq->size, CLIB_CACHE_LINE_BYTES);
78 atq->tmp_bufs = clib_mem_alloc_aligned (
79 sizeof (atq->tmp_bufs[0]) * txq->size, CLIB_CACHE_LINE_BYTES);
81 atq->qtx_tail = ad->bar0 + IAVF_QTX_TAIL (txq->queue_id);
83 log_debug (dev, "queue %u alocated", txq->queue_id);
88 iavf_tx_queue_free (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
90 vnet_dev_t *dev = txq->port->dev;
91 iavf_txq_t *atq = vnet_dev_get_tx_queue_data (txq);
92 iavf_txq_t *aq = vnet_dev_get_tx_queue_data (txq);
94 log_debug (dev, "queue %u", txq->queue_id);
95 vnet_dev_dma_mem_free (vm, dev, aq->descs);
96 clib_ring_free (atq->rs_slots);
98 foreach_pointer (p, aq->tmp_descs, aq->tmp_bufs, aq->buffer_indices)
104 iavf_rx_queue_start (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq)
106 vnet_dev_t *dev = rxq->port->dev;
107 iavf_rxq_t *arq = vnet_dev_get_rx_queue_data (rxq);
108 iavf_rx_desc_t *d = arq->descs;
109 u32 n_enq, *bi = arq->buffer_indices;
110 u8 bpi = vnet_dev_get_rx_queue_buffer_pool_index (rxq);
112 n_enq = vlib_buffer_alloc_from_pool (vm, bi, rxq->size - 8, bpi);
117 vlib_buffer_free (vm, bi, n_enq);
118 return VNET_DEV_ERR_BUFFER_ALLOC_FAIL;
121 for (u32 i = 0; i < n_enq; i++)
123 vlib_buffer_t *b = vlib_get_buffer (vm, bi[i]);
124 u64 dma_addr = vnet_dev_get_dma_addr (vm, dev, b->data);
125 d[i] = (iavf_rx_desc_t){ .addr = dma_addr };
128 arq->n_enqueued = n_enq;
130 __atomic_store_n (arq->qrx_tail, n_enq, __ATOMIC_RELEASE);
135 iavf_rx_queue_stop (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq)
137 iavf_rxq_t *arq = vnet_dev_get_rx_queue_data (rxq);
139 __atomic_store_n (arq->qrx_tail, 0, __ATOMIC_RELAXED);
142 vlib_buffer_free_from_ring_no_next (vm, arq->buffer_indices, arq->next,
143 rxq->size, arq->n_enqueued);
144 log_debug (rxq->port->dev, "%u buffers freed from rx queue %u",
145 arq->n_enqueued, rxq->queue_id);
147 arq->n_enqueued = arq->next = 0;
151 iavf_tx_queue_start (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
153 iavf_txq_t *atq = vnet_dev_get_tx_queue_data (txq);
156 clib_ring_reset (atq->rs_slots);
157 __atomic_store_n (atq->qtx_tail, 0, __ATOMIC_RELAXED);
162 iavf_tx_queue_stop (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
164 iavf_txq_t *atq = vnet_dev_get_tx_queue_data (txq);
166 log_debug (txq->port->dev, "queue %u", txq->queue_id);
168 __atomic_store_n (atq->qtx_tail, 0, __ATOMIC_RELAXED);
171 vlib_buffer_free_from_ring_no_next (vm, atq->buffer_indices,
172 atq->next - atq->n_enqueued,
173 txq->size, atq->n_enqueued);
174 log_debug (txq->port->dev, "%u buffers freed from tx queue %u",
175 atq->n_enqueued, txq->queue_id);
177 atq->n_enqueued = atq->next = 0;