162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
262306a36Sopenharmony_ci/* Copyright (c) 2015 - 2021 Intel Corporation */
362306a36Sopenharmony_ci#include "osdep.h"
462306a36Sopenharmony_ci#include "defs.h"
562306a36Sopenharmony_ci#include "user.h"
662306a36Sopenharmony_ci#include "irdma.h"
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/**
962306a36Sopenharmony_ci * irdma_set_fragment - set fragment in wqe
1062306a36Sopenharmony_ci * @wqe: wqe for setting fragment
1162306a36Sopenharmony_ci * @offset: offset value
1262306a36Sopenharmony_ci * @sge: sge length and stag
1362306a36Sopenharmony_ci * @valid: The wqe valid
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_cistatic void irdma_set_fragment(__le64 *wqe, u32 offset, struct ib_sge *sge,
1662306a36Sopenharmony_ci			       u8 valid)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	if (sge) {
1962306a36Sopenharmony_ci		set_64bit_val(wqe, offset,
2062306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_FRAG_TO, sge->addr));
2162306a36Sopenharmony_ci		set_64bit_val(wqe, offset + 8,
2262306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_VALID, valid) |
2362306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_FRAG_LEN, sge->length) |
2462306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_FRAG_STAG, sge->lkey));
2562306a36Sopenharmony_ci	} else {
2662306a36Sopenharmony_ci		set_64bit_val(wqe, offset, 0);
2762306a36Sopenharmony_ci		set_64bit_val(wqe, offset + 8,
2862306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_VALID, valid));
2962306a36Sopenharmony_ci	}
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/**
3362306a36Sopenharmony_ci * irdma_set_fragment_gen_1 - set fragment in wqe
3462306a36Sopenharmony_ci * @wqe: wqe for setting fragment
3562306a36Sopenharmony_ci * @offset: offset value
3662306a36Sopenharmony_ci * @sge: sge length and stag
3762306a36Sopenharmony_ci * @valid: wqe valid flag
3862306a36Sopenharmony_ci */
3962306a36Sopenharmony_cistatic void irdma_set_fragment_gen_1(__le64 *wqe, u32 offset,
4062306a36Sopenharmony_ci				     struct ib_sge *sge, u8 valid)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	if (sge) {
4362306a36Sopenharmony_ci		set_64bit_val(wqe, offset,
4462306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_FRAG_TO, sge->addr));
4562306a36Sopenharmony_ci		set_64bit_val(wqe, offset + 8,
4662306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_LEN, sge->length) |
4762306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_GEN1_FRAG_STAG, sge->lkey));
4862306a36Sopenharmony_ci	} else {
4962306a36Sopenharmony_ci		set_64bit_val(wqe, offset, 0);
5062306a36Sopenharmony_ci		set_64bit_val(wqe, offset + 8, 0);
5162306a36Sopenharmony_ci	}
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/**
5562306a36Sopenharmony_ci * irdma_nop_1 - insert a NOP wqe
5662306a36Sopenharmony_ci * @qp: hw qp ptr
5762306a36Sopenharmony_ci */
5862306a36Sopenharmony_cistatic int irdma_nop_1(struct irdma_qp_uk *qp)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	u64 hdr;
6162306a36Sopenharmony_ci	__le64 *wqe;
6262306a36Sopenharmony_ci	u32 wqe_idx;
6362306a36Sopenharmony_ci	bool signaled = false;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if (!qp->sq_ring.head)
6662306a36Sopenharmony_ci		return -EINVAL;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
6962306a36Sopenharmony_ci	wqe = qp->sq_base[wqe_idx].elem;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	qp->sq_wrtrk_array[wqe_idx].quanta = IRDMA_QP_WQE_MIN_QUANTA;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	set_64bit_val(wqe, 0, 0);
7462306a36Sopenharmony_ci	set_64bit_val(wqe, 8, 0);
7562306a36Sopenharmony_ci	set_64bit_val(wqe, 16, 0);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) |
7862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, signaled) |
7962306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	/* make sure WQE is written before valid bit is set */
8262306a36Sopenharmony_ci	dma_wmb();
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return 0;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/**
9062306a36Sopenharmony_ci * irdma_clr_wqes - clear next 128 sq entries
9162306a36Sopenharmony_ci * @qp: hw qp ptr
9262306a36Sopenharmony_ci * @qp_wqe_idx: wqe_idx
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_civoid irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx)
9562306a36Sopenharmony_ci{
9662306a36Sopenharmony_ci	struct irdma_qp_quanta *sq;
9762306a36Sopenharmony_ci	u32 wqe_idx;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	if (!(qp_wqe_idx & 0x7F)) {
10062306a36Sopenharmony_ci		wqe_idx = (qp_wqe_idx + 128) % qp->sq_ring.size;
10162306a36Sopenharmony_ci		sq = qp->sq_base + wqe_idx;
10262306a36Sopenharmony_ci		if (wqe_idx)
10362306a36Sopenharmony_ci			memset(sq, qp->swqe_polarity ? 0 : 0xFF,
10462306a36Sopenharmony_ci			       128 * sizeof(*sq));
10562306a36Sopenharmony_ci		else
10662306a36Sopenharmony_ci			memset(sq, qp->swqe_polarity ? 0xFF : 0,
10762306a36Sopenharmony_ci			       128 * sizeof(*sq));
10862306a36Sopenharmony_ci	}
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci/**
11262306a36Sopenharmony_ci * irdma_uk_qp_post_wr - ring doorbell
11362306a36Sopenharmony_ci * @qp: hw qp ptr
11462306a36Sopenharmony_ci */
11562306a36Sopenharmony_civoid irdma_uk_qp_post_wr(struct irdma_qp_uk *qp)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	u64 temp;
11862306a36Sopenharmony_ci	u32 hw_sq_tail;
11962306a36Sopenharmony_ci	u32 sw_sq_head;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	/* valid bit is written and loads completed before reading shadow */
12262306a36Sopenharmony_ci	mb();
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	/* read the doorbell shadow area */
12562306a36Sopenharmony_ci	get_64bit_val(qp->shadow_area, 0, &temp);
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	hw_sq_tail = (u32)FIELD_GET(IRDMA_QP_DBSA_HW_SQ_TAIL, temp);
12862306a36Sopenharmony_ci	sw_sq_head = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
12962306a36Sopenharmony_ci	if (sw_sq_head != qp->initial_ring.head) {
13062306a36Sopenharmony_ci		if (sw_sq_head != hw_sq_tail) {
13162306a36Sopenharmony_ci			if (sw_sq_head > qp->initial_ring.head) {
13262306a36Sopenharmony_ci				if (hw_sq_tail >= qp->initial_ring.head &&
13362306a36Sopenharmony_ci				    hw_sq_tail < sw_sq_head)
13462306a36Sopenharmony_ci					writel(qp->qp_id, qp->wqe_alloc_db);
13562306a36Sopenharmony_ci			} else {
13662306a36Sopenharmony_ci				if (hw_sq_tail >= qp->initial_ring.head ||
13762306a36Sopenharmony_ci				    hw_sq_tail < sw_sq_head)
13862306a36Sopenharmony_ci					writel(qp->qp_id, qp->wqe_alloc_db);
13962306a36Sopenharmony_ci			}
14062306a36Sopenharmony_ci		}
14162306a36Sopenharmony_ci	}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	qp->initial_ring.head = qp->sq_ring.head;
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci/**
14762306a36Sopenharmony_ci * irdma_qp_get_next_send_wqe - pad with NOP if needed, return where next WR should go
14862306a36Sopenharmony_ci * @qp: hw qp ptr
14962306a36Sopenharmony_ci * @wqe_idx: return wqe index
15062306a36Sopenharmony_ci * @quanta: size of WR in quanta
15162306a36Sopenharmony_ci * @total_size: size of WR in bytes
15262306a36Sopenharmony_ci * @info: info on WR
15362306a36Sopenharmony_ci */
15462306a36Sopenharmony_ci__le64 *irdma_qp_get_next_send_wqe(struct irdma_qp_uk *qp, u32 *wqe_idx,
15562306a36Sopenharmony_ci				   u16 quanta, u32 total_size,
15662306a36Sopenharmony_ci				   struct irdma_post_sq_info *info)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	__le64 *wqe;
15962306a36Sopenharmony_ci	__le64 *wqe_0 = NULL;
16062306a36Sopenharmony_ci	u16 avail_quanta;
16162306a36Sopenharmony_ci	u16 i;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	avail_quanta = qp->uk_attrs->max_hw_sq_chunk -
16462306a36Sopenharmony_ci		       (IRDMA_RING_CURRENT_HEAD(qp->sq_ring) %
16562306a36Sopenharmony_ci		       qp->uk_attrs->max_hw_sq_chunk);
16662306a36Sopenharmony_ci	if (quanta <= avail_quanta) {
16762306a36Sopenharmony_ci		/* WR fits in current chunk */
16862306a36Sopenharmony_ci		if (quanta > IRDMA_SQ_RING_FREE_QUANTA(qp->sq_ring))
16962306a36Sopenharmony_ci			return NULL;
17062306a36Sopenharmony_ci	} else {
17162306a36Sopenharmony_ci		/* Need to pad with NOP */
17262306a36Sopenharmony_ci		if (quanta + avail_quanta >
17362306a36Sopenharmony_ci			IRDMA_SQ_RING_FREE_QUANTA(qp->sq_ring))
17462306a36Sopenharmony_ci			return NULL;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci		for (i = 0; i < avail_quanta; i++) {
17762306a36Sopenharmony_ci			irdma_nop_1(qp);
17862306a36Sopenharmony_ci			IRDMA_RING_MOVE_HEAD_NOCHECK(qp->sq_ring);
17962306a36Sopenharmony_ci		}
18062306a36Sopenharmony_ci	}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	*wqe_idx = IRDMA_RING_CURRENT_HEAD(qp->sq_ring);
18362306a36Sopenharmony_ci	if (!*wqe_idx)
18462306a36Sopenharmony_ci		qp->swqe_polarity = !qp->swqe_polarity;
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, quanta);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	wqe = qp->sq_base[*wqe_idx].elem;
18962306a36Sopenharmony_ci	if (qp->uk_attrs->hw_rev == IRDMA_GEN_1 && quanta == 1 &&
19062306a36Sopenharmony_ci	    (IRDMA_RING_CURRENT_HEAD(qp->sq_ring) & 1)) {
19162306a36Sopenharmony_ci		wqe_0 = qp->sq_base[IRDMA_RING_CURRENT_HEAD(qp->sq_ring)].elem;
19262306a36Sopenharmony_ci		wqe_0[3] = cpu_to_le64(FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity ? 0 : 1));
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci	qp->sq_wrtrk_array[*wqe_idx].wrid = info->wr_id;
19562306a36Sopenharmony_ci	qp->sq_wrtrk_array[*wqe_idx].wr_len = total_size;
19662306a36Sopenharmony_ci	qp->sq_wrtrk_array[*wqe_idx].quanta = quanta;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	return wqe;
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/**
20262306a36Sopenharmony_ci * irdma_qp_get_next_recv_wqe - get next qp's rcv wqe
20362306a36Sopenharmony_ci * @qp: hw qp ptr
20462306a36Sopenharmony_ci * @wqe_idx: return wqe index
20562306a36Sopenharmony_ci */
20662306a36Sopenharmony_ci__le64 *irdma_qp_get_next_recv_wqe(struct irdma_qp_uk *qp, u32 *wqe_idx)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	__le64 *wqe;
20962306a36Sopenharmony_ci	int ret_code;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	if (IRDMA_RING_FULL_ERR(qp->rq_ring))
21262306a36Sopenharmony_ci		return NULL;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	IRDMA_ATOMIC_RING_MOVE_HEAD(qp->rq_ring, *wqe_idx, ret_code);
21562306a36Sopenharmony_ci	if (ret_code)
21662306a36Sopenharmony_ci		return NULL;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	if (!*wqe_idx)
21962306a36Sopenharmony_ci		qp->rwqe_polarity = !qp->rwqe_polarity;
22062306a36Sopenharmony_ci	/* rq_wqe_size_multiplier is no of 32 byte quanta in one rq wqe */
22162306a36Sopenharmony_ci	wqe = qp->rq_base[*wqe_idx * qp->rq_wqe_size_multiplier].elem;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	return wqe;
22462306a36Sopenharmony_ci}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci/**
22762306a36Sopenharmony_ci * irdma_uk_rdma_write - rdma write operation
22862306a36Sopenharmony_ci * @qp: hw qp ptr
22962306a36Sopenharmony_ci * @info: post sq information
23062306a36Sopenharmony_ci * @post_sq: flag to post sq
23162306a36Sopenharmony_ci */
23262306a36Sopenharmony_ciint irdma_uk_rdma_write(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info,
23362306a36Sopenharmony_ci			bool post_sq)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	u64 hdr;
23662306a36Sopenharmony_ci	__le64 *wqe;
23762306a36Sopenharmony_ci	struct irdma_rdma_write *op_info;
23862306a36Sopenharmony_ci	u32 i, wqe_idx;
23962306a36Sopenharmony_ci	u32 total_size = 0, byte_off;
24062306a36Sopenharmony_ci	int ret_code;
24162306a36Sopenharmony_ci	u32 frag_cnt, addl_frag_cnt;
24262306a36Sopenharmony_ci	bool read_fence = false;
24362306a36Sopenharmony_ci	u16 quanta;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	op_info = &info->op.rdma_write;
24662306a36Sopenharmony_ci	if (op_info->num_lo_sges > qp->max_sq_frag_cnt)
24762306a36Sopenharmony_ci		return -EINVAL;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	for (i = 0; i < op_info->num_lo_sges; i++)
25062306a36Sopenharmony_ci		total_size += op_info->lo_sg_list[i].length;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	read_fence |= info->read_fence;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	if (info->imm_data_valid)
25562306a36Sopenharmony_ci		frag_cnt = op_info->num_lo_sges + 1;
25662306a36Sopenharmony_ci	else
25762306a36Sopenharmony_ci		frag_cnt = op_info->num_lo_sges;
25862306a36Sopenharmony_ci	addl_frag_cnt = frag_cnt > 1 ? (frag_cnt - 1) : 0;
25962306a36Sopenharmony_ci	ret_code = irdma_fragcnt_to_quanta_sq(frag_cnt, &quanta);
26062306a36Sopenharmony_ci	if (ret_code)
26162306a36Sopenharmony_ci		return ret_code;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
26462306a36Sopenharmony_ci					 info);
26562306a36Sopenharmony_ci	if (!wqe)
26662306a36Sopenharmony_ci		return -ENOMEM;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	set_64bit_val(wqe, 16,
27162306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.addr));
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	if (info->imm_data_valid) {
27462306a36Sopenharmony_ci		set_64bit_val(wqe, 0,
27562306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
27662306a36Sopenharmony_ci		i = 0;
27762306a36Sopenharmony_ci	} else {
27862306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, 0,
27962306a36Sopenharmony_ci					    op_info->lo_sg_list,
28062306a36Sopenharmony_ci					    qp->swqe_polarity);
28162306a36Sopenharmony_ci		i = 1;
28262306a36Sopenharmony_ci	}
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	for (byte_off = 32; i < op_info->num_lo_sges; i++) {
28562306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off,
28662306a36Sopenharmony_ci					    &op_info->lo_sg_list[i],
28762306a36Sopenharmony_ci					    qp->swqe_polarity);
28862306a36Sopenharmony_ci		byte_off += 16;
28962306a36Sopenharmony_ci	}
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/* if not an odd number set valid bit in next fragment */
29262306a36Sopenharmony_ci	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(frag_cnt & 0x01) &&
29362306a36Sopenharmony_ci	    frag_cnt) {
29462306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
29562306a36Sopenharmony_ci					    qp->swqe_polarity);
29662306a36Sopenharmony_ci		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
29762306a36Sopenharmony_ci			++addl_frag_cnt;
29862306a36Sopenharmony_ci	}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
30162306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
30262306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid) |
30362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt) |
30462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
30562306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
30662306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
30762306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
30862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	if (post_sq)
31562306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	return 0;
31862306a36Sopenharmony_ci}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci/**
32162306a36Sopenharmony_ci * irdma_uk_rdma_read - rdma read command
32262306a36Sopenharmony_ci * @qp: hw qp ptr
32362306a36Sopenharmony_ci * @info: post sq information
32462306a36Sopenharmony_ci * @inv_stag: flag for inv_stag
32562306a36Sopenharmony_ci * @post_sq: flag to post sq
32662306a36Sopenharmony_ci */
32762306a36Sopenharmony_ciint irdma_uk_rdma_read(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info,
32862306a36Sopenharmony_ci		       bool inv_stag, bool post_sq)
32962306a36Sopenharmony_ci{
33062306a36Sopenharmony_ci	struct irdma_rdma_read *op_info;
33162306a36Sopenharmony_ci	int ret_code;
33262306a36Sopenharmony_ci	u32 i, byte_off, total_size = 0;
33362306a36Sopenharmony_ci	bool local_fence = false;
33462306a36Sopenharmony_ci	u32 addl_frag_cnt;
33562306a36Sopenharmony_ci	__le64 *wqe;
33662306a36Sopenharmony_ci	u32 wqe_idx;
33762306a36Sopenharmony_ci	u16 quanta;
33862306a36Sopenharmony_ci	u64 hdr;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	op_info = &info->op.rdma_read;
34162306a36Sopenharmony_ci	if (qp->max_sq_frag_cnt < op_info->num_lo_sges)
34262306a36Sopenharmony_ci		return -EINVAL;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	for (i = 0; i < op_info->num_lo_sges; i++)
34562306a36Sopenharmony_ci		total_size += op_info->lo_sg_list[i].length;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	ret_code = irdma_fragcnt_to_quanta_sq(op_info->num_lo_sges, &quanta);
34862306a36Sopenharmony_ci	if (ret_code)
34962306a36Sopenharmony_ci		return ret_code;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
35262306a36Sopenharmony_ci					 info);
35362306a36Sopenharmony_ci	if (!wqe)
35462306a36Sopenharmony_ci		return -ENOMEM;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	addl_frag_cnt = op_info->num_lo_sges > 1 ?
35962306a36Sopenharmony_ci			(op_info->num_lo_sges - 1) : 0;
36062306a36Sopenharmony_ci	local_fence |= info->local_fence;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	qp->wqe_ops.iw_set_fragment(wqe, 0, op_info->lo_sg_list,
36362306a36Sopenharmony_ci				    qp->swqe_polarity);
36462306a36Sopenharmony_ci	for (i = 1, byte_off = 32; i < op_info->num_lo_sges; ++i) {
36562306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off,
36662306a36Sopenharmony_ci					    &op_info->lo_sg_list[i],
36762306a36Sopenharmony_ci					    qp->swqe_polarity);
36862306a36Sopenharmony_ci		byte_off += 16;
36962306a36Sopenharmony_ci	}
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	/* if not an odd number set valid bit in next fragment */
37262306a36Sopenharmony_ci	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 &&
37362306a36Sopenharmony_ci	    !(op_info->num_lo_sges & 0x01) && op_info->num_lo_sges) {
37462306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
37562306a36Sopenharmony_ci					    qp->swqe_polarity);
37662306a36Sopenharmony_ci		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
37762306a36Sopenharmony_ci			++addl_frag_cnt;
37862306a36Sopenharmony_ci	}
37962306a36Sopenharmony_ci	set_64bit_val(wqe, 16,
38062306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.addr));
38162306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
38262306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
38362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
38462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_OPCODE,
38562306a36Sopenharmony_ci			 (inv_stag ? IRDMAQP_OP_RDMA_READ_LOC_INV : IRDMAQP_OP_RDMA_READ)) |
38662306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) |
38762306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) |
38862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
38962306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	if (post_sq)
39662306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	return 0;
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci/**
40262306a36Sopenharmony_ci * irdma_uk_send - rdma send command
40362306a36Sopenharmony_ci * @qp: hw qp ptr
40462306a36Sopenharmony_ci * @info: post sq information
40562306a36Sopenharmony_ci * @post_sq: flag to post sq
40662306a36Sopenharmony_ci */
40762306a36Sopenharmony_ciint irdma_uk_send(struct irdma_qp_uk *qp, struct irdma_post_sq_info *info,
40862306a36Sopenharmony_ci		  bool post_sq)
40962306a36Sopenharmony_ci{
41062306a36Sopenharmony_ci	__le64 *wqe;
41162306a36Sopenharmony_ci	struct irdma_post_send *op_info;
41262306a36Sopenharmony_ci	u64 hdr;
41362306a36Sopenharmony_ci	u32 i, wqe_idx, total_size = 0, byte_off;
41462306a36Sopenharmony_ci	int ret_code;
41562306a36Sopenharmony_ci	u32 frag_cnt, addl_frag_cnt;
41662306a36Sopenharmony_ci	bool read_fence = false;
41762306a36Sopenharmony_ci	u16 quanta;
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	op_info = &info->op.send;
42062306a36Sopenharmony_ci	if (qp->max_sq_frag_cnt < op_info->num_sges)
42162306a36Sopenharmony_ci		return -EINVAL;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	for (i = 0; i < op_info->num_sges; i++)
42462306a36Sopenharmony_ci		total_size += op_info->sg_list[i].length;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	if (info->imm_data_valid)
42762306a36Sopenharmony_ci		frag_cnt = op_info->num_sges + 1;
42862306a36Sopenharmony_ci	else
42962306a36Sopenharmony_ci		frag_cnt = op_info->num_sges;
43062306a36Sopenharmony_ci	ret_code = irdma_fragcnt_to_quanta_sq(frag_cnt, &quanta);
43162306a36Sopenharmony_ci	if (ret_code)
43262306a36Sopenharmony_ci		return ret_code;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
43562306a36Sopenharmony_ci					 info);
43662306a36Sopenharmony_ci	if (!wqe)
43762306a36Sopenharmony_ci		return -ENOMEM;
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	read_fence |= info->read_fence;
44262306a36Sopenharmony_ci	addl_frag_cnt = frag_cnt > 1 ? (frag_cnt - 1) : 0;
44362306a36Sopenharmony_ci	if (info->imm_data_valid) {
44462306a36Sopenharmony_ci		set_64bit_val(wqe, 0,
44562306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
44662306a36Sopenharmony_ci		i = 0;
44762306a36Sopenharmony_ci	} else {
44862306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, 0,
44962306a36Sopenharmony_ci					    frag_cnt ? op_info->sg_list : NULL,
45062306a36Sopenharmony_ci					    qp->swqe_polarity);
45162306a36Sopenharmony_ci		i = 1;
45262306a36Sopenharmony_ci	}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	for (byte_off = 32; i < op_info->num_sges; i++) {
45562306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off, &op_info->sg_list[i],
45662306a36Sopenharmony_ci					    qp->swqe_polarity);
45762306a36Sopenharmony_ci		byte_off += 16;
45862306a36Sopenharmony_ci	}
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	/* if not an odd number set valid bit in next fragment */
46162306a36Sopenharmony_ci	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(frag_cnt & 0x01) &&
46262306a36Sopenharmony_ci	    frag_cnt) {
46362306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
46462306a36Sopenharmony_ci					    qp->swqe_polarity);
46562306a36Sopenharmony_ci		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
46662306a36Sopenharmony_ci			++addl_frag_cnt;
46762306a36Sopenharmony_ci	}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	set_64bit_val(wqe, 16,
47062306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_DESTQKEY, op_info->qkey) |
47162306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_DESTQPN, op_info->dest_qp));
47262306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) |
47362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) |
47462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG,
47562306a36Sopenharmony_ci			 (info->imm_data_valid ? 1 : 0)) |
47662306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
47762306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
47862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
47962306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
48062306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
48162306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
48262306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_UDPHEADER, info->udp_hdr) |
48362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_L4LEN, info->l4len) |
48462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	if (post_sq)
49162306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	return 0;
49462306a36Sopenharmony_ci}
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci/**
49762306a36Sopenharmony_ci * irdma_set_mw_bind_wqe_gen_1 - set mw bind wqe
49862306a36Sopenharmony_ci * @wqe: wqe for setting fragment
49962306a36Sopenharmony_ci * @op_info: info for setting bind wqe values
50062306a36Sopenharmony_ci */
50162306a36Sopenharmony_cistatic void irdma_set_mw_bind_wqe_gen_1(__le64 *wqe,
50262306a36Sopenharmony_ci					struct irdma_bind_window *op_info)
50362306a36Sopenharmony_ci{
50462306a36Sopenharmony_ci	set_64bit_val(wqe, 0, (uintptr_t)op_info->va);
50562306a36Sopenharmony_ci	set_64bit_val(wqe, 8,
50662306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_PARENTMRSTAG, op_info->mw_stag) |
50762306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_MWSTAG, op_info->mr_stag));
50862306a36Sopenharmony_ci	set_64bit_val(wqe, 16, op_info->bind_len);
50962306a36Sopenharmony_ci}
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci/**
51262306a36Sopenharmony_ci * irdma_copy_inline_data_gen_1 - Copy inline data to wqe
51362306a36Sopenharmony_ci * @wqe: pointer to wqe
51462306a36Sopenharmony_ci * @sge_list: table of pointers to inline data
51562306a36Sopenharmony_ci * @num_sges: Total inline data length
51662306a36Sopenharmony_ci * @polarity: compatibility parameter
51762306a36Sopenharmony_ci */
51862306a36Sopenharmony_cistatic void irdma_copy_inline_data_gen_1(u8 *wqe, struct ib_sge *sge_list,
51962306a36Sopenharmony_ci					 u32 num_sges, u8 polarity)
52062306a36Sopenharmony_ci{
52162306a36Sopenharmony_ci	u32 quanta_bytes_remaining = 16;
52262306a36Sopenharmony_ci	int i;
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	for (i = 0; i < num_sges; i++) {
52562306a36Sopenharmony_ci		u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr;
52662306a36Sopenharmony_ci		u32 sge_len = sge_list[i].length;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci		while (sge_len) {
52962306a36Sopenharmony_ci			u32 bytes_copied;
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci			bytes_copied = min(sge_len, quanta_bytes_remaining);
53262306a36Sopenharmony_ci			memcpy(wqe, cur_sge, bytes_copied);
53362306a36Sopenharmony_ci			wqe += bytes_copied;
53462306a36Sopenharmony_ci			cur_sge += bytes_copied;
53562306a36Sopenharmony_ci			quanta_bytes_remaining -= bytes_copied;
53662306a36Sopenharmony_ci			sge_len -= bytes_copied;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci			if (!quanta_bytes_remaining) {
53962306a36Sopenharmony_ci				/* Remaining inline bytes reside after hdr */
54062306a36Sopenharmony_ci				wqe += 16;
54162306a36Sopenharmony_ci				quanta_bytes_remaining = 32;
54262306a36Sopenharmony_ci			}
54362306a36Sopenharmony_ci		}
54462306a36Sopenharmony_ci	}
54562306a36Sopenharmony_ci}
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci/**
54862306a36Sopenharmony_ci * irdma_inline_data_size_to_quanta_gen_1 - based on inline data, quanta
54962306a36Sopenharmony_ci * @data_size: data size for inline
55062306a36Sopenharmony_ci *
55162306a36Sopenharmony_ci * Gets the quanta based on inline and immediate data.
55262306a36Sopenharmony_ci */
55362306a36Sopenharmony_cistatic inline u16 irdma_inline_data_size_to_quanta_gen_1(u32 data_size)
55462306a36Sopenharmony_ci{
55562306a36Sopenharmony_ci	return data_size <= 16 ? IRDMA_QP_WQE_MIN_QUANTA : 2;
55662306a36Sopenharmony_ci}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci/**
55962306a36Sopenharmony_ci * irdma_set_mw_bind_wqe - set mw bind in wqe
56062306a36Sopenharmony_ci * @wqe: wqe for setting mw bind
56162306a36Sopenharmony_ci * @op_info: info for setting wqe values
56262306a36Sopenharmony_ci */
56362306a36Sopenharmony_cistatic void irdma_set_mw_bind_wqe(__le64 *wqe,
56462306a36Sopenharmony_ci				  struct irdma_bind_window *op_info)
56562306a36Sopenharmony_ci{
56662306a36Sopenharmony_ci	set_64bit_val(wqe, 0, (uintptr_t)op_info->va);
56762306a36Sopenharmony_ci	set_64bit_val(wqe, 8,
56862306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_PARENTMRSTAG, op_info->mr_stag) |
56962306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_MWSTAG, op_info->mw_stag));
57062306a36Sopenharmony_ci	set_64bit_val(wqe, 16, op_info->bind_len);
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci/**
57462306a36Sopenharmony_ci * irdma_copy_inline_data - Copy inline data to wqe
57562306a36Sopenharmony_ci * @wqe: pointer to wqe
57662306a36Sopenharmony_ci * @sge_list: table of pointers to inline data
57762306a36Sopenharmony_ci * @num_sges: number of SGE's
57862306a36Sopenharmony_ci * @polarity: polarity of wqe valid bit
57962306a36Sopenharmony_ci */
58062306a36Sopenharmony_cistatic void irdma_copy_inline_data(u8 *wqe, struct ib_sge *sge_list,
58162306a36Sopenharmony_ci				   u32 num_sges, u8 polarity)
58262306a36Sopenharmony_ci{
58362306a36Sopenharmony_ci	u8 inline_valid = polarity << IRDMA_INLINE_VALID_S;
58462306a36Sopenharmony_ci	u32 quanta_bytes_remaining = 8;
58562306a36Sopenharmony_ci	bool first_quanta = true;
58662306a36Sopenharmony_ci	int i;
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	wqe += 8;
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci	for (i = 0; i < num_sges; i++) {
59162306a36Sopenharmony_ci		u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr;
59262306a36Sopenharmony_ci		u32 sge_len = sge_list[i].length;
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci		while (sge_len) {
59562306a36Sopenharmony_ci			u32 bytes_copied;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci			bytes_copied = min(sge_len, quanta_bytes_remaining);
59862306a36Sopenharmony_ci			memcpy(wqe, cur_sge, bytes_copied);
59962306a36Sopenharmony_ci			wqe += bytes_copied;
60062306a36Sopenharmony_ci			cur_sge += bytes_copied;
60162306a36Sopenharmony_ci			quanta_bytes_remaining -= bytes_copied;
60262306a36Sopenharmony_ci			sge_len -= bytes_copied;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci			if (!quanta_bytes_remaining) {
60562306a36Sopenharmony_ci				quanta_bytes_remaining = 31;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci				/* Remaining inline bytes reside after hdr */
60862306a36Sopenharmony_ci				if (first_quanta) {
60962306a36Sopenharmony_ci					first_quanta = false;
61062306a36Sopenharmony_ci					wqe += 16;
61162306a36Sopenharmony_ci				} else {
61262306a36Sopenharmony_ci					*wqe = inline_valid;
61362306a36Sopenharmony_ci					wqe++;
61462306a36Sopenharmony_ci				}
61562306a36Sopenharmony_ci			}
61662306a36Sopenharmony_ci		}
61762306a36Sopenharmony_ci	}
61862306a36Sopenharmony_ci	if (!first_quanta && quanta_bytes_remaining < 31)
61962306a36Sopenharmony_ci		*(wqe + quanta_bytes_remaining) = inline_valid;
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci/**
62362306a36Sopenharmony_ci * irdma_inline_data_size_to_quanta - based on inline data, quanta
62462306a36Sopenharmony_ci * @data_size: data size for inline
62562306a36Sopenharmony_ci *
62662306a36Sopenharmony_ci * Gets the quanta based on inline and immediate data.
62762306a36Sopenharmony_ci */
62862306a36Sopenharmony_cistatic u16 irdma_inline_data_size_to_quanta(u32 data_size)
62962306a36Sopenharmony_ci{
63062306a36Sopenharmony_ci	if (data_size <= 8)
63162306a36Sopenharmony_ci		return IRDMA_QP_WQE_MIN_QUANTA;
63262306a36Sopenharmony_ci	else if (data_size <= 39)
63362306a36Sopenharmony_ci		return 2;
63462306a36Sopenharmony_ci	else if (data_size <= 70)
63562306a36Sopenharmony_ci		return 3;
63662306a36Sopenharmony_ci	else if (data_size <= 101)
63762306a36Sopenharmony_ci		return 4;
63862306a36Sopenharmony_ci	else if (data_size <= 132)
63962306a36Sopenharmony_ci		return 5;
64062306a36Sopenharmony_ci	else if (data_size <= 163)
64162306a36Sopenharmony_ci		return 6;
64262306a36Sopenharmony_ci	else if (data_size <= 194)
64362306a36Sopenharmony_ci		return 7;
64462306a36Sopenharmony_ci	else
64562306a36Sopenharmony_ci		return 8;
64662306a36Sopenharmony_ci}
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci/**
64962306a36Sopenharmony_ci * irdma_uk_inline_rdma_write - inline rdma write operation
65062306a36Sopenharmony_ci * @qp: hw qp ptr
65162306a36Sopenharmony_ci * @info: post sq information
65262306a36Sopenharmony_ci * @post_sq: flag to post sq
65362306a36Sopenharmony_ci */
65462306a36Sopenharmony_ciint irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
65562306a36Sopenharmony_ci			       struct irdma_post_sq_info *info, bool post_sq)
65662306a36Sopenharmony_ci{
65762306a36Sopenharmony_ci	__le64 *wqe;
65862306a36Sopenharmony_ci	struct irdma_rdma_write *op_info;
65962306a36Sopenharmony_ci	u64 hdr = 0;
66062306a36Sopenharmony_ci	u32 wqe_idx;
66162306a36Sopenharmony_ci	bool read_fence = false;
66262306a36Sopenharmony_ci	u32 i, total_size = 0;
66362306a36Sopenharmony_ci	u16 quanta;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	op_info = &info->op.rdma_write;
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	if (unlikely(qp->max_sq_frag_cnt < op_info->num_lo_sges))
66862306a36Sopenharmony_ci		return -EINVAL;
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	for (i = 0; i < op_info->num_lo_sges; i++)
67162306a36Sopenharmony_ci		total_size += op_info->lo_sg_list[i].length;
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci	if (unlikely(total_size > qp->max_inline_data))
67462306a36Sopenharmony_ci		return -EINVAL;
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size);
67762306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
67862306a36Sopenharmony_ci					 info);
67962306a36Sopenharmony_ci	if (!wqe)
68062306a36Sopenharmony_ci		return -ENOMEM;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	read_fence |= info->read_fence;
68562306a36Sopenharmony_ci	set_64bit_val(wqe, 16,
68662306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_FRAG_TO, op_info->rem_addr.addr));
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
68962306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
69062306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) |
69162306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) |
69262306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) |
69362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) |
69462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
69562306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
69662306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
69762306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	if (info->imm_data_valid)
70062306a36Sopenharmony_ci		set_64bit_val(wqe, 0,
70162306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->lo_sg_list,
70462306a36Sopenharmony_ci					op_info->num_lo_sges,
70562306a36Sopenharmony_ci					qp->swqe_polarity);
70662306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	if (post_sq)
71162306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	return 0;
71462306a36Sopenharmony_ci}
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci/**
71762306a36Sopenharmony_ci * irdma_uk_inline_send - inline send operation
71862306a36Sopenharmony_ci * @qp: hw qp ptr
71962306a36Sopenharmony_ci * @info: post sq information
72062306a36Sopenharmony_ci * @post_sq: flag to post sq
72162306a36Sopenharmony_ci */
72262306a36Sopenharmony_ciint irdma_uk_inline_send(struct irdma_qp_uk *qp,
72362306a36Sopenharmony_ci			 struct irdma_post_sq_info *info, bool post_sq)
72462306a36Sopenharmony_ci{
72562306a36Sopenharmony_ci	__le64 *wqe;
72662306a36Sopenharmony_ci	struct irdma_post_send *op_info;
72762306a36Sopenharmony_ci	u64 hdr;
72862306a36Sopenharmony_ci	u32 wqe_idx;
72962306a36Sopenharmony_ci	bool read_fence = false;
73062306a36Sopenharmony_ci	u32 i, total_size = 0;
73162306a36Sopenharmony_ci	u16 quanta;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	op_info = &info->op.send;
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci	if (unlikely(qp->max_sq_frag_cnt < op_info->num_sges))
73662306a36Sopenharmony_ci		return -EINVAL;
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci	for (i = 0; i < op_info->num_sges; i++)
73962306a36Sopenharmony_ci		total_size += op_info->sg_list[i].length;
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci	if (unlikely(total_size > qp->max_inline_data))
74262306a36Sopenharmony_ci		return -EINVAL;
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size);
74562306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
74662306a36Sopenharmony_ci					 info);
74762306a36Sopenharmony_ci	if (!wqe)
74862306a36Sopenharmony_ci		return -ENOMEM;
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	set_64bit_val(wqe, 16,
75362306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_DESTQKEY, op_info->qkey) |
75462306a36Sopenharmony_ci		      FIELD_PREP(IRDMAQPSQ_DESTQPN, op_info->dest_qp));
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	read_fence |= info->read_fence;
75762306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) |
75862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) |
75962306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
76062306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) |
76162306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG,
76262306a36Sopenharmony_ci			 (info->imm_data_valid ? 1 : 0)) |
76362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
76462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) |
76562306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_READFENCE, read_fence) |
76662306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, info->local_fence) |
76762306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
76862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_UDPHEADER, info->udp_hdr) |
76962306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_L4LEN, info->l4len) |
77062306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci	if (info->imm_data_valid)
77362306a36Sopenharmony_ci		set_64bit_val(wqe, 0,
77462306a36Sopenharmony_ci			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
77562306a36Sopenharmony_ci	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->sg_list,
77662306a36Sopenharmony_ci					op_info->num_sges, qp->swqe_polarity);
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	if (post_sq)
78362306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	return 0;
78662306a36Sopenharmony_ci}
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci/**
78962306a36Sopenharmony_ci * irdma_uk_stag_local_invalidate - stag invalidate operation
79062306a36Sopenharmony_ci * @qp: hw qp ptr
79162306a36Sopenharmony_ci * @info: post sq information
79262306a36Sopenharmony_ci * @post_sq: flag to post sq
79362306a36Sopenharmony_ci */
79462306a36Sopenharmony_ciint irdma_uk_stag_local_invalidate(struct irdma_qp_uk *qp,
79562306a36Sopenharmony_ci				   struct irdma_post_sq_info *info,
79662306a36Sopenharmony_ci				   bool post_sq)
79762306a36Sopenharmony_ci{
79862306a36Sopenharmony_ci	__le64 *wqe;
79962306a36Sopenharmony_ci	struct irdma_inv_local_stag *op_info;
80062306a36Sopenharmony_ci	u64 hdr;
80162306a36Sopenharmony_ci	u32 wqe_idx;
80262306a36Sopenharmony_ci	bool local_fence = false;
80362306a36Sopenharmony_ci	struct ib_sge sge = {};
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci	op_info = &info->op.inv_local_stag;
80662306a36Sopenharmony_ci	local_fence = info->local_fence;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA,
80962306a36Sopenharmony_ci					 0, info);
81062306a36Sopenharmony_ci	if (!wqe)
81162306a36Sopenharmony_ci		return -ENOMEM;
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	sge.lkey = op_info->target_stag;
81662306a36Sopenharmony_ci	qp->wqe_ops.iw_set_fragment(wqe, 0, &sge, 0);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	set_64bit_val(wqe, 16, 0);
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMA_OP_TYPE_INV_STAG) |
82162306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_READFENCE, info->read_fence) |
82262306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_LOCALFENCE, local_fence) |
82362306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, info->signaled) |
82462306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	if (post_sq)
83162306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci	return 0;
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci/**
83762306a36Sopenharmony_ci * irdma_uk_post_receive - post receive wqe
83862306a36Sopenharmony_ci * @qp: hw qp ptr
83962306a36Sopenharmony_ci * @info: post rq information
84062306a36Sopenharmony_ci */
84162306a36Sopenharmony_ciint irdma_uk_post_receive(struct irdma_qp_uk *qp,
84262306a36Sopenharmony_ci			  struct irdma_post_rq_info *info)
84362306a36Sopenharmony_ci{
84462306a36Sopenharmony_ci	u32 wqe_idx, i, byte_off;
84562306a36Sopenharmony_ci	u32 addl_frag_cnt;
84662306a36Sopenharmony_ci	__le64 *wqe;
84762306a36Sopenharmony_ci	u64 hdr;
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	if (qp->max_rq_frag_cnt < info->num_sges)
85062306a36Sopenharmony_ci		return -EINVAL;
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ci	wqe = irdma_qp_get_next_recv_wqe(qp, &wqe_idx);
85362306a36Sopenharmony_ci	if (!wqe)
85462306a36Sopenharmony_ci		return -ENOMEM;
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	qp->rq_wrid_array[wqe_idx] = info->wr_id;
85762306a36Sopenharmony_ci	addl_frag_cnt = info->num_sges > 1 ? (info->num_sges - 1) : 0;
85862306a36Sopenharmony_ci	qp->wqe_ops.iw_set_fragment(wqe, 0, info->sg_list,
85962306a36Sopenharmony_ci				    qp->rwqe_polarity);
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	for (i = 1, byte_off = 32; i < info->num_sges; i++) {
86262306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off, &info->sg_list[i],
86362306a36Sopenharmony_ci					    qp->rwqe_polarity);
86462306a36Sopenharmony_ci		byte_off += 16;
86562306a36Sopenharmony_ci	}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	/* if not an odd number set valid bit in next fragment */
86862306a36Sopenharmony_ci	if (qp->uk_attrs->hw_rev >= IRDMA_GEN_2 && !(info->num_sges & 0x01) &&
86962306a36Sopenharmony_ci	    info->num_sges) {
87062306a36Sopenharmony_ci		qp->wqe_ops.iw_set_fragment(wqe, byte_off, NULL,
87162306a36Sopenharmony_ci					    qp->rwqe_polarity);
87262306a36Sopenharmony_ci		if (qp->uk_attrs->hw_rev == IRDMA_GEN_2)
87362306a36Sopenharmony_ci			++addl_frag_cnt;
87462306a36Sopenharmony_ci	}
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	set_64bit_val(wqe, 16, 0);
87762306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_ADDFRAGCNT, addl_frag_cnt) |
87862306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->rwqe_polarity);
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci	return 0;
88562306a36Sopenharmony_ci}
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci/**
88862306a36Sopenharmony_ci * irdma_uk_cq_resize - reset the cq buffer info
88962306a36Sopenharmony_ci * @cq: cq to resize
89062306a36Sopenharmony_ci * @cq_base: new cq buffer addr
89162306a36Sopenharmony_ci * @cq_size: number of cqes
89262306a36Sopenharmony_ci */
89362306a36Sopenharmony_civoid irdma_uk_cq_resize(struct irdma_cq_uk *cq, void *cq_base, int cq_size)
89462306a36Sopenharmony_ci{
89562306a36Sopenharmony_ci	cq->cq_base = cq_base;
89662306a36Sopenharmony_ci	cq->cq_size = cq_size;
89762306a36Sopenharmony_ci	IRDMA_RING_INIT(cq->cq_ring, cq->cq_size);
89862306a36Sopenharmony_ci	cq->polarity = 1;
89962306a36Sopenharmony_ci}
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci/**
90262306a36Sopenharmony_ci * irdma_uk_cq_set_resized_cnt - record the count of the resized buffers
90362306a36Sopenharmony_ci * @cq: cq to resize
90462306a36Sopenharmony_ci * @cq_cnt: the count of the resized cq buffers
90562306a36Sopenharmony_ci */
90662306a36Sopenharmony_civoid irdma_uk_cq_set_resized_cnt(struct irdma_cq_uk *cq, u16 cq_cnt)
90762306a36Sopenharmony_ci{
90862306a36Sopenharmony_ci	u64 temp_val;
90962306a36Sopenharmony_ci	u16 sw_cq_sel;
91062306a36Sopenharmony_ci	u8 arm_next_se;
91162306a36Sopenharmony_ci	u8 arm_next;
91262306a36Sopenharmony_ci	u8 arm_seq_num;
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	get_64bit_val(cq->shadow_area, 32, &temp_val);
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci	sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val);
91762306a36Sopenharmony_ci	sw_cq_sel += cq_cnt;
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci	arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val);
92062306a36Sopenharmony_ci	arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val);
92162306a36Sopenharmony_ci	arm_next = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT, temp_val);
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) |
92462306a36Sopenharmony_ci		   FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) |
92562306a36Sopenharmony_ci		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) |
92662306a36Sopenharmony_ci		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, arm_next);
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci	set_64bit_val(cq->shadow_area, 32, temp_val);
92962306a36Sopenharmony_ci}
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_ci/**
93262306a36Sopenharmony_ci * irdma_uk_cq_request_notification - cq notification request (door bell)
93362306a36Sopenharmony_ci * @cq: hw cq
93462306a36Sopenharmony_ci * @cq_notify: notification type
93562306a36Sopenharmony_ci */
93662306a36Sopenharmony_civoid irdma_uk_cq_request_notification(struct irdma_cq_uk *cq,
93762306a36Sopenharmony_ci				      enum irdma_cmpl_notify cq_notify)
93862306a36Sopenharmony_ci{
93962306a36Sopenharmony_ci	u64 temp_val;
94062306a36Sopenharmony_ci	u16 sw_cq_sel;
94162306a36Sopenharmony_ci	u8 arm_next_se = 0;
94262306a36Sopenharmony_ci	u8 arm_next = 0;
94362306a36Sopenharmony_ci	u8 arm_seq_num;
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	get_64bit_val(cq->shadow_area, 32, &temp_val);
94662306a36Sopenharmony_ci	arm_seq_num = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_SEQ_NUM, temp_val);
94762306a36Sopenharmony_ci	arm_seq_num++;
94862306a36Sopenharmony_ci	sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val);
94962306a36Sopenharmony_ci	arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val);
95062306a36Sopenharmony_ci	arm_next_se |= 1;
95162306a36Sopenharmony_ci	if (cq_notify == IRDMA_CQ_COMPL_EVENT)
95262306a36Sopenharmony_ci		arm_next = 1;
95362306a36Sopenharmony_ci	temp_val = FIELD_PREP(IRDMA_CQ_DBSA_ARM_SEQ_NUM, arm_seq_num) |
95462306a36Sopenharmony_ci		   FIELD_PREP(IRDMA_CQ_DBSA_SW_CQ_SELECT, sw_cq_sel) |
95562306a36Sopenharmony_ci		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) |
95662306a36Sopenharmony_ci		   FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, arm_next);
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci	set_64bit_val(cq->shadow_area, 32, temp_val);
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci	writel(cq->cq_id, cq->cqe_alloc_db);
96362306a36Sopenharmony_ci}
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci/**
96662306a36Sopenharmony_ci * irdma_uk_cq_poll_cmpl - get cq completion info
96762306a36Sopenharmony_ci * @cq: hw cq
96862306a36Sopenharmony_ci * @info: cq poll information returned
96962306a36Sopenharmony_ci */
97062306a36Sopenharmony_ciint irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
97162306a36Sopenharmony_ci			  struct irdma_cq_poll_info *info)
97262306a36Sopenharmony_ci{
97362306a36Sopenharmony_ci	u64 comp_ctx, qword0, qword2, qword3;
97462306a36Sopenharmony_ci	__le64 *cqe;
97562306a36Sopenharmony_ci	struct irdma_qp_uk *qp;
97662306a36Sopenharmony_ci	struct irdma_ring *pring = NULL;
97762306a36Sopenharmony_ci	u32 wqe_idx;
97862306a36Sopenharmony_ci	int ret_code;
97962306a36Sopenharmony_ci	bool move_cq_head = true;
98062306a36Sopenharmony_ci	u8 polarity;
98162306a36Sopenharmony_ci	bool ext_valid;
98262306a36Sopenharmony_ci	__le64 *ext_cqe;
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_ci	if (cq->avoid_mem_cflct)
98562306a36Sopenharmony_ci		cqe = IRDMA_GET_CURRENT_EXTENDED_CQ_ELEM(cq);
98662306a36Sopenharmony_ci	else
98762306a36Sopenharmony_ci		cqe = IRDMA_GET_CURRENT_CQ_ELEM(cq);
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci	get_64bit_val(cqe, 24, &qword3);
99062306a36Sopenharmony_ci	polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3);
99162306a36Sopenharmony_ci	if (polarity != cq->polarity)
99262306a36Sopenharmony_ci		return -ENOENT;
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	/* Ensure CQE contents are read after valid bit is checked */
99562306a36Sopenharmony_ci	dma_rmb();
99662306a36Sopenharmony_ci
99762306a36Sopenharmony_ci	ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3);
99862306a36Sopenharmony_ci	if (ext_valid) {
99962306a36Sopenharmony_ci		u64 qword6, qword7;
100062306a36Sopenharmony_ci		u32 peek_head;
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_ci		if (cq->avoid_mem_cflct) {
100362306a36Sopenharmony_ci			ext_cqe = (__le64 *)((u8 *)cqe + 32);
100462306a36Sopenharmony_ci			get_64bit_val(ext_cqe, 24, &qword7);
100562306a36Sopenharmony_ci			polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword7);
100662306a36Sopenharmony_ci		} else {
100762306a36Sopenharmony_ci			peek_head = (cq->cq_ring.head + 1) % cq->cq_ring.size;
100862306a36Sopenharmony_ci			ext_cqe = cq->cq_base[peek_head].buf;
100962306a36Sopenharmony_ci			get_64bit_val(ext_cqe, 24, &qword7);
101062306a36Sopenharmony_ci			polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword7);
101162306a36Sopenharmony_ci			if (!peek_head)
101262306a36Sopenharmony_ci				polarity ^= 1;
101362306a36Sopenharmony_ci		}
101462306a36Sopenharmony_ci		if (polarity != cq->polarity)
101562306a36Sopenharmony_ci			return -ENOENT;
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci		/* Ensure ext CQE contents are read after ext valid bit is checked */
101862306a36Sopenharmony_ci		dma_rmb();
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci		info->imm_valid = (bool)FIELD_GET(IRDMA_CQ_IMMVALID, qword7);
102162306a36Sopenharmony_ci		if (info->imm_valid) {
102262306a36Sopenharmony_ci			u64 qword4;
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci			get_64bit_val(ext_cqe, 0, &qword4);
102562306a36Sopenharmony_ci			info->imm_data = (u32)FIELD_GET(IRDMA_CQ_IMMDATALOW32, qword4);
102662306a36Sopenharmony_ci		}
102762306a36Sopenharmony_ci		info->ud_smac_valid = (bool)FIELD_GET(IRDMA_CQ_UDSMACVALID, qword7);
102862306a36Sopenharmony_ci		info->ud_vlan_valid = (bool)FIELD_GET(IRDMA_CQ_UDVLANVALID, qword7);
102962306a36Sopenharmony_ci		if (info->ud_smac_valid || info->ud_vlan_valid) {
103062306a36Sopenharmony_ci			get_64bit_val(ext_cqe, 16, &qword6);
103162306a36Sopenharmony_ci			if (info->ud_vlan_valid)
103262306a36Sopenharmony_ci				info->ud_vlan = (u16)FIELD_GET(IRDMA_CQ_UDVLAN, qword6);
103362306a36Sopenharmony_ci			if (info->ud_smac_valid) {
103462306a36Sopenharmony_ci				info->ud_smac[5] = qword6 & 0xFF;
103562306a36Sopenharmony_ci				info->ud_smac[4] = (qword6 >> 8) & 0xFF;
103662306a36Sopenharmony_ci				info->ud_smac[3] = (qword6 >> 16) & 0xFF;
103762306a36Sopenharmony_ci				info->ud_smac[2] = (qword6 >> 24) & 0xFF;
103862306a36Sopenharmony_ci				info->ud_smac[1] = (qword6 >> 32) & 0xFF;
103962306a36Sopenharmony_ci				info->ud_smac[0] = (qword6 >> 40) & 0xFF;
104062306a36Sopenharmony_ci			}
104162306a36Sopenharmony_ci		}
104262306a36Sopenharmony_ci	} else {
104362306a36Sopenharmony_ci		info->imm_valid = false;
104462306a36Sopenharmony_ci		info->ud_smac_valid = false;
104562306a36Sopenharmony_ci		info->ud_vlan_valid = false;
104662306a36Sopenharmony_ci	}
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci	info->q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
104962306a36Sopenharmony_ci	info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3);
105062306a36Sopenharmony_ci	info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3);
105162306a36Sopenharmony_ci	if (info->error) {
105262306a36Sopenharmony_ci		info->major_err = FIELD_GET(IRDMA_CQ_MAJERR, qword3);
105362306a36Sopenharmony_ci		info->minor_err = FIELD_GET(IRDMA_CQ_MINERR, qword3);
105462306a36Sopenharmony_ci		if (info->major_err == IRDMA_FLUSH_MAJOR_ERR) {
105562306a36Sopenharmony_ci			info->comp_status = IRDMA_COMPL_STATUS_FLUSHED;
105662306a36Sopenharmony_ci			/* Set the min error to standard flush error code for remaining cqes */
105762306a36Sopenharmony_ci			if (info->minor_err != FLUSH_GENERAL_ERR) {
105862306a36Sopenharmony_ci				qword3 &= ~IRDMA_CQ_MINERR;
105962306a36Sopenharmony_ci				qword3 |= FIELD_PREP(IRDMA_CQ_MINERR, FLUSH_GENERAL_ERR);
106062306a36Sopenharmony_ci				set_64bit_val(cqe, 24, qword3);
106162306a36Sopenharmony_ci			}
106262306a36Sopenharmony_ci		} else {
106362306a36Sopenharmony_ci			info->comp_status = IRDMA_COMPL_STATUS_UNKNOWN;
106462306a36Sopenharmony_ci		}
106562306a36Sopenharmony_ci	} else {
106662306a36Sopenharmony_ci		info->comp_status = IRDMA_COMPL_STATUS_SUCCESS;
106762306a36Sopenharmony_ci	}
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci	get_64bit_val(cqe, 0, &qword0);
107062306a36Sopenharmony_ci	get_64bit_val(cqe, 16, &qword2);
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	info->tcp_seq_num_rtt = (u32)FIELD_GET(IRDMACQ_TCPSEQNUMRTT, qword0);
107362306a36Sopenharmony_ci	info->qp_id = (u32)FIELD_GET(IRDMACQ_QPID, qword2);
107462306a36Sopenharmony_ci	info->ud_src_qpn = (u32)FIELD_GET(IRDMACQ_UDSRCQPN, qword2);
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_ci	get_64bit_val(cqe, 8, &comp_ctx);
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci	info->solicited_event = (bool)FIELD_GET(IRDMACQ_SOEVENT, qword3);
107962306a36Sopenharmony_ci	qp = (struct irdma_qp_uk *)(unsigned long)comp_ctx;
108062306a36Sopenharmony_ci	if (!qp || qp->destroy_pending) {
108162306a36Sopenharmony_ci		ret_code = -EFAULT;
108262306a36Sopenharmony_ci		goto exit;
108362306a36Sopenharmony_ci	}
108462306a36Sopenharmony_ci	wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3);
108562306a36Sopenharmony_ci	info->qp_handle = (irdma_qp_handle)(unsigned long)qp;
108662306a36Sopenharmony_ci	info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3);
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci	if (info->q_type == IRDMA_CQE_QTYPE_RQ) {
108962306a36Sopenharmony_ci		u32 array_idx;
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci		array_idx = wqe_idx / qp->rq_wqe_size_multiplier;
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_ci		if (info->comp_status == IRDMA_COMPL_STATUS_FLUSHED ||
109462306a36Sopenharmony_ci		    info->comp_status == IRDMA_COMPL_STATUS_UNKNOWN) {
109562306a36Sopenharmony_ci			if (!IRDMA_RING_MORE_WORK(qp->rq_ring)) {
109662306a36Sopenharmony_ci				ret_code = -ENOENT;
109762306a36Sopenharmony_ci				goto exit;
109862306a36Sopenharmony_ci			}
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci			info->wr_id = qp->rq_wrid_array[qp->rq_ring.tail];
110162306a36Sopenharmony_ci			array_idx = qp->rq_ring.tail;
110262306a36Sopenharmony_ci		} else {
110362306a36Sopenharmony_ci			info->wr_id = qp->rq_wrid_array[array_idx];
110462306a36Sopenharmony_ci		}
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci		info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0);
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci		if (qword3 & IRDMACQ_STAG) {
110962306a36Sopenharmony_ci			info->stag_invalid_set = true;
111062306a36Sopenharmony_ci			info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2);
111162306a36Sopenharmony_ci		} else {
111262306a36Sopenharmony_ci			info->stag_invalid_set = false;
111362306a36Sopenharmony_ci		}
111462306a36Sopenharmony_ci		IRDMA_RING_SET_TAIL(qp->rq_ring, array_idx + 1);
111562306a36Sopenharmony_ci		if (info->comp_status == IRDMA_COMPL_STATUS_FLUSHED) {
111662306a36Sopenharmony_ci			qp->rq_flush_seen = true;
111762306a36Sopenharmony_ci			if (!IRDMA_RING_MORE_WORK(qp->rq_ring))
111862306a36Sopenharmony_ci				qp->rq_flush_complete = true;
111962306a36Sopenharmony_ci			else
112062306a36Sopenharmony_ci				move_cq_head = false;
112162306a36Sopenharmony_ci		}
112262306a36Sopenharmony_ci		pring = &qp->rq_ring;
112362306a36Sopenharmony_ci	} else { /* q_type is IRDMA_CQE_QTYPE_SQ */
112462306a36Sopenharmony_ci		if (qp->first_sq_wq) {
112562306a36Sopenharmony_ci			if (wqe_idx + 1 >= qp->conn_wqes)
112662306a36Sopenharmony_ci				qp->first_sq_wq = false;
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci			if (wqe_idx < qp->conn_wqes && qp->sq_ring.head == qp->sq_ring.tail) {
112962306a36Sopenharmony_ci				IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
113062306a36Sopenharmony_ci				IRDMA_RING_MOVE_TAIL(cq->cq_ring);
113162306a36Sopenharmony_ci				set_64bit_val(cq->shadow_area, 0,
113262306a36Sopenharmony_ci					      IRDMA_RING_CURRENT_HEAD(cq->cq_ring));
113362306a36Sopenharmony_ci				memset(info, 0,
113462306a36Sopenharmony_ci				       sizeof(struct irdma_cq_poll_info));
113562306a36Sopenharmony_ci				return irdma_uk_cq_poll_cmpl(cq, info);
113662306a36Sopenharmony_ci			}
113762306a36Sopenharmony_ci		}
113862306a36Sopenharmony_ci		if (info->comp_status != IRDMA_COMPL_STATUS_FLUSHED) {
113962306a36Sopenharmony_ci			info->wr_id = qp->sq_wrtrk_array[wqe_idx].wrid;
114062306a36Sopenharmony_ci			if (!info->comp_status)
114162306a36Sopenharmony_ci				info->bytes_xfered = qp->sq_wrtrk_array[wqe_idx].wr_len;
114262306a36Sopenharmony_ci			info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3);
114362306a36Sopenharmony_ci			IRDMA_RING_SET_TAIL(qp->sq_ring,
114462306a36Sopenharmony_ci					    wqe_idx + qp->sq_wrtrk_array[wqe_idx].quanta);
114562306a36Sopenharmony_ci		} else {
114662306a36Sopenharmony_ci			if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) {
114762306a36Sopenharmony_ci				ret_code = -ENOENT;
114862306a36Sopenharmony_ci				goto exit;
114962306a36Sopenharmony_ci			}
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci			do {
115262306a36Sopenharmony_ci				__le64 *sw_wqe;
115362306a36Sopenharmony_ci				u64 wqe_qword;
115462306a36Sopenharmony_ci				u32 tail;
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci				tail = qp->sq_ring.tail;
115762306a36Sopenharmony_ci				sw_wqe = qp->sq_base[tail].elem;
115862306a36Sopenharmony_ci				get_64bit_val(sw_wqe, 24,
115962306a36Sopenharmony_ci					      &wqe_qword);
116062306a36Sopenharmony_ci				info->op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE,
116162306a36Sopenharmony_ci							      wqe_qword);
116262306a36Sopenharmony_ci				IRDMA_RING_SET_TAIL(qp->sq_ring,
116362306a36Sopenharmony_ci						    tail + qp->sq_wrtrk_array[tail].quanta);
116462306a36Sopenharmony_ci				if (info->op_type != IRDMAQP_OP_NOP) {
116562306a36Sopenharmony_ci					info->wr_id = qp->sq_wrtrk_array[tail].wrid;
116662306a36Sopenharmony_ci					info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len;
116762306a36Sopenharmony_ci					break;
116862306a36Sopenharmony_ci				}
116962306a36Sopenharmony_ci			} while (1);
117062306a36Sopenharmony_ci			if (info->op_type == IRDMA_OP_TYPE_BIND_MW &&
117162306a36Sopenharmony_ci			    info->minor_err == FLUSH_PROT_ERR)
117262306a36Sopenharmony_ci				info->minor_err = FLUSH_MW_BIND_ERR;
117362306a36Sopenharmony_ci			qp->sq_flush_seen = true;
117462306a36Sopenharmony_ci			if (!IRDMA_RING_MORE_WORK(qp->sq_ring))
117562306a36Sopenharmony_ci				qp->sq_flush_complete = true;
117662306a36Sopenharmony_ci		}
117762306a36Sopenharmony_ci		pring = &qp->sq_ring;
117862306a36Sopenharmony_ci	}
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	ret_code = 0;
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_ciexit:
118362306a36Sopenharmony_ci	if (!ret_code && info->comp_status == IRDMA_COMPL_STATUS_FLUSHED)
118462306a36Sopenharmony_ci		if (pring && IRDMA_RING_MORE_WORK(*pring))
118562306a36Sopenharmony_ci			move_cq_head = false;
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_ci	if (move_cq_head) {
118862306a36Sopenharmony_ci		IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
118962306a36Sopenharmony_ci		if (!IRDMA_RING_CURRENT_HEAD(cq->cq_ring))
119062306a36Sopenharmony_ci			cq->polarity ^= 1;
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci		if (ext_valid && !cq->avoid_mem_cflct) {
119362306a36Sopenharmony_ci			IRDMA_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
119462306a36Sopenharmony_ci			if (!IRDMA_RING_CURRENT_HEAD(cq->cq_ring))
119562306a36Sopenharmony_ci				cq->polarity ^= 1;
119662306a36Sopenharmony_ci		}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci		IRDMA_RING_MOVE_TAIL(cq->cq_ring);
119962306a36Sopenharmony_ci		if (!cq->avoid_mem_cflct && ext_valid)
120062306a36Sopenharmony_ci			IRDMA_RING_MOVE_TAIL(cq->cq_ring);
120162306a36Sopenharmony_ci		set_64bit_val(cq->shadow_area, 0,
120262306a36Sopenharmony_ci			      IRDMA_RING_CURRENT_HEAD(cq->cq_ring));
120362306a36Sopenharmony_ci	} else {
120462306a36Sopenharmony_ci		qword3 &= ~IRDMA_CQ_WQEIDX;
120562306a36Sopenharmony_ci		qword3 |= FIELD_PREP(IRDMA_CQ_WQEIDX, pring->tail);
120662306a36Sopenharmony_ci		set_64bit_val(cqe, 24, qword3);
120762306a36Sopenharmony_ci	}
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci	return ret_code;
121062306a36Sopenharmony_ci}
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci/**
121362306a36Sopenharmony_ci * irdma_qp_round_up - return round up qp wq depth
121462306a36Sopenharmony_ci * @wqdepth: wq depth in quanta to round up
121562306a36Sopenharmony_ci */
121662306a36Sopenharmony_cistatic int irdma_qp_round_up(u32 wqdepth)
121762306a36Sopenharmony_ci{
121862306a36Sopenharmony_ci	int scount = 1;
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci	for (wqdepth--; scount <= 16; scount *= 2)
122162306a36Sopenharmony_ci		wqdepth |= wqdepth >> scount;
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	return ++wqdepth;
122462306a36Sopenharmony_ci}
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci/**
122762306a36Sopenharmony_ci * irdma_get_wqe_shift - get shift count for maximum wqe size
122862306a36Sopenharmony_ci * @uk_attrs: qp HW attributes
122962306a36Sopenharmony_ci * @sge: Maximum Scatter Gather Elements wqe
123062306a36Sopenharmony_ci * @inline_data: Maximum inline data size
123162306a36Sopenharmony_ci * @shift: Returns the shift needed based on sge
123262306a36Sopenharmony_ci *
123362306a36Sopenharmony_ci * Shift can be used to left shift the wqe size based on number of SGEs and inlind data size.
123462306a36Sopenharmony_ci * For 1 SGE or inline data <= 8, shift = 0 (wqe size of 32
123562306a36Sopenharmony_ci * bytes). For 2 or 3 SGEs or inline data <= 39, shift = 1 (wqe
123662306a36Sopenharmony_ci * size of 64 bytes).
123762306a36Sopenharmony_ci * For 4-7 SGE's and inline <= 101 Shift of 2 otherwise (wqe
123862306a36Sopenharmony_ci * size of 256 bytes).
123962306a36Sopenharmony_ci */
124062306a36Sopenharmony_civoid irdma_get_wqe_shift(struct irdma_uk_attrs *uk_attrs, u32 sge,
124162306a36Sopenharmony_ci			 u32 inline_data, u8 *shift)
124262306a36Sopenharmony_ci{
124362306a36Sopenharmony_ci	*shift = 0;
124462306a36Sopenharmony_ci	if (uk_attrs->hw_rev >= IRDMA_GEN_2) {
124562306a36Sopenharmony_ci		if (sge > 1 || inline_data > 8) {
124662306a36Sopenharmony_ci			if (sge < 4 && inline_data <= 39)
124762306a36Sopenharmony_ci				*shift = 1;
124862306a36Sopenharmony_ci			else if (sge < 8 && inline_data <= 101)
124962306a36Sopenharmony_ci				*shift = 2;
125062306a36Sopenharmony_ci			else
125162306a36Sopenharmony_ci				*shift = 3;
125262306a36Sopenharmony_ci		}
125362306a36Sopenharmony_ci	} else if (sge > 1 || inline_data > 16) {
125462306a36Sopenharmony_ci		*shift = (sge < 4 && inline_data <= 48) ? 1 : 2;
125562306a36Sopenharmony_ci	}
125662306a36Sopenharmony_ci}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_ci/*
125962306a36Sopenharmony_ci * irdma_get_sqdepth - get SQ depth (quanta)
126062306a36Sopenharmony_ci * @uk_attrs: qp HW attributes
126162306a36Sopenharmony_ci * @sq_size: SQ size
126262306a36Sopenharmony_ci * @shift: shift which determines size of WQE
126362306a36Sopenharmony_ci * @sqdepth: depth of SQ
126462306a36Sopenharmony_ci *
126562306a36Sopenharmony_ci */
126662306a36Sopenharmony_ciint irdma_get_sqdepth(struct irdma_uk_attrs *uk_attrs, u32 sq_size, u8 shift,
126762306a36Sopenharmony_ci		      u32 *sqdepth)
126862306a36Sopenharmony_ci{
126962306a36Sopenharmony_ci	u32 min_size = (u32)uk_attrs->min_hw_wq_size << shift;
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	*sqdepth = irdma_qp_round_up((sq_size << shift) + IRDMA_SQ_RSVD);
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	if (*sqdepth < min_size)
127462306a36Sopenharmony_ci		*sqdepth = min_size;
127562306a36Sopenharmony_ci	else if (*sqdepth > uk_attrs->max_hw_wq_quanta)
127662306a36Sopenharmony_ci		return -EINVAL;
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci	return 0;
127962306a36Sopenharmony_ci}
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_ci/*
128262306a36Sopenharmony_ci * irdma_get_rqdepth - get RQ depth (quanta)
128362306a36Sopenharmony_ci * @uk_attrs: qp HW attributes
128462306a36Sopenharmony_ci * @rq_size: RQ size
128562306a36Sopenharmony_ci * @shift: shift which determines size of WQE
128662306a36Sopenharmony_ci * @rqdepth: depth of RQ
128762306a36Sopenharmony_ci */
128862306a36Sopenharmony_ciint irdma_get_rqdepth(struct irdma_uk_attrs *uk_attrs, u32 rq_size, u8 shift,
128962306a36Sopenharmony_ci		      u32 *rqdepth)
129062306a36Sopenharmony_ci{
129162306a36Sopenharmony_ci	u32 min_size = (u32)uk_attrs->min_hw_wq_size << shift;
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ci	*rqdepth = irdma_qp_round_up((rq_size << shift) + IRDMA_RQ_RSVD);
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	if (*rqdepth < min_size)
129662306a36Sopenharmony_ci		*rqdepth = min_size;
129762306a36Sopenharmony_ci	else if (*rqdepth > uk_attrs->max_hw_rq_quanta)
129862306a36Sopenharmony_ci		return -EINVAL;
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	return 0;
130162306a36Sopenharmony_ci}
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_cistatic const struct irdma_wqe_uk_ops iw_wqe_uk_ops = {
130462306a36Sopenharmony_ci	.iw_copy_inline_data = irdma_copy_inline_data,
130562306a36Sopenharmony_ci	.iw_inline_data_size_to_quanta = irdma_inline_data_size_to_quanta,
130662306a36Sopenharmony_ci	.iw_set_fragment = irdma_set_fragment,
130762306a36Sopenharmony_ci	.iw_set_mw_bind_wqe = irdma_set_mw_bind_wqe,
130862306a36Sopenharmony_ci};
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_cistatic const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = {
131162306a36Sopenharmony_ci	.iw_copy_inline_data = irdma_copy_inline_data_gen_1,
131262306a36Sopenharmony_ci	.iw_inline_data_size_to_quanta = irdma_inline_data_size_to_quanta_gen_1,
131362306a36Sopenharmony_ci	.iw_set_fragment = irdma_set_fragment_gen_1,
131462306a36Sopenharmony_ci	.iw_set_mw_bind_wqe = irdma_set_mw_bind_wqe_gen_1,
131562306a36Sopenharmony_ci};
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_ci/**
131862306a36Sopenharmony_ci * irdma_setup_connection_wqes - setup WQEs necessary to complete
131962306a36Sopenharmony_ci * connection.
132062306a36Sopenharmony_ci * @qp: hw qp (user and kernel)
132162306a36Sopenharmony_ci * @info: qp initialization info
132262306a36Sopenharmony_ci */
132362306a36Sopenharmony_cistatic void irdma_setup_connection_wqes(struct irdma_qp_uk *qp,
132462306a36Sopenharmony_ci					struct irdma_qp_uk_init_info *info)
132562306a36Sopenharmony_ci{
132662306a36Sopenharmony_ci	u16 move_cnt = 1;
132762306a36Sopenharmony_ci
132862306a36Sopenharmony_ci	if (!info->legacy_mode &&
132962306a36Sopenharmony_ci	    (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE))
133062306a36Sopenharmony_ci		move_cnt = 3;
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci	qp->conn_wqes = move_cnt;
133362306a36Sopenharmony_ci	IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, move_cnt);
133462306a36Sopenharmony_ci	IRDMA_RING_MOVE_TAIL_BY_COUNT(qp->sq_ring, move_cnt);
133562306a36Sopenharmony_ci	IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->initial_ring, move_cnt);
133662306a36Sopenharmony_ci}
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci/**
133962306a36Sopenharmony_ci * irdma_uk_calc_shift_wq - calculate WQE shift for both SQ and RQ
134062306a36Sopenharmony_ci * @ukinfo: qp initialization info
134162306a36Sopenharmony_ci * @sq_shift: Returns shift of SQ
134262306a36Sopenharmony_ci * @rq_shift: Returns shift of RQ
134362306a36Sopenharmony_ci */
134462306a36Sopenharmony_civoid irdma_uk_calc_shift_wq(struct irdma_qp_uk_init_info *ukinfo, u8 *sq_shift,
134562306a36Sopenharmony_ci			    u8 *rq_shift)
134662306a36Sopenharmony_ci{
134762306a36Sopenharmony_ci	bool imm_support = ukinfo->uk_attrs->hw_rev >= IRDMA_GEN_2;
134862306a36Sopenharmony_ci
134962306a36Sopenharmony_ci	irdma_get_wqe_shift(ukinfo->uk_attrs,
135062306a36Sopenharmony_ci			    imm_support ? ukinfo->max_sq_frag_cnt + 1 :
135162306a36Sopenharmony_ci					  ukinfo->max_sq_frag_cnt,
135262306a36Sopenharmony_ci			    ukinfo->max_inline_data, sq_shift);
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_rq_frag_cnt, 0,
135562306a36Sopenharmony_ci			    rq_shift);
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	if (ukinfo->uk_attrs->hw_rev == IRDMA_GEN_1) {
135862306a36Sopenharmony_ci		if (ukinfo->abi_ver > 4)
135962306a36Sopenharmony_ci			*rq_shift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
136062306a36Sopenharmony_ci	}
136162306a36Sopenharmony_ci}
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci/**
136462306a36Sopenharmony_ci * irdma_uk_calc_depth_shift_sq - calculate depth and shift for SQ size.
136562306a36Sopenharmony_ci * @ukinfo: qp initialization info
136662306a36Sopenharmony_ci * @sq_depth: Returns depth of SQ
136762306a36Sopenharmony_ci * @sq_shift: Returns shift of SQ
136862306a36Sopenharmony_ci */
136962306a36Sopenharmony_ciint irdma_uk_calc_depth_shift_sq(struct irdma_qp_uk_init_info *ukinfo,
137062306a36Sopenharmony_ci				 u32 *sq_depth, u8 *sq_shift)
137162306a36Sopenharmony_ci{
137262306a36Sopenharmony_ci	bool imm_support = ukinfo->uk_attrs->hw_rev >= IRDMA_GEN_2;
137362306a36Sopenharmony_ci	int status;
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci	irdma_get_wqe_shift(ukinfo->uk_attrs,
137662306a36Sopenharmony_ci			    imm_support ? ukinfo->max_sq_frag_cnt + 1 :
137762306a36Sopenharmony_ci			    ukinfo->max_sq_frag_cnt,
137862306a36Sopenharmony_ci			    ukinfo->max_inline_data, sq_shift);
137962306a36Sopenharmony_ci	status = irdma_get_sqdepth(ukinfo->uk_attrs, ukinfo->sq_size,
138062306a36Sopenharmony_ci				   *sq_shift, sq_depth);
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ci	return status;
138362306a36Sopenharmony_ci}
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci/**
138662306a36Sopenharmony_ci * irdma_uk_calc_depth_shift_rq - calculate depth and shift for RQ size.
138762306a36Sopenharmony_ci * @ukinfo: qp initialization info
138862306a36Sopenharmony_ci * @rq_depth: Returns depth of RQ
138962306a36Sopenharmony_ci * @rq_shift: Returns shift of RQ
139062306a36Sopenharmony_ci */
139162306a36Sopenharmony_ciint irdma_uk_calc_depth_shift_rq(struct irdma_qp_uk_init_info *ukinfo,
139262306a36Sopenharmony_ci				 u32 *rq_depth, u8 *rq_shift)
139362306a36Sopenharmony_ci{
139462306a36Sopenharmony_ci	int status;
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_rq_frag_cnt, 0,
139762306a36Sopenharmony_ci			    rq_shift);
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	if (ukinfo->uk_attrs->hw_rev == IRDMA_GEN_1) {
140062306a36Sopenharmony_ci		if (ukinfo->abi_ver > 4)
140162306a36Sopenharmony_ci			*rq_shift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
140262306a36Sopenharmony_ci	}
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci	status = irdma_get_rqdepth(ukinfo->uk_attrs, ukinfo->rq_size,
140562306a36Sopenharmony_ci				   *rq_shift, rq_depth);
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	return status;
140862306a36Sopenharmony_ci}
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci/**
141162306a36Sopenharmony_ci * irdma_uk_qp_init - initialize shared qp
141262306a36Sopenharmony_ci * @qp: hw qp (user and kernel)
141362306a36Sopenharmony_ci * @info: qp initialization info
141462306a36Sopenharmony_ci *
141562306a36Sopenharmony_ci * initializes the vars used in both user and kernel mode.
141662306a36Sopenharmony_ci * size of the wqe depends on numbers of max. fragements
141762306a36Sopenharmony_ci * allowed. Then size of wqe * the number of wqes should be the
141862306a36Sopenharmony_ci * amount of memory allocated for sq and rq.
141962306a36Sopenharmony_ci */
142062306a36Sopenharmony_ciint irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
142162306a36Sopenharmony_ci{
142262306a36Sopenharmony_ci	int ret_code = 0;
142362306a36Sopenharmony_ci	u32 sq_ring_size;
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci	qp->uk_attrs = info->uk_attrs;
142662306a36Sopenharmony_ci	if (info->max_sq_frag_cnt > qp->uk_attrs->max_hw_wq_frags ||
142762306a36Sopenharmony_ci	    info->max_rq_frag_cnt > qp->uk_attrs->max_hw_wq_frags)
142862306a36Sopenharmony_ci		return -EINVAL;
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	qp->qp_caps = info->qp_caps;
143162306a36Sopenharmony_ci	qp->sq_base = info->sq;
143262306a36Sopenharmony_ci	qp->rq_base = info->rq;
143362306a36Sopenharmony_ci	qp->qp_type = info->type ? info->type : IRDMA_QP_TYPE_IWARP;
143462306a36Sopenharmony_ci	qp->shadow_area = info->shadow_area;
143562306a36Sopenharmony_ci	qp->sq_wrtrk_array = info->sq_wrtrk_array;
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	qp->rq_wrid_array = info->rq_wrid_array;
143862306a36Sopenharmony_ci	qp->wqe_alloc_db = info->wqe_alloc_db;
143962306a36Sopenharmony_ci	qp->qp_id = info->qp_id;
144062306a36Sopenharmony_ci	qp->sq_size = info->sq_size;
144162306a36Sopenharmony_ci	qp->max_sq_frag_cnt = info->max_sq_frag_cnt;
144262306a36Sopenharmony_ci	sq_ring_size = qp->sq_size << info->sq_shift;
144362306a36Sopenharmony_ci	IRDMA_RING_INIT(qp->sq_ring, sq_ring_size);
144462306a36Sopenharmony_ci	IRDMA_RING_INIT(qp->initial_ring, sq_ring_size);
144562306a36Sopenharmony_ci	if (info->first_sq_wq) {
144662306a36Sopenharmony_ci		irdma_setup_connection_wqes(qp, info);
144762306a36Sopenharmony_ci		qp->swqe_polarity = 1;
144862306a36Sopenharmony_ci		qp->first_sq_wq = true;
144962306a36Sopenharmony_ci	} else {
145062306a36Sopenharmony_ci		qp->swqe_polarity = 0;
145162306a36Sopenharmony_ci	}
145262306a36Sopenharmony_ci	qp->swqe_polarity_deferred = 1;
145362306a36Sopenharmony_ci	qp->rwqe_polarity = 0;
145462306a36Sopenharmony_ci	qp->rq_size = info->rq_size;
145562306a36Sopenharmony_ci	qp->max_rq_frag_cnt = info->max_rq_frag_cnt;
145662306a36Sopenharmony_ci	qp->max_inline_data = info->max_inline_data;
145762306a36Sopenharmony_ci	qp->rq_wqe_size = info->rq_shift;
145862306a36Sopenharmony_ci	IRDMA_RING_INIT(qp->rq_ring, qp->rq_size);
145962306a36Sopenharmony_ci	qp->rq_wqe_size_multiplier = 1 << info->rq_shift;
146062306a36Sopenharmony_ci	if (qp->uk_attrs->hw_rev == IRDMA_GEN_1)
146162306a36Sopenharmony_ci		qp->wqe_ops = iw_wqe_uk_ops_gen_1;
146262306a36Sopenharmony_ci	else
146362306a36Sopenharmony_ci		qp->wqe_ops = iw_wqe_uk_ops;
146462306a36Sopenharmony_ci	return ret_code;
146562306a36Sopenharmony_ci}
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ci/**
146862306a36Sopenharmony_ci * irdma_uk_cq_init - initialize shared cq (user and kernel)
146962306a36Sopenharmony_ci * @cq: hw cq
147062306a36Sopenharmony_ci * @info: hw cq initialization info
147162306a36Sopenharmony_ci */
147262306a36Sopenharmony_civoid irdma_uk_cq_init(struct irdma_cq_uk *cq,
147362306a36Sopenharmony_ci		      struct irdma_cq_uk_init_info *info)
147462306a36Sopenharmony_ci{
147562306a36Sopenharmony_ci	cq->cq_base = info->cq_base;
147662306a36Sopenharmony_ci	cq->cq_id = info->cq_id;
147762306a36Sopenharmony_ci	cq->cq_size = info->cq_size;
147862306a36Sopenharmony_ci	cq->cqe_alloc_db = info->cqe_alloc_db;
147962306a36Sopenharmony_ci	cq->cq_ack_db = info->cq_ack_db;
148062306a36Sopenharmony_ci	cq->shadow_area = info->shadow_area;
148162306a36Sopenharmony_ci	cq->avoid_mem_cflct = info->avoid_mem_cflct;
148262306a36Sopenharmony_ci	IRDMA_RING_INIT(cq->cq_ring, cq->cq_size);
148362306a36Sopenharmony_ci	cq->polarity = 1;
148462306a36Sopenharmony_ci}
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci/**
148762306a36Sopenharmony_ci * irdma_uk_clean_cq - clean cq entries
148862306a36Sopenharmony_ci * @q: completion context
148962306a36Sopenharmony_ci * @cq: cq to clean
149062306a36Sopenharmony_ci */
149162306a36Sopenharmony_civoid irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq)
149262306a36Sopenharmony_ci{
149362306a36Sopenharmony_ci	__le64 *cqe;
149462306a36Sopenharmony_ci	u64 qword3, comp_ctx;
149562306a36Sopenharmony_ci	u32 cq_head;
149662306a36Sopenharmony_ci	u8 polarity, temp;
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	cq_head = cq->cq_ring.head;
149962306a36Sopenharmony_ci	temp = cq->polarity;
150062306a36Sopenharmony_ci	do {
150162306a36Sopenharmony_ci		if (cq->avoid_mem_cflct)
150262306a36Sopenharmony_ci			cqe = ((struct irdma_extended_cqe *)(cq->cq_base))[cq_head].buf;
150362306a36Sopenharmony_ci		else
150462306a36Sopenharmony_ci			cqe = cq->cq_base[cq_head].buf;
150562306a36Sopenharmony_ci		get_64bit_val(cqe, 24, &qword3);
150662306a36Sopenharmony_ci		polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3);
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_ci		if (polarity != temp)
150962306a36Sopenharmony_ci			break;
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci		/* Ensure CQE contents are read after valid bit is checked */
151262306a36Sopenharmony_ci		dma_rmb();
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_ci		get_64bit_val(cqe, 8, &comp_ctx);
151562306a36Sopenharmony_ci		if ((void *)(unsigned long)comp_ctx == q)
151662306a36Sopenharmony_ci			set_64bit_val(cqe, 8, 0);
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci		cq_head = (cq_head + 1) % cq->cq_ring.size;
151962306a36Sopenharmony_ci		if (!cq_head)
152062306a36Sopenharmony_ci			temp ^= 1;
152162306a36Sopenharmony_ci	} while (true);
152262306a36Sopenharmony_ci}
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci/**
152562306a36Sopenharmony_ci * irdma_nop - post a nop
152662306a36Sopenharmony_ci * @qp: hw qp ptr
152762306a36Sopenharmony_ci * @wr_id: work request id
152862306a36Sopenharmony_ci * @signaled: signaled for completion
152962306a36Sopenharmony_ci * @post_sq: ring doorbell
153062306a36Sopenharmony_ci */
153162306a36Sopenharmony_ciint irdma_nop(struct irdma_qp_uk *qp, u64 wr_id, bool signaled, bool post_sq)
153262306a36Sopenharmony_ci{
153362306a36Sopenharmony_ci	__le64 *wqe;
153462306a36Sopenharmony_ci	u64 hdr;
153562306a36Sopenharmony_ci	u32 wqe_idx;
153662306a36Sopenharmony_ci	struct irdma_post_sq_info info = {};
153762306a36Sopenharmony_ci
153862306a36Sopenharmony_ci	info.wr_id = wr_id;
153962306a36Sopenharmony_ci	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, IRDMA_QP_WQE_MIN_QUANTA,
154062306a36Sopenharmony_ci					 0, &info);
154162306a36Sopenharmony_ci	if (!wqe)
154262306a36Sopenharmony_ci		return -ENOMEM;
154362306a36Sopenharmony_ci
154462306a36Sopenharmony_ci	irdma_clr_wqes(qp, wqe_idx);
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	set_64bit_val(wqe, 0, 0);
154762306a36Sopenharmony_ci	set_64bit_val(wqe, 8, 0);
154862306a36Sopenharmony_ci	set_64bit_val(wqe, 16, 0);
154962306a36Sopenharmony_ci
155062306a36Sopenharmony_ci	hdr = FIELD_PREP(IRDMAQPSQ_OPCODE, IRDMAQP_OP_NOP) |
155162306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_SIGCOMPL, signaled) |
155262306a36Sopenharmony_ci	      FIELD_PREP(IRDMAQPSQ_VALID, qp->swqe_polarity);
155362306a36Sopenharmony_ci
155462306a36Sopenharmony_ci	dma_wmb(); /* make sure WQE is populated before valid bit is set */
155562306a36Sopenharmony_ci
155662306a36Sopenharmony_ci	set_64bit_val(wqe, 24, hdr);
155762306a36Sopenharmony_ci	if (post_sq)
155862306a36Sopenharmony_ci		irdma_uk_qp_post_wr(qp);
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci	return 0;
156162306a36Sopenharmony_ci}
156262306a36Sopenharmony_ci
156362306a36Sopenharmony_ci/**
156462306a36Sopenharmony_ci * irdma_fragcnt_to_quanta_sq - calculate quanta based on fragment count for SQ
156562306a36Sopenharmony_ci * @frag_cnt: number of fragments
156662306a36Sopenharmony_ci * @quanta: quanta for frag_cnt
156762306a36Sopenharmony_ci */
156862306a36Sopenharmony_ciint irdma_fragcnt_to_quanta_sq(u32 frag_cnt, u16 *quanta)
156962306a36Sopenharmony_ci{
157062306a36Sopenharmony_ci	switch (frag_cnt) {
157162306a36Sopenharmony_ci	case 0:
157262306a36Sopenharmony_ci	case 1:
157362306a36Sopenharmony_ci		*quanta = IRDMA_QP_WQE_MIN_QUANTA;
157462306a36Sopenharmony_ci		break;
157562306a36Sopenharmony_ci	case 2:
157662306a36Sopenharmony_ci	case 3:
157762306a36Sopenharmony_ci		*quanta = 2;
157862306a36Sopenharmony_ci		break;
157962306a36Sopenharmony_ci	case 4:
158062306a36Sopenharmony_ci	case 5:
158162306a36Sopenharmony_ci		*quanta = 3;
158262306a36Sopenharmony_ci		break;
158362306a36Sopenharmony_ci	case 6:
158462306a36Sopenharmony_ci	case 7:
158562306a36Sopenharmony_ci		*quanta = 4;
158662306a36Sopenharmony_ci		break;
158762306a36Sopenharmony_ci	case 8:
158862306a36Sopenharmony_ci	case 9:
158962306a36Sopenharmony_ci		*quanta = 5;
159062306a36Sopenharmony_ci		break;
159162306a36Sopenharmony_ci	case 10:
159262306a36Sopenharmony_ci	case 11:
159362306a36Sopenharmony_ci		*quanta = 6;
159462306a36Sopenharmony_ci		break;
159562306a36Sopenharmony_ci	case 12:
159662306a36Sopenharmony_ci	case 13:
159762306a36Sopenharmony_ci		*quanta = 7;
159862306a36Sopenharmony_ci		break;
159962306a36Sopenharmony_ci	case 14:
160062306a36Sopenharmony_ci	case 15: /* when immediate data is present */
160162306a36Sopenharmony_ci		*quanta = 8;
160262306a36Sopenharmony_ci		break;
160362306a36Sopenharmony_ci	default:
160462306a36Sopenharmony_ci		return -EINVAL;
160562306a36Sopenharmony_ci	}
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci	return 0;
160862306a36Sopenharmony_ci}
160962306a36Sopenharmony_ci
161062306a36Sopenharmony_ci/**
161162306a36Sopenharmony_ci * irdma_fragcnt_to_wqesize_rq - calculate wqe size based on fragment count for RQ
161262306a36Sopenharmony_ci * @frag_cnt: number of fragments
161362306a36Sopenharmony_ci * @wqe_size: size in bytes given frag_cnt
161462306a36Sopenharmony_ci */
161562306a36Sopenharmony_ciint irdma_fragcnt_to_wqesize_rq(u32 frag_cnt, u16 *wqe_size)
161662306a36Sopenharmony_ci{
161762306a36Sopenharmony_ci	switch (frag_cnt) {
161862306a36Sopenharmony_ci	case 0:
161962306a36Sopenharmony_ci	case 1:
162062306a36Sopenharmony_ci		*wqe_size = 32;
162162306a36Sopenharmony_ci		break;
162262306a36Sopenharmony_ci	case 2:
162362306a36Sopenharmony_ci	case 3:
162462306a36Sopenharmony_ci		*wqe_size = 64;
162562306a36Sopenharmony_ci		break;
162662306a36Sopenharmony_ci	case 4:
162762306a36Sopenharmony_ci	case 5:
162862306a36Sopenharmony_ci	case 6:
162962306a36Sopenharmony_ci	case 7:
163062306a36Sopenharmony_ci		*wqe_size = 128;
163162306a36Sopenharmony_ci		break;
163262306a36Sopenharmony_ci	case 8:
163362306a36Sopenharmony_ci	case 9:
163462306a36Sopenharmony_ci	case 10:
163562306a36Sopenharmony_ci	case 11:
163662306a36Sopenharmony_ci	case 12:
163762306a36Sopenharmony_ci	case 13:
163862306a36Sopenharmony_ci	case 14:
163962306a36Sopenharmony_ci		*wqe_size = 256;
164062306a36Sopenharmony_ci		break;
164162306a36Sopenharmony_ci	default:
164262306a36Sopenharmony_ci		return -EINVAL;
164362306a36Sopenharmony_ci	}
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci	return 0;
164662306a36Sopenharmony_ci}
1647