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