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