1551c46edSMustafa Ismail // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2551c46edSMustafa Ismail /* Copyright (c) 2015 - 2021 Intel Corporation */ 3551c46edSMustafa Ismail #include "osdep.h" 4551c46edSMustafa Ismail #include "status.h" 5551c46edSMustafa Ismail #include "defs.h" 6551c46edSMustafa Ismail #include "user.h" 7551c46edSMustafa Ismail #include "irdma.h" 8551c46edSMustafa Ismail 9551c46edSMustafa Ismail /** 10551c46edSMustafa Ismail * irdma_set_fragment - set fragment in wqe 11551c46edSMustafa Ismail * @wqe: wqe for setting fragment 12551c46edSMustafa Ismail * @offset: offset value 13551c46edSMustafa Ismail * @sge: sge length and stag 14551c46edSMustafa Ismail * @valid: The wqe valid 15551c46edSMustafa Ismail */ 16551c46edSMustafa Ismail static void irdma_set_fragment(__le64 *wqe, u32 offset, struct irdma_sge *sge, 17551c46edSMustafa Ismail u8 valid) 18551c46edSMustafa Ismail { 19551c46edSMustafa Ismail if (sge) { 20551c46edSMustafa Ismail set_64bit_val(wqe, offset, 21551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_TO, sge->tag_off)); 22551c46edSMustafa Ismail set_64bit_val(wqe, offset + 8, 23551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, valid) | 24551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_LEN, sge->len) | 25551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_STAG, sge->stag)); 26551c46edSMustafa Ismail } else { 27551c46edSMustafa Ismail set_64bit_val(wqe, offset, 0); 28551c46edSMustafa Ismail set_64bit_val(wqe, offset + 8, 29551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, valid)); 30551c46edSMustafa Ismail } 31551c46edSMustafa Ismail } 32551c46edSMustafa Ismail 33551c46edSMustafa Ismail /** 34551c46edSMustafa Ismail * irdma_set_fragment_gen_1 - set fragment in wqe 35551c46edSMustafa Ismail * @wqe: wqe for setting fragment 36551c46edSMustafa Ismail * @offset: offset value 37551c46edSMustafa Ismail * @sge: sge length and stag 38551c46edSMustafa Ismail * @valid: wqe valid flag 39551c46edSMustafa Ismail */ 40551c46edSMustafa Ismail static void irdma_set_fragment_gen_1(__le64 *wqe, u32 offset, 41551c46edSMustafa Ismail struct irdma_sge *sge, u8 valid) 42551c46edSMustafa Ismail { 43551c46edSMustafa Ismail if (sge) { 44551c46edSMustafa Ismail set_64bit_val(wqe, offset, 45551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_TO, sge->tag_off)); 46551c46edSMustafa Ismail set_64bit_val(wqe, offset + 8, 47551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, sge->len) | 48551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, sge->stag)); 49551c46edSMustafa Ismail } else { 50551c46edSMustafa Ismail set_64bit_val(wqe, offset, 0); 51551c46edSMustafa Ismail set_64bit_val(wqe, offset + 8, 0); 52551c46edSMustafa Ismail } 53551c46edSMustafa Ismail } 54551c46edSMustafa Ismail 55551c46edSMustafa Ismail /** 56551c46edSMustafa Ismail * irdma_nop_1 - insert a NOP wqe 57551c46edSMustafa Ismail * @qp: hw qp ptr 58551c46edSMustafa Ismail */ 59551c46edSMustafa Ismail static enum irdma_status_code irdma_nop_1(struct irdma_qp_uk *qp) 60551c46edSMustafa Ismail { 61551c46edSMustafa Ismail u64 hdr; 62551c46edSMustafa Ismail __le64 *wqe; 63551c46edSMustafa Ismail u32 wqe_idx; 64551c46edSMustafa Ismail bool signaled = false; 65551c46edSMustafa Ismail 66551c46edSMustafa Ismail if (!qp->sq_ring.head) 67551c46edSMustafa Ismail return IRDMA_ERR_PARAM; 68551c46edSMustafa Ismail 69551c46edSMustafa Ismail wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring); 70551c46edSMustafa Ismail wqe = qp->sq_base[wqe_idx].elem; 71551c46edSMustafa Ismail 72551c46edSMustafa Ismail qp->sq_wrtrk_array[wqe_idx].quanta = IRDMA_QP_WQE_MIN_QUANTA; 73551c46edSMustafa Ismail 74551c46edSMustafa Ismail set_64bit_val(wqe, 0, 0); 75551c46edSMustafa Ismail set_64bit_val(wqe, 8, 0); 76551c46edSMustafa Ismail set_64bit_val(wqe, 16, 0); 77551c46edSMustafa Ismail 78551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) | 79551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, signaled) | 80551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 81551c46edSMustafa Ismail 82551c46edSMustafa Ismail /* make sure WQE is written before valid bit is set */ 83551c46edSMustafa Ismail dma_wmb(); 84551c46edSMustafa Ismail 85551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 86551c46edSMustafa Ismail 87551c46edSMustafa Ismail return 0; 88551c46edSMustafa Ismail } 89551c46edSMustafa Ismail 90551c46edSMustafa Ismail /** 91551c46edSMustafa Ismail * irdma_clr_wqes - clear next 128 sq entries 92551c46edSMustafa Ismail * @qp: hw qp ptr 93551c46edSMustafa Ismail * @qp_wqe_idx: wqe_idx 94551c46edSMustafa Ismail */ 95551c46edSMustafa Ismail void irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx) 96551c46edSMustafa Ismail { 97551c46edSMustafa Ismail __le64 *wqe; 98551c46edSMustafa Ismail u32 wqe_idx; 99551c46edSMustafa Ismail 100551c46edSMustafa Ismail if (!(qp_wqe_idx & 0x7F)) { 101551c46edSMustafa Ismail wqe_idx = (qp_wqe_idx + 128) % qp->sq_ring.size; 102551c46edSMustafa Ismail wqe = qp->sq_base[wqe_idx].elem; 103551c46edSMustafa Ismail if (wqe_idx) 104551c46edSMustafa Ismail memset(wqe, qp->swqe_polarity ? 0 : 0xFF, 0x1000); 105551c46edSMustafa Ismail else 106551c46edSMustafa Ismail memset(wqe, qp->swqe_polarity ? 0xFF : 0, 0x1000); 107551c46edSMustafa Ismail } 108551c46edSMustafa Ismail } 109551c46edSMustafa Ismail 110551c46edSMustafa Ismail /** 111551c46edSMustafa Ismail * irdma_uk_qp_post_wr - ring doorbell 112551c46edSMustafa Ismail * @qp: hw qp ptr 113551c46edSMustafa Ismail */ 114551c46edSMustafa Ismail void irdma_uk_qp_post_wr(struct irdma_qp_uk *qp) 115551c46edSMustafa Ismail { 116551c46edSMustafa Ismail u64 temp; 117551c46edSMustafa Ismail u32 hw_sq_tail; 118551c46edSMustafa Ismail u32 sw_sq_head; 119551c46edSMustafa Ismail 120551c46edSMustafa Ismail /* valid bit is written and loads completed before reading shadow */ 121551c46edSMustafa Ismail mb(); 122551c46edSMustafa Ismail 123551c46edSMustafa Ismail /* read the doorbell shadow area */ 124551c46edSMustafa Ismail get_64bit_val(qp->shadow_area, 0, &temp); 125551c46edSMustafa Ismail 126551c46edSMustafa Ismail hw_sq_tail = (u32)FIELD_GET(IRDMA_QP_DBSA_HW_SQ_TAIL, temp); 127551c46edSMustafa Ismail sw_sq_head = IRDMA_RING_CURRENT_HEAD(qp->sq_ring); 128551c46edSMustafa Ismail if (sw_sq_head != qp->initial_ring.head) { 129551c46edSMustafa Ismail if (qp->push_dropped) { 130551c46edSMustafa Ismail writel(qp->qp_id, qp->wqe_alloc_db); 131551c46edSMustafa Ismail qp->push_dropped = false; 132551c46edSMustafa Ismail } else if (sw_sq_head != hw_sq_tail) { 133551c46edSMustafa Ismail if (sw_sq_head > qp->initial_ring.head) { 134551c46edSMustafa Ismail if (hw_sq_tail >= qp->initial_ring.head && 135551c46edSMustafa Ismail hw_sq_tail < sw_sq_head) 136551c46edSMustafa Ismail writel(qp->qp_id, qp->wqe_alloc_db); 137551c46edSMustafa Ismail } else { 138551c46edSMustafa Ismail if (hw_sq_tail >= qp->initial_ring.head || 139551c46edSMustafa Ismail hw_sq_tail < sw_sq_head) 140551c46edSMustafa Ismail writel(qp->qp_id, qp->wqe_alloc_db); 141551c46edSMustafa Ismail } 142551c46edSMustafa Ismail } 143551c46edSMustafa Ismail } 144551c46edSMustafa Ismail 145551c46edSMustafa Ismail qp->initial_ring.head = qp->sq_ring.head; 146551c46edSMustafa Ismail } 147551c46edSMustafa Ismail 148551c46edSMustafa Ismail /** 149551c46edSMustafa Ismail * irdma_qp_ring_push_db - ring qp doorbell 150551c46edSMustafa Ismail * @qp: hw qp ptr 151551c46edSMustafa Ismail * @wqe_idx: wqe index 152551c46edSMustafa Ismail */ 153551c46edSMustafa Ismail static void irdma_qp_ring_push_db(struct irdma_qp_uk *qp, u32 wqe_idx) 154551c46edSMustafa Ismail { 155551c46edSMustafa Ismail set_32bit_val(qp->push_db, 0, 156551c46edSMustafa Ismail FIELD_PREP(IRDMA_WQEALLOC_WQE_DESC_INDEX, wqe_idx >> 3) | qp->qp_id); 157551c46edSMustafa Ismail qp->initial_ring.head = qp->sq_ring.head; 158551c46edSMustafa Ismail qp->push_mode = true; 159551c46edSMustafa Ismail qp->push_dropped = false; 160551c46edSMustafa Ismail } 161551c46edSMustafa Ismail 162551c46edSMustafa Ismail void irdma_qp_push_wqe(struct irdma_qp_uk *qp, __le64 *wqe, u16 quanta, 163551c46edSMustafa Ismail u32 wqe_idx, bool post_sq) 164551c46edSMustafa Ismail { 165551c46edSMustafa Ismail __le64 *push; 166551c46edSMustafa Ismail 167551c46edSMustafa Ismail if (IRDMA_RING_CURRENT_HEAD(qp->initial_ring) != 168551c46edSMustafa Ismail IRDMA_RING_CURRENT_TAIL(qp->sq_ring) && 169551c46edSMustafa Ismail !qp->push_mode) { 170551c46edSMustafa Ismail if (post_sq) 171551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 172551c46edSMustafa Ismail } else { 173551c46edSMustafa Ismail push = (__le64 *)((uintptr_t)qp->push_wqe + 174551c46edSMustafa Ismail (wqe_idx & 0x7) * 0x20); 175551c46edSMustafa Ismail memcpy(push, wqe, quanta * IRDMA_QP_WQE_MIN_SIZE); 176551c46edSMustafa Ismail irdma_qp_ring_push_db(qp, wqe_idx); 177551c46edSMustafa Ismail } 178551c46edSMustafa Ismail } 179551c46edSMustafa Ismail 180551c46edSMustafa Ismail /** 181551c46edSMustafa Ismail * irdma_qp_get_next_send_wqe - pad with NOP if needed, return where next WR should go 182551c46edSMustafa Ismail * @qp: hw qp ptr 183551c46edSMustafa Ismail * @wqe_idx: return wqe index 184551c46edSMustafa Ismail * @quanta: size of WR in quanta 185551c46edSMustafa Ismail * @total_size: size of WR in bytes 186551c46edSMustafa Ismail * @info: info on WR 187551c46edSMustafa Ismail */ 188551c46edSMustafa Ismail __le64 *irdma_qp_get_next_send_wqe(struct irdma_qp_uk *qp, u32 *wqe_idx, 189551c46edSMustafa Ismail u16 quanta, u32 total_size, 190551c46edSMustafa Ismail struct irdma_post_sq_info *info) 191551c46edSMustafa Ismail { 192551c46edSMustafa Ismail __le64 *wqe; 193551c46edSMustafa Ismail __le64 *wqe_0 = NULL; 194551c46edSMustafa Ismail u32 nop_wqe_idx; 195551c46edSMustafa Ismail u16 avail_quanta; 196551c46edSMustafa Ismail u16 i; 197551c46edSMustafa Ismail 198551c46edSMustafa Ismail avail_quanta = qp->uk_attrs->max_hw_sq_chunk - 199551c46edSMustafa Ismail (IRDMA_RING_CURRENT_HEAD(qp->sq_ring) % 200551c46edSMustafa Ismail qp->uk_attrs->max_hw_sq_chunk); 201551c46edSMustafa Ismail if (quanta <= avail_quanta) { 202551c46edSMustafa Ismail /* WR fits in current chunk */ 203551c46edSMustafa Ismail if (quanta > IRDMA_SQ_RING_FREE_QUANTA(qp->sq_ring)) 204551c46edSMustafa Ismail return NULL; 205551c46edSMustafa Ismail } else { 206551c46edSMustafa Ismail /* Need to pad with NOP */ 207551c46edSMustafa Ismail if (quanta + avail_quanta > 208551c46edSMustafa Ismail IRDMA_SQ_RING_FREE_QUANTA(qp->sq_ring)) 209551c46edSMustafa Ismail return NULL; 210551c46edSMustafa Ismail 211551c46edSMustafa Ismail nop_wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring); 212551c46edSMustafa Ismail for (i = 0; i < avail_quanta; i++) { 213551c46edSMustafa Ismail irdma_nop_1(qp); 214551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_NOCHECK(qp->sq_ring); 215551c46edSMustafa Ismail } 216551c46edSMustafa Ismail if (qp->push_db && info->push_wqe) 217551c46edSMustafa Ismail irdma_qp_push_wqe(qp, qp->sq_base[nop_wqe_idx].elem, 218551c46edSMustafa Ismail avail_quanta, nop_wqe_idx, true); 219551c46edSMustafa Ismail } 220551c46edSMustafa Ismail 221551c46edSMustafa Ismail *wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring); 222551c46edSMustafa Ismail if (!*wqe_idx) 223551c46edSMustafa Ismail qp->swqe_polarity = !qp->swqe_polarity; 224551c46edSMustafa Ismail 225551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, quanta); 226551c46edSMustafa Ismail 227551c46edSMustafa Ismail wqe = qp->sq_base[*wqe_idx].elem; 228551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_1 && quanta == 1 && 229551c46edSMustafa Ismail (IRDMA_RING_CURRENT_HEAD(qp->sq_ring) & 1)) { 230551c46edSMustafa Ismail wqe_0 = qp->sq_base[IRDMA_RING_CURRENT_HEAD(qp->sq_ring)].elem; 231551c46edSMustafa Ismail wqe_0[3] = cpu_to_le64(FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity ? 0 : 1)); 232551c46edSMustafa Ismail } 233551c46edSMustafa Ismail qp->sq_wrtrk_array[*wqe_idx].wrid = info->wr_id; 234551c46edSMustafa Ismail qp->sq_wrtrk_array[*wqe_idx].wr_len = total_size; 235551c46edSMustafa Ismail qp->sq_wrtrk_array[*wqe_idx].quanta = quanta; 236551c46edSMustafa Ismail 237551c46edSMustafa Ismail return wqe; 238551c46edSMustafa Ismail } 239551c46edSMustafa Ismail 240551c46edSMustafa Ismail /** 241551c46edSMustafa Ismail * irdma_qp_get_next_recv_wqe - get next qp's rcv wqe 242551c46edSMustafa Ismail * @qp: hw qp ptr 243551c46edSMustafa Ismail * @wqe_idx: return wqe index 244551c46edSMustafa Ismail */ 245551c46edSMustafa Ismail __le64 *irdma_qp_get_next_recv_wqe(struct irdma_qp_uk *qp, u32 *wqe_idx) 246551c46edSMustafa Ismail { 247551c46edSMustafa Ismail __le64 *wqe; 248551c46edSMustafa Ismail enum irdma_status_code ret_code; 249551c46edSMustafa Ismail 250551c46edSMustafa Ismail if (IRDMA_RING_FULL_ERR(qp->rq_ring)) 251551c46edSMustafa Ismail return NULL; 252551c46edSMustafa Ismail 253551c46edSMustafa Ismail IRDMA_ATOMIC_RING_MOVE_HEAD(qp->rq_ring, *wqe_idx, ret_code); 254551c46edSMustafa Ismail if (ret_code) 255551c46edSMustafa Ismail return NULL; 256551c46edSMustafa Ismail 257551c46edSMustafa Ismail if (!*wqe_idx) 258551c46edSMustafa Ismail qp->rwqe_polarity = !qp->rwqe_polarity; 259551c46edSMustafa Ismail /* rq_wqe_size_multiplier is no of 32 byte quanta in one rq wqe */ 260551c46edSMustafa Ismail wqe = qp->rq_base[*wqe_idx * qp->rq_wqe_size_multiplier].elem; 261551c46edSMustafa Ismail 262551c46edSMustafa Ismail return wqe; 263551c46edSMustafa Ismail } 264551c46edSMustafa Ismail 265551c46edSMustafa Ismail /** 266551c46edSMustafa Ismail * irdma_uk_rdma_write - rdma write operation 267551c46edSMustafa Ismail * @qp: hw qp ptr 268551c46edSMustafa Ismail * @info: post sq information 269551c46edSMustafa Ismail * @post_sq: flag to post sq 270551c46edSMustafa Ismail */ 271551c46edSMustafa Ismail enum irdma_status_code irdma_uk_rdma_write(struct irdma_qp_uk *qp, 272551c46edSMustafa Ismail struct irdma_post_sq_info *info, 273551c46edSMustafa Ismail bool post_sq) 274551c46edSMustafa Ismail { 275551c46edSMustafa Ismail u64 hdr; 276551c46edSMustafa Ismail __le64 *wqe; 277551c46edSMustafa Ismail struct irdma_rdma_write *op_info; 278551c46edSMustafa Ismail u32 i, wqe_idx; 279551c46edSMustafa Ismail u32 total_size = 0, byte_off; 280551c46edSMustafa Ismail enum irdma_status_code ret_code; 281551c46edSMustafa Ismail u32 frag_cnt, addl_frag_cnt; 282551c46edSMustafa Ismail bool read_fence = false; 283551c46edSMustafa Ismail u16 quanta; 284551c46edSMustafa Ismail 285551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 286551c46edSMustafa Ismail 287551c46edSMustafa Ismail op_info = &info->op.rdma_write; 288551c46edSMustafa Ismail if (op_info->num_lo_sges > qp->max_sq_frag_cnt) 289551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 290551c46edSMustafa Ismail 291551c46edSMustafa Ismail for (i = 0; i < op_info->num_lo_sges; i++) 292551c46edSMustafa Ismail total_size += op_info->lo_sg_list[i].len; 293551c46edSMustafa Ismail 294551c46edSMustafa Ismail read_fence |= info->read_fence; 295551c46edSMustafa Ismail 296551c46edSMustafa Ismail if (info->imm_data_valid) 297551c46edSMustafa Ismail frag_cnt = op_info->num_lo_sges + 1; 298551c46edSMustafa Ismail else 299551c46edSMustafa Ismail frag_cnt = op_info->num_lo_sges; 300551c46edSMustafa Ismail addl_frag_cnt = frag_cnt > 1 ? (frag_cnt - 1) : 0; 301551c46edSMustafa Ismail ret_code = irdma_fragcnt_to_quanta_sq(frag_cnt, &quanta); 302551c46edSMustafa Ismail if (ret_code) 303551c46edSMustafa Ismail return ret_code; 304551c46edSMustafa Ismail 305551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size, 306551c46edSMustafa Ismail info); 307551c46edSMustafa Ismail if (!wqe) 308551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 309551c46edSMustafa Ismail 310551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 311551c46edSMustafa Ismail 312551c46edSMustafa Ismail set_64bit_val(wqe, 16, 313551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.tag_off)); 314551c46edSMustafa Ismail 315551c46edSMustafa Ismail if (info->imm_data_valid) { 316551c46edSMustafa Ismail set_64bit_val(wqe, 0, 317551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); 318551c46edSMustafa Ismail i = 0; 319551c46edSMustafa Ismail } else { 320551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, 0, 321551c46edSMustafa Ismail op_info->lo_sg_list, 322551c46edSMustafa Ismail qp->swqe_polarity); 323551c46edSMustafa Ismail i = 1; 324551c46edSMustafa Ismail } 325551c46edSMustafa Ismail 326551c46edSMustafa Ismail for (byte_off = 32; i < op_info->num_lo_sges; i++) { 327551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, 328551c46edSMustafa Ismail &op_info->lo_sg_list[i], 329551c46edSMustafa Ismail qp->swqe_polarity); 330551c46edSMustafa Ismail byte_off += 16; 331551c46edSMustafa Ismail } 332551c46edSMustafa Ismail 333551c46edSMustafa Ismail /* if not an odd number set valid bit in next fragment */ 334551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(frag_cnt & 0x01) && 335551c46edSMustafa Ismail frag_cnt) { 336551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL, 337551c46edSMustafa Ismail qp->swqe_polarity); 338551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_2) 339551c46edSMustafa Ismail ++addl_frag_cnt; 340551c46edSMustafa Ismail } 341551c46edSMustafa Ismail 342551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.stag) | 343551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | 344551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid) | 345551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt) | 346551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) | 347551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) | 348551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) | 349551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) | 350551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 351551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 352551c46edSMustafa Ismail 353551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 354551c46edSMustafa Ismail 355551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 356551c46edSMustafa Ismail if (info->push_wqe) { 357551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq); 358551c46edSMustafa Ismail } else { 359551c46edSMustafa Ismail if (post_sq) 360551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 361551c46edSMustafa Ismail } 362551c46edSMustafa Ismail 363551c46edSMustafa Ismail return 0; 364551c46edSMustafa Ismail } 365551c46edSMustafa Ismail 366551c46edSMustafa Ismail /** 367551c46edSMustafa Ismail * irdma_uk_rdma_read - rdma read command 368551c46edSMustafa Ismail * @qp: hw qp ptr 369551c46edSMustafa Ismail * @info: post sq information 370551c46edSMustafa Ismail * @inv_stag: flag for inv_stag 371551c46edSMustafa Ismail * @post_sq: flag to post sq 372551c46edSMustafa Ismail */ 373551c46edSMustafa Ismail enum irdma_status_code irdma_uk_rdma_read(struct irdma_qp_uk *qp, 374551c46edSMustafa Ismail struct irdma_post_sq_info *info, 375551c46edSMustafa Ismail bool inv_stag, bool post_sq) 376551c46edSMustafa Ismail { 377551c46edSMustafa Ismail struct irdma_rdma_read *op_info; 378551c46edSMustafa Ismail enum irdma_status_code ret_code; 379551c46edSMustafa Ismail u32 i, byte_off, total_size = 0; 380551c46edSMustafa Ismail bool local_fence = false; 381551c46edSMustafa Ismail u32 addl_frag_cnt; 382551c46edSMustafa Ismail __le64 *wqe; 383551c46edSMustafa Ismail u32 wqe_idx; 384551c46edSMustafa Ismail u16 quanta; 385551c46edSMustafa Ismail u64 hdr; 386551c46edSMustafa Ismail 387551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 388551c46edSMustafa Ismail 389551c46edSMustafa Ismail op_info = &info->op.rdma_read; 390551c46edSMustafa Ismail if (qp->max_sq_frag_cnt < op_info->num_lo_sges) 391551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 392551c46edSMustafa Ismail 393551c46edSMustafa Ismail for (i = 0; i < op_info->num_lo_sges; i++) 394551c46edSMustafa Ismail total_size += op_info->lo_sg_list[i].len; 395551c46edSMustafa Ismail 396551c46edSMustafa Ismail ret_code = irdma_fragcnt_to_quanta_sq(op_info->num_lo_sges, &quanta); 397551c46edSMustafa Ismail if (ret_code) 398551c46edSMustafa Ismail return ret_code; 399551c46edSMustafa Ismail 400551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size, 401551c46edSMustafa Ismail info); 402551c46edSMustafa Ismail if (!wqe) 403551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 404551c46edSMustafa Ismail 405551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 406551c46edSMustafa Ismail 407551c46edSMustafa Ismail addl_frag_cnt = op_info->num_lo_sges > 1 ? 408551c46edSMustafa Ismail (op_info->num_lo_sges - 1) : 0; 409551c46edSMustafa Ismail local_fence |= info->local_fence; 410551c46edSMustafa Ismail 411551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, 0, op_info->lo_sg_list, 412551c46edSMustafa Ismail qp->swqe_polarity); 413551c46edSMustafa Ismail for (i = 1, byte_off = 32; i < op_info->num_lo_sges; ++i) { 414551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, 415551c46edSMustafa Ismail &op_info->lo_sg_list[i], 416551c46edSMustafa Ismail qp->swqe_polarity); 417551c46edSMustafa Ismail byte_off += 16; 418551c46edSMustafa Ismail } 419551c46edSMustafa Ismail 420551c46edSMustafa Ismail /* if not an odd number set valid bit in next fragment */ 421551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && 422551c46edSMustafa Ismail !(op_info->num_lo_sges & 0x01) && op_info->num_lo_sges) { 423551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL, 424551c46edSMustafa Ismail qp->swqe_polarity); 425551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_2) 426551c46edSMustafa Ismail ++addl_frag_cnt; 427551c46edSMustafa Ismail } 428551c46edSMustafa Ismail set_64bit_val(wqe, 16, 429551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.tag_off)); 430551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.stag) | 431551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) | 432551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) | 433551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, 434551c46edSMustafa Ismail (inv_stag ? IRDMAQP_OP_RDMA_READ_LOC_INV : IRDMAQP_OP_RDMA_READ)) | 435551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) | 436551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) | 437551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) | 438551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 439551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 440551c46edSMustafa Ismail 441551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 442551c46edSMustafa Ismail 443551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 444551c46edSMustafa Ismail if (info->push_wqe) { 445551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq); 446551c46edSMustafa Ismail } else { 447551c46edSMustafa Ismail if (post_sq) 448551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 449551c46edSMustafa Ismail } 450551c46edSMustafa Ismail 451551c46edSMustafa Ismail return 0; 452551c46edSMustafa Ismail } 453551c46edSMustafa Ismail 454551c46edSMustafa Ismail /** 455551c46edSMustafa Ismail * irdma_uk_send - rdma send command 456551c46edSMustafa Ismail * @qp: hw qp ptr 457551c46edSMustafa Ismail * @info: post sq information 458551c46edSMustafa Ismail * @post_sq: flag to post sq 459551c46edSMustafa Ismail */ 460551c46edSMustafa Ismail enum irdma_status_code irdma_uk_send(struct irdma_qp_uk *qp, 461551c46edSMustafa Ismail struct irdma_post_sq_info *info, 462551c46edSMustafa Ismail bool post_sq) 463551c46edSMustafa Ismail { 464551c46edSMustafa Ismail __le64 *wqe; 465551c46edSMustafa Ismail struct irdma_post_send *op_info; 466551c46edSMustafa Ismail u64 hdr; 467551c46edSMustafa Ismail u32 i, wqe_idx, total_size = 0, byte_off; 468551c46edSMustafa Ismail enum irdma_status_code ret_code; 469551c46edSMustafa Ismail u32 frag_cnt, addl_frag_cnt; 470551c46edSMustafa Ismail bool read_fence = false; 471551c46edSMustafa Ismail u16 quanta; 472551c46edSMustafa Ismail 473551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 474551c46edSMustafa Ismail 475551c46edSMustafa Ismail op_info = &info->op.send; 476551c46edSMustafa Ismail if (qp->max_sq_frag_cnt < op_info->num_sges) 477551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 478551c46edSMustafa Ismail 479551c46edSMustafa Ismail for (i = 0; i < op_info->num_sges; i++) 480551c46edSMustafa Ismail total_size += op_info->sg_list[i].len; 481551c46edSMustafa Ismail 482551c46edSMustafa Ismail if (info->imm_data_valid) 483551c46edSMustafa Ismail frag_cnt = op_info->num_sges + 1; 484551c46edSMustafa Ismail else 485551c46edSMustafa Ismail frag_cnt = op_info->num_sges; 486551c46edSMustafa Ismail ret_code = irdma_fragcnt_to_quanta_sq(frag_cnt, &quanta); 487551c46edSMustafa Ismail if (ret_code) 488551c46edSMustafa Ismail return ret_code; 489551c46edSMustafa Ismail 490551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size, 491551c46edSMustafa Ismail info); 492551c46edSMustafa Ismail if (!wqe) 493551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 494551c46edSMustafa Ismail 495551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 496551c46edSMustafa Ismail 497551c46edSMustafa Ismail read_fence |= info->read_fence; 498551c46edSMustafa Ismail addl_frag_cnt = frag_cnt > 1 ? (frag_cnt - 1) : 0; 499551c46edSMustafa Ismail if (info->imm_data_valid) { 500551c46edSMustafa Ismail set_64bit_val(wqe, 0, 501551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); 502551c46edSMustafa Ismail i = 0; 503551c46edSMustafa Ismail } else { 504551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, 0, op_info->sg_list, 505551c46edSMustafa Ismail qp->swqe_polarity); 506551c46edSMustafa Ismail i = 1; 507551c46edSMustafa Ismail } 508551c46edSMustafa Ismail 509551c46edSMustafa Ismail for (byte_off = 32; i < op_info->num_sges; i++) { 510551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, &op_info->sg_list[i], 511551c46edSMustafa Ismail qp->swqe_polarity); 512551c46edSMustafa Ismail byte_off += 16; 513551c46edSMustafa Ismail } 514551c46edSMustafa Ismail 515551c46edSMustafa Ismail /* if not an odd number set valid bit in next fragment */ 516551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(frag_cnt & 0x01) && 517551c46edSMustafa Ismail frag_cnt) { 518551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL, 519551c46edSMustafa Ismail qp->swqe_polarity); 520551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_2) 521551c46edSMustafa Ismail ++addl_frag_cnt; 522551c46edSMustafa Ismail } 523551c46edSMustafa Ismail 524551c46edSMustafa Ismail set_64bit_val(wqe, 16, 525551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_DESTQKEY, op_info->qkey) | 526551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_DESTQPN, op_info->dest_qp)); 527551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) | 528551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) | 529551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, 530551c46edSMustafa Ismail (info->imm_data_valid ? 1 : 0)) | 531551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) | 532551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | 533551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) | 534551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) | 535551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) | 536551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) | 537551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 538551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_UDPHEADER, info->udp_hdr) | 539551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_L4LEN, info->l4len) | 540551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 541551c46edSMustafa Ismail 542551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 543551c46edSMustafa Ismail 544551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 545551c46edSMustafa Ismail if (info->push_wqe) { 546551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq); 547551c46edSMustafa Ismail } else { 548551c46edSMustafa Ismail if (post_sq) 549551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 550551c46edSMustafa Ismail } 551551c46edSMustafa Ismail 552551c46edSMustafa Ismail return 0; 553551c46edSMustafa Ismail } 554551c46edSMustafa Ismail 555551c46edSMustafa Ismail /** 556551c46edSMustafa Ismail * irdma_set_mw_bind_wqe_gen_1 - set mw bind wqe 557551c46edSMustafa Ismail * @wqe: wqe for setting fragment 558551c46edSMustafa Ismail * @op_info: info for setting bind wqe values 559551c46edSMustafa Ismail */ 560551c46edSMustafa Ismail static void irdma_set_mw_bind_wqe_gen_1(__le64 *wqe, 561551c46edSMustafa Ismail struct irdma_bind_window *op_info) 562551c46edSMustafa Ismail { 563551c46edSMustafa Ismail set_64bit_val(wqe, 0, (uintptr_t)op_info->va); 564551c46edSMustafa Ismail set_64bit_val(wqe, 8, 565551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PARENTMRSTAG, op_info->mw_stag) | 566551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_MWSTAG, op_info->mr_stag)); 567551c46edSMustafa Ismail set_64bit_val(wqe, 16, op_info->bind_len); 568551c46edSMustafa Ismail } 569551c46edSMustafa Ismail 570551c46edSMustafa Ismail /** 571551c46edSMustafa Ismail * irdma_copy_inline_data_gen_1 - Copy inline data to wqe 572551c46edSMustafa Ismail * @dest: pointer to wqe 573551c46edSMustafa Ismail * @src: pointer to inline data 574551c46edSMustafa Ismail * @len: length of inline data to copy 575551c46edSMustafa Ismail * @polarity: compatibility parameter 576551c46edSMustafa Ismail */ 577551c46edSMustafa Ismail static void irdma_copy_inline_data_gen_1(u8 *dest, u8 *src, u32 len, 578551c46edSMustafa Ismail u8 polarity) 579551c46edSMustafa Ismail { 580551c46edSMustafa Ismail if (len <= 16) { 581551c46edSMustafa Ismail memcpy(dest, src, len); 582551c46edSMustafa Ismail } else { 583551c46edSMustafa Ismail memcpy(dest, src, 16); 584551c46edSMustafa Ismail src += 16; 585551c46edSMustafa Ismail dest = dest + 32; 586551c46edSMustafa Ismail memcpy(dest, src, len - 16); 587551c46edSMustafa Ismail } 588551c46edSMustafa Ismail } 589551c46edSMustafa Ismail 590551c46edSMustafa Ismail /** 591551c46edSMustafa Ismail * irdma_inline_data_size_to_quanta_gen_1 - based on inline data, quanta 592551c46edSMustafa Ismail * @data_size: data size for inline 593551c46edSMustafa Ismail * 594551c46edSMustafa Ismail * Gets the quanta based on inline and immediate data. 595551c46edSMustafa Ismail */ 596551c46edSMustafa Ismail static inline u16 irdma_inline_data_size_to_quanta_gen_1(u32 data_size) 597551c46edSMustafa Ismail { 598551c46edSMustafa Ismail return data_size <= 16 ? IRDMA_QP_WQE_MIN_QUANTA : 2; 599551c46edSMustafa Ismail } 600551c46edSMustafa Ismail 601551c46edSMustafa Ismail /** 602551c46edSMustafa Ismail * irdma_set_mw_bind_wqe - set mw bind in wqe 603551c46edSMustafa Ismail * @wqe: wqe for setting mw bind 604551c46edSMustafa Ismail * @op_info: info for setting wqe values 605551c46edSMustafa Ismail */ 606551c46edSMustafa Ismail static void irdma_set_mw_bind_wqe(__le64 *wqe, 607551c46edSMustafa Ismail struct irdma_bind_window *op_info) 608551c46edSMustafa Ismail { 609551c46edSMustafa Ismail set_64bit_val(wqe, 0, (uintptr_t)op_info->va); 610551c46edSMustafa Ismail set_64bit_val(wqe, 8, 611551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PARENTMRSTAG, op_info->mr_stag) | 612551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_MWSTAG, op_info->mw_stag)); 613551c46edSMustafa Ismail set_64bit_val(wqe, 16, op_info->bind_len); 614551c46edSMustafa Ismail } 615551c46edSMustafa Ismail 616551c46edSMustafa Ismail /** 617551c46edSMustafa Ismail * irdma_copy_inline_data - Copy inline data to wqe 618551c46edSMustafa Ismail * @dest: pointer to wqe 619551c46edSMustafa Ismail * @src: pointer to inline data 620551c46edSMustafa Ismail * @len: length of inline data to copy 621551c46edSMustafa Ismail * @polarity: polarity of wqe valid bit 622551c46edSMustafa Ismail */ 623551c46edSMustafa Ismail static void irdma_copy_inline_data(u8 *dest, u8 *src, u32 len, u8 polarity) 624551c46edSMustafa Ismail { 625551c46edSMustafa Ismail u8 inline_valid = polarity << IRDMA_INLINE_VALID_S; 626551c46edSMustafa Ismail u32 copy_size; 627551c46edSMustafa Ismail 628551c46edSMustafa Ismail dest += 8; 629551c46edSMustafa Ismail if (len <= 8) { 630551c46edSMustafa Ismail memcpy(dest, src, len); 631551c46edSMustafa Ismail return; 632551c46edSMustafa Ismail } 633551c46edSMustafa Ismail 634551c46edSMustafa Ismail *((u64 *)dest) = *((u64 *)src); 635551c46edSMustafa Ismail len -= 8; 636551c46edSMustafa Ismail src += 8; 637551c46edSMustafa Ismail dest += 24; /* point to additional 32 byte quanta */ 638551c46edSMustafa Ismail 639551c46edSMustafa Ismail while (len) { 640551c46edSMustafa Ismail copy_size = len < 31 ? len : 31; 641551c46edSMustafa Ismail memcpy(dest, src, copy_size); 642551c46edSMustafa Ismail *(dest + 31) = inline_valid; 643551c46edSMustafa Ismail len -= copy_size; 644551c46edSMustafa Ismail dest += 32; 645551c46edSMustafa Ismail src += copy_size; 646551c46edSMustafa Ismail } 647551c46edSMustafa Ismail } 648551c46edSMustafa Ismail 649551c46edSMustafa Ismail /** 650551c46edSMustafa Ismail * irdma_inline_data_size_to_quanta - based on inline data, quanta 651551c46edSMustafa Ismail * @data_size: data size for inline 652551c46edSMustafa Ismail * 653551c46edSMustafa Ismail * Gets the quanta based on inline and immediate data. 654551c46edSMustafa Ismail */ 655551c46edSMustafa Ismail static u16 irdma_inline_data_size_to_quanta(u32 data_size) 656551c46edSMustafa Ismail { 657551c46edSMustafa Ismail if (data_size <= 8) 658551c46edSMustafa Ismail return IRDMA_QP_WQE_MIN_QUANTA; 659551c46edSMustafa Ismail else if (data_size <= 39) 660551c46edSMustafa Ismail return 2; 661551c46edSMustafa Ismail else if (data_size <= 70) 662551c46edSMustafa Ismail return 3; 663551c46edSMustafa Ismail else if (data_size <= 101) 664551c46edSMustafa Ismail return 4; 665551c46edSMustafa Ismail else if (data_size <= 132) 666551c46edSMustafa Ismail return 5; 667551c46edSMustafa Ismail else if (data_size <= 163) 668551c46edSMustafa Ismail return 6; 669551c46edSMustafa Ismail else if (data_size <= 194) 670551c46edSMustafa Ismail return 7; 671551c46edSMustafa Ismail else 672551c46edSMustafa Ismail return 8; 673551c46edSMustafa Ismail } 674551c46edSMustafa Ismail 675551c46edSMustafa Ismail /** 676551c46edSMustafa Ismail * irdma_uk_inline_rdma_write - inline rdma write operation 677551c46edSMustafa Ismail * @qp: hw qp ptr 678551c46edSMustafa Ismail * @info: post sq information 679551c46edSMustafa Ismail * @post_sq: flag to post sq 680551c46edSMustafa Ismail */ 681551c46edSMustafa Ismail enum irdma_status_code 682551c46edSMustafa Ismail irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info, 683551c46edSMustafa Ismail bool post_sq) 684551c46edSMustafa Ismail { 685551c46edSMustafa Ismail __le64 *wqe; 686551c46edSMustafa Ismail struct irdma_inline_rdma_write *op_info; 687551c46edSMustafa Ismail u64 hdr = 0; 688551c46edSMustafa Ismail u32 wqe_idx; 689551c46edSMustafa Ismail bool read_fence = false; 690551c46edSMustafa Ismail u16 quanta; 691551c46edSMustafa Ismail 692551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 693551c46edSMustafa Ismail op_info = &info->op.inline_rdma_write; 694551c46edSMustafa Ismail 695551c46edSMustafa Ismail if (op_info->len > qp->max_inline_data) 696551c46edSMustafa Ismail return IRDMA_ERR_INVALID_INLINE_DATA_SIZE; 697551c46edSMustafa Ismail 698551c46edSMustafa Ismail quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len); 699551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len, 700551c46edSMustafa Ismail info); 701551c46edSMustafa Ismail if (!wqe) 702551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 703551c46edSMustafa Ismail 704551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 705551c46edSMustafa Ismail 706551c46edSMustafa Ismail read_fence |= info->read_fence; 707551c46edSMustafa Ismail set_64bit_val(wqe, 16, 708551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.tag_off)); 709551c46edSMustafa Ismail 710551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.stag) | 711551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | 712551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) | 713551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) | 714551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) | 715551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) | 716551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe ? 1 : 0) | 717551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) | 718551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) | 719551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 720551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 721551c46edSMustafa Ismail 722551c46edSMustafa Ismail if (info->imm_data_valid) 723551c46edSMustafa Ismail set_64bit_val(wqe, 0, 724551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); 725551c46edSMustafa Ismail 726551c46edSMustafa Ismail qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len, 727551c46edSMustafa Ismail qp->swqe_polarity); 728551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 729551c46edSMustafa Ismail 730551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 731551c46edSMustafa Ismail 732551c46edSMustafa Ismail if (info->push_wqe) { 733551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq); 734551c46edSMustafa Ismail } else { 735551c46edSMustafa Ismail if (post_sq) 736551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 737551c46edSMustafa Ismail } 738551c46edSMustafa Ismail 739551c46edSMustafa Ismail return 0; 740551c46edSMustafa Ismail } 741551c46edSMustafa Ismail 742551c46edSMustafa Ismail /** 743551c46edSMustafa Ismail * irdma_uk_inline_send - inline send operation 744551c46edSMustafa Ismail * @qp: hw qp ptr 745551c46edSMustafa Ismail * @info: post sq information 746551c46edSMustafa Ismail * @post_sq: flag to post sq 747551c46edSMustafa Ismail */ 748551c46edSMustafa Ismail enum irdma_status_code irdma_uk_inline_send(struct irdma_qp_uk *qp, 749551c46edSMustafa Ismail struct irdma_post_sq_info *info, 750551c46edSMustafa Ismail bool post_sq) 751551c46edSMustafa Ismail { 752551c46edSMustafa Ismail __le64 *wqe; 753551c46edSMustafa Ismail struct irdma_post_inline_send *op_info; 754551c46edSMustafa Ismail u64 hdr; 755551c46edSMustafa Ismail u32 wqe_idx; 756551c46edSMustafa Ismail bool read_fence = false; 757551c46edSMustafa Ismail u16 quanta; 758551c46edSMustafa Ismail 759551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 760551c46edSMustafa Ismail op_info = &info->op.inline_send; 761551c46edSMustafa Ismail 762551c46edSMustafa Ismail if (op_info->len > qp->max_inline_data) 763551c46edSMustafa Ismail return IRDMA_ERR_INVALID_INLINE_DATA_SIZE; 764551c46edSMustafa Ismail 765551c46edSMustafa Ismail quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len); 766551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len, 767551c46edSMustafa Ismail info); 768551c46edSMustafa Ismail if (!wqe) 769551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 770551c46edSMustafa Ismail 771551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 772551c46edSMustafa Ismail 773551c46edSMustafa Ismail set_64bit_val(wqe, 16, 774551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_DESTQKEY, op_info->qkey) | 775551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_DESTQPN, op_info->dest_qp)); 776551c46edSMustafa Ismail 777551c46edSMustafa Ismail read_fence |= info->read_fence; 778551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) | 779551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) | 780551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | 781551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) | 782551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, 783551c46edSMustafa Ismail (info->imm_data_valid ? 1 : 0)) | 784551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) | 785551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) | 786551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) | 787551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) | 788551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) | 789551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 790551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_UDPHEADER, info->udp_hdr) | 791551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_L4LEN, info->l4len) | 792551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 793551c46edSMustafa Ismail 794551c46edSMustafa Ismail if (info->imm_data_valid) 795551c46edSMustafa Ismail set_64bit_val(wqe, 0, 796551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); 797551c46edSMustafa Ismail qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len, 798551c46edSMustafa Ismail qp->swqe_polarity); 799551c46edSMustafa Ismail 800551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 801551c46edSMustafa Ismail 802551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 803551c46edSMustafa Ismail 804551c46edSMustafa Ismail if (info->push_wqe) { 805551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq); 806551c46edSMustafa Ismail } else { 807551c46edSMustafa Ismail if (post_sq) 808551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 809551c46edSMustafa Ismail } 810551c46edSMustafa Ismail 811551c46edSMustafa Ismail return 0; 812551c46edSMustafa Ismail } 813551c46edSMustafa Ismail 814551c46edSMustafa Ismail /** 815551c46edSMustafa Ismail * irdma_uk_stag_local_invalidate - stag invalidate operation 816551c46edSMustafa Ismail * @qp: hw qp ptr 817551c46edSMustafa Ismail * @info: post sq information 818551c46edSMustafa Ismail * @post_sq: flag to post sq 819551c46edSMustafa Ismail */ 820551c46edSMustafa Ismail enum irdma_status_code 821551c46edSMustafa Ismail irdma_uk_stag_local_invalidate(struct irdma_qp_uk *qp, 822551c46edSMustafa Ismail struct irdma_post_sq_info *info, bool post_sq) 823551c46edSMustafa Ismail { 824551c46edSMustafa Ismail __le64 *wqe; 825551c46edSMustafa Ismail struct irdma_inv_local_stag *op_info; 826551c46edSMustafa Ismail u64 hdr; 827551c46edSMustafa Ismail u32 wqe_idx; 828551c46edSMustafa Ismail bool local_fence = false; 829551c46edSMustafa Ismail struct irdma_sge sge = {}; 830551c46edSMustafa Ismail 831551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 832551c46edSMustafa Ismail op_info = &info->op.inv_local_stag; 833551c46edSMustafa Ismail local_fence = info->local_fence; 834551c46edSMustafa Ismail 835551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA, 836551c46edSMustafa Ismail 0, info); 837551c46edSMustafa Ismail if (!wqe) 838551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 839551c46edSMustafa Ismail 840551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 841551c46edSMustafa Ismail 842551c46edSMustafa Ismail sge.stag = op_info->target_stag; 843551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, 0, &sge, 0); 844551c46edSMustafa Ismail 845551c46edSMustafa Ismail set_64bit_val(wqe, 16, 0); 846551c46edSMustafa Ismail 847551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMA_OP_TYPE_INV_STAG) | 848551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) | 849551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) | 850551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) | 851551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 852551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 853551c46edSMustafa Ismail 854551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 855551c46edSMustafa Ismail 856551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 857551c46edSMustafa Ismail 858551c46edSMustafa Ismail if (info->push_wqe) { 859551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, IRDMA_QP_WQE_MIN_QUANTA, wqe_idx, 860551c46edSMustafa Ismail post_sq); 861551c46edSMustafa Ismail } else { 862551c46edSMustafa Ismail if (post_sq) 863551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 864551c46edSMustafa Ismail } 865551c46edSMustafa Ismail 866551c46edSMustafa Ismail return 0; 867551c46edSMustafa Ismail } 868551c46edSMustafa Ismail 869551c46edSMustafa Ismail /** 870551c46edSMustafa Ismail * irdma_uk_mw_bind - bind Memory Window 871551c46edSMustafa Ismail * @qp: hw qp ptr 872551c46edSMustafa Ismail * @info: post sq information 873551c46edSMustafa Ismail * @post_sq: flag to post sq 874551c46edSMustafa Ismail */ 875551c46edSMustafa Ismail enum irdma_status_code irdma_uk_mw_bind(struct irdma_qp_uk *qp, 876551c46edSMustafa Ismail struct irdma_post_sq_info *info, 877551c46edSMustafa Ismail bool post_sq) 878551c46edSMustafa Ismail { 879551c46edSMustafa Ismail __le64 *wqe; 880551c46edSMustafa Ismail struct irdma_bind_window *op_info; 881551c46edSMustafa Ismail u64 hdr; 882551c46edSMustafa Ismail u32 wqe_idx; 883551c46edSMustafa Ismail bool local_fence = false; 884551c46edSMustafa Ismail 885551c46edSMustafa Ismail info->push_wqe = qp->push_db ? true : false; 886551c46edSMustafa Ismail op_info = &info->op.bind_window; 887551c46edSMustafa Ismail local_fence |= info->local_fence; 888551c46edSMustafa Ismail 889551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA, 890551c46edSMustafa Ismail 0, info); 891551c46edSMustafa Ismail if (!wqe) 892551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 893551c46edSMustafa Ismail 894551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 895551c46edSMustafa Ismail 896551c46edSMustafa Ismail qp->wqe_ops.iw_set_mw_bind_wqe(wqe, op_info); 897551c46edSMustafa Ismail 898551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMA_OP_TYPE_BIND_MW) | 899551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_STAGRIGHTS, 900551c46edSMustafa Ismail ((op_info->ena_reads << 2) | (op_info->ena_writes << 3))) | 901551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VABASEDTO, 902551c46edSMustafa Ismail (op_info->addressing_type == IRDMA_ADDR_TYPE_VA_BASED ? 1 : 0)) | 903551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_MEMWINDOWTYPE, 904551c46edSMustafa Ismail (op_info->mem_window_type_1 ? 1 : 0)) | 905551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) | 906551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) | 907551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) | 908551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) | 909551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 910551c46edSMustafa Ismail 911551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 912551c46edSMustafa Ismail 913551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 914551c46edSMustafa Ismail 915551c46edSMustafa Ismail if (info->push_wqe) { 916551c46edSMustafa Ismail irdma_qp_push_wqe(qp, wqe, IRDMA_QP_WQE_MIN_QUANTA, wqe_idx, 917551c46edSMustafa Ismail post_sq); 918551c46edSMustafa Ismail } else { 919551c46edSMustafa Ismail if (post_sq) 920551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 921551c46edSMustafa Ismail } 922551c46edSMustafa Ismail 923551c46edSMustafa Ismail return 0; 924551c46edSMustafa Ismail } 925551c46edSMustafa Ismail 926551c46edSMustafa Ismail /** 927551c46edSMustafa Ismail * irdma_uk_post_receive - post receive wqe 928551c46edSMustafa Ismail * @qp: hw qp ptr 929551c46edSMustafa Ismail * @info: post rq information 930551c46edSMustafa Ismail */ 931551c46edSMustafa Ismail enum irdma_status_code irdma_uk_post_receive(struct irdma_qp_uk *qp, 932551c46edSMustafa Ismail struct irdma_post_rq_info *info) 933551c46edSMustafa Ismail { 934*6407c69dSTatyana Nikolova u32 wqe_idx, i, byte_off; 935551c46edSMustafa Ismail u32 addl_frag_cnt; 936551c46edSMustafa Ismail __le64 *wqe; 937551c46edSMustafa Ismail u64 hdr; 938551c46edSMustafa Ismail 939551c46edSMustafa Ismail if (qp->max_rq_frag_cnt < info->num_sges) 940551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 941551c46edSMustafa Ismail 942551c46edSMustafa Ismail wqe = irdma_qp_get_next_recv_wqe(qp, &wqe_idx); 943551c46edSMustafa Ismail if (!wqe) 944551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 945551c46edSMustafa Ismail 946551c46edSMustafa Ismail qp->rq_wrid_array[wqe_idx] = info->wr_id; 947551c46edSMustafa Ismail addl_frag_cnt = info->num_sges > 1 ? (info->num_sges - 1) : 0; 948551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, 0, info->sg_list, 949551c46edSMustafa Ismail qp->rwqe_polarity); 950551c46edSMustafa Ismail 951551c46edSMustafa Ismail for (i = 1, byte_off = 32; i < info->num_sges; i++) { 952551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, &info->sg_list[i], 953551c46edSMustafa Ismail qp->rwqe_polarity); 954551c46edSMustafa Ismail byte_off += 16; 955551c46edSMustafa Ismail } 956551c46edSMustafa Ismail 957551c46edSMustafa Ismail /* if not an odd number set valid bit in next fragment */ 958551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(info->num_sges & 0x01) && 959551c46edSMustafa Ismail info->num_sges) { 960551c46edSMustafa Ismail qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL, 961551c46edSMustafa Ismail qp->rwqe_polarity); 962551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_2) 963551c46edSMustafa Ismail ++addl_frag_cnt; 964551c46edSMustafa Ismail } 965551c46edSMustafa Ismail 966551c46edSMustafa Ismail set_64bit_val(wqe, 16, 0); 967551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) | 968551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->rwqe_polarity); 969551c46edSMustafa Ismail 970551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 971551c46edSMustafa Ismail 972551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 973551c46edSMustafa Ismail 974551c46edSMustafa Ismail return 0; 975551c46edSMustafa Ismail } 976551c46edSMustafa Ismail 977551c46edSMustafa Ismail /** 978551c46edSMustafa Ismail * irdma_uk_cq_resize - reset the cq buffer info 979551c46edSMustafa Ismail * @cq: cq to resize 980551c46edSMustafa Ismail * @cq_base: new cq buffer addr 981551c46edSMustafa Ismail * @cq_size: number of cqes 982551c46edSMustafa Ismail */ 983551c46edSMustafa Ismail void irdma_uk_cq_resize(struct irdma_cq_uk *cq, void *cq_base, int cq_size) 984551c46edSMustafa Ismail { 985551c46edSMustafa Ismail cq->cq_base = cq_base; 986551c46edSMustafa Ismail cq->cq_size = cq_size; 987551c46edSMustafa Ismail IRDMA_RING_INIT(cq->cq_ring, cq->cq_size); 988551c46edSMustafa Ismail cq->polarity = 1; 989551c46edSMustafa Ismail } 990551c46edSMustafa Ismail 991551c46edSMustafa Ismail /** 992551c46edSMustafa Ismail * irdma_uk_cq_set_resized_cnt - record the count of the resized buffers 993551c46edSMustafa Ismail * @cq: cq to resize 994551c46edSMustafa Ismail * @cq_cnt: the count of the resized cq buffers 995551c46edSMustafa Ismail */ 996551c46edSMustafa Ismail void irdma_uk_cq_set_resized_cnt(struct irdma_cq_uk *cq, u16 cq_cnt) 997551c46edSMustafa Ismail { 998551c46edSMustafa Ismail u64 temp_val; 999551c46edSMustafa Ismail u16 sw_cq_sel; 1000551c46edSMustafa Ismail u8 arm_next_se; 1001551c46edSMustafa Ismail u8 arm_next; 1002551c46edSMustafa Ismail u8 arm_seq_num; 1003551c46edSMustafa Ismail 1004551c46edSMustafa Ismail get_64bit_val(cq->shadow_area, 32, &temp_val); 1005551c46edSMustafa Ismail 1006551c46edSMustafa Ismail sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); 1007551c46edSMustafa Ismail sw_cq_sel += cq_cnt; 1008551c46edSMustafa Ismail 1009551c46edSMustafa Ismail arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val); 1010551c46edSMustafa Ismail arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); 1011551c46edSMustafa Ismail arm_next = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT, temp_val); 1012551c46edSMustafa Ismail 1013551c46edSMustafa Ismail temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) | 1014551c46edSMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) | 1015551c46edSMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | 1016551c46edSMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, arm_next); 1017551c46edSMustafa Ismail 1018551c46edSMustafa Ismail set_64bit_val(cq->shadow_area, 32, temp_val); 1019551c46edSMustafa Ismail } 1020551c46edSMustafa Ismail 1021551c46edSMustafa Ismail /** 1022551c46edSMustafa Ismail * irdma_uk_cq_request_notification - cq notification request (door bell) 1023551c46edSMustafa Ismail * @cq: hw cq 1024551c46edSMustafa Ismail * @cq_notify: notification type 1025551c46edSMustafa Ismail */ 1026551c46edSMustafa Ismail void irdma_uk_cq_request_notification(struct irdma_cq_uk *cq, 1027551c46edSMustafa Ismail enum irdma_cmpl_notify cq_notify) 1028551c46edSMustafa Ismail { 1029551c46edSMustafa Ismail u64 temp_val; 1030551c46edSMustafa Ismail u16 sw_cq_sel; 1031551c46edSMustafa Ismail u8 arm_next_se = 0; 1032551c46edSMustafa Ismail u8 arm_next = 0; 1033551c46edSMustafa Ismail u8 arm_seq_num; 1034551c46edSMustafa Ismail 1035551c46edSMustafa Ismail get_64bit_val(cq->shadow_area, 32, &temp_val); 1036551c46edSMustafa Ismail arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val); 1037551c46edSMustafa Ismail arm_seq_num++; 1038551c46edSMustafa Ismail sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); 1039551c46edSMustafa Ismail arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); 1040551c46edSMustafa Ismail arm_next_se |= 1; 1041551c46edSMustafa Ismail if (cq_notify == IRDMA_CQ_COMPL_EVENT) 1042551c46edSMustafa Ismail arm_next = 1; 1043551c46edSMustafa Ismail temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) | 1044551c46edSMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) | 1045551c46edSMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | 1046551c46edSMustafa Ismail FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, arm_next); 1047551c46edSMustafa Ismail 1048551c46edSMustafa Ismail set_64bit_val(cq->shadow_area, 32, temp_val); 1049551c46edSMustafa Ismail 1050551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 1051551c46edSMustafa Ismail 1052551c46edSMustafa Ismail writel(cq->cq_id, cq->cqe_alloc_db); 1053551c46edSMustafa Ismail } 1054551c46edSMustafa Ismail 1055551c46edSMustafa Ismail /** 1056551c46edSMustafa Ismail * irdma_uk_cq_poll_cmpl - get cq completion info 1057551c46edSMustafa Ismail * @cq: hw cq 1058551c46edSMustafa Ismail * @info: cq poll information returned 1059551c46edSMustafa Ismail */ 1060551c46edSMustafa Ismail enum irdma_status_code 1061551c46edSMustafa Ismail irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, struct irdma_cq_poll_info *info) 1062551c46edSMustafa Ismail { 1063551c46edSMustafa Ismail u64 comp_ctx, qword0, qword2, qword3; 1064551c46edSMustafa Ismail __le64 *cqe; 1065551c46edSMustafa Ismail struct irdma_qp_uk *qp; 1066551c46edSMustafa Ismail struct irdma_ring *pring = NULL; 1067551c46edSMustafa Ismail u32 wqe_idx, q_type; 1068551c46edSMustafa Ismail enum irdma_status_code ret_code; 1069551c46edSMustafa Ismail bool move_cq_head = true; 1070551c46edSMustafa Ismail u8 polarity; 1071551c46edSMustafa Ismail bool ext_valid; 1072551c46edSMustafa Ismail __le64 *ext_cqe; 1073551c46edSMustafa Ismail 1074551c46edSMustafa Ismail if (cq->avoid_mem_cflct) 1075551c46edSMustafa Ismail cqe = IRDMA_GET_CURRENT_EXTENDED_CQ_ELEM(cq); 1076551c46edSMustafa Ismail else 1077551c46edSMustafa Ismail cqe = IRDMA_GET_CURRENT_CQ_ELEM(cq); 1078551c46edSMustafa Ismail 1079551c46edSMustafa Ismail get_64bit_val(cqe, 24, &qword3); 1080551c46edSMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3); 1081551c46edSMustafa Ismail if (polarity != cq->polarity) 1082551c46edSMustafa Ismail return IRDMA_ERR_Q_EMPTY; 1083551c46edSMustafa Ismail 1084551c46edSMustafa Ismail /* Ensure CQE contents are read after valid bit is checked */ 1085551c46edSMustafa Ismail dma_rmb(); 1086551c46edSMustafa Ismail 1087551c46edSMustafa Ismail ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3); 1088551c46edSMustafa Ismail if (ext_valid) { 1089551c46edSMustafa Ismail u64 qword6, qword7; 1090551c46edSMustafa Ismail u32 peek_head; 1091551c46edSMustafa Ismail 1092551c46edSMustafa Ismail if (cq->avoid_mem_cflct) { 1093551c46edSMustafa Ismail ext_cqe = (__le64 *)((u8 *)cqe + 32); 1094551c46edSMustafa Ismail get_64bit_val(ext_cqe, 24, &qword7); 1095551c46edSMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3); 1096551c46edSMustafa Ismail } else { 1097551c46edSMustafa Ismail peek_head = (cq->cq_ring.head + 1) % cq->cq_ring.size; 1098551c46edSMustafa Ismail ext_cqe = cq->cq_base[peek_head].buf; 1099551c46edSMustafa Ismail get_64bit_val(ext_cqe, 24, &qword7); 1100551c46edSMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3); 1101551c46edSMustafa Ismail if (!peek_head) 1102551c46edSMustafa Ismail polarity ^= 1; 1103551c46edSMustafa Ismail } 1104551c46edSMustafa Ismail if (polarity != cq->polarity) 1105551c46edSMustafa Ismail return IRDMA_ERR_Q_EMPTY; 1106551c46edSMustafa Ismail 1107551c46edSMustafa Ismail /* Ensure ext CQE contents are read after ext valid bit is checked */ 1108551c46edSMustafa Ismail dma_rmb(); 1109551c46edSMustafa Ismail 1110551c46edSMustafa Ismail info->imm_valid = (bool)FIELD_GET(IRDMA_CQ_IMMVALID, qword7); 1111551c46edSMustafa Ismail if (info->imm_valid) { 1112551c46edSMustafa Ismail u64 qword4; 1113551c46edSMustafa Ismail 1114551c46edSMustafa Ismail get_64bit_val(ext_cqe, 0, &qword4); 1115551c46edSMustafa Ismail info->imm_data = (u32)FIELD_GET(IRDMA_CQ_IMMDATALOW32, qword4); 1116551c46edSMustafa Ismail } 1117551c46edSMustafa Ismail info->ud_smac_valid = (bool)FIELD_GET(IRDMA_CQ_UDSMACVALID, qword7); 1118551c46edSMustafa Ismail info->ud_vlan_valid = (bool)FIELD_GET(IRDMA_CQ_UDVLANVALID, qword7); 1119551c46edSMustafa Ismail if (info->ud_smac_valid || info->ud_vlan_valid) { 1120551c46edSMustafa Ismail get_64bit_val(ext_cqe, 16, &qword6); 1121551c46edSMustafa Ismail if (info->ud_vlan_valid) 1122551c46edSMustafa Ismail info->ud_vlan = (u16)FIELD_GET(IRDMA_CQ_UDVLAN, qword6); 1123551c46edSMustafa Ismail if (info->ud_smac_valid) { 1124551c46edSMustafa Ismail info->ud_smac[5] = qword6 & 0xFF; 1125551c46edSMustafa Ismail info->ud_smac[4] = (qword6 >> 8) & 0xFF; 1126551c46edSMustafa Ismail info->ud_smac[3] = (qword6 >> 16) & 0xFF; 1127551c46edSMustafa Ismail info->ud_smac[2] = (qword6 >> 24) & 0xFF; 1128551c46edSMustafa Ismail info->ud_smac[1] = (qword6 >> 32) & 0xFF; 1129551c46edSMustafa Ismail info->ud_smac[0] = (qword6 >> 40) & 0xFF; 1130551c46edSMustafa Ismail } 1131551c46edSMustafa Ismail } 1132551c46edSMustafa Ismail } else { 1133551c46edSMustafa Ismail info->imm_valid = false; 1134551c46edSMustafa Ismail info->ud_smac_valid = false; 1135551c46edSMustafa Ismail info->ud_vlan_valid = false; 1136551c46edSMustafa Ismail } 1137551c46edSMustafa Ismail 1138551c46edSMustafa Ismail q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); 1139551c46edSMustafa Ismail info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3); 1140551c46edSMustafa Ismail info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3); 1141551c46edSMustafa Ismail info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3); 1142551c46edSMustafa Ismail if (info->error) { 1143551c46edSMustafa Ismail info->major_err = FIELD_GET(IRDMA_CQ_MAJERR, qword3); 1144551c46edSMustafa Ismail info->minor_err = FIELD_GET(IRDMA_CQ_MINERR, qword3); 1145551c46edSMustafa Ismail if (info->major_err == IRDMA_FLUSH_MAJOR_ERR) { 1146551c46edSMustafa Ismail info->comp_status = IRDMA_COMPL_STATUS_FLUSHED; 1147551c46edSMustafa Ismail /* Set the min error to standard flush error code for remaining cqes */ 1148551c46edSMustafa Ismail if (info->minor_err != FLUSH_GENERAL_ERR) { 1149551c46edSMustafa Ismail qword3 &= ~IRDMA_CQ_MINERR; 1150551c46edSMustafa Ismail qword3 |= FIELD_PREP(IRDMA_CQ_MINERR, FLUSH_GENERAL_ERR); 1151551c46edSMustafa Ismail set_64bit_val(cqe, 24, qword3); 1152551c46edSMustafa Ismail } 1153551c46edSMustafa Ismail } else { 1154551c46edSMustafa Ismail info->comp_status = IRDMA_COMPL_STATUS_UNKNOWN; 1155551c46edSMustafa Ismail } 1156551c46edSMustafa Ismail } else { 1157551c46edSMustafa Ismail info->comp_status = IRDMA_COMPL_STATUS_SUCCESS; 1158551c46edSMustafa Ismail } 1159551c46edSMustafa Ismail 1160551c46edSMustafa Ismail get_64bit_val(cqe, 0, &qword0); 1161551c46edSMustafa Ismail get_64bit_val(cqe, 16, &qword2); 1162551c46edSMustafa Ismail 1163551c46edSMustafa Ismail info->tcp_seq_num_rtt = (u32)FIELD_GET(IRDMACQ_TCPSEQNUMRTT, qword0); 1164551c46edSMustafa Ismail info->qp_id = (u32)FIELD_GET(IRDMACQ_QPID, qword2); 1165551c46edSMustafa Ismail info->ud_src_qpn = (u32)FIELD_GET(IRDMACQ_UDSRCQPN, qword2); 1166551c46edSMustafa Ismail 1167551c46edSMustafa Ismail get_64bit_val(cqe, 8, &comp_ctx); 1168551c46edSMustafa Ismail 1169551c46edSMustafa Ismail info->solicited_event = (bool)FIELD_GET(IRDMACQ_SOEVENT, qword3); 1170551c46edSMustafa Ismail qp = (struct irdma_qp_uk *)(unsigned long)comp_ctx; 1171551c46edSMustafa Ismail if (!qp || qp->destroy_pending) { 1172551c46edSMustafa Ismail ret_code = IRDMA_ERR_Q_DESTROYED; 1173551c46edSMustafa Ismail goto exit; 1174551c46edSMustafa Ismail } 1175551c46edSMustafa Ismail wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3); 1176551c46edSMustafa Ismail info->qp_handle = (irdma_qp_handle)(unsigned long)qp; 1177551c46edSMustafa Ismail 1178551c46edSMustafa Ismail if (q_type == IRDMA_CQE_QTYPE_RQ) { 1179551c46edSMustafa Ismail u32 array_idx; 1180551c46edSMustafa Ismail 1181551c46edSMustafa Ismail array_idx = wqe_idx / qp->rq_wqe_size_multiplier; 1182551c46edSMustafa Ismail 1183551c46edSMustafa Ismail if (info->comp_status == IRDMA_COMPL_STATUS_FLUSHED || 1184551c46edSMustafa Ismail info->comp_status == IRDMA_COMPL_STATUS_UNKNOWN) { 1185551c46edSMustafa Ismail if (!IRDMA_RING_MORE_WORK(qp->rq_ring)) { 1186551c46edSMustafa Ismail ret_code = IRDMA_ERR_Q_EMPTY; 1187551c46edSMustafa Ismail goto exit; 1188551c46edSMustafa Ismail } 1189551c46edSMustafa Ismail 1190551c46edSMustafa Ismail info->wr_id = qp->rq_wrid_array[qp->rq_ring.tail]; 1191551c46edSMustafa Ismail array_idx = qp->rq_ring.tail; 1192551c46edSMustafa Ismail } else { 1193551c46edSMustafa Ismail info->wr_id = qp->rq_wrid_array[array_idx]; 1194551c46edSMustafa Ismail } 1195551c46edSMustafa Ismail 1196551c46edSMustafa Ismail info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0); 1197551c46edSMustafa Ismail 1198551c46edSMustafa Ismail if (info->imm_valid) 1199551c46edSMustafa Ismail info->op_type = IRDMA_OP_TYPE_REC_IMM; 1200551c46edSMustafa Ismail else 1201551c46edSMustafa Ismail info->op_type = IRDMA_OP_TYPE_REC; 1202551c46edSMustafa Ismail if (qword3 & IRDMACQ_STAG) { 1203551c46edSMustafa Ismail info->stag_invalid_set = true; 1204551c46edSMustafa Ismail info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2); 1205551c46edSMustafa Ismail } else { 1206551c46edSMustafa Ismail info->stag_invalid_set = false; 1207551c46edSMustafa Ismail } 1208551c46edSMustafa Ismail IRDMA_RING_SET_TAIL(qp->rq_ring, array_idx + 1); 1209551c46edSMustafa Ismail if (info->comp_status == IRDMA_COMPL_STATUS_FLUSHED) { 1210551c46edSMustafa Ismail qp->rq_flush_seen = true; 1211551c46edSMustafa Ismail if (!IRDMA_RING_MORE_WORK(qp->rq_ring)) 1212551c46edSMustafa Ismail qp->rq_flush_complete = true; 1213551c46edSMustafa Ismail else 1214551c46edSMustafa Ismail move_cq_head = false; 1215551c46edSMustafa Ismail } 1216551c46edSMustafa Ismail pring = &qp->rq_ring; 1217551c46edSMustafa Ismail } else { /* q_type is IRDMA_CQE_QTYPE_SQ */ 1218551c46edSMustafa Ismail if (qp->first_sq_wq) { 1219551c46edSMustafa Ismail if (wqe_idx + 1 >= qp->conn_wqes) 1220551c46edSMustafa Ismail qp->first_sq_wq = false; 1221551c46edSMustafa Ismail 1222551c46edSMustafa Ismail if (wqe_idx < qp->conn_wqes && qp->sq_ring.head == qp->sq_ring.tail) { 1223551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring); 1224551c46edSMustafa Ismail IRDMA_RING_MOVE_TAIL(cq->cq_ring); 1225551c46edSMustafa Ismail set_64bit_val(cq->shadow_area, 0, 1226551c46edSMustafa Ismail IRDMA_RING_CURRENT_HEAD(cq->cq_ring)); 1227551c46edSMustafa Ismail memset(info, 0, 1228551c46edSMustafa Ismail sizeof(struct irdma_cq_poll_info)); 1229551c46edSMustafa Ismail return irdma_uk_cq_poll_cmpl(cq, info); 1230551c46edSMustafa Ismail } 1231551c46edSMustafa Ismail } 1232551c46edSMustafa Ismail /*cease posting push mode on push drop*/ 1233551c46edSMustafa Ismail if (info->push_dropped) { 1234551c46edSMustafa Ismail qp->push_mode = false; 1235551c46edSMustafa Ismail qp->push_dropped = true; 1236551c46edSMustafa Ismail } 1237551c46edSMustafa Ismail if (info->comp_status != IRDMA_COMPL_STATUS_FLUSHED) { 1238551c46edSMustafa Ismail info->wr_id = qp->sq_wrtrk_array[wqe_idx].wrid; 1239551c46edSMustafa Ismail if (!info->comp_status) 1240551c46edSMustafa Ismail info->bytes_xfered = qp->sq_wrtrk_array[wqe_idx].wr_len; 1241551c46edSMustafa Ismail info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3); 1242551c46edSMustafa Ismail IRDMA_RING_SET_TAIL(qp->sq_ring, 1243551c46edSMustafa Ismail wqe_idx + qp->sq_wrtrk_array[wqe_idx].quanta); 1244551c46edSMustafa Ismail } else { 1245551c46edSMustafa Ismail if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) { 1246551c46edSMustafa Ismail ret_code = IRDMA_ERR_Q_EMPTY; 1247551c46edSMustafa Ismail goto exit; 1248551c46edSMustafa Ismail } 1249551c46edSMustafa Ismail 1250551c46edSMustafa Ismail do { 1251551c46edSMustafa Ismail __le64 *sw_wqe; 1252551c46edSMustafa Ismail u64 wqe_qword; 1253551c46edSMustafa Ismail u8 op_type; 1254551c46edSMustafa Ismail u32 tail; 1255551c46edSMustafa Ismail 1256551c46edSMustafa Ismail tail = qp->sq_ring.tail; 1257551c46edSMustafa Ismail sw_wqe = qp->sq_base[tail].elem; 1258551c46edSMustafa Ismail get_64bit_val(sw_wqe, 24, 1259551c46edSMustafa Ismail &wqe_qword); 1260551c46edSMustafa Ismail op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword); 1261551c46edSMustafa Ismail info->op_type = op_type; 1262551c46edSMustafa Ismail IRDMA_RING_SET_TAIL(qp->sq_ring, 1263551c46edSMustafa Ismail tail + qp->sq_wrtrk_array[tail].quanta); 1264551c46edSMustafa Ismail if (op_type != IRDMAQP_OP_NOP) { 1265551c46edSMustafa Ismail info->wr_id = qp->sq_wrtrk_array[tail].wrid; 1266551c46edSMustafa Ismail info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len; 1267551c46edSMustafa Ismail break; 1268551c46edSMustafa Ismail } 1269551c46edSMustafa Ismail } while (1); 1270551c46edSMustafa Ismail qp->sq_flush_seen = true; 1271551c46edSMustafa Ismail if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) 1272551c46edSMustafa Ismail qp->sq_flush_complete = true; 1273551c46edSMustafa Ismail } 1274551c46edSMustafa Ismail pring = &qp->sq_ring; 1275551c46edSMustafa Ismail } 1276551c46edSMustafa Ismail 1277551c46edSMustafa Ismail ret_code = 0; 1278551c46edSMustafa Ismail 1279551c46edSMustafa Ismail exit: 1280551c46edSMustafa Ismail if (!ret_code && info->comp_status == IRDMA_COMPL_STATUS_FLUSHED) 1281551c46edSMustafa Ismail if (pring && IRDMA_RING_MORE_WORK(*pring)) 1282551c46edSMustafa Ismail move_cq_head = false; 1283551c46edSMustafa Ismail 1284551c46edSMustafa Ismail if (move_cq_head) { 1285551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring); 1286551c46edSMustafa Ismail if (!IRDMA_RING_CURRENT_HEAD(cq->cq_ring)) 1287551c46edSMustafa Ismail cq->polarity ^= 1; 1288551c46edSMustafa Ismail 1289551c46edSMustafa Ismail if (ext_valid && !cq->avoid_mem_cflct) { 1290551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring); 1291551c46edSMustafa Ismail if (!IRDMA_RING_CURRENT_HEAD(cq->cq_ring)) 1292551c46edSMustafa Ismail cq->polarity ^= 1; 1293551c46edSMustafa Ismail } 1294551c46edSMustafa Ismail 1295551c46edSMustafa Ismail IRDMA_RING_MOVE_TAIL(cq->cq_ring); 1296551c46edSMustafa Ismail if (!cq->avoid_mem_cflct && ext_valid) 1297551c46edSMustafa Ismail IRDMA_RING_MOVE_TAIL(cq->cq_ring); 1298551c46edSMustafa Ismail set_64bit_val(cq->shadow_area, 0, 1299551c46edSMustafa Ismail IRDMA_RING_CURRENT_HEAD(cq->cq_ring)); 1300551c46edSMustafa Ismail } else { 1301551c46edSMustafa Ismail qword3 &= ~IRDMA_CQ_WQEIDX; 1302551c46edSMustafa Ismail qword3 |= FIELD_PREP(IRDMA_CQ_WQEIDX, pring->tail); 1303551c46edSMustafa Ismail set_64bit_val(cqe, 24, qword3); 1304551c46edSMustafa Ismail } 1305551c46edSMustafa Ismail 1306551c46edSMustafa Ismail return ret_code; 1307551c46edSMustafa Ismail } 1308551c46edSMustafa Ismail 1309551c46edSMustafa Ismail /** 1310551c46edSMustafa Ismail * irdma_qp_round_up - return round up qp wq depth 1311551c46edSMustafa Ismail * @wqdepth: wq depth in quanta to round up 1312551c46edSMustafa Ismail */ 1313551c46edSMustafa Ismail static int irdma_qp_round_up(u32 wqdepth) 1314551c46edSMustafa Ismail { 1315551c46edSMustafa Ismail int scount = 1; 1316551c46edSMustafa Ismail 1317551c46edSMustafa Ismail for (wqdepth--; scount <= 16; scount *= 2) 1318551c46edSMustafa Ismail wqdepth |= wqdepth >> scount; 1319551c46edSMustafa Ismail 1320551c46edSMustafa Ismail return ++wqdepth; 1321551c46edSMustafa Ismail } 1322551c46edSMustafa Ismail 1323551c46edSMustafa Ismail /** 1324551c46edSMustafa Ismail * irdma_get_wqe_shift - get shift count for maximum wqe size 1325551c46edSMustafa Ismail * @uk_attrs: qp HW attributes 1326551c46edSMustafa Ismail * @sge: Maximum Scatter Gather Elements wqe 1327551c46edSMustafa Ismail * @inline_data: Maximum inline data size 1328551c46edSMustafa Ismail * @shift: Returns the shift needed based on sge 1329551c46edSMustafa Ismail * 1330551c46edSMustafa Ismail * Shift can be used to left shift the wqe size based on number of SGEs and inlind data size. 1331551c46edSMustafa Ismail * For 1 SGE or inline data <= 8, shift = 0 (wqe size of 32 1332551c46edSMustafa Ismail * bytes). For 2 or 3 SGEs or inline data <= 39, shift = 1 (wqe 1333551c46edSMustafa Ismail * size of 64 bytes). 1334551c46edSMustafa Ismail * For 4-7 SGE's and inline <= 101 Shift of 2 otherwise (wqe 1335551c46edSMustafa Ismail * size of 256 bytes). 1336551c46edSMustafa Ismail */ 1337551c46edSMustafa Ismail void irdma_get_wqe_shift(struct irdma_uk_attrs *uk_attrs, u32 sge, 1338551c46edSMustafa Ismail u32 inline_data, u8 *shift) 1339551c46edSMustafa Ismail { 1340551c46edSMustafa Ismail *shift = 0; 1341551c46edSMustafa Ismail if (uk_attrs->hw_rev >= IRDMA_GEN_2) { 1342551c46edSMustafa Ismail if (sge > 1 || inline_data > 8) { 1343551c46edSMustafa Ismail if (sge < 4 && inline_data <= 39) 1344551c46edSMustafa Ismail *shift = 1; 1345551c46edSMustafa Ismail else if (sge < 8 && inline_data <= 101) 1346551c46edSMustafa Ismail *shift = 2; 1347551c46edSMustafa Ismail else 1348551c46edSMustafa Ismail *shift = 3; 1349551c46edSMustafa Ismail } 1350551c46edSMustafa Ismail } else if (sge > 1 || inline_data > 16) { 1351551c46edSMustafa Ismail *shift = (sge < 4 && inline_data <= 48) ? 1 : 2; 1352551c46edSMustafa Ismail } 1353551c46edSMustafa Ismail } 1354551c46edSMustafa Ismail 1355551c46edSMustafa Ismail /* 1356551c46edSMustafa Ismail * irdma_get_sqdepth - get SQ depth (quanta) 1357551c46edSMustafa Ismail * @uk_attrs: qp HW attributes 1358551c46edSMustafa Ismail * @sq_size: SQ size 1359551c46edSMustafa Ismail * @shift: shift which determines size of WQE 1360551c46edSMustafa Ismail * @sqdepth: depth of SQ 1361551c46edSMustafa Ismail * 1362551c46edSMustafa Ismail */ 1363551c46edSMustafa Ismail enum irdma_status_code irdma_get_sqdepth(struct irdma_uk_attrs *uk_attrs, 1364551c46edSMustafa Ismail u32 sq_size, u8 shift, u32 *sqdepth) 1365551c46edSMustafa Ismail { 1366551c46edSMustafa Ismail *sqdepth = irdma_qp_round_up((sq_size << shift) + IRDMA_SQ_RSVD); 1367551c46edSMustafa Ismail 1368551c46edSMustafa Ismail if (*sqdepth < (IRDMA_QP_SW_MIN_WQSIZE << shift)) 1369551c46edSMustafa Ismail *sqdepth = IRDMA_QP_SW_MIN_WQSIZE << shift; 1370551c46edSMustafa Ismail else if (*sqdepth > uk_attrs->max_hw_wq_quanta) 1371551c46edSMustafa Ismail return IRDMA_ERR_INVALID_SIZE; 1372551c46edSMustafa Ismail 1373551c46edSMustafa Ismail return 0; 1374551c46edSMustafa Ismail } 1375551c46edSMustafa Ismail 1376551c46edSMustafa Ismail /* 1377551c46edSMustafa Ismail * irdma_get_rqdepth - get RQ depth (quanta) 1378551c46edSMustafa Ismail * @uk_attrs: qp HW attributes 1379551c46edSMustafa Ismail * @rq_size: RQ size 1380551c46edSMustafa Ismail * @shift: shift which determines size of WQE 1381551c46edSMustafa Ismail * @rqdepth: depth of RQ 1382551c46edSMustafa Ismail */ 1383551c46edSMustafa Ismail enum irdma_status_code irdma_get_rqdepth(struct irdma_uk_attrs *uk_attrs, 1384551c46edSMustafa Ismail u32 rq_size, u8 shift, u32 *rqdepth) 1385551c46edSMustafa Ismail { 1386551c46edSMustafa Ismail *rqdepth = irdma_qp_round_up((rq_size << shift) + IRDMA_RQ_RSVD); 1387551c46edSMustafa Ismail 1388551c46edSMustafa Ismail if (*rqdepth < (IRDMA_QP_SW_MIN_WQSIZE << shift)) 1389551c46edSMustafa Ismail *rqdepth = IRDMA_QP_SW_MIN_WQSIZE << shift; 1390551c46edSMustafa Ismail else if (*rqdepth > uk_attrs->max_hw_rq_quanta) 1391551c46edSMustafa Ismail return IRDMA_ERR_INVALID_SIZE; 1392551c46edSMustafa Ismail 1393551c46edSMustafa Ismail return 0; 1394551c46edSMustafa Ismail } 1395551c46edSMustafa Ismail 1396551c46edSMustafa Ismail static const struct irdma_wqe_uk_ops iw_wqe_uk_ops = { 1397551c46edSMustafa Ismail .iw_copy_inline_data = irdma_copy_inline_data, 1398551c46edSMustafa Ismail .iw_inline_data_size_to_quanta = irdma_inline_data_size_to_quanta, 1399551c46edSMustafa Ismail .iw_set_fragment = irdma_set_fragment, 1400551c46edSMustafa Ismail .iw_set_mw_bind_wqe = irdma_set_mw_bind_wqe, 1401551c46edSMustafa Ismail }; 1402551c46edSMustafa Ismail 1403551c46edSMustafa Ismail static const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = { 1404551c46edSMustafa Ismail .iw_copy_inline_data = irdma_copy_inline_data_gen_1, 1405551c46edSMustafa Ismail .iw_inline_data_size_to_quanta = irdma_inline_data_size_to_quanta_gen_1, 1406551c46edSMustafa Ismail .iw_set_fragment = irdma_set_fragment_gen_1, 1407551c46edSMustafa Ismail .iw_set_mw_bind_wqe = irdma_set_mw_bind_wqe_gen_1, 1408551c46edSMustafa Ismail }; 1409551c46edSMustafa Ismail 1410551c46edSMustafa Ismail /** 1411551c46edSMustafa Ismail * irdma_setup_connection_wqes - setup WQEs necessary to complete 1412551c46edSMustafa Ismail * connection. 1413551c46edSMustafa Ismail * @qp: hw qp (user and kernel) 1414551c46edSMustafa Ismail * @info: qp initialization info 1415551c46edSMustafa Ismail */ 1416551c46edSMustafa Ismail static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp, 1417551c46edSMustafa Ismail struct irdma_qp_uk_init_info *info) 1418551c46edSMustafa Ismail { 1419551c46edSMustafa Ismail u16 move_cnt = 1; 1420551c46edSMustafa Ismail 1421551c46edSMustafa Ismail if (!info->legacy_mode && 1422551c46edSMustafa Ismail (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE)) 1423551c46edSMustafa Ismail move_cnt = 3; 1424551c46edSMustafa Ismail 1425551c46edSMustafa Ismail qp->conn_wqes = move_cnt; 1426551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, move_cnt); 1427551c46edSMustafa Ismail IRDMA_RING_MOVE_TAIL_BY_COUNT(qp->sq_ring, move_cnt); 1428551c46edSMustafa Ismail IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->initial_ring, move_cnt); 1429551c46edSMustafa Ismail } 1430551c46edSMustafa Ismail 1431551c46edSMustafa Ismail /** 1432551c46edSMustafa Ismail * irdma_uk_qp_init - initialize shared qp 1433551c46edSMustafa Ismail * @qp: hw qp (user and kernel) 1434551c46edSMustafa Ismail * @info: qp initialization info 1435551c46edSMustafa Ismail * 1436551c46edSMustafa Ismail * initializes the vars used in both user and kernel mode. 1437551c46edSMustafa Ismail * size of the wqe depends on numbers of max. fragements 1438551c46edSMustafa Ismail * allowed. Then size of wqe * the number of wqes should be the 1439551c46edSMustafa Ismail * amount of memory allocated for sq and rq. 1440551c46edSMustafa Ismail */ 1441551c46edSMustafa Ismail enum irdma_status_code irdma_uk_qp_init(struct irdma_qp_uk *qp, 1442551c46edSMustafa Ismail struct irdma_qp_uk_init_info *info) 1443551c46edSMustafa Ismail { 1444551c46edSMustafa Ismail enum irdma_status_code ret_code = 0; 1445551c46edSMustafa Ismail u32 sq_ring_size; 1446551c46edSMustafa Ismail u8 sqshift, rqshift; 1447551c46edSMustafa Ismail 1448551c46edSMustafa Ismail qp->uk_attrs = info->uk_attrs; 1449551c46edSMustafa Ismail if (info->max_sq_frag_cnt > qp->uk_attrs->max_hw_wq_frags || 1450551c46edSMustafa Ismail info->max_rq_frag_cnt > qp->uk_attrs->max_hw_wq_frags) 1451551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 1452551c46edSMustafa Ismail 1453551c46edSMustafa Ismail irdma_get_wqe_shift(qp->uk_attrs, info->max_rq_frag_cnt, 0, &rqshift); 1454551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_1) { 1455551c46edSMustafa Ismail irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt, 1456551c46edSMustafa Ismail info->max_inline_data, &sqshift); 1457551c46edSMustafa Ismail if (info->abi_ver > 4) 1458551c46edSMustafa Ismail rqshift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1; 1459551c46edSMustafa Ismail } else { 1460551c46edSMustafa Ismail irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt + 1, 1461551c46edSMustafa Ismail info->max_inline_data, &sqshift); 1462551c46edSMustafa Ismail } 1463551c46edSMustafa Ismail qp->qp_caps = info->qp_caps; 1464551c46edSMustafa Ismail qp->sq_base = info->sq; 1465551c46edSMustafa Ismail qp->rq_base = info->rq; 1466551c46edSMustafa Ismail qp->qp_type = info->type ? info->type : IRDMA_QP_TYPE_IWARP; 1467551c46edSMustafa Ismail qp->shadow_area = info->shadow_area; 1468551c46edSMustafa Ismail qp->sq_wrtrk_array = info->sq_wrtrk_array; 1469551c46edSMustafa Ismail 1470551c46edSMustafa Ismail qp->rq_wrid_array = info->rq_wrid_array; 1471551c46edSMustafa Ismail qp->wqe_alloc_db = info->wqe_alloc_db; 1472551c46edSMustafa Ismail qp->qp_id = info->qp_id; 1473551c46edSMustafa Ismail qp->sq_size = info->sq_size; 1474551c46edSMustafa Ismail qp->push_mode = false; 1475551c46edSMustafa Ismail qp->max_sq_frag_cnt = info->max_sq_frag_cnt; 1476551c46edSMustafa Ismail sq_ring_size = qp->sq_size << sqshift; 1477551c46edSMustafa Ismail IRDMA_RING_INIT(qp->sq_ring, sq_ring_size); 1478551c46edSMustafa Ismail IRDMA_RING_INIT(qp->initial_ring, sq_ring_size); 1479551c46edSMustafa Ismail if (info->first_sq_wq) { 1480551c46edSMustafa Ismail irdma_setup_connection_wqes(qp, info); 1481551c46edSMustafa Ismail qp->swqe_polarity = 1; 1482551c46edSMustafa Ismail qp->first_sq_wq = true; 1483551c46edSMustafa Ismail } else { 1484551c46edSMustafa Ismail qp->swqe_polarity = 0; 1485551c46edSMustafa Ismail } 1486551c46edSMustafa Ismail qp->swqe_polarity_deferred = 1; 1487551c46edSMustafa Ismail qp->rwqe_polarity = 0; 1488551c46edSMustafa Ismail qp->rq_size = info->rq_size; 1489551c46edSMustafa Ismail qp->max_rq_frag_cnt = info->max_rq_frag_cnt; 1490551c46edSMustafa Ismail qp->max_inline_data = info->max_inline_data; 1491551c46edSMustafa Ismail qp->rq_wqe_size = rqshift; 1492551c46edSMustafa Ismail IRDMA_RING_INIT(qp->rq_ring, qp->rq_size); 1493551c46edSMustafa Ismail qp->rq_wqe_size_multiplier = 1 << rqshift; 1494551c46edSMustafa Ismail if (qp->uk_attrs->hw_rev == IRDMA_GEN_1) 1495551c46edSMustafa Ismail qp->wqe_ops = iw_wqe_uk_ops_gen_1; 1496551c46edSMustafa Ismail else 1497551c46edSMustafa Ismail qp->wqe_ops = iw_wqe_uk_ops; 1498551c46edSMustafa Ismail return ret_code; 1499551c46edSMustafa Ismail } 1500551c46edSMustafa Ismail 1501551c46edSMustafa Ismail /** 1502551c46edSMustafa Ismail * irdma_uk_cq_init - initialize shared cq (user and kernel) 1503551c46edSMustafa Ismail * @cq: hw cq 1504551c46edSMustafa Ismail * @info: hw cq initialization info 1505551c46edSMustafa Ismail */ 1506551c46edSMustafa Ismail enum irdma_status_code irdma_uk_cq_init(struct irdma_cq_uk *cq, 1507551c46edSMustafa Ismail struct irdma_cq_uk_init_info *info) 1508551c46edSMustafa Ismail { 1509551c46edSMustafa Ismail cq->cq_base = info->cq_base; 1510551c46edSMustafa Ismail cq->cq_id = info->cq_id; 1511551c46edSMustafa Ismail cq->cq_size = info->cq_size; 1512551c46edSMustafa Ismail cq->cqe_alloc_db = info->cqe_alloc_db; 1513551c46edSMustafa Ismail cq->cq_ack_db = info->cq_ack_db; 1514551c46edSMustafa Ismail cq->shadow_area = info->shadow_area; 1515551c46edSMustafa Ismail cq->avoid_mem_cflct = info->avoid_mem_cflct; 1516551c46edSMustafa Ismail IRDMA_RING_INIT(cq->cq_ring, cq->cq_size); 1517551c46edSMustafa Ismail cq->polarity = 1; 1518551c46edSMustafa Ismail 1519551c46edSMustafa Ismail return 0; 1520551c46edSMustafa Ismail } 1521551c46edSMustafa Ismail 1522551c46edSMustafa Ismail /** 1523551c46edSMustafa Ismail * irdma_uk_clean_cq - clean cq entries 1524551c46edSMustafa Ismail * @q: completion context 1525551c46edSMustafa Ismail * @cq: cq to clean 1526551c46edSMustafa Ismail */ 1527551c46edSMustafa Ismail void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq) 1528551c46edSMustafa Ismail { 1529551c46edSMustafa Ismail __le64 *cqe; 1530551c46edSMustafa Ismail u64 qword3, comp_ctx; 1531551c46edSMustafa Ismail u32 cq_head; 1532551c46edSMustafa Ismail u8 polarity, temp; 1533551c46edSMustafa Ismail 1534551c46edSMustafa Ismail cq_head = cq->cq_ring.head; 1535551c46edSMustafa Ismail temp = cq->polarity; 1536551c46edSMustafa Ismail do { 1537551c46edSMustafa Ismail if (cq->avoid_mem_cflct) 1538551c46edSMustafa Ismail cqe = ((struct irdma_extended_cqe *)(cq->cq_base))[cq_head].buf; 1539551c46edSMustafa Ismail else 1540551c46edSMustafa Ismail cqe = cq->cq_base[cq_head].buf; 1541551c46edSMustafa Ismail get_64bit_val(cqe, 24, &qword3); 1542551c46edSMustafa Ismail polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3); 1543551c46edSMustafa Ismail 1544551c46edSMustafa Ismail if (polarity != temp) 1545551c46edSMustafa Ismail break; 1546551c46edSMustafa Ismail 1547551c46edSMustafa Ismail get_64bit_val(cqe, 8, &comp_ctx); 1548551c46edSMustafa Ismail if ((void *)(unsigned long)comp_ctx == q) 1549551c46edSMustafa Ismail set_64bit_val(cqe, 8, 0); 1550551c46edSMustafa Ismail 1551551c46edSMustafa Ismail cq_head = (cq_head + 1) % cq->cq_ring.size; 1552551c46edSMustafa Ismail if (!cq_head) 1553551c46edSMustafa Ismail temp ^= 1; 1554551c46edSMustafa Ismail } while (true); 1555551c46edSMustafa Ismail } 1556551c46edSMustafa Ismail 1557551c46edSMustafa Ismail /** 1558551c46edSMustafa Ismail * irdma_nop - post a nop 1559551c46edSMustafa Ismail * @qp: hw qp ptr 1560551c46edSMustafa Ismail * @wr_id: work request id 1561551c46edSMustafa Ismail * @signaled: signaled for completion 1562551c46edSMustafa Ismail * @post_sq: ring doorbell 1563551c46edSMustafa Ismail */ 1564551c46edSMustafa Ismail enum irdma_status_code irdma_nop(struct irdma_qp_uk *qp, u64 wr_id, 1565551c46edSMustafa Ismail bool signaled, bool post_sq) 1566551c46edSMustafa Ismail { 1567551c46edSMustafa Ismail __le64 *wqe; 1568551c46edSMustafa Ismail u64 hdr; 1569551c46edSMustafa Ismail u32 wqe_idx; 1570551c46edSMustafa Ismail struct irdma_post_sq_info info = {}; 1571551c46edSMustafa Ismail 1572551c46edSMustafa Ismail info.push_wqe = false; 1573551c46edSMustafa Ismail info.wr_id = wr_id; 1574551c46edSMustafa Ismail wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA, 1575551c46edSMustafa Ismail 0, &info); 1576551c46edSMustafa Ismail if (!wqe) 1577551c46edSMustafa Ismail return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; 1578551c46edSMustafa Ismail 1579551c46edSMustafa Ismail irdma_clr_wqes(qp, wqe_idx); 1580551c46edSMustafa Ismail 1581551c46edSMustafa Ismail set_64bit_val(wqe, 0, 0); 1582551c46edSMustafa Ismail set_64bit_val(wqe, 8, 0); 1583551c46edSMustafa Ismail set_64bit_val(wqe, 16, 0); 1584551c46edSMustafa Ismail 1585551c46edSMustafa Ismail hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) | 1586551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_SIGCOMPL, signaled) | 1587551c46edSMustafa Ismail FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity); 1588551c46edSMustafa Ismail 1589551c46edSMustafa Ismail dma_wmb(); /* make sure WQE is populated before valid bit is set */ 1590551c46edSMustafa Ismail 1591551c46edSMustafa Ismail set_64bit_val(wqe, 24, hdr); 1592551c46edSMustafa Ismail if (post_sq) 1593551c46edSMustafa Ismail irdma_uk_qp_post_wr(qp); 1594551c46edSMustafa Ismail 1595551c46edSMustafa Ismail return 0; 1596551c46edSMustafa Ismail } 1597551c46edSMustafa Ismail 1598551c46edSMustafa Ismail /** 1599551c46edSMustafa Ismail * irdma_fragcnt_to_quanta_sq - calculate quanta based on fragment count for SQ 1600551c46edSMustafa Ismail * @frag_cnt: number of fragments 1601551c46edSMustafa Ismail * @quanta: quanta for frag_cnt 1602551c46edSMustafa Ismail */ 1603551c46edSMustafa Ismail enum irdma_status_code irdma_fragcnt_to_quanta_sq(u32 frag_cnt, u16 *quanta) 1604551c46edSMustafa Ismail { 1605551c46edSMustafa Ismail switch (frag_cnt) { 1606551c46edSMustafa Ismail case 0: 1607551c46edSMustafa Ismail case 1: 1608551c46edSMustafa Ismail *quanta = IRDMA_QP_WQE_MIN_QUANTA; 1609551c46edSMustafa Ismail break; 1610551c46edSMustafa Ismail case 2: 1611551c46edSMustafa Ismail case 3: 1612551c46edSMustafa Ismail *quanta = 2; 1613551c46edSMustafa Ismail break; 1614551c46edSMustafa Ismail case 4: 1615551c46edSMustafa Ismail case 5: 1616551c46edSMustafa Ismail *quanta = 3; 1617551c46edSMustafa Ismail break; 1618551c46edSMustafa Ismail case 6: 1619551c46edSMustafa Ismail case 7: 1620551c46edSMustafa Ismail *quanta = 4; 1621551c46edSMustafa Ismail break; 1622551c46edSMustafa Ismail case 8: 1623551c46edSMustafa Ismail case 9: 1624551c46edSMustafa Ismail *quanta = 5; 1625551c46edSMustafa Ismail break; 1626551c46edSMustafa Ismail case 10: 1627551c46edSMustafa Ismail case 11: 1628551c46edSMustafa Ismail *quanta = 6; 1629551c46edSMustafa Ismail break; 1630551c46edSMustafa Ismail case 12: 1631551c46edSMustafa Ismail case 13: 1632551c46edSMustafa Ismail *quanta = 7; 1633551c46edSMustafa Ismail break; 1634551c46edSMustafa Ismail case 14: 1635551c46edSMustafa Ismail case 15: /* when immediate data is present */ 1636551c46edSMustafa Ismail *quanta = 8; 1637551c46edSMustafa Ismail break; 1638551c46edSMustafa Ismail default: 1639551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 1640551c46edSMustafa Ismail } 1641551c46edSMustafa Ismail 1642551c46edSMustafa Ismail return 0; 1643551c46edSMustafa Ismail } 1644551c46edSMustafa Ismail 1645551c46edSMustafa Ismail /** 1646551c46edSMustafa Ismail * irdma_fragcnt_to_wqesize_rq - calculate wqe size based on fragment count for RQ 1647551c46edSMustafa Ismail * @frag_cnt: number of fragments 1648551c46edSMustafa Ismail * @wqe_size: size in bytes given frag_cnt 1649551c46edSMustafa Ismail */ 1650551c46edSMustafa Ismail enum irdma_status_code irdma_fragcnt_to_wqesize_rq(u32 frag_cnt, u16 *wqe_size) 1651551c46edSMustafa Ismail { 1652551c46edSMustafa Ismail switch (frag_cnt) { 1653551c46edSMustafa Ismail case 0: 1654551c46edSMustafa Ismail case 1: 1655551c46edSMustafa Ismail *wqe_size = 32; 1656551c46edSMustafa Ismail break; 1657551c46edSMustafa Ismail case 2: 1658551c46edSMustafa Ismail case 3: 1659551c46edSMustafa Ismail *wqe_size = 64; 1660551c46edSMustafa Ismail break; 1661551c46edSMustafa Ismail case 4: 1662551c46edSMustafa Ismail case 5: 1663551c46edSMustafa Ismail case 6: 1664551c46edSMustafa Ismail case 7: 1665551c46edSMustafa Ismail *wqe_size = 128; 1666551c46edSMustafa Ismail break; 1667551c46edSMustafa Ismail case 8: 1668551c46edSMustafa Ismail case 9: 1669551c46edSMustafa Ismail case 10: 1670551c46edSMustafa Ismail case 11: 1671551c46edSMustafa Ismail case 12: 1672551c46edSMustafa Ismail case 13: 1673551c46edSMustafa Ismail case 14: 1674551c46edSMustafa Ismail *wqe_size = 256; 1675551c46edSMustafa Ismail break; 1676551c46edSMustafa Ismail default: 1677551c46edSMustafa Ismail return IRDMA_ERR_INVALID_FRAG_COUNT; 1678551c46edSMustafa Ismail } 1679551c46edSMustafa Ismail 1680551c46edSMustafa Ismail return 0; 1681551c46edSMustafa Ismail } 1682