xref: /freebsd/sys/dev/irdma/irdma_ctrl.c (revision cdcd52d41e246ba1c0fcfad0769bd691487355ef)
1*cdcd52d4SBartosz Sobczak /*-
2*cdcd52d4SBartosz Sobczak  * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
3*cdcd52d4SBartosz Sobczak  *
4*cdcd52d4SBartosz Sobczak  * Copyright (c) 2015 - 2022 Intel Corporation
5*cdcd52d4SBartosz Sobczak  *
6*cdcd52d4SBartosz Sobczak  * This software is available to you under a choice of one of two
7*cdcd52d4SBartosz Sobczak  * licenses.  You may choose to be licensed under the terms of the GNU
8*cdcd52d4SBartosz Sobczak  * General Public License (GPL) Version 2, available from the file
9*cdcd52d4SBartosz Sobczak  * COPYING in the main directory of this source tree, or the
10*cdcd52d4SBartosz Sobczak  * OpenFabrics.org BSD license below:
11*cdcd52d4SBartosz Sobczak  *
12*cdcd52d4SBartosz Sobczak  *   Redistribution and use in source and binary forms, with or
13*cdcd52d4SBartosz Sobczak  *   without modification, are permitted provided that the following
14*cdcd52d4SBartosz Sobczak  *   conditions are met:
15*cdcd52d4SBartosz Sobczak  *
16*cdcd52d4SBartosz Sobczak  *    - Redistributions of source code must retain the above
17*cdcd52d4SBartosz Sobczak  *	copyright notice, this list of conditions and the following
18*cdcd52d4SBartosz Sobczak  *	disclaimer.
19*cdcd52d4SBartosz Sobczak  *
20*cdcd52d4SBartosz Sobczak  *    - Redistributions in binary form must reproduce the above
21*cdcd52d4SBartosz Sobczak  *	copyright notice, this list of conditions and the following
22*cdcd52d4SBartosz Sobczak  *	disclaimer in the documentation and/or other materials
23*cdcd52d4SBartosz Sobczak  *	provided with the distribution.
24*cdcd52d4SBartosz Sobczak  *
25*cdcd52d4SBartosz Sobczak  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26*cdcd52d4SBartosz Sobczak  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27*cdcd52d4SBartosz Sobczak  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28*cdcd52d4SBartosz Sobczak  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29*cdcd52d4SBartosz Sobczak  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30*cdcd52d4SBartosz Sobczak  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31*cdcd52d4SBartosz Sobczak  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32*cdcd52d4SBartosz Sobczak  * SOFTWARE.
33*cdcd52d4SBartosz Sobczak  */
34*cdcd52d4SBartosz Sobczak /*$FreeBSD$*/
35*cdcd52d4SBartosz Sobczak 
36*cdcd52d4SBartosz Sobczak #include "osdep.h"
37*cdcd52d4SBartosz Sobczak #include "irdma_hmc.h"
38*cdcd52d4SBartosz Sobczak #include "irdma_defs.h"
39*cdcd52d4SBartosz Sobczak #include "irdma_type.h"
40*cdcd52d4SBartosz Sobczak #include "irdma_ws.h"
41*cdcd52d4SBartosz Sobczak #include "irdma_protos.h"
42*cdcd52d4SBartosz Sobczak 
43*cdcd52d4SBartosz Sobczak /**
44*cdcd52d4SBartosz Sobczak  * irdma_qp_from_entry - Given entry, get to the qp structure
45*cdcd52d4SBartosz Sobczak  * @entry: Points to list of qp structure
46*cdcd52d4SBartosz Sobczak  */
47*cdcd52d4SBartosz Sobczak static struct irdma_sc_qp *
48*cdcd52d4SBartosz Sobczak irdma_qp_from_entry(struct list_head *entry)
49*cdcd52d4SBartosz Sobczak {
50*cdcd52d4SBartosz Sobczak 	if (!entry)
51*cdcd52d4SBartosz Sobczak 		return NULL;
52*cdcd52d4SBartosz Sobczak 
53*cdcd52d4SBartosz Sobczak 	return (struct irdma_sc_qp *)((char *)entry -
54*cdcd52d4SBartosz Sobczak 				      offsetof(struct irdma_sc_qp, list));
55*cdcd52d4SBartosz Sobczak }
56*cdcd52d4SBartosz Sobczak 
57*cdcd52d4SBartosz Sobczak /**
58*cdcd52d4SBartosz Sobczak  * irdma_get_qp_from_list - get next qp from a list
59*cdcd52d4SBartosz Sobczak  * @head: Listhead of qp's
60*cdcd52d4SBartosz Sobczak  * @qp: current qp
61*cdcd52d4SBartosz Sobczak  */
62*cdcd52d4SBartosz Sobczak struct irdma_sc_qp *
63*cdcd52d4SBartosz Sobczak irdma_get_qp_from_list(struct list_head *head,
64*cdcd52d4SBartosz Sobczak 		       struct irdma_sc_qp *qp)
65*cdcd52d4SBartosz Sobczak {
66*cdcd52d4SBartosz Sobczak 	struct list_head *lastentry;
67*cdcd52d4SBartosz Sobczak 	struct list_head *entry = NULL;
68*cdcd52d4SBartosz Sobczak 
69*cdcd52d4SBartosz Sobczak 	if (list_empty(head))
70*cdcd52d4SBartosz Sobczak 		return NULL;
71*cdcd52d4SBartosz Sobczak 
72*cdcd52d4SBartosz Sobczak 	if (!qp) {
73*cdcd52d4SBartosz Sobczak 		entry = (head)->next;
74*cdcd52d4SBartosz Sobczak 	} else {
75*cdcd52d4SBartosz Sobczak 		lastentry = &qp->list;
76*cdcd52d4SBartosz Sobczak 		entry = (lastentry)->next;
77*cdcd52d4SBartosz Sobczak 		if (entry == head)
78*cdcd52d4SBartosz Sobczak 			return NULL;
79*cdcd52d4SBartosz Sobczak 	}
80*cdcd52d4SBartosz Sobczak 
81*cdcd52d4SBartosz Sobczak 	return irdma_qp_from_entry(entry);
82*cdcd52d4SBartosz Sobczak }
83*cdcd52d4SBartosz Sobczak 
84*cdcd52d4SBartosz Sobczak /**
85*cdcd52d4SBartosz Sobczak  * irdma_sc_suspend_resume_qps - suspend/resume all qp's on VSI
86*cdcd52d4SBartosz Sobczak  * @vsi: the VSI struct pointer
87*cdcd52d4SBartosz Sobczak  * @op: Set to IRDMA_OP_RESUME or IRDMA_OP_SUSPEND
88*cdcd52d4SBartosz Sobczak  */
89*cdcd52d4SBartosz Sobczak void
90*cdcd52d4SBartosz Sobczak irdma_sc_suspend_resume_qps(struct irdma_sc_vsi *vsi, u8 op)
91*cdcd52d4SBartosz Sobczak {
92*cdcd52d4SBartosz Sobczak 	struct irdma_sc_qp *qp = NULL;
93*cdcd52d4SBartosz Sobczak 	u8 i;
94*cdcd52d4SBartosz Sobczak 
95*cdcd52d4SBartosz Sobczak 	for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
96*cdcd52d4SBartosz Sobczak 		mutex_lock(&vsi->qos[i].qos_mutex);
97*cdcd52d4SBartosz Sobczak 		qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
98*cdcd52d4SBartosz Sobczak 		while (qp) {
99*cdcd52d4SBartosz Sobczak 			if (op == IRDMA_OP_RESUME) {
100*cdcd52d4SBartosz Sobczak 				if (!qp->dev->ws_add(vsi, i)) {
101*cdcd52d4SBartosz Sobczak 					qp->qs_handle =
102*cdcd52d4SBartosz Sobczak 					    vsi->qos[qp->user_pri].qs_handle;
103*cdcd52d4SBartosz Sobczak 					irdma_cqp_qp_suspend_resume(qp, op);
104*cdcd52d4SBartosz Sobczak 				} else {
105*cdcd52d4SBartosz Sobczak 					irdma_cqp_qp_suspend_resume(qp, op);
106*cdcd52d4SBartosz Sobczak 					irdma_modify_qp_to_err(qp);
107*cdcd52d4SBartosz Sobczak 				}
108*cdcd52d4SBartosz Sobczak 			} else if (op == IRDMA_OP_SUSPEND) {
109*cdcd52d4SBartosz Sobczak 				/* issue cqp suspend command */
110*cdcd52d4SBartosz Sobczak 				if (!irdma_cqp_qp_suspend_resume(qp, op))
111*cdcd52d4SBartosz Sobczak 					atomic_inc(&vsi->qp_suspend_reqs);
112*cdcd52d4SBartosz Sobczak 			}
113*cdcd52d4SBartosz Sobczak 			qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
114*cdcd52d4SBartosz Sobczak 		}
115*cdcd52d4SBartosz Sobczak 		mutex_unlock(&vsi->qos[i].qos_mutex);
116*cdcd52d4SBartosz Sobczak 	}
117*cdcd52d4SBartosz Sobczak }
118*cdcd52d4SBartosz Sobczak 
119*cdcd52d4SBartosz Sobczak static void
120*cdcd52d4SBartosz Sobczak irdma_set_qos_info(struct irdma_sc_vsi *vsi, struct irdma_l2params *l2p)
121*cdcd52d4SBartosz Sobczak {
122*cdcd52d4SBartosz Sobczak 	u8 i;
123*cdcd52d4SBartosz Sobczak 
124*cdcd52d4SBartosz Sobczak 	vsi->qos_rel_bw = l2p->vsi_rel_bw;
125*cdcd52d4SBartosz Sobczak 	vsi->qos_prio_type = l2p->vsi_prio_type;
126*cdcd52d4SBartosz Sobczak 	vsi->dscp_mode = l2p->dscp_mode;
127*cdcd52d4SBartosz Sobczak 	if (l2p->dscp_mode) {
128*cdcd52d4SBartosz Sobczak 		irdma_memcpy(vsi->dscp_map, l2p->dscp_map, sizeof(vsi->dscp_map));
129*cdcd52d4SBartosz Sobczak 		for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++)
130*cdcd52d4SBartosz Sobczak 			l2p->up2tc[i] = i;
131*cdcd52d4SBartosz Sobczak 	}
132*cdcd52d4SBartosz Sobczak 	for (i = 0; i < IRDMA_MAX_TRAFFIC_CLASS; i++)
133*cdcd52d4SBartosz Sobczak 		vsi->tc_print_warning[i] = true;
134*cdcd52d4SBartosz Sobczak 	for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
135*cdcd52d4SBartosz Sobczak 		if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
136*cdcd52d4SBartosz Sobczak 			vsi->qos[i].qs_handle = l2p->qs_handle_list[i];
137*cdcd52d4SBartosz Sobczak 		if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_2)
138*cdcd52d4SBartosz Sobczak 			irdma_init_config_check(&vsi->cfg_check[i],
139*cdcd52d4SBartosz Sobczak 						l2p->up2tc[i],
140*cdcd52d4SBartosz Sobczak 						l2p->qs_handle_list[i]);
141*cdcd52d4SBartosz Sobczak 		vsi->qos[i].traffic_class = l2p->up2tc[i];
142*cdcd52d4SBartosz Sobczak 		vsi->qos[i].rel_bw =
143*cdcd52d4SBartosz Sobczak 		    l2p->tc_info[vsi->qos[i].traffic_class].rel_bw;
144*cdcd52d4SBartosz Sobczak 		vsi->qos[i].prio_type =
145*cdcd52d4SBartosz Sobczak 		    l2p->tc_info[vsi->qos[i].traffic_class].prio_type;
146*cdcd52d4SBartosz Sobczak 		vsi->qos[i].valid = false;
147*cdcd52d4SBartosz Sobczak 	}
148*cdcd52d4SBartosz Sobczak }
149*cdcd52d4SBartosz Sobczak 
150*cdcd52d4SBartosz Sobczak /**
151*cdcd52d4SBartosz Sobczak  * irdma_change_l2params - given the new l2 parameters, change all qp
152*cdcd52d4SBartosz Sobczak  * @vsi: RDMA VSI pointer
153*cdcd52d4SBartosz Sobczak  * @l2params: New parameters from l2
154*cdcd52d4SBartosz Sobczak  */
155*cdcd52d4SBartosz Sobczak void
156*cdcd52d4SBartosz Sobczak irdma_change_l2params(struct irdma_sc_vsi *vsi,
157*cdcd52d4SBartosz Sobczak 		      struct irdma_l2params *l2params)
158*cdcd52d4SBartosz Sobczak {
159*cdcd52d4SBartosz Sobczak 	if (l2params->mtu_changed) {
160*cdcd52d4SBartosz Sobczak 		vsi->mtu = l2params->mtu;
161*cdcd52d4SBartosz Sobczak 		if (vsi->ieq)
162*cdcd52d4SBartosz Sobczak 			irdma_reinitialize_ieq(vsi);
163*cdcd52d4SBartosz Sobczak 	}
164*cdcd52d4SBartosz Sobczak 
165*cdcd52d4SBartosz Sobczak 	if (!l2params->tc_changed)
166*cdcd52d4SBartosz Sobczak 		return;
167*cdcd52d4SBartosz Sobczak 
168*cdcd52d4SBartosz Sobczak 	vsi->tc_change_pending = false;
169*cdcd52d4SBartosz Sobczak 	irdma_set_qos_info(vsi, l2params);
170*cdcd52d4SBartosz Sobczak 	irdma_sc_suspend_resume_qps(vsi, IRDMA_OP_RESUME);
171*cdcd52d4SBartosz Sobczak }
172*cdcd52d4SBartosz Sobczak 
173*cdcd52d4SBartosz Sobczak /**
174*cdcd52d4SBartosz Sobczak  * irdma_qp_rem_qos - remove qp from qos lists during destroy qp
175*cdcd52d4SBartosz Sobczak  * @qp: qp to be removed from qos
176*cdcd52d4SBartosz Sobczak  */
177*cdcd52d4SBartosz Sobczak void
178*cdcd52d4SBartosz Sobczak irdma_qp_rem_qos(struct irdma_sc_qp *qp)
179*cdcd52d4SBartosz Sobczak {
180*cdcd52d4SBartosz Sobczak 	struct irdma_sc_vsi *vsi = qp->vsi;
181*cdcd52d4SBartosz Sobczak 
182*cdcd52d4SBartosz Sobczak 	irdma_debug(qp->dev, IRDMA_DEBUG_DCB,
183*cdcd52d4SBartosz Sobczak 		    "DCB: Remove qp[%d] UP[%d] qset[%d] on_qoslist[%d]\n",
184*cdcd52d4SBartosz Sobczak 		    qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle, qp->on_qoslist);
185*cdcd52d4SBartosz Sobczak 	mutex_lock(&vsi->qos[qp->user_pri].qos_mutex);
186*cdcd52d4SBartosz Sobczak 	if (qp->on_qoslist) {
187*cdcd52d4SBartosz Sobczak 		qp->on_qoslist = false;
188*cdcd52d4SBartosz Sobczak 		list_del(&qp->list);
189*cdcd52d4SBartosz Sobczak 	}
190*cdcd52d4SBartosz Sobczak 	mutex_unlock(&vsi->qos[qp->user_pri].qos_mutex);
191*cdcd52d4SBartosz Sobczak }
192*cdcd52d4SBartosz Sobczak 
193*cdcd52d4SBartosz Sobczak /**
194*cdcd52d4SBartosz Sobczak  * irdma_qp_add_qos - called during setctx for qp to be added to qos
195*cdcd52d4SBartosz Sobczak  * @qp: qp to be added to qos
196*cdcd52d4SBartosz Sobczak  */
197*cdcd52d4SBartosz Sobczak void
198*cdcd52d4SBartosz Sobczak irdma_qp_add_qos(struct irdma_sc_qp *qp)
199*cdcd52d4SBartosz Sobczak {
200*cdcd52d4SBartosz Sobczak 	struct irdma_sc_vsi *vsi = qp->vsi;
201*cdcd52d4SBartosz Sobczak 
202*cdcd52d4SBartosz Sobczak 	irdma_debug(qp->dev, IRDMA_DEBUG_DCB,
203*cdcd52d4SBartosz Sobczak 		    "DCB: Add qp[%d] UP[%d] qset[%d] on_qoslist[%d]\n",
204*cdcd52d4SBartosz Sobczak 		    qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle, qp->on_qoslist);
205*cdcd52d4SBartosz Sobczak 	mutex_lock(&vsi->qos[qp->user_pri].qos_mutex);
206*cdcd52d4SBartosz Sobczak 	if (!qp->on_qoslist) {
207*cdcd52d4SBartosz Sobczak 		list_add(&qp->list, &vsi->qos[qp->user_pri].qplist);
208*cdcd52d4SBartosz Sobczak 		qp->on_qoslist = true;
209*cdcd52d4SBartosz Sobczak 		qp->qs_handle = vsi->qos[qp->user_pri].qs_handle;
210*cdcd52d4SBartosz Sobczak 	}
211*cdcd52d4SBartosz Sobczak 	mutex_unlock(&vsi->qos[qp->user_pri].qos_mutex);
212*cdcd52d4SBartosz Sobczak }
213*cdcd52d4SBartosz Sobczak 
214*cdcd52d4SBartosz Sobczak /**
215*cdcd52d4SBartosz Sobczak  * irdma_sc_pd_init - initialize sc pd struct
216*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
217*cdcd52d4SBartosz Sobczak  * @pd: sc pd ptr
218*cdcd52d4SBartosz Sobczak  * @pd_id: pd_id for allocated pd
219*cdcd52d4SBartosz Sobczak  * @abi_ver: User/Kernel ABI version
220*cdcd52d4SBartosz Sobczak  */
221*cdcd52d4SBartosz Sobczak void
222*cdcd52d4SBartosz Sobczak irdma_sc_pd_init(struct irdma_sc_dev *dev, struct irdma_sc_pd *pd, u32 pd_id,
223*cdcd52d4SBartosz Sobczak 		 int abi_ver)
224*cdcd52d4SBartosz Sobczak {
225*cdcd52d4SBartosz Sobczak 	pd->pd_id = pd_id;
226*cdcd52d4SBartosz Sobczak 	pd->abi_ver = abi_ver;
227*cdcd52d4SBartosz Sobczak 	pd->dev = dev;
228*cdcd52d4SBartosz Sobczak }
229*cdcd52d4SBartosz Sobczak 
230*cdcd52d4SBartosz Sobczak /**
231*cdcd52d4SBartosz Sobczak  * irdma_sc_add_arp_cache_entry - cqp wqe add arp cache entry
232*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
233*cdcd52d4SBartosz Sobczak  * @info: arp entry information
234*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
235*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
236*cdcd52d4SBartosz Sobczak  */
237*cdcd52d4SBartosz Sobczak static int
238*cdcd52d4SBartosz Sobczak irdma_sc_add_arp_cache_entry(struct irdma_sc_cqp *cqp,
239*cdcd52d4SBartosz Sobczak 			     struct irdma_add_arp_cache_entry_info *info,
240*cdcd52d4SBartosz Sobczak 			     u64 scratch, bool post_sq)
241*cdcd52d4SBartosz Sobczak {
242*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
243*cdcd52d4SBartosz Sobczak 	u64 temp, hdr;
244*cdcd52d4SBartosz Sobczak 
245*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
246*cdcd52d4SBartosz Sobczak 	if (!wqe)
247*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
248*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, info->reach_max);
249*cdcd52d4SBartosz Sobczak 
250*cdcd52d4SBartosz Sobczak 	temp = info->mac_addr[5] | LS_64_1(info->mac_addr[4], 8) |
251*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->mac_addr[3], 16) | LS_64_1(info->mac_addr[2], 24) |
252*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->mac_addr[1], 32) | LS_64_1(info->mac_addr[0], 40);
253*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, temp);
254*cdcd52d4SBartosz Sobczak 
255*cdcd52d4SBartosz Sobczak 	hdr = info->arp_index |
256*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_ARP, IRDMA_CQPSQ_OPCODE) |
257*cdcd52d4SBartosz Sobczak 	    LS_64((info->permanent ? 1 : 0), IRDMA_CQPSQ_MAT_PERMANENT) |
258*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMA_CQPSQ_MAT_ENTRYVALID) |
259*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
260*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
261*cdcd52d4SBartosz Sobczak 
262*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
263*cdcd52d4SBartosz Sobczak 
264*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "ARP_CACHE_ENTRY WQE", wqe,
265*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
266*cdcd52d4SBartosz Sobczak 	if (post_sq)
267*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
268*cdcd52d4SBartosz Sobczak 
269*cdcd52d4SBartosz Sobczak 	return 0;
270*cdcd52d4SBartosz Sobczak }
271*cdcd52d4SBartosz Sobczak 
272*cdcd52d4SBartosz Sobczak /**
273*cdcd52d4SBartosz Sobczak  * irdma_sc_del_arp_cache_entry - dele arp cache entry
274*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
275*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
276*cdcd52d4SBartosz Sobczak  * @arp_index: arp index to delete arp entry
277*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
278*cdcd52d4SBartosz Sobczak  */
279*cdcd52d4SBartosz Sobczak static int
280*cdcd52d4SBartosz Sobczak irdma_sc_del_arp_cache_entry(struct irdma_sc_cqp *cqp, u64 scratch,
281*cdcd52d4SBartosz Sobczak 			     u16 arp_index, bool post_sq)
282*cdcd52d4SBartosz Sobczak {
283*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
284*cdcd52d4SBartosz Sobczak 	u64 hdr;
285*cdcd52d4SBartosz Sobczak 
286*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
287*cdcd52d4SBartosz Sobczak 	if (!wqe)
288*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
289*cdcd52d4SBartosz Sobczak 
290*cdcd52d4SBartosz Sobczak 	hdr = arp_index | LS_64(IRDMA_CQP_OP_MANAGE_ARP, IRDMA_CQPSQ_OPCODE) |
291*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
292*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
293*cdcd52d4SBartosz Sobczak 
294*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
295*cdcd52d4SBartosz Sobczak 
296*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "ARP_CACHE_DEL_ENTRY WQE",
297*cdcd52d4SBartosz Sobczak 			wqe, IRDMA_CQP_WQE_SIZE * 8);
298*cdcd52d4SBartosz Sobczak 	if (post_sq)
299*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
300*cdcd52d4SBartosz Sobczak 
301*cdcd52d4SBartosz Sobczak 	return 0;
302*cdcd52d4SBartosz Sobczak }
303*cdcd52d4SBartosz Sobczak 
304*cdcd52d4SBartosz Sobczak /**
305*cdcd52d4SBartosz Sobczak  * irdma_sc_manage_apbvt_entry - for adding and deleting apbvt entries
306*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
307*cdcd52d4SBartosz Sobczak  * @info: info for apbvt entry to add or delete
308*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
309*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
310*cdcd52d4SBartosz Sobczak  */
311*cdcd52d4SBartosz Sobczak static int
312*cdcd52d4SBartosz Sobczak irdma_sc_manage_apbvt_entry(struct irdma_sc_cqp *cqp,
313*cdcd52d4SBartosz Sobczak 			    struct irdma_apbvt_info *info,
314*cdcd52d4SBartosz Sobczak 			    u64 scratch, bool post_sq)
315*cdcd52d4SBartosz Sobczak {
316*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
317*cdcd52d4SBartosz Sobczak 	u64 hdr;
318*cdcd52d4SBartosz Sobczak 
319*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
320*cdcd52d4SBartosz Sobczak 	if (!wqe)
321*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
322*cdcd52d4SBartosz Sobczak 
323*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, info->port);
324*cdcd52d4SBartosz Sobczak 
325*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_MANAGE_APBVT, IRDMA_CQPSQ_OPCODE) |
326*cdcd52d4SBartosz Sobczak 	    LS_64(info->add, IRDMA_CQPSQ_MAPT_ADDPORT) |
327*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
328*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
329*cdcd52d4SBartosz Sobczak 
330*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
331*cdcd52d4SBartosz Sobczak 
332*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_APBVT WQE", wqe,
333*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
334*cdcd52d4SBartosz Sobczak 	if (post_sq)
335*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
336*cdcd52d4SBartosz Sobczak 
337*cdcd52d4SBartosz Sobczak 	return 0;
338*cdcd52d4SBartosz Sobczak }
339*cdcd52d4SBartosz Sobczak 
340*cdcd52d4SBartosz Sobczak /**
341*cdcd52d4SBartosz Sobczak  * irdma_sc_manage_qhash_table_entry - manage quad hash entries
342*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
343*cdcd52d4SBartosz Sobczak  * @info: info for quad hash to manage
344*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
345*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
346*cdcd52d4SBartosz Sobczak  *
347*cdcd52d4SBartosz Sobczak  * This is called before connection establishment is started.
348*cdcd52d4SBartosz Sobczak  * For passive connections, when listener is created, it will
349*cdcd52d4SBartosz Sobczak  * call with entry type of  IRDMA_QHASH_TYPE_TCP_SYN with local
350*cdcd52d4SBartosz Sobczak  * ip address and tcp port. When SYN is received (passive
351*cdcd52d4SBartosz Sobczak  * connections) or sent (active connections), this routine is
352*cdcd52d4SBartosz Sobczak  * called with entry type of IRDMA_QHASH_TYPE_TCP_ESTABLISHED
353*cdcd52d4SBartosz Sobczak  * and quad is passed in info.
354*cdcd52d4SBartosz Sobczak  *
355*cdcd52d4SBartosz Sobczak  * When iwarp connection is done and its state moves to RTS, the
356*cdcd52d4SBartosz Sobczak  * quad hash entry in the hardware will point to iwarp's qp
357*cdcd52d4SBartosz Sobczak  * number and requires no calls from the driver.
358*cdcd52d4SBartosz Sobczak  */
359*cdcd52d4SBartosz Sobczak static int
360*cdcd52d4SBartosz Sobczak irdma_sc_manage_qhash_table_entry(struct irdma_sc_cqp *cqp,
361*cdcd52d4SBartosz Sobczak 				  struct irdma_qhash_table_info *info,
362*cdcd52d4SBartosz Sobczak 				  u64 scratch, bool post_sq)
363*cdcd52d4SBartosz Sobczak {
364*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
365*cdcd52d4SBartosz Sobczak 	u64 qw1 = 0;
366*cdcd52d4SBartosz Sobczak 	u64 qw2 = 0;
367*cdcd52d4SBartosz Sobczak 	u64 temp;
368*cdcd52d4SBartosz Sobczak 	struct irdma_sc_vsi *vsi = info->vsi;
369*cdcd52d4SBartosz Sobczak 
370*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
371*cdcd52d4SBartosz Sobczak 	if (!wqe)
372*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
373*cdcd52d4SBartosz Sobczak 	temp = info->mac_addr[5] | LS_64_1(info->mac_addr[4], 8) |
374*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->mac_addr[3], 16) | LS_64_1(info->mac_addr[2], 24) |
375*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->mac_addr[1], 32) | LS_64_1(info->mac_addr[0], 40);
376*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, temp);
377*cdcd52d4SBartosz Sobczak 
378*cdcd52d4SBartosz Sobczak 	qw1 = LS_64(info->qp_num, IRDMA_CQPSQ_QHASH_QPN) |
379*cdcd52d4SBartosz Sobczak 	    LS_64(info->dest_port, IRDMA_CQPSQ_QHASH_DEST_PORT);
380*cdcd52d4SBartosz Sobczak 	if (info->ipv4_valid) {
381*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
382*cdcd52d4SBartosz Sobczak 			      LS_64(info->dest_ip[0], IRDMA_CQPSQ_QHASH_ADDR3));
383*cdcd52d4SBartosz Sobczak 	} else {
384*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_56,
385*cdcd52d4SBartosz Sobczak 			      LS_64(info->dest_ip[0], IRDMA_CQPSQ_QHASH_ADDR0) |
386*cdcd52d4SBartosz Sobczak 			      LS_64(info->dest_ip[1], IRDMA_CQPSQ_QHASH_ADDR1));
387*cdcd52d4SBartosz Sobczak 
388*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
389*cdcd52d4SBartosz Sobczak 			      LS_64(info->dest_ip[2], IRDMA_CQPSQ_QHASH_ADDR2) |
390*cdcd52d4SBartosz Sobczak 			      LS_64(info->dest_ip[3], IRDMA_CQPSQ_QHASH_ADDR3));
391*cdcd52d4SBartosz Sobczak 	}
392*cdcd52d4SBartosz Sobczak 	qw2 = LS_64(vsi->qos[info->user_pri].qs_handle,
393*cdcd52d4SBartosz Sobczak 		    IRDMA_CQPSQ_QHASH_QS_HANDLE);
394*cdcd52d4SBartosz Sobczak 	if (info->vlan_valid)
395*cdcd52d4SBartosz Sobczak 		qw2 |= LS_64(info->vlan_id, IRDMA_CQPSQ_QHASH_VLANID);
396*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, qw2);
397*cdcd52d4SBartosz Sobczak 	if (info->entry_type == IRDMA_QHASH_TYPE_TCP_ESTABLISHED) {
398*cdcd52d4SBartosz Sobczak 		qw1 |= LS_64(info->src_port, IRDMA_CQPSQ_QHASH_SRC_PORT);
399*cdcd52d4SBartosz Sobczak 		if (!info->ipv4_valid) {
400*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_40,
401*cdcd52d4SBartosz Sobczak 				      LS_64(info->src_ip[0], IRDMA_CQPSQ_QHASH_ADDR0) |
402*cdcd52d4SBartosz Sobczak 				      LS_64(info->src_ip[1], IRDMA_CQPSQ_QHASH_ADDR1));
403*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_32,
404*cdcd52d4SBartosz Sobczak 				      LS_64(info->src_ip[2], IRDMA_CQPSQ_QHASH_ADDR2) |
405*cdcd52d4SBartosz Sobczak 				      LS_64(info->src_ip[3], IRDMA_CQPSQ_QHASH_ADDR3));
406*cdcd52d4SBartosz Sobczak 		} else {
407*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_32,
408*cdcd52d4SBartosz Sobczak 				      LS_64(info->src_ip[0], IRDMA_CQPSQ_QHASH_ADDR3));
409*cdcd52d4SBartosz Sobczak 		}
410*cdcd52d4SBartosz Sobczak 	}
411*cdcd52d4SBartosz Sobczak 
412*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, qw1);
413*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->polarity, IRDMA_CQPSQ_QHASH_WQEVALID) |
414*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_QUAD_HASH_TABLE_ENTRY,
415*cdcd52d4SBartosz Sobczak 		  IRDMA_CQPSQ_QHASH_OPCODE) |
416*cdcd52d4SBartosz Sobczak 	    LS_64(info->manage, IRDMA_CQPSQ_QHASH_MANAGE) |
417*cdcd52d4SBartosz Sobczak 	    LS_64(info->ipv4_valid, IRDMA_CQPSQ_QHASH_IPV4VALID) |
418*cdcd52d4SBartosz Sobczak 	    LS_64(info->vlan_valid, IRDMA_CQPSQ_QHASH_VLANVALID) |
419*cdcd52d4SBartosz Sobczak 	    LS_64(info->entry_type, IRDMA_CQPSQ_QHASH_ENTRYTYPE);
420*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
421*cdcd52d4SBartosz Sobczak 
422*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, temp);
423*cdcd52d4SBartosz Sobczak 
424*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_QHASH WQE", wqe,
425*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
426*cdcd52d4SBartosz Sobczak 	if (post_sq)
427*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
428*cdcd52d4SBartosz Sobczak 
429*cdcd52d4SBartosz Sobczak 	return 0;
430*cdcd52d4SBartosz Sobczak }
431*cdcd52d4SBartosz Sobczak 
432*cdcd52d4SBartosz Sobczak /**
433*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_init - initialize qp
434*cdcd52d4SBartosz Sobczak  * @qp: sc qp
435*cdcd52d4SBartosz Sobczak  * @info: initialization qp info
436*cdcd52d4SBartosz Sobczak  */
437*cdcd52d4SBartosz Sobczak int
438*cdcd52d4SBartosz Sobczak irdma_sc_qp_init(struct irdma_sc_qp *qp, struct irdma_qp_init_info *info)
439*cdcd52d4SBartosz Sobczak {
440*cdcd52d4SBartosz Sobczak 	int ret_code;
441*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
442*cdcd52d4SBartosz Sobczak 	u16 wqe_size;
443*cdcd52d4SBartosz Sobczak 
444*cdcd52d4SBartosz Sobczak 	if (info->qp_uk_init_info.max_sq_frag_cnt >
445*cdcd52d4SBartosz Sobczak 	    info->pd->dev->hw_attrs.uk_attrs.max_hw_wq_frags ||
446*cdcd52d4SBartosz Sobczak 	    info->qp_uk_init_info.max_rq_frag_cnt >
447*cdcd52d4SBartosz Sobczak 	    info->pd->dev->hw_attrs.uk_attrs.max_hw_wq_frags)
448*cdcd52d4SBartosz Sobczak 		return -EINVAL;
449*cdcd52d4SBartosz Sobczak 
450*cdcd52d4SBartosz Sobczak 	qp->dev = info->pd->dev;
451*cdcd52d4SBartosz Sobczak 	qp->vsi = info->vsi;
452*cdcd52d4SBartosz Sobczak 	qp->ieq_qp = info->vsi->exception_lan_q;
453*cdcd52d4SBartosz Sobczak 	qp->sq_pa = info->sq_pa;
454*cdcd52d4SBartosz Sobczak 	qp->rq_pa = info->rq_pa;
455*cdcd52d4SBartosz Sobczak 	qp->hw_host_ctx_pa = info->host_ctx_pa;
456*cdcd52d4SBartosz Sobczak 	qp->q2_pa = info->q2_pa;
457*cdcd52d4SBartosz Sobczak 	qp->shadow_area_pa = info->shadow_area_pa;
458*cdcd52d4SBartosz Sobczak 	qp->q2_buf = info->q2;
459*cdcd52d4SBartosz Sobczak 	qp->pd = info->pd;
460*cdcd52d4SBartosz Sobczak 	qp->hw_host_ctx = info->host_ctx;
461*cdcd52d4SBartosz Sobczak 	info->qp_uk_init_info.wqe_alloc_db = qp->pd->dev->wqe_alloc_db;
462*cdcd52d4SBartosz Sobczak 	ret_code = irdma_uk_qp_init(&qp->qp_uk, &info->qp_uk_init_info);
463*cdcd52d4SBartosz Sobczak 	if (ret_code)
464*cdcd52d4SBartosz Sobczak 		return ret_code;
465*cdcd52d4SBartosz Sobczak 
466*cdcd52d4SBartosz Sobczak 	qp->virtual_map = info->virtual_map;
467*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = info->pd->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
468*cdcd52d4SBartosz Sobczak 
469*cdcd52d4SBartosz Sobczak 	if ((info->virtual_map && info->sq_pa >= pble_obj_cnt) ||
470*cdcd52d4SBartosz Sobczak 	    (info->virtual_map && info->rq_pa >= pble_obj_cnt))
471*cdcd52d4SBartosz Sobczak 		return -EINVAL;
472*cdcd52d4SBartosz Sobczak 
473*cdcd52d4SBartosz Sobczak 	qp->llp_stream_handle = (void *)(-1);
474*cdcd52d4SBartosz Sobczak 	qp->qp_uk.force_fence = true;
475*cdcd52d4SBartosz Sobczak 	qp->hw_sq_size = irdma_get_encoded_wqe_size(qp->qp_uk.sq_ring.size,
476*cdcd52d4SBartosz Sobczak 						    IRDMA_QUEUE_TYPE_SQ_RQ);
477*cdcd52d4SBartosz Sobczak 	irdma_debug(qp->dev, IRDMA_DEBUG_WQE,
478*cdcd52d4SBartosz Sobczak 		    "hw_sq_size[%04d] sq_ring.size[%04d]\n", qp->hw_sq_size,
479*cdcd52d4SBartosz Sobczak 		    qp->qp_uk.sq_ring.size);
480*cdcd52d4SBartosz Sobczak 	if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1)
481*cdcd52d4SBartosz Sobczak 		wqe_size = IRDMA_WQE_SIZE_128;
482*cdcd52d4SBartosz Sobczak 	else
483*cdcd52d4SBartosz Sobczak 		ret_code = irdma_fragcnt_to_wqesize_rq(qp->qp_uk.max_rq_frag_cnt,
484*cdcd52d4SBartosz Sobczak 						       &wqe_size);
485*cdcd52d4SBartosz Sobczak 	if (ret_code)
486*cdcd52d4SBartosz Sobczak 		return ret_code;
487*cdcd52d4SBartosz Sobczak 
488*cdcd52d4SBartosz Sobczak 	qp->hw_rq_size =
489*cdcd52d4SBartosz Sobczak 	    irdma_get_encoded_wqe_size(qp->qp_uk.rq_size *
490*cdcd52d4SBartosz Sobczak 				       (wqe_size / IRDMA_QP_WQE_MIN_SIZE),
491*cdcd52d4SBartosz Sobczak 				       IRDMA_QUEUE_TYPE_SQ_RQ);
492*cdcd52d4SBartosz Sobczak 	irdma_debug(qp->dev, IRDMA_DEBUG_WQE,
493*cdcd52d4SBartosz Sobczak 		    "hw_rq_size[%04d] qp_uk.rq_size[%04d] wqe_size[%04d]\n",
494*cdcd52d4SBartosz Sobczak 		    qp->hw_rq_size, qp->qp_uk.rq_size, wqe_size);
495*cdcd52d4SBartosz Sobczak 
496*cdcd52d4SBartosz Sobczak 	qp->sq_tph_val = info->sq_tph_val;
497*cdcd52d4SBartosz Sobczak 	qp->rq_tph_val = info->rq_tph_val;
498*cdcd52d4SBartosz Sobczak 	qp->sq_tph_en = info->sq_tph_en;
499*cdcd52d4SBartosz Sobczak 	qp->rq_tph_en = info->rq_tph_en;
500*cdcd52d4SBartosz Sobczak 	qp->rcv_tph_en = info->rcv_tph_en;
501*cdcd52d4SBartosz Sobczak 	qp->xmit_tph_en = info->xmit_tph_en;
502*cdcd52d4SBartosz Sobczak 	qp->qp_uk.first_sq_wq = info->qp_uk_init_info.first_sq_wq;
503*cdcd52d4SBartosz Sobczak 	qp->qs_handle = qp->vsi->qos[qp->user_pri].qs_handle;
504*cdcd52d4SBartosz Sobczak 
505*cdcd52d4SBartosz Sobczak 	return 0;
506*cdcd52d4SBartosz Sobczak }
507*cdcd52d4SBartosz Sobczak 
508*cdcd52d4SBartosz Sobczak /**
509*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_create - create qp
510*cdcd52d4SBartosz Sobczak  * @qp: sc qp
511*cdcd52d4SBartosz Sobczak  * @info: qp create info
512*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
513*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
514*cdcd52d4SBartosz Sobczak  */
515*cdcd52d4SBartosz Sobczak int
516*cdcd52d4SBartosz Sobczak irdma_sc_qp_create(struct irdma_sc_qp *qp, struct irdma_create_qp_info *info,
517*cdcd52d4SBartosz Sobczak 		   u64 scratch, bool post_sq)
518*cdcd52d4SBartosz Sobczak {
519*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
520*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
521*cdcd52d4SBartosz Sobczak 	u64 hdr;
522*cdcd52d4SBartosz Sobczak 
523*cdcd52d4SBartosz Sobczak 	cqp = qp->dev->cqp;
524*cdcd52d4SBartosz Sobczak 	if (qp->qp_uk.qp_id < cqp->dev->hw_attrs.min_hw_qp_id ||
525*cdcd52d4SBartosz Sobczak 	    qp->qp_uk.qp_id > (cqp->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt - 1))
526*cdcd52d4SBartosz Sobczak 		return -EINVAL;
527*cdcd52d4SBartosz Sobczak 
528*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
529*cdcd52d4SBartosz Sobczak 	if (!wqe)
530*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
531*cdcd52d4SBartosz Sobczak 
532*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, qp->hw_host_ctx_pa);
533*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, qp->shadow_area_pa);
534*cdcd52d4SBartosz Sobczak 
535*cdcd52d4SBartosz Sobczak 	hdr = qp->qp_uk.qp_id |
536*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_CREATE_QP, IRDMA_CQPSQ_OPCODE) |
537*cdcd52d4SBartosz Sobczak 	    LS_64((info->ord_valid ? 1 : 0), IRDMA_CQPSQ_QP_ORDVALID) |
538*cdcd52d4SBartosz Sobczak 	    LS_64(info->tcp_ctx_valid, IRDMA_CQPSQ_QP_TOECTXVALID) |
539*cdcd52d4SBartosz Sobczak 	    LS_64(info->mac_valid, IRDMA_CQPSQ_QP_MACVALID) |
540*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.qp_type, IRDMA_CQPSQ_QP_QPTYPE) |
541*cdcd52d4SBartosz Sobczak 	    LS_64(qp->virtual_map, IRDMA_CQPSQ_QP_VQ) |
542*cdcd52d4SBartosz Sobczak 	    LS_64(info->force_lpb, IRDMA_CQPSQ_QP_FORCELOOPBACK) |
543*cdcd52d4SBartosz Sobczak 	    LS_64(info->cq_num_valid, IRDMA_CQPSQ_QP_CQNUMVALID) |
544*cdcd52d4SBartosz Sobczak 	    LS_64(info->arp_cache_idx_valid, IRDMA_CQPSQ_QP_ARPTABIDXVALID) |
545*cdcd52d4SBartosz Sobczak 	    LS_64(info->next_iwarp_state, IRDMA_CQPSQ_QP_NEXTIWSTATE) |
546*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
547*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
548*cdcd52d4SBartosz Sobczak 
549*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
550*cdcd52d4SBartosz Sobczak 
551*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "QP_CREATE WQE", wqe,
552*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
553*cdcd52d4SBartosz Sobczak 	if (post_sq)
554*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
555*cdcd52d4SBartosz Sobczak 
556*cdcd52d4SBartosz Sobczak 	return 0;
557*cdcd52d4SBartosz Sobczak }
558*cdcd52d4SBartosz Sobczak 
559*cdcd52d4SBartosz Sobczak /**
560*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_modify - modify qp cqp wqe
561*cdcd52d4SBartosz Sobczak  * @qp: sc qp
562*cdcd52d4SBartosz Sobczak  * @info: modify qp info
563*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
564*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
565*cdcd52d4SBartosz Sobczak  */
566*cdcd52d4SBartosz Sobczak int
567*cdcd52d4SBartosz Sobczak irdma_sc_qp_modify(struct irdma_sc_qp *qp, struct irdma_modify_qp_info *info,
568*cdcd52d4SBartosz Sobczak 		   u64 scratch, bool post_sq)
569*cdcd52d4SBartosz Sobczak {
570*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
571*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
572*cdcd52d4SBartosz Sobczak 	u64 hdr;
573*cdcd52d4SBartosz Sobczak 	u8 term_actions = 0;
574*cdcd52d4SBartosz Sobczak 	u8 term_len = 0;
575*cdcd52d4SBartosz Sobczak 
576*cdcd52d4SBartosz Sobczak 	cqp = qp->dev->cqp;
577*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
578*cdcd52d4SBartosz Sobczak 	if (!wqe)
579*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
580*cdcd52d4SBartosz Sobczak 
581*cdcd52d4SBartosz Sobczak 	if (info->next_iwarp_state == IRDMA_QP_STATE_TERMINATE) {
582*cdcd52d4SBartosz Sobczak 		if (info->dont_send_fin)
583*cdcd52d4SBartosz Sobczak 			term_actions += IRDMAQP_TERM_SEND_TERM_ONLY;
584*cdcd52d4SBartosz Sobczak 		if (info->dont_send_term)
585*cdcd52d4SBartosz Sobczak 			term_actions += IRDMAQP_TERM_SEND_FIN_ONLY;
586*cdcd52d4SBartosz Sobczak 		if (term_actions == IRDMAQP_TERM_SEND_TERM_AND_FIN ||
587*cdcd52d4SBartosz Sobczak 		    term_actions == IRDMAQP_TERM_SEND_TERM_ONLY)
588*cdcd52d4SBartosz Sobczak 			term_len = info->termlen;
589*cdcd52d4SBartosz Sobczak 	}
590*cdcd52d4SBartosz Sobczak 
591*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
592*cdcd52d4SBartosz Sobczak 		      LS_64(info->new_mss, IRDMA_CQPSQ_QP_NEWMSS) |
593*cdcd52d4SBartosz Sobczak 		      LS_64(term_len, IRDMA_CQPSQ_QP_TERMLEN));
594*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, qp->hw_host_ctx_pa);
595*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, qp->shadow_area_pa);
596*cdcd52d4SBartosz Sobczak 
597*cdcd52d4SBartosz Sobczak 	hdr = qp->qp_uk.qp_id |
598*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MODIFY_QP, IRDMA_CQPSQ_OPCODE) |
599*cdcd52d4SBartosz Sobczak 	    LS_64(info->ord_valid, IRDMA_CQPSQ_QP_ORDVALID) |
600*cdcd52d4SBartosz Sobczak 	    LS_64(info->tcp_ctx_valid, IRDMA_CQPSQ_QP_TOECTXVALID) |
601*cdcd52d4SBartosz Sobczak 	    LS_64(info->cached_var_valid, IRDMA_CQPSQ_QP_CACHEDVARVALID) |
602*cdcd52d4SBartosz Sobczak 	    LS_64(qp->virtual_map, IRDMA_CQPSQ_QP_VQ) |
603*cdcd52d4SBartosz Sobczak 	    LS_64(info->force_lpb, IRDMA_CQPSQ_QP_FORCELOOPBACK) |
604*cdcd52d4SBartosz Sobczak 	    LS_64(info->cq_num_valid, IRDMA_CQPSQ_QP_CQNUMVALID) |
605*cdcd52d4SBartosz Sobczak 	    LS_64(info->mac_valid, IRDMA_CQPSQ_QP_MACVALID) |
606*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.qp_type, IRDMA_CQPSQ_QP_QPTYPE) |
607*cdcd52d4SBartosz Sobczak 	    LS_64(info->mss_change, IRDMA_CQPSQ_QP_MSSCHANGE) |
608*cdcd52d4SBartosz Sobczak 	    LS_64(info->remove_hash_idx, IRDMA_CQPSQ_QP_REMOVEHASHENTRY) |
609*cdcd52d4SBartosz Sobczak 	    LS_64(term_actions, IRDMA_CQPSQ_QP_TERMACT) |
610*cdcd52d4SBartosz Sobczak 	    LS_64(info->reset_tcp_conn, IRDMA_CQPSQ_QP_RESETCON) |
611*cdcd52d4SBartosz Sobczak 	    LS_64(info->arp_cache_idx_valid, IRDMA_CQPSQ_QP_ARPTABIDXVALID) |
612*cdcd52d4SBartosz Sobczak 	    LS_64(info->next_iwarp_state, IRDMA_CQPSQ_QP_NEXTIWSTATE) |
613*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
614*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
615*cdcd52d4SBartosz Sobczak 
616*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
617*cdcd52d4SBartosz Sobczak 
618*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "QP_MODIFY WQE", wqe,
619*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
620*cdcd52d4SBartosz Sobczak 	if (post_sq)
621*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
622*cdcd52d4SBartosz Sobczak 
623*cdcd52d4SBartosz Sobczak 	return 0;
624*cdcd52d4SBartosz Sobczak }
625*cdcd52d4SBartosz Sobczak 
626*cdcd52d4SBartosz Sobczak /**
627*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_destroy - cqp destroy qp
628*cdcd52d4SBartosz Sobczak  * @qp: sc qp
629*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
630*cdcd52d4SBartosz Sobczak  * @remove_hash_idx: flag if to remove hash idx
631*cdcd52d4SBartosz Sobczak  * @ignore_mw_bnd: memory window bind flag
632*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
633*cdcd52d4SBartosz Sobczak  */
634*cdcd52d4SBartosz Sobczak int
635*cdcd52d4SBartosz Sobczak irdma_sc_qp_destroy(struct irdma_sc_qp *qp, u64 scratch,
636*cdcd52d4SBartosz Sobczak 		    bool remove_hash_idx, bool ignore_mw_bnd, bool post_sq)
637*cdcd52d4SBartosz Sobczak {
638*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
639*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
640*cdcd52d4SBartosz Sobczak 	u64 hdr;
641*cdcd52d4SBartosz Sobczak 
642*cdcd52d4SBartosz Sobczak 	cqp = qp->dev->cqp;
643*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
644*cdcd52d4SBartosz Sobczak 	if (!wqe)
645*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
646*cdcd52d4SBartosz Sobczak 
647*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, qp->hw_host_ctx_pa);
648*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, qp->shadow_area_pa);
649*cdcd52d4SBartosz Sobczak 
650*cdcd52d4SBartosz Sobczak 	hdr = qp->qp_uk.qp_id |
651*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_DESTROY_QP, IRDMA_CQPSQ_OPCODE) |
652*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.qp_type, IRDMA_CQPSQ_QP_QPTYPE) |
653*cdcd52d4SBartosz Sobczak 	    LS_64(ignore_mw_bnd, IRDMA_CQPSQ_QP_IGNOREMWBOUND) |
654*cdcd52d4SBartosz Sobczak 	    LS_64(remove_hash_idx, IRDMA_CQPSQ_QP_REMOVEHASHENTRY) |
655*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
656*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
657*cdcd52d4SBartosz Sobczak 
658*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
659*cdcd52d4SBartosz Sobczak 
660*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "QP_DESTROY WQE", wqe,
661*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
662*cdcd52d4SBartosz Sobczak 	if (post_sq)
663*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
664*cdcd52d4SBartosz Sobczak 
665*cdcd52d4SBartosz Sobczak 	return 0;
666*cdcd52d4SBartosz Sobczak }
667*cdcd52d4SBartosz Sobczak 
668*cdcd52d4SBartosz Sobczak /**
669*cdcd52d4SBartosz Sobczak  * irdma_sc_get_encoded_ird_size -
670*cdcd52d4SBartosz Sobczak  * @ird_size: IRD size
671*cdcd52d4SBartosz Sobczak  * The ird from the connection is rounded to a supported HW setting and then encoded
672*cdcd52d4SBartosz Sobczak  * for ird_size field of qp_ctx. Consumers are expected to provide valid ird size based
673*cdcd52d4SBartosz Sobczak  * on hardware attributes. IRD size defaults to a value of 4 in case of invalid input
674*cdcd52d4SBartosz Sobczak  */
675*cdcd52d4SBartosz Sobczak static u8 irdma_sc_get_encoded_ird_size(u16 ird_size) {
676*cdcd52d4SBartosz Sobczak 	switch (ird_size ?
677*cdcd52d4SBartosz Sobczak 		roundup_pow_of_two(2 * ird_size) : 4) {
678*cdcd52d4SBartosz Sobczak 	case 256:
679*cdcd52d4SBartosz Sobczak 		return IRDMA_IRD_HW_SIZE_256;
680*cdcd52d4SBartosz Sobczak 	case 128:
681*cdcd52d4SBartosz Sobczak 		return IRDMA_IRD_HW_SIZE_128;
682*cdcd52d4SBartosz Sobczak 	case 64:
683*cdcd52d4SBartosz Sobczak 	case 32:
684*cdcd52d4SBartosz Sobczak 		return IRDMA_IRD_HW_SIZE_64;
685*cdcd52d4SBartosz Sobczak 	case 16:
686*cdcd52d4SBartosz Sobczak 	case 8:
687*cdcd52d4SBartosz Sobczak 		return IRDMA_IRD_HW_SIZE_16;
688*cdcd52d4SBartosz Sobczak 	case 4:
689*cdcd52d4SBartosz Sobczak 	default:
690*cdcd52d4SBartosz Sobczak 		break;
691*cdcd52d4SBartosz Sobczak 	}
692*cdcd52d4SBartosz Sobczak 
693*cdcd52d4SBartosz Sobczak 	return IRDMA_IRD_HW_SIZE_4;
694*cdcd52d4SBartosz Sobczak }
695*cdcd52d4SBartosz Sobczak 
696*cdcd52d4SBartosz Sobczak /**
697*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_setctx_roce - set qp's context
698*cdcd52d4SBartosz Sobczak  * @qp: sc qp
699*cdcd52d4SBartosz Sobczak  * @qp_ctx: context ptr
700*cdcd52d4SBartosz Sobczak  * @info: ctx info
701*cdcd52d4SBartosz Sobczak  */
702*cdcd52d4SBartosz Sobczak void
703*cdcd52d4SBartosz Sobczak irdma_sc_qp_setctx_roce(struct irdma_sc_qp *qp, __le64 * qp_ctx,
704*cdcd52d4SBartosz Sobczak 			struct irdma_qp_host_ctx_info *info)
705*cdcd52d4SBartosz Sobczak {
706*cdcd52d4SBartosz Sobczak 	struct irdma_roce_offload_info *roce_info;
707*cdcd52d4SBartosz Sobczak 	struct irdma_udp_offload_info *udp;
708*cdcd52d4SBartosz Sobczak 	u8 push_mode_en;
709*cdcd52d4SBartosz Sobczak 	u32 push_idx;
710*cdcd52d4SBartosz Sobczak 	u64 mac;
711*cdcd52d4SBartosz Sobczak 
712*cdcd52d4SBartosz Sobczak 	roce_info = info->roce_info;
713*cdcd52d4SBartosz Sobczak 	udp = info->udp_info;
714*cdcd52d4SBartosz Sobczak 
715*cdcd52d4SBartosz Sobczak 	mac = LS_64_1(roce_info->mac_addr[5], 16) |
716*cdcd52d4SBartosz Sobczak 	    LS_64_1(roce_info->mac_addr[4], 24) |
717*cdcd52d4SBartosz Sobczak 	    LS_64_1(roce_info->mac_addr[3], 32) |
718*cdcd52d4SBartosz Sobczak 	    LS_64_1(roce_info->mac_addr[2], 40) |
719*cdcd52d4SBartosz Sobczak 	    LS_64_1(roce_info->mac_addr[1], 48) |
720*cdcd52d4SBartosz Sobczak 	    LS_64_1(roce_info->mac_addr[0], 56);
721*cdcd52d4SBartosz Sobczak 
722*cdcd52d4SBartosz Sobczak 	qp->user_pri = info->user_pri;
723*cdcd52d4SBartosz Sobczak 	if (qp->push_idx == IRDMA_INVALID_PUSH_PAGE_INDEX) {
724*cdcd52d4SBartosz Sobczak 		push_mode_en = 0;
725*cdcd52d4SBartosz Sobczak 		push_idx = 0;
726*cdcd52d4SBartosz Sobczak 	} else {
727*cdcd52d4SBartosz Sobczak 		push_mode_en = 1;
728*cdcd52d4SBartosz Sobczak 		push_idx = qp->push_idx;
729*cdcd52d4SBartosz Sobczak 	}
730*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_0,
731*cdcd52d4SBartosz Sobczak 		      LS_64(qp->qp_uk.rq_wqe_size, IRDMAQPC_RQWQESIZE) |
732*cdcd52d4SBartosz Sobczak 		      LS_64(qp->rcv_tph_en, IRDMAQPC_RCVTPHEN) |
733*cdcd52d4SBartosz Sobczak 		      LS_64(qp->xmit_tph_en, IRDMAQPC_XMITTPHEN) |
734*cdcd52d4SBartosz Sobczak 		      LS_64(qp->rq_tph_en, IRDMAQPC_RQTPHEN) |
735*cdcd52d4SBartosz Sobczak 		      LS_64(qp->sq_tph_en, IRDMAQPC_SQTPHEN) |
736*cdcd52d4SBartosz Sobczak 		      LS_64(push_idx, IRDMAQPC_PPIDX) |
737*cdcd52d4SBartosz Sobczak 		      LS_64(push_mode_en, IRDMAQPC_PMENA) |
738*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->pd_id >> 16, IRDMAQPC_PDIDXHI) |
739*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->dctcp_en, IRDMAQPC_DC_TCP_EN) |
740*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->err_rq_idx_valid, IRDMAQPC_ERR_RQ_IDX_VALID) |
741*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->is_qp1, IRDMAQPC_ISQP1) |
742*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->roce_tver, IRDMAQPC_ROCE_TVER) |
743*cdcd52d4SBartosz Sobczak 		      LS_64(udp->ipv4, IRDMAQPC_IPV4) |
744*cdcd52d4SBartosz Sobczak 		      LS_64(udp->insert_vlan_tag, IRDMAQPC_INSERTVLANTAG));
745*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_8, qp->sq_pa);
746*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_16, qp->rq_pa);
747*cdcd52d4SBartosz Sobczak 	if (roce_info->dcqcn_en || roce_info->dctcp_en) {
748*cdcd52d4SBartosz Sobczak 		udp->tos &= ~ECN_CODE_PT_MASK;
749*cdcd52d4SBartosz Sobczak 		udp->tos |= ECN_CODE_PT_VAL;
750*cdcd52d4SBartosz Sobczak 	}
751*cdcd52d4SBartosz Sobczak 
752*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_24,
753*cdcd52d4SBartosz Sobczak 		      LS_64(qp->hw_rq_size, IRDMAQPC_RQSIZE) |
754*cdcd52d4SBartosz Sobczak 		      LS_64(qp->hw_sq_size, IRDMAQPC_SQSIZE) |
755*cdcd52d4SBartosz Sobczak 		      LS_64(udp->ttl, IRDMAQPC_TTL) | LS_64(udp->tos, IRDMAQPC_TOS) |
756*cdcd52d4SBartosz Sobczak 		      LS_64(udp->src_port, IRDMAQPC_SRCPORTNUM) |
757*cdcd52d4SBartosz Sobczak 		      LS_64(udp->dst_port, IRDMAQPC_DESTPORTNUM));
758*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_32,
759*cdcd52d4SBartosz Sobczak 		      LS_64(udp->dest_ip_addr[2], IRDMAQPC_DESTIPADDR2) |
760*cdcd52d4SBartosz Sobczak 		      LS_64(udp->dest_ip_addr[3], IRDMAQPC_DESTIPADDR3));
761*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_40,
762*cdcd52d4SBartosz Sobczak 		      LS_64(udp->dest_ip_addr[0], IRDMAQPC_DESTIPADDR0) |
763*cdcd52d4SBartosz Sobczak 		      LS_64(udp->dest_ip_addr[1], IRDMAQPC_DESTIPADDR1));
764*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_48,
765*cdcd52d4SBartosz Sobczak 		      LS_64(udp->snd_mss, IRDMAQPC_SNDMSS) |
766*cdcd52d4SBartosz Sobczak 		      LS_64(udp->vlan_tag, IRDMAQPC_VLANTAG) |
767*cdcd52d4SBartosz Sobczak 		      LS_64(udp->arp_idx, IRDMAQPC_ARPIDX));
768*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_56,
769*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->p_key, IRDMAQPC_PKEY) |
770*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->pd_id, IRDMAQPC_PDIDX) |
771*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->ack_credits, IRDMAQPC_ACKCREDITS) |
772*cdcd52d4SBartosz Sobczak 		      LS_64(udp->flow_label, IRDMAQPC_FLOWLABEL));
773*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_64,
774*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->qkey, IRDMAQPC_QKEY) |
775*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->dest_qp, IRDMAQPC_DESTQP));
776*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_80,
777*cdcd52d4SBartosz Sobczak 		      LS_64(udp->psn_nxt, IRDMAQPC_PSNNXT) |
778*cdcd52d4SBartosz Sobczak 		      LS_64(udp->lsn, IRDMAQPC_LSN));
779*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_88, LS_64(udp->epsn, IRDMAQPC_EPSN));
780*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_96,
781*cdcd52d4SBartosz Sobczak 		      LS_64(udp->psn_max, IRDMAQPC_PSNMAX) |
782*cdcd52d4SBartosz Sobczak 		      LS_64(udp->psn_una, IRDMAQPC_PSNUNA));
783*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_112,
784*cdcd52d4SBartosz Sobczak 		      LS_64(udp->cwnd, IRDMAQPC_CWNDROCE));
785*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_128,
786*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->err_rq_idx, IRDMAQPC_ERR_RQ_IDX) |
787*cdcd52d4SBartosz Sobczak 		      LS_64(udp->rnr_nak_thresh, IRDMAQPC_RNRNAK_THRESH) |
788*cdcd52d4SBartosz Sobczak 		      LS_64(udp->rexmit_thresh, IRDMAQPC_REXMIT_THRESH) |
789*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->rtomin, IRDMAQPC_RTOMIN));
790*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_136,
791*cdcd52d4SBartosz Sobczak 		      LS_64(info->send_cq_num, IRDMAQPC_TXCQNUM) |
792*cdcd52d4SBartosz Sobczak 		      LS_64(info->rcv_cq_num, IRDMAQPC_RXCQNUM));
793*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_144,
794*cdcd52d4SBartosz Sobczak 		      LS_64(info->stats_idx, IRDMAQPC_STAT_INDEX));
795*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_152, mac);
796*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_160,
797*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->ord_size, IRDMAQPC_ORDSIZE) |
798*cdcd52d4SBartosz Sobczak 		      LS_64(irdma_sc_get_encoded_ird_size(roce_info->ird_size), IRDMAQPC_IRDSIZE) |
799*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->wr_rdresp_en, IRDMAQPC_WRRDRSPOK) |
800*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->rd_en, IRDMAQPC_RDOK) |
801*cdcd52d4SBartosz Sobczak 		      LS_64(info->stats_idx_valid, IRDMAQPC_USESTATSINSTANCE) |
802*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->bind_en, IRDMAQPC_BINDEN) |
803*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->fast_reg_en, IRDMAQPC_FASTREGEN) |
804*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->dcqcn_en, IRDMAQPC_DCQCNENABLE) |
805*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->rcv_no_icrc, IRDMAQPC_RCVNOICRC) |
806*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->fw_cc_enable, IRDMAQPC_FW_CC_ENABLE) |
807*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->udprivcq_en, IRDMAQPC_UDPRIVCQENABLE) |
808*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->priv_mode_en, IRDMAQPC_PRIVEN) |
809*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->timely_en, IRDMAQPC_TIMELYENABLE));
810*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_168,
811*cdcd52d4SBartosz Sobczak 		      LS_64(info->qp_compl_ctx, IRDMAQPC_QPCOMPCTX));
812*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_176,
813*cdcd52d4SBartosz Sobczak 		      LS_64(qp->sq_tph_val, IRDMAQPC_SQTPHVAL) |
814*cdcd52d4SBartosz Sobczak 		      LS_64(qp->rq_tph_val, IRDMAQPC_RQTPHVAL) |
815*cdcd52d4SBartosz Sobczak 		      LS_64(qp->qs_handle, IRDMAQPC_QSHANDLE));
816*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_184,
817*cdcd52d4SBartosz Sobczak 		      LS_64(udp->local_ipaddr[3], IRDMAQPC_LOCAL_IPADDR3) |
818*cdcd52d4SBartosz Sobczak 		      LS_64(udp->local_ipaddr[2], IRDMAQPC_LOCAL_IPADDR2));
819*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_192,
820*cdcd52d4SBartosz Sobczak 		      LS_64(udp->local_ipaddr[1], IRDMAQPC_LOCAL_IPADDR1) |
821*cdcd52d4SBartosz Sobczak 		      LS_64(udp->local_ipaddr[0], IRDMAQPC_LOCAL_IPADDR0));
822*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_200,
823*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->t_high, IRDMAQPC_THIGH) |
824*cdcd52d4SBartosz Sobczak 		      LS_64(roce_info->t_low, IRDMAQPC_TLOW));
825*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_208,
826*cdcd52d4SBartosz Sobczak 		      LS_64(info->rem_endpoint_idx, IRDMAQPC_REMENDPOINTIDX));
827*cdcd52d4SBartosz Sobczak 
828*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_WQE, "QP_HOST CTX WQE", qp_ctx,
829*cdcd52d4SBartosz Sobczak 			IRDMA_QP_CTX_SIZE);
830*cdcd52d4SBartosz Sobczak }
831*cdcd52d4SBartosz Sobczak 
832*cdcd52d4SBartosz Sobczak /*
833*cdcd52d4SBartosz Sobczak  * irdma_sc_alloc_local_mac_entry - allocate a mac entry @cqp: struct for cqp hw @scratch: u64 saved to be used during
834*cdcd52d4SBartosz Sobczak  * cqp completion @post_sq: flag for cqp db to ring
835*cdcd52d4SBartosz Sobczak  */
836*cdcd52d4SBartosz Sobczak static int
837*cdcd52d4SBartosz Sobczak irdma_sc_alloc_local_mac_entry(struct irdma_sc_cqp *cqp, u64 scratch,
838*cdcd52d4SBartosz Sobczak 			       bool post_sq)
839*cdcd52d4SBartosz Sobczak {
840*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
841*cdcd52d4SBartosz Sobczak 	u64 hdr;
842*cdcd52d4SBartosz Sobczak 
843*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
844*cdcd52d4SBartosz Sobczak 	if (!wqe)
845*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
846*cdcd52d4SBartosz Sobczak 
847*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_ALLOCATE_LOC_MAC_TABLE_ENTRY,
848*cdcd52d4SBartosz Sobczak 		    IRDMA_CQPSQ_OPCODE) |
849*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
850*cdcd52d4SBartosz Sobczak 
851*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
852*cdcd52d4SBartosz Sobczak 
853*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
854*cdcd52d4SBartosz Sobczak 
855*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "ALLOCATE_LOCAL_MAC WQE",
856*cdcd52d4SBartosz Sobczak 			wqe, IRDMA_CQP_WQE_SIZE * 8);
857*cdcd52d4SBartosz Sobczak 
858*cdcd52d4SBartosz Sobczak 	if (post_sq)
859*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
860*cdcd52d4SBartosz Sobczak 	return 0;
861*cdcd52d4SBartosz Sobczak }
862*cdcd52d4SBartosz Sobczak 
863*cdcd52d4SBartosz Sobczak /**
864*cdcd52d4SBartosz Sobczak  * irdma_sc_add_local_mac_entry - add mac enry
865*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
866*cdcd52d4SBartosz Sobczak  * @info:mac addr info
867*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
868*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
869*cdcd52d4SBartosz Sobczak  */
870*cdcd52d4SBartosz Sobczak static int
871*cdcd52d4SBartosz Sobczak irdma_sc_add_local_mac_entry(struct irdma_sc_cqp *cqp,
872*cdcd52d4SBartosz Sobczak 			     struct irdma_local_mac_entry_info *info,
873*cdcd52d4SBartosz Sobczak 			     u64 scratch, bool post_sq)
874*cdcd52d4SBartosz Sobczak {
875*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
876*cdcd52d4SBartosz Sobczak 	u64 temp, header;
877*cdcd52d4SBartosz Sobczak 
878*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
879*cdcd52d4SBartosz Sobczak 	if (!wqe)
880*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
881*cdcd52d4SBartosz Sobczak 	temp = info->mac_addr[5] | LS_64_1(info->mac_addr[4], 8) |
882*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->mac_addr[3], 16) | LS_64_1(info->mac_addr[2], 24) |
883*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->mac_addr[1], 32) | LS_64_1(info->mac_addr[0], 40);
884*cdcd52d4SBartosz Sobczak 
885*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, temp);
886*cdcd52d4SBartosz Sobczak 
887*cdcd52d4SBartosz Sobczak 	header = LS_64(info->entry_idx, IRDMA_CQPSQ_MLM_TABLEIDX) |
888*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_LOC_MAC_TABLE, IRDMA_CQPSQ_OPCODE) |
889*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
890*cdcd52d4SBartosz Sobczak 
891*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
892*cdcd52d4SBartosz Sobczak 
893*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, header);
894*cdcd52d4SBartosz Sobczak 
895*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "ADD_LOCAL_MAC WQE", wqe,
896*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
897*cdcd52d4SBartosz Sobczak 
898*cdcd52d4SBartosz Sobczak 	if (post_sq)
899*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
900*cdcd52d4SBartosz Sobczak 	return 0;
901*cdcd52d4SBartosz Sobczak }
902*cdcd52d4SBartosz Sobczak 
903*cdcd52d4SBartosz Sobczak /**
904*cdcd52d4SBartosz Sobczak  * irdma_sc_del_local_mac_entry - cqp wqe to dele local mac
905*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
906*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
907*cdcd52d4SBartosz Sobczak  * @entry_idx: index of mac entry
908*cdcd52d4SBartosz Sobczak  * @ignore_ref_count: to force mac adde delete
909*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
910*cdcd52d4SBartosz Sobczak  */
911*cdcd52d4SBartosz Sobczak static int
912*cdcd52d4SBartosz Sobczak irdma_sc_del_local_mac_entry(struct irdma_sc_cqp *cqp, u64 scratch,
913*cdcd52d4SBartosz Sobczak 			     u16 entry_idx, u8 ignore_ref_count,
914*cdcd52d4SBartosz Sobczak 			     bool post_sq)
915*cdcd52d4SBartosz Sobczak {
916*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
917*cdcd52d4SBartosz Sobczak 	u64 header;
918*cdcd52d4SBartosz Sobczak 
919*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
920*cdcd52d4SBartosz Sobczak 	if (!wqe)
921*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
922*cdcd52d4SBartosz Sobczak 	header = LS_64(entry_idx, IRDMA_CQPSQ_MLM_TABLEIDX) |
923*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_LOC_MAC_TABLE, IRDMA_CQPSQ_OPCODE) |
924*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMA_CQPSQ_MLM_FREEENTRY) |
925*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID) |
926*cdcd52d4SBartosz Sobczak 	    LS_64(ignore_ref_count, IRDMA_CQPSQ_MLM_IGNORE_REF_CNT);
927*cdcd52d4SBartosz Sobczak 
928*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
929*cdcd52d4SBartosz Sobczak 
930*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, header);
931*cdcd52d4SBartosz Sobczak 
932*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "DEL_LOCAL_MAC_IPADDR WQE",
933*cdcd52d4SBartosz Sobczak 			wqe, IRDMA_CQP_WQE_SIZE * 8);
934*cdcd52d4SBartosz Sobczak 
935*cdcd52d4SBartosz Sobczak 	if (post_sq)
936*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
937*cdcd52d4SBartosz Sobczak 	return 0;
938*cdcd52d4SBartosz Sobczak }
939*cdcd52d4SBartosz Sobczak 
940*cdcd52d4SBartosz Sobczak /**
941*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_setctx - set qp's context
942*cdcd52d4SBartosz Sobczak  * @qp: sc qp
943*cdcd52d4SBartosz Sobczak  * @qp_ctx: context ptr
944*cdcd52d4SBartosz Sobczak  * @info: ctx info
945*cdcd52d4SBartosz Sobczak  */
946*cdcd52d4SBartosz Sobczak void
947*cdcd52d4SBartosz Sobczak irdma_sc_qp_setctx(struct irdma_sc_qp *qp, __le64 * qp_ctx,
948*cdcd52d4SBartosz Sobczak 		   struct irdma_qp_host_ctx_info *info)
949*cdcd52d4SBartosz Sobczak {
950*cdcd52d4SBartosz Sobczak 	struct irdma_iwarp_offload_info *iw;
951*cdcd52d4SBartosz Sobczak 	struct irdma_tcp_offload_info *tcp;
952*cdcd52d4SBartosz Sobczak 	struct irdma_sc_dev *dev;
953*cdcd52d4SBartosz Sobczak 	u8 push_mode_en;
954*cdcd52d4SBartosz Sobczak 	u32 push_idx;
955*cdcd52d4SBartosz Sobczak 	u64 qw0, qw3, qw7 = 0, qw16 = 0;
956*cdcd52d4SBartosz Sobczak 	u64 mac = 0;
957*cdcd52d4SBartosz Sobczak 
958*cdcd52d4SBartosz Sobczak 	iw = info->iwarp_info;
959*cdcd52d4SBartosz Sobczak 	tcp = info->tcp_info;
960*cdcd52d4SBartosz Sobczak 	dev = qp->dev;
961*cdcd52d4SBartosz Sobczak 	if (iw->rcv_mark_en) {
962*cdcd52d4SBartosz Sobczak 		qp->pfpdu.marker_len = 4;
963*cdcd52d4SBartosz Sobczak 		qp->pfpdu.rcv_start_seq = tcp->rcv_nxt;
964*cdcd52d4SBartosz Sobczak 	}
965*cdcd52d4SBartosz Sobczak 	qp->user_pri = info->user_pri;
966*cdcd52d4SBartosz Sobczak 	if (qp->push_idx == IRDMA_INVALID_PUSH_PAGE_INDEX) {
967*cdcd52d4SBartosz Sobczak 		push_mode_en = 0;
968*cdcd52d4SBartosz Sobczak 		push_idx = 0;
969*cdcd52d4SBartosz Sobczak 	} else {
970*cdcd52d4SBartosz Sobczak 		push_mode_en = 1;
971*cdcd52d4SBartosz Sobczak 		push_idx = qp->push_idx;
972*cdcd52d4SBartosz Sobczak 	}
973*cdcd52d4SBartosz Sobczak 	qw0 = LS_64(qp->qp_uk.rq_wqe_size, IRDMAQPC_RQWQESIZE) |
974*cdcd52d4SBartosz Sobczak 	    LS_64(qp->rcv_tph_en, IRDMAQPC_RCVTPHEN) |
975*cdcd52d4SBartosz Sobczak 	    LS_64(qp->xmit_tph_en, IRDMAQPC_XMITTPHEN) |
976*cdcd52d4SBartosz Sobczak 	    LS_64(qp->rq_tph_en, IRDMAQPC_RQTPHEN) |
977*cdcd52d4SBartosz Sobczak 	    LS_64(qp->sq_tph_en, IRDMAQPC_SQTPHEN) |
978*cdcd52d4SBartosz Sobczak 	    LS_64(push_idx, IRDMAQPC_PPIDX) |
979*cdcd52d4SBartosz Sobczak 	    LS_64(push_mode_en, IRDMAQPC_PMENA);
980*cdcd52d4SBartosz Sobczak 
981*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_8, qp->sq_pa);
982*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_16, qp->rq_pa);
983*cdcd52d4SBartosz Sobczak 
984*cdcd52d4SBartosz Sobczak 	qw3 = LS_64(qp->hw_rq_size, IRDMAQPC_RQSIZE) |
985*cdcd52d4SBartosz Sobczak 	    LS_64(qp->hw_sq_size, IRDMAQPC_SQSIZE);
986*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
987*cdcd52d4SBartosz Sobczak 		qw3 |= LS_64(qp->src_mac_addr_idx, IRDMAQPC_GEN1_SRCMACADDRIDX);
988*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_136,
989*cdcd52d4SBartosz Sobczak 		      LS_64(info->send_cq_num, IRDMAQPC_TXCQNUM) |
990*cdcd52d4SBartosz Sobczak 		      LS_64(info->rcv_cq_num, IRDMAQPC_RXCQNUM));
991*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_168,
992*cdcd52d4SBartosz Sobczak 		      LS_64(info->qp_compl_ctx, IRDMAQPC_QPCOMPCTX));
993*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_176,
994*cdcd52d4SBartosz Sobczak 		      LS_64(qp->sq_tph_val, IRDMAQPC_SQTPHVAL) |
995*cdcd52d4SBartosz Sobczak 		      LS_64(qp->rq_tph_val, IRDMAQPC_RQTPHVAL) |
996*cdcd52d4SBartosz Sobczak 		      LS_64(qp->qs_handle, IRDMAQPC_QSHANDLE) |
997*cdcd52d4SBartosz Sobczak 		      LS_64(qp->ieq_qp, IRDMAQPC_EXCEPTION_LAN_QUEUE));
998*cdcd52d4SBartosz Sobczak 	if (info->iwarp_info_valid) {
999*cdcd52d4SBartosz Sobczak 		qw0 |= LS_64(iw->ddp_ver, IRDMAQPC_DDP_VER) |
1000*cdcd52d4SBartosz Sobczak 		    LS_64(iw->rdmap_ver, IRDMAQPC_RDMAP_VER) |
1001*cdcd52d4SBartosz Sobczak 		    LS_64(iw->dctcp_en, IRDMAQPC_DC_TCP_EN) |
1002*cdcd52d4SBartosz Sobczak 		    LS_64(iw->ecn_en, IRDMAQPC_ECN_EN) |
1003*cdcd52d4SBartosz Sobczak 		    LS_64(iw->ib_rd_en, IRDMAQPC_IBRDENABLE) |
1004*cdcd52d4SBartosz Sobczak 		    LS_64(iw->pd_id >> 16, IRDMAQPC_PDIDXHI) |
1005*cdcd52d4SBartosz Sobczak 		    LS_64(iw->err_rq_idx_valid, IRDMAQPC_ERR_RQ_IDX_VALID);
1006*cdcd52d4SBartosz Sobczak 		qw7 |= LS_64(iw->pd_id, IRDMAQPC_PDIDX);
1007*cdcd52d4SBartosz Sobczak 		qw16 |= LS_64(iw->err_rq_idx, IRDMAQPC_ERR_RQ_IDX) |
1008*cdcd52d4SBartosz Sobczak 		    LS_64(iw->rtomin, IRDMAQPC_RTOMIN);
1009*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_144,
1010*cdcd52d4SBartosz Sobczak 			      LS_64(qp->q2_pa >> 8, IRDMAQPC_Q2ADDR) |
1011*cdcd52d4SBartosz Sobczak 			      LS_64(info->stats_idx, IRDMAQPC_STAT_INDEX));
1012*cdcd52d4SBartosz Sobczak 
1013*cdcd52d4SBartosz Sobczak 		if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
1014*cdcd52d4SBartosz Sobczak 			mac = LS_64_1(iw->mac_addr[5], 16) |
1015*cdcd52d4SBartosz Sobczak 			    LS_64_1(iw->mac_addr[4], 24) |
1016*cdcd52d4SBartosz Sobczak 			    LS_64_1(iw->mac_addr[3], 32) |
1017*cdcd52d4SBartosz Sobczak 			    LS_64_1(iw->mac_addr[2], 40) |
1018*cdcd52d4SBartosz Sobczak 			    LS_64_1(iw->mac_addr[1], 48) |
1019*cdcd52d4SBartosz Sobczak 			    LS_64_1(iw->mac_addr[0], 56);
1020*cdcd52d4SBartosz Sobczak 		}
1021*cdcd52d4SBartosz Sobczak 
1022*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_152,
1023*cdcd52d4SBartosz Sobczak 			      mac | LS_64(iw->last_byte_sent, IRDMAQPC_LASTBYTESENT));
1024*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_160,
1025*cdcd52d4SBartosz Sobczak 			      LS_64(iw->ord_size, IRDMAQPC_ORDSIZE) |
1026*cdcd52d4SBartosz Sobczak 			      LS_64(irdma_sc_get_encoded_ird_size(iw->ird_size), IRDMAQPC_IRDSIZE) |
1027*cdcd52d4SBartosz Sobczak 			      LS_64(iw->wr_rdresp_en, IRDMAQPC_WRRDRSPOK) |
1028*cdcd52d4SBartosz Sobczak 			      LS_64(iw->rd_en, IRDMAQPC_RDOK) |
1029*cdcd52d4SBartosz Sobczak 			      LS_64(iw->snd_mark_en, IRDMAQPC_SNDMARKERS) |
1030*cdcd52d4SBartosz Sobczak 			      LS_64(iw->bind_en, IRDMAQPC_BINDEN) |
1031*cdcd52d4SBartosz Sobczak 			      LS_64(iw->fast_reg_en, IRDMAQPC_FASTREGEN) |
1032*cdcd52d4SBartosz Sobczak 			      LS_64(iw->priv_mode_en, IRDMAQPC_PRIVEN) |
1033*cdcd52d4SBartosz Sobczak 			      LS_64(info->stats_idx_valid, IRDMAQPC_USESTATSINSTANCE) |
1034*cdcd52d4SBartosz Sobczak 			      LS_64(1, IRDMAQPC_IWARPMODE) |
1035*cdcd52d4SBartosz Sobczak 			      LS_64(iw->rcv_mark_en, IRDMAQPC_RCVMARKERS) |
1036*cdcd52d4SBartosz Sobczak 			      LS_64(iw->align_hdrs, IRDMAQPC_ALIGNHDRS) |
1037*cdcd52d4SBartosz Sobczak 			      LS_64(iw->rcv_no_mpa_crc, IRDMAQPC_RCVNOMPACRC) |
1038*cdcd52d4SBartosz Sobczak 			      LS_64(iw->rcv_mark_offset, IRDMAQPC_RCVMARKOFFSET) |
1039*cdcd52d4SBartosz Sobczak 			      LS_64(iw->snd_mark_offset, IRDMAQPC_SNDMARKOFFSET) |
1040*cdcd52d4SBartosz Sobczak 			      LS_64(iw->timely_en, IRDMAQPC_TIMELYENABLE));
1041*cdcd52d4SBartosz Sobczak 	}
1042*cdcd52d4SBartosz Sobczak 	if (info->tcp_info_valid) {
1043*cdcd52d4SBartosz Sobczak 		qw0 |= LS_64(tcp->ipv4, IRDMAQPC_IPV4) |
1044*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->no_nagle, IRDMAQPC_NONAGLE) |
1045*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->insert_vlan_tag, IRDMAQPC_INSERTVLANTAG) |
1046*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->time_stamp, IRDMAQPC_TIMESTAMP) |
1047*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->cwnd_inc_limit, IRDMAQPC_LIMIT) |
1048*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->drop_ooo_seg, IRDMAQPC_DROPOOOSEG) |
1049*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->dup_ack_thresh, IRDMAQPC_DUPACK_THRESH);
1050*cdcd52d4SBartosz Sobczak 
1051*cdcd52d4SBartosz Sobczak 		if (iw->ecn_en || iw->dctcp_en) {
1052*cdcd52d4SBartosz Sobczak 			tcp->tos &= ~ECN_CODE_PT_MASK;
1053*cdcd52d4SBartosz Sobczak 			tcp->tos |= ECN_CODE_PT_VAL;
1054*cdcd52d4SBartosz Sobczak 		}
1055*cdcd52d4SBartosz Sobczak 
1056*cdcd52d4SBartosz Sobczak 		qw3 |= LS_64(tcp->ttl, IRDMAQPC_TTL) |
1057*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->avoid_stretch_ack, IRDMAQPC_AVOIDSTRETCHACK) |
1058*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->tos, IRDMAQPC_TOS) |
1059*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->src_port, IRDMAQPC_SRCPORTNUM) |
1060*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->dst_port, IRDMAQPC_DESTPORTNUM);
1061*cdcd52d4SBartosz Sobczak 		if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) {
1062*cdcd52d4SBartosz Sobczak 			qw3 |= LS_64(tcp->src_mac_addr_idx,
1063*cdcd52d4SBartosz Sobczak 				     IRDMAQPC_GEN1_SRCMACADDRIDX);
1064*cdcd52d4SBartosz Sobczak 
1065*cdcd52d4SBartosz Sobczak 			qp->src_mac_addr_idx = tcp->src_mac_addr_idx;
1066*cdcd52d4SBartosz Sobczak 		}
1067*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_32,
1068*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->dest_ip_addr[2], IRDMAQPC_DESTIPADDR2) |
1069*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->dest_ip_addr[3], IRDMAQPC_DESTIPADDR3));
1070*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_40,
1071*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->dest_ip_addr[0], IRDMAQPC_DESTIPADDR0) |
1072*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->dest_ip_addr[1], IRDMAQPC_DESTIPADDR1));
1073*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_48,
1074*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_mss, IRDMAQPC_SNDMSS) |
1075*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->syn_rst_handling, IRDMAQPC_SYN_RST_HANDLING) |
1076*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->vlan_tag, IRDMAQPC_VLANTAG) |
1077*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->arp_idx, IRDMAQPC_ARPIDX));
1078*cdcd52d4SBartosz Sobczak 		qw7 |= LS_64(tcp->flow_label, IRDMAQPC_FLOWLABEL) |
1079*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->wscale, IRDMAQPC_WSCALE) |
1080*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->ignore_tcp_opt, IRDMAQPC_IGNORE_TCP_OPT) |
1081*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->ignore_tcp_uns_opt,
1082*cdcd52d4SBartosz Sobczak 			  IRDMAQPC_IGNORE_TCP_UNS_OPT) |
1083*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->tcp_state, IRDMAQPC_TCPSTATE) |
1084*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->rcv_wscale, IRDMAQPC_RCVSCALE) |
1085*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->snd_wscale, IRDMAQPC_SNDSCALE);
1086*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_72,
1087*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->time_stamp_recent, IRDMAQPC_TIMESTAMP_RECENT) |
1088*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->time_stamp_age, IRDMAQPC_TIMESTAMP_AGE));
1089*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_80,
1090*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_nxt, IRDMAQPC_SNDNXT) |
1091*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_wnd, IRDMAQPC_SNDWND));
1092*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_88,
1093*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->rcv_nxt, IRDMAQPC_RCVNXT) |
1094*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->rcv_wnd, IRDMAQPC_RCVWND));
1095*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_96,
1096*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_max, IRDMAQPC_SNDMAX) |
1097*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_una, IRDMAQPC_SNDUNA));
1098*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_104,
1099*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->srtt, IRDMAQPC_SRTT) |
1100*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->rtt_var, IRDMAQPC_RTTVAR));
1101*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_112,
1102*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->ss_thresh, IRDMAQPC_SSTHRESH) |
1103*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->cwnd, IRDMAQPC_CWND));
1104*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_120,
1105*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_wl1, IRDMAQPC_SNDWL1) |
1106*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->snd_wl2, IRDMAQPC_SNDWL2));
1107*cdcd52d4SBartosz Sobczak 		qw16 |= LS_64(tcp->max_snd_window, IRDMAQPC_MAXSNDWND) |
1108*cdcd52d4SBartosz Sobczak 		    LS_64(tcp->rexmit_thresh, IRDMAQPC_REXMIT_THRESH);
1109*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_184,
1110*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->local_ipaddr[3], IRDMAQPC_LOCAL_IPADDR3) |
1111*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->local_ipaddr[2], IRDMAQPC_LOCAL_IPADDR2));
1112*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_192,
1113*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->local_ipaddr[1], IRDMAQPC_LOCAL_IPADDR1) |
1114*cdcd52d4SBartosz Sobczak 			      LS_64(tcp->local_ipaddr[0], IRDMAQPC_LOCAL_IPADDR0));
1115*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_200,
1116*cdcd52d4SBartosz Sobczak 			      LS_64(iw->t_high, IRDMAQPC_THIGH) |
1117*cdcd52d4SBartosz Sobczak 			      LS_64(iw->t_low, IRDMAQPC_TLOW));
1118*cdcd52d4SBartosz Sobczak 		set_64bit_val(qp_ctx, IRDMA_BYTE_208,
1119*cdcd52d4SBartosz Sobczak 			      LS_64(info->rem_endpoint_idx, IRDMAQPC_REMENDPOINTIDX));
1120*cdcd52d4SBartosz Sobczak 	}
1121*cdcd52d4SBartosz Sobczak 
1122*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_0, qw0);
1123*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_24, qw3);
1124*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_56, qw7);
1125*cdcd52d4SBartosz Sobczak 	set_64bit_val(qp_ctx, IRDMA_BYTE_128, qw16);
1126*cdcd52d4SBartosz Sobczak 
1127*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_WQE, "QP_HOST CTX", qp_ctx,
1128*cdcd52d4SBartosz Sobczak 			IRDMA_QP_CTX_SIZE);
1129*cdcd52d4SBartosz Sobczak }
1130*cdcd52d4SBartosz Sobczak 
1131*cdcd52d4SBartosz Sobczak /**
1132*cdcd52d4SBartosz Sobczak  * irdma_sc_alloc_stag - mr stag alloc
1133*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
1134*cdcd52d4SBartosz Sobczak  * @info: stag info
1135*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
1136*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
1137*cdcd52d4SBartosz Sobczak  */
1138*cdcd52d4SBartosz Sobczak static int
1139*cdcd52d4SBartosz Sobczak irdma_sc_alloc_stag(struct irdma_sc_dev *dev,
1140*cdcd52d4SBartosz Sobczak 		    struct irdma_allocate_stag_info *info,
1141*cdcd52d4SBartosz Sobczak 		    u64 scratch, bool post_sq)
1142*cdcd52d4SBartosz Sobczak {
1143*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1144*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
1145*cdcd52d4SBartosz Sobczak 	u64 hdr;
1146*cdcd52d4SBartosz Sobczak 	enum irdma_page_size page_size;
1147*cdcd52d4SBartosz Sobczak 
1148*cdcd52d4SBartosz Sobczak 	if (info->page_size == 0x40000000)
1149*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_1G;
1150*cdcd52d4SBartosz Sobczak 	else if (info->page_size == 0x200000)
1151*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_2M;
1152*cdcd52d4SBartosz Sobczak 	else
1153*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_4K;
1154*cdcd52d4SBartosz Sobczak 
1155*cdcd52d4SBartosz Sobczak 	cqp = dev->cqp;
1156*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
1157*cdcd52d4SBartosz Sobczak 	if (!wqe)
1158*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
1159*cdcd52d4SBartosz Sobczak 
1160*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
1161*cdcd52d4SBartosz Sobczak 		      FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID) |
1162*cdcd52d4SBartosz Sobczak 		      LS_64(info->total_len, IRDMA_CQPSQ_STAG_STAGLEN));
1163*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
1164*cdcd52d4SBartosz Sobczak 		      LS_64(info->stag_idx, IRDMA_CQPSQ_STAG_IDX));
1165*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40,
1166*cdcd52d4SBartosz Sobczak 		      LS_64(info->hmc_fcn_index, IRDMA_CQPSQ_STAG_HMCFNIDX));
1167*cdcd52d4SBartosz Sobczak 
1168*cdcd52d4SBartosz Sobczak 	if (info->chunk_size)
1169*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
1170*cdcd52d4SBartosz Sobczak 			      LS_64(info->first_pm_pbl_idx, IRDMA_CQPSQ_STAG_FIRSTPMPBLIDX));
1171*cdcd52d4SBartosz Sobczak 
1172*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_ALLOC_STAG, IRDMA_CQPSQ_OPCODE) |
1173*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMA_CQPSQ_STAG_MR) |
1174*cdcd52d4SBartosz Sobczak 	    LS_64(info->access_rights, IRDMA_CQPSQ_STAG_ARIGHTS) |
1175*cdcd52d4SBartosz Sobczak 	    LS_64(info->chunk_size, IRDMA_CQPSQ_STAG_LPBLSIZE) |
1176*cdcd52d4SBartosz Sobczak 	    LS_64(page_size, IRDMA_CQPSQ_STAG_HPAGESIZE) |
1177*cdcd52d4SBartosz Sobczak 	    LS_64(info->remote_access, IRDMA_CQPSQ_STAG_REMACCENABLED) |
1178*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_hmc_fcn_index, IRDMA_CQPSQ_STAG_USEHMCFNIDX) |
1179*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_pf_rid, IRDMA_CQPSQ_STAG_USEPFRID) |
1180*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
1181*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1182*cdcd52d4SBartosz Sobczak 
1183*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1184*cdcd52d4SBartosz Sobczak 
1185*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "ALLOC_STAG WQE", wqe,
1186*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
1187*cdcd52d4SBartosz Sobczak 	if (post_sq)
1188*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
1189*cdcd52d4SBartosz Sobczak 
1190*cdcd52d4SBartosz Sobczak 	return 0;
1191*cdcd52d4SBartosz Sobczak }
1192*cdcd52d4SBartosz Sobczak 
1193*cdcd52d4SBartosz Sobczak /**
1194*cdcd52d4SBartosz Sobczak  * irdma_sc_mr_reg_non_shared - non-shared mr registration
1195*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
1196*cdcd52d4SBartosz Sobczak  * @info: mr info
1197*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
1198*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
1199*cdcd52d4SBartosz Sobczak  */
1200*cdcd52d4SBartosz Sobczak static int
1201*cdcd52d4SBartosz Sobczak irdma_sc_mr_reg_non_shared(struct irdma_sc_dev *dev,
1202*cdcd52d4SBartosz Sobczak 			   struct irdma_reg_ns_stag_info *info,
1203*cdcd52d4SBartosz Sobczak 			   u64 scratch, bool post_sq)
1204*cdcd52d4SBartosz Sobczak {
1205*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1206*cdcd52d4SBartosz Sobczak 	u64 fbo;
1207*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
1208*cdcd52d4SBartosz Sobczak 	u64 hdr;
1209*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
1210*cdcd52d4SBartosz Sobczak 	bool remote_access;
1211*cdcd52d4SBartosz Sobczak 	u8 addr_type;
1212*cdcd52d4SBartosz Sobczak 	enum irdma_page_size page_size;
1213*cdcd52d4SBartosz Sobczak 
1214*cdcd52d4SBartosz Sobczak 	if (info->page_size == 0x40000000)
1215*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_1G;
1216*cdcd52d4SBartosz Sobczak 	else if (info->page_size == 0x200000)
1217*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_2M;
1218*cdcd52d4SBartosz Sobczak 	else if (info->page_size == 0x1000)
1219*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_4K;
1220*cdcd52d4SBartosz Sobczak 	else
1221*cdcd52d4SBartosz Sobczak 		return -EINVAL;
1222*cdcd52d4SBartosz Sobczak 
1223*cdcd52d4SBartosz Sobczak 	if (info->access_rights & (IRDMA_ACCESS_FLAGS_REMOTEREAD_ONLY |
1224*cdcd52d4SBartosz Sobczak 				   IRDMA_ACCESS_FLAGS_REMOTEWRITE_ONLY))
1225*cdcd52d4SBartosz Sobczak 		remote_access = true;
1226*cdcd52d4SBartosz Sobczak 	else
1227*cdcd52d4SBartosz Sobczak 		remote_access = false;
1228*cdcd52d4SBartosz Sobczak 
1229*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
1230*cdcd52d4SBartosz Sobczak 	if (info->chunk_size && info->first_pm_pbl_index >= pble_obj_cnt)
1231*cdcd52d4SBartosz Sobczak 		return -EINVAL;
1232*cdcd52d4SBartosz Sobczak 
1233*cdcd52d4SBartosz Sobczak 	cqp = dev->cqp;
1234*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
1235*cdcd52d4SBartosz Sobczak 	if (!wqe)
1236*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
1237*cdcd52d4SBartosz Sobczak 	fbo = info->va & (info->page_size - 1);
1238*cdcd52d4SBartosz Sobczak 
1239*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0,
1240*cdcd52d4SBartosz Sobczak 		      (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED ?
1241*cdcd52d4SBartosz Sobczak 		       info->va : fbo));
1242*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
1243*cdcd52d4SBartosz Sobczak 		      LS_64(info->total_len, IRDMA_CQPSQ_STAG_STAGLEN) |
1244*cdcd52d4SBartosz Sobczak 		      FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID));
1245*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
1246*cdcd52d4SBartosz Sobczak 		      LS_64(info->stag_key, IRDMA_CQPSQ_STAG_KEY) |
1247*cdcd52d4SBartosz Sobczak 		      LS_64(info->stag_idx, IRDMA_CQPSQ_STAG_IDX));
1248*cdcd52d4SBartosz Sobczak 	if (!info->chunk_size)
1249*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_32, info->reg_addr_pa);
1250*cdcd52d4SBartosz Sobczak 	else
1251*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
1252*cdcd52d4SBartosz Sobczak 			      LS_64(info->first_pm_pbl_index, IRDMA_CQPSQ_STAG_FIRSTPMPBLIDX));
1253*cdcd52d4SBartosz Sobczak 
1254*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, info->hmc_fcn_index);
1255*cdcd52d4SBartosz Sobczak 
1256*cdcd52d4SBartosz Sobczak 	addr_type = (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED) ? 1 : 0;
1257*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_REG_MR, IRDMA_CQPSQ_OPCODE) |
1258*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMA_CQPSQ_STAG_MR) |
1259*cdcd52d4SBartosz Sobczak 	    LS_64(info->chunk_size, IRDMA_CQPSQ_STAG_LPBLSIZE) |
1260*cdcd52d4SBartosz Sobczak 	    LS_64(page_size, IRDMA_CQPSQ_STAG_HPAGESIZE) |
1261*cdcd52d4SBartosz Sobczak 	    LS_64(info->access_rights, IRDMA_CQPSQ_STAG_ARIGHTS) |
1262*cdcd52d4SBartosz Sobczak 	    LS_64(remote_access, IRDMA_CQPSQ_STAG_REMACCENABLED) |
1263*cdcd52d4SBartosz Sobczak 	    LS_64(addr_type, IRDMA_CQPSQ_STAG_VABASEDTO) |
1264*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_hmc_fcn_index, IRDMA_CQPSQ_STAG_USEHMCFNIDX) |
1265*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_pf_rid, IRDMA_CQPSQ_STAG_USEPFRID) |
1266*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
1267*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1268*cdcd52d4SBartosz Sobczak 
1269*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1270*cdcd52d4SBartosz Sobczak 
1271*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "MR_REG_NS WQE", wqe,
1272*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
1273*cdcd52d4SBartosz Sobczak 	if (post_sq)
1274*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
1275*cdcd52d4SBartosz Sobczak 
1276*cdcd52d4SBartosz Sobczak 	return 0;
1277*cdcd52d4SBartosz Sobczak }
1278*cdcd52d4SBartosz Sobczak 
1279*cdcd52d4SBartosz Sobczak /**
1280*cdcd52d4SBartosz Sobczak  * irdma_sc_dealloc_stag - deallocate stag
1281*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
1282*cdcd52d4SBartosz Sobczak  * @info: dealloc stag info
1283*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
1284*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
1285*cdcd52d4SBartosz Sobczak  */
1286*cdcd52d4SBartosz Sobczak static int
1287*cdcd52d4SBartosz Sobczak irdma_sc_dealloc_stag(struct irdma_sc_dev *dev,
1288*cdcd52d4SBartosz Sobczak 		      struct irdma_dealloc_stag_info *info,
1289*cdcd52d4SBartosz Sobczak 		      u64 scratch, bool post_sq)
1290*cdcd52d4SBartosz Sobczak {
1291*cdcd52d4SBartosz Sobczak 	u64 hdr;
1292*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1293*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
1294*cdcd52d4SBartosz Sobczak 
1295*cdcd52d4SBartosz Sobczak 	cqp = dev->cqp;
1296*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
1297*cdcd52d4SBartosz Sobczak 	if (!wqe)
1298*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
1299*cdcd52d4SBartosz Sobczak 
1300*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
1301*cdcd52d4SBartosz Sobczak 		      FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID));
1302*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
1303*cdcd52d4SBartosz Sobczak 		      LS_64(info->stag_idx, IRDMA_CQPSQ_STAG_IDX));
1304*cdcd52d4SBartosz Sobczak 
1305*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_DEALLOC_STAG, IRDMA_CQPSQ_OPCODE) |
1306*cdcd52d4SBartosz Sobczak 	    LS_64(info->mr, IRDMA_CQPSQ_STAG_MR) |
1307*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
1308*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1309*cdcd52d4SBartosz Sobczak 
1310*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1311*cdcd52d4SBartosz Sobczak 
1312*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "DEALLOC_STAG WQE", wqe,
1313*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
1314*cdcd52d4SBartosz Sobczak 	if (post_sq)
1315*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
1316*cdcd52d4SBartosz Sobczak 
1317*cdcd52d4SBartosz Sobczak 	return 0;
1318*cdcd52d4SBartosz Sobczak }
1319*cdcd52d4SBartosz Sobczak 
1320*cdcd52d4SBartosz Sobczak /**
1321*cdcd52d4SBartosz Sobczak  * irdma_sc_mw_alloc - mw allocate
1322*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
1323*cdcd52d4SBartosz Sobczak  * @info: memory window allocation information
1324*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
1325*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
1326*cdcd52d4SBartosz Sobczak  */
1327*cdcd52d4SBartosz Sobczak static int
1328*cdcd52d4SBartosz Sobczak irdma_sc_mw_alloc(struct irdma_sc_dev *dev,
1329*cdcd52d4SBartosz Sobczak 		  struct irdma_mw_alloc_info *info, u64 scratch,
1330*cdcd52d4SBartosz Sobczak 		  bool post_sq)
1331*cdcd52d4SBartosz Sobczak {
1332*cdcd52d4SBartosz Sobczak 	u64 hdr;
1333*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
1334*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1335*cdcd52d4SBartosz Sobczak 
1336*cdcd52d4SBartosz Sobczak 	cqp = dev->cqp;
1337*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
1338*cdcd52d4SBartosz Sobczak 	if (!wqe)
1339*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
1340*cdcd52d4SBartosz Sobczak 
1341*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
1342*cdcd52d4SBartosz Sobczak 		      FLD_LS_64(dev, info->pd_id, IRDMA_CQPSQ_STAG_PDID));
1343*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
1344*cdcd52d4SBartosz Sobczak 		      LS_64(info->mw_stag_index, IRDMA_CQPSQ_STAG_IDX));
1345*cdcd52d4SBartosz Sobczak 
1346*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_ALLOC_STAG, IRDMA_CQPSQ_OPCODE) |
1347*cdcd52d4SBartosz Sobczak 	    LS_64(info->mw_wide, IRDMA_CQPSQ_STAG_MWTYPE) |
1348*cdcd52d4SBartosz Sobczak 	    LS_64(info->mw1_bind_dont_vldt_key,
1349*cdcd52d4SBartosz Sobczak 		  IRDMA_CQPSQ_STAG_MW1_BIND_DONT_VLDT_KEY) |
1350*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
1351*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1352*cdcd52d4SBartosz Sobczak 
1353*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1354*cdcd52d4SBartosz Sobczak 
1355*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "MW_ALLOC WQE", wqe,
1356*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
1357*cdcd52d4SBartosz Sobczak 	if (post_sq)
1358*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
1359*cdcd52d4SBartosz Sobczak 
1360*cdcd52d4SBartosz Sobczak 	return 0;
1361*cdcd52d4SBartosz Sobczak }
1362*cdcd52d4SBartosz Sobczak 
1363*cdcd52d4SBartosz Sobczak /**
1364*cdcd52d4SBartosz Sobczak  * irdma_sc_mr_fast_register - Posts RDMA fast register mr WR to iwarp qp
1365*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
1366*cdcd52d4SBartosz Sobczak  * @info: fast mr info
1367*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
1368*cdcd52d4SBartosz Sobczak  */
1369*cdcd52d4SBartosz Sobczak int
1370*cdcd52d4SBartosz Sobczak irdma_sc_mr_fast_register(struct irdma_sc_qp *qp,
1371*cdcd52d4SBartosz Sobczak 			  struct irdma_fast_reg_stag_info *info,
1372*cdcd52d4SBartosz Sobczak 			  bool post_sq)
1373*cdcd52d4SBartosz Sobczak {
1374*cdcd52d4SBartosz Sobczak 	u64 temp, hdr;
1375*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1376*cdcd52d4SBartosz Sobczak 	u32 wqe_idx;
1377*cdcd52d4SBartosz Sobczak 	enum irdma_page_size page_size;
1378*cdcd52d4SBartosz Sobczak 	struct irdma_post_sq_info sq_info = {0};
1379*cdcd52d4SBartosz Sobczak 
1380*cdcd52d4SBartosz Sobczak 	if (info->page_size == 0x40000000)
1381*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_1G;
1382*cdcd52d4SBartosz Sobczak 	else if (info->page_size == 0x200000)
1383*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_2M;
1384*cdcd52d4SBartosz Sobczak 	else
1385*cdcd52d4SBartosz Sobczak 		page_size = IRDMA_PAGE_SIZE_4K;
1386*cdcd52d4SBartosz Sobczak 
1387*cdcd52d4SBartosz Sobczak 	sq_info.wr_id = info->wr_id;
1388*cdcd52d4SBartosz Sobczak 	sq_info.signaled = info->signaled;
1389*cdcd52d4SBartosz Sobczak 	sq_info.push_wqe = info->push_wqe;
1390*cdcd52d4SBartosz Sobczak 
1391*cdcd52d4SBartosz Sobczak 	wqe = irdma_qp_get_next_send_wqe(&qp->qp_uk, &wqe_idx,
1392*cdcd52d4SBartosz Sobczak 					 IRDMA_QP_WQE_MIN_QUANTA, 0, &sq_info);
1393*cdcd52d4SBartosz Sobczak 	if (!wqe)
1394*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
1395*cdcd52d4SBartosz Sobczak 
1396*cdcd52d4SBartosz Sobczak 	irdma_clr_wqes(&qp->qp_uk, wqe_idx);
1397*cdcd52d4SBartosz Sobczak 
1398*cdcd52d4SBartosz Sobczak 	qp->qp_uk.sq_wrtrk_array[wqe_idx].signaled = info->signaled;
1399*cdcd52d4SBartosz Sobczak 	irdma_debug(qp->dev, IRDMA_DEBUG_MR,
1400*cdcd52d4SBartosz Sobczak 		    "wr_id[%llxh] wqe_idx[%04d] location[%p]\n", (unsigned long long)info->wr_id,
1401*cdcd52d4SBartosz Sobczak 		    wqe_idx, &qp->qp_uk.sq_wrtrk_array[wqe_idx].wrid);
1402*cdcd52d4SBartosz Sobczak 
1403*cdcd52d4SBartosz Sobczak 	temp = (info->addr_type == IRDMA_ADDR_TYPE_VA_BASED) ?
1404*cdcd52d4SBartosz Sobczak 	    (uintptr_t)info->va : info->fbo;
1405*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, temp);
1406*cdcd52d4SBartosz Sobczak 
1407*cdcd52d4SBartosz Sobczak 	temp = RS_64(info->first_pm_pbl_index >> 16, IRDMAQPSQ_FIRSTPMPBLIDXHI);
1408*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
1409*cdcd52d4SBartosz Sobczak 		      LS_64(temp, IRDMAQPSQ_FIRSTPMPBLIDXHI) |
1410*cdcd52d4SBartosz Sobczak 		      LS_64(info->reg_addr_pa >> IRDMAQPSQ_PBLADDR_S, IRDMAQPSQ_PBLADDR));
1411*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
1412*cdcd52d4SBartosz Sobczak 		      info->total_len |
1413*cdcd52d4SBartosz Sobczak 		      LS_64(info->first_pm_pbl_index, IRDMAQPSQ_FIRSTPMPBLIDXLO));
1414*cdcd52d4SBartosz Sobczak 
1415*cdcd52d4SBartosz Sobczak 	hdr = LS_64(info->stag_key, IRDMAQPSQ_STAGKEY) |
1416*cdcd52d4SBartosz Sobczak 	    LS_64(info->stag_idx, IRDMAQPSQ_STAGINDEX) |
1417*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMAQP_OP_FAST_REGISTER, IRDMAQPSQ_OPCODE) |
1418*cdcd52d4SBartosz Sobczak 	    LS_64(info->chunk_size, IRDMAQPSQ_LPBLSIZE) |
1419*cdcd52d4SBartosz Sobczak 	    LS_64(page_size, IRDMAQPSQ_HPAGESIZE) |
1420*cdcd52d4SBartosz Sobczak 	    LS_64(info->access_rights, IRDMAQPSQ_STAGRIGHTS) |
1421*cdcd52d4SBartosz Sobczak 	    LS_64(info->addr_type, IRDMAQPSQ_VABASEDTO) |
1422*cdcd52d4SBartosz Sobczak 	    LS_64((sq_info.push_wqe ? 1 : 0), IRDMAQPSQ_PUSHWQE) |
1423*cdcd52d4SBartosz Sobczak 	    LS_64(info->read_fence, IRDMAQPSQ_READFENCE) |
1424*cdcd52d4SBartosz Sobczak 	    LS_64(info->local_fence, IRDMAQPSQ_LOCALFENCE) |
1425*cdcd52d4SBartosz Sobczak 	    LS_64(info->signaled, IRDMAQPSQ_SIGCOMPL) |
1426*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1427*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1428*cdcd52d4SBartosz Sobczak 
1429*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1430*cdcd52d4SBartosz Sobczak 
1431*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_WQE, "FAST_REG WQE", wqe,
1432*cdcd52d4SBartosz Sobczak 			IRDMA_QP_WQE_MIN_SIZE);
1433*cdcd52d4SBartosz Sobczak 	if (sq_info.push_wqe) {
1434*cdcd52d4SBartosz Sobczak 		irdma_qp_push_wqe(&qp->qp_uk, wqe, IRDMA_QP_WQE_MIN_QUANTA,
1435*cdcd52d4SBartosz Sobczak 				  wqe_idx, post_sq);
1436*cdcd52d4SBartosz Sobczak 	} else {
1437*cdcd52d4SBartosz Sobczak 		if (post_sq)
1438*cdcd52d4SBartosz Sobczak 			irdma_uk_qp_post_wr(&qp->qp_uk);
1439*cdcd52d4SBartosz Sobczak 	}
1440*cdcd52d4SBartosz Sobczak 
1441*cdcd52d4SBartosz Sobczak 	return 0;
1442*cdcd52d4SBartosz Sobczak }
1443*cdcd52d4SBartosz Sobczak 
1444*cdcd52d4SBartosz Sobczak /**
1445*cdcd52d4SBartosz Sobczak  * irdma_sc_gen_rts_ae - request AE generated after RTS
1446*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
1447*cdcd52d4SBartosz Sobczak  */
1448*cdcd52d4SBartosz Sobczak static void
1449*cdcd52d4SBartosz Sobczak irdma_sc_gen_rts_ae(struct irdma_sc_qp *qp)
1450*cdcd52d4SBartosz Sobczak {
1451*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1452*cdcd52d4SBartosz Sobczak 	u64 hdr;
1453*cdcd52d4SBartosz Sobczak 	struct irdma_qp_uk *qp_uk;
1454*cdcd52d4SBartosz Sobczak 
1455*cdcd52d4SBartosz Sobczak 	qp_uk = &qp->qp_uk;
1456*cdcd52d4SBartosz Sobczak 
1457*cdcd52d4SBartosz Sobczak 	wqe = qp_uk->sq_base[1].elem;
1458*cdcd52d4SBartosz Sobczak 
1459*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMAQP_OP_NOP, IRDMAQPSQ_OPCODE) |
1460*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMAQPSQ_LOCALFENCE) |
1461*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1462*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1463*cdcd52d4SBartosz Sobczak 
1464*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1465*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_QP, "NOP W/LOCAL FENCE WQE", wqe,
1466*cdcd52d4SBartosz Sobczak 			IRDMA_QP_WQE_MIN_SIZE);
1467*cdcd52d4SBartosz Sobczak 
1468*cdcd52d4SBartosz Sobczak 	wqe = qp_uk->sq_base[2].elem;
1469*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMAQP_OP_GEN_RTS_AE, IRDMAQPSQ_OPCODE) |
1470*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1471*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1472*cdcd52d4SBartosz Sobczak 
1473*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1474*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_QP, "CONN EST WQE", wqe,
1475*cdcd52d4SBartosz Sobczak 			IRDMA_QP_WQE_MIN_SIZE);
1476*cdcd52d4SBartosz Sobczak }
1477*cdcd52d4SBartosz Sobczak 
1478*cdcd52d4SBartosz Sobczak /**
1479*cdcd52d4SBartosz Sobczak  * irdma_sc_send_lsmm - send last streaming mode message
1480*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
1481*cdcd52d4SBartosz Sobczak  * @lsmm_buf: buffer with lsmm message
1482*cdcd52d4SBartosz Sobczak  * @size: size of lsmm buffer
1483*cdcd52d4SBartosz Sobczak  * @stag: stag of lsmm buffer
1484*cdcd52d4SBartosz Sobczak  */
1485*cdcd52d4SBartosz Sobczak int
1486*cdcd52d4SBartosz Sobczak irdma_sc_send_lsmm(struct irdma_sc_qp *qp, void *lsmm_buf, u32 size,
1487*cdcd52d4SBartosz Sobczak 		   irdma_stag stag)
1488*cdcd52d4SBartosz Sobczak {
1489*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1490*cdcd52d4SBartosz Sobczak 	u64 hdr;
1491*cdcd52d4SBartosz Sobczak 	struct irdma_qp_uk *qp_uk;
1492*cdcd52d4SBartosz Sobczak 
1493*cdcd52d4SBartosz Sobczak 	qp_uk = &qp->qp_uk;
1494*cdcd52d4SBartosz Sobczak 	wqe = qp_uk->sq_base->elem;
1495*cdcd52d4SBartosz Sobczak 
1496*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, (uintptr_t)lsmm_buf);
1497*cdcd52d4SBartosz Sobczak 	if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) {
1498*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_8,
1499*cdcd52d4SBartosz Sobczak 			      LS_64(size, IRDMAQPSQ_GEN1_FRAG_LEN) |
1500*cdcd52d4SBartosz Sobczak 			      LS_64(stag, IRDMAQPSQ_GEN1_FRAG_STAG));
1501*cdcd52d4SBartosz Sobczak 	} else {
1502*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_8,
1503*cdcd52d4SBartosz Sobczak 			      LS_64(size, IRDMAQPSQ_FRAG_LEN) |
1504*cdcd52d4SBartosz Sobczak 			      LS_64(stag, IRDMAQPSQ_FRAG_STAG) |
1505*cdcd52d4SBartosz Sobczak 			      LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID));
1506*cdcd52d4SBartosz Sobczak 	}
1507*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, 0);
1508*cdcd52d4SBartosz Sobczak 
1509*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMAQP_OP_RDMA_SEND, IRDMAQPSQ_OPCODE) |
1510*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMAQPSQ_STREAMMODE) |
1511*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMAQPSQ_WAITFORRCVPDU) |
1512*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1513*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1514*cdcd52d4SBartosz Sobczak 
1515*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1516*cdcd52d4SBartosz Sobczak 
1517*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_WQE, "SEND_LSMM WQE", wqe,
1518*cdcd52d4SBartosz Sobczak 			IRDMA_QP_WQE_MIN_SIZE);
1519*cdcd52d4SBartosz Sobczak 
1520*cdcd52d4SBartosz Sobczak 	if (qp->dev->hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_RTS_AE)
1521*cdcd52d4SBartosz Sobczak 		irdma_sc_gen_rts_ae(qp);
1522*cdcd52d4SBartosz Sobczak 
1523*cdcd52d4SBartosz Sobczak 	return 0;
1524*cdcd52d4SBartosz Sobczak }
1525*cdcd52d4SBartosz Sobczak 
1526*cdcd52d4SBartosz Sobczak /**
1527*cdcd52d4SBartosz Sobczak  * irdma_sc_send_lsmm_nostag - for privilege qp
1528*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
1529*cdcd52d4SBartosz Sobczak  * @lsmm_buf: buffer with lsmm message
1530*cdcd52d4SBartosz Sobczak  * @size: size of lsmm buffer
1531*cdcd52d4SBartosz Sobczak  */
1532*cdcd52d4SBartosz Sobczak int
1533*cdcd52d4SBartosz Sobczak irdma_sc_send_lsmm_nostag(struct irdma_sc_qp *qp, void *lsmm_buf, u32 size)
1534*cdcd52d4SBartosz Sobczak {
1535*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1536*cdcd52d4SBartosz Sobczak 	u64 hdr;
1537*cdcd52d4SBartosz Sobczak 	struct irdma_qp_uk *qp_uk;
1538*cdcd52d4SBartosz Sobczak 
1539*cdcd52d4SBartosz Sobczak 	qp_uk = &qp->qp_uk;
1540*cdcd52d4SBartosz Sobczak 	wqe = qp_uk->sq_base->elem;
1541*cdcd52d4SBartosz Sobczak 
1542*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, (uintptr_t)lsmm_buf);
1543*cdcd52d4SBartosz Sobczak 
1544*cdcd52d4SBartosz Sobczak 	if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1)
1545*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_8,
1546*cdcd52d4SBartosz Sobczak 			      LS_64(size, IRDMAQPSQ_GEN1_FRAG_LEN));
1547*cdcd52d4SBartosz Sobczak 	else
1548*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_8,
1549*cdcd52d4SBartosz Sobczak 			      LS_64(size, IRDMAQPSQ_FRAG_LEN) |
1550*cdcd52d4SBartosz Sobczak 			      LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID));
1551*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, 0);
1552*cdcd52d4SBartosz Sobczak 
1553*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMAQP_OP_RDMA_SEND, IRDMAQPSQ_OPCODE) |
1554*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMAQPSQ_STREAMMODE) |
1555*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMAQPSQ_WAITFORRCVPDU) |
1556*cdcd52d4SBartosz Sobczak 	    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1557*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1558*cdcd52d4SBartosz Sobczak 
1559*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1560*cdcd52d4SBartosz Sobczak 
1561*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_WQE, "SEND_LSMM_NOSTAG WQE", wqe,
1562*cdcd52d4SBartosz Sobczak 			IRDMA_QP_WQE_MIN_SIZE);
1563*cdcd52d4SBartosz Sobczak 
1564*cdcd52d4SBartosz Sobczak 	return 0;
1565*cdcd52d4SBartosz Sobczak }
1566*cdcd52d4SBartosz Sobczak 
1567*cdcd52d4SBartosz Sobczak /**
1568*cdcd52d4SBartosz Sobczak  * irdma_sc_send_rtt - send last read0 or write0
1569*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
1570*cdcd52d4SBartosz Sobczak  * @read: Do read0 or write0
1571*cdcd52d4SBartosz Sobczak  */
1572*cdcd52d4SBartosz Sobczak int
1573*cdcd52d4SBartosz Sobczak irdma_sc_send_rtt(struct irdma_sc_qp *qp, bool read)
1574*cdcd52d4SBartosz Sobczak {
1575*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
1576*cdcd52d4SBartosz Sobczak 	u64 hdr;
1577*cdcd52d4SBartosz Sobczak 	struct irdma_qp_uk *qp_uk;
1578*cdcd52d4SBartosz Sobczak 
1579*cdcd52d4SBartosz Sobczak 	qp_uk = &qp->qp_uk;
1580*cdcd52d4SBartosz Sobczak 	wqe = qp_uk->sq_base->elem;
1581*cdcd52d4SBartosz Sobczak 
1582*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, 0);
1583*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, 0);
1584*cdcd52d4SBartosz Sobczak 	if (read) {
1585*cdcd52d4SBartosz Sobczak 		if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) {
1586*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_8,
1587*cdcd52d4SBartosz Sobczak 				      LS_64(0xabcd, IRDMAQPSQ_GEN1_FRAG_STAG));
1588*cdcd52d4SBartosz Sobczak 		} else {
1589*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_8,
1590*cdcd52d4SBartosz Sobczak 				      (u64)0xabcd | LS_64(qp->qp_uk.swqe_polarity,
1591*cdcd52d4SBartosz Sobczak 							   IRDMAQPSQ_VALID));
1592*cdcd52d4SBartosz Sobczak 		}
1593*cdcd52d4SBartosz Sobczak 		hdr = LS_64(0x1234, IRDMAQPSQ_REMSTAG) |
1594*cdcd52d4SBartosz Sobczak 		    LS_64(IRDMAQP_OP_RDMA_READ, IRDMAQPSQ_OPCODE) |
1595*cdcd52d4SBartosz Sobczak 		    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1596*cdcd52d4SBartosz Sobczak 
1597*cdcd52d4SBartosz Sobczak 	} else {
1598*cdcd52d4SBartosz Sobczak 		if (qp->qp_uk.uk_attrs->hw_rev == IRDMA_GEN_1) {
1599*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_8, 0);
1600*cdcd52d4SBartosz Sobczak 		} else {
1601*cdcd52d4SBartosz Sobczak 			set_64bit_val(wqe, IRDMA_BYTE_8,
1602*cdcd52d4SBartosz Sobczak 				      LS_64(qp->qp_uk.swqe_polarity,
1603*cdcd52d4SBartosz Sobczak 					    IRDMAQPSQ_VALID));
1604*cdcd52d4SBartosz Sobczak 		}
1605*cdcd52d4SBartosz Sobczak 		hdr = LS_64(IRDMAQP_OP_RDMA_WRITE, IRDMAQPSQ_OPCODE) |
1606*cdcd52d4SBartosz Sobczak 		    LS_64(qp->qp_uk.swqe_polarity, IRDMAQPSQ_VALID);
1607*cdcd52d4SBartosz Sobczak 	}
1608*cdcd52d4SBartosz Sobczak 
1609*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
1610*cdcd52d4SBartosz Sobczak 
1611*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
1612*cdcd52d4SBartosz Sobczak 
1613*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(qp->dev, IRDMA_DEBUG_WQE, "RTR WQE", wqe,
1614*cdcd52d4SBartosz Sobczak 			IRDMA_QP_WQE_MIN_SIZE);
1615*cdcd52d4SBartosz Sobczak 
1616*cdcd52d4SBartosz Sobczak 	if (qp->dev->hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_RTS_AE)
1617*cdcd52d4SBartosz Sobczak 		irdma_sc_gen_rts_ae(qp);
1618*cdcd52d4SBartosz Sobczak 
1619*cdcd52d4SBartosz Sobczak 	return 0;
1620*cdcd52d4SBartosz Sobczak }
1621*cdcd52d4SBartosz Sobczak 
1622*cdcd52d4SBartosz Sobczak /**
1623*cdcd52d4SBartosz Sobczak  * irdma_iwarp_opcode - determine if incoming is rdma layer
1624*cdcd52d4SBartosz Sobczak  * @info: aeq info for the packet
1625*cdcd52d4SBartosz Sobczak  * @pkt: packet for error
1626*cdcd52d4SBartosz Sobczak  */
1627*cdcd52d4SBartosz Sobczak static u32 irdma_iwarp_opcode(struct irdma_aeqe_info *info, u8 *pkt){
1628*cdcd52d4SBartosz Sobczak 	BE16 *mpa;
1629*cdcd52d4SBartosz Sobczak 	u32 opcode = 0xffffffff;
1630*cdcd52d4SBartosz Sobczak 
1631*cdcd52d4SBartosz Sobczak 	if (info->q2_data_written) {
1632*cdcd52d4SBartosz Sobczak 		mpa = (BE16 *) pkt;
1633*cdcd52d4SBartosz Sobczak 		opcode = IRDMA_NTOHS(mpa[1]) & 0xf;
1634*cdcd52d4SBartosz Sobczak 	}
1635*cdcd52d4SBartosz Sobczak 
1636*cdcd52d4SBartosz Sobczak 	return opcode;
1637*cdcd52d4SBartosz Sobczak }
1638*cdcd52d4SBartosz Sobczak 
1639*cdcd52d4SBartosz Sobczak /**
1640*cdcd52d4SBartosz Sobczak  * irdma_locate_mpa - return pointer to mpa in the pkt
1641*cdcd52d4SBartosz Sobczak  * @pkt: packet with data
1642*cdcd52d4SBartosz Sobczak  */
1643*cdcd52d4SBartosz Sobczak static u8 *irdma_locate_mpa(u8 *pkt) {
1644*cdcd52d4SBartosz Sobczak 	/* skip over ethernet header */
1645*cdcd52d4SBartosz Sobczak 	pkt += IRDMA_MAC_HLEN;
1646*cdcd52d4SBartosz Sobczak 
1647*cdcd52d4SBartosz Sobczak 	/* Skip over IP and TCP headers */
1648*cdcd52d4SBartosz Sobczak 	pkt += 4 * (pkt[0] & 0x0f);
1649*cdcd52d4SBartosz Sobczak 	pkt += 4 * ((pkt[12] >> 4) & 0x0f);
1650*cdcd52d4SBartosz Sobczak 
1651*cdcd52d4SBartosz Sobczak 	return pkt;
1652*cdcd52d4SBartosz Sobczak }
1653*cdcd52d4SBartosz Sobczak 
1654*cdcd52d4SBartosz Sobczak /**
1655*cdcd52d4SBartosz Sobczak  * irdma_bld_termhdr_ctrl - setup terminate hdr control fields
1656*cdcd52d4SBartosz Sobczak  * @qp: sc qp ptr for pkt
1657*cdcd52d4SBartosz Sobczak  * @hdr: term hdr
1658*cdcd52d4SBartosz Sobczak  * @opcode: flush opcode for termhdr
1659*cdcd52d4SBartosz Sobczak  * @layer_etype: error layer + error type
1660*cdcd52d4SBartosz Sobczak  * @err: error cod ein the header
1661*cdcd52d4SBartosz Sobczak  */
1662*cdcd52d4SBartosz Sobczak static void
1663*cdcd52d4SBartosz Sobczak irdma_bld_termhdr_ctrl(struct irdma_sc_qp *qp,
1664*cdcd52d4SBartosz Sobczak 		       struct irdma_terminate_hdr *hdr,
1665*cdcd52d4SBartosz Sobczak 		       enum irdma_flush_opcode opcode,
1666*cdcd52d4SBartosz Sobczak 		       u8 layer_etype, u8 err)
1667*cdcd52d4SBartosz Sobczak {
1668*cdcd52d4SBartosz Sobczak 	qp->flush_code = opcode;
1669*cdcd52d4SBartosz Sobczak 	hdr->layer_etype = layer_etype;
1670*cdcd52d4SBartosz Sobczak 	hdr->error_code = err;
1671*cdcd52d4SBartosz Sobczak }
1672*cdcd52d4SBartosz Sobczak 
1673*cdcd52d4SBartosz Sobczak /**
1674*cdcd52d4SBartosz Sobczak  * irdma_bld_termhdr_ddp_rdma - setup ddp and rdma hdrs in terminate hdr
1675*cdcd52d4SBartosz Sobczak  * @pkt: ptr to mpa in offending pkt
1676*cdcd52d4SBartosz Sobczak  * @hdr: term hdr
1677*cdcd52d4SBartosz Sobczak  * @copy_len: offending pkt length to be copied to term hdr
1678*cdcd52d4SBartosz Sobczak  * @is_tagged: DDP tagged or untagged
1679*cdcd52d4SBartosz Sobczak  */
1680*cdcd52d4SBartosz Sobczak static void
1681*cdcd52d4SBartosz Sobczak irdma_bld_termhdr_ddp_rdma(u8 *pkt, struct irdma_terminate_hdr *hdr,
1682*cdcd52d4SBartosz Sobczak 			   int *copy_len, u8 *is_tagged)
1683*cdcd52d4SBartosz Sobczak {
1684*cdcd52d4SBartosz Sobczak 	u16 ddp_seg_len;
1685*cdcd52d4SBartosz Sobczak 
1686*cdcd52d4SBartosz Sobczak 	ddp_seg_len = IRDMA_NTOHS(*(BE16 *) pkt);
1687*cdcd52d4SBartosz Sobczak 	if (ddp_seg_len) {
1688*cdcd52d4SBartosz Sobczak 		*copy_len = 2;
1689*cdcd52d4SBartosz Sobczak 		hdr->hdrct = DDP_LEN_FLAG;
1690*cdcd52d4SBartosz Sobczak 		if (pkt[2] & 0x80) {
1691*cdcd52d4SBartosz Sobczak 			*is_tagged = 1;
1692*cdcd52d4SBartosz Sobczak 			if (ddp_seg_len >= TERM_DDP_LEN_TAGGED) {
1693*cdcd52d4SBartosz Sobczak 				*copy_len += TERM_DDP_LEN_TAGGED;
1694*cdcd52d4SBartosz Sobczak 				hdr->hdrct |= DDP_HDR_FLAG;
1695*cdcd52d4SBartosz Sobczak 			}
1696*cdcd52d4SBartosz Sobczak 		} else {
1697*cdcd52d4SBartosz Sobczak 			if (ddp_seg_len >= TERM_DDP_LEN_UNTAGGED) {
1698*cdcd52d4SBartosz Sobczak 				*copy_len += TERM_DDP_LEN_UNTAGGED;
1699*cdcd52d4SBartosz Sobczak 				hdr->hdrct |= DDP_HDR_FLAG;
1700*cdcd52d4SBartosz Sobczak 			}
1701*cdcd52d4SBartosz Sobczak 			if (ddp_seg_len >= (TERM_DDP_LEN_UNTAGGED + TERM_RDMA_LEN) &&
1702*cdcd52d4SBartosz Sobczak 			    ((pkt[3] & RDMA_OPCODE_M) == RDMA_READ_REQ_OPCODE)) {
1703*cdcd52d4SBartosz Sobczak 				*copy_len += TERM_RDMA_LEN;
1704*cdcd52d4SBartosz Sobczak 				hdr->hdrct |= RDMA_HDR_FLAG;
1705*cdcd52d4SBartosz Sobczak 			}
1706*cdcd52d4SBartosz Sobczak 		}
1707*cdcd52d4SBartosz Sobczak 	}
1708*cdcd52d4SBartosz Sobczak }
1709*cdcd52d4SBartosz Sobczak 
1710*cdcd52d4SBartosz Sobczak /**
1711*cdcd52d4SBartosz Sobczak  * irdma_bld_terminate_hdr - build terminate message header
1712*cdcd52d4SBartosz Sobczak  * @qp: qp associated with received terminate AE
1713*cdcd52d4SBartosz Sobczak  * @info: the struct contiaing AE information
1714*cdcd52d4SBartosz Sobczak  */
1715*cdcd52d4SBartosz Sobczak static int
1716*cdcd52d4SBartosz Sobczak irdma_bld_terminate_hdr(struct irdma_sc_qp *qp,
1717*cdcd52d4SBartosz Sobczak 			struct irdma_aeqe_info *info)
1718*cdcd52d4SBartosz Sobczak {
1719*cdcd52d4SBartosz Sobczak 	u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET;
1720*cdcd52d4SBartosz Sobczak 	int copy_len = 0;
1721*cdcd52d4SBartosz Sobczak 	u8 is_tagged = 0;
1722*cdcd52d4SBartosz Sobczak 	u32 opcode;
1723*cdcd52d4SBartosz Sobczak 	struct irdma_terminate_hdr *termhdr;
1724*cdcd52d4SBartosz Sobczak 
1725*cdcd52d4SBartosz Sobczak 	termhdr = (struct irdma_terminate_hdr *)qp->q2_buf;
1726*cdcd52d4SBartosz Sobczak 	memset(termhdr, 0, Q2_BAD_FRAME_OFFSET);
1727*cdcd52d4SBartosz Sobczak 
1728*cdcd52d4SBartosz Sobczak 	if (info->q2_data_written) {
1729*cdcd52d4SBartosz Sobczak 		pkt = irdma_locate_mpa(pkt);
1730*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ddp_rdma(pkt, termhdr, &copy_len, &is_tagged);
1731*cdcd52d4SBartosz Sobczak 	}
1732*cdcd52d4SBartosz Sobczak 
1733*cdcd52d4SBartosz Sobczak 	opcode = irdma_iwarp_opcode(info, pkt);
1734*cdcd52d4SBartosz Sobczak 	qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
1735*cdcd52d4SBartosz Sobczak 	qp->sq_flush_code = info->sq;
1736*cdcd52d4SBartosz Sobczak 	qp->rq_flush_code = info->rq;
1737*cdcd52d4SBartosz Sobczak 
1738*cdcd52d4SBartosz Sobczak 	switch (info->ae_id) {
1739*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_UNALLOCATED_STAG:
1740*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1741*cdcd52d4SBartosz Sobczak 		if (opcode == IRDMA_OP_TYPE_RDMA_WRITE)
1742*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR,
1743*cdcd52d4SBartosz Sobczak 					       (LAYER_DDP << 4) | DDP_TAGGED_BUF,
1744*cdcd52d4SBartosz Sobczak 					       DDP_TAGGED_INV_STAG);
1745*cdcd52d4SBartosz Sobczak 		else
1746*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1747*cdcd52d4SBartosz Sobczak 					       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1748*cdcd52d4SBartosz Sobczak 					       RDMAP_INV_STAG);
1749*cdcd52d4SBartosz Sobczak 		break;
1750*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_BOUNDS_VIOLATION:
1751*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1752*cdcd52d4SBartosz Sobczak 		if (info->q2_data_written)
1753*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR,
1754*cdcd52d4SBartosz Sobczak 					       (LAYER_DDP << 4) | DDP_TAGGED_BUF,
1755*cdcd52d4SBartosz Sobczak 					       DDP_TAGGED_BOUNDS);
1756*cdcd52d4SBartosz Sobczak 		else
1757*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1758*cdcd52d4SBartosz Sobczak 					       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1759*cdcd52d4SBartosz Sobczak 					       RDMAP_INV_BOUNDS);
1760*cdcd52d4SBartosz Sobczak 		break;
1761*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_BAD_PD:
1762*cdcd52d4SBartosz Sobczak 		switch (opcode) {
1763*cdcd52d4SBartosz Sobczak 		case IRDMA_OP_TYPE_RDMA_WRITE:
1764*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_PROT_ERR,
1765*cdcd52d4SBartosz Sobczak 					       (LAYER_DDP << 4) | DDP_TAGGED_BUF,
1766*cdcd52d4SBartosz Sobczak 					       DDP_TAGGED_UNASSOC_STAG);
1767*cdcd52d4SBartosz Sobczak 			break;
1768*cdcd52d4SBartosz Sobczak 		case IRDMA_OP_TYPE_SEND_INV:
1769*cdcd52d4SBartosz Sobczak 		case IRDMA_OP_TYPE_SEND_SOL_INV:
1770*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1771*cdcd52d4SBartosz Sobczak 					       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1772*cdcd52d4SBartosz Sobczak 					       RDMAP_CANT_INV_STAG);
1773*cdcd52d4SBartosz Sobczak 			break;
1774*cdcd52d4SBartosz Sobczak 		default:
1775*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1776*cdcd52d4SBartosz Sobczak 					       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1777*cdcd52d4SBartosz Sobczak 					       RDMAP_UNASSOC_STAG);
1778*cdcd52d4SBartosz Sobczak 		}
1779*cdcd52d4SBartosz Sobczak 		break;
1780*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_INVALID_STAG:
1781*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1782*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1783*cdcd52d4SBartosz Sobczak 				       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1784*cdcd52d4SBartosz Sobczak 				       RDMAP_INV_STAG);
1785*cdcd52d4SBartosz Sobczak 		break;
1786*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_BAD_QP:
1787*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_QP_OP_ERR,
1788*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1789*cdcd52d4SBartosz Sobczak 				       DDP_UNTAGGED_INV_QN);
1790*cdcd52d4SBartosz Sobczak 		break;
1791*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_BAD_STAG_KEY:
1792*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_BAD_STAG_INDEX:
1793*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1794*cdcd52d4SBartosz Sobczak 		switch (opcode) {
1795*cdcd52d4SBartosz Sobczak 		case IRDMA_OP_TYPE_SEND_INV:
1796*cdcd52d4SBartosz Sobczak 		case IRDMA_OP_TYPE_SEND_SOL_INV:
1797*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_OP_ERR,
1798*cdcd52d4SBartosz Sobczak 					       (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
1799*cdcd52d4SBartosz Sobczak 					       RDMAP_CANT_INV_STAG);
1800*cdcd52d4SBartosz Sobczak 			break;
1801*cdcd52d4SBartosz Sobczak 		default:
1802*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1803*cdcd52d4SBartosz Sobczak 					       (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
1804*cdcd52d4SBartosz Sobczak 					       RDMAP_INV_STAG);
1805*cdcd52d4SBartosz Sobczak 		}
1806*cdcd52d4SBartosz Sobczak 		break;
1807*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_RIGHTS_VIOLATION:
1808*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
1809*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_PRIV_OPERATION_DENIED:
1810*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1811*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1812*cdcd52d4SBartosz Sobczak 				       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1813*cdcd52d4SBartosz Sobczak 				       RDMAP_ACCESS);
1814*cdcd52d4SBartosz Sobczak 		break;
1815*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_TO_WRAP:
1816*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1817*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_ACCESS_ERR,
1818*cdcd52d4SBartosz Sobczak 				       (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT,
1819*cdcd52d4SBartosz Sobczak 				       RDMAP_TO_WRAP);
1820*cdcd52d4SBartosz Sobczak 		break;
1821*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
1822*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1823*cdcd52d4SBartosz Sobczak 				       (LAYER_MPA << 4) | DDP_LLP, MPA_CRC);
1824*cdcd52d4SBartosz Sobczak 		break;
1825*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_SEGMENT_TOO_SMALL:
1826*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_LEN_ERR,
1827*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_CATASTROPHIC,
1828*cdcd52d4SBartosz Sobczak 				       DDP_CATASTROPHIC_LOCAL);
1829*cdcd52d4SBartosz Sobczak 		break;
1830*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LCE_QP_CATASTROPHIC:
1831*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_NO_L_BIT:
1832*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_FATAL_ERR,
1833*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_CATASTROPHIC,
1834*cdcd52d4SBartosz Sobczak 				       DDP_CATASTROPHIC_LOCAL);
1835*cdcd52d4SBartosz Sobczak 		break;
1836*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN:
1837*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1838*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1839*cdcd52d4SBartosz Sobczak 				       DDP_UNTAGGED_INV_MSN_RANGE);
1840*cdcd52d4SBartosz Sobczak 		break;
1841*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
1842*cdcd52d4SBartosz Sobczak 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
1843*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_LOC_LEN_ERR,
1844*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1845*cdcd52d4SBartosz Sobczak 				       DDP_UNTAGGED_INV_TOO_LONG);
1846*cdcd52d4SBartosz Sobczak 		break;
1847*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION:
1848*cdcd52d4SBartosz Sobczak 		if (is_tagged)
1849*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1850*cdcd52d4SBartosz Sobczak 					       (LAYER_DDP << 4) | DDP_TAGGED_BUF,
1851*cdcd52d4SBartosz Sobczak 					       DDP_TAGGED_INV_DDP_VER);
1852*cdcd52d4SBartosz Sobczak 		else
1853*cdcd52d4SBartosz Sobczak 			irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1854*cdcd52d4SBartosz Sobczak 					       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1855*cdcd52d4SBartosz Sobczak 					       DDP_UNTAGGED_INV_DDP_VER);
1856*cdcd52d4SBartosz Sobczak 		break;
1857*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_MO:
1858*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1859*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1860*cdcd52d4SBartosz Sobczak 				       DDP_UNTAGGED_INV_MO);
1861*cdcd52d4SBartosz Sobczak 		break;
1862*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
1863*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_REM_OP_ERR,
1864*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1865*cdcd52d4SBartosz Sobczak 				       DDP_UNTAGGED_INV_MSN_NO_BUF);
1866*cdcd52d4SBartosz Sobczak 		break;
1867*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_QN:
1868*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1869*cdcd52d4SBartosz Sobczak 				       (LAYER_DDP << 4) | DDP_UNTAGGED_BUF,
1870*cdcd52d4SBartosz Sobczak 				       DDP_UNTAGGED_INV_QN);
1871*cdcd52d4SBartosz Sobczak 		break;
1872*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
1873*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_GENERAL_ERR,
1874*cdcd52d4SBartosz Sobczak 				       (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
1875*cdcd52d4SBartosz Sobczak 				       RDMAP_INV_RDMAP_VER);
1876*cdcd52d4SBartosz Sobczak 		break;
1877*cdcd52d4SBartosz Sobczak 	default:
1878*cdcd52d4SBartosz Sobczak 		irdma_bld_termhdr_ctrl(qp, termhdr, FLUSH_FATAL_ERR,
1879*cdcd52d4SBartosz Sobczak 				       (LAYER_RDMA << 4) | RDMAP_REMOTE_OP,
1880*cdcd52d4SBartosz Sobczak 				       RDMAP_UNSPECIFIED);
1881*cdcd52d4SBartosz Sobczak 		break;
1882*cdcd52d4SBartosz Sobczak 	}
1883*cdcd52d4SBartosz Sobczak 
1884*cdcd52d4SBartosz Sobczak 	if (copy_len)
1885*cdcd52d4SBartosz Sobczak 		irdma_memcpy(termhdr + 1, pkt, copy_len);
1886*cdcd52d4SBartosz Sobczak 
1887*cdcd52d4SBartosz Sobczak 	return sizeof(struct irdma_terminate_hdr) + copy_len;
1888*cdcd52d4SBartosz Sobczak }
1889*cdcd52d4SBartosz Sobczak 
1890*cdcd52d4SBartosz Sobczak /**
1891*cdcd52d4SBartosz Sobczak  * irdma_terminate_send_fin() - Send fin for terminate message
1892*cdcd52d4SBartosz Sobczak  * @qp: qp associated with received terminate AE
1893*cdcd52d4SBartosz Sobczak  */
1894*cdcd52d4SBartosz Sobczak void
1895*cdcd52d4SBartosz Sobczak irdma_terminate_send_fin(struct irdma_sc_qp *qp)
1896*cdcd52d4SBartosz Sobczak {
1897*cdcd52d4SBartosz Sobczak 	irdma_term_modify_qp(qp, IRDMA_QP_STATE_TERMINATE,
1898*cdcd52d4SBartosz Sobczak 			     IRDMAQP_TERM_SEND_FIN_ONLY, 0);
1899*cdcd52d4SBartosz Sobczak }
1900*cdcd52d4SBartosz Sobczak 
1901*cdcd52d4SBartosz Sobczak /**
1902*cdcd52d4SBartosz Sobczak  * irdma_terminate_connection() - Bad AE and send terminate to remote QP
1903*cdcd52d4SBartosz Sobczak  * @qp: qp associated with received terminate AE
1904*cdcd52d4SBartosz Sobczak  * @info: the struct contiaing AE information
1905*cdcd52d4SBartosz Sobczak  */
1906*cdcd52d4SBartosz Sobczak void
1907*cdcd52d4SBartosz Sobczak irdma_terminate_connection(struct irdma_sc_qp *qp,
1908*cdcd52d4SBartosz Sobczak 			   struct irdma_aeqe_info *info)
1909*cdcd52d4SBartosz Sobczak {
1910*cdcd52d4SBartosz Sobczak 	u8 termlen = 0;
1911*cdcd52d4SBartosz Sobczak 
1912*cdcd52d4SBartosz Sobczak 	if (qp->term_flags & IRDMA_TERM_SENT)
1913*cdcd52d4SBartosz Sobczak 		return;
1914*cdcd52d4SBartosz Sobczak 
1915*cdcd52d4SBartosz Sobczak 	termlen = irdma_bld_terminate_hdr(qp, info);
1916*cdcd52d4SBartosz Sobczak 	irdma_terminate_start_timer(qp);
1917*cdcd52d4SBartosz Sobczak 	qp->term_flags |= IRDMA_TERM_SENT;
1918*cdcd52d4SBartosz Sobczak 	irdma_term_modify_qp(qp, IRDMA_QP_STATE_TERMINATE,
1919*cdcd52d4SBartosz Sobczak 			     IRDMAQP_TERM_SEND_TERM_ONLY, termlen);
1920*cdcd52d4SBartosz Sobczak }
1921*cdcd52d4SBartosz Sobczak 
1922*cdcd52d4SBartosz Sobczak /**
1923*cdcd52d4SBartosz Sobczak  * irdma_terminate_received - handle terminate received AE
1924*cdcd52d4SBartosz Sobczak  * @qp: qp associated with received terminate AE
1925*cdcd52d4SBartosz Sobczak  * @info: the struct contiaing AE information
1926*cdcd52d4SBartosz Sobczak  */
1927*cdcd52d4SBartosz Sobczak void
1928*cdcd52d4SBartosz Sobczak irdma_terminate_received(struct irdma_sc_qp *qp,
1929*cdcd52d4SBartosz Sobczak 			 struct irdma_aeqe_info *info)
1930*cdcd52d4SBartosz Sobczak {
1931*cdcd52d4SBartosz Sobczak 	u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET;
1932*cdcd52d4SBartosz Sobczak 	BE32 *mpa;
1933*cdcd52d4SBartosz Sobczak 	u8 ddp_ctl;
1934*cdcd52d4SBartosz Sobczak 	u8 rdma_ctl;
1935*cdcd52d4SBartosz Sobczak 	u16 aeq_id = 0;
1936*cdcd52d4SBartosz Sobczak 	struct irdma_terminate_hdr *termhdr;
1937*cdcd52d4SBartosz Sobczak 
1938*cdcd52d4SBartosz Sobczak 	mpa = (BE32 *) irdma_locate_mpa(pkt);
1939*cdcd52d4SBartosz Sobczak 	if (info->q2_data_written) {
1940*cdcd52d4SBartosz Sobczak 		/* did not validate the frame - do it now */
1941*cdcd52d4SBartosz Sobczak 		ddp_ctl = (ntohl(mpa[0]) >> 8) & 0xff;
1942*cdcd52d4SBartosz Sobczak 		rdma_ctl = ntohl(mpa[0]) & 0xff;
1943*cdcd52d4SBartosz Sobczak 		if ((ddp_ctl & 0xc0) != 0x40)
1944*cdcd52d4SBartosz Sobczak 			aeq_id = IRDMA_AE_LCE_QP_CATASTROPHIC;
1945*cdcd52d4SBartosz Sobczak 		else if ((ddp_ctl & 0x03) != 1)
1946*cdcd52d4SBartosz Sobczak 			aeq_id = IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION;
1947*cdcd52d4SBartosz Sobczak 		else if (ntohl(mpa[2]) != 2)
1948*cdcd52d4SBartosz Sobczak 			aeq_id = IRDMA_AE_DDP_UBE_INVALID_QN;
1949*cdcd52d4SBartosz Sobczak 		else if (ntohl(mpa[3]) != 1)
1950*cdcd52d4SBartosz Sobczak 			aeq_id = IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN;
1951*cdcd52d4SBartosz Sobczak 		else if (ntohl(mpa[4]) != 0)
1952*cdcd52d4SBartosz Sobczak 			aeq_id = IRDMA_AE_DDP_UBE_INVALID_MO;
1953*cdcd52d4SBartosz Sobczak 		else if ((rdma_ctl & 0xc0) != 0x40)
1954*cdcd52d4SBartosz Sobczak 			aeq_id = IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION;
1955*cdcd52d4SBartosz Sobczak 
1956*cdcd52d4SBartosz Sobczak 		info->ae_id = aeq_id;
1957*cdcd52d4SBartosz Sobczak 		if (info->ae_id) {
1958*cdcd52d4SBartosz Sobczak 			/* Bad terminate recvd - send back a terminate */
1959*cdcd52d4SBartosz Sobczak 			irdma_terminate_connection(qp, info);
1960*cdcd52d4SBartosz Sobczak 			return;
1961*cdcd52d4SBartosz Sobczak 		}
1962*cdcd52d4SBartosz Sobczak 	}
1963*cdcd52d4SBartosz Sobczak 
1964*cdcd52d4SBartosz Sobczak 	qp->term_flags |= IRDMA_TERM_RCVD;
1965*cdcd52d4SBartosz Sobczak 	qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
1966*cdcd52d4SBartosz Sobczak 	termhdr = (struct irdma_terminate_hdr *)&mpa[5];
1967*cdcd52d4SBartosz Sobczak 	if (termhdr->layer_etype == RDMAP_REMOTE_PROT ||
1968*cdcd52d4SBartosz Sobczak 	    termhdr->layer_etype == RDMAP_REMOTE_OP) {
1969*cdcd52d4SBartosz Sobczak 		irdma_terminate_done(qp, 0);
1970*cdcd52d4SBartosz Sobczak 	} else {
1971*cdcd52d4SBartosz Sobczak 		irdma_terminate_start_timer(qp);
1972*cdcd52d4SBartosz Sobczak 		irdma_terminate_send_fin(qp);
1973*cdcd52d4SBartosz Sobczak 	}
1974*cdcd52d4SBartosz Sobczak }
1975*cdcd52d4SBartosz Sobczak 
1976*cdcd52d4SBartosz Sobczak static int
1977*cdcd52d4SBartosz Sobczak irdma_null_ws_add(struct irdma_sc_vsi *vsi, u8 user_pri)
1978*cdcd52d4SBartosz Sobczak {
1979*cdcd52d4SBartosz Sobczak 	return 0;
1980*cdcd52d4SBartosz Sobczak }
1981*cdcd52d4SBartosz Sobczak 
1982*cdcd52d4SBartosz Sobczak static void
1983*cdcd52d4SBartosz Sobczak irdma_null_ws_remove(struct irdma_sc_vsi *vsi, u8 user_pri)
1984*cdcd52d4SBartosz Sobczak {
1985*cdcd52d4SBartosz Sobczak 	/* do nothing */
1986*cdcd52d4SBartosz Sobczak }
1987*cdcd52d4SBartosz Sobczak 
1988*cdcd52d4SBartosz Sobczak static void
1989*cdcd52d4SBartosz Sobczak irdma_null_ws_reset(struct irdma_sc_vsi *vsi)
1990*cdcd52d4SBartosz Sobczak {
1991*cdcd52d4SBartosz Sobczak 	/* do nothing */
1992*cdcd52d4SBartosz Sobczak }
1993*cdcd52d4SBartosz Sobczak 
1994*cdcd52d4SBartosz Sobczak /**
1995*cdcd52d4SBartosz Sobczak  * irdma_sc_vsi_init - Init the vsi structure
1996*cdcd52d4SBartosz Sobczak  * @vsi: pointer to vsi structure to initialize
1997*cdcd52d4SBartosz Sobczak  * @info: the info used to initialize the vsi struct
1998*cdcd52d4SBartosz Sobczak  */
1999*cdcd52d4SBartosz Sobczak void
2000*cdcd52d4SBartosz Sobczak irdma_sc_vsi_init(struct irdma_sc_vsi *vsi,
2001*cdcd52d4SBartosz Sobczak 		  struct irdma_vsi_init_info *info)
2002*cdcd52d4SBartosz Sobczak {
2003*cdcd52d4SBartosz Sobczak 	u8 i;
2004*cdcd52d4SBartosz Sobczak 
2005*cdcd52d4SBartosz Sobczak 	vsi->dev = info->dev;
2006*cdcd52d4SBartosz Sobczak 	vsi->back_vsi = info->back_vsi;
2007*cdcd52d4SBartosz Sobczak 	vsi->register_qset = info->register_qset;
2008*cdcd52d4SBartosz Sobczak 	vsi->unregister_qset = info->unregister_qset;
2009*cdcd52d4SBartosz Sobczak 	vsi->mtu = info->params->mtu;
2010*cdcd52d4SBartosz Sobczak 	vsi->exception_lan_q = info->exception_lan_q;
2011*cdcd52d4SBartosz Sobczak 	vsi->vsi_idx = info->pf_data_vsi_num;
2012*cdcd52d4SBartosz Sobczak 	if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
2013*cdcd52d4SBartosz Sobczak 		vsi->fcn_id = info->dev->hmc_fn_id;
2014*cdcd52d4SBartosz Sobczak 
2015*cdcd52d4SBartosz Sobczak 	irdma_set_qos_info(vsi, info->params);
2016*cdcd52d4SBartosz Sobczak 	for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
2017*cdcd52d4SBartosz Sobczak 		mutex_init(&vsi->qos[i].qos_mutex);
2018*cdcd52d4SBartosz Sobczak 		INIT_LIST_HEAD(&vsi->qos[i].qplist);
2019*cdcd52d4SBartosz Sobczak 	}
2020*cdcd52d4SBartosz Sobczak 	if (vsi->register_qset) {
2021*cdcd52d4SBartosz Sobczak 		vsi->dev->ws_add = irdma_ws_add;
2022*cdcd52d4SBartosz Sobczak 		vsi->dev->ws_remove = irdma_ws_remove;
2023*cdcd52d4SBartosz Sobczak 		vsi->dev->ws_reset = irdma_ws_reset;
2024*cdcd52d4SBartosz Sobczak 	} else {
2025*cdcd52d4SBartosz Sobczak 		vsi->dev->ws_add = irdma_null_ws_add;
2026*cdcd52d4SBartosz Sobczak 		vsi->dev->ws_remove = irdma_null_ws_remove;
2027*cdcd52d4SBartosz Sobczak 		vsi->dev->ws_reset = irdma_null_ws_reset;
2028*cdcd52d4SBartosz Sobczak 	}
2029*cdcd52d4SBartosz Sobczak }
2030*cdcd52d4SBartosz Sobczak 
2031*cdcd52d4SBartosz Sobczak /**
2032*cdcd52d4SBartosz Sobczak  * irdma_get_fcn_id - Return the function id
2033*cdcd52d4SBartosz Sobczak  * @vsi: pointer to the vsi
2034*cdcd52d4SBartosz Sobczak  */
2035*cdcd52d4SBartosz Sobczak static u8 irdma_get_fcn_id(struct irdma_sc_vsi *vsi){
2036*cdcd52d4SBartosz Sobczak 	struct irdma_stats_inst_info stats_info = {0};
2037*cdcd52d4SBartosz Sobczak 	struct irdma_sc_dev *dev = vsi->dev;
2038*cdcd52d4SBartosz Sobczak 	u8 fcn_id = IRDMA_INVALID_FCN_ID;
2039*cdcd52d4SBartosz Sobczak 	u8 start_idx, max_stats, i;
2040*cdcd52d4SBartosz Sobczak 
2041*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1) {
2042*cdcd52d4SBartosz Sobczak 		if (!irdma_cqp_stats_inst_cmd(vsi, IRDMA_OP_STATS_ALLOCATE,
2043*cdcd52d4SBartosz Sobczak 					      &stats_info))
2044*cdcd52d4SBartosz Sobczak 			return stats_info.stats_idx;
2045*cdcd52d4SBartosz Sobczak 	}
2046*cdcd52d4SBartosz Sobczak 
2047*cdcd52d4SBartosz Sobczak 	start_idx = 1;
2048*cdcd52d4SBartosz Sobczak 	max_stats = 16;
2049*cdcd52d4SBartosz Sobczak 	for (i = start_idx; i < max_stats; i++)
2050*cdcd52d4SBartosz Sobczak 		if (!dev->fcn_id_array[i]) {
2051*cdcd52d4SBartosz Sobczak 			fcn_id = i;
2052*cdcd52d4SBartosz Sobczak 			dev->fcn_id_array[i] = true;
2053*cdcd52d4SBartosz Sobczak 			break;
2054*cdcd52d4SBartosz Sobczak 		}
2055*cdcd52d4SBartosz Sobczak 
2056*cdcd52d4SBartosz Sobczak 	return fcn_id;
2057*cdcd52d4SBartosz Sobczak }
2058*cdcd52d4SBartosz Sobczak 
2059*cdcd52d4SBartosz Sobczak /**
2060*cdcd52d4SBartosz Sobczak  * irdma_vsi_stats_init - Initialize the vsi statistics
2061*cdcd52d4SBartosz Sobczak  * @vsi: pointer to the vsi structure
2062*cdcd52d4SBartosz Sobczak  * @info: The info structure used for initialization
2063*cdcd52d4SBartosz Sobczak  */
2064*cdcd52d4SBartosz Sobczak int
2065*cdcd52d4SBartosz Sobczak irdma_vsi_stats_init(struct irdma_sc_vsi *vsi,
2066*cdcd52d4SBartosz Sobczak 		     struct irdma_vsi_stats_info *info)
2067*cdcd52d4SBartosz Sobczak {
2068*cdcd52d4SBartosz Sobczak 	u8 fcn_id = info->fcn_id;
2069*cdcd52d4SBartosz Sobczak 	struct irdma_dma_mem *stats_buff_mem;
2070*cdcd52d4SBartosz Sobczak 
2071*cdcd52d4SBartosz Sobczak 	vsi->pestat = info->pestat;
2072*cdcd52d4SBartosz Sobczak 	vsi->pestat->hw = vsi->dev->hw;
2073*cdcd52d4SBartosz Sobczak 	vsi->pestat->vsi = vsi;
2074*cdcd52d4SBartosz Sobczak 	stats_buff_mem = &vsi->pestat->gather_info.stats_buff_mem;
2075*cdcd52d4SBartosz Sobczak 	stats_buff_mem->size = IRDMA_GATHER_STATS_BUF_SIZE * 2;
2076*cdcd52d4SBartosz Sobczak 	stats_buff_mem->va = irdma_allocate_dma_mem(vsi->pestat->hw,
2077*cdcd52d4SBartosz Sobczak 						    stats_buff_mem,
2078*cdcd52d4SBartosz Sobczak 						    stats_buff_mem->size, 1);
2079*cdcd52d4SBartosz Sobczak 	if (!stats_buff_mem->va)
2080*cdcd52d4SBartosz Sobczak 		return -ENOMEM;
2081*cdcd52d4SBartosz Sobczak 
2082*cdcd52d4SBartosz Sobczak 	vsi->pestat->gather_info.gather_stats_va = stats_buff_mem->va;
2083*cdcd52d4SBartosz Sobczak 	vsi->pestat->gather_info.last_gather_stats_va =
2084*cdcd52d4SBartosz Sobczak 	    (void *)((uintptr_t)stats_buff_mem->va +
2085*cdcd52d4SBartosz Sobczak 		     IRDMA_GATHER_STATS_BUF_SIZE);
2086*cdcd52d4SBartosz Sobczak 
2087*cdcd52d4SBartosz Sobczak 	irdma_hw_stats_start_timer(vsi);
2088*cdcd52d4SBartosz Sobczak 	if (info->alloc_fcn_id)
2089*cdcd52d4SBartosz Sobczak 		fcn_id = irdma_get_fcn_id(vsi);
2090*cdcd52d4SBartosz Sobczak 	if (fcn_id == IRDMA_INVALID_FCN_ID)
2091*cdcd52d4SBartosz Sobczak 		goto stats_error;
2092*cdcd52d4SBartosz Sobczak 
2093*cdcd52d4SBartosz Sobczak 	vsi->stats_fcn_id_alloc = info->alloc_fcn_id;
2094*cdcd52d4SBartosz Sobczak 	vsi->fcn_id = fcn_id;
2095*cdcd52d4SBartosz Sobczak 	if (info->alloc_fcn_id) {
2096*cdcd52d4SBartosz Sobczak 		vsi->pestat->gather_info.use_stats_inst = true;
2097*cdcd52d4SBartosz Sobczak 		vsi->pestat->gather_info.stats_inst_index = fcn_id;
2098*cdcd52d4SBartosz Sobczak 	}
2099*cdcd52d4SBartosz Sobczak 
2100*cdcd52d4SBartosz Sobczak 	return 0;
2101*cdcd52d4SBartosz Sobczak 
2102*cdcd52d4SBartosz Sobczak stats_error:
2103*cdcd52d4SBartosz Sobczak 	irdma_free_dma_mem(vsi->pestat->hw, stats_buff_mem);
2104*cdcd52d4SBartosz Sobczak 
2105*cdcd52d4SBartosz Sobczak 	return -EIO;
2106*cdcd52d4SBartosz Sobczak }
2107*cdcd52d4SBartosz Sobczak 
2108*cdcd52d4SBartosz Sobczak /**
2109*cdcd52d4SBartosz Sobczak  * irdma_vsi_stats_free - Free the vsi stats
2110*cdcd52d4SBartosz Sobczak  * @vsi: pointer to the vsi structure
2111*cdcd52d4SBartosz Sobczak  */
2112*cdcd52d4SBartosz Sobczak void
2113*cdcd52d4SBartosz Sobczak irdma_vsi_stats_free(struct irdma_sc_vsi *vsi)
2114*cdcd52d4SBartosz Sobczak {
2115*cdcd52d4SBartosz Sobczak 	struct irdma_stats_inst_info stats_info = {0};
2116*cdcd52d4SBartosz Sobczak 	u8 fcn_id = vsi->fcn_id;
2117*cdcd52d4SBartosz Sobczak 	struct irdma_sc_dev *dev = vsi->dev;
2118*cdcd52d4SBartosz Sobczak 
2119*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1) {
2120*cdcd52d4SBartosz Sobczak 		if (vsi->stats_fcn_id_alloc) {
2121*cdcd52d4SBartosz Sobczak 			stats_info.stats_idx = vsi->fcn_id;
2122*cdcd52d4SBartosz Sobczak 			irdma_cqp_stats_inst_cmd(vsi, IRDMA_OP_STATS_FREE,
2123*cdcd52d4SBartosz Sobczak 						 &stats_info);
2124*cdcd52d4SBartosz Sobczak 		}
2125*cdcd52d4SBartosz Sobczak 	} else {
2126*cdcd52d4SBartosz Sobczak 		if (vsi->stats_fcn_id_alloc &&
2127*cdcd52d4SBartosz Sobczak 		    fcn_id < vsi->dev->hw_attrs.max_stat_inst)
2128*cdcd52d4SBartosz Sobczak 			vsi->dev->fcn_id_array[fcn_id] = false;
2129*cdcd52d4SBartosz Sobczak 	}
2130*cdcd52d4SBartosz Sobczak 
2131*cdcd52d4SBartosz Sobczak 	if (!vsi->pestat)
2132*cdcd52d4SBartosz Sobczak 		return;
2133*cdcd52d4SBartosz Sobczak 	irdma_hw_stats_stop_timer(vsi);
2134*cdcd52d4SBartosz Sobczak 	irdma_free_dma_mem(vsi->pestat->hw,
2135*cdcd52d4SBartosz Sobczak 			   &vsi->pestat->gather_info.stats_buff_mem);
2136*cdcd52d4SBartosz Sobczak }
2137*cdcd52d4SBartosz Sobczak 
2138*cdcd52d4SBartosz Sobczak /**
2139*cdcd52d4SBartosz Sobczak  * irdma_get_encoded_wqe_size - given wq size, returns hardware encoded size
2140*cdcd52d4SBartosz Sobczak  * @wqsize: size of the wq (sq, rq) to encoded_size
2141*cdcd52d4SBartosz Sobczak  * @queue_type: queue type selected for the calculation algorithm
2142*cdcd52d4SBartosz Sobczak  */
2143*cdcd52d4SBartosz Sobczak u8
2144*cdcd52d4SBartosz Sobczak irdma_get_encoded_wqe_size(u32 wqsize, enum irdma_queue_type queue_type)
2145*cdcd52d4SBartosz Sobczak {
2146*cdcd52d4SBartosz Sobczak 	u8 encoded_size = 0;
2147*cdcd52d4SBartosz Sobczak 
2148*cdcd52d4SBartosz Sobczak 	/*
2149*cdcd52d4SBartosz Sobczak 	 * cqp sq's hw coded value starts from 1 for size of 4 while it starts from 0 for qp' wq's.
2150*cdcd52d4SBartosz Sobczak 	 */
2151*cdcd52d4SBartosz Sobczak 	if (queue_type == IRDMA_QUEUE_TYPE_CQP)
2152*cdcd52d4SBartosz Sobczak 		encoded_size = 1;
2153*cdcd52d4SBartosz Sobczak 	wqsize >>= 2;
2154*cdcd52d4SBartosz Sobczak 	while (wqsize >>= 1)
2155*cdcd52d4SBartosz Sobczak 		encoded_size++;
2156*cdcd52d4SBartosz Sobczak 
2157*cdcd52d4SBartosz Sobczak 	return encoded_size;
2158*cdcd52d4SBartosz Sobczak }
2159*cdcd52d4SBartosz Sobczak 
2160*cdcd52d4SBartosz Sobczak /**
2161*cdcd52d4SBartosz Sobczak  * irdma_sc_gather_stats - collect the statistics
2162*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2163*cdcd52d4SBartosz Sobczak  * @info: gather stats info structure
2164*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2165*cdcd52d4SBartosz Sobczak  */
2166*cdcd52d4SBartosz Sobczak static int
2167*cdcd52d4SBartosz Sobczak irdma_sc_gather_stats(struct irdma_sc_cqp *cqp,
2168*cdcd52d4SBartosz Sobczak 		      struct irdma_stats_gather_info *info,
2169*cdcd52d4SBartosz Sobczak 		      u64 scratch)
2170*cdcd52d4SBartosz Sobczak {
2171*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2172*cdcd52d4SBartosz Sobczak 	u64 temp;
2173*cdcd52d4SBartosz Sobczak 
2174*cdcd52d4SBartosz Sobczak 	if (info->stats_buff_mem.size < IRDMA_GATHER_STATS_BUF_SIZE)
2175*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2176*cdcd52d4SBartosz Sobczak 
2177*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2178*cdcd52d4SBartosz Sobczak 	if (!wqe)
2179*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2180*cdcd52d4SBartosz Sobczak 
2181*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40,
2182*cdcd52d4SBartosz Sobczak 		      LS_64(info->hmc_fcn_index, IRDMA_CQPSQ_STATS_HMC_FCN_INDEX));
2183*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, info->stats_buff_mem.pa);
2184*cdcd52d4SBartosz Sobczak 
2185*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->polarity, IRDMA_CQPSQ_STATS_WQEVALID) |
2186*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_stats_inst, IRDMA_CQPSQ_STATS_USE_INST) |
2187*cdcd52d4SBartosz Sobczak 	    LS_64(info->stats_inst_index, IRDMA_CQPSQ_STATS_INST_INDEX) |
2188*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_hmc_fcn_index,
2189*cdcd52d4SBartosz Sobczak 		  IRDMA_CQPSQ_STATS_USE_HMC_FCN_INDEX) |
2190*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_GATHER_STATS, IRDMA_CQPSQ_STATS_OP);
2191*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2192*cdcd52d4SBartosz Sobczak 
2193*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, temp);
2194*cdcd52d4SBartosz Sobczak 
2195*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_STATS, "GATHER_STATS WQE", wqe,
2196*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2197*cdcd52d4SBartosz Sobczak 
2198*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
2199*cdcd52d4SBartosz Sobczak 	irdma_debug(cqp->dev, IRDMA_DEBUG_STATS,
2200*cdcd52d4SBartosz Sobczak 		    "CQP SQ head 0x%x tail 0x%x size 0x%x\n", cqp->sq_ring.head,
2201*cdcd52d4SBartosz Sobczak 		    cqp->sq_ring.tail, cqp->sq_ring.size);
2202*cdcd52d4SBartosz Sobczak 
2203*cdcd52d4SBartosz Sobczak 	return 0;
2204*cdcd52d4SBartosz Sobczak }
2205*cdcd52d4SBartosz Sobczak 
2206*cdcd52d4SBartosz Sobczak /**
2207*cdcd52d4SBartosz Sobczak  * irdma_sc_manage_stats_inst - allocate or free stats instance
2208*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2209*cdcd52d4SBartosz Sobczak  * @info: stats info structure
2210*cdcd52d4SBartosz Sobczak  * @alloc: alloc vs. delete flag
2211*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2212*cdcd52d4SBartosz Sobczak  */
2213*cdcd52d4SBartosz Sobczak static int
2214*cdcd52d4SBartosz Sobczak irdma_sc_manage_stats_inst(struct irdma_sc_cqp *cqp,
2215*cdcd52d4SBartosz Sobczak 			   struct irdma_stats_inst_info *info,
2216*cdcd52d4SBartosz Sobczak 			   bool alloc, u64 scratch)
2217*cdcd52d4SBartosz Sobczak {
2218*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2219*cdcd52d4SBartosz Sobczak 	u64 temp;
2220*cdcd52d4SBartosz Sobczak 
2221*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2222*cdcd52d4SBartosz Sobczak 	if (!wqe)
2223*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2224*cdcd52d4SBartosz Sobczak 
2225*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40,
2226*cdcd52d4SBartosz Sobczak 		      LS_64(info->hmc_fn_id, IRDMA_CQPSQ_STATS_HMC_FCN_INDEX));
2227*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->polarity, IRDMA_CQPSQ_STATS_WQEVALID) |
2228*cdcd52d4SBartosz Sobczak 	    LS_64(alloc, IRDMA_CQPSQ_STATS_ALLOC_INST) |
2229*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_hmc_fcn_index, IRDMA_CQPSQ_STATS_USE_HMC_FCN_INDEX) |
2230*cdcd52d4SBartosz Sobczak 	    LS_64(info->stats_idx, IRDMA_CQPSQ_STATS_INST_INDEX) |
2231*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_STATS, IRDMA_CQPSQ_STATS_OP);
2232*cdcd52d4SBartosz Sobczak 
2233*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2234*cdcd52d4SBartosz Sobczak 
2235*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, temp);
2236*cdcd52d4SBartosz Sobczak 
2237*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_STATS WQE", wqe,
2238*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2239*cdcd52d4SBartosz Sobczak 
2240*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
2241*cdcd52d4SBartosz Sobczak 	return 0;
2242*cdcd52d4SBartosz Sobczak }
2243*cdcd52d4SBartosz Sobczak 
2244*cdcd52d4SBartosz Sobczak /**
2245*cdcd52d4SBartosz Sobczak  * irdma_sc_set_up_map - set the up map table
2246*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2247*cdcd52d4SBartosz Sobczak  * @info: User priority map info
2248*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2249*cdcd52d4SBartosz Sobczak  */
2250*cdcd52d4SBartosz Sobczak static int
2251*cdcd52d4SBartosz Sobczak irdma_sc_set_up_map(struct irdma_sc_cqp *cqp,
2252*cdcd52d4SBartosz Sobczak 		    struct irdma_up_info *info, u64 scratch)
2253*cdcd52d4SBartosz Sobczak {
2254*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2255*cdcd52d4SBartosz Sobczak 	u64 temp;
2256*cdcd52d4SBartosz Sobczak 
2257*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2258*cdcd52d4SBartosz Sobczak 	if (!wqe)
2259*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2260*cdcd52d4SBartosz Sobczak 
2261*cdcd52d4SBartosz Sobczak 	temp = info->map[0] | LS_64_1(info->map[1], 8) |
2262*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->map[2], 16) | LS_64_1(info->map[3], 24) |
2263*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->map[4], 32) | LS_64_1(info->map[5], 40) |
2264*cdcd52d4SBartosz Sobczak 	    LS_64_1(info->map[6], 48) | LS_64_1(info->map[7], 56);
2265*cdcd52d4SBartosz Sobczak 
2266*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, temp);
2267*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40,
2268*cdcd52d4SBartosz Sobczak 		      LS_64(info->cnp_up_override, IRDMA_CQPSQ_UP_CNPOVERRIDE) |
2269*cdcd52d4SBartosz Sobczak 		      LS_64(info->hmc_fcn_idx, IRDMA_CQPSQ_UP_HMCFCNIDX));
2270*cdcd52d4SBartosz Sobczak 
2271*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->polarity, IRDMA_CQPSQ_UP_WQEVALID) |
2272*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_vlan, IRDMA_CQPSQ_UP_USEVLAN) |
2273*cdcd52d4SBartosz Sobczak 	    LS_64(info->use_cnp_up_override, IRDMA_CQPSQ_UP_USEOVERRIDE) |
2274*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_UP_MAP, IRDMA_CQPSQ_UP_OP);
2275*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2276*cdcd52d4SBartosz Sobczak 
2277*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, temp);
2278*cdcd52d4SBartosz Sobczak 
2279*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "UPMAP WQE", wqe,
2280*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2281*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
2282*cdcd52d4SBartosz Sobczak 
2283*cdcd52d4SBartosz Sobczak 	return 0;
2284*cdcd52d4SBartosz Sobczak }
2285*cdcd52d4SBartosz Sobczak 
2286*cdcd52d4SBartosz Sobczak /**
2287*cdcd52d4SBartosz Sobczak  * irdma_sc_manage_ws_node - create/modify/destroy WS node
2288*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2289*cdcd52d4SBartosz Sobczak  * @info: node info structure
2290*cdcd52d4SBartosz Sobczak  * @node_op: 0 for add 1 for modify, 2 for delete
2291*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2292*cdcd52d4SBartosz Sobczak  */
2293*cdcd52d4SBartosz Sobczak static int
2294*cdcd52d4SBartosz Sobczak irdma_sc_manage_ws_node(struct irdma_sc_cqp *cqp,
2295*cdcd52d4SBartosz Sobczak 			struct irdma_ws_node_info *info,
2296*cdcd52d4SBartosz Sobczak 			enum irdma_ws_node_op node_op, u64 scratch)
2297*cdcd52d4SBartosz Sobczak {
2298*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2299*cdcd52d4SBartosz Sobczak 	u64 temp = 0;
2300*cdcd52d4SBartosz Sobczak 
2301*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2302*cdcd52d4SBartosz Sobczak 	if (!wqe)
2303*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2304*cdcd52d4SBartosz Sobczak 
2305*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32,
2306*cdcd52d4SBartosz Sobczak 		      LS_64(info->vsi, IRDMA_CQPSQ_WS_VSI) |
2307*cdcd52d4SBartosz Sobczak 		      LS_64(info->weight, IRDMA_CQPSQ_WS_WEIGHT));
2308*cdcd52d4SBartosz Sobczak 
2309*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->polarity, IRDMA_CQPSQ_WS_WQEVALID) |
2310*cdcd52d4SBartosz Sobczak 	    LS_64(node_op, IRDMA_CQPSQ_WS_NODEOP) |
2311*cdcd52d4SBartosz Sobczak 	    LS_64(info->enable, IRDMA_CQPSQ_WS_ENABLENODE) |
2312*cdcd52d4SBartosz Sobczak 	    LS_64(info->type_leaf, IRDMA_CQPSQ_WS_NODETYPE) |
2313*cdcd52d4SBartosz Sobczak 	    LS_64(info->prio_type, IRDMA_CQPSQ_WS_PRIOTYPE) |
2314*cdcd52d4SBartosz Sobczak 	    LS_64(info->tc, IRDMA_CQPSQ_WS_TC) |
2315*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_WORK_SCHED_NODE, IRDMA_CQPSQ_WS_OP) |
2316*cdcd52d4SBartosz Sobczak 	    LS_64(info->parent_id, IRDMA_CQPSQ_WS_PARENTID) |
2317*cdcd52d4SBartosz Sobczak 	    LS_64(info->id, IRDMA_CQPSQ_WS_NODEID);
2318*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2319*cdcd52d4SBartosz Sobczak 
2320*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, temp);
2321*cdcd52d4SBartosz Sobczak 
2322*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_WS WQE", wqe,
2323*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2324*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
2325*cdcd52d4SBartosz Sobczak 
2326*cdcd52d4SBartosz Sobczak 	return 0;
2327*cdcd52d4SBartosz Sobczak }
2328*cdcd52d4SBartosz Sobczak 
2329*cdcd52d4SBartosz Sobczak /**
2330*cdcd52d4SBartosz Sobczak  * irdma_sc_qp_flush_wqes - flush qp's wqe
2331*cdcd52d4SBartosz Sobczak  * @qp: sc qp
2332*cdcd52d4SBartosz Sobczak  * @info: dlush information
2333*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2334*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
2335*cdcd52d4SBartosz Sobczak  */
2336*cdcd52d4SBartosz Sobczak int
2337*cdcd52d4SBartosz Sobczak irdma_sc_qp_flush_wqes(struct irdma_sc_qp *qp,
2338*cdcd52d4SBartosz Sobczak 		       struct irdma_qp_flush_info *info, u64 scratch,
2339*cdcd52d4SBartosz Sobczak 		       bool post_sq)
2340*cdcd52d4SBartosz Sobczak {
2341*cdcd52d4SBartosz Sobczak 	u64 temp = 0;
2342*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2343*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
2344*cdcd52d4SBartosz Sobczak 	u64 hdr;
2345*cdcd52d4SBartosz Sobczak 	bool flush_sq = false, flush_rq = false;
2346*cdcd52d4SBartosz Sobczak 
2347*cdcd52d4SBartosz Sobczak 	if (info->rq && !qp->flush_rq)
2348*cdcd52d4SBartosz Sobczak 		flush_rq = true;
2349*cdcd52d4SBartosz Sobczak 	if (info->sq && !qp->flush_sq)
2350*cdcd52d4SBartosz Sobczak 		flush_sq = true;
2351*cdcd52d4SBartosz Sobczak 	qp->flush_sq |= flush_sq;
2352*cdcd52d4SBartosz Sobczak 	qp->flush_rq |= flush_rq;
2353*cdcd52d4SBartosz Sobczak 
2354*cdcd52d4SBartosz Sobczak 	if (!flush_sq && !flush_rq) {
2355*cdcd52d4SBartosz Sobczak 		irdma_debug(qp->dev, IRDMA_DEBUG_CQP,
2356*cdcd52d4SBartosz Sobczak 			    "Additional flush request ignored for qp %x\n", qp->qp_uk.qp_id);
2357*cdcd52d4SBartosz Sobczak 		return -EALREADY;
2358*cdcd52d4SBartosz Sobczak 	}
2359*cdcd52d4SBartosz Sobczak 
2360*cdcd52d4SBartosz Sobczak 	cqp = qp->pd->dev->cqp;
2361*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2362*cdcd52d4SBartosz Sobczak 	if (!wqe)
2363*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2364*cdcd52d4SBartosz Sobczak 
2365*cdcd52d4SBartosz Sobczak 	if (info->userflushcode) {
2366*cdcd52d4SBartosz Sobczak 		if (flush_rq)
2367*cdcd52d4SBartosz Sobczak 			temp |= LS_64(info->rq_minor_code, IRDMA_CQPSQ_FWQE_RQMNERR) |
2368*cdcd52d4SBartosz Sobczak 			    LS_64(info->rq_major_code, IRDMA_CQPSQ_FWQE_RQMJERR);
2369*cdcd52d4SBartosz Sobczak 		if (flush_sq)
2370*cdcd52d4SBartosz Sobczak 			temp |= LS_64(info->sq_minor_code, IRDMA_CQPSQ_FWQE_SQMNERR) |
2371*cdcd52d4SBartosz Sobczak 			    LS_64(info->sq_major_code, IRDMA_CQPSQ_FWQE_SQMJERR);
2372*cdcd52d4SBartosz Sobczak 	}
2373*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, temp);
2374*cdcd52d4SBartosz Sobczak 
2375*cdcd52d4SBartosz Sobczak 	temp = (info->generate_ae) ?
2376*cdcd52d4SBartosz Sobczak 	    info->ae_code | LS_64(info->ae_src, IRDMA_CQPSQ_FWQE_AESOURCE) : 0;
2377*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, temp);
2378*cdcd52d4SBartosz Sobczak 
2379*cdcd52d4SBartosz Sobczak 	hdr = qp->qp_uk.qp_id |
2380*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_FLUSH_WQES, IRDMA_CQPSQ_OPCODE) |
2381*cdcd52d4SBartosz Sobczak 	    LS_64(info->generate_ae, IRDMA_CQPSQ_FWQE_GENERATE_AE) |
2382*cdcd52d4SBartosz Sobczak 	    LS_64(info->userflushcode, IRDMA_CQPSQ_FWQE_USERFLCODE) |
2383*cdcd52d4SBartosz Sobczak 	    LS_64(flush_sq, IRDMA_CQPSQ_FWQE_FLUSHSQ) |
2384*cdcd52d4SBartosz Sobczak 	    LS_64(flush_rq, IRDMA_CQPSQ_FWQE_FLUSHRQ) |
2385*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2386*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2387*cdcd52d4SBartosz Sobczak 
2388*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2389*cdcd52d4SBartosz Sobczak 
2390*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "QP_FLUSH WQE", wqe,
2391*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2392*cdcd52d4SBartosz Sobczak 	if (post_sq)
2393*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2394*cdcd52d4SBartosz Sobczak 
2395*cdcd52d4SBartosz Sobczak 	return 0;
2396*cdcd52d4SBartosz Sobczak }
2397*cdcd52d4SBartosz Sobczak 
2398*cdcd52d4SBartosz Sobczak /**
2399*cdcd52d4SBartosz Sobczak  * irdma_sc_gen_ae - generate AE, uses flush WQE CQP OP
2400*cdcd52d4SBartosz Sobczak  * @qp: sc qp
2401*cdcd52d4SBartosz Sobczak  * @info: gen ae information
2402*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2403*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
2404*cdcd52d4SBartosz Sobczak  */
2405*cdcd52d4SBartosz Sobczak static int
2406*cdcd52d4SBartosz Sobczak irdma_sc_gen_ae(struct irdma_sc_qp *qp,
2407*cdcd52d4SBartosz Sobczak 		struct irdma_gen_ae_info *info, u64 scratch,
2408*cdcd52d4SBartosz Sobczak 		bool post_sq)
2409*cdcd52d4SBartosz Sobczak {
2410*cdcd52d4SBartosz Sobczak 	u64 temp;
2411*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2412*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
2413*cdcd52d4SBartosz Sobczak 	u64 hdr;
2414*cdcd52d4SBartosz Sobczak 
2415*cdcd52d4SBartosz Sobczak 	cqp = qp->pd->dev->cqp;
2416*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2417*cdcd52d4SBartosz Sobczak 	if (!wqe)
2418*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2419*cdcd52d4SBartosz Sobczak 
2420*cdcd52d4SBartosz Sobczak 	temp = info->ae_code | LS_64(info->ae_src, IRDMA_CQPSQ_FWQE_AESOURCE);
2421*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, temp);
2422*cdcd52d4SBartosz Sobczak 
2423*cdcd52d4SBartosz Sobczak 	hdr = qp->qp_uk.qp_id | LS_64(IRDMA_CQP_OP_GEN_AE, IRDMA_CQPSQ_OPCODE) |
2424*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMA_CQPSQ_FWQE_GENERATE_AE) |
2425*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2426*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2427*cdcd52d4SBartosz Sobczak 
2428*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2429*cdcd52d4SBartosz Sobczak 
2430*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "GEN_AE WQE", wqe,
2431*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2432*cdcd52d4SBartosz Sobczak 	if (post_sq)
2433*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2434*cdcd52d4SBartosz Sobczak 
2435*cdcd52d4SBartosz Sobczak 	return 0;
2436*cdcd52d4SBartosz Sobczak }
2437*cdcd52d4SBartosz Sobczak 
2438*cdcd52d4SBartosz Sobczak /*** irdma_sc_qp_upload_context - upload qp's context
2439*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
2440*cdcd52d4SBartosz Sobczak  * @info: upload context info ptr for return
2441*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2442*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
2443*cdcd52d4SBartosz Sobczak  */
2444*cdcd52d4SBartosz Sobczak static int
2445*cdcd52d4SBartosz Sobczak irdma_sc_qp_upload_context(struct irdma_sc_dev *dev,
2446*cdcd52d4SBartosz Sobczak 			   struct irdma_upload_context_info *info,
2447*cdcd52d4SBartosz Sobczak 			   u64 scratch, bool post_sq)
2448*cdcd52d4SBartosz Sobczak {
2449*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2450*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
2451*cdcd52d4SBartosz Sobczak 	u64 hdr;
2452*cdcd52d4SBartosz Sobczak 
2453*cdcd52d4SBartosz Sobczak 	cqp = dev->cqp;
2454*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2455*cdcd52d4SBartosz Sobczak 	if (!wqe)
2456*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2457*cdcd52d4SBartosz Sobczak 
2458*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, info->buf_pa);
2459*cdcd52d4SBartosz Sobczak 
2460*cdcd52d4SBartosz Sobczak 	hdr = LS_64(info->qp_id, IRDMA_CQPSQ_UCTX_QPID) |
2461*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_UPLOAD_CONTEXT, IRDMA_CQPSQ_OPCODE) |
2462*cdcd52d4SBartosz Sobczak 	    LS_64(info->qp_type, IRDMA_CQPSQ_UCTX_QPTYPE) |
2463*cdcd52d4SBartosz Sobczak 	    LS_64(info->raw_format, IRDMA_CQPSQ_UCTX_RAWFORMAT) |
2464*cdcd52d4SBartosz Sobczak 	    LS_64(info->freeze_qp, IRDMA_CQPSQ_UCTX_FREEZEQP) |
2465*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2466*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2467*cdcd52d4SBartosz Sobczak 
2468*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2469*cdcd52d4SBartosz Sobczak 
2470*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "QP_UPLOAD_CTX WQE", wqe,
2471*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2472*cdcd52d4SBartosz Sobczak 	if (post_sq)
2473*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2474*cdcd52d4SBartosz Sobczak 
2475*cdcd52d4SBartosz Sobczak 	return 0;
2476*cdcd52d4SBartosz Sobczak }
2477*cdcd52d4SBartosz Sobczak 
2478*cdcd52d4SBartosz Sobczak /**
2479*cdcd52d4SBartosz Sobczak  * irdma_sc_manage_push_page - Handle push page
2480*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2481*cdcd52d4SBartosz Sobczak  * @info: push page info
2482*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2483*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
2484*cdcd52d4SBartosz Sobczak  */
2485*cdcd52d4SBartosz Sobczak static int
2486*cdcd52d4SBartosz Sobczak irdma_sc_manage_push_page(struct irdma_sc_cqp *cqp,
2487*cdcd52d4SBartosz Sobczak 			  struct irdma_cqp_manage_push_page_info *info,
2488*cdcd52d4SBartosz Sobczak 			  u64 scratch, bool post_sq)
2489*cdcd52d4SBartosz Sobczak {
2490*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2491*cdcd52d4SBartosz Sobczak 	u64 hdr;
2492*cdcd52d4SBartosz Sobczak 
2493*cdcd52d4SBartosz Sobczak 	if (info->free_page &&
2494*cdcd52d4SBartosz Sobczak 	    info->push_idx >= cqp->dev->hw_attrs.max_hw_device_pages)
2495*cdcd52d4SBartosz Sobczak 		return -EINVAL;
2496*cdcd52d4SBartosz Sobczak 
2497*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2498*cdcd52d4SBartosz Sobczak 	if (!wqe)
2499*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2500*cdcd52d4SBartosz Sobczak 
2501*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, info->qs_handle);
2502*cdcd52d4SBartosz Sobczak 	hdr = LS_64(info->push_idx, IRDMA_CQPSQ_MPP_PPIDX) |
2503*cdcd52d4SBartosz Sobczak 	    LS_64(info->push_page_type, IRDMA_CQPSQ_MPP_PPTYPE) |
2504*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_PUSH_PAGES, IRDMA_CQPSQ_OPCODE) |
2505*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID) |
2506*cdcd52d4SBartosz Sobczak 	    LS_64(info->free_page, IRDMA_CQPSQ_MPP_FREE_PAGE);
2507*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2508*cdcd52d4SBartosz Sobczak 
2509*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2510*cdcd52d4SBartosz Sobczak 
2511*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_PUSH_PAGES WQE", wqe,
2512*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2513*cdcd52d4SBartosz Sobczak 	if (post_sq)
2514*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2515*cdcd52d4SBartosz Sobczak 
2516*cdcd52d4SBartosz Sobczak 	return 0;
2517*cdcd52d4SBartosz Sobczak }
2518*cdcd52d4SBartosz Sobczak 
2519*cdcd52d4SBartosz Sobczak /**
2520*cdcd52d4SBartosz Sobczak  * irdma_sc_suspend_qp - suspend qp for param change
2521*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2522*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
2523*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2524*cdcd52d4SBartosz Sobczak  */
2525*cdcd52d4SBartosz Sobczak static int
2526*cdcd52d4SBartosz Sobczak irdma_sc_suspend_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp,
2527*cdcd52d4SBartosz Sobczak 		    u64 scratch)
2528*cdcd52d4SBartosz Sobczak {
2529*cdcd52d4SBartosz Sobczak 	u64 hdr;
2530*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2531*cdcd52d4SBartosz Sobczak 
2532*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2533*cdcd52d4SBartosz Sobczak 	if (!wqe)
2534*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2535*cdcd52d4SBartosz Sobczak 
2536*cdcd52d4SBartosz Sobczak 	hdr = LS_64(qp->qp_uk.qp_id, IRDMA_CQPSQ_SUSPENDQP_QPID) |
2537*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_SUSPEND_QP, IRDMA_CQPSQ_OPCODE) |
2538*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2539*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2540*cdcd52d4SBartosz Sobczak 
2541*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2542*cdcd52d4SBartosz Sobczak 
2543*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "SUSPEND_QP WQE", wqe,
2544*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2545*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
2546*cdcd52d4SBartosz Sobczak 
2547*cdcd52d4SBartosz Sobczak 	return 0;
2548*cdcd52d4SBartosz Sobczak }
2549*cdcd52d4SBartosz Sobczak 
2550*cdcd52d4SBartosz Sobczak /**
2551*cdcd52d4SBartosz Sobczak  * irdma_sc_resume_qp - resume qp after suspend
2552*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2553*cdcd52d4SBartosz Sobczak  * @qp: sc qp struct
2554*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2555*cdcd52d4SBartosz Sobczak  */
2556*cdcd52d4SBartosz Sobczak static int
2557*cdcd52d4SBartosz Sobczak irdma_sc_resume_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp,
2558*cdcd52d4SBartosz Sobczak 		   u64 scratch)
2559*cdcd52d4SBartosz Sobczak {
2560*cdcd52d4SBartosz Sobczak 	u64 hdr;
2561*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2562*cdcd52d4SBartosz Sobczak 
2563*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2564*cdcd52d4SBartosz Sobczak 	if (!wqe)
2565*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2566*cdcd52d4SBartosz Sobczak 
2567*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
2568*cdcd52d4SBartosz Sobczak 		      LS_64(qp->qs_handle, IRDMA_CQPSQ_RESUMEQP_QSHANDLE));
2569*cdcd52d4SBartosz Sobczak 
2570*cdcd52d4SBartosz Sobczak 	hdr = LS_64(qp->qp_uk.qp_id, IRDMA_CQPSQ_RESUMEQP_QPID) |
2571*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_RESUME_QP, IRDMA_CQPSQ_OPCODE) |
2572*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2573*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2574*cdcd52d4SBartosz Sobczak 
2575*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2576*cdcd52d4SBartosz Sobczak 
2577*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "RESUME_QP WQE", wqe,
2578*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2579*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
2580*cdcd52d4SBartosz Sobczak 
2581*cdcd52d4SBartosz Sobczak 	return 0;
2582*cdcd52d4SBartosz Sobczak }
2583*cdcd52d4SBartosz Sobczak 
2584*cdcd52d4SBartosz Sobczak /**
2585*cdcd52d4SBartosz Sobczak  * irdma_sc_cq_ack - acknowledge completion q
2586*cdcd52d4SBartosz Sobczak  * @cq: cq struct
2587*cdcd52d4SBartosz Sobczak  */
2588*cdcd52d4SBartosz Sobczak static inline void
2589*cdcd52d4SBartosz Sobczak irdma_sc_cq_ack(struct irdma_sc_cq *cq)
2590*cdcd52d4SBartosz Sobczak {
2591*cdcd52d4SBartosz Sobczak 	db_wr32(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);
2592*cdcd52d4SBartosz Sobczak }
2593*cdcd52d4SBartosz Sobczak 
2594*cdcd52d4SBartosz Sobczak /**
2595*cdcd52d4SBartosz Sobczak  * irdma_sc_cq_init - initialize completion q
2596*cdcd52d4SBartosz Sobczak  * @cq: cq struct
2597*cdcd52d4SBartosz Sobczak  * @info: cq initialization info
2598*cdcd52d4SBartosz Sobczak  */
2599*cdcd52d4SBartosz Sobczak int
2600*cdcd52d4SBartosz Sobczak irdma_sc_cq_init(struct irdma_sc_cq *cq, struct irdma_cq_init_info *info)
2601*cdcd52d4SBartosz Sobczak {
2602*cdcd52d4SBartosz Sobczak 	int ret_code;
2603*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
2604*cdcd52d4SBartosz Sobczak 
2605*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
2606*cdcd52d4SBartosz Sobczak 	if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
2607*cdcd52d4SBartosz Sobczak 		return -EINVAL;
2608*cdcd52d4SBartosz Sobczak 
2609*cdcd52d4SBartosz Sobczak 	cq->cq_pa = info->cq_base_pa;
2610*cdcd52d4SBartosz Sobczak 	cq->dev = info->dev;
2611*cdcd52d4SBartosz Sobczak 	cq->ceq_id = info->ceq_id;
2612*cdcd52d4SBartosz Sobczak 	info->cq_uk_init_info.cqe_alloc_db = cq->dev->cq_arm_db;
2613*cdcd52d4SBartosz Sobczak 	info->cq_uk_init_info.cq_ack_db = cq->dev->cq_ack_db;
2614*cdcd52d4SBartosz Sobczak 	ret_code = irdma_uk_cq_init(&cq->cq_uk, &info->cq_uk_init_info);
2615*cdcd52d4SBartosz Sobczak 	if (ret_code)
2616*cdcd52d4SBartosz Sobczak 		return ret_code;
2617*cdcd52d4SBartosz Sobczak 
2618*cdcd52d4SBartosz Sobczak 	cq->virtual_map = info->virtual_map;
2619*cdcd52d4SBartosz Sobczak 	cq->pbl_chunk_size = info->pbl_chunk_size;
2620*cdcd52d4SBartosz Sobczak 	cq->ceqe_mask = info->ceqe_mask;
2621*cdcd52d4SBartosz Sobczak 	cq->cq_type = (info->type) ? info->type : IRDMA_CQ_TYPE_IWARP;
2622*cdcd52d4SBartosz Sobczak 	cq->shadow_area_pa = info->shadow_area_pa;
2623*cdcd52d4SBartosz Sobczak 	cq->shadow_read_threshold = info->shadow_read_threshold;
2624*cdcd52d4SBartosz Sobczak 	cq->ceq_id_valid = info->ceq_id_valid;
2625*cdcd52d4SBartosz Sobczak 	cq->tph_en = info->tph_en;
2626*cdcd52d4SBartosz Sobczak 	cq->tph_val = info->tph_val;
2627*cdcd52d4SBartosz Sobczak 	cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
2628*cdcd52d4SBartosz Sobczak 	cq->vsi = info->vsi;
2629*cdcd52d4SBartosz Sobczak 
2630*cdcd52d4SBartosz Sobczak 	return 0;
2631*cdcd52d4SBartosz Sobczak }
2632*cdcd52d4SBartosz Sobczak 
2633*cdcd52d4SBartosz Sobczak /**
2634*cdcd52d4SBartosz Sobczak  * irdma_sc_cq_create - create completion q
2635*cdcd52d4SBartosz Sobczak  * @cq: cq struct
2636*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2637*cdcd52d4SBartosz Sobczak  * @check_overflow: flag for overflow check
2638*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
2639*cdcd52d4SBartosz Sobczak  */
2640*cdcd52d4SBartosz Sobczak static int
2641*cdcd52d4SBartosz Sobczak irdma_sc_cq_create(struct irdma_sc_cq *cq, u64 scratch,
2642*cdcd52d4SBartosz Sobczak 		   bool check_overflow, bool post_sq)
2643*cdcd52d4SBartosz Sobczak {
2644*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2645*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
2646*cdcd52d4SBartosz Sobczak 	u64 hdr;
2647*cdcd52d4SBartosz Sobczak 	struct irdma_sc_ceq *ceq;
2648*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
2649*cdcd52d4SBartosz Sobczak 
2650*cdcd52d4SBartosz Sobczak 	cqp = cq->dev->cqp;
2651*cdcd52d4SBartosz Sobczak 	if (cq->cq_uk.cq_id > (cqp->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt - 1))
2652*cdcd52d4SBartosz Sobczak 		return -EINVAL;
2653*cdcd52d4SBartosz Sobczak 
2654*cdcd52d4SBartosz Sobczak 	if (cq->ceq_id > (cq->dev->hmc_fpm_misc.max_ceqs - 1))
2655*cdcd52d4SBartosz Sobczak 		return -EINVAL;
2656*cdcd52d4SBartosz Sobczak 
2657*cdcd52d4SBartosz Sobczak 	ceq = cq->dev->ceq[cq->ceq_id];
2658*cdcd52d4SBartosz Sobczak 	if (ceq && ceq->reg_cq)
2659*cdcd52d4SBartosz Sobczak 		ret_code = irdma_sc_add_cq_ctx(ceq, cq);
2660*cdcd52d4SBartosz Sobczak 
2661*cdcd52d4SBartosz Sobczak 	if (ret_code)
2662*cdcd52d4SBartosz Sobczak 		return ret_code;
2663*cdcd52d4SBartosz Sobczak 
2664*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2665*cdcd52d4SBartosz Sobczak 	if (!wqe) {
2666*cdcd52d4SBartosz Sobczak 		if (ceq && ceq->reg_cq)
2667*cdcd52d4SBartosz Sobczak 			irdma_sc_remove_cq_ctx(ceq, cq);
2668*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2669*cdcd52d4SBartosz Sobczak 	}
2670*cdcd52d4SBartosz Sobczak 
2671*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, cq->cq_uk.cq_size);
2672*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, RS_64_1(cq, 1));
2673*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
2674*cdcd52d4SBartosz Sobczak 		      LS_64(cq->shadow_read_threshold,
2675*cdcd52d4SBartosz Sobczak 			    IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD));
2676*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, (cq->virtual_map ? 0 : cq->cq_pa));
2677*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, cq->shadow_area_pa);
2678*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48,
2679*cdcd52d4SBartosz Sobczak 		      LS_64((cq->virtual_map ? cq->first_pm_pbl_idx : 0),
2680*cdcd52d4SBartosz Sobczak 			    IRDMA_CQPSQ_CQ_FIRSTPMPBLIDX));
2681*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_56,
2682*cdcd52d4SBartosz Sobczak 		      LS_64(cq->tph_val, IRDMA_CQPSQ_TPHVAL) |
2683*cdcd52d4SBartosz Sobczak 		      LS_64(cq->vsi->vsi_idx, IRDMA_CQPSQ_VSIIDX));
2684*cdcd52d4SBartosz Sobczak 
2685*cdcd52d4SBartosz Sobczak 	hdr = FLD_LS_64(cq->dev, cq->cq_uk.cq_id, IRDMA_CQPSQ_CQ_CQID) |
2686*cdcd52d4SBartosz Sobczak 	    FLD_LS_64(cq->dev, (cq->ceq_id_valid ? cq->ceq_id : 0),
2687*cdcd52d4SBartosz Sobczak 		      IRDMA_CQPSQ_CQ_CEQID) |
2688*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_CREATE_CQ, IRDMA_CQPSQ_OPCODE) |
2689*cdcd52d4SBartosz Sobczak 	    LS_64(cq->pbl_chunk_size, IRDMA_CQPSQ_CQ_LPBLSIZE) |
2690*cdcd52d4SBartosz Sobczak 	    LS_64(check_overflow, IRDMA_CQPSQ_CQ_CHKOVERFLOW) |
2691*cdcd52d4SBartosz Sobczak 	    LS_64(cq->virtual_map, IRDMA_CQPSQ_CQ_VIRTMAP) |
2692*cdcd52d4SBartosz Sobczak 	    LS_64(cq->ceqe_mask, IRDMA_CQPSQ_CQ_ENCEQEMASK) |
2693*cdcd52d4SBartosz Sobczak 	    LS_64(cq->ceq_id_valid, IRDMA_CQPSQ_CQ_CEQIDVALID) |
2694*cdcd52d4SBartosz Sobczak 	    LS_64(cq->tph_en, IRDMA_CQPSQ_TPHEN) |
2695*cdcd52d4SBartosz Sobczak 	    LS_64(cq->cq_uk.avoid_mem_cflct, IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT) |
2696*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2697*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2698*cdcd52d4SBartosz Sobczak 
2699*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2700*cdcd52d4SBartosz Sobczak 
2701*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CQ_CREATE WQE", wqe,
2702*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2703*cdcd52d4SBartosz Sobczak 	if (post_sq)
2704*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2705*cdcd52d4SBartosz Sobczak 
2706*cdcd52d4SBartosz Sobczak 	return 0;
2707*cdcd52d4SBartosz Sobczak }
2708*cdcd52d4SBartosz Sobczak 
2709*cdcd52d4SBartosz Sobczak /**
2710*cdcd52d4SBartosz Sobczak  * irdma_sc_cq_destroy - destroy completion q
2711*cdcd52d4SBartosz Sobczak  * @cq: cq struct
2712*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2713*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
2714*cdcd52d4SBartosz Sobczak  */
2715*cdcd52d4SBartosz Sobczak int
2716*cdcd52d4SBartosz Sobczak irdma_sc_cq_destroy(struct irdma_sc_cq *cq, u64 scratch, bool post_sq)
2717*cdcd52d4SBartosz Sobczak {
2718*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
2719*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2720*cdcd52d4SBartosz Sobczak 	u64 hdr;
2721*cdcd52d4SBartosz Sobczak 	struct irdma_sc_ceq *ceq;
2722*cdcd52d4SBartosz Sobczak 
2723*cdcd52d4SBartosz Sobczak 	cqp = cq->dev->cqp;
2724*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2725*cdcd52d4SBartosz Sobczak 	if (!wqe)
2726*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2727*cdcd52d4SBartosz Sobczak 
2728*cdcd52d4SBartosz Sobczak 	ceq = cq->dev->ceq[cq->ceq_id];
2729*cdcd52d4SBartosz Sobczak 	if (ceq && ceq->reg_cq)
2730*cdcd52d4SBartosz Sobczak 		irdma_sc_remove_cq_ctx(ceq, cq);
2731*cdcd52d4SBartosz Sobczak 
2732*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, cq->cq_uk.cq_size);
2733*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, RS_64_1(cq, 1));
2734*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, cq->shadow_area_pa);
2735*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48,
2736*cdcd52d4SBartosz Sobczak 		      (cq->virtual_map ? cq->first_pm_pbl_idx : 0));
2737*cdcd52d4SBartosz Sobczak 
2738*cdcd52d4SBartosz Sobczak 	hdr = cq->cq_uk.cq_id |
2739*cdcd52d4SBartosz Sobczak 	    FLD_LS_64(cq->dev, (cq->ceq_id_valid ? cq->ceq_id : 0),
2740*cdcd52d4SBartosz Sobczak 		      IRDMA_CQPSQ_CQ_CEQID) |
2741*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_DESTROY_CQ, IRDMA_CQPSQ_OPCODE) |
2742*cdcd52d4SBartosz Sobczak 	    LS_64(cq->pbl_chunk_size, IRDMA_CQPSQ_CQ_LPBLSIZE) |
2743*cdcd52d4SBartosz Sobczak 	    LS_64(cq->virtual_map, IRDMA_CQPSQ_CQ_VIRTMAP) |
2744*cdcd52d4SBartosz Sobczak 	    LS_64(cq->ceqe_mask, IRDMA_CQPSQ_CQ_ENCEQEMASK) |
2745*cdcd52d4SBartosz Sobczak 	    LS_64(cq->ceq_id_valid, IRDMA_CQPSQ_CQ_CEQIDVALID) |
2746*cdcd52d4SBartosz Sobczak 	    LS_64(cq->tph_en, IRDMA_CQPSQ_TPHEN) |
2747*cdcd52d4SBartosz Sobczak 	    LS_64(cq->cq_uk.avoid_mem_cflct, IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT) |
2748*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2749*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2750*cdcd52d4SBartosz Sobczak 
2751*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2752*cdcd52d4SBartosz Sobczak 
2753*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CQ_DESTROY WQE", wqe,
2754*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2755*cdcd52d4SBartosz Sobczak 	if (post_sq)
2756*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2757*cdcd52d4SBartosz Sobczak 
2758*cdcd52d4SBartosz Sobczak 	return 0;
2759*cdcd52d4SBartosz Sobczak }
2760*cdcd52d4SBartosz Sobczak 
2761*cdcd52d4SBartosz Sobczak /**
2762*cdcd52d4SBartosz Sobczak  * irdma_sc_cq_resize - set resized cq buffer info
2763*cdcd52d4SBartosz Sobczak  * @cq: resized cq
2764*cdcd52d4SBartosz Sobczak  * @info: resized cq buffer info
2765*cdcd52d4SBartosz Sobczak  */
2766*cdcd52d4SBartosz Sobczak void
2767*cdcd52d4SBartosz Sobczak irdma_sc_cq_resize(struct irdma_sc_cq *cq, struct irdma_modify_cq_info *info)
2768*cdcd52d4SBartosz Sobczak {
2769*cdcd52d4SBartosz Sobczak 	cq->virtual_map = info->virtual_map;
2770*cdcd52d4SBartosz Sobczak 	cq->cq_pa = info->cq_pa;
2771*cdcd52d4SBartosz Sobczak 	cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
2772*cdcd52d4SBartosz Sobczak 	cq->pbl_chunk_size = info->pbl_chunk_size;
2773*cdcd52d4SBartosz Sobczak 	irdma_uk_cq_resize(&cq->cq_uk, info->cq_base, info->cq_size);
2774*cdcd52d4SBartosz Sobczak }
2775*cdcd52d4SBartosz Sobczak 
2776*cdcd52d4SBartosz Sobczak /**
2777*cdcd52d4SBartosz Sobczak  * irdma_sc_cq_modify - modify a Completion Queue
2778*cdcd52d4SBartosz Sobczak  * @cq: cq struct
2779*cdcd52d4SBartosz Sobczak  * @info: modification info struct
2780*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
2781*cdcd52d4SBartosz Sobczak  * @post_sq: flag to post to sq
2782*cdcd52d4SBartosz Sobczak  */
2783*cdcd52d4SBartosz Sobczak static int
2784*cdcd52d4SBartosz Sobczak irdma_sc_cq_modify(struct irdma_sc_cq *cq,
2785*cdcd52d4SBartosz Sobczak 		   struct irdma_modify_cq_info *info, u64 scratch,
2786*cdcd52d4SBartosz Sobczak 		   bool post_sq)
2787*cdcd52d4SBartosz Sobczak {
2788*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
2789*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
2790*cdcd52d4SBartosz Sobczak 	u64 hdr;
2791*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
2792*cdcd52d4SBartosz Sobczak 
2793*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = cq->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
2794*cdcd52d4SBartosz Sobczak 	if (info->cq_resize && info->virtual_map &&
2795*cdcd52d4SBartosz Sobczak 	    info->first_pm_pbl_idx >= pble_obj_cnt)
2796*cdcd52d4SBartosz Sobczak 		return -EINVAL;
2797*cdcd52d4SBartosz Sobczak 
2798*cdcd52d4SBartosz Sobczak 	cqp = cq->dev->cqp;
2799*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
2800*cdcd52d4SBartosz Sobczak 	if (!wqe)
2801*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
2802*cdcd52d4SBartosz Sobczak 
2803*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, info->cq_size);
2804*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, RS_64_1(cq, 1));
2805*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
2806*cdcd52d4SBartosz Sobczak 		      LS_64(info->shadow_read_threshold,
2807*cdcd52d4SBartosz Sobczak 			    IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD));
2808*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, info->cq_pa);
2809*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, cq->shadow_area_pa);
2810*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48, info->first_pm_pbl_idx);
2811*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_56,
2812*cdcd52d4SBartosz Sobczak 		      LS_64(cq->tph_val, IRDMA_CQPSQ_TPHVAL) |
2813*cdcd52d4SBartosz Sobczak 		      LS_64(cq->vsi->vsi_idx, IRDMA_CQPSQ_VSIIDX));
2814*cdcd52d4SBartosz Sobczak 
2815*cdcd52d4SBartosz Sobczak 	hdr = cq->cq_uk.cq_id |
2816*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MODIFY_CQ, IRDMA_CQPSQ_OPCODE) |
2817*cdcd52d4SBartosz Sobczak 	    LS_64(info->cq_resize, IRDMA_CQPSQ_CQ_CQRESIZE) |
2818*cdcd52d4SBartosz Sobczak 	    LS_64(info->pbl_chunk_size, IRDMA_CQPSQ_CQ_LPBLSIZE) |
2819*cdcd52d4SBartosz Sobczak 	    LS_64(info->check_overflow, IRDMA_CQPSQ_CQ_CHKOVERFLOW) |
2820*cdcd52d4SBartosz Sobczak 	    LS_64(info->virtual_map, IRDMA_CQPSQ_CQ_VIRTMAP) |
2821*cdcd52d4SBartosz Sobczak 	    LS_64(cq->ceqe_mask, IRDMA_CQPSQ_CQ_ENCEQEMASK) |
2822*cdcd52d4SBartosz Sobczak 	    LS_64(cq->tph_en, IRDMA_CQPSQ_TPHEN) |
2823*cdcd52d4SBartosz Sobczak 	    LS_64(cq->cq_uk.avoid_mem_cflct, IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT) |
2824*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
2825*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
2826*cdcd52d4SBartosz Sobczak 
2827*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
2828*cdcd52d4SBartosz Sobczak 
2829*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CQ_MODIFY WQE", wqe,
2830*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
2831*cdcd52d4SBartosz Sobczak 	if (post_sq)
2832*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
2833*cdcd52d4SBartosz Sobczak 
2834*cdcd52d4SBartosz Sobczak 	return 0;
2835*cdcd52d4SBartosz Sobczak }
2836*cdcd52d4SBartosz Sobczak 
2837*cdcd52d4SBartosz Sobczak /**
2838*cdcd52d4SBartosz Sobczak  * irdma_check_cqp_progress - check cqp processing progress
2839*cdcd52d4SBartosz Sobczak  * @timeout: timeout info struct
2840*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
2841*cdcd52d4SBartosz Sobczak  */
2842*cdcd52d4SBartosz Sobczak void
2843*cdcd52d4SBartosz Sobczak irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev)
2844*cdcd52d4SBartosz Sobczak {
2845*cdcd52d4SBartosz Sobczak 	if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]) {
2846*cdcd52d4SBartosz Sobczak 		timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS];
2847*cdcd52d4SBartosz Sobczak 		timeout->count = 0;
2848*cdcd52d4SBartosz Sobczak 	} else {
2849*cdcd52d4SBartosz Sobczak 		if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] !=
2850*cdcd52d4SBartosz Sobczak 		    timeout->compl_cqp_cmds)
2851*cdcd52d4SBartosz Sobczak 			timeout->count++;
2852*cdcd52d4SBartosz Sobczak 	}
2853*cdcd52d4SBartosz Sobczak }
2854*cdcd52d4SBartosz Sobczak 
2855*cdcd52d4SBartosz Sobczak /**
2856*cdcd52d4SBartosz Sobczak  * irdma_get_cqp_reg_info - get head and tail for cqp using registers
2857*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2858*cdcd52d4SBartosz Sobczak  * @val: cqp tail register value
2859*cdcd52d4SBartosz Sobczak  * @tail: wqtail register value
2860*cdcd52d4SBartosz Sobczak  * @error: cqp processing err
2861*cdcd52d4SBartosz Sobczak  */
2862*cdcd52d4SBartosz Sobczak static inline void
2863*cdcd52d4SBartosz Sobczak irdma_get_cqp_reg_info(struct irdma_sc_cqp *cqp, u32 *val,
2864*cdcd52d4SBartosz Sobczak 		       u32 *tail, u32 *error)
2865*cdcd52d4SBartosz Sobczak {
2866*cdcd52d4SBartosz Sobczak 	*val = readl(cqp->dev->hw_regs[IRDMA_CQPTAIL]);
2867*cdcd52d4SBartosz Sobczak 	*tail = RS_32(*val, IRDMA_CQPTAIL_WQTAIL);
2868*cdcd52d4SBartosz Sobczak 	*error = RS_32(*val, IRDMA_CQPTAIL_CQP_OP_ERR);
2869*cdcd52d4SBartosz Sobczak }
2870*cdcd52d4SBartosz Sobczak 
2871*cdcd52d4SBartosz Sobczak /**
2872*cdcd52d4SBartosz Sobczak  * irdma_cqp_poll_registers - poll cqp registers
2873*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
2874*cdcd52d4SBartosz Sobczak  * @tail: wqtail register value
2875*cdcd52d4SBartosz Sobczak  * @count: how many times to try for completion
2876*cdcd52d4SBartosz Sobczak  */
2877*cdcd52d4SBartosz Sobczak static int
2878*cdcd52d4SBartosz Sobczak irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail,
2879*cdcd52d4SBartosz Sobczak 			 u32 count)
2880*cdcd52d4SBartosz Sobczak {
2881*cdcd52d4SBartosz Sobczak 	u32 i = 0;
2882*cdcd52d4SBartosz Sobczak 	u32 newtail, error, val;
2883*cdcd52d4SBartosz Sobczak 
2884*cdcd52d4SBartosz Sobczak 	while (i++ < count) {
2885*cdcd52d4SBartosz Sobczak 		irdma_get_cqp_reg_info(cqp, &val, &newtail, &error);
2886*cdcd52d4SBartosz Sobczak 		if (error) {
2887*cdcd52d4SBartosz Sobczak 			error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]);
2888*cdcd52d4SBartosz Sobczak 			irdma_debug(cqp->dev, IRDMA_DEBUG_CQP,
2889*cdcd52d4SBartosz Sobczak 				    "CQPERRCODES error_code[x%08X]\n", error);
2890*cdcd52d4SBartosz Sobczak 			return -EIO;
2891*cdcd52d4SBartosz Sobczak 		}
2892*cdcd52d4SBartosz Sobczak 		if (newtail != tail) {
2893*cdcd52d4SBartosz Sobczak 			/* SUCCESS */
2894*cdcd52d4SBartosz Sobczak 			IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
2895*cdcd52d4SBartosz Sobczak 			cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++;
2896*cdcd52d4SBartosz Sobczak 			return 0;
2897*cdcd52d4SBartosz Sobczak 		}
2898*cdcd52d4SBartosz Sobczak 		irdma_usec_delay(cqp->dev->hw_attrs.max_sleep_count);
2899*cdcd52d4SBartosz Sobczak 	}
2900*cdcd52d4SBartosz Sobczak 
2901*cdcd52d4SBartosz Sobczak 	return -ETIMEDOUT;
2902*cdcd52d4SBartosz Sobczak }
2903*cdcd52d4SBartosz Sobczak 
2904*cdcd52d4SBartosz Sobczak /**
2905*cdcd52d4SBartosz Sobczak  * irdma_sc_decode_fpm_commit - decode a 64 bit value into count and base
2906*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
2907*cdcd52d4SBartosz Sobczak  * @buf: pointer to commit buffer
2908*cdcd52d4SBartosz Sobczak  * @buf_idx: buffer index
2909*cdcd52d4SBartosz Sobczak  * @obj_info: object info pointer
2910*cdcd52d4SBartosz Sobczak  * @rsrc_idx: indexs of memory resource
2911*cdcd52d4SBartosz Sobczak  */
2912*cdcd52d4SBartosz Sobczak static u64 irdma_sc_decode_fpm_commit(struct irdma_sc_dev *dev, __le64 * buf,
2913*cdcd52d4SBartosz Sobczak 				      u32 buf_idx, struct irdma_hmc_obj_info *obj_info,
2914*cdcd52d4SBartosz Sobczak 				      u32 rsrc_idx){
2915*cdcd52d4SBartosz Sobczak 	u64 temp;
2916*cdcd52d4SBartosz Sobczak 
2917*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, buf_idx, &temp);
2918*cdcd52d4SBartosz Sobczak 
2919*cdcd52d4SBartosz Sobczak 	switch (rsrc_idx) {
2920*cdcd52d4SBartosz Sobczak 	case IRDMA_HMC_IW_QP:
2921*cdcd52d4SBartosz Sobczak 		obj_info[rsrc_idx].cnt = (u32)RS_64(temp, IRDMA_COMMIT_FPM_QPCNT);
2922*cdcd52d4SBartosz Sobczak 		break;
2923*cdcd52d4SBartosz Sobczak 	case IRDMA_HMC_IW_CQ:
2924*cdcd52d4SBartosz Sobczak 		obj_info[rsrc_idx].cnt = (u32)FLD_RS_64(dev, temp, IRDMA_COMMIT_FPM_CQCNT);
2925*cdcd52d4SBartosz Sobczak 		break;
2926*cdcd52d4SBartosz Sobczak 	case IRDMA_HMC_IW_APBVT_ENTRY:
2927*cdcd52d4SBartosz Sobczak 		obj_info[rsrc_idx].cnt = 1;
2928*cdcd52d4SBartosz Sobczak 		break;
2929*cdcd52d4SBartosz Sobczak 	default:
2930*cdcd52d4SBartosz Sobczak 		obj_info[rsrc_idx].cnt = (u32)temp;
2931*cdcd52d4SBartosz Sobczak 		break;
2932*cdcd52d4SBartosz Sobczak 	}
2933*cdcd52d4SBartosz Sobczak 
2934*cdcd52d4SBartosz Sobczak 	obj_info[rsrc_idx].base = (u64)RS_64_1(temp, IRDMA_COMMIT_FPM_BASE_S) * 512;
2935*cdcd52d4SBartosz Sobczak 
2936*cdcd52d4SBartosz Sobczak 	return temp;
2937*cdcd52d4SBartosz Sobczak }
2938*cdcd52d4SBartosz Sobczak 
2939*cdcd52d4SBartosz Sobczak /**
2940*cdcd52d4SBartosz Sobczak  * irdma_sc_parse_fpm_commit_buf - parse fpm commit buffer
2941*cdcd52d4SBartosz Sobczak  * @dev: pointer to dev struct
2942*cdcd52d4SBartosz Sobczak  * @buf: ptr to fpm commit buffer
2943*cdcd52d4SBartosz Sobczak  * @info: ptr to irdma_hmc_obj_info struct
2944*cdcd52d4SBartosz Sobczak  * @sd: number of SDs for HMC objects
2945*cdcd52d4SBartosz Sobczak  *
2946*cdcd52d4SBartosz Sobczak  * parses fpm commit info and copy base value
2947*cdcd52d4SBartosz Sobczak  * of hmc objects in hmc_info
2948*cdcd52d4SBartosz Sobczak  */
2949*cdcd52d4SBartosz Sobczak static int
2950*cdcd52d4SBartosz Sobczak irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 * buf,
2951*cdcd52d4SBartosz Sobczak 			      struct irdma_hmc_obj_info *info,
2952*cdcd52d4SBartosz Sobczak 			      u32 *sd)
2953*cdcd52d4SBartosz Sobczak {
2954*cdcd52d4SBartosz Sobczak 	u64 size;
2955*cdcd52d4SBartosz Sobczak 	u32 i;
2956*cdcd52d4SBartosz Sobczak 	u64 max_base = 0;
2957*cdcd52d4SBartosz Sobczak 	u32 last_hmc_obj = 0;
2958*cdcd52d4SBartosz Sobczak 
2959*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_0, info,
2960*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_QP);
2961*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_8, info,
2962*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_CQ);
2963*cdcd52d4SBartosz Sobczak 	/* skiping RSRVD */
2964*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_24, info,
2965*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_HTE);
2966*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_32, info,
2967*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_ARP);
2968*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_40, info,
2969*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_APBVT_ENTRY);
2970*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_48, info,
2971*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_MR);
2972*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_56, info,
2973*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_XF);
2974*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_64, info,
2975*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_XFFL);
2976*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_72, info,
2977*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_Q1);
2978*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_80, info,
2979*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_Q1FL);
2980*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_88, info,
2981*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_TIMER);
2982*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_112, info,
2983*cdcd52d4SBartosz Sobczak 				   IRDMA_HMC_IW_PBLE);
2984*cdcd52d4SBartosz Sobczak 	/* skipping RSVD. */
2985*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1) {
2986*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_96, info,
2987*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_FSIMC);
2988*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_104, info,
2989*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_FSIAV);
2990*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_128, info,
2991*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_RRF);
2992*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_136, info,
2993*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_RRFFL);
2994*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_144, info,
2995*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_HDR);
2996*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_152, info,
2997*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_MD);
2998*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_160, info,
2999*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_OOISC);
3000*cdcd52d4SBartosz Sobczak 		irdma_sc_decode_fpm_commit(dev, buf, IRDMA_BYTE_168, info,
3001*cdcd52d4SBartosz Sobczak 					   IRDMA_HMC_IW_OOISCFFL);
3002*cdcd52d4SBartosz Sobczak 	}
3003*cdcd52d4SBartosz Sobczak 
3004*cdcd52d4SBartosz Sobczak 	/* searching for the last object in HMC to find the size of the HMC area. */
3005*cdcd52d4SBartosz Sobczak 	for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++) {
3006*cdcd52d4SBartosz Sobczak 		if (info[i].base > max_base) {
3007*cdcd52d4SBartosz Sobczak 			max_base = info[i].base;
3008*cdcd52d4SBartosz Sobczak 			last_hmc_obj = i;
3009*cdcd52d4SBartosz Sobczak 		}
3010*cdcd52d4SBartosz Sobczak 	}
3011*cdcd52d4SBartosz Sobczak 
3012*cdcd52d4SBartosz Sobczak 	size = info[last_hmc_obj].cnt * info[last_hmc_obj].size +
3013*cdcd52d4SBartosz Sobczak 	    info[last_hmc_obj].base;
3014*cdcd52d4SBartosz Sobczak 
3015*cdcd52d4SBartosz Sobczak 	if (size & 0x1FFFFF)
3016*cdcd52d4SBartosz Sobczak 		*sd = (u32)((size >> 21) + 1);	/* add 1 for remainder */
3017*cdcd52d4SBartosz Sobczak 	else
3018*cdcd52d4SBartosz Sobczak 		*sd = (u32)(size >> 21);
3019*cdcd52d4SBartosz Sobczak 
3020*cdcd52d4SBartosz Sobczak 	return 0;
3021*cdcd52d4SBartosz Sobczak }
3022*cdcd52d4SBartosz Sobczak 
3023*cdcd52d4SBartosz Sobczak /**
3024*cdcd52d4SBartosz Sobczak  * irdma_sc_decode_fpm_query() - Decode a 64 bit value into max count and size
3025*cdcd52d4SBartosz Sobczak  * @buf: ptr to fpm query buffer
3026*cdcd52d4SBartosz Sobczak  * @buf_idx: index into buf
3027*cdcd52d4SBartosz Sobczak  * @obj_info: ptr to irdma_hmc_obj_info struct
3028*cdcd52d4SBartosz Sobczak  * @rsrc_idx: resource index into info
3029*cdcd52d4SBartosz Sobczak  *
3030*cdcd52d4SBartosz Sobczak  * Decode a 64 bit value from fpm query buffer into max count and size
3031*cdcd52d4SBartosz Sobczak  */
3032*cdcd52d4SBartosz Sobczak static u64 irdma_sc_decode_fpm_query(__le64 * buf, u32 buf_idx,
3033*cdcd52d4SBartosz Sobczak 				     struct irdma_hmc_obj_info *obj_info,
3034*cdcd52d4SBartosz Sobczak 				     u32 rsrc_idx){
3035*cdcd52d4SBartosz Sobczak 	u64 temp;
3036*cdcd52d4SBartosz Sobczak 	u32 size;
3037*cdcd52d4SBartosz Sobczak 
3038*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, buf_idx, &temp);
3039*cdcd52d4SBartosz Sobczak 	obj_info[rsrc_idx].max_cnt = (u32)temp;
3040*cdcd52d4SBartosz Sobczak 	size = (u32)RS_64_1(temp, 32);
3041*cdcd52d4SBartosz Sobczak 	obj_info[rsrc_idx].size = LS_64_1(1, size);
3042*cdcd52d4SBartosz Sobczak 
3043*cdcd52d4SBartosz Sobczak 	return temp;
3044*cdcd52d4SBartosz Sobczak }
3045*cdcd52d4SBartosz Sobczak 
3046*cdcd52d4SBartosz Sobczak /**
3047*cdcd52d4SBartosz Sobczak  * irdma_sc_parse_fpm_query_buf() - parses fpm query buffer
3048*cdcd52d4SBartosz Sobczak  * @dev: ptr to shared code device
3049*cdcd52d4SBartosz Sobczak  * @buf: ptr to fpm query buffer
3050*cdcd52d4SBartosz Sobczak  * @hmc_info: ptr to irdma_hmc_obj_info struct
3051*cdcd52d4SBartosz Sobczak  * @hmc_fpm_misc: ptr to fpm data
3052*cdcd52d4SBartosz Sobczak  *
3053*cdcd52d4SBartosz Sobczak  * parses fpm query buffer and copy max_cnt and
3054*cdcd52d4SBartosz Sobczak  * size value of hmc objects in hmc_info
3055*cdcd52d4SBartosz Sobczak  */
3056*cdcd52d4SBartosz Sobczak static int
3057*cdcd52d4SBartosz Sobczak irdma_sc_parse_fpm_query_buf(struct irdma_sc_dev *dev, __le64 * buf,
3058*cdcd52d4SBartosz Sobczak 			     struct irdma_hmc_info *hmc_info,
3059*cdcd52d4SBartosz Sobczak 			     struct irdma_hmc_fpm_misc *hmc_fpm_misc)
3060*cdcd52d4SBartosz Sobczak {
3061*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_obj_info *obj_info;
3062*cdcd52d4SBartosz Sobczak 	u64 temp;
3063*cdcd52d4SBartosz Sobczak 	u32 size;
3064*cdcd52d4SBartosz Sobczak 	u16 max_pe_sds;
3065*cdcd52d4SBartosz Sobczak 
3066*cdcd52d4SBartosz Sobczak 	obj_info = hmc_info->hmc_obj;
3067*cdcd52d4SBartosz Sobczak 
3068*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, IRDMA_BYTE_0, &temp);
3069*cdcd52d4SBartosz Sobczak 	hmc_info->first_sd_index = (u16)RS_64(temp, IRDMA_QUERY_FPM_FIRST_PE_SD_INDEX);
3070*cdcd52d4SBartosz Sobczak 	max_pe_sds = (u16)RS_64(temp, IRDMA_QUERY_FPM_MAX_PE_SDS);
3071*cdcd52d4SBartosz Sobczak 
3072*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->max_sds = max_pe_sds;
3073*cdcd52d4SBartosz Sobczak 	hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index;
3074*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, 8, &temp);
3075*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_QP].max_cnt = (u32)RS_64(temp, IRDMA_QUERY_FPM_MAX_QPS);
3076*cdcd52d4SBartosz Sobczak 	size = (u32)RS_64_1(temp, 32);
3077*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_QP].size = LS_64_1(1, size);
3078*cdcd52d4SBartosz Sobczak 
3079*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, 16, &temp);
3080*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_CQ].max_cnt = (u32)RS_64(temp, IRDMA_QUERY_FPM_MAX_CQS);
3081*cdcd52d4SBartosz Sobczak 	size = (u32)RS_64_1(temp, 32);
3082*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_CQ].size = LS_64_1(1, size);
3083*cdcd52d4SBartosz Sobczak 
3084*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 32, obj_info, IRDMA_HMC_IW_HTE);
3085*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 40, obj_info, IRDMA_HMC_IW_ARP);
3086*cdcd52d4SBartosz Sobczak 
3087*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_APBVT_ENTRY].size = 8192;
3088*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_APBVT_ENTRY].max_cnt = 1;
3089*cdcd52d4SBartosz Sobczak 
3090*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 48, obj_info, IRDMA_HMC_IW_MR);
3091*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 56, obj_info, IRDMA_HMC_IW_XF);
3092*cdcd52d4SBartosz Sobczak 
3093*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, 64, &temp);
3094*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_XFFL].max_cnt = (u32)temp;
3095*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_XFFL].size = 4;
3096*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->xf_block_size = RS_64(temp, IRDMA_QUERY_FPM_XFBLOCKSIZE);
3097*cdcd52d4SBartosz Sobczak 	if (!hmc_fpm_misc->xf_block_size)
3098*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3099*cdcd52d4SBartosz Sobczak 
3100*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 72, obj_info, IRDMA_HMC_IW_Q1);
3101*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, 80, &temp);
3102*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_Q1FL].max_cnt = (u32)temp;
3103*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_Q1FL].size = 4;
3104*cdcd52d4SBartosz Sobczak 
3105*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->q1_block_size = RS_64(temp, IRDMA_QUERY_FPM_Q1BLOCKSIZE);
3106*cdcd52d4SBartosz Sobczak 	if (!hmc_fpm_misc->q1_block_size)
3107*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3108*cdcd52d4SBartosz Sobczak 
3109*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 88, obj_info, IRDMA_HMC_IW_TIMER);
3110*cdcd52d4SBartosz Sobczak 
3111*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, 112, &temp);
3112*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_PBLE].max_cnt = (u32)temp;
3113*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_PBLE].size = 8;
3114*cdcd52d4SBartosz Sobczak 
3115*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, 120, &temp);
3116*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->max_ceqs = RS_64(temp, IRDMA_QUERY_FPM_MAX_CEQS);
3117*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->ht_multiplier = RS_64(temp, IRDMA_QUERY_FPM_HTMULTIPLIER);
3118*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->timer_bucket = RS_64(temp, IRDMA_QUERY_FPM_TIMERBUCKET);
3119*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
3120*cdcd52d4SBartosz Sobczak 		return 0;
3121*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 96, obj_info, IRDMA_HMC_IW_FSIMC);
3122*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 104, obj_info, IRDMA_HMC_IW_FSIAV);
3123*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 128, obj_info, IRDMA_HMC_IW_RRF);
3124*cdcd52d4SBartosz Sobczak 
3125*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, IRDMA_BYTE_136, &temp);
3126*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_RRFFL].max_cnt = (u32)temp;
3127*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_RRFFL].size = 4;
3128*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->rrf_block_size = RS_64(temp, IRDMA_QUERY_FPM_RRFBLOCKSIZE);
3129*cdcd52d4SBartosz Sobczak 	if (!hmc_fpm_misc->rrf_block_size &&
3130*cdcd52d4SBartosz Sobczak 	    obj_info[IRDMA_HMC_IW_RRFFL].max_cnt)
3131*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3132*cdcd52d4SBartosz Sobczak 
3133*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 144, obj_info, IRDMA_HMC_IW_HDR);
3134*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 152, obj_info, IRDMA_HMC_IW_MD);
3135*cdcd52d4SBartosz Sobczak 	irdma_sc_decode_fpm_query(buf, 160, obj_info, IRDMA_HMC_IW_OOISC);
3136*cdcd52d4SBartosz Sobczak 
3137*cdcd52d4SBartosz Sobczak 	get_64bit_val(buf, IRDMA_BYTE_168, &temp);
3138*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt = (u32)temp;
3139*cdcd52d4SBartosz Sobczak 	obj_info[IRDMA_HMC_IW_OOISCFFL].size = 4;
3140*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc->ooiscf_block_size = RS_64(temp, IRDMA_QUERY_FPM_OOISCFBLOCKSIZE);
3141*cdcd52d4SBartosz Sobczak 	if (!hmc_fpm_misc->ooiscf_block_size &&
3142*cdcd52d4SBartosz Sobczak 	    obj_info[IRDMA_HMC_IW_OOISCFFL].max_cnt)
3143*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3144*cdcd52d4SBartosz Sobczak 
3145*cdcd52d4SBartosz Sobczak 	return 0;
3146*cdcd52d4SBartosz Sobczak }
3147*cdcd52d4SBartosz Sobczak 
3148*cdcd52d4SBartosz Sobczak /**
3149*cdcd52d4SBartosz Sobczak  * irdma_sc_find_reg_cq - find cq ctx index
3150*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3151*cdcd52d4SBartosz Sobczak  * @cq: cq sc structure
3152*cdcd52d4SBartosz Sobczak  */
3153*cdcd52d4SBartosz Sobczak static u32 irdma_sc_find_reg_cq(struct irdma_sc_ceq *ceq,
3154*cdcd52d4SBartosz Sobczak 				struct irdma_sc_cq *cq){
3155*cdcd52d4SBartosz Sobczak 	u32 i;
3156*cdcd52d4SBartosz Sobczak 
3157*cdcd52d4SBartosz Sobczak 	for (i = 0; i < ceq->reg_cq_size; i++) {
3158*cdcd52d4SBartosz Sobczak 		if (cq == ceq->reg_cq[i])
3159*cdcd52d4SBartosz Sobczak 			return i;
3160*cdcd52d4SBartosz Sobczak 	}
3161*cdcd52d4SBartosz Sobczak 
3162*cdcd52d4SBartosz Sobczak 	return IRDMA_INVALID_CQ_IDX;
3163*cdcd52d4SBartosz Sobczak }
3164*cdcd52d4SBartosz Sobczak 
3165*cdcd52d4SBartosz Sobczak /**
3166*cdcd52d4SBartosz Sobczak  * irdma_sc_add_cq_ctx - add cq ctx tracking for ceq
3167*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3168*cdcd52d4SBartosz Sobczak  * @cq: cq sc structure
3169*cdcd52d4SBartosz Sobczak  */
3170*cdcd52d4SBartosz Sobczak int
3171*cdcd52d4SBartosz Sobczak irdma_sc_add_cq_ctx(struct irdma_sc_ceq *ceq, struct irdma_sc_cq *cq)
3172*cdcd52d4SBartosz Sobczak {
3173*cdcd52d4SBartosz Sobczak 	unsigned long flags;
3174*cdcd52d4SBartosz Sobczak 
3175*cdcd52d4SBartosz Sobczak 	spin_lock_irqsave(&ceq->req_cq_lock, flags);
3176*cdcd52d4SBartosz Sobczak 
3177*cdcd52d4SBartosz Sobczak 	if (ceq->reg_cq_size == ceq->elem_cnt) {
3178*cdcd52d4SBartosz Sobczak 		spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
3179*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
3180*cdcd52d4SBartosz Sobczak 	}
3181*cdcd52d4SBartosz Sobczak 
3182*cdcd52d4SBartosz Sobczak 	ceq->reg_cq[ceq->reg_cq_size++] = cq;
3183*cdcd52d4SBartosz Sobczak 
3184*cdcd52d4SBartosz Sobczak 	spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
3185*cdcd52d4SBartosz Sobczak 
3186*cdcd52d4SBartosz Sobczak 	return 0;
3187*cdcd52d4SBartosz Sobczak }
3188*cdcd52d4SBartosz Sobczak 
3189*cdcd52d4SBartosz Sobczak /**
3190*cdcd52d4SBartosz Sobczak  * irdma_sc_remove_cq_ctx - remove cq ctx tracking for ceq
3191*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3192*cdcd52d4SBartosz Sobczak  * @cq: cq sc structure
3193*cdcd52d4SBartosz Sobczak  */
3194*cdcd52d4SBartosz Sobczak void
3195*cdcd52d4SBartosz Sobczak irdma_sc_remove_cq_ctx(struct irdma_sc_ceq *ceq, struct irdma_sc_cq *cq)
3196*cdcd52d4SBartosz Sobczak {
3197*cdcd52d4SBartosz Sobczak 	unsigned long flags;
3198*cdcd52d4SBartosz Sobczak 	u32 cq_ctx_idx;
3199*cdcd52d4SBartosz Sobczak 
3200*cdcd52d4SBartosz Sobczak 	spin_lock_irqsave(&ceq->req_cq_lock, flags);
3201*cdcd52d4SBartosz Sobczak 	cq_ctx_idx = irdma_sc_find_reg_cq(ceq, cq);
3202*cdcd52d4SBartosz Sobczak 	if (cq_ctx_idx == IRDMA_INVALID_CQ_IDX)
3203*cdcd52d4SBartosz Sobczak 		goto exit;
3204*cdcd52d4SBartosz Sobczak 
3205*cdcd52d4SBartosz Sobczak 	ceq->reg_cq_size--;
3206*cdcd52d4SBartosz Sobczak 	if (cq_ctx_idx != ceq->reg_cq_size)
3207*cdcd52d4SBartosz Sobczak 		ceq->reg_cq[cq_ctx_idx] = ceq->reg_cq[ceq->reg_cq_size];
3208*cdcd52d4SBartosz Sobczak 	ceq->reg_cq[ceq->reg_cq_size] = NULL;
3209*cdcd52d4SBartosz Sobczak 
3210*cdcd52d4SBartosz Sobczak exit:
3211*cdcd52d4SBartosz Sobczak 	spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
3212*cdcd52d4SBartosz Sobczak }
3213*cdcd52d4SBartosz Sobczak 
3214*cdcd52d4SBartosz Sobczak /**
3215*cdcd52d4SBartosz Sobczak  * irdma_sc_cqp_init - Initialize buffers for a control Queue Pair
3216*cdcd52d4SBartosz Sobczak  * @cqp: IWARP control queue pair pointer
3217*cdcd52d4SBartosz Sobczak  * @info: IWARP control queue pair init info pointer
3218*cdcd52d4SBartosz Sobczak  *
3219*cdcd52d4SBartosz Sobczak  * Initializes the object and context buffers for a control Queue Pair.
3220*cdcd52d4SBartosz Sobczak  */
3221*cdcd52d4SBartosz Sobczak int
3222*cdcd52d4SBartosz Sobczak irdma_sc_cqp_init(struct irdma_sc_cqp *cqp,
3223*cdcd52d4SBartosz Sobczak 		  struct irdma_cqp_init_info *info)
3224*cdcd52d4SBartosz Sobczak {
3225*cdcd52d4SBartosz Sobczak 	u8 hw_sq_size;
3226*cdcd52d4SBartosz Sobczak 
3227*cdcd52d4SBartosz Sobczak 	if (info->sq_size > IRDMA_CQP_SW_SQSIZE_2048 ||
3228*cdcd52d4SBartosz Sobczak 	    info->sq_size < IRDMA_CQP_SW_SQSIZE_4 ||
3229*cdcd52d4SBartosz Sobczak 	    ((info->sq_size & (info->sq_size - 1))))
3230*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3231*cdcd52d4SBartosz Sobczak 
3232*cdcd52d4SBartosz Sobczak 	hw_sq_size = irdma_get_encoded_wqe_size(info->sq_size,
3233*cdcd52d4SBartosz Sobczak 						IRDMA_QUEUE_TYPE_CQP);
3234*cdcd52d4SBartosz Sobczak 	cqp->size = sizeof(*cqp);
3235*cdcd52d4SBartosz Sobczak 	cqp->sq_size = info->sq_size;
3236*cdcd52d4SBartosz Sobczak 	cqp->hw_sq_size = hw_sq_size;
3237*cdcd52d4SBartosz Sobczak 	cqp->sq_base = info->sq;
3238*cdcd52d4SBartosz Sobczak 	cqp->host_ctx = info->host_ctx;
3239*cdcd52d4SBartosz Sobczak 	cqp->sq_pa = info->sq_pa;
3240*cdcd52d4SBartosz Sobczak 	cqp->host_ctx_pa = info->host_ctx_pa;
3241*cdcd52d4SBartosz Sobczak 	cqp->dev = info->dev;
3242*cdcd52d4SBartosz Sobczak 	cqp->struct_ver = info->struct_ver;
3243*cdcd52d4SBartosz Sobczak 	cqp->hw_maj_ver = info->hw_maj_ver;
3244*cdcd52d4SBartosz Sobczak 	cqp->hw_min_ver = info->hw_min_ver;
3245*cdcd52d4SBartosz Sobczak 	cqp->scratch_array = info->scratch_array;
3246*cdcd52d4SBartosz Sobczak 	cqp->polarity = 0;
3247*cdcd52d4SBartosz Sobczak 	cqp->en_datacenter_tcp = info->en_datacenter_tcp;
3248*cdcd52d4SBartosz Sobczak 	cqp->ena_vf_count = info->ena_vf_count;
3249*cdcd52d4SBartosz Sobczak 	cqp->hmc_profile = info->hmc_profile;
3250*cdcd52d4SBartosz Sobczak 	cqp->ceqs_per_vf = info->ceqs_per_vf;
3251*cdcd52d4SBartosz Sobczak 	cqp->disable_packed = info->disable_packed;
3252*cdcd52d4SBartosz Sobczak 	cqp->rocev2_rto_policy = info->rocev2_rto_policy;
3253*cdcd52d4SBartosz Sobczak 	cqp->protocol_used = info->protocol_used;
3254*cdcd52d4SBartosz Sobczak 	irdma_memcpy(&cqp->dcqcn_params, &info->dcqcn_params, sizeof(cqp->dcqcn_params));
3255*cdcd52d4SBartosz Sobczak 	cqp->en_rem_endpoint_trk = info->en_rem_endpoint_trk;
3256*cdcd52d4SBartosz Sobczak 	info->dev->cqp = cqp;
3257*cdcd52d4SBartosz Sobczak 
3258*cdcd52d4SBartosz Sobczak 	IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size);
3259*cdcd52d4SBartosz Sobczak 	cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] = 0;
3260*cdcd52d4SBartosz Sobczak 	cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS] = 0;
3261*cdcd52d4SBartosz Sobczak 	/* for the cqp commands backlog. */
3262*cdcd52d4SBartosz Sobczak 	INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head);
3263*cdcd52d4SBartosz Sobczak 
3264*cdcd52d4SBartosz Sobczak 	writel(0, cqp->dev->hw_regs[IRDMA_CQPTAIL]);
3265*cdcd52d4SBartosz Sobczak 	writel(0, cqp->dev->hw_regs[IRDMA_CQPDB]);
3266*cdcd52d4SBartosz Sobczak 	writel(0, cqp->dev->hw_regs[IRDMA_CCQPSTATUS]);
3267*cdcd52d4SBartosz Sobczak 
3268*cdcd52d4SBartosz Sobczak 	irdma_debug(cqp->dev, IRDMA_DEBUG_WQE,
3269*cdcd52d4SBartosz Sobczak 		    "sq_size[%04d] hw_sq_size[%04d] sq_base[%p] sq_pa[%llxh] cqp[%p] polarity[x%04x]\n",
3270*cdcd52d4SBartosz Sobczak 		    cqp->sq_size, cqp->hw_sq_size, cqp->sq_base, (unsigned long long)cqp->sq_pa, cqp,
3271*cdcd52d4SBartosz Sobczak 		    cqp->polarity);
3272*cdcd52d4SBartosz Sobczak 	return 0;
3273*cdcd52d4SBartosz Sobczak }
3274*cdcd52d4SBartosz Sobczak 
3275*cdcd52d4SBartosz Sobczak /**
3276*cdcd52d4SBartosz Sobczak  * irdma_sc_cqp_create - create cqp during bringup
3277*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3278*cdcd52d4SBartosz Sobczak  * @maj_err: If error, major err number
3279*cdcd52d4SBartosz Sobczak  * @min_err: If error, minor err number
3280*cdcd52d4SBartosz Sobczak  */
3281*cdcd52d4SBartosz Sobczak int
3282*cdcd52d4SBartosz Sobczak irdma_sc_cqp_create(struct irdma_sc_cqp *cqp, u16 *maj_err, u16 *min_err)
3283*cdcd52d4SBartosz Sobczak {
3284*cdcd52d4SBartosz Sobczak 	u64 temp;
3285*cdcd52d4SBartosz Sobczak 	u8 hw_rev;
3286*cdcd52d4SBartosz Sobczak 	u32 cnt = 0, p1, p2, val = 0, err_code;
3287*cdcd52d4SBartosz Sobczak 	int ret_code;
3288*cdcd52d4SBartosz Sobczak 
3289*cdcd52d4SBartosz Sobczak 	hw_rev = cqp->dev->hw_attrs.uk_attrs.hw_rev;
3290*cdcd52d4SBartosz Sobczak 	cqp->sdbuf.size = IRDMA_UPDATE_SD_BUFF_SIZE * cqp->sq_size;
3291*cdcd52d4SBartosz Sobczak 	cqp->sdbuf.va = irdma_allocate_dma_mem(cqp->dev->hw, &cqp->sdbuf,
3292*cdcd52d4SBartosz Sobczak 					       cqp->sdbuf.size,
3293*cdcd52d4SBartosz Sobczak 					       IRDMA_SD_BUF_ALIGNMENT);
3294*cdcd52d4SBartosz Sobczak 	if (!cqp->sdbuf.va)
3295*cdcd52d4SBartosz Sobczak 		return -ENOMEM;
3296*cdcd52d4SBartosz Sobczak 
3297*cdcd52d4SBartosz Sobczak 	spin_lock_init(&cqp->dev->cqp_lock);
3298*cdcd52d4SBartosz Sobczak 
3299*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->hw_sq_size, IRDMA_CQPHC_SQSIZE) |
3300*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->struct_ver, IRDMA_CQPHC_SVER) |
3301*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->disable_packed, IRDMA_CQPHC_DISABLE_PFPDUS) |
3302*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->ceqs_per_vf, IRDMA_CQPHC_CEQPERVF);
3303*cdcd52d4SBartosz Sobczak 	if (hw_rev >= IRDMA_GEN_2) {
3304*cdcd52d4SBartosz Sobczak 		temp |= LS_64(cqp->rocev2_rto_policy, IRDMA_CQPHC_ROCEV2_RTO_POLICY) |
3305*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->protocol_used, IRDMA_CQPHC_PROTOCOL_USED);
3306*cdcd52d4SBartosz Sobczak 	}
3307*cdcd52d4SBartosz Sobczak 
3308*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_0, temp);
3309*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_8, cqp->sq_pa);
3310*cdcd52d4SBartosz Sobczak 
3311*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->ena_vf_count, IRDMA_CQPHC_ENABLED_VFS) |
3312*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->hmc_profile, IRDMA_CQPHC_HMC_PROFILE);
3313*cdcd52d4SBartosz Sobczak 	if (hw_rev >= IRDMA_GEN_2)
3314*cdcd52d4SBartosz Sobczak 		temp |= LS_64(cqp->en_rem_endpoint_trk, IRDMA_CQPHC_EN_REM_ENDPOINT_TRK);
3315*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_16, temp);
3316*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_24, (uintptr_t)cqp);
3317*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->hw_maj_ver, IRDMA_CQPHC_HW_MAJVER) |
3318*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->hw_min_ver, IRDMA_CQPHC_HW_MINVER);
3319*cdcd52d4SBartosz Sobczak 	if (hw_rev >= IRDMA_GEN_2) {
3320*cdcd52d4SBartosz Sobczak 		temp |= LS_64(cqp->dcqcn_params.min_rate, IRDMA_CQPHC_MIN_RATE) |
3321*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->dcqcn_params.min_dec_factor, IRDMA_CQPHC_MIN_DEC_FACTOR);
3322*cdcd52d4SBartosz Sobczak 	}
3323*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_32, temp);
3324*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_40, 0);
3325*cdcd52d4SBartosz Sobczak 	temp = 0;
3326*cdcd52d4SBartosz Sobczak 	if (hw_rev >= IRDMA_GEN_2) {
3327*cdcd52d4SBartosz Sobczak 		temp |= LS_64(cqp->dcqcn_params.dcqcn_t, IRDMA_CQPHC_DCQCN_T) |
3328*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->dcqcn_params.rai_factor, IRDMA_CQPHC_RAI_FACTOR) |
3329*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->dcqcn_params.hai_factor, IRDMA_CQPHC_HAI_FACTOR);
3330*cdcd52d4SBartosz Sobczak 	}
3331*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_48, temp);
3332*cdcd52d4SBartosz Sobczak 	temp = 0;
3333*cdcd52d4SBartosz Sobczak 	if (hw_rev >= IRDMA_GEN_2) {
3334*cdcd52d4SBartosz Sobczak 		temp |= LS_64(cqp->dcqcn_params.dcqcn_b, IRDMA_CQPHC_DCQCN_B) |
3335*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->dcqcn_params.dcqcn_f, IRDMA_CQPHC_DCQCN_F) |
3336*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->dcqcn_params.cc_cfg_valid, IRDMA_CQPHC_CC_CFG_VALID) |
3337*cdcd52d4SBartosz Sobczak 		    LS_64(cqp->dcqcn_params.rreduce_mperiod, IRDMA_CQPHC_RREDUCE_MPERIOD);
3338*cdcd52d4SBartosz Sobczak 	}
3339*cdcd52d4SBartosz Sobczak 	set_64bit_val(cqp->host_ctx, IRDMA_BYTE_56, temp);
3340*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CQP_HOST_CTX WQE",
3341*cdcd52d4SBartosz Sobczak 			cqp->host_ctx, IRDMA_CQP_CTX_SIZE * 8);
3342*cdcd52d4SBartosz Sobczak 	p1 = RS_32_1(cqp->host_ctx_pa, 32);
3343*cdcd52d4SBartosz Sobczak 	p2 = (u32)cqp->host_ctx_pa;
3344*cdcd52d4SBartosz Sobczak 
3345*cdcd52d4SBartosz Sobczak 	writel(p1, cqp->dev->hw_regs[IRDMA_CCQPHIGH]);
3346*cdcd52d4SBartosz Sobczak 	writel(p2, cqp->dev->hw_regs[IRDMA_CCQPLOW]);
3347*cdcd52d4SBartosz Sobczak 
3348*cdcd52d4SBartosz Sobczak 	do {
3349*cdcd52d4SBartosz Sobczak 		if (cnt++ > cqp->dev->hw_attrs.max_done_count) {
3350*cdcd52d4SBartosz Sobczak 			ret_code = -ETIMEDOUT;
3351*cdcd52d4SBartosz Sobczak 			goto err;
3352*cdcd52d4SBartosz Sobczak 		}
3353*cdcd52d4SBartosz Sobczak 		irdma_usec_delay(cqp->dev->hw_attrs.max_sleep_count);
3354*cdcd52d4SBartosz Sobczak 		val = readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS]);
3355*cdcd52d4SBartosz Sobczak 	} while (!val);
3356*cdcd52d4SBartosz Sobczak 
3357*cdcd52d4SBartosz Sobczak 	if (FLD_RS_32(cqp->dev, val, IRDMA_CCQPSTATUS_CCQP_ERR)) {
3358*cdcd52d4SBartosz Sobczak 		ret_code = -EOPNOTSUPP;
3359*cdcd52d4SBartosz Sobczak 		goto err;
3360*cdcd52d4SBartosz Sobczak 	}
3361*cdcd52d4SBartosz Sobczak 
3362*cdcd52d4SBartosz Sobczak 	cqp->process_cqp_sds = irdma_update_sds_noccq;
3363*cdcd52d4SBartosz Sobczak 	return 0;
3364*cdcd52d4SBartosz Sobczak 
3365*cdcd52d4SBartosz Sobczak err:
3366*cdcd52d4SBartosz Sobczak 	spin_lock_destroy(&cqp->dev->cqp_lock);
3367*cdcd52d4SBartosz Sobczak 	irdma_free_dma_mem(cqp->dev->hw, &cqp->sdbuf);
3368*cdcd52d4SBartosz Sobczak 	err_code = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]);
3369*cdcd52d4SBartosz Sobczak 	*min_err = RS_32(err_code, IRDMA_CQPERRCODES_CQP_MINOR_CODE);
3370*cdcd52d4SBartosz Sobczak 	*maj_err = RS_32(err_code, IRDMA_CQPERRCODES_CQP_MAJOR_CODE);
3371*cdcd52d4SBartosz Sobczak 	return ret_code;
3372*cdcd52d4SBartosz Sobczak }
3373*cdcd52d4SBartosz Sobczak 
3374*cdcd52d4SBartosz Sobczak /**
3375*cdcd52d4SBartosz Sobczak  * irdma_sc_cqp_post_sq - post of cqp's sq
3376*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3377*cdcd52d4SBartosz Sobczak  */
3378*cdcd52d4SBartosz Sobczak void
3379*cdcd52d4SBartosz Sobczak irdma_sc_cqp_post_sq(struct irdma_sc_cqp *cqp)
3380*cdcd52d4SBartosz Sobczak {
3381*cdcd52d4SBartosz Sobczak 	db_wr32(IRDMA_RING_CURRENT_HEAD(cqp->sq_ring), cqp->dev->cqp_db);
3382*cdcd52d4SBartosz Sobczak 
3383*cdcd52d4SBartosz Sobczak 	irdma_debug(cqp->dev, IRDMA_DEBUG_WQE,
3384*cdcd52d4SBartosz Sobczak 		    "CQP SQ head 0x%x tail 0x%x size 0x%x\n", cqp->sq_ring.head,
3385*cdcd52d4SBartosz Sobczak 		    cqp->sq_ring.tail, cqp->sq_ring.size);
3386*cdcd52d4SBartosz Sobczak }
3387*cdcd52d4SBartosz Sobczak 
3388*cdcd52d4SBartosz Sobczak /**
3389*cdcd52d4SBartosz Sobczak  * irdma_sc_cqp_get_next_send_wqe_idx - get next wqe on cqp sq
3390*cdcd52d4SBartosz Sobczak  * and pass back index
3391*cdcd52d4SBartosz Sobczak  * @cqp: CQP HW structure
3392*cdcd52d4SBartosz Sobczak  * @scratch: private data for CQP WQE
3393*cdcd52d4SBartosz Sobczak  * @wqe_idx: WQE index of CQP SQ
3394*cdcd52d4SBartosz Sobczak  */
3395*cdcd52d4SBartosz Sobczak __le64 *
3396*cdcd52d4SBartosz Sobczak irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch,
3397*cdcd52d4SBartosz Sobczak 				   u32 *wqe_idx)
3398*cdcd52d4SBartosz Sobczak {
3399*cdcd52d4SBartosz Sobczak 	__le64 *wqe = NULL;
3400*cdcd52d4SBartosz Sobczak 	int ret_code;
3401*cdcd52d4SBartosz Sobczak 
3402*cdcd52d4SBartosz Sobczak 	if (IRDMA_RING_FULL_ERR(cqp->sq_ring)) {
3403*cdcd52d4SBartosz Sobczak 		irdma_debug(cqp->dev, IRDMA_DEBUG_WQE,
3404*cdcd52d4SBartosz Sobczak 			    "CQP SQ is full, head 0x%x tail 0x%x size 0x%x\n",
3405*cdcd52d4SBartosz Sobczak 			    cqp->sq_ring.head, cqp->sq_ring.tail,
3406*cdcd52d4SBartosz Sobczak 			    cqp->sq_ring.size);
3407*cdcd52d4SBartosz Sobczak 		return NULL;
3408*cdcd52d4SBartosz Sobczak 	}
3409*cdcd52d4SBartosz Sobczak 	IRDMA_ATOMIC_RING_MOVE_HEAD(cqp->sq_ring, *wqe_idx, ret_code);
3410*cdcd52d4SBartosz Sobczak 	if (ret_code)
3411*cdcd52d4SBartosz Sobczak 		return NULL;
3412*cdcd52d4SBartosz Sobczak 
3413*cdcd52d4SBartosz Sobczak 	cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS]++;
3414*cdcd52d4SBartosz Sobczak 	if (!*wqe_idx)
3415*cdcd52d4SBartosz Sobczak 		cqp->polarity = !cqp->polarity;
3416*cdcd52d4SBartosz Sobczak 	wqe = cqp->sq_base[*wqe_idx].elem;
3417*cdcd52d4SBartosz Sobczak 	cqp->scratch_array[*wqe_idx] = scratch;
3418*cdcd52d4SBartosz Sobczak 
3419*cdcd52d4SBartosz Sobczak 	memset(&wqe[0], 0, 24);
3420*cdcd52d4SBartosz Sobczak 	memset(&wqe[4], 0, 32);
3421*cdcd52d4SBartosz Sobczak 
3422*cdcd52d4SBartosz Sobczak 	return wqe;
3423*cdcd52d4SBartosz Sobczak }
3424*cdcd52d4SBartosz Sobczak 
3425*cdcd52d4SBartosz Sobczak /**
3426*cdcd52d4SBartosz Sobczak  * irdma_sc_cqp_destroy - destroy cqp during close
3427*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3428*cdcd52d4SBartosz Sobczak  */
3429*cdcd52d4SBartosz Sobczak int
3430*cdcd52d4SBartosz Sobczak irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp)
3431*cdcd52d4SBartosz Sobczak {
3432*cdcd52d4SBartosz Sobczak 	u32 cnt = 0, val;
3433*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
3434*cdcd52d4SBartosz Sobczak 
3435*cdcd52d4SBartosz Sobczak 	writel(0, cqp->dev->hw_regs[IRDMA_CCQPHIGH]);
3436*cdcd52d4SBartosz Sobczak 	writel(0, cqp->dev->hw_regs[IRDMA_CCQPLOW]);
3437*cdcd52d4SBartosz Sobczak 	do {
3438*cdcd52d4SBartosz Sobczak 		if (cnt++ > cqp->dev->hw_attrs.max_done_count) {
3439*cdcd52d4SBartosz Sobczak 			ret_code = -ETIMEDOUT;
3440*cdcd52d4SBartosz Sobczak 			break;
3441*cdcd52d4SBartosz Sobczak 		}
3442*cdcd52d4SBartosz Sobczak 		irdma_usec_delay(cqp->dev->hw_attrs.max_sleep_count);
3443*cdcd52d4SBartosz Sobczak 		val = readl(cqp->dev->hw_regs[IRDMA_CCQPSTATUS]);
3444*cdcd52d4SBartosz Sobczak 	} while (FLD_RS_32(cqp->dev, val, IRDMA_CCQPSTATUS_CCQP_DONE));
3445*cdcd52d4SBartosz Sobczak 
3446*cdcd52d4SBartosz Sobczak 	irdma_free_dma_mem(cqp->dev->hw, &cqp->sdbuf);
3447*cdcd52d4SBartosz Sobczak 	spin_lock_destroy(&cqp->dev->cqp_lock);
3448*cdcd52d4SBartosz Sobczak 	return ret_code;
3449*cdcd52d4SBartosz Sobczak }
3450*cdcd52d4SBartosz Sobczak 
3451*cdcd52d4SBartosz Sobczak /**
3452*cdcd52d4SBartosz Sobczak  * irdma_sc_ccq_arm - enable intr for control cq
3453*cdcd52d4SBartosz Sobczak  * @ccq: ccq sc struct
3454*cdcd52d4SBartosz Sobczak  */
3455*cdcd52d4SBartosz Sobczak void
3456*cdcd52d4SBartosz Sobczak irdma_sc_ccq_arm(struct irdma_sc_cq *ccq)
3457*cdcd52d4SBartosz Sobczak {
3458*cdcd52d4SBartosz Sobczak 	u64 temp_val;
3459*cdcd52d4SBartosz Sobczak 	u16 sw_cq_sel;
3460*cdcd52d4SBartosz Sobczak 	u8 arm_next_se;
3461*cdcd52d4SBartosz Sobczak 	u8 arm_seq_num;
3462*cdcd52d4SBartosz Sobczak 
3463*cdcd52d4SBartosz Sobczak 	get_64bit_val(ccq->cq_uk.shadow_area, IRDMA_BYTE_32, &temp_val);
3464*cdcd52d4SBartosz Sobczak 	sw_cq_sel = (u16)RS_64(temp_val, IRDMA_CQ_DBSA_SW_CQ_SELECT);
3465*cdcd52d4SBartosz Sobczak 	arm_next_se = (u8)RS_64(temp_val, IRDMA_CQ_DBSA_ARM_NEXT_SE);
3466*cdcd52d4SBartosz Sobczak 	arm_seq_num = (u8)RS_64(temp_val, IRDMA_CQ_DBSA_ARM_SEQ_NUM);
3467*cdcd52d4SBartosz Sobczak 	arm_seq_num++;
3468*cdcd52d4SBartosz Sobczak 	temp_val = LS_64(arm_seq_num, IRDMA_CQ_DBSA_ARM_SEQ_NUM) |
3469*cdcd52d4SBartosz Sobczak 	    LS_64(sw_cq_sel, IRDMA_CQ_DBSA_SW_CQ_SELECT) |
3470*cdcd52d4SBartosz Sobczak 	    LS_64(arm_next_se, IRDMA_CQ_DBSA_ARM_NEXT_SE) |
3471*cdcd52d4SBartosz Sobczak 	    LS_64(1, IRDMA_CQ_DBSA_ARM_NEXT);
3472*cdcd52d4SBartosz Sobczak 	set_64bit_val(ccq->cq_uk.shadow_area, IRDMA_BYTE_32, temp_val);
3473*cdcd52d4SBartosz Sobczak 
3474*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure shadow area is updated before arming */
3475*cdcd52d4SBartosz Sobczak 
3476*cdcd52d4SBartosz Sobczak 	db_wr32(ccq->cq_uk.cq_id, ccq->dev->cq_arm_db);
3477*cdcd52d4SBartosz Sobczak }
3478*cdcd52d4SBartosz Sobczak 
3479*cdcd52d4SBartosz Sobczak /**
3480*cdcd52d4SBartosz Sobczak  * irdma_sc_ccq_get_cqe_info - get ccq's cq entry
3481*cdcd52d4SBartosz Sobczak  * @ccq: ccq sc struct
3482*cdcd52d4SBartosz Sobczak  * @info: completion q entry to return
3483*cdcd52d4SBartosz Sobczak  */
3484*cdcd52d4SBartosz Sobczak int
3485*cdcd52d4SBartosz Sobczak irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,
3486*cdcd52d4SBartosz Sobczak 			  struct irdma_ccq_cqe_info *info)
3487*cdcd52d4SBartosz Sobczak {
3488*cdcd52d4SBartosz Sobczak 	u64 qp_ctx, temp, temp1;
3489*cdcd52d4SBartosz Sobczak 	__le64 *cqe;
3490*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
3491*cdcd52d4SBartosz Sobczak 	u32 wqe_idx;
3492*cdcd52d4SBartosz Sobczak 	u32 error;
3493*cdcd52d4SBartosz Sobczak 	u8 polarity;
3494*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
3495*cdcd52d4SBartosz Sobczak 
3496*cdcd52d4SBartosz Sobczak 	if (ccq->cq_uk.avoid_mem_cflct)
3497*cdcd52d4SBartosz Sobczak 		cqe = IRDMA_GET_CURRENT_EXTENDED_CQ_ELEM(&ccq->cq_uk);
3498*cdcd52d4SBartosz Sobczak 	else
3499*cdcd52d4SBartosz Sobczak 		cqe = IRDMA_GET_CURRENT_CQ_ELEM(&ccq->cq_uk);
3500*cdcd52d4SBartosz Sobczak 
3501*cdcd52d4SBartosz Sobczak 	get_64bit_val(cqe, IRDMA_BYTE_24, &temp);
3502*cdcd52d4SBartosz Sobczak 	polarity = (u8)RS_64(temp, IRDMA_CQ_VALID);
3503*cdcd52d4SBartosz Sobczak 	if (polarity != ccq->cq_uk.polarity)
3504*cdcd52d4SBartosz Sobczak 		return -ENOENT;
3505*cdcd52d4SBartosz Sobczak 
3506*cdcd52d4SBartosz Sobczak 	get_64bit_val(cqe, IRDMA_BYTE_8, &qp_ctx);
3507*cdcd52d4SBartosz Sobczak 	cqp = (struct irdma_sc_cqp *)(irdma_uintptr) qp_ctx;
3508*cdcd52d4SBartosz Sobczak 	info->error = (bool)RS_64(temp, IRDMA_CQ_ERROR);
3509*cdcd52d4SBartosz Sobczak 	info->maj_err_code = IRDMA_CQPSQ_MAJ_NO_ERROR;
3510*cdcd52d4SBartosz Sobczak 	info->min_err_code = (u16)RS_64(temp, IRDMA_CQ_MINERR);
3511*cdcd52d4SBartosz Sobczak 	if (info->error) {
3512*cdcd52d4SBartosz Sobczak 		info->maj_err_code = (u16)RS_64(temp, IRDMA_CQ_MAJERR);
3513*cdcd52d4SBartosz Sobczak 		error = readl(cqp->dev->hw_regs[IRDMA_CQPERRCODES]);
3514*cdcd52d4SBartosz Sobczak 		irdma_debug(cqp->dev, IRDMA_DEBUG_CQP,
3515*cdcd52d4SBartosz Sobczak 			    "CQPERRCODES error_code[x%08X]\n", error);
3516*cdcd52d4SBartosz Sobczak 	}
3517*cdcd52d4SBartosz Sobczak 
3518*cdcd52d4SBartosz Sobczak 	wqe_idx = (u32)RS_64(temp, IRDMA_CQ_WQEIDX);
3519*cdcd52d4SBartosz Sobczak 	info->scratch = cqp->scratch_array[wqe_idx];
3520*cdcd52d4SBartosz Sobczak 
3521*cdcd52d4SBartosz Sobczak 	get_64bit_val(cqe, IRDMA_BYTE_16, &temp1);
3522*cdcd52d4SBartosz Sobczak 	info->op_ret_val = (u32)RS_64(temp1, IRDMA_CCQ_OPRETVAL);
3523*cdcd52d4SBartosz Sobczak 	get_64bit_val(cqp->sq_base[wqe_idx].elem, IRDMA_BYTE_24, &temp1);
3524*cdcd52d4SBartosz Sobczak 	info->op_code = (u8)RS_64(temp1, IRDMA_CQPSQ_OPCODE);
3525*cdcd52d4SBartosz Sobczak 	info->cqp = cqp;
3526*cdcd52d4SBartosz Sobczak 
3527*cdcd52d4SBartosz Sobczak 	/* move the head for cq */
3528*cdcd52d4SBartosz Sobczak 	IRDMA_RING_MOVE_HEAD(ccq->cq_uk.cq_ring, ret_code);
3529*cdcd52d4SBartosz Sobczak 	if (!IRDMA_RING_CURRENT_HEAD(ccq->cq_uk.cq_ring))
3530*cdcd52d4SBartosz Sobczak 		ccq->cq_uk.polarity ^= 1;
3531*cdcd52d4SBartosz Sobczak 
3532*cdcd52d4SBartosz Sobczak 	/* update cq tail in cq shadow memory also */
3533*cdcd52d4SBartosz Sobczak 	IRDMA_RING_MOVE_TAIL(ccq->cq_uk.cq_ring);
3534*cdcd52d4SBartosz Sobczak 	set_64bit_val(ccq->cq_uk.shadow_area, IRDMA_BYTE_0,
3535*cdcd52d4SBartosz Sobczak 		      IRDMA_RING_CURRENT_HEAD(ccq->cq_uk.cq_ring));
3536*cdcd52d4SBartosz Sobczak 
3537*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure shadow area is updated before moving tail */
3538*cdcd52d4SBartosz Sobczak 
3539*cdcd52d4SBartosz Sobczak 	IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
3540*cdcd52d4SBartosz Sobczak 	ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++;
3541*cdcd52d4SBartosz Sobczak 
3542*cdcd52d4SBartosz Sobczak 	return ret_code;
3543*cdcd52d4SBartosz Sobczak }
3544*cdcd52d4SBartosz Sobczak 
3545*cdcd52d4SBartosz Sobczak /**
3546*cdcd52d4SBartosz Sobczak  * irdma_sc_poll_for_cqp_op_done - Waits for last write to complete in CQP SQ
3547*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3548*cdcd52d4SBartosz Sobczak  * @op_code: cqp opcode for completion
3549*cdcd52d4SBartosz Sobczak  * @compl_info: completion q entry to return
3550*cdcd52d4SBartosz Sobczak  */
3551*cdcd52d4SBartosz Sobczak int
3552*cdcd52d4SBartosz Sobczak irdma_sc_poll_for_cqp_op_done(struct irdma_sc_cqp *cqp, u8 op_code,
3553*cdcd52d4SBartosz Sobczak 			      struct irdma_ccq_cqe_info *compl_info)
3554*cdcd52d4SBartosz Sobczak {
3555*cdcd52d4SBartosz Sobczak 	struct irdma_ccq_cqe_info info = {0};
3556*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cq *ccq;
3557*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
3558*cdcd52d4SBartosz Sobczak 	u32 cnt = 0;
3559*cdcd52d4SBartosz Sobczak 
3560*cdcd52d4SBartosz Sobczak 	ccq = cqp->dev->ccq;
3561*cdcd52d4SBartosz Sobczak 	while (1) {
3562*cdcd52d4SBartosz Sobczak 		if (cnt++ > 100 * cqp->dev->hw_attrs.max_done_count)
3563*cdcd52d4SBartosz Sobczak 			return -ETIMEDOUT;
3564*cdcd52d4SBartosz Sobczak 
3565*cdcd52d4SBartosz Sobczak 		if (cqp->dev->no_cqp)
3566*cdcd52d4SBartosz Sobczak 			return -ETIMEDOUT;
3567*cdcd52d4SBartosz Sobczak 
3568*cdcd52d4SBartosz Sobczak 		if (irdma_sc_ccq_get_cqe_info(ccq, &info)) {
3569*cdcd52d4SBartosz Sobczak 			irdma_usec_delay(cqp->dev->hw_attrs.max_sleep_count);
3570*cdcd52d4SBartosz Sobczak 			continue;
3571*cdcd52d4SBartosz Sobczak 		}
3572*cdcd52d4SBartosz Sobczak 		if (info.error && info.op_code != IRDMA_CQP_OP_QUERY_STAG) {
3573*cdcd52d4SBartosz Sobczak 			ret_code = -EIO;
3574*cdcd52d4SBartosz Sobczak 			break;
3575*cdcd52d4SBartosz Sobczak 		}
3576*cdcd52d4SBartosz Sobczak 		/* make sure op code matches */
3577*cdcd52d4SBartosz Sobczak 		if (op_code == info.op_code)
3578*cdcd52d4SBartosz Sobczak 			break;
3579*cdcd52d4SBartosz Sobczak 		irdma_debug(cqp->dev, IRDMA_DEBUG_WQE,
3580*cdcd52d4SBartosz Sobczak 			    "opcode mismatch for my op code 0x%x, returned opcode %x\n",
3581*cdcd52d4SBartosz Sobczak 			    op_code, info.op_code);
3582*cdcd52d4SBartosz Sobczak 	}
3583*cdcd52d4SBartosz Sobczak 
3584*cdcd52d4SBartosz Sobczak 	if (compl_info)
3585*cdcd52d4SBartosz Sobczak 		irdma_memcpy(compl_info, &info, sizeof(*compl_info));
3586*cdcd52d4SBartosz Sobczak 
3587*cdcd52d4SBartosz Sobczak 	return ret_code;
3588*cdcd52d4SBartosz Sobczak }
3589*cdcd52d4SBartosz Sobczak 
3590*cdcd52d4SBartosz Sobczak /**
3591*cdcd52d4SBartosz Sobczak  * irdma_sc_manage_hmc_pm_func_table - manage of function table
3592*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3593*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
3594*cdcd52d4SBartosz Sobczak  * @info: info for the manage function table operation
3595*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
3596*cdcd52d4SBartosz Sobczak  */
3597*cdcd52d4SBartosz Sobczak static int
3598*cdcd52d4SBartosz Sobczak irdma_sc_manage_hmc_pm_func_table(struct irdma_sc_cqp *cqp,
3599*cdcd52d4SBartosz Sobczak 				  struct irdma_hmc_fcn_info *info,
3600*cdcd52d4SBartosz Sobczak 				  u64 scratch, bool post_sq)
3601*cdcd52d4SBartosz Sobczak {
3602*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
3603*cdcd52d4SBartosz Sobczak 	u64 hdr;
3604*cdcd52d4SBartosz Sobczak 
3605*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
3606*cdcd52d4SBartosz Sobczak 	if (!wqe)
3607*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
3608*cdcd52d4SBartosz Sobczak 
3609*cdcd52d4SBartosz Sobczak 	hdr = LS_64(info->vf_id, IRDMA_CQPSQ_MHMC_VFIDX) |
3610*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_MANAGE_HMC_PM_FUNC_TABLE,
3611*cdcd52d4SBartosz Sobczak 		  IRDMA_CQPSQ_OPCODE) |
3612*cdcd52d4SBartosz Sobczak 	    LS_64(info->free_fcn, IRDMA_CQPSQ_MHMC_FREEPMFN) |
3613*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
3614*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
3615*cdcd52d4SBartosz Sobczak 
3616*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
3617*cdcd52d4SBartosz Sobczak 
3618*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE,
3619*cdcd52d4SBartosz Sobczak 			"MANAGE_HMC_PM_FUNC_TABLE WQE", wqe,
3620*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
3621*cdcd52d4SBartosz Sobczak 	if (post_sq)
3622*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
3623*cdcd52d4SBartosz Sobczak 
3624*cdcd52d4SBartosz Sobczak 	return 0;
3625*cdcd52d4SBartosz Sobczak }
3626*cdcd52d4SBartosz Sobczak 
3627*cdcd52d4SBartosz Sobczak /**
3628*cdcd52d4SBartosz Sobczak  * irdma_sc_commit_fpm_val_done - wait for cqp eqe completion
3629*cdcd52d4SBartosz Sobczak  * for fpm commit
3630*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3631*cdcd52d4SBartosz Sobczak  */
3632*cdcd52d4SBartosz Sobczak static int
3633*cdcd52d4SBartosz Sobczak irdma_sc_commit_fpm_val_done(struct irdma_sc_cqp *cqp)
3634*cdcd52d4SBartosz Sobczak {
3635*cdcd52d4SBartosz Sobczak 	return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_COMMIT_FPM_VAL,
3636*cdcd52d4SBartosz Sobczak 					     NULL);
3637*cdcd52d4SBartosz Sobczak }
3638*cdcd52d4SBartosz Sobczak 
3639*cdcd52d4SBartosz Sobczak /**
3640*cdcd52d4SBartosz Sobczak  * irdma_sc_commit_fpm_val - cqp wqe for commit fpm values
3641*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3642*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
3643*cdcd52d4SBartosz Sobczak  * @hmc_fn_id: hmc function id
3644*cdcd52d4SBartosz Sobczak  * @commit_fpm_mem: Memory for fpm values
3645*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
3646*cdcd52d4SBartosz Sobczak  * @wait_type: poll ccq or cqp registers for cqp completion
3647*cdcd52d4SBartosz Sobczak  */
3648*cdcd52d4SBartosz Sobczak static int
3649*cdcd52d4SBartosz Sobczak irdma_sc_commit_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch,
3650*cdcd52d4SBartosz Sobczak 			u8 hmc_fn_id,
3651*cdcd52d4SBartosz Sobczak 			struct irdma_dma_mem *commit_fpm_mem,
3652*cdcd52d4SBartosz Sobczak 			bool post_sq, u8 wait_type)
3653*cdcd52d4SBartosz Sobczak {
3654*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
3655*cdcd52d4SBartosz Sobczak 	u64 hdr;
3656*cdcd52d4SBartosz Sobczak 	u32 tail, val, error;
3657*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
3658*cdcd52d4SBartosz Sobczak 
3659*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
3660*cdcd52d4SBartosz Sobczak 	if (!wqe)
3661*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
3662*cdcd52d4SBartosz Sobczak 
3663*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, hmc_fn_id);
3664*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, commit_fpm_mem->pa);
3665*cdcd52d4SBartosz Sobczak 
3666*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_COMMIT_FPM_BUF_SIZE, IRDMA_CQPSQ_BUFSIZE) |
3667*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_COMMIT_FPM_VAL, IRDMA_CQPSQ_OPCODE) |
3668*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
3669*cdcd52d4SBartosz Sobczak 
3670*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
3671*cdcd52d4SBartosz Sobczak 
3672*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
3673*cdcd52d4SBartosz Sobczak 
3674*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "COMMIT_FPM_VAL WQE", wqe,
3675*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
3676*cdcd52d4SBartosz Sobczak 	irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
3677*cdcd52d4SBartosz Sobczak 
3678*cdcd52d4SBartosz Sobczak 	if (post_sq) {
3679*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
3680*cdcd52d4SBartosz Sobczak 		if (wait_type == IRDMA_CQP_WAIT_POLL_REGS)
3681*cdcd52d4SBartosz Sobczak 			ret_code = irdma_cqp_poll_registers(cqp, tail,
3682*cdcd52d4SBartosz Sobczak 							    cqp->dev->hw_attrs.max_done_count);
3683*cdcd52d4SBartosz Sobczak 		else if (wait_type == IRDMA_CQP_WAIT_POLL_CQ)
3684*cdcd52d4SBartosz Sobczak 			ret_code = irdma_sc_commit_fpm_val_done(cqp);
3685*cdcd52d4SBartosz Sobczak 	}
3686*cdcd52d4SBartosz Sobczak 
3687*cdcd52d4SBartosz Sobczak 	return ret_code;
3688*cdcd52d4SBartosz Sobczak }
3689*cdcd52d4SBartosz Sobczak 
3690*cdcd52d4SBartosz Sobczak /**
3691*cdcd52d4SBartosz Sobczak  * irdma_sc_query_fpm_val_done - poll for cqp wqe completion for
3692*cdcd52d4SBartosz Sobczak  * query fpm
3693*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3694*cdcd52d4SBartosz Sobczak  */
3695*cdcd52d4SBartosz Sobczak static int
3696*cdcd52d4SBartosz Sobczak irdma_sc_query_fpm_val_done(struct irdma_sc_cqp *cqp)
3697*cdcd52d4SBartosz Sobczak {
3698*cdcd52d4SBartosz Sobczak 	return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_QUERY_FPM_VAL,
3699*cdcd52d4SBartosz Sobczak 					     NULL);
3700*cdcd52d4SBartosz Sobczak }
3701*cdcd52d4SBartosz Sobczak 
3702*cdcd52d4SBartosz Sobczak /**
3703*cdcd52d4SBartosz Sobczak  * irdma_sc_query_fpm_val - cqp wqe query fpm values
3704*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
3705*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
3706*cdcd52d4SBartosz Sobczak  * @hmc_fn_id: hmc function id
3707*cdcd52d4SBartosz Sobczak  * @query_fpm_mem: memory for return fpm values
3708*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
3709*cdcd52d4SBartosz Sobczak  * @wait_type: poll ccq or cqp registers for cqp completion
3710*cdcd52d4SBartosz Sobczak  */
3711*cdcd52d4SBartosz Sobczak static int
3712*cdcd52d4SBartosz Sobczak irdma_sc_query_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch,
3713*cdcd52d4SBartosz Sobczak 		       u8 hmc_fn_id,
3714*cdcd52d4SBartosz Sobczak 		       struct irdma_dma_mem *query_fpm_mem,
3715*cdcd52d4SBartosz Sobczak 		       bool post_sq, u8 wait_type)
3716*cdcd52d4SBartosz Sobczak {
3717*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
3718*cdcd52d4SBartosz Sobczak 	u64 hdr;
3719*cdcd52d4SBartosz Sobczak 	u32 tail, val, error;
3720*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
3721*cdcd52d4SBartosz Sobczak 
3722*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
3723*cdcd52d4SBartosz Sobczak 	if (!wqe)
3724*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
3725*cdcd52d4SBartosz Sobczak 
3726*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, hmc_fn_id);
3727*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, query_fpm_mem->pa);
3728*cdcd52d4SBartosz Sobczak 
3729*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_QUERY_FPM_VAL, IRDMA_CQPSQ_OPCODE) |
3730*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
3731*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
3732*cdcd52d4SBartosz Sobczak 
3733*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
3734*cdcd52d4SBartosz Sobczak 
3735*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "QUERY_FPM WQE", wqe,
3736*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
3737*cdcd52d4SBartosz Sobczak 	irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
3738*cdcd52d4SBartosz Sobczak 
3739*cdcd52d4SBartosz Sobczak 	if (post_sq) {
3740*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
3741*cdcd52d4SBartosz Sobczak 		if (wait_type == IRDMA_CQP_WAIT_POLL_REGS)
3742*cdcd52d4SBartosz Sobczak 			ret_code = irdma_cqp_poll_registers(cqp, tail,
3743*cdcd52d4SBartosz Sobczak 							    cqp->dev->hw_attrs.max_done_count);
3744*cdcd52d4SBartosz Sobczak 		else if (wait_type == IRDMA_CQP_WAIT_POLL_CQ)
3745*cdcd52d4SBartosz Sobczak 			ret_code = irdma_sc_query_fpm_val_done(cqp);
3746*cdcd52d4SBartosz Sobczak 	}
3747*cdcd52d4SBartosz Sobczak 
3748*cdcd52d4SBartosz Sobczak 	return ret_code;
3749*cdcd52d4SBartosz Sobczak }
3750*cdcd52d4SBartosz Sobczak 
3751*cdcd52d4SBartosz Sobczak /**
3752*cdcd52d4SBartosz Sobczak  * irdma_sc_ceq_init - initialize ceq
3753*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3754*cdcd52d4SBartosz Sobczak  * @info: ceq initialization info
3755*cdcd52d4SBartosz Sobczak  */
3756*cdcd52d4SBartosz Sobczak int
3757*cdcd52d4SBartosz Sobczak irdma_sc_ceq_init(struct irdma_sc_ceq *ceq,
3758*cdcd52d4SBartosz Sobczak 		  struct irdma_ceq_init_info *info)
3759*cdcd52d4SBartosz Sobczak {
3760*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
3761*cdcd52d4SBartosz Sobczak 
3762*cdcd52d4SBartosz Sobczak 	if (info->elem_cnt < info->dev->hw_attrs.min_hw_ceq_size ||
3763*cdcd52d4SBartosz Sobczak 	    info->elem_cnt > info->dev->hw_attrs.max_hw_ceq_size)
3764*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3765*cdcd52d4SBartosz Sobczak 
3766*cdcd52d4SBartosz Sobczak 	if (info->ceq_id > (info->dev->hmc_fpm_misc.max_ceqs - 1))
3767*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3768*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
3769*cdcd52d4SBartosz Sobczak 
3770*cdcd52d4SBartosz Sobczak 	if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
3771*cdcd52d4SBartosz Sobczak 		return -EINVAL;
3772*cdcd52d4SBartosz Sobczak 
3773*cdcd52d4SBartosz Sobczak 	ceq->size = sizeof(*ceq);
3774*cdcd52d4SBartosz Sobczak 	ceq->ceqe_base = (struct irdma_ceqe *)info->ceqe_base;
3775*cdcd52d4SBartosz Sobczak 	ceq->ceq_id = info->ceq_id;
3776*cdcd52d4SBartosz Sobczak 	ceq->dev = info->dev;
3777*cdcd52d4SBartosz Sobczak 	ceq->elem_cnt = info->elem_cnt;
3778*cdcd52d4SBartosz Sobczak 	ceq->ceq_elem_pa = info->ceqe_pa;
3779*cdcd52d4SBartosz Sobczak 	ceq->virtual_map = info->virtual_map;
3780*cdcd52d4SBartosz Sobczak 	ceq->itr_no_expire = info->itr_no_expire;
3781*cdcd52d4SBartosz Sobczak 	ceq->reg_cq = info->reg_cq;
3782*cdcd52d4SBartosz Sobczak 	ceq->reg_cq_size = 0;
3783*cdcd52d4SBartosz Sobczak 	spin_lock_init(&ceq->req_cq_lock);
3784*cdcd52d4SBartosz Sobczak 	ceq->pbl_chunk_size = (ceq->virtual_map ? info->pbl_chunk_size : 0);
3785*cdcd52d4SBartosz Sobczak 	ceq->first_pm_pbl_idx = (ceq->virtual_map ? info->first_pm_pbl_idx : 0);
3786*cdcd52d4SBartosz Sobczak 	ceq->pbl_list = (ceq->virtual_map ? info->pbl_list : NULL);
3787*cdcd52d4SBartosz Sobczak 	ceq->tph_en = info->tph_en;
3788*cdcd52d4SBartosz Sobczak 	ceq->tph_val = info->tph_val;
3789*cdcd52d4SBartosz Sobczak 	ceq->vsi = info->vsi;
3790*cdcd52d4SBartosz Sobczak 	ceq->polarity = 1;
3791*cdcd52d4SBartosz Sobczak 	IRDMA_RING_INIT(ceq->ceq_ring, ceq->elem_cnt);
3792*cdcd52d4SBartosz Sobczak 	ceq->dev->ceq[info->ceq_id] = ceq;
3793*cdcd52d4SBartosz Sobczak 
3794*cdcd52d4SBartosz Sobczak 	return 0;
3795*cdcd52d4SBartosz Sobczak }
3796*cdcd52d4SBartosz Sobczak 
3797*cdcd52d4SBartosz Sobczak /**
3798*cdcd52d4SBartosz Sobczak  * irdma_sc_ceq_create - create ceq wqe
3799*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3800*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
3801*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
3802*cdcd52d4SBartosz Sobczak  */
3803*cdcd52d4SBartosz Sobczak 
3804*cdcd52d4SBartosz Sobczak static int
3805*cdcd52d4SBartosz Sobczak irdma_sc_ceq_create(struct irdma_sc_ceq *ceq, u64 scratch,
3806*cdcd52d4SBartosz Sobczak 		    bool post_sq)
3807*cdcd52d4SBartosz Sobczak {
3808*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
3809*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
3810*cdcd52d4SBartosz Sobczak 	u64 hdr;
3811*cdcd52d4SBartosz Sobczak 
3812*cdcd52d4SBartosz Sobczak 	cqp = ceq->dev->cqp;
3813*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
3814*cdcd52d4SBartosz Sobczak 	if (!wqe)
3815*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
3816*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, ceq->elem_cnt);
3817*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32,
3818*cdcd52d4SBartosz Sobczak 		      (ceq->virtual_map ? 0 : ceq->ceq_elem_pa));
3819*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48,
3820*cdcd52d4SBartosz Sobczak 		      (ceq->virtual_map ? ceq->first_pm_pbl_idx : 0));
3821*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_56,
3822*cdcd52d4SBartosz Sobczak 		      LS_64(ceq->tph_val, IRDMA_CQPSQ_TPHVAL) |
3823*cdcd52d4SBartosz Sobczak 		      LS_64(ceq->vsi->vsi_idx, IRDMA_CQPSQ_VSIIDX));
3824*cdcd52d4SBartosz Sobczak 	hdr = LS_64(ceq->ceq_id, IRDMA_CQPSQ_CEQ_CEQID) |
3825*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_CREATE_CEQ, IRDMA_CQPSQ_OPCODE) |
3826*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->pbl_chunk_size, IRDMA_CQPSQ_CEQ_LPBLSIZE) |
3827*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->virtual_map, IRDMA_CQPSQ_CEQ_VMAP) |
3828*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->itr_no_expire, IRDMA_CQPSQ_CEQ_ITRNOEXPIRE) |
3829*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->tph_en, IRDMA_CQPSQ_TPHEN) |
3830*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
3831*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
3832*cdcd52d4SBartosz Sobczak 
3833*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
3834*cdcd52d4SBartosz Sobczak 
3835*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CEQ_CREATE WQE", wqe,
3836*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
3837*cdcd52d4SBartosz Sobczak 	if (post_sq)
3838*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
3839*cdcd52d4SBartosz Sobczak 
3840*cdcd52d4SBartosz Sobczak 	return 0;
3841*cdcd52d4SBartosz Sobczak }
3842*cdcd52d4SBartosz Sobczak 
3843*cdcd52d4SBartosz Sobczak /**
3844*cdcd52d4SBartosz Sobczak  * irdma_sc_cceq_create_done - poll for control ceq wqe to complete
3845*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3846*cdcd52d4SBartosz Sobczak  */
3847*cdcd52d4SBartosz Sobczak static int
3848*cdcd52d4SBartosz Sobczak irdma_sc_cceq_create_done(struct irdma_sc_ceq *ceq)
3849*cdcd52d4SBartosz Sobczak {
3850*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
3851*cdcd52d4SBartosz Sobczak 
3852*cdcd52d4SBartosz Sobczak 	cqp = ceq->dev->cqp;
3853*cdcd52d4SBartosz Sobczak 	return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CEQ,
3854*cdcd52d4SBartosz Sobczak 					     NULL);
3855*cdcd52d4SBartosz Sobczak }
3856*cdcd52d4SBartosz Sobczak 
3857*cdcd52d4SBartosz Sobczak /**
3858*cdcd52d4SBartosz Sobczak  * irdma_sc_cceq_destroy_done - poll for destroy cceq to complete
3859*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3860*cdcd52d4SBartosz Sobczak  */
3861*cdcd52d4SBartosz Sobczak int
3862*cdcd52d4SBartosz Sobczak irdma_sc_cceq_destroy_done(struct irdma_sc_ceq *ceq)
3863*cdcd52d4SBartosz Sobczak {
3864*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
3865*cdcd52d4SBartosz Sobczak 
3866*cdcd52d4SBartosz Sobczak 	if (ceq->reg_cq)
3867*cdcd52d4SBartosz Sobczak 		irdma_sc_remove_cq_ctx(ceq, ceq->dev->ccq);
3868*cdcd52d4SBartosz Sobczak 
3869*cdcd52d4SBartosz Sobczak 	cqp = ceq->dev->cqp;
3870*cdcd52d4SBartosz Sobczak 	cqp->process_cqp_sds = irdma_update_sds_noccq;
3871*cdcd52d4SBartosz Sobczak 
3872*cdcd52d4SBartosz Sobczak 	return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_DESTROY_CEQ,
3873*cdcd52d4SBartosz Sobczak 					     NULL);
3874*cdcd52d4SBartosz Sobczak }
3875*cdcd52d4SBartosz Sobczak 
3876*cdcd52d4SBartosz Sobczak /**
3877*cdcd52d4SBartosz Sobczak  * irdma_sc_cceq_create - create cceq
3878*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3879*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
3880*cdcd52d4SBartosz Sobczak  */
3881*cdcd52d4SBartosz Sobczak int
3882*cdcd52d4SBartosz Sobczak irdma_sc_cceq_create(struct irdma_sc_ceq *ceq, u64 scratch)
3883*cdcd52d4SBartosz Sobczak {
3884*cdcd52d4SBartosz Sobczak 	int ret_code;
3885*cdcd52d4SBartosz Sobczak 	struct irdma_sc_dev *dev = ceq->dev;
3886*cdcd52d4SBartosz Sobczak 
3887*cdcd52d4SBartosz Sobczak 	dev->ccq->vsi = ceq->vsi;
3888*cdcd52d4SBartosz Sobczak 	if (ceq->reg_cq) {
3889*cdcd52d4SBartosz Sobczak 		ret_code = irdma_sc_add_cq_ctx(ceq, ceq->dev->ccq);
3890*cdcd52d4SBartosz Sobczak 		if (ret_code)
3891*cdcd52d4SBartosz Sobczak 			return ret_code;
3892*cdcd52d4SBartosz Sobczak 	}
3893*cdcd52d4SBartosz Sobczak 
3894*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_ceq_create(ceq, scratch, true);
3895*cdcd52d4SBartosz Sobczak 	if (!ret_code)
3896*cdcd52d4SBartosz Sobczak 		return irdma_sc_cceq_create_done(ceq);
3897*cdcd52d4SBartosz Sobczak 
3898*cdcd52d4SBartosz Sobczak 	return ret_code;
3899*cdcd52d4SBartosz Sobczak }
3900*cdcd52d4SBartosz Sobczak 
3901*cdcd52d4SBartosz Sobczak /**
3902*cdcd52d4SBartosz Sobczak  * irdma_sc_ceq_destroy - destroy ceq
3903*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3904*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
3905*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
3906*cdcd52d4SBartosz Sobczak  */
3907*cdcd52d4SBartosz Sobczak int
3908*cdcd52d4SBartosz Sobczak irdma_sc_ceq_destroy(struct irdma_sc_ceq *ceq, u64 scratch, bool post_sq)
3909*cdcd52d4SBartosz Sobczak {
3910*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
3911*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
3912*cdcd52d4SBartosz Sobczak 	u64 hdr;
3913*cdcd52d4SBartosz Sobczak 
3914*cdcd52d4SBartosz Sobczak 	cqp = ceq->dev->cqp;
3915*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
3916*cdcd52d4SBartosz Sobczak 	if (!wqe)
3917*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
3918*cdcd52d4SBartosz Sobczak 
3919*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, ceq->elem_cnt);
3920*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48, ceq->first_pm_pbl_idx);
3921*cdcd52d4SBartosz Sobczak 	hdr = ceq->ceq_id |
3922*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_DESTROY_CEQ, IRDMA_CQPSQ_OPCODE) |
3923*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->pbl_chunk_size, IRDMA_CQPSQ_CEQ_LPBLSIZE) |
3924*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->virtual_map, IRDMA_CQPSQ_CEQ_VMAP) |
3925*cdcd52d4SBartosz Sobczak 	    LS_64(ceq->tph_en, IRDMA_CQPSQ_TPHEN) |
3926*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
3927*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
3928*cdcd52d4SBartosz Sobczak 
3929*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
3930*cdcd52d4SBartosz Sobczak 
3931*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CEQ_DESTROY WQE", wqe,
3932*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
3933*cdcd52d4SBartosz Sobczak 	ceq->dev->ceq[ceq->ceq_id] = NULL;
3934*cdcd52d4SBartosz Sobczak 	if (post_sq)
3935*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
3936*cdcd52d4SBartosz Sobczak 
3937*cdcd52d4SBartosz Sobczak 	return 0;
3938*cdcd52d4SBartosz Sobczak }
3939*cdcd52d4SBartosz Sobczak 
3940*cdcd52d4SBartosz Sobczak /**
3941*cdcd52d4SBartosz Sobczak  * irdma_sc_process_ceq - process ceq
3942*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
3943*cdcd52d4SBartosz Sobczak  * @ceq: ceq sc structure
3944*cdcd52d4SBartosz Sobczak  *
3945*cdcd52d4SBartosz Sobczak  * It is expected caller serializes this function with cleanup_ceqes()
3946*cdcd52d4SBartosz Sobczak  * because these functions manipulate the same ceq
3947*cdcd52d4SBartosz Sobczak  */
3948*cdcd52d4SBartosz Sobczak void *
3949*cdcd52d4SBartosz Sobczak irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq)
3950*cdcd52d4SBartosz Sobczak {
3951*cdcd52d4SBartosz Sobczak 	u64 temp;
3952*cdcd52d4SBartosz Sobczak 	__le64 *ceqe;
3953*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cq *cq = NULL;
3954*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cq *temp_cq;
3955*cdcd52d4SBartosz Sobczak 	u8 polarity;
3956*cdcd52d4SBartosz Sobczak 	u32 cq_idx;
3957*cdcd52d4SBartosz Sobczak 	unsigned long flags;
3958*cdcd52d4SBartosz Sobczak 
3959*cdcd52d4SBartosz Sobczak 	do {
3960*cdcd52d4SBartosz Sobczak 		cq_idx = 0;
3961*cdcd52d4SBartosz Sobczak 		ceqe = IRDMA_GET_CURRENT_CEQ_ELEM(ceq);
3962*cdcd52d4SBartosz Sobczak 		get_64bit_val(ceqe, IRDMA_BYTE_0, &temp);
3963*cdcd52d4SBartosz Sobczak 		polarity = (u8)RS_64(temp, IRDMA_CEQE_VALID);
3964*cdcd52d4SBartosz Sobczak 		if (polarity != ceq->polarity)
3965*cdcd52d4SBartosz Sobczak 			return NULL;
3966*cdcd52d4SBartosz Sobczak 
3967*cdcd52d4SBartosz Sobczak 		temp_cq = (struct irdma_sc_cq *)(irdma_uintptr) LS_64_1(temp, 1);
3968*cdcd52d4SBartosz Sobczak 		if (!temp_cq) {
3969*cdcd52d4SBartosz Sobczak 			cq_idx = IRDMA_INVALID_CQ_IDX;
3970*cdcd52d4SBartosz Sobczak 			IRDMA_RING_MOVE_TAIL(ceq->ceq_ring);
3971*cdcd52d4SBartosz Sobczak 
3972*cdcd52d4SBartosz Sobczak 			if (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring))
3973*cdcd52d4SBartosz Sobczak 				ceq->polarity ^= 1;
3974*cdcd52d4SBartosz Sobczak 			continue;
3975*cdcd52d4SBartosz Sobczak 		}
3976*cdcd52d4SBartosz Sobczak 
3977*cdcd52d4SBartosz Sobczak 		cq = temp_cq;
3978*cdcd52d4SBartosz Sobczak 		if (ceq->reg_cq) {
3979*cdcd52d4SBartosz Sobczak 			spin_lock_irqsave(&ceq->req_cq_lock, flags);
3980*cdcd52d4SBartosz Sobczak 			cq_idx = irdma_sc_find_reg_cq(ceq, cq);
3981*cdcd52d4SBartosz Sobczak 			spin_unlock_irqrestore(&ceq->req_cq_lock, flags);
3982*cdcd52d4SBartosz Sobczak 		}
3983*cdcd52d4SBartosz Sobczak 
3984*cdcd52d4SBartosz Sobczak 		IRDMA_RING_MOVE_TAIL(ceq->ceq_ring);
3985*cdcd52d4SBartosz Sobczak 		if (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring))
3986*cdcd52d4SBartosz Sobczak 			ceq->polarity ^= 1;
3987*cdcd52d4SBartosz Sobczak 	} while (cq_idx == IRDMA_INVALID_CQ_IDX);
3988*cdcd52d4SBartosz Sobczak 
3989*cdcd52d4SBartosz Sobczak 	if (cq) {
3990*cdcd52d4SBartosz Sobczak 		cq->cq_uk.armed = false;
3991*cdcd52d4SBartosz Sobczak 		irdma_sc_cq_ack(cq);
3992*cdcd52d4SBartosz Sobczak 	}
3993*cdcd52d4SBartosz Sobczak 	return cq;
3994*cdcd52d4SBartosz Sobczak }
3995*cdcd52d4SBartosz Sobczak 
3996*cdcd52d4SBartosz Sobczak /**
3997*cdcd52d4SBartosz Sobczak  * irdma_sc_cleanup_ceqes - clear the valid ceqes ctx matching the cq
3998*cdcd52d4SBartosz Sobczak  * @cq: cq for which the ceqes need to be cleaned up
3999*cdcd52d4SBartosz Sobczak  * @ceq: ceq ptr
4000*cdcd52d4SBartosz Sobczak  *
4001*cdcd52d4SBartosz Sobczak  * The function is called after the cq is destroyed to cleanup
4002*cdcd52d4SBartosz Sobczak  * its pending ceqe entries. It is expected caller serializes this
4003*cdcd52d4SBartosz Sobczak  * function with process_ceq() in interrupt context.
4004*cdcd52d4SBartosz Sobczak  */
4005*cdcd52d4SBartosz Sobczak void
4006*cdcd52d4SBartosz Sobczak irdma_sc_cleanup_ceqes(struct irdma_sc_cq *cq, struct irdma_sc_ceq *ceq)
4007*cdcd52d4SBartosz Sobczak {
4008*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cq *next_cq;
4009*cdcd52d4SBartosz Sobczak 	u8 ceq_polarity = ceq->polarity;
4010*cdcd52d4SBartosz Sobczak 	__le64 *ceqe;
4011*cdcd52d4SBartosz Sobczak 	u8 polarity;
4012*cdcd52d4SBartosz Sobczak 	u64 temp;
4013*cdcd52d4SBartosz Sobczak 	int next;
4014*cdcd52d4SBartosz Sobczak 	u32 i;
4015*cdcd52d4SBartosz Sobczak 
4016*cdcd52d4SBartosz Sobczak 	next = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, 0);
4017*cdcd52d4SBartosz Sobczak 
4018*cdcd52d4SBartosz Sobczak 	for (i = 1; i <= IRDMA_RING_SIZE(*ceq); i++) {
4019*cdcd52d4SBartosz Sobczak 		ceqe = IRDMA_GET_CEQ_ELEM_AT_POS(ceq, next);
4020*cdcd52d4SBartosz Sobczak 
4021*cdcd52d4SBartosz Sobczak 		get_64bit_val(ceqe, IRDMA_BYTE_0, &temp);
4022*cdcd52d4SBartosz Sobczak 		polarity = (u8)RS_64(temp, IRDMA_CEQE_VALID);
4023*cdcd52d4SBartosz Sobczak 		if (polarity != ceq_polarity)
4024*cdcd52d4SBartosz Sobczak 			return;
4025*cdcd52d4SBartosz Sobczak 
4026*cdcd52d4SBartosz Sobczak 		next_cq = (struct irdma_sc_cq *)(irdma_uintptr) LS_64_1(temp, 1);
4027*cdcd52d4SBartosz Sobczak 		if (cq == next_cq)
4028*cdcd52d4SBartosz Sobczak 			set_64bit_val(ceqe, IRDMA_BYTE_0, temp & IRDMA_CEQE_VALID_M);
4029*cdcd52d4SBartosz Sobczak 
4030*cdcd52d4SBartosz Sobczak 		next = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, i);
4031*cdcd52d4SBartosz Sobczak 		if (!next)
4032*cdcd52d4SBartosz Sobczak 			ceq_polarity ^= 1;
4033*cdcd52d4SBartosz Sobczak 	}
4034*cdcd52d4SBartosz Sobczak }
4035*cdcd52d4SBartosz Sobczak 
4036*cdcd52d4SBartosz Sobczak /**
4037*cdcd52d4SBartosz Sobczak  * irdma_sc_aeq_init - initialize aeq
4038*cdcd52d4SBartosz Sobczak  * @aeq: aeq structure ptr
4039*cdcd52d4SBartosz Sobczak  * @info: aeq initialization info
4040*cdcd52d4SBartosz Sobczak  */
4041*cdcd52d4SBartosz Sobczak int
4042*cdcd52d4SBartosz Sobczak irdma_sc_aeq_init(struct irdma_sc_aeq *aeq,
4043*cdcd52d4SBartosz Sobczak 		  struct irdma_aeq_init_info *info)
4044*cdcd52d4SBartosz Sobczak {
4045*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
4046*cdcd52d4SBartosz Sobczak 
4047*cdcd52d4SBartosz Sobczak 	if (info->elem_cnt < info->dev->hw_attrs.min_hw_aeq_size ||
4048*cdcd52d4SBartosz Sobczak 	    info->elem_cnt > info->dev->hw_attrs.max_hw_aeq_size)
4049*cdcd52d4SBartosz Sobczak 		return -EINVAL;
4050*cdcd52d4SBartosz Sobczak 
4051*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
4052*cdcd52d4SBartosz Sobczak 
4053*cdcd52d4SBartosz Sobczak 	if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
4054*cdcd52d4SBartosz Sobczak 		return -EINVAL;
4055*cdcd52d4SBartosz Sobczak 
4056*cdcd52d4SBartosz Sobczak 	aeq->size = sizeof(*aeq);
4057*cdcd52d4SBartosz Sobczak 	aeq->polarity = 1;
4058*cdcd52d4SBartosz Sobczak 	aeq->aeqe_base = (struct irdma_sc_aeqe *)info->aeqe_base;
4059*cdcd52d4SBartosz Sobczak 	aeq->dev = info->dev;
4060*cdcd52d4SBartosz Sobczak 	aeq->elem_cnt = info->elem_cnt;
4061*cdcd52d4SBartosz Sobczak 	aeq->aeq_elem_pa = info->aeq_elem_pa;
4062*cdcd52d4SBartosz Sobczak 	IRDMA_RING_INIT(aeq->aeq_ring, aeq->elem_cnt);
4063*cdcd52d4SBartosz Sobczak 	aeq->virtual_map = info->virtual_map;
4064*cdcd52d4SBartosz Sobczak 	aeq->pbl_list = (aeq->virtual_map ? info->pbl_list : NULL);
4065*cdcd52d4SBartosz Sobczak 	aeq->pbl_chunk_size = (aeq->virtual_map ? info->pbl_chunk_size : 0);
4066*cdcd52d4SBartosz Sobczak 	aeq->first_pm_pbl_idx = (aeq->virtual_map ? info->first_pm_pbl_idx : 0);
4067*cdcd52d4SBartosz Sobczak 	aeq->msix_idx = info->msix_idx;
4068*cdcd52d4SBartosz Sobczak 	info->dev->aeq = aeq;
4069*cdcd52d4SBartosz Sobczak 
4070*cdcd52d4SBartosz Sobczak 	return 0;
4071*cdcd52d4SBartosz Sobczak }
4072*cdcd52d4SBartosz Sobczak 
4073*cdcd52d4SBartosz Sobczak /**
4074*cdcd52d4SBartosz Sobczak  * irdma_sc_aeq_create - create aeq
4075*cdcd52d4SBartosz Sobczak  * @aeq: aeq structure ptr
4076*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4077*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
4078*cdcd52d4SBartosz Sobczak  */
4079*cdcd52d4SBartosz Sobczak static int
4080*cdcd52d4SBartosz Sobczak irdma_sc_aeq_create(struct irdma_sc_aeq *aeq, u64 scratch,
4081*cdcd52d4SBartosz Sobczak 		    bool post_sq)
4082*cdcd52d4SBartosz Sobczak {
4083*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
4084*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
4085*cdcd52d4SBartosz Sobczak 	u64 hdr;
4086*cdcd52d4SBartosz Sobczak 
4087*cdcd52d4SBartosz Sobczak 	cqp = aeq->dev->cqp;
4088*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
4089*cdcd52d4SBartosz Sobczak 	if (!wqe)
4090*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
4091*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, aeq->elem_cnt);
4092*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32,
4093*cdcd52d4SBartosz Sobczak 		      (aeq->virtual_map ? 0 : aeq->aeq_elem_pa));
4094*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48,
4095*cdcd52d4SBartosz Sobczak 		      (aeq->virtual_map ? aeq->first_pm_pbl_idx : 0));
4096*cdcd52d4SBartosz Sobczak 
4097*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_CREATE_AEQ, IRDMA_CQPSQ_OPCODE) |
4098*cdcd52d4SBartosz Sobczak 	    LS_64(aeq->pbl_chunk_size, IRDMA_CQPSQ_AEQ_LPBLSIZE) |
4099*cdcd52d4SBartosz Sobczak 	    LS_64(aeq->virtual_map, IRDMA_CQPSQ_AEQ_VMAP) |
4100*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
4101*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
4102*cdcd52d4SBartosz Sobczak 
4103*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
4104*cdcd52d4SBartosz Sobczak 
4105*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "AEQ_CREATE WQE", wqe,
4106*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
4107*cdcd52d4SBartosz Sobczak 	if (post_sq)
4108*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
4109*cdcd52d4SBartosz Sobczak 
4110*cdcd52d4SBartosz Sobczak 	return 0;
4111*cdcd52d4SBartosz Sobczak }
4112*cdcd52d4SBartosz Sobczak 
4113*cdcd52d4SBartosz Sobczak /**
4114*cdcd52d4SBartosz Sobczak  * irdma_sc_aeq_destroy - destroy aeq during close
4115*cdcd52d4SBartosz Sobczak  * @aeq: aeq structure ptr
4116*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4117*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
4118*cdcd52d4SBartosz Sobczak  */
4119*cdcd52d4SBartosz Sobczak static int
4120*cdcd52d4SBartosz Sobczak irdma_sc_aeq_destroy(struct irdma_sc_aeq *aeq, u64 scratch,
4121*cdcd52d4SBartosz Sobczak 		     bool post_sq)
4122*cdcd52d4SBartosz Sobczak {
4123*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
4124*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
4125*cdcd52d4SBartosz Sobczak 	struct irdma_sc_dev *dev;
4126*cdcd52d4SBartosz Sobczak 	u64 hdr;
4127*cdcd52d4SBartosz Sobczak 
4128*cdcd52d4SBartosz Sobczak 	dev = aeq->dev;
4129*cdcd52d4SBartosz Sobczak 	writel(0, dev->hw_regs[IRDMA_PFINT_AEQCTL]);
4130*cdcd52d4SBartosz Sobczak 
4131*cdcd52d4SBartosz Sobczak 	cqp = dev->cqp;
4132*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
4133*cdcd52d4SBartosz Sobczak 	if (!wqe)
4134*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
4135*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, aeq->elem_cnt);
4136*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_48, aeq->first_pm_pbl_idx);
4137*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_DESTROY_AEQ, IRDMA_CQPSQ_OPCODE) |
4138*cdcd52d4SBartosz Sobczak 	    LS_64(aeq->pbl_chunk_size, IRDMA_CQPSQ_AEQ_LPBLSIZE) |
4139*cdcd52d4SBartosz Sobczak 	    LS_64(aeq->virtual_map, IRDMA_CQPSQ_AEQ_VMAP) |
4140*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
4141*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
4142*cdcd52d4SBartosz Sobczak 
4143*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
4144*cdcd52d4SBartosz Sobczak 
4145*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "AEQ_DESTROY WQE", wqe,
4146*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
4147*cdcd52d4SBartosz Sobczak 	if (post_sq)
4148*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
4149*cdcd52d4SBartosz Sobczak 	return 0;
4150*cdcd52d4SBartosz Sobczak }
4151*cdcd52d4SBartosz Sobczak 
4152*cdcd52d4SBartosz Sobczak /**
4153*cdcd52d4SBartosz Sobczak  * irdma_sc_get_next_aeqe - get next aeq entry
4154*cdcd52d4SBartosz Sobczak  * @aeq: aeq structure ptr
4155*cdcd52d4SBartosz Sobczak  * @info: aeqe info to be returned
4156*cdcd52d4SBartosz Sobczak  */
4157*cdcd52d4SBartosz Sobczak int
4158*cdcd52d4SBartosz Sobczak irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq,
4159*cdcd52d4SBartosz Sobczak 		       struct irdma_aeqe_info *info)
4160*cdcd52d4SBartosz Sobczak {
4161*cdcd52d4SBartosz Sobczak 	u64 temp, compl_ctx;
4162*cdcd52d4SBartosz Sobczak 	__le64 *aeqe;
4163*cdcd52d4SBartosz Sobczak 	u16 wqe_idx;
4164*cdcd52d4SBartosz Sobczak 	u8 ae_src;
4165*cdcd52d4SBartosz Sobczak 	u8 polarity;
4166*cdcd52d4SBartosz Sobczak 
4167*cdcd52d4SBartosz Sobczak 	aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq);
4168*cdcd52d4SBartosz Sobczak 	get_64bit_val(aeqe, IRDMA_BYTE_0, &compl_ctx);
4169*cdcd52d4SBartosz Sobczak 	get_64bit_val(aeqe, IRDMA_BYTE_8, &temp);
4170*cdcd52d4SBartosz Sobczak 	polarity = (u8)RS_64(temp, IRDMA_AEQE_VALID);
4171*cdcd52d4SBartosz Sobczak 
4172*cdcd52d4SBartosz Sobczak 	if (aeq->polarity != polarity)
4173*cdcd52d4SBartosz Sobczak 		return -ENOENT;
4174*cdcd52d4SBartosz Sobczak 
4175*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(aeq->dev, IRDMA_DEBUG_WQE, "AEQ_ENTRY WQE", aeqe, 16);
4176*cdcd52d4SBartosz Sobczak 
4177*cdcd52d4SBartosz Sobczak 	ae_src = (u8)RS_64(temp, IRDMA_AEQE_AESRC);
4178*cdcd52d4SBartosz Sobczak 	wqe_idx = (u16)RS_64(temp, IRDMA_AEQE_WQDESCIDX);
4179*cdcd52d4SBartosz Sobczak 	info->qp_cq_id = (u32)RS_64(temp, IRDMA_AEQE_QPCQID_LOW) |
4180*cdcd52d4SBartosz Sobczak 	    ((u32)RS_64(temp, IRDMA_AEQE_QPCQID_HI) << 18);
4181*cdcd52d4SBartosz Sobczak 	info->ae_id = (u16)RS_64(temp, IRDMA_AEQE_AECODE);
4182*cdcd52d4SBartosz Sobczak 	info->tcp_state = (u8)RS_64(temp, IRDMA_AEQE_TCPSTATE);
4183*cdcd52d4SBartosz Sobczak 	info->iwarp_state = (u8)RS_64(temp, IRDMA_AEQE_IWSTATE);
4184*cdcd52d4SBartosz Sobczak 	info->q2_data_written = (u8)RS_64(temp, IRDMA_AEQE_Q2DATA);
4185*cdcd52d4SBartosz Sobczak 	info->aeqe_overflow = (bool)RS_64(temp, IRDMA_AEQE_OVERFLOW);
4186*cdcd52d4SBartosz Sobczak 
4187*cdcd52d4SBartosz Sobczak 	info->ae_src = ae_src;
4188*cdcd52d4SBartosz Sobczak 	switch (info->ae_id) {
4189*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_PRIV_OPERATION_DENIED:
4190*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_INVALIDATE_TYPE1_MW:
4191*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_MWBIND_ZERO_BASED_TYPE1_MW:
4192*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_FASTREG_INVALID_PBL_HPS_CFG:
4193*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_AMP_FASTREG_PBLE_MISMATCH:
4194*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
4195*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_UDA_XMIT_BAD_PD:
4196*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT:
4197*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_BAD_CLOSE:
4198*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RDMA_READ_WHILE_ORD_ZERO:
4199*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_STAG_ZERO_INVALID:
4200*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_IB_RREQ_AND_Q1_FULL:
4201*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_IB_INVALID_REQUEST:
4202*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_WQE_UNEXPECTED_OPCODE:
4203*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_IB_REMOTE_ACCESS_ERROR:
4204*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_IB_REMOTE_OP_ERROR:
4205*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION:
4206*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_MO:
4207*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_UBE_INVALID_QN:
4208*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_DDP_NO_L_BIT:
4209*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
4210*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RDMAP_ROE_UNEXPECTED_OPCODE:
4211*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_ROE_INVALID_RDMA_READ_REQUEST:
4212*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_ROE_INVALID_RDMA_WRITE_OR_READ_RESP:
4213*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_ROCE_RSP_LENGTH_ERROR:
4214*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_INVALID_ARP_ENTRY:
4215*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_INVALID_TCP_OPTION_RCVD:
4216*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_STALE_ARP_ENTRY:
4217*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_INVALID_AH_ENTRY:
4218*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
4219*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_SEGMENT_TOO_SMALL:
4220*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_TOO_MANY_RETRIES:
4221*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_DOUBT_REACHABILITY:
4222*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_CONNECTION_ESTABLISHED:
4223*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RESET_SENT:
4224*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_TERMINATE_SENT:
4225*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RESET_NOT_SENT:
4226*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LCE_QP_CATASTROPHIC:
4227*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_QP_SUSPEND_COMPLETE:
4228*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_UDA_L4LEN_INVALID:
4229*cdcd52d4SBartosz Sobczak 		info->qp = true;
4230*cdcd52d4SBartosz Sobczak 		info->compl_ctx = compl_ctx;
4231*cdcd52d4SBartosz Sobczak 		break;
4232*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LCE_CQ_CATASTROPHIC:
4233*cdcd52d4SBartosz Sobczak 		info->cq = true;
4234*cdcd52d4SBartosz Sobczak 		info->compl_ctx = LS_64_1(compl_ctx, 1);
4235*cdcd52d4SBartosz Sobczak 		ae_src = IRDMA_AE_SOURCE_RSVD;
4236*cdcd52d4SBartosz Sobczak 		break;
4237*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_ROCE_EMPTY_MCG:
4238*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_ROCE_BAD_MC_IP_ADDR:
4239*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_ROCE_BAD_MC_QPID:
4240*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_MCG_QP_PROTOCOL_MISMATCH:
4241*cdcd52d4SBartosz Sobczak 		/* fallthrough */
4242*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_CONNECTION_RESET:
4243*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_SYN_RECEIVED:
4244*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_FIN_RECEIVED:
4245*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_CLOSE_COMPLETE:
4246*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_LLP_TERMINATE_RECEIVED:
4247*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE:
4248*cdcd52d4SBartosz Sobczak 		ae_src = IRDMA_AE_SOURCE_RSVD;
4249*cdcd52d4SBartosz Sobczak 		info->qp = true;
4250*cdcd52d4SBartosz Sobczak 		info->compl_ctx = compl_ctx;
4251*cdcd52d4SBartosz Sobczak 		break;
4252*cdcd52d4SBartosz Sobczak 	default:
4253*cdcd52d4SBartosz Sobczak 		break;
4254*cdcd52d4SBartosz Sobczak 	}
4255*cdcd52d4SBartosz Sobczak 
4256*cdcd52d4SBartosz Sobczak 	switch (ae_src) {
4257*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_RQ:
4258*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_RQ_0011:
4259*cdcd52d4SBartosz Sobczak 		info->qp = true;
4260*cdcd52d4SBartosz Sobczak 		info->rq = true;
4261*cdcd52d4SBartosz Sobczak 		info->wqe_idx = wqe_idx;
4262*cdcd52d4SBartosz Sobczak 		info->compl_ctx = compl_ctx;
4263*cdcd52d4SBartosz Sobczak 		break;
4264*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_CQ:
4265*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_CQ_0110:
4266*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_CQ_1010:
4267*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_CQ_1110:
4268*cdcd52d4SBartosz Sobczak 		info->cq = true;
4269*cdcd52d4SBartosz Sobczak 		info->compl_ctx = LS_64_1(compl_ctx, 1);
4270*cdcd52d4SBartosz Sobczak 		break;
4271*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_SQ:
4272*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_SQ_0111:
4273*cdcd52d4SBartosz Sobczak 		info->qp = true;
4274*cdcd52d4SBartosz Sobczak 		info->sq = true;
4275*cdcd52d4SBartosz Sobczak 		info->wqe_idx = wqe_idx;
4276*cdcd52d4SBartosz Sobczak 		info->compl_ctx = compl_ctx;
4277*cdcd52d4SBartosz Sobczak 		break;
4278*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_IN_WR:
4279*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_IN_RR:
4280*cdcd52d4SBartosz Sobczak 		info->qp = true;
4281*cdcd52d4SBartosz Sobczak 		info->compl_ctx = compl_ctx;
4282*cdcd52d4SBartosz Sobczak 		info->in_rdrsp_wr = true;
4283*cdcd52d4SBartosz Sobczak 		break;
4284*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_OUT_RR:
4285*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_OUT_RR_1111:
4286*cdcd52d4SBartosz Sobczak 		info->qp = true;
4287*cdcd52d4SBartosz Sobczak 		info->compl_ctx = compl_ctx;
4288*cdcd52d4SBartosz Sobczak 		info->out_rdrsp = true;
4289*cdcd52d4SBartosz Sobczak 		break;
4290*cdcd52d4SBartosz Sobczak 	case IRDMA_AE_SOURCE_RSVD:
4291*cdcd52d4SBartosz Sobczak 	default:
4292*cdcd52d4SBartosz Sobczak 		break;
4293*cdcd52d4SBartosz Sobczak 	}
4294*cdcd52d4SBartosz Sobczak 
4295*cdcd52d4SBartosz Sobczak 	IRDMA_RING_MOVE_TAIL(aeq->aeq_ring);
4296*cdcd52d4SBartosz Sobczak 	if (!IRDMA_RING_CURRENT_TAIL(aeq->aeq_ring))
4297*cdcd52d4SBartosz Sobczak 		aeq->polarity ^= 1;
4298*cdcd52d4SBartosz Sobczak 
4299*cdcd52d4SBartosz Sobczak 	return 0;
4300*cdcd52d4SBartosz Sobczak }
4301*cdcd52d4SBartosz Sobczak 
4302*cdcd52d4SBartosz Sobczak /**
4303*cdcd52d4SBartosz Sobczak  * irdma_sc_repost_aeq_entries - repost completed aeq entries
4304*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
4305*cdcd52d4SBartosz Sobczak  * @count: allocate count
4306*cdcd52d4SBartosz Sobczak  */
4307*cdcd52d4SBartosz Sobczak int
4308*cdcd52d4SBartosz Sobczak irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count)
4309*cdcd52d4SBartosz Sobczak {
4310*cdcd52d4SBartosz Sobczak 	writel(count, dev->hw_regs[IRDMA_AEQALLOC]);
4311*cdcd52d4SBartosz Sobczak 
4312*cdcd52d4SBartosz Sobczak 	return 0;
4313*cdcd52d4SBartosz Sobczak }
4314*cdcd52d4SBartosz Sobczak 
4315*cdcd52d4SBartosz Sobczak /**
4316*cdcd52d4SBartosz Sobczak  * irdma_sc_ccq_init - initialize control cq
4317*cdcd52d4SBartosz Sobczak  * @cq: sc's cq ctruct
4318*cdcd52d4SBartosz Sobczak  * @info: info for control cq initialization
4319*cdcd52d4SBartosz Sobczak  */
4320*cdcd52d4SBartosz Sobczak int
4321*cdcd52d4SBartosz Sobczak irdma_sc_ccq_init(struct irdma_sc_cq *cq, struct irdma_ccq_init_info *info)
4322*cdcd52d4SBartosz Sobczak {
4323*cdcd52d4SBartosz Sobczak 	u32 pble_obj_cnt;
4324*cdcd52d4SBartosz Sobczak 
4325*cdcd52d4SBartosz Sobczak 	if (info->num_elem < info->dev->hw_attrs.uk_attrs.min_hw_cq_size ||
4326*cdcd52d4SBartosz Sobczak 	    info->num_elem > info->dev->hw_attrs.uk_attrs.max_hw_cq_size)
4327*cdcd52d4SBartosz Sobczak 		return -EINVAL;
4328*cdcd52d4SBartosz Sobczak 
4329*cdcd52d4SBartosz Sobczak 	if (info->ceq_id > (info->dev->hmc_fpm_misc.max_ceqs - 1))
4330*cdcd52d4SBartosz Sobczak 		return -EINVAL;
4331*cdcd52d4SBartosz Sobczak 
4332*cdcd52d4SBartosz Sobczak 	pble_obj_cnt = info->dev->hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt;
4333*cdcd52d4SBartosz Sobczak 
4334*cdcd52d4SBartosz Sobczak 	if (info->virtual_map && info->first_pm_pbl_idx >= pble_obj_cnt)
4335*cdcd52d4SBartosz Sobczak 		return -EINVAL;
4336*cdcd52d4SBartosz Sobczak 
4337*cdcd52d4SBartosz Sobczak 	cq->cq_pa = info->cq_pa;
4338*cdcd52d4SBartosz Sobczak 	cq->cq_uk.cq_base = info->cq_base;
4339*cdcd52d4SBartosz Sobczak 	cq->shadow_area_pa = info->shadow_area_pa;
4340*cdcd52d4SBartosz Sobczak 	cq->cq_uk.shadow_area = info->shadow_area;
4341*cdcd52d4SBartosz Sobczak 	cq->shadow_read_threshold = info->shadow_read_threshold;
4342*cdcd52d4SBartosz Sobczak 	cq->dev = info->dev;
4343*cdcd52d4SBartosz Sobczak 	cq->ceq_id = info->ceq_id;
4344*cdcd52d4SBartosz Sobczak 	cq->cq_uk.cq_size = info->num_elem;
4345*cdcd52d4SBartosz Sobczak 	cq->cq_type = IRDMA_CQ_TYPE_CQP;
4346*cdcd52d4SBartosz Sobczak 	cq->ceqe_mask = info->ceqe_mask;
4347*cdcd52d4SBartosz Sobczak 	IRDMA_RING_INIT(cq->cq_uk.cq_ring, info->num_elem);
4348*cdcd52d4SBartosz Sobczak 	cq->cq_uk.cq_id = 0;	/* control cq is id 0 always */
4349*cdcd52d4SBartosz Sobczak 	cq->ceq_id_valid = info->ceq_id_valid;
4350*cdcd52d4SBartosz Sobczak 	cq->tph_en = info->tph_en;
4351*cdcd52d4SBartosz Sobczak 	cq->tph_val = info->tph_val;
4352*cdcd52d4SBartosz Sobczak 	cq->cq_uk.avoid_mem_cflct = info->avoid_mem_cflct;
4353*cdcd52d4SBartosz Sobczak 	cq->pbl_list = info->pbl_list;
4354*cdcd52d4SBartosz Sobczak 	cq->virtual_map = info->virtual_map;
4355*cdcd52d4SBartosz Sobczak 	cq->pbl_chunk_size = info->pbl_chunk_size;
4356*cdcd52d4SBartosz Sobczak 	cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
4357*cdcd52d4SBartosz Sobczak 	cq->cq_uk.polarity = true;
4358*cdcd52d4SBartosz Sobczak 	cq->vsi = info->vsi;
4359*cdcd52d4SBartosz Sobczak 	cq->cq_uk.cq_ack_db = cq->dev->cq_ack_db;
4360*cdcd52d4SBartosz Sobczak 
4361*cdcd52d4SBartosz Sobczak 	/* Only applicable to CQs other than CCQ so initialize to zero */
4362*cdcd52d4SBartosz Sobczak 	cq->cq_uk.cqe_alloc_db = NULL;
4363*cdcd52d4SBartosz Sobczak 
4364*cdcd52d4SBartosz Sobczak 	info->dev->ccq = cq;
4365*cdcd52d4SBartosz Sobczak 	return 0;
4366*cdcd52d4SBartosz Sobczak }
4367*cdcd52d4SBartosz Sobczak 
4368*cdcd52d4SBartosz Sobczak /**
4369*cdcd52d4SBartosz Sobczak  * irdma_sc_ccq_create_done - poll cqp for ccq create
4370*cdcd52d4SBartosz Sobczak  * @ccq: ccq sc struct
4371*cdcd52d4SBartosz Sobczak  */
4372*cdcd52d4SBartosz Sobczak static inline int
4373*cdcd52d4SBartosz Sobczak irdma_sc_ccq_create_done(struct irdma_sc_cq *ccq)
4374*cdcd52d4SBartosz Sobczak {
4375*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
4376*cdcd52d4SBartosz Sobczak 
4377*cdcd52d4SBartosz Sobczak 	cqp = ccq->dev->cqp;
4378*cdcd52d4SBartosz Sobczak 
4379*cdcd52d4SBartosz Sobczak 	return irdma_sc_poll_for_cqp_op_done(cqp, IRDMA_CQP_OP_CREATE_CQ, NULL);
4380*cdcd52d4SBartosz Sobczak }
4381*cdcd52d4SBartosz Sobczak 
4382*cdcd52d4SBartosz Sobczak /**
4383*cdcd52d4SBartosz Sobczak  * irdma_sc_ccq_create - create control cq
4384*cdcd52d4SBartosz Sobczak  * @ccq: ccq sc struct
4385*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4386*cdcd52d4SBartosz Sobczak  * @check_overflow: overlow flag for ccq
4387*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
4388*cdcd52d4SBartosz Sobczak  */
4389*cdcd52d4SBartosz Sobczak int
4390*cdcd52d4SBartosz Sobczak irdma_sc_ccq_create(struct irdma_sc_cq *ccq, u64 scratch,
4391*cdcd52d4SBartosz Sobczak 		    bool check_overflow, bool post_sq)
4392*cdcd52d4SBartosz Sobczak {
4393*cdcd52d4SBartosz Sobczak 	int ret_code;
4394*cdcd52d4SBartosz Sobczak 
4395*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_cq_create(ccq, scratch, check_overflow, post_sq);
4396*cdcd52d4SBartosz Sobczak 	if (ret_code)
4397*cdcd52d4SBartosz Sobczak 		return ret_code;
4398*cdcd52d4SBartosz Sobczak 
4399*cdcd52d4SBartosz Sobczak 	if (post_sq) {
4400*cdcd52d4SBartosz Sobczak 		ret_code = irdma_sc_ccq_create_done(ccq);
4401*cdcd52d4SBartosz Sobczak 		if (ret_code)
4402*cdcd52d4SBartosz Sobczak 			return ret_code;
4403*cdcd52d4SBartosz Sobczak 	}
4404*cdcd52d4SBartosz Sobczak 	ccq->dev->cqp->process_cqp_sds = irdma_cqp_sds_cmd;
4405*cdcd52d4SBartosz Sobczak 
4406*cdcd52d4SBartosz Sobczak 	return 0;
4407*cdcd52d4SBartosz Sobczak }
4408*cdcd52d4SBartosz Sobczak 
4409*cdcd52d4SBartosz Sobczak /**
4410*cdcd52d4SBartosz Sobczak  * irdma_sc_ccq_destroy - destroy ccq during close
4411*cdcd52d4SBartosz Sobczak  * @ccq: ccq sc struct
4412*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4413*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
4414*cdcd52d4SBartosz Sobczak  */
4415*cdcd52d4SBartosz Sobczak int
4416*cdcd52d4SBartosz Sobczak irdma_sc_ccq_destroy(struct irdma_sc_cq *ccq, u64 scratch, bool post_sq)
4417*cdcd52d4SBartosz Sobczak {
4418*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp;
4419*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
4420*cdcd52d4SBartosz Sobczak 	u64 hdr;
4421*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
4422*cdcd52d4SBartosz Sobczak 	u32 tail, val, error;
4423*cdcd52d4SBartosz Sobczak 
4424*cdcd52d4SBartosz Sobczak 	cqp = ccq->dev->cqp;
4425*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
4426*cdcd52d4SBartosz Sobczak 	if (!wqe)
4427*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
4428*cdcd52d4SBartosz Sobczak 
4429*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, ccq->cq_uk.cq_size);
4430*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, RS_64_1(ccq, 1));
4431*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_40, ccq->shadow_area_pa);
4432*cdcd52d4SBartosz Sobczak 
4433*cdcd52d4SBartosz Sobczak 	hdr = ccq->cq_uk.cq_id |
4434*cdcd52d4SBartosz Sobczak 	    FLD_LS_64(ccq->dev, (ccq->ceq_id_valid ? ccq->ceq_id : 0),
4435*cdcd52d4SBartosz Sobczak 		      IRDMA_CQPSQ_CQ_CEQID) |
4436*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_DESTROY_CQ, IRDMA_CQPSQ_OPCODE) |
4437*cdcd52d4SBartosz Sobczak 	    LS_64(ccq->ceqe_mask, IRDMA_CQPSQ_CQ_ENCEQEMASK) |
4438*cdcd52d4SBartosz Sobczak 	    LS_64(ccq->ceq_id_valid, IRDMA_CQPSQ_CQ_CEQIDVALID) |
4439*cdcd52d4SBartosz Sobczak 	    LS_64(ccq->tph_en, IRDMA_CQPSQ_TPHEN) |
4440*cdcd52d4SBartosz Sobczak 	    LS_64(ccq->cq_uk.avoid_mem_cflct, IRDMA_CQPSQ_CQ_AVOIDMEMCNFLCT) |
4441*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
4442*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
4443*cdcd52d4SBartosz Sobczak 
4444*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
4445*cdcd52d4SBartosz Sobczak 
4446*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "CCQ_DESTROY WQE", wqe,
4447*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
4448*cdcd52d4SBartosz Sobczak 	irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
4449*cdcd52d4SBartosz Sobczak 
4450*cdcd52d4SBartosz Sobczak 	if (post_sq) {
4451*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
4452*cdcd52d4SBartosz Sobczak 		ret_code = irdma_cqp_poll_registers(cqp, tail,
4453*cdcd52d4SBartosz Sobczak 						    cqp->dev->hw_attrs.max_done_count);
4454*cdcd52d4SBartosz Sobczak 	}
4455*cdcd52d4SBartosz Sobczak 
4456*cdcd52d4SBartosz Sobczak 	cqp->process_cqp_sds = irdma_update_sds_noccq;
4457*cdcd52d4SBartosz Sobczak 
4458*cdcd52d4SBartosz Sobczak 	return ret_code;
4459*cdcd52d4SBartosz Sobczak }
4460*cdcd52d4SBartosz Sobczak 
4461*cdcd52d4SBartosz Sobczak /**
4462*cdcd52d4SBartosz Sobczak  * irdma_sc_init_iw_hmc() - queries fpm values using cqp and populates hmc_info
4463*cdcd52d4SBartosz Sobczak  * @dev : ptr to irdma_dev struct
4464*cdcd52d4SBartosz Sobczak  * @hmc_fn_id: hmc function id
4465*cdcd52d4SBartosz Sobczak  */
4466*cdcd52d4SBartosz Sobczak int
4467*cdcd52d4SBartosz Sobczak irdma_sc_init_iw_hmc(struct irdma_sc_dev *dev, u8 hmc_fn_id)
4468*cdcd52d4SBartosz Sobczak {
4469*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_info *hmc_info;
4470*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_fpm_misc *hmc_fpm_misc;
4471*cdcd52d4SBartosz Sobczak 	struct irdma_dma_mem query_fpm_mem;
4472*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
4473*cdcd52d4SBartosz Sobczak 	u8 wait_type;
4474*cdcd52d4SBartosz Sobczak 
4475*cdcd52d4SBartosz Sobczak 	hmc_info = dev->hmc_info;
4476*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc = &dev->hmc_fpm_misc;
4477*cdcd52d4SBartosz Sobczak 	query_fpm_mem.pa = dev->fpm_query_buf_pa;
4478*cdcd52d4SBartosz Sobczak 	query_fpm_mem.va = dev->fpm_query_buf;
4479*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_fn_id = hmc_fn_id;
4480*cdcd52d4SBartosz Sobczak 	wait_type = (u8)IRDMA_CQP_WAIT_POLL_REGS;
4481*cdcd52d4SBartosz Sobczak 
4482*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_query_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id,
4483*cdcd52d4SBartosz Sobczak 					  &query_fpm_mem, true, wait_type);
4484*cdcd52d4SBartosz Sobczak 	if (ret_code)
4485*cdcd52d4SBartosz Sobczak 		return ret_code;
4486*cdcd52d4SBartosz Sobczak 
4487*cdcd52d4SBartosz Sobczak 	/* parse the fpm_query_buf and fill hmc obj info */
4488*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_parse_fpm_query_buf(dev, query_fpm_mem.va, hmc_info,
4489*cdcd52d4SBartosz Sobczak 						hmc_fpm_misc);
4490*cdcd52d4SBartosz Sobczak 
4491*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_HMC, "QUERY FPM BUFFER",
4492*cdcd52d4SBartosz Sobczak 			query_fpm_mem.va, IRDMA_QUERY_FPM_BUF_SIZE);
4493*cdcd52d4SBartosz Sobczak 	return ret_code;
4494*cdcd52d4SBartosz Sobczak }
4495*cdcd52d4SBartosz Sobczak 
4496*cdcd52d4SBartosz Sobczak /**
4497*cdcd52d4SBartosz Sobczak  * irdma_sc_cfg_iw_fpm() - commits hmc obj cnt values using cqp
4498*cdcd52d4SBartosz Sobczak  * command and populates fpm base address in hmc_info
4499*cdcd52d4SBartosz Sobczak  * @dev : ptr to irdma_dev struct
4500*cdcd52d4SBartosz Sobczak  * @hmc_fn_id: hmc function id
4501*cdcd52d4SBartosz Sobczak  */
4502*cdcd52d4SBartosz Sobczak static int
4503*cdcd52d4SBartosz Sobczak irdma_sc_cfg_iw_fpm(struct irdma_sc_dev *dev, u8 hmc_fn_id)
4504*cdcd52d4SBartosz Sobczak {
4505*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_obj_info *obj_info;
4506*cdcd52d4SBartosz Sobczak 	__le64 *buf;
4507*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_info *hmc_info;
4508*cdcd52d4SBartosz Sobczak 	struct irdma_dma_mem commit_fpm_mem;
4509*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
4510*cdcd52d4SBartosz Sobczak 	u8 wait_type;
4511*cdcd52d4SBartosz Sobczak 
4512*cdcd52d4SBartosz Sobczak 	hmc_info = dev->hmc_info;
4513*cdcd52d4SBartosz Sobczak 	obj_info = hmc_info->hmc_obj;
4514*cdcd52d4SBartosz Sobczak 	buf = dev->fpm_commit_buf;
4515*cdcd52d4SBartosz Sobczak 
4516*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_0, (u64)obj_info[IRDMA_HMC_IW_QP].cnt);
4517*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_8, (u64)obj_info[IRDMA_HMC_IW_CQ].cnt);
4518*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_16, (u64)0);	/* RSRVD */
4519*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_24, (u64)obj_info[IRDMA_HMC_IW_HTE].cnt);
4520*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_32, (u64)obj_info[IRDMA_HMC_IW_ARP].cnt);
4521*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_40, (u64)0);	/* RSVD */
4522*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_48, (u64)obj_info[IRDMA_HMC_IW_MR].cnt);
4523*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_56, (u64)obj_info[IRDMA_HMC_IW_XF].cnt);
4524*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_64, (u64)obj_info[IRDMA_HMC_IW_XFFL].cnt);
4525*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_72, (u64)obj_info[IRDMA_HMC_IW_Q1].cnt);
4526*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_80, (u64)obj_info[IRDMA_HMC_IW_Q1FL].cnt);
4527*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_88,
4528*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_TIMER].cnt);
4529*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_96,
4530*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_FSIMC].cnt);
4531*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_104,
4532*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_FSIAV].cnt);
4533*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_112,
4534*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_PBLE].cnt);
4535*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_120, (u64)0);	/* RSVD */
4536*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_128, (u64)obj_info[IRDMA_HMC_IW_RRF].cnt);
4537*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_136,
4538*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_RRFFL].cnt);
4539*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_144, (u64)obj_info[IRDMA_HMC_IW_HDR].cnt);
4540*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_152, (u64)obj_info[IRDMA_HMC_IW_MD].cnt);
4541*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_160,
4542*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_OOISC].cnt);
4543*cdcd52d4SBartosz Sobczak 	set_64bit_val(buf, IRDMA_BYTE_168,
4544*cdcd52d4SBartosz Sobczak 		      (u64)obj_info[IRDMA_HMC_IW_OOISCFFL].cnt);
4545*cdcd52d4SBartosz Sobczak 	commit_fpm_mem.pa = dev->fpm_commit_buf_pa;
4546*cdcd52d4SBartosz Sobczak 	commit_fpm_mem.va = dev->fpm_commit_buf;
4547*cdcd52d4SBartosz Sobczak 
4548*cdcd52d4SBartosz Sobczak 	wait_type = (u8)IRDMA_CQP_WAIT_POLL_REGS;
4549*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_HMC, "COMMIT FPM BUFFER",
4550*cdcd52d4SBartosz Sobczak 			commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE);
4551*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_commit_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id,
4552*cdcd52d4SBartosz Sobczak 					   &commit_fpm_mem, true, wait_type);
4553*cdcd52d4SBartosz Sobczak 	if (!ret_code)
4554*cdcd52d4SBartosz Sobczak 		ret_code = irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf,
4555*cdcd52d4SBartosz Sobczak 							 hmc_info->hmc_obj,
4556*cdcd52d4SBartosz Sobczak 							 &hmc_info->sd_table.sd_cnt);
4557*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_HMC, "COMMIT FPM BUFFER",
4558*cdcd52d4SBartosz Sobczak 			commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE);
4559*cdcd52d4SBartosz Sobczak 
4560*cdcd52d4SBartosz Sobczak 	return ret_code;
4561*cdcd52d4SBartosz Sobczak }
4562*cdcd52d4SBartosz Sobczak 
4563*cdcd52d4SBartosz Sobczak /**
4564*cdcd52d4SBartosz Sobczak  * cqp_sds_wqe_fill - fill cqp wqe doe sd
4565*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
4566*cdcd52d4SBartosz Sobczak  * @info: sd info for wqe
4567*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4568*cdcd52d4SBartosz Sobczak  */
4569*cdcd52d4SBartosz Sobczak static int
4570*cdcd52d4SBartosz Sobczak cqp_sds_wqe_fill(struct irdma_sc_cqp *cqp,
4571*cdcd52d4SBartosz Sobczak 		 struct irdma_update_sds_info *info, u64 scratch)
4572*cdcd52d4SBartosz Sobczak {
4573*cdcd52d4SBartosz Sobczak 	u64 data;
4574*cdcd52d4SBartosz Sobczak 	u64 hdr;
4575*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
4576*cdcd52d4SBartosz Sobczak 	int mem_entries, wqe_entries;
4577*cdcd52d4SBartosz Sobczak 	struct irdma_dma_mem *sdbuf = &cqp->sdbuf;
4578*cdcd52d4SBartosz Sobczak 	u64 offset = 0;
4579*cdcd52d4SBartosz Sobczak 	u32 wqe_idx;
4580*cdcd52d4SBartosz Sobczak 
4581*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe_idx(cqp, scratch, &wqe_idx);
4582*cdcd52d4SBartosz Sobczak 	if (!wqe)
4583*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
4584*cdcd52d4SBartosz Sobczak 
4585*cdcd52d4SBartosz Sobczak 	wqe_entries = (info->cnt > 3) ? 3 : info->cnt;
4586*cdcd52d4SBartosz Sobczak 	mem_entries = info->cnt - wqe_entries;
4587*cdcd52d4SBartosz Sobczak 
4588*cdcd52d4SBartosz Sobczak 	if (mem_entries) {
4589*cdcd52d4SBartosz Sobczak 		offset = wqe_idx * IRDMA_UPDATE_SD_BUFF_SIZE;
4590*cdcd52d4SBartosz Sobczak 		irdma_memcpy(((char *)sdbuf->va + offset), &info->entry[3], mem_entries << 4);
4591*cdcd52d4SBartosz Sobczak 
4592*cdcd52d4SBartosz Sobczak 		data = (u64)sdbuf->pa + offset;
4593*cdcd52d4SBartosz Sobczak 	} else {
4594*cdcd52d4SBartosz Sobczak 		data = 0;
4595*cdcd52d4SBartosz Sobczak 	}
4596*cdcd52d4SBartosz Sobczak 	data |= LS_64(info->hmc_fn_id, IRDMA_CQPSQ_UPESD_HMCFNID);
4597*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, data);
4598*cdcd52d4SBartosz Sobczak 
4599*cdcd52d4SBartosz Sobczak 	switch (wqe_entries) {
4600*cdcd52d4SBartosz Sobczak 	case 3:
4601*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
4602*cdcd52d4SBartosz Sobczak 			      (LS_64(info->entry[2].cmd, IRDMA_CQPSQ_UPESD_SDCMD) |
4603*cdcd52d4SBartosz Sobczak 			       LS_64(1, IRDMA_CQPSQ_UPESD_ENTRY_VALID)));
4604*cdcd52d4SBartosz Sobczak 
4605*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_56, info->entry[2].data);
4606*cdcd52d4SBartosz Sobczak 		/* fallthrough */
4607*cdcd52d4SBartosz Sobczak 	case 2:
4608*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_32,
4609*cdcd52d4SBartosz Sobczak 			      (LS_64(info->entry[1].cmd, IRDMA_CQPSQ_UPESD_SDCMD) |
4610*cdcd52d4SBartosz Sobczak 			       LS_64(1, IRDMA_CQPSQ_UPESD_ENTRY_VALID)));
4611*cdcd52d4SBartosz Sobczak 
4612*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_40, info->entry[1].data);
4613*cdcd52d4SBartosz Sobczak 		/* fallthrough */
4614*cdcd52d4SBartosz Sobczak 	case 1:
4615*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_0,
4616*cdcd52d4SBartosz Sobczak 			      LS_64(info->entry[0].cmd, IRDMA_CQPSQ_UPESD_SDCMD));
4617*cdcd52d4SBartosz Sobczak 
4618*cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_8, info->entry[0].data);
4619*cdcd52d4SBartosz Sobczak 		break;
4620*cdcd52d4SBartosz Sobczak 	default:
4621*cdcd52d4SBartosz Sobczak 		break;
4622*cdcd52d4SBartosz Sobczak 	}
4623*cdcd52d4SBartosz Sobczak 
4624*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_UPDATE_PE_SDS, IRDMA_CQPSQ_OPCODE) |
4625*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID) |
4626*cdcd52d4SBartosz Sobczak 	    LS_64(mem_entries, IRDMA_CQPSQ_UPESD_ENTRY_COUNT);
4627*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
4628*cdcd52d4SBartosz Sobczak 
4629*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
4630*cdcd52d4SBartosz Sobczak 
4631*cdcd52d4SBartosz Sobczak 	if (mem_entries)
4632*cdcd52d4SBartosz Sobczak 		irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "UPDATE_PE_SDS WQE Buffer",
4633*cdcd52d4SBartosz Sobczak 				(char *)sdbuf->va + offset, mem_entries << 4);
4634*cdcd52d4SBartosz Sobczak 
4635*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "UPDATE_PE_SDS WQE", wqe,
4636*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
4637*cdcd52d4SBartosz Sobczak 
4638*cdcd52d4SBartosz Sobczak 	return 0;
4639*cdcd52d4SBartosz Sobczak }
4640*cdcd52d4SBartosz Sobczak 
4641*cdcd52d4SBartosz Sobczak /**
4642*cdcd52d4SBartosz Sobczak  * irdma_update_pe_sds - cqp wqe for sd
4643*cdcd52d4SBartosz Sobczak  * @dev: ptr to irdma_dev struct
4644*cdcd52d4SBartosz Sobczak  * @info: sd info for sd's
4645*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4646*cdcd52d4SBartosz Sobczak  */
4647*cdcd52d4SBartosz Sobczak static int
4648*cdcd52d4SBartosz Sobczak irdma_update_pe_sds(struct irdma_sc_dev *dev,
4649*cdcd52d4SBartosz Sobczak 		    struct irdma_update_sds_info *info, u64 scratch)
4650*cdcd52d4SBartosz Sobczak {
4651*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp = dev->cqp;
4652*cdcd52d4SBartosz Sobczak 	int ret_code;
4653*cdcd52d4SBartosz Sobczak 
4654*cdcd52d4SBartosz Sobczak 	ret_code = cqp_sds_wqe_fill(cqp, info, scratch);
4655*cdcd52d4SBartosz Sobczak 	if (!ret_code)
4656*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
4657*cdcd52d4SBartosz Sobczak 
4658*cdcd52d4SBartosz Sobczak 	return ret_code;
4659*cdcd52d4SBartosz Sobczak }
4660*cdcd52d4SBartosz Sobczak 
4661*cdcd52d4SBartosz Sobczak /**
4662*cdcd52d4SBartosz Sobczak  * irdma_update_sds_noccq - update sd before ccq created
4663*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
4664*cdcd52d4SBartosz Sobczak  * @info: sd info for sd's
4665*cdcd52d4SBartosz Sobczak  */
4666*cdcd52d4SBartosz Sobczak int
4667*cdcd52d4SBartosz Sobczak irdma_update_sds_noccq(struct irdma_sc_dev *dev,
4668*cdcd52d4SBartosz Sobczak 		       struct irdma_update_sds_info *info)
4669*cdcd52d4SBartosz Sobczak {
4670*cdcd52d4SBartosz Sobczak 	u32 error, val, tail;
4671*cdcd52d4SBartosz Sobczak 	struct irdma_sc_cqp *cqp = dev->cqp;
4672*cdcd52d4SBartosz Sobczak 	int ret_code;
4673*cdcd52d4SBartosz Sobczak 
4674*cdcd52d4SBartosz Sobczak 	ret_code = cqp_sds_wqe_fill(cqp, info, 0);
4675*cdcd52d4SBartosz Sobczak 	if (ret_code)
4676*cdcd52d4SBartosz Sobczak 		return ret_code;
4677*cdcd52d4SBartosz Sobczak 
4678*cdcd52d4SBartosz Sobczak 	irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
4679*cdcd52d4SBartosz Sobczak 
4680*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
4681*cdcd52d4SBartosz Sobczak 	return irdma_cqp_poll_registers(cqp, tail,
4682*cdcd52d4SBartosz Sobczak 					cqp->dev->hw_attrs.max_done_count);
4683*cdcd52d4SBartosz Sobczak }
4684*cdcd52d4SBartosz Sobczak 
4685*cdcd52d4SBartosz Sobczak /**
4686*cdcd52d4SBartosz Sobczak  * irdma_sc_static_hmc_pages_allocated - cqp wqe to allocate hmc pages
4687*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
4688*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4689*cdcd52d4SBartosz Sobczak  * @hmc_fn_id: hmc function id
4690*cdcd52d4SBartosz Sobczak  * @post_sq: flag for cqp db to ring
4691*cdcd52d4SBartosz Sobczak  * @poll_registers: flag to poll register for cqp completion
4692*cdcd52d4SBartosz Sobczak  */
4693*cdcd52d4SBartosz Sobczak int
4694*cdcd52d4SBartosz Sobczak irdma_sc_static_hmc_pages_allocated(struct irdma_sc_cqp *cqp, u64 scratch,
4695*cdcd52d4SBartosz Sobczak 				    u8 hmc_fn_id, bool post_sq,
4696*cdcd52d4SBartosz Sobczak 				    bool poll_registers)
4697*cdcd52d4SBartosz Sobczak {
4698*cdcd52d4SBartosz Sobczak 	u64 hdr;
4699*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
4700*cdcd52d4SBartosz Sobczak 	u32 tail, val, error;
4701*cdcd52d4SBartosz Sobczak 
4702*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
4703*cdcd52d4SBartosz Sobczak 	if (!wqe)
4704*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
4705*cdcd52d4SBartosz Sobczak 
4706*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
4707*cdcd52d4SBartosz Sobczak 		      LS_64(hmc_fn_id, IRDMA_SHMC_PAGE_ALLOCATED_HMC_FN_ID));
4708*cdcd52d4SBartosz Sobczak 
4709*cdcd52d4SBartosz Sobczak 	hdr = LS_64(IRDMA_CQP_OP_SHMC_PAGES_ALLOCATED, IRDMA_CQPSQ_OPCODE) |
4710*cdcd52d4SBartosz Sobczak 	    LS_64(cqp->polarity, IRDMA_CQPSQ_WQEVALID);
4711*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
4712*cdcd52d4SBartosz Sobczak 
4713*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, hdr);
4714*cdcd52d4SBartosz Sobczak 
4715*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "SHMC_PAGES_ALLOCATED WQE",
4716*cdcd52d4SBartosz Sobczak 			wqe, IRDMA_CQP_WQE_SIZE * 8);
4717*cdcd52d4SBartosz Sobczak 	irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
4718*cdcd52d4SBartosz Sobczak 
4719*cdcd52d4SBartosz Sobczak 	if (post_sq) {
4720*cdcd52d4SBartosz Sobczak 		irdma_sc_cqp_post_sq(cqp);
4721*cdcd52d4SBartosz Sobczak 		if (poll_registers)
4722*cdcd52d4SBartosz Sobczak 			/* check for cqp sq tail update */
4723*cdcd52d4SBartosz Sobczak 			return irdma_cqp_poll_registers(cqp, tail,
4724*cdcd52d4SBartosz Sobczak 							cqp->dev->hw_attrs.max_done_count);
4725*cdcd52d4SBartosz Sobczak 		else
4726*cdcd52d4SBartosz Sobczak 			return irdma_sc_poll_for_cqp_op_done(cqp,
4727*cdcd52d4SBartosz Sobczak 							     IRDMA_CQP_OP_SHMC_PAGES_ALLOCATED,
4728*cdcd52d4SBartosz Sobczak 							     NULL);
4729*cdcd52d4SBartosz Sobczak 	}
4730*cdcd52d4SBartosz Sobczak 
4731*cdcd52d4SBartosz Sobczak 	return 0;
4732*cdcd52d4SBartosz Sobczak }
4733*cdcd52d4SBartosz Sobczak 
4734*cdcd52d4SBartosz Sobczak /**
4735*cdcd52d4SBartosz Sobczak  * irdma_cqp_ring_full - check if cqp ring is full
4736*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
4737*cdcd52d4SBartosz Sobczak  */
4738*cdcd52d4SBartosz Sobczak static bool
4739*cdcd52d4SBartosz Sobczak irdma_cqp_ring_full(struct irdma_sc_cqp *cqp)
4740*cdcd52d4SBartosz Sobczak {
4741*cdcd52d4SBartosz Sobczak 	return IRDMA_RING_FULL_ERR(cqp->sq_ring);
4742*cdcd52d4SBartosz Sobczak }
4743*cdcd52d4SBartosz Sobczak 
4744*cdcd52d4SBartosz Sobczak /**
4745*cdcd52d4SBartosz Sobczak  * irdma_est_sd - returns approximate number of SDs for HMC
4746*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
4747*cdcd52d4SBartosz Sobczak  * @hmc_info: hmc structure, size and count for HMC objects
4748*cdcd52d4SBartosz Sobczak  */
4749*cdcd52d4SBartosz Sobczak static u32 irdma_est_sd(struct irdma_sc_dev *dev,
4750*cdcd52d4SBartosz Sobczak 			struct irdma_hmc_info *hmc_info){
4751*cdcd52d4SBartosz Sobczak 	int i;
4752*cdcd52d4SBartosz Sobczak 	u64 size = 0;
4753*cdcd52d4SBartosz Sobczak 	u64 sd;
4754*cdcd52d4SBartosz Sobczak 
4755*cdcd52d4SBartosz Sobczak 	for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++)
4756*cdcd52d4SBartosz Sobczak 		if (i != IRDMA_HMC_IW_PBLE)
4757*cdcd52d4SBartosz Sobczak 			size += round_up(hmc_info->hmc_obj[i].cnt *
4758*cdcd52d4SBartosz Sobczak 					 hmc_info->hmc_obj[i].size, 512);
4759*cdcd52d4SBartosz Sobczak 	size += round_up(hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt *
4760*cdcd52d4SBartosz Sobczak 			 hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].size, 512);
4761*cdcd52d4SBartosz Sobczak 	if (size & 0x1FFFFF)
4762*cdcd52d4SBartosz Sobczak 		sd = (size >> 21) + 1;	/* add 1 for remainder */
4763*cdcd52d4SBartosz Sobczak 	else
4764*cdcd52d4SBartosz Sobczak 		sd = size >> 21;
4765*cdcd52d4SBartosz Sobczak 	if (sd > 0xFFFFFFFF) {
4766*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_HMC, "sd overflow[%ld]\n", sd);
4767*cdcd52d4SBartosz Sobczak 		sd = 0xFFFFFFFF - 1;
4768*cdcd52d4SBartosz Sobczak 	}
4769*cdcd52d4SBartosz Sobczak 
4770*cdcd52d4SBartosz Sobczak 	return (u32)sd;
4771*cdcd52d4SBartosz Sobczak }
4772*cdcd52d4SBartosz Sobczak 
4773*cdcd52d4SBartosz Sobczak /**
4774*cdcd52d4SBartosz Sobczak  * irdma_sc_query_rdma_features - query RDMA features and FW ver
4775*cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
4776*cdcd52d4SBartosz Sobczak  * @buf: buffer to hold query info
4777*cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
4778*cdcd52d4SBartosz Sobczak  */
4779*cdcd52d4SBartosz Sobczak static int
4780*cdcd52d4SBartosz Sobczak irdma_sc_query_rdma_features(struct irdma_sc_cqp *cqp,
4781*cdcd52d4SBartosz Sobczak 			     struct irdma_dma_mem *buf, u64 scratch)
4782*cdcd52d4SBartosz Sobczak {
4783*cdcd52d4SBartosz Sobczak 	__le64 *wqe;
4784*cdcd52d4SBartosz Sobczak 	u64 temp;
4785*cdcd52d4SBartosz Sobczak 	u32 tail, val, error;
4786*cdcd52d4SBartosz Sobczak 	int status;
4787*cdcd52d4SBartosz Sobczak 
4788*cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
4789*cdcd52d4SBartosz Sobczak 	if (!wqe)
4790*cdcd52d4SBartosz Sobczak 		return -ENOSPC;
4791*cdcd52d4SBartosz Sobczak 
4792*cdcd52d4SBartosz Sobczak 	temp = buf->pa;
4793*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, temp);
4794*cdcd52d4SBartosz Sobczak 
4795*cdcd52d4SBartosz Sobczak 	temp = LS_64(cqp->polarity, IRDMA_CQPSQ_QUERY_RDMA_FEATURES_WQEVALID) |
4796*cdcd52d4SBartosz Sobczak 	    LS_64(buf->size, IRDMA_CQPSQ_QUERY_RDMA_FEATURES_BUF_LEN) |
4797*cdcd52d4SBartosz Sobczak 	    LS_64(IRDMA_CQP_OP_QUERY_RDMA_FEATURES, IRDMA_CQPSQ_UP_OP);
4798*cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* make sure WQE is written before valid bit is set */
4799*cdcd52d4SBartosz Sobczak 
4800*cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24, temp);
4801*cdcd52d4SBartosz Sobczak 
4802*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "QUERY RDMA FEATURES", wqe,
4803*cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
4804*cdcd52d4SBartosz Sobczak 	irdma_get_cqp_reg_info(cqp, &val, &tail, &error);
4805*cdcd52d4SBartosz Sobczak 
4806*cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
4807*cdcd52d4SBartosz Sobczak 	status = irdma_cqp_poll_registers(cqp, tail,
4808*cdcd52d4SBartosz Sobczak 					  cqp->dev->hw_attrs.max_done_count);
4809*cdcd52d4SBartosz Sobczak 	if (error || status)
4810*cdcd52d4SBartosz Sobczak 		status = -EIO;
4811*cdcd52d4SBartosz Sobczak 
4812*cdcd52d4SBartosz Sobczak 	return status;
4813*cdcd52d4SBartosz Sobczak }
4814*cdcd52d4SBartosz Sobczak 
4815*cdcd52d4SBartosz Sobczak /**
4816*cdcd52d4SBartosz Sobczak  * irdma_get_rdma_features - get RDMA features
4817*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
4818*cdcd52d4SBartosz Sobczak  */
4819*cdcd52d4SBartosz Sobczak int
4820*cdcd52d4SBartosz Sobczak irdma_get_rdma_features(struct irdma_sc_dev *dev)
4821*cdcd52d4SBartosz Sobczak {
4822*cdcd52d4SBartosz Sobczak 	int ret_code;
4823*cdcd52d4SBartosz Sobczak 	struct irdma_dma_mem feat_buf;
4824*cdcd52d4SBartosz Sobczak 	u64 temp;
4825*cdcd52d4SBartosz Sobczak 	u16 byte_idx, feat_type, feat_cnt, feat_idx;
4826*cdcd52d4SBartosz Sobczak 
4827*cdcd52d4SBartosz Sobczak 	feat_buf.size = IRDMA_FEATURE_BUF_SIZE;
4828*cdcd52d4SBartosz Sobczak 	feat_buf.va = irdma_allocate_dma_mem(dev->hw, &feat_buf, feat_buf.size,
4829*cdcd52d4SBartosz Sobczak 					     IRDMA_FEATURE_BUF_ALIGNMENT);
4830*cdcd52d4SBartosz Sobczak 	if (!feat_buf.va)
4831*cdcd52d4SBartosz Sobczak 		return -ENOMEM;
4832*cdcd52d4SBartosz Sobczak 
4833*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0);
4834*cdcd52d4SBartosz Sobczak 	if (ret_code)
4835*cdcd52d4SBartosz Sobczak 		goto exit;
4836*cdcd52d4SBartosz Sobczak 
4837*cdcd52d4SBartosz Sobczak 	get_64bit_val(feat_buf.va, IRDMA_BYTE_0, &temp);
4838*cdcd52d4SBartosz Sobczak 	feat_cnt = (u16)RS_64(temp, IRDMA_FEATURE_CNT);
4839*cdcd52d4SBartosz Sobczak 	if (feat_cnt < IRDMA_MIN_FEATURES) {
4840*cdcd52d4SBartosz Sobczak 		ret_code = -EINVAL;
4841*cdcd52d4SBartosz Sobczak 		goto exit;
4842*cdcd52d4SBartosz Sobczak 	} else if (feat_cnt > IRDMA_MAX_FEATURES) {
4843*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_DEV,
4844*cdcd52d4SBartosz Sobczak 			    "feature buf size insufficient,"
4845*cdcd52d4SBartosz Sobczak 			    "retrying with larger buffer\n");
4846*cdcd52d4SBartosz Sobczak 		irdma_free_dma_mem(dev->hw, &feat_buf);
4847*cdcd52d4SBartosz Sobczak 		feat_buf.size = 8 * feat_cnt;
4848*cdcd52d4SBartosz Sobczak 		feat_buf.va = irdma_allocate_dma_mem(dev->hw, &feat_buf,
4849*cdcd52d4SBartosz Sobczak 						     feat_buf.size,
4850*cdcd52d4SBartosz Sobczak 						     IRDMA_FEATURE_BUF_ALIGNMENT);
4851*cdcd52d4SBartosz Sobczak 		if (!feat_buf.va)
4852*cdcd52d4SBartosz Sobczak 			return -ENOMEM;
4853*cdcd52d4SBartosz Sobczak 
4854*cdcd52d4SBartosz Sobczak 		ret_code = irdma_sc_query_rdma_features(dev->cqp, &feat_buf, 0);
4855*cdcd52d4SBartosz Sobczak 		if (ret_code)
4856*cdcd52d4SBartosz Sobczak 			goto exit;
4857*cdcd52d4SBartosz Sobczak 
4858*cdcd52d4SBartosz Sobczak 		get_64bit_val(feat_buf.va, IRDMA_BYTE_0, &temp);
4859*cdcd52d4SBartosz Sobczak 		feat_cnt = (u16)RS_64(temp, IRDMA_FEATURE_CNT);
4860*cdcd52d4SBartosz Sobczak 		if (feat_cnt < IRDMA_MIN_FEATURES) {
4861*cdcd52d4SBartosz Sobczak 			ret_code = -EINVAL;
4862*cdcd52d4SBartosz Sobczak 			goto exit;
4863*cdcd52d4SBartosz Sobczak 		}
4864*cdcd52d4SBartosz Sobczak 	}
4865*cdcd52d4SBartosz Sobczak 
4866*cdcd52d4SBartosz Sobczak 	irdma_debug_buf(dev, IRDMA_DEBUG_WQE, "QUERY RDMA FEATURES", feat_buf.va,
4867*cdcd52d4SBartosz Sobczak 			feat_cnt * 8);
4868*cdcd52d4SBartosz Sobczak 
4869*cdcd52d4SBartosz Sobczak 	for (byte_idx = 0, feat_idx = 0; feat_idx < min(feat_cnt, (u16)IRDMA_MAX_FEATURES);
4870*cdcd52d4SBartosz Sobczak 	     feat_idx++, byte_idx += 8) {
4871*cdcd52d4SBartosz Sobczak 		get_64bit_val(feat_buf.va, byte_idx, &temp);
4872*cdcd52d4SBartosz Sobczak 		feat_type = RS_64(temp, IRDMA_FEATURE_TYPE);
4873*cdcd52d4SBartosz Sobczak 		dev->feature_info[feat_type] = temp;
4874*cdcd52d4SBartosz Sobczak 	}
4875*cdcd52d4SBartosz Sobczak exit:
4876*cdcd52d4SBartosz Sobczak 	irdma_free_dma_mem(dev->hw, &feat_buf);
4877*cdcd52d4SBartosz Sobczak 	return ret_code;
4878*cdcd52d4SBartosz Sobczak }
4879*cdcd52d4SBartosz Sobczak 
4880*cdcd52d4SBartosz Sobczak static u32 irdma_q1_cnt(struct irdma_sc_dev *dev,
4881*cdcd52d4SBartosz Sobczak 			struct irdma_hmc_info *hmc_info, u32 qpwanted){
4882*cdcd52d4SBartosz Sobczak 	u32 q1_cnt;
4883*cdcd52d4SBartosz Sobczak 
4884*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) {
4885*cdcd52d4SBartosz Sobczak 		q1_cnt = roundup_pow_of_two(dev->hw_attrs.max_hw_ird * 2 * qpwanted);
4886*cdcd52d4SBartosz Sobczak 	} else {
4887*cdcd52d4SBartosz Sobczak 		if (dev->cqp->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
4888*cdcd52d4SBartosz Sobczak 			q1_cnt = roundup_pow_of_two(dev->hw_attrs.max_hw_ird * 2 * qpwanted + 512);
4889*cdcd52d4SBartosz Sobczak 		else
4890*cdcd52d4SBartosz Sobczak 			q1_cnt = dev->hw_attrs.max_hw_ird * 2 * qpwanted;
4891*cdcd52d4SBartosz Sobczak 	}
4892*cdcd52d4SBartosz Sobczak 
4893*cdcd52d4SBartosz Sobczak 	return q1_cnt;
4894*cdcd52d4SBartosz Sobczak }
4895*cdcd52d4SBartosz Sobczak 
4896*cdcd52d4SBartosz Sobczak static void
4897*cdcd52d4SBartosz Sobczak cfg_fpm_value_gen_1(struct irdma_sc_dev *dev,
4898*cdcd52d4SBartosz Sobczak 		    struct irdma_hmc_info *hmc_info, u32 qpwanted)
4899*cdcd52d4SBartosz Sobczak {
4900*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt = roundup_pow_of_two(qpwanted * dev->hw_attrs.max_hw_wqes);
4901*cdcd52d4SBartosz Sobczak }
4902*cdcd52d4SBartosz Sobczak 
4903*cdcd52d4SBartosz Sobczak static void
4904*cdcd52d4SBartosz Sobczak cfg_fpm_value_gen_2(struct irdma_sc_dev *dev,
4905*cdcd52d4SBartosz Sobczak 		    struct irdma_hmc_info *hmc_info, u32 qpwanted)
4906*cdcd52d4SBartosz Sobczak {
4907*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_fpm_misc *hmc_fpm_misc = &dev->hmc_fpm_misc;
4908*cdcd52d4SBartosz Sobczak 
4909*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt =
4910*cdcd52d4SBartosz Sobczak 	    4 * hmc_fpm_misc->xf_block_size * qpwanted;
4911*cdcd52d4SBartosz Sobczak 
4912*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_HDR].cnt = qpwanted;
4913*cdcd52d4SBartosz Sobczak 
4914*cdcd52d4SBartosz Sobczak 	if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].max_cnt)
4915*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt = 32 * qpwanted;
4916*cdcd52d4SBartosz Sobczak 	if (hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].max_cnt)
4917*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_RRFFL].cnt =
4918*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_RRF].cnt /
4919*cdcd52d4SBartosz Sobczak 		    hmc_fpm_misc->rrf_block_size;
4920*cdcd52d4SBartosz Sobczak 	if (hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].max_cnt)
4921*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].cnt = 32 * qpwanted;
4922*cdcd52d4SBartosz Sobczak 	if (hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].max_cnt)
4923*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_OOISCFFL].cnt =
4924*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_OOISC].cnt /
4925*cdcd52d4SBartosz Sobczak 		    hmc_fpm_misc->ooiscf_block_size;
4926*cdcd52d4SBartosz Sobczak }
4927*cdcd52d4SBartosz Sobczak 
4928*cdcd52d4SBartosz Sobczak /**
4929*cdcd52d4SBartosz Sobczak  * irdma_cfg_fpm_val - configure HMC objects
4930*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
4931*cdcd52d4SBartosz Sobczak  * @qp_count: desired qp count
4932*cdcd52d4SBartosz Sobczak  */
4933*cdcd52d4SBartosz Sobczak int
4934*cdcd52d4SBartosz Sobczak irdma_cfg_fpm_val(struct irdma_sc_dev *dev, u32 qp_count)
4935*cdcd52d4SBartosz Sobczak {
4936*cdcd52d4SBartosz Sobczak 	struct irdma_virt_mem virt_mem;
4937*cdcd52d4SBartosz Sobczak 	u32 i, mem_size;
4938*cdcd52d4SBartosz Sobczak 	u32 qpwanted, mrwanted, pblewanted;
4939*cdcd52d4SBartosz Sobczak 	u32 powerof2, hte;
4940*cdcd52d4SBartosz Sobczak 	u32 sd_needed;
4941*cdcd52d4SBartosz Sobczak 	u32 sd_diff;
4942*cdcd52d4SBartosz Sobczak 	u32 loop_count = 0;
4943*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_info *hmc_info;
4944*cdcd52d4SBartosz Sobczak 	struct irdma_hmc_fpm_misc *hmc_fpm_misc;
4945*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
4946*cdcd52d4SBartosz Sobczak 	u32 max_sds;
4947*cdcd52d4SBartosz Sobczak 
4948*cdcd52d4SBartosz Sobczak 	hmc_info = dev->hmc_info;
4949*cdcd52d4SBartosz Sobczak 	hmc_fpm_misc = &dev->hmc_fpm_misc;
4950*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_init_iw_hmc(dev, dev->hmc_fn_id);
4951*cdcd52d4SBartosz Sobczak 	if (ret_code) {
4952*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_HMC,
4953*cdcd52d4SBartosz Sobczak 			    "irdma_sc_init_iw_hmc returned error_code = %d\n",
4954*cdcd52d4SBartosz Sobczak 			    ret_code);
4955*cdcd52d4SBartosz Sobczak 		return ret_code;
4956*cdcd52d4SBartosz Sobczak 	}
4957*cdcd52d4SBartosz Sobczak 
4958*cdcd52d4SBartosz Sobczak 	max_sds = hmc_fpm_misc->max_sds;
4959*cdcd52d4SBartosz Sobczak 
4960*cdcd52d4SBartosz Sobczak 	for (i = IRDMA_HMC_IW_QP; i < IRDMA_HMC_IW_MAX; i++)
4961*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt;
4962*cdcd52d4SBartosz Sobczak 
4963*cdcd52d4SBartosz Sobczak 	sd_needed = irdma_est_sd(dev, hmc_info);
4964*cdcd52d4SBartosz Sobczak 	irdma_debug(dev, IRDMA_DEBUG_HMC, "sd count %d where max sd is %d\n",
4965*cdcd52d4SBartosz Sobczak 		    hmc_info->sd_table.sd_cnt, max_sds);
4966*cdcd52d4SBartosz Sobczak 
4967*cdcd52d4SBartosz Sobczak 	qpwanted = min(qp_count, hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt);
4968*cdcd52d4SBartosz Sobczak 
4969*cdcd52d4SBartosz Sobczak 	powerof2 = 1;
4970*cdcd52d4SBartosz Sobczak 	while (powerof2 <= qpwanted)
4971*cdcd52d4SBartosz Sobczak 		powerof2 *= 2;
4972*cdcd52d4SBartosz Sobczak 	powerof2 /= 2;
4973*cdcd52d4SBartosz Sobczak 	qpwanted = powerof2;
4974*cdcd52d4SBartosz Sobczak 
4975*cdcd52d4SBartosz Sobczak 	mrwanted = hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt;
4976*cdcd52d4SBartosz Sobczak 	pblewanted = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt;
4977*cdcd52d4SBartosz Sobczak 
4978*cdcd52d4SBartosz Sobczak 	irdma_debug(dev, IRDMA_DEBUG_HMC,
4979*cdcd52d4SBartosz Sobczak 		    "req_qp=%d max_sd=%d, max_qp = %d, max_cq=%d, max_mr=%d, max_pble=%d, mc=%d, av=%d\n",
4980*cdcd52d4SBartosz Sobczak 		    qp_count, max_sds,
4981*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_QP].max_cnt,
4982*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].max_cnt,
4983*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_MR].max_cnt,
4984*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].max_cnt,
4985*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt,
4986*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt);
4987*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt =
4988*cdcd52d4SBartosz Sobczak 	    hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].max_cnt;
4989*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt =
4990*cdcd52d4SBartosz Sobczak 	    hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].max_cnt;
4991*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].cnt =
4992*cdcd52d4SBartosz Sobczak 	    hmc_info->hmc_obj[IRDMA_HMC_IW_ARP].max_cnt;
4993*cdcd52d4SBartosz Sobczak 
4994*cdcd52d4SBartosz Sobczak 	hmc_info->hmc_obj[IRDMA_HMC_IW_APBVT_ENTRY].cnt = 1;
4995*cdcd52d4SBartosz Sobczak 
4996*cdcd52d4SBartosz Sobczak 	while (irdma_q1_cnt(dev, hmc_info, qpwanted) > hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].max_cnt)
4997*cdcd52d4SBartosz Sobczak 		qpwanted /= 2;
4998*cdcd52d4SBartosz Sobczak 
4999*cdcd52d4SBartosz Sobczak 	if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1) {
5000*cdcd52d4SBartosz Sobczak 		cfg_fpm_value_gen_1(dev, hmc_info, qpwanted);
5001*cdcd52d4SBartosz Sobczak 		while (hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt > hmc_info->hmc_obj[IRDMA_HMC_IW_XF].max_cnt) {
5002*cdcd52d4SBartosz Sobczak 			qpwanted /= 2;
5003*cdcd52d4SBartosz Sobczak 			cfg_fpm_value_gen_1(dev, hmc_info, qpwanted);
5004*cdcd52d4SBartosz Sobczak 		}
5005*cdcd52d4SBartosz Sobczak 	}
5006*cdcd52d4SBartosz Sobczak 
5007*cdcd52d4SBartosz Sobczak 	do {
5008*cdcd52d4SBartosz Sobczak 		++loop_count;
5009*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt = qpwanted;
5010*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt =
5011*cdcd52d4SBartosz Sobczak 		    min(2 * qpwanted, hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt);
5012*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_RESERVED].cnt = 0;	/* Reserved */
5013*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt = mrwanted;
5014*cdcd52d4SBartosz Sobczak 
5015*cdcd52d4SBartosz Sobczak 		hte = round_up(qpwanted + hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt, 512);
5016*cdcd52d4SBartosz Sobczak 		powerof2 = 1;
5017*cdcd52d4SBartosz Sobczak 		while (powerof2 < hte)
5018*cdcd52d4SBartosz Sobczak 			powerof2 *= 2;
5019*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_HTE].cnt =
5020*cdcd52d4SBartosz Sobczak 		    powerof2 * hmc_fpm_misc->ht_multiplier;
5021*cdcd52d4SBartosz Sobczak 		if (dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
5022*cdcd52d4SBartosz Sobczak 			cfg_fpm_value_gen_1(dev, hmc_info, qpwanted);
5023*cdcd52d4SBartosz Sobczak 		else
5024*cdcd52d4SBartosz Sobczak 			cfg_fpm_value_gen_2(dev, hmc_info, qpwanted);
5025*cdcd52d4SBartosz Sobczak 
5026*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt = irdma_q1_cnt(dev, hmc_info, qpwanted);
5027*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_XFFL].cnt =
5028*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_XF].cnt / hmc_fpm_misc->xf_block_size;
5029*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_Q1FL].cnt =
5030*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_Q1].cnt / hmc_fpm_misc->q1_block_size;
5031*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_TIMER].cnt =
5032*cdcd52d4SBartosz Sobczak 		    (round_up(qpwanted, 512) / 512 + 1) * hmc_fpm_misc->timer_bucket;
5033*cdcd52d4SBartosz Sobczak 
5034*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted;
5035*cdcd52d4SBartosz Sobczak 		sd_needed = irdma_est_sd(dev, hmc_info);
5036*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_HMC,
5037*cdcd52d4SBartosz Sobczak 			    "sd_needed = %d, max_sds=%d, mrwanted=%d, pblewanted=%d qpwanted=%d\n",
5038*cdcd52d4SBartosz Sobczak 			    sd_needed, max_sds, mrwanted, pblewanted, qpwanted);
5039*cdcd52d4SBartosz Sobczak 
5040*cdcd52d4SBartosz Sobczak 		/* Do not reduce resources further. All objects fit with max SDs */
5041*cdcd52d4SBartosz Sobczak 		if (sd_needed <= max_sds)
5042*cdcd52d4SBartosz Sobczak 			break;
5043*cdcd52d4SBartosz Sobczak 
5044*cdcd52d4SBartosz Sobczak 		sd_diff = sd_needed - max_sds;
5045*cdcd52d4SBartosz Sobczak 		if (sd_diff > 128) {
5046*cdcd52d4SBartosz Sobczak 			if (!(loop_count % 2) && qpwanted > 128) {
5047*cdcd52d4SBartosz Sobczak 				qpwanted /= 2;
5048*cdcd52d4SBartosz Sobczak 			} else {
5049*cdcd52d4SBartosz Sobczak 				mrwanted /= 2;
5050*cdcd52d4SBartosz Sobczak 				pblewanted /= 2;
5051*cdcd52d4SBartosz Sobczak 			}
5052*cdcd52d4SBartosz Sobczak 			continue;
5053*cdcd52d4SBartosz Sobczak 		}
5054*cdcd52d4SBartosz Sobczak 		if (dev->cqp->hmc_profile != IRDMA_HMC_PROFILE_FAVOR_VF &&
5055*cdcd52d4SBartosz Sobczak 		    pblewanted > (512 * FPM_MULTIPLIER * sd_diff)) {
5056*cdcd52d4SBartosz Sobczak 			pblewanted -= 256 * FPM_MULTIPLIER * sd_diff;
5057*cdcd52d4SBartosz Sobczak 			continue;
5058*cdcd52d4SBartosz Sobczak 		} else if (pblewanted > (100 * FPM_MULTIPLIER)) {
5059*cdcd52d4SBartosz Sobczak 			pblewanted -= 10 * FPM_MULTIPLIER;
5060*cdcd52d4SBartosz Sobczak 		} else if (pblewanted > FPM_MULTIPLIER) {
5061*cdcd52d4SBartosz Sobczak 			pblewanted -= FPM_MULTIPLIER;
5062*cdcd52d4SBartosz Sobczak 		} else if (qpwanted <= 128) {
5063*cdcd52d4SBartosz Sobczak 			if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt > 256)
5064*cdcd52d4SBartosz Sobczak 				hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt /= 2;
5065*cdcd52d4SBartosz Sobczak 			if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt > 256)
5066*cdcd52d4SBartosz Sobczak 				hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt /= 2;
5067*cdcd52d4SBartosz Sobczak 		}
5068*cdcd52d4SBartosz Sobczak 		if (mrwanted > FPM_MULTIPLIER)
5069*cdcd52d4SBartosz Sobczak 			mrwanted -= FPM_MULTIPLIER;
5070*cdcd52d4SBartosz Sobczak 		if (!(loop_count % 10) && qpwanted > 128) {
5071*cdcd52d4SBartosz Sobczak 			qpwanted /= 2;
5072*cdcd52d4SBartosz Sobczak 			if (hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt > 256)
5073*cdcd52d4SBartosz Sobczak 				hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt /= 2;
5074*cdcd52d4SBartosz Sobczak 		}
5075*cdcd52d4SBartosz Sobczak 	} while (loop_count < 2000);
5076*cdcd52d4SBartosz Sobczak 
5077*cdcd52d4SBartosz Sobczak 	if (sd_needed > max_sds) {
5078*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_HMC,
5079*cdcd52d4SBartosz Sobczak 			    "cfg_fpm failed loop_cnt=%d, sd_needed=%d, max sd count %d\n",
5080*cdcd52d4SBartosz Sobczak 			    loop_count, sd_needed, hmc_info->sd_table.sd_cnt);
5081*cdcd52d4SBartosz Sobczak 		return -EINVAL;
5082*cdcd52d4SBartosz Sobczak 	}
5083*cdcd52d4SBartosz Sobczak 
5084*cdcd52d4SBartosz Sobczak 	if (loop_count > 1 && sd_needed < max_sds) {
5085*cdcd52d4SBartosz Sobczak 		pblewanted += (max_sds - sd_needed) * 256 * FPM_MULTIPLIER;
5086*cdcd52d4SBartosz Sobczak 		hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt = pblewanted;
5087*cdcd52d4SBartosz Sobczak 		sd_needed = irdma_est_sd(dev, hmc_info);
5088*cdcd52d4SBartosz Sobczak 	}
5089*cdcd52d4SBartosz Sobczak 
5090*cdcd52d4SBartosz Sobczak 	irdma_debug(dev, IRDMA_DEBUG_HMC,
5091*cdcd52d4SBartosz Sobczak 		    "loop_cnt=%d, sd_needed=%d, qpcnt = %d, cqcnt=%d, mrcnt=%d, pblecnt=%d, mc=%d, ah=%d, max sd count %d, first sd index %d\n",
5092*cdcd52d4SBartosz Sobczak 		    loop_count, sd_needed,
5093*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_QP].cnt,
5094*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt,
5095*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_MR].cnt,
5096*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt,
5097*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_FSIMC].cnt,
5098*cdcd52d4SBartosz Sobczak 		    hmc_info->hmc_obj[IRDMA_HMC_IW_FSIAV].cnt,
5099*cdcd52d4SBartosz Sobczak 		    hmc_info->sd_table.sd_cnt, hmc_info->first_sd_index);
5100*cdcd52d4SBartosz Sobczak 
5101*cdcd52d4SBartosz Sobczak 	ret_code = irdma_sc_cfg_iw_fpm(dev, dev->hmc_fn_id);
5102*cdcd52d4SBartosz Sobczak 	if (ret_code) {
5103*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_HMC,
5104*cdcd52d4SBartosz Sobczak 			    "cfg_iw_fpm returned error_code[x%08X]\n",
5105*cdcd52d4SBartosz Sobczak 			    readl(dev->hw_regs[IRDMA_CQPERRCODES]));
5106*cdcd52d4SBartosz Sobczak 		return ret_code;
5107*cdcd52d4SBartosz Sobczak 	}
5108*cdcd52d4SBartosz Sobczak 
5109*cdcd52d4SBartosz Sobczak 	mem_size = sizeof(struct irdma_hmc_sd_entry) *
5110*cdcd52d4SBartosz Sobczak 	    (hmc_info->sd_table.sd_cnt + hmc_info->first_sd_index + 1);
5111*cdcd52d4SBartosz Sobczak 	virt_mem.size = mem_size;
5112*cdcd52d4SBartosz Sobczak 	virt_mem.va = kzalloc(virt_mem.size, GFP_ATOMIC);
5113*cdcd52d4SBartosz Sobczak 	if (!virt_mem.va) {
5114*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_HMC,
5115*cdcd52d4SBartosz Sobczak 			    "failed to allocate memory for sd_entry buffer\n");
5116*cdcd52d4SBartosz Sobczak 		return -ENOMEM;
5117*cdcd52d4SBartosz Sobczak 	}
5118*cdcd52d4SBartosz Sobczak 	hmc_info->sd_table.sd_entry = virt_mem.va;
5119*cdcd52d4SBartosz Sobczak 
5120*cdcd52d4SBartosz Sobczak 	return ret_code;
5121*cdcd52d4SBartosz Sobczak }
5122*cdcd52d4SBartosz Sobczak 
5123*cdcd52d4SBartosz Sobczak /**
5124*cdcd52d4SBartosz Sobczak  * irdma_exec_cqp_cmd - execute cqp cmd when wqe are available
5125*cdcd52d4SBartosz Sobczak  * @dev: rdma device
5126*cdcd52d4SBartosz Sobczak  * @pcmdinfo: cqp command info
5127*cdcd52d4SBartosz Sobczak  */
5128*cdcd52d4SBartosz Sobczak static int
5129*cdcd52d4SBartosz Sobczak irdma_exec_cqp_cmd(struct irdma_sc_dev *dev,
5130*cdcd52d4SBartosz Sobczak 		   struct cqp_cmds_info *pcmdinfo)
5131*cdcd52d4SBartosz Sobczak {
5132*cdcd52d4SBartosz Sobczak 	int status;
5133*cdcd52d4SBartosz Sobczak 	struct irdma_dma_mem val_mem;
5134*cdcd52d4SBartosz Sobczak 	bool alloc = false;
5135*cdcd52d4SBartosz Sobczak 
5136*cdcd52d4SBartosz Sobczak 	dev->cqp_cmd_stats[pcmdinfo->cqp_cmd]++;
5137*cdcd52d4SBartosz Sobczak 	switch (pcmdinfo->cqp_cmd) {
5138*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_CEQ_DESTROY:
5139*cdcd52d4SBartosz Sobczak 		status = irdma_sc_ceq_destroy(pcmdinfo->in.u.ceq_destroy.ceq,
5140*cdcd52d4SBartosz Sobczak 					      pcmdinfo->in.u.ceq_destroy.scratch,
5141*cdcd52d4SBartosz Sobczak 					      pcmdinfo->post_sq);
5142*cdcd52d4SBartosz Sobczak 		break;
5143*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_AEQ_DESTROY:
5144*cdcd52d4SBartosz Sobczak 		status = irdma_sc_aeq_destroy(pcmdinfo->in.u.aeq_destroy.aeq,
5145*cdcd52d4SBartosz Sobczak 					      pcmdinfo->in.u.aeq_destroy.scratch,
5146*cdcd52d4SBartosz Sobczak 					      pcmdinfo->post_sq);
5147*cdcd52d4SBartosz Sobczak 
5148*cdcd52d4SBartosz Sobczak 		break;
5149*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_CEQ_CREATE:
5150*cdcd52d4SBartosz Sobczak 		status = irdma_sc_ceq_create(pcmdinfo->in.u.ceq_create.ceq,
5151*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.ceq_create.scratch,
5152*cdcd52d4SBartosz Sobczak 					     pcmdinfo->post_sq);
5153*cdcd52d4SBartosz Sobczak 		break;
5154*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_AEQ_CREATE:
5155*cdcd52d4SBartosz Sobczak 		status = irdma_sc_aeq_create(pcmdinfo->in.u.aeq_create.aeq,
5156*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.aeq_create.scratch,
5157*cdcd52d4SBartosz Sobczak 					     pcmdinfo->post_sq);
5158*cdcd52d4SBartosz Sobczak 		break;
5159*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QP_UPLOAD_CONTEXT:
5160*cdcd52d4SBartosz Sobczak 		status = irdma_sc_qp_upload_context(pcmdinfo->in.u.qp_upload_context.dev,
5161*cdcd52d4SBartosz Sobczak 						    &pcmdinfo->in.u.qp_upload_context.info,
5162*cdcd52d4SBartosz Sobczak 						    pcmdinfo->in.u.qp_upload_context.scratch,
5163*cdcd52d4SBartosz Sobczak 						    pcmdinfo->post_sq);
5164*cdcd52d4SBartosz Sobczak 		break;
5165*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_CQ_CREATE:
5166*cdcd52d4SBartosz Sobczak 		status = irdma_sc_cq_create(pcmdinfo->in.u.cq_create.cq,
5167*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.cq_create.scratch,
5168*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.cq_create.check_overflow,
5169*cdcd52d4SBartosz Sobczak 					    pcmdinfo->post_sq);
5170*cdcd52d4SBartosz Sobczak 		break;
5171*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_CQ_MODIFY:
5172*cdcd52d4SBartosz Sobczak 		status = irdma_sc_cq_modify(pcmdinfo->in.u.cq_modify.cq,
5173*cdcd52d4SBartosz Sobczak 					    &pcmdinfo->in.u.cq_modify.info,
5174*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.cq_modify.scratch,
5175*cdcd52d4SBartosz Sobczak 					    pcmdinfo->post_sq);
5176*cdcd52d4SBartosz Sobczak 		break;
5177*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_CQ_DESTROY:
5178*cdcd52d4SBartosz Sobczak 		status = irdma_sc_cq_destroy(pcmdinfo->in.u.cq_destroy.cq,
5179*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.cq_destroy.scratch,
5180*cdcd52d4SBartosz Sobczak 					     pcmdinfo->post_sq);
5181*cdcd52d4SBartosz Sobczak 		break;
5182*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QP_FLUSH_WQES:
5183*cdcd52d4SBartosz Sobczak 		status = irdma_sc_qp_flush_wqes(pcmdinfo->in.u.qp_flush_wqes.qp,
5184*cdcd52d4SBartosz Sobczak 						&pcmdinfo->in.u.qp_flush_wqes.info,
5185*cdcd52d4SBartosz Sobczak 						pcmdinfo->in.u.qp_flush_wqes.scratch,
5186*cdcd52d4SBartosz Sobczak 						pcmdinfo->post_sq);
5187*cdcd52d4SBartosz Sobczak 		break;
5188*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_GEN_AE:
5189*cdcd52d4SBartosz Sobczak 		status = irdma_sc_gen_ae(pcmdinfo->in.u.gen_ae.qp,
5190*cdcd52d4SBartosz Sobczak 					 &pcmdinfo->in.u.gen_ae.info,
5191*cdcd52d4SBartosz Sobczak 					 pcmdinfo->in.u.gen_ae.scratch,
5192*cdcd52d4SBartosz Sobczak 					 pcmdinfo->post_sq);
5193*cdcd52d4SBartosz Sobczak 		break;
5194*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MANAGE_PUSH_PAGE:
5195*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_push_page(pcmdinfo->in.u.manage_push_page.cqp,
5196*cdcd52d4SBartosz Sobczak 						   &pcmdinfo->in.u.manage_push_page.info,
5197*cdcd52d4SBartosz Sobczak 						   pcmdinfo->in.u.manage_push_page.scratch,
5198*cdcd52d4SBartosz Sobczak 						   pcmdinfo->post_sq);
5199*cdcd52d4SBartosz Sobczak 		break;
5200*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_UPDATE_PE_SDS:
5201*cdcd52d4SBartosz Sobczak 		status = irdma_update_pe_sds(pcmdinfo->in.u.update_pe_sds.dev,
5202*cdcd52d4SBartosz Sobczak 					     &pcmdinfo->in.u.update_pe_sds.info,
5203*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.update_pe_sds.scratch);
5204*cdcd52d4SBartosz Sobczak 		break;
5205*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MANAGE_HMC_PM_FUNC_TABLE:
5206*cdcd52d4SBartosz Sobczak 		/* switch to calling through the call table */
5207*cdcd52d4SBartosz Sobczak 		status =
5208*cdcd52d4SBartosz Sobczak 		    irdma_sc_manage_hmc_pm_func_table(pcmdinfo->in.u.manage_hmc_pm.dev->cqp,
5209*cdcd52d4SBartosz Sobczak 						      &pcmdinfo->in.u.manage_hmc_pm.info,
5210*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.manage_hmc_pm.scratch,
5211*cdcd52d4SBartosz Sobczak 						      true);
5212*cdcd52d4SBartosz Sobczak 		break;
5213*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_SUSPEND:
5214*cdcd52d4SBartosz Sobczak 		status = irdma_sc_suspend_qp(pcmdinfo->in.u.suspend_resume.cqp,
5215*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.suspend_resume.qp,
5216*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.suspend_resume.scratch);
5217*cdcd52d4SBartosz Sobczak 		break;
5218*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_RESUME:
5219*cdcd52d4SBartosz Sobczak 		status = irdma_sc_resume_qp(pcmdinfo->in.u.suspend_resume.cqp,
5220*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.suspend_resume.qp,
5221*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.suspend_resume.scratch);
5222*cdcd52d4SBartosz Sobczak 		break;
5223*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QUERY_FPM_VAL:
5224*cdcd52d4SBartosz Sobczak 		val_mem.pa = pcmdinfo->in.u.query_fpm_val.fpm_val_pa;
5225*cdcd52d4SBartosz Sobczak 		val_mem.va = pcmdinfo->in.u.query_fpm_val.fpm_val_va;
5226*cdcd52d4SBartosz Sobczak 		status = irdma_sc_query_fpm_val(pcmdinfo->in.u.query_fpm_val.cqp,
5227*cdcd52d4SBartosz Sobczak 						pcmdinfo->in.u.query_fpm_val.scratch,
5228*cdcd52d4SBartosz Sobczak 						pcmdinfo->in.u.query_fpm_val.hmc_fn_id,
5229*cdcd52d4SBartosz Sobczak 						&val_mem, true, IRDMA_CQP_WAIT_EVENT);
5230*cdcd52d4SBartosz Sobczak 		break;
5231*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_COMMIT_FPM_VAL:
5232*cdcd52d4SBartosz Sobczak 		val_mem.pa = pcmdinfo->in.u.commit_fpm_val.fpm_val_pa;
5233*cdcd52d4SBartosz Sobczak 		val_mem.va = pcmdinfo->in.u.commit_fpm_val.fpm_val_va;
5234*cdcd52d4SBartosz Sobczak 		status = irdma_sc_commit_fpm_val(pcmdinfo->in.u.commit_fpm_val.cqp,
5235*cdcd52d4SBartosz Sobczak 						 pcmdinfo->in.u.commit_fpm_val.scratch,
5236*cdcd52d4SBartosz Sobczak 						 pcmdinfo->in.u.commit_fpm_val.hmc_fn_id,
5237*cdcd52d4SBartosz Sobczak 						 &val_mem,
5238*cdcd52d4SBartosz Sobczak 						 true,
5239*cdcd52d4SBartosz Sobczak 						 IRDMA_CQP_WAIT_EVENT);
5240*cdcd52d4SBartosz Sobczak 		break;
5241*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_STATS_ALLOCATE:
5242*cdcd52d4SBartosz Sobczak 		alloc = true;
5243*cdcd52d4SBartosz Sobczak 		/* fallthrough */
5244*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_STATS_FREE:
5245*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_stats_inst(pcmdinfo->in.u.stats_manage.cqp,
5246*cdcd52d4SBartosz Sobczak 						    &pcmdinfo->in.u.stats_manage.info,
5247*cdcd52d4SBartosz Sobczak 						    alloc,
5248*cdcd52d4SBartosz Sobczak 						    pcmdinfo->in.u.stats_manage.scratch);
5249*cdcd52d4SBartosz Sobczak 		break;
5250*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_STATS_GATHER:
5251*cdcd52d4SBartosz Sobczak 		status = irdma_sc_gather_stats(pcmdinfo->in.u.stats_gather.cqp,
5252*cdcd52d4SBartosz Sobczak 					       &pcmdinfo->in.u.stats_gather.info,
5253*cdcd52d4SBartosz Sobczak 					       pcmdinfo->in.u.stats_gather.scratch);
5254*cdcd52d4SBartosz Sobczak 		break;
5255*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_WS_MODIFY_NODE:
5256*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp,
5257*cdcd52d4SBartosz Sobczak 						 &pcmdinfo->in.u.ws_node.info,
5258*cdcd52d4SBartosz Sobczak 						 IRDMA_MODIFY_NODE,
5259*cdcd52d4SBartosz Sobczak 						 pcmdinfo->in.u.ws_node.scratch);
5260*cdcd52d4SBartosz Sobczak 		break;
5261*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_WS_DELETE_NODE:
5262*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp,
5263*cdcd52d4SBartosz Sobczak 						 &pcmdinfo->in.u.ws_node.info,
5264*cdcd52d4SBartosz Sobczak 						 IRDMA_DEL_NODE,
5265*cdcd52d4SBartosz Sobczak 						 pcmdinfo->in.u.ws_node.scratch);
5266*cdcd52d4SBartosz Sobczak 		break;
5267*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_WS_ADD_NODE:
5268*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_ws_node(pcmdinfo->in.u.ws_node.cqp,
5269*cdcd52d4SBartosz Sobczak 						 &pcmdinfo->in.u.ws_node.info,
5270*cdcd52d4SBartosz Sobczak 						 IRDMA_ADD_NODE,
5271*cdcd52d4SBartosz Sobczak 						 pcmdinfo->in.u.ws_node.scratch);
5272*cdcd52d4SBartosz Sobczak 		break;
5273*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_SET_UP_MAP:
5274*cdcd52d4SBartosz Sobczak 		status = irdma_sc_set_up_map(pcmdinfo->in.u.up_map.cqp,
5275*cdcd52d4SBartosz Sobczak 					     &pcmdinfo->in.u.up_map.info,
5276*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.up_map.scratch);
5277*cdcd52d4SBartosz Sobczak 		break;
5278*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QUERY_RDMA_FEATURES:
5279*cdcd52d4SBartosz Sobczak 		status = irdma_sc_query_rdma_features(pcmdinfo->in.u.query_rdma.cqp,
5280*cdcd52d4SBartosz Sobczak 						      &pcmdinfo->in.u.query_rdma.query_buff_mem,
5281*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.query_rdma.scratch);
5282*cdcd52d4SBartosz Sobczak 		break;
5283*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_DELETE_ARP_CACHE_ENTRY:
5284*cdcd52d4SBartosz Sobczak 		status = irdma_sc_del_arp_cache_entry(pcmdinfo->in.u.del_arp_cache_entry.cqp,
5285*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.del_arp_cache_entry.scratch,
5286*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.del_arp_cache_entry.arp_index,
5287*cdcd52d4SBartosz Sobczak 						      pcmdinfo->post_sq);
5288*cdcd52d4SBartosz Sobczak 		break;
5289*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MANAGE_APBVT_ENTRY:
5290*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_apbvt_entry(pcmdinfo->in.u.manage_apbvt_entry.cqp,
5291*cdcd52d4SBartosz Sobczak 						     &pcmdinfo->in.u.manage_apbvt_entry.info,
5292*cdcd52d4SBartosz Sobczak 						     pcmdinfo->in.u.manage_apbvt_entry.scratch,
5293*cdcd52d4SBartosz Sobczak 						     pcmdinfo->post_sq);
5294*cdcd52d4SBartosz Sobczak 		break;
5295*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MANAGE_QHASH_TABLE_ENTRY:
5296*cdcd52d4SBartosz Sobczak 		status = irdma_sc_manage_qhash_table_entry(pcmdinfo->in.u.manage_qhash_table_entry.cqp,
5297*cdcd52d4SBartosz Sobczak 							   &pcmdinfo->in.u.manage_qhash_table_entry.info,
5298*cdcd52d4SBartosz Sobczak 							   pcmdinfo->in.u.manage_qhash_table_entry.scratch,
5299*cdcd52d4SBartosz Sobczak 							   pcmdinfo->post_sq);
5300*cdcd52d4SBartosz Sobczak 		break;
5301*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QP_MODIFY:
5302*cdcd52d4SBartosz Sobczak 		status = irdma_sc_qp_modify(pcmdinfo->in.u.qp_modify.qp,
5303*cdcd52d4SBartosz Sobczak 					    &pcmdinfo->in.u.qp_modify.info,
5304*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.qp_modify.scratch,
5305*cdcd52d4SBartosz Sobczak 					    pcmdinfo->post_sq);
5306*cdcd52d4SBartosz Sobczak 		break;
5307*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QP_CREATE:
5308*cdcd52d4SBartosz Sobczak 		status = irdma_sc_qp_create(pcmdinfo->in.u.qp_create.qp,
5309*cdcd52d4SBartosz Sobczak 					    &pcmdinfo->in.u.qp_create.info,
5310*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.qp_create.scratch,
5311*cdcd52d4SBartosz Sobczak 					    pcmdinfo->post_sq);
5312*cdcd52d4SBartosz Sobczak 		break;
5313*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_QP_DESTROY:
5314*cdcd52d4SBartosz Sobczak 		status = irdma_sc_qp_destroy(pcmdinfo->in.u.qp_destroy.qp,
5315*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.qp_destroy.scratch,
5316*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.qp_destroy.remove_hash_idx,
5317*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.qp_destroy.ignore_mw_bnd,
5318*cdcd52d4SBartosz Sobczak 					     pcmdinfo->post_sq);
5319*cdcd52d4SBartosz Sobczak 		break;
5320*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_ALLOC_STAG:
5321*cdcd52d4SBartosz Sobczak 		status = irdma_sc_alloc_stag(pcmdinfo->in.u.alloc_stag.dev,
5322*cdcd52d4SBartosz Sobczak 					     &pcmdinfo->in.u.alloc_stag.info,
5323*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.alloc_stag.scratch,
5324*cdcd52d4SBartosz Sobczak 					     pcmdinfo->post_sq);
5325*cdcd52d4SBartosz Sobczak 		break;
5326*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MR_REG_NON_SHARED:
5327*cdcd52d4SBartosz Sobczak 		status = irdma_sc_mr_reg_non_shared(pcmdinfo->in.u.mr_reg_non_shared.dev,
5328*cdcd52d4SBartosz Sobczak 						    &pcmdinfo->in.u.mr_reg_non_shared.info,
5329*cdcd52d4SBartosz Sobczak 						    pcmdinfo->in.u.mr_reg_non_shared.scratch,
5330*cdcd52d4SBartosz Sobczak 						    pcmdinfo->post_sq);
5331*cdcd52d4SBartosz Sobczak 		break;
5332*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_DEALLOC_STAG:
5333*cdcd52d4SBartosz Sobczak 		status = irdma_sc_dealloc_stag(pcmdinfo->in.u.dealloc_stag.dev,
5334*cdcd52d4SBartosz Sobczak 					       &pcmdinfo->in.u.dealloc_stag.info,
5335*cdcd52d4SBartosz Sobczak 					       pcmdinfo->in.u.dealloc_stag.scratch,
5336*cdcd52d4SBartosz Sobczak 					       pcmdinfo->post_sq);
5337*cdcd52d4SBartosz Sobczak 		break;
5338*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MW_ALLOC:
5339*cdcd52d4SBartosz Sobczak 		status = irdma_sc_mw_alloc(pcmdinfo->in.u.mw_alloc.dev,
5340*cdcd52d4SBartosz Sobczak 					   &pcmdinfo->in.u.mw_alloc.info,
5341*cdcd52d4SBartosz Sobczak 					   pcmdinfo->in.u.mw_alloc.scratch,
5342*cdcd52d4SBartosz Sobczak 					   pcmdinfo->post_sq);
5343*cdcd52d4SBartosz Sobczak 		break;
5344*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_ADD_ARP_CACHE_ENTRY:
5345*cdcd52d4SBartosz Sobczak 		status = irdma_sc_add_arp_cache_entry(pcmdinfo->in.u.add_arp_cache_entry.cqp,
5346*cdcd52d4SBartosz Sobczak 						      &pcmdinfo->in.u.add_arp_cache_entry.info,
5347*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.add_arp_cache_entry.scratch,
5348*cdcd52d4SBartosz Sobczak 						      pcmdinfo->post_sq);
5349*cdcd52d4SBartosz Sobczak 		break;
5350*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY:
5351*cdcd52d4SBartosz Sobczak 		status = irdma_sc_alloc_local_mac_entry(pcmdinfo->in.u.alloc_local_mac_entry.cqp,
5352*cdcd52d4SBartosz Sobczak 							pcmdinfo->in.u.alloc_local_mac_entry.scratch,
5353*cdcd52d4SBartosz Sobczak 							pcmdinfo->post_sq);
5354*cdcd52d4SBartosz Sobczak 		break;
5355*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_ADD_LOCAL_MAC_ENTRY:
5356*cdcd52d4SBartosz Sobczak 		status = irdma_sc_add_local_mac_entry(pcmdinfo->in.u.add_local_mac_entry.cqp,
5357*cdcd52d4SBartosz Sobczak 						      &pcmdinfo->in.u.add_local_mac_entry.info,
5358*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.add_local_mac_entry.scratch,
5359*cdcd52d4SBartosz Sobczak 						      pcmdinfo->post_sq);
5360*cdcd52d4SBartosz Sobczak 		break;
5361*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_DELETE_LOCAL_MAC_ENTRY:
5362*cdcd52d4SBartosz Sobczak 		status = irdma_sc_del_local_mac_entry(pcmdinfo->in.u.del_local_mac_entry.cqp,
5363*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.del_local_mac_entry.scratch,
5364*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.del_local_mac_entry.entry_idx,
5365*cdcd52d4SBartosz Sobczak 						      pcmdinfo->in.u.del_local_mac_entry.ignore_ref_count,
5366*cdcd52d4SBartosz Sobczak 						      pcmdinfo->post_sq);
5367*cdcd52d4SBartosz Sobczak 		break;
5368*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_AH_CREATE:
5369*cdcd52d4SBartosz Sobczak 		status = irdma_sc_create_ah(pcmdinfo->in.u.ah_create.cqp,
5370*cdcd52d4SBartosz Sobczak 					    &pcmdinfo->in.u.ah_create.info,
5371*cdcd52d4SBartosz Sobczak 					    pcmdinfo->in.u.ah_create.scratch);
5372*cdcd52d4SBartosz Sobczak 		break;
5373*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_AH_DESTROY:
5374*cdcd52d4SBartosz Sobczak 		status = irdma_sc_destroy_ah(pcmdinfo->in.u.ah_destroy.cqp,
5375*cdcd52d4SBartosz Sobczak 					     &pcmdinfo->in.u.ah_destroy.info,
5376*cdcd52d4SBartosz Sobczak 					     pcmdinfo->in.u.ah_destroy.scratch);
5377*cdcd52d4SBartosz Sobczak 		break;
5378*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MC_CREATE:
5379*cdcd52d4SBartosz Sobczak 		status = irdma_sc_create_mcast_grp(pcmdinfo->in.u.mc_create.cqp,
5380*cdcd52d4SBartosz Sobczak 						   &pcmdinfo->in.u.mc_create.info,
5381*cdcd52d4SBartosz Sobczak 						   pcmdinfo->in.u.mc_create.scratch);
5382*cdcd52d4SBartosz Sobczak 		break;
5383*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MC_DESTROY:
5384*cdcd52d4SBartosz Sobczak 		status = irdma_sc_destroy_mcast_grp(pcmdinfo->in.u.mc_destroy.cqp,
5385*cdcd52d4SBartosz Sobczak 						    &pcmdinfo->in.u.mc_destroy.info,
5386*cdcd52d4SBartosz Sobczak 						    pcmdinfo->in.u.mc_destroy.scratch);
5387*cdcd52d4SBartosz Sobczak 		break;
5388*cdcd52d4SBartosz Sobczak 	case IRDMA_OP_MC_MODIFY:
5389*cdcd52d4SBartosz Sobczak 		status = irdma_sc_modify_mcast_grp(pcmdinfo->in.u.mc_modify.cqp,
5390*cdcd52d4SBartosz Sobczak 						   &pcmdinfo->in.u.mc_modify.info,
5391*cdcd52d4SBartosz Sobczak 						   pcmdinfo->in.u.mc_modify.scratch);
5392*cdcd52d4SBartosz Sobczak 		break;
5393*cdcd52d4SBartosz Sobczak 	default:
5394*cdcd52d4SBartosz Sobczak 		status = -EOPNOTSUPP;
5395*cdcd52d4SBartosz Sobczak 		break;
5396*cdcd52d4SBartosz Sobczak 	}
5397*cdcd52d4SBartosz Sobczak 
5398*cdcd52d4SBartosz Sobczak 	return status;
5399*cdcd52d4SBartosz Sobczak }
5400*cdcd52d4SBartosz Sobczak 
5401*cdcd52d4SBartosz Sobczak /**
5402*cdcd52d4SBartosz Sobczak  * irdma_process_cqp_cmd - process all cqp commands
5403*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
5404*cdcd52d4SBartosz Sobczak  * @pcmdinfo: cqp command info
5405*cdcd52d4SBartosz Sobczak  */
5406*cdcd52d4SBartosz Sobczak int
5407*cdcd52d4SBartosz Sobczak irdma_process_cqp_cmd(struct irdma_sc_dev *dev,
5408*cdcd52d4SBartosz Sobczak 		      struct cqp_cmds_info *pcmdinfo)
5409*cdcd52d4SBartosz Sobczak {
5410*cdcd52d4SBartosz Sobczak 	int status = 0;
5411*cdcd52d4SBartosz Sobczak 	unsigned long flags;
5412*cdcd52d4SBartosz Sobczak 
5413*cdcd52d4SBartosz Sobczak 	if (dev->no_cqp)
5414*cdcd52d4SBartosz Sobczak 		return -EFAULT;
5415*cdcd52d4SBartosz Sobczak 
5416*cdcd52d4SBartosz Sobczak 	spin_lock_irqsave(&dev->cqp_lock, flags);
5417*cdcd52d4SBartosz Sobczak 	if (list_empty(&dev->cqp_cmd_head) && !irdma_cqp_ring_full(dev->cqp))
5418*cdcd52d4SBartosz Sobczak 		status = irdma_exec_cqp_cmd(dev, pcmdinfo);
5419*cdcd52d4SBartosz Sobczak 	else
5420*cdcd52d4SBartosz Sobczak 		list_add_tail(&pcmdinfo->cqp_cmd_entry, &dev->cqp_cmd_head);
5421*cdcd52d4SBartosz Sobczak 	spin_unlock_irqrestore(&dev->cqp_lock, flags);
5422*cdcd52d4SBartosz Sobczak 	return status;
5423*cdcd52d4SBartosz Sobczak }
5424*cdcd52d4SBartosz Sobczak 
5425*cdcd52d4SBartosz Sobczak /**
5426*cdcd52d4SBartosz Sobczak  * irdma_process_bh - called from tasklet for cqp list
5427*cdcd52d4SBartosz Sobczak  * @dev: sc device struct
5428*cdcd52d4SBartosz Sobczak  */
5429*cdcd52d4SBartosz Sobczak int
5430*cdcd52d4SBartosz Sobczak irdma_process_bh(struct irdma_sc_dev *dev)
5431*cdcd52d4SBartosz Sobczak {
5432*cdcd52d4SBartosz Sobczak 	int status = 0;
5433*cdcd52d4SBartosz Sobczak 	struct cqp_cmds_info *pcmdinfo;
5434*cdcd52d4SBartosz Sobczak 	unsigned long flags;
5435*cdcd52d4SBartosz Sobczak 
5436*cdcd52d4SBartosz Sobczak 	spin_lock_irqsave(&dev->cqp_lock, flags);
5437*cdcd52d4SBartosz Sobczak 	while (!list_empty(&dev->cqp_cmd_head) &&
5438*cdcd52d4SBartosz Sobczak 	       !irdma_cqp_ring_full(dev->cqp)) {
5439*cdcd52d4SBartosz Sobczak 		pcmdinfo = (struct cqp_cmds_info *)irdma_remove_cqp_head(dev);
5440*cdcd52d4SBartosz Sobczak 		status = irdma_exec_cqp_cmd(dev, pcmdinfo);
5441*cdcd52d4SBartosz Sobczak 		if (status)
5442*cdcd52d4SBartosz Sobczak 			break;
5443*cdcd52d4SBartosz Sobczak 	}
5444*cdcd52d4SBartosz Sobczak 	spin_unlock_irqrestore(&dev->cqp_lock, flags);
5445*cdcd52d4SBartosz Sobczak 	return status;
5446*cdcd52d4SBartosz Sobczak }
5447*cdcd52d4SBartosz Sobczak 
5448*cdcd52d4SBartosz Sobczak /**
5449*cdcd52d4SBartosz Sobczak  * irdma_cfg_aeq- Configure AEQ interrupt
5450*cdcd52d4SBartosz Sobczak  * @dev: pointer to the device structure
5451*cdcd52d4SBartosz Sobczak  * @idx: vector index
5452*cdcd52d4SBartosz Sobczak  * @enable: True to enable, False disables
5453*cdcd52d4SBartosz Sobczak  */
5454*cdcd52d4SBartosz Sobczak void
5455*cdcd52d4SBartosz Sobczak irdma_cfg_aeq(struct irdma_sc_dev *dev, u32 idx, bool enable)
5456*cdcd52d4SBartosz Sobczak {
5457*cdcd52d4SBartosz Sobczak 	u32 reg_val;
5458*cdcd52d4SBartosz Sobczak 	reg_val = enable ? IRDMA_PFINT_AEQCTL_CAUSE_ENA_M : 0;
5459*cdcd52d4SBartosz Sobczak 	reg_val |= (idx << IRDMA_PFINT_AEQCTL_MSIX_INDX_S) |
5460*cdcd52d4SBartosz Sobczak 	    IRDMA_PFINT_AEQCTL_ITR_INDX_M;
5461*cdcd52d4SBartosz Sobczak 	writel(reg_val, dev->hw_regs[IRDMA_PFINT_AEQCTL]);
5462*cdcd52d4SBartosz Sobczak }
5463*cdcd52d4SBartosz Sobczak 
5464*cdcd52d4SBartosz Sobczak /**
5465*cdcd52d4SBartosz Sobczak  * sc_vsi_update_stats - Update statistics
5466*cdcd52d4SBartosz Sobczak  * @vsi: sc_vsi instance to update
5467*cdcd52d4SBartosz Sobczak  */
5468*cdcd52d4SBartosz Sobczak void
5469*cdcd52d4SBartosz Sobczak sc_vsi_update_stats(struct irdma_sc_vsi *vsi)
5470*cdcd52d4SBartosz Sobczak {
5471*cdcd52d4SBartosz Sobczak 	struct irdma_gather_stats *gather_stats;
5472*cdcd52d4SBartosz Sobczak 	struct irdma_gather_stats *last_gather_stats;
5473*cdcd52d4SBartosz Sobczak 
5474*cdcd52d4SBartosz Sobczak 	gather_stats = vsi->pestat->gather_info.gather_stats_va;
5475*cdcd52d4SBartosz Sobczak 	last_gather_stats = vsi->pestat->gather_info.last_gather_stats_va;
5476*cdcd52d4SBartosz Sobczak 	irdma_update_stats(&vsi->pestat->hw_stats, gather_stats,
5477*cdcd52d4SBartosz Sobczak 			   last_gather_stats, vsi->dev->hw_stats_map,
5478*cdcd52d4SBartosz Sobczak 			   vsi->dev->hw_attrs.max_stat_idx);
5479*cdcd52d4SBartosz Sobczak }
5480*cdcd52d4SBartosz Sobczak 
5481*cdcd52d4SBartosz Sobczak /**
5482*cdcd52d4SBartosz Sobczak  * irdma_wait_pe_ready - Check if firmware is ready
5483*cdcd52d4SBartosz Sobczak  * @dev: provides access to registers
5484*cdcd52d4SBartosz Sobczak  */
5485*cdcd52d4SBartosz Sobczak static int
5486*cdcd52d4SBartosz Sobczak irdma_wait_pe_ready(struct irdma_sc_dev *dev)
5487*cdcd52d4SBartosz Sobczak {
5488*cdcd52d4SBartosz Sobczak 	u32 statuscpu0;
5489*cdcd52d4SBartosz Sobczak 	u32 statuscpu1;
5490*cdcd52d4SBartosz Sobczak 	u32 statuscpu2;
5491*cdcd52d4SBartosz Sobczak 	u32 retrycount = 0;
5492*cdcd52d4SBartosz Sobczak 
5493*cdcd52d4SBartosz Sobczak 	do {
5494*cdcd52d4SBartosz Sobczak 		statuscpu0 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS0]);
5495*cdcd52d4SBartosz Sobczak 		statuscpu1 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS1]);
5496*cdcd52d4SBartosz Sobczak 		statuscpu2 = readl(dev->hw_regs[IRDMA_GLPE_CPUSTATUS2]);
5497*cdcd52d4SBartosz Sobczak 		if (statuscpu0 == 0x80 && statuscpu1 == 0x80 &&
5498*cdcd52d4SBartosz Sobczak 		    statuscpu2 == 0x80)
5499*cdcd52d4SBartosz Sobczak 			return 0;
5500*cdcd52d4SBartosz Sobczak 		mdelay(1000);
5501*cdcd52d4SBartosz Sobczak 	} while (retrycount++ < dev->hw_attrs.max_pe_ready_count);
5502*cdcd52d4SBartosz Sobczak 	return -1;
5503*cdcd52d4SBartosz Sobczak }
5504*cdcd52d4SBartosz Sobczak 
5505*cdcd52d4SBartosz Sobczak static inline void
5506*cdcd52d4SBartosz Sobczak irdma_sc_init_hw(struct irdma_sc_dev *dev)
5507*cdcd52d4SBartosz Sobczak {
5508*cdcd52d4SBartosz Sobczak 	switch (dev->hw_attrs.uk_attrs.hw_rev) {
5509*cdcd52d4SBartosz Sobczak 	case IRDMA_GEN_2:
5510*cdcd52d4SBartosz Sobczak 		icrdma_init_hw(dev);
5511*cdcd52d4SBartosz Sobczak 		break;
5512*cdcd52d4SBartosz Sobczak 	}
5513*cdcd52d4SBartosz Sobczak }
5514*cdcd52d4SBartosz Sobczak 
5515*cdcd52d4SBartosz Sobczak /**
5516*cdcd52d4SBartosz Sobczak  * irdma_sc_dev_init - Initialize control part of device
5517*cdcd52d4SBartosz Sobczak  * @ver: version
5518*cdcd52d4SBartosz Sobczak  * @dev: Device pointer
5519*cdcd52d4SBartosz Sobczak  * @info: Device init info
5520*cdcd52d4SBartosz Sobczak  */
5521*cdcd52d4SBartosz Sobczak int
5522*cdcd52d4SBartosz Sobczak irdma_sc_dev_init(enum irdma_vers ver, struct irdma_sc_dev *dev,
5523*cdcd52d4SBartosz Sobczak 		  struct irdma_device_init_info *info)
5524*cdcd52d4SBartosz Sobczak {
5525*cdcd52d4SBartosz Sobczak 	u32 val;
5526*cdcd52d4SBartosz Sobczak 	int ret_code = 0;
5527*cdcd52d4SBartosz Sobczak 	u8 db_size;
5528*cdcd52d4SBartosz Sobczak 
5529*cdcd52d4SBartosz Sobczak 	INIT_LIST_HEAD(&dev->cqp_cmd_head);	/* for CQP command backlog */
5530*cdcd52d4SBartosz Sobczak 	mutex_init(&dev->ws_mutex);
5531*cdcd52d4SBartosz Sobczak 	dev->debug_mask = info->debug_mask;
5532*cdcd52d4SBartosz Sobczak 	dev->hmc_fn_id = info->hmc_fn_id;
5533*cdcd52d4SBartosz Sobczak 	dev->fpm_query_buf_pa = info->fpm_query_buf_pa;
5534*cdcd52d4SBartosz Sobczak 	dev->fpm_query_buf = info->fpm_query_buf;
5535*cdcd52d4SBartosz Sobczak 	dev->fpm_commit_buf_pa = info->fpm_commit_buf_pa;
5536*cdcd52d4SBartosz Sobczak 	dev->fpm_commit_buf = info->fpm_commit_buf;
5537*cdcd52d4SBartosz Sobczak 	dev->hw = info->hw;
5538*cdcd52d4SBartosz Sobczak 	dev->hw->hw_addr = info->bar0;
5539*cdcd52d4SBartosz Sobczak 	/* Setup the hardware limits, hmc may limit further */
5540*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.min_hw_qp_id = IRDMA_MIN_IW_QP_ID;
5541*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.min_hw_aeq_size = IRDMA_MIN_AEQ_ENTRIES;
5542*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_aeq_size = IRDMA_MAX_AEQ_ENTRIES;
5543*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.min_hw_ceq_size = IRDMA_MIN_CEQ_ENTRIES;
5544*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_ceq_size = IRDMA_MAX_CEQ_ENTRIES;
5545*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.uk_attrs.min_hw_cq_size = IRDMA_MIN_CQ_SIZE;
5546*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.uk_attrs.max_hw_cq_size = IRDMA_MAX_CQ_SIZE;
5547*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_outbound_msg_size = IRDMA_MAX_OUTBOUND_MSG_SIZE;
5548*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_mr_size = IRDMA_MAX_MR_SIZE;
5549*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_inbound_msg_size = IRDMA_MAX_INBOUND_MSG_SIZE;
5550*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_device_pages = IRDMA_MAX_PUSH_PAGE_COUNT;
5551*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.uk_attrs.max_hw_inline = IRDMA_MAX_INLINE_DATA_SIZE;
5552*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_wqes = IRDMA_MAX_WQ_ENTRIES;
5553*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_qp_wr = IRDMA_MAX_QP_WRS(IRDMA_MAX_QUANTA_PER_WR);
5554*cdcd52d4SBartosz Sobczak 
5555*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.uk_attrs.max_hw_rq_quanta = IRDMA_QP_SW_MAX_RQ_QUANTA;
5556*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.uk_attrs.max_hw_wq_quanta = IRDMA_QP_SW_MAX_WQ_QUANTA;
5557*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_pds = IRDMA_MAX_PDS;
5558*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_hw_ena_vf_count = IRDMA_MAX_PE_ENA_VF_COUNT;
5559*cdcd52d4SBartosz Sobczak 
5560*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_pe_ready_count = 14;
5561*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_done_count = IRDMA_DONE_COUNT;
5562*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_sleep_count = IRDMA_SLEEP_COUNT;
5563*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.max_cqp_compl_wait_time_ms = CQP_COMPL_WAIT_TIME_MS;
5564*cdcd52d4SBartosz Sobczak 
5565*cdcd52d4SBartosz Sobczak 	dev->hw_attrs.uk_attrs.hw_rev = ver;
5566*cdcd52d4SBartosz Sobczak 	irdma_sc_init_hw(dev);
5567*cdcd52d4SBartosz Sobczak 
5568*cdcd52d4SBartosz Sobczak 	if (irdma_wait_pe_ready(dev))
5569*cdcd52d4SBartosz Sobczak 		return -ETIMEDOUT;
5570*cdcd52d4SBartosz Sobczak 
5571*cdcd52d4SBartosz Sobczak 	val = readl(dev->hw_regs[IRDMA_GLPCI_LBARCTRL]);
5572*cdcd52d4SBartosz Sobczak 	db_size = (u8)RS_32(val, IRDMA_GLPCI_LBARCTRL_PE_DB_SIZE);
5573*cdcd52d4SBartosz Sobczak 	if (db_size != IRDMA_PE_DB_SIZE_4M && db_size != IRDMA_PE_DB_SIZE_8M) {
5574*cdcd52d4SBartosz Sobczak 		irdma_debug(dev, IRDMA_DEBUG_DEV,
5575*cdcd52d4SBartosz Sobczak 			    "RDMA PE doorbell is not enabled in CSR val 0x%x db_size=%d\n",
5576*cdcd52d4SBartosz Sobczak 			    val, db_size);
5577*cdcd52d4SBartosz Sobczak 		return -ENODEV;
5578*cdcd52d4SBartosz Sobczak 	}
5579*cdcd52d4SBartosz Sobczak 	dev->db_addr = dev->hw->hw_addr + (uintptr_t)dev->hw_regs[IRDMA_DB_ADDR_OFFSET];
5580*cdcd52d4SBartosz Sobczak 
5581*cdcd52d4SBartosz Sobczak 	return ret_code;
5582*cdcd52d4SBartosz Sobczak }
5583*cdcd52d4SBartosz Sobczak 
5584*cdcd52d4SBartosz Sobczak /**
5585*cdcd52d4SBartosz Sobczak  * irdma_stat_val - Extract HW counter value from statistics buffer
5586*cdcd52d4SBartosz Sobczak  * @stats_val: pointer to statistics buffer
5587*cdcd52d4SBartosz Sobczak  * @byteoff: byte offset of counter value in the buffer (8B-aligned)
5588*cdcd52d4SBartosz Sobczak  * @bitoff: bit offset of counter value within 8B entry
5589*cdcd52d4SBartosz Sobczak  * @bitmask: maximum counter value (e.g. 0xffffff for 24-bit counter)
5590*cdcd52d4SBartosz Sobczak  */
5591*cdcd52d4SBartosz Sobczak static inline u64 irdma_stat_val(const u64 *stats_val, u16 byteoff,
5592*cdcd52d4SBartosz Sobczak 				 u8 bitoff, u64 bitmask){
5593*cdcd52d4SBartosz Sobczak 	u16 idx = byteoff / sizeof(*stats_val);
5594*cdcd52d4SBartosz Sobczak 
5595*cdcd52d4SBartosz Sobczak 	return (stats_val[idx] >> bitoff) & bitmask;
5596*cdcd52d4SBartosz Sobczak }
5597*cdcd52d4SBartosz Sobczak 
5598*cdcd52d4SBartosz Sobczak /**
5599*cdcd52d4SBartosz Sobczak  * irdma_stat_delta - Calculate counter delta
5600*cdcd52d4SBartosz Sobczak  * @new_val: updated counter value
5601*cdcd52d4SBartosz Sobczak  * @old_val: last counter value
5602*cdcd52d4SBartosz Sobczak  * @max_val: maximum counter value (e.g. 0xffffff for 24-bit counter)
5603*cdcd52d4SBartosz Sobczak  */
5604*cdcd52d4SBartosz Sobczak static inline u64 irdma_stat_delta(u64 new_val, u64 old_val, u64 max_val) {
5605*cdcd52d4SBartosz Sobczak 	if (new_val >= old_val)
5606*cdcd52d4SBartosz Sobczak 		return new_val - old_val;
5607*cdcd52d4SBartosz Sobczak 	else
5608*cdcd52d4SBartosz Sobczak 		/* roll-over case */
5609*cdcd52d4SBartosz Sobczak 		return max_val - old_val + new_val + 1;
5610*cdcd52d4SBartosz Sobczak }
5611*cdcd52d4SBartosz Sobczak 
5612*cdcd52d4SBartosz Sobczak /**
5613*cdcd52d4SBartosz Sobczak  * irdma_update_stats - Update statistics
5614*cdcd52d4SBartosz Sobczak  * @hw_stats: hw_stats instance to update
5615*cdcd52d4SBartosz Sobczak  * @gather_stats: updated stat counters
5616*cdcd52d4SBartosz Sobczak  * @last_gather_stats: last stat counters
5617*cdcd52d4SBartosz Sobczak  * @map: HW stat map (hw_stats => gather_stats)
5618*cdcd52d4SBartosz Sobczak  * @max_stat_idx: number of HW stats
5619*cdcd52d4SBartosz Sobczak  */
5620*cdcd52d4SBartosz Sobczak void
5621*cdcd52d4SBartosz Sobczak irdma_update_stats(struct irdma_dev_hw_stats *hw_stats,
5622*cdcd52d4SBartosz Sobczak 		   struct irdma_gather_stats *gather_stats,
5623*cdcd52d4SBartosz Sobczak 		   struct irdma_gather_stats *last_gather_stats,
5624*cdcd52d4SBartosz Sobczak 		   const struct irdma_hw_stat_map *map,
5625*cdcd52d4SBartosz Sobczak 		   u16 max_stat_idx)
5626*cdcd52d4SBartosz Sobczak {
5627*cdcd52d4SBartosz Sobczak 	u64 *stats_val = hw_stats->stats_val;
5628*cdcd52d4SBartosz Sobczak 	u16 i;
5629*cdcd52d4SBartosz Sobczak 
5630*cdcd52d4SBartosz Sobczak 	for (i = 0; i < max_stat_idx; i++) {
5631*cdcd52d4SBartosz Sobczak 		u64 new_val = irdma_stat_val(gather_stats->val,
5632*cdcd52d4SBartosz Sobczak 					     map[i].byteoff, map[i].bitoff,
5633*cdcd52d4SBartosz Sobczak 					     map[i].bitmask);
5634*cdcd52d4SBartosz Sobczak 		u64 last_val = irdma_stat_val(last_gather_stats->val,
5635*cdcd52d4SBartosz Sobczak 					      map[i].byteoff, map[i].bitoff,
5636*cdcd52d4SBartosz Sobczak 					      map[i].bitmask);
5637*cdcd52d4SBartosz Sobczak 
5638*cdcd52d4SBartosz Sobczak 		stats_val[i] += irdma_stat_delta(new_val, last_val,
5639*cdcd52d4SBartosz Sobczak 						 map[i].bitmask);
5640*cdcd52d4SBartosz Sobczak 	}
5641*cdcd52d4SBartosz Sobczak 
5642*cdcd52d4SBartosz Sobczak 	irdma_memcpy(last_gather_stats, gather_stats,
5643*cdcd52d4SBartosz Sobczak 		     sizeof(*last_gather_stats));
5644*cdcd52d4SBartosz Sobczak }
5645