82f32ec9d010b57aedb19829a826be1fd5b6ac1c
[vpp.git] / src / plugins / rdma / rdma.h
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2018 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #ifndef _RDMA_H_
19 #define _RDMA_H_
20
21 #include <infiniband/verbs.h>
22 #include <vlib/log.h>
23 #include <vlib/pci/pci.h>
24 #include <vnet/interface.h>
25 #include <vnet/ethernet/mac_address.h>
26 #include <rdma/rdma_mlx5dv.h>
27
28 #define foreach_rdma_device_flags \
29   _(0, ERROR, "error") \
30   _(1, ADMIN_UP, "admin-up") \
31   _(2, LINK_UP, "link-up") \
32   _(3, PROMISC, "promiscuous") \
33   _(4, MLX5DV, "mlx5dv")
34
35 enum
36 {
37 #define _(a, b, c) RDMA_DEVICE_F_##b = (1 << a),
38   foreach_rdma_device_flags
39 #undef _
40 };
41
42 typedef struct
43 {
44   CLIB_ALIGN_MARK (align0, MLX5_SEND_WQE_BB);
45   struct mlx5_wqe_ctrl_seg ctrl;
46   struct mlx5_wqe_eth_seg eseg;
47   struct mlx5_wqe_data_seg dseg;
48 } rdma_mlx5_wqe_t;
49 #define RDMA_MLX5_WQE_SZ        sizeof(rdma_mlx5_wqe_t)
50 #define RDMA_MLX5_WQE_DS        (RDMA_MLX5_WQE_SZ/sizeof(struct mlx5_wqe_data_seg))
51 STATIC_ASSERT (RDMA_MLX5_WQE_SZ == MLX5_SEND_WQE_BB &&
52                RDMA_MLX5_WQE_SZ % sizeof (struct mlx5_wqe_data_seg) == 0,
53                "bad size");
54
55 typedef struct
56 {
57   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
58   struct ibv_cq *cq;
59   struct ibv_wq *wq;
60   u32 *bufs;
61   u32 size;
62   u32 head;
63   u32 tail;
64   u32 cq_ci;
65   u16 log2_cq_size;
66   u16 n_mini_cqes;
67   u16 n_mini_cqes_left;
68   u16 last_cqe_flags;
69   mlx5dv_cqe_t *cqes;
70   mlx5dv_rwq_t *wqes;
71   volatile u32 *wq_db;
72   volatile u32 *cq_db;
73   u32 cqn;
74   u32 wqe_cnt;
75   u32 wq_stride;
76 } rdma_rxq_t;
77
78 typedef struct
79 {
80   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
81
82   /* following fields are accessed in datapath */
83   clib_spinlock_t lock;
84
85   union
86   {
87     struct
88     {
89       /* ibverb datapath. Cache of cq, sq below */
90       struct ibv_cq *ibv_cq;
91       struct ibv_qp *ibv_qp;
92     };
93     struct
94     {
95       /* direct verbs datapath */
96       rdma_mlx5_wqe_t *dv_sq_wqes;
97       volatile u32 *dv_sq_dbrec;
98       volatile u64 *dv_sq_db;
99       struct mlx5_cqe64 *dv_cq_cqes;
100       volatile u32 *dv_cq_dbrec;
101     };
102   };
103
104   u32 *bufs;                    /* vlib_buffer ring buffer */
105   u16 head;
106   u16 tail;
107   u16 dv_cq_idx;                /* monotonic CQE index (valid only for direct verbs) */
108   u8 bufs_log2sz;               /* log2 vlib_buffer entries */
109   u8 dv_sq_log2sz:4;            /* log2 SQ WQE entries (valid only for direct verbs) */
110   u8 dv_cq_log2sz:4;            /* log2 CQ CQE entries (valid only for direct verbs) */
111     STRUCT_MARK (cacheline1);
112
113   /* WQE template (valid only for direct verbs) */
114   u8 dv_wqe_tmpl[64];
115
116   /* end of 2nd 64-bytes cacheline (or 1st 128-bytes cacheline) */
117     STRUCT_MARK (cacheline2);
118
119   /* fields below are not accessed in datapath */
120   struct ibv_cq *cq;
121   struct ibv_qp *qp;
122
123 } rdma_txq_t;
124 STATIC_ASSERT_OFFSET_OF (rdma_txq_t, cacheline1, 64);
125 STATIC_ASSERT_OFFSET_OF (rdma_txq_t, cacheline2, 128);
126
127 #define RDMA_TXQ_DV_INVALID_ID  0xffffffff
128
129 #define RDMA_TXQ_BUF_SZ(txq)    (1U << (txq)->bufs_log2sz)
130 #define RDMA_TXQ_DV_SQ_SZ(txq)  (1U << (txq)->dv_sq_log2sz)
131 #define RDMA_TXQ_DV_CQ_SZ(txq)  (1U << (txq)->dv_cq_log2sz)
132
133 #define RDMA_TXQ_USED_SZ(head, tail)            ((u16)((u16)(tail) - (u16)(head)))
134 #define RDMA_TXQ_AVAIL_SZ(txq, head, tail)      ((u16)(RDMA_TXQ_BUF_SZ (txq) - RDMA_TXQ_USED_SZ (head, tail)))
135
136 typedef struct
137 {
138   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
139
140   /* following fields are accessed in datapath */
141   rdma_rxq_t *rxqs;
142   rdma_txq_t *txqs;
143   u32 flags;
144   u32 per_interface_next_index;
145   u32 sw_if_index;
146   u32 hw_if_index;
147   u32 lkey;                     /* cache of mr->lkey */
148   u8 pool;                      /* buffer pool index */
149
150   /* fields below are not accessed in datapath */
151   vlib_pci_device_info_t *pci;
152   u8 *name;
153   u8 *linux_ifname;
154   mac_address_t hwaddr;
155   u32 async_event_clib_file_index;
156   u32 dev_instance;
157
158   struct ibv_context *ctx;
159   struct ibv_pd *pd;
160   struct ibv_mr *mr;
161   struct ibv_qp *rx_qp;
162   struct ibv_rwq_ind_table *rx_rwq_ind_tbl;
163   struct ibv_flow *flow_ucast;
164   struct ibv_flow *flow_mcast;
165
166   clib_error_t *error;
167 } rdma_device_t;
168
169 typedef struct
170 {
171   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
172   union
173   {
174     u16 cqe_flags[VLIB_FRAME_SIZE];
175     u16x8 cqe_flags8[VLIB_FRAME_SIZE / 8];
176     u16x16 cqe_flags16[VLIB_FRAME_SIZE / 16];
177   };
178   vlib_buffer_t buffer_template;
179 } rdma_per_thread_data_t;
180
181 typedef struct
182 {
183   rdma_per_thread_data_t *per_thread_data;
184   rdma_device_t *devices;
185   vlib_log_class_t log_class;
186   u16 msg_id_base;
187 } rdma_main_t;
188
189 extern rdma_main_t rdma_main;
190
191 typedef enum
192 {
193   RDMA_MODE_AUTO = 0,
194   RDMA_MODE_IBV,
195   RDMA_MODE_DV,
196 } rdma_mode_t;
197
198 typedef struct
199 {
200   u8 *ifname;
201   u8 *name;
202   u32 rxq_size;
203   u32 txq_size;
204   u32 rxq_num;
205   rdma_mode_t mode;
206
207   /* return */
208   int rv;
209   u32 sw_if_index;
210   clib_error_t *error;
211 } rdma_create_if_args_t;
212
213 void rdma_create_if (vlib_main_t * vm, rdma_create_if_args_t * args);
214 void rdma_delete_if (vlib_main_t * vm, rdma_device_t * rd);
215
216 extern vlib_node_registration_t rdma_input_node;
217 extern vnet_device_class_t rdma_device_class;
218
219 format_function_t format_rdma_device;
220 format_function_t format_rdma_device_name;
221 format_function_t format_rdma_input_trace;
222 format_function_t format_rdma_rxq;
223 unformat_function_t unformat_rdma_create_if_args;
224
225 typedef struct
226 {
227   u32 next_index;
228   u32 hw_if_index;
229   u16 cqe_flags;
230 } rdma_input_trace_t;
231
232 #define foreach_rdma_tx_func_error \
233 _(SEGMENT_SIZE_EXCEEDED, "segment size exceeded") \
234 _(NO_FREE_SLOTS, "no free tx slots") \
235 _(SUBMISSION, "tx submission errors") \
236 _(COMPLETION, "tx completion errors")
237
238 typedef enum
239 {
240 #define _(f,s) RDMA_TX_ERROR_##f,
241   foreach_rdma_tx_func_error
242 #undef _
243     RDMA_TX_N_ERROR,
244 } rdma_tx_func_error_t;
245
246 #endif /* _RDMA_H_ */
247
248 /*
249  * fd.io coding-style-patch-verification: ON
250  *
251  * Local Variables:
252  * eval: (c-set-style "gnu")
253  * End:
254  */