1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2020 Mellanox Technologies Ltd. */
3
4 #include <linux/vdpa.h>
5 #include <uapi/linux/virtio_ids.h>
6 #include <linux/virtio_config.h>
7 #include <linux/mlx5/qp.h>
8 #include <linux/mlx5/device.h>
9 #include <linux/mlx5/vport.h>
10 #include <linux/mlx5/fs.h>
11 #include <linux/mlx5/device.h>
12 #include <linux/mlx5/mpfs.h>
13 #include "mlx5_vnet.h"
14 #include "mlx5_vdpa_ifc.h"
15 #include "mlx5_vdpa.h"
16
17 #define to_mvdev(__vdev) container_of((__vdev), struct mlx5_vdpa_dev, vdev)
18
19 #define VALID_FEATURES_MASK \
20 (BIT_ULL(VIRTIO_NET_F_CSUM) | BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) | \
21 BIT_ULL(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) | BIT_ULL(VIRTIO_NET_F_MTU) | BIT_ULL(VIRTIO_NET_F_MAC) | \
22 BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) | BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) | \
23 BIT_ULL(VIRTIO_NET_F_GUEST_ECN) | BIT_ULL(VIRTIO_NET_F_GUEST_UFO) | BIT_ULL(VIRTIO_NET_F_HOST_TSO4) | \
24 BIT_ULL(VIRTIO_NET_F_HOST_TSO6) | BIT_ULL(VIRTIO_NET_F_HOST_ECN) | BIT_ULL(VIRTIO_NET_F_HOST_UFO) | \
25 BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | BIT_ULL(VIRTIO_NET_F_STATUS) | BIT_ULL(VIRTIO_NET_F_CTRL_VQ) | \
26 BIT_ULL(VIRTIO_NET_F_CTRL_RX) | BIT_ULL(VIRTIO_NET_F_CTRL_VLAN) | \
27 BIT_ULL(VIRTIO_NET_F_CTRL_RX_EXTRA) | BIT_ULL(VIRTIO_NET_F_GUEST_ANNOUNCE) | \
28 BIT_ULL(VIRTIO_NET_F_MQ) | BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) | BIT_ULL(VIRTIO_NET_F_HASH_REPORT) | \
29 BIT_ULL(VIRTIO_NET_F_RSS) | BIT_ULL(VIRTIO_NET_F_RSC_EXT) | BIT_ULL(VIRTIO_NET_F_STANDBY) | \
30 BIT_ULL(VIRTIO_NET_F_SPEED_DUPLEX) | BIT_ULL(VIRTIO_F_NOTIFY_ON_EMPTY) | \
31 BIT_ULL(VIRTIO_F_ANY_LAYOUT) | BIT_ULL(VIRTIO_F_VERSION_1) | BIT_ULL(VIRTIO_F_ACCESS_PLATFORM) | \
32 BIT_ULL(VIRTIO_F_RING_PACKED) | BIT_ULL(VIRTIO_F_ORDER_PLATFORM) | BIT_ULL(VIRTIO_F_SR_IOV))
33
34 #define VALID_STATUS_MASK \
35 (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK | \
36 VIRTIO_CONFIG_S_FEATURES_OK | VIRTIO_CONFIG_S_NEEDS_RESET | VIRTIO_CONFIG_S_FAILED)
37
38 struct mlx5_vdpa_net_resources {
39 u32 tisn;
40 u32 tdn;
41 u32 tirn;
42 u32 rqtn;
43 bool valid;
44 };
45
46 struct mlx5_vdpa_cq_buf {
47 struct mlx5_frag_buf_ctrl fbc;
48 struct mlx5_frag_buf frag_buf;
49 int cqe_size;
50 int nent;
51 };
52
53 struct mlx5_vdpa_cq {
54 struct mlx5_core_cq mcq;
55 struct mlx5_vdpa_cq_buf buf;
56 struct mlx5_db db;
57 int cqe;
58 };
59
60 struct mlx5_vdpa_umem {
61 struct mlx5_frag_buf_ctrl fbc;
62 struct mlx5_frag_buf frag_buf;
63 int size;
64 u32 id;
65 };
66
67 struct mlx5_vdpa_qp {
68 struct mlx5_core_qp mqp;
69 struct mlx5_frag_buf frag_buf;
70 struct mlx5_db db;
71 u16 head;
72 bool fw;
73 };
74
75 struct mlx5_vq_restore_info {
76 u32 num_ent;
77 u64 desc_addr;
78 u64 device_addr;
79 u64 driver_addr;
80 u16 avail_index;
81 u16 used_index;
82 bool ready;
83 struct vdpa_callback cb;
84 bool restore;
85 };
86
87 struct mlx5_vdpa_virtqueue {
88 bool ready;
89 u64 desc_addr;
90 u64 device_addr;
91 u64 driver_addr;
92 u32 num_ent;
93 struct vdpa_callback event_cb;
94
95 /* Resources for implementing the notification channel from the device
96 * to the driver. fwqp is the firmware end of an RC connection; the
97 * other end is vqqp used by the driver. cq is is where completions are
98 * reported.
99 */
100 struct mlx5_vdpa_cq cq;
101 struct mlx5_vdpa_qp fwqp;
102 struct mlx5_vdpa_qp vqqp;
103
104 /* umem resources are required for the virtqueue operation. They're use
105 * is internal and they must be provided by the driver.
106 */
107 struct mlx5_vdpa_umem umem1;
108 struct mlx5_vdpa_umem umem2;
109 struct mlx5_vdpa_umem umem3;
110
111 bool initialized;
112 int index;
113 u32 virtq_id;
114 struct mlx5_vdpa_net *ndev;
115 u16 avail_idx;
116 u16 used_idx;
117 int fw_state;
118
119 /* keep last in the struct */
120 struct mlx5_vq_restore_info ri;
121 };
122
123 /* We will remove this limitation once mlx5_vdpa_alloc_resources()
124 * provides for driver space allocation
125 */
126 #define MLX5_MAX_SUPPORTED_VQS 16
127
128 struct mlx5_vdpa_net {
129 struct mlx5_vdpa_dev mvdev;
130 struct mlx5_vdpa_net_resources res;
131 struct virtio_net_config config;
132 struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS];
133
134 /* Serialize vq resources creation and destruction. This is required
135 * since memory map might change and we need to destroy and create
136 * resources while driver in operational.
137 */
138 struct mutex reslock;
139 struct mlx5_flow_table *rxft;
140 struct mlx5_fc *rx_counter;
141 struct mlx5_flow_handle *rx_rule;
142 bool setup;
143 u16 mtu;
144 };
145
146 static void free_resources(struct mlx5_vdpa_net *ndev);
147 static void init_mvqs(struct mlx5_vdpa_net *ndev);
148 static int setup_driver(struct mlx5_vdpa_net *ndev);
149 static void teardown_driver(struct mlx5_vdpa_net *ndev);
150
151 static bool mlx5_vdpa_debug;
152
153 #define MLX5_LOG_VIO_FLAG(_feature) \
154 do { \
155 if (features & BIT_ULL(_feature)) \
156 mlx5_vdpa_info(mvdev, "%s\n", #_feature); \
157 } while (0)
158
159 #define MLX5_LOG_VIO_STAT(_status) \
160 do { \
161 if (status & (_status)) \
162 mlx5_vdpa_info(mvdev, "%s\n", #_status); \
163 } while (0)
164
print_status(struct mlx5_vdpa_dev * mvdev,u8 status,bool set)165 static void print_status(struct mlx5_vdpa_dev *mvdev, u8 status, bool set)
166 {
167 if (status & ~VALID_STATUS_MASK)
168 mlx5_vdpa_warn(mvdev, "Warning: there are invalid status bits 0x%x\n",
169 status & ~VALID_STATUS_MASK);
170
171 if (!mlx5_vdpa_debug)
172 return;
173
174 mlx5_vdpa_info(mvdev, "driver status %s", set ? "set" : "get");
175 if (set && !status) {
176 mlx5_vdpa_info(mvdev, "driver resets the device\n");
177 return;
178 }
179
180 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_ACKNOWLEDGE);
181 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_DRIVER);
182 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_DRIVER_OK);
183 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_FEATURES_OK);
184 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_NEEDS_RESET);
185 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_FAILED);
186 }
187
print_features(struct mlx5_vdpa_dev * mvdev,u64 features,bool set)188 static void print_features(struct mlx5_vdpa_dev *mvdev, u64 features, bool set)
189 {
190 if (features & ~VALID_FEATURES_MASK)
191 mlx5_vdpa_warn(mvdev, "There are invalid feature bits 0x%llx\n",
192 features & ~VALID_FEATURES_MASK);
193
194 if (!mlx5_vdpa_debug)
195 return;
196
197 mlx5_vdpa_info(mvdev, "driver %s feature bits:\n", set ? "sets" : "reads");
198 if (!features)
199 mlx5_vdpa_info(mvdev, "all feature bits are cleared\n");
200
201 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CSUM);
202 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_CSUM);
203 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS);
204 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MTU);
205 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MAC);
206 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_TSO4);
207 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_TSO6);
208 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_ECN);
209 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_UFO);
210 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_TSO4);
211 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_TSO6);
212 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_ECN);
213 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_UFO);
214 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MRG_RXBUF);
215 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_STATUS);
216 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_VQ);
217 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_RX);
218 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_VLAN);
219 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_RX_EXTRA);
220 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_ANNOUNCE);
221 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MQ);
222 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_MAC_ADDR);
223 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HASH_REPORT);
224 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_RSS);
225 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_RSC_EXT);
226 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_STANDBY);
227 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_SPEED_DUPLEX);
228 MLX5_LOG_VIO_FLAG(VIRTIO_F_NOTIFY_ON_EMPTY);
229 MLX5_LOG_VIO_FLAG(VIRTIO_F_ANY_LAYOUT);
230 MLX5_LOG_VIO_FLAG(VIRTIO_F_VERSION_1);
231 MLX5_LOG_VIO_FLAG(VIRTIO_F_ACCESS_PLATFORM);
232 MLX5_LOG_VIO_FLAG(VIRTIO_F_RING_PACKED);
233 MLX5_LOG_VIO_FLAG(VIRTIO_F_ORDER_PLATFORM);
234 MLX5_LOG_VIO_FLAG(VIRTIO_F_SR_IOV);
235 }
236
create_tis(struct mlx5_vdpa_net * ndev)237 static int create_tis(struct mlx5_vdpa_net *ndev)
238 {
239 struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
240 u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
241 void *tisc;
242 int err;
243
244 tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
245 MLX5_SET(tisc, tisc, transport_domain, ndev->res.tdn);
246 err = mlx5_vdpa_create_tis(mvdev, in, &ndev->res.tisn);
247 if (err)
248 mlx5_vdpa_warn(mvdev, "create TIS (%d)\n", err);
249
250 return err;
251 }
252
destroy_tis(struct mlx5_vdpa_net * ndev)253 static void destroy_tis(struct mlx5_vdpa_net *ndev)
254 {
255 mlx5_vdpa_destroy_tis(&ndev->mvdev, ndev->res.tisn);
256 }
257
258 #define MLX5_VDPA_CQE_SIZE 64
259 #define MLX5_VDPA_LOG_CQE_SIZE ilog2(MLX5_VDPA_CQE_SIZE)
260
cq_frag_buf_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_cq_buf * buf,int nent)261 static int cq_frag_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_cq_buf *buf, int nent)
262 {
263 struct mlx5_frag_buf *frag_buf = &buf->frag_buf;
264 u8 log_wq_stride = MLX5_VDPA_LOG_CQE_SIZE;
265 u8 log_wq_sz = MLX5_VDPA_LOG_CQE_SIZE;
266 int err;
267
268 err = mlx5_frag_buf_alloc_node(ndev->mvdev.mdev, nent * MLX5_VDPA_CQE_SIZE, frag_buf,
269 ndev->mvdev.mdev->priv.numa_node);
270 if (err)
271 return err;
272
273 mlx5_init_fbc(frag_buf->frags, log_wq_stride, log_wq_sz, &buf->fbc);
274
275 buf->cqe_size = MLX5_VDPA_CQE_SIZE;
276 buf->nent = nent;
277
278 return 0;
279 }
280
umem_frag_buf_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_umem * umem,int size)281 static int umem_frag_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_umem *umem, int size)
282 {
283 struct mlx5_frag_buf *frag_buf = &umem->frag_buf;
284
285 return mlx5_frag_buf_alloc_node(ndev->mvdev.mdev, size, frag_buf,
286 ndev->mvdev.mdev->priv.numa_node);
287 }
288
cq_frag_buf_free(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_cq_buf * buf)289 static void cq_frag_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_cq_buf *buf)
290 {
291 mlx5_frag_buf_free(ndev->mvdev.mdev, &buf->frag_buf);
292 }
293
get_cqe(struct mlx5_vdpa_cq * vcq,int n)294 static void *get_cqe(struct mlx5_vdpa_cq *vcq, int n)
295 {
296 return mlx5_frag_buf_get_wqe(&vcq->buf.fbc, n);
297 }
298
cq_frag_buf_init(struct mlx5_vdpa_cq * vcq,struct mlx5_vdpa_cq_buf * buf)299 static void cq_frag_buf_init(struct mlx5_vdpa_cq *vcq, struct mlx5_vdpa_cq_buf *buf)
300 {
301 struct mlx5_cqe64 *cqe64;
302 void *cqe;
303 int i;
304
305 for (i = 0; i < buf->nent; i++) {
306 cqe = get_cqe(vcq, i);
307 cqe64 = cqe;
308 cqe64->op_own = MLX5_CQE_INVALID << 4;
309 }
310 }
311
get_sw_cqe(struct mlx5_vdpa_cq * cq,int n)312 static void *get_sw_cqe(struct mlx5_vdpa_cq *cq, int n)
313 {
314 struct mlx5_cqe64 *cqe64 = get_cqe(cq, n & (cq->cqe - 1));
315
316 if (likely(get_cqe_opcode(cqe64) != MLX5_CQE_INVALID) &&
317 !((cqe64->op_own & MLX5_CQE_OWNER_MASK) ^ !!(n & cq->cqe)))
318 return cqe64;
319
320 return NULL;
321 }
322
rx_post(struct mlx5_vdpa_qp * vqp,int n)323 static void rx_post(struct mlx5_vdpa_qp *vqp, int n)
324 {
325 vqp->head += n;
326 vqp->db.db[0] = cpu_to_be32(vqp->head);
327 }
328
qp_prepare(struct mlx5_vdpa_net * ndev,bool fw,void * in,struct mlx5_vdpa_virtqueue * mvq,u32 num_ent)329 static void qp_prepare(struct mlx5_vdpa_net *ndev, bool fw, void *in,
330 struct mlx5_vdpa_virtqueue *mvq, u32 num_ent)
331 {
332 struct mlx5_vdpa_qp *vqp;
333 __be64 *pas;
334 void *qpc;
335
336 vqp = fw ? &mvq->fwqp : &mvq->vqqp;
337 MLX5_SET(create_qp_in, in, uid, ndev->mvdev.res.uid);
338 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
339 if (vqp->fw) {
340 /* Firmware QP is allocated by the driver for the firmware's
341 * use so we can skip part of the params as they will be chosen by firmware
342 */
343 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
344 MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
345 MLX5_SET(qpc, qpc, no_sq, 1);
346 return;
347 }
348
349 MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
350 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
351 MLX5_SET(qpc, qpc, pd, ndev->mvdev.res.pdn);
352 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
353 MLX5_SET(qpc, qpc, uar_page, ndev->mvdev.res.uar->index);
354 MLX5_SET(qpc, qpc, log_page_size, vqp->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
355 MLX5_SET(qpc, qpc, no_sq, 1);
356 MLX5_SET(qpc, qpc, cqn_rcv, mvq->cq.mcq.cqn);
357 MLX5_SET(qpc, qpc, log_rq_size, ilog2(num_ent));
358 MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ);
359 pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, in, pas);
360 mlx5_fill_page_frag_array(&vqp->frag_buf, pas);
361 }
362
rq_buf_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_qp * vqp,u32 num_ent)363 static int rq_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp, u32 num_ent)
364 {
365 return mlx5_frag_buf_alloc_node(ndev->mvdev.mdev,
366 num_ent * sizeof(struct mlx5_wqe_data_seg), &vqp->frag_buf,
367 ndev->mvdev.mdev->priv.numa_node);
368 }
369
rq_buf_free(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_qp * vqp)370 static void rq_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp)
371 {
372 mlx5_frag_buf_free(ndev->mvdev.mdev, &vqp->frag_buf);
373 }
374
qp_create(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,struct mlx5_vdpa_qp * vqp)375 static int qp_create(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
376 struct mlx5_vdpa_qp *vqp)
377 {
378 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
379 int inlen = MLX5_ST_SZ_BYTES(create_qp_in);
380 u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};
381 void *qpc;
382 void *in;
383 int err;
384
385 if (!vqp->fw) {
386 vqp = &mvq->vqqp;
387 err = rq_buf_alloc(ndev, vqp, mvq->num_ent);
388 if (err)
389 return err;
390
391 err = mlx5_db_alloc(ndev->mvdev.mdev, &vqp->db);
392 if (err)
393 goto err_db;
394 inlen += vqp->frag_buf.npages * sizeof(__be64);
395 }
396
397 in = kzalloc(inlen, GFP_KERNEL);
398 if (!in) {
399 err = -ENOMEM;
400 goto err_kzalloc;
401 }
402
403 qp_prepare(ndev, vqp->fw, in, mvq, mvq->num_ent);
404 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
405 MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
406 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
407 MLX5_SET(qpc, qpc, pd, ndev->mvdev.res.pdn);
408 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
409 if (!vqp->fw)
410 MLX5_SET64(qpc, qpc, dbr_addr, vqp->db.dma);
411 MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
412 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
413 kfree(in);
414 if (err)
415 goto err_kzalloc;
416
417 vqp->mqp.uid = ndev->mvdev.res.uid;
418 vqp->mqp.qpn = MLX5_GET(create_qp_out, out, qpn);
419
420 if (!vqp->fw)
421 rx_post(vqp, mvq->num_ent);
422
423 return 0;
424
425 err_kzalloc:
426 if (!vqp->fw)
427 mlx5_db_free(ndev->mvdev.mdev, &vqp->db);
428 err_db:
429 if (!vqp->fw)
430 rq_buf_free(ndev, vqp);
431
432 return err;
433 }
434
qp_destroy(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_qp * vqp)435 static void qp_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp)
436 {
437 u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {};
438
439 MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
440 MLX5_SET(destroy_qp_in, in, qpn, vqp->mqp.qpn);
441 MLX5_SET(destroy_qp_in, in, uid, ndev->mvdev.res.uid);
442 if (mlx5_cmd_exec_in(ndev->mvdev.mdev, destroy_qp, in))
443 mlx5_vdpa_warn(&ndev->mvdev, "destroy qp 0x%x\n", vqp->mqp.qpn);
444 if (!vqp->fw) {
445 mlx5_db_free(ndev->mvdev.mdev, &vqp->db);
446 rq_buf_free(ndev, vqp);
447 }
448 }
449
next_cqe_sw(struct mlx5_vdpa_cq * cq)450 static void *next_cqe_sw(struct mlx5_vdpa_cq *cq)
451 {
452 return get_sw_cqe(cq, cq->mcq.cons_index);
453 }
454
mlx5_vdpa_poll_one(struct mlx5_vdpa_cq * vcq)455 static int mlx5_vdpa_poll_one(struct mlx5_vdpa_cq *vcq)
456 {
457 struct mlx5_cqe64 *cqe64;
458
459 cqe64 = next_cqe_sw(vcq);
460 if (!cqe64)
461 return -EAGAIN;
462
463 vcq->mcq.cons_index++;
464 return 0;
465 }
466
mlx5_vdpa_handle_completions(struct mlx5_vdpa_virtqueue * mvq,int num)467 static void mlx5_vdpa_handle_completions(struct mlx5_vdpa_virtqueue *mvq, int num)
468 {
469 mlx5_cq_set_ci(&mvq->cq.mcq);
470
471 /* make sure CQ cosumer update is visible to the hardware before updating
472 * RX doorbell record.
473 */
474 dma_wmb();
475 rx_post(&mvq->vqqp, num);
476 if (mvq->event_cb.callback)
477 mvq->event_cb.callback(mvq->event_cb.private);
478 }
479
mlx5_vdpa_cq_comp(struct mlx5_core_cq * mcq,struct mlx5_eqe * eqe)480 static void mlx5_vdpa_cq_comp(struct mlx5_core_cq *mcq, struct mlx5_eqe *eqe)
481 {
482 struct mlx5_vdpa_virtqueue *mvq = container_of(mcq, struct mlx5_vdpa_virtqueue, cq.mcq);
483 struct mlx5_vdpa_net *ndev = mvq->ndev;
484 void __iomem *uar_page = ndev->mvdev.res.uar->map;
485 int num = 0;
486
487 while (!mlx5_vdpa_poll_one(&mvq->cq)) {
488 num++;
489 if (num > mvq->num_ent / 2) {
490 /* If completions keep coming while we poll, we want to
491 * let the hardware know that we consumed them by
492 * updating the doorbell record. We also let vdpa core
493 * know about this so it passes it on the virtio driver
494 * on the guest.
495 */
496 mlx5_vdpa_handle_completions(mvq, num);
497 num = 0;
498 }
499 }
500
501 if (num)
502 mlx5_vdpa_handle_completions(mvq, num);
503
504 mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
505 }
506
cq_create(struct mlx5_vdpa_net * ndev,u16 idx,u32 num_ent)507 static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
508 {
509 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
510 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
511 void __iomem *uar_page = ndev->mvdev.res.uar->map;
512 u32 out[MLX5_ST_SZ_DW(create_cq_out)];
513 struct mlx5_vdpa_cq *vcq = &mvq->cq;
514 __be64 *pas;
515 int inlen;
516 void *cqc;
517 void *in;
518 int err;
519 int eqn;
520
521 err = mlx5_db_alloc(mdev, &vcq->db);
522 if (err)
523 return err;
524
525 vcq->mcq.set_ci_db = vcq->db.db;
526 vcq->mcq.arm_db = vcq->db.db + 1;
527 vcq->mcq.cqe_sz = 64;
528
529 err = cq_frag_buf_alloc(ndev, &vcq->buf, num_ent);
530 if (err)
531 goto err_db;
532
533 cq_frag_buf_init(vcq, &vcq->buf);
534
535 inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
536 MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * vcq->buf.frag_buf.npages;
537 in = kzalloc(inlen, GFP_KERNEL);
538 if (!in) {
539 err = -ENOMEM;
540 goto err_vzalloc;
541 }
542
543 MLX5_SET(create_cq_in, in, uid, ndev->mvdev.res.uid);
544 pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas);
545 mlx5_fill_page_frag_array(&vcq->buf.frag_buf, pas);
546
547 cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
548 MLX5_SET(cqc, cqc, log_page_size, vcq->buf.frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
549
550 /* Use vector 0 by default. Consider adding code to choose least used
551 * vector.
552 */
553 err = mlx5_vector2eqn(mdev, 0, &eqn);
554 if (err)
555 goto err_vec;
556
557 cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
558 MLX5_SET(cqc, cqc, log_cq_size, ilog2(num_ent));
559 MLX5_SET(cqc, cqc, uar_page, ndev->mvdev.res.uar->index);
560 MLX5_SET(cqc, cqc, c_eqn, eqn);
561 MLX5_SET64(cqc, cqc, dbr_addr, vcq->db.dma);
562
563 err = mlx5_core_create_cq(mdev, &vcq->mcq, in, inlen, out, sizeof(out));
564 if (err)
565 goto err_vec;
566
567 vcq->mcq.comp = mlx5_vdpa_cq_comp;
568 vcq->cqe = num_ent;
569 vcq->mcq.set_ci_db = vcq->db.db;
570 vcq->mcq.arm_db = vcq->db.db + 1;
571 mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
572 kfree(in);
573 return 0;
574
575 err_vec:
576 kfree(in);
577 err_vzalloc:
578 cq_frag_buf_free(ndev, &vcq->buf);
579 err_db:
580 mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
581 return err;
582 }
583
cq_destroy(struct mlx5_vdpa_net * ndev,u16 idx)584 static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 idx)
585 {
586 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
587 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
588 struct mlx5_vdpa_cq *vcq = &mvq->cq;
589
590 if (mlx5_core_destroy_cq(mdev, &vcq->mcq)) {
591 mlx5_vdpa_warn(&ndev->mvdev, "destroy CQ 0x%x\n", vcq->mcq.cqn);
592 return;
593 }
594 cq_frag_buf_free(ndev, &vcq->buf);
595 mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
596 }
597
set_umem_size(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int num,struct mlx5_vdpa_umem ** umemp)598 static void set_umem_size(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num,
599 struct mlx5_vdpa_umem **umemp)
600 {
601 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
602 int p_a;
603 int p_b;
604
605 switch (num) {
606 case 1:
607 p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_a);
608 p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_b);
609 *umemp = &mvq->umem1;
610 break;
611 case 2:
612 p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_a);
613 p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_b);
614 *umemp = &mvq->umem2;
615 break;
616 case 3:
617 p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_a);
618 p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_b);
619 *umemp = &mvq->umem3;
620 break;
621 }
622 (*umemp)->size = p_a * mvq->num_ent + p_b;
623 }
624
umem_frag_buf_free(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_umem * umem)625 static void umem_frag_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_umem *umem)
626 {
627 mlx5_frag_buf_free(ndev->mvdev.mdev, &umem->frag_buf);
628 }
629
create_umem(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int num)630 static int create_umem(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num)
631 {
632 int inlen;
633 u32 out[MLX5_ST_SZ_DW(create_umem_out)] = {};
634 void *um;
635 void *in;
636 int err;
637 __be64 *pas;
638 struct mlx5_vdpa_umem *umem;
639
640 set_umem_size(ndev, mvq, num, &umem);
641 err = umem_frag_buf_alloc(ndev, umem, umem->size);
642 if (err)
643 return err;
644
645 inlen = MLX5_ST_SZ_BYTES(create_umem_in) + MLX5_ST_SZ_BYTES(mtt) * umem->frag_buf.npages;
646
647 in = kzalloc(inlen, GFP_KERNEL);
648 if (!in) {
649 err = -ENOMEM;
650 goto err_in;
651 }
652
653 MLX5_SET(create_umem_in, in, opcode, MLX5_CMD_OP_CREATE_UMEM);
654 MLX5_SET(create_umem_in, in, uid, ndev->mvdev.res.uid);
655 um = MLX5_ADDR_OF(create_umem_in, in, umem);
656 MLX5_SET(umem, um, log_page_size, umem->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
657 MLX5_SET64(umem, um, num_of_mtt, umem->frag_buf.npages);
658
659 pas = (__be64 *)MLX5_ADDR_OF(umem, um, mtt[0]);
660 mlx5_fill_page_frag_array_perm(&umem->frag_buf, pas, MLX5_MTT_PERM_RW);
661
662 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
663 if (err) {
664 mlx5_vdpa_warn(&ndev->mvdev, "create umem(%d)\n", err);
665 goto err_cmd;
666 }
667
668 kfree(in);
669 umem->id = MLX5_GET(create_umem_out, out, umem_id);
670
671 return 0;
672
673 err_cmd:
674 kfree(in);
675 err_in:
676 umem_frag_buf_free(ndev, umem);
677 return err;
678 }
679
umem_destroy(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int num)680 static void umem_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num)
681 {
682 u32 in[MLX5_ST_SZ_DW(destroy_umem_in)] = {};
683 u32 out[MLX5_ST_SZ_DW(destroy_umem_out)] = {};
684 struct mlx5_vdpa_umem *umem;
685
686 switch (num) {
687 case 1:
688 umem = &mvq->umem1;
689 break;
690 case 2:
691 umem = &mvq->umem2;
692 break;
693 case 3:
694 umem = &mvq->umem3;
695 break;
696 }
697
698 MLX5_SET(destroy_umem_in, in, opcode, MLX5_CMD_OP_DESTROY_UMEM);
699 MLX5_SET(destroy_umem_in, in, umem_id, umem->id);
700 if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out)))
701 return;
702
703 umem_frag_buf_free(ndev, umem);
704 }
705
umems_create(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)706 static int umems_create(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
707 {
708 int num;
709 int err;
710
711 for (num = 1; num <= 3; num++) {
712 err = create_umem(ndev, mvq, num);
713 if (err)
714 goto err_umem;
715 }
716 return 0;
717
718 err_umem:
719 for (num--; num > 0; num--)
720 umem_destroy(ndev, mvq, num);
721
722 return err;
723 }
724
umems_destroy(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)725 static void umems_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
726 {
727 int num;
728
729 for (num = 3; num > 0; num--)
730 umem_destroy(ndev, mvq, num);
731 }
732
get_queue_type(struct mlx5_vdpa_net * ndev)733 static int get_queue_type(struct mlx5_vdpa_net *ndev)
734 {
735 u32 type_mask;
736
737 type_mask = MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, virtio_queue_type);
738
739 /* prefer split queue */
740 if (type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED)
741 return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED;
742
743 WARN_ON(!(type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT));
744
745 return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT;
746 }
747
vq_is_tx(u16 idx)748 static bool vq_is_tx(u16 idx)
749 {
750 return idx % 2;
751 }
752
get_features_12_3(u64 features)753 static u16 get_features_12_3(u64 features)
754 {
755 return (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_TSO4)) << 9) |
756 (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_TSO6)) << 8) |
757 (!!(features & BIT_ULL(VIRTIO_NET_F_CSUM)) << 7) |
758 (!!(features & BIT_ULL(VIRTIO_NET_F_GUEST_CSUM)) << 6);
759 }
760
create_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)761 static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
762 {
763 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
764 u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
765 void *obj_context;
766 void *cmd_hdr;
767 void *vq_ctx;
768 void *in;
769 int err;
770
771 err = umems_create(ndev, mvq);
772 if (err)
773 return err;
774
775 in = kzalloc(inlen, GFP_KERNEL);
776 if (!in) {
777 err = -ENOMEM;
778 goto err_alloc;
779 }
780
781 cmd_hdr = MLX5_ADDR_OF(create_virtio_net_q_in, in, general_obj_in_cmd_hdr);
782
783 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
784 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
785 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
786
787 obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context);
788 MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx);
789 MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx);
790 MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3,
791 get_features_12_3(ndev->mvdev.actual_features));
792 vq_ctx = MLX5_ADDR_OF(virtio_net_q_object, obj_context, virtio_q_context);
793 MLX5_SET(virtio_q, vq_ctx, virtio_q_type, get_queue_type(ndev));
794
795 if (vq_is_tx(mvq->index))
796 MLX5_SET(virtio_net_q_object, obj_context, tisn_or_qpn, ndev->res.tisn);
797
798 MLX5_SET(virtio_q, vq_ctx, event_mode, MLX5_VIRTIO_Q_EVENT_MODE_QP_MODE);
799 MLX5_SET(virtio_q, vq_ctx, queue_index, mvq->index);
800 MLX5_SET(virtio_q, vq_ctx, event_qpn_or_msix, mvq->fwqp.mqp.qpn);
801 MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent);
802 MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0,
803 !!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_F_VERSION_1)));
804 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
805 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
806 MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
807 MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr.mkey.key);
808 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
809 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
810 MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
811 MLX5_SET(virtio_q, vq_ctx, umem_2_size, mvq->umem2.size);
812 MLX5_SET(virtio_q, vq_ctx, umem_3_id, mvq->umem3.id);
813 MLX5_SET(virtio_q, vq_ctx, umem_3_size, mvq->umem3.size);
814 MLX5_SET(virtio_q, vq_ctx, pd, ndev->mvdev.res.pdn);
815
816 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
817 if (err)
818 goto err_cmd;
819
820 kfree(in);
821 mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
822
823 return 0;
824
825 err_cmd:
826 kfree(in);
827 err_alloc:
828 umems_destroy(ndev, mvq);
829 return err;
830 }
831
destroy_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)832 static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
833 {
834 u32 in[MLX5_ST_SZ_DW(destroy_virtio_net_q_in)] = {};
835 u32 out[MLX5_ST_SZ_DW(destroy_virtio_net_q_out)] = {};
836
837 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.opcode,
838 MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
839 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_id, mvq->virtq_id);
840 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.uid, ndev->mvdev.res.uid);
841 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_type,
842 MLX5_OBJ_TYPE_VIRTIO_NET_Q);
843 if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out))) {
844 mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
845 return;
846 }
847 umems_destroy(ndev, mvq);
848 }
849
get_rqpn(struct mlx5_vdpa_virtqueue * mvq,bool fw)850 static u32 get_rqpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
851 {
852 return fw ? mvq->vqqp.mqp.qpn : mvq->fwqp.mqp.qpn;
853 }
854
get_qpn(struct mlx5_vdpa_virtqueue * mvq,bool fw)855 static u32 get_qpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
856 {
857 return fw ? mvq->fwqp.mqp.qpn : mvq->vqqp.mqp.qpn;
858 }
859
alloc_inout(struct mlx5_vdpa_net * ndev,int cmd,void ** in,int * inlen,void ** out,int * outlen,u32 qpn,u32 rqpn)860 static void alloc_inout(struct mlx5_vdpa_net *ndev, int cmd, void **in, int *inlen, void **out,
861 int *outlen, u32 qpn, u32 rqpn)
862 {
863 void *qpc;
864 void *pp;
865
866 switch (cmd) {
867 case MLX5_CMD_OP_2RST_QP:
868 *inlen = MLX5_ST_SZ_BYTES(qp_2rst_in);
869 *outlen = MLX5_ST_SZ_BYTES(qp_2rst_out);
870 *in = kzalloc(*inlen, GFP_KERNEL);
871 *out = kzalloc(*outlen, GFP_KERNEL);
872 if (!*in || !*out)
873 goto outerr;
874
875 MLX5_SET(qp_2rst_in, *in, opcode, cmd);
876 MLX5_SET(qp_2rst_in, *in, uid, ndev->mvdev.res.uid);
877 MLX5_SET(qp_2rst_in, *in, qpn, qpn);
878 break;
879 case MLX5_CMD_OP_RST2INIT_QP:
880 *inlen = MLX5_ST_SZ_BYTES(rst2init_qp_in);
881 *outlen = MLX5_ST_SZ_BYTES(rst2init_qp_out);
882 *in = kzalloc(*inlen, GFP_KERNEL);
883 *out = kzalloc(MLX5_ST_SZ_BYTES(rst2init_qp_out), GFP_KERNEL);
884 if (!*in || !*out)
885 goto outerr;
886
887 MLX5_SET(rst2init_qp_in, *in, opcode, cmd);
888 MLX5_SET(rst2init_qp_in, *in, uid, ndev->mvdev.res.uid);
889 MLX5_SET(rst2init_qp_in, *in, qpn, qpn);
890 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
891 MLX5_SET(qpc, qpc, remote_qpn, rqpn);
892 MLX5_SET(qpc, qpc, rwe, 1);
893 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
894 MLX5_SET(ads, pp, vhca_port_num, 1);
895 break;
896 case MLX5_CMD_OP_INIT2RTR_QP:
897 *inlen = MLX5_ST_SZ_BYTES(init2rtr_qp_in);
898 *outlen = MLX5_ST_SZ_BYTES(init2rtr_qp_out);
899 *in = kzalloc(*inlen, GFP_KERNEL);
900 *out = kzalloc(MLX5_ST_SZ_BYTES(init2rtr_qp_out), GFP_KERNEL);
901 if (!*in || !*out)
902 goto outerr;
903
904 MLX5_SET(init2rtr_qp_in, *in, opcode, cmd);
905 MLX5_SET(init2rtr_qp_in, *in, uid, ndev->mvdev.res.uid);
906 MLX5_SET(init2rtr_qp_in, *in, qpn, qpn);
907 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
908 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
909 MLX5_SET(qpc, qpc, log_msg_max, 30);
910 MLX5_SET(qpc, qpc, remote_qpn, rqpn);
911 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
912 MLX5_SET(ads, pp, fl, 1);
913 break;
914 case MLX5_CMD_OP_RTR2RTS_QP:
915 *inlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_in);
916 *outlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_out);
917 *in = kzalloc(*inlen, GFP_KERNEL);
918 *out = kzalloc(MLX5_ST_SZ_BYTES(rtr2rts_qp_out), GFP_KERNEL);
919 if (!*in || !*out)
920 goto outerr;
921
922 MLX5_SET(rtr2rts_qp_in, *in, opcode, cmd);
923 MLX5_SET(rtr2rts_qp_in, *in, uid, ndev->mvdev.res.uid);
924 MLX5_SET(rtr2rts_qp_in, *in, qpn, qpn);
925 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
926 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
927 MLX5_SET(ads, pp, ack_timeout, 14);
928 MLX5_SET(qpc, qpc, retry_count, 7);
929 MLX5_SET(qpc, qpc, rnr_retry, 7);
930 break;
931 default:
932 goto outerr_nullify;
933 }
934
935 return;
936
937 outerr:
938 kfree(*in);
939 kfree(*out);
940 outerr_nullify:
941 *in = NULL;
942 *out = NULL;
943 }
944
free_inout(void * in,void * out)945 static void free_inout(void *in, void *out)
946 {
947 kfree(in);
948 kfree(out);
949 }
950
951 /* Two QPs are used by each virtqueue. One is used by the driver and one by
952 * firmware. The fw argument indicates whether the subjected QP is the one used
953 * by firmware.
954 */
modify_qp(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,bool fw,int cmd)955 static int modify_qp(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, bool fw, int cmd)
956 {
957 int outlen;
958 int inlen;
959 void *out;
960 void *in;
961 int err;
962
963 alloc_inout(ndev, cmd, &in, &inlen, &out, &outlen, get_qpn(mvq, fw), get_rqpn(mvq, fw));
964 if (!in || !out)
965 return -ENOMEM;
966
967 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, outlen);
968 free_inout(in, out);
969 return err;
970 }
971
connect_qps(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)972 static int connect_qps(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
973 {
974 int err;
975
976 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_2RST_QP);
977 if (err)
978 return err;
979
980 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_2RST_QP);
981 if (err)
982 return err;
983
984 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_RST2INIT_QP);
985 if (err)
986 return err;
987
988 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_RST2INIT_QP);
989 if (err)
990 return err;
991
992 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_INIT2RTR_QP);
993 if (err)
994 return err;
995
996 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_INIT2RTR_QP);
997 if (err)
998 return err;
999
1000 return modify_qp(ndev, mvq, true, MLX5_CMD_OP_RTR2RTS_QP);
1001 }
1002
1003 struct mlx5_virtq_attr {
1004 u8 state;
1005 u16 available_index;
1006 u16 used_index;
1007 };
1008
query_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,struct mlx5_virtq_attr * attr)1009 static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
1010 struct mlx5_virtq_attr *attr)
1011 {
1012 int outlen = MLX5_ST_SZ_BYTES(query_virtio_net_q_out);
1013 u32 in[MLX5_ST_SZ_DW(query_virtio_net_q_in)] = {};
1014 void *out;
1015 void *obj_context;
1016 void *cmd_hdr;
1017 int err;
1018
1019 out = kzalloc(outlen, GFP_KERNEL);
1020 if (!out)
1021 return -ENOMEM;
1022
1023 cmd_hdr = MLX5_ADDR_OF(query_virtio_net_q_in, in, general_obj_in_cmd_hdr);
1024
1025 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
1026 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1027 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1028 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1029 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, outlen);
1030 if (err)
1031 goto err_cmd;
1032
1033 obj_context = MLX5_ADDR_OF(query_virtio_net_q_out, out, obj_context);
1034 memset(attr, 0, sizeof(*attr));
1035 attr->state = MLX5_GET(virtio_net_q_object, obj_context, state);
1036 attr->available_index = MLX5_GET(virtio_net_q_object, obj_context, hw_available_index);
1037 attr->used_index = MLX5_GET(virtio_net_q_object, obj_context, hw_used_index);
1038 kfree(out);
1039 return 0;
1040
1041 err_cmd:
1042 kfree(out);
1043 return err;
1044 }
1045
modify_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int state)1046 static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
1047 {
1048 int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
1049 u32 out[MLX5_ST_SZ_DW(modify_virtio_net_q_out)] = {};
1050 void *obj_context;
1051 void *cmd_hdr;
1052 void *in;
1053 int err;
1054
1055 in = kzalloc(inlen, GFP_KERNEL);
1056 if (!in)
1057 return -ENOMEM;
1058
1059 cmd_hdr = MLX5_ADDR_OF(modify_virtio_net_q_in, in, general_obj_in_cmd_hdr);
1060
1061 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
1062 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1063 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1064 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1065
1066 obj_context = MLX5_ADDR_OF(modify_virtio_net_q_in, in, obj_context);
1067 MLX5_SET64(virtio_net_q_object, obj_context, modify_field_select,
1068 MLX5_VIRTQ_MODIFY_MASK_STATE);
1069 MLX5_SET(virtio_net_q_object, obj_context, state, state);
1070 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
1071 kfree(in);
1072 if (!err)
1073 mvq->fw_state = state;
1074
1075 return err;
1076 }
1077
setup_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1078 static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1079 {
1080 u16 idx = mvq->index;
1081 int err;
1082
1083 if (!mvq->num_ent)
1084 return 0;
1085
1086 if (mvq->initialized) {
1087 mlx5_vdpa_warn(&ndev->mvdev, "attempt re init\n");
1088 return -EINVAL;
1089 }
1090
1091 err = cq_create(ndev, idx, mvq->num_ent);
1092 if (err)
1093 return err;
1094
1095 err = qp_create(ndev, mvq, &mvq->fwqp);
1096 if (err)
1097 goto err_fwqp;
1098
1099 err = qp_create(ndev, mvq, &mvq->vqqp);
1100 if (err)
1101 goto err_vqqp;
1102
1103 err = connect_qps(ndev, mvq);
1104 if (err)
1105 goto err_connect;
1106
1107 err = create_virtqueue(ndev, mvq);
1108 if (err)
1109 goto err_connect;
1110
1111 if (mvq->ready) {
1112 err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
1113 if (err) {
1114 mlx5_vdpa_warn(&ndev->mvdev, "failed to modify to ready vq idx %d(%d)\n",
1115 idx, err);
1116 goto err_connect;
1117 }
1118 }
1119
1120 mvq->initialized = true;
1121 return 0;
1122
1123 err_connect:
1124 qp_destroy(ndev, &mvq->vqqp);
1125 err_vqqp:
1126 qp_destroy(ndev, &mvq->fwqp);
1127 err_fwqp:
1128 cq_destroy(ndev, idx);
1129 return err;
1130 }
1131
suspend_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1132 static void suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1133 {
1134 struct mlx5_virtq_attr attr;
1135
1136 if (!mvq->initialized)
1137 return;
1138
1139 if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY)
1140 return;
1141
1142 if (modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND))
1143 mlx5_vdpa_warn(&ndev->mvdev, "modify to suspend failed\n");
1144
1145 if (query_virtqueue(ndev, mvq, &attr)) {
1146 mlx5_vdpa_warn(&ndev->mvdev, "failed to query virtqueue\n");
1147 return;
1148 }
1149 mvq->avail_idx = attr.available_index;
1150 mvq->used_idx = attr.used_index;
1151 }
1152
suspend_vqs(struct mlx5_vdpa_net * ndev)1153 static void suspend_vqs(struct mlx5_vdpa_net *ndev)
1154 {
1155 int i;
1156
1157 for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++)
1158 suspend_vq(ndev, &ndev->vqs[i]);
1159 }
1160
teardown_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1161 static void teardown_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1162 {
1163 if (!mvq->initialized)
1164 return;
1165
1166 suspend_vq(ndev, mvq);
1167 destroy_virtqueue(ndev, mvq);
1168 qp_destroy(ndev, &mvq->vqqp);
1169 qp_destroy(ndev, &mvq->fwqp);
1170 cq_destroy(ndev, mvq->index);
1171 mvq->initialized = false;
1172 }
1173
create_rqt(struct mlx5_vdpa_net * ndev)1174 static int create_rqt(struct mlx5_vdpa_net *ndev)
1175 {
1176 int log_max_rqt;
1177 __be32 *list;
1178 void *rqtc;
1179 int inlen;
1180 void *in;
1181 int i, j;
1182 int err;
1183
1184 log_max_rqt = min_t(int, 1, MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size));
1185 if (log_max_rqt < 1)
1186 return -EOPNOTSUPP;
1187
1188 inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + (1 << log_max_rqt) * MLX5_ST_SZ_BYTES(rq_num);
1189 in = kzalloc(inlen, GFP_KERNEL);
1190 if (!in)
1191 return -ENOMEM;
1192
1193 MLX5_SET(create_rqt_in, in, uid, ndev->mvdev.res.uid);
1194 rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
1195
1196 MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q);
1197 MLX5_SET(rqtc, rqtc, rqt_max_size, 1 << log_max_rqt);
1198 MLX5_SET(rqtc, rqtc, rqt_actual_size, 1);
1199 list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]);
1200 for (i = 0, j = 0; j < ndev->mvdev.max_vqs; j++) {
1201 if (!ndev->vqs[j].initialized)
1202 continue;
1203
1204 if (!vq_is_tx(ndev->vqs[j].index)) {
1205 list[i] = cpu_to_be32(ndev->vqs[j].virtq_id);
1206 i++;
1207 }
1208 }
1209
1210 err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);
1211 kfree(in);
1212 if (err)
1213 return err;
1214
1215 return 0;
1216 }
1217
destroy_rqt(struct mlx5_vdpa_net * ndev)1218 static void destroy_rqt(struct mlx5_vdpa_net *ndev)
1219 {
1220 mlx5_vdpa_destroy_rqt(&ndev->mvdev, ndev->res.rqtn);
1221 }
1222
create_tir(struct mlx5_vdpa_net * ndev)1223 static int create_tir(struct mlx5_vdpa_net *ndev)
1224 {
1225 #define HASH_IP_L4PORTS \
1226 (MLX5_HASH_FIELD_SEL_SRC_IP | MLX5_HASH_FIELD_SEL_DST_IP | MLX5_HASH_FIELD_SEL_L4_SPORT | \
1227 MLX5_HASH_FIELD_SEL_L4_DPORT)
1228 static const u8 rx_hash_toeplitz_key[] = { 0x2c, 0xc6, 0x81, 0xd1, 0x5b, 0xdb, 0xf4, 0xf7,
1229 0xfc, 0xa2, 0x83, 0x19, 0xdb, 0x1a, 0x3e, 0x94,
1230 0x6b, 0x9e, 0x38, 0xd9, 0x2c, 0x9c, 0x03, 0xd1,
1231 0xad, 0x99, 0x44, 0xa7, 0xd9, 0x56, 0x3d, 0x59,
1232 0x06, 0x3c, 0x25, 0xf3, 0xfc, 0x1f, 0xdc, 0x2a };
1233 void *rss_key;
1234 void *outer;
1235 void *tirc;
1236 void *in;
1237 int err;
1238
1239 in = kzalloc(MLX5_ST_SZ_BYTES(create_tir_in), GFP_KERNEL);
1240 if (!in)
1241 return -ENOMEM;
1242
1243 MLX5_SET(create_tir_in, in, uid, ndev->mvdev.res.uid);
1244 tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
1245 MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
1246
1247 MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
1248 MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_TOEPLITZ);
1249 rss_key = MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
1250 memcpy(rss_key, rx_hash_toeplitz_key, sizeof(rx_hash_toeplitz_key));
1251
1252 outer = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
1253 MLX5_SET(rx_hash_field_select, outer, l3_prot_type, MLX5_L3_PROT_TYPE_IPV4);
1254 MLX5_SET(rx_hash_field_select, outer, l4_prot_type, MLX5_L4_PROT_TYPE_TCP);
1255 MLX5_SET(rx_hash_field_select, outer, selected_fields, HASH_IP_L4PORTS);
1256
1257 MLX5_SET(tirc, tirc, indirect_table, ndev->res.rqtn);
1258 MLX5_SET(tirc, tirc, transport_domain, ndev->res.tdn);
1259
1260 err = mlx5_vdpa_create_tir(&ndev->mvdev, in, &ndev->res.tirn);
1261 kfree(in);
1262 return err;
1263 }
1264
destroy_tir(struct mlx5_vdpa_net * ndev)1265 static void destroy_tir(struct mlx5_vdpa_net *ndev)
1266 {
1267 mlx5_vdpa_destroy_tir(&ndev->mvdev, ndev->res.tirn);
1268 }
1269
add_fwd_to_tir(struct mlx5_vdpa_net * ndev)1270 static int add_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1271 {
1272 struct mlx5_flow_destination dest[2] = {};
1273 struct mlx5_flow_table_attr ft_attr = {};
1274 struct mlx5_flow_act flow_act = {};
1275 struct mlx5_flow_namespace *ns;
1276 int err;
1277
1278 /* for now, one entry, match all, forward to tir */
1279 ft_attr.max_fte = 1;
1280 ft_attr.autogroup.max_num_groups = 1;
1281
1282 ns = mlx5_get_flow_namespace(ndev->mvdev.mdev, MLX5_FLOW_NAMESPACE_BYPASS);
1283 if (!ns) {
1284 mlx5_vdpa_warn(&ndev->mvdev, "get flow namespace\n");
1285 return -EOPNOTSUPP;
1286 }
1287
1288 ndev->rxft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
1289 if (IS_ERR(ndev->rxft))
1290 return PTR_ERR(ndev->rxft);
1291
1292 ndev->rx_counter = mlx5_fc_create(ndev->mvdev.mdev, false);
1293 if (IS_ERR(ndev->rx_counter)) {
1294 err = PTR_ERR(ndev->rx_counter);
1295 goto err_fc;
1296 }
1297
1298 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_COUNT;
1299 dest[0].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1300 dest[0].tir_num = ndev->res.tirn;
1301 dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1302 dest[1].counter_id = mlx5_fc_id(ndev->rx_counter);
1303 ndev->rx_rule = mlx5_add_flow_rules(ndev->rxft, NULL, &flow_act, dest, 2);
1304 if (IS_ERR(ndev->rx_rule)) {
1305 err = PTR_ERR(ndev->rx_rule);
1306 ndev->rx_rule = NULL;
1307 goto err_rule;
1308 }
1309
1310 return 0;
1311
1312 err_rule:
1313 mlx5_fc_destroy(ndev->mvdev.mdev, ndev->rx_counter);
1314 err_fc:
1315 mlx5_destroy_flow_table(ndev->rxft);
1316 return err;
1317 }
1318
remove_fwd_to_tir(struct mlx5_vdpa_net * ndev)1319 static void remove_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1320 {
1321 if (!ndev->rx_rule)
1322 return;
1323
1324 mlx5_del_flow_rules(ndev->rx_rule);
1325 mlx5_fc_destroy(ndev->mvdev.mdev, ndev->rx_counter);
1326 mlx5_destroy_flow_table(ndev->rxft);
1327
1328 ndev->rx_rule = NULL;
1329 }
1330
mlx5_vdpa_kick_vq(struct vdpa_device * vdev,u16 idx)1331 static void mlx5_vdpa_kick_vq(struct vdpa_device *vdev, u16 idx)
1332 {
1333 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1334 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1335 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1336
1337 if (unlikely(!mvq->ready))
1338 return;
1339
1340 iowrite16(idx, ndev->mvdev.res.kick_addr);
1341 }
1342
mlx5_vdpa_set_vq_address(struct vdpa_device * vdev,u16 idx,u64 desc_area,u64 driver_area,u64 device_area)1343 static int mlx5_vdpa_set_vq_address(struct vdpa_device *vdev, u16 idx, u64 desc_area,
1344 u64 driver_area, u64 device_area)
1345 {
1346 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1347 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1348 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1349
1350 mvq->desc_addr = desc_area;
1351 mvq->device_addr = device_area;
1352 mvq->driver_addr = driver_area;
1353 return 0;
1354 }
1355
mlx5_vdpa_set_vq_num(struct vdpa_device * vdev,u16 idx,u32 num)1356 static void mlx5_vdpa_set_vq_num(struct vdpa_device *vdev, u16 idx, u32 num)
1357 {
1358 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1359 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1360 struct mlx5_vdpa_virtqueue *mvq;
1361
1362 mvq = &ndev->vqs[idx];
1363 mvq->num_ent = num;
1364 }
1365
mlx5_vdpa_set_vq_cb(struct vdpa_device * vdev,u16 idx,struct vdpa_callback * cb)1366 static void mlx5_vdpa_set_vq_cb(struct vdpa_device *vdev, u16 idx, struct vdpa_callback *cb)
1367 {
1368 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1369 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1370 struct mlx5_vdpa_virtqueue *vq = &ndev->vqs[idx];
1371
1372 vq->event_cb = *cb;
1373 }
1374
mlx5_vdpa_set_vq_ready(struct vdpa_device * vdev,u16 idx,bool ready)1375 static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready)
1376 {
1377 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1378 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1379 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1380
1381 if (!ready)
1382 suspend_vq(ndev, mvq);
1383
1384 mvq->ready = ready;
1385 }
1386
mlx5_vdpa_get_vq_ready(struct vdpa_device * vdev,u16 idx)1387 static bool mlx5_vdpa_get_vq_ready(struct vdpa_device *vdev, u16 idx)
1388 {
1389 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1390 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1391 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1392
1393 return mvq->ready;
1394 }
1395
mlx5_vdpa_set_vq_state(struct vdpa_device * vdev,u16 idx,const struct vdpa_vq_state * state)1396 static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx,
1397 const struct vdpa_vq_state *state)
1398 {
1399 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1400 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1401 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1402
1403 if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY) {
1404 mlx5_vdpa_warn(mvdev, "can't modify available index\n");
1405 return -EINVAL;
1406 }
1407
1408 mvq->used_idx = state->avail_index;
1409 mvq->avail_idx = state->avail_index;
1410 return 0;
1411 }
1412
mlx5_vdpa_get_vq_state(struct vdpa_device * vdev,u16 idx,struct vdpa_vq_state * state)1413 static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa_vq_state *state)
1414 {
1415 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1416 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1417 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1418 struct mlx5_virtq_attr attr;
1419 int err;
1420
1421 /* If the virtq object was destroyed, use the value saved at
1422 * the last minute of suspend_vq. This caters for userspace
1423 * that cares about emulating the index after vq is stopped.
1424 */
1425 if (!mvq->initialized) {
1426 /* Firmware returns a wrong value for the available index.
1427 * Since both values should be identical, we take the value of
1428 * used_idx which is reported correctly.
1429 */
1430 state->avail_index = mvq->used_idx;
1431 return 0;
1432 }
1433
1434 err = query_virtqueue(ndev, mvq, &attr);
1435 if (err) {
1436 mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n");
1437 return err;
1438 }
1439 state->avail_index = attr.used_index;
1440 return 0;
1441 }
1442
mlx5_vdpa_get_vq_align(struct vdpa_device * vdev)1443 static u32 mlx5_vdpa_get_vq_align(struct vdpa_device *vdev)
1444 {
1445 return PAGE_SIZE;
1446 }
1447
1448 enum { MLX5_VIRTIO_NET_F_GUEST_CSUM = 1 << 9,
1449 MLX5_VIRTIO_NET_F_CSUM = 1 << 10,
1450 MLX5_VIRTIO_NET_F_HOST_TSO6 = 1 << 11,
1451 MLX5_VIRTIO_NET_F_HOST_TSO4 = 1 << 12,
1452 };
1453
mlx_to_vritio_features(u16 dev_features)1454 static u64 mlx_to_vritio_features(u16 dev_features)
1455 {
1456 u64 result = 0;
1457
1458 if (dev_features & MLX5_VIRTIO_NET_F_GUEST_CSUM)
1459 result |= BIT_ULL(VIRTIO_NET_F_GUEST_CSUM);
1460 if (dev_features & MLX5_VIRTIO_NET_F_CSUM)
1461 result |= BIT_ULL(VIRTIO_NET_F_CSUM);
1462 if (dev_features & MLX5_VIRTIO_NET_F_HOST_TSO6)
1463 result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO6);
1464 if (dev_features & MLX5_VIRTIO_NET_F_HOST_TSO4)
1465 result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO4);
1466
1467 return result;
1468 }
1469
mlx5_vdpa_get_features(struct vdpa_device * vdev)1470 static u64 mlx5_vdpa_get_features(struct vdpa_device *vdev)
1471 {
1472 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1473 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1474 u16 dev_features;
1475
1476 dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, device_features_bits_mask);
1477 ndev->mvdev.mlx_features = mlx_to_vritio_features(dev_features);
1478 if (MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, virtio_version_1_0))
1479 ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_VERSION_1);
1480 ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM);
1481 print_features(mvdev, ndev->mvdev.mlx_features, false);
1482 return ndev->mvdev.mlx_features;
1483 }
1484
verify_min_features(struct mlx5_vdpa_dev * mvdev,u64 features)1485 static int verify_min_features(struct mlx5_vdpa_dev *mvdev, u64 features)
1486 {
1487 if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)))
1488 return -EOPNOTSUPP;
1489
1490 return 0;
1491 }
1492
setup_virtqueues(struct mlx5_vdpa_net * ndev)1493 static int setup_virtqueues(struct mlx5_vdpa_net *ndev)
1494 {
1495 int err;
1496 int i;
1497
1498 for (i = 0; i < 2 * mlx5_vdpa_max_qps(ndev->mvdev.max_vqs); i++) {
1499 err = setup_vq(ndev, &ndev->vqs[i]);
1500 if (err)
1501 goto err_vq;
1502 }
1503
1504 return 0;
1505
1506 err_vq:
1507 for (--i; i >= 0; i--)
1508 teardown_vq(ndev, &ndev->vqs[i]);
1509
1510 return err;
1511 }
1512
teardown_virtqueues(struct mlx5_vdpa_net * ndev)1513 static void teardown_virtqueues(struct mlx5_vdpa_net *ndev)
1514 {
1515 struct mlx5_vdpa_virtqueue *mvq;
1516 int i;
1517
1518 for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) {
1519 mvq = &ndev->vqs[i];
1520 if (!mvq->initialized)
1521 continue;
1522
1523 teardown_vq(ndev, mvq);
1524 }
1525 }
1526
1527 /* TODO: cross-endian support */
mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev * mvdev)1528 static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
1529 {
1530 return virtio_legacy_is_little_endian() ||
1531 (mvdev->actual_features & BIT_ULL(VIRTIO_F_VERSION_1));
1532 }
1533
cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev * mvdev,u16 val)1534 static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val)
1535 {
1536 return __cpu_to_virtio16(mlx5_vdpa_is_little_endian(mvdev), val);
1537 }
1538
mlx5_vdpa_set_features(struct vdpa_device * vdev,u64 features)1539 static int mlx5_vdpa_set_features(struct vdpa_device *vdev, u64 features)
1540 {
1541 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1542 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1543 int err;
1544
1545 print_features(mvdev, features, true);
1546
1547 err = verify_min_features(mvdev, features);
1548 if (err)
1549 return err;
1550
1551 ndev->mvdev.actual_features = features & ndev->mvdev.mlx_features;
1552 ndev->config.mtu = cpu_to_mlx5vdpa16(mvdev, ndev->mtu);
1553 ndev->config.status |= cpu_to_mlx5vdpa16(mvdev, VIRTIO_NET_S_LINK_UP);
1554 return err;
1555 }
1556
mlx5_vdpa_set_config_cb(struct vdpa_device * vdev,struct vdpa_callback * cb)1557 static void mlx5_vdpa_set_config_cb(struct vdpa_device *vdev, struct vdpa_callback *cb)
1558 {
1559 /* not implemented */
1560 mlx5_vdpa_warn(to_mvdev(vdev), "set config callback not supported\n");
1561 }
1562
1563 #define MLX5_VDPA_MAX_VQ_ENTRIES 256
mlx5_vdpa_get_vq_num_max(struct vdpa_device * vdev)1564 static u16 mlx5_vdpa_get_vq_num_max(struct vdpa_device *vdev)
1565 {
1566 return MLX5_VDPA_MAX_VQ_ENTRIES;
1567 }
1568
mlx5_vdpa_get_device_id(struct vdpa_device * vdev)1569 static u32 mlx5_vdpa_get_device_id(struct vdpa_device *vdev)
1570 {
1571 return VIRTIO_ID_NET;
1572 }
1573
mlx5_vdpa_get_vendor_id(struct vdpa_device * vdev)1574 static u32 mlx5_vdpa_get_vendor_id(struct vdpa_device *vdev)
1575 {
1576 return PCI_VENDOR_ID_MELLANOX;
1577 }
1578
mlx5_vdpa_get_status(struct vdpa_device * vdev)1579 static u8 mlx5_vdpa_get_status(struct vdpa_device *vdev)
1580 {
1581 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1582 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1583
1584 print_status(mvdev, ndev->mvdev.status, false);
1585 return ndev->mvdev.status;
1586 }
1587
save_channel_info(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1588 static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1589 {
1590 struct mlx5_vq_restore_info *ri = &mvq->ri;
1591 struct mlx5_virtq_attr attr;
1592 int err;
1593
1594 if (!mvq->initialized)
1595 return 0;
1596
1597 err = query_virtqueue(ndev, mvq, &attr);
1598 if (err)
1599 return err;
1600
1601 ri->avail_index = attr.available_index;
1602 ri->used_index = attr.used_index;
1603 ri->ready = mvq->ready;
1604 ri->num_ent = mvq->num_ent;
1605 ri->desc_addr = mvq->desc_addr;
1606 ri->device_addr = mvq->device_addr;
1607 ri->driver_addr = mvq->driver_addr;
1608 ri->cb = mvq->event_cb;
1609 ri->restore = true;
1610 return 0;
1611 }
1612
save_channels_info(struct mlx5_vdpa_net * ndev)1613 static int save_channels_info(struct mlx5_vdpa_net *ndev)
1614 {
1615 int i;
1616
1617 for (i = 0; i < ndev->mvdev.max_vqs; i++) {
1618 memset(&ndev->vqs[i].ri, 0, sizeof(ndev->vqs[i].ri));
1619 save_channel_info(ndev, &ndev->vqs[i]);
1620 }
1621 return 0;
1622 }
1623
mlx5_clear_vqs(struct mlx5_vdpa_net * ndev)1624 static void mlx5_clear_vqs(struct mlx5_vdpa_net *ndev)
1625 {
1626 int i;
1627
1628 for (i = 0; i < ndev->mvdev.max_vqs; i++)
1629 memset(&ndev->vqs[i], 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1630 }
1631
restore_channels_info(struct mlx5_vdpa_net * ndev)1632 static void restore_channels_info(struct mlx5_vdpa_net *ndev)
1633 {
1634 struct mlx5_vdpa_virtqueue *mvq;
1635 struct mlx5_vq_restore_info *ri;
1636 int i;
1637
1638 mlx5_clear_vqs(ndev);
1639 init_mvqs(ndev);
1640 for (i = 0; i < ndev->mvdev.max_vqs; i++) {
1641 mvq = &ndev->vqs[i];
1642 ri = &mvq->ri;
1643 if (!ri->restore)
1644 continue;
1645
1646 mvq->avail_idx = ri->avail_index;
1647 mvq->used_idx = ri->used_index;
1648 mvq->ready = ri->ready;
1649 mvq->num_ent = ri->num_ent;
1650 mvq->desc_addr = ri->desc_addr;
1651 mvq->device_addr = ri->device_addr;
1652 mvq->driver_addr = ri->driver_addr;
1653 mvq->event_cb = ri->cb;
1654 }
1655 }
1656
mlx5_vdpa_change_map(struct mlx5_vdpa_net * ndev,struct vhost_iotlb * iotlb)1657 static int mlx5_vdpa_change_map(struct mlx5_vdpa_net *ndev, struct vhost_iotlb *iotlb)
1658 {
1659 int err;
1660
1661 suspend_vqs(ndev);
1662 err = save_channels_info(ndev);
1663 if (err)
1664 goto err_mr;
1665
1666 teardown_driver(ndev);
1667 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1668 err = mlx5_vdpa_create_mr(&ndev->mvdev, iotlb);
1669 if (err)
1670 goto err_mr;
1671
1672 if (!(ndev->mvdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
1673 return 0;
1674
1675 restore_channels_info(ndev);
1676 err = setup_driver(ndev);
1677 if (err)
1678 goto err_setup;
1679
1680 return 0;
1681
1682 err_setup:
1683 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1684 err_mr:
1685 return err;
1686 }
1687
setup_driver(struct mlx5_vdpa_net * ndev)1688 static int setup_driver(struct mlx5_vdpa_net *ndev)
1689 {
1690 int err;
1691
1692 mutex_lock(&ndev->reslock);
1693 if (ndev->setup) {
1694 mlx5_vdpa_warn(&ndev->mvdev, "setup driver called for already setup driver\n");
1695 err = 0;
1696 goto out;
1697 }
1698 err = setup_virtqueues(ndev);
1699 if (err) {
1700 mlx5_vdpa_warn(&ndev->mvdev, "setup_virtqueues\n");
1701 goto out;
1702 }
1703
1704 err = create_rqt(ndev);
1705 if (err) {
1706 mlx5_vdpa_warn(&ndev->mvdev, "create_rqt\n");
1707 goto err_rqt;
1708 }
1709
1710 err = create_tir(ndev);
1711 if (err) {
1712 mlx5_vdpa_warn(&ndev->mvdev, "create_tir\n");
1713 goto err_tir;
1714 }
1715
1716 err = add_fwd_to_tir(ndev);
1717 if (err) {
1718 mlx5_vdpa_warn(&ndev->mvdev, "add_fwd_to_tir\n");
1719 goto err_fwd;
1720 }
1721 ndev->setup = true;
1722 mutex_unlock(&ndev->reslock);
1723
1724 return 0;
1725
1726 err_fwd:
1727 destroy_tir(ndev);
1728 err_tir:
1729 destroy_rqt(ndev);
1730 err_rqt:
1731 teardown_virtqueues(ndev);
1732 out:
1733 mutex_unlock(&ndev->reslock);
1734 return err;
1735 }
1736
teardown_driver(struct mlx5_vdpa_net * ndev)1737 static void teardown_driver(struct mlx5_vdpa_net *ndev)
1738 {
1739 mutex_lock(&ndev->reslock);
1740 if (!ndev->setup)
1741 goto out;
1742
1743 remove_fwd_to_tir(ndev);
1744 destroy_tir(ndev);
1745 destroy_rqt(ndev);
1746 teardown_virtqueues(ndev);
1747 ndev->setup = false;
1748 out:
1749 mutex_unlock(&ndev->reslock);
1750 }
1751
clear_vqs_ready(struct mlx5_vdpa_net * ndev)1752 static void clear_vqs_ready(struct mlx5_vdpa_net *ndev)
1753 {
1754 int i;
1755
1756 for (i = 0; i < ndev->mvdev.max_vqs; i++)
1757 ndev->vqs[i].ready = false;
1758 }
1759
mlx5_vdpa_set_status(struct vdpa_device * vdev,u8 status)1760 static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
1761 {
1762 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1763 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1764 int err;
1765
1766 print_status(mvdev, status, true);
1767 if (!status) {
1768 mlx5_vdpa_info(mvdev, "performing device reset\n");
1769 teardown_driver(ndev);
1770 clear_vqs_ready(ndev);
1771 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1772 ndev->mvdev.status = 0;
1773 ndev->mvdev.mlx_features = 0;
1774 ++mvdev->generation;
1775 return;
1776 }
1777
1778 if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
1779 if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
1780 err = setup_driver(ndev);
1781 if (err) {
1782 mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
1783 goto err_setup;
1784 }
1785 } else {
1786 mlx5_vdpa_warn(mvdev, "did not expect DRIVER_OK to be cleared\n");
1787 return;
1788 }
1789 }
1790
1791 ndev->mvdev.status = status;
1792 return;
1793
1794 err_setup:
1795 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1796 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
1797 }
1798
mlx5_vdpa_get_config(struct vdpa_device * vdev,unsigned int offset,void * buf,unsigned int len)1799 static void mlx5_vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf,
1800 unsigned int len)
1801 {
1802 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1803 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1804
1805 if (offset + len <= sizeof(struct virtio_net_config))
1806 memcpy(buf, (u8 *)&ndev->config + offset, len);
1807 }
1808
mlx5_vdpa_set_config(struct vdpa_device * vdev,unsigned int offset,const void * buf,unsigned int len)1809 static void mlx5_vdpa_set_config(struct vdpa_device *vdev, unsigned int offset, const void *buf,
1810 unsigned int len)
1811 {
1812 /* not supported */
1813 }
1814
mlx5_vdpa_get_generation(struct vdpa_device * vdev)1815 static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
1816 {
1817 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1818
1819 return mvdev->generation;
1820 }
1821
mlx5_vdpa_set_map(struct vdpa_device * vdev,struct vhost_iotlb * iotlb)1822 static int mlx5_vdpa_set_map(struct vdpa_device *vdev, struct vhost_iotlb *iotlb)
1823 {
1824 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1825 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1826 bool change_map;
1827 int err;
1828
1829 err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map);
1830 if (err) {
1831 mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
1832 return err;
1833 }
1834
1835 if (change_map)
1836 return mlx5_vdpa_change_map(ndev, iotlb);
1837
1838 return 0;
1839 }
1840
mlx5_vdpa_free(struct vdpa_device * vdev)1841 static void mlx5_vdpa_free(struct vdpa_device *vdev)
1842 {
1843 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1844 struct mlx5_core_dev *pfmdev;
1845 struct mlx5_vdpa_net *ndev;
1846
1847 ndev = to_mlx5_vdpa_ndev(mvdev);
1848
1849 free_resources(ndev);
1850 if (!is_zero_ether_addr(ndev->config.mac)) {
1851 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
1852 mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
1853 }
1854 mlx5_vdpa_free_resources(&ndev->mvdev);
1855 mutex_destroy(&ndev->reslock);
1856 }
1857
mlx5_get_vq_notification(struct vdpa_device * vdev,u16 idx)1858 static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)
1859 {
1860 struct vdpa_notification_area ret = {};
1861
1862 return ret;
1863 }
1864
mlx5_get_vq_irq(struct vdpa_device * vdv,u16 idx)1865 static int mlx5_get_vq_irq(struct vdpa_device *vdv, u16 idx)
1866 {
1867 return -EOPNOTSUPP;
1868 }
1869
1870 static const struct vdpa_config_ops mlx5_vdpa_ops = {
1871 .set_vq_address = mlx5_vdpa_set_vq_address,
1872 .set_vq_num = mlx5_vdpa_set_vq_num,
1873 .kick_vq = mlx5_vdpa_kick_vq,
1874 .set_vq_cb = mlx5_vdpa_set_vq_cb,
1875 .set_vq_ready = mlx5_vdpa_set_vq_ready,
1876 .get_vq_ready = mlx5_vdpa_get_vq_ready,
1877 .set_vq_state = mlx5_vdpa_set_vq_state,
1878 .get_vq_state = mlx5_vdpa_get_vq_state,
1879 .get_vq_notification = mlx5_get_vq_notification,
1880 .get_vq_irq = mlx5_get_vq_irq,
1881 .get_vq_align = mlx5_vdpa_get_vq_align,
1882 .get_features = mlx5_vdpa_get_features,
1883 .set_features = mlx5_vdpa_set_features,
1884 .set_config_cb = mlx5_vdpa_set_config_cb,
1885 .get_vq_num_max = mlx5_vdpa_get_vq_num_max,
1886 .get_device_id = mlx5_vdpa_get_device_id,
1887 .get_vendor_id = mlx5_vdpa_get_vendor_id,
1888 .get_status = mlx5_vdpa_get_status,
1889 .set_status = mlx5_vdpa_set_status,
1890 .get_config = mlx5_vdpa_get_config,
1891 .set_config = mlx5_vdpa_set_config,
1892 .get_generation = mlx5_vdpa_get_generation,
1893 .set_map = mlx5_vdpa_set_map,
1894 .free = mlx5_vdpa_free,
1895 };
1896
query_mtu(struct mlx5_core_dev * mdev,u16 * mtu)1897 static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
1898 {
1899 u16 hw_mtu;
1900 int err;
1901
1902 err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu);
1903 if (err)
1904 return err;
1905
1906 *mtu = hw_mtu - MLX5V_ETH_HARD_MTU;
1907 return 0;
1908 }
1909
alloc_resources(struct mlx5_vdpa_net * ndev)1910 static int alloc_resources(struct mlx5_vdpa_net *ndev)
1911 {
1912 struct mlx5_vdpa_net_resources *res = &ndev->res;
1913 int err;
1914
1915 if (res->valid) {
1916 mlx5_vdpa_warn(&ndev->mvdev, "resources already allocated\n");
1917 return -EEXIST;
1918 }
1919
1920 err = mlx5_vdpa_alloc_transport_domain(&ndev->mvdev, &res->tdn);
1921 if (err)
1922 return err;
1923
1924 err = create_tis(ndev);
1925 if (err)
1926 goto err_tis;
1927
1928 res->valid = true;
1929
1930 return 0;
1931
1932 err_tis:
1933 mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
1934 return err;
1935 }
1936
free_resources(struct mlx5_vdpa_net * ndev)1937 static void free_resources(struct mlx5_vdpa_net *ndev)
1938 {
1939 struct mlx5_vdpa_net_resources *res = &ndev->res;
1940
1941 if (!res->valid)
1942 return;
1943
1944 destroy_tis(ndev);
1945 mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
1946 res->valid = false;
1947 }
1948
init_mvqs(struct mlx5_vdpa_net * ndev)1949 static void init_mvqs(struct mlx5_vdpa_net *ndev)
1950 {
1951 struct mlx5_vdpa_virtqueue *mvq;
1952 int i;
1953
1954 for (i = 0; i < 2 * mlx5_vdpa_max_qps(ndev->mvdev.max_vqs); ++i) {
1955 mvq = &ndev->vqs[i];
1956 memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1957 mvq->index = i;
1958 mvq->ndev = ndev;
1959 mvq->fwqp.fw = true;
1960 }
1961 for (; i < ndev->mvdev.max_vqs; i++) {
1962 mvq = &ndev->vqs[i];
1963 memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1964 mvq->index = i;
1965 mvq->ndev = ndev;
1966 }
1967 }
1968
mlx5_vdpa_add_dev(struct mlx5_core_dev * mdev)1969 void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
1970 {
1971 struct virtio_net_config *config;
1972 struct mlx5_core_dev *pfmdev;
1973 struct mlx5_vdpa_dev *mvdev;
1974 struct mlx5_vdpa_net *ndev;
1975 u32 max_vqs;
1976 int err;
1977
1978 /* we save one virtqueue for control virtqueue should we require it */
1979 max_vqs = MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
1980 max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
1981
1982 ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
1983 2 * mlx5_vdpa_max_qps(max_vqs));
1984 if (IS_ERR(ndev))
1985 return ndev;
1986
1987 ndev->mvdev.max_vqs = max_vqs;
1988 mvdev = &ndev->mvdev;
1989 mvdev->mdev = mdev;
1990 init_mvqs(ndev);
1991 mutex_init(&ndev->reslock);
1992 config = &ndev->config;
1993 err = query_mtu(mdev, &ndev->mtu);
1994 if (err)
1995 goto err_mtu;
1996
1997 err = mlx5_query_nic_vport_mac_address(mdev, 0, 0, config->mac);
1998 if (err)
1999 goto err_mtu;
2000
2001 if (!is_zero_ether_addr(config->mac)) {
2002 pfmdev = pci_get_drvdata(pci_physfn(mdev->pdev));
2003 err = mlx5_mpfs_add_mac(pfmdev, config->mac);
2004 if (err)
2005 goto err_mtu;
2006 }
2007
2008 mvdev->vdev.dma_dev = mdev->device;
2009 err = mlx5_vdpa_alloc_resources(&ndev->mvdev);
2010 if (err)
2011 goto err_mpfs;
2012
2013 err = alloc_resources(ndev);
2014 if (err)
2015 goto err_res;
2016
2017 err = vdpa_register_device(&mvdev->vdev);
2018 if (err)
2019 goto err_reg;
2020
2021 return ndev;
2022
2023 err_reg:
2024 free_resources(ndev);
2025 err_res:
2026 mlx5_vdpa_free_resources(&ndev->mvdev);
2027 err_mpfs:
2028 if (!is_zero_ether_addr(config->mac))
2029 mlx5_mpfs_del_mac(pfmdev, config->mac);
2030 err_mtu:
2031 mutex_destroy(&ndev->reslock);
2032 put_device(&mvdev->vdev.dev);
2033 return ERR_PTR(err);
2034 }
2035
mlx5_vdpa_remove_dev(struct mlx5_vdpa_dev * mvdev)2036 void mlx5_vdpa_remove_dev(struct mlx5_vdpa_dev *mvdev)
2037 {
2038 vdpa_unregister_device(&mvdev->vdev);
2039 }
2040