xref: /linux/drivers/infiniband/hw/ionic/ionic_fw.h (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */
3 
4 #ifndef _IONIC_FW_H_
5 #define _IONIC_FW_H_
6 
7 #include <linux/kernel.h>
8 #include <rdma/ib_verbs.h>
9 
10 /* common for ib spec */
11 
12 #define IONIC_EXP_DBELL_SZ		8
13 
14 enum ionic_mrid_bits {
15 	IONIC_MRID_INDEX_SHIFT		= 8,
16 };
17 
18 static inline u32 ionic_mrid(u32 index, u8 key)
19 {
20 	return (index << IONIC_MRID_INDEX_SHIFT) | key;
21 }
22 
23 static inline u32 ionic_mrid_index(u32 lrkey)
24 {
25 	return lrkey >> IONIC_MRID_INDEX_SHIFT;
26 }
27 
28 /* common to all versions */
29 
30 /* wqe scatter gather element */
31 struct ionic_sge {
32 	__be64				va;
33 	__be32				len;
34 	__be32				lkey;
35 };
36 
37 /* admin queue mr type */
38 enum ionic_mr_flags {
39 	/* bits that determine mr access */
40 	IONIC_MRF_LOCAL_WRITE		= BIT(0),
41 	IONIC_MRF_REMOTE_WRITE		= BIT(1),
42 	IONIC_MRF_REMOTE_READ		= BIT(2),
43 	IONIC_MRF_REMOTE_ATOMIC		= BIT(3),
44 	IONIC_MRF_MW_BIND		= BIT(4),
45 	IONIC_MRF_ZERO_BASED		= BIT(5),
46 	IONIC_MRF_ON_DEMAND		= BIT(6),
47 	IONIC_MRF_PB			= BIT(7),
48 	IONIC_MRF_ACCESS_MASK		= BIT(12) - 1,
49 
50 	/* bits that determine mr type */
51 	IONIC_MRF_UKEY_EN		= BIT(13),
52 	IONIC_MRF_IS_MW			= BIT(14),
53 	IONIC_MRF_INV_EN		= BIT(15),
54 
55 	/* base flags combinations for mr types */
56 	IONIC_MRF_USER_MR		= 0,
57 	IONIC_MRF_PHYS_MR		= (IONIC_MRF_UKEY_EN |
58 					   IONIC_MRF_INV_EN),
59 	IONIC_MRF_MW_1			= (IONIC_MRF_UKEY_EN |
60 					   IONIC_MRF_IS_MW),
61 	IONIC_MRF_MW_2			= (IONIC_MRF_UKEY_EN |
62 					   IONIC_MRF_IS_MW |
63 					   IONIC_MRF_INV_EN),
64 };
65 
66 static inline int to_ionic_mr_flags(int access)
67 {
68 	int flags = 0;
69 
70 	if (access & IB_ACCESS_LOCAL_WRITE)
71 		flags |= IONIC_MRF_LOCAL_WRITE;
72 
73 	if (access & IB_ACCESS_REMOTE_READ)
74 		flags |= IONIC_MRF_REMOTE_READ;
75 
76 	if (access & IB_ACCESS_REMOTE_WRITE)
77 		flags |= IONIC_MRF_REMOTE_WRITE;
78 
79 	if (access & IB_ACCESS_REMOTE_ATOMIC)
80 		flags |= IONIC_MRF_REMOTE_ATOMIC;
81 
82 	if (access & IB_ACCESS_MW_BIND)
83 		flags |= IONIC_MRF_MW_BIND;
84 
85 	if (access & IB_ZERO_BASED)
86 		flags |= IONIC_MRF_ZERO_BASED;
87 
88 	return flags;
89 }
90 
91 enum ionic_qp_flags {
92 	/* bits that determine qp access */
93 	IONIC_QPF_REMOTE_WRITE		= BIT(0),
94 	IONIC_QPF_REMOTE_READ		= BIT(1),
95 	IONIC_QPF_REMOTE_ATOMIC		= BIT(2),
96 
97 	/* bits that determine other qp behavior */
98 	IONIC_QPF_SQ_PB			= BIT(6),
99 	IONIC_QPF_RQ_PB			= BIT(7),
100 	IONIC_QPF_SQ_SPEC		= BIT(8),
101 	IONIC_QPF_RQ_SPEC		= BIT(9),
102 	IONIC_QPF_REMOTE_PRIVILEGED	= BIT(10),
103 	IONIC_QPF_SQ_DRAINING		= BIT(11),
104 	IONIC_QPF_SQD_NOTIFY		= BIT(12),
105 	IONIC_QPF_SQ_CMB		= BIT(13),
106 	IONIC_QPF_RQ_CMB		= BIT(14),
107 	IONIC_QPF_PRIVILEGED		= BIT(15),
108 };
109 
110 static inline int from_ionic_qp_flags(int flags)
111 {
112 	int access_flags = 0;
113 
114 	if (flags & IONIC_QPF_REMOTE_WRITE)
115 		access_flags |= IB_ACCESS_REMOTE_WRITE;
116 
117 	if (flags & IONIC_QPF_REMOTE_READ)
118 		access_flags |= IB_ACCESS_REMOTE_READ;
119 
120 	if (flags & IONIC_QPF_REMOTE_ATOMIC)
121 		access_flags |= IB_ACCESS_REMOTE_ATOMIC;
122 
123 	return access_flags;
124 }
125 
126 static inline int to_ionic_qp_flags(int access, bool sqd_notify,
127 				    bool sq_is_cmb, bool rq_is_cmb,
128 				    bool sq_spec, bool rq_spec,
129 				    bool privileged, bool remote_privileged)
130 {
131 	int flags = 0;
132 
133 	if (access & IB_ACCESS_REMOTE_WRITE)
134 		flags |= IONIC_QPF_REMOTE_WRITE;
135 
136 	if (access & IB_ACCESS_REMOTE_READ)
137 		flags |= IONIC_QPF_REMOTE_READ;
138 
139 	if (access & IB_ACCESS_REMOTE_ATOMIC)
140 		flags |= IONIC_QPF_REMOTE_ATOMIC;
141 
142 	if (sqd_notify)
143 		flags |= IONIC_QPF_SQD_NOTIFY;
144 
145 	if (sq_is_cmb)
146 		flags |= IONIC_QPF_SQ_CMB;
147 
148 	if (rq_is_cmb)
149 		flags |= IONIC_QPF_RQ_CMB;
150 
151 	if (sq_spec)
152 		flags |= IONIC_QPF_SQ_SPEC;
153 
154 	if (rq_spec)
155 		flags |= IONIC_QPF_RQ_SPEC;
156 
157 	if (privileged)
158 		flags |= IONIC_QPF_PRIVILEGED;
159 
160 	if (remote_privileged)
161 		flags |= IONIC_QPF_REMOTE_PRIVILEGED;
162 
163 	return flags;
164 }
165 
166 /* cqe non-admin status indicated in status_length field when err bit is set */
167 enum ionic_status {
168 	IONIC_STS_OK,
169 	IONIC_STS_LOCAL_LEN_ERR,
170 	IONIC_STS_LOCAL_QP_OPER_ERR,
171 	IONIC_STS_LOCAL_PROT_ERR,
172 	IONIC_STS_WQE_FLUSHED_ERR,
173 	IONIC_STS_MEM_MGMT_OPER_ERR,
174 	IONIC_STS_BAD_RESP_ERR,
175 	IONIC_STS_LOCAL_ACC_ERR,
176 	IONIC_STS_REMOTE_INV_REQ_ERR,
177 	IONIC_STS_REMOTE_ACC_ERR,
178 	IONIC_STS_REMOTE_OPER_ERR,
179 	IONIC_STS_RETRY_EXCEEDED,
180 	IONIC_STS_RNR_RETRY_EXCEEDED,
181 	IONIC_STS_XRC_VIO_ERR,
182 	IONIC_STS_LOCAL_SGL_INV_ERR,
183 };
184 
185 static inline int ionic_to_ib_status(int sts)
186 {
187 	switch (sts) {
188 	case IONIC_STS_OK:
189 		return IB_WC_SUCCESS;
190 	case IONIC_STS_LOCAL_LEN_ERR:
191 		return IB_WC_LOC_LEN_ERR;
192 	case IONIC_STS_LOCAL_QP_OPER_ERR:
193 	case IONIC_STS_LOCAL_SGL_INV_ERR:
194 		return IB_WC_LOC_QP_OP_ERR;
195 	case IONIC_STS_LOCAL_PROT_ERR:
196 		return IB_WC_LOC_PROT_ERR;
197 	case IONIC_STS_WQE_FLUSHED_ERR:
198 		return IB_WC_WR_FLUSH_ERR;
199 	case IONIC_STS_MEM_MGMT_OPER_ERR:
200 		return IB_WC_MW_BIND_ERR;
201 	case IONIC_STS_BAD_RESP_ERR:
202 		return IB_WC_BAD_RESP_ERR;
203 	case IONIC_STS_LOCAL_ACC_ERR:
204 		return IB_WC_LOC_ACCESS_ERR;
205 	case IONIC_STS_REMOTE_INV_REQ_ERR:
206 		return IB_WC_REM_INV_REQ_ERR;
207 	case IONIC_STS_REMOTE_ACC_ERR:
208 		return IB_WC_REM_ACCESS_ERR;
209 	case IONIC_STS_REMOTE_OPER_ERR:
210 		return IB_WC_REM_OP_ERR;
211 	case IONIC_STS_RETRY_EXCEEDED:
212 		return IB_WC_RETRY_EXC_ERR;
213 	case IONIC_STS_RNR_RETRY_EXCEEDED:
214 		return IB_WC_RNR_RETRY_EXC_ERR;
215 	case IONIC_STS_XRC_VIO_ERR:
216 	default:
217 		return IB_WC_GENERAL_ERR;
218 	}
219 }
220 
221 /* admin queue qp type */
222 enum ionic_qp_type {
223 	IONIC_QPT_RC,
224 	IONIC_QPT_UC,
225 	IONIC_QPT_RD,
226 	IONIC_QPT_UD,
227 	IONIC_QPT_SRQ,
228 	IONIC_QPT_XRC_INI,
229 	IONIC_QPT_XRC_TGT,
230 	IONIC_QPT_XRC_SRQ,
231 };
232 
233 static inline int to_ionic_qp_type(enum ib_qp_type type)
234 {
235 	switch (type) {
236 	case IB_QPT_GSI:
237 	case IB_QPT_UD:
238 		return IONIC_QPT_UD;
239 	case IB_QPT_RC:
240 		return IONIC_QPT_RC;
241 	case IB_QPT_UC:
242 		return IONIC_QPT_UC;
243 	case IB_QPT_XRC_INI:
244 		return IONIC_QPT_XRC_INI;
245 	case IB_QPT_XRC_TGT:
246 		return IONIC_QPT_XRC_TGT;
247 	default:
248 		return -EINVAL;
249 	}
250 }
251 
252 /* admin queue qp state */
253 enum ionic_qp_state {
254 	IONIC_QPS_RESET,
255 	IONIC_QPS_INIT,
256 	IONIC_QPS_RTR,
257 	IONIC_QPS_RTS,
258 	IONIC_QPS_SQD,
259 	IONIC_QPS_SQE,
260 	IONIC_QPS_ERR,
261 };
262 
263 static inline int from_ionic_qp_state(enum ionic_qp_state state)
264 {
265 	switch (state) {
266 	case IONIC_QPS_RESET:
267 		return IB_QPS_RESET;
268 	case IONIC_QPS_INIT:
269 		return IB_QPS_INIT;
270 	case IONIC_QPS_RTR:
271 		return IB_QPS_RTR;
272 	case IONIC_QPS_RTS:
273 		return IB_QPS_RTS;
274 	case IONIC_QPS_SQD:
275 		return IB_QPS_SQD;
276 	case IONIC_QPS_SQE:
277 		return IB_QPS_SQE;
278 	case IONIC_QPS_ERR:
279 		return IB_QPS_ERR;
280 	default:
281 		return -EINVAL;
282 	}
283 }
284 
285 static inline int to_ionic_qp_state(enum ib_qp_state state)
286 {
287 	switch (state) {
288 	case IB_QPS_RESET:
289 		return IONIC_QPS_RESET;
290 	case IB_QPS_INIT:
291 		return IONIC_QPS_INIT;
292 	case IB_QPS_RTR:
293 		return IONIC_QPS_RTR;
294 	case IB_QPS_RTS:
295 		return IONIC_QPS_RTS;
296 	case IB_QPS_SQD:
297 		return IONIC_QPS_SQD;
298 	case IB_QPS_SQE:
299 		return IONIC_QPS_SQE;
300 	case IB_QPS_ERR:
301 		return IONIC_QPS_ERR;
302 	default:
303 		return 0;
304 	}
305 }
306 
307 static inline int to_ionic_qp_modify_state(enum ib_qp_state to_state,
308 					   enum ib_qp_state from_state)
309 {
310 	return to_ionic_qp_state(to_state) |
311 		(to_ionic_qp_state(from_state) << 4);
312 }
313 
314 /* fw abi v1 */
315 
316 /* data payload part of v1 wqe */
317 union ionic_v1_pld {
318 	struct ionic_sge	sgl[2];
319 	__be32			spec32[8];
320 	__be16			spec16[16];
321 	__u8			data[32];
322 };
323 
324 /* completion queue v1 cqe */
325 struct ionic_v1_cqe {
326 	union {
327 		struct {
328 			__be16		cmd_idx;
329 			__u8		cmd_op;
330 			__u8		rsvd[17];
331 			__le16		old_sq_cindex;
332 			__le16		old_rq_cq_cindex;
333 		} admin;
334 		struct {
335 			__le64		wqe_idx_timestamp;
336 			__be32		src_qpn_op;
337 			__u8		src_mac[6];
338 			__be16		vlan_tag;
339 			__be32		imm_data_rkey;
340 		} recv;
341 		struct {
342 			__u8		rsvd[4];
343 			__be32		msg_msn;
344 			__u8		rsvd2[8];
345 			__le64		npg_wqe_idx_timestamp;
346 		} send;
347 	};
348 	__be32				status_length;
349 	__be32				qid_type_flags;
350 };
351 
352 /* bits for cqe wqe_idx and timestamp */
353 enum ionic_v1_cqe_wqe_idx_timestamp_bits {
354 	IONIC_V1_CQE_WQE_IDX_MASK	= 0xffff,
355 	IONIC_V1_CQE_TIMESTAMP_SHIFT	= 16,
356 };
357 
358 /* bits for cqe recv */
359 enum ionic_v1_cqe_src_qpn_bits {
360 	IONIC_V1_CQE_RECV_QPN_MASK	= 0xffffff,
361 	IONIC_V1_CQE_RECV_OP_SHIFT	= 24,
362 
363 	/* MASK could be 0x3, but need 0x1f for makeshift values:
364 	 * OP_TYPE_RDMA_OPER_WITH_IMM, OP_TYPE_SEND_RCVD
365 	 */
366 	IONIC_V1_CQE_RECV_OP_MASK	= 0x1f,
367 	IONIC_V1_CQE_RECV_OP_SEND	= 0,
368 	IONIC_V1_CQE_RECV_OP_SEND_INV	= 1,
369 	IONIC_V1_CQE_RECV_OP_SEND_IMM	= 2,
370 	IONIC_V1_CQE_RECV_OP_RDMA_IMM	= 3,
371 
372 	IONIC_V1_CQE_RECV_IS_IPV4	= BIT(7 + IONIC_V1_CQE_RECV_OP_SHIFT),
373 	IONIC_V1_CQE_RECV_IS_VLAN	= BIT(6 + IONIC_V1_CQE_RECV_OP_SHIFT),
374 };
375 
376 /* bits for cqe qid_type_flags */
377 enum ionic_v1_cqe_qtf_bits {
378 	IONIC_V1_CQE_COLOR		= BIT(0),
379 	IONIC_V1_CQE_ERROR		= BIT(1),
380 	IONIC_V1_CQE_TYPE_SHIFT		= 5,
381 	IONIC_V1_CQE_TYPE_MASK		= 0x7,
382 	IONIC_V1_CQE_QID_SHIFT		= 8,
383 
384 	IONIC_V1_CQE_TYPE_ADMIN		= 0,
385 	IONIC_V1_CQE_TYPE_RECV		= 1,
386 	IONIC_V1_CQE_TYPE_SEND_MSN	= 2,
387 	IONIC_V1_CQE_TYPE_SEND_NPG	= 3,
388 };
389 
390 static inline bool ionic_v1_cqe_color(struct ionic_v1_cqe *cqe)
391 {
392 	return cqe->qid_type_flags & cpu_to_be32(IONIC_V1_CQE_COLOR);
393 }
394 
395 static inline bool ionic_v1_cqe_error(struct ionic_v1_cqe *cqe)
396 {
397 	return cqe->qid_type_flags & cpu_to_be32(IONIC_V1_CQE_ERROR);
398 }
399 
400 static inline bool ionic_v1_cqe_recv_is_ipv4(struct ionic_v1_cqe *cqe)
401 {
402 	return cqe->recv.src_qpn_op & cpu_to_be32(IONIC_V1_CQE_RECV_IS_IPV4);
403 }
404 
405 static inline bool ionic_v1_cqe_recv_is_vlan(struct ionic_v1_cqe *cqe)
406 {
407 	return cqe->recv.src_qpn_op & cpu_to_be32(IONIC_V1_CQE_RECV_IS_VLAN);
408 }
409 
410 static inline void ionic_v1_cqe_clean(struct ionic_v1_cqe *cqe)
411 {
412 	cqe->qid_type_flags |= cpu_to_be32(~0u << IONIC_V1_CQE_QID_SHIFT);
413 }
414 
415 static inline u32 ionic_v1_cqe_qtf(struct ionic_v1_cqe *cqe)
416 {
417 	return be32_to_cpu(cqe->qid_type_flags);
418 }
419 
420 static inline u8 ionic_v1_cqe_qtf_type(u32 qtf)
421 {
422 	return (qtf >> IONIC_V1_CQE_TYPE_SHIFT) & IONIC_V1_CQE_TYPE_MASK;
423 }
424 
425 static inline u32 ionic_v1_cqe_qtf_qid(u32 qtf)
426 {
427 	return qtf >> IONIC_V1_CQE_QID_SHIFT;
428 }
429 
430 /* v1 base wqe header */
431 struct ionic_v1_base_hdr {
432 	__le64				wqe_idx;
433 	__u8				op;
434 	__u8				num_sge_key;
435 	__be16				flags;
436 	__be32				imm_data_key;
437 };
438 
439 /* v1 receive wqe body */
440 struct ionic_v1_recv_bdy {
441 	__u8				rsvd[16];
442 	union ionic_v1_pld		pld;
443 };
444 
445 /* v1 send/rdma wqe body (common, has sgl) */
446 struct ionic_v1_common_bdy {
447 	union {
448 		struct {
449 			__be32		ah_id;
450 			__be32		dest_qpn;
451 			__be32		dest_qkey;
452 		} send;
453 		struct {
454 			__be32		remote_va_high;
455 			__be32		remote_va_low;
456 			__be32		remote_rkey;
457 		} rdma;
458 	};
459 	__be32				length;
460 	union ionic_v1_pld		pld;
461 };
462 
463 /* v1 atomic wqe body */
464 struct ionic_v1_atomic_bdy {
465 	__be32				remote_va_high;
466 	__be32				remote_va_low;
467 	__be32				remote_rkey;
468 	__be32				swap_add_high;
469 	__be32				swap_add_low;
470 	__be32				compare_high;
471 	__be32				compare_low;
472 	__u8				rsvd[4];
473 	struct ionic_sge		sge;
474 };
475 
476 /* v1 reg mr wqe body */
477 struct ionic_v1_reg_mr_bdy {
478 	__be64				va;
479 	__be64				length;
480 	__be64				offset;
481 	__be64				dma_addr;
482 	__be32				map_count;
483 	__be16				flags;
484 	__u8				dir_size_log2;
485 	__u8				page_size_log2;
486 	__u8				rsvd[8];
487 };
488 
489 /* v1 bind mw wqe body */
490 struct ionic_v1_bind_mw_bdy {
491 	__be64				va;
492 	__be64				length;
493 	__be32				lkey;
494 	__be16				flags;
495 	__u8				rsvd[26];
496 };
497 
498 /* v1 send/recv wqe */
499 struct ionic_v1_wqe {
500 	struct ionic_v1_base_hdr	base;
501 	union {
502 		struct ionic_v1_recv_bdy	recv;
503 		struct ionic_v1_common_bdy	common;
504 		struct ionic_v1_atomic_bdy	atomic;
505 		struct ionic_v1_reg_mr_bdy	reg_mr;
506 		struct ionic_v1_bind_mw_bdy	bind_mw;
507 	};
508 };
509 
510 /* queue pair v1 send opcodes */
511 enum ionic_v1_op {
512 	IONIC_V1_OP_SEND,
513 	IONIC_V1_OP_SEND_INV,
514 	IONIC_V1_OP_SEND_IMM,
515 	IONIC_V1_OP_RDMA_READ,
516 	IONIC_V1_OP_RDMA_WRITE,
517 	IONIC_V1_OP_RDMA_WRITE_IMM,
518 	IONIC_V1_OP_ATOMIC_CS,
519 	IONIC_V1_OP_ATOMIC_FA,
520 	IONIC_V1_OP_REG_MR,
521 	IONIC_V1_OP_LOCAL_INV,
522 	IONIC_V1_OP_BIND_MW,
523 
524 	/* flags */
525 	IONIC_V1_FLAG_FENCE		= BIT(0),
526 	IONIC_V1_FLAG_SOL		= BIT(1),
527 	IONIC_V1_FLAG_INL		= BIT(2),
528 	IONIC_V1_FLAG_SIG		= BIT(3),
529 
530 	/* flags last four bits for sgl spec format */
531 	IONIC_V1_FLAG_SPEC32		= (1u << 12),
532 	IONIC_V1_FLAG_SPEC16		= (2u << 12),
533 	IONIC_V1_SPEC_FIRST_SGE		= 2,
534 };
535 
536 /* queue pair v2 send opcodes */
537 enum ionic_v2_op {
538 	IONIC_V2_OPSL_OUT          = 0x20,
539 	IONIC_V2_OPSL_IMM          = 0x40,
540 	IONIC_V2_OPSL_INV          = 0x80,
541 
542 	IONIC_V2_OP_SEND           = 0x0 | IONIC_V2_OPSL_OUT,
543 	IONIC_V2_OP_SEND_IMM       = IONIC_V2_OP_SEND | IONIC_V2_OPSL_IMM,
544 	IONIC_V2_OP_SEND_INV       = IONIC_V2_OP_SEND | IONIC_V2_OPSL_INV,
545 
546 	IONIC_V2_OP_RDMA_WRITE     = 0x1 | IONIC_V2_OPSL_OUT,
547 	IONIC_V2_OP_RDMA_WRITE_IMM = IONIC_V2_OP_RDMA_WRITE | IONIC_V2_OPSL_IMM,
548 
549 	IONIC_V2_OP_RDMA_READ      = 0x2,
550 
551 	IONIC_V2_OP_ATOMIC_CS      = 0x4,
552 	IONIC_V2_OP_ATOMIC_FA      = 0x5,
553 	IONIC_V2_OP_REG_MR         = 0x6,
554 	IONIC_V2_OP_LOCAL_INV      = 0x7,
555 	IONIC_V2_OP_BIND_MW        = 0x8,
556 };
557 
558 static inline size_t ionic_v1_send_wqe_min_size(int min_sge, int min_data,
559 						int spec, bool expdb)
560 {
561 	size_t sz_wqe, sz_sgl, sz_data;
562 
563 	if (spec > IONIC_V1_SPEC_FIRST_SGE)
564 		min_sge += IONIC_V1_SPEC_FIRST_SGE;
565 
566 	if (expdb) {
567 		min_sge += 1;
568 		min_data += IONIC_EXP_DBELL_SZ;
569 	}
570 
571 	sz_wqe = sizeof(struct ionic_v1_wqe);
572 	sz_sgl = offsetof(struct ionic_v1_wqe, common.pld.sgl[min_sge]);
573 	sz_data = offsetof(struct ionic_v1_wqe, common.pld.data[min_data]);
574 
575 	if (sz_sgl > sz_wqe)
576 		sz_wqe = sz_sgl;
577 
578 	if (sz_data > sz_wqe)
579 		sz_wqe = sz_data;
580 
581 	return sz_wqe;
582 }
583 
584 static inline int ionic_v1_send_wqe_max_sge(u8 stride_log2, int spec,
585 					    bool expdb)
586 {
587 	struct ionic_sge *sge = (void *)(1ull << stride_log2);
588 	struct ionic_v1_wqe *wqe = (void *)0;
589 	int num_sge = 0;
590 
591 	if (expdb)
592 		sge -= 1;
593 
594 	if (spec > IONIC_V1_SPEC_FIRST_SGE)
595 		num_sge = IONIC_V1_SPEC_FIRST_SGE;
596 
597 	num_sge = sge - &wqe->common.pld.sgl[num_sge];
598 
599 	if (spec && num_sge > spec)
600 		num_sge = spec;
601 
602 	return num_sge;
603 }
604 
605 static inline int ionic_v1_send_wqe_max_data(u8 stride_log2, bool expdb)
606 {
607 	struct ionic_v1_wqe *wqe = (void *)0;
608 	__u8 *data = (void *)(1ull << stride_log2);
609 
610 	if (expdb)
611 		data -= IONIC_EXP_DBELL_SZ;
612 
613 	return data - wqe->common.pld.data;
614 }
615 
616 static inline size_t ionic_v1_recv_wqe_min_size(int min_sge, int spec,
617 						bool expdb)
618 {
619 	size_t sz_wqe, sz_sgl;
620 
621 	if (spec > IONIC_V1_SPEC_FIRST_SGE)
622 		min_sge += IONIC_V1_SPEC_FIRST_SGE;
623 
624 	if (expdb)
625 		min_sge += 1;
626 
627 	sz_wqe = sizeof(struct ionic_v1_wqe);
628 	sz_sgl = offsetof(struct ionic_v1_wqe, recv.pld.sgl[min_sge]);
629 
630 	if (sz_sgl > sz_wqe)
631 		sz_wqe = sz_sgl;
632 
633 	return sz_wqe;
634 }
635 
636 static inline int ionic_v1_recv_wqe_max_sge(u8 stride_log2, int spec,
637 					    bool expdb)
638 {
639 	struct ionic_sge *sge = (void *)(1ull << stride_log2);
640 	struct ionic_v1_wqe *wqe = (void *)0;
641 	int num_sge = 0;
642 
643 	if (expdb)
644 		sge -= 1;
645 
646 	if (spec > IONIC_V1_SPEC_FIRST_SGE)
647 		num_sge = IONIC_V1_SPEC_FIRST_SGE;
648 
649 	num_sge = sge - &wqe->recv.pld.sgl[num_sge];
650 
651 	if (spec && num_sge > spec)
652 		num_sge = spec;
653 
654 	return num_sge;
655 }
656 
657 static inline int ionic_v1_use_spec_sge(int min_sge, int spec)
658 {
659 	if (!spec || min_sge > spec)
660 		return 0;
661 
662 	if (min_sge <= IONIC_V1_SPEC_FIRST_SGE)
663 		return IONIC_V1_SPEC_FIRST_SGE;
664 
665 	return spec;
666 }
667 
668 struct ionic_admin_stats_hdr {
669 	__le64		dma_addr;
670 	__le32		length;
671 	__le32		id_ver;
672 	__u8		type_state;
673 } __packed;
674 
675 #define IONIC_ADMIN_STATS_HDRS_IN_V1_LEN 17
676 static_assert(sizeof(struct ionic_admin_stats_hdr) ==
677 	       IONIC_ADMIN_STATS_HDRS_IN_V1_LEN);
678 
679 struct ionic_admin_create_ah {
680 	__le64		dma_addr;
681 	__le32		length;
682 	__le32		pd_id;
683 	__le32		id_ver;
684 	__le16		dbid_flags;
685 	__u8		csum_profile;
686 	__u8		crypto;
687 } __packed;
688 
689 #define IONIC_ADMIN_CREATE_AH_IN_V1_LEN 24
690 static_assert(sizeof(struct ionic_admin_create_ah) ==
691 	       IONIC_ADMIN_CREATE_AH_IN_V1_LEN);
692 
693 struct ionic_admin_destroy_ah {
694 	__le32		ah_id;
695 } __packed;
696 
697 #define IONIC_ADMIN_DESTROY_AH_IN_V1_LEN 4
698 static_assert(sizeof(struct ionic_admin_destroy_ah) ==
699 	       IONIC_ADMIN_DESTROY_AH_IN_V1_LEN);
700 
701 struct ionic_admin_query_ah {
702 	__le64		dma_addr;
703 } __packed;
704 
705 #define IONIC_ADMIN_QUERY_AH_IN_V1_LEN 8
706 static_assert(sizeof(struct ionic_admin_query_ah) ==
707 	       IONIC_ADMIN_QUERY_AH_IN_V1_LEN);
708 
709 struct ionic_admin_create_mr {
710 	__le64		va;
711 	__le64		length;
712 	__le32		pd_id;
713 	__le32		id_ver;
714 	__le32		tbl_index;
715 	__le32		map_count;
716 	__le64		dma_addr;
717 	__le16		dbid_flags;
718 	__u8		pt_type;
719 	__u8		dir_size_log2;
720 	__u8		page_size_log2;
721 } __packed;
722 
723 #define IONIC_ADMIN_CREATE_MR_IN_V1_LEN 45
724 static_assert(sizeof(struct ionic_admin_create_mr) ==
725 	       IONIC_ADMIN_CREATE_MR_IN_V1_LEN);
726 
727 struct ionic_admin_destroy_mr {
728 	__le32		mr_id;
729 } __packed;
730 
731 #define IONIC_ADMIN_DESTROY_MR_IN_V1_LEN 4
732 static_assert(sizeof(struct ionic_admin_destroy_mr) ==
733 	       IONIC_ADMIN_DESTROY_MR_IN_V1_LEN);
734 
735 struct ionic_admin_create_cq {
736 	__le32		eq_id;
737 	__u8		depth_log2;
738 	__u8		stride_log2;
739 	__u8		dir_size_log2_rsvd;
740 	__u8		page_size_log2;
741 	__le32		cq_flags;
742 	__le32		id_ver;
743 	__le32		tbl_index;
744 	__le32		map_count;
745 	__le64		dma_addr;
746 	__le16		dbid_flags;
747 } __packed;
748 
749 #define IONIC_ADMIN_CREATE_CQ_IN_V1_LEN 34
750 static_assert(sizeof(struct ionic_admin_create_cq) ==
751 	       IONIC_ADMIN_CREATE_CQ_IN_V1_LEN);
752 
753 struct ionic_admin_destroy_cq {
754 	__le32		cq_id;
755 } __packed;
756 
757 #define IONIC_ADMIN_DESTROY_CQ_IN_V1_LEN 4
758 static_assert(sizeof(struct ionic_admin_destroy_cq) ==
759 	       IONIC_ADMIN_DESTROY_CQ_IN_V1_LEN);
760 
761 struct ionic_admin_create_qp {
762 	__le32		pd_id;
763 	__be32		priv_flags;
764 	__le32		sq_cq_id;
765 	__u8		sq_depth_log2;
766 	__u8		sq_stride_log2;
767 	__u8		sq_dir_size_log2_rsvd;
768 	__u8		sq_page_size_log2;
769 	__le32		sq_tbl_index_xrcd_id;
770 	__le32		sq_map_count;
771 	__le64		sq_dma_addr;
772 	__le32		rq_cq_id;
773 	__u8		rq_depth_log2;
774 	__u8		rq_stride_log2;
775 	__u8		rq_dir_size_log2_rsvd;
776 	__u8		rq_page_size_log2;
777 	__le32		rq_tbl_index_srq_id;
778 	__le32		rq_map_count;
779 	__le64		rq_dma_addr;
780 	__le32		id_ver;
781 	__le16		dbid_flags;
782 	__u8		type_state;
783 	__u8		rsvd;
784 } __packed;
785 
786 #define IONIC_ADMIN_CREATE_QP_IN_V1_LEN 64
787 static_assert(sizeof(struct ionic_admin_create_qp) ==
788 	       IONIC_ADMIN_CREATE_QP_IN_V1_LEN);
789 
790 struct ionic_admin_destroy_qp {
791 	__le32		qp_id;
792 } __packed;
793 
794 #define IONIC_ADMIN_DESTROY_QP_IN_V1_LEN 4
795 static_assert(sizeof(struct ionic_admin_destroy_qp) ==
796 	       IONIC_ADMIN_DESTROY_QP_IN_V1_LEN);
797 
798 struct ionic_admin_mod_qp {
799 	__be32		attr_mask;
800 	__u8		dcqcn_profile;
801 	__u8		tfp_csum_profile;
802 	__be16		access_flags;
803 	__le32		rq_psn;
804 	__le32		sq_psn;
805 	__le32		qkey_dest_qpn;
806 	__le32		rate_limit_kbps;
807 	__u8		pmtu;
808 	__u8		retry;
809 	__u8		rnr_timer;
810 	__u8		retry_timeout;
811 	__u8		rsq_depth;
812 	__u8		rrq_depth;
813 	__le16		pkey_id;
814 	__le32		ah_id_len;
815 	__u8		en_pcp;
816 	__u8		ip_dscp;
817 	__u8		rsvd2;
818 	__u8		type_state;
819 	union {
820 		struct {
821 			__le16		rsvd1;
822 		};
823 		__le32		rrq_index;
824 	};
825 	__le32		rsq_index;
826 	__le64		dma_addr;
827 	__le32		id_ver;
828 } __packed;
829 
830 #define IONIC_ADMIN_MODIFY_QP_IN_V1_LEN 60
831 static_assert(sizeof(struct ionic_admin_mod_qp) ==
832 	       IONIC_ADMIN_MODIFY_QP_IN_V1_LEN);
833 
834 struct ionic_admin_query_qp {
835 	__le64		hdr_dma_addr;
836 	__le64		sq_dma_addr;
837 	__le64		rq_dma_addr;
838 	__le32		ah_id;
839 	__le32		id_ver;
840 	__le16		dbid_flags;
841 } __packed;
842 
843 #define IONIC_ADMIN_QUERY_QP_IN_V1_LEN 34
844 static_assert(sizeof(struct ionic_admin_query_qp) ==
845 	       IONIC_ADMIN_QUERY_QP_IN_V1_LEN);
846 
847 #define ADMIN_WQE_STRIDE	64
848 #define ADMIN_WQE_HDR_LEN	4
849 
850 /* admin queue v1 wqe */
851 struct ionic_v1_admin_wqe {
852 	__u8				op;
853 	__u8				rsvd;
854 	__le16				len;
855 
856 	union {
857 		struct ionic_admin_stats_hdr stats;
858 		struct ionic_admin_create_ah create_ah;
859 		struct ionic_admin_destroy_ah destroy_ah;
860 		struct ionic_admin_query_ah query_ah;
861 		struct ionic_admin_create_mr create_mr;
862 		struct ionic_admin_destroy_mr destroy_mr;
863 		struct ionic_admin_create_cq create_cq;
864 		struct ionic_admin_destroy_cq destroy_cq;
865 		struct ionic_admin_create_qp create_qp;
866 		struct ionic_admin_destroy_qp destroy_qp;
867 		struct ionic_admin_mod_qp mod_qp;
868 		struct ionic_admin_query_qp query_qp;
869 	} cmd;
870 };
871 
872 /* side data for query qp */
873 struct ionic_v1_admin_query_qp_sq {
874 	__u8				rnr_timer;
875 	__u8				retry_timeout;
876 	__be16				access_perms_flags;
877 	__be16				rsvd;
878 	__be16				pkey_id;
879 	__be32				qkey_dest_qpn;
880 	__be32				rate_limit_kbps;
881 	__be32				rq_psn;
882 };
883 
884 struct ionic_v1_admin_query_qp_rq {
885 	__u8				state_pmtu;
886 	__u8				retry_rnrtry;
887 	__u8				rrq_depth;
888 	__u8				rsq_depth;
889 	__be32				sq_psn;
890 	__be16				access_perms_flags;
891 	__be16				rsvd;
892 };
893 
894 /* admin queue v1 opcodes */
895 enum ionic_v1_admin_op {
896 	IONIC_V1_ADMIN_NOOP,
897 	IONIC_V1_ADMIN_CREATE_CQ,
898 	IONIC_V1_ADMIN_CREATE_QP,
899 	IONIC_V1_ADMIN_CREATE_MR,
900 	IONIC_V1_ADMIN_STATS_HDRS,
901 	IONIC_V1_ADMIN_STATS_VALS,
902 	IONIC_V1_ADMIN_DESTROY_MR,
903 	IONIC_V1_ADMIN_RSVD_7,		/* RESIZE_CQ */
904 	IONIC_V1_ADMIN_DESTROY_CQ,
905 	IONIC_V1_ADMIN_MODIFY_QP,
906 	IONIC_V1_ADMIN_QUERY_QP,
907 	IONIC_V1_ADMIN_DESTROY_QP,
908 	IONIC_V1_ADMIN_DEBUG,
909 	IONIC_V1_ADMIN_CREATE_AH,
910 	IONIC_V1_ADMIN_QUERY_AH,
911 	IONIC_V1_ADMIN_MODIFY_DCQCN,
912 	IONIC_V1_ADMIN_DESTROY_AH,
913 	IONIC_V1_ADMIN_QP_STATS_HDRS,
914 	IONIC_V1_ADMIN_QP_STATS_VALS,
915 	IONIC_V1_ADMIN_OPCODES_MAX,
916 };
917 
918 /* admin queue v1 cqe status */
919 enum ionic_v1_admin_status {
920 	IONIC_V1_ASTS_OK,
921 	IONIC_V1_ASTS_BAD_CMD,
922 	IONIC_V1_ASTS_BAD_INDEX,
923 	IONIC_V1_ASTS_BAD_STATE,
924 	IONIC_V1_ASTS_BAD_TYPE,
925 	IONIC_V1_ASTS_BAD_ATTR,
926 	IONIC_V1_ASTS_MSG_TOO_BIG,
927 };
928 
929 /* event queue v1 eqe */
930 struct ionic_v1_eqe {
931 	__be32				evt;
932 };
933 
934 /* bits for cqe queue_type_flags */
935 enum ionic_v1_eqe_evt_bits {
936 	IONIC_V1_EQE_COLOR		= BIT(0),
937 	IONIC_V1_EQE_TYPE_SHIFT		= 1,
938 	IONIC_V1_EQE_TYPE_MASK		= 0x7,
939 	IONIC_V1_EQE_CODE_SHIFT		= 4,
940 	IONIC_V1_EQE_CODE_MASK		= 0xf,
941 	IONIC_V1_EQE_QID_SHIFT		= 8,
942 
943 	/* cq events */
944 	IONIC_V1_EQE_TYPE_CQ		= 0,
945 	/* cq normal events */
946 	IONIC_V1_EQE_CQ_NOTIFY		= 0,
947 	/* cq error events */
948 	IONIC_V1_EQE_CQ_ERR		= 8,
949 
950 	/* qp and srq events */
951 	IONIC_V1_EQE_TYPE_QP		= 1,
952 	/* qp normal events */
953 	IONIC_V1_EQE_SRQ_LEVEL		= 0,
954 	IONIC_V1_EQE_SQ_DRAIN		= 1,
955 	IONIC_V1_EQE_QP_COMM_EST	= 2,
956 	IONIC_V1_EQE_QP_LAST_WQE	= 3,
957 	/* qp error events */
958 	IONIC_V1_EQE_QP_ERR		= 8,
959 	IONIC_V1_EQE_QP_ERR_REQUEST	= 9,
960 	IONIC_V1_EQE_QP_ERR_ACCESS	= 10,
961 };
962 
963 enum ionic_tfp_csum_profiles {
964 	IONIC_TFP_CSUM_PROF_ETH_IPV4_UDP				= 0,
965 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP				= 1,
966 	IONIC_TFP_CSUM_PROF_ETH_IPV6_UDP				= 2,
967 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV6_UDP				= 3,
968 	IONIC_TFP_CSUM_PROF_IPV4_UDP_VXLAN_ETH_QTAG_IPV4_UDP		= 4,
969 	IONIC_TFP_CSUM_PROF_IPV4_UDP_VXLAN_ETH_QTAG_IPV6_UDP		= 5,
970 	IONIC_TFP_CSUM_PROF_QTAG_IPV4_UDP_VXLAN_ETH_QTAG_IPV4_UDP	= 6,
971 	IONIC_TFP_CSUM_PROF_QTAG_IPV4_UDP_VXLAN_ETH_QTAG_IPV6_UDP	= 7,
972 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP_ESP_IPV4_UDP		= 8,
973 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_ESP_UDP			= 9,
974 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP_ESP_UDP			= 10,
975 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV6_ESP_UDP			= 11,
976 	IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP_CSUM			= 12,
977 };
978 
979 static inline bool ionic_v1_eqe_color(struct ionic_v1_eqe *eqe)
980 {
981 	return eqe->evt & cpu_to_be32(IONIC_V1_EQE_COLOR);
982 }
983 
984 static inline u32 ionic_v1_eqe_evt(struct ionic_v1_eqe *eqe)
985 {
986 	return be32_to_cpu(eqe->evt);
987 }
988 
989 static inline u8 ionic_v1_eqe_evt_type(u32 evt)
990 {
991 	return (evt >> IONIC_V1_EQE_TYPE_SHIFT) & IONIC_V1_EQE_TYPE_MASK;
992 }
993 
994 static inline u8 ionic_v1_eqe_evt_code(u32 evt)
995 {
996 	return (evt >> IONIC_V1_EQE_CODE_SHIFT) & IONIC_V1_EQE_CODE_MASK;
997 }
998 
999 static inline u32 ionic_v1_eqe_evt_qid(u32 evt)
1000 {
1001 	return evt >> IONIC_V1_EQE_QID_SHIFT;
1002 }
1003 
1004 enum ionic_v1_stat_bits {
1005 	IONIC_V1_STAT_TYPE_SHIFT	= 28,
1006 	IONIC_V1_STAT_TYPE_NONE		= 0,
1007 	IONIC_V1_STAT_TYPE_8		= 1,
1008 	IONIC_V1_STAT_TYPE_LE16		= 2,
1009 	IONIC_V1_STAT_TYPE_LE32		= 3,
1010 	IONIC_V1_STAT_TYPE_LE64		= 4,
1011 	IONIC_V1_STAT_TYPE_BE16		= 5,
1012 	IONIC_V1_STAT_TYPE_BE32		= 6,
1013 	IONIC_V1_STAT_TYPE_BE64		= 7,
1014 	IONIC_V1_STAT_OFF_MASK		= BIT(IONIC_V1_STAT_TYPE_SHIFT) - 1,
1015 };
1016 
1017 struct ionic_v1_stat {
1018 	union {
1019 		__be32		be_type_off;
1020 		u32		type_off;
1021 	};
1022 	char			name[28];
1023 };
1024 
1025 static inline int ionic_v1_stat_type(struct ionic_v1_stat *hdr)
1026 {
1027 	return hdr->type_off >> IONIC_V1_STAT_TYPE_SHIFT;
1028 }
1029 
1030 static inline unsigned int ionic_v1_stat_off(struct ionic_v1_stat *hdr)
1031 {
1032 	return hdr->type_off & IONIC_V1_STAT_OFF_MASK;
1033 }
1034 
1035 #endif /* _IONIC_FW_H_ */
1036