projects/linux·blob master · refs

1035 lines · 22.9 KiB

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
14enum ionic_mrid_bits {
15 IONIC_MRID_INDEX_SHIFT = 8,
16};
17
18static inline u32 ionic_mrid(u32 index, u8 key)
19{
20 return (index << IONIC_MRID_INDEX_SHIFT) | key;
21}
22
23static 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 */
31struct ionic_sge {
32 __be64 va;
33 __be32 len;
34 __be32 lkey;
35};
36
37/* admin queue mr type */
38enum 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
66static 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
91enum 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
110static 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
126static 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 */
167enum 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
185static 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 */
222enum 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
233static 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 */
253enum 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
263static 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
285static 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
307static 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 */
317union 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 */
325struct 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 */
353enum 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 */
359enum 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 */
377enum 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
390static 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
395static 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
400static 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
405static 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
410static 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
415static inline u32 ionic_v1_cqe_qtf(struct ionic_v1_cqe *cqe)
416{
417 return be32_to_cpu(cqe->qid_type_flags);
418}
419
420static 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
425static 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 */
431struct 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 */
440struct 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) */
446struct 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 */
464struct 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 */
477struct 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 */
490struct 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 */
499struct 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 */
511enum 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 */
537enum 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
558static 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
584static 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
605static 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
616static 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
636static 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
657static 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
668struct 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
676static_assert(sizeof(struct ionic_admin_stats_hdr) ==
677 IONIC_ADMIN_STATS_HDRS_IN_V1_LEN);
678
679struct 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
690static_assert(sizeof(struct ionic_admin_create_ah) ==
691 IONIC_ADMIN_CREATE_AH_IN_V1_LEN);
692
693struct ionic_admin_destroy_ah {
694 __le32 ah_id;
695} __packed;
696
697#define IONIC_ADMIN_DESTROY_AH_IN_V1_LEN 4
698static_assert(sizeof(struct ionic_admin_destroy_ah) ==
699 IONIC_ADMIN_DESTROY_AH_IN_V1_LEN);
700
701struct ionic_admin_query_ah {
702 __le64 dma_addr;
703} __packed;
704
705#define IONIC_ADMIN_QUERY_AH_IN_V1_LEN 8
706static_assert(sizeof(struct ionic_admin_query_ah) ==
707 IONIC_ADMIN_QUERY_AH_IN_V1_LEN);
708
709struct 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
724static_assert(sizeof(struct ionic_admin_create_mr) ==
725 IONIC_ADMIN_CREATE_MR_IN_V1_LEN);
726
727struct ionic_admin_destroy_mr {
728 __le32 mr_id;
729} __packed;
730
731#define IONIC_ADMIN_DESTROY_MR_IN_V1_LEN 4
732static_assert(sizeof(struct ionic_admin_destroy_mr) ==
733 IONIC_ADMIN_DESTROY_MR_IN_V1_LEN);
734
735struct 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
750static_assert(sizeof(struct ionic_admin_create_cq) ==
751 IONIC_ADMIN_CREATE_CQ_IN_V1_LEN);
752
753struct ionic_admin_destroy_cq {
754 __le32 cq_id;
755} __packed;
756
757#define IONIC_ADMIN_DESTROY_CQ_IN_V1_LEN 4
758static_assert(sizeof(struct ionic_admin_destroy_cq) ==
759 IONIC_ADMIN_DESTROY_CQ_IN_V1_LEN);
760
761struct 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
787static_assert(sizeof(struct ionic_admin_create_qp) ==
788 IONIC_ADMIN_CREATE_QP_IN_V1_LEN);
789
790struct ionic_admin_destroy_qp {
791 __le32 qp_id;
792} __packed;
793
794#define IONIC_ADMIN_DESTROY_QP_IN_V1_LEN 4
795static_assert(sizeof(struct ionic_admin_destroy_qp) ==
796 IONIC_ADMIN_DESTROY_QP_IN_V1_LEN);
797
798struct 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
831static_assert(sizeof(struct ionic_admin_mod_qp) ==
832 IONIC_ADMIN_MODIFY_QP_IN_V1_LEN);
833
834struct 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
844static_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 */
851struct 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 */
873struct 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
884struct 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 */
895enum 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 */
919enum 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 */
930struct ionic_v1_eqe {
931 __be32 evt;
932};
933
934/* bits for cqe queue_type_flags */
935enum 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
963enum 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
979static 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
984static inline u32 ionic_v1_eqe_evt(struct ionic_v1_eqe *eqe)
985{
986 return be32_to_cpu(eqe->evt);
987}
988
989static 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
994static 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
999static inline u32 ionic_v1_eqe_evt_qid(u32 evt)
1000{
1001 return evt >> IONIC_V1_EQE_QID_SHIFT;
1002}
1003
1004enum 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
1017struct ionic_v1_stat {
1018 union {
1019 __be32 be_type_off;
1020 u32 type_off;
1021 };
1022 char name[28];
1023};
1024
1025static inline int ionic_v1_stat_type(struct ionic_v1_stat *hdr)
1026{
1027 return hdr->type_off >> IONIC_V1_STAT_TYPE_SHIFT;
1028}
1029
1030static 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_ */