xref: /linux/drivers/vdpa/mlx5/net/mlx5_vnet.c (revision 62111654)
1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2020 Mellanox Technologies Ltd. */
3 
4 #include <linux/module.h>
5 #include <linux/vdpa.h>
6 #include <linux/vringh.h>
7 #include <uapi/linux/virtio_net.h>
8 #include <uapi/linux/virtio_ids.h>
9 #include <uapi/linux/vdpa.h>
10 #include <uapi/linux/vhost_types.h>
11 #include <linux/virtio_config.h>
12 #include <linux/auxiliary_bus.h>
13 #include <linux/mlx5/cq.h>
14 #include <linux/mlx5/qp.h>
15 #include <linux/mlx5/device.h>
16 #include <linux/mlx5/driver.h>
17 #include <linux/mlx5/vport.h>
18 #include <linux/mlx5/fs.h>
19 #include <linux/mlx5/mlx5_ifc_vdpa.h>
20 #include <linux/mlx5/mpfs.h>
21 #include "mlx5_vdpa.h"
22 #include "mlx5_vnet.h"
23 
24 MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
25 MODULE_DESCRIPTION("Mellanox VDPA driver");
26 MODULE_LICENSE("Dual BSD/GPL");
27 
28 #define VALID_FEATURES_MASK                                                                        \
29 	(BIT_ULL(VIRTIO_NET_F_CSUM) | BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) |                                   \
30 	 BIT_ULL(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) | BIT_ULL(VIRTIO_NET_F_MTU) | BIT_ULL(VIRTIO_NET_F_MAC) |   \
31 	 BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) | BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) |                             \
32 	 BIT_ULL(VIRTIO_NET_F_GUEST_ECN) | BIT_ULL(VIRTIO_NET_F_GUEST_UFO) | BIT_ULL(VIRTIO_NET_F_HOST_TSO4) | \
33 	 BIT_ULL(VIRTIO_NET_F_HOST_TSO6) | BIT_ULL(VIRTIO_NET_F_HOST_ECN) | BIT_ULL(VIRTIO_NET_F_HOST_UFO) |   \
34 	 BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | BIT_ULL(VIRTIO_NET_F_STATUS) | BIT_ULL(VIRTIO_NET_F_CTRL_VQ) |      \
35 	 BIT_ULL(VIRTIO_NET_F_CTRL_RX) | BIT_ULL(VIRTIO_NET_F_CTRL_VLAN) |                                 \
36 	 BIT_ULL(VIRTIO_NET_F_CTRL_RX_EXTRA) | BIT_ULL(VIRTIO_NET_F_GUEST_ANNOUNCE) |                      \
37 	 BIT_ULL(VIRTIO_NET_F_MQ) | BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) | BIT_ULL(VIRTIO_NET_F_HASH_REPORT) |  \
38 	 BIT_ULL(VIRTIO_NET_F_RSS) | BIT_ULL(VIRTIO_NET_F_RSC_EXT) | BIT_ULL(VIRTIO_NET_F_STANDBY) |           \
39 	 BIT_ULL(VIRTIO_NET_F_SPEED_DUPLEX) | BIT_ULL(VIRTIO_F_NOTIFY_ON_EMPTY) |                          \
40 	 BIT_ULL(VIRTIO_F_ANY_LAYOUT) | BIT_ULL(VIRTIO_F_VERSION_1) | BIT_ULL(VIRTIO_F_ACCESS_PLATFORM) |      \
41 	 BIT_ULL(VIRTIO_F_RING_PACKED) | BIT_ULL(VIRTIO_F_ORDER_PLATFORM) | BIT_ULL(VIRTIO_F_SR_IOV))
42 
43 #define VALID_STATUS_MASK                                                                          \
44 	(VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK |        \
45 	 VIRTIO_CONFIG_S_FEATURES_OK | VIRTIO_CONFIG_S_NEEDS_RESET | VIRTIO_CONFIG_S_FAILED)
46 
47 #define MLX5_FEATURE(_mvdev, _feature) (!!((_mvdev)->actual_features & BIT_ULL(_feature)))
48 
49 #define MLX5V_UNTAGGED 0x1000
50 
51 /* Device must start with 1 queue pair, as per VIRTIO v1.2 spec, section
52  * 5.1.6.5.5 "Device operation in multiqueue mode":
53  *
54  * Multiqueue is disabled by default.
55  * The driver enables multiqueue by sending a command using class
56  * VIRTIO_NET_CTRL_MQ. The command selects the mode of multiqueue
57  * operation, as follows: ...
58  */
59 #define MLX5V_DEFAULT_VQ_COUNT 2
60 
61 #define MLX5V_DEFAULT_VQ_SIZE 256
62 
63 struct mlx5_vdpa_cq_buf {
64 	struct mlx5_frag_buf_ctrl fbc;
65 	struct mlx5_frag_buf frag_buf;
66 	int cqe_size;
67 	int nent;
68 };
69 
70 struct mlx5_vdpa_cq {
71 	struct mlx5_core_cq mcq;
72 	struct mlx5_vdpa_cq_buf buf;
73 	struct mlx5_db db;
74 	int cqe;
75 };
76 
77 struct mlx5_vdpa_umem {
78 	struct mlx5_frag_buf_ctrl fbc;
79 	struct mlx5_frag_buf frag_buf;
80 	int size;
81 	u32 id;
82 };
83 
84 struct mlx5_vdpa_qp {
85 	struct mlx5_core_qp mqp;
86 	struct mlx5_frag_buf frag_buf;
87 	struct mlx5_db db;
88 	u16 head;
89 	bool fw;
90 };
91 
92 struct mlx5_vq_restore_info {
93 	u32 num_ent;
94 	u64 desc_addr;
95 	u64 device_addr;
96 	u64 driver_addr;
97 	u16 avail_index;
98 	u16 used_index;
99 	struct msi_map map;
100 	bool ready;
101 	bool restore;
102 };
103 
104 struct mlx5_vdpa_virtqueue {
105 	bool ready;
106 	u64 desc_addr;
107 	u64 device_addr;
108 	u64 driver_addr;
109 	u32 num_ent;
110 
111 	/* Resources for implementing the notification channel from the device
112 	 * to the driver. fwqp is the firmware end of an RC connection; the
113 	 * other end is vqqp used by the driver. cq is where completions are
114 	 * reported.
115 	 */
116 	struct mlx5_vdpa_cq cq;
117 	struct mlx5_vdpa_qp fwqp;
118 	struct mlx5_vdpa_qp vqqp;
119 
120 	/* umem resources are required for the virtqueue operation. They're use
121 	 * is internal and they must be provided by the driver.
122 	 */
123 	struct mlx5_vdpa_umem umem1;
124 	struct mlx5_vdpa_umem umem2;
125 	struct mlx5_vdpa_umem umem3;
126 
127 	u32 counter_set_id;
128 	bool initialized;
129 	int index;
130 	u32 virtq_id;
131 	struct mlx5_vdpa_net *ndev;
132 	u16 avail_idx;
133 	u16 used_idx;
134 	int fw_state;
135 
136 	u64 modified_fields;
137 
138 	struct mlx5_vdpa_mr *vq_mr;
139 	struct mlx5_vdpa_mr *desc_mr;
140 
141 	struct msi_map map;
142 
143 	/* keep last in the struct */
144 	struct mlx5_vq_restore_info ri;
145 };
146 
is_index_valid(struct mlx5_vdpa_dev * mvdev,u16 idx)147 static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx)
148 {
149 	if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_MQ))) {
150 		if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
151 			return idx < 2;
152 		else
153 			return idx < 3;
154 	}
155 
156 	return idx <= mvdev->max_idx;
157 }
158 
159 static void free_fixed_resources(struct mlx5_vdpa_net *ndev);
160 static void mvqs_set_defaults(struct mlx5_vdpa_net *ndev);
161 static int setup_vq_resources(struct mlx5_vdpa_net *ndev, bool filled);
162 static void teardown_vq_resources(struct mlx5_vdpa_net *ndev);
163 static int resume_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq);
164 
165 static bool mlx5_vdpa_debug;
166 
167 #define MLX5_LOG_VIO_FLAG(_feature)                                                                \
168 	do {                                                                                       \
169 		if (features & BIT_ULL(_feature))                                                  \
170 			mlx5_vdpa_info(mvdev, "%s\n", #_feature);                                  \
171 	} while (0)
172 
173 #define MLX5_LOG_VIO_STAT(_status)                                                                 \
174 	do {                                                                                       \
175 		if (status & (_status))                                                            \
176 			mlx5_vdpa_info(mvdev, "%s\n", #_status);                                   \
177 	} while (0)
178 
179 /* TODO: cross-endian support */
mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev * mvdev)180 static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
181 {
182 	return virtio_legacy_is_little_endian() ||
183 		(mvdev->actual_features & BIT_ULL(VIRTIO_F_VERSION_1));
184 }
185 
mlx5vdpa16_to_cpu(struct mlx5_vdpa_dev * mvdev,__virtio16 val)186 static u16 mlx5vdpa16_to_cpu(struct mlx5_vdpa_dev *mvdev, __virtio16 val)
187 {
188 	return __virtio16_to_cpu(mlx5_vdpa_is_little_endian(mvdev), val);
189 }
190 
cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev * mvdev,u16 val)191 static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val)
192 {
193 	return __cpu_to_virtio16(mlx5_vdpa_is_little_endian(mvdev), val);
194 }
195 
ctrl_vq_idx(struct mlx5_vdpa_dev * mvdev)196 static u16 ctrl_vq_idx(struct mlx5_vdpa_dev *mvdev)
197 {
198 	if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_MQ)))
199 		return 2;
200 
201 	return mvdev->max_vqs;
202 }
203 
is_ctrl_vq_idx(struct mlx5_vdpa_dev * mvdev,u16 idx)204 static bool is_ctrl_vq_idx(struct mlx5_vdpa_dev *mvdev, u16 idx)
205 {
206 	return idx == ctrl_vq_idx(mvdev);
207 }
208 
print_status(struct mlx5_vdpa_dev * mvdev,u8 status,bool set)209 static void print_status(struct mlx5_vdpa_dev *mvdev, u8 status, bool set)
210 {
211 	if (status & ~VALID_STATUS_MASK)
212 		mlx5_vdpa_warn(mvdev, "Warning: there are invalid status bits 0x%x\n",
213 			       status & ~VALID_STATUS_MASK);
214 
215 	if (!mlx5_vdpa_debug)
216 		return;
217 
218 	mlx5_vdpa_info(mvdev, "driver status %s", set ? "set" : "get");
219 	if (set && !status) {
220 		mlx5_vdpa_info(mvdev, "driver resets the device\n");
221 		return;
222 	}
223 
224 	MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_ACKNOWLEDGE);
225 	MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_DRIVER);
226 	MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_DRIVER_OK);
227 	MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_FEATURES_OK);
228 	MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_NEEDS_RESET);
229 	MLX5_LOG_VIO_STAT(VIRTIO_CONFIG_S_FAILED);
230 }
231 
print_features(struct mlx5_vdpa_dev * mvdev,u64 features,bool set)232 static void print_features(struct mlx5_vdpa_dev *mvdev, u64 features, bool set)
233 {
234 	if (features & ~VALID_FEATURES_MASK)
235 		mlx5_vdpa_warn(mvdev, "There are invalid feature bits 0x%llx\n",
236 			       features & ~VALID_FEATURES_MASK);
237 
238 	if (!mlx5_vdpa_debug)
239 		return;
240 
241 	mlx5_vdpa_info(mvdev, "driver %s feature bits:\n", set ? "sets" : "reads");
242 	if (!features)
243 		mlx5_vdpa_info(mvdev, "all feature bits are cleared\n");
244 
245 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CSUM);
246 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_CSUM);
247 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS);
248 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MTU);
249 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MAC);
250 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_TSO4);
251 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_TSO6);
252 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_ECN);
253 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_UFO);
254 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_TSO4);
255 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_TSO6);
256 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_ECN);
257 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HOST_UFO);
258 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MRG_RXBUF);
259 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_STATUS);
260 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_VQ);
261 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_RX);
262 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_VLAN);
263 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_RX_EXTRA);
264 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_GUEST_ANNOUNCE);
265 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_MQ);
266 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_CTRL_MAC_ADDR);
267 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_HASH_REPORT);
268 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_RSS);
269 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_RSC_EXT);
270 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_STANDBY);
271 	MLX5_LOG_VIO_FLAG(VIRTIO_NET_F_SPEED_DUPLEX);
272 	MLX5_LOG_VIO_FLAG(VIRTIO_F_NOTIFY_ON_EMPTY);
273 	MLX5_LOG_VIO_FLAG(VIRTIO_F_ANY_LAYOUT);
274 	MLX5_LOG_VIO_FLAG(VIRTIO_F_VERSION_1);
275 	MLX5_LOG_VIO_FLAG(VIRTIO_F_ACCESS_PLATFORM);
276 	MLX5_LOG_VIO_FLAG(VIRTIO_F_RING_PACKED);
277 	MLX5_LOG_VIO_FLAG(VIRTIO_F_ORDER_PLATFORM);
278 	MLX5_LOG_VIO_FLAG(VIRTIO_F_SR_IOV);
279 }
280 
create_tis(struct mlx5_vdpa_net * ndev)281 static int create_tis(struct mlx5_vdpa_net *ndev)
282 {
283 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
284 	u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
285 	void *tisc;
286 	int err;
287 
288 	tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
289 	MLX5_SET(tisc, tisc, transport_domain, ndev->res.tdn);
290 	err = mlx5_vdpa_create_tis(mvdev, in, &ndev->res.tisn);
291 	if (err)
292 		mlx5_vdpa_warn(mvdev, "create TIS (%d)\n", err);
293 
294 	return err;
295 }
296 
destroy_tis(struct mlx5_vdpa_net * ndev)297 static void destroy_tis(struct mlx5_vdpa_net *ndev)
298 {
299 	mlx5_vdpa_destroy_tis(&ndev->mvdev, ndev->res.tisn);
300 }
301 
302 #define MLX5_VDPA_CQE_SIZE 64
303 #define MLX5_VDPA_LOG_CQE_SIZE ilog2(MLX5_VDPA_CQE_SIZE)
304 
cq_frag_buf_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_cq_buf * buf,int nent)305 static int cq_frag_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_cq_buf *buf, int nent)
306 {
307 	struct mlx5_frag_buf *frag_buf = &buf->frag_buf;
308 	u8 log_wq_stride = MLX5_VDPA_LOG_CQE_SIZE;
309 	u8 log_wq_sz = MLX5_VDPA_LOG_CQE_SIZE;
310 	int err;
311 
312 	err = mlx5_frag_buf_alloc_node(ndev->mvdev.mdev, nent * MLX5_VDPA_CQE_SIZE, frag_buf,
313 				       ndev->mvdev.mdev->priv.numa_node);
314 	if (err)
315 		return err;
316 
317 	mlx5_init_fbc(frag_buf->frags, log_wq_stride, log_wq_sz, &buf->fbc);
318 
319 	buf->cqe_size = MLX5_VDPA_CQE_SIZE;
320 	buf->nent = nent;
321 
322 	return 0;
323 }
324 
umem_frag_buf_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_umem * umem,int size)325 static int umem_frag_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_umem *umem, int size)
326 {
327 	struct mlx5_frag_buf *frag_buf = &umem->frag_buf;
328 
329 	return mlx5_frag_buf_alloc_node(ndev->mvdev.mdev, size, frag_buf,
330 					ndev->mvdev.mdev->priv.numa_node);
331 }
332 
cq_frag_buf_free(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_cq_buf * buf)333 static void cq_frag_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_cq_buf *buf)
334 {
335 	mlx5_frag_buf_free(ndev->mvdev.mdev, &buf->frag_buf);
336 }
337 
get_cqe(struct mlx5_vdpa_cq * vcq,int n)338 static void *get_cqe(struct mlx5_vdpa_cq *vcq, int n)
339 {
340 	return mlx5_frag_buf_get_wqe(&vcq->buf.fbc, n);
341 }
342 
cq_frag_buf_init(struct mlx5_vdpa_cq * vcq,struct mlx5_vdpa_cq_buf * buf)343 static void cq_frag_buf_init(struct mlx5_vdpa_cq *vcq, struct mlx5_vdpa_cq_buf *buf)
344 {
345 	struct mlx5_cqe64 *cqe64;
346 	void *cqe;
347 	int i;
348 
349 	for (i = 0; i < buf->nent; i++) {
350 		cqe = get_cqe(vcq, i);
351 		cqe64 = cqe;
352 		cqe64->op_own = MLX5_CQE_INVALID << 4;
353 	}
354 }
355 
get_sw_cqe(struct mlx5_vdpa_cq * cq,int n)356 static void *get_sw_cqe(struct mlx5_vdpa_cq *cq, int n)
357 {
358 	struct mlx5_cqe64 *cqe64 = get_cqe(cq, n & (cq->cqe - 1));
359 
360 	if (likely(get_cqe_opcode(cqe64) != MLX5_CQE_INVALID) &&
361 	    !((cqe64->op_own & MLX5_CQE_OWNER_MASK) ^ !!(n & cq->cqe)))
362 		return cqe64;
363 
364 	return NULL;
365 }
366 
rx_post(struct mlx5_vdpa_qp * vqp,int n)367 static void rx_post(struct mlx5_vdpa_qp *vqp, int n)
368 {
369 	vqp->head += n;
370 	vqp->db.db[0] = cpu_to_be32(vqp->head);
371 }
372 
qp_prepare(struct mlx5_vdpa_net * ndev,bool fw,void * in,struct mlx5_vdpa_virtqueue * mvq,u32 num_ent)373 static void qp_prepare(struct mlx5_vdpa_net *ndev, bool fw, void *in,
374 		       struct mlx5_vdpa_virtqueue *mvq, u32 num_ent)
375 {
376 	struct mlx5_vdpa_qp *vqp;
377 	__be64 *pas;
378 	void *qpc;
379 
380 	vqp = fw ? &mvq->fwqp : &mvq->vqqp;
381 	MLX5_SET(create_qp_in, in, uid, ndev->mvdev.res.uid);
382 	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
383 	if (vqp->fw) {
384 		/* Firmware QP is allocated by the driver for the firmware's
385 		 * use so we can skip part of the params as they will be chosen by firmware
386 		 */
387 		qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
388 		MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
389 		MLX5_SET(qpc, qpc, no_sq, 1);
390 		return;
391 	}
392 
393 	MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
394 	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
395 	MLX5_SET(qpc, qpc, pd, ndev->mvdev.res.pdn);
396 	MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
397 	MLX5_SET(qpc, qpc, uar_page, ndev->mvdev.res.uar->index);
398 	MLX5_SET(qpc, qpc, log_page_size, vqp->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
399 	MLX5_SET(qpc, qpc, no_sq, 1);
400 	MLX5_SET(qpc, qpc, cqn_rcv, mvq->cq.mcq.cqn);
401 	MLX5_SET(qpc, qpc, log_rq_size, ilog2(num_ent));
402 	MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ);
403 	pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, in, pas);
404 	mlx5_fill_page_frag_array(&vqp->frag_buf, pas);
405 }
406 
rq_buf_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_qp * vqp,u32 num_ent)407 static int rq_buf_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp, u32 num_ent)
408 {
409 	return mlx5_frag_buf_alloc_node(ndev->mvdev.mdev,
410 					num_ent * sizeof(struct mlx5_wqe_data_seg), &vqp->frag_buf,
411 					ndev->mvdev.mdev->priv.numa_node);
412 }
413 
rq_buf_free(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_qp * vqp)414 static void rq_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp)
415 {
416 	mlx5_frag_buf_free(ndev->mvdev.mdev, &vqp->frag_buf);
417 }
418 
qp_create(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,struct mlx5_vdpa_qp * vqp)419 static int qp_create(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
420 		     struct mlx5_vdpa_qp *vqp)
421 {
422 	struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
423 	int inlen = MLX5_ST_SZ_BYTES(create_qp_in);
424 	u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};
425 	void *qpc;
426 	void *in;
427 	int err;
428 
429 	if (!vqp->fw) {
430 		vqp = &mvq->vqqp;
431 		err = rq_buf_alloc(ndev, vqp, mvq->num_ent);
432 		if (err)
433 			return err;
434 
435 		err = mlx5_db_alloc(ndev->mvdev.mdev, &vqp->db);
436 		if (err)
437 			goto err_db;
438 		inlen += vqp->frag_buf.npages * sizeof(__be64);
439 	}
440 
441 	in = kzalloc(inlen, GFP_KERNEL);
442 	if (!in) {
443 		err = -ENOMEM;
444 		goto err_kzalloc;
445 	}
446 
447 	qp_prepare(ndev, vqp->fw, in, mvq, mvq->num_ent);
448 	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
449 	MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
450 	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
451 	MLX5_SET(qpc, qpc, pd, ndev->mvdev.res.pdn);
452 	MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
453 	if (!vqp->fw)
454 		MLX5_SET64(qpc, qpc, dbr_addr, vqp->db.dma);
455 	MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
456 	err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
457 	kfree(in);
458 	if (err)
459 		goto err_kzalloc;
460 
461 	vqp->mqp.uid = ndev->mvdev.res.uid;
462 	vqp->mqp.qpn = MLX5_GET(create_qp_out, out, qpn);
463 
464 	if (!vqp->fw)
465 		rx_post(vqp, mvq->num_ent);
466 
467 	return 0;
468 
469 err_kzalloc:
470 	if (!vqp->fw)
471 		mlx5_db_free(ndev->mvdev.mdev, &vqp->db);
472 err_db:
473 	if (!vqp->fw)
474 		rq_buf_free(ndev, vqp);
475 
476 	return err;
477 }
478 
qp_destroy(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_qp * vqp)479 static void qp_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_qp *vqp)
480 {
481 	u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {};
482 
483 	MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
484 	MLX5_SET(destroy_qp_in, in, qpn, vqp->mqp.qpn);
485 	MLX5_SET(destroy_qp_in, in, uid, ndev->mvdev.res.uid);
486 	if (mlx5_cmd_exec_in(ndev->mvdev.mdev, destroy_qp, in))
487 		mlx5_vdpa_warn(&ndev->mvdev, "destroy qp 0x%x\n", vqp->mqp.qpn);
488 	if (!vqp->fw) {
489 		mlx5_db_free(ndev->mvdev.mdev, &vqp->db);
490 		rq_buf_free(ndev, vqp);
491 	}
492 }
493 
next_cqe_sw(struct mlx5_vdpa_cq * cq)494 static void *next_cqe_sw(struct mlx5_vdpa_cq *cq)
495 {
496 	return get_sw_cqe(cq, cq->mcq.cons_index);
497 }
498 
mlx5_vdpa_poll_one(struct mlx5_vdpa_cq * vcq)499 static int mlx5_vdpa_poll_one(struct mlx5_vdpa_cq *vcq)
500 {
501 	struct mlx5_cqe64 *cqe64;
502 
503 	cqe64 = next_cqe_sw(vcq);
504 	if (!cqe64)
505 		return -EAGAIN;
506 
507 	vcq->mcq.cons_index++;
508 	return 0;
509 }
510 
mlx5_vdpa_handle_completions(struct mlx5_vdpa_virtqueue * mvq,int num)511 static void mlx5_vdpa_handle_completions(struct mlx5_vdpa_virtqueue *mvq, int num)
512 {
513 	struct mlx5_vdpa_net *ndev = mvq->ndev;
514 	struct vdpa_callback *event_cb;
515 
516 	event_cb = &ndev->event_cbs[mvq->index];
517 	mlx5_cq_set_ci(&mvq->cq.mcq);
518 
519 	/* make sure CQ cosumer update is visible to the hardware before updating
520 	 * RX doorbell record.
521 	 */
522 	dma_wmb();
523 	rx_post(&mvq->vqqp, num);
524 	if (event_cb->callback)
525 		event_cb->callback(event_cb->private);
526 }
527 
mlx5_vdpa_cq_comp(struct mlx5_core_cq * mcq,struct mlx5_eqe * eqe)528 static void mlx5_vdpa_cq_comp(struct mlx5_core_cq *mcq, struct mlx5_eqe *eqe)
529 {
530 	struct mlx5_vdpa_virtqueue *mvq = container_of(mcq, struct mlx5_vdpa_virtqueue, cq.mcq);
531 	struct mlx5_vdpa_net *ndev = mvq->ndev;
532 	void __iomem *uar_page = ndev->mvdev.res.uar->map;
533 	int num = 0;
534 
535 	while (!mlx5_vdpa_poll_one(&mvq->cq)) {
536 		num++;
537 		if (num > mvq->num_ent / 2) {
538 			/* If completions keep coming while we poll, we want to
539 			 * let the hardware know that we consumed them by
540 			 * updating the doorbell record.  We also let vdpa core
541 			 * know about this so it passes it on the virtio driver
542 			 * on the guest.
543 			 */
544 			mlx5_vdpa_handle_completions(mvq, num);
545 			num = 0;
546 		}
547 	}
548 
549 	if (num)
550 		mlx5_vdpa_handle_completions(mvq, num);
551 
552 	mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
553 }
554 
cq_create(struct mlx5_vdpa_net * ndev,u16 idx,u32 num_ent)555 static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
556 {
557 	struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
558 	struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
559 	void __iomem *uar_page = ndev->mvdev.res.uar->map;
560 	u32 out[MLX5_ST_SZ_DW(create_cq_out)];
561 	struct mlx5_vdpa_cq *vcq = &mvq->cq;
562 	__be64 *pas;
563 	int inlen;
564 	void *cqc;
565 	void *in;
566 	int err;
567 	int eqn;
568 
569 	err = mlx5_db_alloc(mdev, &vcq->db);
570 	if (err)
571 		return err;
572 
573 	vcq->mcq.set_ci_db = vcq->db.db;
574 	vcq->mcq.arm_db = vcq->db.db + 1;
575 	vcq->mcq.cqe_sz = 64;
576 
577 	err = cq_frag_buf_alloc(ndev, &vcq->buf, num_ent);
578 	if (err)
579 		goto err_db;
580 
581 	cq_frag_buf_init(vcq, &vcq->buf);
582 
583 	inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
584 		MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * vcq->buf.frag_buf.npages;
585 	in = kzalloc(inlen, GFP_KERNEL);
586 	if (!in) {
587 		err = -ENOMEM;
588 		goto err_vzalloc;
589 	}
590 
591 	MLX5_SET(create_cq_in, in, uid, ndev->mvdev.res.uid);
592 	pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas);
593 	mlx5_fill_page_frag_array(&vcq->buf.frag_buf, pas);
594 
595 	cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
596 	MLX5_SET(cqc, cqc, log_page_size, vcq->buf.frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
597 
598 	/* Use vector 0 by default. Consider adding code to choose least used
599 	 * vector.
600 	 */
601 	err = mlx5_comp_eqn_get(mdev, 0, &eqn);
602 	if (err)
603 		goto err_vec;
604 
605 	cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
606 	MLX5_SET(cqc, cqc, log_cq_size, ilog2(num_ent));
607 	MLX5_SET(cqc, cqc, uar_page, ndev->mvdev.res.uar->index);
608 	MLX5_SET(cqc, cqc, c_eqn_or_apu_element, eqn);
609 	MLX5_SET64(cqc, cqc, dbr_addr, vcq->db.dma);
610 
611 	err = mlx5_core_create_cq(mdev, &vcq->mcq, in, inlen, out, sizeof(out));
612 	if (err)
613 		goto err_vec;
614 
615 	vcq->mcq.comp = mlx5_vdpa_cq_comp;
616 	vcq->cqe = num_ent;
617 	vcq->mcq.set_ci_db = vcq->db.db;
618 	vcq->mcq.arm_db = vcq->db.db + 1;
619 	mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
620 	kfree(in);
621 	return 0;
622 
623 err_vec:
624 	kfree(in);
625 err_vzalloc:
626 	cq_frag_buf_free(ndev, &vcq->buf);
627 err_db:
628 	mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
629 	return err;
630 }
631 
cq_destroy(struct mlx5_vdpa_net * ndev,u16 idx)632 static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 idx)
633 {
634 	struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[idx];
635 	struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
636 	struct mlx5_vdpa_cq *vcq = &mvq->cq;
637 
638 	if (mlx5_core_destroy_cq(mdev, &vcq->mcq)) {
639 		mlx5_vdpa_warn(&ndev->mvdev, "destroy CQ 0x%x\n", vcq->mcq.cqn);
640 		return;
641 	}
642 	cq_frag_buf_free(ndev, &vcq->buf);
643 	mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
644 }
645 
read_umem_params(struct mlx5_vdpa_net * ndev)646 static int read_umem_params(struct mlx5_vdpa_net *ndev)
647 {
648 	u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
649 	u16 opmod = (MLX5_CAP_VDPA_EMULATION << 1) | (HCA_CAP_OPMOD_GET_CUR & 0x01);
650 	struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
651 	int out_size;
652 	void *caps;
653 	void *out;
654 	int err;
655 
656 	out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out);
657 	out = kzalloc(out_size, GFP_KERNEL);
658 	if (!out)
659 		return -ENOMEM;
660 
661 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
662 	MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
663 	err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out);
664 	if (err) {
665 		mlx5_vdpa_warn(&ndev->mvdev,
666 			"Failed reading vdpa umem capabilities with err %d\n", err);
667 		goto out;
668 	}
669 
670 	caps =  MLX5_ADDR_OF(query_hca_cap_out, out, capability);
671 
672 	ndev->umem_1_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_1_buffer_param_a);
673 	ndev->umem_1_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_1_buffer_param_b);
674 
675 	ndev->umem_2_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_2_buffer_param_a);
676 	ndev->umem_2_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_2_buffer_param_b);
677 
678 	ndev->umem_3_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_3_buffer_param_a);
679 	ndev->umem_3_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_3_buffer_param_b);
680 
681 out:
682 	kfree(out);
683 	return 0;
684 }
685 
set_umem_size(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int num,struct mlx5_vdpa_umem ** umemp)686 static void set_umem_size(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num,
687 			  struct mlx5_vdpa_umem **umemp)
688 {
689 	u32 p_a;
690 	u32 p_b;
691 
692 	switch (num) {
693 	case 1:
694 		p_a = ndev->umem_1_buffer_param_a;
695 		p_b = ndev->umem_1_buffer_param_b;
696 		*umemp = &mvq->umem1;
697 		break;
698 	case 2:
699 		p_a = ndev->umem_2_buffer_param_a;
700 		p_b = ndev->umem_2_buffer_param_b;
701 		*umemp = &mvq->umem2;
702 		break;
703 	case 3:
704 		p_a = ndev->umem_3_buffer_param_a;
705 		p_b = ndev->umem_3_buffer_param_b;
706 		*umemp = &mvq->umem3;
707 		break;
708 	}
709 
710 	(*umemp)->size = p_a * mvq->num_ent + p_b;
711 }
712 
umem_frag_buf_free(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_umem * umem)713 static void umem_frag_buf_free(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_umem *umem)
714 {
715 	mlx5_frag_buf_free(ndev->mvdev.mdev, &umem->frag_buf);
716 }
717 
create_umem(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int num)718 static int create_umem(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num)
719 {
720 	int inlen;
721 	u32 out[MLX5_ST_SZ_DW(create_umem_out)] = {};
722 	void *um;
723 	void *in;
724 	int err;
725 	__be64 *pas;
726 	struct mlx5_vdpa_umem *umem;
727 
728 	set_umem_size(ndev, mvq, num, &umem);
729 	err = umem_frag_buf_alloc(ndev, umem, umem->size);
730 	if (err)
731 		return err;
732 
733 	inlen = MLX5_ST_SZ_BYTES(create_umem_in) + MLX5_ST_SZ_BYTES(mtt) * umem->frag_buf.npages;
734 
735 	in = kzalloc(inlen, GFP_KERNEL);
736 	if (!in) {
737 		err = -ENOMEM;
738 		goto err_in;
739 	}
740 
741 	MLX5_SET(create_umem_in, in, opcode, MLX5_CMD_OP_CREATE_UMEM);
742 	MLX5_SET(create_umem_in, in, uid, ndev->mvdev.res.uid);
743 	um = MLX5_ADDR_OF(create_umem_in, in, umem);
744 	MLX5_SET(umem, um, log_page_size, umem->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
745 	MLX5_SET64(umem, um, num_of_mtt, umem->frag_buf.npages);
746 
747 	pas = (__be64 *)MLX5_ADDR_OF(umem, um, mtt[0]);
748 	mlx5_fill_page_frag_array_perm(&umem->frag_buf, pas, MLX5_MTT_PERM_RW);
749 
750 	err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
751 	if (err) {
752 		mlx5_vdpa_warn(&ndev->mvdev, "create umem(%d)\n", err);
753 		goto err_cmd;
754 	}
755 
756 	kfree(in);
757 	umem->id = MLX5_GET(create_umem_out, out, umem_id);
758 
759 	return 0;
760 
761 err_cmd:
762 	kfree(in);
763 err_in:
764 	umem_frag_buf_free(ndev, umem);
765 	return err;
766 }
767 
umem_destroy(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int num)768 static void umem_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num)
769 {
770 	u32 in[MLX5_ST_SZ_DW(destroy_umem_in)] = {};
771 	u32 out[MLX5_ST_SZ_DW(destroy_umem_out)] = {};
772 	struct mlx5_vdpa_umem *umem;
773 
774 	switch (num) {
775 	case 1:
776 		umem = &mvq->umem1;
777 		break;
778 	case 2:
779 		umem = &mvq->umem2;
780 		break;
781 	case 3:
782 		umem = &mvq->umem3;
783 		break;
784 	}
785 
786 	MLX5_SET(destroy_umem_in, in, opcode, MLX5_CMD_OP_DESTROY_UMEM);
787 	MLX5_SET(destroy_umem_in, in, umem_id, umem->id);
788 	if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out)))
789 		return;
790 
791 	umem_frag_buf_free(ndev, umem);
792 }
793 
umems_create(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)794 static int umems_create(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
795 {
796 	int num;
797 	int err;
798 
799 	for (num = 1; num <= 3; num++) {
800 		err = create_umem(ndev, mvq, num);
801 		if (err)
802 			goto err_umem;
803 	}
804 	return 0;
805 
806 err_umem:
807 	for (num--; num > 0; num--)
808 		umem_destroy(ndev, mvq, num);
809 
810 	return err;
811 }
812 
umems_destroy(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)813 static void umems_destroy(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
814 {
815 	int num;
816 
817 	for (num = 3; num > 0; num--)
818 		umem_destroy(ndev, mvq, num);
819 }
820 
get_queue_type(struct mlx5_vdpa_net * ndev)821 static int get_queue_type(struct mlx5_vdpa_net *ndev)
822 {
823 	u32 type_mask;
824 
825 	type_mask = MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, virtio_queue_type);
826 
827 	/* prefer split queue */
828 	if (type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT)
829 		return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT;
830 
831 	WARN_ON(!(type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED));
832 
833 	return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED;
834 }
835 
vq_is_tx(u16 idx)836 static bool vq_is_tx(u16 idx)
837 {
838 	return idx % 2;
839 }
840 
841 enum {
842 	MLX5_VIRTIO_NET_F_MRG_RXBUF = 2,
843 	MLX5_VIRTIO_NET_F_HOST_ECN = 4,
844 	MLX5_VIRTIO_NET_F_GUEST_ECN = 6,
845 	MLX5_VIRTIO_NET_F_GUEST_TSO6 = 7,
846 	MLX5_VIRTIO_NET_F_GUEST_TSO4 = 8,
847 	MLX5_VIRTIO_NET_F_GUEST_CSUM = 9,
848 	MLX5_VIRTIO_NET_F_CSUM = 10,
849 	MLX5_VIRTIO_NET_F_HOST_TSO6 = 11,
850 	MLX5_VIRTIO_NET_F_HOST_TSO4 = 12,
851 };
852 
get_features(u64 features)853 static u16 get_features(u64 features)
854 {
855 	return (!!(features & BIT_ULL(VIRTIO_NET_F_MRG_RXBUF)) << MLX5_VIRTIO_NET_F_MRG_RXBUF) |
856 	       (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_ECN)) << MLX5_VIRTIO_NET_F_HOST_ECN) |
857 	       (!!(features & BIT_ULL(VIRTIO_NET_F_GUEST_ECN)) << MLX5_VIRTIO_NET_F_GUEST_ECN) |
858 	       (!!(features & BIT_ULL(VIRTIO_NET_F_GUEST_TSO6)) << MLX5_VIRTIO_NET_F_GUEST_TSO6) |
859 	       (!!(features & BIT_ULL(VIRTIO_NET_F_GUEST_TSO4)) << MLX5_VIRTIO_NET_F_GUEST_TSO4) |
860 	       (!!(features & BIT_ULL(VIRTIO_NET_F_CSUM)) << MLX5_VIRTIO_NET_F_CSUM) |
861 	       (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_TSO6)) << MLX5_VIRTIO_NET_F_HOST_TSO6) |
862 	       (!!(features & BIT_ULL(VIRTIO_NET_F_HOST_TSO4)) << MLX5_VIRTIO_NET_F_HOST_TSO4);
863 }
864 
counters_supported(const struct mlx5_vdpa_dev * mvdev)865 static bool counters_supported(const struct mlx5_vdpa_dev *mvdev)
866 {
867 	return MLX5_CAP_GEN_64(mvdev->mdev, general_obj_types) &
868 	       BIT_ULL(MLX5_OBJ_TYPE_VIRTIO_Q_COUNTERS);
869 }
870 
msix_mode_supported(struct mlx5_vdpa_dev * mvdev)871 static bool msix_mode_supported(struct mlx5_vdpa_dev *mvdev)
872 {
873 	return MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, event_mode) &
874 		(1 << MLX5_VIRTIO_Q_EVENT_MODE_MSIX_MODE) &&
875 		pci_msix_can_alloc_dyn(mvdev->mdev->pdev);
876 }
877 
create_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,bool filled)878 static int create_virtqueue(struct mlx5_vdpa_net *ndev,
879 			    struct mlx5_vdpa_virtqueue *mvq,
880 			    bool filled)
881 {
882 	int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
883 	u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
884 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
885 	struct mlx5_vdpa_mr *vq_mr;
886 	struct mlx5_vdpa_mr *vq_desc_mr;
887 	u64 features = filled ? mvdev->actual_features : mvdev->mlx_features;
888 	void *obj_context;
889 	u16 mlx_features;
890 	void *cmd_hdr;
891 	void *vq_ctx;
892 	void *in;
893 	int err;
894 
895 	err = umems_create(ndev, mvq);
896 	if (err)
897 		return err;
898 
899 	in = kzalloc(inlen, GFP_KERNEL);
900 	if (!in) {
901 		err = -ENOMEM;
902 		goto err_alloc;
903 	}
904 
905 	mlx_features = get_features(features);
906 	cmd_hdr = MLX5_ADDR_OF(create_virtio_net_q_in, in, general_obj_in_cmd_hdr);
907 
908 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
909 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
910 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
911 
912 	obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context);
913 	MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3,
914 		 mlx_features >> 3);
915 	MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_2_0,
916 		 mlx_features & 7);
917 	vq_ctx = MLX5_ADDR_OF(virtio_net_q_object, obj_context, virtio_q_context);
918 	MLX5_SET(virtio_q, vq_ctx, virtio_q_type, get_queue_type(ndev));
919 
920 	if (vq_is_tx(mvq->index))
921 		MLX5_SET(virtio_net_q_object, obj_context, tisn_or_qpn, ndev->res.tisn);
922 
923 	if (mvq->map.virq) {
924 		MLX5_SET(virtio_q, vq_ctx, event_mode, MLX5_VIRTIO_Q_EVENT_MODE_MSIX_MODE);
925 		MLX5_SET(virtio_q, vq_ctx, event_qpn_or_msix, mvq->map.index);
926 	} else {
927 		MLX5_SET(virtio_q, vq_ctx, event_mode, MLX5_VIRTIO_Q_EVENT_MODE_QP_MODE);
928 		MLX5_SET(virtio_q, vq_ctx, event_qpn_or_msix, mvq->fwqp.mqp.qpn);
929 	}
930 
931 	MLX5_SET(virtio_q, vq_ctx, queue_index, mvq->index);
932 	MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent);
933 	MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0,
934 		 !!(features & BIT_ULL(VIRTIO_F_VERSION_1)));
935 
936 	if (filled) {
937 		MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx);
938 		MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx);
939 
940 		MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
941 		MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
942 		MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
943 
944 		vq_mr = mvdev->mres.mr[mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_GROUP]];
945 		if (vq_mr)
946 			MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
947 
948 		vq_desc_mr = mvdev->mres.mr[mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
949 		if (vq_desc_mr &&
950 		    MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported))
951 			MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey);
952 	} else {
953 		/* If there is no mr update, make sure that the existing ones are set
954 		 * modify to ready.
955 		 */
956 		vq_mr = mvdev->mres.mr[mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_GROUP]];
957 		if (vq_mr)
958 			mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY;
959 
960 		vq_desc_mr = mvdev->mres.mr[mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
961 		if (vq_desc_mr)
962 			mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY;
963 	}
964 
965 	MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
966 	MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
967 	MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
968 	MLX5_SET(virtio_q, vq_ctx, umem_2_size, mvq->umem2.size);
969 	MLX5_SET(virtio_q, vq_ctx, umem_3_id, mvq->umem3.id);
970 	MLX5_SET(virtio_q, vq_ctx, umem_3_size, mvq->umem3.size);
971 	MLX5_SET(virtio_q, vq_ctx, pd, ndev->mvdev.res.pdn);
972 	if (counters_supported(&ndev->mvdev))
973 		MLX5_SET(virtio_q, vq_ctx, counter_set_id, mvq->counter_set_id);
974 
975 	err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out));
976 	if (err)
977 		goto err_cmd;
978 
979 	mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT;
980 	kfree(in);
981 	mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
982 
983 	if (filled) {
984 		mlx5_vdpa_get_mr(mvdev, vq_mr);
985 		mvq->vq_mr = vq_mr;
986 
987 		if (vq_desc_mr &&
988 		    MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) {
989 			mlx5_vdpa_get_mr(mvdev, vq_desc_mr);
990 			mvq->desc_mr = vq_desc_mr;
991 		}
992 	}
993 
994 	return 0;
995 
996 err_cmd:
997 	kfree(in);
998 err_alloc:
999 	umems_destroy(ndev, mvq);
1000 	return err;
1001 }
1002 
destroy_virtqueue(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1003 static void destroy_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1004 {
1005 	u32 in[MLX5_ST_SZ_DW(destroy_virtio_net_q_in)] = {};
1006 	u32 out[MLX5_ST_SZ_DW(destroy_virtio_net_q_out)] = {};
1007 
1008 	MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.opcode,
1009 		 MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
1010 	MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_id, mvq->virtq_id);
1011 	MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.uid, ndev->mvdev.res.uid);
1012 	MLX5_SET(destroy_virtio_net_q_in, in, general_obj_out_cmd_hdr.obj_type,
1013 		 MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1014 	if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out))) {
1015 		mlx5_vdpa_warn(&ndev->mvdev, "destroy virtqueue 0x%x\n", mvq->virtq_id);
1016 		return;
1017 	}
1018 	mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
1019 	umems_destroy(ndev, mvq);
1020 
1021 	mlx5_vdpa_put_mr(&ndev->mvdev, mvq->vq_mr);
1022 	mvq->vq_mr = NULL;
1023 
1024 	mlx5_vdpa_put_mr(&ndev->mvdev, mvq->desc_mr);
1025 	mvq->desc_mr = NULL;
1026 }
1027 
get_rqpn(struct mlx5_vdpa_virtqueue * mvq,bool fw)1028 static u32 get_rqpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
1029 {
1030 	return fw ? mvq->vqqp.mqp.qpn : mvq->fwqp.mqp.qpn;
1031 }
1032 
get_qpn(struct mlx5_vdpa_virtqueue * mvq,bool fw)1033 static u32 get_qpn(struct mlx5_vdpa_virtqueue *mvq, bool fw)
1034 {
1035 	return fw ? mvq->fwqp.mqp.qpn : mvq->vqqp.mqp.qpn;
1036 }
1037 
alloc_inout(struct mlx5_vdpa_net * ndev,int cmd,void ** in,int * inlen,void ** out,int * outlen,u32 qpn,u32 rqpn)1038 static void alloc_inout(struct mlx5_vdpa_net *ndev, int cmd, void **in, int *inlen, void **out,
1039 			int *outlen, u32 qpn, u32 rqpn)
1040 {
1041 	void *qpc;
1042 	void *pp;
1043 
1044 	switch (cmd) {
1045 	case MLX5_CMD_OP_2RST_QP:
1046 		*inlen = MLX5_ST_SZ_BYTES(qp_2rst_in);
1047 		*outlen = MLX5_ST_SZ_BYTES(qp_2rst_out);
1048 		*in = kzalloc(*inlen, GFP_KERNEL);
1049 		*out = kzalloc(*outlen, GFP_KERNEL);
1050 		if (!*in || !*out)
1051 			goto outerr;
1052 
1053 		MLX5_SET(qp_2rst_in, *in, opcode, cmd);
1054 		MLX5_SET(qp_2rst_in, *in, uid, ndev->mvdev.res.uid);
1055 		MLX5_SET(qp_2rst_in, *in, qpn, qpn);
1056 		break;
1057 	case MLX5_CMD_OP_RST2INIT_QP:
1058 		*inlen = MLX5_ST_SZ_BYTES(rst2init_qp_in);
1059 		*outlen = MLX5_ST_SZ_BYTES(rst2init_qp_out);
1060 		*in = kzalloc(*inlen, GFP_KERNEL);
1061 		*out = kzalloc(MLX5_ST_SZ_BYTES(rst2init_qp_out), GFP_KERNEL);
1062 		if (!*in || !*out)
1063 			goto outerr;
1064 
1065 		MLX5_SET(rst2init_qp_in, *in, opcode, cmd);
1066 		MLX5_SET(rst2init_qp_in, *in, uid, ndev->mvdev.res.uid);
1067 		MLX5_SET(rst2init_qp_in, *in, qpn, qpn);
1068 		qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
1069 		MLX5_SET(qpc, qpc, remote_qpn, rqpn);
1070 		MLX5_SET(qpc, qpc, rwe, 1);
1071 		pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
1072 		MLX5_SET(ads, pp, vhca_port_num, 1);
1073 		break;
1074 	case MLX5_CMD_OP_INIT2RTR_QP:
1075 		*inlen = MLX5_ST_SZ_BYTES(init2rtr_qp_in);
1076 		*outlen = MLX5_ST_SZ_BYTES(init2rtr_qp_out);
1077 		*in = kzalloc(*inlen, GFP_KERNEL);
1078 		*out = kzalloc(MLX5_ST_SZ_BYTES(init2rtr_qp_out), GFP_KERNEL);
1079 		if (!*in || !*out)
1080 			goto outerr;
1081 
1082 		MLX5_SET(init2rtr_qp_in, *in, opcode, cmd);
1083 		MLX5_SET(init2rtr_qp_in, *in, uid, ndev->mvdev.res.uid);
1084 		MLX5_SET(init2rtr_qp_in, *in, qpn, qpn);
1085 		qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
1086 		MLX5_SET(qpc, qpc, mtu, MLX5_QPC_MTU_256_BYTES);
1087 		MLX5_SET(qpc, qpc, log_msg_max, 30);
1088 		MLX5_SET(qpc, qpc, remote_qpn, rqpn);
1089 		pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
1090 		MLX5_SET(ads, pp, fl, 1);
1091 		break;
1092 	case MLX5_CMD_OP_RTR2RTS_QP:
1093 		*inlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_in);
1094 		*outlen = MLX5_ST_SZ_BYTES(rtr2rts_qp_out);
1095 		*in = kzalloc(*inlen, GFP_KERNEL);
1096 		*out = kzalloc(MLX5_ST_SZ_BYTES(rtr2rts_qp_out), GFP_KERNEL);
1097 		if (!*in || !*out)
1098 			goto outerr;
1099 
1100 		MLX5_SET(rtr2rts_qp_in, *in, opcode, cmd);
1101 		MLX5_SET(rtr2rts_qp_in, *in, uid, ndev->mvdev.res.uid);
1102 		MLX5_SET(rtr2rts_qp_in, *in, qpn, qpn);
1103 		qpc = MLX5_ADDR_OF(rst2init_qp_in, *in, qpc);
1104 		pp = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
1105 		MLX5_SET(ads, pp, ack_timeout, 14);
1106 		MLX5_SET(qpc, qpc, retry_count, 7);
1107 		MLX5_SET(qpc, qpc, rnr_retry, 7);
1108 		break;
1109 	default:
1110 		goto outerr_nullify;
1111 	}
1112 
1113 	return;
1114 
1115 outerr:
1116 	kfree(*in);
1117 	kfree(*out);
1118 outerr_nullify:
1119 	*in = NULL;
1120 	*out = NULL;
1121 }
1122 
free_inout(void * in,void * out)1123 static void free_inout(void *in, void *out)
1124 {
1125 	kfree(in);
1126 	kfree(out);
1127 }
1128 
1129 /* Two QPs are used by each virtqueue. One is used by the driver and one by
1130  * firmware. The fw argument indicates whether the subjected QP is the one used
1131  * by firmware.
1132  */
modify_qp(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,bool fw,int cmd)1133 static int modify_qp(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, bool fw, int cmd)
1134 {
1135 	int outlen;
1136 	int inlen;
1137 	void *out;
1138 	void *in;
1139 	int err;
1140 
1141 	alloc_inout(ndev, cmd, &in, &inlen, &out, &outlen, get_qpn(mvq, fw), get_rqpn(mvq, fw));
1142 	if (!in || !out)
1143 		return -ENOMEM;
1144 
1145 	err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, outlen);
1146 	free_inout(in, out);
1147 	return err;
1148 }
1149 
connect_qps(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1150 static int connect_qps(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1151 {
1152 	int err;
1153 
1154 	err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_2RST_QP);
1155 	if (err)
1156 		return err;
1157 
1158 	err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_2RST_QP);
1159 	if (err)
1160 		return err;
1161 
1162 	err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_RST2INIT_QP);
1163 	if (err)
1164 		return err;
1165 
1166 	err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_RST2INIT_QP);
1167 	if (err)
1168 		return err;
1169 
1170 	err = modify_qp(ndev, mvq, true, MLX5_CMD_OP_INIT2RTR_QP);
1171 	if (err)
1172 		return err;
1173 
1174 	err = modify_qp(ndev, mvq, false, MLX5_CMD_OP_INIT2RTR_QP);
1175 	if (err)
1176 		return err;
1177 
1178 	return modify_qp(ndev, mvq, true, MLX5_CMD_OP_RTR2RTS_QP);
1179 }
1180 
1181 struct mlx5_virtq_attr {
1182 	u8 state;
1183 	u16 available_index;
1184 	u16 used_index;
1185 };
1186 
1187 struct mlx5_virtqueue_query_mem {
1188 	u8 in[MLX5_ST_SZ_BYTES(query_virtio_net_q_in)];
1189 	u8 out[MLX5_ST_SZ_BYTES(query_virtio_net_q_out)];
1190 };
1191 
1192 struct mlx5_virtqueue_modify_mem {
1193 	u8 in[MLX5_ST_SZ_BYTES(modify_virtio_net_q_in)];
1194 	u8 out[MLX5_ST_SZ_BYTES(modify_virtio_net_q_out)];
1195 };
1196 
fill_query_virtqueue_cmd(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,struct mlx5_virtqueue_query_mem * cmd)1197 static void fill_query_virtqueue_cmd(struct mlx5_vdpa_net *ndev,
1198 				     struct mlx5_vdpa_virtqueue *mvq,
1199 				     struct mlx5_virtqueue_query_mem *cmd)
1200 {
1201 	void *cmd_hdr = MLX5_ADDR_OF(query_virtio_net_q_in, cmd->in, general_obj_in_cmd_hdr);
1202 
1203 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
1204 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1205 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1206 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1207 }
1208 
query_virtqueue_end(struct mlx5_vdpa_net * ndev,struct mlx5_virtqueue_query_mem * cmd,struct mlx5_virtq_attr * attr)1209 static void query_virtqueue_end(struct mlx5_vdpa_net *ndev,
1210 				struct mlx5_virtqueue_query_mem *cmd,
1211 				struct mlx5_virtq_attr *attr)
1212 {
1213 	void *obj_context = MLX5_ADDR_OF(query_virtio_net_q_out, cmd->out, obj_context);
1214 
1215 	memset(attr, 0, sizeof(*attr));
1216 	attr->state = MLX5_GET(virtio_net_q_object, obj_context, state);
1217 	attr->available_index = MLX5_GET(virtio_net_q_object, obj_context, hw_available_index);
1218 	attr->used_index = MLX5_GET(virtio_net_q_object, obj_context, hw_used_index);
1219 }
1220 
query_virtqueues(struct mlx5_vdpa_net * ndev,int start_vq,int num_vqs,struct mlx5_virtq_attr * attrs)1221 static int query_virtqueues(struct mlx5_vdpa_net *ndev,
1222 			    int start_vq,
1223 			    int num_vqs,
1224 			    struct mlx5_virtq_attr *attrs)
1225 {
1226 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
1227 	struct mlx5_virtqueue_query_mem *cmd_mem;
1228 	struct mlx5_vdpa_async_cmd *cmds;
1229 	int err = 0;
1230 
1231 	WARN(start_vq + num_vqs > mvdev->max_vqs, "query vq range invalid [%d, %d), max_vqs: %u\n",
1232 	     start_vq, start_vq + num_vqs, mvdev->max_vqs);
1233 
1234 	cmds = kvcalloc(num_vqs, sizeof(*cmds), GFP_KERNEL);
1235 	cmd_mem = kvcalloc(num_vqs, sizeof(*cmd_mem), GFP_KERNEL);
1236 	if (!cmds || !cmd_mem) {
1237 		err = -ENOMEM;
1238 		goto done;
1239 	}
1240 
1241 	for (int i = 0; i < num_vqs; i++) {
1242 		cmds[i].in = &cmd_mem[i].in;
1243 		cmds[i].inlen = sizeof(cmd_mem[i].in);
1244 		cmds[i].out = &cmd_mem[i].out;
1245 		cmds[i].outlen = sizeof(cmd_mem[i].out);
1246 		fill_query_virtqueue_cmd(ndev, &ndev->vqs[start_vq + i], &cmd_mem[i]);
1247 	}
1248 
1249 	err = mlx5_vdpa_exec_async_cmds(&ndev->mvdev, cmds, num_vqs);
1250 	if (err) {
1251 		mlx5_vdpa_err(mvdev, "error issuing query cmd for vq range [%d, %d): %d\n",
1252 			      start_vq, start_vq + num_vqs, err);
1253 		goto done;
1254 	}
1255 
1256 	for (int i = 0; i < num_vqs; i++) {
1257 		struct mlx5_vdpa_async_cmd *cmd = &cmds[i];
1258 		int vq_idx = start_vq + i;
1259 
1260 		if (cmd->err) {
1261 			mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, err);
1262 			if (!err)
1263 				err = cmd->err;
1264 			continue;
1265 		}
1266 
1267 		query_virtqueue_end(ndev, &cmd_mem[i], &attrs[i]);
1268 	}
1269 
1270 done:
1271 	kvfree(cmd_mem);
1272 	kvfree(cmds);
1273 	return err;
1274 }
1275 
is_resumable(struct mlx5_vdpa_net * ndev)1276 static bool is_resumable(struct mlx5_vdpa_net *ndev)
1277 {
1278 	return ndev->mvdev.vdev.config->resume;
1279 }
1280 
is_valid_state_change(int oldstate,int newstate,bool resumable)1281 static bool is_valid_state_change(int oldstate, int newstate, bool resumable)
1282 {
1283 	switch (oldstate) {
1284 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
1285 		return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY;
1286 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
1287 		return newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
1288 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
1289 		return resumable ? newstate == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY : false;
1290 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR:
1291 	default:
1292 		return false;
1293 	}
1294 }
1295 
modifiable_virtqueue_fields(struct mlx5_vdpa_virtqueue * mvq)1296 static bool modifiable_virtqueue_fields(struct mlx5_vdpa_virtqueue *mvq)
1297 {
1298 	/* Only state is always modifiable */
1299 	if (mvq->modified_fields & ~MLX5_VIRTQ_MODIFY_MASK_STATE)
1300 		return mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT ||
1301 		       mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND;
1302 
1303 	return true;
1304 }
1305 
fill_modify_virtqueue_cmd(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int state,struct mlx5_virtqueue_modify_mem * cmd)1306 static void fill_modify_virtqueue_cmd(struct mlx5_vdpa_net *ndev,
1307 				      struct mlx5_vdpa_virtqueue *mvq,
1308 				      int state,
1309 				      struct mlx5_virtqueue_modify_mem *cmd)
1310 {
1311 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
1312 	struct mlx5_vdpa_mr *desc_mr = NULL;
1313 	struct mlx5_vdpa_mr *vq_mr = NULL;
1314 	void *obj_context;
1315 	void *cmd_hdr;
1316 	void *vq_ctx;
1317 
1318 	cmd_hdr = MLX5_ADDR_OF(modify_virtio_net_q_in, cmd->in, general_obj_in_cmd_hdr);
1319 
1320 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
1321 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_NET_Q);
1322 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->virtq_id);
1323 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1324 
1325 	obj_context = MLX5_ADDR_OF(modify_virtio_net_q_in, cmd->in, obj_context);
1326 	vq_ctx = MLX5_ADDR_OF(virtio_net_q_object, obj_context, virtio_q_context);
1327 
1328 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_STATE)
1329 		MLX5_SET(virtio_net_q_object, obj_context, state, state);
1330 
1331 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_ADDRS) {
1332 		MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
1333 		MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
1334 		MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
1335 	}
1336 
1337 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_AVAIL_IDX)
1338 		MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx);
1339 
1340 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_USED_IDX)
1341 		MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx);
1342 
1343 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_QUEUE_VIRTIO_VERSION)
1344 		MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0,
1345 			!!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_F_VERSION_1)));
1346 
1347 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_QUEUE_FEATURES) {
1348 		u16 mlx_features = get_features(ndev->mvdev.actual_features);
1349 
1350 		MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3,
1351 			 mlx_features >> 3);
1352 		MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_2_0,
1353 			 mlx_features & 7);
1354 	}
1355 
1356 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY) {
1357 		vq_mr = mvdev->mres.mr[mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_GROUP]];
1358 
1359 		if (vq_mr)
1360 			MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
1361 		else
1362 			mvq->modified_fields &= ~MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY;
1363 	}
1364 
1365 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY) {
1366 		desc_mr = mvdev->mres.mr[mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
1367 
1368 		if (desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported))
1369 			MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, desc_mr->mkey);
1370 		else
1371 			mvq->modified_fields &= ~MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY;
1372 	}
1373 
1374 	MLX5_SET64(virtio_net_q_object, obj_context, modify_field_select, mvq->modified_fields);
1375 }
1376 
modify_virtqueue_end(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,int state)1377 static void modify_virtqueue_end(struct mlx5_vdpa_net *ndev,
1378 				 struct mlx5_vdpa_virtqueue *mvq,
1379 				 int state)
1380 {
1381 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
1382 
1383 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY) {
1384 		unsigned int asid = mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_GROUP];
1385 		struct mlx5_vdpa_mr *vq_mr = mvdev->mres.mr[asid];
1386 
1387 		mlx5_vdpa_put_mr(mvdev, mvq->vq_mr);
1388 		mlx5_vdpa_get_mr(mvdev, vq_mr);
1389 		mvq->vq_mr = vq_mr;
1390 	}
1391 
1392 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY) {
1393 		unsigned int asid = mvdev->mres.group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP];
1394 		struct mlx5_vdpa_mr *desc_mr = mvdev->mres.mr[asid];
1395 
1396 		mlx5_vdpa_put_mr(mvdev, mvq->desc_mr);
1397 		mlx5_vdpa_get_mr(mvdev, desc_mr);
1398 		mvq->desc_mr = desc_mr;
1399 	}
1400 
1401 	if (mvq->modified_fields & MLX5_VIRTQ_MODIFY_MASK_STATE)
1402 		mvq->fw_state = state;
1403 
1404 	mvq->modified_fields = 0;
1405 }
1406 
counter_set_alloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1407 static int counter_set_alloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1408 {
1409 	u32 in[MLX5_ST_SZ_DW(create_virtio_q_counters_in)] = {};
1410 	u32 out[MLX5_ST_SZ_DW(create_virtio_q_counters_out)] = {};
1411 	void *cmd_hdr;
1412 	int err;
1413 
1414 	if (!counters_supported(&ndev->mvdev))
1415 		return 0;
1416 
1417 	cmd_hdr = MLX5_ADDR_OF(create_virtio_q_counters_in, in, hdr);
1418 
1419 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
1420 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_Q_COUNTERS);
1421 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
1422 
1423 	err = mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out));
1424 	if (err)
1425 		return err;
1426 
1427 	mvq->counter_set_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
1428 
1429 	return 0;
1430 }
1431 
counter_set_dealloc(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1432 static void counter_set_dealloc(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1433 {
1434 	u32 in[MLX5_ST_SZ_DW(destroy_virtio_q_counters_in)] = {};
1435 	u32 out[MLX5_ST_SZ_DW(destroy_virtio_q_counters_out)] = {};
1436 
1437 	if (!counters_supported(&ndev->mvdev))
1438 		return;
1439 
1440 	MLX5_SET(destroy_virtio_q_counters_in, in, hdr.opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
1441 	MLX5_SET(destroy_virtio_q_counters_in, in, hdr.obj_id, mvq->counter_set_id);
1442 	MLX5_SET(destroy_virtio_q_counters_in, in, hdr.uid, ndev->mvdev.res.uid);
1443 	MLX5_SET(destroy_virtio_q_counters_in, in, hdr.obj_type, MLX5_OBJ_TYPE_VIRTIO_Q_COUNTERS);
1444 	if (mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out)))
1445 		mlx5_vdpa_warn(&ndev->mvdev, "dealloc counter set 0x%x\n", mvq->counter_set_id);
1446 }
1447 
mlx5_vdpa_int_handler(int irq,void * priv)1448 static irqreturn_t mlx5_vdpa_int_handler(int irq, void *priv)
1449 {
1450 	struct vdpa_callback *cb = priv;
1451 
1452 	if (cb->callback)
1453 		return cb->callback(cb->private);
1454 
1455 	return IRQ_HANDLED;
1456 }
1457 
alloc_vector(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1458 static void alloc_vector(struct mlx5_vdpa_net *ndev,
1459 			 struct mlx5_vdpa_virtqueue *mvq)
1460 {
1461 	struct mlx5_vdpa_irq_pool *irqp = &ndev->irqp;
1462 	struct mlx5_vdpa_irq_pool_entry *ent;
1463 	int err;
1464 	int i;
1465 
1466 	for (i = 0; i < irqp->num_ent; i++) {
1467 		ent = &irqp->entries[i];
1468 		if (!ent->used) {
1469 			snprintf(ent->name, MLX5_VDPA_IRQ_NAME_LEN, "%s-vq-%d",
1470 				 dev_name(&ndev->mvdev.vdev.dev), mvq->index);
1471 			ent->dev_id = &ndev->event_cbs[mvq->index];
1472 			err = request_irq(ent->map.virq, mlx5_vdpa_int_handler, 0,
1473 					  ent->name, ent->dev_id);
1474 			if (err)
1475 				return;
1476 
1477 			ent->used = true;
1478 			mvq->map = ent->map;
1479 			return;
1480 		}
1481 	}
1482 }
1483 
dealloc_vector(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1484 static void dealloc_vector(struct mlx5_vdpa_net *ndev,
1485 			   struct mlx5_vdpa_virtqueue *mvq)
1486 {
1487 	struct mlx5_vdpa_irq_pool *irqp = &ndev->irqp;
1488 	int i;
1489 
1490 	for (i = 0; i < irqp->num_ent; i++)
1491 		if (mvq->map.virq == irqp->entries[i].map.virq) {
1492 			free_irq(mvq->map.virq, irqp->entries[i].dev_id);
1493 			irqp->entries[i].used = false;
1494 			return;
1495 		}
1496 }
1497 
setup_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,bool filled)1498 static int setup_vq(struct mlx5_vdpa_net *ndev,
1499 		    struct mlx5_vdpa_virtqueue *mvq,
1500 		    bool filled)
1501 {
1502 	u16 idx = mvq->index;
1503 	int err;
1504 
1505 	if (mvq->initialized)
1506 		return 0;
1507 
1508 	err = cq_create(ndev, idx, mvq->num_ent);
1509 	if (err)
1510 		return err;
1511 
1512 	err = qp_create(ndev, mvq, &mvq->fwqp);
1513 	if (err)
1514 		goto err_fwqp;
1515 
1516 	err = qp_create(ndev, mvq, &mvq->vqqp);
1517 	if (err)
1518 		goto err_vqqp;
1519 
1520 	err = connect_qps(ndev, mvq);
1521 	if (err)
1522 		goto err_connect;
1523 
1524 	err = counter_set_alloc(ndev, mvq);
1525 	if (err)
1526 		goto err_connect;
1527 
1528 	alloc_vector(ndev, mvq);
1529 	err = create_virtqueue(ndev, mvq, filled);
1530 	if (err)
1531 		goto err_vq;
1532 
1533 	mvq->initialized = true;
1534 
1535 	if (mvq->ready) {
1536 		err = resume_vq(ndev, mvq);
1537 		if (err)
1538 			goto err_modify;
1539 	}
1540 
1541 	return 0;
1542 
1543 err_modify:
1544 	destroy_virtqueue(ndev, mvq);
1545 err_vq:
1546 	dealloc_vector(ndev, mvq);
1547 	counter_set_dealloc(ndev, mvq);
1548 err_connect:
1549 	qp_destroy(ndev, &mvq->vqqp);
1550 err_vqqp:
1551 	qp_destroy(ndev, &mvq->fwqp);
1552 err_fwqp:
1553 	cq_destroy(ndev, idx);
1554 	return err;
1555 }
1556 
modify_virtqueues(struct mlx5_vdpa_net * ndev,int start_vq,int num_vqs,int state)1557 static int modify_virtqueues(struct mlx5_vdpa_net *ndev, int start_vq, int num_vqs, int state)
1558 {
1559 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
1560 	struct mlx5_virtqueue_modify_mem *cmd_mem;
1561 	struct mlx5_vdpa_async_cmd *cmds;
1562 	int err = 0;
1563 
1564 	WARN(start_vq + num_vqs > mvdev->max_vqs, "modify vq range invalid [%d, %d), max_vqs: %u\n",
1565 	     start_vq, start_vq + num_vqs, mvdev->max_vqs);
1566 
1567 	cmds = kvcalloc(num_vqs, sizeof(*cmds), GFP_KERNEL);
1568 	cmd_mem = kvcalloc(num_vqs, sizeof(*cmd_mem), GFP_KERNEL);
1569 	if (!cmds || !cmd_mem) {
1570 		err = -ENOMEM;
1571 		goto done;
1572 	}
1573 
1574 	for (int i = 0; i < num_vqs; i++) {
1575 		struct mlx5_vdpa_async_cmd *cmd = &cmds[i];
1576 		struct mlx5_vdpa_virtqueue *mvq;
1577 		int vq_idx = start_vq + i;
1578 
1579 		mvq = &ndev->vqs[vq_idx];
1580 
1581 		if (!modifiable_virtqueue_fields(mvq)) {
1582 			err = -EINVAL;
1583 			goto done;
1584 		}
1585 
1586 		if (mvq->fw_state != state) {
1587 			if (!is_valid_state_change(mvq->fw_state, state, is_resumable(ndev))) {
1588 				err = -EINVAL;
1589 				goto done;
1590 			}
1591 
1592 			mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_STATE;
1593 		}
1594 
1595 		cmd->in = &cmd_mem[i].in;
1596 		cmd->inlen = sizeof(cmd_mem[i].in);
1597 		cmd->out = &cmd_mem[i].out;
1598 		cmd->outlen = sizeof(cmd_mem[i].out);
1599 		fill_modify_virtqueue_cmd(ndev, mvq, state, &cmd_mem[i]);
1600 	}
1601 
1602 	err = mlx5_vdpa_exec_async_cmds(&ndev->mvdev, cmds, num_vqs);
1603 	if (err) {
1604 		mlx5_vdpa_err(mvdev, "error issuing modify cmd for vq range [%d, %d)\n",
1605 			      start_vq, start_vq + num_vqs);
1606 		goto done;
1607 	}
1608 
1609 	for (int i = 0; i < num_vqs; i++) {
1610 		struct mlx5_vdpa_async_cmd *cmd = &cmds[i];
1611 		struct mlx5_vdpa_virtqueue *mvq;
1612 		int vq_idx = start_vq + i;
1613 
1614 		mvq = &ndev->vqs[vq_idx];
1615 
1616 		if (cmd->err) {
1617 			mlx5_vdpa_err(mvdev, "modify vq %d failed, state: %d -> %d, err: %d\n",
1618 				      vq_idx, mvq->fw_state, state, err);
1619 			if (!err)
1620 				err = cmd->err;
1621 			continue;
1622 		}
1623 
1624 		modify_virtqueue_end(ndev, mvq, state);
1625 	}
1626 
1627 done:
1628 	kvfree(cmd_mem);
1629 	kvfree(cmds);
1630 	return err;
1631 }
1632 
suspend_vqs(struct mlx5_vdpa_net * ndev,int start_vq,int num_vqs)1633 static int suspend_vqs(struct mlx5_vdpa_net *ndev, int start_vq, int num_vqs)
1634 {
1635 	struct mlx5_vdpa_virtqueue *mvq;
1636 	struct mlx5_virtq_attr *attrs;
1637 	int vq_idx, i;
1638 	int err;
1639 
1640 	if (start_vq >= ndev->cur_num_vqs)
1641 		return -EINVAL;
1642 
1643 	mvq = &ndev->vqs[start_vq];
1644 	if (!mvq->initialized)
1645 		return 0;
1646 
1647 	if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY)
1648 		return 0;
1649 
1650 	err = modify_virtqueues(ndev, start_vq, num_vqs, MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND);
1651 	if (err)
1652 		return err;
1653 
1654 	attrs = kcalloc(num_vqs, sizeof(struct mlx5_virtq_attr), GFP_KERNEL);
1655 	if (!attrs)
1656 		return -ENOMEM;
1657 
1658 	err = query_virtqueues(ndev, start_vq, num_vqs, attrs);
1659 	if (err)
1660 		goto done;
1661 
1662 	for (i = 0, vq_idx = start_vq; i < num_vqs; i++, vq_idx++) {
1663 		mvq = &ndev->vqs[vq_idx];
1664 		mvq->avail_idx = attrs[i].available_index;
1665 		mvq->used_idx = attrs[i].used_index;
1666 	}
1667 
1668 done:
1669 	kfree(attrs);
1670 	return err;
1671 }
1672 
suspend_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1673 static int suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1674 {
1675 	return suspend_vqs(ndev, mvq->index, 1);
1676 }
1677 
resume_vqs(struct mlx5_vdpa_net * ndev,int start_vq,int num_vqs)1678 static int resume_vqs(struct mlx5_vdpa_net *ndev, int start_vq, int num_vqs)
1679 {
1680 	struct mlx5_vdpa_virtqueue *mvq;
1681 	int err;
1682 
1683 	if (start_vq >= ndev->mvdev.max_vqs)
1684 		return -EINVAL;
1685 
1686 	mvq = &ndev->vqs[start_vq];
1687 	if (!mvq->initialized)
1688 		return 0;
1689 
1690 	if (mvq->index >= ndev->cur_num_vqs)
1691 		return 0;
1692 
1693 	switch (mvq->fw_state) {
1694 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT:
1695 		/* Due to a FW quirk we need to modify the VQ fields first then change state.
1696 		 * This should be fixed soon. After that, a single command can be used.
1697 		 */
1698 		err = modify_virtqueues(ndev, start_vq, num_vqs, mvq->fw_state);
1699 		if (err)
1700 			return err;
1701 		break;
1702 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND:
1703 		if (!is_resumable(ndev)) {
1704 			mlx5_vdpa_warn(&ndev->mvdev, "vq %d is not resumable\n", mvq->index);
1705 			return -EINVAL;
1706 		}
1707 		break;
1708 	case MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY:
1709 		return 0;
1710 	default:
1711 		mlx5_vdpa_err(&ndev->mvdev, "resume vq %u called from bad state %d\n",
1712 			       mvq->index, mvq->fw_state);
1713 		return -EINVAL;
1714 	}
1715 
1716 	return modify_virtqueues(ndev, start_vq, num_vqs, MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY);
1717 }
1718 
resume_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1719 static int resume_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1720 {
1721 	return resume_vqs(ndev, mvq->index, 1);
1722 }
1723 
teardown_vq(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)1724 static void teardown_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1725 {
1726 	if (!mvq->initialized)
1727 		return;
1728 
1729 	suspend_vq(ndev, mvq);
1730 	mvq->modified_fields = 0;
1731 	destroy_virtqueue(ndev, mvq);
1732 	dealloc_vector(ndev, mvq);
1733 	counter_set_dealloc(ndev, mvq);
1734 	qp_destroy(ndev, &mvq->vqqp);
1735 	qp_destroy(ndev, &mvq->fwqp);
1736 	cq_destroy(ndev, mvq->index);
1737 	mvq->initialized = false;
1738 }
1739 
create_rqt(struct mlx5_vdpa_net * ndev)1740 static int create_rqt(struct mlx5_vdpa_net *ndev)
1741 {
1742 	int rqt_table_size = roundup_pow_of_two(ndev->rqt_size);
1743 	int act_sz = roundup_pow_of_two(ndev->cur_num_vqs / 2);
1744 	__be32 *list;
1745 	void *rqtc;
1746 	int inlen;
1747 	void *in;
1748 	int i, j;
1749 	int err;
1750 
1751 	inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + rqt_table_size * MLX5_ST_SZ_BYTES(rq_num);
1752 	in = kzalloc(inlen, GFP_KERNEL);
1753 	if (!in)
1754 		return -ENOMEM;
1755 
1756 	MLX5_SET(create_rqt_in, in, uid, ndev->mvdev.res.uid);
1757 	rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
1758 
1759 	MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q);
1760 	MLX5_SET(rqtc, rqtc, rqt_max_size, rqt_table_size);
1761 	list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]);
1762 	for (i = 0, j = 0; i < act_sz; i++, j += 2)
1763 		list[i] = cpu_to_be32(ndev->vqs[j % ndev->cur_num_vqs].virtq_id);
1764 
1765 	MLX5_SET(rqtc, rqtc, rqt_actual_size, act_sz);
1766 	err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);
1767 	kfree(in);
1768 	if (err)
1769 		return err;
1770 
1771 	return 0;
1772 }
1773 
1774 #define MLX5_MODIFY_RQT_NUM_RQS ((u64)1)
1775 
modify_rqt(struct mlx5_vdpa_net * ndev,int num)1776 static int modify_rqt(struct mlx5_vdpa_net *ndev, int num)
1777 {
1778 	int act_sz = roundup_pow_of_two(num / 2);
1779 	__be32 *list;
1780 	void *rqtc;
1781 	int inlen;
1782 	void *in;
1783 	int i, j;
1784 	int err;
1785 
1786 	inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + act_sz * MLX5_ST_SZ_BYTES(rq_num);
1787 	in = kzalloc(inlen, GFP_KERNEL);
1788 	if (!in)
1789 		return -ENOMEM;
1790 
1791 	MLX5_SET(modify_rqt_in, in, uid, ndev->mvdev.res.uid);
1792 	MLX5_SET64(modify_rqt_in, in, bitmask, MLX5_MODIFY_RQT_NUM_RQS);
1793 	rqtc = MLX5_ADDR_OF(modify_rqt_in, in, ctx);
1794 	MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q);
1795 
1796 	list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]);
1797 	for (i = 0, j = 0; i < act_sz; i++, j = j + 2)
1798 		list[i] = cpu_to_be32(ndev->vqs[j % num].virtq_id);
1799 
1800 	MLX5_SET(rqtc, rqtc, rqt_actual_size, act_sz);
1801 	err = mlx5_vdpa_modify_rqt(&ndev->mvdev, in, inlen, ndev->res.rqtn);
1802 	kfree(in);
1803 	if (err)
1804 		return err;
1805 
1806 	return 0;
1807 }
1808 
destroy_rqt(struct mlx5_vdpa_net * ndev)1809 static void destroy_rqt(struct mlx5_vdpa_net *ndev)
1810 {
1811 	mlx5_vdpa_destroy_rqt(&ndev->mvdev, ndev->res.rqtn);
1812 }
1813 
create_tir(struct mlx5_vdpa_net * ndev)1814 static int create_tir(struct mlx5_vdpa_net *ndev)
1815 {
1816 #define HASH_IP_L4PORTS                                                                            \
1817 	(MLX5_HASH_FIELD_SEL_SRC_IP | MLX5_HASH_FIELD_SEL_DST_IP | MLX5_HASH_FIELD_SEL_L4_SPORT |  \
1818 	 MLX5_HASH_FIELD_SEL_L4_DPORT)
1819 	static const u8 rx_hash_toeplitz_key[] = { 0x2c, 0xc6, 0x81, 0xd1, 0x5b, 0xdb, 0xf4, 0xf7,
1820 						   0xfc, 0xa2, 0x83, 0x19, 0xdb, 0x1a, 0x3e, 0x94,
1821 						   0x6b, 0x9e, 0x38, 0xd9, 0x2c, 0x9c, 0x03, 0xd1,
1822 						   0xad, 0x99, 0x44, 0xa7, 0xd9, 0x56, 0x3d, 0x59,
1823 						   0x06, 0x3c, 0x25, 0xf3, 0xfc, 0x1f, 0xdc, 0x2a };
1824 	void *rss_key;
1825 	void *outer;
1826 	void *tirc;
1827 	void *in;
1828 	int err;
1829 
1830 	in = kzalloc(MLX5_ST_SZ_BYTES(create_tir_in), GFP_KERNEL);
1831 	if (!in)
1832 		return -ENOMEM;
1833 
1834 	MLX5_SET(create_tir_in, in, uid, ndev->mvdev.res.uid);
1835 	tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
1836 	MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
1837 
1838 	MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
1839 	MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_TOEPLITZ);
1840 	rss_key = MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
1841 	memcpy(rss_key, rx_hash_toeplitz_key, sizeof(rx_hash_toeplitz_key));
1842 
1843 	outer = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
1844 	MLX5_SET(rx_hash_field_select, outer, l3_prot_type, MLX5_L3_PROT_TYPE_IPV4);
1845 	MLX5_SET(rx_hash_field_select, outer, l4_prot_type, MLX5_L4_PROT_TYPE_TCP);
1846 	MLX5_SET(rx_hash_field_select, outer, selected_fields, HASH_IP_L4PORTS);
1847 
1848 	MLX5_SET(tirc, tirc, indirect_table, ndev->res.rqtn);
1849 	MLX5_SET(tirc, tirc, transport_domain, ndev->res.tdn);
1850 
1851 	err = mlx5_vdpa_create_tir(&ndev->mvdev, in, &ndev->res.tirn);
1852 	kfree(in);
1853 	if (err)
1854 		return err;
1855 
1856 	mlx5_vdpa_add_tirn(ndev);
1857 	return err;
1858 }
1859 
destroy_tir(struct mlx5_vdpa_net * ndev)1860 static void destroy_tir(struct mlx5_vdpa_net *ndev)
1861 {
1862 	mlx5_vdpa_remove_tirn(ndev);
1863 	mlx5_vdpa_destroy_tir(&ndev->mvdev, ndev->res.tirn);
1864 }
1865 
1866 #define MAX_STEERING_ENT 0x8000
1867 #define MAX_STEERING_GROUPS 2
1868 
1869 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
1870        #define NUM_DESTS 2
1871 #else
1872        #define NUM_DESTS 1
1873 #endif
1874 
add_steering_counters(struct mlx5_vdpa_net * ndev,struct macvlan_node * node,struct mlx5_flow_act * flow_act,struct mlx5_flow_destination * dests)1875 static int add_steering_counters(struct mlx5_vdpa_net *ndev,
1876 				 struct macvlan_node *node,
1877 				 struct mlx5_flow_act *flow_act,
1878 				 struct mlx5_flow_destination *dests)
1879 {
1880 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
1881 	int err;
1882 
1883 	node->ucast_counter.counter = mlx5_fc_create(ndev->mvdev.mdev, false);
1884 	if (IS_ERR(node->ucast_counter.counter))
1885 		return PTR_ERR(node->ucast_counter.counter);
1886 
1887 	node->mcast_counter.counter = mlx5_fc_create(ndev->mvdev.mdev, false);
1888 	if (IS_ERR(node->mcast_counter.counter)) {
1889 		err = PTR_ERR(node->mcast_counter.counter);
1890 		goto err_mcast_counter;
1891 	}
1892 
1893 	dests[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1894 	flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
1895 	return 0;
1896 
1897 err_mcast_counter:
1898 	mlx5_fc_destroy(ndev->mvdev.mdev, node->ucast_counter.counter);
1899 	return err;
1900 #else
1901 	return 0;
1902 #endif
1903 }
1904 
remove_steering_counters(struct mlx5_vdpa_net * ndev,struct macvlan_node * node)1905 static void remove_steering_counters(struct mlx5_vdpa_net *ndev,
1906 				     struct macvlan_node *node)
1907 {
1908 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
1909 	mlx5_fc_destroy(ndev->mvdev.mdev, node->mcast_counter.counter);
1910 	mlx5_fc_destroy(ndev->mvdev.mdev, node->ucast_counter.counter);
1911 #endif
1912 }
1913 
mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net * ndev,u8 * mac,struct macvlan_node * node)1914 static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac,
1915 					struct macvlan_node *node)
1916 {
1917 	struct mlx5_flow_destination dests[NUM_DESTS] = {};
1918 	struct mlx5_flow_act flow_act = {};
1919 	struct mlx5_flow_spec *spec;
1920 	void *headers_c;
1921 	void *headers_v;
1922 	u8 *dmac_c;
1923 	u8 *dmac_v;
1924 	int err;
1925 	u16 vid;
1926 
1927 	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
1928 	if (!spec)
1929 		return -ENOMEM;
1930 
1931 	vid = key2vid(node->macvlan);
1932 	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1933 	headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, outer_headers);
1934 	headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers);
1935 	dmac_c = MLX5_ADDR_OF(fte_match_param, headers_c, outer_headers.dmac_47_16);
1936 	dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, outer_headers.dmac_47_16);
1937 	eth_broadcast_addr(dmac_c);
1938 	ether_addr_copy(dmac_v, mac);
1939 	if (ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN)) {
1940 		MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
1941 		MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid);
1942 	}
1943 	if (node->tagged) {
1944 		MLX5_SET(fte_match_set_lyr_2_4, headers_v, cvlan_tag, 1);
1945 		MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, vid);
1946 	}
1947 	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
1948 	dests[0].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1949 	dests[0].tir_num = ndev->res.tirn;
1950 	err = add_steering_counters(ndev, node, &flow_act, dests);
1951 	if (err)
1952 		goto out_free;
1953 
1954 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
1955 	dests[1].counter_id = mlx5_fc_id(node->ucast_counter.counter);
1956 #endif
1957 	node->ucast_rule = mlx5_add_flow_rules(ndev->rxft, spec, &flow_act, dests, NUM_DESTS);
1958 	if (IS_ERR(node->ucast_rule)) {
1959 		err = PTR_ERR(node->ucast_rule);
1960 		goto err_ucast;
1961 	}
1962 
1963 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
1964 	dests[1].counter_id = mlx5_fc_id(node->mcast_counter.counter);
1965 #endif
1966 
1967 	memset(dmac_c, 0, ETH_ALEN);
1968 	memset(dmac_v, 0, ETH_ALEN);
1969 	dmac_c[0] = 1;
1970 	dmac_v[0] = 1;
1971 	node->mcast_rule = mlx5_add_flow_rules(ndev->rxft, spec, &flow_act, dests, NUM_DESTS);
1972 	if (IS_ERR(node->mcast_rule)) {
1973 		err = PTR_ERR(node->mcast_rule);
1974 		goto err_mcast;
1975 	}
1976 	kvfree(spec);
1977 	mlx5_vdpa_add_rx_counters(ndev, node);
1978 	return 0;
1979 
1980 err_mcast:
1981 	mlx5_del_flow_rules(node->ucast_rule);
1982 err_ucast:
1983 	remove_steering_counters(ndev, node);
1984 out_free:
1985 	kvfree(spec);
1986 	return err;
1987 }
1988 
mlx5_vdpa_del_mac_vlan_rules(struct mlx5_vdpa_net * ndev,struct macvlan_node * node)1989 static void mlx5_vdpa_del_mac_vlan_rules(struct mlx5_vdpa_net *ndev,
1990 					 struct macvlan_node *node)
1991 {
1992 	mlx5_vdpa_remove_rx_counters(ndev, node);
1993 	mlx5_del_flow_rules(node->ucast_rule);
1994 	mlx5_del_flow_rules(node->mcast_rule);
1995 }
1996 
search_val(u8 * mac,u16 vlan,bool tagged)1997 static u64 search_val(u8 *mac, u16 vlan, bool tagged)
1998 {
1999 	u64 val;
2000 
2001 	if (!tagged)
2002 		vlan = MLX5V_UNTAGGED;
2003 
2004 	val = (u64)vlan << 48 |
2005 	      (u64)mac[0] << 40 |
2006 	      (u64)mac[1] << 32 |
2007 	      (u64)mac[2] << 24 |
2008 	      (u64)mac[3] << 16 |
2009 	      (u64)mac[4] << 8 |
2010 	      (u64)mac[5];
2011 
2012 	return val;
2013 }
2014 
mac_vlan_lookup(struct mlx5_vdpa_net * ndev,u64 value)2015 static struct macvlan_node *mac_vlan_lookup(struct mlx5_vdpa_net *ndev, u64 value)
2016 {
2017 	struct macvlan_node *pos;
2018 	u32 idx;
2019 
2020 	idx = hash_64(value, 8); // tbd 8
2021 	hlist_for_each_entry(pos, &ndev->macvlan_hash[idx], hlist) {
2022 		if (pos->macvlan == value)
2023 			return pos;
2024 	}
2025 	return NULL;
2026 }
2027 
mac_vlan_add(struct mlx5_vdpa_net * ndev,u8 * mac,u16 vid,bool tagged)2028 static int mac_vlan_add(struct mlx5_vdpa_net *ndev, u8 *mac, u16 vid, bool tagged)
2029 {
2030 	struct macvlan_node *ptr;
2031 	u64 val;
2032 	u32 idx;
2033 	int err;
2034 
2035 	val = search_val(mac, vid, tagged);
2036 	if (mac_vlan_lookup(ndev, val))
2037 		return -EEXIST;
2038 
2039 	ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
2040 	if (!ptr)
2041 		return -ENOMEM;
2042 
2043 	ptr->tagged = tagged;
2044 	ptr->macvlan = val;
2045 	ptr->ndev = ndev;
2046 	err = mlx5_vdpa_add_mac_vlan_rules(ndev, ndev->config.mac, ptr);
2047 	if (err)
2048 		goto err_add;
2049 
2050 	idx = hash_64(val, 8);
2051 	hlist_add_head(&ptr->hlist, &ndev->macvlan_hash[idx]);
2052 	return 0;
2053 
2054 err_add:
2055 	kfree(ptr);
2056 	return err;
2057 }
2058 
mac_vlan_del(struct mlx5_vdpa_net * ndev,u8 * mac,u16 vlan,bool tagged)2059 static void mac_vlan_del(struct mlx5_vdpa_net *ndev, u8 *mac, u16 vlan, bool tagged)
2060 {
2061 	struct macvlan_node *ptr;
2062 
2063 	ptr = mac_vlan_lookup(ndev, search_val(mac, vlan, tagged));
2064 	if (!ptr)
2065 		return;
2066 
2067 	hlist_del(&ptr->hlist);
2068 	mlx5_vdpa_del_mac_vlan_rules(ndev, ptr);
2069 	remove_steering_counters(ndev, ptr);
2070 	kfree(ptr);
2071 }
2072 
clear_mac_vlan_table(struct mlx5_vdpa_net * ndev)2073 static void clear_mac_vlan_table(struct mlx5_vdpa_net *ndev)
2074 {
2075 	struct macvlan_node *pos;
2076 	struct hlist_node *n;
2077 	int i;
2078 
2079 	for (i = 0; i < MLX5V_MACVLAN_SIZE; i++) {
2080 		hlist_for_each_entry_safe(pos, n, &ndev->macvlan_hash[i], hlist) {
2081 			hlist_del(&pos->hlist);
2082 			mlx5_vdpa_del_mac_vlan_rules(ndev, pos);
2083 			remove_steering_counters(ndev, pos);
2084 			kfree(pos);
2085 		}
2086 	}
2087 }
2088 
setup_steering(struct mlx5_vdpa_net * ndev)2089 static int setup_steering(struct mlx5_vdpa_net *ndev)
2090 {
2091 	struct mlx5_flow_table_attr ft_attr = {};
2092 	struct mlx5_flow_namespace *ns;
2093 	int err;
2094 
2095 	ft_attr.max_fte = MAX_STEERING_ENT;
2096 	ft_attr.autogroup.max_num_groups = MAX_STEERING_GROUPS;
2097 
2098 	ns = mlx5_get_flow_namespace(ndev->mvdev.mdev, MLX5_FLOW_NAMESPACE_BYPASS);
2099 	if (!ns) {
2100 		mlx5_vdpa_err(&ndev->mvdev, "failed to get flow namespace\n");
2101 		return -EOPNOTSUPP;
2102 	}
2103 
2104 	ndev->rxft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
2105 	if (IS_ERR(ndev->rxft)) {
2106 		mlx5_vdpa_err(&ndev->mvdev, "failed to create flow table\n");
2107 		return PTR_ERR(ndev->rxft);
2108 	}
2109 	mlx5_vdpa_add_rx_flow_table(ndev);
2110 
2111 	err = mac_vlan_add(ndev, ndev->config.mac, 0, false);
2112 	if (err)
2113 		goto err_add;
2114 
2115 	return 0;
2116 
2117 err_add:
2118 	mlx5_vdpa_remove_rx_flow_table(ndev);
2119 	mlx5_destroy_flow_table(ndev->rxft);
2120 	return err;
2121 }
2122 
teardown_steering(struct mlx5_vdpa_net * ndev)2123 static void teardown_steering(struct mlx5_vdpa_net *ndev)
2124 {
2125 	clear_mac_vlan_table(ndev);
2126 	mlx5_vdpa_remove_rx_flow_table(ndev);
2127 	mlx5_destroy_flow_table(ndev->rxft);
2128 }
2129 
handle_ctrl_mac(struct mlx5_vdpa_dev * mvdev,u8 cmd)2130 static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
2131 {
2132 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2133 	struct mlx5_control_vq *cvq = &mvdev->cvq;
2134 	virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
2135 	struct mlx5_core_dev *pfmdev;
2136 	size_t read;
2137 	u8 mac[ETH_ALEN], mac_back[ETH_ALEN];
2138 
2139 	pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
2140 	switch (cmd) {
2141 	case VIRTIO_NET_CTRL_MAC_ADDR_SET:
2142 		read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, (void *)mac, ETH_ALEN);
2143 		if (read != ETH_ALEN)
2144 			break;
2145 
2146 		if (!memcmp(ndev->config.mac, mac, 6)) {
2147 			status = VIRTIO_NET_OK;
2148 			break;
2149 		}
2150 
2151 		if (is_zero_ether_addr(mac))
2152 			break;
2153 
2154 		if (!is_zero_ether_addr(ndev->config.mac)) {
2155 			if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
2156 				mlx5_vdpa_warn(mvdev, "failed to delete old MAC %pM from MPFS table\n",
2157 					       ndev->config.mac);
2158 				break;
2159 			}
2160 		}
2161 
2162 		if (mlx5_mpfs_add_mac(pfmdev, mac)) {
2163 			mlx5_vdpa_warn(mvdev, "failed to insert new MAC %pM into MPFS table\n",
2164 				       mac);
2165 			break;
2166 		}
2167 
2168 		/* backup the original mac address so that if failed to add the forward rules
2169 		 * we could restore it
2170 		 */
2171 		memcpy(mac_back, ndev->config.mac, ETH_ALEN);
2172 
2173 		memcpy(ndev->config.mac, mac, ETH_ALEN);
2174 
2175 		/* Need recreate the flow table entry, so that the packet could forward back
2176 		 */
2177 		mac_vlan_del(ndev, mac_back, 0, false);
2178 
2179 		if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
2180 			mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
2181 
2182 			/* Although it hardly run here, we still need double check */
2183 			if (is_zero_ether_addr(mac_back)) {
2184 				mlx5_vdpa_warn(mvdev, "restore mac failed: Original MAC is zero\n");
2185 				break;
2186 			}
2187 
2188 			/* Try to restore original mac address to MFPS table, and try to restore
2189 			 * the forward rule entry.
2190 			 */
2191 			if (mlx5_mpfs_del_mac(pfmdev, ndev->config.mac)) {
2192 				mlx5_vdpa_warn(mvdev, "restore mac failed: delete MAC %pM from MPFS table failed\n",
2193 					       ndev->config.mac);
2194 			}
2195 
2196 			if (mlx5_mpfs_add_mac(pfmdev, mac_back)) {
2197 				mlx5_vdpa_warn(mvdev, "restore mac failed: insert old MAC %pM into MPFS table failed\n",
2198 					       mac_back);
2199 			}
2200 
2201 			memcpy(ndev->config.mac, mac_back, ETH_ALEN);
2202 
2203 			if (mac_vlan_add(ndev, ndev->config.mac, 0, false))
2204 				mlx5_vdpa_warn(mvdev, "restore forward rules failed: insert forward rules failed\n");
2205 
2206 			break;
2207 		}
2208 
2209 		status = VIRTIO_NET_OK;
2210 		break;
2211 
2212 	default:
2213 		break;
2214 	}
2215 
2216 	return status;
2217 }
2218 
change_num_qps(struct mlx5_vdpa_dev * mvdev,int newqps)2219 static int change_num_qps(struct mlx5_vdpa_dev *mvdev, int newqps)
2220 {
2221 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2222 	int cur_vqs = ndev->cur_num_vqs;
2223 	int new_vqs = newqps * 2;
2224 	int err;
2225 	int i;
2226 
2227 	if (cur_vqs > new_vqs) {
2228 		err = modify_rqt(ndev, new_vqs);
2229 		if (err)
2230 			return err;
2231 
2232 		if (is_resumable(ndev)) {
2233 			suspend_vqs(ndev, new_vqs, cur_vqs - new_vqs);
2234 		} else {
2235 			for (i = new_vqs; i < cur_vqs; i++)
2236 				teardown_vq(ndev, &ndev->vqs[i]);
2237 		}
2238 
2239 		ndev->cur_num_vqs = new_vqs;
2240 	} else {
2241 		ndev->cur_num_vqs = new_vqs;
2242 
2243 		for (i = cur_vqs; i < new_vqs; i++) {
2244 			err = setup_vq(ndev, &ndev->vqs[i], false);
2245 			if (err)
2246 				goto clean_added;
2247 		}
2248 
2249 		err = resume_vqs(ndev, cur_vqs, new_vqs - cur_vqs);
2250 		if (err)
2251 			goto clean_added;
2252 
2253 		err = modify_rqt(ndev, new_vqs);
2254 		if (err)
2255 			goto clean_added;
2256 	}
2257 	return 0;
2258 
2259 clean_added:
2260 	for (--i; i >= cur_vqs; --i)
2261 		teardown_vq(ndev, &ndev->vqs[i]);
2262 
2263 	ndev->cur_num_vqs = cur_vqs;
2264 
2265 	return err;
2266 }
2267 
handle_ctrl_mq(struct mlx5_vdpa_dev * mvdev,u8 cmd)2268 static virtio_net_ctrl_ack handle_ctrl_mq(struct mlx5_vdpa_dev *mvdev, u8 cmd)
2269 {
2270 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2271 	virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
2272 	struct mlx5_control_vq *cvq = &mvdev->cvq;
2273 	struct virtio_net_ctrl_mq mq;
2274 	size_t read;
2275 	u16 newqps;
2276 
2277 	switch (cmd) {
2278 	case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET:
2279 		/* This mq feature check aligns with pre-existing userspace
2280 		 * implementation.
2281 		 *
2282 		 * Without it, an untrusted driver could fake a multiqueue config
2283 		 * request down to a non-mq device that may cause kernel to
2284 		 * panic due to uninitialized resources for extra vqs. Even with
2285 		 * a well behaving guest driver, it is not expected to allow
2286 		 * changing the number of vqs on a non-mq device.
2287 		 */
2288 		if (!MLX5_FEATURE(mvdev, VIRTIO_NET_F_MQ))
2289 			break;
2290 
2291 		read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, (void *)&mq, sizeof(mq));
2292 		if (read != sizeof(mq))
2293 			break;
2294 
2295 		newqps = mlx5vdpa16_to_cpu(mvdev, mq.virtqueue_pairs);
2296 		if (newqps < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN ||
2297 		    newqps > ndev->rqt_size)
2298 			break;
2299 
2300 		if (ndev->cur_num_vqs == 2 * newqps) {
2301 			status = VIRTIO_NET_OK;
2302 			break;
2303 		}
2304 
2305 		if (!change_num_qps(mvdev, newqps))
2306 			status = VIRTIO_NET_OK;
2307 
2308 		break;
2309 	default:
2310 		break;
2311 	}
2312 
2313 	return status;
2314 }
2315 
handle_ctrl_vlan(struct mlx5_vdpa_dev * mvdev,u8 cmd)2316 static virtio_net_ctrl_ack handle_ctrl_vlan(struct mlx5_vdpa_dev *mvdev, u8 cmd)
2317 {
2318 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2319 	virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
2320 	struct mlx5_control_vq *cvq = &mvdev->cvq;
2321 	__virtio16 vlan;
2322 	size_t read;
2323 	u16 id;
2324 
2325 	if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN)))
2326 		return status;
2327 
2328 	switch (cmd) {
2329 	case VIRTIO_NET_CTRL_VLAN_ADD:
2330 		read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, &vlan, sizeof(vlan));
2331 		if (read != sizeof(vlan))
2332 			break;
2333 
2334 		id = mlx5vdpa16_to_cpu(mvdev, vlan);
2335 		if (mac_vlan_add(ndev, ndev->config.mac, id, true))
2336 			break;
2337 
2338 		status = VIRTIO_NET_OK;
2339 		break;
2340 	case VIRTIO_NET_CTRL_VLAN_DEL:
2341 		read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, &vlan, sizeof(vlan));
2342 		if (read != sizeof(vlan))
2343 			break;
2344 
2345 		id = mlx5vdpa16_to_cpu(mvdev, vlan);
2346 		mac_vlan_del(ndev, ndev->config.mac, id, true);
2347 		status = VIRTIO_NET_OK;
2348 		break;
2349 	default:
2350 		break;
2351 	}
2352 
2353 	return status;
2354 }
2355 
mlx5_cvq_kick_handler(struct work_struct * work)2356 static void mlx5_cvq_kick_handler(struct work_struct *work)
2357 {
2358 	virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
2359 	struct virtio_net_ctrl_hdr ctrl;
2360 	struct mlx5_vdpa_wq_ent *wqent;
2361 	struct mlx5_vdpa_dev *mvdev;
2362 	struct mlx5_control_vq *cvq;
2363 	struct mlx5_vdpa_net *ndev;
2364 	size_t read, write;
2365 	int err;
2366 
2367 	wqent = container_of(work, struct mlx5_vdpa_wq_ent, work);
2368 	mvdev = wqent->mvdev;
2369 	ndev = to_mlx5_vdpa_ndev(mvdev);
2370 	cvq = &mvdev->cvq;
2371 
2372 	down_write(&ndev->reslock);
2373 
2374 	if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK))
2375 		goto out;
2376 
2377 	if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
2378 		goto out;
2379 
2380 	if (!cvq->ready)
2381 		goto out;
2382 
2383 	while (true) {
2384 		err = vringh_getdesc_iotlb(&cvq->vring, &cvq->riov, &cvq->wiov, &cvq->head,
2385 					   GFP_ATOMIC);
2386 		if (err <= 0)
2387 			break;
2388 
2389 		read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, &ctrl, sizeof(ctrl));
2390 		if (read != sizeof(ctrl))
2391 			break;
2392 
2393 		cvq->received_desc++;
2394 		switch (ctrl.class) {
2395 		case VIRTIO_NET_CTRL_MAC:
2396 			status = handle_ctrl_mac(mvdev, ctrl.cmd);
2397 			break;
2398 		case VIRTIO_NET_CTRL_MQ:
2399 			status = handle_ctrl_mq(mvdev, ctrl.cmd);
2400 			break;
2401 		case VIRTIO_NET_CTRL_VLAN:
2402 			status = handle_ctrl_vlan(mvdev, ctrl.cmd);
2403 			break;
2404 		default:
2405 			break;
2406 		}
2407 
2408 		/* Make sure data is written before advancing index */
2409 		smp_wmb();
2410 
2411 		write = vringh_iov_push_iotlb(&cvq->vring, &cvq->wiov, &status, sizeof(status));
2412 		vringh_complete_iotlb(&cvq->vring, cvq->head, write);
2413 		vringh_kiov_cleanup(&cvq->riov);
2414 		vringh_kiov_cleanup(&cvq->wiov);
2415 
2416 		if (vringh_need_notify_iotlb(&cvq->vring))
2417 			vringh_notify(&cvq->vring);
2418 
2419 		cvq->completed_desc++;
2420 		queue_work(mvdev->wq, &wqent->work);
2421 		break;
2422 	}
2423 
2424 out:
2425 	up_write(&ndev->reslock);
2426 }
2427 
mlx5_vdpa_kick_vq(struct vdpa_device * vdev,u16 idx)2428 static void mlx5_vdpa_kick_vq(struct vdpa_device *vdev, u16 idx)
2429 {
2430 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2431 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2432 	struct mlx5_vdpa_virtqueue *mvq;
2433 
2434 	if (!is_index_valid(mvdev, idx))
2435 		return;
2436 
2437 	if (unlikely(is_ctrl_vq_idx(mvdev, idx))) {
2438 		if (!mvdev->wq || !mvdev->cvq.ready)
2439 			return;
2440 
2441 		queue_work(mvdev->wq, &ndev->cvq_ent.work);
2442 		return;
2443 	}
2444 
2445 	mvq = &ndev->vqs[idx];
2446 	if (unlikely(!mvq->ready))
2447 		return;
2448 
2449 	iowrite16(idx, ndev->mvdev.res.kick_addr);
2450 }
2451 
mlx5_vdpa_set_vq_address(struct vdpa_device * vdev,u16 idx,u64 desc_area,u64 driver_area,u64 device_area)2452 static int mlx5_vdpa_set_vq_address(struct vdpa_device *vdev, u16 idx, u64 desc_area,
2453 				    u64 driver_area, u64 device_area)
2454 {
2455 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2456 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2457 	struct mlx5_vdpa_virtqueue *mvq;
2458 
2459 	if (!is_index_valid(mvdev, idx))
2460 		return -EINVAL;
2461 
2462 	if (is_ctrl_vq_idx(mvdev, idx)) {
2463 		mvdev->cvq.desc_addr = desc_area;
2464 		mvdev->cvq.device_addr = device_area;
2465 		mvdev->cvq.driver_addr = driver_area;
2466 		return 0;
2467 	}
2468 
2469 	mvq = &ndev->vqs[idx];
2470 	mvq->desc_addr = desc_area;
2471 	mvq->device_addr = device_area;
2472 	mvq->driver_addr = driver_area;
2473 	mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_ADDRS;
2474 	return 0;
2475 }
2476 
mlx5_vdpa_set_vq_num(struct vdpa_device * vdev,u16 idx,u32 num)2477 static void mlx5_vdpa_set_vq_num(struct vdpa_device *vdev, u16 idx, u32 num)
2478 {
2479 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2480 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2481 	struct mlx5_vdpa_virtqueue *mvq;
2482 
2483 	if (!is_index_valid(mvdev, idx))
2484 		return;
2485 
2486         if (is_ctrl_vq_idx(mvdev, idx)) {
2487                 struct mlx5_control_vq *cvq = &mvdev->cvq;
2488 
2489                 cvq->vring.vring.num = num;
2490                 return;
2491         }
2492 
2493 	mvq = &ndev->vqs[idx];
2494 	ndev->needs_teardown = num != mvq->num_ent;
2495 	mvq->num_ent = num;
2496 }
2497 
mlx5_vdpa_set_vq_cb(struct vdpa_device * vdev,u16 idx,struct vdpa_callback * cb)2498 static void mlx5_vdpa_set_vq_cb(struct vdpa_device *vdev, u16 idx, struct vdpa_callback *cb)
2499 {
2500 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2501 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2502 
2503 	ndev->event_cbs[idx] = *cb;
2504 	if (is_ctrl_vq_idx(mvdev, idx))
2505 		mvdev->cvq.event_cb = *cb;
2506 }
2507 
mlx5_cvq_notify(struct vringh * vring)2508 static void mlx5_cvq_notify(struct vringh *vring)
2509 {
2510 	struct mlx5_control_vq *cvq = container_of(vring, struct mlx5_control_vq, vring);
2511 
2512 	if (!cvq->event_cb.callback)
2513 		return;
2514 
2515 	cvq->event_cb.callback(cvq->event_cb.private);
2516 }
2517 
set_cvq_ready(struct mlx5_vdpa_dev * mvdev,bool ready)2518 static void set_cvq_ready(struct mlx5_vdpa_dev *mvdev, bool ready)
2519 {
2520 	struct mlx5_control_vq *cvq = &mvdev->cvq;
2521 
2522 	cvq->ready = ready;
2523 	if (!ready)
2524 		return;
2525 
2526 	cvq->vring.notify = mlx5_cvq_notify;
2527 }
2528 
mlx5_vdpa_set_vq_ready(struct vdpa_device * vdev,u16 idx,bool ready)2529 static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready)
2530 {
2531 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2532 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2533 	struct mlx5_vdpa_virtqueue *mvq;
2534 
2535 	if (!mvdev->actual_features)
2536 		return;
2537 
2538 	if (!is_index_valid(mvdev, idx))
2539 		return;
2540 
2541 	if (is_ctrl_vq_idx(mvdev, idx)) {
2542 		set_cvq_ready(mvdev, ready);
2543 		return;
2544 	}
2545 
2546 	mvq = &ndev->vqs[idx];
2547 	if (!ready) {
2548 		suspend_vq(ndev, mvq);
2549 	} else if (mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) {
2550 		if (resume_vq(ndev, mvq))
2551 			ready = false;
2552 	}
2553 
2554 	mvq->ready = ready;
2555 }
2556 
mlx5_vdpa_get_vq_ready(struct vdpa_device * vdev,u16 idx)2557 static bool mlx5_vdpa_get_vq_ready(struct vdpa_device *vdev, u16 idx)
2558 {
2559 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2560 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2561 
2562 	if (!is_index_valid(mvdev, idx))
2563 		return false;
2564 
2565 	if (is_ctrl_vq_idx(mvdev, idx))
2566 		return mvdev->cvq.ready;
2567 
2568 	return ndev->vqs[idx].ready;
2569 }
2570 
mlx5_vdpa_set_vq_state(struct vdpa_device * vdev,u16 idx,const struct vdpa_vq_state * state)2571 static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx,
2572 				  const struct vdpa_vq_state *state)
2573 {
2574 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2575 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2576 	struct mlx5_vdpa_virtqueue *mvq;
2577 
2578 	if (!is_index_valid(mvdev, idx))
2579 		return -EINVAL;
2580 
2581 	if (is_ctrl_vq_idx(mvdev, idx)) {
2582 		mvdev->cvq.vring.last_avail_idx = state->split.avail_index;
2583 		return 0;
2584 	}
2585 
2586 	mvq = &ndev->vqs[idx];
2587 	if (mvq->fw_state == MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY) {
2588 		mlx5_vdpa_warn(mvdev, "can't modify available index\n");
2589 		return -EINVAL;
2590 	}
2591 
2592 	mvq->used_idx = state->split.avail_index;
2593 	mvq->avail_idx = state->split.avail_index;
2594 	mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_AVAIL_IDX |
2595 				MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_USED_IDX;
2596 	return 0;
2597 }
2598 
mlx5_vdpa_get_vq_state(struct vdpa_device * vdev,u16 idx,struct vdpa_vq_state * state)2599 static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa_vq_state *state)
2600 {
2601 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2602 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2603 	struct mlx5_vdpa_virtqueue *mvq;
2604 	struct mlx5_virtq_attr attr;
2605 	int err;
2606 
2607 	if (!is_index_valid(mvdev, idx))
2608 		return -EINVAL;
2609 
2610 	if (is_ctrl_vq_idx(mvdev, idx)) {
2611 		state->split.avail_index = mvdev->cvq.vring.last_avail_idx;
2612 		return 0;
2613 	}
2614 
2615 	mvq = &ndev->vqs[idx];
2616 	/* If the virtq object was destroyed, use the value saved at
2617 	 * the last minute of suspend_vq. This caters for userspace
2618 	 * that cares about emulating the index after vq is stopped.
2619 	 */
2620 	if (!mvq->initialized) {
2621 		/* Firmware returns a wrong value for the available index.
2622 		 * Since both values should be identical, we take the value of
2623 		 * used_idx which is reported correctly.
2624 		 */
2625 		state->split.avail_index = mvq->used_idx;
2626 		return 0;
2627 	}
2628 
2629 	err = query_virtqueues(ndev, mvq->index, 1, &attr);
2630 	if (err) {
2631 		mlx5_vdpa_err(mvdev, "failed to query virtqueue\n");
2632 		return err;
2633 	}
2634 	state->split.avail_index = attr.used_index;
2635 	return 0;
2636 }
2637 
mlx5_vdpa_get_vq_align(struct vdpa_device * vdev)2638 static u32 mlx5_vdpa_get_vq_align(struct vdpa_device *vdev)
2639 {
2640 	return PAGE_SIZE;
2641 }
2642 
mlx5_vdpa_get_vq_group(struct vdpa_device * vdev,u16 idx)2643 static u32 mlx5_vdpa_get_vq_group(struct vdpa_device *vdev, u16 idx)
2644 {
2645 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2646 
2647 	if (is_ctrl_vq_idx(mvdev, idx))
2648 		return MLX5_VDPA_CVQ_GROUP;
2649 
2650 	return MLX5_VDPA_DATAVQ_GROUP;
2651 }
2652 
mlx5_vdpa_get_vq_desc_group(struct vdpa_device * vdev,u16 idx)2653 static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
2654 {
2655 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2656 
2657 	if (is_ctrl_vq_idx(mvdev, idx))
2658 		return MLX5_VDPA_CVQ_GROUP;
2659 
2660 	return MLX5_VDPA_DATAVQ_DESC_GROUP;
2661 }
2662 
mlx_to_vritio_features(u16 dev_features)2663 static u64 mlx_to_vritio_features(u16 dev_features)
2664 {
2665 	u64 result = 0;
2666 
2667 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_MRG_RXBUF))
2668 		result |= BIT_ULL(VIRTIO_NET_F_MRG_RXBUF);
2669 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_HOST_ECN))
2670 		result |= BIT_ULL(VIRTIO_NET_F_HOST_ECN);
2671 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_GUEST_ECN))
2672 		result |= BIT_ULL(VIRTIO_NET_F_GUEST_ECN);
2673 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_GUEST_TSO6))
2674 		result |= BIT_ULL(VIRTIO_NET_F_GUEST_TSO6);
2675 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_GUEST_TSO4))
2676 		result |= BIT_ULL(VIRTIO_NET_F_GUEST_TSO4);
2677 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_GUEST_CSUM))
2678 		result |= BIT_ULL(VIRTIO_NET_F_GUEST_CSUM);
2679 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_CSUM))
2680 		result |= BIT_ULL(VIRTIO_NET_F_CSUM);
2681 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_HOST_TSO6))
2682 		result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO6);
2683 	if (dev_features & BIT_ULL(MLX5_VIRTIO_NET_F_HOST_TSO4))
2684 		result |= BIT_ULL(VIRTIO_NET_F_HOST_TSO4);
2685 
2686 	return result;
2687 }
2688 
get_supported_features(struct mlx5_core_dev * mdev)2689 static u64 get_supported_features(struct mlx5_core_dev *mdev)
2690 {
2691 	u64 mlx_vdpa_features = 0;
2692 	u16 dev_features;
2693 
2694 	dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mdev, device_features_bits_mask);
2695 	mlx_vdpa_features |= mlx_to_vritio_features(dev_features);
2696 	if (MLX5_CAP_DEV_VDPA_EMULATION(mdev, virtio_version_1_0))
2697 		mlx_vdpa_features |= BIT_ULL(VIRTIO_F_VERSION_1);
2698 	mlx_vdpa_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM);
2699 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_VQ);
2700 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR);
2701 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MQ);
2702 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_STATUS);
2703 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MTU);
2704 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_VLAN);
2705 	mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MAC);
2706 
2707 	return mlx_vdpa_features;
2708 }
2709 
mlx5_vdpa_get_device_features(struct vdpa_device * vdev)2710 static u64 mlx5_vdpa_get_device_features(struct vdpa_device *vdev)
2711 {
2712 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2713 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2714 
2715 	print_features(mvdev, ndev->mvdev.mlx_features, false);
2716 	return ndev->mvdev.mlx_features;
2717 }
2718 
verify_driver_features(struct mlx5_vdpa_dev * mvdev,u64 features)2719 static int verify_driver_features(struct mlx5_vdpa_dev *mvdev, u64 features)
2720 {
2721 	/* Minimum features to expect */
2722 	if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)))
2723 		return -EOPNOTSUPP;
2724 
2725 	/* Double check features combination sent down by the driver.
2726 	 * Fail invalid features due to absence of the depended feature.
2727 	 *
2728 	 * Per VIRTIO v1.1 specification, section 5.1.3.1 Feature bit
2729 	 * requirements: "VIRTIO_NET_F_MQ Requires VIRTIO_NET_F_CTRL_VQ".
2730 	 * By failing the invalid features sent down by untrusted drivers,
2731 	 * we're assured the assumption made upon is_index_valid() and
2732 	 * is_ctrl_vq_idx() will not be compromised.
2733 	 */
2734 	if ((features & (BIT_ULL(VIRTIO_NET_F_MQ) | BIT_ULL(VIRTIO_NET_F_CTRL_VQ))) ==
2735             BIT_ULL(VIRTIO_NET_F_MQ))
2736 		return -EINVAL;
2737 
2738 	return 0;
2739 }
2740 
setup_virtqueues(struct mlx5_vdpa_dev * mvdev,bool filled)2741 static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev, bool filled)
2742 {
2743 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2744 	int err;
2745 	int i;
2746 
2747 	for (i = 0; i < mvdev->max_vqs; i++) {
2748 		err = setup_vq(ndev, &ndev->vqs[i], filled);
2749 		if (err)
2750 			goto err_vq;
2751 	}
2752 
2753 	return 0;
2754 
2755 err_vq:
2756 	for (--i; i >= 0; i--)
2757 		teardown_vq(ndev, &ndev->vqs[i]);
2758 
2759 	return err;
2760 }
2761 
teardown_virtqueues(struct mlx5_vdpa_net * ndev)2762 static void teardown_virtqueues(struct mlx5_vdpa_net *ndev)
2763 {
2764 	int i;
2765 
2766 	for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--)
2767 		teardown_vq(ndev, &ndev->vqs[i]);
2768 }
2769 
update_cvq_info(struct mlx5_vdpa_dev * mvdev)2770 static void update_cvq_info(struct mlx5_vdpa_dev *mvdev)
2771 {
2772 	if (MLX5_FEATURE(mvdev, VIRTIO_NET_F_CTRL_VQ)) {
2773 		if (MLX5_FEATURE(mvdev, VIRTIO_NET_F_MQ)) {
2774 			/* MQ supported. CVQ index is right above the last data virtqueue's */
2775 			mvdev->max_idx = mvdev->max_vqs;
2776 		} else {
2777 			/* Only CVQ supportted. data virtqueues occupy indices 0 and 1.
2778 			 * CVQ gets index 2
2779 			 */
2780 			mvdev->max_idx = 2;
2781 		}
2782 	} else {
2783 		/* Two data virtqueues only: one for rx and one for tx */
2784 		mvdev->max_idx = 1;
2785 	}
2786 }
2787 
query_vport_state(struct mlx5_core_dev * mdev,u8 opmod,u16 vport)2788 static u8 query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
2789 {
2790 	u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {};
2791 	u32 in[MLX5_ST_SZ_DW(query_vport_state_in)] = {};
2792 	int err;
2793 
2794 	MLX5_SET(query_vport_state_in, in, opcode, MLX5_CMD_OP_QUERY_VPORT_STATE);
2795 	MLX5_SET(query_vport_state_in, in, op_mod, opmod);
2796 	MLX5_SET(query_vport_state_in, in, vport_number, vport);
2797 	if (vport)
2798 		MLX5_SET(query_vport_state_in, in, other_vport, 1);
2799 
2800 	err = mlx5_cmd_exec_inout(mdev, query_vport_state, in, out);
2801 	if (err)
2802 		return 0;
2803 
2804 	return MLX5_GET(query_vport_state_out, out, state);
2805 }
2806 
get_link_state(struct mlx5_vdpa_dev * mvdev)2807 static bool get_link_state(struct mlx5_vdpa_dev *mvdev)
2808 {
2809 	if (query_vport_state(mvdev->mdev, MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT, 0) ==
2810 	    VPORT_STATE_UP)
2811 		return true;
2812 
2813 	return false;
2814 }
2815 
update_carrier(struct work_struct * work)2816 static void update_carrier(struct work_struct *work)
2817 {
2818 	struct mlx5_vdpa_wq_ent *wqent;
2819 	struct mlx5_vdpa_dev *mvdev;
2820 	struct mlx5_vdpa_net *ndev;
2821 
2822 	wqent = container_of(work, struct mlx5_vdpa_wq_ent, work);
2823 	mvdev = wqent->mvdev;
2824 	ndev = to_mlx5_vdpa_ndev(mvdev);
2825 	if (get_link_state(mvdev))
2826 		ndev->config.status |= cpu_to_mlx5vdpa16(mvdev, VIRTIO_NET_S_LINK_UP);
2827 	else
2828 		ndev->config.status &= cpu_to_mlx5vdpa16(mvdev, ~VIRTIO_NET_S_LINK_UP);
2829 
2830 	if (ndev->config_cb.callback)
2831 		ndev->config_cb.callback(ndev->config_cb.private);
2832 
2833 	kfree(wqent);
2834 }
2835 
queue_link_work(struct mlx5_vdpa_net * ndev)2836 static int queue_link_work(struct mlx5_vdpa_net *ndev)
2837 {
2838 	struct mlx5_vdpa_wq_ent *wqent;
2839 
2840 	wqent = kzalloc(sizeof(*wqent), GFP_ATOMIC);
2841 	if (!wqent)
2842 		return -ENOMEM;
2843 
2844 	wqent->mvdev = &ndev->mvdev;
2845 	INIT_WORK(&wqent->work, update_carrier);
2846 	queue_work(ndev->mvdev.wq, &wqent->work);
2847 	return 0;
2848 }
2849 
event_handler(struct notifier_block * nb,unsigned long event,void * param)2850 static int event_handler(struct notifier_block *nb, unsigned long event, void *param)
2851 {
2852 	struct mlx5_vdpa_net *ndev = container_of(nb, struct mlx5_vdpa_net, nb);
2853 	struct mlx5_eqe *eqe = param;
2854 	int ret = NOTIFY_DONE;
2855 
2856 	if (ndev->mvdev.suspended)
2857 		return NOTIFY_DONE;
2858 
2859 	if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
2860 		switch (eqe->sub_type) {
2861 		case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
2862 		case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
2863 			if (queue_link_work(ndev))
2864 				return NOTIFY_DONE;
2865 
2866 			ret = NOTIFY_OK;
2867 			break;
2868 		default:
2869 			return NOTIFY_DONE;
2870 		}
2871 		return ret;
2872 	}
2873 	return ret;
2874 }
2875 
register_link_notifier(struct mlx5_vdpa_net * ndev)2876 static void register_link_notifier(struct mlx5_vdpa_net *ndev)
2877 {
2878 	if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_STATUS)))
2879 		return;
2880 
2881 	ndev->nb.notifier_call = event_handler;
2882 	mlx5_notifier_register(ndev->mvdev.mdev, &ndev->nb);
2883 	ndev->nb_registered = true;
2884 	queue_link_work(ndev);
2885 }
2886 
unregister_link_notifier(struct mlx5_vdpa_net * ndev)2887 static void unregister_link_notifier(struct mlx5_vdpa_net *ndev)
2888 {
2889 	if (!ndev->nb_registered)
2890 		return;
2891 
2892 	ndev->nb_registered = false;
2893 	mlx5_notifier_unregister(ndev->mvdev.mdev, &ndev->nb);
2894 	if (ndev->mvdev.wq)
2895 		flush_workqueue(ndev->mvdev.wq);
2896 }
2897 
mlx5_vdpa_get_backend_features(const struct vdpa_device * vdpa)2898 static u64 mlx5_vdpa_get_backend_features(const struct vdpa_device *vdpa)
2899 {
2900 	return BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK);
2901 }
2902 
mlx5_vdpa_set_driver_features(struct vdpa_device * vdev,u64 features)2903 static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features)
2904 {
2905 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2906 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2907 	u64 old_features = mvdev->actual_features;
2908 	u64 diff_features;
2909 	int err;
2910 
2911 	print_features(mvdev, features, true);
2912 
2913 	err = verify_driver_features(mvdev, features);
2914 	if (err)
2915 		return err;
2916 
2917 	ndev->mvdev.actual_features = features & ndev->mvdev.mlx_features;
2918 
2919 	/* Interested in changes of vq features only. */
2920 	if (get_features(old_features) != get_features(mvdev->actual_features)) {
2921 		for (int i = 0; i < mvdev->max_vqs; ++i) {
2922 			struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[i];
2923 
2924 			mvq->modified_fields |= (
2925 				MLX5_VIRTQ_MODIFY_MASK_QUEUE_VIRTIO_VERSION |
2926 				MLX5_VIRTQ_MODIFY_MASK_QUEUE_FEATURES
2927 			);
2928 		}
2929 	}
2930 
2931 	/* When below features diverge from initial device features, VQs need a full teardown. */
2932 #define NEEDS_TEARDOWN_MASK (BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | \
2933 			     BIT_ULL(VIRTIO_NET_F_CSUM) | \
2934 			     BIT_ULL(VIRTIO_F_VERSION_1))
2935 
2936 	diff_features = mvdev->mlx_features ^ mvdev->actual_features;
2937 	ndev->needs_teardown = !!(diff_features & NEEDS_TEARDOWN_MASK);
2938 
2939 	update_cvq_info(mvdev);
2940 	return err;
2941 }
2942 
mlx5_vdpa_set_config_cb(struct vdpa_device * vdev,struct vdpa_callback * cb)2943 static void mlx5_vdpa_set_config_cb(struct vdpa_device *vdev, struct vdpa_callback *cb)
2944 {
2945 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2946 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2947 
2948 	ndev->config_cb = *cb;
2949 }
2950 
2951 #define MLX5_VDPA_MAX_VQ_ENTRIES 256
mlx5_vdpa_get_vq_num_max(struct vdpa_device * vdev)2952 static u16 mlx5_vdpa_get_vq_num_max(struct vdpa_device *vdev)
2953 {
2954 	return MLX5_VDPA_MAX_VQ_ENTRIES;
2955 }
2956 
mlx5_vdpa_get_device_id(struct vdpa_device * vdev)2957 static u32 mlx5_vdpa_get_device_id(struct vdpa_device *vdev)
2958 {
2959 	return VIRTIO_ID_NET;
2960 }
2961 
mlx5_vdpa_get_vendor_id(struct vdpa_device * vdev)2962 static u32 mlx5_vdpa_get_vendor_id(struct vdpa_device *vdev)
2963 {
2964 	return PCI_VENDOR_ID_MELLANOX;
2965 }
2966 
mlx5_vdpa_get_status(struct vdpa_device * vdev)2967 static u8 mlx5_vdpa_get_status(struct vdpa_device *vdev)
2968 {
2969 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2970 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2971 
2972 	print_status(mvdev, ndev->mvdev.status, false);
2973 	return ndev->mvdev.status;
2974 }
2975 
save_channel_info(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq)2976 static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
2977 {
2978 	struct mlx5_vq_restore_info *ri = &mvq->ri;
2979 	struct mlx5_virtq_attr attr = {};
2980 	int err;
2981 
2982 	if (mvq->initialized) {
2983 		err = query_virtqueues(ndev, mvq->index, 1, &attr);
2984 		if (err)
2985 			return err;
2986 	}
2987 
2988 	ri->avail_index = attr.available_index;
2989 	ri->used_index = attr.used_index;
2990 	ri->ready = mvq->ready;
2991 	ri->num_ent = mvq->num_ent;
2992 	ri->desc_addr = mvq->desc_addr;
2993 	ri->device_addr = mvq->device_addr;
2994 	ri->driver_addr = mvq->driver_addr;
2995 	ri->map = mvq->map;
2996 	ri->restore = true;
2997 	return 0;
2998 }
2999 
save_channels_info(struct mlx5_vdpa_net * ndev)3000 static int save_channels_info(struct mlx5_vdpa_net *ndev)
3001 {
3002 	int i;
3003 
3004 	for (i = 0; i < ndev->mvdev.max_vqs; i++) {
3005 		memset(&ndev->vqs[i].ri, 0, sizeof(ndev->vqs[i].ri));
3006 		save_channel_info(ndev, &ndev->vqs[i]);
3007 	}
3008 	return 0;
3009 }
3010 
mlx5_clear_vqs(struct mlx5_vdpa_net * ndev)3011 static void mlx5_clear_vqs(struct mlx5_vdpa_net *ndev)
3012 {
3013 	int i;
3014 
3015 	for (i = 0; i < ndev->mvdev.max_vqs; i++)
3016 		memset(&ndev->vqs[i], 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
3017 }
3018 
restore_channels_info(struct mlx5_vdpa_net * ndev)3019 static void restore_channels_info(struct mlx5_vdpa_net *ndev)
3020 {
3021 	struct mlx5_vdpa_virtqueue *mvq;
3022 	struct mlx5_vq_restore_info *ri;
3023 	int i;
3024 
3025 	mlx5_clear_vqs(ndev);
3026 	mvqs_set_defaults(ndev);
3027 	for (i = 0; i < ndev->mvdev.max_vqs; i++) {
3028 		mvq = &ndev->vqs[i];
3029 		ri = &mvq->ri;
3030 		if (!ri->restore)
3031 			continue;
3032 
3033 		mvq->avail_idx = ri->avail_index;
3034 		mvq->used_idx = ri->used_index;
3035 		mvq->ready = ri->ready;
3036 		mvq->num_ent = ri->num_ent;
3037 		mvq->desc_addr = ri->desc_addr;
3038 		mvq->device_addr = ri->device_addr;
3039 		mvq->driver_addr = ri->driver_addr;
3040 		mvq->map = ri->map;
3041 	}
3042 }
3043 
mlx5_vdpa_change_map(struct mlx5_vdpa_dev * mvdev,struct mlx5_vdpa_mr * new_mr,unsigned int asid)3044 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
3045 				struct mlx5_vdpa_mr *new_mr,
3046 				unsigned int asid)
3047 {
3048 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3049 	bool teardown = !is_resumable(ndev);
3050 	int err;
3051 
3052 	suspend_vqs(ndev, 0, ndev->cur_num_vqs);
3053 	if (teardown) {
3054 		err = save_channels_info(ndev);
3055 		if (err)
3056 			return err;
3057 
3058 		teardown_vq_resources(ndev);
3059 	}
3060 
3061 	mlx5_vdpa_update_mr(mvdev, new_mr, asid);
3062 
3063 	for (int i = 0; i < mvdev->max_vqs; i++)
3064 		ndev->vqs[i].modified_fields |= MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY |
3065 						MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY;
3066 
3067 	if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)
3068 		return 0;
3069 
3070 	if (teardown) {
3071 		restore_channels_info(ndev);
3072 		err = setup_vq_resources(ndev, true);
3073 		if (err)
3074 			return err;
3075 	}
3076 
3077 	resume_vqs(ndev, 0, ndev->cur_num_vqs);
3078 
3079 	return 0;
3080 }
3081 
3082 /* reslock must be held for this function */
setup_vq_resources(struct mlx5_vdpa_net * ndev,bool filled)3083 static int setup_vq_resources(struct mlx5_vdpa_net *ndev, bool filled)
3084 {
3085 	struct mlx5_vdpa_dev *mvdev = &ndev->mvdev;
3086 	int err;
3087 
3088 	WARN_ON(!rwsem_is_locked(&ndev->reslock));
3089 
3090 	if (ndev->setup) {
3091 		mlx5_vdpa_warn(mvdev, "setup driver called for already setup driver\n");
3092 		err = 0;
3093 		goto out;
3094 	}
3095 	mlx5_vdpa_add_debugfs(ndev);
3096 
3097 	err = read_umem_params(ndev);
3098 	if (err)
3099 		goto err_setup;
3100 
3101 	err = setup_virtqueues(mvdev, filled);
3102 	if (err) {
3103 		mlx5_vdpa_warn(mvdev, "setup_virtqueues\n");
3104 		goto err_setup;
3105 	}
3106 
3107 	err = create_rqt(ndev);
3108 	if (err) {
3109 		mlx5_vdpa_warn(mvdev, "create_rqt\n");
3110 		goto err_rqt;
3111 	}
3112 
3113 	err = create_tir(ndev);
3114 	if (err) {
3115 		mlx5_vdpa_warn(mvdev, "create_tir\n");
3116 		goto err_tir;
3117 	}
3118 
3119 	err = setup_steering(ndev);
3120 	if (err) {
3121 		mlx5_vdpa_warn(mvdev, "setup_steering\n");
3122 		goto err_fwd;
3123 	}
3124 	ndev->setup = true;
3125 
3126 	return 0;
3127 
3128 err_fwd:
3129 	destroy_tir(ndev);
3130 err_tir:
3131 	destroy_rqt(ndev);
3132 err_rqt:
3133 	teardown_virtqueues(ndev);
3134 err_setup:
3135 	mlx5_vdpa_remove_debugfs(ndev);
3136 out:
3137 	return err;
3138 }
3139 
3140 /* reslock must be held for this function */
teardown_vq_resources(struct mlx5_vdpa_net * ndev)3141 static void teardown_vq_resources(struct mlx5_vdpa_net *ndev)
3142 {
3143 
3144 	WARN_ON(!rwsem_is_locked(&ndev->reslock));
3145 
3146 	if (!ndev->setup)
3147 		return;
3148 
3149 	mlx5_vdpa_remove_debugfs(ndev);
3150 	teardown_steering(ndev);
3151 	destroy_tir(ndev);
3152 	destroy_rqt(ndev);
3153 	teardown_virtqueues(ndev);
3154 	ndev->setup = false;
3155 	ndev->needs_teardown = false;
3156 }
3157 
setup_cvq_vring(struct mlx5_vdpa_dev * mvdev)3158 static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev)
3159 {
3160 	struct mlx5_control_vq *cvq = &mvdev->cvq;
3161 	int err = 0;
3162 
3163 	if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) {
3164 		u16 idx = cvq->vring.last_avail_idx;
3165 
3166 		err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features,
3167 					cvq->vring.vring.num, false,
3168 					(struct vring_desc *)(uintptr_t)cvq->desc_addr,
3169 					(struct vring_avail *)(uintptr_t)cvq->driver_addr,
3170 					(struct vring_used *)(uintptr_t)cvq->device_addr);
3171 
3172 		if (!err)
3173 			cvq->vring.last_avail_idx = cvq->vring.last_used_idx = idx;
3174 	}
3175 	return err;
3176 }
3177 
mlx5_vdpa_set_status(struct vdpa_device * vdev,u8 status)3178 static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
3179 {
3180 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3181 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3182 	int err;
3183 
3184 	print_status(mvdev, status, true);
3185 
3186 	down_write(&ndev->reslock);
3187 
3188 	if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
3189 		if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
3190 			err = setup_cvq_vring(mvdev);
3191 			if (err) {
3192 				mlx5_vdpa_warn(mvdev, "failed to setup control VQ vring\n");
3193 				goto err_setup;
3194 			}
3195 			register_link_notifier(ndev);
3196 
3197 			if (ndev->needs_teardown)
3198 				teardown_vq_resources(ndev);
3199 
3200 			if (ndev->setup) {
3201 				err = resume_vqs(ndev, 0, ndev->cur_num_vqs);
3202 				if (err) {
3203 					mlx5_vdpa_warn(mvdev, "failed to resume VQs\n");
3204 					goto err_driver;
3205 				}
3206 			} else {
3207 				err = setup_vq_resources(ndev, true);
3208 				if (err) {
3209 					mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
3210 					goto err_driver;
3211 				}
3212 			}
3213 		} else {
3214 			mlx5_vdpa_warn(mvdev, "did not expect DRIVER_OK to be cleared\n");
3215 			goto err_clear;
3216 		}
3217 	}
3218 
3219 	ndev->mvdev.status = status;
3220 	up_write(&ndev->reslock);
3221 	return;
3222 
3223 err_driver:
3224 	unregister_link_notifier(ndev);
3225 err_setup:
3226 	mlx5_vdpa_clean_mrs(&ndev->mvdev);
3227 	ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
3228 err_clear:
3229 	up_write(&ndev->reslock);
3230 }
3231 
init_group_to_asid_map(struct mlx5_vdpa_dev * mvdev)3232 static void init_group_to_asid_map(struct mlx5_vdpa_dev *mvdev)
3233 {
3234 	int i;
3235 
3236 	/* default mapping all groups are mapped to asid 0 */
3237 	for (i = 0; i < MLX5_VDPA_NUMVQ_GROUPS; i++)
3238 		mvdev->mres.group2asid[i] = 0;
3239 }
3240 
needs_vqs_reset(const struct mlx5_vdpa_dev * mvdev)3241 static bool needs_vqs_reset(const struct mlx5_vdpa_dev *mvdev)
3242 {
3243 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3244 	struct mlx5_vdpa_virtqueue *mvq = &ndev->vqs[0];
3245 
3246 	if (mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK)
3247 		return true;
3248 
3249 	if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_INIT)
3250 		return true;
3251 
3252 	return mvq->modified_fields & (
3253 		MLX5_VIRTQ_MODIFY_MASK_STATE |
3254 		MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_ADDRS |
3255 		MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_AVAIL_IDX |
3256 		MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_USED_IDX
3257 	);
3258 }
3259 
mlx5_vdpa_compat_reset(struct vdpa_device * vdev,u32 flags)3260 static int mlx5_vdpa_compat_reset(struct vdpa_device *vdev, u32 flags)
3261 {
3262 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3263 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3264 	bool vq_reset;
3265 
3266 	print_status(mvdev, 0, true);
3267 	mlx5_vdpa_info(mvdev, "performing device reset\n");
3268 
3269 	down_write(&ndev->reslock);
3270 	unregister_link_notifier(ndev);
3271 	vq_reset = needs_vqs_reset(mvdev);
3272 	if (vq_reset) {
3273 		teardown_vq_resources(ndev);
3274 		mvqs_set_defaults(ndev);
3275 	}
3276 
3277 	if (flags & VDPA_RESET_F_CLEAN_MAP)
3278 		mlx5_vdpa_clean_mrs(&ndev->mvdev);
3279 	ndev->mvdev.status = 0;
3280 	ndev->mvdev.suspended = false;
3281 	ndev->cur_num_vqs = MLX5V_DEFAULT_VQ_COUNT;
3282 	ndev->mvdev.cvq.ready = false;
3283 	ndev->mvdev.cvq.received_desc = 0;
3284 	ndev->mvdev.cvq.completed_desc = 0;
3285 	memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs + 1));
3286 	ndev->mvdev.actual_features = 0;
3287 	init_group_to_asid_map(mvdev);
3288 	++mvdev->generation;
3289 
3290 	if ((flags & VDPA_RESET_F_CLEAN_MAP) &&
3291 	    MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
3292 		if (mlx5_vdpa_create_dma_mr(mvdev))
3293 			mlx5_vdpa_err(mvdev, "create MR failed\n");
3294 	}
3295 	if (vq_reset)
3296 		setup_vq_resources(ndev, false);
3297 	up_write(&ndev->reslock);
3298 
3299 	return 0;
3300 }
3301 
mlx5_vdpa_reset(struct vdpa_device * vdev)3302 static int mlx5_vdpa_reset(struct vdpa_device *vdev)
3303 {
3304 	return mlx5_vdpa_compat_reset(vdev, 0);
3305 }
3306 
mlx5_vdpa_get_config_size(struct vdpa_device * vdev)3307 static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev)
3308 {
3309 	return sizeof(struct virtio_net_config);
3310 }
3311 
mlx5_vdpa_get_config(struct vdpa_device * vdev,unsigned int offset,void * buf,unsigned int len)3312 static void mlx5_vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf,
3313 				 unsigned int len)
3314 {
3315 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3316 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3317 
3318 	if (offset + len <= sizeof(struct virtio_net_config))
3319 		memcpy(buf, (u8 *)&ndev->config + offset, len);
3320 }
3321 
mlx5_vdpa_set_config(struct vdpa_device * vdev,unsigned int offset,const void * buf,unsigned int len)3322 static void mlx5_vdpa_set_config(struct vdpa_device *vdev, unsigned int offset, const void *buf,
3323 				 unsigned int len)
3324 {
3325 	/* not supported */
3326 }
3327 
mlx5_vdpa_get_generation(struct vdpa_device * vdev)3328 static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
3329 {
3330 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3331 
3332 	return mvdev->generation;
3333 }
3334 
set_map_data(struct mlx5_vdpa_dev * mvdev,struct vhost_iotlb * iotlb,unsigned int asid)3335 static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
3336 			unsigned int asid)
3337 {
3338 	struct mlx5_vdpa_mr *new_mr;
3339 	int err;
3340 
3341 	if (asid >= MLX5_VDPA_NUM_AS)
3342 		return -EINVAL;
3343 
3344 	if (vhost_iotlb_itree_first(iotlb, 0, U64_MAX)) {
3345 		new_mr = mlx5_vdpa_create_mr(mvdev, iotlb);
3346 		if (IS_ERR(new_mr)) {
3347 			err = PTR_ERR(new_mr);
3348 			mlx5_vdpa_err(mvdev, "create map failed(%d)\n", err);
3349 			return err;
3350 		}
3351 	} else {
3352 		/* Empty iotlbs don't have an mr but will clear the previous mr. */
3353 		new_mr = NULL;
3354 	}
3355 
3356 	if (!mvdev->mres.mr[asid]) {
3357 		mlx5_vdpa_update_mr(mvdev, new_mr, asid);
3358 	} else {
3359 		err = mlx5_vdpa_change_map(mvdev, new_mr, asid);
3360 		if (err) {
3361 			mlx5_vdpa_err(mvdev, "change map failed(%d)\n", err);
3362 			goto out_err;
3363 		}
3364 	}
3365 
3366 	return mlx5_vdpa_update_cvq_iotlb(mvdev, iotlb, asid);
3367 
3368 out_err:
3369 	mlx5_vdpa_put_mr(mvdev, new_mr);
3370 	return err;
3371 }
3372 
mlx5_vdpa_set_map(struct vdpa_device * vdev,unsigned int asid,struct vhost_iotlb * iotlb)3373 static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,
3374 			     struct vhost_iotlb *iotlb)
3375 {
3376 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3377 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3378 	int err = -EINVAL;
3379 
3380 	down_write(&ndev->reslock);
3381 	err = set_map_data(mvdev, iotlb, asid);
3382 	up_write(&ndev->reslock);
3383 	return err;
3384 }
3385 
mlx5_vdpa_reset_map(struct vdpa_device * vdev,unsigned int asid)3386 static int mlx5_vdpa_reset_map(struct vdpa_device *vdev, unsigned int asid)
3387 {
3388 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3389 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3390 	int err;
3391 
3392 	down_write(&ndev->reslock);
3393 	err = mlx5_vdpa_reset_mr(mvdev, asid);
3394 	up_write(&ndev->reslock);
3395 	return err;
3396 }
3397 
mlx5_get_vq_dma_dev(struct vdpa_device * vdev,u16 idx)3398 static struct device *mlx5_get_vq_dma_dev(struct vdpa_device *vdev, u16 idx)
3399 {
3400 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3401 
3402 	if (is_ctrl_vq_idx(mvdev, idx))
3403 		return &vdev->dev;
3404 
3405 	return mvdev->vdev.dma_dev;
3406 }
3407 
free_irqs(struct mlx5_vdpa_net * ndev)3408 static void free_irqs(struct mlx5_vdpa_net *ndev)
3409 {
3410 	struct mlx5_vdpa_irq_pool_entry *ent;
3411 	int i;
3412 
3413 	if (!msix_mode_supported(&ndev->mvdev))
3414 		return;
3415 
3416 	if (!ndev->irqp.entries)
3417 		return;
3418 
3419 	for (i = ndev->irqp.num_ent - 1; i >= 0; i--) {
3420 		ent = ndev->irqp.entries + i;
3421 		if (ent->map.virq)
3422 			pci_msix_free_irq(ndev->mvdev.mdev->pdev, ent->map);
3423 	}
3424 	kfree(ndev->irqp.entries);
3425 }
3426 
mlx5_vdpa_free(struct vdpa_device * vdev)3427 static void mlx5_vdpa_free(struct vdpa_device *vdev)
3428 {
3429 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3430 	struct mlx5_core_dev *pfmdev;
3431 	struct mlx5_vdpa_net *ndev;
3432 
3433 	ndev = to_mlx5_vdpa_ndev(mvdev);
3434 
3435 	free_fixed_resources(ndev);
3436 	mlx5_vdpa_clean_mrs(mvdev);
3437 	mlx5_vdpa_destroy_mr_resources(&ndev->mvdev);
3438 	mlx5_cmd_cleanup_async_ctx(&mvdev->async_ctx);
3439 
3440 	if (!is_zero_ether_addr(ndev->config.mac)) {
3441 		pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
3442 		mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
3443 	}
3444 	mlx5_vdpa_free_resources(&ndev->mvdev);
3445 	free_irqs(ndev);
3446 	kfree(ndev->event_cbs);
3447 	kfree(ndev->vqs);
3448 }
3449 
mlx5_get_vq_notification(struct vdpa_device * vdev,u16 idx)3450 static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)
3451 {
3452 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3453 	struct vdpa_notification_area ret = {};
3454 	struct mlx5_vdpa_net *ndev;
3455 	phys_addr_t addr;
3456 
3457 	if (!is_index_valid(mvdev, idx) || is_ctrl_vq_idx(mvdev, idx))
3458 		return ret;
3459 
3460 	/* If SF BAR size is smaller than PAGE_SIZE, do not use direct
3461 	 * notification to avoid the risk of mapping pages that contain BAR of more
3462 	 * than one SF
3463 	 */
3464 	if (MLX5_CAP_GEN(mvdev->mdev, log_min_sf_size) + 12 < PAGE_SHIFT)
3465 		return ret;
3466 
3467 	ndev = to_mlx5_vdpa_ndev(mvdev);
3468 	addr = (phys_addr_t)ndev->mvdev.res.phys_kick_addr;
3469 	ret.addr = addr;
3470 	ret.size = PAGE_SIZE;
3471 	return ret;
3472 }
3473 
mlx5_get_vq_irq(struct vdpa_device * vdev,u16 idx)3474 static int mlx5_get_vq_irq(struct vdpa_device *vdev, u16 idx)
3475 {
3476 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3477 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3478 	struct mlx5_vdpa_virtqueue *mvq;
3479 
3480 	if (!is_index_valid(mvdev, idx))
3481 		return -EINVAL;
3482 
3483 	if (is_ctrl_vq_idx(mvdev, idx))
3484 		return -EOPNOTSUPP;
3485 
3486 	mvq = &ndev->vqs[idx];
3487 	if (!mvq->map.virq)
3488 		return -EOPNOTSUPP;
3489 
3490 	return mvq->map.virq;
3491 }
3492 
mlx5_vdpa_get_driver_features(struct vdpa_device * vdev)3493 static u64 mlx5_vdpa_get_driver_features(struct vdpa_device *vdev)
3494 {
3495 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3496 
3497 	return mvdev->actual_features;
3498 }
3499 
counter_set_query(struct mlx5_vdpa_net * ndev,struct mlx5_vdpa_virtqueue * mvq,u64 * received_desc,u64 * completed_desc)3500 static int counter_set_query(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
3501 			     u64 *received_desc, u64 *completed_desc)
3502 {
3503 	u32 in[MLX5_ST_SZ_DW(query_virtio_q_counters_in)] = {};
3504 	u32 out[MLX5_ST_SZ_DW(query_virtio_q_counters_out)] = {};
3505 	void *cmd_hdr;
3506 	void *ctx;
3507 	int err;
3508 
3509 	if (!counters_supported(&ndev->mvdev))
3510 		return -EOPNOTSUPP;
3511 
3512 	if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY)
3513 		return -EAGAIN;
3514 
3515 	cmd_hdr = MLX5_ADDR_OF(query_virtio_q_counters_in, in, hdr);
3516 
3517 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
3518 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_type, MLX5_OBJ_TYPE_VIRTIO_Q_COUNTERS);
3519 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid);
3520 	MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, obj_id, mvq->counter_set_id);
3521 
3522 	err = mlx5_cmd_exec(ndev->mvdev.mdev, in, sizeof(in), out, sizeof(out));
3523 	if (err)
3524 		return err;
3525 
3526 	ctx = MLX5_ADDR_OF(query_virtio_q_counters_out, out, counters);
3527 	*received_desc = MLX5_GET64(virtio_q_counters, ctx, received_desc);
3528 	*completed_desc = MLX5_GET64(virtio_q_counters, ctx, completed_desc);
3529 	return 0;
3530 }
3531 
mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device * vdev,u16 idx,struct sk_buff * msg,struct netlink_ext_ack * extack)3532 static int mlx5_vdpa_get_vendor_vq_stats(struct vdpa_device *vdev, u16 idx,
3533 					 struct sk_buff *msg,
3534 					 struct netlink_ext_ack *extack)
3535 {
3536 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3537 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3538 	struct mlx5_vdpa_virtqueue *mvq;
3539 	struct mlx5_control_vq *cvq;
3540 	u64 received_desc;
3541 	u64 completed_desc;
3542 	int err = 0;
3543 
3544 	down_read(&ndev->reslock);
3545 	if (!is_index_valid(mvdev, idx)) {
3546 		NL_SET_ERR_MSG_MOD(extack, "virtqueue index is not valid");
3547 		err = -EINVAL;
3548 		goto out_err;
3549 	}
3550 
3551 	if (idx == ctrl_vq_idx(mvdev)) {
3552 		cvq = &mvdev->cvq;
3553 		received_desc = cvq->received_desc;
3554 		completed_desc = cvq->completed_desc;
3555 		goto out;
3556 	}
3557 
3558 	mvq = &ndev->vqs[idx];
3559 	err = counter_set_query(ndev, mvq, &received_desc, &completed_desc);
3560 	if (err) {
3561 		NL_SET_ERR_MSG_MOD(extack, "failed to query hardware");
3562 		goto out_err;
3563 	}
3564 
3565 out:
3566 	err = -EMSGSIZE;
3567 	if (nla_put_string(msg, VDPA_ATTR_DEV_VENDOR_ATTR_NAME, "received_desc"))
3568 		goto out_err;
3569 
3570 	if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_VENDOR_ATTR_VALUE, received_desc,
3571 			      VDPA_ATTR_PAD))
3572 		goto out_err;
3573 
3574 	if (nla_put_string(msg, VDPA_ATTR_DEV_VENDOR_ATTR_NAME, "completed_desc"))
3575 		goto out_err;
3576 
3577 	if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_VENDOR_ATTR_VALUE, completed_desc,
3578 			      VDPA_ATTR_PAD))
3579 		goto out_err;
3580 
3581 	err = 0;
3582 out_err:
3583 	up_read(&ndev->reslock);
3584 	return err;
3585 }
3586 
mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev * mvdev)3587 static void mlx5_vdpa_cvq_suspend(struct mlx5_vdpa_dev *mvdev)
3588 {
3589 	struct mlx5_control_vq *cvq;
3590 
3591 	if (!(mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)))
3592 		return;
3593 
3594 	cvq = &mvdev->cvq;
3595 	cvq->ready = false;
3596 }
3597 
mlx5_vdpa_suspend(struct vdpa_device * vdev)3598 static int mlx5_vdpa_suspend(struct vdpa_device *vdev)
3599 {
3600 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3601 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
3602 	int err;
3603 
3604 	mlx5_vdpa_info(mvdev, "suspending device\n");
3605 
3606 	down_write(&ndev->reslock);
3607 	err = suspend_vqs(ndev, 0, ndev->cur_num_vqs);
3608 	mlx5_vdpa_cvq_suspend(mvdev);
3609 	mvdev->suspended = true;
3610 	up_write(&ndev->reslock);
3611 
3612 	return err;
3613 }
3614 
mlx5_vdpa_resume(struct vdpa_device * vdev)3615 static int mlx5_vdpa_resume(struct vdpa_device *vdev)
3616 {
3617 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3618 	struct mlx5_vdpa_net *ndev;
3619 	int err;
3620 
3621 	ndev = to_mlx5_vdpa_ndev(mvdev);
3622 
3623 	mlx5_vdpa_info(mvdev, "resuming device\n");
3624 
3625 	down_write(&ndev->reslock);
3626 	mvdev->suspended = false;
3627 	err = resume_vqs(ndev, 0, ndev->cur_num_vqs);
3628 	queue_link_work(ndev);
3629 	up_write(&ndev->reslock);
3630 
3631 	return err;
3632 }
3633 
mlx5_set_group_asid(struct vdpa_device * vdev,u32 group,unsigned int asid)3634 static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group,
3635 			       unsigned int asid)
3636 {
3637 	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
3638 	int err = 0;
3639 
3640 	if (group >= MLX5_VDPA_NUMVQ_GROUPS)
3641 		return -EINVAL;
3642 
3643 	mvdev->mres.group2asid[group] = asid;
3644 
3645 	mutex_lock(&mvdev->mres.lock);
3646 	if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mres.mr[asid])
3647 		err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mres.mr[asid]->iotlb, asid);
3648 	mutex_unlock(&mvdev->mres.lock);
3649 
3650 	return err;
3651 }
3652 
3653 static const struct vdpa_config_ops mlx5_vdpa_ops = {
3654 	.set_vq_address = mlx5_vdpa_set_vq_address,
3655 	.set_vq_num = mlx5_vdpa_set_vq_num,
3656 	.kick_vq = mlx5_vdpa_kick_vq,
3657 	.set_vq_cb = mlx5_vdpa_set_vq_cb,
3658 	.set_vq_ready = mlx5_vdpa_set_vq_ready,
3659 	.get_vq_ready = mlx5_vdpa_get_vq_ready,
3660 	.set_vq_state = mlx5_vdpa_set_vq_state,
3661 	.get_vq_state = mlx5_vdpa_get_vq_state,
3662 	.get_vendor_vq_stats = mlx5_vdpa_get_vendor_vq_stats,
3663 	.get_vq_notification = mlx5_get_vq_notification,
3664 	.get_vq_irq = mlx5_get_vq_irq,
3665 	.get_vq_align = mlx5_vdpa_get_vq_align,
3666 	.get_vq_group = mlx5_vdpa_get_vq_group,
3667 	.get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not supported. */
3668 	.get_device_features = mlx5_vdpa_get_device_features,
3669 	.get_backend_features = mlx5_vdpa_get_backend_features,
3670 	.set_driver_features = mlx5_vdpa_set_driver_features,
3671 	.get_driver_features = mlx5_vdpa_get_driver_features,
3672 	.set_config_cb = mlx5_vdpa_set_config_cb,
3673 	.get_vq_num_max = mlx5_vdpa_get_vq_num_max,
3674 	.get_device_id = mlx5_vdpa_get_device_id,
3675 	.get_vendor_id = mlx5_vdpa_get_vendor_id,
3676 	.get_status = mlx5_vdpa_get_status,
3677 	.set_status = mlx5_vdpa_set_status,
3678 	.reset = mlx5_vdpa_reset,
3679 	.compat_reset = mlx5_vdpa_compat_reset,
3680 	.get_config_size = mlx5_vdpa_get_config_size,
3681 	.get_config = mlx5_vdpa_get_config,
3682 	.set_config = mlx5_vdpa_set_config,
3683 	.get_generation = mlx5_vdpa_get_generation,
3684 	.set_map = mlx5_vdpa_set_map,
3685 	.reset_map = mlx5_vdpa_reset_map,
3686 	.set_group_asid = mlx5_set_group_asid,
3687 	.get_vq_dma_dev = mlx5_get_vq_dma_dev,
3688 	.free = mlx5_vdpa_free,
3689 	.suspend = mlx5_vdpa_suspend,
3690 	.resume = mlx5_vdpa_resume, /* Op disabled if not supported. */
3691 };
3692 
query_mtu(struct mlx5_core_dev * mdev,u16 * mtu)3693 static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
3694 {
3695 	u16 hw_mtu;
3696 	int err;
3697 
3698 	err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu);
3699 	if (err)
3700 		return err;
3701 
3702 	*mtu = hw_mtu - MLX5V_ETH_HARD_MTU;
3703 	return 0;
3704 }
3705 
alloc_fixed_resources(struct mlx5_vdpa_net * ndev)3706 static int alloc_fixed_resources(struct mlx5_vdpa_net *ndev)
3707 {
3708 	struct mlx5_vdpa_net_resources *res = &ndev->res;
3709 	int err;
3710 
3711 	if (res->valid) {
3712 		mlx5_vdpa_warn(&ndev->mvdev, "resources already allocated\n");
3713 		return -EEXIST;
3714 	}
3715 
3716 	err = mlx5_vdpa_alloc_transport_domain(&ndev->mvdev, &res->tdn);
3717 	if (err)
3718 		return err;
3719 
3720 	err = create_tis(ndev);
3721 	if (err)
3722 		goto err_tis;
3723 
3724 	res->valid = true;
3725 
3726 	return 0;
3727 
3728 err_tis:
3729 	mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
3730 	return err;
3731 }
3732 
free_fixed_resources(struct mlx5_vdpa_net * ndev)3733 static void free_fixed_resources(struct mlx5_vdpa_net *ndev)
3734 {
3735 	struct mlx5_vdpa_net_resources *res = &ndev->res;
3736 
3737 	if (!res->valid)
3738 		return;
3739 
3740 	destroy_tis(ndev);
3741 	mlx5_vdpa_dealloc_transport_domain(&ndev->mvdev, res->tdn);
3742 	res->valid = false;
3743 }
3744 
mvqs_set_defaults(struct mlx5_vdpa_net * ndev)3745 static void mvqs_set_defaults(struct mlx5_vdpa_net *ndev)
3746 {
3747 	struct mlx5_vdpa_virtqueue *mvq;
3748 	int i;
3749 
3750 	for (i = 0; i < ndev->mvdev.max_vqs; ++i) {
3751 		mvq = &ndev->vqs[i];
3752 		memset(mvq, 0, offsetof(struct mlx5_vdpa_virtqueue, ri));
3753 		mvq->index = i;
3754 		mvq->ndev = ndev;
3755 		mvq->fwqp.fw = true;
3756 		mvq->fw_state = MLX5_VIRTIO_NET_Q_OBJECT_NONE;
3757 		mvq->num_ent = MLX5V_DEFAULT_VQ_SIZE;
3758 	}
3759 }
3760 
3761 struct mlx5_vdpa_mgmtdev {
3762 	struct vdpa_mgmt_dev mgtdev;
3763 	struct mlx5_adev *madev;
3764 	struct mlx5_vdpa_net *ndev;
3765 	struct vdpa_config_ops vdpa_ops;
3766 };
3767 
config_func_mtu(struct mlx5_core_dev * mdev,u16 mtu)3768 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
3769 {
3770 	int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
3771 	void *in;
3772 	int err;
3773 
3774 	in = kvzalloc(inlen, GFP_KERNEL);
3775 	if (!in)
3776 		return -ENOMEM;
3777 
3778 	MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1);
3779 	MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu,
3780 		 mtu + MLX5V_ETH_HARD_MTU);
3781 	MLX5_SET(modify_nic_vport_context_in, in, opcode,
3782 		 MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
3783 
3784 	err = mlx5_cmd_exec_in(mdev, modify_nic_vport_context, in);
3785 
3786 	kvfree(in);
3787 	return err;
3788 }
3789 
allocate_irqs(struct mlx5_vdpa_net * ndev)3790 static void allocate_irqs(struct mlx5_vdpa_net *ndev)
3791 {
3792 	struct mlx5_vdpa_irq_pool_entry *ent;
3793 	int i;
3794 
3795 	if (!msix_mode_supported(&ndev->mvdev))
3796 		return;
3797 
3798 	if (!ndev->mvdev.mdev->pdev)
3799 		return;
3800 
3801 	ndev->irqp.entries = kcalloc(ndev->mvdev.max_vqs, sizeof(*ndev->irqp.entries), GFP_KERNEL);
3802 	if (!ndev->irqp.entries)
3803 		return;
3804 
3805 
3806 	for (i = 0; i < ndev->mvdev.max_vqs; i++) {
3807 		ent = ndev->irqp.entries + i;
3808 		snprintf(ent->name, MLX5_VDPA_IRQ_NAME_LEN, "%s-vq-%d",
3809 			 dev_name(&ndev->mvdev.vdev.dev), i);
3810 		ent->map = pci_msix_alloc_irq_at(ndev->mvdev.mdev->pdev, MSI_ANY_INDEX, NULL);
3811 		if (!ent->map.virq)
3812 			return;
3813 
3814 		ndev->irqp.num_ent++;
3815 	}
3816 }
3817 
mlx5_vdpa_dev_add(struct vdpa_mgmt_dev * v_mdev,const char * name,const struct vdpa_dev_set_config * add_config)3818 static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
3819 			     const struct vdpa_dev_set_config *add_config)
3820 {
3821 	struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct mlx5_vdpa_mgmtdev, mgtdev);
3822 	struct virtio_net_config *config;
3823 	struct mlx5_core_dev *pfmdev;
3824 	struct mlx5_vdpa_dev *mvdev;
3825 	struct mlx5_vdpa_net *ndev;
3826 	struct mlx5_core_dev *mdev;
3827 	u64 device_features;
3828 	u32 max_vqs;
3829 	u16 mtu;
3830 	int err;
3831 
3832 	if (mgtdev->ndev)
3833 		return -ENOSPC;
3834 
3835 	mdev = mgtdev->madev->mdev;
3836 	device_features = mgtdev->mgtdev.supported_features;
3837 	if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES)) {
3838 		if (add_config->device_features & ~device_features) {
3839 			dev_warn(mdev->device,
3840 				 "The provisioned features 0x%llx are not supported by this device with features 0x%llx\n",
3841 				 add_config->device_features, device_features);
3842 			return -EINVAL;
3843 		}
3844 		device_features &= add_config->device_features;
3845 	} else {
3846 		device_features &= ~BIT_ULL(VIRTIO_NET_F_MRG_RXBUF);
3847 	}
3848 	if (!(device_features & BIT_ULL(VIRTIO_F_VERSION_1) &&
3849 	      device_features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM))) {
3850 		dev_warn(mdev->device,
3851 			 "Must provision minimum features 0x%llx for this device",
3852 			 BIT_ULL(VIRTIO_F_VERSION_1) | BIT_ULL(VIRTIO_F_ACCESS_PLATFORM));
3853 		return -EOPNOTSUPP;
3854 	}
3855 
3856 	if (!(MLX5_CAP_DEV_VDPA_EMULATION(mdev, virtio_queue_type) &
3857 	    MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT)) {
3858 		dev_warn(mdev->device, "missing support for split virtqueues\n");
3859 		return -EOPNOTSUPP;
3860 	}
3861 
3862 	max_vqs = min_t(int, MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues),
3863 			1 << MLX5_CAP_GEN(mdev, log_max_rqt_size));
3864 	if (max_vqs < 2) {
3865 		dev_warn(mdev->device,
3866 			 "%d virtqueues are supported. At least 2 are required\n",
3867 			 max_vqs);
3868 		return -EAGAIN;
3869 	}
3870 
3871 	if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) {
3872 		if (add_config->net.max_vq_pairs > max_vqs / 2)
3873 			return -EINVAL;
3874 		max_vqs = min_t(u32, max_vqs, 2 * add_config->net.max_vq_pairs);
3875 	} else {
3876 		max_vqs = 2;
3877 	}
3878 
3879 	ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mgtdev->vdpa_ops,
3880 				 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);
3881 	if (IS_ERR(ndev))
3882 		return PTR_ERR(ndev);
3883 
3884 	ndev->mvdev.max_vqs = max_vqs;
3885 	mvdev = &ndev->mvdev;
3886 	mvdev->mdev = mdev;
3887 
3888 	ndev->vqs = kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
3889 	ndev->event_cbs = kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL);
3890 	if (!ndev->vqs || !ndev->event_cbs) {
3891 		err = -ENOMEM;
3892 		goto err_alloc;
3893 	}
3894 	ndev->cur_num_vqs = MLX5V_DEFAULT_VQ_COUNT;
3895 
3896 	mvqs_set_defaults(ndev);
3897 	allocate_irqs(ndev);
3898 	init_rwsem(&ndev->reslock);
3899 	config = &ndev->config;
3900 
3901 	if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MTU)) {
3902 		err = config_func_mtu(mdev, add_config->net.mtu);
3903 		if (err)
3904 			goto err_alloc;
3905 	}
3906 
3907 	if (device_features & BIT_ULL(VIRTIO_NET_F_MTU)) {
3908 		err = query_mtu(mdev, &mtu);
3909 		if (err)
3910 			goto err_alloc;
3911 
3912 		ndev->config.mtu = cpu_to_mlx5vdpa16(mvdev, mtu);
3913 	}
3914 
3915 	if (device_features & BIT_ULL(VIRTIO_NET_F_STATUS)) {
3916 		if (get_link_state(mvdev))
3917 			ndev->config.status |= cpu_to_mlx5vdpa16(mvdev, VIRTIO_NET_S_LINK_UP);
3918 		else
3919 			ndev->config.status &= cpu_to_mlx5vdpa16(mvdev, ~VIRTIO_NET_S_LINK_UP);
3920 	}
3921 
3922 	if (add_config->mask & (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR)) {
3923 		memcpy(ndev->config.mac, add_config->net.mac, ETH_ALEN);
3924 	/* No bother setting mac address in config if not going to provision _F_MAC */
3925 	} else if ((add_config->mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES)) == 0 ||
3926 		   device_features & BIT_ULL(VIRTIO_NET_F_MAC)) {
3927 		err = mlx5_query_nic_vport_mac_address(mdev, 0, 0, config->mac);
3928 		if (err)
3929 			goto err_alloc;
3930 	}
3931 
3932 	if (!is_zero_ether_addr(config->mac)) {
3933 		pfmdev = pci_get_drvdata(pci_physfn(mdev->pdev));
3934 		err = mlx5_mpfs_add_mac(pfmdev, config->mac);
3935 		if (err)
3936 			goto err_alloc;
3937 	} else if ((add_config->mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES)) == 0) {
3938 		/*
3939 		 * We used to clear _F_MAC feature bit if seeing
3940 		 * zero mac address when device features are not
3941 		 * specifically provisioned. Keep the behaviour
3942 		 * so old scripts do not break.
3943 		 */
3944 		device_features &= ~BIT_ULL(VIRTIO_NET_F_MAC);
3945 	} else if (device_features & BIT_ULL(VIRTIO_NET_F_MAC)) {
3946 		/* Don't provision zero mac address for _F_MAC */
3947 		mlx5_vdpa_warn(&ndev->mvdev,
3948 			       "No mac address provisioned?\n");
3949 		err = -EINVAL;
3950 		goto err_alloc;
3951 	}
3952 
3953 	if (device_features & BIT_ULL(VIRTIO_NET_F_MQ)) {
3954 		config->max_virtqueue_pairs = cpu_to_mlx5vdpa16(mvdev, max_vqs / 2);
3955 		ndev->rqt_size = max_vqs / 2;
3956 	} else {
3957 		ndev->rqt_size = 1;
3958 	}
3959 
3960 	mlx5_cmd_init_async_ctx(mdev, &mvdev->async_ctx);
3961 
3962 	ndev->mvdev.mlx_features = device_features;
3963 	mvdev->vdev.dma_dev = &mdev->pdev->dev;
3964 	err = mlx5_vdpa_alloc_resources(&ndev->mvdev);
3965 	if (err)
3966 		goto err_mpfs;
3967 
3968 	err = mlx5_vdpa_init_mr_resources(mvdev);
3969 	if (err)
3970 		goto err_res;
3971 
3972 	if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
3973 		err = mlx5_vdpa_create_dma_mr(mvdev);
3974 		if (err)
3975 			goto err_mr_res;
3976 	}
3977 
3978 	err = alloc_fixed_resources(ndev);
3979 	if (err)
3980 		goto err_mr;
3981 
3982 	ndev->cvq_ent.mvdev = mvdev;
3983 	INIT_WORK(&ndev->cvq_ent.work, mlx5_cvq_kick_handler);
3984 	mvdev->wq = create_singlethread_workqueue("mlx5_vdpa_wq");
3985 	if (!mvdev->wq) {
3986 		err = -ENOMEM;
3987 		goto err_res2;
3988 	}
3989 
3990 	mvdev->vdev.mdev = &mgtdev->mgtdev;
3991 	err = _vdpa_register_device(&mvdev->vdev, max_vqs + 1);
3992 	if (err)
3993 		goto err_reg;
3994 
3995 	mgtdev->ndev = ndev;
3996 
3997 	/* For virtio-vdpa, the device was set up during device register. */
3998 	if (ndev->setup)
3999 		return 0;
4000 
4001 	down_write(&ndev->reslock);
4002 	err = setup_vq_resources(ndev, false);
4003 	up_write(&ndev->reslock);
4004 	if (err)
4005 		goto err_setup_vq_res;
4006 
4007 	return 0;
4008 
4009 err_setup_vq_res:
4010 	_vdpa_unregister_device(&mvdev->vdev);
4011 err_reg:
4012 	destroy_workqueue(mvdev->wq);
4013 err_res2:
4014 	free_fixed_resources(ndev);
4015 err_mr:
4016 	mlx5_vdpa_clean_mrs(mvdev);
4017 err_mr_res:
4018 	mlx5_vdpa_destroy_mr_resources(mvdev);
4019 err_res:
4020 	mlx5_vdpa_free_resources(&ndev->mvdev);
4021 err_mpfs:
4022 	if (!is_zero_ether_addr(config->mac))
4023 		mlx5_mpfs_del_mac(pfmdev, config->mac);
4024 err_alloc:
4025 	put_device(&mvdev->vdev.dev);
4026 	return err;
4027 }
4028 
mlx5_vdpa_dev_del(struct vdpa_mgmt_dev * v_mdev,struct vdpa_device * dev)4029 static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *dev)
4030 {
4031 	struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct mlx5_vdpa_mgmtdev, mgtdev);
4032 	struct mlx5_vdpa_dev *mvdev = to_mvdev(dev);
4033 	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
4034 	struct workqueue_struct *wq;
4035 
4036 	unregister_link_notifier(ndev);
4037 	_vdpa_unregister_device(dev);
4038 
4039 	down_write(&ndev->reslock);
4040 	teardown_vq_resources(ndev);
4041 	up_write(&ndev->reslock);
4042 
4043 	wq = mvdev->wq;
4044 	mvdev->wq = NULL;
4045 	destroy_workqueue(wq);
4046 	mgtdev->ndev = NULL;
4047 }
4048 
mlx5_vdpa_set_attr(struct vdpa_mgmt_dev * v_mdev,struct vdpa_device * dev,const struct vdpa_dev_set_config * add_config)4049 static int mlx5_vdpa_set_attr(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *dev,
4050 			      const struct vdpa_dev_set_config *add_config)
4051 {
4052 	struct virtio_net_config *config;
4053 	struct mlx5_core_dev *pfmdev;
4054 	struct mlx5_vdpa_dev *mvdev;
4055 	struct mlx5_vdpa_net *ndev;
4056 	struct mlx5_core_dev *mdev;
4057 	int err = -EOPNOTSUPP;
4058 
4059 	mvdev = to_mvdev(dev);
4060 	ndev = to_mlx5_vdpa_ndev(mvdev);
4061 	mdev = mvdev->mdev;
4062 	config = &ndev->config;
4063 
4064 	down_write(&ndev->reslock);
4065 	if (add_config->mask & (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR)) {
4066 		pfmdev = pci_get_drvdata(pci_physfn(mdev->pdev));
4067 		err = mlx5_mpfs_add_mac(pfmdev, config->mac);
4068 		if (!err)
4069 			ether_addr_copy(config->mac, add_config->net.mac);
4070 	}
4071 
4072 	up_write(&ndev->reslock);
4073 	return err;
4074 }
4075 
4076 static const struct vdpa_mgmtdev_ops mdev_ops = {
4077 	.dev_add = mlx5_vdpa_dev_add,
4078 	.dev_del = mlx5_vdpa_dev_del,
4079 	.dev_set_attr = mlx5_vdpa_set_attr,
4080 };
4081 
4082 static struct virtio_device_id id_table[] = {
4083 	{ VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID },
4084 	{ 0 },
4085 };
4086 
mlx5v_probe(struct auxiliary_device * adev,const struct auxiliary_device_id * id)4087 static int mlx5v_probe(struct auxiliary_device *adev,
4088 		       const struct auxiliary_device_id *id)
4089 
4090 {
4091 	struct mlx5_adev *madev = container_of(adev, struct mlx5_adev, adev);
4092 	struct mlx5_core_dev *mdev = madev->mdev;
4093 	struct mlx5_vdpa_mgmtdev *mgtdev;
4094 	int err;
4095 
4096 	mgtdev = kzalloc(sizeof(*mgtdev), GFP_KERNEL);
4097 	if (!mgtdev)
4098 		return -ENOMEM;
4099 
4100 	mgtdev->mgtdev.ops = &mdev_ops;
4101 	mgtdev->mgtdev.device = mdev->device;
4102 	mgtdev->mgtdev.id_table = id_table;
4103 	mgtdev->mgtdev.config_attr_mask = BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR) |
4104 					  BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP) |
4105 					  BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MTU) |
4106 					  BIT_ULL(VDPA_ATTR_DEV_FEATURES);
4107 	mgtdev->mgtdev.max_supported_vqs =
4108 		MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
4109 	mgtdev->mgtdev.supported_features = get_supported_features(mdev);
4110 	mgtdev->madev = madev;
4111 	mgtdev->vdpa_ops = mlx5_vdpa_ops;
4112 
4113 	if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported))
4114 		mgtdev->vdpa_ops.get_vq_desc_group = NULL;
4115 
4116 	if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, freeze_to_rdy_supported))
4117 		mgtdev->vdpa_ops.resume = NULL;
4118 
4119 	err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
4120 	if (err)
4121 		goto reg_err;
4122 
4123 	auxiliary_set_drvdata(adev, mgtdev);
4124 
4125 	return 0;
4126 
4127 reg_err:
4128 	kfree(mgtdev);
4129 	return err;
4130 }
4131 
mlx5v_remove(struct auxiliary_device * adev)4132 static void mlx5v_remove(struct auxiliary_device *adev)
4133 {
4134 	struct mlx5_vdpa_mgmtdev *mgtdev;
4135 
4136 	mgtdev = auxiliary_get_drvdata(adev);
4137 	vdpa_mgmtdev_unregister(&mgtdev->mgtdev);
4138 	kfree(mgtdev);
4139 }
4140 
4141 static const struct auxiliary_device_id mlx5v_id_table[] = {
4142 	{ .name = MLX5_ADEV_NAME ".vnet", },
4143 	{},
4144 };
4145 
4146 MODULE_DEVICE_TABLE(auxiliary, mlx5v_id_table);
4147 
4148 static struct auxiliary_driver mlx5v_driver = {
4149 	.name = "vnet",
4150 	.probe = mlx5v_probe,
4151 	.remove = mlx5v_remove,
4152 	.id_table = mlx5v_id_table,
4153 };
4154 
4155 module_auxiliary_driver(mlx5v_driver);
4156