16afa5a06d45db0d5c05246308695203f2cf1143
[dpdk.git] / drivers / vdpa / sfc / sfc_vdpa_ops.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020-2021 Xilinx, Inc.
3  */
4
5 #include <rte_errno.h>
6 #include <rte_malloc.h>
7 #include <rte_vdpa.h>
8 #include <rte_vhost.h>
9
10 #include <vdpa_driver.h>
11
12 #include "efx.h"
13 #include "sfc_vdpa_ops.h"
14 #include "sfc_vdpa.h"
15
16 /* These protocol features are needed to enable notifier ctrl */
17 #define SFC_VDPA_PROTOCOL_FEATURES \
18                 ((1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
19                  (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ) | \
20                  (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) | \
21                  (1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) | \
22                  (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD))
23
24 /*
25  * Set of features which are enabled by default.
26  * Protocol feature bit is needed to enable notification notifier ctrl.
27  */
28 #define SFC_VDPA_DEFAULT_FEATURES \
29                 (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
30
31 static int
32 sfc_vdpa_get_queue_num(struct rte_vdpa_device *vdpa_dev, uint32_t *queue_num)
33 {
34         RTE_SET_USED(vdpa_dev);
35         RTE_SET_USED(queue_num);
36
37         return -1;
38 }
39
40 static int
41 sfc_vdpa_get_device_features(struct sfc_vdpa_ops_data *ops_data)
42 {
43         int rc;
44         uint64_t dev_features;
45         efx_nic_t *nic;
46
47         nic = sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle)->nic;
48
49         rc = efx_virtio_get_features(nic, EFX_VIRTIO_DEVICE_TYPE_NET,
50                                      &dev_features);
51         if (rc != 0) {
52                 sfc_vdpa_err(ops_data->dev_handle,
53                              "could not read device feature: %s",
54                              rte_strerror(rc));
55                 return rc;
56         }
57
58         ops_data->dev_features = dev_features;
59
60         sfc_vdpa_info(ops_data->dev_handle,
61                       "device supported virtio features : 0x%" PRIx64,
62                       ops_data->dev_features);
63
64         return 0;
65 }
66
67 static int
68 sfc_vdpa_get_features(struct rte_vdpa_device *vdpa_dev, uint64_t *features)
69 {
70         struct sfc_vdpa_ops_data *ops_data;
71
72         ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
73         if (ops_data == NULL)
74                 return -1;
75
76         *features = ops_data->drv_features;
77
78         sfc_vdpa_info(ops_data->dev_handle,
79                       "vDPA ops get_feature :: features : 0x%" PRIx64,
80                       *features);
81
82         return 0;
83 }
84
85 static int
86 sfc_vdpa_get_protocol_features(struct rte_vdpa_device *vdpa_dev,
87                                uint64_t *features)
88 {
89         struct sfc_vdpa_ops_data *ops_data;
90
91         ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
92         if (ops_data == NULL)
93                 return -1;
94
95         *features = SFC_VDPA_PROTOCOL_FEATURES;
96
97         sfc_vdpa_info(ops_data->dev_handle,
98                       "vDPA ops get_protocol_feature :: features : 0x%" PRIx64,
99                       *features);
100
101         return 0;
102 }
103
104 static int
105 sfc_vdpa_dev_config(int vid)
106 {
107         RTE_SET_USED(vid);
108
109         return -1;
110 }
111
112 static int
113 sfc_vdpa_dev_close(int vid)
114 {
115         RTE_SET_USED(vid);
116
117         return -1;
118 }
119
120 static int
121 sfc_vdpa_set_vring_state(int vid, int vring, int state)
122 {
123         RTE_SET_USED(vid);
124         RTE_SET_USED(vring);
125         RTE_SET_USED(state);
126
127         return -1;
128 }
129
130 static int
131 sfc_vdpa_set_features(int vid)
132 {
133         RTE_SET_USED(vid);
134
135         return -1;
136 }
137
138 static struct rte_vdpa_dev_ops sfc_vdpa_ops = {
139         .get_queue_num = sfc_vdpa_get_queue_num,
140         .get_features = sfc_vdpa_get_features,
141         .get_protocol_features = sfc_vdpa_get_protocol_features,
142         .dev_conf = sfc_vdpa_dev_config,
143         .dev_close = sfc_vdpa_dev_close,
144         .set_vring_state = sfc_vdpa_set_vring_state,
145         .set_features = sfc_vdpa_set_features,
146 };
147
148 struct sfc_vdpa_ops_data *
149 sfc_vdpa_device_init(void *dev_handle, enum sfc_vdpa_context context)
150 {
151         struct sfc_vdpa_ops_data *ops_data;
152         struct rte_pci_device *pci_dev;
153         int rc;
154
155         /* Create vDPA ops context */
156         ops_data = rte_zmalloc("vdpa", sizeof(struct sfc_vdpa_ops_data), 0);
157         if (ops_data == NULL)
158                 return NULL;
159
160         ops_data->vdpa_context = context;
161         ops_data->dev_handle = dev_handle;
162
163         pci_dev = sfc_vdpa_adapter_by_dev_handle(dev_handle)->pdev;
164
165         /* Register vDPA Device */
166         sfc_vdpa_log_init(dev_handle, "register vDPA device");
167         ops_data->vdpa_dev =
168                 rte_vdpa_register_device(&pci_dev->device, &sfc_vdpa_ops);
169         if (ops_data->vdpa_dev == NULL) {
170                 sfc_vdpa_err(dev_handle, "vDPA device registration failed");
171                 goto fail_register_device;
172         }
173
174         /* Read supported device features */
175         sfc_vdpa_log_init(dev_handle, "get device feature");
176         rc = sfc_vdpa_get_device_features(ops_data);
177         if (rc != 0)
178                 goto fail_get_dev_feature;
179
180         /* Driver features are superset of device supported feature
181          * and any additional features supported by the driver.
182          */
183         ops_data->drv_features =
184                 ops_data->dev_features | SFC_VDPA_DEFAULT_FEATURES;
185
186         ops_data->state = SFC_VDPA_STATE_INITIALIZED;
187
188         return ops_data;
189
190 fail_get_dev_feature:
191         rte_vdpa_unregister_device(ops_data->vdpa_dev);
192
193 fail_register_device:
194         rte_free(ops_data);
195         return NULL;
196 }
197
198 void
199 sfc_vdpa_device_fini(struct sfc_vdpa_ops_data *ops_data)
200 {
201         rte_vdpa_unregister_device(ops_data->vdpa_dev);
202
203         rte_free(ops_data);
204 }