1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2020 Mellanox Technologies Ltd. */
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 "mlx5_vnet.h"
13 #include "mlx5_vdpa_ifc.h"
14 #include "mlx5_vdpa.h"
16 #define to_mvdev(__vdev) container_of((__vdev), struct mlx5_vdpa_dev, vdev)
18 #define VALID_FEATURES_MASK \
19 (BIT_ULL(VIRTIO_NET_F_CSUM) | BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) | \
20 BIT_ULL(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) | BIT_ULL(VIRTIO_NET_F_MTU) | BIT_ULL(VIRTIO_NET_F_MAC) | \
21 BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) | BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) | \
22 BIT_ULL(VIRTIO_NET_F_GUEST_ECN) | BIT_ULL(VIRTIO_NET_F_GUEST_UFO) | BIT_ULL(VIRTIO_NET_F_HOST_TSO4) | \
23 BIT_ULL(VIRTIO_NET_F_HOST_TSO6) | BIT_ULL(VIRTIO_NET_F_HOST_ECN) | BIT_ULL(VIRTIO_NET_F_HOST_UFO) | \
24 BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | BIT_ULL(VIRTIO_NET_F_STATUS) | BIT_ULL(VIRTIO_NET_F_CTRL_VQ) | \
25 BIT_ULL(VIRTIO_NET_F_CTRL_RX) | BIT_ULL(VIRTIO_NET_F_CTRL_VLAN) | \
26 BIT_ULL(VIRTIO_NET_F_CTRL_RX_EXTRA) | BIT_ULL(VIRTIO_NET_F_GUEST_ANNOUNCE) | \
27 BIT_ULL(VIRTIO_NET_F_MQ) | BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) | BIT_ULL(VIRTIO_NET_F_HASH_REPORT) | \
28 BIT_ULL(VIRTIO_NET_F_RSS) | BIT_ULL(VIRTIO_NET_F_RSC_EXT) | BIT_ULL(VIRTIO_NET_F_STANDBY) | \
29 BIT_ULL(VIRTIO_NET_F_SPEED_DUPLEX) | BIT_ULL(VIRTIO_F_NOTIFY_ON_EMPTY) | \
30 BIT_ULL(VIRTIO_F_ANY_LAYOUT) | BIT_ULL(VIRTIO_F_VERSION_1) | BIT_ULL(VIRTIO_F_ACCESS_PLATFORM) | \
31 BIT_ULL(VIRTIO_F_RING_PACKED) | BIT_ULL(VIRTIO_F_ORDER_PLATFORM) | BIT_ULL(VIRTIO_F_SR_IOV))
33 #define VALID_STATUS_MASK \
34 (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK | \
35 VIRTIO_CONFIG_S_FEATURES_OK | VIRTIO_CONFIG_S_NEEDS_RESET | VIRTIO_CONFIG_S_FAILED)
37 struct mlx5_vdpa_net_resources {
45 struct mlx5_vdpa_cq_buf {
46 struct mlx5_frag_buf_ctrl fbc;
47 struct mlx5_frag_buf frag_buf;
53 struct mlx5_core_cq mcq;
54 struct mlx5_vdpa_cq_buf buf;
59 struct mlx5_vdpa_umem {
60 struct mlx5_frag_buf_ctrl fbc;
61 struct mlx5_frag_buf frag_buf;
67 struct mlx5_core_qp mqp;
68 struct mlx5_frag_buf frag_buf;
74 struct mlx5_vq_restore_info {
81 struct vdpa_callback cb;
85 struct mlx5_vdpa_virtqueue {
91 struct vdpa_callback event_cb;
93 /* Resources for implementing the notification channel from the device
94 * to the driver. fwqp is the firmware end of an RC connection; the
95 * other end is vqqp used by the driver. cq is is where completions are
98 struct mlx5_vdpa_cq cq;
99 struct mlx5_vdpa_qp fwqp;
100 struct mlx5_vdpa_qp vqqp;
102 /* umem resources are required for the virtqueue operation. They're use
103 * is internal and they must be provided by the driver.
105 struct mlx5_vdpa_umem umem1;
106 struct mlx5_vdpa_umem umem2;
107 struct mlx5_vdpa_umem umem3;
112 struct mlx5_vdpa_net *ndev;
116 /* keep last in the struct */
117 struct mlx5_vq_restore_info ri;
120 /* We will remove this limitation once mlx5_vdpa_alloc_resources()
121 * provides for driver space allocation
123 #define MLX5_MAX_SUPPORTED_VQS 16
125 struct mlx5_vdpa_net {
126 struct mlx5_vdpa_dev mvdev;
127 struct mlx5_vdpa_net_resources res;
128 struct virtio_net_config config;
129 struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS];
131 /* Serialize vq resources creation and destruction. This is required
132 * since memory map might change and we need to destroy and create
133 * resources while driver in operational.
135 struct mutex reslock;
136 struct mlx5_flow_table *rxft;
137 struct mlx5_fc *rx_counter;
138 struct mlx5_flow_handle *rx_rule;
143 static void free_resources(struct mlx5_vdpa_net *ndev);
144 static void init_mvqs(struct mlx5_vdpa_net *ndev);
145 static int setup_driver(struct mlx5_vdpa_net *ndev);
146 static void teardown_driver(struct mlx5_vdpa_net *ndev);
148 static bool mlx5_vdpa_debug;
150 #define MLX5_LOG_VIO_FLAG(_feature) \
152 if (features & BIT_ULL(_feature)) \
153 mlx5_vdpa_info(mvdev, "%s\n", #_feature); \
156 #define MLX5_LOG_VIO_STAT(_status) \
158 if (status & (_status)) \
159 mlx5_vdpa_info(mvdev, "%s\n", #_status); \
162 static void print_status(struct mlx5_vdpa_dev *mvdev, u8 status, bool set)
164 if (status & ~VALID_STATUS_MASK)
165 mlx5_vdpa_warn(mvdev, "Warning: there are invalid status bits 0x%x\n",
166 status & ~VALID_STATUS_MASK);
168 if (!mlx5_vdpa_debug)
171 mlx5_vdpa_info(mvdev, "driver status %s", set ? "set" : "get");
172 if (set && !status) {
173 mlx5_vdpa_info(mvdev, "driver resets the device\n");
177 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_ACKNOWLEDGE);
178 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_DRIVER);
179 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_DRIVER_OK);
180 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_FEATURES_OK);
181 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_NEEDS_RESET);
182 MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_FAILED);
185 static void print_features(struct mlx5_vdpa_dev *mvdev, u64 features, bool set)
187 if (features & ~VALID_FEATURES_MASK)
188 mlx5_vdpa_warn(mvdev, "There are invalid feature bits 0x%llx\n",
189 features & ~VALID_FEATURES_MASK);
191 if (!mlx5_vdpa_debug)
194 mlx5_vdpa_info(mvdev, "driver %s feature bits:\n", set ? "sets" : "reads");
196 mlx5_vdpa_info(mvdev, "all feature bits are cleared\n");
198 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CSUM);
199 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_CSUM);
200 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS);
201 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MTU);
202 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MAC);
203 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_TSO4);
204 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_TSO6);
205 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_ECN);
206 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_UFO);
207 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_TSO4);
208 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_TSO6);
209 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_ECN);
210 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_UFO);
211 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MRG_RXBUF);
212 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_STATUS);
213 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_VQ);
214 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_RX);
215 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_VLAN);
216 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_RX_EXTRA);
217 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_ANNOUNCE);
218 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MQ);
219 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_MAC_ADDR);
220 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HASH_REPORT);
221 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_RSS);
222 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_RSC_EXT);
223 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_STANDBY);
224 MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_SPEED_DUPLEX);
225 MLX5_LOG_VIO_FLAG(VIRTIO_F_NOTIFY_ON_EMPTY);
226 MLX5_LOG_VIO_FLAG(VIRTIO_F_ANY_LAYOUT);
227 MLX5_LOG_VIO_FLAG(VIRTIO_F_VERSION_1);
228 MLX5_LOG_VIO_FLAG(VIRTIO_F_ACCESS_PLATFORM);
229 MLX5_LOG_VIO_FLAG(VIRTIO_F_RING_PACKED);
230 MLX5_LOG_VIO_FLAG(VIRTIO_F_ORDER_PLATFORM);
231 MLX5_LOG_VIO_FLAG(VIRTIO_F_SR_IOV);
234 static int create_tis(struct mlx5_vdpa_net *ndev)
236 struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
237 u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
241 tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
242 MLX5_SET(tisc, tisc, transport_domain, ndev->res.tdn);
243 err = mlx5_vdpa_create_tis(mvdev, in, &ndev->res.tisn);
245 mlx5_vdpa_warn(mvdev, "create TIS (%d)\n", err);
250 static void destroy_tis(struct mlx5_vdpa_net *ndev)
252 mlx5_vdpa_destroy_tis(&ndev->mvdev, ndev->res.tisn);
255 #define MLX5_VDPA_CQE_SIZE 64
256 #define MLX5_VDPA_LOG_CQE_SIZE ilog2(MLX5_VDPA_CQE_SIZE)
258 static int cq_frag_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_cq_buf *buf, int nent)
260 struct mlx5_frag_buf *frag_buf = &buf->frag_buf;
261 u8 log_wq_stride = MLX5_VDPA_LOG_CQE_SIZE;
262 u8 log_wq_sz = MLX5_VDPA_LOG_CQE_SIZE;
265 err = mlx5_frag_buf_alloc_node(ndev->mvdev.mdev, nent * MLX5_VDPA_CQE_SIZE, frag_buf,
266 ndev->mvdev.mdev->priv.numa_node);
270 mlx5_init_fbc(frag_buf->frags, log_wq_stride, log_wq_sz, &buf->fbc);
272 buf->cqe_size = MLX5_VDPA_CQE_SIZE;
278 static int umem_frag_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_umem *umem, int size)
280 struct mlx5_frag_buf *frag_buf = &umem->frag_buf;
282 return mlx5_frag_buf_alloc_node(ndev->mvdev.mdev, size, frag_buf,
283 ndev->mvdev.mdev->priv.numa_node);
286 static void cq_frag_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_cq_buf *buf)
288 mlx5_frag_buf_free(ndev->mvdev.mdev, &buf->frag_buf);
291 static void *get_cqe(struct mlx5_vdpa_cq *vcq, int n)
293 return mlx5_frag_buf_get_wqe(&vcq->buf.fbc, n);
296 static void cq_frag_buf_init(struct mlx5_vdpa_cq *vcq, struct mlx5_vdpa_cq_buf *buf)
298 struct mlx5_cqe64 *cqe64;
302 for (i = 0; i < buf->nent; i++) {
303 cqe = get_cqe(vcq, i);
305 cqe64->op_own = MLX5_CQE_INVALID << 4;
309 static void *get_sw_cqe(struct mlx5_vdpa_cq *cq, int n)
311 struct mlx5_cqe64 *cqe64 = get_cqe(cq, n & (cq->cqe - 1));
313 if (likely(get_cqe_opcode(cqe64) != MLX5_CQE_INVALID) &&
314 !((cqe64->op_own & MLX5_CQE_OWNER_MASK) ^ !!(n & cq->cqe)))
320 static void rx_post(struct mlx5_vdpa_qp *vqp, int n)
323 vqp->db.db[0] = cpu_to_be32(vqp->head);
326 static void qp_prepare(struct mlx5_vdpa_net *ndev, bool fw, void *in,
327 struct mlx5_vdpa_virtqueue *mvq, u32 num_ent)
329 struct mlx5_vdpa_qp *vqp;
333 vqp = fw ? &mvq->fwqp : &mvq->vqqp;
334 MLX5_SET(create_qp_in, in, uid, ndev->mvdev.res.uid);
335 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
337 /* Firmware QP is allocated by the driver for the firmware's
338 * use so we can skip part of the params as they will be chosen by firmware
340 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
341 MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
342 MLX5_SET(qpc, qpc, no_sq, 1);
346 MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
347 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
348 MLX5_SET(qpc, qpc, pd, ndev->mvdev.res.pdn);
349 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
350 MLX5_SET(qpc, qpc, uar_page, ndev->mvdev.res.uar->index);
351 MLX5_SET(qpc, qpc, log_page_size, vqp->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
352 MLX5_SET(qpc, qpc, no_sq, 1);
353 MLX5_SET(qpc, qpc, cqn_rcv, mvq->cq.mcq.cqn);
354 MLX5_SET(qpc, qpc, log_rq_size, ilog2(num_ent));
355 MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ);
356 pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, in, pas);
357 mlx5_fill_page_frag_array(&vqp->frag_buf, pas);
360 static int rq_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp, u32 num_ent)
362 return mlx5_frag_buf_alloc_node(ndev->mvdev.mdev,
363 num_ent * sizeof(struct mlx5_wqe_data_seg), &vqp->frag_buf,
364 ndev->mvdev.mdev->priv.numa_node);
367 static void rq_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp)
369 mlx5_frag_buf_free(ndev->mvdev.mdev, &vqp->frag_buf);
372 static int qp_create(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
373 struct mlx5_vdpa_qp *vqp)
375 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
376 int inlen = MLX5_ST_SZ_BYTES(create_qp_in);
377 u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};
384 err = rq_buf_alloc(ndev, vqp, mvq->num_ent);
388 err = mlx5_db_alloc(ndev->mvdev.mdev, &vqp->db);
391 inlen += vqp->frag_buf.npages * sizeof(__be64);
394 in = kzalloc(inlen, GFP_KERNEL);
400 qp_prepare(ndev, vqp->fw, in, mvq, mvq->num_ent);
401 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
402 MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
403 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
404 MLX5_SET(qpc, qpc, pd, ndev->mvdev.res.pdn);
405 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
407 MLX5_SET64(qpc, qpc, dbr_addr, vqp->db.dma);
408 MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
409 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
414 vqp->mqp.uid = ndev->mvdev.res.uid;
415 vqp->mqp.qpn = MLX5_GET(create_qp_out, out, qpn);
418 rx_post(vqp, mvq->num_ent);
424 mlx5_db_free(ndev->mvdev.mdev, &vqp->db);
427 rq_buf_free(ndev, vqp);
432 static void qp_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp)
434 u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {};
436 MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
437 MLX5_SET(destroy_qp_in, in, qpn, vqp->mqp.qpn);
438 MLX5_SET(destroy_qp_in, in, uid, ndev->mvdev.res.uid);
439 if (mlx5_cmd_exec_in(ndev->mvdev.mdev, destroy_qp, in))
440 mlx5_vdpa_warn(&ndev->mvdev, "destroy qp 0x%x\n", vqp->mqp.qpn);
442 mlx5_db_free(ndev->mvdev.mdev, &vqp->db);
443 rq_buf_free(ndev, vqp);
447 static void *next_cqe_sw(struct mlx5_vdpa_cq *cq)
449 return get_sw_cqe(cq, cq->mcq.cons_index);
452 static int mlx5_vdpa_poll_one(struct mlx5_vdpa_cq *vcq)
454 struct mlx5_cqe64 *cqe64;
456 cqe64 = next_cqe_sw(vcq);
460 vcq->mcq.cons_index++;
464 static void mlx5_vdpa_handle_completions(struct mlx5_vdpa_virtqueue *mvq, int num)
466 mlx5_cq_set_ci(&mvq->cq.mcq);
468 /* make sure CQ cosumer update is visible to the hardware before updating
469 * RX doorbell record.
472 rx_post(&mvq->vqqp, num);
473 if (mvq->event_cb.callback)
474 mvq->event_cb.callback(mvq->event_cb.private);
477 static void mlx5_vdpa_cq_comp(struct mlx5_core_cq *mcq, struct mlx5_eqe *eqe)
479 struct mlx5_vdpa_virtqueue *mvq = container_of(mcq, struct mlx5_vdpa_virtqueue, cq.mcq);
480 struct mlx5_vdpa_net *ndev = mvq->ndev;
481 void __iomem *uar_page = ndev->mvdev.res.uar->map;
484 while (!mlx5_vdpa_poll_one(&mvq->cq)) {
486 if (num > mvq->num_ent / 2) {
487 /* If completions keep coming while we poll, we want to
488 * let the hardware know that we consumed them by
489 * updating the doorbell record. We also let vdpa core
490 * know about this so it passes it on the virtio driver
493 mlx5_vdpa_handle_completions(mvq, num);
499 mlx5_vdpa_handle_completions(mvq, num);
501 mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
504 static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
506 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
507 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
508 void __iomem *uar_page = ndev->mvdev.res.uar->map;
509 u32 out[MLX5_ST_SZ_DW(create_cq_out)];
510 struct mlx5_vdpa_cq *vcq = &mvq->cq;
519 err = mlx5_db_alloc(mdev, &vcq->db);
523 vcq->mcq.set_ci_db = vcq->db.db;
524 vcq->mcq.arm_db = vcq->db.db + 1;
525 vcq->mcq.cqe_sz = 64;
527 err = cq_frag_buf_alloc(ndev, &vcq->buf, num_ent);
531 cq_frag_buf_init(vcq, &vcq->buf);
533 inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
534 MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * vcq->buf.frag_buf.npages;
535 in = kzalloc(inlen, GFP_KERNEL);
541 MLX5_SET(create_cq_in, in, uid, ndev->mvdev.res.uid);
542 pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas);
543 mlx5_fill_page_frag_array(&vcq->buf.frag_buf, pas);
545 cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
546 MLX5_SET(cqc, cqc, log_page_size, vcq->buf.frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
548 /* Use vector 0 by default. Consider adding code to choose least used
551 err = mlx5_vector2eqn(mdev, 0, &eqn, &irqn);
555 cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
556 MLX5_SET(cqc, cqc, log_cq_size, ilog2(num_ent));
557 MLX5_SET(cqc, cqc, uar_page, ndev->mvdev.res.uar->index);
558 MLX5_SET(cqc, cqc, c_eqn, eqn);
559 MLX5_SET64(cqc, cqc, dbr_addr, vcq->db.dma);
561 err = mlx5_core_create_cq(mdev, &vcq->mcq, in, inlen, out, sizeof(out));
565 vcq->mcq.comp = mlx5_vdpa_cq_comp;
567 vcq->mcq.set_ci_db = vcq->db.db;
568 vcq->mcq.arm_db = vcq->db.db + 1;
569 mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
576 cq_frag_buf_free(ndev, &vcq->buf);
578 mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
582 static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 idx)
584 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
585 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
586 struct mlx5_vdpa_cq *vcq = &mvq->cq;
588 if (mlx5_core_destroy_cq(mdev, &vcq->mcq)) {
589 mlx5_vdpa_warn(&ndev->mvdev, "destroy CQ 0x%x\n", vcq->mcq.cqn);
592 cq_frag_buf_free(ndev, &vcq->buf);
593 mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
596 static int umem_size(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num,
597 struct mlx5_vdpa_umem **umemp)
599 struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
605 p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_a);
606 p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_b);
607 *umemp = &mvq->umem1;
610 p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_a);
611 p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_b);
612 *umemp = &mvq->umem2;
615 p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_a);
616 p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_b);
617 *umemp = &mvq->umem3;
620 return p_a * mvq->num_ent + p_b;
623 static void umem_frag_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_umem *umem)
625 mlx5_frag_buf_free(ndev->mvdev.mdev, &umem->frag_buf);
628 static int create_umem(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num)
631 u32 out[MLX5_ST_SZ_DW(create_umem_out)] = {};
637 struct mlx5_vdpa_umem *umem;
639 size = umem_size(ndev, mvq, num, &umem);
644 err = umem_frag_buf_alloc(ndev, umem, size);
648 inlen = MLX5_ST_SZ_BYTES(create_umem_in) + MLX5_ST_SZ_BYTES(mtt) * umem->frag_buf.npages;
650 in = kzalloc(inlen, GFP_KERNEL);
656 MLX5_SET(create_umem_in, in, opcode, MLX5_CMD_OP_CREATE_UMEM);
657 MLX5_SET(create_umem_in, in, uid, ndev->mvdev.res.uid);
658 um = MLX5_ADDR_OF(create_umem_in, in, umem);
659 MLX5_SET(umem, um, log_page_size, umem->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
660 MLX5_SET64(umem, um, num_of_mtt, umem->frag_buf.npages);
662 pas = (__be64 *)MLX5_ADDR_OF(umem, um, mtt[0]);
663 mlx5_fill_page_frag_array_perm(&umem->frag_buf, pas, MLX5_MTT_PERM_RW);
665 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
667 mlx5_vdpa_warn(&ndev->mvdev, "create umem(%d)\n", err);
672 umem->id = MLX5_GET(create_umem_out, out, umem_id);
679 umem_frag_buf_free(ndev, umem);
683 static void umem_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num)
685 u32 in[MLX5_ST_SZ_DW(destroy_umem_in)] = {};
686 u32 out[MLX5_ST_SZ_DW(destroy_umem_out)] = {};
687 struct mlx5_vdpa_umem *umem;
701 MLX5_SET(destroy_umem_in, in, opcode, MLX5_CMD_OP_DESTROY_UMEM);
702 MLX5_SET(destroy_umem_in, in, umem_id, umem->id);
703 if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out)))
706 umem_frag_buf_free(ndev, umem);
709 static int umems_create(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
714 for (num = 1; num <= 3; num++) {
715 err = create_umem(ndev, mvq, num);
722 for (num--; num > 0; num--)
723 umem_destroy(ndev, mvq, num);
728 static void umems_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
732 for (num = 3; num > 0; num--)
733 umem_destroy(ndev, mvq, num);
736 static int get_queue_type(struct mlx5_vdpa_net *ndev)
740 type_mask = MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, virtio_queue_type);
742 /* prefer split queue */
743 if (type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED)
744 return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED;
746 WARN_ON(!(type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT));
748 return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT;
751 static bool vq_is_tx(u16 idx)
756 static u16 get_features_12_3(u64 features)
758 return (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_TSO4)) << 9) |
759 (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_TSO6)) << 8) |
760 (!!(features & BIT_ULL(VIRTIO_NET_F_CSUM)) << 7) |
761 (!!(features & BIT_ULL(VIRTIO_NET_F_GUEST_CSUM)) << 6);
764 static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
766 int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
767 u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
774 err = umems_create(ndev, mvq);
778 in = kzalloc(inlen, GFP_KERNEL);
784 cmd_hdr = MLX5_ADDR_OF(create_virtio_net_q_in, in, general_obj_in_cmd_hdr);
786 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
787 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
788 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
790 obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context);
791 MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx);
792 MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3,
793 get_features_12_3(ndev->mvdev.actual_features));
794 vq_ctx = MLX5_ADDR_OF(virtio_net_q_object, obj_context, virtio_q_context);
795 MLX5_SET(virtio_q, vq_ctx, virtio_q_type, get_queue_type(ndev));
797 if (vq_is_tx(mvq->index))
798 MLX5_SET(virtio_net_q_object, obj_context, tisn_or_qpn, ndev->res.tisn);
800 MLX5_SET(virtio_q, vq_ctx, event_mode, MLX5_VIRTIO_Q_EVENT_MODE_QP_MODE);
801 MLX5_SET(virtio_q, vq_ctx, queue_index, mvq->index);
802 MLX5_SET(virtio_q, vq_ctx, event_qpn_or_msix, mvq->fwqp.mqp.qpn);
803 MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent);
804 MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0,
805 !!(ndev->mvdev.actual_features & VIRTIO_F_VERSION_1));
806 MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
807 MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
808 MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
809 MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr.mkey.key);
810 MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
811 MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
812 MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
813 MLX5_SET(virtio_q, vq_ctx, umem_2_size, mvq->umem1.size);
814 MLX5_SET(virtio_q, vq_ctx, umem_3_id, mvq->umem3.id);
815 MLX5_SET(virtio_q, vq_ctx, umem_3_size, mvq->umem1.size);
816 MLX5_SET(virtio_q, vq_ctx, pd, ndev->mvdev.res.pdn);
817 if (MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, eth_frame_offload_type))
818 MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0, 1);
820 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
825 mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
832 umems_destroy(ndev, mvq);
836 static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
838 u32 in[MLX5_ST_SZ_DW(destroy_virtio_net_q_in)] = {};
839 u32 out[MLX5_ST_SZ_DW(destroy_virtio_net_q_out)] = {};
841 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.opcode,
842 MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
843 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_id, mvq->virtq_id);
844 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.uid, ndev->mvdev.res.uid);
845 MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_type,
846 MLX5_OBJ_TYPE_VIRTIO_NET_Q);
847 if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out))) {
848 mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
851 umems_destroy(ndev, mvq);
854 static u32 get_rqpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
856 return fw ? mvq->vqqp.mqp.qpn : mvq->fwqp.mqp.qpn;
859 static u32 get_qpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
861 return fw ? mvq->fwqp.mqp.qpn : mvq->vqqp.mqp.qpn;
864 static void alloc_inout(struct mlx5_vdpa_net *ndev, int cmd, void **in, int *inlen, void **out,
865 int *outlen, u32 qpn, u32 rqpn)
871 case MLX5_CMD_OP_2RST_QP:
872 *inlen = MLX5_ST_SZ_BYTES(qp_2rst_in);
873 *outlen = MLX5_ST_SZ_BYTES(qp_2rst_out);
874 *in = kzalloc(*inlen, GFP_KERNEL);
875 *out = kzalloc(*outlen, GFP_KERNEL);
879 MLX5_SET(qp_2rst_in, *in, opcode, cmd);
880 MLX5_SET(qp_2rst_in, *in, uid, ndev->mvdev.res.uid);
881 MLX5_SET(qp_2rst_in, *in, qpn, qpn);
883 case MLX5_CMD_OP_RST2INIT_QP:
884 *inlen = MLX5_ST_SZ_BYTES(rst2init_qp_in);
885 *outlen = MLX5_ST_SZ_BYTES(rst2init_qp_out);
886 *in = kzalloc(*inlen, GFP_KERNEL);
887 *out = kzalloc(MLX5_ST_SZ_BYTES(rst2init_qp_out), GFP_KERNEL);
891 MLX5_SET(rst2init_qp_in, *in, opcode, cmd);
892 MLX5_SET(rst2init_qp_in, *in, uid, ndev->mvdev.res.uid);
893 MLX5_SET(rst2init_qp_in, *in, qpn, qpn);
894 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
895 MLX5_SET(qpc, qpc, remote_qpn, rqpn);
896 MLX5_SET(qpc, qpc, rwe, 1);
897 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
898 MLX5_SET(ads, pp, vhca_port_num, 1);
900 case MLX5_CMD_OP_INIT2RTR_QP:
901 *inlen = MLX5_ST_SZ_BYTES(init2rtr_qp_in);
902 *outlen = MLX5_ST_SZ_BYTES(init2rtr_qp_out);
903 *in = kzalloc(*inlen, GFP_KERNEL);
904 *out = kzalloc(MLX5_ST_SZ_BYTES(init2rtr_qp_out), GFP_KERNEL);
908 MLX5_SET(init2rtr_qp_in, *in, opcode, cmd);
909 MLX5_SET(init2rtr_qp_in, *in, uid, ndev->mvdev.res.uid);
910 MLX5_SET(init2rtr_qp_in, *in, qpn, qpn);
911 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
912 MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
913 MLX5_SET(qpc, qpc, log_msg_max, 30);
914 MLX5_SET(qpc, qpc, remote_qpn, rqpn);
915 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
916 MLX5_SET(ads, pp, fl, 1);
918 case MLX5_CMD_OP_RTR2RTS_QP:
919 *inlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_in);
920 *outlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_out);
921 *in = kzalloc(*inlen, GFP_KERNEL);
922 *out = kzalloc(MLX5_ST_SZ_BYTES(rtr2rts_qp_out), GFP_KERNEL);
926 MLX5_SET(rtr2rts_qp_in, *in, opcode, cmd);
927 MLX5_SET(rtr2rts_qp_in, *in, uid, ndev->mvdev.res.uid);
928 MLX5_SET(rtr2rts_qp_in, *in, qpn, qpn);
929 qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
930 pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
931 MLX5_SET(ads, pp, ack_timeout, 14);
932 MLX5_SET(qpc, qpc, retry_count, 7);
933 MLX5_SET(qpc, qpc, rnr_retry, 7);
949 static void free_inout(void *in, void *out)
955 /* Two QPs are used by each virtqueue. One is used by the driver and one by
956 * firmware. The fw argument indicates whether the subjected QP is the one used
959 static int modify_qp(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, bool fw, int cmd)
967 alloc_inout(ndev, cmd, &in, &inlen, &out, &outlen, get_qpn(mvq, fw), get_rqpn(mvq, fw));
971 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, outlen);
976 static int connect_qps(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
980 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_2RST_QP);
984 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_2RST_QP);
988 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_RST2INIT_QP);
992 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_RST2INIT_QP);
996 err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_INIT2RTR_QP);
1000 err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_INIT2RTR_QP);
1004 return modify_qp(ndev, mvq, true, MLX5_CMD_OP_RTR2RTS_QP);
1007 struct mlx5_virtq_attr {
1009 u16 available_index;
1012 static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
1013 struct mlx5_virtq_attr *attr)
1015 int outlen = MLX5_ST_SZ_BYTES(query_virtio_net_q_out);
1016 u32 in[MLX5_ST_SZ_DW(query_virtio_net_q_in)] = {};
1022 out = kzalloc(outlen, GFP_KERNEL);
1026 cmd_hdr = MLX5_ADDR_OF(query_virtio_net_q_in, in, general_obj_in_cmd_hdr);
1028 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
1029 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1030 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1031 MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1032 err = mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, outlen);
1036 obj_context = MLX5_ADDR_OF(query_virtio_net_q_out, out, obj_context);
1037 memset(attr, 0, sizeof(*attr));
1038 attr->state = MLX5_GET(virtio_net_q_object, obj_context, state);
1039 attr->available_index = MLX5_GET(virtio_net_q_object, obj_context, hw_available_index);
1048 static int modify_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int state)
1050 int inlen = MLX5_ST_SZ_BYTES(modify_virtio_net_q_in);
1051 u32 out[MLX5_ST_SZ_DW(modify_virtio_net_q_out)] = {};
1057 in = kzalloc(inlen, GFP_KERNEL);
1061 cmd_hdr = MLX5_ADDR_OF(modify_virtio_net_q_in, in, general_obj_in_cmd_hdr);
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);
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));
1075 mvq->fw_state = state;
1080 static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1082 u16 idx = mvq->index;
1088 if (mvq->initialized) {
1089 mlx5_vdpa_warn(&ndev->mvdev, "attempt re init\n");
1093 err = cq_create(ndev, idx, mvq->num_ent);
1097 err = qp_create(ndev, mvq, &mvq->fwqp);
1101 err = qp_create(ndev, mvq, &mvq->vqqp);
1105 err = connect_qps(ndev, mvq);
1109 err = create_virtqueue(ndev, mvq);
1114 err = modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
1116 mlx5_vdpa_warn(&ndev->mvdev, "failed to modify to ready vq idx %d(%d)\n",
1122 mvq->initialized = true;
1126 qp_destroy(ndev, &mvq->vqqp);
1128 qp_destroy(ndev, &mvq->fwqp);
1130 cq_destroy(ndev, idx);
1134 static void suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1136 struct mlx5_virtq_attr attr;
1138 if (!mvq->initialized)
1141 if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY)
1144 if (modify_virtqueue(ndev, mvq, MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND))
1145 mlx5_vdpa_warn(&ndev->mvdev, "modify to suspend failed\n");
1147 if (query_virtqueue(ndev, mvq, &attr)) {
1148 mlx5_vdpa_warn(&ndev->mvdev, "failed to query virtqueue\n");
1151 mvq->avail_idx = attr.available_index;
1154 static void suspend_vqs(struct mlx5_vdpa_net *ndev)
1158 for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++)
1159 suspend_vq(ndev, &ndev->vqs[i]);
1162 static void teardown_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1164 if (!mvq->initialized)
1167 suspend_vq(ndev, mvq);
1168 destroy_virtqueue(ndev, mvq);
1169 qp_destroy(ndev, &mvq->vqqp);
1170 qp_destroy(ndev, &mvq->fwqp);
1171 cq_destroy(ndev, mvq->index);
1172 mvq->initialized = false;
1175 static int create_rqt(struct mlx5_vdpa_net *ndev)
1185 log_max_rqt = min_t(int, 1, MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size));
1186 if (log_max_rqt < 1)
1189 inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + (1 << log_max_rqt) * MLX5_ST_SZ_BYTES(rq_num);
1190 in = kzalloc(inlen, GFP_KERNEL);
1194 MLX5_SET(create_rqt_in, in, uid, ndev->mvdev.res.uid);
1195 rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
1197 MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q);
1198 MLX5_SET(rqtc, rqtc, rqt_max_size, 1 << log_max_rqt);
1199 MLX5_SET(rqtc, rqtc, rqt_actual_size, 1);
1200 list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]);
1201 for (i = 0, j = 0; j < ndev->mvdev.max_vqs; j++) {
1202 if (!ndev->vqs[j].initialized)
1205 if (!vq_is_tx(ndev->vqs[j].index)) {
1206 list[i] = cpu_to_be32(ndev->vqs[j].virtq_id);
1211 err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);
1219 static void destroy_rqt(struct mlx5_vdpa_net *ndev)
1221 mlx5_vdpa_destroy_rqt(&ndev->mvdev, ndev->res.rqtn);
1224 static int create_tir(struct mlx5_vdpa_net *ndev)
1226 #define HASH_IP_L4PORTS \
1227 (MLX5_HASH_FIELD_SEL_SRC_IP | MLX5_HASH_FIELD_SEL_DST_IP | MLX5_HASH_FIELD_SEL_L4_SPORT | \
1228 MLX5_HASH_FIELD_SEL_L4_DPORT)
1229 static const u8 rx_hash_toeplitz_key[] = { 0x2c, 0xc6, 0x81, 0xd1, 0x5b, 0xdb, 0xf4, 0xf7,
1230 0xfc, 0xa2, 0x83, 0x19, 0xdb, 0x1a, 0x3e, 0x94,
1231 0x6b, 0x9e, 0x38, 0xd9, 0x2c, 0x9c, 0x03, 0xd1,
1232 0xad, 0x99, 0x44, 0xa7, 0xd9, 0x56, 0x3d, 0x59,
1233 0x06, 0x3c, 0x25, 0xf3, 0xfc, 0x1f, 0xdc, 0x2a };
1240 in = kzalloc(MLX5_ST_SZ_BYTES(create_tir_in), GFP_KERNEL);
1244 MLX5_SET(create_tir_in, in, uid, ndev->mvdev.res.uid);
1245 tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
1246 MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
1248 MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
1249 MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_TOEPLITZ);
1250 rss_key = MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
1251 memcpy(rss_key, rx_hash_toeplitz_key, sizeof(rx_hash_toeplitz_key));
1253 outer = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
1254 MLX5_SET(rx_hash_field_select, outer, l3_prot_type, MLX5_L3_PROT_TYPE_IPV4);
1255 MLX5_SET(rx_hash_field_select, outer, l4_prot_type, MLX5_L4_PROT_TYPE_TCP);
1256 MLX5_SET(rx_hash_field_select, outer, selected_fields, HASH_IP_L4PORTS);
1258 MLX5_SET(tirc, tirc, indirect_table, ndev->res.rqtn);
1259 MLX5_SET(tirc, tirc, transport_domain, ndev->res.tdn);
1261 err = mlx5_vdpa_create_tir(&ndev->mvdev, in, &ndev->res.tirn);
1266 static void destroy_tir(struct mlx5_vdpa_net *ndev)
1268 mlx5_vdpa_destroy_tir(&ndev->mvdev, ndev->res.tirn);
1271 static int add_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1273 struct mlx5_flow_destination dest[2] = {};
1274 struct mlx5_flow_table_attr ft_attr = {};
1275 struct mlx5_flow_act flow_act = {};
1276 struct mlx5_flow_namespace *ns;
1279 /* for now, one entry, match all, forward to tir */
1280 ft_attr.max_fte = 1;
1281 ft_attr.autogroup.max_num_groups = 1;
1283 ns = mlx5_get_flow_namespace(ndev->mvdev.mdev, MLX5_FLOW_NAMESPACE_BYPASS);
1285 mlx5_vdpa_warn(&ndev->mvdev, "get flow namespace\n");
1289 ndev->rxft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
1290 if (IS_ERR(ndev->rxft))
1291 return PTR_ERR(ndev->rxft);
1293 ndev->rx_counter = mlx5_fc_create(ndev->mvdev.mdev, false);
1294 if (IS_ERR(ndev->rx_counter)) {
1295 err = PTR_ERR(ndev->rx_counter);
1299 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_COUNT;
1300 dest[0].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1301 dest[0].tir_num = ndev->res.tirn;
1302 dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1303 dest[1].counter_id = mlx5_fc_id(ndev->rx_counter);
1304 ndev->rx_rule = mlx5_add_flow_rules(ndev->rxft, NULL, &flow_act, dest, 2);
1305 if (IS_ERR(ndev->rx_rule)) {
1306 err = PTR_ERR(ndev->rx_rule);
1307 ndev->rx_rule = NULL;
1314 mlx5_fc_destroy(ndev->mvdev.mdev, ndev->rx_counter);
1316 mlx5_destroy_flow_table(ndev->rxft);
1320 static void remove_fwd_to_tir(struct mlx5_vdpa_net *ndev)
1325 mlx5_del_flow_rules(ndev->rx_rule);
1326 mlx5_fc_destroy(ndev->mvdev.mdev, ndev->rx_counter);
1327 mlx5_destroy_flow_table(ndev->rxft);
1329 ndev->rx_rule = NULL;
1332 static void mlx5_vdpa_kick_vq(struct vdpa_device *vdev, u16 idx)
1334 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1335 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1336 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1338 if (unlikely(!mvq->ready))
1341 iowrite16(idx, ndev->mvdev.res.kick_addr);
1344 static int mlx5_vdpa_set_vq_address(struct vdpa_device *vdev, u16 idx, u64 desc_area,
1345 u64 driver_area, u64 device_area)
1347 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1348 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1349 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1351 mvq->desc_addr = desc_area;
1352 mvq->device_addr = device_area;
1353 mvq->driver_addr = driver_area;
1357 static void mlx5_vdpa_set_vq_num(struct vdpa_device *vdev, u16 idx, u32 num)
1359 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1360 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1361 struct mlx5_vdpa_virtqueue *mvq;
1363 mvq = &ndev->vqs[idx];
1367 static void mlx5_vdpa_set_vq_cb(struct vdpa_device *vdev, u16 idx, struct vdpa_callback *cb)
1369 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1370 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1371 struct mlx5_vdpa_virtqueue *vq = &ndev->vqs[idx];
1376 static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready)
1378 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1379 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1380 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1383 suspend_vq(ndev, mvq);
1388 static bool mlx5_vdpa_get_vq_ready(struct vdpa_device *vdev, u16 idx)
1390 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1391 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1392 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1397 static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx,
1398 const struct vdpa_vq_state *state)
1400 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1401 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1402 struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
1404 if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY) {
1405 mlx5_vdpa_warn(mvdev, "can't modify available index\n");
1409 mvq->avail_idx = state->avail_index;
1413 static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa_vq_state *state)
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;
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.
1425 if (!mvq->initialized) {
1426 state->avail_index = mvq->avail_idx;
1430 err = query_virtqueue(ndev, mvq, &attr);
1432 mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n");
1435 state->avail_index = attr.available_index;
1439 static u32 mlx5_vdpa_get_vq_align(struct vdpa_device *vdev)
1444 enum { MLX5_VIRTIO_NET_F_GUEST_CSUM = 1 << 9,
1445 MLX5_VIRTIO_NET_F_CSUM = 1 << 10,
1446 MLX5_VIRTIO_NET_F_HOST_TSO6 = 1 << 11,
1447 MLX5_VIRTIO_NET_F_HOST_TSO4 = 1 << 12,
1450 static u64 mlx_to_vritio_features(u16 dev_features)
1454 if (dev_features & MLX5_VIRTIO_NET_F_GUEST_CSUM)
1455 result |= BIT_ULL(VIRTIO_NET_F_GUEST_CSUM);
1456 if (dev_features & MLX5_VIRTIO_NET_F_CSUM)
1457 result |= BIT_ULL(VIRTIO_NET_F_CSUM);
1458 if (dev_features & MLX5_VIRTIO_NET_F_HOST_TSO6)
1459 result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO6);
1460 if (dev_features & MLX5_VIRTIO_NET_F_HOST_TSO4)
1461 result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO4);
1466 static u64 mlx5_vdpa_get_features(struct vdpa_device *vdev)
1468 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1469 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1472 dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, device_features_bits_mask);
1473 ndev->mvdev.mlx_features = mlx_to_vritio_features(dev_features);
1474 if (MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, virtio_version_1_0))
1475 ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_VERSION_1);
1476 ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM);
1477 print_features(mvdev, ndev->mvdev.mlx_features, false);
1478 return ndev->mvdev.mlx_features;
1481 static int verify_min_features(struct mlx5_vdpa_dev *mvdev, u64 features)
1483 if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)))
1489 static int setup_virtqueues(struct mlx5_vdpa_net *ndev)
1494 for (i = 0; i < 2 * mlx5_vdpa_max_qps(ndev->mvdev.max_vqs); i++) {
1495 err = setup_vq(ndev, &ndev->vqs[i]);
1503 for (--i; i >= 0; i--)
1504 teardown_vq(ndev, &ndev->vqs[i]);
1509 static void teardown_virtqueues(struct mlx5_vdpa_net *ndev)
1511 struct mlx5_vdpa_virtqueue *mvq;
1514 for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) {
1515 mvq = &ndev->vqs[i];
1516 if (!mvq->initialized)
1519 teardown_vq(ndev, mvq);
1523 /* TODO: cross-endian support */
1524 static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
1526 return virtio_legacy_is_little_endian() ||
1527 (mvdev->actual_features & (1ULL << VIRTIO_F_VERSION_1));
1530 static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val)
1532 return __cpu_to_virtio16(mlx5_vdpa_is_little_endian(mvdev), val);
1535 static int mlx5_vdpa_set_features(struct vdpa_device *vdev, u64 features)
1537 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1538 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1541 print_features(mvdev, features, true);
1543 err = verify_min_features(mvdev, features);
1547 ndev->mvdev.actual_features = features & ndev->mvdev.mlx_features;
1548 ndev->config.mtu = cpu_to_mlx5vdpa16(mvdev, ndev->mtu);
1549 ndev->config.status |= cpu_to_mlx5vdpa16(mvdev, VIRTIO_NET_S_LINK_UP);
1553 static void mlx5_vdpa_set_config_cb(struct vdpa_device *vdev, struct vdpa_callback *cb)
1555 /* not implemented */
1556 mlx5_vdpa_warn(to_mvdev(vdev), "set config callback not supported\n");
1559 #define MLX5_VDPA_MAX_VQ_ENTRIES 256
1560 static u16 mlx5_vdpa_get_vq_num_max(struct vdpa_device *vdev)
1562 return MLX5_VDPA_MAX_VQ_ENTRIES;
1565 static u32 mlx5_vdpa_get_device_id(struct vdpa_device *vdev)
1567 return VIRTIO_ID_NET;
1570 static u32 mlx5_vdpa_get_vendor_id(struct vdpa_device *vdev)
1572 return PCI_VENDOR_ID_MELLANOX;
1575 static u8 mlx5_vdpa_get_status(struct vdpa_device *vdev)
1577 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1578 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1580 print_status(mvdev, ndev->mvdev.status, false);
1581 return ndev->mvdev.status;
1584 static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1586 struct mlx5_vq_restore_info *ri = &mvq->ri;
1587 struct mlx5_virtq_attr attr;
1590 if (!mvq->initialized)
1593 err = query_virtqueue(ndev, mvq, &attr);
1597 ri->avail_index = attr.available_index;
1598 ri->ready = mvq->ready;
1599 ri->num_ent = mvq->num_ent;
1600 ri->desc_addr = mvq->desc_addr;
1601 ri->device_addr = mvq->device_addr;
1602 ri->driver_addr = mvq->driver_addr;
1603 ri->cb = mvq->event_cb;
1608 static int save_channels_info(struct mlx5_vdpa_net *ndev)
1612 for (i = 0; i < ndev->mvdev.max_vqs; i++) {
1613 memset(&ndev->vqs[i].ri, 0, sizeof(ndev->vqs[i].ri));
1614 save_channel_info(ndev, &ndev->vqs[i]);
1619 static void mlx5_clear_vqs(struct mlx5_vdpa_net *ndev)
1623 for (i = 0; i < ndev->mvdev.max_vqs; i++)
1624 memset(&ndev->vqs[i], 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1627 static void restore_channels_info(struct mlx5_vdpa_net *ndev)
1629 struct mlx5_vdpa_virtqueue *mvq;
1630 struct mlx5_vq_restore_info *ri;
1633 mlx5_clear_vqs(ndev);
1635 for (i = 0; i < ndev->mvdev.max_vqs; i++) {
1636 mvq = &ndev->vqs[i];
1641 mvq->avail_idx = ri->avail_index;
1642 mvq->ready = ri->ready;
1643 mvq->num_ent = ri->num_ent;
1644 mvq->desc_addr = ri->desc_addr;
1645 mvq->device_addr = ri->device_addr;
1646 mvq->driver_addr = ri->driver_addr;
1647 mvq->event_cb = ri->cb;
1651 static int mlx5_vdpa_change_map(struct mlx5_vdpa_net *ndev, struct vhost_iotlb *iotlb)
1656 err = save_channels_info(ndev);
1660 teardown_driver(ndev);
1661 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1662 err = mlx5_vdpa_create_mr(&ndev->mvdev, iotlb);
1666 if (!(ndev->mvdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
1669 restore_channels_info(ndev);
1670 err = setup_driver(ndev);
1677 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1682 static int setup_driver(struct mlx5_vdpa_net *ndev)
1686 mutex_lock(&ndev->reslock);
1688 mlx5_vdpa_warn(&ndev->mvdev, "setup driver called for already setup driver\n");
1692 err = setup_virtqueues(ndev);
1694 mlx5_vdpa_warn(&ndev->mvdev, "setup_virtqueues\n");
1698 err = create_rqt(ndev);
1700 mlx5_vdpa_warn(&ndev->mvdev, "create_rqt\n");
1704 err = create_tir(ndev);
1706 mlx5_vdpa_warn(&ndev->mvdev, "create_tir\n");
1710 err = add_fwd_to_tir(ndev);
1712 mlx5_vdpa_warn(&ndev->mvdev, "add_fwd_to_tir\n");
1716 mutex_unlock(&ndev->reslock);
1725 teardown_virtqueues(ndev);
1727 mutex_unlock(&ndev->reslock);
1731 static void teardown_driver(struct mlx5_vdpa_net *ndev)
1733 mutex_lock(&ndev->reslock);
1737 remove_fwd_to_tir(ndev);
1740 teardown_virtqueues(ndev);
1741 ndev->setup = false;
1743 mutex_unlock(&ndev->reslock);
1746 static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
1748 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1749 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1752 print_status(mvdev, status, true);
1754 mlx5_vdpa_info(mvdev, "performing device reset\n");
1755 teardown_driver(ndev);
1756 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1757 ndev->mvdev.status = 0;
1758 ndev->mvdev.mlx_features = 0;
1759 ++mvdev->generation;
1763 if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
1764 if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
1765 err = setup_driver(ndev);
1767 mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
1771 mlx5_vdpa_warn(mvdev, "did not expect DRIVER_OK to be cleared\n");
1776 ndev->mvdev.status = status;
1780 mlx5_vdpa_destroy_mr(&ndev->mvdev);
1781 ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
1784 static void mlx5_vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf,
1787 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1788 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1790 if (offset + len < sizeof(struct virtio_net_config))
1791 memcpy(buf, (u8 *)&ndev->config + offset, len);
1794 static void mlx5_vdpa_set_config(struct vdpa_device *vdev, unsigned int offset, const void *buf,
1800 static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
1802 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1804 return mvdev->generation;
1807 static int mlx5_vdpa_set_map(struct vdpa_device *vdev, struct vhost_iotlb *iotlb)
1809 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1810 struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
1814 err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map);
1816 mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
1821 return mlx5_vdpa_change_map(ndev, iotlb);
1826 static void mlx5_vdpa_free(struct vdpa_device *vdev)
1828 struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
1829 struct mlx5_vdpa_net *ndev;
1831 ndev = to_mlx5_vdpa_ndev(mvdev);
1833 free_resources(ndev);
1834 mlx5_vdpa_free_resources(&ndev->mvdev);
1835 mutex_destroy(&ndev->reslock);
1838 static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)
1840 struct vdpa_notification_area ret = {};
1845 static int mlx5_get_vq_irq(struct vdpa_device *vdv, u16 idx)
1850 static const struct vdpa_config_ops mlx5_vdpa_ops = {
1851 .set_vq_address = mlx5_vdpa_set_vq_address,
1852 .set_vq_num = mlx5_vdpa_set_vq_num,
1853 .kick_vq = mlx5_vdpa_kick_vq,
1854 .set_vq_cb = mlx5_vdpa_set_vq_cb,
1855 .set_vq_ready = mlx5_vdpa_set_vq_ready,
1856 .get_vq_ready = mlx5_vdpa_get_vq_ready,
1857 .set_vq_state = mlx5_vdpa_set_vq_state,
1858 .get_vq_state = mlx5_vdpa_get_vq_state,
1859 .get_vq_notification = mlx5_get_vq_notification,
1860 .get_vq_irq = mlx5_get_vq_irq,
1861 .get_vq_align = mlx5_vdpa_get_vq_align,
1862 .get_features = mlx5_vdpa_get_features,
1863 .set_features = mlx5_vdpa_set_features,
1864 .set_config_cb = mlx5_vdpa_set_config_cb,
1865 .get_vq_num_max = mlx5_vdpa_get_vq_num_max,
1866 .get_device_id = mlx5_vdpa_get_device_id,
1867 .get_vendor_id = mlx5_vdpa_get_vendor_id,
1868 .get_status = mlx5_vdpa_get_status,
1869 .set_status = mlx5_vdpa_set_status,
1870 .get_config = mlx5_vdpa_get_config,
1871 .set_config = mlx5_vdpa_set_config,
1872 .get_generation = mlx5_vdpa_get_generation,
1873 .set_map = mlx5_vdpa_set_map,
1874 .free = mlx5_vdpa_free,
1877 static int alloc_resources(struct mlx5_vdpa_net *ndev)
1879 struct mlx5_vdpa_net_resources *res = &ndev->res;
1883 mlx5_vdpa_warn(&ndev->mvdev, "resources already allocated\n");
1887 err = mlx5_vdpa_alloc_transport_domain(&ndev->mvdev, &res->tdn);
1891 err = create_tis(ndev);
1900 mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
1904 static void free_resources(struct mlx5_vdpa_net *ndev)
1906 struct mlx5_vdpa_net_resources *res = &ndev->res;
1912 mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
1916 static void init_mvqs(struct mlx5_vdpa_net *ndev)
1918 struct mlx5_vdpa_virtqueue *mvq;
1921 for (i = 0; i < 2 * mlx5_vdpa_max_qps(ndev->mvdev.max_vqs); ++i) {
1922 mvq = &ndev->vqs[i];
1923 memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1926 mvq->fwqp.fw = true;
1928 for (; i < ndev->mvdev.max_vqs; i++) {
1929 mvq = &ndev->vqs[i];
1930 memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
1936 void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
1938 struct virtio_net_config *config;
1939 struct mlx5_vdpa_dev *mvdev;
1940 struct mlx5_vdpa_net *ndev;
1944 /* we save one virtqueue for control virtqueue should we require it */
1945 max_vqs = MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
1946 max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
1948 ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
1949 2 * mlx5_vdpa_max_qps(max_vqs));
1953 ndev->mvdev.max_vqs = max_vqs;
1954 mvdev = &ndev->mvdev;
1957 mutex_init(&ndev->reslock);
1958 config = &ndev->config;
1959 err = mlx5_query_nic_vport_mtu(mdev, &ndev->mtu);
1963 err = mlx5_query_nic_vport_mac_address(mdev, 0, 0, config->mac);
1967 mvdev->vdev.dma_dev = mdev->device;
1968 err = mlx5_vdpa_alloc_resources(&ndev->mvdev);
1972 err = alloc_resources(ndev);
1976 err = vdpa_register_device(&mvdev->vdev);
1983 free_resources(ndev);
1985 mlx5_vdpa_free_resources(&ndev->mvdev);
1987 mutex_destroy(&ndev->reslock);
1988 put_device(&mvdev->vdev.dev);
1989 return ERR_PTR(err);
1992 void mlx5_vdpa_remove_dev(struct mlx5_vdpa_dev *mvdev)
1994 vdpa_unregister_device(&mvdev->vdev);