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 __u64 wqe_id; 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 __u64 npg_wqe_id; 346 } send; 347 }; 348 __be32 status_length; 349 __be32 qid_type_flags; 350 }; 351 352 /* bits for cqe recv */ 353 enum ionic_v1_cqe_src_qpn_bits { 354 IONIC_V1_CQE_RECV_QPN_MASK = 0xffffff, 355 IONIC_V1_CQE_RECV_OP_SHIFT = 24, 356 357 /* MASK could be 0x3, but need 0x1f for makeshift values: 358 * OP_TYPE_RDMA_OPER_WITH_IMM, OP_TYPE_SEND_RCVD 359 */ 360 IONIC_V1_CQE_RECV_OP_MASK = 0x1f, 361 IONIC_V1_CQE_RECV_OP_SEND = 0, 362 IONIC_V1_CQE_RECV_OP_SEND_INV = 1, 363 IONIC_V1_CQE_RECV_OP_SEND_IMM = 2, 364 IONIC_V1_CQE_RECV_OP_RDMA_IMM = 3, 365 366 IONIC_V1_CQE_RECV_IS_IPV4 = BIT(7 + IONIC_V1_CQE_RECV_OP_SHIFT), 367 IONIC_V1_CQE_RECV_IS_VLAN = BIT(6 + IONIC_V1_CQE_RECV_OP_SHIFT), 368 }; 369 370 /* bits for cqe qid_type_flags */ 371 enum ionic_v1_cqe_qtf_bits { 372 IONIC_V1_CQE_COLOR = BIT(0), 373 IONIC_V1_CQE_ERROR = BIT(1), 374 IONIC_V1_CQE_TYPE_SHIFT = 5, 375 IONIC_V1_CQE_TYPE_MASK = 0x7, 376 IONIC_V1_CQE_QID_SHIFT = 8, 377 378 IONIC_V1_CQE_TYPE_ADMIN = 0, 379 IONIC_V1_CQE_TYPE_RECV = 1, 380 IONIC_V1_CQE_TYPE_SEND_MSN = 2, 381 IONIC_V1_CQE_TYPE_SEND_NPG = 3, 382 }; 383 384 static inline bool ionic_v1_cqe_color(struct ionic_v1_cqe *cqe) 385 { 386 return cqe->qid_type_flags & cpu_to_be32(IONIC_V1_CQE_COLOR); 387 } 388 389 static inline bool ionic_v1_cqe_error(struct ionic_v1_cqe *cqe) 390 { 391 return cqe->qid_type_flags & cpu_to_be32(IONIC_V1_CQE_ERROR); 392 } 393 394 static inline bool ionic_v1_cqe_recv_is_ipv4(struct ionic_v1_cqe *cqe) 395 { 396 return cqe->recv.src_qpn_op & cpu_to_be32(IONIC_V1_CQE_RECV_IS_IPV4); 397 } 398 399 static inline bool ionic_v1_cqe_recv_is_vlan(struct ionic_v1_cqe *cqe) 400 { 401 return cqe->recv.src_qpn_op & cpu_to_be32(IONIC_V1_CQE_RECV_IS_VLAN); 402 } 403 404 static inline void ionic_v1_cqe_clean(struct ionic_v1_cqe *cqe) 405 { 406 cqe->qid_type_flags |= cpu_to_be32(~0u << IONIC_V1_CQE_QID_SHIFT); 407 } 408 409 static inline u32 ionic_v1_cqe_qtf(struct ionic_v1_cqe *cqe) 410 { 411 return be32_to_cpu(cqe->qid_type_flags); 412 } 413 414 static inline u8 ionic_v1_cqe_qtf_type(u32 qtf) 415 { 416 return (qtf >> IONIC_V1_CQE_TYPE_SHIFT) & IONIC_V1_CQE_TYPE_MASK; 417 } 418 419 static inline u32 ionic_v1_cqe_qtf_qid(u32 qtf) 420 { 421 return qtf >> IONIC_V1_CQE_QID_SHIFT; 422 } 423 424 /* v1 base wqe header */ 425 struct ionic_v1_base_hdr { 426 __u64 wqe_id; 427 __u8 op; 428 __u8 num_sge_key; 429 __be16 flags; 430 __be32 imm_data_key; 431 }; 432 433 /* v1 receive wqe body */ 434 struct ionic_v1_recv_bdy { 435 __u8 rsvd[16]; 436 union ionic_v1_pld pld; 437 }; 438 439 /* v1 send/rdma wqe body (common, has sgl) */ 440 struct ionic_v1_common_bdy { 441 union { 442 struct { 443 __be32 ah_id; 444 __be32 dest_qpn; 445 __be32 dest_qkey; 446 } send; 447 struct { 448 __be32 remote_va_high; 449 __be32 remote_va_low; 450 __be32 remote_rkey; 451 } rdma; 452 }; 453 __be32 length; 454 union ionic_v1_pld pld; 455 }; 456 457 /* v1 atomic wqe body */ 458 struct ionic_v1_atomic_bdy { 459 __be32 remote_va_high; 460 __be32 remote_va_low; 461 __be32 remote_rkey; 462 __be32 swap_add_high; 463 __be32 swap_add_low; 464 __be32 compare_high; 465 __be32 compare_low; 466 __u8 rsvd[4]; 467 struct ionic_sge sge; 468 }; 469 470 /* v1 reg mr wqe body */ 471 struct ionic_v1_reg_mr_bdy { 472 __be64 va; 473 __be64 length; 474 __be64 offset; 475 __be64 dma_addr; 476 __be32 map_count; 477 __be16 flags; 478 __u8 dir_size_log2; 479 __u8 page_size_log2; 480 __u8 rsvd[8]; 481 }; 482 483 /* v1 bind mw wqe body */ 484 struct ionic_v1_bind_mw_bdy { 485 __be64 va; 486 __be64 length; 487 __be32 lkey; 488 __be16 flags; 489 __u8 rsvd[26]; 490 }; 491 492 /* v1 send/recv wqe */ 493 struct ionic_v1_wqe { 494 struct ionic_v1_base_hdr base; 495 union { 496 struct ionic_v1_recv_bdy recv; 497 struct ionic_v1_common_bdy common; 498 struct ionic_v1_atomic_bdy atomic; 499 struct ionic_v1_reg_mr_bdy reg_mr; 500 struct ionic_v1_bind_mw_bdy bind_mw; 501 }; 502 }; 503 504 /* queue pair v1 send opcodes */ 505 enum ionic_v1_op { 506 IONIC_V1_OP_SEND, 507 IONIC_V1_OP_SEND_INV, 508 IONIC_V1_OP_SEND_IMM, 509 IONIC_V1_OP_RDMA_READ, 510 IONIC_V1_OP_RDMA_WRITE, 511 IONIC_V1_OP_RDMA_WRITE_IMM, 512 IONIC_V1_OP_ATOMIC_CS, 513 IONIC_V1_OP_ATOMIC_FA, 514 IONIC_V1_OP_REG_MR, 515 IONIC_V1_OP_LOCAL_INV, 516 IONIC_V1_OP_BIND_MW, 517 518 /* flags */ 519 IONIC_V1_FLAG_FENCE = BIT(0), 520 IONIC_V1_FLAG_SOL = BIT(1), 521 IONIC_V1_FLAG_INL = BIT(2), 522 IONIC_V1_FLAG_SIG = BIT(3), 523 524 /* flags last four bits for sgl spec format */ 525 IONIC_V1_FLAG_SPEC32 = (1u << 12), 526 IONIC_V1_FLAG_SPEC16 = (2u << 12), 527 IONIC_V1_SPEC_FIRST_SGE = 2, 528 }; 529 530 /* queue pair v2 send opcodes */ 531 enum ionic_v2_op { 532 IONIC_V2_OPSL_OUT = 0x20, 533 IONIC_V2_OPSL_IMM = 0x40, 534 IONIC_V2_OPSL_INV = 0x80, 535 536 IONIC_V2_OP_SEND = 0x0 | IONIC_V2_OPSL_OUT, 537 IONIC_V2_OP_SEND_IMM = IONIC_V2_OP_SEND | IONIC_V2_OPSL_IMM, 538 IONIC_V2_OP_SEND_INV = IONIC_V2_OP_SEND | IONIC_V2_OPSL_INV, 539 540 IONIC_V2_OP_RDMA_WRITE = 0x1 | IONIC_V2_OPSL_OUT, 541 IONIC_V2_OP_RDMA_WRITE_IMM = IONIC_V2_OP_RDMA_WRITE | IONIC_V2_OPSL_IMM, 542 543 IONIC_V2_OP_RDMA_READ = 0x2, 544 545 IONIC_V2_OP_ATOMIC_CS = 0x4, 546 IONIC_V2_OP_ATOMIC_FA = 0x5, 547 IONIC_V2_OP_REG_MR = 0x6, 548 IONIC_V2_OP_LOCAL_INV = 0x7, 549 IONIC_V2_OP_BIND_MW = 0x8, 550 }; 551 552 static inline size_t ionic_v1_send_wqe_min_size(int min_sge, int min_data, 553 int spec, bool expdb) 554 { 555 size_t sz_wqe, sz_sgl, sz_data; 556 557 if (spec > IONIC_V1_SPEC_FIRST_SGE) 558 min_sge += IONIC_V1_SPEC_FIRST_SGE; 559 560 if (expdb) { 561 min_sge += 1; 562 min_data += IONIC_EXP_DBELL_SZ; 563 } 564 565 sz_wqe = sizeof(struct ionic_v1_wqe); 566 sz_sgl = offsetof(struct ionic_v1_wqe, common.pld.sgl[min_sge]); 567 sz_data = offsetof(struct ionic_v1_wqe, common.pld.data[min_data]); 568 569 if (sz_sgl > sz_wqe) 570 sz_wqe = sz_sgl; 571 572 if (sz_data > sz_wqe) 573 sz_wqe = sz_data; 574 575 return sz_wqe; 576 } 577 578 static inline int ionic_v1_send_wqe_max_sge(u8 stride_log2, int spec, 579 bool expdb) 580 { 581 struct ionic_sge *sge = (void *)(1ull << stride_log2); 582 struct ionic_v1_wqe *wqe = (void *)0; 583 int num_sge = 0; 584 585 if (expdb) 586 sge -= 1; 587 588 if (spec > IONIC_V1_SPEC_FIRST_SGE) 589 num_sge = IONIC_V1_SPEC_FIRST_SGE; 590 591 num_sge = sge - &wqe->common.pld.sgl[num_sge]; 592 593 if (spec && num_sge > spec) 594 num_sge = spec; 595 596 return num_sge; 597 } 598 599 static inline int ionic_v1_send_wqe_max_data(u8 stride_log2, bool expdb) 600 { 601 struct ionic_v1_wqe *wqe = (void *)0; 602 __u8 *data = (void *)(1ull << stride_log2); 603 604 if (expdb) 605 data -= IONIC_EXP_DBELL_SZ; 606 607 return data - wqe->common.pld.data; 608 } 609 610 static inline size_t ionic_v1_recv_wqe_min_size(int min_sge, int spec, 611 bool expdb) 612 { 613 size_t sz_wqe, sz_sgl; 614 615 if (spec > IONIC_V1_SPEC_FIRST_SGE) 616 min_sge += IONIC_V1_SPEC_FIRST_SGE; 617 618 if (expdb) 619 min_sge += 1; 620 621 sz_wqe = sizeof(struct ionic_v1_wqe); 622 sz_sgl = offsetof(struct ionic_v1_wqe, recv.pld.sgl[min_sge]); 623 624 if (sz_sgl > sz_wqe) 625 sz_wqe = sz_sgl; 626 627 return sz_wqe; 628 } 629 630 static inline int ionic_v1_recv_wqe_max_sge(u8 stride_log2, int spec, 631 bool expdb) 632 { 633 struct ionic_sge *sge = (void *)(1ull << stride_log2); 634 struct ionic_v1_wqe *wqe = (void *)0; 635 int num_sge = 0; 636 637 if (expdb) 638 sge -= 1; 639 640 if (spec > IONIC_V1_SPEC_FIRST_SGE) 641 num_sge = IONIC_V1_SPEC_FIRST_SGE; 642 643 num_sge = sge - &wqe->recv.pld.sgl[num_sge]; 644 645 if (spec && num_sge > spec) 646 num_sge = spec; 647 648 return num_sge; 649 } 650 651 static inline int ionic_v1_use_spec_sge(int min_sge, int spec) 652 { 653 if (!spec || min_sge > spec) 654 return 0; 655 656 if (min_sge <= IONIC_V1_SPEC_FIRST_SGE) 657 return IONIC_V1_SPEC_FIRST_SGE; 658 659 return spec; 660 } 661 662 struct ionic_admin_create_ah { 663 __le64 dma_addr; 664 __le32 length; 665 __le32 pd_id; 666 __le32 id_ver; 667 __le16 dbid_flags; 668 __u8 csum_profile; 669 __u8 crypto; 670 } __packed; 671 672 #define IONIC_ADMIN_CREATE_AH_IN_V1_LEN 24 673 static_assert(sizeof(struct ionic_admin_create_ah) == 674 IONIC_ADMIN_CREATE_AH_IN_V1_LEN); 675 676 struct ionic_admin_destroy_ah { 677 __le32 ah_id; 678 } __packed; 679 680 #define IONIC_ADMIN_DESTROY_AH_IN_V1_LEN 4 681 static_assert(sizeof(struct ionic_admin_destroy_ah) == 682 IONIC_ADMIN_DESTROY_AH_IN_V1_LEN); 683 684 struct ionic_admin_query_ah { 685 __le64 dma_addr; 686 } __packed; 687 688 #define IONIC_ADMIN_QUERY_AH_IN_V1_LEN 8 689 static_assert(sizeof(struct ionic_admin_query_ah) == 690 IONIC_ADMIN_QUERY_AH_IN_V1_LEN); 691 692 struct ionic_admin_create_mr { 693 __le64 va; 694 __le64 length; 695 __le32 pd_id; 696 __le32 id_ver; 697 __le32 tbl_index; 698 __le32 map_count; 699 __le64 dma_addr; 700 __le16 dbid_flags; 701 __u8 pt_type; 702 __u8 dir_size_log2; 703 __u8 page_size_log2; 704 } __packed; 705 706 #define IONIC_ADMIN_CREATE_MR_IN_V1_LEN 45 707 static_assert(sizeof(struct ionic_admin_create_mr) == 708 IONIC_ADMIN_CREATE_MR_IN_V1_LEN); 709 710 struct ionic_admin_destroy_mr { 711 __le32 mr_id; 712 } __packed; 713 714 #define IONIC_ADMIN_DESTROY_MR_IN_V1_LEN 4 715 static_assert(sizeof(struct ionic_admin_destroy_mr) == 716 IONIC_ADMIN_DESTROY_MR_IN_V1_LEN); 717 718 struct ionic_admin_create_cq { 719 __le32 eq_id; 720 __u8 depth_log2; 721 __u8 stride_log2; 722 __u8 dir_size_log2_rsvd; 723 __u8 page_size_log2; 724 __le32 cq_flags; 725 __le32 id_ver; 726 __le32 tbl_index; 727 __le32 map_count; 728 __le64 dma_addr; 729 __le16 dbid_flags; 730 } __packed; 731 732 #define IONIC_ADMIN_CREATE_CQ_IN_V1_LEN 34 733 static_assert(sizeof(struct ionic_admin_create_cq) == 734 IONIC_ADMIN_CREATE_CQ_IN_V1_LEN); 735 736 struct ionic_admin_destroy_cq { 737 __le32 cq_id; 738 } __packed; 739 740 #define IONIC_ADMIN_DESTROY_CQ_IN_V1_LEN 4 741 static_assert(sizeof(struct ionic_admin_destroy_cq) == 742 IONIC_ADMIN_DESTROY_CQ_IN_V1_LEN); 743 744 struct ionic_admin_create_qp { 745 __le32 pd_id; 746 __be32 priv_flags; 747 __le32 sq_cq_id; 748 __u8 sq_depth_log2; 749 __u8 sq_stride_log2; 750 __u8 sq_dir_size_log2_rsvd; 751 __u8 sq_page_size_log2; 752 __le32 sq_tbl_index_xrcd_id; 753 __le32 sq_map_count; 754 __le64 sq_dma_addr; 755 __le32 rq_cq_id; 756 __u8 rq_depth_log2; 757 __u8 rq_stride_log2; 758 __u8 rq_dir_size_log2_rsvd; 759 __u8 rq_page_size_log2; 760 __le32 rq_tbl_index_srq_id; 761 __le32 rq_map_count; 762 __le64 rq_dma_addr; 763 __le32 id_ver; 764 __le16 dbid_flags; 765 __u8 type_state; 766 __u8 rsvd; 767 } __packed; 768 769 #define IONIC_ADMIN_CREATE_QP_IN_V1_LEN 64 770 static_assert(sizeof(struct ionic_admin_create_qp) == 771 IONIC_ADMIN_CREATE_QP_IN_V1_LEN); 772 773 struct ionic_admin_destroy_qp { 774 __le32 qp_id; 775 } __packed; 776 777 #define IONIC_ADMIN_DESTROY_QP_IN_V1_LEN 4 778 static_assert(sizeof(struct ionic_admin_destroy_qp) == 779 IONIC_ADMIN_DESTROY_QP_IN_V1_LEN); 780 781 struct ionic_admin_mod_qp { 782 __be32 attr_mask; 783 __u8 dcqcn_profile; 784 __u8 tfp_csum_profile; 785 __be16 access_flags; 786 __le32 rq_psn; 787 __le32 sq_psn; 788 __le32 qkey_dest_qpn; 789 __le32 rate_limit_kbps; 790 __u8 pmtu; 791 __u8 retry; 792 __u8 rnr_timer; 793 __u8 retry_timeout; 794 __u8 rsq_depth; 795 __u8 rrq_depth; 796 __le16 pkey_id; 797 __le32 ah_id_len; 798 __u8 en_pcp; 799 __u8 ip_dscp; 800 __u8 rsvd2; 801 __u8 type_state; 802 union { 803 struct { 804 __le16 rsvd1; 805 }; 806 __le32 rrq_index; 807 }; 808 __le32 rsq_index; 809 __le64 dma_addr; 810 __le32 id_ver; 811 } __packed; 812 813 #define IONIC_ADMIN_MODIFY_QP_IN_V1_LEN 60 814 static_assert(sizeof(struct ionic_admin_mod_qp) == 815 IONIC_ADMIN_MODIFY_QP_IN_V1_LEN); 816 817 struct ionic_admin_query_qp { 818 __le64 hdr_dma_addr; 819 __le64 sq_dma_addr; 820 __le64 rq_dma_addr; 821 __le32 ah_id; 822 __le32 id_ver; 823 __le16 dbid_flags; 824 } __packed; 825 826 #define IONIC_ADMIN_QUERY_QP_IN_V1_LEN 34 827 static_assert(sizeof(struct ionic_admin_query_qp) == 828 IONIC_ADMIN_QUERY_QP_IN_V1_LEN); 829 830 #define ADMIN_WQE_STRIDE 64 831 #define ADMIN_WQE_HDR_LEN 4 832 833 /* admin queue v1 wqe */ 834 struct ionic_v1_admin_wqe { 835 __u8 op; 836 __u8 rsvd; 837 __le16 len; 838 839 union { 840 struct ionic_admin_create_ah create_ah; 841 struct ionic_admin_destroy_ah destroy_ah; 842 struct ionic_admin_query_ah query_ah; 843 struct ionic_admin_create_mr create_mr; 844 struct ionic_admin_destroy_mr destroy_mr; 845 struct ionic_admin_create_cq create_cq; 846 struct ionic_admin_destroy_cq destroy_cq; 847 struct ionic_admin_create_qp create_qp; 848 struct ionic_admin_destroy_qp destroy_qp; 849 struct ionic_admin_mod_qp mod_qp; 850 struct ionic_admin_query_qp query_qp; 851 } cmd; 852 }; 853 854 /* side data for query qp */ 855 struct ionic_v1_admin_query_qp_sq { 856 __u8 rnr_timer; 857 __u8 retry_timeout; 858 __be16 access_perms_flags; 859 __be16 rsvd; 860 __be16 pkey_id; 861 __be32 qkey_dest_qpn; 862 __be32 rate_limit_kbps; 863 __be32 rq_psn; 864 }; 865 866 struct ionic_v1_admin_query_qp_rq { 867 __u8 state_pmtu; 868 __u8 retry_rnrtry; 869 __u8 rrq_depth; 870 __u8 rsq_depth; 871 __be32 sq_psn; 872 __be16 access_perms_flags; 873 __be16 rsvd; 874 }; 875 876 /* admin queue v1 opcodes */ 877 enum ionic_v1_admin_op { 878 IONIC_V1_ADMIN_NOOP, 879 IONIC_V1_ADMIN_CREATE_CQ, 880 IONIC_V1_ADMIN_CREATE_QP, 881 IONIC_V1_ADMIN_CREATE_MR, 882 IONIC_V1_ADMIN_STATS_HDRS, 883 IONIC_V1_ADMIN_STATS_VALS, 884 IONIC_V1_ADMIN_DESTROY_MR, 885 IONIC_V1_ADMIN_RSVD_7, /* RESIZE_CQ */ 886 IONIC_V1_ADMIN_DESTROY_CQ, 887 IONIC_V1_ADMIN_MODIFY_QP, 888 IONIC_V1_ADMIN_QUERY_QP, 889 IONIC_V1_ADMIN_DESTROY_QP, 890 IONIC_V1_ADMIN_DEBUG, 891 IONIC_V1_ADMIN_CREATE_AH, 892 IONIC_V1_ADMIN_QUERY_AH, 893 IONIC_V1_ADMIN_MODIFY_DCQCN, 894 IONIC_V1_ADMIN_DESTROY_AH, 895 IONIC_V1_ADMIN_QP_STATS_HDRS, 896 IONIC_V1_ADMIN_QP_STATS_VALS, 897 IONIC_V1_ADMIN_OPCODES_MAX, 898 }; 899 900 /* admin queue v1 cqe status */ 901 enum ionic_v1_admin_status { 902 IONIC_V1_ASTS_OK, 903 IONIC_V1_ASTS_BAD_CMD, 904 IONIC_V1_ASTS_BAD_INDEX, 905 IONIC_V1_ASTS_BAD_STATE, 906 IONIC_V1_ASTS_BAD_TYPE, 907 IONIC_V1_ASTS_BAD_ATTR, 908 IONIC_V1_ASTS_MSG_TOO_BIG, 909 }; 910 911 /* event queue v1 eqe */ 912 struct ionic_v1_eqe { 913 __be32 evt; 914 }; 915 916 /* bits for cqe queue_type_flags */ 917 enum ionic_v1_eqe_evt_bits { 918 IONIC_V1_EQE_COLOR = BIT(0), 919 IONIC_V1_EQE_TYPE_SHIFT = 1, 920 IONIC_V1_EQE_TYPE_MASK = 0x7, 921 IONIC_V1_EQE_CODE_SHIFT = 4, 922 IONIC_V1_EQE_CODE_MASK = 0xf, 923 IONIC_V1_EQE_QID_SHIFT = 8, 924 925 /* cq events */ 926 IONIC_V1_EQE_TYPE_CQ = 0, 927 /* cq normal events */ 928 IONIC_V1_EQE_CQ_NOTIFY = 0, 929 /* cq error events */ 930 IONIC_V1_EQE_CQ_ERR = 8, 931 932 /* qp and srq events */ 933 IONIC_V1_EQE_TYPE_QP = 1, 934 /* qp normal events */ 935 IONIC_V1_EQE_SRQ_LEVEL = 0, 936 IONIC_V1_EQE_SQ_DRAIN = 1, 937 IONIC_V1_EQE_QP_COMM_EST = 2, 938 IONIC_V1_EQE_QP_LAST_WQE = 3, 939 /* qp error events */ 940 IONIC_V1_EQE_QP_ERR = 8, 941 IONIC_V1_EQE_QP_ERR_REQUEST = 9, 942 IONIC_V1_EQE_QP_ERR_ACCESS = 10, 943 }; 944 945 enum ionic_tfp_csum_profiles { 946 IONIC_TFP_CSUM_PROF_ETH_IPV4_UDP = 0, 947 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP = 1, 948 IONIC_TFP_CSUM_PROF_ETH_IPV6_UDP = 2, 949 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV6_UDP = 3, 950 IONIC_TFP_CSUM_PROF_IPV4_UDP_VXLAN_ETH_QTAG_IPV4_UDP = 4, 951 IONIC_TFP_CSUM_PROF_IPV4_UDP_VXLAN_ETH_QTAG_IPV6_UDP = 5, 952 IONIC_TFP_CSUM_PROF_QTAG_IPV4_UDP_VXLAN_ETH_QTAG_IPV4_UDP = 6, 953 IONIC_TFP_CSUM_PROF_QTAG_IPV4_UDP_VXLAN_ETH_QTAG_IPV6_UDP = 7, 954 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP_ESP_IPV4_UDP = 8, 955 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_ESP_UDP = 9, 956 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP_ESP_UDP = 10, 957 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV6_ESP_UDP = 11, 958 IONIC_TFP_CSUM_PROF_ETH_QTAG_IPV4_UDP_CSUM = 12, 959 }; 960 961 static inline bool ionic_v1_eqe_color(struct ionic_v1_eqe *eqe) 962 { 963 return eqe->evt & cpu_to_be32(IONIC_V1_EQE_COLOR); 964 } 965 966 static inline u32 ionic_v1_eqe_evt(struct ionic_v1_eqe *eqe) 967 { 968 return be32_to_cpu(eqe->evt); 969 } 970 971 static inline u8 ionic_v1_eqe_evt_type(u32 evt) 972 { 973 return (evt >> IONIC_V1_EQE_TYPE_SHIFT) & IONIC_V1_EQE_TYPE_MASK; 974 } 975 976 static inline u8 ionic_v1_eqe_evt_code(u32 evt) 977 { 978 return (evt >> IONIC_V1_EQE_CODE_SHIFT) & IONIC_V1_EQE_CODE_MASK; 979 } 980 981 static inline u32 ionic_v1_eqe_evt_qid(u32 evt) 982 { 983 return evt >> IONIC_V1_EQE_QID_SHIFT; 984 } 985 986 #endif /* _IONIC_FW_H_ */ 987