1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020-2021 Xilinx, Inc.
7 #include <rte_common.h>
13 #include "sfc_vdpa_ops.h"
15 extern uint32_t sfc_logtype_driver;
18 #define PAGE_SIZE (sysconf(_SC_PAGESIZE))
22 sfc_vdpa_dma_alloc(struct sfc_vdpa_adapter *sva, const char *name,
23 size_t len, efsys_mem_t *esmp)
26 size_t mcdi_buff_size;
27 const struct rte_memzone *mz = NULL;
28 int numa_node = sva->pdev->device.numa_node;
31 mcdi_buff_size = RTE_ALIGN_CEIL(len, PAGE_SIZE);
33 sfc_vdpa_log_init(sva, "name=%s, len=%zu", name, len);
35 mz = rte_memzone_reserve_aligned(name, mcdi_buff_size,
37 RTE_MEMZONE_IOVA_CONTIG,
40 sfc_vdpa_err(sva, "cannot reserve memory for %s: len=%#x: %s",
41 name, (unsigned int)len, rte_strerror(rte_errno));
45 /* IOVA address for MCDI would be re-calculated if mapping
46 * using default IOVA would fail.
47 * TODO: Earlier there was no way to get valid IOVA range.
48 * Recently a patch has been submitted to get the IOVA range
49 * using ioctl. VFIO_IOMMU_GET_INFO. This patch is available
50 * in the kernel version >= 5.4. Support to get the default
51 * IOVA address for MCDI buffer using available IOVA range
52 * would be added later. Meanwhile default IOVA for MCDI buffer
53 * is kept at high mem at 2TB. In case of overlap new available
54 * addresses would be searched and same would be used.
56 mcdi_iova = SFC_VDPA_DEFAULT_MCDI_IOVA;
59 ret = rte_vfio_container_dma_map(sva->vfio_container_fd,
60 (uint64_t)mz->addr, mcdi_iova,
65 mcdi_iova = mcdi_iova >> 1;
66 if (mcdi_iova < mcdi_buff_size) {
68 "DMA mapping failed for MCDI : %s",
69 rte_strerror(rte_errno));
75 esmp->esm_addr = mcdi_iova;
76 esmp->esm_base = mz->addr;
77 sva->mcdi_buff_size = mcdi_buff_size;
80 "DMA name=%s len=%zu => virt=%p iova=0x%" PRIx64,
81 name, len, esmp->esm_base, esmp->esm_addr);
87 sfc_vdpa_dma_free(struct sfc_vdpa_adapter *sva, efsys_mem_t *esmp)
91 sfc_vdpa_log_init(sva, "name=%s", esmp->esm_mz->name);
93 ret = rte_vfio_container_dma_unmap(sva->vfio_container_fd,
94 (uint64_t)esmp->esm_base,
95 esmp->esm_addr, sva->mcdi_buff_size);
97 sfc_vdpa_err(sva, "DMA unmap failed for MCDI : %s",
98 rte_strerror(rte_errno));
101 "DMA free name=%s => virt=%p iova=0x%" PRIx64,
102 esmp->esm_mz->name, esmp->esm_base, esmp->esm_addr);
104 rte_free((void *)(esmp->esm_base));
106 sva->mcdi_buff_size = 0;
107 memset(esmp, 0, sizeof(*esmp));
111 sfc_vdpa_mem_bar_init(struct sfc_vdpa_adapter *sva,
112 const efx_bar_region_t *mem_ebrp)
114 struct rte_pci_device *pci_dev = sva->pdev;
115 efsys_bar_t *ebp = &sva->mem_bar;
116 struct rte_mem_resource *res =
117 &pci_dev->mem_resource[mem_ebrp->ebr_index];
119 SFC_BAR_LOCK_INIT(ebp, pci_dev->name);
120 ebp->esb_rid = mem_ebrp->ebr_index;
121 ebp->esb_dev = pci_dev;
122 ebp->esb_base = res->addr;
128 sfc_vdpa_mem_bar_fini(struct sfc_vdpa_adapter *sva)
130 efsys_bar_t *ebp = &sva->mem_bar;
132 SFC_BAR_LOCK_DESTROY(ebp);
133 memset(ebp, 0, sizeof(*ebp));
137 sfc_vdpa_nic_probe(struct sfc_vdpa_adapter *sva)
139 efx_nic_t *enp = sva->nic;
142 rc = efx_nic_probe(enp, EFX_FW_VARIANT_DONT_CARE);
144 sfc_vdpa_err(sva, "nic probe failed: %s", rte_strerror(rc));
150 sfc_vdpa_estimate_resource_limits(struct sfc_vdpa_adapter *sva)
152 efx_drv_limits_t limits;
154 uint32_t evq_allocated;
155 uint32_t rxq_allocated;
156 uint32_t txq_allocated;
157 uint32_t max_queue_cnt;
159 memset(&limits, 0, sizeof(limits));
161 /* Request at least one Rx and Tx queue */
162 limits.edl_min_rxq_count = 1;
163 limits.edl_min_txq_count = 1;
164 /* Management event queue plus event queue for Tx/Rx queue */
165 limits.edl_min_evq_count =
166 1 + RTE_MAX(limits.edl_min_rxq_count, limits.edl_min_txq_count);
168 limits.edl_max_rxq_count = SFC_VDPA_MAX_QUEUE_PAIRS;
169 limits.edl_max_txq_count = SFC_VDPA_MAX_QUEUE_PAIRS;
170 limits.edl_max_evq_count = 1 + SFC_VDPA_MAX_QUEUE_PAIRS;
172 SFC_VDPA_ASSERT(limits.edl_max_evq_count >= limits.edl_min_rxq_count);
173 SFC_VDPA_ASSERT(limits.edl_max_rxq_count >= limits.edl_min_rxq_count);
174 SFC_VDPA_ASSERT(limits.edl_max_txq_count >= limits.edl_min_rxq_count);
176 /* Configure the minimum required resources needed for the
177 * driver to operate, and the maximum desired resources that the
178 * driver is capable of using.
180 sfc_vdpa_log_init(sva, "set drv limit");
181 efx_nic_set_drv_limits(sva->nic, &limits);
183 sfc_vdpa_log_init(sva, "init nic");
184 rc = efx_nic_init(sva->nic);
186 sfc_vdpa_err(sva, "nic init failed: %s", rte_strerror(rc));
190 /* Find resource dimensions assigned by firmware to this function */
191 rc = efx_nic_get_vi_pool(sva->nic, &evq_allocated, &rxq_allocated,
194 sfc_vdpa_err(sva, "vi pool get failed: %s", rte_strerror(rc));
195 goto fail_get_vi_pool;
198 /* It still may allocate more than maximum, ensure limit */
199 evq_allocated = RTE_MIN(evq_allocated, limits.edl_max_evq_count);
200 rxq_allocated = RTE_MIN(rxq_allocated, limits.edl_max_rxq_count);
201 txq_allocated = RTE_MIN(txq_allocated, limits.edl_max_txq_count);
204 max_queue_cnt = RTE_MIN(rxq_allocated, txq_allocated);
205 /* Subtract management EVQ not used for traffic */
206 max_queue_cnt = RTE_MIN(evq_allocated - 1, max_queue_cnt);
208 SFC_VDPA_ASSERT(max_queue_cnt > 0);
210 sva->max_queue_count = max_queue_cnt;
215 efx_nic_fini(sva->nic);
217 sfc_vdpa_log_init(sva, "failed: %s", rte_strerror(rc));
222 sfc_vdpa_hw_init(struct sfc_vdpa_adapter *sva)
224 efx_bar_region_t mem_ebr;
228 sfc_vdpa_log_init(sva, "entry");
230 sfc_vdpa_log_init(sva, "get family");
231 rc = sfc_efx_family(sva->pdev, &mem_ebr, &sva->family);
234 sfc_vdpa_log_init(sva,
235 "family is %u, membar is %d,"
236 "function control window offset is %#" PRIx64,
237 sva->family, mem_ebr.ebr_index, mem_ebr.ebr_offset);
239 sfc_vdpa_log_init(sva, "init mem bar");
240 rc = sfc_vdpa_mem_bar_init(sva, &mem_ebr);
242 goto fail_mem_bar_init;
244 sfc_vdpa_log_init(sva, "create nic");
245 rte_spinlock_init(&sva->nic_lock);
246 rc = efx_nic_create(sva->family, (efsys_identifier_t *)sva,
247 &sva->mem_bar, mem_ebr.ebr_offset,
248 &sva->nic_lock, &enp);
250 sfc_vdpa_err(sva, "nic create failed: %s", rte_strerror(rc));
251 goto fail_nic_create;
255 sfc_vdpa_log_init(sva, "init mcdi");
256 rc = sfc_vdpa_mcdi_init(sva);
258 sfc_vdpa_err(sva, "mcdi init failed: %s", rte_strerror(rc));
262 sfc_vdpa_log_init(sva, "probe nic");
263 rc = sfc_vdpa_nic_probe(sva);
267 sfc_vdpa_log_init(sva, "reset nic");
268 rc = efx_nic_reset(enp);
270 sfc_vdpa_err(sva, "nic reset failed: %s", rte_strerror(rc));
274 sfc_vdpa_log_init(sva, "estimate resource limits");
275 rc = sfc_vdpa_estimate_resource_limits(sva);
277 goto fail_estimate_rsrc_limits;
279 sfc_vdpa_log_init(sva, "init virtio");
280 rc = efx_virtio_init(enp);
282 sfc_vdpa_err(sva, "virtio init failed: %s", rte_strerror(rc));
283 goto fail_virtio_init;
286 sfc_vdpa_log_init(sva, "done");
293 fail_estimate_rsrc_limits:
295 efx_nic_unprobe(enp);
298 sfc_vdpa_mcdi_fini(sva);
301 sfc_vdpa_log_init(sva, "destroy nic");
303 efx_nic_destroy(enp);
306 sfc_vdpa_mem_bar_fini(sva);
310 sfc_vdpa_log_init(sva, "failed: %s", rte_strerror(rc));
315 sfc_vdpa_hw_fini(struct sfc_vdpa_adapter *sva)
317 efx_nic_t *enp = sva->nic;
319 sfc_vdpa_log_init(sva, "entry");
321 sfc_vdpa_log_init(sva, "virtio fini");
322 efx_virtio_fini(enp);
324 sfc_vdpa_log_init(sva, "unprobe nic");
325 efx_nic_unprobe(enp);
327 sfc_vdpa_log_init(sva, "mcdi fini");
328 sfc_vdpa_mcdi_fini(sva);
330 sfc_vdpa_log_init(sva, "nic fini");
333 sfc_vdpa_log_init(sva, "destroy nic");
335 efx_nic_destroy(enp);
337 sfc_vdpa_mem_bar_fini(sva);