/*******************************************************************************
*
* Copyright (c) 2015-2016 Intel Corporation.  All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses.  You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenFabrics.org BSD license below:
*
*   Redistribution and use in source and binary forms, with or
*   without modification, are permitted provided that the following
*   conditions are met:
*
*    - Redistributions of source code must retain the above
*	copyright notice, this list of conditions and the following
*	disclaimer.
*
*    - Redistributions in binary form must reproduce the above
*	copyright notice, this list of conditions and the following
*	disclaimer in the documentation and/or other materials
*	provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*******************************************************************************/

#include "i40iw_osdep.h"
#include "i40iw_register.h"
#include "i40iw_status.h"
#include "i40iw_hmc.h"

#include "i40iw_d.h"
#include "i40iw_type.h"
#include "i40iw_p.h"
#include "i40iw_vf.h"
#include "i40iw_virtchnl.h"

/**
 * i40iw_insert_wqe_hdr - write wqe header
 * @wqe: cqp wqe for header
 * @header: header for the cqp wqe
 */
void i40iw_insert_wqe_hdr(u64 *wqe, u64 header)
{
	wmb();            /* make sure WQE is populated before polarity is set */
	set_64bit_val(wqe, 24, header);
}

void i40iw_check_cqp_progress(struct i40iw_cqp_timeout *cqp_timeout, struct i40iw_sc_dev *dev)
{
	if (cqp_timeout->compl_cqp_cmds != dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]) {
		cqp_timeout->compl_cqp_cmds = dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS];
		cqp_timeout->count = 0;
	} else {
		if (dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] != cqp_timeout->compl_cqp_cmds)
			cqp_timeout->count++;
	}
}

/**
 * i40iw_get_cqp_reg_info - get head and tail for cqp using registers
 * @cqp: struct for cqp hw
 * @val: cqp tail register value
 * @tail:wqtail register value
 * @error: cqp processing err
 */
static inline void i40iw_get_cqp_reg_info(struct i40iw_sc_cqp *cqp,
					  u32 *val,
					  u32 *tail,
					  u32 *error)
{
	if (cqp->dev->is_pf) {
		*val = i40iw_rd32(cqp->dev->hw, I40E_PFPE_CQPTAIL);
		*tail = RS_32(*val, I40E_PFPE_CQPTAIL_WQTAIL);
		*error = RS_32(*val, I40E_PFPE_CQPTAIL_CQP_OP_ERR);
	} else {
		*val = i40iw_rd32(cqp->dev->hw, I40E_VFPE_CQPTAIL1);
		*tail = RS_32(*val, I40E_VFPE_CQPTAIL_WQTAIL);
		*error = RS_32(*val, I40E_VFPE_CQPTAIL_CQP_OP_ERR);
	}
}

/**
 * i40iw_cqp_poll_registers - poll cqp registers
 * @cqp: struct for cqp hw
 * @tail:wqtail register value
 * @count: how many times to try for completion
 */
static enum i40iw_status_code i40iw_cqp_poll_registers(
						struct i40iw_sc_cqp *cqp,
						u32 tail,
						u32 count)
{
	u32 i = 0;
	u32 newtail, error, val;

	while (i < count) {
		i++;
		i40iw_get_cqp_reg_info(cqp, &val, &newtail, &error);
		if (error) {
			error = (cqp->dev->is_pf) ?
				 i40iw_rd32(cqp->dev->hw, I40E_PFPE_CQPERRCODES) :
				 i40iw_rd32(cqp->dev->hw, I40E_VFPE_CQPERRCODES1);
			return I40IW_ERR_CQP_COMPL_ERROR;
		}
		if (newtail != tail) {
			/* SUCCESS */
			I40IW_RING_MOVE_TAIL(cqp->sq_ring);
			cqp->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]++;
			return 0;
		}
		udelay(I40IW_SLEEP_COUNT);
	}
	return I40IW_ERR_TIMEOUT;
}

/**
 * i40iw_sc_parse_fpm_commit_buf - parse fpm commit buffer
 * @buf: ptr to fpm commit buffer
 * @info: ptr to i40iw_hmc_obj_info struct
 * @sd: number of SDs for HMC objects
 *
 * parses fpm commit info and copy base value
 * of hmc objects in hmc_info
 */
static enum i40iw_status_code i40iw_sc_parse_fpm_commit_buf(
				u64 *buf,
				struct i40iw_hmc_obj_info *info,
				u32 *sd)
{
	u64 temp;
	u64 size;
	u64 base = 0;
	u32 i, j;
	u32 k = 0;

	/* copy base values in obj_info */
	for (i = I40IW_HMC_IW_QP, j = 0; i <= I40IW_HMC_IW_PBLE; i++, j += 8) {
		if ((i == I40IW_HMC_IW_SRQ) ||
			(i == I40IW_HMC_IW_FSIMC) ||
			(i == I40IW_HMC_IW_FSIAV)) {
			info[i].base = 0;
			info[i].cnt = 0;
			continue;
		}
		get_64bit_val(buf, j, &temp);
		info[i].base = RS_64_1(temp, 32) * 512;
		if (info[i].base > base) {
			base = info[i].base;
			k = i;
		}
		if (i == I40IW_HMC_IW_APBVT_ENTRY) {
			info[i].cnt = 1;
			continue;
		}
		if (i == I40IW_HMC_IW_QP)
			info[i].cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS);
		else if (i == I40IW_HMC_IW_CQ)
			info[i].cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS);
		else
			info[i].cnt = (u32)(temp);
	}
	size = info[k].cnt * info[k].size + info[k].base;
	if (size & 0x1FFFFF)
		*sd = (u32)((size >> 21) + 1); /* add 1 for remainder */
	else
		*sd = (u32)(size >> 21);

	return 0;
}

/**
 * i40iw_sc_decode_fpm_query() - Decode a 64 bit value into max count and size
 * @buf: ptr to fpm query buffer
 * @buf_idx: index into buf
 * @obj_info: ptr to i40iw_hmc_obj_info struct
 * @rsrc_idx: resource index into info
 *
 * Decode a 64 bit value from fpm query buffer into max count and size
 */
static u64 i40iw_sc_decode_fpm_query(u64 *buf,
					    u32 buf_idx,
					    struct i40iw_hmc_obj_info *obj_info,
					    u32 rsrc_idx)
{
	u64 temp;
	u32 size;

	get_64bit_val(buf, buf_idx, &temp);
	obj_info[rsrc_idx].max_cnt = (u32)temp;
	size = (u32)RS_64_1(temp, 32);
	obj_info[rsrc_idx].size = LS_64_1(1, size);

	return temp;
}

/**
 * i40iw_sc_parse_fpm_query_buf() - parses fpm query buffer
 * @buf: ptr to fpm query buffer
 * @hmc_info: ptr to i40iw_hmc_obj_info struct
 * @hmc_fpm_misc: ptr to fpm data
 *
 * parses fpm query buffer and copy max_cnt and
 * size value of hmc objects in hmc_info
 */
static enum i40iw_status_code i40iw_sc_parse_fpm_query_buf(
				u64 *buf,
				struct i40iw_hmc_info *hmc_info,
				struct i40iw_hmc_fpm_misc *hmc_fpm_misc)
{
	struct i40iw_hmc_obj_info *obj_info;
	u64 temp;
	u32 size;
	u16 max_pe_sds;

	obj_info = hmc_info->hmc_obj;

	get_64bit_val(buf, 0, &temp);
	hmc_info->first_sd_index = (u16)RS_64(temp, I40IW_QUERY_FPM_FIRST_PE_SD_INDEX);
	max_pe_sds = (u16)RS_64(temp, I40IW_QUERY_FPM_MAX_PE_SDS);

	/* Reduce SD count for VFs by 1 to account for PBLE backing page rounding */
	if (hmc_info->hmc_fn_id >= I40IW_FIRST_VF_FPM_ID)
		max_pe_sds--;
	hmc_fpm_misc->max_sds = max_pe_sds;
	hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index;

	get_64bit_val(buf, 8, &temp);
	obj_info[I40IW_HMC_IW_QP].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS);
	size = (u32)RS_64_1(temp, 32);
	obj_info[I40IW_HMC_IW_QP].size = LS_64_1(1, size);

	get_64bit_val(buf, 16, &temp);
	obj_info[I40IW_HMC_IW_CQ].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS);
	size = (u32)RS_64_1(temp, 32);
	obj_info[I40IW_HMC_IW_CQ].size = LS_64_1(1, size);

	i40iw_sc_decode_fpm_query(buf, 32, obj_info, I40IW_HMC_IW_HTE);
	i40iw_sc_decode_fpm_query(buf, 40, obj_info, I40IW_HMC_IW_ARP);

	obj_info[I40IW_HMC_IW_APBVT_ENTRY].size = 8192;
	obj_info[I40IW_HMC_IW_APBVT_ENTRY].max_cnt = 1;

	i40iw_sc_decode_fpm_query(buf, 48, obj_info, I40IW_HMC_IW_MR);
	i40iw_sc_decode_fpm_query(buf, 56, obj_info, I40IW_HMC_IW_XF);

	get_64bit_val(buf, 64, &temp);
	obj_info[I40IW_HMC_IW_XFFL].max_cnt = (u32)temp;
	obj_info[I40IW_HMC_IW_XFFL].size = 4;
	hmc_fpm_misc->xf_block_size = RS_64(temp, I40IW_QUERY_FPM_XFBLOCKSIZE);
	if (!hmc_fpm_misc->xf_block_size)
		return I40IW_ERR_INVALID_SIZE;

	i40iw_sc_decode_fpm_query(buf, 72, obj_info, I40IW_HMC_IW_Q1);

	get_64bit_val(buf, 80, &temp);
	obj_info[I40IW_HMC_IW_Q1FL].max_cnt = (u32)temp;
	obj_info[I40IW_HMC_IW_Q1FL].size = 4;
	hmc_fpm_misc->q1_block_size = RS_64(temp, I40IW_QUERY_FPM_Q1BLOCKSIZE);
	if (!hmc_fpm_misc->q1_block_size)
		return I40IW_ERR_INVALID_SIZE;

	i40iw_sc_decode_fpm_query(buf, 88, obj_info, I40IW_HMC_IW_TIMER);

	get_64bit_val(buf, 112, &temp);
	obj_info[I40IW_HMC_IW_PBLE].max_cnt = (u32)temp;
	obj_info[I40IW_HMC_IW_PBLE].size = 8;

	get_64bit_val(buf, 120, &temp);
	hmc_fpm_misc->max_ceqs = (u8)RS_64(temp, I40IW_QUERY_FPM_MAX_CEQS);
	hmc_fpm_misc->ht_multiplier = RS_64(temp, I40IW_QUERY_FPM_HTMULTIPLIER);
	hmc_fpm_misc->timer_bucket = RS_64(temp, I40IW_QUERY_FPM_TIMERBUCKET);

	return 0;
}

/**
 * i40iw_fill_qos_list - Change all unknown qs handles to available ones
 * @qs_list: list of qs_handles to be fixed with valid qs_handles
 */
static void i40iw_fill_qos_list(u16 *qs_list)
{
	u16 qshandle = qs_list[0];
	int i;

	for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) {
		if (qs_list[i] == QS_HANDLE_UNKNOWN)
			qs_list[i] = qshandle;
		else
			qshandle = qs_list[i];
	}
}

/**
 * i40iw_qp_from_entry - Given entry, get to the qp structure
 * @entry: Points to list of qp structure
 */
static struct i40iw_sc_qp *i40iw_qp_from_entry(struct list_head *entry)
{
	if (!entry)
		return NULL;

	return (struct i40iw_sc_qp *)((char *)entry - offsetof(struct i40iw_sc_qp, list));
}

/**
 * i40iw_get_qp - get the next qp from the list given current qp
 * @head: Listhead of qp's
 * @qp: current qp
 */
static struct i40iw_sc_qp *i40iw_get_qp(struct list_head *head, struct i40iw_sc_qp *qp)
{
	struct list_head *entry = NULL;
	struct list_head *lastentry;

	if (list_empty(head))
		return NULL;

	if (!qp) {
		entry = head->next;
	} else {
		lastentry = &qp->list;
		entry = (lastentry != head) ? lastentry->next : NULL;
	}

	return i40iw_qp_from_entry(entry);
}

/**
 * i40iw_change_l2params - given the new l2 parameters, change all qp
 * @vsi: pointer to the vsi structure
 * @l2params: New paramaters from l2
 */
void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2params)
{
	struct i40iw_sc_dev *dev = vsi->dev;
	struct i40iw_sc_qp *qp = NULL;
	bool qs_handle_change = false;
	unsigned long flags;
	u16 qs_handle;
	int i;

	if (vsi->mtu != l2params->mtu) {
		vsi->mtu = l2params->mtu;
		i40iw_reinitialize_ieq(dev);
	}

	i40iw_fill_qos_list(l2params->qs_handle_list);
	for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) {
		qs_handle = l2params->qs_handle_list[i];
		if (vsi->qos[i].qs_handle != qs_handle)
			qs_handle_change = true;
		spin_lock_irqsave(&vsi->qos[i].lock, flags);
		qp = i40iw_get_qp(&vsi->qos[i].qplist, qp);
		while (qp) {
			if (qs_handle_change) {
				qp->qs_handle = qs_handle;
				/* issue cqp suspend command */
				i40iw_qp_suspend_resume(dev, qp, true);
			}
			qp = i40iw_get_qp(&vsi->qos[i].qplist, qp);
		}
		spin_unlock_irqrestore(&vsi->qos[i].lock, flags);
		vsi->qos[i].qs_handle = qs_handle;
	}
}

/**
 * i40iw_qp_rem_qos - remove qp from qos lists during destroy qp
 * @qp: qp to be removed from qos
 */
void i40iw_qp_rem_qos(struct i40iw_sc_qp *qp)
{
	struct i40iw_sc_vsi *vsi = qp->vsi;
	unsigned long flags;

	if (!qp->on_qoslist)
		return;
	spin_lock_irqsave(&vsi->qos[qp->user_pri].lock, flags);
	list_del(&qp->list);
	spin_unlock_irqrestore(&vsi->qos[qp->user_pri].lock, flags);
}

/**
 * i40iw_qp_add_qos - called during setctx fot qp to be added to qos
 * @qp: qp to be added to qos
 */
void i40iw_qp_add_qos(struct i40iw_sc_qp *qp)
{
	struct i40iw_sc_vsi *vsi = qp->vsi;
	unsigned long flags;

	if (qp->on_qoslist)
		return;
	spin_lock_irqsave(&vsi->qos[qp->user_pri].lock, flags);
	qp->qs_handle = vsi->qos[qp->user_pri].qs_handle;
	list_add(&qp->list, &vsi->qos[qp->user_pri].qplist);
	qp->on_qoslist = true;
	spin_unlock_irqrestore(&vsi->qos[qp->user_pri].lock, flags);
}

/**
 * i40iw_sc_pd_init - initialize sc pd struct
 * @dev: sc device struct
 * @pd: sc pd ptr
 * @pd_id: pd_id for allocated pd
 * @abi_ver: ABI version from user context, -1 if not valid
 */
static void i40iw_sc_pd_init(struct i40iw_sc_dev *dev,
			     struct i40iw_sc_pd *pd,
			     u16 pd_id,
			     int abi_ver)
{
	pd->size = sizeof(*pd);
	pd->pd_id = pd_id;
	pd->abi_ver = abi_ver;
	pd->dev = dev;
}

/**
 * i40iw_get_encoded_wqe_size - given wq size, returns hardware encoded size
 * @wqsize: size of the wq (sq, rq, srq) to encoded_size
 * @cqpsq: encoded size for sq for cqp as its encoded size is 1+ other wq's
 */
u8 i40iw_get_encoded_wqe_size(u32 wqsize, bool cqpsq)
{
	u8 encoded_size = 0;

	/* cqp sq's hw coded value starts from 1 for size of 4
	 * while it starts from 0 for qp' wq's.
	 */
	if (cqpsq)
		encoded_size = 1;
	wqsize >>= 2;
	while (wqsize >>= 1)
		encoded_size++;
	return encoded_size;
}

/**
 * i40iw_sc_cqp_init - Initialize buffers for a control Queue Pair
 * @cqp: IWARP control queue pair pointer
 * @info: IWARP control queue pair init info pointer
 *
 * Initializes the object and context buffers for a control Queue Pair.
 */
static enum i40iw_status_code i40iw_sc_cqp_init(struct i40iw_sc_cqp *cqp,
						struct i40iw_cqp_init_info *info)
{
	u8 hw_sq_size;

	if ((info->sq_size > I40IW_CQP_SW_SQSIZE_2048) ||
	    (info->sq_size < I40IW_CQP_SW_SQSIZE_4) ||
	    ((info->sq_size & (info->sq_size - 1))))
		return I40IW_ERR_INVALID_SIZE;

	hw_sq_size = i40iw_get_encoded_wqe_size(info->sq_size, true);
	cqp->size = sizeof(*cqp);
	cqp->sq_size = info->sq_size;
	cqp->hw_sq_size = hw_sq_size;
	cqp->sq_base = info->sq;
	cqp->host_ctx = info->host_ctx;
	cqp->sq_pa = info->sq_pa;
	cqp->host_ctx_pa = info->host_ctx_pa;
	cqp->dev = info->dev;
	cqp->struct_ver = info->struct_ver;
	cqp->scratch_array = info->scratch_array;
	cqp->polarity = 0;
	cqp->en_datacenter_tcp = info->en_datacenter_tcp;
	cqp->enabled_vf_count = info->enabled_vf_count;
	cqp->hmc_profile = info->hmc_profile;
	info->dev->cqp = cqp;

	I40IW_RING_INIT(cqp->sq_ring, cqp->sq_size);
	cqp->dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] = 0;
	cqp->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS] = 0;
	INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head);               /* for the cqp commands backlog. */

	i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPTAIL, 0);
	i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPDB, 0);

	i40iw_debug(cqp->dev, I40IW_DEBUG_WQE,
		    "%s: sq_size[%04d] hw_sq_size[%04d] sq_base[%p] sq_pa[%llxh] cqp[%p] polarity[x%04X]\n",
		    __func__, cqp->sq_size, cqp->hw_sq_size,
		    cqp->sq_base, cqp->sq_pa, cqp, cqp->polarity);
	return 0;
}

/**
 * i40iw_sc_cqp_create - create cqp during bringup
 * @cqp: struct for cqp hw
 * @maj_err: If error, major err number
 * @min_err: If error, minor err number
 */
static enum i40iw_status_code i40iw_sc_cqp_create(struct i40iw_sc_cqp *cqp,
						  u16 *maj_err,
						  u16 *min_err)
{
	u64 temp;
	u32 cnt = 0, p1, p2, val = 0, err_code;
	enum i40iw_status_code ret_code;

	*maj_err = 0;
	*min_err = 0;

	ret_code = i40iw_allocate_dma_mem(cqp->dev->hw,
					  &cqp->sdbuf,
					  I40IW_UPDATE_SD_BUF_SIZE * cqp->sq_size,
					  I40IW_SD_BUF_ALIGNMENT);

	if (ret_code)
		goto exit;

	temp = LS_64(cqp->hw_sq_size, I40IW_CQPHC_SQSIZE) |
	       LS_64(cqp->struct_ver, I40IW_CQPHC_SVER);

	set_64bit_val(cqp->host_ctx, 0, temp);
	set_64bit_val(cqp->host_ctx, 8, cqp->sq_pa);
	temp = LS_64(cqp->enabled_vf_count, I40IW_CQPHC_ENABLED_VFS) |
	       LS_64(cqp->hmc_profile, I40IW_CQPHC_HMC_PROFILE);
	set_64bit_val(cqp->host_ctx, 16, temp);
	set_64bit_val(cqp->host_ctx, 24, (uintptr_t)cqp);
	set_64bit_val(cqp->host_ctx, 32, 0);
	set_64bit_val(cqp->host_ctx, 40, 0);
	set_64bit_val(cqp->host_ctx, 48, 0);
	set_64bit_val(cqp->host_ctx, 56, 0);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CQP_HOST_CTX",
			cqp->host_ctx, I40IW_CQP_CTX_SIZE * 8);

	p1 = RS_32_1(cqp->host_ctx_pa, 32);
	p2 = (u32)cqp->host_ctx_pa;

	if (cqp->dev->is_pf) {
		i40iw_wr32(cqp->dev->hw, I40E_PFPE_CCQPHIGH, p1);
		i40iw_wr32(cqp->dev->hw, I40E_PFPE_CCQPLOW, p2);
	} else {
		i40iw_wr32(cqp->dev->hw, I40E_VFPE_CCQPHIGH1, p1);
		i40iw_wr32(cqp->dev->hw, I40E_VFPE_CCQPLOW1, p2);
	}
	do {
		if (cnt++ > I40IW_DONE_COUNT) {
			i40iw_free_dma_mem(cqp->dev->hw, &cqp->sdbuf);
			ret_code = I40IW_ERR_TIMEOUT;
			/*
			 * read PFPE_CQPERRORCODES register to get the minor
			 * and major error code
			 */
			if (cqp->dev->is_pf)
				err_code = i40iw_rd32(cqp->dev->hw, I40E_PFPE_CQPERRCODES);
			else
				err_code = i40iw_rd32(cqp->dev->hw, I40E_VFPE_CQPERRCODES1);
			*min_err = RS_32(err_code, I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE);
			*maj_err = RS_32(err_code, I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE);
			goto exit;
		}
		udelay(I40IW_SLEEP_COUNT);
		if (cqp->dev->is_pf)
			val = i40iw_rd32(cqp->dev->hw, I40E_PFPE_CCQPSTATUS);
		else
			val = i40iw_rd32(cqp->dev->hw, I40E_VFPE_CCQPSTATUS1);
	} while (!val);

exit:
	if (!ret_code)
		cqp->process_cqp_sds = i40iw_update_sds_noccq;
	return ret_code;
}

/**
 * i40iw_sc_cqp_post_sq - post of cqp's sq
 * @cqp: struct for cqp hw
 */
void i40iw_sc_cqp_post_sq(struct i40iw_sc_cqp *cqp)
{
	if (cqp->dev->is_pf)
		i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPDB, I40IW_RING_GETCURRENT_HEAD(cqp->sq_ring));
	else
		i40iw_wr32(cqp->dev->hw, I40E_VFPE_CQPDB1, I40IW_RING_GETCURRENT_HEAD(cqp->sq_ring));

	i40iw_debug(cqp->dev,
		    I40IW_DEBUG_WQE,
		    "%s: HEAD_TAIL[%04d,%04d,%04d]\n",
		    __func__,
		    cqp->sq_ring.head,
		    cqp->sq_ring.tail,
		    cqp->sq_ring.size);
}

/**
 * i40iw_sc_cqp_get_next_send_wqe_idx - get next WQE on CQP SQ and pass back the index
 * @cqp: pointer to CQP structure
 * @scratch: private data for CQP WQE
 * @wqe_idx: WQE index for next WQE on CQP SQ
 */
static u64 *i40iw_sc_cqp_get_next_send_wqe_idx(struct i40iw_sc_cqp *cqp,
					       u64 scratch, u32 *wqe_idx)
{
	u64 *wqe = NULL;
	enum i40iw_status_code ret_code;

	if (I40IW_RING_FULL_ERR(cqp->sq_ring)) {
		i40iw_debug(cqp->dev,
			    I40IW_DEBUG_WQE,
			    "%s: ring is full head %x tail %x size %x\n",
			    __func__,
			    cqp->sq_ring.head,
			    cqp->sq_ring.tail,
			    cqp->sq_ring.size);
		return NULL;
	}
	I40IW_ATOMIC_RING_MOVE_HEAD(cqp->sq_ring, *wqe_idx, ret_code);
	cqp->dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS]++;
	if (ret_code)
		return NULL;
	if (!*wqe_idx)
		cqp->polarity = !cqp->polarity;

	wqe = cqp->sq_base[*wqe_idx].elem;
	cqp->scratch_array[*wqe_idx] = scratch;
	I40IW_CQP_INIT_WQE(wqe);

	return wqe;
}

/**
 * i40iw_sc_cqp_get_next_send_wqe - get next wqe on cqp sq
 * @cqp: struct for cqp hw
 * @scratch: private data for CQP WQE
 */
u64 *i40iw_sc_cqp_get_next_send_wqe(struct i40iw_sc_cqp *cqp, u64 scratch)
{
	u32 wqe_idx;

	return i40iw_sc_cqp_get_next_send_wqe_idx(cqp, scratch, &wqe_idx);
}

/**
 * i40iw_sc_cqp_destroy - destroy cqp during close
 * @cqp: struct for cqp hw
 */
static enum i40iw_status_code i40iw_sc_cqp_destroy(struct i40iw_sc_cqp *cqp)
{
	u32 cnt = 0, val = 1;
	enum i40iw_status_code ret_code = 0;
	u32 cqpstat_addr;

	if (cqp->dev->is_pf) {
		i40iw_wr32(cqp->dev->hw, I40E_PFPE_CCQPHIGH, 0);
		i40iw_wr32(cqp->dev->hw, I40E_PFPE_CCQPLOW, 0);
		cqpstat_addr = I40E_PFPE_CCQPSTATUS;
	} else {
		i40iw_wr32(cqp->dev->hw, I40E_VFPE_CCQPHIGH1, 0);
		i40iw_wr32(cqp->dev->hw, I40E_VFPE_CCQPLOW1, 0);
		cqpstat_addr = I40E_VFPE_CCQPSTATUS1;
	}
	do {
		if (cnt++ > I40IW_DONE_COUNT) {
			ret_code = I40IW_ERR_TIMEOUT;
			break;
		}
		udelay(I40IW_SLEEP_COUNT);
		val = i40iw_rd32(cqp->dev->hw, cqpstat_addr);
	} while (val);

	i40iw_free_dma_mem(cqp->dev->hw, &cqp->sdbuf);
	return ret_code;
}

/**
 * i40iw_sc_ccq_arm - enable intr for control cq
 * @ccq: ccq sc struct
 */
static void i40iw_sc_ccq_arm(struct i40iw_sc_cq *ccq)
{
	u64 temp_val;
	u16 sw_cq_sel;
	u8 arm_next_se;
	u8 arm_seq_num;

	/* write to cq doorbell shadow area */
	/* arm next se should always be zero */
	get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val);

	sw_cq_sel = (u16)RS_64(temp_val, I40IW_CQ_DBSA_SW_CQ_SELECT);
	arm_next_se = (u8)RS_64(temp_val, I40IW_CQ_DBSA_ARM_NEXT_SE);

	arm_seq_num = (u8)RS_64(temp_val, I40IW_CQ_DBSA_ARM_SEQ_NUM);
	arm_seq_num++;

	temp_val = LS_64(arm_seq_num, I40IW_CQ_DBSA_ARM_SEQ_NUM) |
		   LS_64(sw_cq_sel, I40IW_CQ_DBSA_SW_CQ_SELECT) |
		   LS_64(arm_next_se, I40IW_CQ_DBSA_ARM_NEXT_SE) |
		   LS_64(1, I40IW_CQ_DBSA_ARM_NEXT);

	set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val);

	wmb();       /* make sure shadow area is updated before arming */

	if (ccq->dev->is_pf)
		i40iw_wr32(ccq->dev->hw, I40E_PFPE_CQARM, ccq->cq_uk.cq_id);
	else
		i40iw_wr32(ccq->dev->hw, I40E_VFPE_CQARM1, ccq->cq_uk.cq_id);
}

/**
 * i40iw_sc_ccq_get_cqe_info - get ccq's cq entry
 * @ccq: ccq sc struct
 * @info: completion q entry to return
 */
static enum i40iw_status_code i40iw_sc_ccq_get_cqe_info(
					struct i40iw_sc_cq *ccq,
					struct i40iw_ccq_cqe_info *info)
{
	u64 qp_ctx, temp, temp1;
	u64 *cqe;
	struct i40iw_sc_cqp *cqp;
	u32 wqe_idx;
	u8 polarity;
	enum i40iw_status_code ret_code = 0;

	if (ccq->cq_uk.avoid_mem_cflct)
		cqe = (u64 *)I40IW_GET_CURRENT_EXTENDED_CQ_ELEMENT(&ccq->cq_uk);
	else
		cqe = (u64 *)I40IW_GET_CURRENT_CQ_ELEMENT(&ccq->cq_uk);

	get_64bit_val(cqe, 24, &temp);
	polarity = (u8)RS_64(temp, I40IW_CQ_VALID);
	if (polarity != ccq->cq_uk.polarity)
		return I40IW_ERR_QUEUE_EMPTY;

	get_64bit_val(cqe, 8, &qp_ctx);
	cqp = (struct i40iw_sc_cqp *)(unsigned long)qp_ctx;
	info->error = (bool)RS_64(temp, I40IW_CQ_ERROR);
	info->min_err_code = (u16)RS_64(temp, I40IW_CQ_MINERR);
	if (info->error) {
		info->maj_err_code = (u16)RS_64(temp, I40IW_CQ_MAJERR);
		info->min_err_code = (u16)RS_64(temp, I40IW_CQ_MINERR);
	}
	wqe_idx = (u32)RS_64(temp, I40IW_CQ_WQEIDX);
	info->scratch = cqp->scratch_array[wqe_idx];

	get_64bit_val(cqe, 16, &temp1);
	info->op_ret_val = (u32)RS_64(temp1, I40IW_CCQ_OPRETVAL);
	get_64bit_val(cqp->sq_base[wqe_idx].elem, 24, &temp1);
	info->op_code = (u8)RS_64(temp1, I40IW_CQPSQ_OPCODE);
	info->cqp = cqp;

	/*  move the head for cq */
	I40IW_RING_MOVE_HEAD(ccq->cq_uk.cq_ring, ret_code);
	if (I40IW_RING_GETCURRENT_HEAD(ccq->cq_uk.cq_ring) == 0)
		ccq->cq_uk.polarity ^= 1;

	/* update cq tail in cq shadow memory also */
	I40IW_RING_MOVE_TAIL(ccq->cq_uk.cq_ring);
	set_64bit_val(ccq->cq_uk.shadow_area,
		      0,
		      I40IW_RING_GETCURRENT_HEAD(ccq->cq_uk.cq_ring));
	wmb(); /* write shadow area before tail */
	I40IW_RING_MOVE_TAIL(cqp->sq_ring);
	ccq->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]++;

	return ret_code;
}

/**
 * i40iw_sc_poll_for_cqp_op_done - Waits for last write to complete in CQP SQ
 * @cqp: struct for cqp hw
 * @op_code: cqp opcode for completion
 * @compl_info: completion q entry to return
 */
static enum i40iw_status_code i40iw_sc_poll_for_cqp_op_done(
					struct i40iw_sc_cqp *cqp,
					u8 op_code,
					struct i40iw_ccq_cqe_info *compl_info)
{
	struct i40iw_ccq_cqe_info info;
	struct i40iw_sc_cq *ccq;
	enum i40iw_status_code ret_code = 0;
	u32 cnt = 0;

	memset(&info, 0, sizeof(info));
	ccq = cqp->dev->ccq;
	while (1) {
		if (cnt++ > I40IW_DONE_COUNT)
			return I40IW_ERR_TIMEOUT;

		if (i40iw_sc_ccq_get_cqe_info(ccq, &info)) {
			udelay(I40IW_SLEEP_COUNT);
			continue;
		}

		if (info.error) {
			ret_code = I40IW_ERR_CQP_COMPL_ERROR;
			break;
		}
		/* check if opcode is cq create */
		if (op_code != info.op_code) {
			i40iw_debug(cqp->dev, I40IW_DEBUG_WQE,
				    "%s: opcode mismatch for my op code 0x%x, returned opcode %x\n",
				    __func__, op_code, info.op_code);
		}
		/* success, exit out of the loop */
		if (op_code == info.op_code)
			break;
	}

	if (compl_info)
		memcpy(compl_info, &info, sizeof(*compl_info));

	return ret_code;
}

/**
 * i40iw_sc_manage_hmc_pm_func_table - manage of function table
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @vf_index: vf index for cqp
 * @free_pm_fcn: function number
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_manage_hmc_pm_func_table(
				struct i40iw_sc_cqp *cqp,
				u64 scratch,
				u8 vf_index,
				bool free_pm_fcn,
				bool post_sq)
{
	u64 *wqe;
	u64 header;

	if (vf_index >= I40IW_MAX_VF_PER_PF)
		return I40IW_ERR_INVALID_VF_ID;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	header = LS_64(vf_index, I40IW_CQPSQ_MHMC_VFIDX) |
		 LS_64(I40IW_CQP_OP_MANAGE_HMC_PM_FUNC_TABLE, I40IW_CQPSQ_OPCODE) |
		 LS_64(free_pm_fcn, I40IW_CQPSQ_MHMC_FREEPMFN) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "MANAGE_HMC_PM_FUNC_TABLE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);
	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_set_hmc_resource_profile - cqp wqe for hmc profile
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @hmc_profile_type: type of profile to set
 * @vf_num: vf number for profile
 * @post_sq: flag for cqp db to ring
 * @poll_registers: flag to poll register for cqp completion
 */
static enum i40iw_status_code i40iw_sc_set_hmc_resource_profile(
				struct i40iw_sc_cqp *cqp,
				u64 scratch,
				u8 hmc_profile_type,
				u8 vf_num, bool post_sq,
				bool poll_registers)
{
	u64 *wqe;
	u64 header;
	u32 val, tail, error;
	enum i40iw_status_code ret_code = 0;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 16,
		      (LS_64(hmc_profile_type, I40IW_CQPSQ_SHMCRP_HMC_PROFILE) |
				LS_64(vf_num, I40IW_CQPSQ_SHMCRP_VFNUM)));

	header = LS_64(I40IW_CQP_OP_SET_HMC_RESOURCE_PROFILE, I40IW_CQPSQ_OPCODE) |
		       LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "MANAGE_HMC_PM_FUNC_TABLE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	i40iw_get_cqp_reg_info(cqp, &val, &tail, &error);
	if (error)
		return I40IW_ERR_CQP_COMPL_ERROR;

	if (post_sq) {
		i40iw_sc_cqp_post_sq(cqp);
		if (poll_registers)
			ret_code = i40iw_cqp_poll_registers(cqp, tail, 1000000);
		else
			ret_code = i40iw_sc_poll_for_cqp_op_done(cqp,
								 I40IW_CQP_OP_SHMC_PAGES_ALLOCATED,
								 NULL);
	}

	return ret_code;
}

/**
 * i40iw_sc_manage_hmc_pm_func_table_done - wait for cqp wqe completion for function table
 * @cqp: struct for cqp hw
 */
static enum i40iw_status_code i40iw_sc_manage_hmc_pm_func_table_done(struct i40iw_sc_cqp *cqp)
{
	return i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_MANAGE_HMC_PM_FUNC_TABLE, NULL);
}

/**
 * i40iw_sc_commit_fpm_values_done - wait for cqp eqe completion for fpm commit
 * @cqp: struct for cqp hw
 */
static enum i40iw_status_code i40iw_sc_commit_fpm_values_done(struct i40iw_sc_cqp *cqp)
{
	return i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_COMMIT_FPM_VALUES, NULL);
}

/**
 * i40iw_sc_commit_fpm_values - cqp wqe for commit fpm values
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @hmc_fn_id: hmc function id
 * @commit_fpm_mem: Memory for fpm values
 * @post_sq: flag for cqp db to ring
 * @wait_type: poll ccq or cqp registers for cqp completion
 */
static enum i40iw_status_code i40iw_sc_commit_fpm_values(
					struct i40iw_sc_cqp *cqp,
					u64 scratch,
					u8 hmc_fn_id,
					struct i40iw_dma_mem *commit_fpm_mem,
					bool post_sq,
					u8 wait_type)
{
	u64 *wqe;
	u64 header;
	u32 tail, val, error;
	enum i40iw_status_code ret_code = 0;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 16, hmc_fn_id);
	set_64bit_val(wqe, 32, commit_fpm_mem->pa);

	header = LS_64(I40IW_CQP_OP_COMMIT_FPM_VALUES, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "COMMIT_FPM_VALUES WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	i40iw_get_cqp_reg_info(cqp, &val, &tail, &error);
	if (error)
		return I40IW_ERR_CQP_COMPL_ERROR;

	if (post_sq) {
		i40iw_sc_cqp_post_sq(cqp);

		if (wait_type == I40IW_CQP_WAIT_POLL_REGS)
			ret_code = i40iw_cqp_poll_registers(cqp, tail, I40IW_DONE_COUNT);
		else if (wait_type == I40IW_CQP_WAIT_POLL_CQ)
			ret_code = i40iw_sc_commit_fpm_values_done(cqp);
	}

	return ret_code;
}

/**
 * i40iw_sc_query_rdma_features_done - poll cqp for query features done
 * @cqp: struct for cqp hw
 */
static enum i40iw_status_code
i40iw_sc_query_rdma_features_done(struct i40iw_sc_cqp *cqp)
{
	return i40iw_sc_poll_for_cqp_op_done(
		cqp, I40IW_CQP_OP_QUERY_RDMA_FEATURES, NULL);
}

/**
 * i40iw_sc_query_rdma_features - query rdma features
 * @cqp: struct for cqp hw
 * @feat_mem: holds PA for HW to use
 * @scratch: u64 saved to be used during cqp completion
 */
static enum i40iw_status_code
i40iw_sc_query_rdma_features(struct i40iw_sc_cqp *cqp,
			     struct i40iw_dma_mem *feat_mem, u64 scratch)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 32, feat_mem->pa);

	header = LS_64(I40IW_CQP_OP_QUERY_RDMA_FEATURES, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID) | feat_mem->size;

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QUERY RDMA FEATURES WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	i40iw_sc_cqp_post_sq(cqp);

	return 0;
}

/**
 * i40iw_get_rdma_features - get RDMA features
 * @dev: sc device struct
 */
enum i40iw_status_code i40iw_get_rdma_features(struct i40iw_sc_dev *dev)
{
	enum i40iw_status_code ret_code;
	struct i40iw_dma_mem feat_buf;
	u64 temp;
	u16 byte_idx, feat_type, feat_cnt;

	ret_code = i40iw_allocate_dma_mem(dev->hw, &feat_buf,
					  I40IW_FEATURE_BUF_SIZE,
					  I40IW_FEATURE_BUF_ALIGNMENT);

	if (ret_code)
		return I40IW_ERR_NO_MEMORY;

	ret_code = i40iw_sc_query_rdma_features(dev->cqp, &feat_buf, 0);
	if (!ret_code)
		ret_code = i40iw_sc_query_rdma_features_done(dev->cqp);

	if (ret_code)
		goto exit;

	get_64bit_val(feat_buf.va, 0, &temp);
	feat_cnt = RS_64(temp, I40IW_FEATURE_CNT);
	if (feat_cnt < I40IW_MAX_FEATURES) {
		ret_code = I40IW_ERR_INVALID_FEAT_CNT;
		goto exit;
	} else if (feat_cnt > I40IW_MAX_FEATURES) {
		i40iw_debug(dev, I40IW_DEBUG_CQP,
			    "features buf size insufficient\n");
	}

	for (byte_idx = 0, feat_type = 0; feat_type < I40IW_MAX_FEATURES;
	     feat_type++, byte_idx += 8) {
		get_64bit_val((u64 *)feat_buf.va, byte_idx, &temp);
		dev->feature_info[feat_type] = RS_64(temp, I40IW_FEATURE_INFO);
	}
exit:
	i40iw_free_dma_mem(dev->hw, &feat_buf);

	return ret_code;
}

/**
 * i40iw_sc_query_fpm_values_done - poll for cqp wqe completion for query fpm
 * @cqp: struct for cqp hw
 */
static enum i40iw_status_code i40iw_sc_query_fpm_values_done(struct i40iw_sc_cqp *cqp)
{
	return i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_QUERY_FPM_VALUES, NULL);
}

/**
 * i40iw_sc_query_fpm_values - cqp wqe query fpm values
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @hmc_fn_id: hmc function id
 * @query_fpm_mem: memory for return fpm values
 * @post_sq: flag for cqp db to ring
 * @wait_type: poll ccq or cqp registers for cqp completion
 */
static enum i40iw_status_code i40iw_sc_query_fpm_values(
					struct i40iw_sc_cqp *cqp,
					u64 scratch,
					u8 hmc_fn_id,
					struct i40iw_dma_mem *query_fpm_mem,
					bool post_sq,
					u8 wait_type)
{
	u64 *wqe;
	u64 header;
	u32 tail, val, error;
	enum i40iw_status_code ret_code = 0;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 16, hmc_fn_id);
	set_64bit_val(wqe, 32, query_fpm_mem->pa);

	header = LS_64(I40IW_CQP_OP_QUERY_FPM_VALUES, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QUERY_FPM WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	/* read the tail from CQP_TAIL register */
	i40iw_get_cqp_reg_info(cqp, &val, &tail, &error);

	if (error)
		return I40IW_ERR_CQP_COMPL_ERROR;

	if (post_sq) {
		i40iw_sc_cqp_post_sq(cqp);
		if (wait_type == I40IW_CQP_WAIT_POLL_REGS)
			ret_code = i40iw_cqp_poll_registers(cqp, tail, I40IW_DONE_COUNT);
		else if (wait_type == I40IW_CQP_WAIT_POLL_CQ)
			ret_code = i40iw_sc_query_fpm_values_done(cqp);
	}

	return ret_code;
}

/**
 * i40iw_sc_add_arp_cache_entry - cqp wqe add arp cache entry
 * @cqp: struct for cqp hw
 * @info: arp entry information
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_add_arp_cache_entry(
				struct i40iw_sc_cqp *cqp,
				struct i40iw_add_arp_cache_entry_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 *wqe;
	u64 temp, header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 8, info->reach_max);

	temp = info->mac_addr[5] |
	       LS_64_1(info->mac_addr[4], 8) |
	       LS_64_1(info->mac_addr[3], 16) |
	       LS_64_1(info->mac_addr[2], 24) |
	       LS_64_1(info->mac_addr[1], 32) |
	       LS_64_1(info->mac_addr[0], 40);

	set_64bit_val(wqe, 16, temp);

	header = info->arp_index |
		 LS_64(I40IW_CQP_OP_MANAGE_ARP, I40IW_CQPSQ_OPCODE) |
		 LS_64((info->permanent ? 1 : 0), I40IW_CQPSQ_MAT_PERMANENT) |
		 LS_64(1, I40IW_CQPSQ_MAT_ENTRYVALID) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "ARP_CACHE_ENTRY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_del_arp_cache_entry - dele arp cache entry
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @arp_index: arp index to delete arp entry
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_del_arp_cache_entry(
					struct i40iw_sc_cqp *cqp,
					u64 scratch,
					u16 arp_index,
					bool post_sq)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	header = arp_index |
		 LS_64(I40IW_CQP_OP_MANAGE_ARP, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "ARP_CACHE_DEL_ENTRY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_query_arp_cache_entry - cqp wqe to query arp and arp index
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @arp_index: arp index to delete arp entry
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_query_arp_cache_entry(
				struct i40iw_sc_cqp *cqp,
				u64 scratch,
				u16 arp_index,
				bool post_sq)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	header = arp_index |
		 LS_64(I40IW_CQP_OP_MANAGE_ARP, I40IW_CQPSQ_OPCODE) |
		 LS_64(1, I40IW_CQPSQ_MAT_QUERY) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QUERY_ARP_CACHE_ENTRY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_manage_apbvt_entry - for adding and deleting apbvt entries
 * @cqp: struct for cqp hw
 * @info: info for apbvt entry to add or delete
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_manage_apbvt_entry(
				struct i40iw_sc_cqp *cqp,
				struct i40iw_apbvt_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 16, info->port);

	header = LS_64(I40IW_CQP_OP_MANAGE_APBVT, I40IW_CQPSQ_OPCODE) |
		 LS_64(info->add, I40IW_CQPSQ_MAPT_ADDPORT) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "MANAGE_APBVT WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_manage_qhash_table_entry - manage quad hash entries
 * @cqp: struct for cqp hw
 * @info: info for quad hash to manage
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 *
 * This is called before connection establishment is started. For passive connections, when
 * listener is created, it will call with entry type of  I40IW_QHASH_TYPE_TCP_SYN with local
 * ip address and tcp port. When SYN is received (passive connections) or
 * sent (active connections), this routine is called with entry type of
 * I40IW_QHASH_TYPE_TCP_ESTABLISHED and quad is passed in info.
 *
 * When iwarp connection is done and its state moves to RTS, the quad hash entry in
 * the hardware will point to iwarp's qp number and requires no calls from the driver.
 */
static enum i40iw_status_code i40iw_sc_manage_qhash_table_entry(
					struct i40iw_sc_cqp *cqp,
					struct i40iw_qhash_table_info *info,
					u64 scratch,
					bool post_sq)
{
	u64 *wqe;
	u64 qw1 = 0;
	u64 qw2 = 0;
	u64 temp;
	struct i40iw_sc_vsi *vsi = info->vsi;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	temp = info->mac_addr[5] |
		LS_64_1(info->mac_addr[4], 8) |
		LS_64_1(info->mac_addr[3], 16) |
		LS_64_1(info->mac_addr[2], 24) |
		LS_64_1(info->mac_addr[1], 32) |
		LS_64_1(info->mac_addr[0], 40);

	set_64bit_val(wqe, 0, temp);

	qw1 = LS_64(info->qp_num, I40IW_CQPSQ_QHASH_QPN) |
	      LS_64(info->dest_port, I40IW_CQPSQ_QHASH_DEST_PORT);
	if (info->ipv4_valid) {
		set_64bit_val(wqe,
			      48,
			      LS_64(info->dest_ip[0], I40IW_CQPSQ_QHASH_ADDR3));
	} else {
		set_64bit_val(wqe,
			      56,
			      LS_64(info->dest_ip[0], I40IW_CQPSQ_QHASH_ADDR0) |
			      LS_64(info->dest_ip[1], I40IW_CQPSQ_QHASH_ADDR1));

		set_64bit_val(wqe,
			      48,
			      LS_64(info->dest_ip[2], I40IW_CQPSQ_QHASH_ADDR2) |
			      LS_64(info->dest_ip[3], I40IW_CQPSQ_QHASH_ADDR3));
	}
	qw2 = LS_64(vsi->qos[info->user_pri].qs_handle, I40IW_CQPSQ_QHASH_QS_HANDLE);
	if (info->vlan_valid)
		qw2 |= LS_64(info->vlan_id, I40IW_CQPSQ_QHASH_VLANID);
	set_64bit_val(wqe, 16, qw2);
	if (info->entry_type == I40IW_QHASH_TYPE_TCP_ESTABLISHED) {
		qw1 |= LS_64(info->src_port, I40IW_CQPSQ_QHASH_SRC_PORT);
		if (!info->ipv4_valid) {
			set_64bit_val(wqe,
				      40,
				      LS_64(info->src_ip[0], I40IW_CQPSQ_QHASH_ADDR0) |
				      LS_64(info->src_ip[1], I40IW_CQPSQ_QHASH_ADDR1));
			set_64bit_val(wqe,
				      32,
				      LS_64(info->src_ip[2], I40IW_CQPSQ_QHASH_ADDR2) |
				      LS_64(info->src_ip[3], I40IW_CQPSQ_QHASH_ADDR3));
		} else {
			set_64bit_val(wqe,
				      32,
				      LS_64(info->src_ip[0], I40IW_CQPSQ_QHASH_ADDR3));
		}
	}

	set_64bit_val(wqe, 8, qw1);
	temp = LS_64(cqp->polarity, I40IW_CQPSQ_QHASH_WQEVALID) |
	       LS_64(I40IW_CQP_OP_MANAGE_QUAD_HASH_TABLE_ENTRY, I40IW_CQPSQ_QHASH_OPCODE) |
	       LS_64(info->manage, I40IW_CQPSQ_QHASH_MANAGE) |
	       LS_64(info->ipv4_valid, I40IW_CQPSQ_QHASH_IPV4VALID) |
	       LS_64(info->vlan_valid, I40IW_CQPSQ_QHASH_VLANVALID) |
	       LS_64(info->entry_type, I40IW_CQPSQ_QHASH_ENTRYTYPE);

	i40iw_insert_wqe_hdr(wqe, temp);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "MANAGE_QHASH WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_alloc_local_mac_ipaddr_entry - cqp wqe for loc mac entry
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_alloc_local_mac_ipaddr_entry(
					struct i40iw_sc_cqp *cqp,
					u64 scratch,
					bool post_sq)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	header = LS_64(I40IW_CQP_OP_ALLOCATE_LOC_MAC_IP_TABLE_ENTRY, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "ALLOCATE_LOCAL_MAC_IPADDR WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);
	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_add_local_mac_ipaddr_entry - add mac enry
 * @cqp: struct for cqp hw
 * @info:mac addr info
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_add_local_mac_ipaddr_entry(
				struct i40iw_sc_cqp *cqp,
				struct i40iw_local_mac_ipaddr_entry_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 *wqe;
	u64 temp, header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	temp = info->mac_addr[5] |
		LS_64_1(info->mac_addr[4], 8) |
		LS_64_1(info->mac_addr[3], 16) |
		LS_64_1(info->mac_addr[2], 24) |
		LS_64_1(info->mac_addr[1], 32) |
		LS_64_1(info->mac_addr[0], 40);

	set_64bit_val(wqe, 32, temp);

	header = LS_64(info->entry_idx, I40IW_CQPSQ_MLIPA_IPTABLEIDX) |
		 LS_64(I40IW_CQP_OP_MANAGE_LOC_MAC_IP_TABLE, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "ADD_LOCAL_MAC_IPADDR WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_del_local_mac_ipaddr_entry - cqp wqe to dele local mac
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @entry_idx: index of mac entry
 * @ignore_ref_count: to force mac adde delete
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_del_local_mac_ipaddr_entry(
				struct i40iw_sc_cqp *cqp,
				u64 scratch,
				u8 entry_idx,
				u8 ignore_ref_count,
				bool post_sq)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	header = LS_64(entry_idx, I40IW_CQPSQ_MLIPA_IPTABLEIDX) |
		 LS_64(I40IW_CQP_OP_MANAGE_LOC_MAC_IP_TABLE, I40IW_CQPSQ_OPCODE) |
		 LS_64(1, I40IW_CQPSQ_MLIPA_FREEENTRY) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID) |
		 LS_64(ignore_ref_count, I40IW_CQPSQ_MLIPA_IGNORE_REF_CNT);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "DEL_LOCAL_MAC_IPADDR WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_cqp_nop - send a nop wqe
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_cqp_nop(struct i40iw_sc_cqp *cqp,
					       u64 scratch,
					       bool post_sq)
{
	u64 *wqe;
	u64 header;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	header = LS_64(I40IW_CQP_OP_NOP, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "NOP WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_ceq_init - initialize ceq
 * @ceq: ceq sc structure
 * @info: ceq initialization info
 */
static enum i40iw_status_code i40iw_sc_ceq_init(struct i40iw_sc_ceq *ceq,
						struct i40iw_ceq_init_info *info)
{
	u32 pble_obj_cnt;

	if ((info->elem_cnt < I40IW_MIN_CEQ_ENTRIES) ||
	    (info->elem_cnt > I40IW_MAX_CEQ_ENTRIES))
		return I40IW_ERR_INVALID_SIZE;

	if (info->ceq_id >= I40IW_MAX_CEQID)
		return I40IW_ERR_INVALID_CEQ_ID;

	pble_obj_cnt = info->dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if (info->virtual_map && (info->first_pm_pbl_idx >= pble_obj_cnt))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	ceq->size = sizeof(*ceq);
	ceq->ceqe_base = (struct i40iw_ceqe *)info->ceqe_base;
	ceq->ceq_id = info->ceq_id;
	ceq->dev = info->dev;
	ceq->elem_cnt = info->elem_cnt;
	ceq->ceq_elem_pa = info->ceqe_pa;
	ceq->virtual_map = info->virtual_map;

	ceq->pbl_chunk_size = (ceq->virtual_map ? info->pbl_chunk_size : 0);
	ceq->first_pm_pbl_idx = (ceq->virtual_map ? info->first_pm_pbl_idx : 0);
	ceq->pbl_list = (ceq->virtual_map ? info->pbl_list : NULL);

	ceq->tph_en = info->tph_en;
	ceq->tph_val = info->tph_val;
	ceq->polarity = 1;
	I40IW_RING_INIT(ceq->ceq_ring, ceq->elem_cnt);
	ceq->dev->ceq[info->ceq_id] = ceq;

	return 0;
}

/**
 * i40iw_sc_ceq_create - create ceq wqe
 * @ceq: ceq sc structure
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_ceq_create(struct i40iw_sc_ceq *ceq,
						  u64 scratch,
						  bool post_sq)
{
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;
	u64 header;

	cqp = ceq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 16, ceq->elem_cnt);
	set_64bit_val(wqe, 32, (ceq->virtual_map ? 0 : ceq->ceq_elem_pa));
	set_64bit_val(wqe, 48, (ceq->virtual_map ? ceq->first_pm_pbl_idx : 0));
	set_64bit_val(wqe, 56, LS_64(ceq->tph_val, I40IW_CQPSQ_TPHVAL));

	header = ceq->ceq_id |
		 LS_64(I40IW_CQP_OP_CREATE_CEQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(ceq->pbl_chunk_size, I40IW_CQPSQ_CEQ_LPBLSIZE) |
		 LS_64(ceq->virtual_map, I40IW_CQPSQ_CEQ_VMAP) |
		 LS_64(ceq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CEQ_CREATE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_cceq_create_done - poll for control ceq wqe to complete
 * @ceq: ceq sc structure
 */
static enum i40iw_status_code i40iw_sc_cceq_create_done(struct i40iw_sc_ceq *ceq)
{
	struct i40iw_sc_cqp *cqp;

	cqp = ceq->dev->cqp;
	return i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_CREATE_CEQ, NULL);
}

/**
 * i40iw_sc_cceq_destroy_done - poll for destroy cceq to complete
 * @ceq: ceq sc structure
 */
static enum i40iw_status_code i40iw_sc_cceq_destroy_done(struct i40iw_sc_ceq *ceq)
{
	struct i40iw_sc_cqp *cqp;

	cqp = ceq->dev->cqp;
	cqp->process_cqp_sds = i40iw_update_sds_noccq;
	return i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_DESTROY_CEQ, NULL);
}

/**
 * i40iw_sc_cceq_create - create cceq
 * @ceq: ceq sc structure
 * @scratch: u64 saved to be used during cqp completion
 */
static enum i40iw_status_code i40iw_sc_cceq_create(struct i40iw_sc_ceq *ceq, u64 scratch)
{
	enum i40iw_status_code ret_code;

	ret_code = i40iw_sc_ceq_create(ceq, scratch, true);
	if (!ret_code)
		ret_code = i40iw_sc_cceq_create_done(ceq);
	return ret_code;
}

/**
 * i40iw_sc_ceq_destroy - destroy ceq
 * @ceq: ceq sc structure
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_ceq_destroy(struct i40iw_sc_ceq *ceq,
						   u64 scratch,
						   bool post_sq)
{
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;
	u64 header;

	cqp = ceq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 16, ceq->elem_cnt);
	set_64bit_val(wqe, 48, ceq->first_pm_pbl_idx);
	header = ceq->ceq_id |
		 LS_64(I40IW_CQP_OP_DESTROY_CEQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(ceq->pbl_chunk_size, I40IW_CQPSQ_CEQ_LPBLSIZE) |
		 LS_64(ceq->virtual_map, I40IW_CQPSQ_CEQ_VMAP) |
		 LS_64(ceq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CEQ_DESTROY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_process_ceq - process ceq
 * @dev: sc device struct
 * @ceq: ceq sc structure
 */
static void *i40iw_sc_process_ceq(struct i40iw_sc_dev *dev, struct i40iw_sc_ceq *ceq)
{
	u64 temp;
	u64 *ceqe;
	struct i40iw_sc_cq *cq = NULL;
	u8 polarity;

	ceqe = (u64 *)I40IW_GET_CURRENT_CEQ_ELEMENT(ceq);
	get_64bit_val(ceqe, 0, &temp);
	polarity = (u8)RS_64(temp, I40IW_CEQE_VALID);
	if (polarity != ceq->polarity)
		return cq;

	cq = (struct i40iw_sc_cq *)(unsigned long)LS_64_1(temp, 1);

	I40IW_RING_MOVE_TAIL(ceq->ceq_ring);
	if (I40IW_RING_GETCURRENT_TAIL(ceq->ceq_ring) == 0)
		ceq->polarity ^= 1;

	if (dev->is_pf)
		i40iw_wr32(dev->hw, I40E_PFPE_CQACK, cq->cq_uk.cq_id);
	else
		i40iw_wr32(dev->hw, I40E_VFPE_CQACK1, cq->cq_uk.cq_id);

	return cq;
}

/**
 * i40iw_sc_aeq_init - initialize aeq
 * @aeq: aeq structure ptr
 * @info: aeq initialization info
 */
static enum i40iw_status_code i40iw_sc_aeq_init(struct i40iw_sc_aeq *aeq,
						struct i40iw_aeq_init_info *info)
{
	u32 pble_obj_cnt;

	if ((info->elem_cnt < I40IW_MIN_AEQ_ENTRIES) ||
	    (info->elem_cnt > I40IW_MAX_AEQ_ENTRIES))
		return I40IW_ERR_INVALID_SIZE;
	pble_obj_cnt = info->dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if (info->virtual_map && (info->first_pm_pbl_idx >= pble_obj_cnt))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	aeq->size = sizeof(*aeq);
	aeq->polarity = 1;
	aeq->aeqe_base = (struct i40iw_sc_aeqe *)info->aeqe_base;
	aeq->dev = info->dev;
	aeq->elem_cnt = info->elem_cnt;

	aeq->aeq_elem_pa = info->aeq_elem_pa;
	I40IW_RING_INIT(aeq->aeq_ring, aeq->elem_cnt);
	info->dev->aeq = aeq;

	aeq->virtual_map = info->virtual_map;
	aeq->pbl_list = (aeq->virtual_map ? info->pbl_list : NULL);
	aeq->pbl_chunk_size = (aeq->virtual_map ? info->pbl_chunk_size : 0);
	aeq->first_pm_pbl_idx = (aeq->virtual_map ? info->first_pm_pbl_idx : 0);
	info->dev->aeq = aeq;
	return 0;
}

/**
 * i40iw_sc_aeq_create - create aeq
 * @aeq: aeq structure ptr
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_aeq_create(struct i40iw_sc_aeq *aeq,
						  u64 scratch,
						  bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;

	cqp = aeq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 16, aeq->elem_cnt);
	set_64bit_val(wqe, 32,
		      (aeq->virtual_map ? 0 : aeq->aeq_elem_pa));
	set_64bit_val(wqe, 48,
		      (aeq->virtual_map ? aeq->first_pm_pbl_idx : 0));

	header = LS_64(I40IW_CQP_OP_CREATE_AEQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(aeq->pbl_chunk_size, I40IW_CQPSQ_AEQ_LPBLSIZE) |
		 LS_64(aeq->virtual_map, I40IW_CQPSQ_AEQ_VMAP) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "AEQ_CREATE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);
	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_aeq_destroy - destroy aeq during close
 * @aeq: aeq structure ptr
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_aeq_destroy(struct i40iw_sc_aeq *aeq,
						   u64 scratch,
						   bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;

	cqp = aeq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 16, aeq->elem_cnt);
	set_64bit_val(wqe, 48, aeq->first_pm_pbl_idx);
	header = LS_64(I40IW_CQP_OP_DESTROY_AEQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(aeq->pbl_chunk_size, I40IW_CQPSQ_AEQ_LPBLSIZE) |
		 LS_64(aeq->virtual_map, I40IW_CQPSQ_AEQ_VMAP) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "AEQ_DESTROY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);
	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_get_next_aeqe - get next aeq entry
 * @aeq: aeq structure ptr
 * @info: aeqe info to be returned
 */
static enum i40iw_status_code i40iw_sc_get_next_aeqe(struct i40iw_sc_aeq *aeq,
						     struct i40iw_aeqe_info *info)
{
	u64 temp, compl_ctx;
	u64 *aeqe;
	u16 wqe_idx;
	u8 ae_src;
	u8 polarity;

	aeqe = (u64 *)I40IW_GET_CURRENT_AEQ_ELEMENT(aeq);
	get_64bit_val(aeqe, 0, &compl_ctx);
	get_64bit_val(aeqe, 8, &temp);
	polarity = (u8)RS_64(temp, I40IW_AEQE_VALID);

	if (aeq->polarity != polarity)
		return I40IW_ERR_QUEUE_EMPTY;

	i40iw_debug_buf(aeq->dev, I40IW_DEBUG_WQE, "AEQ_ENTRY", aeqe, 16);

	ae_src = (u8)RS_64(temp, I40IW_AEQE_AESRC);
	wqe_idx = (u16)RS_64(temp, I40IW_AEQE_WQDESCIDX);
	info->qp_cq_id = (u32)RS_64(temp, I40IW_AEQE_QPCQID);
	info->ae_id = (u16)RS_64(temp, I40IW_AEQE_AECODE);
	info->tcp_state = (u8)RS_64(temp, I40IW_AEQE_TCPSTATE);
	info->iwarp_state = (u8)RS_64(temp, I40IW_AEQE_IWSTATE);
	info->q2_data_written = (u8)RS_64(temp, I40IW_AEQE_Q2DATA);
	info->aeqe_overflow = (bool)RS_64(temp, I40IW_AEQE_OVERFLOW);

	switch (info->ae_id) {
	case I40IW_AE_PRIV_OPERATION_DENIED:
	case I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG:
	case I40IW_AE_UDA_XMIT_DGRAM_TOO_SHORT:
	case I40IW_AE_BAD_CLOSE:
	case I40IW_AE_RDMAP_ROE_BAD_LLP_CLOSE:
	case I40IW_AE_RDMA_READ_WHILE_ORD_ZERO:
	case I40IW_AE_STAG_ZERO_INVALID:
	case I40IW_AE_IB_RREQ_AND_Q1_FULL:
	case I40IW_AE_WQE_UNEXPECTED_OPCODE:
	case I40IW_AE_DDP_UBE_INVALID_DDP_VERSION:
	case I40IW_AE_DDP_UBE_INVALID_MO:
	case I40IW_AE_DDP_UBE_INVALID_QN:
	case I40IW_AE_DDP_NO_L_BIT:
	case I40IW_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
	case I40IW_AE_RDMAP_ROE_UNEXPECTED_OPCODE:
	case I40IW_AE_ROE_INVALID_RDMA_READ_REQUEST:
	case I40IW_AE_ROE_INVALID_RDMA_WRITE_OR_READ_RESP:
	case I40IW_AE_INVALID_ARP_ENTRY:
	case I40IW_AE_INVALID_TCP_OPTION_RCVD:
	case I40IW_AE_STALE_ARP_ENTRY:
	case I40IW_AE_LLP_CLOSE_COMPLETE:
	case I40IW_AE_LLP_CONNECTION_RESET:
	case I40IW_AE_LLP_FIN_RECEIVED:
	case I40IW_AE_LLP_RECEIVED_MPA_CRC_ERROR:
	case I40IW_AE_LLP_SEGMENT_TOO_SMALL:
	case I40IW_AE_LLP_SYN_RECEIVED:
	case I40IW_AE_LLP_TERMINATE_RECEIVED:
	case I40IW_AE_LLP_TOO_MANY_RETRIES:
	case I40IW_AE_LLP_DOUBT_REACHABILITY:
	case I40IW_AE_RESET_SENT:
	case I40IW_AE_TERMINATE_SENT:
	case I40IW_AE_RESET_NOT_SENT:
	case I40IW_AE_LCE_QP_CATASTROPHIC:
	case I40IW_AE_QP_SUSPEND_COMPLETE:
		info->qp = true;
		info->compl_ctx = compl_ctx;
		ae_src = I40IW_AE_SOURCE_RSVD;
		break;
	case I40IW_AE_LCE_CQ_CATASTROPHIC:
		info->cq = true;
		info->compl_ctx = LS_64_1(compl_ctx, 1);
		ae_src = I40IW_AE_SOURCE_RSVD;
		break;
	}

	switch (ae_src) {
	case I40IW_AE_SOURCE_RQ:
	case I40IW_AE_SOURCE_RQ_0011:
		info->qp = true;
		info->wqe_idx = wqe_idx;
		info->compl_ctx = compl_ctx;
		break;
	case I40IW_AE_SOURCE_CQ:
	case I40IW_AE_SOURCE_CQ_0110:
	case I40IW_AE_SOURCE_CQ_1010:
	case I40IW_AE_SOURCE_CQ_1110:
		info->cq = true;
		info->compl_ctx = LS_64_1(compl_ctx, 1);
		break;
	case I40IW_AE_SOURCE_SQ:
	case I40IW_AE_SOURCE_SQ_0111:
		info->qp = true;
		info->sq = true;
		info->wqe_idx = wqe_idx;
		info->compl_ctx = compl_ctx;
		break;
	case I40IW_AE_SOURCE_IN_RR_WR:
	case I40IW_AE_SOURCE_IN_RR_WR_1011:
		info->qp = true;
		info->compl_ctx = compl_ctx;
		info->in_rdrsp_wr = true;
		break;
	case I40IW_AE_SOURCE_OUT_RR:
	case I40IW_AE_SOURCE_OUT_RR_1111:
		info->qp = true;
		info->compl_ctx = compl_ctx;
		info->out_rdrsp = true;
		break;
	case I40IW_AE_SOURCE_RSVD:
	default:
		break;
	}
	I40IW_RING_MOVE_TAIL(aeq->aeq_ring);
	if (I40IW_RING_GETCURRENT_TAIL(aeq->aeq_ring) == 0)
		aeq->polarity ^= 1;
	return 0;
}

/**
 * i40iw_sc_repost_aeq_entries - repost completed aeq entries
 * @dev: sc device struct
 * @count: allocate count
 */
static enum i40iw_status_code i40iw_sc_repost_aeq_entries(struct i40iw_sc_dev *dev,
							  u32 count)
{

	if (dev->is_pf)
		i40iw_wr32(dev->hw, I40E_PFPE_AEQALLOC, count);
	else
		i40iw_wr32(dev->hw, I40E_VFPE_AEQALLOC1, count);

	return 0;
}

/**
 * i40iw_sc_aeq_create_done - create aeq
 * @aeq: aeq structure ptr
 */
static enum i40iw_status_code i40iw_sc_aeq_create_done(struct i40iw_sc_aeq *aeq)
{
	struct i40iw_sc_cqp *cqp;

	cqp = aeq->dev->cqp;
	return i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_CREATE_AEQ, NULL);
}

/**
 * i40iw_sc_aeq_destroy_done - destroy of aeq during close
 * @aeq: aeq structure ptr
 */
static enum i40iw_status_code i40iw_sc_aeq_destroy_done(struct i40iw_sc_aeq *aeq)
{
	struct i40iw_sc_cqp *cqp;

	cqp = aeq->dev->cqp;
	return  i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_DESTROY_AEQ, NULL);
}

/**
 * i40iw_sc_ccq_init - initialize control cq
 * @cq: sc's cq ctruct
 * @info: info for control cq initialization
 */
static enum i40iw_status_code i40iw_sc_ccq_init(struct i40iw_sc_cq *cq,
						struct i40iw_ccq_init_info *info)
{
	u32 pble_obj_cnt;

	if (info->num_elem < I40IW_MIN_CQ_SIZE || info->num_elem > I40IW_MAX_CQ_SIZE)
		return I40IW_ERR_INVALID_SIZE;

	if (info->ceq_id > I40IW_MAX_CEQID)
		return I40IW_ERR_INVALID_CEQ_ID;

	pble_obj_cnt = info->dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if (info->virtual_map && (info->first_pm_pbl_idx >= pble_obj_cnt))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	cq->cq_pa = info->cq_pa;
	cq->cq_uk.cq_base = info->cq_base;
	cq->shadow_area_pa = info->shadow_area_pa;
	cq->cq_uk.shadow_area = info->shadow_area;
	cq->shadow_read_threshold = info->shadow_read_threshold;
	cq->dev = info->dev;
	cq->ceq_id = info->ceq_id;
	cq->cq_uk.cq_size = info->num_elem;
	cq->cq_type = I40IW_CQ_TYPE_CQP;
	cq->ceqe_mask = info->ceqe_mask;
	I40IW_RING_INIT(cq->cq_uk.cq_ring, info->num_elem);

	cq->cq_uk.cq_id = 0;    /* control cq is id 0 always */
	cq->ceq_id_valid = info->ceq_id_valid;
	cq->tph_en = info->tph_en;
	cq->tph_val = info->tph_val;
	cq->cq_uk.avoid_mem_cflct = info->avoid_mem_cflct;

	cq->pbl_list = info->pbl_list;
	cq->virtual_map = info->virtual_map;
	cq->pbl_chunk_size = info->pbl_chunk_size;
	cq->first_pm_pbl_idx = info->first_pm_pbl_idx;
	cq->cq_uk.polarity = true;

	/* following are only for iw cqs so initialize them to zero */
	cq->cq_uk.cqe_alloc_reg = NULL;
	info->dev->ccq = cq;
	return 0;
}

/**
 * i40iw_sc_ccq_create_done - poll cqp for ccq create
 * @ccq: ccq sc struct
 */
static enum i40iw_status_code i40iw_sc_ccq_create_done(struct i40iw_sc_cq *ccq)
{
	struct i40iw_sc_cqp *cqp;

	cqp = ccq->dev->cqp;
	return	i40iw_sc_poll_for_cqp_op_done(cqp, I40IW_CQP_OP_CREATE_CQ, NULL);
}

/**
 * i40iw_sc_ccq_create - create control cq
 * @ccq: ccq sc struct
 * @scratch: u64 saved to be used during cqp completion
 * @check_overflow: overlow flag for ccq
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_ccq_create(struct i40iw_sc_cq *ccq,
						  u64 scratch,
						  bool check_overflow,
						  bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;
	enum i40iw_status_code ret_code;

	cqp = ccq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 0, ccq->cq_uk.cq_size);
	set_64bit_val(wqe, 8, RS_64_1(ccq, 1));
	set_64bit_val(wqe, 16,
		      LS_64(ccq->shadow_read_threshold, I40IW_CQPSQ_CQ_SHADOW_READ_THRESHOLD));
	set_64bit_val(wqe, 32, (ccq->virtual_map ? 0 : ccq->cq_pa));
	set_64bit_val(wqe, 40, ccq->shadow_area_pa);
	set_64bit_val(wqe, 48,
		      (ccq->virtual_map ? ccq->first_pm_pbl_idx : 0));
	set_64bit_val(wqe, 56,
		      LS_64(ccq->tph_val, I40IW_CQPSQ_TPHVAL));

	header = ccq->cq_uk.cq_id |
		 LS_64((ccq->ceq_id_valid ? ccq->ceq_id : 0), I40IW_CQPSQ_CQ_CEQID) |
		 LS_64(I40IW_CQP_OP_CREATE_CQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(ccq->pbl_chunk_size, I40IW_CQPSQ_CQ_LPBLSIZE) |
		 LS_64(check_overflow, I40IW_CQPSQ_CQ_CHKOVERFLOW) |
		 LS_64(ccq->virtual_map, I40IW_CQPSQ_CQ_VIRTMAP) |
		 LS_64(ccq->ceqe_mask, I40IW_CQPSQ_CQ_ENCEQEMASK) |
		 LS_64(ccq->ceq_id_valid, I40IW_CQPSQ_CQ_CEQIDVALID) |
		 LS_64(ccq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(ccq->cq_uk.avoid_mem_cflct, I40IW_CQPSQ_CQ_AVOIDMEMCNFLCT) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CCQ_CREATE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq) {
		i40iw_sc_cqp_post_sq(cqp);
		ret_code = i40iw_sc_ccq_create_done(ccq);
		if (ret_code)
			return ret_code;
	}
	cqp->process_cqp_sds = i40iw_cqp_sds_cmd;

	return 0;
}

/**
 * i40iw_sc_ccq_destroy - destroy ccq during close
 * @ccq: ccq sc struct
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_ccq_destroy(struct i40iw_sc_cq *ccq,
						   u64 scratch,
						   bool post_sq)
{
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;
	u64 header;
	enum i40iw_status_code ret_code = 0;
	u32 tail, val, error;

	cqp = ccq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 0, ccq->cq_uk.cq_size);
	set_64bit_val(wqe, 8, RS_64_1(ccq, 1));
	set_64bit_val(wqe, 40, ccq->shadow_area_pa);

	header = ccq->cq_uk.cq_id |
		 LS_64((ccq->ceq_id_valid ? ccq->ceq_id : 0), I40IW_CQPSQ_CQ_CEQID) |
		 LS_64(I40IW_CQP_OP_DESTROY_CQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(ccq->ceqe_mask, I40IW_CQPSQ_CQ_ENCEQEMASK) |
		 LS_64(ccq->ceq_id_valid, I40IW_CQPSQ_CQ_CEQIDVALID) |
		 LS_64(ccq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(ccq->cq_uk.avoid_mem_cflct, I40IW_CQPSQ_CQ_AVOIDMEMCNFLCT) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CCQ_DESTROY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	i40iw_get_cqp_reg_info(cqp, &val, &tail, &error);
	if (error)
		return I40IW_ERR_CQP_COMPL_ERROR;

	if (post_sq) {
		i40iw_sc_cqp_post_sq(cqp);
		ret_code = i40iw_cqp_poll_registers(cqp, tail, 1000);
	}

	cqp->process_cqp_sds = i40iw_update_sds_noccq;

	return ret_code;
}

/**
 * i40iw_sc_cq_init - initialize completion q
 * @cq: cq struct
 * @info: cq initialization info
 */
static enum i40iw_status_code i40iw_sc_cq_init(struct i40iw_sc_cq *cq,
					       struct i40iw_cq_init_info *info)
{
	u32 __iomem *cqe_alloc_reg = NULL;
	enum i40iw_status_code ret_code;
	u32 pble_obj_cnt;
	u32 arm_offset;

	pble_obj_cnt = info->dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if (info->virtual_map && (info->first_pm_pbl_idx >= pble_obj_cnt))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	cq->cq_pa = info->cq_base_pa;
	cq->dev = info->dev;
	cq->ceq_id = info->ceq_id;
	arm_offset = (info->dev->is_pf) ? I40E_PFPE_CQARM : I40E_VFPE_CQARM1;
	if (i40iw_get_hw_addr(cq->dev))
		cqe_alloc_reg = (u32 __iomem *)(i40iw_get_hw_addr(cq->dev) +
					      arm_offset);
	info->cq_uk_init_info.cqe_alloc_reg = cqe_alloc_reg;
	ret_code = i40iw_cq_uk_init(&cq->cq_uk, &info->cq_uk_init_info);
	if (ret_code)
		return ret_code;
	cq->virtual_map = info->virtual_map;
	cq->pbl_chunk_size = info->pbl_chunk_size;
	cq->ceqe_mask = info->ceqe_mask;
	cq->cq_type = (info->type) ? info->type : I40IW_CQ_TYPE_IWARP;

	cq->shadow_area_pa = info->shadow_area_pa;
	cq->shadow_read_threshold = info->shadow_read_threshold;

	cq->ceq_id_valid = info->ceq_id_valid;
	cq->tph_en = info->tph_en;
	cq->tph_val = info->tph_val;

	cq->first_pm_pbl_idx = info->first_pm_pbl_idx;

	return 0;
}

/**
 * i40iw_sc_cq_create - create completion q
 * @cq: cq struct
 * @scratch: u64 saved to be used during cqp completion
 * @check_overflow: flag for overflow check
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_cq_create(struct i40iw_sc_cq *cq,
						 u64 scratch,
						 bool check_overflow,
						 bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;

	if (cq->cq_uk.cq_id > I40IW_MAX_CQID)
		return I40IW_ERR_INVALID_CQ_ID;

	if (cq->ceq_id > I40IW_MAX_CEQID)
		return I40IW_ERR_INVALID_CEQ_ID;

	cqp = cq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 0, cq->cq_uk.cq_size);
	set_64bit_val(wqe, 8, RS_64_1(cq, 1));
	set_64bit_val(wqe,
		      16,
		      LS_64(cq->shadow_read_threshold, I40IW_CQPSQ_CQ_SHADOW_READ_THRESHOLD));

	set_64bit_val(wqe, 32, (cq->virtual_map ? 0 : cq->cq_pa));

	set_64bit_val(wqe, 40, cq->shadow_area_pa);
	set_64bit_val(wqe, 48, (cq->virtual_map ? cq->first_pm_pbl_idx : 0));
	set_64bit_val(wqe, 56, LS_64(cq->tph_val, I40IW_CQPSQ_TPHVAL));

	header = cq->cq_uk.cq_id |
		 LS_64((cq->ceq_id_valid ? cq->ceq_id : 0), I40IW_CQPSQ_CQ_CEQID) |
		 LS_64(I40IW_CQP_OP_CREATE_CQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(cq->pbl_chunk_size, I40IW_CQPSQ_CQ_LPBLSIZE) |
		 LS_64(check_overflow, I40IW_CQPSQ_CQ_CHKOVERFLOW) |
		 LS_64(cq->virtual_map, I40IW_CQPSQ_CQ_VIRTMAP) |
		 LS_64(cq->ceqe_mask, I40IW_CQPSQ_CQ_ENCEQEMASK) |
		 LS_64(cq->ceq_id_valid, I40IW_CQPSQ_CQ_CEQIDVALID) |
		 LS_64(cq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(cq->cq_uk.avoid_mem_cflct, I40IW_CQPSQ_CQ_AVOIDMEMCNFLCT) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CQ_CREATE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_cq_destroy - destroy completion q
 * @cq: cq struct
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_cq_destroy(struct i40iw_sc_cq *cq,
						  u64 scratch,
						  bool post_sq)
{
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;
	u64 header;

	cqp = cq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 0, cq->cq_uk.cq_size);
	set_64bit_val(wqe, 8, RS_64_1(cq, 1));
	set_64bit_val(wqe, 40, cq->shadow_area_pa);
	set_64bit_val(wqe, 48, (cq->virtual_map ? cq->first_pm_pbl_idx : 0));

	header = cq->cq_uk.cq_id |
		 LS_64((cq->ceq_id_valid ? cq->ceq_id : 0), I40IW_CQPSQ_CQ_CEQID) |
		 LS_64(I40IW_CQP_OP_DESTROY_CQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(cq->pbl_chunk_size, I40IW_CQPSQ_CQ_LPBLSIZE) |
		 LS_64(cq->virtual_map, I40IW_CQPSQ_CQ_VIRTMAP) |
		 LS_64(cq->ceqe_mask, I40IW_CQPSQ_CQ_ENCEQEMASK) |
		 LS_64(cq->ceq_id_valid, I40IW_CQPSQ_CQ_CEQIDVALID) |
		 LS_64(cq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(cq->cq_uk.avoid_mem_cflct, I40IW_CQPSQ_CQ_AVOIDMEMCNFLCT) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CQ_DESTROY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_cq_modify - modify a Completion Queue
 * @cq: cq struct
 * @info: modification info struct
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag to post to sq
 */
static enum i40iw_status_code i40iw_sc_cq_modify(struct i40iw_sc_cq *cq,
						 struct i40iw_modify_cq_info *info,
						 u64 scratch,
						 bool post_sq)
{
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;
	u64 header;
	u32 cq_size, ceq_id, first_pm_pbl_idx;
	u8 pbl_chunk_size;
	bool virtual_map, ceq_id_valid, check_overflow;
	u32 pble_obj_cnt;

	if (info->ceq_valid && (info->ceq_id > I40IW_MAX_CEQID))
		return I40IW_ERR_INVALID_CEQ_ID;

	pble_obj_cnt = cq->dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if (info->cq_resize && info->virtual_map &&
	    (info->first_pm_pbl_idx >= pble_obj_cnt))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	cqp = cq->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	cq->pbl_list = info->pbl_list;
	cq->cq_pa = info->cq_pa;
	cq->first_pm_pbl_idx = info->first_pm_pbl_idx;

	cq_size = info->cq_resize ? info->cq_size : cq->cq_uk.cq_size;
	if (info->ceq_change) {
		ceq_id_valid = true;
		ceq_id = info->ceq_id;
	} else {
		ceq_id_valid = cq->ceq_id_valid;
		ceq_id = ceq_id_valid ? cq->ceq_id : 0;
	}
	virtual_map = info->cq_resize ? info->virtual_map : cq->virtual_map;
	first_pm_pbl_idx = (info->cq_resize ?
			    (info->virtual_map ? info->first_pm_pbl_idx : 0) :
			    (cq->virtual_map ? cq->first_pm_pbl_idx : 0));
	pbl_chunk_size = (info->cq_resize ?
			  (info->virtual_map ? info->pbl_chunk_size : 0) :
			  (cq->virtual_map ? cq->pbl_chunk_size : 0));
	check_overflow = info->check_overflow_change ? info->check_overflow :
			 cq->check_overflow;
	cq->cq_uk.cq_size = cq_size;
	cq->ceq_id_valid = ceq_id_valid;
	cq->ceq_id = ceq_id;
	cq->virtual_map = virtual_map;
	cq->first_pm_pbl_idx = first_pm_pbl_idx;
	cq->pbl_chunk_size = pbl_chunk_size;
	cq->check_overflow = check_overflow;

	set_64bit_val(wqe, 0, cq_size);
	set_64bit_val(wqe, 8, RS_64_1(cq, 1));
	set_64bit_val(wqe, 16,
		      LS_64(info->shadow_read_threshold, I40IW_CQPSQ_CQ_SHADOW_READ_THRESHOLD));
	set_64bit_val(wqe, 32, (cq->virtual_map ? 0 : cq->cq_pa));
	set_64bit_val(wqe, 40, cq->shadow_area_pa);
	set_64bit_val(wqe, 48, (cq->virtual_map ? first_pm_pbl_idx : 0));
	set_64bit_val(wqe, 56, LS_64(cq->tph_val, I40IW_CQPSQ_TPHVAL));

	header = cq->cq_uk.cq_id |
		 LS_64(ceq_id, I40IW_CQPSQ_CQ_CEQID) |
		 LS_64(I40IW_CQP_OP_MODIFY_CQ, I40IW_CQPSQ_OPCODE) |
		 LS_64(info->cq_resize, I40IW_CQPSQ_CQ_CQRESIZE) |
		 LS_64(pbl_chunk_size, I40IW_CQPSQ_CQ_LPBLSIZE) |
		 LS_64(check_overflow, I40IW_CQPSQ_CQ_CHKOVERFLOW) |
		 LS_64(virtual_map, I40IW_CQPSQ_CQ_VIRTMAP) |
		 LS_64(cq->ceqe_mask, I40IW_CQPSQ_CQ_ENCEQEMASK) |
		 LS_64(ceq_id_valid, I40IW_CQPSQ_CQ_CEQIDVALID) |
		 LS_64(cq->tph_en, I40IW_CQPSQ_TPHEN) |
		 LS_64(cq->cq_uk.avoid_mem_cflct, I40IW_CQPSQ_CQ_AVOIDMEMCNFLCT) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "CQ_MODIFY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_qp_init - initialize qp
 * @qp: sc qp
 * @info: initialization qp info
 */
static enum i40iw_status_code i40iw_sc_qp_init(struct i40iw_sc_qp *qp,
					       struct i40iw_qp_init_info *info)
{
	u32 __iomem *wqe_alloc_reg = NULL;
	enum i40iw_status_code ret_code;
	u32 pble_obj_cnt;
	u8 wqe_size;
	u32 offset;

	qp->dev = info->pd->dev;
	qp->vsi = info->vsi;
	qp->sq_pa = info->sq_pa;
	qp->rq_pa = info->rq_pa;
	qp->hw_host_ctx_pa = info->host_ctx_pa;
	qp->q2_pa = info->q2_pa;
	qp->shadow_area_pa = info->shadow_area_pa;

	qp->q2_buf = info->q2;
	qp->pd = info->pd;
	qp->hw_host_ctx = info->host_ctx;
	offset = (qp->pd->dev->is_pf) ? I40E_PFPE_WQEALLOC : I40E_VFPE_WQEALLOC1;
	if (i40iw_get_hw_addr(qp->pd->dev))
		wqe_alloc_reg = (u32 __iomem *)(i40iw_get_hw_addr(qp->pd->dev) +
					      offset);

	info->qp_uk_init_info.wqe_alloc_reg = wqe_alloc_reg;
	info->qp_uk_init_info.abi_ver = qp->pd->abi_ver;
	ret_code = i40iw_qp_uk_init(&qp->qp_uk, &info->qp_uk_init_info);
	if (ret_code)
		return ret_code;
	qp->virtual_map = info->virtual_map;

	pble_obj_cnt = info->pd->dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if ((info->virtual_map && (info->sq_pa >= pble_obj_cnt)) ||
	    (info->virtual_map && (info->rq_pa >= pble_obj_cnt)))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	qp->llp_stream_handle = (void *)(-1);
	qp->qp_type = (info->type) ? info->type : I40IW_QP_TYPE_IWARP;

	qp->hw_sq_size = i40iw_get_encoded_wqe_size(qp->qp_uk.sq_ring.size,
						    false);
	i40iw_debug(qp->dev, I40IW_DEBUG_WQE, "%s: hw_sq_size[%04d] sq_ring.size[%04d]\n",
		    __func__, qp->hw_sq_size, qp->qp_uk.sq_ring.size);

	switch (qp->pd->abi_ver) {
	case 4:
		ret_code = i40iw_fragcnt_to_wqesize_rq(qp->qp_uk.max_rq_frag_cnt,
						       &wqe_size);
		if (ret_code)
			return ret_code;
		break;
	case 5: /* fallthrough until next ABI version */
	default:
		if (qp->qp_uk.max_rq_frag_cnt > I40IW_MAX_WQ_FRAGMENT_COUNT)
			return I40IW_ERR_INVALID_FRAG_COUNT;
		wqe_size = I40IW_MAX_WQE_SIZE_RQ;
		break;
	}
	qp->hw_rq_size = i40iw_get_encoded_wqe_size(qp->qp_uk.rq_size *
				(wqe_size / I40IW_QP_WQE_MIN_SIZE), false);
	i40iw_debug(qp->dev, I40IW_DEBUG_WQE,
		    "%s: hw_rq_size[%04d] qp_uk.rq_size[%04d] wqe_size[%04d]\n",
		    __func__, qp->hw_rq_size, qp->qp_uk.rq_size, wqe_size);
	qp->sq_tph_val = info->sq_tph_val;
	qp->rq_tph_val = info->rq_tph_val;
	qp->sq_tph_en = info->sq_tph_en;
	qp->rq_tph_en = info->rq_tph_en;
	qp->rcv_tph_en = info->rcv_tph_en;
	qp->xmit_tph_en = info->xmit_tph_en;
	qp->qs_handle = qp->vsi->qos[qp->user_pri].qs_handle;

	return 0;
}

/**
 * i40iw_sc_qp_create - create qp
 * @qp: sc qp
 * @info: qp create info
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_qp_create(
				struct i40iw_sc_qp *qp,
				struct i40iw_create_qp_info *info,
				u64 scratch,
				bool post_sq)
{
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;
	u64 header;

	if ((qp->qp_uk.qp_id < I40IW_MIN_IW_QP_ID) ||
	    (qp->qp_uk.qp_id > I40IW_MAX_IW_QP_ID))
		return I40IW_ERR_INVALID_QP_ID;

	cqp = qp->pd->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	set_64bit_val(wqe, 16, qp->hw_host_ctx_pa);

	set_64bit_val(wqe, 40, qp->shadow_area_pa);

	header = qp->qp_uk.qp_id |
		 LS_64(I40IW_CQP_OP_CREATE_QP, I40IW_CQPSQ_OPCODE) |
		 LS_64((info->ord_valid ? 1 : 0), I40IW_CQPSQ_QP_ORDVALID) |
		 LS_64(info->tcp_ctx_valid, I40IW_CQPSQ_QP_TOECTXVALID) |
		 LS_64(qp->qp_type, I40IW_CQPSQ_QP_QPTYPE) |
		 LS_64(qp->virtual_map, I40IW_CQPSQ_QP_VQ) |
		 LS_64(info->cq_num_valid, I40IW_CQPSQ_QP_CQNUMVALID) |
		 LS_64(info->arp_cache_idx_valid, I40IW_CQPSQ_QP_ARPTABIDXVALID) |
		 LS_64(info->next_iwarp_state, I40IW_CQPSQ_QP_NEXTIWSTATE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QP_CREATE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_qp_modify - modify qp cqp wqe
 * @qp: sc qp
 * @info: modify qp info
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_qp_modify(
				struct i40iw_sc_qp *qp,
				struct i40iw_modify_qp_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;
	u8 term_actions = 0;
	u8 term_len = 0;

	cqp = qp->pd->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	if (info->next_iwarp_state == I40IW_QP_STATE_TERMINATE) {
		if (info->dont_send_fin)
			term_actions += I40IWQP_TERM_SEND_TERM_ONLY;
		if (info->dont_send_term)
			term_actions += I40IWQP_TERM_SEND_FIN_ONLY;
		if ((term_actions == I40IWQP_TERM_SEND_TERM_AND_FIN) ||
		    (term_actions == I40IWQP_TERM_SEND_TERM_ONLY))
			term_len = info->termlen;
	}

	set_64bit_val(wqe,
		      8,
		      LS_64(term_len, I40IW_CQPSQ_QP_TERMLEN));

	set_64bit_val(wqe, 16, qp->hw_host_ctx_pa);
	set_64bit_val(wqe, 40, qp->shadow_area_pa);

	header = qp->qp_uk.qp_id |
		 LS_64(I40IW_CQP_OP_MODIFY_QP, I40IW_CQPSQ_OPCODE) |
		 LS_64(info->ord_valid, I40IW_CQPSQ_QP_ORDVALID) |
		 LS_64(info->tcp_ctx_valid, I40IW_CQPSQ_QP_TOECTXVALID) |
		 LS_64(info->cached_var_valid, I40IW_CQPSQ_QP_CACHEDVARVALID) |
		 LS_64(qp->virtual_map, I40IW_CQPSQ_QP_VQ) |
		 LS_64(info->cq_num_valid, I40IW_CQPSQ_QP_CQNUMVALID) |
		 LS_64(info->force_loopback, I40IW_CQPSQ_QP_FORCELOOPBACK) |
		 LS_64(qp->qp_type, I40IW_CQPSQ_QP_QPTYPE) |
		 LS_64(info->remove_hash_idx, I40IW_CQPSQ_QP_REMOVEHASHENTRY) |
		 LS_64(term_actions, I40IW_CQPSQ_QP_TERMACT) |
		 LS_64(info->reset_tcp_conn, I40IW_CQPSQ_QP_RESETCON) |
		 LS_64(info->arp_cache_idx_valid, I40IW_CQPSQ_QP_ARPTABIDXVALID) |
		 LS_64(info->next_iwarp_state, I40IW_CQPSQ_QP_NEXTIWSTATE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QP_MODIFY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_qp_destroy - cqp destroy qp
 * @qp: sc qp
 * @scratch: u64 saved to be used during cqp completion
 * @remove_hash_idx: flag if to remove hash idx
 * @ignore_mw_bnd: memory window bind flag
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_qp_destroy(
					struct i40iw_sc_qp *qp,
					u64 scratch,
					bool remove_hash_idx,
					bool ignore_mw_bnd,
					bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;

	i40iw_qp_rem_qos(qp);
	cqp = qp->pd->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 16, qp->hw_host_ctx_pa);
	set_64bit_val(wqe, 40, qp->shadow_area_pa);

	header = qp->qp_uk.qp_id |
		 LS_64(I40IW_CQP_OP_DESTROY_QP, I40IW_CQPSQ_OPCODE) |
		 LS_64(qp->qp_type, I40IW_CQPSQ_QP_QPTYPE) |
		 LS_64(ignore_mw_bnd, I40IW_CQPSQ_QP_IGNOREMWBOUND) |
		 LS_64(remove_hash_idx, I40IW_CQPSQ_QP_REMOVEHASHENTRY) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);
	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QP_DESTROY WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_qp_flush_wqes - flush qp's wqe
 * @qp: sc qp
 * @info: dlush information
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_qp_flush_wqes(
				struct i40iw_sc_qp *qp,
				struct i40iw_qp_flush_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 temp = 0;
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;
	bool flush_sq = false, flush_rq = false;

	if (info->rq && !qp->flush_rq)
		flush_rq = true;

	if (info->sq && !qp->flush_sq)
		flush_sq = true;

	qp->flush_sq |= flush_sq;
	qp->flush_rq |= flush_rq;
	if (!flush_sq && !flush_rq)
		return 0;

	cqp = qp->pd->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	if (info->userflushcode) {
		if (flush_rq) {
			temp |= LS_64(info->rq_minor_code, I40IW_CQPSQ_FWQE_RQMNERR) |
				LS_64(info->rq_major_code, I40IW_CQPSQ_FWQE_RQMJERR);
		}
		if (flush_sq) {
			temp |= LS_64(info->sq_minor_code, I40IW_CQPSQ_FWQE_SQMNERR) |
				LS_64(info->sq_major_code, I40IW_CQPSQ_FWQE_SQMJERR);
		}
	}
	set_64bit_val(wqe, 16, temp);

	temp = (info->generate_ae) ?
		info->ae_code | LS_64(info->ae_source, I40IW_CQPSQ_FWQE_AESOURCE) : 0;

	set_64bit_val(wqe, 8, temp);

	header = qp->qp_uk.qp_id |
		 LS_64(I40IW_CQP_OP_FLUSH_WQES, I40IW_CQPSQ_OPCODE) |
		 LS_64(info->generate_ae, I40IW_CQPSQ_FWQE_GENERATE_AE) |
		 LS_64(info->userflushcode, I40IW_CQPSQ_FWQE_USERFLCODE) |
		 LS_64(flush_sq, I40IW_CQPSQ_FWQE_FLUSHSQ) |
		 LS_64(flush_rq, I40IW_CQPSQ_FWQE_FLUSHRQ) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "QP_FLUSH WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_gen_ae - generate AE, currently uses flush WQE CQP OP
 * @qp: sc qp
 * @info: gen ae information
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_gen_ae(
				struct i40iw_sc_qp *qp,
				struct i40iw_gen_ae_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 temp;
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;

	cqp = qp->pd->dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	temp = info->ae_code |
	       LS_64(info->ae_source, I40IW_CQPSQ_FWQE_AESOURCE);

	set_64bit_val(wqe, 8, temp);

	header = qp->qp_uk.qp_id |
		 LS_64(I40IW_CQP_OP_GEN_AE, I40IW_CQPSQ_OPCODE) |
		 LS_64(1, I40IW_CQPSQ_FWQE_GENERATE_AE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "GEN_AE WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_qp_upload_context - upload qp's context
 * @dev: sc device struct
 * @info: upload context info ptr for return
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_qp_upload_context(
					struct i40iw_sc_dev *dev,
					struct i40iw_upload_context_info *info,
					u64 scratch,
					bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;

	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 16, info->buf_pa);

	header = LS_64(info->qp_id, I40IW_CQPSQ_UCTX_QPID) |
		 LS_64(I40IW_CQP_OP_UPLOAD_CONTEXT, I40IW_CQPSQ_OPCODE) |
		 LS_64(info->qp_type, I40IW_CQPSQ_UCTX_QPTYPE) |
		 LS_64(info->raw_format, I40IW_CQPSQ_UCTX_RAWFORMAT) |
		 LS_64(info->freeze_qp, I40IW_CQPSQ_UCTX_FREEZEQP) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "QP_UPLOAD_CTX WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_qp_setctx - set qp's context
 * @qp: sc qp
 * @qp_ctx: context ptr
 * @info: ctx info
 */
static enum i40iw_status_code i40iw_sc_qp_setctx(
				struct i40iw_sc_qp *qp,
				u64 *qp_ctx,
				struct i40iw_qp_host_ctx_info *info)
{
	struct i40iwarp_offload_info *iw;
	struct i40iw_tcp_offload_info *tcp;
	struct i40iw_sc_vsi *vsi;
	struct i40iw_sc_dev *dev;
	u64 qw0, qw3, qw7 = 0;

	iw = info->iwarp_info;
	tcp = info->tcp_info;
	vsi = qp->vsi;
	dev = qp->dev;
	if (info->add_to_qoslist) {
		qp->user_pri = info->user_pri;
		i40iw_qp_add_qos(qp);
		i40iw_debug(qp->dev, I40IW_DEBUG_DCB, "%s qp[%d] UP[%d] qset[%d]\n",
			    __func__, qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle);
	}
	qw0 = LS_64(qp->qp_uk.rq_wqe_size, I40IWQPC_RQWQESIZE) |
	      LS_64(info->err_rq_idx_valid, I40IWQPC_ERR_RQ_IDX_VALID) |
	      LS_64(qp->rcv_tph_en, I40IWQPC_RCVTPHEN) |
	      LS_64(qp->xmit_tph_en, I40IWQPC_XMITTPHEN) |
	      LS_64(qp->rq_tph_en, I40IWQPC_RQTPHEN) |
	      LS_64(qp->sq_tph_en, I40IWQPC_SQTPHEN);

	set_64bit_val(qp_ctx, 8, qp->sq_pa);
	set_64bit_val(qp_ctx, 16, qp->rq_pa);

	qw3 = LS_64(qp->src_mac_addr_idx, I40IWQPC_SRCMACADDRIDX) |
	      LS_64(qp->hw_rq_size, I40IWQPC_RQSIZE) |
	      LS_64(qp->hw_sq_size, I40IWQPC_SQSIZE);

	set_64bit_val(qp_ctx,
		      128,
		      LS_64(info->err_rq_idx, I40IWQPC_ERR_RQ_IDX));

	set_64bit_val(qp_ctx,
		      136,
		      LS_64(info->send_cq_num, I40IWQPC_TXCQNUM) |
		      LS_64(info->rcv_cq_num, I40IWQPC_RXCQNUM));

	set_64bit_val(qp_ctx,
		      168,
		      LS_64(info->qp_compl_ctx, I40IWQPC_QPCOMPCTX));
	set_64bit_val(qp_ctx,
		      176,
		      LS_64(qp->sq_tph_val, I40IWQPC_SQTPHVAL) |
		      LS_64(qp->rq_tph_val, I40IWQPC_RQTPHVAL) |
		      LS_64(qp->qs_handle, I40IWQPC_QSHANDLE) |
		      LS_64(vsi->exception_lan_queue, I40IWQPC_EXCEPTION_LAN_QUEUE));

	if (info->iwarp_info_valid) {
		qw0 |= LS_64(iw->ddp_ver, I40IWQPC_DDP_VER) |
		       LS_64(iw->rdmap_ver, I40IWQPC_RDMAP_VER);

		qw7 |= LS_64(iw->pd_id, I40IWQPC_PDIDX);
		set_64bit_val(qp_ctx,
			      144,
			      LS_64(qp->q2_pa, I40IWQPC_Q2ADDR) |
			      LS_64(vsi->fcn_id, I40IWQPC_STAT_INDEX));
		set_64bit_val(qp_ctx,
			      152,
			      LS_64(iw->last_byte_sent, I40IWQPC_LASTBYTESENT));

		set_64bit_val(qp_ctx,
			      160,
			      LS_64(iw->ord_size, I40IWQPC_ORDSIZE) |
			      LS_64(iw->ird_size, I40IWQPC_IRDSIZE) |
			      LS_64(iw->wr_rdresp_en, I40IWQPC_WRRDRSPOK) |
			      LS_64(iw->rd_enable, I40IWQPC_RDOK) |
			      LS_64(iw->snd_mark_en, I40IWQPC_SNDMARKERS) |
			      LS_64(iw->bind_en, I40IWQPC_BINDEN) |
			      LS_64(iw->fast_reg_en, I40IWQPC_FASTREGEN) |
			      LS_64(iw->priv_mode_en, I40IWQPC_PRIVEN) |
			      LS_64((((vsi->stats_fcn_id_alloc) &&
				      (dev->is_pf) && (vsi->fcn_id >= I40IW_FIRST_NON_PF_STAT)) ? 1 : 0),
				    I40IWQPC_USESTATSINSTANCE) |
			      LS_64(1, I40IWQPC_IWARPMODE) |
			      LS_64(iw->rcv_mark_en, I40IWQPC_RCVMARKERS) |
			      LS_64(iw->align_hdrs, I40IWQPC_ALIGNHDRS) |
			      LS_64(iw->rcv_no_mpa_crc, I40IWQPC_RCVNOMPACRC) |
			      LS_64(iw->rcv_mark_offset, I40IWQPC_RCVMARKOFFSET) |
			      LS_64(iw->snd_mark_offset, I40IWQPC_SNDMARKOFFSET));
	}
	if (info->tcp_info_valid) {
		qw0 |= LS_64(tcp->ipv4, I40IWQPC_IPV4) |
		       LS_64(tcp->no_nagle, I40IWQPC_NONAGLE) |
		       LS_64(tcp->insert_vlan_tag, I40IWQPC_INSERTVLANTAG) |
		       LS_64(tcp->time_stamp, I40IWQPC_TIMESTAMP) |
		       LS_64(tcp->cwnd_inc_limit, I40IWQPC_LIMIT) |
		       LS_64(tcp->drop_ooo_seg, I40IWQPC_DROPOOOSEG) |
		       LS_64(tcp->dup_ack_thresh, I40IWQPC_DUPACK_THRESH);

		qw3 |= LS_64(tcp->ttl, I40IWQPC_TTL) |
		       LS_64(tcp->src_mac_addr_idx, I40IWQPC_SRCMACADDRIDX) |
		       LS_64(tcp->avoid_stretch_ack, I40IWQPC_AVOIDSTRETCHACK) |
		       LS_64(tcp->tos, I40IWQPC_TOS) |
		       LS_64(tcp->src_port, I40IWQPC_SRCPORTNUM) |
		       LS_64(tcp->dst_port, I40IWQPC_DESTPORTNUM);

		qp->src_mac_addr_idx = tcp->src_mac_addr_idx;
		set_64bit_val(qp_ctx,
			      32,
			      LS_64(tcp->dest_ip_addr2, I40IWQPC_DESTIPADDR2) |
			      LS_64(tcp->dest_ip_addr3, I40IWQPC_DESTIPADDR3));

		set_64bit_val(qp_ctx,
			      40,
			      LS_64(tcp->dest_ip_addr0, I40IWQPC_DESTIPADDR0) |
			      LS_64(tcp->dest_ip_addr1, I40IWQPC_DESTIPADDR1));

		set_64bit_val(qp_ctx,
			      48,
			      LS_64(tcp->snd_mss, I40IWQPC_SNDMSS) |
				LS_64(tcp->vlan_tag, I40IWQPC_VLANTAG) |
				LS_64(tcp->arp_idx, I40IWQPC_ARPIDX));

		qw7 |= LS_64(tcp->flow_label, I40IWQPC_FLOWLABEL) |
		       LS_64(tcp->wscale, I40IWQPC_WSCALE) |
		       LS_64(tcp->ignore_tcp_opt, I40IWQPC_IGNORE_TCP_OPT) |
		       LS_64(tcp->ignore_tcp_uns_opt, I40IWQPC_IGNORE_TCP_UNS_OPT) |
		       LS_64(tcp->tcp_state, I40IWQPC_TCPSTATE) |
		       LS_64(tcp->rcv_wscale, I40IWQPC_RCVSCALE) |
		       LS_64(tcp->snd_wscale, I40IWQPC_SNDSCALE);

		set_64bit_val(qp_ctx,
			      72,
			      LS_64(tcp->time_stamp_recent, I40IWQPC_TIMESTAMP_RECENT) |
			      LS_64(tcp->time_stamp_age, I40IWQPC_TIMESTAMP_AGE));
		set_64bit_val(qp_ctx,
			      80,
			      LS_64(tcp->snd_nxt, I40IWQPC_SNDNXT) |
			      LS_64(tcp->snd_wnd, I40IWQPC_SNDWND));

		set_64bit_val(qp_ctx,
			      88,
			      LS_64(tcp->rcv_nxt, I40IWQPC_RCVNXT) |
			      LS_64(tcp->rcv_wnd, I40IWQPC_RCVWND));
		set_64bit_val(qp_ctx,
			      96,
			      LS_64(tcp->snd_max, I40IWQPC_SNDMAX) |
			      LS_64(tcp->snd_una, I40IWQPC_SNDUNA));
		set_64bit_val(qp_ctx,
			      104,
			      LS_64(tcp->srtt, I40IWQPC_SRTT) |
			      LS_64(tcp->rtt_var, I40IWQPC_RTTVAR));
		set_64bit_val(qp_ctx,
			      112,
			      LS_64(tcp->ss_thresh, I40IWQPC_SSTHRESH) |
			      LS_64(tcp->cwnd, I40IWQPC_CWND));
		set_64bit_val(qp_ctx,
			      120,
			      LS_64(tcp->snd_wl1, I40IWQPC_SNDWL1) |
			      LS_64(tcp->snd_wl2, I40IWQPC_SNDWL2));
		set_64bit_val(qp_ctx,
			      128,
			      LS_64(tcp->max_snd_window, I40IWQPC_MAXSNDWND) |
			      LS_64(tcp->rexmit_thresh, I40IWQPC_REXMIT_THRESH));
		set_64bit_val(qp_ctx,
			      184,
			      LS_64(tcp->local_ipaddr3, I40IWQPC_LOCAL_IPADDR3) |
			      LS_64(tcp->local_ipaddr2, I40IWQPC_LOCAL_IPADDR2));
		set_64bit_val(qp_ctx,
			      192,
			      LS_64(tcp->local_ipaddr1, I40IWQPC_LOCAL_IPADDR1) |
			      LS_64(tcp->local_ipaddr0, I40IWQPC_LOCAL_IPADDR0));
	}

	set_64bit_val(qp_ctx, 0, qw0);
	set_64bit_val(qp_ctx, 24, qw3);
	set_64bit_val(qp_ctx, 56, qw7);

	i40iw_debug_buf(qp->dev, I40IW_DEBUG_WQE, "QP_HOST)CTX WQE",
			qp_ctx, I40IW_QP_CTX_SIZE);
	return 0;
}

/**
 * i40iw_sc_alloc_stag - mr stag alloc
 * @dev: sc device struct
 * @info: stag info
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_alloc_stag(
				struct i40iw_sc_dev *dev,
				struct i40iw_allocate_stag_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 header;
	enum i40iw_page_size page_size;

	page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K;
	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe,
		      8,
		      LS_64(info->pd_id, I40IW_CQPSQ_STAG_PDID) |
		      LS_64(info->total_len, I40IW_CQPSQ_STAG_STAGLEN));
	set_64bit_val(wqe,
		      16,
		      LS_64(info->stag_idx, I40IW_CQPSQ_STAG_IDX));
	set_64bit_val(wqe,
		      40,
		      LS_64(info->hmc_fcn_index, I40IW_CQPSQ_STAG_HMCFNIDX));

	header = LS_64(I40IW_CQP_OP_ALLOC_STAG, I40IW_CQPSQ_OPCODE) |
		 LS_64(1, I40IW_CQPSQ_STAG_MR) |
		 LS_64(info->access_rights, I40IW_CQPSQ_STAG_ARIGHTS) |
		 LS_64(info->chunk_size, I40IW_CQPSQ_STAG_LPBLSIZE) |
		 LS_64(page_size, I40IW_CQPSQ_STAG_HPAGESIZE) |
		 LS_64(info->remote_access, I40IW_CQPSQ_STAG_REMACCENABLED) |
		 LS_64(info->use_hmc_fcn_index, I40IW_CQPSQ_STAG_USEHMCFNIDX) |
		 LS_64(info->use_pf_rid, I40IW_CQPSQ_STAG_USEPFRID) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "ALLOC_STAG WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_mr_reg_non_shared - non-shared mr registration
 * @dev: sc device struct
 * @info: mr info
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_mr_reg_non_shared(
				struct i40iw_sc_dev *dev,
				struct i40iw_reg_ns_stag_info *info,
				u64 scratch,
				bool post_sq)
{
	u64 *wqe;
	u64 temp;
	struct i40iw_sc_cqp *cqp;
	u64 header;
	u32 pble_obj_cnt;
	bool remote_access;
	u8 addr_type;
	enum i40iw_page_size page_size;

	page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K;
	if (info->access_rights & (I40IW_ACCESS_FLAGS_REMOTEREAD_ONLY |
				   I40IW_ACCESS_FLAGS_REMOTEWRITE_ONLY))
		remote_access = true;
	else
		remote_access = false;

	pble_obj_cnt = dev->hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt;

	if (info->chunk_size && (info->first_pm_pbl_index >= pble_obj_cnt))
		return I40IW_ERR_INVALID_PBLE_INDEX;

	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	temp = (info->addr_type == I40IW_ADDR_TYPE_VA_BASED) ? (uintptr_t)info->va : info->fbo;
	set_64bit_val(wqe, 0, temp);

	set_64bit_val(wqe,
		      8,
		      LS_64(info->total_len, I40IW_CQPSQ_STAG_STAGLEN) |
		      LS_64(info->pd_id, I40IW_CQPSQ_STAG_PDID));

	set_64bit_val(wqe,
		      16,
		      LS_64(info->stag_key, I40IW_CQPSQ_STAG_KEY) |
		      LS_64(info->stag_idx, I40IW_CQPSQ_STAG_IDX));
	if (!info->chunk_size) {
		set_64bit_val(wqe, 32, info->reg_addr_pa);
		set_64bit_val(wqe, 48, 0);
	} else {
		set_64bit_val(wqe, 32, 0);
		set_64bit_val(wqe, 48, info->first_pm_pbl_index);
	}
	set_64bit_val(wqe, 40, info->hmc_fcn_index);
	set_64bit_val(wqe, 56, 0);

	addr_type = (info->addr_type == I40IW_ADDR_TYPE_VA_BASED) ? 1 : 0;
	header = LS_64(I40IW_CQP_OP_REG_MR, I40IW_CQPSQ_OPCODE) |
		 LS_64(1, I40IW_CQPSQ_STAG_MR) |
		 LS_64(info->chunk_size, I40IW_CQPSQ_STAG_LPBLSIZE) |
		 LS_64(page_size, I40IW_CQPSQ_STAG_HPAGESIZE) |
		 LS_64(info->access_rights, I40IW_CQPSQ_STAG_ARIGHTS) |
		 LS_64(remote_access, I40IW_CQPSQ_STAG_REMACCENABLED) |
		 LS_64(addr_type, I40IW_CQPSQ_STAG_VABASEDTO) |
		 LS_64(info->use_hmc_fcn_index, I40IW_CQPSQ_STAG_USEHMCFNIDX) |
		 LS_64(info->use_pf_rid, I40IW_CQPSQ_STAG_USEPFRID) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "MR_REG_NS WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_mr_reg_shared - registered shared memory region
 * @dev: sc device struct
 * @info: info for shared memory registeration
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_mr_reg_shared(
					struct i40iw_sc_dev *dev,
					struct i40iw_register_shared_stag *info,
					u64 scratch,
					bool post_sq)
{
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;
	u64 temp, va64, fbo, header;
	u32 va32;
	bool remote_access;
	u8 addr_type;

	if (info->access_rights & (I40IW_ACCESS_FLAGS_REMOTEREAD_ONLY |
				   I40IW_ACCESS_FLAGS_REMOTEWRITE_ONLY))
		remote_access = true;
	else
		remote_access = false;
	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	va64 = (uintptr_t)(info->va);
	va32 = (u32)(va64 & 0x00000000FFFFFFFF);
	fbo = (u64)(va32 & (4096 - 1));

	set_64bit_val(wqe,
		      0,
		      (info->addr_type == I40IW_ADDR_TYPE_VA_BASED ? (uintptr_t)info->va : fbo));

	set_64bit_val(wqe,
		      8,
		      LS_64(info->pd_id, I40IW_CQPSQ_STAG_PDID));
	temp = LS_64(info->new_stag_key, I40IW_CQPSQ_STAG_KEY) |
	       LS_64(info->new_stag_idx, I40IW_CQPSQ_STAG_IDX) |
	       LS_64(info->parent_stag_idx, I40IW_CQPSQ_STAG_PARENTSTAGIDX);
	set_64bit_val(wqe, 16, temp);

	addr_type = (info->addr_type == I40IW_ADDR_TYPE_VA_BASED) ? 1 : 0;
	header = LS_64(I40IW_CQP_OP_REG_SMR, I40IW_CQPSQ_OPCODE) |
		 LS_64(1, I40IW_CQPSQ_STAG_MR) |
		 LS_64(info->access_rights, I40IW_CQPSQ_STAG_ARIGHTS) |
		 LS_64(remote_access, I40IW_CQPSQ_STAG_REMACCENABLED) |
		 LS_64(addr_type, I40IW_CQPSQ_STAG_VABASEDTO) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "MR_REG_SHARED WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_dealloc_stag - deallocate stag
 * @dev: sc device struct
 * @info: dealloc stag info
 * @scratch: u64 saved to be used during cqp completion
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_dealloc_stag(
					struct i40iw_sc_dev *dev,
					struct i40iw_dealloc_stag_info *info,
					u64 scratch,
					bool post_sq)
{
	u64 header;
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;

	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe,
		      8,
		      LS_64(info->pd_id, I40IW_CQPSQ_STAG_PDID));
	set_64bit_val(wqe,
		      16,
		      LS_64(info->stag_idx, I40IW_CQPSQ_STAG_IDX));

	header = LS_64(I40IW_CQP_OP_DEALLOC_STAG, I40IW_CQPSQ_OPCODE) |
		 LS_64(info->mr, I40IW_CQPSQ_STAG_MR) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "DEALLOC_STAG WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_query_stag - query hardware for stag
 * @dev: sc device struct
 * @scratch: u64 saved to be used during cqp completion
 * @stag_index: stag index for query
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_query_stag(struct i40iw_sc_dev *dev,
						  u64 scratch,
						  u32 stag_index,
						  bool post_sq)
{
	u64 header;
	u64 *wqe;
	struct i40iw_sc_cqp *cqp;

	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe,
		      16,
		      LS_64(stag_index, I40IW_CQPSQ_QUERYSTAG_IDX));

	header = LS_64(I40IW_CQP_OP_QUERY_STAG, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "QUERY_STAG WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_mw_alloc - mw allocate
 * @dev: sc device struct
 * @scratch: u64 saved to be used during cqp completion
 * @mw_stag_index:stag index
 * @pd_id: pd is for this mw
 * @post_sq: flag for cqp db to ring
 */
static enum i40iw_status_code i40iw_sc_mw_alloc(
					struct i40iw_sc_dev *dev,
					u64 scratch,
					u32 mw_stag_index,
					u16 pd_id,
					bool post_sq)
{
	u64 header;
	struct i40iw_sc_cqp *cqp;
	u64 *wqe;

	cqp = dev->cqp;
	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe, 8, LS_64(pd_id, I40IW_CQPSQ_STAG_PDID));
	set_64bit_val(wqe,
		      16,
		      LS_64(mw_stag_index, I40IW_CQPSQ_STAG_IDX));

	header = LS_64(I40IW_CQP_OP_ALLOC_STAG, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(dev, I40IW_DEBUG_WQE, "MW_ALLOC WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	if (post_sq)
		i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_mr_fast_register - Posts RDMA fast register mr WR to iwarp qp
 * @qp: sc qp struct
 * @info: fast mr info
 * @post_sq: flag for cqp db to ring
 */
enum i40iw_status_code i40iw_sc_mr_fast_register(
				struct i40iw_sc_qp *qp,
				struct i40iw_fast_reg_stag_info *info,
				bool post_sq)
{
	u64 temp, header;
	u64 *wqe;
	u32 wqe_idx;
	enum i40iw_page_size page_size;

	page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K;
	wqe = i40iw_qp_get_next_send_wqe(&qp->qp_uk, &wqe_idx, I40IW_QP_WQE_MIN_SIZE,
					 0, info->wr_id);
	if (!wqe)
		return I40IW_ERR_QP_TOOMANY_WRS_POSTED;

	i40iw_debug(qp->dev, I40IW_DEBUG_MR, "%s: wr_id[%llxh] wqe_idx[%04d] location[%p]\n",
		    __func__, info->wr_id, wqe_idx,
		    &qp->qp_uk.sq_wrtrk_array[wqe_idx].wrid);
	temp = (info->addr_type == I40IW_ADDR_TYPE_VA_BASED) ? (uintptr_t)info->va : info->fbo;
	set_64bit_val(wqe, 0, temp);

	temp = RS_64(info->first_pm_pbl_index >> 16, I40IWQPSQ_FIRSTPMPBLIDXHI);
	set_64bit_val(wqe,
		      8,
		      LS_64(temp, I40IWQPSQ_FIRSTPMPBLIDXHI) |
		      LS_64(info->reg_addr_pa >> I40IWQPSQ_PBLADDR_SHIFT, I40IWQPSQ_PBLADDR));

	set_64bit_val(wqe,
		      16,
		      info->total_len |
		      LS_64(info->first_pm_pbl_index, I40IWQPSQ_FIRSTPMPBLIDXLO));

	header = LS_64(info->stag_key, I40IWQPSQ_STAGKEY) |
		 LS_64(info->stag_idx, I40IWQPSQ_STAGINDEX) |
		 LS_64(I40IWQP_OP_FAST_REGISTER, I40IWQPSQ_OPCODE) |
		 LS_64(info->chunk_size, I40IWQPSQ_LPBLSIZE) |
		 LS_64(page_size, I40IWQPSQ_HPAGESIZE) |
		 LS_64(info->access_rights, I40IWQPSQ_STAGRIGHTS) |
		 LS_64(info->addr_type, I40IWQPSQ_VABASEDTO) |
		 LS_64(info->read_fence, I40IWQPSQ_READFENCE) |
		 LS_64(info->local_fence, I40IWQPSQ_LOCALFENCE) |
		 LS_64(info->signaled, I40IWQPSQ_SIGCOMPL) |
		 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(qp->dev, I40IW_DEBUG_WQE, "FAST_REG WQE",
			wqe, I40IW_QP_WQE_MIN_SIZE);

	if (post_sq)
		i40iw_qp_post_wr(&qp->qp_uk);
	return 0;
}

/**
 * i40iw_sc_send_lsmm - send last streaming mode message
 * @qp: sc qp struct
 * @lsmm_buf: buffer with lsmm message
 * @size: size of lsmm buffer
 * @stag: stag of lsmm buffer
 */
static void i40iw_sc_send_lsmm(struct i40iw_sc_qp *qp,
			       void *lsmm_buf,
			       u32 size,
			       i40iw_stag stag)
{
	u64 *wqe;
	u64 header;
	struct i40iw_qp_uk *qp_uk;

	qp_uk = &qp->qp_uk;
	wqe = qp_uk->sq_base->elem;

	set_64bit_val(wqe, 0, (uintptr_t)lsmm_buf);

	set_64bit_val(wqe, 8, (size | LS_64(stag, I40IWQPSQ_FRAG_STAG)));

	set_64bit_val(wqe, 16, 0);

	header = LS_64(I40IWQP_OP_RDMA_SEND, I40IWQPSQ_OPCODE) |
		 LS_64(1, I40IWQPSQ_STREAMMODE) |
		 LS_64(1, I40IWQPSQ_WAITFORRCVPDU) |
		 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(qp->dev, I40IW_DEBUG_QP, "SEND_LSMM WQE",
			wqe, I40IW_QP_WQE_MIN_SIZE);
}

/**
 * i40iw_sc_send_lsmm_nostag - for privilege qp
 * @qp: sc qp struct
 * @lsmm_buf: buffer with lsmm message
 * @size: size of lsmm buffer
 */
static void i40iw_sc_send_lsmm_nostag(struct i40iw_sc_qp *qp,
				      void *lsmm_buf,
				      u32 size)
{
	u64 *wqe;
	u64 header;
	struct i40iw_qp_uk *qp_uk;

	qp_uk = &qp->qp_uk;
	wqe = qp_uk->sq_base->elem;

	set_64bit_val(wqe, 0, (uintptr_t)lsmm_buf);

	set_64bit_val(wqe, 8, size);

	set_64bit_val(wqe, 16, 0);

	header = LS_64(I40IWQP_OP_RDMA_SEND, I40IWQPSQ_OPCODE) |
		 LS_64(1, I40IWQPSQ_STREAMMODE) |
		 LS_64(1, I40IWQPSQ_WAITFORRCVPDU) |
		 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(qp->dev, I40IW_DEBUG_WQE, "SEND_LSMM_NOSTAG WQE",
			wqe, I40IW_QP_WQE_MIN_SIZE);
}

/**
 * i40iw_sc_send_rtt - send last read0 or write0
 * @qp: sc qp struct
 * @read: Do read0 or write0
 */
static void i40iw_sc_send_rtt(struct i40iw_sc_qp *qp, bool read)
{
	u64 *wqe;
	u64 header;
	struct i40iw_qp_uk *qp_uk;

	qp_uk = &qp->qp_uk;
	wqe = qp_uk->sq_base->elem;

	set_64bit_val(wqe, 0, 0);
	set_64bit_val(wqe, 8, 0);
	set_64bit_val(wqe, 16, 0);
	if (read) {
		header = LS_64(0x1234, I40IWQPSQ_REMSTAG) |
			 LS_64(I40IWQP_OP_RDMA_READ, I40IWQPSQ_OPCODE) |
			 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID);
		set_64bit_val(wqe, 8, ((u64)0xabcd << 32));
	} else {
		header = LS_64(I40IWQP_OP_RDMA_WRITE, I40IWQPSQ_OPCODE) |
			 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID);
	}

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(qp->dev, I40IW_DEBUG_WQE, "RTR WQE",
			wqe, I40IW_QP_WQE_MIN_SIZE);
}

/**
 * i40iw_sc_post_wqe0 - send wqe with opcode
 * @qp: sc qp struct
 * @opcode: opcode to use for wqe0
 */
static enum i40iw_status_code i40iw_sc_post_wqe0(struct i40iw_sc_qp *qp, u8 opcode)
{
	u64 *wqe;
	u64 header;
	struct i40iw_qp_uk *qp_uk;

	qp_uk = &qp->qp_uk;
	wqe = qp_uk->sq_base->elem;

	if (!wqe)
		return I40IW_ERR_QP_TOOMANY_WRS_POSTED;
	switch (opcode) {
	case I40IWQP_OP_NOP:
		set_64bit_val(wqe, 0, 0);
		set_64bit_val(wqe, 8, 0);
		set_64bit_val(wqe, 16, 0);
		header = LS_64(I40IWQP_OP_NOP, I40IWQPSQ_OPCODE) |
			 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID);

		i40iw_insert_wqe_hdr(wqe, header);
		break;
	case I40IWQP_OP_RDMA_SEND:
		set_64bit_val(wqe, 0, 0);
		set_64bit_val(wqe, 8, 0);
		set_64bit_val(wqe, 16, 0);
		header = LS_64(I40IWQP_OP_RDMA_SEND, I40IWQPSQ_OPCODE) |
			 LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID) |
			 LS_64(1, I40IWQPSQ_STREAMMODE) |
			 LS_64(1, I40IWQPSQ_WAITFORRCVPDU);

		i40iw_insert_wqe_hdr(wqe, header);
		break;
	default:
		i40iw_debug(qp->dev, I40IW_DEBUG_QP, "%s: Invalid WQE zero opcode\n",
			    __func__);
		break;
	}
	return 0;
}

/**
 * i40iw_sc_init_iw_hmc() - queries fpm values using cqp and populates hmc_info
 * @dev : ptr to i40iw_dev struct
 * @hmc_fn_id: hmc function id
 */
enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev, u8 hmc_fn_id)
{
	struct i40iw_hmc_info *hmc_info;
	struct i40iw_dma_mem query_fpm_mem;
	struct i40iw_virt_mem virt_mem;
	struct i40iw_vfdev *vf_dev = NULL;
	u32 mem_size;
	enum i40iw_status_code ret_code = 0;
	bool poll_registers = true;
	u16 iw_vf_idx;
	u8 wait_type;

	if (hmc_fn_id >= I40IW_MAX_VF_FPM_ID ||
	    (dev->hmc_fn_id != hmc_fn_id && hmc_fn_id < I40IW_FIRST_VF_FPM_ID))
		return I40IW_ERR_INVALID_HMCFN_ID;

	i40iw_debug(dev, I40IW_DEBUG_HMC, "hmc_fn_id %u, dev->hmc_fn_id %u\n", hmc_fn_id,
		    dev->hmc_fn_id);
	if (hmc_fn_id == dev->hmc_fn_id) {
		hmc_info = dev->hmc_info;
		query_fpm_mem.pa = dev->fpm_query_buf_pa;
		query_fpm_mem.va = dev->fpm_query_buf;
	} else {
		vf_dev = i40iw_vfdev_from_fpm(dev, hmc_fn_id);
		if (!vf_dev)
			return I40IW_ERR_INVALID_VF_ID;

		hmc_info = &vf_dev->hmc_info;
		iw_vf_idx = vf_dev->iw_vf_idx;
		i40iw_debug(dev, I40IW_DEBUG_HMC, "vf_dev %p, hmc_info %p, hmc_obj %p\n", vf_dev,
			    hmc_info, hmc_info->hmc_obj);
		if (!vf_dev->fpm_query_buf) {
			if (!dev->vf_fpm_query_buf[iw_vf_idx].va) {
				ret_code = i40iw_alloc_query_fpm_buf(dev,
								     &dev->vf_fpm_query_buf[iw_vf_idx]);
				if (ret_code)
					return ret_code;
			}
			vf_dev->fpm_query_buf = dev->vf_fpm_query_buf[iw_vf_idx].va;
			vf_dev->fpm_query_buf_pa = dev->vf_fpm_query_buf[iw_vf_idx].pa;
		}
		query_fpm_mem.pa = vf_dev->fpm_query_buf_pa;
		query_fpm_mem.va = vf_dev->fpm_query_buf;
		/**
		 * It is HARDWARE specific:
		 * this call is done by PF for VF and
		 * i40iw_sc_query_fpm_values needs ccq poll
		 * because PF ccq is already created.
		 */
		poll_registers = false;
	}

	hmc_info->hmc_fn_id = hmc_fn_id;

	if (hmc_fn_id != dev->hmc_fn_id) {
		ret_code =
			i40iw_cqp_query_fpm_values_cmd(dev, &query_fpm_mem, hmc_fn_id);
	} else {
		wait_type = poll_registers ? (u8)I40IW_CQP_WAIT_POLL_REGS :
			    (u8)I40IW_CQP_WAIT_POLL_CQ;

		ret_code = i40iw_sc_query_fpm_values(
					dev->cqp,
					0,
					hmc_info->hmc_fn_id,
					&query_fpm_mem,
					true,
					wait_type);
	}
	if (ret_code)
		return ret_code;

	/* parse the fpm_query_buf and fill hmc obj info */
	ret_code =
		i40iw_sc_parse_fpm_query_buf((u64 *)query_fpm_mem.va,
					     hmc_info,
					     &dev->hmc_fpm_misc);
	if (ret_code)
		return ret_code;
	i40iw_debug_buf(dev, I40IW_DEBUG_HMC, "QUERY FPM BUFFER",
			query_fpm_mem.va, I40IW_QUERY_FPM_BUF_SIZE);

	if (hmc_fn_id != dev->hmc_fn_id) {
		i40iw_cqp_commit_fpm_values_cmd(dev, &query_fpm_mem, hmc_fn_id);

		/* parse the fpm_commit_buf and fill hmc obj info */
		i40iw_sc_parse_fpm_commit_buf((u64 *)query_fpm_mem.va, hmc_info->hmc_obj, &hmc_info->sd_table.sd_cnt);
		mem_size = sizeof(struct i40iw_hmc_sd_entry) *
			   (hmc_info->sd_table.sd_cnt + hmc_info->first_sd_index);
		ret_code = i40iw_allocate_virt_mem(dev->hw, &virt_mem, mem_size);
		if (ret_code)
			return ret_code;
		hmc_info->sd_table.sd_entry = virt_mem.va;
	}

	return ret_code;
}

/**
 * i40iw_sc_configure_iw_fpm() - commits hmc obj cnt values using cqp command and
 * populates fpm base address in hmc_info
 * @dev : ptr to i40iw_dev struct
 * @hmc_fn_id: hmc function id
 */
static enum i40iw_status_code i40iw_sc_configure_iw_fpm(struct i40iw_sc_dev *dev,
							u8 hmc_fn_id)
{
	struct i40iw_hmc_info *hmc_info;
	struct i40iw_hmc_obj_info *obj_info;
	u64 *buf;
	struct i40iw_dma_mem commit_fpm_mem;
	u32 i, j;
	enum i40iw_status_code ret_code = 0;
	bool poll_registers = true;
	u8 wait_type;

	if (hmc_fn_id >= I40IW_MAX_VF_FPM_ID ||
	    (dev->hmc_fn_id != hmc_fn_id && hmc_fn_id < I40IW_FIRST_VF_FPM_ID))
		return I40IW_ERR_INVALID_HMCFN_ID;

	if (hmc_fn_id == dev->hmc_fn_id) {
		hmc_info = dev->hmc_info;
	} else {
		hmc_info = i40iw_vf_hmcinfo_from_fpm(dev, hmc_fn_id);
		poll_registers = false;
	}
	if (!hmc_info)
		return I40IW_ERR_BAD_PTR;

	obj_info = hmc_info->hmc_obj;
	buf = dev->fpm_commit_buf;

	/* copy cnt values in commit buf */
	for (i = I40IW_HMC_IW_QP, j = 0; i <= I40IW_HMC_IW_PBLE;
	     i++, j += 8)
		set_64bit_val(buf, j, (u64)obj_info[i].cnt);

	set_64bit_val(buf, 40, 0);   /* APBVT rsvd */

	commit_fpm_mem.pa = dev->fpm_commit_buf_pa;
	commit_fpm_mem.va = dev->fpm_commit_buf;
	wait_type = poll_registers ? (u8)I40IW_CQP_WAIT_POLL_REGS :
			(u8)I40IW_CQP_WAIT_POLL_CQ;
	ret_code = i40iw_sc_commit_fpm_values(
					dev->cqp,
					0,
					hmc_info->hmc_fn_id,
					&commit_fpm_mem,
					true,
					wait_type);

	/* parse the fpm_commit_buf and fill hmc obj info */
	if (!ret_code)
		ret_code = i40iw_sc_parse_fpm_commit_buf(dev->fpm_commit_buf,
							 hmc_info->hmc_obj,
							 &hmc_info->sd_table.sd_cnt);

	i40iw_debug_buf(dev, I40IW_DEBUG_HMC, "COMMIT FPM BUFFER",
			commit_fpm_mem.va, I40IW_COMMIT_FPM_BUF_SIZE);

	return ret_code;
}

/**
 * cqp_sds_wqe_fill - fill cqp wqe doe sd
 * @cqp: struct for cqp hw
 * @info: sd info for wqe
 * @scratch: u64 saved to be used during cqp completion
 */
static enum i40iw_status_code cqp_sds_wqe_fill(struct i40iw_sc_cqp *cqp,
					       struct i40iw_update_sds_info *info,
					       u64 scratch)
{
	u64 data;
	u64 header;
	u64 *wqe;
	int mem_entries, wqe_entries;
	struct i40iw_dma_mem *sdbuf = &cqp->sdbuf;
	u64 offset;
	u32 wqe_idx;

	wqe = i40iw_sc_cqp_get_next_send_wqe_idx(cqp, scratch, &wqe_idx);
	if (!wqe)
		return I40IW_ERR_RING_FULL;

	I40IW_CQP_INIT_WQE(wqe);
	wqe_entries = (info->cnt > 3) ? 3 : info->cnt;
	mem_entries = info->cnt - wqe_entries;

	header = LS_64(I40IW_CQP_OP_UPDATE_PE_SDS, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID) |
		 LS_64(mem_entries, I40IW_CQPSQ_UPESD_ENTRY_COUNT);

	if (mem_entries) {
		offset = wqe_idx * I40IW_UPDATE_SD_BUF_SIZE;
		memcpy((char *)sdbuf->va + offset, &info->entry[3],
		       mem_entries << 4);
		data = (u64)sdbuf->pa + offset;
	} else {
		data = 0;
	}
	data |= LS_64(info->hmc_fn_id, I40IW_CQPSQ_UPESD_HMCFNID);

	set_64bit_val(wqe, 16, data);

	switch (wqe_entries) {
	case 3:
		set_64bit_val(wqe, 48,
			      (LS_64(info->entry[2].cmd, I40IW_CQPSQ_UPESD_SDCMD) |
					LS_64(1, I40IW_CQPSQ_UPESD_ENTRY_VALID)));

		set_64bit_val(wqe, 56, info->entry[2].data);
		fallthrough;
	case 2:
		set_64bit_val(wqe, 32,
			      (LS_64(info->entry[1].cmd, I40IW_CQPSQ_UPESD_SDCMD) |
					LS_64(1, I40IW_CQPSQ_UPESD_ENTRY_VALID)));

		set_64bit_val(wqe, 40, info->entry[1].data);
		fallthrough;
	case 1:
		set_64bit_val(wqe, 0,
			      LS_64(info->entry[0].cmd, I40IW_CQPSQ_UPESD_SDCMD));

		set_64bit_val(wqe, 8, info->entry[0].data);
		break;
	default:
		break;
	}

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "UPDATE_PE_SDS WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);
	return 0;
}

/**
 * i40iw_update_pe_sds - cqp wqe for sd
 * @dev: ptr to i40iw_dev struct
 * @info: sd info for sd's
 * @scratch: u64 saved to be used during cqp completion
 */
static enum i40iw_status_code i40iw_update_pe_sds(struct i40iw_sc_dev *dev,
						  struct i40iw_update_sds_info *info,
						  u64 scratch)
{
	struct i40iw_sc_cqp *cqp = dev->cqp;
	enum i40iw_status_code ret_code;

	ret_code = cqp_sds_wqe_fill(cqp, info, scratch);
	if (!ret_code)
		i40iw_sc_cqp_post_sq(cqp);

	return ret_code;
}

/**
 * i40iw_update_sds_noccq - update sd before ccq created
 * @dev: sc device struct
 * @info: sd info for sd's
 */
enum i40iw_status_code i40iw_update_sds_noccq(struct i40iw_sc_dev *dev,
					      struct i40iw_update_sds_info *info)
{
	u32 error, val, tail;
	struct i40iw_sc_cqp *cqp = dev->cqp;
	enum i40iw_status_code ret_code;

	ret_code = cqp_sds_wqe_fill(cqp, info, 0);
	if (ret_code)
		return ret_code;
	i40iw_get_cqp_reg_info(cqp, &val, &tail, &error);
	if (error)
		return I40IW_ERR_CQP_COMPL_ERROR;

	i40iw_sc_cqp_post_sq(cqp);
	ret_code = i40iw_cqp_poll_registers(cqp, tail, I40IW_DONE_COUNT);

	return ret_code;
}

/**
 * i40iw_sc_suspend_qp - suspend qp for param change
 * @cqp: struct for cqp hw
 * @qp: sc qp struct
 * @scratch: u64 saved to be used during cqp completion
 */
enum i40iw_status_code i40iw_sc_suspend_qp(struct i40iw_sc_cqp *cqp,
					   struct i40iw_sc_qp *qp,
					   u64 scratch)
{
	u64 header;
	u64 *wqe;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	header = LS_64(qp->qp_uk.qp_id, I40IW_CQPSQ_SUSPENDQP_QPID) |
		 LS_64(I40IW_CQP_OP_SUSPEND_QP, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "SUSPEND_QP WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_resume_qp - resume qp after suspend
 * @cqp: struct for cqp hw
 * @qp: sc qp struct
 * @scratch: u64 saved to be used during cqp completion
 */
enum i40iw_status_code i40iw_sc_resume_qp(struct i40iw_sc_cqp *cqp,
					  struct i40iw_sc_qp *qp,
					  u64 scratch)
{
	u64 header;
	u64 *wqe;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe,
		      16,
			LS_64(qp->qs_handle, I40IW_CQPSQ_RESUMEQP_QSHANDLE));

	header = LS_64(qp->qp_uk.qp_id, I40IW_CQPSQ_RESUMEQP_QPID) |
		 LS_64(I40IW_CQP_OP_RESUME_QP, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "RESUME_QP WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);

	i40iw_sc_cqp_post_sq(cqp);
	return 0;
}

/**
 * i40iw_sc_static_hmc_pages_allocated - cqp wqe to allocate hmc pages
 * @cqp: struct for cqp hw
 * @scratch: u64 saved to be used during cqp completion
 * @hmc_fn_id: hmc function id
 * @post_sq: flag for cqp db to ring
 * @poll_registers: flag to poll register for cqp completion
 */
enum i40iw_status_code i40iw_sc_static_hmc_pages_allocated(
					struct i40iw_sc_cqp *cqp,
					u64 scratch,
					u8 hmc_fn_id,
					bool post_sq,
					bool poll_registers)
{
	u64 header;
	u64 *wqe;
	u32 tail, val, error;
	enum i40iw_status_code ret_code = 0;

	wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
	if (!wqe)
		return I40IW_ERR_RING_FULL;
	set_64bit_val(wqe,
		      16,
		      LS_64(hmc_fn_id, I40IW_SHMC_PAGE_ALLOCATED_HMC_FN_ID));

	header = LS_64(I40IW_CQP_OP_SHMC_PAGES_ALLOCATED, I40IW_CQPSQ_OPCODE) |
		 LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);

	i40iw_insert_wqe_hdr(wqe, header);

	i40iw_debug_buf(cqp->dev, I40IW_DEBUG_WQE, "SHMC_PAGES_ALLOCATED WQE",
			wqe, I40IW_CQP_WQE_SIZE * 8);
	i40iw_get_cqp_reg_info(cqp, &val, &tail, &error);
	if (error) {
		ret_code = I40IW_ERR_CQP_COMPL_ERROR;
		return ret_code;
	}
	if (post_sq) {
		i40iw_sc_cqp_post_sq(cqp);
		if (poll_registers)
			/* check for cqp sq tail update */
			ret_code = i40iw_cqp_poll_registers(cqp, tail, 1000);
		else
			ret_code = i40iw_sc_poll_for_cqp_op_done(cqp,
								 I40IW_CQP_OP_SHMC_PAGES_ALLOCATED,
								 NULL);
	}

	return ret_code;
}

/**
 * i40iw_ring_full - check if cqp ring is full
 * @cqp: struct for cqp hw
 */
static bool i40iw_ring_full(struct i40iw_sc_cqp *cqp)
{
	return I40IW_RING_FULL_ERR(cqp->sq_ring);
}

/**
 * i40iw_est_sd - returns approximate number of SDs for HMC
 * @dev: sc device struct
 * @hmc_info: hmc structure, size and count for HMC objects
 */
static u64 i40iw_est_sd(struct i40iw_sc_dev *dev, struct i40iw_hmc_info *hmc_info)
{
	int i;
	u64 size = 0;
	u64 sd;

	for (i = I40IW_HMC_IW_QP; i < I40IW_HMC_IW_PBLE; i++)
		size += hmc_info->hmc_obj[i].cnt * hmc_info->hmc_obj[i].size;

	if (dev->is_pf)
		size += hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt * hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].size;

	if (size & 0x1FFFFF)
		sd = (size >> 21) + 1; /* add 1 for remainder */
	else
		sd = size >> 21;

	if (!dev->is_pf) {
		/* 2MB alignment for VF PBLE HMC */
		size = hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt * hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].size;
		if (size & 0x1FFFFF)
			sd += (size >> 21) + 1; /* add 1 for remainder */
		else
			sd += size >> 21;
	}

	return sd;
}

/**
 * i40iw_config_fpm_values - configure HMC objects
 * @dev: sc device struct
 * @qp_count: desired qp count
 */
enum i40iw_status_code i40iw_config_fpm_values(struct i40iw_sc_dev *dev, u32 qp_count)
{
	struct i40iw_virt_mem virt_mem;
	u32 i, mem_size;
	u32 qpwantedoriginal, qpwanted, mrwanted, pblewanted;
	u64 sd_needed;
	u32 loop_count = 0;

	struct i40iw_hmc_info *hmc_info;
	struct i40iw_hmc_fpm_misc *hmc_fpm_misc;
	enum i40iw_status_code ret_code = 0;

	hmc_info = dev->hmc_info;
	hmc_fpm_misc = &dev->hmc_fpm_misc;

	ret_code = i40iw_sc_init_iw_hmc(dev, dev->hmc_fn_id);
	if (ret_code) {
		i40iw_debug(dev, I40IW_DEBUG_HMC,
			    "i40iw_sc_init_iw_hmc returned error_code = %d\n",
			    ret_code);
		return ret_code;
	}

	for (i = I40IW_HMC_IW_QP; i < I40IW_HMC_IW_MAX; i++)
		hmc_info->hmc_obj[i].cnt = hmc_info->hmc_obj[i].max_cnt;
	sd_needed = i40iw_est_sd(dev, hmc_info);
	i40iw_debug(dev, I40IW_DEBUG_HMC,
		    "%s: FW initial max sd_count[%08lld] first_sd_index[%04d]\n",
		    __func__, sd_needed, hmc_info->first_sd_index);
	i40iw_debug(dev, I40IW_DEBUG_HMC,
		    "%s: sd count %d where max sd is %d\n",
		    __func__, hmc_info->sd_table.sd_cnt,
		    hmc_fpm_misc->max_sds);

	qpwanted = min(qp_count, hmc_info->hmc_obj[I40IW_HMC_IW_QP].max_cnt);
	qpwantedoriginal = qpwanted;
	mrwanted = hmc_info->hmc_obj[I40IW_HMC_IW_MR].max_cnt;
	pblewanted = hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].max_cnt;

	i40iw_debug(dev, I40IW_DEBUG_HMC,
		    "req_qp=%d max_sd=%d, max_qp = %d, max_cq=%d, max_mr=%d, max_pble=%d\n",
		    qp_count, hmc_fpm_misc->max_sds,
		    hmc_info->hmc_obj[I40IW_HMC_IW_QP].max_cnt,
		    hmc_info->hmc_obj[I40IW_HMC_IW_CQ].max_cnt,
		    hmc_info->hmc_obj[I40IW_HMC_IW_MR].max_cnt,
		    hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].max_cnt);

	do {
		++loop_count;
		hmc_info->hmc_obj[I40IW_HMC_IW_QP].cnt = qpwanted;
		hmc_info->hmc_obj[I40IW_HMC_IW_CQ].cnt =
			min(2 * qpwanted, hmc_info->hmc_obj[I40IW_HMC_IW_CQ].cnt);
		hmc_info->hmc_obj[I40IW_HMC_IW_SRQ].cnt = 0x00; /* Reserved */
		hmc_info->hmc_obj[I40IW_HMC_IW_HTE].cnt =
					qpwanted * hmc_fpm_misc->ht_multiplier;
		hmc_info->hmc_obj[I40IW_HMC_IW_ARP].cnt =
			hmc_info->hmc_obj[I40IW_HMC_IW_ARP].max_cnt;
		hmc_info->hmc_obj[I40IW_HMC_IW_APBVT_ENTRY].cnt = 1;
		hmc_info->hmc_obj[I40IW_HMC_IW_MR].cnt = mrwanted;

		hmc_info->hmc_obj[I40IW_HMC_IW_XF].cnt =
			roundup_pow_of_two(I40IW_MAX_WQ_ENTRIES * qpwanted);
		hmc_info->hmc_obj[I40IW_HMC_IW_Q1].cnt =
			roundup_pow_of_two(2 * I40IW_MAX_IRD_SIZE * qpwanted);
		hmc_info->hmc_obj[I40IW_HMC_IW_XFFL].cnt =
			hmc_info->hmc_obj[I40IW_HMC_IW_XF].cnt / hmc_fpm_misc->xf_block_size;
		hmc_info->hmc_obj[I40IW_HMC_IW_Q1FL].cnt =
			hmc_info->hmc_obj[I40IW_HMC_IW_Q1].cnt / hmc_fpm_misc->q1_block_size;
		hmc_info->hmc_obj[I40IW_HMC_IW_TIMER].cnt =
			((qpwanted) / 512 + 1) * hmc_fpm_misc->timer_bucket;
		hmc_info->hmc_obj[I40IW_HMC_IW_FSIMC].cnt = 0x00;
		hmc_info->hmc_obj[I40IW_HMC_IW_FSIAV].cnt = 0x00;
		hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt = pblewanted;

		/* How much memory is needed for all the objects. */
		sd_needed = i40iw_est_sd(dev, hmc_info);
		if ((loop_count > 1000) ||
		    ((!(loop_count % 10)) &&
		    (qpwanted > qpwantedoriginal * 2 / 3))) {
			if (qpwanted > FPM_MULTIPLIER)
				qpwanted = roundup_pow_of_two(qpwanted -
							      FPM_MULTIPLIER);
			qpwanted >>= 1;
		}
		if (mrwanted > FPM_MULTIPLIER * 10)
			mrwanted -= FPM_MULTIPLIER * 10;
		if (pblewanted > FPM_MULTIPLIER * 1000)
			pblewanted -= FPM_MULTIPLIER * 1000;
	} while (sd_needed > hmc_fpm_misc->max_sds && loop_count < 2000);

	i40iw_debug(dev, I40IW_DEBUG_HMC,
		    "loop_cnt=%d, sd_needed=%lld, qpcnt = %d, cqcnt=%d, mrcnt=%d, pblecnt=%d\n",
		    loop_count, sd_needed,
		    hmc_info->hmc_obj[I40IW_HMC_IW_QP].cnt,
		    hmc_info->hmc_obj[I40IW_HMC_IW_CQ].cnt,
		    hmc_info->hmc_obj[I40IW_HMC_IW_MR].cnt,
		    hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].cnt);

	ret_code = i40iw_sc_configure_iw_fpm(dev, dev->hmc_fn_id);
	if (ret_code) {
		i40iw_debug(dev, I40IW_DEBUG_HMC,
			    "configure_iw_fpm returned error_code[x%08X]\n",
			    i40iw_rd32(dev->hw, dev->is_pf ? I40E_PFPE_CQPERRCODES : I40E_VFPE_CQPERRCODES1));
		return ret_code;
	}

	mem_size = sizeof(struct i40iw_hmc_sd_entry) *
		   (hmc_info->sd_table.sd_cnt + hmc_info->first_sd_index + 1);
	ret_code = i40iw_allocate_virt_mem(dev->hw, &virt_mem, mem_size);
	if (ret_code) {
		i40iw_debug(dev, I40IW_DEBUG_HMC,
			    "%s: failed to allocate memory for sd_entry buffer\n",
			    __func__);
		return ret_code;
	}
	hmc_info->sd_table.sd_entry = virt_mem.va;

	return ret_code;
}

/**
 * i40iw_exec_cqp_cmd - execute cqp cmd when wqe are available
 * @dev: rdma device
 * @pcmdinfo: cqp command info
 */
static enum i40iw_status_code i40iw_exec_cqp_cmd(struct i40iw_sc_dev *dev,
						 struct cqp_commands_info *pcmdinfo)
{
	enum i40iw_status_code status;
	struct i40iw_dma_mem values_mem;

	dev->cqp_cmd_stats[pcmdinfo->cqp_cmd]++;
	switch (pcmdinfo->cqp_cmd) {
	case OP_DELETE_LOCAL_MAC_IPADDR_ENTRY:
		status = i40iw_sc_del_local_mac_ipaddr_entry(
				pcmdinfo->in.u.del_local_mac_ipaddr_entry.cqp,
				pcmdinfo->in.u.del_local_mac_ipaddr_entry.scratch,
				pcmdinfo->in.u.del_local_mac_ipaddr_entry.entry_idx,
				pcmdinfo->in.u.del_local_mac_ipaddr_entry.ignore_ref_count,
				pcmdinfo->post_sq);
		break;
	case OP_CEQ_DESTROY:
		status = i40iw_sc_ceq_destroy(pcmdinfo->in.u.ceq_destroy.ceq,
					      pcmdinfo->in.u.ceq_destroy.scratch,
					      pcmdinfo->post_sq);
		break;
	case OP_AEQ_DESTROY:
		status = i40iw_sc_aeq_destroy(pcmdinfo->in.u.aeq_destroy.aeq,
					      pcmdinfo->in.u.aeq_destroy.scratch,
					      pcmdinfo->post_sq);

		break;
	case OP_DELETE_ARP_CACHE_ENTRY:
		status = i40iw_sc_del_arp_cache_entry(
				pcmdinfo->in.u.del_arp_cache_entry.cqp,
				pcmdinfo->in.u.del_arp_cache_entry.scratch,
				pcmdinfo->in.u.del_arp_cache_entry.arp_index,
				pcmdinfo->post_sq);
		break;
	case OP_MANAGE_APBVT_ENTRY:
		status = i40iw_sc_manage_apbvt_entry(
				pcmdinfo->in.u.manage_apbvt_entry.cqp,
				&pcmdinfo->in.u.manage_apbvt_entry.info,
				pcmdinfo->in.u.manage_apbvt_entry.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_CEQ_CREATE:
		status = i40iw_sc_ceq_create(pcmdinfo->in.u.ceq_create.ceq,
					     pcmdinfo->in.u.ceq_create.scratch,
					     pcmdinfo->post_sq);
		break;
	case OP_AEQ_CREATE:
		status = i40iw_sc_aeq_create(pcmdinfo->in.u.aeq_create.aeq,
					     pcmdinfo->in.u.aeq_create.scratch,
					     pcmdinfo->post_sq);
		break;
	case OP_ALLOC_LOCAL_MAC_IPADDR_ENTRY:
		status = i40iw_sc_alloc_local_mac_ipaddr_entry(
				pcmdinfo->in.u.alloc_local_mac_ipaddr_entry.cqp,
				pcmdinfo->in.u.alloc_local_mac_ipaddr_entry.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_ADD_LOCAL_MAC_IPADDR_ENTRY:
		status = i40iw_sc_add_local_mac_ipaddr_entry(
				pcmdinfo->in.u.add_local_mac_ipaddr_entry.cqp,
				&pcmdinfo->in.u.add_local_mac_ipaddr_entry.info,
				pcmdinfo->in.u.add_local_mac_ipaddr_entry.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_MANAGE_QHASH_TABLE_ENTRY:
		status = i40iw_sc_manage_qhash_table_entry(
				pcmdinfo->in.u.manage_qhash_table_entry.cqp,
				&pcmdinfo->in.u.manage_qhash_table_entry.info,
				pcmdinfo->in.u.manage_qhash_table_entry.scratch,
				pcmdinfo->post_sq);

		break;
	case OP_QP_MODIFY:
		status = i40iw_sc_qp_modify(
				pcmdinfo->in.u.qp_modify.qp,
				&pcmdinfo->in.u.qp_modify.info,
				pcmdinfo->in.u.qp_modify.scratch,
				pcmdinfo->post_sq);

		break;
	case OP_QP_UPLOAD_CONTEXT:
		status = i40iw_sc_qp_upload_context(
				pcmdinfo->in.u.qp_upload_context.dev,
				&pcmdinfo->in.u.qp_upload_context.info,
				pcmdinfo->in.u.qp_upload_context.scratch,
				pcmdinfo->post_sq);

		break;
	case OP_CQ_CREATE:
		status = i40iw_sc_cq_create(
				pcmdinfo->in.u.cq_create.cq,
				pcmdinfo->in.u.cq_create.scratch,
				pcmdinfo->in.u.cq_create.check_overflow,
				pcmdinfo->post_sq);
		break;
	case OP_CQ_DESTROY:
		status = i40iw_sc_cq_destroy(
				pcmdinfo->in.u.cq_destroy.cq,
				pcmdinfo->in.u.cq_destroy.scratch,
				pcmdinfo->post_sq);

		break;
	case OP_QP_CREATE:
		status = i40iw_sc_qp_create(
				pcmdinfo->in.u.qp_create.qp,
				&pcmdinfo->in.u.qp_create.info,
				pcmdinfo->in.u.qp_create.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_QP_DESTROY:
		status = i40iw_sc_qp_destroy(
				pcmdinfo->in.u.qp_destroy.qp,
				pcmdinfo->in.u.qp_destroy.scratch,
				pcmdinfo->in.u.qp_destroy.remove_hash_idx,
				pcmdinfo->in.u.qp_destroy.
				ignore_mw_bnd,
				pcmdinfo->post_sq);

		break;
	case OP_ALLOC_STAG:
		status = i40iw_sc_alloc_stag(
				pcmdinfo->in.u.alloc_stag.dev,
				&pcmdinfo->in.u.alloc_stag.info,
				pcmdinfo->in.u.alloc_stag.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_MR_REG_NON_SHARED:
		status = i40iw_sc_mr_reg_non_shared(
				pcmdinfo->in.u.mr_reg_non_shared.dev,
				&pcmdinfo->in.u.mr_reg_non_shared.info,
				pcmdinfo->in.u.mr_reg_non_shared.scratch,
				pcmdinfo->post_sq);

		break;
	case OP_DEALLOC_STAG:
		status = i40iw_sc_dealloc_stag(
				pcmdinfo->in.u.dealloc_stag.dev,
				&pcmdinfo->in.u.dealloc_stag.info,
				pcmdinfo->in.u.dealloc_stag.scratch,
				pcmdinfo->post_sq);

		break;
	case OP_MW_ALLOC:
		status = i40iw_sc_mw_alloc(
				pcmdinfo->in.u.mw_alloc.dev,
				pcmdinfo->in.u.mw_alloc.scratch,
				pcmdinfo->in.u.mw_alloc.mw_stag_index,
				pcmdinfo->in.u.mw_alloc.pd_id,
				pcmdinfo->post_sq);

		break;
	case OP_QP_FLUSH_WQES:
		status = i40iw_sc_qp_flush_wqes(
				pcmdinfo->in.u.qp_flush_wqes.qp,
				&pcmdinfo->in.u.qp_flush_wqes.info,
				pcmdinfo->in.u.qp_flush_wqes.
				scratch, pcmdinfo->post_sq);
		break;
	case OP_GEN_AE:
		status = i40iw_sc_gen_ae(
				pcmdinfo->in.u.gen_ae.qp,
				&pcmdinfo->in.u.gen_ae.info,
				pcmdinfo->in.u.gen_ae.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_ADD_ARP_CACHE_ENTRY:
		status = i40iw_sc_add_arp_cache_entry(
				pcmdinfo->in.u.add_arp_cache_entry.cqp,
				&pcmdinfo->in.u.add_arp_cache_entry.info,
				pcmdinfo->in.u.add_arp_cache_entry.scratch,
				pcmdinfo->post_sq);
		break;
	case OP_UPDATE_PE_SDS:
		/* case I40IW_CQP_OP_UPDATE_PE_SDS */
		status = i40iw_update_pe_sds(
				pcmdinfo->in.u.update_pe_sds.dev,
				&pcmdinfo->in.u.update_pe_sds.info,
				pcmdinfo->in.u.update_pe_sds.
				scratch);

		break;
	case OP_MANAGE_HMC_PM_FUNC_TABLE:
		status = i40iw_sc_manage_hmc_pm_func_table(
				pcmdinfo->in.u.manage_hmc_pm.dev->cqp,
				pcmdinfo->in.u.manage_hmc_pm.scratch,
				(u8)pcmdinfo->in.u.manage_hmc_pm.info.vf_id,
				pcmdinfo->in.u.manage_hmc_pm.info.free_fcn,
				true);
		break;
	case OP_SUSPEND:
		status = i40iw_sc_suspend_qp(
				pcmdinfo->in.u.suspend_resume.cqp,
				pcmdinfo->in.u.suspend_resume.qp,
				pcmdinfo->in.u.suspend_resume.scratch);
		break;
	case OP_RESUME:
		status = i40iw_sc_resume_qp(
				pcmdinfo->in.u.suspend_resume.cqp,
				pcmdinfo->in.u.suspend_resume.qp,
				pcmdinfo->in.u.suspend_resume.scratch);
		break;
	case OP_MANAGE_VF_PBLE_BP:
		status = i40iw_manage_vf_pble_bp(
				pcmdinfo->in.u.manage_vf_pble_bp.cqp,
				&pcmdinfo->in.u.manage_vf_pble_bp.info,
				pcmdinfo->in.u.manage_vf_pble_bp.scratch, true);
		break;
	case OP_QUERY_FPM_VALUES:
		values_mem.pa = pcmdinfo->in.u.query_fpm_values.fpm_values_pa;
		values_mem.va = pcmdinfo->in.u.query_fpm_values.fpm_values_va;
		status = i40iw_sc_query_fpm_values(
				pcmdinfo->in.u.query_fpm_values.cqp,
				pcmdinfo->in.u.query_fpm_values.scratch,
				pcmdinfo->in.u.query_fpm_values.hmc_fn_id,
				&values_mem, true, I40IW_CQP_WAIT_EVENT);
		break;
	case OP_COMMIT_FPM_VALUES:
		values_mem.pa = pcmdinfo->in.u.commit_fpm_values.fpm_values_pa;
		values_mem.va = pcmdinfo->in.u.commit_fpm_values.fpm_values_va;
		status = i40iw_sc_commit_fpm_values(
				pcmdinfo->in.u.commit_fpm_values.cqp,
				pcmdinfo->in.u.commit_fpm_values.scratch,
				pcmdinfo->in.u.commit_fpm_values.hmc_fn_id,
				&values_mem,
				true,
				I40IW_CQP_WAIT_EVENT);
		break;
	case OP_QUERY_RDMA_FEATURES:
		values_mem.pa = pcmdinfo->in.u.query_rdma_features.cap_pa;
		values_mem.va = pcmdinfo->in.u.query_rdma_features.cap_va;
		status = i40iw_sc_query_rdma_features(
			pcmdinfo->in.u.query_rdma_features.cqp, &values_mem,
			pcmdinfo->in.u.query_rdma_features.scratch);
		break;
	default:
		status = I40IW_NOT_SUPPORTED;
		break;
	}

	return status;
}

/**
 * i40iw_process_cqp_cmd - process all cqp commands
 * @dev: sc device struct
 * @pcmdinfo: cqp command info
 */
enum i40iw_status_code i40iw_process_cqp_cmd(struct i40iw_sc_dev *dev,
					     struct cqp_commands_info *pcmdinfo)
{
	enum i40iw_status_code status = 0;
	unsigned long flags;

	spin_lock_irqsave(&dev->cqp_lock, flags);
	if (list_empty(&dev->cqp_cmd_head) && !i40iw_ring_full(dev->cqp))
		status = i40iw_exec_cqp_cmd(dev, pcmdinfo);
	else
		list_add_tail(&pcmdinfo->cqp_cmd_entry, &dev->cqp_cmd_head);
	spin_unlock_irqrestore(&dev->cqp_lock, flags);
	return status;
}

/**
 * i40iw_process_bh - called from tasklet for cqp list
 * @dev: sc device struct
 */
enum i40iw_status_code i40iw_process_bh(struct i40iw_sc_dev *dev)
{
	enum i40iw_status_code status = 0;
	struct cqp_commands_info *pcmdinfo;
	unsigned long flags;

	spin_lock_irqsave(&dev->cqp_lock, flags);
	while (!list_empty(&dev->cqp_cmd_head) && !i40iw_ring_full(dev->cqp)) {
		pcmdinfo = (struct cqp_commands_info *)i40iw_remove_head(&dev->cqp_cmd_head);

		status = i40iw_exec_cqp_cmd(dev, pcmdinfo);
		if (status)
			break;
	}
	spin_unlock_irqrestore(&dev->cqp_lock, flags);
	return status;
}

/**
 * i40iw_iwarp_opcode - determine if incoming is rdma layer
 * @info: aeq info for the packet
 * @pkt: packet for error
 */
static u32 i40iw_iwarp_opcode(struct i40iw_aeqe_info *info, u8 *pkt)
{
	__be16 *mpa;
	u32 opcode = 0xffffffff;

	if (info->q2_data_written) {
		mpa = (__be16 *)pkt;
		opcode = ntohs(mpa[1]) & 0xf;
	}
	return opcode;
}

/**
 * i40iw_locate_mpa - return pointer to mpa in the pkt
 * @pkt: packet with data
 */
static u8 *i40iw_locate_mpa(u8 *pkt)
{
	/* skip over ethernet header */
	pkt += I40IW_MAC_HLEN;

	/* Skip over IP and TCP headers */
	pkt += 4 * (pkt[0] & 0x0f);
	pkt += 4 * ((pkt[12] >> 4) & 0x0f);
	return pkt;
}

/**
 * i40iw_setup_termhdr - termhdr for terminate pkt
 * @qp: sc qp ptr for pkt
 * @hdr: term hdr
 * @opcode: flush opcode for termhdr
 * @layer_etype: error layer + error type
 * @err: error cod ein the header
 */
static void i40iw_setup_termhdr(struct i40iw_sc_qp *qp,
				struct i40iw_terminate_hdr *hdr,
				enum i40iw_flush_opcode opcode,
				u8 layer_etype,
				u8 err)
{
	qp->flush_code = opcode;
	hdr->layer_etype = layer_etype;
	hdr->error_code = err;
}

/**
 * i40iw_bld_terminate_hdr - build terminate message header
 * @qp: qp associated with received terminate AE
 * @info: the struct contiaing AE information
 */
static int i40iw_bld_terminate_hdr(struct i40iw_sc_qp *qp,
				   struct i40iw_aeqe_info *info)
{
	u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET;
	u16 ddp_seg_len;
	int copy_len = 0;
	u8 is_tagged = 0;
	u32 opcode;
	struct i40iw_terminate_hdr *termhdr;

	termhdr = (struct i40iw_terminate_hdr *)qp->q2_buf;
	memset(termhdr, 0, Q2_BAD_FRAME_OFFSET);

	if (info->q2_data_written) {
		/* Use data from offending packet to fill in ddp & rdma hdrs */
		pkt = i40iw_locate_mpa(pkt);
		ddp_seg_len = ntohs(*(__be16 *)pkt);
		if (ddp_seg_len) {
			copy_len = 2;
			termhdr->hdrct = DDP_LEN_FLAG;
			if (pkt[2] & 0x80) {
				is_tagged = 1;
				if (ddp_seg_len >= TERM_DDP_LEN_TAGGED) {
					copy_len += TERM_DDP_LEN_TAGGED;
					termhdr->hdrct |= DDP_HDR_FLAG;
				}
			} else {
				if (ddp_seg_len >= TERM_DDP_LEN_UNTAGGED) {
					copy_len += TERM_DDP_LEN_UNTAGGED;
					termhdr->hdrct |= DDP_HDR_FLAG;
				}

				if (ddp_seg_len >= (TERM_DDP_LEN_UNTAGGED + TERM_RDMA_LEN)) {
					if ((pkt[3] & RDMA_OPCODE_MASK) == RDMA_READ_REQ_OPCODE) {
						copy_len += TERM_RDMA_LEN;
						termhdr->hdrct |= RDMA_HDR_FLAG;
					}
				}
			}
		}
	}

	opcode = i40iw_iwarp_opcode(info, pkt);

	switch (info->ae_id) {
	case I40IW_AE_AMP_UNALLOCATED_STAG:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		if (opcode == I40IW_OP_TYPE_RDMA_WRITE)
			i40iw_setup_termhdr(qp, termhdr, FLUSH_PROT_ERR,
					    (LAYER_DDP << 4) | DDP_TAGGED_BUFFER, DDP_TAGGED_INV_STAG);
		else
			i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
					    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_INV_STAG);
		break;
	case I40IW_AE_AMP_BOUNDS_VIOLATION:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		if (info->q2_data_written)
			i40iw_setup_termhdr(qp, termhdr, FLUSH_PROT_ERR,
					    (LAYER_DDP << 4) | DDP_TAGGED_BUFFER, DDP_TAGGED_BOUNDS);
		else
			i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
					    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_INV_BOUNDS);
		break;
	case I40IW_AE_AMP_BAD_PD:
		switch (opcode) {
		case I40IW_OP_TYPE_RDMA_WRITE:
			i40iw_setup_termhdr(qp, termhdr, FLUSH_PROT_ERR,
					    (LAYER_DDP << 4) | DDP_TAGGED_BUFFER, DDP_TAGGED_UNASSOC_STAG);
			break;
		case I40IW_OP_TYPE_SEND_INV:
		case I40IW_OP_TYPE_SEND_SOL_INV:
			i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
					    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_CANT_INV_STAG);
			break;
		default:
			i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
					    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_UNASSOC_STAG);
		}
		break;
	case I40IW_AE_AMP_INVALID_STAG:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
				    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_INV_STAG);
		break;
	case I40IW_AE_AMP_BAD_QP:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_LOC_QP_OP_ERR,
				    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_QN);
		break;
	case I40IW_AE_AMP_BAD_STAG_KEY:
	case I40IW_AE_AMP_BAD_STAG_INDEX:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		switch (opcode) {
		case I40IW_OP_TYPE_SEND_INV:
		case I40IW_OP_TYPE_SEND_SOL_INV:
			i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_OP_ERR,
					    (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, RDMAP_CANT_INV_STAG);
			break;
		default:
			i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
					    (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, RDMAP_INV_STAG);
		}
		break;
	case I40IW_AE_AMP_RIGHTS_VIOLATION:
	case I40IW_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
	case I40IW_AE_PRIV_OPERATION_DENIED:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
				    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_ACCESS);
		break;
	case I40IW_AE_AMP_TO_WRAP:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR,
				    (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_TO_WRAP);
		break;
	case I40IW_AE_LLP_RECEIVED_MPA_CRC_ERROR:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
				    (LAYER_MPA << 4) | DDP_LLP, MPA_CRC);
		break;
	case I40IW_AE_LLP_SEGMENT_TOO_LARGE:
	case I40IW_AE_LLP_SEGMENT_TOO_SMALL:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_LOC_LEN_ERR,
				    (LAYER_DDP << 4) | DDP_CATASTROPHIC, DDP_CATASTROPHIC_LOCAL);
		break;
	case I40IW_AE_LCE_QP_CATASTROPHIC:
	case I40IW_AE_DDP_NO_L_BIT:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_FATAL_ERR,
				    (LAYER_DDP << 4) | DDP_CATASTROPHIC, DDP_CATASTROPHIC_LOCAL);
		break;
	case I40IW_AE_DDP_INVALID_MSN_GAP_IN_MSN:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
				    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_MSN_RANGE);
		break;
	case I40IW_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
		qp->eventtype = TERM_EVENT_QP_ACCESS_ERR;
		i40iw_setup_termhdr(qp, termhdr, FLUSH_LOC_LEN_ERR,
				    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_TOO_LONG);
		break;
	case I40IW_AE_DDP_UBE_INVALID_DDP_VERSION:
		if (is_tagged)
			i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
					    (LAYER_DDP << 4) | DDP_TAGGED_BUFFER, DDP_TAGGED_INV_DDP_VER);
		else
			i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
					    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_DDP_VER);
		break;
	case I40IW_AE_DDP_UBE_INVALID_MO:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
				    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_MO);
		break;
	case I40IW_AE_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_OP_ERR,
				    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_MSN_NO_BUF);
		break;
	case I40IW_AE_DDP_UBE_INVALID_QN:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
				    (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_QN);
		break;
	case I40IW_AE_RDMAP_ROE_INVALID_RDMAP_VERSION:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR,
				    (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, RDMAP_INV_RDMAP_VER);
		break;
	case I40IW_AE_RDMAP_ROE_UNEXPECTED_OPCODE:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_LOC_QP_OP_ERR,
				    (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, RDMAP_UNEXPECTED_OP);
		break;
	default:
		i40iw_setup_termhdr(qp, termhdr, FLUSH_FATAL_ERR,
				    (LAYER_RDMA << 4) | RDMAP_REMOTE_OP, RDMAP_UNSPECIFIED);
		break;
	}

	if (copy_len)
		memcpy(termhdr + 1, pkt, copy_len);

	return sizeof(struct i40iw_terminate_hdr) + copy_len;
}

/**
 * i40iw_terminate_send_fin() - Send fin for terminate message
 * @qp: qp associated with received terminate AE
 */
void i40iw_terminate_send_fin(struct i40iw_sc_qp *qp)
{
	/* Send the fin only */
	i40iw_term_modify_qp(qp,
			     I40IW_QP_STATE_TERMINATE,
			     I40IWQP_TERM_SEND_FIN_ONLY,
			     0);
}

/**
 * i40iw_terminate_connection() - Bad AE and send terminate to remote QP
 * @qp: qp associated with received terminate AE
 * @info: the struct contiaing AE information
 */
void i40iw_terminate_connection(struct i40iw_sc_qp *qp, struct i40iw_aeqe_info *info)
{
	u8 termlen = 0;

	if (qp->term_flags & I40IW_TERM_SENT)
		return;         /* Sanity check */

	/* Eventtype can change from bld_terminate_hdr */
	qp->eventtype = TERM_EVENT_QP_FATAL;
	termlen = i40iw_bld_terminate_hdr(qp, info);
	i40iw_terminate_start_timer(qp);
	qp->term_flags |= I40IW_TERM_SENT;
	i40iw_term_modify_qp(qp, I40IW_QP_STATE_TERMINATE,
			     I40IWQP_TERM_SEND_TERM_ONLY, termlen);
}

/**
 * i40iw_terminate_received - handle terminate received AE
 * @qp: qp associated with received terminate AE
 * @info: the struct contiaing AE information
 */
void i40iw_terminate_received(struct i40iw_sc_qp *qp, struct i40iw_aeqe_info *info)
{
	u8 *pkt = qp->q2_buf + Q2_BAD_FRAME_OFFSET;
	__be32 *mpa;
	u8 ddp_ctl;
	u8 rdma_ctl;
	u16 aeq_id = 0;
	struct i40iw_terminate_hdr *termhdr;

	mpa = (__be32 *)i40iw_locate_mpa(pkt);
	if (info->q2_data_written) {
		/* did not validate the frame - do it now */
		ddp_ctl = (ntohl(mpa[0]) >> 8) & 0xff;
		rdma_ctl = ntohl(mpa[0]) & 0xff;
		if ((ddp_ctl & 0xc0) != 0x40)
			aeq_id = I40IW_AE_LCE_QP_CATASTROPHIC;
		else if ((ddp_ctl & 0x03) != 1)
			aeq_id = I40IW_AE_DDP_UBE_INVALID_DDP_VERSION;
		else if (ntohl(mpa[2]) != 2)
			aeq_id = I40IW_AE_DDP_UBE_INVALID_QN;
		else if (ntohl(mpa[3]) != 1)
			aeq_id = I40IW_AE_DDP_INVALID_MSN_GAP_IN_MSN;
		else if (ntohl(mpa[4]) != 0)
			aeq_id = I40IW_AE_DDP_UBE_INVALID_MO;
		else if ((rdma_ctl & 0xc0) != 0x40)
			aeq_id = I40IW_AE_RDMAP_ROE_INVALID_RDMAP_VERSION;

		info->ae_id = aeq_id;
		if (info->ae_id) {
			/* Bad terminate recvd - send back a terminate */
			i40iw_terminate_connection(qp, info);
			return;
		}
	}

	qp->term_flags |= I40IW_TERM_RCVD;
	qp->eventtype = TERM_EVENT_QP_FATAL;
	termhdr = (struct i40iw_terminate_hdr *)&mpa[5];
	if (termhdr->layer_etype == RDMAP_REMOTE_PROT ||
	    termhdr->layer_etype == RDMAP_REMOTE_OP) {
		i40iw_terminate_done(qp, 0);
	} else {
		i40iw_terminate_start_timer(qp);
		i40iw_terminate_send_fin(qp);
	}
}

/**
 * i40iw_sc_vsi_init - Initialize virtual device
 * @vsi: pointer to the vsi structure
 * @info: parameters to initialize vsi
 **/
void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *info)
{
	int i;

	vsi->dev = info->dev;
	vsi->back_vsi = info->back_vsi;
	vsi->mtu = info->params->mtu;
	vsi->exception_lan_queue = info->exception_lan_queue;
	i40iw_fill_qos_list(info->params->qs_handle_list);

	for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) {
		vsi->qos[i].qs_handle = info->params->qs_handle_list[i];
		i40iw_debug(vsi->dev, I40IW_DEBUG_DCB, "qset[%d]: %d\n", i,
			    vsi->qos[i].qs_handle);
		spin_lock_init(&vsi->qos[i].lock);
		INIT_LIST_HEAD(&vsi->qos[i].qplist);
	}
}

/**
 * i40iw_hw_stats_init - Initiliaze HW stats table
 * @stats: pestat struct
 * @fcn_idx: PCI fn id
 * @is_pf: Is it a PF?
 *
 * Populate the HW stats table with register offset addr for each
 * stats. And start the perioidic stats timer.
 */
void i40iw_hw_stats_init(struct i40iw_vsi_pestat *stats, u8 fcn_idx, bool is_pf)
{
	u32 stats_reg_offset;
	u32 stats_index;
	struct i40iw_dev_hw_stats_offsets *stats_table =
		&stats->hw_stats_offsets;
	struct i40iw_dev_hw_stats *last_rd_stats = &stats->last_read_hw_stats;

	if (is_pf) {
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXDISCARD] =
				I40E_GLPES_PFIP4RXDISCARD(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXTRUNC] =
				I40E_GLPES_PFIP4RXTRUNC(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4TXNOROUTE] =
				I40E_GLPES_PFIP4TXNOROUTE(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXDISCARD] =
				I40E_GLPES_PFIP6RXDISCARD(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXTRUNC] =
				I40E_GLPES_PFIP6RXTRUNC(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6TXNOROUTE] =
				I40E_GLPES_PFIP6TXNOROUTE(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRTXSEG] =
				I40E_GLPES_PFTCPRTXSEG(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXOPTERR] =
				I40E_GLPES_PFTCPRXOPTERR(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXPROTOERR] =
				I40E_GLPES_PFTCPRXPROTOERR(fcn_idx);

		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXOCTS] =
				I40E_GLPES_PFIP4RXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXPKTS] =
				I40E_GLPES_PFIP4RXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXFRAGS] =
				I40E_GLPES_PFIP4RXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXMCPKTS] =
				I40E_GLPES_PFIP4RXMCPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXOCTS] =
				I40E_GLPES_PFIP4TXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXPKTS] =
				I40E_GLPES_PFIP4TXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXFRAGS] =
				I40E_GLPES_PFIP4TXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXMCPKTS] =
				I40E_GLPES_PFIP4TXMCPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXOCTS] =
				I40E_GLPES_PFIP6RXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXPKTS] =
				I40E_GLPES_PFIP6RXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXFRAGS] =
				I40E_GLPES_PFIP6RXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXMCPKTS] =
				I40E_GLPES_PFIP6RXMCPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXOCTS] =
				I40E_GLPES_PFIP6TXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
				I40E_GLPES_PFIP6TXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
				I40E_GLPES_PFIP6TXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXFRAGS] =
				I40E_GLPES_PFIP6TXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPRXSEGS] =
				I40E_GLPES_PFTCPRXSEGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPTXSEG] =
				I40E_GLPES_PFTCPTXSEGLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXRDS] =
				I40E_GLPES_PFRDMARXRDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXSNDS] =
				I40E_GLPES_PFRDMARXSNDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXWRS] =
				I40E_GLPES_PFRDMARXWRSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXRDS] =
				I40E_GLPES_PFRDMATXRDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXSNDS] =
				I40E_GLPES_PFRDMATXSNDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXWRS] =
				I40E_GLPES_PFRDMATXWRSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVBND] =
				I40E_GLPES_PFRDMAVBNDLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVINV] =
				I40E_GLPES_PFRDMAVINVLO(fcn_idx);
	} else {
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXDISCARD] =
				I40E_GLPES_VFIP4RXDISCARD(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXTRUNC] =
				I40E_GLPES_VFIP4RXTRUNC(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4TXNOROUTE] =
				I40E_GLPES_VFIP4TXNOROUTE(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXDISCARD] =
				I40E_GLPES_VFIP6RXDISCARD(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXTRUNC] =
				I40E_GLPES_VFIP6RXTRUNC(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6TXNOROUTE] =
				I40E_GLPES_VFIP6TXNOROUTE(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRTXSEG] =
				I40E_GLPES_VFTCPRTXSEG(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXOPTERR] =
				I40E_GLPES_VFTCPRXOPTERR(fcn_idx);
		stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXPROTOERR] =
				I40E_GLPES_VFTCPRXPROTOERR(fcn_idx);

		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXOCTS] =
				I40E_GLPES_VFIP4RXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXPKTS] =
				I40E_GLPES_VFIP4RXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXFRAGS] =
				I40E_GLPES_VFIP4RXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXMCPKTS] =
				I40E_GLPES_VFIP4RXMCPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXOCTS] =
				I40E_GLPES_VFIP4TXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXPKTS] =
				I40E_GLPES_VFIP4TXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXFRAGS] =
				I40E_GLPES_VFIP4TXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXMCPKTS] =
				I40E_GLPES_VFIP4TXMCPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXOCTS] =
				I40E_GLPES_VFIP6RXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXPKTS] =
				I40E_GLPES_VFIP6RXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXFRAGS] =
				I40E_GLPES_VFIP6RXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXMCPKTS] =
				I40E_GLPES_VFIP6RXMCPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXOCTS] =
				I40E_GLPES_VFIP6TXOCTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
				I40E_GLPES_VFIP6TXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
				I40E_GLPES_VFIP6TXPKTSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXFRAGS] =
				I40E_GLPES_VFIP6TXFRAGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPRXSEGS] =
				I40E_GLPES_VFTCPRXSEGSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPTXSEG] =
				I40E_GLPES_VFTCPTXSEGLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXRDS] =
				I40E_GLPES_VFRDMARXRDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXSNDS] =
				I40E_GLPES_VFRDMARXSNDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXWRS] =
				I40E_GLPES_VFRDMARXWRSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXRDS] =
				I40E_GLPES_VFRDMATXRDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXSNDS] =
				I40E_GLPES_VFRDMATXSNDSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXWRS] =
				I40E_GLPES_VFRDMATXWRSLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVBND] =
				I40E_GLPES_VFRDMAVBNDLO(fcn_idx);
		stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVINV] =
				I40E_GLPES_VFRDMAVINVLO(fcn_idx);
	}

	for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_64;
	     stats_index++) {
		stats_reg_offset = stats_table->stats_offset_64[stats_index];
		last_rd_stats->stats_value_64[stats_index] =
			readq(stats->hw->hw_addr + stats_reg_offset);
	}

	for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_32;
	     stats_index++) {
		stats_reg_offset = stats_table->stats_offset_32[stats_index];
		last_rd_stats->stats_value_32[stats_index] =
			i40iw_rd32(stats->hw, stats_reg_offset);
	}
}

/**
 * i40iw_hw_stats_read_32 - Read 32-bit HW stats counters and accommodates for roll-overs.
 * @stats: pestat struct
 * @index: index in HW stats table which contains offset reg-addr
 * @value: hw stats value
 */
void i40iw_hw_stats_read_32(struct i40iw_vsi_pestat *stats,
			    enum i40iw_hw_stats_index_32b index,
			    u64 *value)
{
	struct i40iw_dev_hw_stats_offsets *stats_table =
		&stats->hw_stats_offsets;
	struct i40iw_dev_hw_stats *last_rd_stats = &stats->last_read_hw_stats;
	struct i40iw_dev_hw_stats *hw_stats = &stats->hw_stats;
	u64 new_stats_value = 0;
	u32 stats_reg_offset = stats_table->stats_offset_32[index];

	new_stats_value = i40iw_rd32(stats->hw, stats_reg_offset);
	/*roll-over case */
	if (new_stats_value < last_rd_stats->stats_value_32[index])
		hw_stats->stats_value_32[index] += new_stats_value;
	else
		hw_stats->stats_value_32[index] +=
			new_stats_value - last_rd_stats->stats_value_32[index];
	last_rd_stats->stats_value_32[index] = new_stats_value;
	*value = hw_stats->stats_value_32[index];
}

/**
 * i40iw_hw_stats_read_64 - Read HW stats counters (greater than 32-bit) and accommodates for roll-overs.
 * @stats: pestat struct
 * @index: index in HW stats table which contains offset reg-addr
 * @value: hw stats value
 */
void i40iw_hw_stats_read_64(struct i40iw_vsi_pestat *stats,
			    enum i40iw_hw_stats_index_64b index,
			    u64 *value)
{
	struct i40iw_dev_hw_stats_offsets *stats_table =
		&stats->hw_stats_offsets;
	struct i40iw_dev_hw_stats *last_rd_stats = &stats->last_read_hw_stats;
	struct i40iw_dev_hw_stats *hw_stats = &stats->hw_stats;
	u64 new_stats_value = 0;
	u32 stats_reg_offset = stats_table->stats_offset_64[index];

	new_stats_value = readq(stats->hw->hw_addr + stats_reg_offset);
	/*roll-over case */
	if (new_stats_value < last_rd_stats->stats_value_64[index])
		hw_stats->stats_value_64[index] += new_stats_value;
	else
		hw_stats->stats_value_64[index] +=
			new_stats_value - last_rd_stats->stats_value_64[index];
	last_rd_stats->stats_value_64[index] = new_stats_value;
	*value = hw_stats->stats_value_64[index];
}

/**
 * i40iw_hw_stats_read_all - read all HW stat counters
 * @stats: pestat struct
 * @stats_values: hw stats structure
 *
 * Read all the HW stat counters and populates hw_stats structure
 * of passed-in vsi's pestat as well as copy created in stat_values.
 */
void i40iw_hw_stats_read_all(struct i40iw_vsi_pestat *stats,
			     struct i40iw_dev_hw_stats *stats_values)
{
	u32 stats_index;
	unsigned long flags;

	spin_lock_irqsave(&stats->lock, flags);

	for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_32;
	     stats_index++)
		i40iw_hw_stats_read_32(stats, stats_index,
				       &stats_values->stats_value_32[stats_index]);
	for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_64;
	     stats_index++)
		i40iw_hw_stats_read_64(stats, stats_index,
				       &stats_values->stats_value_64[stats_index]);
	spin_unlock_irqrestore(&stats->lock, flags);
}

/**
 * i40iw_hw_stats_refresh_all - Update all HW stats structs
 * @stats: pestat struct
 *
 * Read all the HW stats counters to refresh values in hw_stats structure
 * of passed-in dev's pestat
 */
void i40iw_hw_stats_refresh_all(struct i40iw_vsi_pestat *stats)
{
	u64 stats_value;
	u32 stats_index;
	unsigned long flags;

	spin_lock_irqsave(&stats->lock, flags);

	for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_32;
	     stats_index++)
		i40iw_hw_stats_read_32(stats, stats_index, &stats_value);
	for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_64;
	     stats_index++)
		i40iw_hw_stats_read_64(stats, stats_index, &stats_value);
	spin_unlock_irqrestore(&stats->lock, flags);
}

/**
 * i40iw_get_fcn_id - Return the function id
 * @dev: pointer to the device
 */
static u8 i40iw_get_fcn_id(struct i40iw_sc_dev *dev)
{
	u8 fcn_id = I40IW_INVALID_FCN_ID;
	u8 i;

	for (i = I40IW_FIRST_NON_PF_STAT; i < I40IW_MAX_STATS_COUNT; i++)
		if (!dev->fcn_id_array[i]) {
			fcn_id = i;
			dev->fcn_id_array[i] = true;
			break;
		}
	return fcn_id;
}

/**
 * i40iw_vsi_stats_init - Initialize the vsi statistics
 * @vsi: pointer to the vsi structure
 * @info: The info structure used for initialization
 */
enum i40iw_status_code i40iw_vsi_stats_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_stats_info *info)
{
	u8 fcn_id = info->fcn_id;

	if (info->alloc_fcn_id)
		fcn_id = i40iw_get_fcn_id(vsi->dev);

	if (fcn_id == I40IW_INVALID_FCN_ID)
		return I40IW_ERR_NOT_READY;

	vsi->pestat = info->pestat;
	vsi->pestat->hw = vsi->dev->hw;
	vsi->pestat->vsi = vsi;

	if (info->stats_initialize) {
		i40iw_hw_stats_init(vsi->pestat, fcn_id, true);
		spin_lock_init(&vsi->pestat->lock);
		i40iw_hw_stats_start_timer(vsi);
	}
	vsi->stats_fcn_id_alloc = info->alloc_fcn_id;
	vsi->fcn_id = fcn_id;
	return I40IW_SUCCESS;
}

/**
 * i40iw_vsi_stats_free - Free the vsi stats
 * @vsi: pointer to the vsi structure
 */
void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi)
{
	u8 fcn_id = vsi->fcn_id;

	if (vsi->stats_fcn_id_alloc && fcn_id < I40IW_MAX_STATS_COUNT)
		vsi->dev->fcn_id_array[fcn_id] = false;
	i40iw_hw_stats_stop_timer(vsi);
}

static const struct i40iw_cqp_ops iw_cqp_ops = {
	.cqp_init = i40iw_sc_cqp_init,
	.cqp_create = i40iw_sc_cqp_create,
	.cqp_post_sq = i40iw_sc_cqp_post_sq,
	.cqp_get_next_send_wqe = i40iw_sc_cqp_get_next_send_wqe,
	.cqp_destroy = i40iw_sc_cqp_destroy,
	.poll_for_cqp_op_done = i40iw_sc_poll_for_cqp_op_done
};

static const struct i40iw_ccq_ops iw_ccq_ops = {
	.ccq_init = i40iw_sc_ccq_init,
	.ccq_create = i40iw_sc_ccq_create,
	.ccq_destroy = i40iw_sc_ccq_destroy,
	.ccq_create_done = i40iw_sc_ccq_create_done,
	.ccq_get_cqe_info = i40iw_sc_ccq_get_cqe_info,
	.ccq_arm = i40iw_sc_ccq_arm
};

static const struct i40iw_ceq_ops iw_ceq_ops = {
	.ceq_init = i40iw_sc_ceq_init,
	.ceq_create = i40iw_sc_ceq_create,
	.cceq_create_done = i40iw_sc_cceq_create_done,
	.cceq_destroy_done = i40iw_sc_cceq_destroy_done,
	.cceq_create = i40iw_sc_cceq_create,
	.ceq_destroy = i40iw_sc_ceq_destroy,
	.process_ceq = i40iw_sc_process_ceq
};

static const struct i40iw_aeq_ops iw_aeq_ops = {
	.aeq_init = i40iw_sc_aeq_init,
	.aeq_create = i40iw_sc_aeq_create,
	.aeq_destroy = i40iw_sc_aeq_destroy,
	.get_next_aeqe = i40iw_sc_get_next_aeqe,
	.repost_aeq_entries = i40iw_sc_repost_aeq_entries,
	.aeq_create_done = i40iw_sc_aeq_create_done,
	.aeq_destroy_done = i40iw_sc_aeq_destroy_done
};

/* iwarp pd ops */
static const struct i40iw_pd_ops iw_pd_ops = {
	.pd_init = i40iw_sc_pd_init,
};

static const struct i40iw_priv_qp_ops iw_priv_qp_ops = {
	.qp_init = i40iw_sc_qp_init,
	.qp_create = i40iw_sc_qp_create,
	.qp_modify = i40iw_sc_qp_modify,
	.qp_destroy = i40iw_sc_qp_destroy,
	.qp_flush_wqes = i40iw_sc_qp_flush_wqes,
	.qp_upload_context = i40iw_sc_qp_upload_context,
	.qp_setctx = i40iw_sc_qp_setctx,
	.qp_send_lsmm = i40iw_sc_send_lsmm,
	.qp_send_lsmm_nostag = i40iw_sc_send_lsmm_nostag,
	.qp_send_rtt = i40iw_sc_send_rtt,
	.qp_post_wqe0 = i40iw_sc_post_wqe0,
	.iw_mr_fast_register = i40iw_sc_mr_fast_register
};

static const struct i40iw_priv_cq_ops iw_priv_cq_ops = {
	.cq_init = i40iw_sc_cq_init,
	.cq_create = i40iw_sc_cq_create,
	.cq_destroy = i40iw_sc_cq_destroy,
	.cq_modify = i40iw_sc_cq_modify,
};

static const struct i40iw_mr_ops iw_mr_ops = {
	.alloc_stag = i40iw_sc_alloc_stag,
	.mr_reg_non_shared = i40iw_sc_mr_reg_non_shared,
	.mr_reg_shared = i40iw_sc_mr_reg_shared,
	.dealloc_stag = i40iw_sc_dealloc_stag,
	.query_stag = i40iw_sc_query_stag,
	.mw_alloc = i40iw_sc_mw_alloc
};

static const struct i40iw_cqp_misc_ops iw_cqp_misc_ops = {
	.manage_hmc_pm_func_table = i40iw_sc_manage_hmc_pm_func_table,
	.set_hmc_resource_profile = i40iw_sc_set_hmc_resource_profile,
	.commit_fpm_values = i40iw_sc_commit_fpm_values,
	.query_fpm_values = i40iw_sc_query_fpm_values,
	.static_hmc_pages_allocated = i40iw_sc_static_hmc_pages_allocated,
	.add_arp_cache_entry = i40iw_sc_add_arp_cache_entry,
	.del_arp_cache_entry = i40iw_sc_del_arp_cache_entry,
	.query_arp_cache_entry = i40iw_sc_query_arp_cache_entry,
	.manage_apbvt_entry = i40iw_sc_manage_apbvt_entry,
	.manage_qhash_table_entry = i40iw_sc_manage_qhash_table_entry,
	.alloc_local_mac_ipaddr_table_entry = i40iw_sc_alloc_local_mac_ipaddr_entry,
	.add_local_mac_ipaddr_entry = i40iw_sc_add_local_mac_ipaddr_entry,
	.del_local_mac_ipaddr_entry = i40iw_sc_del_local_mac_ipaddr_entry,
	.cqp_nop = i40iw_sc_cqp_nop,
	.commit_fpm_values_done = i40iw_sc_commit_fpm_values_done,
	.query_fpm_values_done = i40iw_sc_query_fpm_values_done,
	.manage_hmc_pm_func_table_done = i40iw_sc_manage_hmc_pm_func_table_done,
	.update_suspend_qp = i40iw_sc_suspend_qp,
	.update_resume_qp = i40iw_sc_resume_qp
};

static const struct i40iw_hmc_ops iw_hmc_ops = {
	.init_iw_hmc = i40iw_sc_init_iw_hmc,
	.parse_fpm_query_buf = i40iw_sc_parse_fpm_query_buf,
	.configure_iw_fpm = i40iw_sc_configure_iw_fpm,
	.parse_fpm_commit_buf = i40iw_sc_parse_fpm_commit_buf,
	.create_hmc_object = i40iw_sc_create_hmc_obj,
	.del_hmc_object = i40iw_sc_del_hmc_obj
};

/**
 * i40iw_device_init - Initialize IWARP device
 * @dev: IWARP device pointer
 * @info: IWARP init info
 */
enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev,
					 struct i40iw_device_init_info *info)
{
	u32 val;
	u32 vchnl_ver = 0;
	u16 hmc_fcn = 0;
	enum i40iw_status_code ret_code = 0;
	u8 db_size;

	spin_lock_init(&dev->cqp_lock);

	i40iw_device_init_uk(&dev->dev_uk);

	dev->debug_mask = info->debug_mask;

	dev->hmc_fn_id = info->hmc_fn_id;
	dev->is_pf = info->is_pf;

	dev->fpm_query_buf_pa = info->fpm_query_buf_pa;
	dev->fpm_query_buf = info->fpm_query_buf;

	dev->fpm_commit_buf_pa = info->fpm_commit_buf_pa;
	dev->fpm_commit_buf = info->fpm_commit_buf;

	dev->hw = info->hw;
	dev->hw->hw_addr = info->bar0;

	if (dev->is_pf) {
		val = i40iw_rd32(dev->hw, I40E_GLPCI_DREVID);
		dev->hw_rev = (u8)RS_32(val, I40E_GLPCI_DREVID_DEFAULT_REVID);

		val = i40iw_rd32(dev->hw, I40E_GLPCI_LBARCTRL);
		db_size = (u8)RS_32(val, I40E_GLPCI_LBARCTRL_PE_DB_SIZE);
		if ((db_size != I40IW_PE_DB_SIZE_4M) &&
		    (db_size != I40IW_PE_DB_SIZE_8M)) {
			i40iw_debug(dev, I40IW_DEBUG_DEV,
				    "%s: PE doorbell is not enabled in CSR val 0x%x\n",
				    __func__, val);
			ret_code = I40IW_ERR_PE_DOORBELL_NOT_ENABLED;
			return ret_code;
		}
		dev->db_addr = dev->hw->hw_addr + I40IW_DB_ADDR_OFFSET;
		dev->vchnl_if.vchnl_recv = i40iw_vchnl_recv_pf;
	} else {
		dev->db_addr = dev->hw->hw_addr + I40IW_VF_DB_ADDR_OFFSET;
	}

	dev->cqp_ops = &iw_cqp_ops;
	dev->ccq_ops = &iw_ccq_ops;
	dev->ceq_ops = &iw_ceq_ops;
	dev->aeq_ops = &iw_aeq_ops;
	dev->cqp_misc_ops = &iw_cqp_misc_ops;
	dev->iw_pd_ops = &iw_pd_ops;
	dev->iw_priv_qp_ops = &iw_priv_qp_ops;
	dev->iw_priv_cq_ops = &iw_priv_cq_ops;
	dev->mr_ops = &iw_mr_ops;
	dev->hmc_ops = &iw_hmc_ops;
	dev->vchnl_if.vchnl_send = info->vchnl_send;
	if (dev->vchnl_if.vchnl_send)
		dev->vchnl_up = true;
	else
		dev->vchnl_up = false;
	if (!dev->is_pf) {
		dev->vchnl_if.vchnl_recv = i40iw_vchnl_recv_vf;
		ret_code = i40iw_vchnl_vf_get_ver(dev, &vchnl_ver);
		if (!ret_code) {
			i40iw_debug(dev, I40IW_DEBUG_DEV,
				    "%s: Get Channel version rc = 0x%0x, version is %u\n",
				__func__, ret_code, vchnl_ver);
			ret_code = i40iw_vchnl_vf_get_hmc_fcn(dev, &hmc_fcn);
			if (!ret_code) {
				i40iw_debug(dev, I40IW_DEBUG_DEV,
					    "%s Get HMC function rc = 0x%0x, hmc fcn is %u\n",
					    __func__, ret_code, hmc_fcn);
				dev->hmc_fn_id = (u8)hmc_fcn;
			}
		}
	}
	dev->iw_vf_cqp_ops = &iw_vf_cqp_ops;

	return ret_code;
}
