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 if (MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, eth_frame_offload_type))
816 MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0, 1);
817
818 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
819 if (err)
820 goto err_cmd;
821
822 kfree(in);
823 mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
824
825 return 0;
826
827 err_cmd:
828 kfree(in);
829 err_alloc:
830 umems_destroy(ndev, mvq);
831 return err;
832 }
833
destroy_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)834 static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
835 {
836 u32 in[MLX5_ST_SZ_DW(destroy_virtio_net_q_in)] = {};
837 u32 out[MLX5_ST_SZ_DW(destroy_virtio_net_q_out)] = {};
838
839 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.opcode,
840 MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
841 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_id, mvq->virtq_id);
842 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.uid, ndev->mvdev.res.uid);
843 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_type,
844 MLX5_OBJ_TYPE_VIRTIO_NET_Q);
845 if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out))) {
846 mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
847 return;
848 }
849 umems_destroy(ndev, mvq);
850 }
851
get_rqpn(struct mlx5_vdpa_virtqueue * mvq,bool fw)852 static u32 get_rqpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
853 {
854 return fw ? mvq->vqqp.mqp.qpn : mvq->fwqp.mqp.qpn;
855 }
856
get_qpn(struct mlx5_vdpa_virtqueue * mvq,bool fw)857 static u32 get_qpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
858 {
859 return fw ? mvq->fwqp.mqp.qpn : mvq->vqqp.mqp.qpn;
860 }
861
alloc_inout(struct mlx5_vdpa_net * ndev,int cmd,void ** in,int * inlen,void ** out,int * outlen,u32 qpn,u32 rqpn)862 static void alloc_inout(struct mlx5_vdpa_net *ndev, int cmd, void **in, int *inlen, void **out,
863 int *outlen, u32 qpn, u32 rqpn)
864 {
865 void *qpc;
866 void *pp;
867
868 switch (cmd) {
869 case MLX5_CMD_OP_2RST_QP:
870 *inlen = MLX5_ST_SZ_BYTES(qp_2rst_in);
871 *outlen = MLX5_ST_SZ_BYTES(qp_2rst_out);
872 *in = kzalloc(*inlen, GFP_KERNEL);
873 *out = kzalloc(*outlen, GFP_KERNEL);
874 if (!*in || !*out)
875 goto outerr;
876
877 MLX5_SET(qp_2rst_in, *in, opcode, cmd);
878 MLX5_SET(qp_2rst_in, *in, uid, ndev->mvdev.res.uid);
879 MLX5_SET(qp_2rst_in, *in, qpn, qpn);
880 break;
881 case MLX5_CMD_OP_RST2INIT_QP:
882 *inlen = MLX5_ST_SZ_BYTES(rst2init_qp_in);
883 *outlen = MLX5_ST_SZ_BYTES(rst2init_qp_out);
884 *in = kzalloc(*inlen, GFP_KERNEL);
885 *out = kzalloc(MLX5_ST_SZ_BYTES(rst2init_qp_out), GFP_KERNEL);
886 if (!*in || !*out)
887 goto outerr;
888
889 MLX5_SET(rst2init_qp_in, *in, opcode, cmd);
890 MLX5_SET(rst2init_qp_in, *in, uid, ndev->mvdev.res.uid);
891 MLX5_SET(rst2init_qp_in, *in, qpn, qpn);
892 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
893 MLX5_SET(qpc, qpc, remote_qpn, rqpn);
894 MLX5_SET(qpc, qpc, rwe, 1);
895 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
896 MLX5_SET(ads, pp, vhca_port_num, 1);
897 break;
898 case MLX5_CMD_OP_INIT2RTR_QP:
899 *inlen = MLX5_ST_SZ_BYTES(init2rtr_qp_in);
900 *outlen = MLX5_ST_SZ_BYTES(init2rtr_qp_out);
901 *in = kzalloc(*inlen, GFP_KERNEL);
902 *out = kzalloc(MLX5_ST_SZ_BYTES(init2rtr_qp_out), GFP_KERNEL);
903 if (!*in || !*out)
904 goto outerr;
905
906 MLX5_SET(init2rtr_qp_in, *in, opcode, cmd);
907 MLX5_SET(init2rtr_qp_in, *in, uid, ndev->mvdev.res.uid);
908 MLX5_SET(init2rtr_qp_in, *in, qpn, qpn);
909 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
910 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
911 MLX5_SET(qpc, qpc, log_msg_max, 30);
912 MLX5_SET(qpc, qpc, remote_qpn, rqpn);
913 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
914 MLX5_SET(ads, pp, fl, 1);
915 break;
916 case MLX5_CMD_OP_RTR2RTS_QP:
917 *inlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_in);
918 *outlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_out);
919 *in = kzalloc(*inlen, GFP_KERNEL);
920 *out = kzalloc(MLX5_ST_SZ_BYTES(rtr2rts_qp_out), GFP_KERNEL);
921 if (!*in || !*out)
922 goto outerr;
923
924 MLX5_SET(rtr2rts_qp_in, *in, opcode, cmd);
925 MLX5_SET(rtr2rts_qp_in, *in, uid, ndev->mvdev.res.uid);
926 MLX5_SET(rtr2rts_qp_in, *in, qpn, qpn);
927 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
928 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
929 MLX5_SET(ads, pp, ack_timeout, 14);
930 MLX5_SET(qpc, qpc, retry_count, 7);
931 MLX5_SET(qpc, qpc, rnr_retry, 7);
932 break;
933 default:
934 goto outerr_nullify;
935 }
936
937 return;
938
939 outerr:
940 kfree(*in);
941 kfree(*out);
942 outerr_nullify:
943 *in = NULL;
944 *out = NULL;
945 }
946
free_inout(void * in,void * out)947 static void free_inout(void *in, void *out)
948 {
949 kfree(in);
950 kfree(out);
951 }
952
953 /* Two QPs are used by each virtqueue. One is used by the driver and one by
954 * firmware. The fw argument indicates whether the subjected QP is the one used
955 * by firmware.
956 */
modify_qp(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,bool fw,int cmd)957 static int modify_qp(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, bool fw, int cmd)
958 {
959 int outlen;
960 int inlen;
961 void *out;
962 void *in;
963 int err;
964
965 alloc_inout(ndev, cmd, &in, &inlen, &out, &outlen, get_qpn(mvq, fw), get_rqpn(mvq, fw));
966 if (!in || !out)
967 return -ENOMEM;
968
969 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, outlen);
970 free_inout(in, out);
971 return err;
972 }
973
connect_qps(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)974 static int connect_qps(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
975 {
976 int err;
977
978 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_2RST_QP);
979 if (err)
980 return err;
981
982 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_2RST_QP);
983 if (err)
984 return err;
985
986 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_RST2INIT_QP);
987 if (err)
988 return err;
989
990 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_RST2INIT_QP);
991 if (err)
992 return err;
993
994 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_INIT2RTR_QP);
995 if (err)
996 return err;
997
998 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_INIT2RTR_QP);
999 if (err)
1000 return err;
1001
1002 return modify_qp(ndev, mvq, true, MLX5_CMD_OP_RTR2RTS_QP);
1003 }
1004
1005 struct mlx5_virtq_attr {
1006 u8 state;
1007 u16 available_index;
1008 u16 used_index;
1009 };
1010
query_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,struct mlx5_virtq_attr * attr)1011 static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
1012 struct mlx5_virtq_attr *attr)
1013 {
1014 int outlen = MLX5_ST_SZ_BYTES(query_virtio_net_q_out);
1015 u32 in[MLX5_ST_SZ_DW(query_virtio_net_q_in)] = {};
1016 void *out;
1017 void *obj_context;
1018 void *cmd_hdr;
1019 int err;
1020
1021 out = kzalloc(outlen, GFP_KERNEL);
1022 if (!out)
1023 return -ENOMEM;
1024
1025 cmd_hdr = MLX5_ADDR_OF(query_virtio_net_q_in, in, general_obj_in_cmd_hdr);
1026
1027 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
1028 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1029 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1030 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1031 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, outlen);
1032 if (err)
1033 goto err_cmd;
1034
1035 obj_context = MLX5_ADDR_OF(query_virtio_net_q_out, out, obj_context);
1036 memset(attr, 0, sizeof(*attr));
1037 attr->state = MLX5_GET(virtio_net_q_object, obj_context, state);
1038 attr->available_index = MLX5_GET(virtio_net_q_object, obj_context, hw_available_index);
1039 attr->used_index = MLX5_GET(virtio_net_q_object, obj_context, hw_used_index);
1040 kfree(out);
1041 return 0;
1042
1043 err_cmd:
1044 kfree(out);
1045 return err;
1046 }
1047
modify_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int state)1048 static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
1049 {
1050 int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
1051 u32 out[MLX5_ST_SZ_DW(modify_virtio_net_q_out)] = {};
1052 void *obj_context;
1053 void *cmd_hdr;
1054 void *in;
1055 int err;
1056
1057 in = kzalloc(inlen, GFP_KERNEL);
1058 if (!in)
1059 return -ENOMEM;
1060
1061 cmd_hdr = MLX5_ADDR_OF(modify_virtio_net_q_in, in, general_obj_in_cmd_hdr);
1062
1063 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
1064 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1065 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1066 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1067
1068 obj_context = MLX5_ADDR_OF(modify_virtio_net_q_in, in, obj_context);
1069 MLX5_SET64(virtio_net_q_object, obj_context, modify_field_select,
1070 MLX5_VIRTQ_MODIFY_MASK_STATE);
1071 MLX5_SET(virtio_net_q_object, obj_context, state, state);
1072 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
1073 kfree(in);
1074 if (!err)
1075 mvq->fw_state = state;
1076
1077 return err;
1078 }
1079
setup_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1080 static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1081 {
1082 u16 idx = mvq->index;
1083 int err;
1084
1085 if (!mvq->num_ent)
1086 return 0;
1087
1088 if (mvq->initialized) {
1089 mlx5_vdpa_warn(&ndev->mvdev, "attempt re init\n");
1090 return -EINVAL;
1091 }
1092
1093 err = cq_create(ndev, idx, mvq->num_ent);
1094 if (err)
1095 return err;
1096
1097 err = qp_create(ndev, mvq, &mvq->fwqp);
1098 if (err)
1099 goto err_fwqp;
1100
1101 err = qp_create(ndev, mvq, &mvq->vqqp);
1102 if (err)
1103 goto err_vqqp;
1104
1105 err = connect_qps(ndev, mvq);
1106 if (err)
1107 goto err_connect;
1108
1109 err = create_virtqueue(ndev, mvq);
1110 if (err)
1111 goto err_connect;
1112
1113 if (mvq->ready) {
1114 err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
1115 if (err) {
1116 mlx5_vdpa_warn(&ndev->mvdev, "failed to modify to ready vq idx %d(%d)\n",
1117 idx, err);
1118 goto err_connect;
1119 }
1120 }
1121
1122 mvq->initialized = true;
1123 return 0;
1124
1125 err_connect:
1126 qp_destroy(ndev, &mvq->vqqp);
1127 err_vqqp:
1128 qp_destroy(ndev, &mvq->fwqp);
1129 err_fwqp:
1130 cq_destroy(ndev, idx);
1131 return err;
1132 }
1133
suspend_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1134 static void suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1135 {
1136 struct mlx5_virtq_attr attr;
1137
1138 if (!mvq->initialized)
1139 return;
1140
1141 if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY)
1142 return;
1143
1144 if (modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND))
1145 mlx5_vdpa_warn(&ndev->mvdev, "modify to suspend failed\n");
1146
1147 if (query_virtqueue(ndev, mvq, &attr)) {
1148 mlx5_vdpa_warn(&ndev->mvdev, "failed to query virtqueue\n");
1149 return;
1150 }
1151 mvq->avail_idx = attr.available_index;
1152 mvq->used_idx = attr.used_index;
1153 }
1154
suspend_vqs(struct mlx5_vdpa_net * ndev)1155 static void suspend_vqs(struct mlx5_vdpa_net *ndev)
1156 {
1157 int i;
1158
1159 for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++)
1160 suspend_vq(ndev, &ndev->vqs[i]);
1161 }
1162
teardown_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1163 static void teardown_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1164 {
1165 if (!mvq->initialized)
1166 return;
1167
1168 suspend_vq(ndev, mvq);
1169 destroy_virtqueue(ndev, mvq);
1170 qp_destroy(ndev, &mvq->vqqp);
1171 qp_destroy(ndev, &mvq->fwqp);
1172 cq_destroy(ndev, mvq->index);
1173 mvq->initialized = false;
1174 }
1175
create_rqt(struct mlx5_vdpa_net * ndev)1176 static int create_rqt(struct mlx5_vdpa_net *ndev)
1177 {
1178 int log_max_rqt;
1179 __be32 *list;
1180 void *rqtc;
1181 int inlen;
1182 void *in;
1183 int i, j;
1184 int err;
1185
1186 log_max_rqt = min_t(int, 1, MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size));
1187 if (log_max_rqt < 1)
1188 return -EOPNOTSUPP;
1189
1190 inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + (1 << log_max_rqt) * MLX5_ST_SZ_BYTES(rq_num);
1191 in = kzalloc(inlen, GFP_KERNEL);
1192 if (!in)
1193 return -ENOMEM;
1194
1195 MLX5_SET(create_rqt_in, in, uid, ndev->mvdev.res.uid);
1196 rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
1197
1198 MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q);
1199 MLX5_SET(rqtc, rqtc, rqt_max_size, 1 << log_max_rqt);
1200 MLX5_SET(rqtc, rqtc, rqt_actual_size, 1);
1201 list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]);
1202 for (i = 0, j = 0; j < ndev->mvdev.max_vqs; j++) {
1203 if (!ndev->vqs[j].initialized)
1204 continue;
1205
1206 if (!vq_is_tx(ndev->vqs[j].index)) {
1207 list[i] = cpu_to_be32(ndev->vqs[j].virtq_id);
1208 i++;
1209 }
1210 }
1211
1212 err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);
1213 kfree(in);
1214 if (err)
1215 return err;
1216
1217 return 0;
1218 }
1219
destroy_rqt(struct mlx5_vdpa_net * ndev)1220 static void destroy_rqt(struct mlx5_vdpa_net *ndev)
1221 {
1222 mlx5_vdpa_destroy_rqt(&ndev->mvdev, ndev->res.rqtn);
1223 }
1224
create_tir(struct mlx5_vdpa_net * ndev)1225 static int create_tir(struct mlx5_vdpa_net *ndev)
1226 {
1227 #define HASH_IP_L4PORTS \
1228 (MLX5_HASH_FIELD_SEL_SRC_IP | MLX5_HASH_FIELD_SEL_DST_IP | MLX5_HASH_FIELD_SEL_L4_SPORT | \
1229 MLX5_HASH_FIELD_SEL_L4_DPORT)
1230 static const u8 rx_hash_toeplitz_key[] = { 0x2c, 0xc6, 0x81, 0xd1, 0x5b, 0xdb, 0xf4, 0xf7,
1231 0xfc, 0xa2, 0x83, 0x19, 0xdb, 0x1a, 0x3e, 0x94,
1232 0x6b, 0x9e, 0x38, 0xd9, 0x2c, 0x9c, 0x03, 0xd1,
1233 0xad, 0x99, 0x44, 0xa7, 0xd9, 0x56, 0x3d, 0x59,
1234 0x06, 0x3c, 0x25, 0xf3, 0xfc, 0x1f, 0xdc, 0x2a };
1235 void *rss_key;
1236 void *outer;
1237 void *tirc;
1238 void *in;
1239 int err;
1240
1241 in = kzalloc(MLX5_ST_SZ_BYTES(create_tir_in), GFP_KERNEL);
1242 if (!in)
1243 return -ENOMEM;
1244
1245 MLX5_SET(create_tir_in, in, uid, ndev->mvdev.res.uid);
1246 tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
1247 MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
1248
1249 MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
1250 MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_TOEPLITZ);
1251 rss_key = MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
1252 memcpy(rss_key, rx_hash_toeplitz_key, sizeof(rx_hash_toeplitz_key));
1253
1254 outer = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
1255 MLX5_SET(rx_hash_field_select, outer, l3_prot_type, MLX5_L3_PROT_TYPE_IPV4);
1256 MLX5_SET(rx_hash_field_select, outer, l4_prot_type, MLX5_L4_PROT_TYPE_TCP);
1257 MLX5_SET(rx_hash_field_select, outer, selected_fields, HASH_IP_L4PORTS);
1258
1259 MLX5_SET(tirc, tirc, indirect_table, ndev->res.rqtn);
1260 MLX5_SET(tirc, tirc, transport_domain, ndev->res.tdn);
1261
1262 err = mlx5_vdpa_create_tir(&ndev->mvdev, in, &ndev->res.tirn);
1263 kfree(in);
1264 return err;
1265 }
1266
destroy_tir(struct mlx5_vdpa_net * ndev)1267 static void destroy_tir(struct mlx5_vdpa_net *ndev)
1268 {
1269 mlx5_vdpa_destroy_tir(&ndev->mvdev, ndev->res.tirn);
1270 }
1271
add_fwd_to_tir(struct mlx5_vdpa_net * ndev)1272 static int add_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1273 {
1274 struct mlx5_flow_destination dest[2] = {};
1275 struct mlx5_flow_table_attr ft_attr = {};
1276 struct mlx5_flow_act flow_act = {};
1277 struct mlx5_flow_namespace *ns;
1278 int err;
1279
1280 /* for now, one entry, match all, forward to tir */
1281 ft_attr.max_fte = 1;
1282 ft_attr.autogroup.max_num_groups = 1;
1283
1284 ns = mlx5_get_flow_namespace(ndev->mvdev.mdev, MLX5_FLOW_NAMESPACE_BYPASS);
1285 if (!ns) {
1286 mlx5_vdpa_warn(&ndev->mvdev, "get flow namespace\n");
1287 return -EOPNOTSUPP;
1288 }
1289
1290 ndev->rxft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
1291 if (IS_ERR(ndev->rxft))
1292 return PTR_ERR(ndev->rxft);
1293
1294 ndev->rx_counter = mlx5_fc_create(ndev->mvdev.mdev, false);
1295 if (IS_ERR(ndev->rx_counter)) {
1296 err = PTR_ERR(ndev->rx_counter);
1297 goto err_fc;
1298 }
1299
1300 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_COUNT;
1301 dest[0].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1302 dest[0].tir_num = ndev->res.tirn;
1303 dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1304 dest[1].counter_id = mlx5_fc_id(ndev->rx_counter);
1305 ndev->rx_rule = mlx5_add_flow_rules(ndev->rxft, NULL, &flow_act, dest, 2);
1306 if (IS_ERR(ndev->rx_rule)) {
1307 err = PTR_ERR(ndev->rx_rule);
1308 ndev->rx_rule = NULL;
1309 goto err_rule;
1310 }
1311
1312 return 0;
1313
1314 err_rule:
1315 mlx5_fc_destroy(ndev->mvdev.mdev, ndev->rx_counter);
1316 err_fc:
1317 mlx5_destroy_flow_table(ndev->rxft);
1318 return err;
1319 }
1320
remove_fwd_to_tir(struct mlx5_vdpa_net * ndev)1321 static void remove_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1322 {
1323 if (!ndev->rx_rule)
1324 return;
1325
1326 mlx5_del_flow_rules(ndev->rx_rule);
1327 mlx5_fc_destroy(ndev->mvdev.mdev, ndev->rx_counter);
1328 mlx5_destroy_flow_table(ndev->rxft);
1329
1330 ndev->rx_rule = NULL;
1331 }
1332
mlx5_vdpa_kick_vq(struct vdpa_device * vdev,u16 idx)1333 static void mlx5_vdpa_kick_vq(struct vdpa_device *vdev, u16 idx)
1334 {
1335 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1336 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1337 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1338
1339 if (unlikely(!mvq->ready))
1340 return;
1341
1342 iowrite16(idx, ndev->mvdev.res.kick_addr);
1343 }
1344
mlx5_vdpa_set_vq_address(struct vdpa_device * vdev,u16 idx,u64 desc_area,u64 driver_area,u64 device_area)1345 static int mlx5_vdpa_set_vq_address(struct vdpa_device *vdev, u16 idx, u64 desc_area,
1346 u64 driver_area, u64 device_area)
1347 {
1348 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1349 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1350 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1351
1352 mvq->desc_addr = desc_area;
1353 mvq->device_addr = device_area;
1354 mvq->driver_addr = driver_area;
1355 return 0;
1356 }
1357
mlx5_vdpa_set_vq_num(struct vdpa_device * vdev,u16 idx,u32 num)1358 static void mlx5_vdpa_set_vq_num(struct vdpa_device *vdev, u16 idx, u32 num)
1359 {
1360 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1361 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1362 struct mlx5_vdpa_virtqueue *mvq;
1363
1364 mvq = &ndev->vqs[idx];
1365 mvq->num_ent = num;
1366 }
1367
mlx5_vdpa_set_vq_cb(struct vdpa_device * vdev,u16 idx,struct vdpa_callback * cb)1368 static void mlx5_vdpa_set_vq_cb(struct vdpa_device *vdev, u16 idx, struct vdpa_callback *cb)
1369 {
1370 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1371 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1372 struct mlx5_vdpa_virtqueue *vq = &ndev->vqs[idx];
1373
1374 vq->event_cb = *cb;
1375 }
1376
mlx5_vdpa_set_vq_ready(struct vdpa_device * vdev,u16 idx,bool ready)1377 static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready)
1378 {
1379 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1380 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1381 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1382
1383 if (!ready)
1384 suspend_vq(ndev, mvq);
1385
1386 mvq->ready = ready;
1387 }
1388
mlx5_vdpa_get_vq_ready(struct vdpa_device * vdev,u16 idx)1389 static bool mlx5_vdpa_get_vq_ready(struct vdpa_device *vdev, u16 idx)
1390 {
1391 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1392 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1393 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1394
1395 return mvq->ready;
1396 }
1397
mlx5_vdpa_set_vq_state(struct vdpa_device * vdev,u16 idx,const struct vdpa_vq_state * state)1398 static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx,
1399 const struct vdpa_vq_state *state)
1400 {
1401 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1402 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1403 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1404
1405 if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY) {
1406 mlx5_vdpa_warn(mvdev, "can't modify available index\n");
1407 return -EINVAL;
1408 }
1409
1410 mvq->used_idx = state->avail_index;
1411 mvq->avail_idx = state->avail_index;
1412 return 0;
1413 }
1414
mlx5_vdpa_get_vq_state(struct vdpa_device * vdev,u16 idx,struct vdpa_vq_state * state)1415 static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa_vq_state *state)
1416 {
1417 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1418 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1419 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1420 struct mlx5_virtq_attr attr;
1421 int err;
1422
1423 /* If the virtq object was destroyed, use the value saved at
1424 * the last minute of suspend_vq. This caters for userspace
1425 * that cares about emulating the index after vq is stopped.
1426 */
1427 if (!mvq->initialized) {
1428 /* Firmware returns a wrong value for the available index.
1429 * Since both values should be identical, we take the value of
1430 * used_idx which is reported correctly.
1431 */
1432 state->avail_index = mvq->used_idx;
1433 return 0;
1434 }
1435
1436 err = query_virtqueue(ndev, mvq, &attr);
1437 if (err) {
1438 mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n");
1439 return err;
1440 }
1441 state->avail_index = attr.used_index;
1442 return 0;
1443 }
1444
mlx5_vdpa_get_vq_align(struct vdpa_device * vdev)1445 static u32 mlx5_vdpa_get_vq_align(struct vdpa_device *vdev)
1446 {
1447 return PAGE_SIZE;
1448 }
1449
1450 enum { MLX5_VIRTIO_NET_F_GUEST_CSUM = 1 << 9,
1451 MLX5_VIRTIO_NET_F_CSUM = 1 << 10,
1452 MLX5_VIRTIO_NET_F_HOST_TSO6 = 1 << 11,
1453 MLX5_VIRTIO_NET_F_HOST_TSO4 = 1 << 12,
1454 };
1455
mlx_to_vritio_features(u16 dev_features)1456 static u64 mlx_to_vritio_features(u16 dev_features)
1457 {
1458 u64 result = 0;
1459
1460 if (dev_features & MLX5_VIRTIO_NET_F_GUEST_CSUM)
1461 result |= BIT_ULL(VIRTIO_NET_F_GUEST_CSUM);
1462 if (dev_features & MLX5_VIRTIO_NET_F_CSUM)
1463 result |= BIT_ULL(VIRTIO_NET_F_CSUM);
1464 if (dev_features & MLX5_VIRTIO_NET_F_HOST_TSO6)
1465 result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO6);
1466 if (dev_features & MLX5_VIRTIO_NET_F_HOST_TSO4)
1467 result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO4);
1468
1469 return result;
1470 }
1471
mlx5_vdpa_get_features(struct vdpa_device * vdev)1472 static u64 mlx5_vdpa_get_features(struct vdpa_device *vdev)
1473 {
1474 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1475 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1476 u16 dev_features;
1477
1478 dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, device_features_bits_mask);
1479 ndev->mvdev.mlx_features = mlx_to_vritio_features(dev_features);
1480 if (MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, virtio_version_1_0))
1481 ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_VERSION_1);
1482 ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM);
1483 print_features(mvdev, ndev->mvdev.mlx_features, false);
1484 return ndev->mvdev.mlx_features;
1485 }
1486
verify_min_features(struct mlx5_vdpa_dev * mvdev,u64 features)1487 static int verify_min_features(struct mlx5_vdpa_dev *mvdev, u64 features)
1488 {
1489 if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)))
1490 return -EOPNOTSUPP;
1491
1492 return 0;
1493 }
1494
setup_virtqueues(struct mlx5_vdpa_net * ndev)1495 static int setup_virtqueues(struct mlx5_vdpa_net *ndev)
1496 {
1497 int err;
1498 int i;
1499
1500 for (i = 0; i < 2 * mlx5_vdpa_max_qps(ndev->mvdev.max_vqs); i++) {
1501 err = setup_vq(ndev, &ndev->vqs[i]);
1502 if (err)
1503 goto err_vq;
1504 }
1505
1506 return 0;
1507
1508 err_vq:
1509 for (--i; i >= 0; i--)
1510 teardown_vq(ndev, &ndev->vqs[i]);
1511
1512 return err;
1513 }
1514
teardown_virtqueues(struct mlx5_vdpa_net * ndev)1515 static void teardown_virtqueues(struct mlx5_vdpa_net *ndev)
1516 {
1517 struct mlx5_vdpa_virtqueue *mvq;
1518 int i;
1519
1520 for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) {
1521 mvq = &ndev->vqs[i];
1522 if (!mvq->initialized)
1523 continue;
1524
1525 teardown_vq(ndev, mvq);
1526 }
1527 }
1528
1529 /* TODO: cross-endian support */
mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev * mvdev)1530 static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
1531 {
1532 return virtio_legacy_is_little_endian() ||
1533 (mvdev->actual_features & BIT_ULL(VIRTIO_F_VERSION_1));
1534 }
1535
cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev * mvdev,u16 val)1536 static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val)
1537 {
1538 return __cpu_to_virtio16(mlx5_vdpa_is_little_endian(mvdev), val);
1539 }
1540
mlx5_vdpa_set_features(struct vdpa_device * vdev,u64 features)1541 static int mlx5_vdpa_set_features(struct vdpa_device *vdev, u64 features)
1542 {
1543 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1544 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1545 int err;
1546
1547 print_features(mvdev, features, true);
1548
1549 err = verify_min_features(mvdev, features);
1550 if (err)
1551 return err;
1552
1553 ndev->mvdev.actual_features = features & ndev->mvdev.mlx_features;
1554 ndev->config.mtu = cpu_to_mlx5vdpa16(mvdev, ndev->mtu);
1555 ndev->config.status |= cpu_to_mlx5vdpa16(mvdev, VIRTIO_NET_S_LINK_UP);
1556 return err;
1557 }
1558
mlx5_vdpa_set_config_cb(struct vdpa_device * vdev,struct vdpa_callback * cb)1559 static void mlx5_vdpa_set_config_cb(struct vdpa_device *vdev, struct vdpa_callback *cb)
1560 {
1561 /* not implemented */
1562 mlx5_vdpa_warn(to_mvdev(vdev), "set config callback not supported\n");
1563 }
1564
1565 #define MLX5_VDPA_MAX_VQ_ENTRIES 256
mlx5_vdpa_get_vq_num_max(struct vdpa_device * vdev)1566 static u16 mlx5_vdpa_get_vq_num_max(struct vdpa_device *vdev)
1567 {
1568 return MLX5_VDPA_MAX_VQ_ENTRIES;
1569 }
1570
mlx5_vdpa_get_device_id(struct vdpa_device * vdev)1571 static u32 mlx5_vdpa_get_device_id(struct vdpa_device *vdev)
1572 {
1573 return VIRTIO_ID_NET;
1574 }
1575
mlx5_vdpa_get_vendor_id(struct vdpa_device * vdev)1576 static u32 mlx5_vdpa_get_vendor_id(struct vdpa_device *vdev)
1577 {
1578 return PCI_VENDOR_ID_MELLANOX;
1579 }
1580
mlx5_vdpa_get_status(struct vdpa_device * vdev)1581 static u8 mlx5_vdpa_get_status(struct vdpa_device *vdev)
1582 {
1583 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1584 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1585
1586 print_status(mvdev, ndev->mvdev.status, false);
1587 return ndev->mvdev.status;
1588 }
1589
save_channel_info(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1590 static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1591 {
1592 struct mlx5_vq_restore_info *ri = &mvq->ri;
1593 struct mlx5_virtq_attr attr;
1594 int err;
1595
1596 if (!mvq->initialized)
1597 return 0;
1598
1599 err = query_virtqueue(ndev, mvq, &attr);
1600 if (err)
1601 return err;
1602
1603 ri->avail_index = attr.available_index;
1604 ri->used_index = attr.used_index;
1605 ri->ready = mvq->ready;
1606 ri->num_ent = mvq->num_ent;
1607 ri->desc_addr = mvq->desc_addr;
1608 ri->device_addr = mvq->device_addr;
1609 ri->driver_addr = mvq->driver_addr;
1610 ri->cb = mvq->event_cb;
1611 ri->restore = true;
1612 return 0;
1613 }
1614
save_channels_info(struct mlx5_vdpa_net * ndev)1615 static int save_channels_info(struct mlx5_vdpa_net *ndev)
1616 {
1617 int i;
1618
1619 for (i = 0; i < ndev->mvdev.max_vqs; i++) {
1620 memset(&ndev->vqs[i].ri, 0, sizeof(ndev->vqs[i].ri));
1621 save_channel_info(ndev, &ndev->vqs[i]);
1622 }
1623 return 0;
1624 }
1625
mlx5_clear_vqs(struct mlx5_vdpa_net * ndev)1626 static void mlx5_clear_vqs(struct mlx5_vdpa_net *ndev)
1627 {
1628 int i;
1629
1630 for (i = 0; i < ndev->mvdev.max_vqs; i++)
1631 memset(&ndev->vqs[i], 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1632 }
1633
restore_channels_info(struct mlx5_vdpa_net * ndev)1634 static void restore_channels_info(struct mlx5_vdpa_net *ndev)
1635 {
1636 struct mlx5_vdpa_virtqueue *mvq;
1637 struct mlx5_vq_restore_info *ri;
1638 int i;
1639
1640 mlx5_clear_vqs(ndev);
1641 init_mvqs(ndev);
1642 for (i = 0; i < ndev->mvdev.max_vqs; i++) {
1643 mvq = &ndev->vqs[i];
1644 ri = &mvq->ri;
1645 if (!ri->restore)
1646 continue;
1647
1648 mvq->avail_idx = ri->avail_index;
1649 mvq->used_idx = ri->used_index;
1650 mvq->ready = ri->ready;
1651 mvq->num_ent = ri->num_ent;
1652 mvq->desc_addr = ri->desc_addr;
1653 mvq->device_addr = ri->device_addr;
1654 mvq->driver_addr = ri->driver_addr;
1655 mvq->event_cb = ri->cb;
1656 }
1657 }
1658
mlx5_vdpa_change_map(struct mlx5_vdpa_net * ndev,struct vhost_iotlb * iotlb)1659 static int mlx5_vdpa_change_map(struct mlx5_vdpa_net *ndev, struct vhost_iotlb *iotlb)
1660 {
1661 int err;
1662
1663 suspend_vqs(ndev);
1664 err = save_channels_info(ndev);
1665 if (err)
1666 goto err_mr;
1667
1668 teardown_driver(ndev);
1669 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1670 err = mlx5_vdpa_create_mr(&ndev->mvdev, iotlb);
1671 if (err)
1672 goto err_mr;
1673
1674 if (!(ndev->mvdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
1675 return 0;
1676
1677 restore_channels_info(ndev);
1678 err = setup_driver(ndev);
1679 if (err)
1680 goto err_setup;
1681
1682 return 0;
1683
1684 err_setup:
1685 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1686 err_mr:
1687 return err;
1688 }
1689
setup_driver(struct mlx5_vdpa_net * ndev)1690 static int setup_driver(struct mlx5_vdpa_net *ndev)
1691 {
1692 int err;
1693
1694 mutex_lock(&ndev->reslock);
1695 if (ndev->setup) {
1696 mlx5_vdpa_warn(&ndev->mvdev, "setup driver called for already setup driver\n");
1697 err = 0;
1698 goto out;
1699 }
1700 err = setup_virtqueues(ndev);
1701 if (err) {
1702 mlx5_vdpa_warn(&ndev->mvdev, "setup_virtqueues\n");
1703 goto out;
1704 }
1705
1706 err = create_rqt(ndev);
1707 if (err) {
1708 mlx5_vdpa_warn(&ndev->mvdev, "create_rqt\n");
1709 goto err_rqt;
1710 }
1711
1712 err = create_tir(ndev);
1713 if (err) {
1714 mlx5_vdpa_warn(&ndev->mvdev, "create_tir\n");
1715 goto err_tir;
1716 }
1717
1718 err = add_fwd_to_tir(ndev);
1719 if (err) {
1720 mlx5_vdpa_warn(&ndev->mvdev, "add_fwd_to_tir\n");
1721 goto err_fwd;
1722 }
1723 ndev->setup = true;
1724 mutex_unlock(&ndev->reslock);
1725
1726 return 0;
1727
1728 err_fwd:
1729 destroy_tir(ndev);
1730 err_tir:
1731 destroy_rqt(ndev);
1732 err_rqt:
1733 teardown_virtqueues(ndev);
1734 out:
1735 mutex_unlock(&ndev->reslock);
1736 return err;
1737 }
1738
teardown_driver(struct mlx5_vdpa_net * ndev)1739 static void teardown_driver(struct mlx5_vdpa_net *ndev)
1740 {
1741 mutex_lock(&ndev->reslock);
1742 if (!ndev->setup)
1743 goto out;
1744
1745 remove_fwd_to_tir(ndev);
1746 destroy_tir(ndev);
1747 destroy_rqt(ndev);
1748 teardown_virtqueues(ndev);
1749 ndev->setup = false;
1750 out:
1751 mutex_unlock(&ndev->reslock);
1752 }
1753
clear_vqs_ready(struct mlx5_vdpa_net * ndev)1754 static void clear_vqs_ready(struct mlx5_vdpa_net *ndev)
1755 {
1756 int i;
1757
1758 for (i = 0; i < ndev->mvdev.max_vqs; i++)
1759 ndev->vqs[i].ready = false;
1760 }
1761
mlx5_vdpa_set_status(struct vdpa_device * vdev,u8 status)1762 static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
1763 {
1764 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1765 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1766 int err;
1767
1768 print_status(mvdev, status, true);
1769 if (!status) {
1770 mlx5_vdpa_info(mvdev, "performing device reset\n");
1771 teardown_driver(ndev);
1772 clear_vqs_ready(ndev);
1773 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1774 ndev->mvdev.status = 0;
1775 ndev->mvdev.mlx_features = 0;
1776 ++mvdev->generation;
1777 return;
1778 }
1779
1780 if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
1781 if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
1782 err = setup_driver(ndev);
1783 if (err) {
1784 mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
1785 goto err_setup;
1786 }
1787 } else {
1788 mlx5_vdpa_warn(mvdev, "did not expect DRIVER_OK to be cleared\n");
1789 return;
1790 }
1791 }
1792
1793 ndev->mvdev.status = status;
1794 return;
1795
1796 err_setup:
1797 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1798 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
1799 }
1800
mlx5_vdpa_get_config(struct vdpa_device * vdev,unsigned int offset,void * buf,unsigned int len)1801 static void mlx5_vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf,
1802 unsigned int len)
1803 {
1804 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1805 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1806
1807 if (offset + len <= sizeof(struct virtio_net_config))
1808 memcpy(buf, (u8 *)&ndev->config + offset, len);
1809 }
1810
mlx5_vdpa_set_config(struct vdpa_device * vdev,unsigned int offset,const void * buf,unsigned int len)1811 static void mlx5_vdpa_set_config(struct vdpa_device *vdev, unsigned int offset, const void *buf,
1812 unsigned int len)
1813 {
1814 /* not supported */
1815 }
1816
mlx5_vdpa_get_generation(struct vdpa_device * vdev)1817 static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
1818 {
1819 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1820
1821 return mvdev->generation;
1822 }
1823
mlx5_vdpa_set_map(struct vdpa_device * vdev,struct vhost_iotlb * iotlb)1824 static int mlx5_vdpa_set_map(struct vdpa_device *vdev, struct vhost_iotlb *iotlb)
1825 {
1826 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1827 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1828 bool change_map;
1829 int err;
1830
1831 err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map);
1832 if (err) {
1833 mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
1834 return err;
1835 }
1836
1837 if (change_map)
1838 return mlx5_vdpa_change_map(ndev, iotlb);
1839
1840 return 0;
1841 }
1842
mlx5_vdpa_free(struct vdpa_device * vdev)1843 static void mlx5_vdpa_free(struct vdpa_device *vdev)
1844 {
1845 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1846 struct mlx5_core_dev *pfmdev;
1847 struct mlx5_vdpa_net *ndev;
1848
1849 ndev = to_mlx5_vdpa_ndev(mvdev);
1850
1851 free_resources(ndev);
1852 if (!is_zero_ether_addr(ndev->config.mac)) {
1853 pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
1854 mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
1855 }
1856 mlx5_vdpa_free_resources(&ndev->mvdev);
1857 mutex_destroy(&ndev->reslock);
1858 }
1859
mlx5_get_vq_notification(struct vdpa_device * vdev,u16 idx)1860 static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)
1861 {
1862 struct vdpa_notification_area ret = {};
1863
1864 return ret;
1865 }
1866
mlx5_get_vq_irq(struct vdpa_device * vdv,u16 idx)1867 static int mlx5_get_vq_irq(struct vdpa_device *vdv, u16 idx)
1868 {
1869 return -EOPNOTSUPP;
1870 }
1871
1872 static const struct vdpa_config_ops mlx5_vdpa_ops = {
1873 .set_vq_address = mlx5_vdpa_set_vq_address,
1874 .set_vq_num = mlx5_vdpa_set_vq_num,
1875 .kick_vq = mlx5_vdpa_kick_vq,
1876 .set_vq_cb = mlx5_vdpa_set_vq_cb,
1877 .set_vq_ready = mlx5_vdpa_set_vq_ready,
1878 .get_vq_ready = mlx5_vdpa_get_vq_ready,
1879 .set_vq_state = mlx5_vdpa_set_vq_state,
1880 .get_vq_state = mlx5_vdpa_get_vq_state,
1881 .get_vq_notification = mlx5_get_vq_notification,
1882 .get_vq_irq = mlx5_get_vq_irq,
1883 .get_vq_align = mlx5_vdpa_get_vq_align,
1884 .get_features = mlx5_vdpa_get_features,
1885 .set_features = mlx5_vdpa_set_features,
1886 .set_config_cb = mlx5_vdpa_set_config_cb,
1887 .get_vq_num_max = mlx5_vdpa_get_vq_num_max,
1888 .get_device_id = mlx5_vdpa_get_device_id,
1889 .get_vendor_id = mlx5_vdpa_get_vendor_id,
1890 .get_status = mlx5_vdpa_get_status,
1891 .set_status = mlx5_vdpa_set_status,
1892 .get_config = mlx5_vdpa_get_config,
1893 .set_config = mlx5_vdpa_set_config,
1894 .get_generation = mlx5_vdpa_get_generation,
1895 .set_map = mlx5_vdpa_set_map,
1896 .free = mlx5_vdpa_free,
1897 };
1898
query_mtu(struct mlx5_core_dev * mdev,u16 * mtu)1899 static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
1900 {
1901 u16 hw_mtu;
1902 int err;
1903
1904 err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu);
1905 if (err)
1906 return err;
1907
1908 *mtu = hw_mtu - MLX5V_ETH_HARD_MTU;
1909 return 0;
1910 }
1911
alloc_resources(struct mlx5_vdpa_net * ndev)1912 static int alloc_resources(struct mlx5_vdpa_net *ndev)
1913 {
1914 struct mlx5_vdpa_net_resources *res = &ndev->res;
1915 int err;
1916
1917 if (res->valid) {
1918 mlx5_vdpa_warn(&ndev->mvdev, "resources already allocated\n");
1919 return -EEXIST;
1920 }
1921
1922 err = mlx5_vdpa_alloc_transport_domain(&ndev->mvdev, &res->tdn);
1923 if (err)
1924 return err;
1925
1926 err = create_tis(ndev);
1927 if (err)
1928 goto err_tis;
1929
1930 res->valid = true;
1931
1932 return 0;
1933
1934 err_tis:
1935 mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
1936 return err;
1937 }
1938
free_resources(struct mlx5_vdpa_net * ndev)1939 static void free_resources(struct mlx5_vdpa_net *ndev)
1940 {
1941 struct mlx5_vdpa_net_resources *res = &ndev->res;
1942
1943 if (!res->valid)
1944 return;
1945
1946 destroy_tis(ndev);
1947 mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
1948 res->valid = false;
1949 }
1950
init_mvqs(struct mlx5_vdpa_net * ndev)1951 static void init_mvqs(struct mlx5_vdpa_net *ndev)
1952 {
1953 struct mlx5_vdpa_virtqueue *mvq;
1954 int i;
1955
1956 for (i = 0; i < 2 * mlx5_vdpa_max_qps(ndev->mvdev.max_vqs); ++i) {
1957 mvq = &ndev->vqs[i];
1958 memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1959 mvq->index = i;
1960 mvq->ndev = ndev;
1961 mvq->fwqp.fw = true;
1962 }
1963 for (; i < ndev->mvdev.max_vqs; i++) {
1964 mvq = &ndev->vqs[i];
1965 memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1966 mvq->index = i;
1967 mvq->ndev = ndev;
1968 }
1969 }
1970
mlx5_vdpa_add_dev(struct mlx5_core_dev * mdev)1971 void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
1972 {
1973 struct virtio_net_config *config;
1974 struct mlx5_core_dev *pfmdev;
1975 struct mlx5_vdpa_dev *mvdev;
1976 struct mlx5_vdpa_net *ndev;
1977 u32 max_vqs;
1978 int err;
1979
1980 /* we save one virtqueue for control virtqueue should we require it */
1981 max_vqs = MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
1982 max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
1983
1984 ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
1985 2 * mlx5_vdpa_max_qps(max_vqs));
1986 if (IS_ERR(ndev))
1987 return ndev;
1988
1989 ndev->mvdev.max_vqs = max_vqs;
1990 mvdev = &ndev->mvdev;
1991 mvdev->mdev = mdev;
1992 init_mvqs(ndev);
1993 mutex_init(&ndev->reslock);
1994 config = &ndev->config;
1995 err = query_mtu(mdev, &ndev->mtu);
1996 if (err)
1997 goto err_mtu;
1998
1999 err = mlx5_query_nic_vport_mac_address(mdev, 0, 0, config->mac);
2000 if (err)
2001 goto err_mtu;
2002
2003 if (!is_zero_ether_addr(config->mac)) {
2004 pfmdev = pci_get_drvdata(pci_physfn(mdev->pdev));
2005 err = mlx5_mpfs_add_mac(pfmdev, config->mac);
2006 if (err)
2007 goto err_mtu;
2008 }
2009
2010 mvdev->vdev.dma_dev = mdev->device;
2011 err = mlx5_vdpa_alloc_resources(&ndev->mvdev);
2012 if (err)
2013 goto err_mpfs;
2014
2015 err = alloc_resources(ndev);
2016 if (err)
2017 goto err_res;
2018
2019 err = vdpa_register_device(&mvdev->vdev);
2020 if (err)
2021 goto err_reg;
2022
2023 return ndev;
2024
2025 err_reg:
2026 free_resources(ndev);
2027 err_res:
2028 mlx5_vdpa_free_resources(&ndev->mvdev);
2029 err_mpfs:
2030 if (!is_zero_ether_addr(config->mac))
2031 mlx5_mpfs_del_mac(pfmdev, config->mac);
2032 err_mtu:
2033 mutex_destroy(&ndev->reslock);
2034 put_device(&mvdev->vdev.dev);
2035 return ERR_PTR(err);
2036 }
2037
mlx5_vdpa_remove_dev(struct mlx5_vdpa_dev * mvdev)2038 void mlx5_vdpa_remove_dev(struct mlx5_vdpa_dev *mvdev)
2039 {
2040 vdpa_unregister_device(&mvdev->vdev);
2041 }
2042