1fe57c72b8ab21df8286a9fdadf20c98bc2c7440
[dpdk.git] / drivers / vdpa / mlx5 / mlx5_vdpa.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2019 Mellanox Technologies, Ltd
3  */
4
5 #ifndef RTE_PMD_MLX5_VDPA_H_
6 #define RTE_PMD_MLX5_VDPA_H_
7
8 #include <linux/virtio_net.h>
9 #include <sys/queue.h>
10
11 #ifdef PEDANTIC
12 #pragma GCC diagnostic ignored "-Wpedantic"
13 #endif
14 #include <rte_vdpa.h>
15 #include <rte_vdpa_dev.h>
16 #include <rte_vhost.h>
17 #ifdef PEDANTIC
18 #pragma GCC diagnostic error "-Wpedantic"
19 #endif
20 #include <rte_spinlock.h>
21 #include <rte_interrupts.h>
22
23 #include <mlx5_glue.h>
24 #include <mlx5_devx_cmds.h>
25 #include <mlx5_common_devx.h>
26 #include <mlx5_prm.h>
27
28
29 #define MLX5_VDPA_INTR_RETRIES 256
30 #define MLX5_VDPA_INTR_RETRIES_USEC 1000
31
32 #ifndef VIRTIO_F_ORDER_PLATFORM
33 #define VIRTIO_F_ORDER_PLATFORM 36
34 #endif
35
36 #ifndef VIRTIO_F_RING_PACKED
37 #define VIRTIO_F_RING_PACKED 34
38 #endif
39
40 #define MLX5_VDPA_DEFAULT_TIMER_DELAY_US 0u
41 #define MLX5_VDPA_DEFAULT_TIMER_STEP_US 1u
42
43 struct mlx5_vdpa_cq {
44         uint16_t log_desc_n;
45         uint32_t cq_ci:24;
46         uint32_t arm_sn:2;
47         uint32_t armed:1;
48         int callfd;
49         rte_spinlock_t sl;
50         struct mlx5_devx_cq cq_obj;
51         uint64_t errors;
52 };
53
54 struct mlx5_vdpa_event_qp {
55         struct mlx5_vdpa_cq cq;
56         struct mlx5_devx_obj *fw_qp;
57         struct mlx5_devx_qp sw_qp;
58 };
59
60 struct mlx5_vdpa_query_mr {
61         SLIST_ENTRY(mlx5_vdpa_query_mr) next;
62         void *addr;
63         uint64_t length;
64         struct mlx5dv_devx_umem *umem;
65         struct mlx5_devx_obj *mkey;
66         int is_indirect;
67 };
68
69 enum {
70         MLX5_VDPA_NOTIFIER_STATE_DISABLED,
71         MLX5_VDPA_NOTIFIER_STATE_ENABLED,
72         MLX5_VDPA_NOTIFIER_STATE_ERR
73 };
74
75 struct mlx5_vdpa_virtq {
76         SLIST_ENTRY(mlx5_vdpa_virtq) next;
77         uint8_t enable;
78         uint16_t index;
79         uint16_t vq_size;
80         uint8_t notifier_state;
81         bool stopped;
82         uint32_t version;
83         struct mlx5_vdpa_priv *priv;
84         struct mlx5_devx_obj *virtq;
85         struct mlx5_devx_obj *counters;
86         struct mlx5_vdpa_event_qp eqp;
87         struct {
88                 struct mlx5dv_devx_umem *obj;
89                 void *buf;
90                 uint32_t size;
91         } umems[3];
92         struct rte_intr_handle intr_handle;
93         uint64_t err_time[3]; /* RDTSC time of recent errors. */
94         uint32_t n_retry;
95         struct mlx5_devx_virtio_q_couners_attr reset;
96 };
97
98 struct mlx5_vdpa_steer {
99         struct mlx5_devx_obj *rqt;
100         void *domain;
101         void *tbl;
102         struct {
103                 struct mlx5dv_flow_matcher *matcher;
104                 struct mlx5_devx_obj *tir;
105                 void *tir_action;
106                 void *flow;
107         } rss[7];
108 };
109
110 enum {
111         MLX5_VDPA_EVENT_MODE_DYNAMIC_TIMER,
112         MLX5_VDPA_EVENT_MODE_FIXED_TIMER,
113         MLX5_VDPA_EVENT_MODE_ONLY_INTERRUPT
114 };
115
116 struct mlx5_vdpa_priv {
117         TAILQ_ENTRY(mlx5_vdpa_priv) next;
118         uint8_t configured;
119         pthread_mutex_t vq_config_lock;
120         uint64_t no_traffic_counter;
121         pthread_t timer_tid;
122         int event_mode;
123         int event_core; /* Event thread cpu affinity core. */
124         uint32_t event_us;
125         uint32_t timer_delay_us;
126         uint32_t no_traffic_max;
127         uint8_t hw_latency_mode; /* Hardware CQ moderation mode. */
128         uint16_t hw_max_latency_us; /* Hardware CQ moderation period in usec. */
129         uint16_t hw_max_pending_comp; /* Hardware CQ moderation counter. */
130         struct rte_vdpa_device *vdev; /* vDPA device. */
131         struct mlx5_common_device *cdev; /* Backend mlx5 device. */
132         int vid; /* vhost device id. */
133         struct mlx5_hca_vdpa_attr caps;
134         uint32_t pdn; /* Protection Domain number. */
135         struct ibv_pd *pd;
136         uint32_t gpa_mkey_index;
137         struct ibv_mr *null_mr;
138         struct rte_vhost_memory *vmem;
139         struct mlx5dv_devx_event_channel *eventc;
140         struct mlx5dv_devx_event_channel *err_chnl;
141         struct mlx5dv_devx_uar *uar;
142         struct rte_intr_handle err_intr_handle;
143         struct mlx5_devx_obj *td;
144         struct mlx5_devx_obj *tiss[16]; /* TIS list for each LAG port. */
145         uint16_t nr_virtqs;
146         uint8_t num_lag_ports;
147         uint8_t qp_ts_format;
148         uint64_t features; /* Negotiated features. */
149         uint16_t log_max_rqt_size;
150         struct mlx5_vdpa_steer steer;
151         struct mlx5dv_var *var;
152         void *virtq_db_addr;
153         SLIST_HEAD(mr_list, mlx5_vdpa_query_mr) mr_list;
154         struct mlx5_vdpa_virtq virtqs[];
155 };
156
157 enum {
158         MLX5_VDPA_STATS_RECEIVED_DESCRIPTORS,
159         MLX5_VDPA_STATS_COMPLETED_DESCRIPTORS,
160         MLX5_VDPA_STATS_BAD_DESCRIPTOR_ERRORS,
161         MLX5_VDPA_STATS_EXCEED_MAX_CHAIN,
162         MLX5_VDPA_STATS_INVALID_BUFFER,
163         MLX5_VDPA_STATS_COMPLETION_ERRORS,
164         MLX5_VDPA_STATS_MAX
165 };
166
167 /*
168  * Check whether virtq is for traffic receive.
169  * According to VIRTIO_NET Spec the virtqueues index identity its type by:
170  * 0 receiveq1
171  * 1 transmitq1
172  * ...
173  * 2(N-1) receiveqN
174  * 2(N-1)+1 transmitqN
175  * 2N controlq
176  */
177 static inline uint8_t
178 is_virtq_recvq(int virtq_index, int nr_vring)
179 {
180         if (virtq_index % 2 == 0 && virtq_index != nr_vring - 1)
181                 return 1;
182         return 0;
183 }
184
185 /**
186  * Release all the prepared memory regions and all their related resources.
187  *
188  * @param[in] priv
189  *   The vdpa driver private structure.
190  */
191 void mlx5_vdpa_mem_dereg(struct mlx5_vdpa_priv *priv);
192
193 /**
194  * Register all the memory regions of the virtio device to the HW and allocate
195  * all their related resources.
196  *
197  * @param[in] priv
198  *   The vdpa driver private structure.
199  *
200  * @return
201  *   0 on success, a negative errno value otherwise and rte_errno is set.
202  */
203 int mlx5_vdpa_mem_register(struct mlx5_vdpa_priv *priv);
204
205
206 /**
207  * Create an event QP and all its related resources.
208  *
209  * @param[in] priv
210  *   The vdpa driver private structure.
211  * @param[in] desc_n
212  *   Number of descriptors.
213  * @param[in] callfd
214  *   The guest notification file descriptor.
215  * @param[in/out] eqp
216  *   Pointer to the event QP structure.
217  *
218  * @return
219  *   0 on success, -1 otherwise and rte_errno is set.
220  */
221 int mlx5_vdpa_event_qp_create(struct mlx5_vdpa_priv *priv, uint16_t desc_n,
222                               int callfd, struct mlx5_vdpa_event_qp *eqp);
223
224 /**
225  * Destroy an event QP and all its related resources.
226  *
227  * @param[in/out] eqp
228  *   Pointer to the event QP structure.
229  */
230 void mlx5_vdpa_event_qp_destroy(struct mlx5_vdpa_event_qp *eqp);
231
232 /**
233  * Release all the event global resources.
234  *
235  * @param[in] priv
236  *   The vdpa driver private structure.
237  */
238 void mlx5_vdpa_event_qp_global_release(struct mlx5_vdpa_priv *priv);
239
240 /**
241  * Setup CQE event.
242  *
243  * @param[in] priv
244  *   The vdpa driver private structure.
245  *
246  * @return
247  *   0 on success, a negative errno value otherwise and rte_errno is set.
248  */
249 int mlx5_vdpa_cqe_event_setup(struct mlx5_vdpa_priv *priv);
250
251 /**
252  * Unset CQE event .
253  *
254  * @param[in] priv
255  *   The vdpa driver private structure.
256  */
257 void mlx5_vdpa_cqe_event_unset(struct mlx5_vdpa_priv *priv);
258
259 /**
260  * Setup error interrupt handler.
261  *
262  * @param[in] priv
263  *   The vdpa driver private structure.
264  *
265  * @return
266  *   0 on success, a negative errno value otherwise and rte_errno is set.
267  */
268 int mlx5_vdpa_err_event_setup(struct mlx5_vdpa_priv *priv);
269
270 /**
271  * Unset error event handler.
272  *
273  * @param[in] priv
274  *   The vdpa driver private structure.
275  */
276 void mlx5_vdpa_err_event_unset(struct mlx5_vdpa_priv *priv);
277
278 /**
279  * Release a virtq and all its related resources.
280  *
281  * @param[in] priv
282  *   The vdpa driver private structure.
283  */
284 void mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv);
285
286 /**
287  * Create all the HW virtqs resources and all their related resources.
288  *
289  * @param[in] priv
290  *   The vdpa driver private structure.
291  *
292  * @return
293  *   0 on success, a negative errno value otherwise and rte_errno is set.
294  */
295 int mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv);
296
297 /**
298  * Enable\Disable virtq..
299  *
300  * @param[in] priv
301  *   The vdpa driver private structure.
302  * @param[in] index
303  *   The virtq index.
304  * @param[in] enable
305  *   Set to enable, otherwise disable.
306  *
307  * @return
308  *   0 on success, a negative value otherwise.
309  */
310 int mlx5_vdpa_virtq_enable(struct mlx5_vdpa_priv *priv, int index, int enable);
311
312 /**
313  * Unset steering and release all its related resources- stop traffic.
314  *
315  * @param[in] priv
316  *   The vdpa driver private structure.
317  */
318 void mlx5_vdpa_steer_unset(struct mlx5_vdpa_priv *priv);
319
320 /**
321  * Update steering according to the received queues status.
322  *
323  * @param[in] priv
324  *   The vdpa driver private structure.
325  *
326  * @return
327  *   0 on success, a negative value otherwise.
328  */
329 int mlx5_vdpa_steer_update(struct mlx5_vdpa_priv *priv);
330
331 /**
332  * Setup steering and all its related resources to enable RSS traffic from the
333  * device to all the Rx host queues.
334  *
335  * @param[in] priv
336  *   The vdpa driver private structure.
337  *
338  * @return
339  *   0 on success, a negative value otherwise.
340  */
341 int mlx5_vdpa_steer_setup(struct mlx5_vdpa_priv *priv);
342
343 /**
344  * Enable\Disable live migration logging.
345  *
346  * @param[in] priv
347  *   The vdpa driver private structure.
348  * @param[in] enable
349  *   Set for enable, unset for disable.
350  *
351  * @return
352  *   0 on success, a negative value otherwise.
353  */
354 int mlx5_vdpa_logging_enable(struct mlx5_vdpa_priv *priv, int enable);
355
356 /**
357  * Set dirty bitmap logging to allow live migration.
358  *
359  * @param[in] priv
360  *   The vdpa driver private structure.
361  * @param[in] log_base
362  *   Vhost log base.
363  * @param[in] log_size
364  *   Vhost log size.
365  *
366  * @return
367  *   0 on success, a negative value otherwise.
368  */
369 int mlx5_vdpa_dirty_bitmap_set(struct mlx5_vdpa_priv *priv, uint64_t log_base,
370                                uint64_t log_size);
371
372 /**
373  * Log all virtqs information for live migration.
374  *
375  * @param[in] priv
376  *   The vdpa driver private structure.
377  * @param[in] enable
378  *   Set for enable, unset for disable.
379  *
380  * @return
381  *   0 on success, a negative value otherwise.
382  */
383 int mlx5_vdpa_lm_log(struct mlx5_vdpa_priv *priv);
384
385 /**
386  * Modify virtq state to be ready or suspend.
387  *
388  * @param[in] virtq
389  *   The vdpa driver private virtq structure.
390  * @param[in] state
391  *   Set for ready, otherwise suspend.
392  *
393  * @return
394  *   0 on success, a negative value otherwise.
395  */
396 int mlx5_vdpa_virtq_modify(struct mlx5_vdpa_virtq *virtq, int state);
397
398 /**
399  * Stop virtq before destroying it.
400  *
401  * @param[in] priv
402  *   The vdpa driver private structure.
403  * @param[in] index
404  *   The virtq index.
405  *
406  * @return
407  *   0 on success, a negative value otherwise.
408  */
409 int mlx5_vdpa_virtq_stop(struct mlx5_vdpa_priv *priv, int index);
410
411 /**
412  * Query virtq information.
413  *
414  * @param[in] priv
415  *   The vdpa driver private structure.
416  * @param[in] index
417  *   The virtq index.
418  *
419  * @return
420  *   0 on success, a negative value otherwise.
421  */
422 int mlx5_vdpa_virtq_query(struct mlx5_vdpa_priv *priv, int index);
423
424 /**
425  * Get virtq statistics.
426  *
427  * @param[in] priv
428  *   The vdpa driver private structure.
429  * @param[in] qid
430  *   The virtq index.
431  * @param stats
432  *   The virtq statistics array to fill.
433  * @param n
434  *   The number of elements in @p stats array.
435  *
436  * @return
437  *   A negative value on error, otherwise the number of entries filled in the
438  *   @p stats array.
439  */
440 int
441 mlx5_vdpa_virtq_stats_get(struct mlx5_vdpa_priv *priv, int qid,
442                           struct rte_vdpa_stat *stats, unsigned int n);
443
444 /**
445  * Reset virtq statistics.
446  *
447  * @param[in] priv
448  *   The vdpa driver private structure.
449  * @param[in] qid
450  *   The virtq index.
451  *
452  * @return
453  *   A negative value on error, otherwise 0.
454  */
455 int
456 mlx5_vdpa_virtq_stats_reset(struct mlx5_vdpa_priv *priv, int qid);
457 #endif /* RTE_PMD_MLX5_VDPA_H_ */