16dad9a73SVijay Kumar Srivastava /* SPDX-License-Identifier: BSD-3-Clause
26dad9a73SVijay Kumar Srivastava * Copyright(c) 2020-2021 Xilinx, Inc.
36dad9a73SVijay Kumar Srivastava */
46dad9a73SVijay Kumar Srivastava
5630be406SVijay Kumar Srivastava #include <pthread.h>
6630be406SVijay Kumar Srivastava #include <unistd.h>
7b1196136SVijay Kumar Srivastava #include <sys/ioctl.h>
8b1196136SVijay Kumar Srivastava
9f66a66e6SVijay Kumar Srivastava #include <rte_errno.h>
106dad9a73SVijay Kumar Srivastava #include <rte_malloc.h>
116dad9a73SVijay Kumar Srivastava #include <rte_vdpa.h>
12b1196136SVijay Kumar Srivastava #include <rte_vfio.h>
136dad9a73SVijay Kumar Srivastava #include <rte_vhost.h>
146dad9a73SVijay Kumar Srivastava
156dad9a73SVijay Kumar Srivastava #include <vdpa_driver.h>
166dad9a73SVijay Kumar Srivastava
17f66a66e6SVijay Kumar Srivastava #include "efx.h"
186dad9a73SVijay Kumar Srivastava #include "sfc_vdpa_ops.h"
196dad9a73SVijay Kumar Srivastava #include "sfc_vdpa.h"
206dad9a73SVijay Kumar Srivastava
21f66a66e6SVijay Kumar Srivastava /* These protocol features are needed to enable notifier ctrl */
22f66a66e6SVijay Kumar Srivastava #define SFC_VDPA_PROTOCOL_FEATURES \
23f66a66e6SVijay Kumar Srivastava ((1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
24f1eb477eSNobuhiro Miki (1ULL << VHOST_USER_PROTOCOL_F_BACKEND_REQ) | \
25f1eb477eSNobuhiro Miki (1ULL << VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD) | \
26f66a66e6SVijay Kumar Srivastava (1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) | \
27f2c0e634SAbhimanyu Saini (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) | \
28f2c0e634SAbhimanyu Saini (1ULL << VHOST_USER_PROTOCOL_F_MQ))
29f66a66e6SVijay Kumar Srivastava
30f66a66e6SVijay Kumar Srivastava /*
31f66a66e6SVijay Kumar Srivastava * Set of features which are enabled by default.
32f66a66e6SVijay Kumar Srivastava * Protocol feature bit is needed to enable notification notifier ctrl.
336dad9a73SVijay Kumar Srivastava */
34f66a66e6SVijay Kumar Srivastava #define SFC_VDPA_DEFAULT_FEATURES \
35f2c0e634SAbhimanyu Saini ((1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
36f2c0e634SAbhimanyu Saini (1ULL << VIRTIO_NET_F_MQ))
37f66a66e6SVijay Kumar Srivastava
38b1196136SVijay Kumar Srivastava #define SFC_VDPA_MSIX_IRQ_SET_BUF_LEN \
39b1196136SVijay Kumar Srivastava (sizeof(struct vfio_irq_set) + \
40b1196136SVijay Kumar Srivastava sizeof(int) * (SFC_VDPA_MAX_QUEUE_PAIRS * 2 + 1))
416dad9a73SVijay Kumar Srivastava
42b1196136SVijay Kumar Srivastava /* It will be used for target VF when calling function is not PF */
43b1196136SVijay Kumar Srivastava #define SFC_VDPA_VF_NULL 0xFFFF
446dad9a73SVijay Kumar Srivastava
456dad9a73SVijay Kumar Srivastava static int
sfc_vdpa_get_device_features(struct sfc_vdpa_ops_data * ops_data)46f66a66e6SVijay Kumar Srivastava sfc_vdpa_get_device_features(struct sfc_vdpa_ops_data *ops_data)
47f66a66e6SVijay Kumar Srivastava {
48f66a66e6SVijay Kumar Srivastava int rc;
49f66a66e6SVijay Kumar Srivastava uint64_t dev_features;
50f66a66e6SVijay Kumar Srivastava efx_nic_t *nic;
51f66a66e6SVijay Kumar Srivastava
52f66a66e6SVijay Kumar Srivastava nic = sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle)->nic;
53f66a66e6SVijay Kumar Srivastava
54f66a66e6SVijay Kumar Srivastava rc = efx_virtio_get_features(nic, EFX_VIRTIO_DEVICE_TYPE_NET,
55f66a66e6SVijay Kumar Srivastava &dev_features);
56f66a66e6SVijay Kumar Srivastava if (rc != 0) {
57f66a66e6SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
58f66a66e6SVijay Kumar Srivastava "could not read device feature: %s",
59f66a66e6SVijay Kumar Srivastava rte_strerror(rc));
60f66a66e6SVijay Kumar Srivastava return rc;
61f66a66e6SVijay Kumar Srivastava }
62f66a66e6SVijay Kumar Srivastava
63f66a66e6SVijay Kumar Srivastava ops_data->dev_features = dev_features;
64f66a66e6SVijay Kumar Srivastava
65f66a66e6SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
66f66a66e6SVijay Kumar Srivastava "device supported virtio features : 0x%" PRIx64,
67f66a66e6SVijay Kumar Srivastava ops_data->dev_features);
68f66a66e6SVijay Kumar Srivastava
69f66a66e6SVijay Kumar Srivastava return 0;
70f66a66e6SVijay Kumar Srivastava }
71f66a66e6SVijay Kumar Srivastava
72b1196136SVijay Kumar Srivastava static uint64_t
hva_to_gpa(int vid,uint64_t hva)73b1196136SVijay Kumar Srivastava hva_to_gpa(int vid, uint64_t hva)
74b1196136SVijay Kumar Srivastava {
75b1196136SVijay Kumar Srivastava struct rte_vhost_memory *vhost_mem = NULL;
76b1196136SVijay Kumar Srivastava struct rte_vhost_mem_region *mem_reg = NULL;
77b1196136SVijay Kumar Srivastava uint32_t i;
78b1196136SVijay Kumar Srivastava uint64_t gpa = 0;
79b1196136SVijay Kumar Srivastava
80b1196136SVijay Kumar Srivastava if (rte_vhost_get_mem_table(vid, &vhost_mem) < 0)
81b1196136SVijay Kumar Srivastava goto error;
82b1196136SVijay Kumar Srivastava
83b1196136SVijay Kumar Srivastava for (i = 0; i < vhost_mem->nregions; i++) {
84b1196136SVijay Kumar Srivastava mem_reg = &vhost_mem->regions[i];
85b1196136SVijay Kumar Srivastava
86b1196136SVijay Kumar Srivastava if (hva >= mem_reg->host_user_addr &&
87b1196136SVijay Kumar Srivastava hva < mem_reg->host_user_addr + mem_reg->size) {
88b1196136SVijay Kumar Srivastava gpa = (hva - mem_reg->host_user_addr) +
89b1196136SVijay Kumar Srivastava mem_reg->guest_phys_addr;
90b1196136SVijay Kumar Srivastava break;
91b1196136SVijay Kumar Srivastava }
92b1196136SVijay Kumar Srivastava }
93b1196136SVijay Kumar Srivastava
94b1196136SVijay Kumar Srivastava error:
95b1196136SVijay Kumar Srivastava free(vhost_mem);
96b1196136SVijay Kumar Srivastava return gpa;
97b1196136SVijay Kumar Srivastava }
98b1196136SVijay Kumar Srivastava
99b1196136SVijay Kumar Srivastava static int
sfc_vdpa_enable_vfio_intr(struct sfc_vdpa_ops_data * ops_data)100b1196136SVijay Kumar Srivastava sfc_vdpa_enable_vfio_intr(struct sfc_vdpa_ops_data *ops_data)
101b1196136SVijay Kumar Srivastava {
102b1196136SVijay Kumar Srivastava int rc;
103b1196136SVijay Kumar Srivastava int *irq_fd_ptr;
104b1196136SVijay Kumar Srivastava int vfio_dev_fd;
105b1196136SVijay Kumar Srivastava uint32_t i, num_vring;
106b1196136SVijay Kumar Srivastava struct rte_vhost_vring vring;
107b1196136SVijay Kumar Srivastava struct vfio_irq_set *irq_set;
108b1196136SVijay Kumar Srivastava struct rte_pci_device *pci_dev;
109b1196136SVijay Kumar Srivastava char irq_set_buf[SFC_VDPA_MSIX_IRQ_SET_BUF_LEN];
110b1196136SVijay Kumar Srivastava void *dev;
111b1196136SVijay Kumar Srivastava
112b1196136SVijay Kumar Srivastava num_vring = rte_vhost_get_vring_num(ops_data->vid);
113b1196136SVijay Kumar Srivastava dev = ops_data->dev_handle;
114b1196136SVijay Kumar Srivastava vfio_dev_fd = sfc_vdpa_adapter_by_dev_handle(dev)->vfio_dev_fd;
115b1196136SVijay Kumar Srivastava pci_dev = sfc_vdpa_adapter_by_dev_handle(dev)->pdev;
116b1196136SVijay Kumar Srivastava
117b1196136SVijay Kumar Srivastava irq_set = (struct vfio_irq_set *)irq_set_buf;
118b1196136SVijay Kumar Srivastava irq_set->argsz = sizeof(irq_set_buf);
119b1196136SVijay Kumar Srivastava irq_set->count = num_vring + 1;
120b1196136SVijay Kumar Srivastava irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
121b1196136SVijay Kumar Srivastava VFIO_IRQ_SET_ACTION_TRIGGER;
122b1196136SVijay Kumar Srivastava irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
123b1196136SVijay Kumar Srivastava irq_set->start = 0;
124b1196136SVijay Kumar Srivastava irq_fd_ptr = (int *)&irq_set->data;
125b1196136SVijay Kumar Srivastava irq_fd_ptr[RTE_INTR_VEC_ZERO_OFFSET] =
126b1196136SVijay Kumar Srivastava rte_intr_fd_get(pci_dev->intr_handle);
127b1196136SVijay Kumar Srivastava
128b1196136SVijay Kumar Srivastava for (i = 0; i < num_vring; i++) {
129b1196136SVijay Kumar Srivastava rc = rte_vhost_get_vhost_vring(ops_data->vid, i, &vring);
130b1196136SVijay Kumar Srivastava if (rc)
131b1196136SVijay Kumar Srivastava return -1;
132b1196136SVijay Kumar Srivastava
133b1196136SVijay Kumar Srivastava irq_fd_ptr[RTE_INTR_VEC_RXTX_OFFSET + i] = vring.callfd;
134b1196136SVijay Kumar Srivastava }
135b1196136SVijay Kumar Srivastava
136b1196136SVijay Kumar Srivastava rc = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
137b1196136SVijay Kumar Srivastava if (rc) {
138b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
139b1196136SVijay Kumar Srivastava "error enabling MSI-X interrupts: %s",
140b1196136SVijay Kumar Srivastava strerror(errno));
141b1196136SVijay Kumar Srivastava return -1;
142b1196136SVijay Kumar Srivastava }
143b1196136SVijay Kumar Srivastava
144b1196136SVijay Kumar Srivastava return 0;
145b1196136SVijay Kumar Srivastava }
146b1196136SVijay Kumar Srivastava
147b1196136SVijay Kumar Srivastava static int
sfc_vdpa_disable_vfio_intr(struct sfc_vdpa_ops_data * ops_data)148b1196136SVijay Kumar Srivastava sfc_vdpa_disable_vfio_intr(struct sfc_vdpa_ops_data *ops_data)
149b1196136SVijay Kumar Srivastava {
150b1196136SVijay Kumar Srivastava int rc;
151b1196136SVijay Kumar Srivastava int vfio_dev_fd;
152b1196136SVijay Kumar Srivastava struct vfio_irq_set irq_set;
153b1196136SVijay Kumar Srivastava void *dev;
154b1196136SVijay Kumar Srivastava
155b1196136SVijay Kumar Srivastava dev = ops_data->dev_handle;
156b1196136SVijay Kumar Srivastava vfio_dev_fd = sfc_vdpa_adapter_by_dev_handle(dev)->vfio_dev_fd;
157b1196136SVijay Kumar Srivastava
158b1196136SVijay Kumar Srivastava irq_set.argsz = sizeof(irq_set);
159b1196136SVijay Kumar Srivastava irq_set.count = 0;
160b1196136SVijay Kumar Srivastava irq_set.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
161b1196136SVijay Kumar Srivastava irq_set.index = VFIO_PCI_MSIX_IRQ_INDEX;
162b1196136SVijay Kumar Srivastava irq_set.start = 0;
163b1196136SVijay Kumar Srivastava
164b1196136SVijay Kumar Srivastava rc = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, &irq_set);
165b1196136SVijay Kumar Srivastava if (rc) {
166b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
167b1196136SVijay Kumar Srivastava "error disabling MSI-X interrupts: %s",
168b1196136SVijay Kumar Srivastava strerror(errno));
169b1196136SVijay Kumar Srivastava return -1;
170b1196136SVijay Kumar Srivastava }
171b1196136SVijay Kumar Srivastava
172b1196136SVijay Kumar Srivastava return 0;
173b1196136SVijay Kumar Srivastava }
174b1196136SVijay Kumar Srivastava
175b1196136SVijay Kumar Srivastava static int
sfc_vdpa_get_vring_info(struct sfc_vdpa_ops_data * ops_data,int vq_num,struct sfc_vdpa_vring_info * vring)176b1196136SVijay Kumar Srivastava sfc_vdpa_get_vring_info(struct sfc_vdpa_ops_data *ops_data,
177b1196136SVijay Kumar Srivastava int vq_num, struct sfc_vdpa_vring_info *vring)
178b1196136SVijay Kumar Srivastava {
179b1196136SVijay Kumar Srivastava int rc;
180b1196136SVijay Kumar Srivastava uint64_t gpa;
181b1196136SVijay Kumar Srivastava struct rte_vhost_vring vq;
182b1196136SVijay Kumar Srivastava
183b1196136SVijay Kumar Srivastava rc = rte_vhost_get_vhost_vring(ops_data->vid, vq_num, &vq);
184b1196136SVijay Kumar Srivastava if (rc < 0) {
185b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
186b1196136SVijay Kumar Srivastava "get vhost vring failed: %s", rte_strerror(rc));
187b1196136SVijay Kumar Srivastava return rc;
188b1196136SVijay Kumar Srivastava }
189b1196136SVijay Kumar Srivastava
190b1196136SVijay Kumar Srivastava gpa = hva_to_gpa(ops_data->vid, (uint64_t)(uintptr_t)vq.desc);
191b1196136SVijay Kumar Srivastava if (gpa == 0) {
192b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
193b1196136SVijay Kumar Srivastava "fail to get GPA for descriptor ring.");
194b1196136SVijay Kumar Srivastava return -1;
195b1196136SVijay Kumar Srivastava }
196b1196136SVijay Kumar Srivastava vring->desc = gpa;
197b1196136SVijay Kumar Srivastava
198b1196136SVijay Kumar Srivastava gpa = hva_to_gpa(ops_data->vid, (uint64_t)(uintptr_t)vq.avail);
199b1196136SVijay Kumar Srivastava if (gpa == 0) {
200b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
201b1196136SVijay Kumar Srivastava "fail to get GPA for available ring.");
202b1196136SVijay Kumar Srivastava return -1;
203b1196136SVijay Kumar Srivastava }
204b1196136SVijay Kumar Srivastava vring->avail = gpa;
205b1196136SVijay Kumar Srivastava
206b1196136SVijay Kumar Srivastava gpa = hva_to_gpa(ops_data->vid, (uint64_t)(uintptr_t)vq.used);
207b1196136SVijay Kumar Srivastava if (gpa == 0) {
208b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
209b1196136SVijay Kumar Srivastava "fail to get GPA for used ring.");
210b1196136SVijay Kumar Srivastava return -1;
211b1196136SVijay Kumar Srivastava }
212b1196136SVijay Kumar Srivastava vring->used = gpa;
213b1196136SVijay Kumar Srivastava
214b1196136SVijay Kumar Srivastava vring->size = vq.size;
215b1196136SVijay Kumar Srivastava
216b1196136SVijay Kumar Srivastava rc = rte_vhost_get_vring_base(ops_data->vid, vq_num,
217b1196136SVijay Kumar Srivastava &vring->last_avail_idx,
218b1196136SVijay Kumar Srivastava &vring->last_used_idx);
219b1196136SVijay Kumar Srivastava
220b1196136SVijay Kumar Srivastava return rc;
221b1196136SVijay Kumar Srivastava }
222b1196136SVijay Kumar Srivastava
223b1196136SVijay Kumar Srivastava static int
sfc_vdpa_virtq_start(struct sfc_vdpa_ops_data * ops_data,int vq_num)224b1196136SVijay Kumar Srivastava sfc_vdpa_virtq_start(struct sfc_vdpa_ops_data *ops_data, int vq_num)
225b1196136SVijay Kumar Srivastava {
226b1196136SVijay Kumar Srivastava int rc;
227d9a1ef20SAbhimanyu Saini uint32_t doorbell;
228b1196136SVijay Kumar Srivastava efx_virtio_vq_t *vq;
229b1196136SVijay Kumar Srivastava struct sfc_vdpa_vring_info vring;
230b1196136SVijay Kumar Srivastava efx_virtio_vq_cfg_t vq_cfg;
231b1196136SVijay Kumar Srivastava efx_virtio_vq_dyncfg_t vq_dyncfg;
232b1196136SVijay Kumar Srivastava
233b1196136SVijay Kumar Srivastava vq = ops_data->vq_cxt[vq_num].vq;
234b1196136SVijay Kumar Srivastava if (vq == NULL)
235b1196136SVijay Kumar Srivastava return -1;
236b1196136SVijay Kumar Srivastava
237b1196136SVijay Kumar Srivastava rc = sfc_vdpa_get_vring_info(ops_data, vq_num, &vring);
238b1196136SVijay Kumar Srivastava if (rc < 0) {
239b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
240b1196136SVijay Kumar Srivastava "get vring info failed: %s", rte_strerror(rc));
241b1196136SVijay Kumar Srivastava goto fail_vring_info;
242b1196136SVijay Kumar Srivastava }
243b1196136SVijay Kumar Srivastava
244b1196136SVijay Kumar Srivastava vq_cfg.evvc_target_vf = SFC_VDPA_VF_NULL;
245b1196136SVijay Kumar Srivastava
246b1196136SVijay Kumar Srivastava /* even virtqueue for RX and odd for TX */
247b1196136SVijay Kumar Srivastava if (vq_num % 2) {
248b1196136SVijay Kumar Srivastava vq_cfg.evvc_type = EFX_VIRTIO_VQ_TYPE_NET_TXQ;
249b1196136SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
250b1196136SVijay Kumar Srivastava "configure virtqueue # %d (TXQ)", vq_num);
251b1196136SVijay Kumar Srivastava } else {
252b1196136SVijay Kumar Srivastava vq_cfg.evvc_type = EFX_VIRTIO_VQ_TYPE_NET_RXQ;
253b1196136SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
254b1196136SVijay Kumar Srivastava "configure virtqueue # %d (RXQ)", vq_num);
255b1196136SVijay Kumar Srivastava }
256b1196136SVijay Kumar Srivastava
257b1196136SVijay Kumar Srivastava vq_cfg.evvc_vq_num = vq_num;
258b1196136SVijay Kumar Srivastava vq_cfg.evvc_desc_tbl_addr = vring.desc;
259b1196136SVijay Kumar Srivastava vq_cfg.evvc_avail_ring_addr = vring.avail;
260b1196136SVijay Kumar Srivastava vq_cfg.evvc_used_ring_addr = vring.used;
261b1196136SVijay Kumar Srivastava vq_cfg.evvc_vq_size = vring.size;
262b1196136SVijay Kumar Srivastava
26305308e34SAbhimanyu Saini vq_dyncfg.evvd_vq_used_idx = vring.last_used_idx;
26405308e34SAbhimanyu Saini vq_dyncfg.evvd_vq_avail_idx = vring.last_avail_idx;
265b1196136SVijay Kumar Srivastava
266b1196136SVijay Kumar Srivastava /* MSI-X vector is function-relative */
267b1196136SVijay Kumar Srivastava vq_cfg.evvc_msix_vector = RTE_INTR_VEC_RXTX_OFFSET + vq_num;
268b1196136SVijay Kumar Srivastava if (ops_data->vdpa_context == SFC_VDPA_AS_VF)
269b1196136SVijay Kumar Srivastava vq_cfg.evvc_pas_id = 0;
270b1196136SVijay Kumar Srivastava vq_cfg.evcc_features = ops_data->dev_features &
271b1196136SVijay Kumar Srivastava ops_data->req_features;
272b1196136SVijay Kumar Srivastava
273b1196136SVijay Kumar Srivastava /* Start virtqueue */
274b1196136SVijay Kumar Srivastava rc = efx_virtio_qstart(vq, &vq_cfg, &vq_dyncfg);
275b1196136SVijay Kumar Srivastava if (rc != 0) {
276b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
277b1196136SVijay Kumar Srivastava "virtqueue start failed: %s",
278b1196136SVijay Kumar Srivastava rte_strerror(rc));
279b1196136SVijay Kumar Srivastava goto fail_virtio_qstart;
280b1196136SVijay Kumar Srivastava }
281b1196136SVijay Kumar Srivastava
282b1196136SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
283b1196136SVijay Kumar Srivastava "virtqueue started successfully for vq_num %d", vq_num);
284b1196136SVijay Kumar Srivastava
285d9a1ef20SAbhimanyu Saini rc = efx_virtio_get_doorbell_offset(vq, &doorbell);
286d9a1ef20SAbhimanyu Saini if (rc != 0) {
287d9a1ef20SAbhimanyu Saini sfc_vdpa_err(ops_data->dev_handle,
288d9a1ef20SAbhimanyu Saini "failed to get doorbell offset: %s",
289d9a1ef20SAbhimanyu Saini rte_strerror(rc));
290d9a1ef20SAbhimanyu Saini goto fail_doorbell;
291d9a1ef20SAbhimanyu Saini }
292d9a1ef20SAbhimanyu Saini
293d9a1ef20SAbhimanyu Saini /*
294d9a1ef20SAbhimanyu Saini * Cache the bar_offset here for each VQ here, it will come
295d9a1ef20SAbhimanyu Saini * in handy when sfc_vdpa_get_notify_area() is invoked.
296d9a1ef20SAbhimanyu Saini */
297d9a1ef20SAbhimanyu Saini ops_data->vq_cxt[vq_num].doorbell = (void *)(uintptr_t)doorbell;
298b1196136SVijay Kumar Srivastava ops_data->vq_cxt[vq_num].enable = B_TRUE;
299b1196136SVijay Kumar Srivastava
300b1196136SVijay Kumar Srivastava return rc;
301b1196136SVijay Kumar Srivastava
302d9a1ef20SAbhimanyu Saini fail_doorbell:
303b1196136SVijay Kumar Srivastava fail_virtio_qstart:
304d9a1ef20SAbhimanyu Saini efx_virtio_qdestroy(vq);
305b1196136SVijay Kumar Srivastava fail_vring_info:
306b1196136SVijay Kumar Srivastava return rc;
307b1196136SVijay Kumar Srivastava }
308b1196136SVijay Kumar Srivastava
309b1196136SVijay Kumar Srivastava static int
sfc_vdpa_virtq_stop(struct sfc_vdpa_ops_data * ops_data,int vq_num)310b1196136SVijay Kumar Srivastava sfc_vdpa_virtq_stop(struct sfc_vdpa_ops_data *ops_data, int vq_num)
311b1196136SVijay Kumar Srivastava {
312b1196136SVijay Kumar Srivastava int rc;
313b1196136SVijay Kumar Srivastava efx_virtio_vq_dyncfg_t vq_idx;
314b1196136SVijay Kumar Srivastava efx_virtio_vq_t *vq;
315b1196136SVijay Kumar Srivastava
316b1196136SVijay Kumar Srivastava if (ops_data->vq_cxt[vq_num].enable != B_TRUE)
317b1196136SVijay Kumar Srivastava return -1;
318b1196136SVijay Kumar Srivastava
319b1196136SVijay Kumar Srivastava vq = ops_data->vq_cxt[vq_num].vq;
320b1196136SVijay Kumar Srivastava if (vq == NULL)
321b1196136SVijay Kumar Srivastava return -1;
322b1196136SVijay Kumar Srivastava
323b1196136SVijay Kumar Srivastava /* stop the vq */
324b1196136SVijay Kumar Srivastava rc = efx_virtio_qstop(vq, &vq_idx);
325b1196136SVijay Kumar Srivastava if (rc == 0) {
32605308e34SAbhimanyu Saini ops_data->vq_cxt[vq_num].cidx = vq_idx.evvd_vq_used_idx;
32705308e34SAbhimanyu Saini ops_data->vq_cxt[vq_num].pidx = vq_idx.evvd_vq_avail_idx;
328b1196136SVijay Kumar Srivastava }
329b1196136SVijay Kumar Srivastava ops_data->vq_cxt[vq_num].enable = B_FALSE;
330b1196136SVijay Kumar Srivastava
331b1196136SVijay Kumar Srivastava return rc;
332b1196136SVijay Kumar Srivastava }
333b1196136SVijay Kumar Srivastava
334b1196136SVijay Kumar Srivastava static int
sfc_vdpa_configure(struct sfc_vdpa_ops_data * ops_data)335b1196136SVijay Kumar Srivastava sfc_vdpa_configure(struct sfc_vdpa_ops_data *ops_data)
336b1196136SVijay Kumar Srivastava {
337b1196136SVijay Kumar Srivastava int rc, i;
338b1196136SVijay Kumar Srivastava int nr_vring;
339b1196136SVijay Kumar Srivastava int max_vring_cnt;
340b1196136SVijay Kumar Srivastava efx_virtio_vq_t *vq;
341b1196136SVijay Kumar Srivastava efx_nic_t *nic;
342b1196136SVijay Kumar Srivastava void *dev;
343b1196136SVijay Kumar Srivastava
344b1196136SVijay Kumar Srivastava dev = ops_data->dev_handle;
345b1196136SVijay Kumar Srivastava nic = sfc_vdpa_adapter_by_dev_handle(dev)->nic;
346b1196136SVijay Kumar Srivastava
347b1196136SVijay Kumar Srivastava SFC_EFX_ASSERT(ops_data->state == SFC_VDPA_STATE_INITIALIZED);
348b1196136SVijay Kumar Srivastava
349b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_CONFIGURING;
350b1196136SVijay Kumar Srivastava
351b1196136SVijay Kumar Srivastava nr_vring = rte_vhost_get_vring_num(ops_data->vid);
352b1196136SVijay Kumar Srivastava max_vring_cnt =
353b1196136SVijay Kumar Srivastava (sfc_vdpa_adapter_by_dev_handle(dev)->max_queue_count * 2);
354b1196136SVijay Kumar Srivastava
355b1196136SVijay Kumar Srivastava /* number of vring should not be more than supported max vq count */
356b1196136SVijay Kumar Srivastava if (nr_vring > max_vring_cnt) {
357b1196136SVijay Kumar Srivastava sfc_vdpa_err(dev,
358b1196136SVijay Kumar Srivastava "nr_vring (%d) is > max vring count (%d)",
359b1196136SVijay Kumar Srivastava nr_vring, max_vring_cnt);
360b1196136SVijay Kumar Srivastava goto fail_vring_num;
361b1196136SVijay Kumar Srivastava }
362b1196136SVijay Kumar Srivastava
363b1196136SVijay Kumar Srivastava rc = sfc_vdpa_dma_map(ops_data, true);
364b1196136SVijay Kumar Srivastava if (rc) {
365b1196136SVijay Kumar Srivastava sfc_vdpa_err(dev,
366b1196136SVijay Kumar Srivastava "DMA map failed: %s", rte_strerror(rc));
367b1196136SVijay Kumar Srivastava goto fail_dma_map;
368b1196136SVijay Kumar Srivastava }
369b1196136SVijay Kumar Srivastava
370b1196136SVijay Kumar Srivastava for (i = 0; i < nr_vring; i++) {
371b1196136SVijay Kumar Srivastava rc = efx_virtio_qcreate(nic, &vq);
372b1196136SVijay Kumar Srivastava if ((rc != 0) || (vq == NULL)) {
373b1196136SVijay Kumar Srivastava sfc_vdpa_err(dev,
374b1196136SVijay Kumar Srivastava "virtqueue create failed: %s",
375b1196136SVijay Kumar Srivastava rte_strerror(rc));
376b1196136SVijay Kumar Srivastava goto fail_vq_create;
377b1196136SVijay Kumar Srivastava }
378b1196136SVijay Kumar Srivastava
379b1196136SVijay Kumar Srivastava /* store created virtqueue context */
380b1196136SVijay Kumar Srivastava ops_data->vq_cxt[i].vq = vq;
381b1196136SVijay Kumar Srivastava }
382b1196136SVijay Kumar Srivastava
383b1196136SVijay Kumar Srivastava ops_data->vq_count = i;
384b1196136SVijay Kumar Srivastava
385b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_CONFIGURED;
386b1196136SVijay Kumar Srivastava
387b1196136SVijay Kumar Srivastava return 0;
388b1196136SVijay Kumar Srivastava
389b1196136SVijay Kumar Srivastava fail_vq_create:
390b1196136SVijay Kumar Srivastava sfc_vdpa_dma_map(ops_data, false);
391b1196136SVijay Kumar Srivastava
392b1196136SVijay Kumar Srivastava fail_dma_map:
393b1196136SVijay Kumar Srivastava fail_vring_num:
394b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_INITIALIZED;
395b1196136SVijay Kumar Srivastava
396b1196136SVijay Kumar Srivastava return -1;
397b1196136SVijay Kumar Srivastava }
398b1196136SVijay Kumar Srivastava
399b1196136SVijay Kumar Srivastava static void
sfc_vdpa_close(struct sfc_vdpa_ops_data * ops_data)400b1196136SVijay Kumar Srivastava sfc_vdpa_close(struct sfc_vdpa_ops_data *ops_data)
401b1196136SVijay Kumar Srivastava {
402b1196136SVijay Kumar Srivastava int i;
403b1196136SVijay Kumar Srivastava
404b1196136SVijay Kumar Srivastava if (ops_data->state != SFC_VDPA_STATE_CONFIGURED)
405b1196136SVijay Kumar Srivastava return;
406b1196136SVijay Kumar Srivastava
407b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_CLOSING;
408b1196136SVijay Kumar Srivastava
409b1196136SVijay Kumar Srivastava for (i = 0; i < ops_data->vq_count; i++) {
410b1196136SVijay Kumar Srivastava if (ops_data->vq_cxt[i].vq == NULL)
411b1196136SVijay Kumar Srivastava continue;
412b1196136SVijay Kumar Srivastava
413b1196136SVijay Kumar Srivastava efx_virtio_qdestroy(ops_data->vq_cxt[i].vq);
414b1196136SVijay Kumar Srivastava }
415b1196136SVijay Kumar Srivastava
416b1196136SVijay Kumar Srivastava sfc_vdpa_dma_map(ops_data, false);
417b1196136SVijay Kumar Srivastava
418b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_INITIALIZED;
419b1196136SVijay Kumar Srivastava }
420b1196136SVijay Kumar Srivastava
421b1196136SVijay Kumar Srivastava static void
sfc_vdpa_stop(struct sfc_vdpa_ops_data * ops_data)422b1196136SVijay Kumar Srivastava sfc_vdpa_stop(struct sfc_vdpa_ops_data *ops_data)
423b1196136SVijay Kumar Srivastava {
424b1196136SVijay Kumar Srivastava int i;
425b1196136SVijay Kumar Srivastava int rc;
426b1196136SVijay Kumar Srivastava
427b1196136SVijay Kumar Srivastava if (ops_data->state != SFC_VDPA_STATE_STARTED)
428b1196136SVijay Kumar Srivastava return;
429b1196136SVijay Kumar Srivastava
430b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_STOPPING;
431b1196136SVijay Kumar Srivastava
432b1196136SVijay Kumar Srivastava for (i = 0; i < ops_data->vq_count; i++) {
433b1196136SVijay Kumar Srivastava rc = sfc_vdpa_virtq_stop(ops_data, i);
434b1196136SVijay Kumar Srivastava if (rc != 0)
435b1196136SVijay Kumar Srivastava continue;
436b1196136SVijay Kumar Srivastava }
437b1196136SVijay Kumar Srivastava
438b1196136SVijay Kumar Srivastava sfc_vdpa_disable_vfio_intr(ops_data);
439b1196136SVijay Kumar Srivastava
440cfeed08aSVijay Kumar Srivastava sfc_vdpa_filter_remove(ops_data);
441cfeed08aSVijay Kumar Srivastava
442b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_CONFIGURED;
443b1196136SVijay Kumar Srivastava }
444b1196136SVijay Kumar Srivastava
445b1196136SVijay Kumar Srivastava static int
sfc_vdpa_start(struct sfc_vdpa_ops_data * ops_data)446b1196136SVijay Kumar Srivastava sfc_vdpa_start(struct sfc_vdpa_ops_data *ops_data)
447b1196136SVijay Kumar Srivastava {
448b1196136SVijay Kumar Srivastava int i, j;
449b1196136SVijay Kumar Srivastava int rc;
450b1196136SVijay Kumar Srivastava
451b1196136SVijay Kumar Srivastava SFC_EFX_ASSERT(ops_data->state == SFC_VDPA_STATE_CONFIGURED);
452b1196136SVijay Kumar Srivastava
453b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "entry");
454b1196136SVijay Kumar Srivastava
455b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_STARTING;
456b1196136SVijay Kumar Srivastava
457b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "enable interrupts");
458b1196136SVijay Kumar Srivastava rc = sfc_vdpa_enable_vfio_intr(ops_data);
459b1196136SVijay Kumar Srivastava if (rc < 0) {
460b1196136SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
461b1196136SVijay Kumar Srivastava "vfio intr allocation failed: %s",
462b1196136SVijay Kumar Srivastava rte_strerror(rc));
463b1196136SVijay Kumar Srivastava goto fail_enable_vfio_intr;
464b1196136SVijay Kumar Srivastava }
465b1196136SVijay Kumar Srivastava
466b1196136SVijay Kumar Srivastava rte_vhost_get_negotiated_features(ops_data->vid,
467b1196136SVijay Kumar Srivastava &ops_data->req_features);
468b1196136SVijay Kumar Srivastava
469b1196136SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
470b1196136SVijay Kumar Srivastava "negotiated feature : 0x%" PRIx64,
471b1196136SVijay Kumar Srivastava ops_data->req_features);
472b1196136SVijay Kumar Srivastava
473b1196136SVijay Kumar Srivastava for (i = 0; i < ops_data->vq_count; i++) {
474b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle,
475b1196136SVijay Kumar Srivastava "starting vq# %d", i);
476b1196136SVijay Kumar Srivastava rc = sfc_vdpa_virtq_start(ops_data, i);
477b1196136SVijay Kumar Srivastava if (rc != 0)
478b1196136SVijay Kumar Srivastava goto fail_vq_start;
479b1196136SVijay Kumar Srivastava }
480b1196136SVijay Kumar Srivastava
481cfeed08aSVijay Kumar Srivastava ops_data->vq_count = i;
482cfeed08aSVijay Kumar Srivastava
483cfeed08aSVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle,
484cfeed08aSVijay Kumar Srivastava "configure MAC filters");
485cfeed08aSVijay Kumar Srivastava rc = sfc_vdpa_filter_config(ops_data);
486cfeed08aSVijay Kumar Srivastava if (rc != 0) {
487cfeed08aSVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
488cfeed08aSVijay Kumar Srivastava "MAC filter config failed: %s",
489cfeed08aSVijay Kumar Srivastava rte_strerror(rc));
490cfeed08aSVijay Kumar Srivastava goto fail_filter_cfg;
491cfeed08aSVijay Kumar Srivastava }
492cfeed08aSVijay Kumar Srivastava
493b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_STARTED;
494b1196136SVijay Kumar Srivastava
495b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "done");
496b1196136SVijay Kumar Srivastava
497b1196136SVijay Kumar Srivastava return 0;
498b1196136SVijay Kumar Srivastava
499cfeed08aSVijay Kumar Srivastava fail_filter_cfg:
500cfeed08aSVijay Kumar Srivastava /* remove already created filters */
501cfeed08aSVijay Kumar Srivastava sfc_vdpa_filter_remove(ops_data);
502b1196136SVijay Kumar Srivastava fail_vq_start:
503b1196136SVijay Kumar Srivastava /* stop already started virtqueues */
504b1196136SVijay Kumar Srivastava for (j = 0; j < i; j++)
505b1196136SVijay Kumar Srivastava sfc_vdpa_virtq_stop(ops_data, j);
506b1196136SVijay Kumar Srivastava sfc_vdpa_disable_vfio_intr(ops_data);
507b1196136SVijay Kumar Srivastava
508b1196136SVijay Kumar Srivastava fail_enable_vfio_intr:
509b1196136SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_CONFIGURED;
510b1196136SVijay Kumar Srivastava
511b1196136SVijay Kumar Srivastava return rc;
512b1196136SVijay Kumar Srivastava }
513b1196136SVijay Kumar Srivastava
514b1196136SVijay Kumar Srivastava static int
sfc_vdpa_get_queue_num(struct rte_vdpa_device * vdpa_dev,uint32_t * queue_num)515b1196136SVijay Kumar Srivastava sfc_vdpa_get_queue_num(struct rte_vdpa_device *vdpa_dev, uint32_t *queue_num)
516b1196136SVijay Kumar Srivastava {
517b1196136SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
518b1196136SVijay Kumar Srivastava void *dev;
519b1196136SVijay Kumar Srivastava
520b1196136SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
521b1196136SVijay Kumar Srivastava if (ops_data == NULL)
522b1196136SVijay Kumar Srivastava return -1;
523b1196136SVijay Kumar Srivastava
524b1196136SVijay Kumar Srivastava dev = ops_data->dev_handle;
525b1196136SVijay Kumar Srivastava *queue_num = sfc_vdpa_adapter_by_dev_handle(dev)->max_queue_count;
526b1196136SVijay Kumar Srivastava
527b1196136SVijay Kumar Srivastava sfc_vdpa_info(dev, "vDPA ops get_queue_num :: supported queue num : %u",
528b1196136SVijay Kumar Srivastava *queue_num);
529b1196136SVijay Kumar Srivastava
530b1196136SVijay Kumar Srivastava return 0;
531b1196136SVijay Kumar Srivastava }
532b1196136SVijay Kumar Srivastava
533f66a66e6SVijay Kumar Srivastava static int
sfc_vdpa_get_features(struct rte_vdpa_device * vdpa_dev,uint64_t * features)5346dad9a73SVijay Kumar Srivastava sfc_vdpa_get_features(struct rte_vdpa_device *vdpa_dev, uint64_t *features)
5356dad9a73SVijay Kumar Srivastava {
536f66a66e6SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
5376dad9a73SVijay Kumar Srivastava
538f66a66e6SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
539f66a66e6SVijay Kumar Srivastava if (ops_data == NULL)
5406dad9a73SVijay Kumar Srivastava return -1;
541f66a66e6SVijay Kumar Srivastava
542f66a66e6SVijay Kumar Srivastava *features = ops_data->drv_features;
543f66a66e6SVijay Kumar Srivastava
544f66a66e6SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
545f66a66e6SVijay Kumar Srivastava "vDPA ops get_feature :: features : 0x%" PRIx64,
546f66a66e6SVijay Kumar Srivastava *features);
547f66a66e6SVijay Kumar Srivastava
548f66a66e6SVijay Kumar Srivastava return 0;
5496dad9a73SVijay Kumar Srivastava }
5506dad9a73SVijay Kumar Srivastava
5516dad9a73SVijay Kumar Srivastava static int
sfc_vdpa_get_protocol_features(struct rte_vdpa_device * vdpa_dev,uint64_t * features)5526dad9a73SVijay Kumar Srivastava sfc_vdpa_get_protocol_features(struct rte_vdpa_device *vdpa_dev,
5536dad9a73SVijay Kumar Srivastava uint64_t *features)
5546dad9a73SVijay Kumar Srivastava {
555f66a66e6SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
5566dad9a73SVijay Kumar Srivastava
557f66a66e6SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
558f66a66e6SVijay Kumar Srivastava if (ops_data == NULL)
5596dad9a73SVijay Kumar Srivastava return -1;
560f66a66e6SVijay Kumar Srivastava
561f66a66e6SVijay Kumar Srivastava *features = SFC_VDPA_PROTOCOL_FEATURES;
562f66a66e6SVijay Kumar Srivastava
563f66a66e6SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
564f66a66e6SVijay Kumar Srivastava "vDPA ops get_protocol_feature :: features : 0x%" PRIx64,
565f66a66e6SVijay Kumar Srivastava *features);
566f66a66e6SVijay Kumar Srivastava
567f66a66e6SVijay Kumar Srivastava return 0;
5686dad9a73SVijay Kumar Srivastava }
5696dad9a73SVijay Kumar Srivastava
570*a7ba40b2SThomas Monjalon static uint32_t
sfc_vdpa_notify_ctrl(void * arg)571630be406SVijay Kumar Srivastava sfc_vdpa_notify_ctrl(void *arg)
572630be406SVijay Kumar Srivastava {
573630be406SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
574630be406SVijay Kumar Srivastava int vid;
575630be406SVijay Kumar Srivastava
576630be406SVijay Kumar Srivastava ops_data = arg;
577630be406SVijay Kumar Srivastava if (ops_data == NULL)
578*a7ba40b2SThomas Monjalon return 0;
579630be406SVijay Kumar Srivastava
580a3f35d4aSDavid Marchand sfc_vdpa_adapter_lock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
581630be406SVijay Kumar Srivastava
582630be406SVijay Kumar Srivastava vid = ops_data->vid;
583630be406SVijay Kumar Srivastava
584630be406SVijay Kumar Srivastava if (rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, true) != 0)
585630be406SVijay Kumar Srivastava sfc_vdpa_info(ops_data->dev_handle,
586630be406SVijay Kumar Srivastava "vDPA (%s): Notifier could not get configured",
587630be406SVijay Kumar Srivastava ops_data->vdpa_dev->device->name);
588630be406SVijay Kumar Srivastava
589a3f35d4aSDavid Marchand sfc_vdpa_adapter_unlock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
590630be406SVijay Kumar Srivastava
591*a7ba40b2SThomas Monjalon return 0;
592630be406SVijay Kumar Srivastava }
593630be406SVijay Kumar Srivastava
594630be406SVijay Kumar Srivastava static int
sfc_vdpa_setup_notify_ctrl(struct sfc_vdpa_ops_data * ops_data)595630be406SVijay Kumar Srivastava sfc_vdpa_setup_notify_ctrl(struct sfc_vdpa_ops_data *ops_data)
596630be406SVijay Kumar Srivastava {
597630be406SVijay Kumar Srivastava int ret;
598630be406SVijay Kumar Srivastava
599630be406SVijay Kumar Srivastava ops_data->is_notify_thread_started = false;
600630be406SVijay Kumar Srivastava
601630be406SVijay Kumar Srivastava /*
602630be406SVijay Kumar Srivastava * Use rte_vhost_host_notifier_ctrl in a thread to avoid
603630be406SVijay Kumar Srivastava * dead lock scenario when multiple VFs are used in single vdpa
604630be406SVijay Kumar Srivastava * application and multiple VFs are passed to a single VM.
605630be406SVijay Kumar Srivastava */
606*a7ba40b2SThomas Monjalon ret = rte_thread_create_internal_control(&ops_data->notify_tid,
607*a7ba40b2SThomas Monjalon "sfc-vdpa", sfc_vdpa_notify_ctrl, ops_data);
608630be406SVijay Kumar Srivastava if (ret != 0) {
609630be406SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
610630be406SVijay Kumar Srivastava "failed to create notify_ctrl thread: %s",
611630be406SVijay Kumar Srivastava rte_strerror(ret));
612630be406SVijay Kumar Srivastava return -1;
613630be406SVijay Kumar Srivastava }
614630be406SVijay Kumar Srivastava ops_data->is_notify_thread_started = true;
615630be406SVijay Kumar Srivastava
616630be406SVijay Kumar Srivastava return 0;
617630be406SVijay Kumar Srivastava }
618630be406SVijay Kumar Srivastava
6196dad9a73SVijay Kumar Srivastava static int
sfc_vdpa_dev_config(int vid)6206dad9a73SVijay Kumar Srivastava sfc_vdpa_dev_config(int vid)
6216dad9a73SVijay Kumar Srivastava {
622b1196136SVijay Kumar Srivastava struct rte_vdpa_device *vdpa_dev;
623b1196136SVijay Kumar Srivastava int rc;
624b1196136SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
625b1196136SVijay Kumar Srivastava
626b1196136SVijay Kumar Srivastava vdpa_dev = rte_vhost_get_vdpa_device(vid);
627b1196136SVijay Kumar Srivastava
628b1196136SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
629b1196136SVijay Kumar Srivastava if (ops_data == NULL) {
630d8875804SWeiguo Li SFC_VDPA_GENERIC_LOG(ERR,
631b1196136SVijay Kumar Srivastava "invalid vDPA device : %p, vid : %d",
632b1196136SVijay Kumar Srivastava vdpa_dev, vid);
633b1196136SVijay Kumar Srivastava return -1;
634b1196136SVijay Kumar Srivastava }
635b1196136SVijay Kumar Srivastava
636b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "entry");
637b1196136SVijay Kumar Srivastava
638b1196136SVijay Kumar Srivastava ops_data->vid = vid;
639b1196136SVijay Kumar Srivastava
640a3f35d4aSDavid Marchand sfc_vdpa_adapter_lock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
641b1196136SVijay Kumar Srivastava
642b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "configuring");
643b1196136SVijay Kumar Srivastava rc = sfc_vdpa_configure(ops_data);
644b1196136SVijay Kumar Srivastava if (rc != 0)
645b1196136SVijay Kumar Srivastava goto fail_vdpa_config;
646b1196136SVijay Kumar Srivastava
647b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "starting");
648b1196136SVijay Kumar Srivastava rc = sfc_vdpa_start(ops_data);
649b1196136SVijay Kumar Srivastava if (rc != 0)
650b1196136SVijay Kumar Srivastava goto fail_vdpa_start;
651b1196136SVijay Kumar Srivastava
652630be406SVijay Kumar Srivastava rc = sfc_vdpa_setup_notify_ctrl(ops_data);
653630be406SVijay Kumar Srivastava if (rc != 0)
654630be406SVijay Kumar Srivastava goto fail_vdpa_notify;
655b1196136SVijay Kumar Srivastava
656a3f35d4aSDavid Marchand sfc_vdpa_adapter_unlock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
657b1196136SVijay Kumar Srivastava
658b1196136SVijay Kumar Srivastava sfc_vdpa_log_init(ops_data->dev_handle, "done");
659b1196136SVijay Kumar Srivastava
660b1196136SVijay Kumar Srivastava return 0;
661b1196136SVijay Kumar Srivastava
662630be406SVijay Kumar Srivastava fail_vdpa_notify:
663630be406SVijay Kumar Srivastava sfc_vdpa_stop(ops_data);
664630be406SVijay Kumar Srivastava
665b1196136SVijay Kumar Srivastava fail_vdpa_start:
666b1196136SVijay Kumar Srivastava sfc_vdpa_close(ops_data);
667b1196136SVijay Kumar Srivastava
668b1196136SVijay Kumar Srivastava fail_vdpa_config:
669a3f35d4aSDavid Marchand sfc_vdpa_adapter_unlock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
6706dad9a73SVijay Kumar Srivastava
6716dad9a73SVijay Kumar Srivastava return -1;
6726dad9a73SVijay Kumar Srivastava }
6736dad9a73SVijay Kumar Srivastava
6746dad9a73SVijay Kumar Srivastava static int
sfc_vdpa_dev_close(int vid)6756dad9a73SVijay Kumar Srivastava sfc_vdpa_dev_close(int vid)
6766dad9a73SVijay Kumar Srivastava {
677630be406SVijay Kumar Srivastava int ret;
678b1196136SVijay Kumar Srivastava struct rte_vdpa_device *vdpa_dev;
679b1196136SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
6806dad9a73SVijay Kumar Srivastava
681b1196136SVijay Kumar Srivastava vdpa_dev = rte_vhost_get_vdpa_device(vid);
682b1196136SVijay Kumar Srivastava
683b1196136SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
684b1196136SVijay Kumar Srivastava if (ops_data == NULL) {
685d8875804SWeiguo Li SFC_VDPA_GENERIC_LOG(ERR,
686b1196136SVijay Kumar Srivastava "invalid vDPA device : %p, vid : %d",
687b1196136SVijay Kumar Srivastava vdpa_dev, vid);
6886dad9a73SVijay Kumar Srivastava return -1;
6896dad9a73SVijay Kumar Srivastava }
6906dad9a73SVijay Kumar Srivastava
691a3f35d4aSDavid Marchand sfc_vdpa_adapter_lock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
692630be406SVijay Kumar Srivastava if (ops_data->is_notify_thread_started == true) {
693*a7ba40b2SThomas Monjalon ret = pthread_cancel((pthread_t)ops_data->notify_tid.opaque_id);
694630be406SVijay Kumar Srivastava if (ret != 0) {
695630be406SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
696630be406SVijay Kumar Srivastava "failed to cancel notify_ctrl thread: %s",
697630be406SVijay Kumar Srivastava rte_strerror(ret));
698630be406SVijay Kumar Srivastava }
699630be406SVijay Kumar Srivastava
700*a7ba40b2SThomas Monjalon ret = rte_thread_join(ops_data->notify_tid, NULL);
701630be406SVijay Kumar Srivastava if (ret != 0) {
702630be406SVijay Kumar Srivastava sfc_vdpa_err(ops_data->dev_handle,
703630be406SVijay Kumar Srivastava "failed to join terminated notify_ctrl thread: %s",
704630be406SVijay Kumar Srivastava rte_strerror(ret));
705630be406SVijay Kumar Srivastava }
706630be406SVijay Kumar Srivastava }
707630be406SVijay Kumar Srivastava ops_data->is_notify_thread_started = false;
708b1196136SVijay Kumar Srivastava
709b1196136SVijay Kumar Srivastava sfc_vdpa_stop(ops_data);
710b1196136SVijay Kumar Srivastava sfc_vdpa_close(ops_data);
711b1196136SVijay Kumar Srivastava
712a3f35d4aSDavid Marchand sfc_vdpa_adapter_unlock(sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle));
713b1196136SVijay Kumar Srivastava
714b1196136SVijay Kumar Srivastava return 0;
715b1196136SVijay Kumar Srivastava }
716b1196136SVijay Kumar Srivastava
7176dad9a73SVijay Kumar Srivastava static int
sfc_vdpa_set_vring_state(int vid,int vring,int state)7186dad9a73SVijay Kumar Srivastava sfc_vdpa_set_vring_state(int vid, int vring, int state)
7196dad9a73SVijay Kumar Srivastava {
720b3fc3504SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
721b3fc3504SVijay Kumar Srivastava struct rte_vdpa_device *vdpa_dev;
722b3fc3504SVijay Kumar Srivastava efx_rc_t rc;
723b3fc3504SVijay Kumar Srivastava int vring_max;
724b3fc3504SVijay Kumar Srivastava void *dev;
7256dad9a73SVijay Kumar Srivastava
726b3fc3504SVijay Kumar Srivastava vdpa_dev = rte_vhost_get_vdpa_device(vid);
727b3fc3504SVijay Kumar Srivastava
728b3fc3504SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
729b3fc3504SVijay Kumar Srivastava if (ops_data == NULL)
7306dad9a73SVijay Kumar Srivastava return -1;
731b3fc3504SVijay Kumar Srivastava
732b3fc3504SVijay Kumar Srivastava dev = ops_data->dev_handle;
733b3fc3504SVijay Kumar Srivastava
734b3fc3504SVijay Kumar Srivastava sfc_vdpa_info(dev,
735b3fc3504SVijay Kumar Srivastava "vDPA ops set_vring_state: vid: %d, vring: %d, state:%d",
736b3fc3504SVijay Kumar Srivastava vid, vring, state);
737b3fc3504SVijay Kumar Srivastava
738b3fc3504SVijay Kumar Srivastava vring_max = (sfc_vdpa_adapter_by_dev_handle(dev)->max_queue_count * 2);
739b3fc3504SVijay Kumar Srivastava
740b3fc3504SVijay Kumar Srivastava if (vring < 0 || vring > vring_max) {
741b3fc3504SVijay Kumar Srivastava sfc_vdpa_err(dev, "received invalid vring id : %d to set state",
742b3fc3504SVijay Kumar Srivastava vring);
743b3fc3504SVijay Kumar Srivastava return -1;
744b3fc3504SVijay Kumar Srivastava }
745b3fc3504SVijay Kumar Srivastava
746b3fc3504SVijay Kumar Srivastava /*
747b3fc3504SVijay Kumar Srivastava * Skip if device is not yet started. virtqueues state can be
748b3fc3504SVijay Kumar Srivastava * changed once it is created and other configurations are done.
749b3fc3504SVijay Kumar Srivastava */
750b3fc3504SVijay Kumar Srivastava if (ops_data->state != SFC_VDPA_STATE_STARTED)
751b3fc3504SVijay Kumar Srivastava return 0;
752b3fc3504SVijay Kumar Srivastava
753b3fc3504SVijay Kumar Srivastava if (ops_data->vq_cxt[vring].enable == state)
754b3fc3504SVijay Kumar Srivastava return 0;
755b3fc3504SVijay Kumar Srivastava
756b3fc3504SVijay Kumar Srivastava if (state == 0) {
757b3fc3504SVijay Kumar Srivastava rc = sfc_vdpa_virtq_stop(ops_data, vring);
758b3fc3504SVijay Kumar Srivastava if (rc != 0) {
759b3fc3504SVijay Kumar Srivastava sfc_vdpa_err(dev, "virtqueue stop failed: %s",
760b3fc3504SVijay Kumar Srivastava rte_strerror(rc));
761b3fc3504SVijay Kumar Srivastava }
762b3fc3504SVijay Kumar Srivastava } else {
763b3fc3504SVijay Kumar Srivastava rc = sfc_vdpa_virtq_start(ops_data, vring);
764b3fc3504SVijay Kumar Srivastava if (rc != 0) {
765b3fc3504SVijay Kumar Srivastava sfc_vdpa_err(dev, "virtqueue start failed: %s",
766b3fc3504SVijay Kumar Srivastava rte_strerror(rc));
767b3fc3504SVijay Kumar Srivastava }
768b3fc3504SVijay Kumar Srivastava }
769b3fc3504SVijay Kumar Srivastava
770b3fc3504SVijay Kumar Srivastava return rc;
7716dad9a73SVijay Kumar Srivastava }
7726dad9a73SVijay Kumar Srivastava
7736dad9a73SVijay Kumar Srivastava static int
sfc_vdpa_set_features(int vid)7746dad9a73SVijay Kumar Srivastava sfc_vdpa_set_features(int vid)
7756dad9a73SVijay Kumar Srivastava {
7766dad9a73SVijay Kumar Srivastava RTE_SET_USED(vid);
7776dad9a73SVijay Kumar Srivastava
7786dad9a73SVijay Kumar Srivastava return -1;
7796dad9a73SVijay Kumar Srivastava }
7806dad9a73SVijay Kumar Srivastava
781340c4bd0SVijay Kumar Srivastava static int
sfc_vdpa_get_vfio_device_fd(int vid)782340c4bd0SVijay Kumar Srivastava sfc_vdpa_get_vfio_device_fd(int vid)
783340c4bd0SVijay Kumar Srivastava {
784340c4bd0SVijay Kumar Srivastava struct rte_vdpa_device *vdpa_dev;
785340c4bd0SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
786340c4bd0SVijay Kumar Srivastava int vfio_dev_fd;
787340c4bd0SVijay Kumar Srivastava void *dev;
788340c4bd0SVijay Kumar Srivastava
789340c4bd0SVijay Kumar Srivastava vdpa_dev = rte_vhost_get_vdpa_device(vid);
790340c4bd0SVijay Kumar Srivastava
791340c4bd0SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
792340c4bd0SVijay Kumar Srivastava if (ops_data == NULL)
793340c4bd0SVijay Kumar Srivastava return -1;
794340c4bd0SVijay Kumar Srivastava
795340c4bd0SVijay Kumar Srivastava dev = ops_data->dev_handle;
796340c4bd0SVijay Kumar Srivastava vfio_dev_fd = sfc_vdpa_adapter_by_dev_handle(dev)->vfio_dev_fd;
797340c4bd0SVijay Kumar Srivastava
798340c4bd0SVijay Kumar Srivastava sfc_vdpa_info(dev, "vDPA ops get_vfio_device_fd :: vfio fd : %d",
799340c4bd0SVijay Kumar Srivastava vfio_dev_fd);
800340c4bd0SVijay Kumar Srivastava
801340c4bd0SVijay Kumar Srivastava return vfio_dev_fd;
802340c4bd0SVijay Kumar Srivastava }
803340c4bd0SVijay Kumar Srivastava
804630be406SVijay Kumar Srivastava static int
sfc_vdpa_get_notify_area(int vid,int qid,uint64_t * offset,uint64_t * size)805630be406SVijay Kumar Srivastava sfc_vdpa_get_notify_area(int vid, int qid, uint64_t *offset, uint64_t *size)
806630be406SVijay Kumar Srivastava {
807630be406SVijay Kumar Srivastava int ret;
808630be406SVijay Kumar Srivastava efx_nic_t *nic;
809630be406SVijay Kumar Srivastava int vfio_dev_fd;
8102eb13ddeSAbhimanyu Saini volatile void *doorbell;
8112eb13ddeSAbhimanyu Saini struct rte_pci_device *pci_dev;
812630be406SVijay Kumar Srivastava struct rte_vdpa_device *vdpa_dev;
813630be406SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
814630be406SVijay Kumar Srivastava struct vfio_region_info reg = { .argsz = sizeof(reg) };
815630be406SVijay Kumar Srivastava const efx_nic_cfg_t *encp;
816630be406SVijay Kumar Srivastava int max_vring_cnt;
817630be406SVijay Kumar Srivastava int64_t len;
818630be406SVijay Kumar Srivastava void *dev;
819630be406SVijay Kumar Srivastava
820630be406SVijay Kumar Srivastava vdpa_dev = rte_vhost_get_vdpa_device(vid);
821630be406SVijay Kumar Srivastava
822630be406SVijay Kumar Srivastava ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
823630be406SVijay Kumar Srivastava if (ops_data == NULL)
824630be406SVijay Kumar Srivastava return -1;
825630be406SVijay Kumar Srivastava
826630be406SVijay Kumar Srivastava dev = ops_data->dev_handle;
827630be406SVijay Kumar Srivastava
828630be406SVijay Kumar Srivastava vfio_dev_fd = sfc_vdpa_adapter_by_dev_handle(dev)->vfio_dev_fd;
829630be406SVijay Kumar Srivastava max_vring_cnt =
830630be406SVijay Kumar Srivastava (sfc_vdpa_adapter_by_dev_handle(dev)->max_queue_count * 2);
831630be406SVijay Kumar Srivastava
832630be406SVijay Kumar Srivastava nic = sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle)->nic;
833630be406SVijay Kumar Srivastava encp = efx_nic_cfg_get(nic);
834630be406SVijay Kumar Srivastava
835630be406SVijay Kumar Srivastava if (qid >= max_vring_cnt) {
836630be406SVijay Kumar Srivastava sfc_vdpa_err(dev, "invalid qid : %d", qid);
837630be406SVijay Kumar Srivastava return -1;
838630be406SVijay Kumar Srivastava }
839630be406SVijay Kumar Srivastava
840630be406SVijay Kumar Srivastava reg.index = sfc_vdpa_adapter_by_dev_handle(dev)->mem_bar.esb_rid;
841630be406SVijay Kumar Srivastava ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, ®);
842630be406SVijay Kumar Srivastava if (ret != 0) {
843630be406SVijay Kumar Srivastava sfc_vdpa_err(dev, "could not get device region info: %s",
844630be406SVijay Kumar Srivastava strerror(errno));
845630be406SVijay Kumar Srivastava return ret;
846630be406SVijay Kumar Srivastava }
847630be406SVijay Kumar Srivastava
848d9a1ef20SAbhimanyu Saini /* Use bar_offset that was cached during sfc_vdpa_virtq_start() */
849d9a1ef20SAbhimanyu Saini *offset = reg.offset + (uint64_t)ops_data->vq_cxt[qid].doorbell;
850630be406SVijay Kumar Srivastava
851630be406SVijay Kumar Srivastava len = (1U << encp->enc_vi_window_shift) / 2;
852630be406SVijay Kumar Srivastava if (len >= sysconf(_SC_PAGESIZE)) {
853630be406SVijay Kumar Srivastava *size = sysconf(_SC_PAGESIZE);
854630be406SVijay Kumar Srivastava } else {
855630be406SVijay Kumar Srivastava sfc_vdpa_err(dev, "invalid VI window size : 0x%" PRIx64, len);
856630be406SVijay Kumar Srivastava return -1;
857630be406SVijay Kumar Srivastava }
858630be406SVijay Kumar Srivastava
859630be406SVijay Kumar Srivastava sfc_vdpa_info(dev, "vDPA ops get_notify_area :: offset : 0x%" PRIx64,
860630be406SVijay Kumar Srivastava *offset);
861630be406SVijay Kumar Srivastava
8622eb13ddeSAbhimanyu Saini pci_dev = sfc_vdpa_adapter_by_dev_handle(dev)->pdev;
8632eb13ddeSAbhimanyu Saini doorbell = (uint8_t *)pci_dev->mem_resource[reg.index].addr + *offset;
8642eb13ddeSAbhimanyu Saini
8652eb13ddeSAbhimanyu Saini /*
8662eb13ddeSAbhimanyu Saini * virtio-net driver in VM sends queue notifications before
8672eb13ddeSAbhimanyu Saini * vDPA has a chance to setup the queues and notification area,
8682eb13ddeSAbhimanyu Saini * and hence the HW misses these doorbell notifications.
8692eb13ddeSAbhimanyu Saini * Since, it is safe to send duplicate doorbell, send another
8702eb13ddeSAbhimanyu Saini * doorbell from vDPA driver as workaround for this timing issue.
8712eb13ddeSAbhimanyu Saini */
8722eb13ddeSAbhimanyu Saini rte_write16(qid, doorbell);
8732eb13ddeSAbhimanyu Saini
874630be406SVijay Kumar Srivastava return 0;
875630be406SVijay Kumar Srivastava }
876630be406SVijay Kumar Srivastava
8776dad9a73SVijay Kumar Srivastava static struct rte_vdpa_dev_ops sfc_vdpa_ops = {
8786dad9a73SVijay Kumar Srivastava .get_queue_num = sfc_vdpa_get_queue_num,
8796dad9a73SVijay Kumar Srivastava .get_features = sfc_vdpa_get_features,
8806dad9a73SVijay Kumar Srivastava .get_protocol_features = sfc_vdpa_get_protocol_features,
8816dad9a73SVijay Kumar Srivastava .dev_conf = sfc_vdpa_dev_config,
8826dad9a73SVijay Kumar Srivastava .dev_close = sfc_vdpa_dev_close,
8836dad9a73SVijay Kumar Srivastava .set_vring_state = sfc_vdpa_set_vring_state,
8846dad9a73SVijay Kumar Srivastava .set_features = sfc_vdpa_set_features,
885340c4bd0SVijay Kumar Srivastava .get_vfio_device_fd = sfc_vdpa_get_vfio_device_fd,
886630be406SVijay Kumar Srivastava .get_notify_area = sfc_vdpa_get_notify_area,
8876dad9a73SVijay Kumar Srivastava };
8886dad9a73SVijay Kumar Srivastava
8896dad9a73SVijay Kumar Srivastava struct sfc_vdpa_ops_data *
sfc_vdpa_device_init(void * dev_handle,enum sfc_vdpa_context context)8906dad9a73SVijay Kumar Srivastava sfc_vdpa_device_init(void *dev_handle, enum sfc_vdpa_context context)
8916dad9a73SVijay Kumar Srivastava {
8926dad9a73SVijay Kumar Srivastava struct sfc_vdpa_ops_data *ops_data;
8936dad9a73SVijay Kumar Srivastava struct rte_pci_device *pci_dev;
894f66a66e6SVijay Kumar Srivastava int rc;
8956dad9a73SVijay Kumar Srivastava
8966dad9a73SVijay Kumar Srivastava /* Create vDPA ops context */
8976dad9a73SVijay Kumar Srivastava ops_data = rte_zmalloc("vdpa", sizeof(struct sfc_vdpa_ops_data), 0);
8986dad9a73SVijay Kumar Srivastava if (ops_data == NULL)
8996dad9a73SVijay Kumar Srivastava return NULL;
9006dad9a73SVijay Kumar Srivastava
9016dad9a73SVijay Kumar Srivastava ops_data->vdpa_context = context;
9026dad9a73SVijay Kumar Srivastava ops_data->dev_handle = dev_handle;
9036dad9a73SVijay Kumar Srivastava
9046dad9a73SVijay Kumar Srivastava pci_dev = sfc_vdpa_adapter_by_dev_handle(dev_handle)->pdev;
9056dad9a73SVijay Kumar Srivastava
9066dad9a73SVijay Kumar Srivastava /* Register vDPA Device */
9076dad9a73SVijay Kumar Srivastava sfc_vdpa_log_init(dev_handle, "register vDPA device");
9086dad9a73SVijay Kumar Srivastava ops_data->vdpa_dev =
9096dad9a73SVijay Kumar Srivastava rte_vdpa_register_device(&pci_dev->device, &sfc_vdpa_ops);
9106dad9a73SVijay Kumar Srivastava if (ops_data->vdpa_dev == NULL) {
9116dad9a73SVijay Kumar Srivastava sfc_vdpa_err(dev_handle, "vDPA device registration failed");
9126dad9a73SVijay Kumar Srivastava goto fail_register_device;
9136dad9a73SVijay Kumar Srivastava }
9146dad9a73SVijay Kumar Srivastava
915f66a66e6SVijay Kumar Srivastava /* Read supported device features */
916f66a66e6SVijay Kumar Srivastava sfc_vdpa_log_init(dev_handle, "get device feature");
917f66a66e6SVijay Kumar Srivastava rc = sfc_vdpa_get_device_features(ops_data);
918f66a66e6SVijay Kumar Srivastava if (rc != 0)
919f66a66e6SVijay Kumar Srivastava goto fail_get_dev_feature;
920f66a66e6SVijay Kumar Srivastava
921f66a66e6SVijay Kumar Srivastava /* Driver features are superset of device supported feature
922f66a66e6SVijay Kumar Srivastava * and any additional features supported by the driver.
923f66a66e6SVijay Kumar Srivastava */
924f66a66e6SVijay Kumar Srivastava ops_data->drv_features =
925f66a66e6SVijay Kumar Srivastava ops_data->dev_features | SFC_VDPA_DEFAULT_FEATURES;
926f66a66e6SVijay Kumar Srivastava
9276dad9a73SVijay Kumar Srivastava ops_data->state = SFC_VDPA_STATE_INITIALIZED;
9286dad9a73SVijay Kumar Srivastava
9296dad9a73SVijay Kumar Srivastava return ops_data;
9306dad9a73SVijay Kumar Srivastava
931f66a66e6SVijay Kumar Srivastava fail_get_dev_feature:
932f66a66e6SVijay Kumar Srivastava rte_vdpa_unregister_device(ops_data->vdpa_dev);
933f66a66e6SVijay Kumar Srivastava
9346dad9a73SVijay Kumar Srivastava fail_register_device:
9356dad9a73SVijay Kumar Srivastava rte_free(ops_data);
9366dad9a73SVijay Kumar Srivastava return NULL;
9376dad9a73SVijay Kumar Srivastava }
9386dad9a73SVijay Kumar Srivastava
9396dad9a73SVijay Kumar Srivastava void
sfc_vdpa_device_fini(struct sfc_vdpa_ops_data * ops_data)9406dad9a73SVijay Kumar Srivastava sfc_vdpa_device_fini(struct sfc_vdpa_ops_data *ops_data)
9416dad9a73SVijay Kumar Srivastava {
9426dad9a73SVijay Kumar Srivastava rte_vdpa_unregister_device(ops_data->vdpa_dev);
9436dad9a73SVijay Kumar Srivastava
9446dad9a73SVijay Kumar Srivastava rte_free(ops_data);
9456dad9a73SVijay Kumar Srivastava }
946