cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

uk.c (43552B)


      1// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
      2/* Copyright (c) 2015 - 2021 Intel Corporation */
      3#include "osdep.h"
      4#include "defs.h"
      5#include "user.h"
      6#include "irdma.h"
      7
      8/**
      9 * irdma_set_fragment - set fragment in wqe
     10 * @wqe: wqe for setting fragment
     11 * @offset: offset value
     12 * @sge: sge length and stag
     13 * @valid: The wqe valid
     14 */
     15static void irdma_set_fragment(__le64 *wqe, u32 offset, struct ib_sge *sge,
     16			       u8 valid)
     17{
     18	if (sge) {
     19		set_64bit_val(wqe, offset,
     20			      FIELD_PREP(IRDMAQPSQ_FRAG_TO, sge->addr));
     21		set_64bit_val(wqe, offset + 8,
     22			      FIELD_PREP(IRDMAQPSQ_VALID, valid) |
     23			      FIELD_PREP(IRDMAQPSQ_FRAG_LEN, sge->length) |
     24			      FIELD_PREP(IRDMAQPSQ_FRAG_STAG, sge->lkey));
     25	} else {
     26		set_64bit_val(wqe, offset, 0);
     27		set_64bit_val(wqe, offset + 8,
     28			      FIELD_PREP(IRDMAQPSQ_VALID, valid));
     29	}
     30}
     31
     32/**
     33 * irdma_set_fragment_gen_1 - set fragment in wqe
     34 * @wqe: wqe for setting fragment
     35 * @offset: offset value
     36 * @sge: sge length and stag
     37 * @valid: wqe valid flag
     38 */
     39static void irdma_set_fragment_gen_1(__le64 *wqe, u32 offset,
     40				     struct ib_sge *sge, u8 valid)
     41{
     42	if (sge) {
     43		set_64bit_val(wqe, offset,
     44			      FIELD_PREP(IRDMAQPSQ_FRAG_TO, sge->addr));
     45		set_64bit_val(wqe, offset + 8,
     46			      FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, sge->length) |
     47			      FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, sge->lkey));
     48	} else {
     49		set_64bit_val(wqe, offset, 0);
     50		set_64bit_val(wqe, offset + 8, 0);
     51	}
     52}
     53
     54/**
     55 * irdma_nop_1 - insert a NOP wqe
     56 * @qp: hw qp ptr
     57 */
     58static int irdma_nop_1(struct irdma_qp_uk *qp)
     59{
     60	u64 hdr;
     61	__le64 *wqe;
     62	u32 wqe_idx;
     63	bool signaled = false;
     64
     65	if (!qp->sq_ring.head)
     66		return -EINVAL;
     67
     68	wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
     69	wqe = qp->sq_base[wqe_idx].elem;
     70
     71	qp->sq_wrtrk_array[wqe_idx].quanta = IRDMA_QP_WQE_MIN_QUANTA;
     72
     73	set_64bit_val(wqe, 0, 0);
     74	set_64bit_val(wqe, 8, 0);
     75	set_64bit_val(wqe, 16, 0);
     76
     77	hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) |
     78	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, signaled) |
     79	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
     80
     81	/* make sure WQE is written before valid bit is set */
     82	dma_wmb();
     83
     84	set_64bit_val(wqe, 24, hdr);
     85
     86	return 0;
     87}
     88
     89/**
     90 * irdma_clr_wqes - clear next 128 sq entries
     91 * @qp: hw qp ptr
     92 * @qp_wqe_idx: wqe_idx
     93 */
     94void irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx)
     95{
     96	__le64 *wqe;
     97	u32 wqe_idx;
     98
     99	if (!(qp_wqe_idx & 0x7F)) {
    100		wqe_idx = (qp_wqe_idx + 128) % qp->sq_ring.size;
    101		wqe = qp->sq_base[wqe_idx].elem;
    102		if (wqe_idx)
    103			memset(wqe, qp->swqe_polarity ? 0 : 0xFF, 0x1000);
    104		else
    105			memset(wqe, qp->swqe_polarity ? 0xFF : 0, 0x1000);
    106	}
    107}
    108
    109/**
    110 * irdma_uk_qp_post_wr - ring doorbell
    111 * @qp: hw qp ptr
    112 */
    113void irdma_uk_qp_post_wr(struct irdma_qp_uk *qp)
    114{
    115	u64 temp;
    116	u32 hw_sq_tail;
    117	u32 sw_sq_head;
    118
    119	/* valid bit is written and loads completed before reading shadow */
    120	mb();
    121
    122	/* read the doorbell shadow area */
    123	get_64bit_val(qp->shadow_area, 0, &temp);
    124
    125	hw_sq_tail = (u32)FIELD_GET(IRDMA_QP_DBSA_HW_SQ_TAIL, temp);
    126	sw_sq_head = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
    127	if (sw_sq_head != qp->initial_ring.head) {
    128		if (qp->push_dropped) {
    129			writel(qp->qp_id, qp->wqe_alloc_db);
    130			qp->push_dropped = false;
    131		} else if (sw_sq_head != hw_sq_tail) {
    132			if (sw_sq_head > qp->initial_ring.head) {
    133				if (hw_sq_tail >= qp->initial_ring.head &&
    134				    hw_sq_tail < sw_sq_head)
    135					writel(qp->qp_id, qp->wqe_alloc_db);
    136			} else {
    137				if (hw_sq_tail >= qp->initial_ring.head ||
    138				    hw_sq_tail < sw_sq_head)
    139					writel(qp->qp_id, qp->wqe_alloc_db);
    140			}
    141		}
    142	}
    143
    144	qp->initial_ring.head = qp->sq_ring.head;
    145}
    146
    147/**
    148 * irdma_qp_ring_push_db -  ring qp doorbell
    149 * @qp: hw qp ptr
    150 * @wqe_idx: wqe index
    151 */
    152static void irdma_qp_ring_push_db(struct irdma_qp_uk *qp, u32 wqe_idx)
    153{
    154	set_32bit_val(qp->push_db, 0,
    155		      FIELD_PREP(IRDMA_WQEALLOC_WQE_DESC_INDEX, wqe_idx >> 3) | qp->qp_id);
    156	qp->initial_ring.head = qp->sq_ring.head;
    157	qp->push_mode = true;
    158	qp->push_dropped = false;
    159}
    160
    161void irdma_qp_push_wqe(struct irdma_qp_uk *qp, __le64 *wqe, u16 quanta,
    162		       u32 wqe_idx, bool post_sq)
    163{
    164	__le64 *push;
    165
    166	if (IRDMA_RING_CURRENT_HEAD(qp->initial_ring) !=
    167		    IRDMA_RING_CURRENT_TAIL(qp->sq_ring) &&
    168	    !qp->push_mode) {
    169		if (post_sq)
    170			irdma_uk_qp_post_wr(qp);
    171	} else {
    172		push = (__le64 *)((uintptr_t)qp->push_wqe +
    173				  (wqe_idx & 0x7) * 0x20);
    174		memcpy(push, wqe, quanta * IRDMA_QP_WQE_MIN_SIZE);
    175		irdma_qp_ring_push_db(qp, wqe_idx);
    176	}
    177}
    178
    179/**
    180 * irdma_qp_get_next_send_wqe - pad with NOP if needed, return where next WR should go
    181 * @qp: hw qp ptr
    182 * @wqe_idx: return wqe index
    183 * @quanta: size of WR in quanta
    184 * @total_size: size of WR in bytes
    185 * @info: info on WR
    186 */
    187__le64 *irdma_qp_get_next_send_wqe(struct irdma_qp_uk *qp, u32 *wqe_idx,
    188				   u16 quanta, u32 total_size,
    189				   struct irdma_post_sq_info *info)
    190{
    191	__le64 *wqe;
    192	__le64 *wqe_0 = NULL;
    193	u32 nop_wqe_idx;
    194	u16 avail_quanta;
    195	u16 i;
    196
    197	avail_quanta = qp->uk_attrs->max_hw_sq_chunk -
    198		       (IRDMA_RING_CURRENT_HEAD(qp->sq_ring) %
    199		       qp->uk_attrs->max_hw_sq_chunk);
    200	if (quanta <= avail_quanta) {
    201		/* WR fits in current chunk */
    202		if (quanta > IRDMA_SQ_RING_FREE_QUANTA(qp->sq_ring))
    203			return NULL;
    204	} else {
    205		/* Need to pad with NOP */
    206		if (quanta + avail_quanta >
    207			IRDMA_SQ_RING_FREE_QUANTA(qp->sq_ring))
    208			return NULL;
    209
    210		nop_wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
    211		for (i = 0; i < avail_quanta; i++) {
    212			irdma_nop_1(qp);
    213			IRDMA_RING_MOVE_HEAD_NOCHECK(qp->sq_ring);
    214		}
    215		if (qp->push_db && info->push_wqe)
    216			irdma_qp_push_wqe(qp, qp->sq_base[nop_wqe_idx].elem,
    217					  avail_quanta, nop_wqe_idx, true);
    218	}
    219
    220	*wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
    221	if (!*wqe_idx)
    222		qp->swqe_polarity = !qp->swqe_polarity;
    223
    224	IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, quanta);
    225
    226	wqe = qp->sq_base[*wqe_idx].elem;
    227	if (qp->uk_attrs->hw_rev == IRDMA_GEN_1 && quanta == 1 &&
    228	    (IRDMA_RING_CURRENT_HEAD(qp->sq_ring) & 1)) {
    229		wqe_0 = qp->sq_base[IRDMA_RING_CURRENT_HEAD(qp->sq_ring)].elem;
    230		wqe_0[3] = cpu_to_le64(FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity ? 0 : 1));
    231	}
    232	qp->sq_wrtrk_array[*wqe_idx].wrid = info->wr_id;
    233	qp->sq_wrtrk_array[*wqe_idx].wr_len = total_size;
    234	qp->sq_wrtrk_array[*wqe_idx].quanta = quanta;
    235
    236	return wqe;
    237}
    238
    239/**
    240 * irdma_qp_get_next_recv_wqe - get next qp's rcv wqe
    241 * @qp: hw qp ptr
    242 * @wqe_idx: return wqe index
    243 */
    244__le64 *irdma_qp_get_next_recv_wqe(struct irdma_qp_uk *qp, u32 *wqe_idx)
    245{
    246	__le64 *wqe;
    247	int ret_code;
    248
    249	if (IRDMA_RING_FULL_ERR(qp->rq_ring))
    250		return NULL;
    251
    252	IRDMA_ATOMIC_RING_MOVE_HEAD(qp->rq_ring, *wqe_idx, ret_code);
    253	if (ret_code)
    254		return NULL;
    255
    256	if (!*wqe_idx)
    257		qp->rwqe_polarity = !qp->rwqe_polarity;
    258	/* rq_wqe_size_multiplier is no of 32 byte quanta in one rq wqe */
    259	wqe = qp->rq_base[*wqe_idx * qp->rq_wqe_size_multiplier].elem;
    260
    261	return wqe;
    262}
    263
    264/**
    265 * irdma_uk_rdma_write - rdma write operation
    266 * @qp: hw qp ptr
    267 * @info: post sq information
    268 * @post_sq: flag to post sq
    269 */
    270int irdma_uk_rdma_write(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info,
    271			bool post_sq)
    272{
    273	u64 hdr;
    274	__le64 *wqe;
    275	struct irdma_rdma_write *op_info;
    276	u32 i, wqe_idx;
    277	u32 total_size = 0, byte_off;
    278	int ret_code;
    279	u32 frag_cnt, addl_frag_cnt;
    280	bool read_fence = false;
    281	u16 quanta;
    282
    283	info->push_wqe = qp->push_db ? true : false;
    284
    285	op_info = &info->op.rdma_write;
    286	if (op_info->num_lo_sges > qp->max_sq_frag_cnt)
    287		return -EINVAL;
    288
    289	for (i = 0; i < op_info->num_lo_sges; i++)
    290		total_size += op_info->lo_sg_list[i].length;
    291
    292	read_fence |= info->read_fence;
    293
    294	if (info->imm_data_valid)
    295		frag_cnt = op_info->num_lo_sges + 1;
    296	else
    297		frag_cnt = op_info->num_lo_sges;
    298	addl_frag_cnt = frag_cnt > 1 ? (frag_cnt - 1) : 0;
    299	ret_code = irdma_fragcnt_to_quanta_sq(frag_cnt, &quanta);
    300	if (ret_code)
    301		return ret_code;
    302
    303	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
    304					 info);
    305	if (!wqe)
    306		return -ENOMEM;
    307
    308	irdma_clr_wqes(qp, wqe_idx);
    309
    310	set_64bit_val(wqe, 16,
    311		      FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.addr));
    312
    313	if (info->imm_data_valid) {
    314		set_64bit_val(wqe, 0,
    315			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
    316		i = 0;
    317	} else {
    318		qp->wqe_ops.iw_set_fragment(wqe, 0,
    319					    op_info->lo_sg_list,
    320					    qp->swqe_polarity);
    321		i = 1;
    322	}
    323
    324	for (byte_off = 32; i < op_info->num_lo_sges; i++) {
    325		qp->wqe_ops.iw_set_fragment(wqe, byte_off,
    326					    &op_info->lo_sg_list[i],
    327					    qp->swqe_polarity);
    328		byte_off += 16;
    329	}
    330
    331	/* if not an odd number set valid bit in next fragment */
    332	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(frag_cnt & 0x01) &&
    333	    frag_cnt) {
    334		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
    335					    qp->swqe_polarity);
    336		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
    337			++addl_frag_cnt;
    338	}
    339
    340	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
    341	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
    342	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid) |
    343	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt) |
    344	      FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
    345	      FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) |
    346	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
    347	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
    348	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
    349	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
    350
    351	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    352
    353	set_64bit_val(wqe, 24, hdr);
    354	if (info->push_wqe) {
    355		irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq);
    356	} else {
    357		if (post_sq)
    358			irdma_uk_qp_post_wr(qp);
    359	}
    360
    361	return 0;
    362}
    363
    364/**
    365 * irdma_uk_rdma_read - rdma read command
    366 * @qp: hw qp ptr
    367 * @info: post sq information
    368 * @inv_stag: flag for inv_stag
    369 * @post_sq: flag to post sq
    370 */
    371int irdma_uk_rdma_read(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info,
    372		       bool inv_stag, bool post_sq)
    373{
    374	struct irdma_rdma_read *op_info;
    375	int ret_code;
    376	u32 i, byte_off, total_size = 0;
    377	bool local_fence = false;
    378	u32 addl_frag_cnt;
    379	__le64 *wqe;
    380	u32 wqe_idx;
    381	u16 quanta;
    382	u64 hdr;
    383
    384	info->push_wqe = qp->push_db ? true : false;
    385
    386	op_info = &info->op.rdma_read;
    387	if (qp->max_sq_frag_cnt < op_info->num_lo_sges)
    388		return -EINVAL;
    389
    390	for (i = 0; i < op_info->num_lo_sges; i++)
    391		total_size += op_info->lo_sg_list[i].length;
    392
    393	ret_code = irdma_fragcnt_to_quanta_sq(op_info->num_lo_sges, &quanta);
    394	if (ret_code)
    395		return ret_code;
    396
    397	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
    398					 info);
    399	if (!wqe)
    400		return -ENOMEM;
    401
    402	irdma_clr_wqes(qp, wqe_idx);
    403
    404	addl_frag_cnt = op_info->num_lo_sges > 1 ?
    405			(op_info->num_lo_sges - 1) : 0;
    406	local_fence |= info->local_fence;
    407
    408	qp->wqe_ops.iw_set_fragment(wqe, 0, op_info->lo_sg_list,
    409				    qp->swqe_polarity);
    410	for (i = 1, byte_off = 32; i < op_info->num_lo_sges; ++i) {
    411		qp->wqe_ops.iw_set_fragment(wqe, byte_off,
    412					    &op_info->lo_sg_list[i],
    413					    qp->swqe_polarity);
    414		byte_off += 16;
    415	}
    416
    417	/* if not an odd number set valid bit in next fragment */
    418	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 &&
    419	    !(op_info->num_lo_sges & 0x01) && op_info->num_lo_sges) {
    420		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
    421					    qp->swqe_polarity);
    422		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
    423			++addl_frag_cnt;
    424	}
    425	set_64bit_val(wqe, 16,
    426		      FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.addr));
    427	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
    428	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
    429	      FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
    430	      FIELD_PREP(IRDMAQPSQ_OPCODE,
    431			 (inv_stag ? IRDMAQP_OP_RDMA_READ_LOC_INV : IRDMAQP_OP_RDMA_READ)) |
    432	      FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) |
    433	      FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) |
    434	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) |
    435	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
    436	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
    437
    438	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    439
    440	set_64bit_val(wqe, 24, hdr);
    441	if (info->push_wqe) {
    442		irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq);
    443	} else {
    444		if (post_sq)
    445			irdma_uk_qp_post_wr(qp);
    446	}
    447
    448	return 0;
    449}
    450
    451/**
    452 * irdma_uk_send - rdma send command
    453 * @qp: hw qp ptr
    454 * @info: post sq information
    455 * @post_sq: flag to post sq
    456 */
    457int irdma_uk_send(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info,
    458		  bool post_sq)
    459{
    460	__le64 *wqe;
    461	struct irdma_post_send *op_info;
    462	u64 hdr;
    463	u32 i, wqe_idx, total_size = 0, byte_off;
    464	int ret_code;
    465	u32 frag_cnt, addl_frag_cnt;
    466	bool read_fence = false;
    467	u16 quanta;
    468
    469	info->push_wqe = qp->push_db ? true : false;
    470
    471	op_info = &info->op.send;
    472	if (qp->max_sq_frag_cnt < op_info->num_sges)
    473		return -EINVAL;
    474
    475	for (i = 0; i < op_info->num_sges; i++)
    476		total_size += op_info->sg_list[i].length;
    477
    478	if (info->imm_data_valid)
    479		frag_cnt = op_info->num_sges + 1;
    480	else
    481		frag_cnt = op_info->num_sges;
    482	ret_code = irdma_fragcnt_to_quanta_sq(frag_cnt, &quanta);
    483	if (ret_code)
    484		return ret_code;
    485
    486	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
    487					 info);
    488	if (!wqe)
    489		return -ENOMEM;
    490
    491	irdma_clr_wqes(qp, wqe_idx);
    492
    493	read_fence |= info->read_fence;
    494	addl_frag_cnt = frag_cnt > 1 ? (frag_cnt - 1) : 0;
    495	if (info->imm_data_valid) {
    496		set_64bit_val(wqe, 0,
    497			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
    498		i = 0;
    499	} else {
    500		qp->wqe_ops.iw_set_fragment(wqe, 0, op_info->sg_list,
    501					    qp->swqe_polarity);
    502		i = 1;
    503	}
    504
    505	for (byte_off = 32; i < op_info->num_sges; i++) {
    506		qp->wqe_ops.iw_set_fragment(wqe, byte_off, &op_info->sg_list[i],
    507					    qp->swqe_polarity);
    508		byte_off += 16;
    509	}
    510
    511	/* if not an odd number set valid bit in next fragment */
    512	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(frag_cnt & 0x01) &&
    513	    frag_cnt) {
    514		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
    515					    qp->swqe_polarity);
    516		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
    517			++addl_frag_cnt;
    518	}
    519
    520	set_64bit_val(wqe, 16,
    521		      FIELD_PREP(IRDMAQPSQ_DESTQKEY, op_info->qkey) |
    522		      FIELD_PREP(IRDMAQPSQ_DESTQPN, op_info->dest_qp));
    523	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) |
    524	      FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) |
    525	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG,
    526			 (info->imm_data_valid ? 1 : 0)) |
    527	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
    528	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
    529	      FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
    530	      FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) |
    531	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
    532	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
    533	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
    534	      FIELD_PREP(IRDMAQPSQ_UDPHEADER, info->udp_hdr) |
    535	      FIELD_PREP(IRDMAQPSQ_L4LEN, info->l4len) |
    536	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
    537
    538	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    539
    540	set_64bit_val(wqe, 24, hdr);
    541	if (info->push_wqe) {
    542		irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq);
    543	} else {
    544		if (post_sq)
    545			irdma_uk_qp_post_wr(qp);
    546	}
    547
    548	return 0;
    549}
    550
    551/**
    552 * irdma_set_mw_bind_wqe_gen_1 - set mw bind wqe
    553 * @wqe: wqe for setting fragment
    554 * @op_info: info for setting bind wqe values
    555 */
    556static void irdma_set_mw_bind_wqe_gen_1(__le64 *wqe,
    557					struct irdma_bind_window *op_info)
    558{
    559	set_64bit_val(wqe, 0, (uintptr_t)op_info->va);
    560	set_64bit_val(wqe, 8,
    561		      FIELD_PREP(IRDMAQPSQ_PARENTMRSTAG, op_info->mw_stag) |
    562		      FIELD_PREP(IRDMAQPSQ_MWSTAG, op_info->mr_stag));
    563	set_64bit_val(wqe, 16, op_info->bind_len);
    564}
    565
    566/**
    567 * irdma_copy_inline_data_gen_1 - Copy inline data to wqe
    568 * @dest: pointer to wqe
    569 * @src: pointer to inline data
    570 * @len: length of inline data to copy
    571 * @polarity: compatibility parameter
    572 */
    573static void irdma_copy_inline_data_gen_1(u8 *dest, u8 *src, u32 len,
    574					 u8 polarity)
    575{
    576	if (len <= 16) {
    577		memcpy(dest, src, len);
    578	} else {
    579		memcpy(dest, src, 16);
    580		src += 16;
    581		dest = dest + 32;
    582		memcpy(dest, src, len - 16);
    583	}
    584}
    585
    586/**
    587 * irdma_inline_data_size_to_quanta_gen_1 - based on inline data, quanta
    588 * @data_size: data size for inline
    589 *
    590 * Gets the quanta based on inline and immediate data.
    591 */
    592static inline u16 irdma_inline_data_size_to_quanta_gen_1(u32 data_size)
    593{
    594	return data_size <= 16 ? IRDMA_QP_WQE_MIN_QUANTA : 2;
    595}
    596
    597/**
    598 * irdma_set_mw_bind_wqe - set mw bind in wqe
    599 * @wqe: wqe for setting mw bind
    600 * @op_info: info for setting wqe values
    601 */
    602static void irdma_set_mw_bind_wqe(__le64 *wqe,
    603				  struct irdma_bind_window *op_info)
    604{
    605	set_64bit_val(wqe, 0, (uintptr_t)op_info->va);
    606	set_64bit_val(wqe, 8,
    607		      FIELD_PREP(IRDMAQPSQ_PARENTMRSTAG, op_info->mr_stag) |
    608		      FIELD_PREP(IRDMAQPSQ_MWSTAG, op_info->mw_stag));
    609	set_64bit_val(wqe, 16, op_info->bind_len);
    610}
    611
    612/**
    613 * irdma_copy_inline_data - Copy inline data to wqe
    614 * @dest: pointer to wqe
    615 * @src: pointer to inline data
    616 * @len: length of inline data to copy
    617 * @polarity: polarity of wqe valid bit
    618 */
    619static void irdma_copy_inline_data(u8 *dest, u8 *src, u32 len, u8 polarity)
    620{
    621	u8 inline_valid = polarity << IRDMA_INLINE_VALID_S;
    622	u32 copy_size;
    623
    624	dest += 8;
    625	if (len <= 8) {
    626		memcpy(dest, src, len);
    627		return;
    628	}
    629
    630	*((u64 *)dest) = *((u64 *)src);
    631	len -= 8;
    632	src += 8;
    633	dest += 24; /* point to additional 32 byte quanta */
    634
    635	while (len) {
    636		copy_size = len < 31 ? len : 31;
    637		memcpy(dest, src, copy_size);
    638		*(dest + 31) = inline_valid;
    639		len -= copy_size;
    640		dest += 32;
    641		src += copy_size;
    642	}
    643}
    644
    645/**
    646 * irdma_inline_data_size_to_quanta - based on inline data, quanta
    647 * @data_size: data size for inline
    648 *
    649 * Gets the quanta based on inline and immediate data.
    650 */
    651static u16 irdma_inline_data_size_to_quanta(u32 data_size)
    652{
    653	if (data_size <= 8)
    654		return IRDMA_QP_WQE_MIN_QUANTA;
    655	else if (data_size <= 39)
    656		return 2;
    657	else if (data_size <= 70)
    658		return 3;
    659	else if (data_size <= 101)
    660		return 4;
    661	else if (data_size <= 132)
    662		return 5;
    663	else if (data_size <= 163)
    664		return 6;
    665	else if (data_size <= 194)
    666		return 7;
    667	else
    668		return 8;
    669}
    670
    671/**
    672 * irdma_uk_inline_rdma_write - inline rdma write operation
    673 * @qp: hw qp ptr
    674 * @info: post sq information
    675 * @post_sq: flag to post sq
    676 */
    677int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
    678			       struct irdma_post_sq_info *info, bool post_sq)
    679{
    680	__le64 *wqe;
    681	struct irdma_inline_rdma_write *op_info;
    682	u64 hdr = 0;
    683	u32 wqe_idx;
    684	bool read_fence = false;
    685	u16 quanta;
    686
    687	info->push_wqe = qp->push_db ? true : false;
    688	op_info = &info->op.inline_rdma_write;
    689
    690	if (op_info->len > qp->max_inline_data)
    691		return -EINVAL;
    692
    693	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len);
    694	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len,
    695					 info);
    696	if (!wqe)
    697		return -ENOMEM;
    698
    699	irdma_clr_wqes(qp, wqe_idx);
    700
    701	read_fence |= info->read_fence;
    702	set_64bit_val(wqe, 16,
    703		      FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.addr));
    704
    705	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
    706	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
    707	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) |
    708	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) |
    709	      FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) |
    710	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) |
    711	      FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe ? 1 : 0) |
    712	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
    713	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
    714	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
    715	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
    716
    717	if (info->imm_data_valid)
    718		set_64bit_val(wqe, 0,
    719			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
    720
    721	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len,
    722					qp->swqe_polarity);
    723	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    724
    725	set_64bit_val(wqe, 24, hdr);
    726
    727	if (info->push_wqe) {
    728		irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq);
    729	} else {
    730		if (post_sq)
    731			irdma_uk_qp_post_wr(qp);
    732	}
    733
    734	return 0;
    735}
    736
    737/**
    738 * irdma_uk_inline_send - inline send operation
    739 * @qp: hw qp ptr
    740 * @info: post sq information
    741 * @post_sq: flag to post sq
    742 */
    743int irdma_uk_inline_send(struct irdma_qp_uk *qp,
    744			 struct irdma_post_sq_info *info, bool post_sq)
    745{
    746	__le64 *wqe;
    747	struct irdma_post_inline_send *op_info;
    748	u64 hdr;
    749	u32 wqe_idx;
    750	bool read_fence = false;
    751	u16 quanta;
    752
    753	info->push_wqe = qp->push_db ? true : false;
    754	op_info = &info->op.inline_send;
    755
    756	if (op_info->len > qp->max_inline_data)
    757		return -EINVAL;
    758
    759	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len);
    760	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len,
    761					 info);
    762	if (!wqe)
    763		return -ENOMEM;
    764
    765	irdma_clr_wqes(qp, wqe_idx);
    766
    767	set_64bit_val(wqe, 16,
    768		      FIELD_PREP(IRDMAQPSQ_DESTQKEY, op_info->qkey) |
    769		      FIELD_PREP(IRDMAQPSQ_DESTQPN, op_info->dest_qp));
    770
    771	read_fence |= info->read_fence;
    772	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) |
    773	      FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) |
    774	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
    775	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) |
    776	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG,
    777			 (info->imm_data_valid ? 1 : 0)) |
    778	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
    779	      FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) |
    780	      FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) |
    781	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
    782	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
    783	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
    784	      FIELD_PREP(IRDMAQPSQ_UDPHEADER, info->udp_hdr) |
    785	      FIELD_PREP(IRDMAQPSQ_L4LEN, info->l4len) |
    786	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
    787
    788	if (info->imm_data_valid)
    789		set_64bit_val(wqe, 0,
    790			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
    791	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len,
    792					qp->swqe_polarity);
    793
    794	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    795
    796	set_64bit_val(wqe, 24, hdr);
    797
    798	if (info->push_wqe) {
    799		irdma_qp_push_wqe(qp, wqe, quanta, wqe_idx, post_sq);
    800	} else {
    801		if (post_sq)
    802			irdma_uk_qp_post_wr(qp);
    803	}
    804
    805	return 0;
    806}
    807
    808/**
    809 * irdma_uk_stag_local_invalidate - stag invalidate operation
    810 * @qp: hw qp ptr
    811 * @info: post sq information
    812 * @post_sq: flag to post sq
    813 */
    814int irdma_uk_stag_local_invalidate(struct irdma_qp_uk *qp,
    815				   struct irdma_post_sq_info *info,
    816				   bool post_sq)
    817{
    818	__le64 *wqe;
    819	struct irdma_inv_local_stag *op_info;
    820	u64 hdr;
    821	u32 wqe_idx;
    822	bool local_fence = false;
    823	struct ib_sge sge = {};
    824
    825	info->push_wqe = qp->push_db ? true : false;
    826	op_info = &info->op.inv_local_stag;
    827	local_fence = info->local_fence;
    828
    829	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA,
    830					 0, info);
    831	if (!wqe)
    832		return -ENOMEM;
    833
    834	irdma_clr_wqes(qp, wqe_idx);
    835
    836	sge.lkey = op_info->target_stag;
    837	qp->wqe_ops.iw_set_fragment(wqe, 0, &sge, 0);
    838
    839	set_64bit_val(wqe, 16, 0);
    840
    841	hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMA_OP_TYPE_INV_STAG) |
    842	      FIELD_PREP(IRDMAQPSQ_PUSHWQE, info->push_wqe) |
    843	      FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) |
    844	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) |
    845	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
    846	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
    847
    848	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    849
    850	set_64bit_val(wqe, 24, hdr);
    851
    852	if (info->push_wqe) {
    853		irdma_qp_push_wqe(qp, wqe, IRDMA_QP_WQE_MIN_QUANTA, wqe_idx,
    854				  post_sq);
    855	} else {
    856		if (post_sq)
    857			irdma_uk_qp_post_wr(qp);
    858	}
    859
    860	return 0;
    861}
    862
    863/**
    864 * irdma_uk_post_receive - post receive wqe
    865 * @qp: hw qp ptr
    866 * @info: post rq information
    867 */
    868int irdma_uk_post_receive(struct irdma_qp_uk *qp,
    869			  struct irdma_post_rq_info *info)
    870{
    871	u32 wqe_idx, i, byte_off;
    872	u32 addl_frag_cnt;
    873	__le64 *wqe;
    874	u64 hdr;
    875
    876	if (qp->max_rq_frag_cnt < info->num_sges)
    877		return -EINVAL;
    878
    879	wqe = irdma_qp_get_next_recv_wqe(qp, &wqe_idx);
    880	if (!wqe)
    881		return -ENOMEM;
    882
    883	qp->rq_wrid_array[wqe_idx] = info->wr_id;
    884	addl_frag_cnt = info->num_sges > 1 ? (info->num_sges - 1) : 0;
    885	qp->wqe_ops.iw_set_fragment(wqe, 0, info->sg_list,
    886				    qp->rwqe_polarity);
    887
    888	for (i = 1, byte_off = 32; i < info->num_sges; i++) {
    889		qp->wqe_ops.iw_set_fragment(wqe, byte_off, &info->sg_list[i],
    890					    qp->rwqe_polarity);
    891		byte_off += 16;
    892	}
    893
    894	/* if not an odd number set valid bit in next fragment */
    895	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(info->num_sges & 0x01) &&
    896	    info->num_sges) {
    897		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
    898					    qp->rwqe_polarity);
    899		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
    900			++addl_frag_cnt;
    901	}
    902
    903	set_64bit_val(wqe, 16, 0);
    904	hdr = FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
    905	      FIELD_PREP(IRDMAQPSQ_VALID, qp->rwqe_polarity);
    906
    907	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    908
    909	set_64bit_val(wqe, 24, hdr);
    910
    911	return 0;
    912}
    913
    914/**
    915 * irdma_uk_cq_resize - reset the cq buffer info
    916 * @cq: cq to resize
    917 * @cq_base: new cq buffer addr
    918 * @cq_size: number of cqes
    919 */
    920void irdma_uk_cq_resize(struct irdma_cq_uk *cq, void *cq_base, int cq_size)
    921{
    922	cq->cq_base = cq_base;
    923	cq->cq_size = cq_size;
    924	IRDMA_RING_INIT(cq->cq_ring, cq->cq_size);
    925	cq->polarity = 1;
    926}
    927
    928/**
    929 * irdma_uk_cq_set_resized_cnt - record the count of the resized buffers
    930 * @cq: cq to resize
    931 * @cq_cnt: the count of the resized cq buffers
    932 */
    933void irdma_uk_cq_set_resized_cnt(struct irdma_cq_uk *cq, u16 cq_cnt)
    934{
    935	u64 temp_val;
    936	u16 sw_cq_sel;
    937	u8 arm_next_se;
    938	u8 arm_next;
    939	u8 arm_seq_num;
    940
    941	get_64bit_val(cq->shadow_area, 32, &temp_val);
    942
    943	sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val);
    944	sw_cq_sel += cq_cnt;
    945
    946	arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val);
    947	arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val);
    948	arm_next = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT, temp_val);
    949
    950	temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) |
    951		   FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) |
    952		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) |
    953		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, arm_next);
    954
    955	set_64bit_val(cq->shadow_area, 32, temp_val);
    956}
    957
    958/**
    959 * irdma_uk_cq_request_notification - cq notification request (door bell)
    960 * @cq: hw cq
    961 * @cq_notify: notification type
    962 */
    963void irdma_uk_cq_request_notification(struct irdma_cq_uk *cq,
    964				      enum irdma_cmpl_notify cq_notify)
    965{
    966	u64 temp_val;
    967	u16 sw_cq_sel;
    968	u8 arm_next_se = 0;
    969	u8 arm_next = 0;
    970	u8 arm_seq_num;
    971
    972	get_64bit_val(cq->shadow_area, 32, &temp_val);
    973	arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val);
    974	arm_seq_num++;
    975	sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val);
    976	arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val);
    977	arm_next_se |= 1;
    978	if (cq_notify == IRDMA_CQ_COMPL_EVENT)
    979		arm_next = 1;
    980	temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) |
    981		   FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) |
    982		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) |
    983		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, arm_next);
    984
    985	set_64bit_val(cq->shadow_area, 32, temp_val);
    986
    987	dma_wmb(); /* make sure WQE is populated before valid bit is set */
    988
    989	writel(cq->cq_id, cq->cqe_alloc_db);
    990}
    991
    992/**
    993 * irdma_uk_cq_poll_cmpl - get cq completion info
    994 * @cq: hw cq
    995 * @info: cq poll information returned
    996 */
    997int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
    998			  struct irdma_cq_poll_info *info)
    999{
   1000	u64 comp_ctx, qword0, qword2, qword3;
   1001	__le64 *cqe;
   1002	struct irdma_qp_uk *qp;
   1003	struct irdma_ring *pring = NULL;
   1004	u32 wqe_idx, q_type;
   1005	int ret_code;
   1006	bool move_cq_head = true;
   1007	u8 polarity;
   1008	bool ext_valid;
   1009	__le64 *ext_cqe;
   1010
   1011	if (cq->avoid_mem_cflct)
   1012		cqe = IRDMA_GET_CURRENT_EXTENDED_CQ_ELEM(cq);
   1013	else
   1014		cqe = IRDMA_GET_CURRENT_CQ_ELEM(cq);
   1015
   1016	get_64bit_val(cqe, 24, &qword3);
   1017	polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3);
   1018	if (polarity != cq->polarity)
   1019		return -ENOENT;
   1020
   1021	/* Ensure CQE contents are read after valid bit is checked */
   1022	dma_rmb();
   1023
   1024	ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3);
   1025	if (ext_valid) {
   1026		u64 qword6, qword7;
   1027		u32 peek_head;
   1028
   1029		if (cq->avoid_mem_cflct) {
   1030			ext_cqe = (__le64 *)((u8 *)cqe + 32);
   1031			get_64bit_val(ext_cqe, 24, &qword7);
   1032			polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword7);
   1033		} else {
   1034			peek_head = (cq->cq_ring.head + 1) % cq->cq_ring.size;
   1035			ext_cqe = cq->cq_base[peek_head].buf;
   1036			get_64bit_val(ext_cqe, 24, &qword7);
   1037			polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword7);
   1038			if (!peek_head)
   1039				polarity ^= 1;
   1040		}
   1041		if (polarity != cq->polarity)
   1042			return -ENOENT;
   1043
   1044		/* Ensure ext CQE contents are read after ext valid bit is checked */
   1045		dma_rmb();
   1046
   1047		info->imm_valid = (bool)FIELD_GET(IRDMA_CQ_IMMVALID, qword7);
   1048		if (info->imm_valid) {
   1049			u64 qword4;
   1050
   1051			get_64bit_val(ext_cqe, 0, &qword4);
   1052			info->imm_data = (u32)FIELD_GET(IRDMA_CQ_IMMDATALOW32, qword4);
   1053		}
   1054		info->ud_smac_valid = (bool)FIELD_GET(IRDMA_CQ_UDSMACVALID, qword7);
   1055		info->ud_vlan_valid = (bool)FIELD_GET(IRDMA_CQ_UDVLANVALID, qword7);
   1056		if (info->ud_smac_valid || info->ud_vlan_valid) {
   1057			get_64bit_val(ext_cqe, 16, &qword6);
   1058			if (info->ud_vlan_valid)
   1059				info->ud_vlan = (u16)FIELD_GET(IRDMA_CQ_UDVLAN, qword6);
   1060			if (info->ud_smac_valid) {
   1061				info->ud_smac[5] = qword6 & 0xFF;
   1062				info->ud_smac[4] = (qword6 >> 8) & 0xFF;
   1063				info->ud_smac[3] = (qword6 >> 16) & 0xFF;
   1064				info->ud_smac[2] = (qword6 >> 24) & 0xFF;
   1065				info->ud_smac[1] = (qword6 >> 32) & 0xFF;
   1066				info->ud_smac[0] = (qword6 >> 40) & 0xFF;
   1067			}
   1068		}
   1069	} else {
   1070		info->imm_valid = false;
   1071		info->ud_smac_valid = false;
   1072		info->ud_vlan_valid = false;
   1073	}
   1074
   1075	q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
   1076	info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3);
   1077	info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3);
   1078	info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3);
   1079	if (info->error) {
   1080		info->major_err = FIELD_GET(IRDMA_CQ_MAJERR, qword3);
   1081		info->minor_err = FIELD_GET(IRDMA_CQ_MINERR, qword3);
   1082		if (info->major_err == IRDMA_FLUSH_MAJOR_ERR) {
   1083			info->comp_status = IRDMA_COMPL_STATUS_FLUSHED;
   1084			/* Set the min error to standard flush error code for remaining cqes */
   1085			if (info->minor_err != FLUSH_GENERAL_ERR) {
   1086				qword3 &= ~IRDMA_CQ_MINERR;
   1087				qword3 |= FIELD_PREP(IRDMA_CQ_MINERR, FLUSH_GENERAL_ERR);
   1088				set_64bit_val(cqe, 24, qword3);
   1089			}
   1090		} else {
   1091			info->comp_status = IRDMA_COMPL_STATUS_UNKNOWN;
   1092		}
   1093	} else {
   1094		info->comp_status = IRDMA_COMPL_STATUS_SUCCESS;
   1095	}
   1096
   1097	get_64bit_val(cqe, 0, &qword0);
   1098	get_64bit_val(cqe, 16, &qword2);
   1099
   1100	info->tcp_seq_num_rtt = (u32)FIELD_GET(IRDMACQ_TCPSEQNUMRTT, qword0);
   1101	info->qp_id = (u32)FIELD_GET(IRDMACQ_QPID, qword2);
   1102	info->ud_src_qpn = (u32)FIELD_GET(IRDMACQ_UDSRCQPN, qword2);
   1103
   1104	get_64bit_val(cqe, 8, &comp_ctx);
   1105
   1106	info->solicited_event = (bool)FIELD_GET(IRDMACQ_SOEVENT, qword3);
   1107	qp = (struct irdma_qp_uk *)(unsigned long)comp_ctx;
   1108	if (!qp || qp->destroy_pending) {
   1109		ret_code = -EFAULT;
   1110		goto exit;
   1111	}
   1112	wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3);
   1113	info->qp_handle = (irdma_qp_handle)(unsigned long)qp;
   1114
   1115	if (q_type == IRDMA_CQE_QTYPE_RQ) {
   1116		u32 array_idx;
   1117
   1118		array_idx = wqe_idx / qp->rq_wqe_size_multiplier;
   1119
   1120		if (info->comp_status == IRDMA_COMPL_STATUS_FLUSHED ||
   1121		    info->comp_status == IRDMA_COMPL_STATUS_UNKNOWN) {
   1122			if (!IRDMA_RING_MORE_WORK(qp->rq_ring)) {
   1123				ret_code = -ENOENT;
   1124				goto exit;
   1125			}
   1126
   1127			info->wr_id = qp->rq_wrid_array[qp->rq_ring.tail];
   1128			array_idx = qp->rq_ring.tail;
   1129		} else {
   1130			info->wr_id = qp->rq_wrid_array[array_idx];
   1131		}
   1132
   1133		info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0);
   1134
   1135		if (info->imm_valid)
   1136			info->op_type = IRDMA_OP_TYPE_REC_IMM;
   1137		else
   1138			info->op_type = IRDMA_OP_TYPE_REC;
   1139		if (qword3 & IRDMACQ_STAG) {
   1140			info->stag_invalid_set = true;
   1141			info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2);
   1142		} else {
   1143			info->stag_invalid_set = false;
   1144		}
   1145		IRDMA_RING_SET_TAIL(qp->rq_ring, array_idx + 1);
   1146		if (info->comp_status == IRDMA_COMPL_STATUS_FLUSHED) {
   1147			qp->rq_flush_seen = true;
   1148			if (!IRDMA_RING_MORE_WORK(qp->rq_ring))
   1149				qp->rq_flush_complete = true;
   1150			else
   1151				move_cq_head = false;
   1152		}
   1153		pring = &qp->rq_ring;
   1154	} else { /* q_type is IRDMA_CQE_QTYPE_SQ */
   1155		if (qp->first_sq_wq) {
   1156			if (wqe_idx + 1 >= qp->conn_wqes)
   1157				qp->first_sq_wq = false;
   1158
   1159			if (wqe_idx < qp->conn_wqes && qp->sq_ring.head == qp->sq_ring.tail) {
   1160				IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
   1161				IRDMA_RING_MOVE_TAIL(cq->cq_ring);
   1162				set_64bit_val(cq->shadow_area, 0,
   1163					      IRDMA_RING_CURRENT_HEAD(cq->cq_ring));
   1164				memset(info, 0,
   1165				       sizeof(struct irdma_cq_poll_info));
   1166				return irdma_uk_cq_poll_cmpl(cq, info);
   1167			}
   1168		}
   1169		/*cease posting push mode on push drop*/
   1170		if (info->push_dropped) {
   1171			qp->push_mode = false;
   1172			qp->push_dropped = true;
   1173		}
   1174		if (info->comp_status != IRDMA_COMPL_STATUS_FLUSHED) {
   1175			info->wr_id = qp->sq_wrtrk_array[wqe_idx].wrid;
   1176			if (!info->comp_status)
   1177				info->bytes_xfered = qp->sq_wrtrk_array[wqe_idx].wr_len;
   1178			info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3);
   1179			IRDMA_RING_SET_TAIL(qp->sq_ring,
   1180					    wqe_idx + qp->sq_wrtrk_array[wqe_idx].quanta);
   1181		} else {
   1182			if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) {
   1183				ret_code = -ENOENT;
   1184				goto exit;
   1185			}
   1186
   1187			do {
   1188				__le64 *sw_wqe;
   1189				u64 wqe_qword;
   1190				u8 op_type;
   1191				u32 tail;
   1192
   1193				tail = qp->sq_ring.tail;
   1194				sw_wqe = qp->sq_base[tail].elem;
   1195				get_64bit_val(sw_wqe, 24,
   1196					      &wqe_qword);
   1197				op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword);
   1198				info->op_type = op_type;
   1199				IRDMA_RING_SET_TAIL(qp->sq_ring,
   1200						    tail + qp->sq_wrtrk_array[tail].quanta);
   1201				if (op_type != IRDMAQP_OP_NOP) {
   1202					info->wr_id = qp->sq_wrtrk_array[tail].wrid;
   1203					info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len;
   1204					break;
   1205				}
   1206			} while (1);
   1207			qp->sq_flush_seen = true;
   1208			if (!IRDMA_RING_MORE_WORK(qp->sq_ring))
   1209				qp->sq_flush_complete = true;
   1210		}
   1211		pring = &qp->sq_ring;
   1212	}
   1213
   1214	ret_code = 0;
   1215
   1216exit:
   1217	if (!ret_code && info->comp_status == IRDMA_COMPL_STATUS_FLUSHED)
   1218		if (pring && IRDMA_RING_MORE_WORK(*pring))
   1219			move_cq_head = false;
   1220
   1221	if (move_cq_head) {
   1222		IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
   1223		if (!IRDMA_RING_CURRENT_HEAD(cq->cq_ring))
   1224			cq->polarity ^= 1;
   1225
   1226		if (ext_valid && !cq->avoid_mem_cflct) {
   1227			IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
   1228			if (!IRDMA_RING_CURRENT_HEAD(cq->cq_ring))
   1229				cq->polarity ^= 1;
   1230		}
   1231
   1232		IRDMA_RING_MOVE_TAIL(cq->cq_ring);
   1233		if (!cq->avoid_mem_cflct && ext_valid)
   1234			IRDMA_RING_MOVE_TAIL(cq->cq_ring);
   1235		set_64bit_val(cq->shadow_area, 0,
   1236			      IRDMA_RING_CURRENT_HEAD(cq->cq_ring));
   1237	} else {
   1238		qword3 &= ~IRDMA_CQ_WQEIDX;
   1239		qword3 |= FIELD_PREP(IRDMA_CQ_WQEIDX, pring->tail);
   1240		set_64bit_val(cqe, 24, qword3);
   1241	}
   1242
   1243	return ret_code;
   1244}
   1245
   1246/**
   1247 * irdma_qp_round_up - return round up qp wq depth
   1248 * @wqdepth: wq depth in quanta to round up
   1249 */
   1250static int irdma_qp_round_up(u32 wqdepth)
   1251{
   1252	int scount = 1;
   1253
   1254	for (wqdepth--; scount <= 16; scount *= 2)
   1255		wqdepth |= wqdepth >> scount;
   1256
   1257	return ++wqdepth;
   1258}
   1259
   1260/**
   1261 * irdma_get_wqe_shift - get shift count for maximum wqe size
   1262 * @uk_attrs: qp HW attributes
   1263 * @sge: Maximum Scatter Gather Elements wqe
   1264 * @inline_data: Maximum inline data size
   1265 * @shift: Returns the shift needed based on sge
   1266 *
   1267 * Shift can be used to left shift the wqe size based on number of SGEs and inlind data size.
   1268 * For 1 SGE or inline data <= 8, shift = 0 (wqe size of 32
   1269 * bytes). For 2 or 3 SGEs or inline data <= 39, shift = 1 (wqe
   1270 * size of 64 bytes).
   1271 * For 4-7 SGE's and inline <= 101 Shift of 2 otherwise (wqe
   1272 * size of 256 bytes).
   1273 */
   1274void irdma_get_wqe_shift(struct irdma_uk_attrs *uk_attrs, u32 sge,
   1275			 u32 inline_data, u8 *shift)
   1276{
   1277	*shift = 0;
   1278	if (uk_attrs->hw_rev >= IRDMA_GEN_2) {
   1279		if (sge > 1 || inline_data > 8) {
   1280			if (sge < 4 && inline_data <= 39)
   1281				*shift = 1;
   1282			else if (sge < 8 && inline_data <= 101)
   1283				*shift = 2;
   1284			else
   1285				*shift = 3;
   1286		}
   1287	} else if (sge > 1 || inline_data > 16) {
   1288		*shift = (sge < 4 && inline_data <= 48) ? 1 : 2;
   1289	}
   1290}
   1291
   1292/*
   1293 * irdma_get_sqdepth - get SQ depth (quanta)
   1294 * @uk_attrs: qp HW attributes
   1295 * @sq_size: SQ size
   1296 * @shift: shift which determines size of WQE
   1297 * @sqdepth: depth of SQ
   1298 *
   1299 */
   1300int irdma_get_sqdepth(struct irdma_uk_attrs *uk_attrs, u32 sq_size, u8 shift,
   1301		      u32 *sqdepth)
   1302{
   1303	*sqdepth = irdma_qp_round_up((sq_size << shift) + IRDMA_SQ_RSVD);
   1304
   1305	if (*sqdepth < (IRDMA_QP_SW_MIN_WQSIZE << shift))
   1306		*sqdepth = IRDMA_QP_SW_MIN_WQSIZE << shift;
   1307	else if (*sqdepth > uk_attrs->max_hw_wq_quanta)
   1308		return -EINVAL;
   1309
   1310	return 0;
   1311}
   1312
   1313/*
   1314 * irdma_get_rqdepth - get RQ depth (quanta)
   1315 * @uk_attrs: qp HW attributes
   1316 * @rq_size: RQ size
   1317 * @shift: shift which determines size of WQE
   1318 * @rqdepth: depth of RQ
   1319 */
   1320int irdma_get_rqdepth(struct irdma_uk_attrs *uk_attrs, u32 rq_size, u8 shift,
   1321		      u32 *rqdepth)
   1322{
   1323	*rqdepth = irdma_qp_round_up((rq_size << shift) + IRDMA_RQ_RSVD);
   1324
   1325	if (*rqdepth < (IRDMA_QP_SW_MIN_WQSIZE << shift))
   1326		*rqdepth = IRDMA_QP_SW_MIN_WQSIZE << shift;
   1327	else if (*rqdepth > uk_attrs->max_hw_rq_quanta)
   1328		return -EINVAL;
   1329
   1330	return 0;
   1331}
   1332
   1333static const struct irdma_wqe_uk_ops iw_wqe_uk_ops = {
   1334	.iw_copy_inline_data = irdma_copy_inline_data,
   1335	.iw_inline_data_size_to_quanta = irdma_inline_data_size_to_quanta,
   1336	.iw_set_fragment = irdma_set_fragment,
   1337	.iw_set_mw_bind_wqe = irdma_set_mw_bind_wqe,
   1338};
   1339
   1340static const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = {
   1341	.iw_copy_inline_data = irdma_copy_inline_data_gen_1,
   1342	.iw_inline_data_size_to_quanta = irdma_inline_data_size_to_quanta_gen_1,
   1343	.iw_set_fragment = irdma_set_fragment_gen_1,
   1344	.iw_set_mw_bind_wqe = irdma_set_mw_bind_wqe_gen_1,
   1345};
   1346
   1347/**
   1348 * irdma_setup_connection_wqes - setup WQEs necessary to complete
   1349 * connection.
   1350 * @qp: hw qp (user and kernel)
   1351 * @info: qp initialization info
   1352 */
   1353static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp,
   1354					struct irdma_qp_uk_init_info *info)
   1355{
   1356	u16 move_cnt = 1;
   1357
   1358	if (!info->legacy_mode &&
   1359	    (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE))
   1360		move_cnt = 3;
   1361
   1362	qp->conn_wqes = move_cnt;
   1363	IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, move_cnt);
   1364	IRDMA_RING_MOVE_TAIL_BY_COUNT(qp->sq_ring, move_cnt);
   1365	IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->initial_ring, move_cnt);
   1366}
   1367
   1368/**
   1369 * irdma_uk_qp_init - initialize shared qp
   1370 * @qp: hw qp (user and kernel)
   1371 * @info: qp initialization info
   1372 *
   1373 * initializes the vars used in both user and kernel mode.
   1374 * size of the wqe depends on numbers of max. fragements
   1375 * allowed. Then size of wqe * the number of wqes should be the
   1376 * amount of memory allocated for sq and rq.
   1377 */
   1378int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
   1379{
   1380	int ret_code = 0;
   1381	u32 sq_ring_size;
   1382	u8 sqshift, rqshift;
   1383
   1384	qp->uk_attrs = info->uk_attrs;
   1385	if (info->max_sq_frag_cnt > qp->uk_attrs->max_hw_wq_frags ||
   1386	    info->max_rq_frag_cnt > qp->uk_attrs->max_hw_wq_frags)
   1387		return -EINVAL;
   1388
   1389	irdma_get_wqe_shift(qp->uk_attrs, info->max_rq_frag_cnt, 0, &rqshift);
   1390	if (qp->uk_attrs->hw_rev == IRDMA_GEN_1) {
   1391		irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt,
   1392				    info->max_inline_data, &sqshift);
   1393		if (info->abi_ver > 4)
   1394			rqshift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
   1395	} else {
   1396		irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt + 1,
   1397				    info->max_inline_data, &sqshift);
   1398	}
   1399	qp->qp_caps = info->qp_caps;
   1400	qp->sq_base = info->sq;
   1401	qp->rq_base = info->rq;
   1402	qp->qp_type = info->type ? info->type : IRDMA_QP_TYPE_IWARP;
   1403	qp->shadow_area = info->shadow_area;
   1404	qp->sq_wrtrk_array = info->sq_wrtrk_array;
   1405
   1406	qp->rq_wrid_array = info->rq_wrid_array;
   1407	qp->wqe_alloc_db = info->wqe_alloc_db;
   1408	qp->qp_id = info->qp_id;
   1409	qp->sq_size = info->sq_size;
   1410	qp->push_mode = false;
   1411	qp->max_sq_frag_cnt = info->max_sq_frag_cnt;
   1412	sq_ring_size = qp->sq_size << sqshift;
   1413	IRDMA_RING_INIT(qp->sq_ring, sq_ring_size);
   1414	IRDMA_RING_INIT(qp->initial_ring, sq_ring_size);
   1415	if (info->first_sq_wq) {
   1416		irdma_setup_connection_wqes(qp, info);
   1417		qp->swqe_polarity = 1;
   1418		qp->first_sq_wq = true;
   1419	} else {
   1420		qp->swqe_polarity = 0;
   1421	}
   1422	qp->swqe_polarity_deferred = 1;
   1423	qp->rwqe_polarity = 0;
   1424	qp->rq_size = info->rq_size;
   1425	qp->max_rq_frag_cnt = info->max_rq_frag_cnt;
   1426	qp->max_inline_data = info->max_inline_data;
   1427	qp->rq_wqe_size = rqshift;
   1428	IRDMA_RING_INIT(qp->rq_ring, qp->rq_size);
   1429	qp->rq_wqe_size_multiplier = 1 << rqshift;
   1430	if (qp->uk_attrs->hw_rev == IRDMA_GEN_1)
   1431		qp->wqe_ops = iw_wqe_uk_ops_gen_1;
   1432	else
   1433		qp->wqe_ops = iw_wqe_uk_ops;
   1434	return ret_code;
   1435}
   1436
   1437/**
   1438 * irdma_uk_cq_init - initialize shared cq (user and kernel)
   1439 * @cq: hw cq
   1440 * @info: hw cq initialization info
   1441 */
   1442void irdma_uk_cq_init(struct irdma_cq_uk *cq,
   1443		      struct irdma_cq_uk_init_info *info)
   1444{
   1445	cq->cq_base = info->cq_base;
   1446	cq->cq_id = info->cq_id;
   1447	cq->cq_size = info->cq_size;
   1448	cq->cqe_alloc_db = info->cqe_alloc_db;
   1449	cq->cq_ack_db = info->cq_ack_db;
   1450	cq->shadow_area = info->shadow_area;
   1451	cq->avoid_mem_cflct = info->avoid_mem_cflct;
   1452	IRDMA_RING_INIT(cq->cq_ring, cq->cq_size);
   1453	cq->polarity = 1;
   1454}
   1455
   1456/**
   1457 * irdma_uk_clean_cq - clean cq entries
   1458 * @q: completion context
   1459 * @cq: cq to clean
   1460 */
   1461void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq)
   1462{
   1463	__le64 *cqe;
   1464	u64 qword3, comp_ctx;
   1465	u32 cq_head;
   1466	u8 polarity, temp;
   1467
   1468	cq_head = cq->cq_ring.head;
   1469	temp = cq->polarity;
   1470	do {
   1471		if (cq->avoid_mem_cflct)
   1472			cqe = ((struct irdma_extended_cqe *)(cq->cq_base))[cq_head].buf;
   1473		else
   1474			cqe = cq->cq_base[cq_head].buf;
   1475		get_64bit_val(cqe, 24, &qword3);
   1476		polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3);
   1477
   1478		if (polarity != temp)
   1479			break;
   1480
   1481		get_64bit_val(cqe, 8, &comp_ctx);
   1482		if ((void *)(unsigned long)comp_ctx == q)
   1483			set_64bit_val(cqe, 8, 0);
   1484
   1485		cq_head = (cq_head + 1) % cq->cq_ring.size;
   1486		if (!cq_head)
   1487			temp ^= 1;
   1488	} while (true);
   1489}
   1490
   1491/**
   1492 * irdma_nop - post a nop
   1493 * @qp: hw qp ptr
   1494 * @wr_id: work request id
   1495 * @signaled: signaled for completion
   1496 * @post_sq: ring doorbell
   1497 */
   1498int irdma_nop(struct irdma_qp_uk *qp, u64 wr_id, bool signaled, bool post_sq)
   1499{
   1500	__le64 *wqe;
   1501	u64 hdr;
   1502	u32 wqe_idx;
   1503	struct irdma_post_sq_info info = {};
   1504
   1505	info.push_wqe = false;
   1506	info.wr_id = wr_id;
   1507	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA,
   1508					 0, &info);
   1509	if (!wqe)
   1510		return -ENOMEM;
   1511
   1512	irdma_clr_wqes(qp, wqe_idx);
   1513
   1514	set_64bit_val(wqe, 0, 0);
   1515	set_64bit_val(wqe, 8, 0);
   1516	set_64bit_val(wqe, 16, 0);
   1517
   1518	hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) |
   1519	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, signaled) |
   1520	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
   1521
   1522	dma_wmb(); /* make sure WQE is populated before valid bit is set */
   1523
   1524	set_64bit_val(wqe, 24, hdr);
   1525	if (post_sq)
   1526		irdma_uk_qp_post_wr(qp);
   1527
   1528	return 0;
   1529}
   1530
   1531/**
   1532 * irdma_fragcnt_to_quanta_sq - calculate quanta based on fragment count for SQ
   1533 * @frag_cnt: number of fragments
   1534 * @quanta: quanta for frag_cnt
   1535 */
   1536int irdma_fragcnt_to_quanta_sq(u32 frag_cnt, u16 *quanta)
   1537{
   1538	switch (frag_cnt) {
   1539	case 0:
   1540	case 1:
   1541		*quanta = IRDMA_QP_WQE_MIN_QUANTA;
   1542		break;
   1543	case 2:
   1544	case 3:
   1545		*quanta = 2;
   1546		break;
   1547	case 4:
   1548	case 5:
   1549		*quanta = 3;
   1550		break;
   1551	case 6:
   1552	case 7:
   1553		*quanta = 4;
   1554		break;
   1555	case 8:
   1556	case 9:
   1557		*quanta = 5;
   1558		break;
   1559	case 10:
   1560	case 11:
   1561		*quanta = 6;
   1562		break;
   1563	case 12:
   1564	case 13:
   1565		*quanta = 7;
   1566		break;
   1567	case 14:
   1568	case 15: /* when immediate data is present */
   1569		*quanta = 8;
   1570		break;
   1571	default:
   1572		return -EINVAL;
   1573	}
   1574
   1575	return 0;
   1576}
   1577
   1578/**
   1579 * irdma_fragcnt_to_wqesize_rq - calculate wqe size based on fragment count for RQ
   1580 * @frag_cnt: number of fragments
   1581 * @wqe_size: size in bytes given frag_cnt
   1582 */
   1583int irdma_fragcnt_to_wqesize_rq(u32 frag_cnt, u16 *wqe_size)
   1584{
   1585	switch (frag_cnt) {
   1586	case 0:
   1587	case 1:
   1588		*wqe_size = 32;
   1589		break;
   1590	case 2:
   1591	case 3:
   1592		*wqe_size = 64;
   1593		break;
   1594	case 4:
   1595	case 5:
   1596	case 6:
   1597	case 7:
   1598		*wqe_size = 128;
   1599		break;
   1600	case 8:
   1601	case 9:
   1602	case 10:
   1603	case 11:
   1604	case 12:
   1605	case 13:
   1606	case 14:
   1607		*wqe_size = 256;
   1608		break;
   1609	default:
   1610		return -EINVAL;
   1611	}
   1612
   1613	return 0;
   1614}