/* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver.
 *
 * Copyright (c) 2006 - 2010 Broadcom Corporation
 * Copyright (c) 2007, 2008 Red Hat, Inc.  All rights reserved.
 * Copyright (c) 2007, 2008 Mike Christie
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
 * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
 */

#include <linux/gfp.h>
#include <scsi/scsi_tcq.h>
#include <scsi/libiscsi.h>
#include "bnx2i.h"

/**
 * bnx2i_get_cid_num - get cid from ep
 * @ep: 	endpoint pointer
 *
 * Only applicable to 57710 family of devices
 */
static u32 bnx2i_get_cid_num(struct bnx2i_endpoint *ep)
{
	u32 cid;

	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
		cid = ep->ep_cid;
	else
		cid = GET_CID_NUM(ep->ep_cid);
	return cid;
}


/**
 * bnx2i_adjust_qp_size - Adjust SQ/RQ/CQ size for 57710 device type
 * @hba: 		Adapter for which adjustments is to be made
 *
 * Only applicable to 57710 family of devices
 */
static void bnx2i_adjust_qp_size(struct bnx2i_hba *hba)
{
	u32 num_elements_per_pg;

	if (test_bit(BNX2I_NX2_DEV_5706, &hba->cnic_dev_type) ||
	    test_bit(BNX2I_NX2_DEV_5708, &hba->cnic_dev_type) ||
	    test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) {
		if (!is_power_of_2(hba->max_sqes))
			hba->max_sqes = rounddown_pow_of_two(hba->max_sqes);

		if (!is_power_of_2(hba->max_rqes))
			hba->max_rqes = rounddown_pow_of_two(hba->max_rqes);
	}

	/* Adjust each queue size if the user selection does not
	 * yield integral num of page buffers
	 */
	/* adjust SQ */
	num_elements_per_pg = PAGE_SIZE / BNX2I_SQ_WQE_SIZE;
	if (hba->max_sqes < num_elements_per_pg)
		hba->max_sqes = num_elements_per_pg;
	else if (hba->max_sqes % num_elements_per_pg)
		hba->max_sqes = (hba->max_sqes + num_elements_per_pg - 1) &
				 ~(num_elements_per_pg - 1);

	/* adjust CQ */
	num_elements_per_pg = PAGE_SIZE / BNX2I_CQE_SIZE;
	if (hba->max_cqes < num_elements_per_pg)
		hba->max_cqes = num_elements_per_pg;
	else if (hba->max_cqes % num_elements_per_pg)
		hba->max_cqes = (hba->max_cqes + num_elements_per_pg - 1) &
				 ~(num_elements_per_pg - 1);

	/* adjust RQ */
	num_elements_per_pg = PAGE_SIZE / BNX2I_RQ_WQE_SIZE;
	if (hba->max_rqes < num_elements_per_pg)
		hba->max_rqes = num_elements_per_pg;
	else if (hba->max_rqes % num_elements_per_pg)
		hba->max_rqes = (hba->max_rqes + num_elements_per_pg - 1) &
				 ~(num_elements_per_pg - 1);
}


/**
 * bnx2i_get_link_state - get network interface link state
 * @hba:	adapter instance pointer
 *
 * updates adapter structure flag based on netdev state
 */
static void bnx2i_get_link_state(struct bnx2i_hba *hba)
{
	if (test_bit(__LINK_STATE_NOCARRIER, &hba->netdev->state))
		set_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
	else
		clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
}


/**
 * bnx2i_iscsi_license_error - displays iscsi license related error message
 * @hba:		adapter instance pointer
 * @error_code:		error classification
 *
 * Puts out an error log when driver is unable to offload iscsi connection
 *	due to license restrictions
 */
static void bnx2i_iscsi_license_error(struct bnx2i_hba *hba, u32 error_code)
{
	if (error_code == ISCSI_KCQE_COMPLETION_STATUS_ISCSI_NOT_SUPPORTED)
		/* iSCSI offload not supported on this device */
		printk(KERN_ERR "bnx2i: iSCSI not supported, dev=%s\n",
				hba->netdev->name);
	if (error_code == ISCSI_KCQE_COMPLETION_STATUS_LOM_ISCSI_NOT_ENABLED)
		/* iSCSI offload not supported on this LOM device */
		printk(KERN_ERR "bnx2i: LOM is not enable to "
				"offload iSCSI connections, dev=%s\n",
				hba->netdev->name);
	set_bit(ADAPTER_STATE_INIT_FAILED, &hba->adapter_state);
}


/**
 * bnx2i_arm_cq_event_coalescing - arms CQ to enable EQ notification
 * @ep:		endpoint (transport indentifier) structure
 * @action:	action, ARM or DISARM. For now only ARM_CQE is used
 *
 * Arm'ing CQ will enable chip to generate global EQ events inorder to interrupt
 *	the driver. EQ event is generated CQ index is hit or at least 1 CQ is
 *	outstanding and on chip timer expires
 */
void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action)
{
	struct bnx2i_5771x_cq_db *cq_db;
	u16 cq_index;
	u16 next_index;
	u32 num_active_cmds;


	/* Coalesce CQ entries only on 10G devices */
	if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
		return;

	/* Do not update CQ DB multiple times before firmware writes
	 * '0xFFFF' to CQDB->SQN field. Deviation may cause spurious
	 * interrupts and other unwanted results
	 */
	cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
	if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
		return;

	if (action == CNIC_ARM_CQE) {
		num_active_cmds = ep->num_active_cmds;
		if (num_active_cmds <= event_coal_min)
			next_index = 1;
		else
			next_index = event_coal_min +
				(num_active_cmds - event_coal_min) / event_coal_div;
		if (!next_index)
			next_index = 1;
		cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1;
		if (cq_index > ep->qp.cqe_size * 2)
			cq_index -= ep->qp.cqe_size * 2;
		if (!cq_index)
			cq_index = 1;

		cq_db->sqn[0] = cq_index;
	}
}


/**
 * bnx2i_get_rq_buf - copy RQ buffer contents to driver buffer
 * @conn:		iscsi connection on which RQ event occured
 * @ptr:		driver buffer to which RQ buffer contents is to
 *			be copied
 * @len:		length of valid data inside RQ buf
 *
 * Copies RQ buffer contents from shared (DMA'able) memory region to
 *	driver buffer. RQ is used to DMA unsolicitated iscsi pdu's and
 *	scsi sense info
 */
void bnx2i_get_rq_buf(struct bnx2i_conn *bnx2i_conn, char *ptr, int len)
{
	if (!bnx2i_conn->ep->qp.rqe_left)
		return;

	bnx2i_conn->ep->qp.rqe_left--;
	memcpy(ptr, (u8 *) bnx2i_conn->ep->qp.rq_cons_qe, len);
	if (bnx2i_conn->ep->qp.rq_cons_qe == bnx2i_conn->ep->qp.rq_last_qe) {
		bnx2i_conn->ep->qp.rq_cons_qe = bnx2i_conn->ep->qp.rq_first_qe;
		bnx2i_conn->ep->qp.rq_cons_idx = 0;
	} else {
		bnx2i_conn->ep->qp.rq_cons_qe++;
		bnx2i_conn->ep->qp.rq_cons_idx++;
	}
}


static void bnx2i_ring_577xx_doorbell(struct bnx2i_conn *conn)
{
	struct bnx2i_5771x_dbell dbell;
	u32 msg;

	memset(&dbell, 0, sizeof(dbell));
	dbell.dbell.header = (B577XX_ISCSI_CONNECTION_TYPE <<
			      B577XX_DOORBELL_HDR_CONN_TYPE_SHIFT);
	msg = *((u32 *)&dbell);
	/* TODO : get doorbell register mapping */
	writel(cpu_to_le32(msg), conn->ep->qp.ctx_base);
}


/**
 * bnx2i_put_rq_buf - Replenish RQ buffer, if required ring on chip doorbell
 * @conn:	iscsi connection on which event to post
 * @count:	number of RQ buffer being posted to chip
 *
 * No need to ring hardware doorbell for 57710 family of devices
 */
void bnx2i_put_rq_buf(struct bnx2i_conn *bnx2i_conn, int count)
{
	struct bnx2i_5771x_sq_rq_db *rq_db;
	u16 hi_bit = (bnx2i_conn->ep->qp.rq_prod_idx & 0x8000);
	struct bnx2i_endpoint *ep = bnx2i_conn->ep;

	ep->qp.rqe_left += count;
	ep->qp.rq_prod_idx &= 0x7FFF;
	ep->qp.rq_prod_idx += count;

	if (ep->qp.rq_prod_idx > bnx2i_conn->hba->max_rqes) {
		ep->qp.rq_prod_idx %= bnx2i_conn->hba->max_rqes;
		if (!hi_bit)
			ep->qp.rq_prod_idx |= 0x8000;
	} else
		ep->qp.rq_prod_idx |= hi_bit;

	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) {
		rq_db = (struct bnx2i_5771x_sq_rq_db *) ep->qp.rq_pgtbl_virt;
		rq_db->prod_idx = ep->qp.rq_prod_idx;
		/* no need to ring hardware doorbell for 57710 */
	} else {
		writew(ep->qp.rq_prod_idx,
		       ep->qp.ctx_base + CNIC_RECV_DOORBELL);
	}
	mmiowb();
}


/**
 * bnx2i_ring_sq_dbell - Ring SQ doorbell to wake-up the processing engine
 * @conn: 		iscsi connection to which new SQ entries belong
 * @count: 		number of SQ WQEs to post
 *
 * SQ DB is updated in host memory and TX Doorbell is rung for 57710 family
 *	of devices. For 5706/5708/5709 new SQ WQE count is written into the
 *	doorbell register
 */
static void bnx2i_ring_sq_dbell(struct bnx2i_conn *bnx2i_conn, int count)
{
	struct bnx2i_5771x_sq_rq_db *sq_db;
	struct bnx2i_endpoint *ep = bnx2i_conn->ep;

	ep->num_active_cmds++;
	wmb();	/* flush SQ WQE memory before the doorbell is rung */
	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) {
		sq_db = (struct bnx2i_5771x_sq_rq_db *) ep->qp.sq_pgtbl_virt;
		sq_db->prod_idx = ep->qp.sq_prod_idx;
		bnx2i_ring_577xx_doorbell(bnx2i_conn);
	} else
		writew(count, ep->qp.ctx_base + CNIC_SEND_DOORBELL);

	mmiowb(); /* flush posted PCI writes */
}


/**
 * bnx2i_ring_dbell_update_sq_params - update SQ driver parameters
 * @conn:	iscsi connection to which new SQ entries belong
 * @count:	number of SQ WQEs to post
 *
 * this routine will update SQ driver parameters and ring the doorbell
 */
static void bnx2i_ring_dbell_update_sq_params(struct bnx2i_conn *bnx2i_conn,
					      int count)
{
	int tmp_cnt;

	if (count == 1) {
		if (bnx2i_conn->ep->qp.sq_prod_qe ==
		    bnx2i_conn->ep->qp.sq_last_qe)
			bnx2i_conn->ep->qp.sq_prod_qe =
						bnx2i_conn->ep->qp.sq_first_qe;
		else
			bnx2i_conn->ep->qp.sq_prod_qe++;
	} else {
		if ((bnx2i_conn->ep->qp.sq_prod_qe + count) <=
		    bnx2i_conn->ep->qp.sq_last_qe)
			bnx2i_conn->ep->qp.sq_prod_qe += count;
		else {
			tmp_cnt = bnx2i_conn->ep->qp.sq_last_qe -
				bnx2i_conn->ep->qp.sq_prod_qe;
			bnx2i_conn->ep->qp.sq_prod_qe =
				&bnx2i_conn->ep->qp.sq_first_qe[count -
								(tmp_cnt + 1)];
		}
	}
	bnx2i_conn->ep->qp.sq_prod_idx += count;
	/* Ring the doorbell */
	bnx2i_ring_sq_dbell(bnx2i_conn, bnx2i_conn->ep->qp.sq_prod_idx);
}


/**
 * bnx2i_send_iscsi_login - post iSCSI login request MP WQE to hardware
 * @conn:	iscsi connection
 * @cmd:	driver command structure which is requesting
 *		a WQE to sent to chip for further processing
 *
 * prepare and post an iSCSI Login request WQE to CNIC firmware
 */
int bnx2i_send_iscsi_login(struct bnx2i_conn *bnx2i_conn,
			   struct iscsi_task *task)
{
	struct bnx2i_cmd *bnx2i_cmd;
	struct bnx2i_login_request *login_wqe;
	struct iscsi_login *login_hdr;
	u32 dword;

	bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data;
	login_hdr = (struct iscsi_login *)task->hdr;
	login_wqe = (struct bnx2i_login_request *)
						bnx2i_conn->ep->qp.sq_prod_qe;

	login_wqe->op_code = login_hdr->opcode;
	login_wqe->op_attr = login_hdr->flags;
	login_wqe->version_max = login_hdr->max_version;
	login_wqe->version_min = login_hdr->min_version;
	login_wqe->data_length = ntoh24(login_hdr->dlength);
	login_wqe->isid_lo = *((u32 *) login_hdr->isid);
	login_wqe->isid_hi = *((u16 *) login_hdr->isid + 2);
	login_wqe->tsih = login_hdr->tsih;
	login_wqe->itt = task->itt |
		(ISCSI_TASK_TYPE_MPATH << ISCSI_LOGIN_REQUEST_TYPE_SHIFT);
	login_wqe->cid = login_hdr->cid;

	login_wqe->cmd_sn = be32_to_cpu(login_hdr->cmdsn);
	login_wqe->exp_stat_sn = be32_to_cpu(login_hdr->exp_statsn);
	login_wqe->flags = ISCSI_LOGIN_REQUEST_UPDATE_EXP_STAT_SN;

	login_wqe->resp_bd_list_addr_lo = (u32) bnx2i_conn->gen_pdu.resp_bd_dma;
	login_wqe->resp_bd_list_addr_hi =
		(u32) ((u64) bnx2i_conn->gen_pdu.resp_bd_dma >> 32);

	dword = ((1 << ISCSI_LOGIN_REQUEST_NUM_RESP_BDS_SHIFT) |
		 (bnx2i_conn->gen_pdu.resp_buf_size <<
		  ISCSI_LOGIN_REQUEST_RESP_BUFFER_LENGTH_SHIFT));
	login_wqe->resp_buffer = dword;
	login_wqe->bd_list_addr_lo = (u32) bnx2i_conn->gen_pdu.req_bd_dma;
	login_wqe->bd_list_addr_hi =
		(u32) ((u64) bnx2i_conn->gen_pdu.req_bd_dma >> 32);
	login_wqe->num_bds = 1;
	login_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
	return 0;
}

/**
 * bnx2i_send_iscsi_tmf - post iSCSI task management request MP WQE to hardware
 * @conn:	iscsi connection
 * @mtask:	driver command structure which is requesting
 *		a WQE to sent to chip for further processing
 *
 * prepare and post an iSCSI Login request WQE to CNIC firmware
 */
int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
			 struct iscsi_task *mtask)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_tm *tmfabort_hdr;
	struct scsi_cmnd *ref_sc;
	struct iscsi_task *ctask;
	struct bnx2i_cmd *bnx2i_cmd;
	struct bnx2i_tmf_request *tmfabort_wqe;
	u32 dword;
	u32 scsi_lun[2];

	bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
	tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
	tmfabort_wqe = (struct bnx2i_tmf_request *)
						bnx2i_conn->ep->qp.sq_prod_qe;

	tmfabort_wqe->op_code = tmfabort_hdr->opcode;
	tmfabort_wqe->op_attr = tmfabort_hdr->flags;

	tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14));
	tmfabort_wqe->reserved2 = 0;
	tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn);

	switch (tmfabort_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) {
	case ISCSI_TM_FUNC_ABORT_TASK:
	case ISCSI_TM_FUNC_TASK_REASSIGN:
		ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
		if (!ctask || !ctask->sc)
			/*
			 * the iscsi layer must have completed the cmd while
			 * was starting up.
			 *
			 * Note: In the case of a SCSI cmd timeout, the task's
			 *       sc is still active; hence ctask->sc != 0
			 *       In this case, the task must be aborted
			 */
			return 0;

		ref_sc = ctask->sc;
		if (ref_sc->sc_data_direction == DMA_TO_DEVICE)
			dword = (ISCSI_TASK_TYPE_WRITE <<
				 ISCSI_CMD_REQUEST_TYPE_SHIFT);
		else
			dword = (ISCSI_TASK_TYPE_READ <<
				 ISCSI_CMD_REQUEST_TYPE_SHIFT);
		tmfabort_wqe->ref_itt = (dword |
					(tmfabort_hdr->rtt & ISCSI_ITT_MASK));
		break;
	default:
		tmfabort_wqe->ref_itt = RESERVED_ITT;
	}
	memcpy(scsi_lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
	tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
	tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);

	tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);

	tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
	tmfabort_wqe->bd_list_addr_hi = (u32)
				((u64) bnx2i_conn->hba->mp_bd_dma >> 32);
	tmfabort_wqe->num_bds = 1;
	tmfabort_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
	return 0;
}

/**
 * bnx2i_send_iscsi_scsicmd - post iSCSI scsicmd request WQE to hardware
 * @conn:	iscsi connection
 * @cmd:	driver command structure which is requesting
 *		a WQE to sent to chip for further processing
 *
 * prepare and post an iSCSI SCSI-CMD request WQE to CNIC firmware
 */
int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *bnx2i_conn,
			     struct bnx2i_cmd *cmd)
{
	struct bnx2i_cmd_request *scsi_cmd_wqe;

	scsi_cmd_wqe = (struct bnx2i_cmd_request *)
						bnx2i_conn->ep->qp.sq_prod_qe;
	memcpy(scsi_cmd_wqe, &cmd->req, sizeof(struct bnx2i_cmd_request));
	scsi_cmd_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
	return 0;
}

/**
 * bnx2i_send_iscsi_nopout - post iSCSI NOPOUT request WQE to hardware
 * @conn:		iscsi connection
 * @cmd:		driver command structure which is requesting
 *			a WQE to sent to chip for further processing
 * @datap:		payload buffer pointer
 * @data_len:		payload data length
 * @unsol:		indicated whether nopout pdu is unsolicited pdu or
 *			in response to target's NOPIN w/ TTT != FFFFFFFF
 *
 * prepare and post a nopout request WQE to CNIC firmware
 */
int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
			    struct iscsi_task *task,
			    char *datap, int data_len, int unsol)
{
	struct bnx2i_endpoint *ep = bnx2i_conn->ep;
	struct bnx2i_cmd *bnx2i_cmd;
	struct bnx2i_nop_out_request *nopout_wqe;
	struct iscsi_nopout *nopout_hdr;

	bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data;
	nopout_hdr = (struct iscsi_nopout *)task->hdr;
	nopout_wqe = (struct bnx2i_nop_out_request *)ep->qp.sq_prod_qe;
	nopout_wqe->op_code = nopout_hdr->opcode;
	nopout_wqe->op_attr = ISCSI_FLAG_CMD_FINAL;
	memcpy(nopout_wqe->lun, nopout_hdr->lun, 8);

	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) {
		u32 tmp = nopout_hdr->lun[0];
		/* 57710 requires LUN field to be swapped */
		nopout_hdr->lun[0] = nopout_hdr->lun[1];
		nopout_hdr->lun[1] = tmp;
	}

	nopout_wqe->itt = ((u16)task->itt |
			   (ISCSI_TASK_TYPE_MPATH <<
			    ISCSI_TMF_REQUEST_TYPE_SHIFT));
	nopout_wqe->ttt = nopout_hdr->ttt;
	nopout_wqe->flags = 0;
	if (!unsol)
		nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;
	else if (nopout_hdr->itt == RESERVED_ITT)
		nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;

	nopout_wqe->cmd_sn = be32_to_cpu(nopout_hdr->cmdsn);
	nopout_wqe->data_length = data_len;
	if (data_len) {
		/* handle payload data, not required in first release */
		printk(KERN_ALERT "NOPOUT: WARNING!! payload len != 0\n");
	} else {
		nopout_wqe->bd_list_addr_lo = (u32)
					bnx2i_conn->hba->mp_bd_dma;
		nopout_wqe->bd_list_addr_hi =
			(u32) ((u64) bnx2i_conn->hba->mp_bd_dma >> 32);
		nopout_wqe->num_bds = 1;
	}
	nopout_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
	return 0;
}


/**
 * bnx2i_send_iscsi_logout - post iSCSI logout request WQE to hardware
 * @conn:	iscsi connection
 * @cmd:	driver command structure which is requesting
 *		a WQE to sent to chip for further processing
 *
 * prepare and post logout request WQE to CNIC firmware
 */
int bnx2i_send_iscsi_logout(struct bnx2i_conn *bnx2i_conn,
			    struct iscsi_task *task)
{
	struct bnx2i_cmd *bnx2i_cmd;
	struct bnx2i_logout_request *logout_wqe;
	struct iscsi_logout *logout_hdr;

	bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data;
	logout_hdr = (struct iscsi_logout *)task->hdr;

	logout_wqe = (struct bnx2i_logout_request *)
						bnx2i_conn->ep->qp.sq_prod_qe;
	memset(logout_wqe, 0x00, sizeof(struct bnx2i_logout_request));

	logout_wqe->op_code = logout_hdr->opcode;
	logout_wqe->cmd_sn = be32_to_cpu(logout_hdr->cmdsn);
	logout_wqe->op_attr =
			logout_hdr->flags | ISCSI_LOGOUT_REQUEST_ALWAYS_ONE;
	logout_wqe->itt = ((u16)task->itt |
			   (ISCSI_TASK_TYPE_MPATH <<
			    ISCSI_LOGOUT_REQUEST_TYPE_SHIFT));
	logout_wqe->data_length = 0;
	logout_wqe->cid = 0;

	logout_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
	logout_wqe->bd_list_addr_hi = (u32)
				((u64) bnx2i_conn->hba->mp_bd_dma >> 32);
	logout_wqe->num_bds = 1;
	logout_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_conn->ep->state = EP_STATE_LOGOUT_SENT;

	bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
	return 0;
}


/**
 * bnx2i_update_iscsi_conn - post iSCSI logout request WQE to hardware
 * @conn:	iscsi connection which requires iscsi parameter update
 *
 * sends down iSCSI Conn Update request to move iSCSI conn to FFP
 */
void bnx2i_update_iscsi_conn(struct iscsi_conn *conn)
{
	struct bnx2i_conn *bnx2i_conn = conn->dd_data;
	struct bnx2i_hba *hba = bnx2i_conn->hba;
	struct kwqe *kwqe_arr[2];
	struct iscsi_kwqe_conn_update *update_wqe;
	struct iscsi_kwqe_conn_update conn_update_kwqe;

	update_wqe = &conn_update_kwqe;

	update_wqe->hdr.op_code = ISCSI_KWQE_OPCODE_UPDATE_CONN;
	update_wqe->hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);

	/* 5771x requires conn context id to be passed as is */
	if (test_bit(BNX2I_NX2_DEV_57710, &bnx2i_conn->ep->hba->cnic_dev_type))
		update_wqe->context_id = bnx2i_conn->ep->ep_cid;
	else
		update_wqe->context_id = (bnx2i_conn->ep->ep_cid >> 7);
	update_wqe->conn_flags = 0;
	if (conn->hdrdgst_en)
		update_wqe->conn_flags |= ISCSI_KWQE_CONN_UPDATE_HEADER_DIGEST;
	if (conn->datadgst_en)
		update_wqe->conn_flags |= ISCSI_KWQE_CONN_UPDATE_DATA_DIGEST;
	if (conn->session->initial_r2t_en)
		update_wqe->conn_flags |= ISCSI_KWQE_CONN_UPDATE_INITIAL_R2T;
	if (conn->session->imm_data_en)
		update_wqe->conn_flags |= ISCSI_KWQE_CONN_UPDATE_IMMEDIATE_DATA;

	update_wqe->max_send_pdu_length = conn->max_xmit_dlength;
	update_wqe->max_recv_pdu_length = conn->max_recv_dlength;
	update_wqe->first_burst_length = conn->session->first_burst;
	update_wqe->max_burst_length = conn->session->max_burst;
	update_wqe->exp_stat_sn = conn->exp_statsn;
	update_wqe->max_outstanding_r2ts = conn->session->max_r2t;
	update_wqe->session_error_recovery_level = conn->session->erl;
	iscsi_conn_printk(KERN_ALERT, conn,
			  "bnx2i: conn update - MBL 0x%x FBL 0x%x"
			  "MRDSL_I 0x%x MRDSL_T 0x%x \n",
			  update_wqe->max_burst_length,
			  update_wqe->first_burst_length,
			  update_wqe->max_recv_pdu_length,
			  update_wqe->max_send_pdu_length);

	kwqe_arr[0] = (struct kwqe *) update_wqe;
	if (hba->cnic && hba->cnic->submit_kwqes)
		hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);
}


/**
 * bnx2i_ep_ofld_timer - post iSCSI logout request WQE to hardware
 * @data:	endpoint (transport handle) structure pointer
 *
 * routine to handle connection offload/destroy request timeout
 */
void bnx2i_ep_ofld_timer(unsigned long data)
{
	struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) data;

	if (ep->state == EP_STATE_OFLD_START) {
		printk(KERN_ALERT "ofld_timer: CONN_OFLD timeout\n");
		ep->state = EP_STATE_OFLD_FAILED;
	} else if (ep->state == EP_STATE_DISCONN_START) {
		printk(KERN_ALERT "ofld_timer: CONN_DISCON timeout\n");
		ep->state = EP_STATE_DISCONN_TIMEDOUT;
	} else if (ep->state == EP_STATE_CLEANUP_START) {
		printk(KERN_ALERT "ofld_timer: CONN_CLEANUP timeout\n");
		ep->state = EP_STATE_CLEANUP_FAILED;
	}

	wake_up_interruptible(&ep->ofld_wait);
}


static int bnx2i_power_of2(u32 val)
{
	u32 power = 0;
	if (val & (val - 1))
		return power;
	val--;
	while (val) {
		val = val >> 1;
		power++;
	}
	return power;
}


/**
 * bnx2i_send_cmd_cleanup_req - send iscsi cmd context clean-up request
 * @hba:	adapter structure pointer
 * @cmd:	driver command structure which is requesting
 *		a WQE to sent to chip for further processing
 *
 * prepares and posts CONN_OFLD_REQ1/2 KWQE
 */
void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba, struct bnx2i_cmd *cmd)
{
	struct bnx2i_cleanup_request *cmd_cleanup;

	cmd_cleanup =
		(struct bnx2i_cleanup_request *)cmd->conn->ep->qp.sq_prod_qe;
	memset(cmd_cleanup, 0x00, sizeof(struct bnx2i_cleanup_request));

	cmd_cleanup->op_code = ISCSI_OPCODE_CLEANUP_REQUEST;
	cmd_cleanup->itt = cmd->req.itt;
	cmd_cleanup->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_ring_dbell_update_sq_params(cmd->conn, 1);
}


/**
 * bnx2i_send_conn_destroy - initiates iscsi connection teardown process
 * @hba:	adapter structure pointer
 * @ep:		endpoint (transport indentifier) structure
 *
 * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE to initiate
 * 	iscsi connection context clean-up process
 */
int bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
{
	struct kwqe *kwqe_arr[2];
	struct iscsi_kwqe_conn_destroy conn_cleanup;
	int rc = -EINVAL;

	memset(&conn_cleanup, 0x00, sizeof(struct iscsi_kwqe_conn_destroy));

	conn_cleanup.hdr.op_code = ISCSI_KWQE_OPCODE_DESTROY_CONN;
	conn_cleanup.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);
	/* 5771x requires conn context id to be passed as is */
	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
		conn_cleanup.context_id = ep->ep_cid;
	else
		conn_cleanup.context_id = (ep->ep_cid >> 7);

	conn_cleanup.reserved0 = (u16)ep->ep_iscsi_cid;

	kwqe_arr[0] = (struct kwqe *) &conn_cleanup;
	if (hba->cnic && hba->cnic->submit_kwqes)
		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);

	return rc;
}


/**
 * bnx2i_570x_send_conn_ofld_req - initiates iscsi conn context setup process
 * @hba: 		adapter structure pointer
 * @ep: 		endpoint (transport indentifier) structure
 *
 * 5706/5708/5709 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
 */
static int bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
					 struct bnx2i_endpoint *ep)
{
	struct kwqe *kwqe_arr[2];
	struct iscsi_kwqe_conn_offload1 ofld_req1;
	struct iscsi_kwqe_conn_offload2 ofld_req2;
	dma_addr_t dma_addr;
	int num_kwqes = 2;
	u32 *ptbl;
	int rc = -EINVAL;

	ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
	ofld_req1.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);

	ofld_req1.iscsi_conn_id = (u16) ep->ep_iscsi_cid;

	dma_addr = ep->qp.sq_pgtbl_phys;
	ofld_req1.sq_page_table_addr_lo = (u32) dma_addr;
	ofld_req1.sq_page_table_addr_hi = (u32) ((u64) dma_addr >> 32);

	dma_addr = ep->qp.cq_pgtbl_phys;
	ofld_req1.cq_page_table_addr_lo = (u32) dma_addr;
	ofld_req1.cq_page_table_addr_hi = (u32) ((u64) dma_addr >> 32);

	ofld_req2.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN2;
	ofld_req2.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);

	dma_addr = ep->qp.rq_pgtbl_phys;
	ofld_req2.rq_page_table_addr_lo = (u32) dma_addr;
	ofld_req2.rq_page_table_addr_hi = (u32) ((u64) dma_addr >> 32);

	ptbl = (u32 *) ep->qp.sq_pgtbl_virt;

	ofld_req2.sq_first_pte.hi = *ptbl++;
	ofld_req2.sq_first_pte.lo = *ptbl;

	ptbl = (u32 *) ep->qp.cq_pgtbl_virt;
	ofld_req2.cq_first_pte.hi = *ptbl++;
	ofld_req2.cq_first_pte.lo = *ptbl;

	kwqe_arr[0] = (struct kwqe *) &ofld_req1;
	kwqe_arr[1] = (struct kwqe *) &ofld_req2;
	ofld_req2.num_additional_wqes = 0;

	if (hba->cnic && hba->cnic->submit_kwqes)
		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);

	return rc;
}


/**
 * bnx2i_5771x_send_conn_ofld_req - initiates iscsi connection context creation
 * @hba: 		adapter structure pointer
 * @ep: 		endpoint (transport indentifier) structure
 *
 * 57710 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
 */
static int bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
					  struct bnx2i_endpoint *ep)
{
	struct kwqe *kwqe_arr[5];
	struct iscsi_kwqe_conn_offload1 ofld_req1;
	struct iscsi_kwqe_conn_offload2 ofld_req2;
	struct iscsi_kwqe_conn_offload3 ofld_req3[1];
	dma_addr_t dma_addr;
	int num_kwqes = 2;
	u32 *ptbl;
	int rc = -EINVAL;

	ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
	ofld_req1.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);

	ofld_req1.iscsi_conn_id = (u16) ep->ep_iscsi_cid;

	dma_addr = ep->qp.sq_pgtbl_phys + ISCSI_SQ_DB_SIZE;
	ofld_req1.sq_page_table_addr_lo = (u32) dma_addr;
	ofld_req1.sq_page_table_addr_hi = (u32) ((u64) dma_addr >> 32);

	dma_addr = ep->qp.cq_pgtbl_phys + ISCSI_CQ_DB_SIZE;
	ofld_req1.cq_page_table_addr_lo = (u32) dma_addr;
	ofld_req1.cq_page_table_addr_hi = (u32) ((u64) dma_addr >> 32);

	ofld_req2.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN2;
	ofld_req2.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);

	dma_addr = ep->qp.rq_pgtbl_phys + ISCSI_RQ_DB_SIZE;
	ofld_req2.rq_page_table_addr_lo = (u32) dma_addr;
	ofld_req2.rq_page_table_addr_hi = (u32) ((u64) dma_addr >> 32);

	ptbl = (u32 *)((u8 *)ep->qp.sq_pgtbl_virt + ISCSI_SQ_DB_SIZE);
	ofld_req2.sq_first_pte.hi = *ptbl++;
	ofld_req2.sq_first_pte.lo = *ptbl;

	ptbl = (u32 *)((u8 *)ep->qp.cq_pgtbl_virt + ISCSI_CQ_DB_SIZE);
	ofld_req2.cq_first_pte.hi = *ptbl++;
	ofld_req2.cq_first_pte.lo = *ptbl;

	kwqe_arr[0] = (struct kwqe *) &ofld_req1;
	kwqe_arr[1] = (struct kwqe *) &ofld_req2;

	ofld_req2.num_additional_wqes = 1;
	memset(ofld_req3, 0x00, sizeof(ofld_req3[0]));
	ptbl = (u32 *)((u8 *)ep->qp.rq_pgtbl_virt + ISCSI_RQ_DB_SIZE);
	ofld_req3[0].qp_first_pte[0].hi = *ptbl++;
	ofld_req3[0].qp_first_pte[0].lo = *ptbl;

	kwqe_arr[2] = (struct kwqe *) ofld_req3;
	/* need if we decide to go with multiple KCQE's per conn */
	num_kwqes += 1;

	if (hba->cnic && hba->cnic->submit_kwqes)
		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);

	return rc;
}

/**
 * bnx2i_send_conn_ofld_req - initiates iscsi connection context setup process
 *
 * @hba: 		adapter structure pointer
 * @ep: 		endpoint (transport indentifier) structure
 *
 * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE
 */
int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
{
	int rc;

	if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
		rc = bnx2i_5771x_send_conn_ofld_req(hba, ep);
	else
		rc = bnx2i_570x_send_conn_ofld_req(hba, ep);

	return rc;
}


/**
 * setup_qp_page_tables - iscsi QP page table setup function
 * @ep:		endpoint (transport indentifier) structure
 *
 * Sets up page tables for SQ/RQ/CQ, 1G/sec (5706/5708/5709) devices requires
 * 	64-bit address in big endian format. Whereas 10G/sec (57710) requires
 * 	PT in little endian format
 */
static void setup_qp_page_tables(struct bnx2i_endpoint *ep)
{
	int num_pages;
	u32 *ptbl;
	dma_addr_t page;
	int cnic_dev_10g;

	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
		cnic_dev_10g = 1;
	else
		cnic_dev_10g = 0;

	/* SQ page table */
	memset(ep->qp.sq_pgtbl_virt, 0, ep->qp.sq_pgtbl_size);
	num_pages = ep->qp.sq_mem_size / PAGE_SIZE;
	page = ep->qp.sq_phys;

	if (cnic_dev_10g)
		ptbl = (u32 *)((u8 *)ep->qp.sq_pgtbl_virt + ISCSI_SQ_DB_SIZE);
	else
		ptbl = (u32 *) ep->qp.sq_pgtbl_virt;
	while (num_pages--) {
		if (cnic_dev_10g) {
			/* PTE is written in little endian format for 57710 */
			*ptbl = (u32) page;
			ptbl++;
			*ptbl = (u32) ((u64) page >> 32);
			ptbl++;
			page += PAGE_SIZE;
		} else {
			/* PTE is written in big endian format for
			 * 5706/5708/5709 devices */
			*ptbl = (u32) ((u64) page >> 32);
			ptbl++;
			*ptbl = (u32) page;
			ptbl++;
			page += PAGE_SIZE;
		}
	}

	/* RQ page table */
	memset(ep->qp.rq_pgtbl_virt, 0, ep->qp.rq_pgtbl_size);
	num_pages = ep->qp.rq_mem_size / PAGE_SIZE;
	page = ep->qp.rq_phys;

	if (cnic_dev_10g)
		ptbl = (u32 *)((u8 *)ep->qp.rq_pgtbl_virt + ISCSI_RQ_DB_SIZE);
	else
		ptbl = (u32 *) ep->qp.rq_pgtbl_virt;
	while (num_pages--) {
		if (cnic_dev_10g) {
			/* PTE is written in little endian format for 57710 */
			*ptbl = (u32) page;
			ptbl++;
			*ptbl = (u32) ((u64) page >> 32);
			ptbl++;
			page += PAGE_SIZE;
		} else {
			/* PTE is written in big endian format for
			 * 5706/5708/5709 devices */
			*ptbl = (u32) ((u64) page >> 32);
			ptbl++;
			*ptbl = (u32) page;
			ptbl++;
			page += PAGE_SIZE;
		}
	}

	/* CQ page table */
	memset(ep->qp.cq_pgtbl_virt, 0, ep->qp.cq_pgtbl_size);
	num_pages = ep->qp.cq_mem_size / PAGE_SIZE;
	page = ep->qp.cq_phys;

	if (cnic_dev_10g)
		ptbl = (u32 *)((u8 *)ep->qp.cq_pgtbl_virt + ISCSI_CQ_DB_SIZE);
	else
		ptbl = (u32 *) ep->qp.cq_pgtbl_virt;
	while (num_pages--) {
		if (cnic_dev_10g) {
			/* PTE is written in little endian format for 57710 */
			*ptbl = (u32) page;
			ptbl++;
			*ptbl = (u32) ((u64) page >> 32);
			ptbl++;
			page += PAGE_SIZE;
		} else {
			/* PTE is written in big endian format for
			 * 5706/5708/5709 devices */
			*ptbl = (u32) ((u64) page >> 32);
			ptbl++;
			*ptbl = (u32) page;
			ptbl++;
			page += PAGE_SIZE;
		}
	}
}


/**
 * bnx2i_alloc_qp_resc - allocates required resources for QP.
 * @hba:	adapter structure pointer
 * @ep:		endpoint (transport indentifier) structure
 *
 * Allocate QP (transport layer for iSCSI connection) resources, DMA'able
 *	memory for SQ/RQ/CQ and page tables. EP structure elements such
 *	as producer/consumer indexes/pointers, queue sizes and page table
 *	contents are setup
 */
int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
{
	struct bnx2i_5771x_cq_db *cq_db;

	ep->hba = hba;
	ep->conn = NULL;
	ep->ep_cid = ep->ep_iscsi_cid = ep->ep_pg_cid = 0;

	/* Allocate page table memory for SQ which is page aligned */
	ep->qp.sq_mem_size = hba->max_sqes * BNX2I_SQ_WQE_SIZE;
	ep->qp.sq_mem_size =
		(ep->qp.sq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK;
	ep->qp.sq_pgtbl_size =
		(ep->qp.sq_mem_size / PAGE_SIZE) * sizeof(void *);
	ep->qp.sq_pgtbl_size =
		(ep->qp.sq_pgtbl_size + (PAGE_SIZE - 1)) & PAGE_MASK;

	ep->qp.sq_pgtbl_virt =
		dma_alloc_coherent(&hba->pcidev->dev, ep->qp.sq_pgtbl_size,
				   &ep->qp.sq_pgtbl_phys, GFP_KERNEL);
	if (!ep->qp.sq_pgtbl_virt) {
		printk(KERN_ALERT "bnx2i: unable to alloc SQ PT mem (%d)\n",
				  ep->qp.sq_pgtbl_size);
		goto mem_alloc_err;
	}

	/* Allocate memory area for actual SQ element */
	ep->qp.sq_virt =
		dma_alloc_coherent(&hba->pcidev->dev, ep->qp.sq_mem_size,
				   &ep->qp.sq_phys, GFP_KERNEL);
	if (!ep->qp.sq_virt) {
		printk(KERN_ALERT "bnx2i: unable to alloc SQ BD memory %d\n",
				  ep->qp.sq_mem_size);
		goto mem_alloc_err;
	}

	memset(ep->qp.sq_virt, 0x00, ep->qp.sq_mem_size);
	ep->qp.sq_first_qe = ep->qp.sq_virt;
	ep->qp.sq_prod_qe = ep->qp.sq_first_qe;
	ep->qp.sq_cons_qe = ep->qp.sq_first_qe;
	ep->qp.sq_last_qe = &ep->qp.sq_first_qe[hba->max_sqes - 1];
	ep->qp.sq_prod_idx = 0;
	ep->qp.sq_cons_idx = 0;
	ep->qp.sqe_left = hba->max_sqes;

	/* Allocate page table memory for CQ which is page aligned */
	ep->qp.cq_mem_size = hba->max_cqes * BNX2I_CQE_SIZE;
	ep->qp.cq_mem_size =
		(ep->qp.cq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK;
	ep->qp.cq_pgtbl_size =
		(ep->qp.cq_mem_size / PAGE_SIZE) * sizeof(void *);
	ep->qp.cq_pgtbl_size =
		(ep->qp.cq_pgtbl_size + (PAGE_SIZE - 1)) & PAGE_MASK;

	ep->qp.cq_pgtbl_virt =
		dma_alloc_coherent(&hba->pcidev->dev, ep->qp.cq_pgtbl_size,
				   &ep->qp.cq_pgtbl_phys, GFP_KERNEL);
	if (!ep->qp.cq_pgtbl_virt) {
		printk(KERN_ALERT "bnx2i: unable to alloc CQ PT memory %d\n",
				  ep->qp.cq_pgtbl_size);
		goto mem_alloc_err;
	}

	/* Allocate memory area for actual CQ element */
	ep->qp.cq_virt =
		dma_alloc_coherent(&hba->pcidev->dev, ep->qp.cq_mem_size,
				   &ep->qp.cq_phys, GFP_KERNEL);
	if (!ep->qp.cq_virt) {
		printk(KERN_ALERT "bnx2i: unable to alloc CQ BD memory %d\n",
				  ep->qp.cq_mem_size);
		goto mem_alloc_err;
	}
	memset(ep->qp.cq_virt, 0x00, ep->qp.cq_mem_size);

	ep->qp.cq_first_qe = ep->qp.cq_virt;
	ep->qp.cq_prod_qe = ep->qp.cq_first_qe;
	ep->qp.cq_cons_qe = ep->qp.cq_first_qe;
	ep->qp.cq_last_qe = &ep->qp.cq_first_qe[hba->max_cqes - 1];
	ep->qp.cq_prod_idx = 0;
	ep->qp.cq_cons_idx = 0;
	ep->qp.cqe_left = hba->max_cqes;
	ep->qp.cqe_exp_seq_sn = ISCSI_INITIAL_SN;
	ep->qp.cqe_size = hba->max_cqes;

	/* Invalidate all EQ CQE index, req only for 57710 */
	cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
	memset(cq_db->sqn, 0xFF, sizeof(cq_db->sqn[0]) * BNX2X_MAX_CQS);

	/* Allocate page table memory for RQ which is page aligned */
	ep->qp.rq_mem_size = hba->max_rqes * BNX2I_RQ_WQE_SIZE;
	ep->qp.rq_mem_size =
		(ep->qp.rq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK;
	ep->qp.rq_pgtbl_size =
		(ep->qp.rq_mem_size / PAGE_SIZE) * sizeof(void *);
	ep->qp.rq_pgtbl_size =
		(ep->qp.rq_pgtbl_size + (PAGE_SIZE - 1)) & PAGE_MASK;

	ep->qp.rq_pgtbl_virt =
		dma_alloc_coherent(&hba->pcidev->dev, ep->qp.rq_pgtbl_size,
				   &ep->qp.rq_pgtbl_phys, GFP_KERNEL);
	if (!ep->qp.rq_pgtbl_virt) {
		printk(KERN_ALERT "bnx2i: unable to alloc RQ PT mem %d\n",
				  ep->qp.rq_pgtbl_size);
		goto mem_alloc_err;
	}

	/* Allocate memory area for actual RQ element */
	ep->qp.rq_virt =
		dma_alloc_coherent(&hba->pcidev->dev, ep->qp.rq_mem_size,
				   &ep->qp.rq_phys, GFP_KERNEL);
	if (!ep->qp.rq_virt) {
		printk(KERN_ALERT "bnx2i: unable to alloc RQ BD memory %d\n",
				  ep->qp.rq_mem_size);
		goto mem_alloc_err;
	}

	ep->qp.rq_first_qe = ep->qp.rq_virt;
	ep->qp.rq_prod_qe = ep->qp.rq_first_qe;
	ep->qp.rq_cons_qe = ep->qp.rq_first_qe;
	ep->qp.rq_last_qe = &ep->qp.rq_first_qe[hba->max_rqes - 1];
	ep->qp.rq_prod_idx = 0x8000;
	ep->qp.rq_cons_idx = 0;
	ep->qp.rqe_left = hba->max_rqes;

	setup_qp_page_tables(ep);

	return 0;

mem_alloc_err:
	bnx2i_free_qp_resc(hba, ep);
	return -ENOMEM;
}



/**
 * bnx2i_free_qp_resc - free memory resources held by QP
 * @hba:	adapter structure pointer
 * @ep:	endpoint (transport indentifier) structure
 *
 * Free QP resources - SQ/RQ/CQ memory and page tables.
 */
void bnx2i_free_qp_resc(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
{
	if (ep->qp.ctx_base) {
		iounmap(ep->qp.ctx_base);
		ep->qp.ctx_base = NULL;
	}
	/* Free SQ mem */
	if (ep->qp.sq_pgtbl_virt) {
		dma_free_coherent(&hba->pcidev->dev, ep->qp.sq_pgtbl_size,
				  ep->qp.sq_pgtbl_virt, ep->qp.sq_pgtbl_phys);
		ep->qp.sq_pgtbl_virt = NULL;
		ep->qp.sq_pgtbl_phys = 0;
	}
	if (ep->qp.sq_virt) {
		dma_free_coherent(&hba->pcidev->dev, ep->qp.sq_mem_size,
				  ep->qp.sq_virt, ep->qp.sq_phys);
		ep->qp.sq_virt = NULL;
		ep->qp.sq_phys = 0;
	}

	/* Free RQ mem */
	if (ep->qp.rq_pgtbl_virt) {
		dma_free_coherent(&hba->pcidev->dev, ep->qp.rq_pgtbl_size,
				  ep->qp.rq_pgtbl_virt, ep->qp.rq_pgtbl_phys);
		ep->qp.rq_pgtbl_virt = NULL;
		ep->qp.rq_pgtbl_phys = 0;
	}
	if (ep->qp.rq_virt) {
		dma_free_coherent(&hba->pcidev->dev, ep->qp.rq_mem_size,
				  ep->qp.rq_virt, ep->qp.rq_phys);
		ep->qp.rq_virt = NULL;
		ep->qp.rq_phys = 0;
	}

	/* Free CQ mem */
	if (ep->qp.cq_pgtbl_virt) {
		dma_free_coherent(&hba->pcidev->dev, ep->qp.cq_pgtbl_size,
				  ep->qp.cq_pgtbl_virt, ep->qp.cq_pgtbl_phys);
		ep->qp.cq_pgtbl_virt = NULL;
		ep->qp.cq_pgtbl_phys = 0;
	}
	if (ep->qp.cq_virt) {
		dma_free_coherent(&hba->pcidev->dev, ep->qp.cq_mem_size,
				  ep->qp.cq_virt, ep->qp.cq_phys);
		ep->qp.cq_virt = NULL;
		ep->qp.cq_phys = 0;
	}
}


/**
 * bnx2i_send_fw_iscsi_init_msg - initiates initial handshake with iscsi f/w
 * @hba:	adapter structure pointer
 *
 * Send down iscsi_init KWQEs which initiates the initial handshake with the f/w
 * 	This results in iSCSi support validation and on-chip context manager
 * 	initialization.  Firmware completes this handshake with a CQE carrying
 * 	the result of iscsi support validation. Parameter carried by
 * 	iscsi init request determines the number of offloaded connection and
 * 	tolerance level for iscsi protocol violation this hba/chip can support
 */
int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba)
{
	struct kwqe *kwqe_arr[3];
	struct iscsi_kwqe_init1 iscsi_init;
	struct iscsi_kwqe_init2 iscsi_init2;
	int rc = 0;
	u64 mask64;

	bnx2i_adjust_qp_size(hba);

	iscsi_init.flags =
		ISCSI_PAGE_SIZE_4K << ISCSI_KWQE_INIT1_PAGE_SIZE_SHIFT;
	if (en_tcp_dack)
		iscsi_init.flags |= ISCSI_KWQE_INIT1_DELAYED_ACK_ENABLE;
	iscsi_init.reserved0 = 0;
	iscsi_init.num_cqs = 1;
	iscsi_init.hdr.op_code = ISCSI_KWQE_OPCODE_INIT1;
	iscsi_init.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);

	iscsi_init.dummy_buffer_addr_lo = (u32) hba->dummy_buf_dma;
	iscsi_init.dummy_buffer_addr_hi =
		(u32) ((u64) hba->dummy_buf_dma >> 32);

	hba->ctx_ccell_tasks =
			((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16));
	iscsi_init.num_ccells_per_conn = hba->num_ccell;
	iscsi_init.num_tasks_per_conn = hba->max_sqes;
	iscsi_init.sq_wqes_per_page = PAGE_SIZE / BNX2I_SQ_WQE_SIZE;
	iscsi_init.sq_num_wqes = hba->max_sqes;
	iscsi_init.cq_log_wqes_per_page =
		(u8) bnx2i_power_of2(PAGE_SIZE / BNX2I_CQE_SIZE);
	iscsi_init.cq_num_wqes = hba->max_cqes;
	iscsi_init.cq_num_pages = (hba->max_cqes * BNX2I_CQE_SIZE +
				   (PAGE_SIZE - 1)) / PAGE_SIZE;
	iscsi_init.sq_num_pages = (hba->max_sqes * BNX2I_SQ_WQE_SIZE +
				   (PAGE_SIZE - 1)) / PAGE_SIZE;
	iscsi_init.rq_buffer_size = BNX2I_RQ_WQE_SIZE;
	iscsi_init.rq_num_wqes = hba->max_rqes;


	iscsi_init2.hdr.op_code = ISCSI_KWQE_OPCODE_INIT2;
	iscsi_init2.hdr.flags =
		(ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT);
	iscsi_init2.max_cq_sqn = hba->max_cqes * 2 + 1;
	mask64 = 0x0ULL;
	mask64 |= (
		/* CISCO MDS */
		(1UL <<
		  ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_NOT_RSRV) |
		/* HP MSA1510i */
		(1UL <<
		  ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_EXP_DATASN) |
		/* EMC */
		(1ULL << ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_LUN));
	if (error_mask1)
		iscsi_init2.error_bit_map[0] = error_mask1;
	else
		iscsi_init2.error_bit_map[0] = (u32) mask64;

	if (error_mask2)
		iscsi_init2.error_bit_map[1] = error_mask2;
	else
		iscsi_init2.error_bit_map[1] = (u32) (mask64 >> 32);

	iscsi_error_mask = mask64;

	kwqe_arr[0] = (struct kwqe *) &iscsi_init;
	kwqe_arr[1] = (struct kwqe *) &iscsi_init2;

	if (hba->cnic && hba->cnic->submit_kwqes)
		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 2);
	return rc;
}


/**
 * bnx2i_process_scsi_cmd_resp - this function handles scsi cmd completion.
 * @conn:	iscsi connection
 * @cqe:	pointer to newly DMA'ed CQE entry for processing
 *
 * process SCSI CMD Response CQE & complete the request to SCSI-ML
 */
static int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session,
				       struct bnx2i_conn *bnx2i_conn,
				       struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct bnx2i_cmd_response *resp_cqe;
	struct bnx2i_cmd *bnx2i_cmd;
	struct iscsi_task *task;
	struct iscsi_cmd_rsp *hdr;
	u32 datalen = 0;

	resp_cqe = (struct bnx2i_cmd_response *)cqe;
	spin_lock(&session->lock);
	task = iscsi_itt_to_task(conn,
				 resp_cqe->itt & ISCSI_CMD_RESPONSE_INDEX);
	if (!task)
		goto fail;

	bnx2i_cmd = task->dd_data;

	if (bnx2i_cmd->req.op_attr & ISCSI_CMD_REQUEST_READ) {
		conn->datain_pdus_cnt +=
			resp_cqe->task_stat.read_stat.num_data_outs;
		conn->rxdata_octets +=
			bnx2i_cmd->req.total_data_transfer_length;
	} else {
		conn->dataout_pdus_cnt +=
			resp_cqe->task_stat.read_stat.num_data_outs;
		conn->r2t_pdus_cnt +=
			resp_cqe->task_stat.read_stat.num_r2ts;
		conn->txdata_octets +=
			bnx2i_cmd->req.total_data_transfer_length;
	}
	bnx2i_iscsi_unmap_sg_list(bnx2i_cmd);

	hdr = (struct iscsi_cmd_rsp *)task->hdr;
	resp_cqe = (struct bnx2i_cmd_response *)cqe;
	hdr->opcode = resp_cqe->op_code;
	hdr->max_cmdsn = cpu_to_be32(resp_cqe->max_cmd_sn);
	hdr->exp_cmdsn = cpu_to_be32(resp_cqe->exp_cmd_sn);
	hdr->response = resp_cqe->response;
	hdr->cmd_status = resp_cqe->status;
	hdr->flags = resp_cqe->response_flags;
	hdr->residual_count = cpu_to_be32(resp_cqe->residual_count);

	if (resp_cqe->op_code == ISCSI_OP_SCSI_DATA_IN)
		goto done;

	if (resp_cqe->status == SAM_STAT_CHECK_CONDITION) {
		datalen = resp_cqe->data_length;
		if (datalen < 2)
			goto done;

		if (datalen > BNX2I_RQ_WQE_SIZE) {
			iscsi_conn_printk(KERN_ERR, conn,
					  "sense data len %d > RQ sz\n",
					  datalen);
			datalen = BNX2I_RQ_WQE_SIZE;
		} else if (datalen > ISCSI_DEF_MAX_RECV_SEG_LEN) {
			iscsi_conn_printk(KERN_ERR, conn,
					  "sense data len %d > conn data\n",
					  datalen);
			datalen = ISCSI_DEF_MAX_RECV_SEG_LEN;
		}

		bnx2i_get_rq_buf(bnx2i_cmd->conn, conn->data, datalen);
		bnx2i_put_rq_buf(bnx2i_cmd->conn, 1);
	}

done:
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr,
			     conn->data, datalen);
fail:
	spin_unlock(&session->lock);
	return 0;
}


/**
 * bnx2i_process_login_resp - this function handles iscsi login response
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process Login Response CQE & complete it to open-iscsi user daemon
 */
static int bnx2i_process_login_resp(struct iscsi_session *session,
				    struct bnx2i_conn *bnx2i_conn,
				    struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_task *task;
	struct bnx2i_login_response *login;
	struct iscsi_login_rsp *resp_hdr;
	int pld_len;
	int pad_len;

	login = (struct bnx2i_login_response *) cqe;
	spin_lock(&session->lock);
	task = iscsi_itt_to_task(conn,
				 login->itt & ISCSI_LOGIN_RESPONSE_INDEX);
	if (!task)
		goto done;

	resp_hdr = (struct iscsi_login_rsp *) &bnx2i_conn->gen_pdu.resp_hdr;
	memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
	resp_hdr->opcode = login->op_code;
	resp_hdr->flags = login->response_flags;
	resp_hdr->max_version = login->version_max;
	resp_hdr->active_version = login->version_active;
	resp_hdr->hlength = 0;

	hton24(resp_hdr->dlength, login->data_length);
	memcpy(resp_hdr->isid, &login->isid_lo, 6);
	resp_hdr->tsih = cpu_to_be16(login->tsih);
	resp_hdr->itt = task->hdr->itt;
	resp_hdr->statsn = cpu_to_be32(login->stat_sn);
	resp_hdr->exp_cmdsn = cpu_to_be32(login->exp_cmd_sn);
	resp_hdr->max_cmdsn = cpu_to_be32(login->max_cmd_sn);
	resp_hdr->status_class = login->status_class;
	resp_hdr->status_detail = login->status_detail;
	pld_len = login->data_length;
	bnx2i_conn->gen_pdu.resp_wr_ptr =
					bnx2i_conn->gen_pdu.resp_buf + pld_len;

	pad_len = 0;
	if (pld_len & 0x3)
		pad_len = 4 - (pld_len % 4);

	if (pad_len) {
		int i = 0;
		for (i = 0; i < pad_len; i++) {
			bnx2i_conn->gen_pdu.resp_wr_ptr[0] = 0;
			bnx2i_conn->gen_pdu.resp_wr_ptr++;
		}
	}

	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr,
		bnx2i_conn->gen_pdu.resp_buf,
		bnx2i_conn->gen_pdu.resp_wr_ptr - bnx2i_conn->gen_pdu.resp_buf);
done:
	spin_unlock(&session->lock);
	return 0;
}

/**
 * bnx2i_process_tmf_resp - this function handles iscsi TMF response
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process iSCSI TMF Response CQE and wake up the driver eh thread.
 */
static int bnx2i_process_tmf_resp(struct iscsi_session *session,
				  struct bnx2i_conn *bnx2i_conn,
				  struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_task *task;
	struct bnx2i_tmf_response *tmf_cqe;
	struct iscsi_tm_rsp *resp_hdr;

	tmf_cqe = (struct bnx2i_tmf_response *)cqe;
	spin_lock(&session->lock);
	task = iscsi_itt_to_task(conn,
				 tmf_cqe->itt & ISCSI_TMF_RESPONSE_INDEX);
	if (!task)
		goto done;

	resp_hdr = (struct iscsi_tm_rsp *) &bnx2i_conn->gen_pdu.resp_hdr;
	memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
	resp_hdr->opcode = tmf_cqe->op_code;
	resp_hdr->max_cmdsn = cpu_to_be32(tmf_cqe->max_cmd_sn);
	resp_hdr->exp_cmdsn = cpu_to_be32(tmf_cqe->exp_cmd_sn);
	resp_hdr->itt = task->hdr->itt;
	resp_hdr->response = tmf_cqe->response;

	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
done:
	spin_unlock(&session->lock);
	return 0;
}

/**
 * bnx2i_process_logout_resp - this function handles iscsi logout response
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process iSCSI Logout Response CQE & make function call to
 * notify the user daemon.
 */
static int bnx2i_process_logout_resp(struct iscsi_session *session,
				     struct bnx2i_conn *bnx2i_conn,
				     struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_task *task;
	struct bnx2i_logout_response *logout;
	struct iscsi_logout_rsp *resp_hdr;

	logout = (struct bnx2i_logout_response *) cqe;
	spin_lock(&session->lock);
	task = iscsi_itt_to_task(conn,
				 logout->itt & ISCSI_LOGOUT_RESPONSE_INDEX);
	if (!task)
		goto done;

	resp_hdr = (struct iscsi_logout_rsp *) &bnx2i_conn->gen_pdu.resp_hdr;
	memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
	resp_hdr->opcode = logout->op_code;
	resp_hdr->flags = logout->response;
	resp_hdr->hlength = 0;

	resp_hdr->itt = task->hdr->itt;
	resp_hdr->statsn = task->hdr->exp_statsn;
	resp_hdr->exp_cmdsn = cpu_to_be32(logout->exp_cmd_sn);
	resp_hdr->max_cmdsn = cpu_to_be32(logout->max_cmd_sn);

	resp_hdr->t2wait = cpu_to_be32(logout->time_to_wait);
	resp_hdr->t2retain = cpu_to_be32(logout->time_to_retain);

	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);

	bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD;
done:
	spin_unlock(&session->lock);
	return 0;
}

/**
 * bnx2i_process_nopin_local_cmpl - this function handles iscsi nopin CQE
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process iSCSI NOPIN local completion CQE, frees IIT and command structures
 */
static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session,
					   struct bnx2i_conn *bnx2i_conn,
					   struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct bnx2i_nop_in_msg *nop_in;
	struct iscsi_task *task;

	nop_in = (struct bnx2i_nop_in_msg *)cqe;
	spin_lock(&session->lock);
	task = iscsi_itt_to_task(conn,
				 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
	if (task)
		__iscsi_put_task(task);
	spin_unlock(&session->lock);
}

/**
 * bnx2i_unsol_pdu_adjust_rq - makes adjustments to RQ after unsol pdu is recvd
 * @conn:	iscsi connection
 *
 * Firmware advances RQ producer index for every unsolicited PDU even if
 *	payload data length is '0'. This function makes corresponding
 *	adjustments on the driver side to match this f/w behavior
 */
static void bnx2i_unsol_pdu_adjust_rq(struct bnx2i_conn *bnx2i_conn)
{
	char dummy_rq_data[2];
	bnx2i_get_rq_buf(bnx2i_conn, dummy_rq_data, 1);
	bnx2i_put_rq_buf(bnx2i_conn, 1);
}


/**
 * bnx2i_process_nopin_mesg - this function handles iscsi nopin CQE
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process iSCSI target's proactive iSCSI NOPIN request
 */
static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
				     struct bnx2i_conn *bnx2i_conn,
				     struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_task *task;
	struct bnx2i_nop_in_msg *nop_in;
	struct iscsi_nopin *hdr;
	int tgt_async_nop = 0;

	nop_in = (struct bnx2i_nop_in_msg *)cqe;

	spin_lock(&session->lock);
	hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr;
	memset(hdr, 0, sizeof(struct iscsi_hdr));
	hdr->opcode = nop_in->op_code;
	hdr->max_cmdsn = cpu_to_be32(nop_in->max_cmd_sn);
	hdr->exp_cmdsn = cpu_to_be32(nop_in->exp_cmd_sn);
	hdr->ttt = cpu_to_be32(nop_in->ttt);

	if (nop_in->itt == (u16) RESERVED_ITT) {
		bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
		hdr->itt = RESERVED_ITT;
		tgt_async_nop = 1;
		goto done;
	}

	/* this is a response to one of our nop-outs */
	task = iscsi_itt_to_task(conn,
			 (itt_t) (nop_in->itt & ISCSI_NOP_IN_MSG_INDEX));
	if (task) {
		hdr->flags = ISCSI_FLAG_CMD_FINAL;
		hdr->itt = task->hdr->itt;
		hdr->ttt = cpu_to_be32(nop_in->ttt);
		memcpy(hdr->lun, nop_in->lun, 8);
	}
done:
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
	spin_unlock(&session->lock);

	return tgt_async_nop;
}


/**
 * bnx2i_process_async_mesg - this function handles iscsi async message
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process iSCSI ASYNC Message
 */
static void bnx2i_process_async_mesg(struct iscsi_session *session,
				     struct bnx2i_conn *bnx2i_conn,
				     struct cqe *cqe)
{
	struct bnx2i_async_msg *async_cqe;
	struct iscsi_async *resp_hdr;
	u8 async_event;

	bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);

	async_cqe = (struct bnx2i_async_msg *)cqe;
	async_event = async_cqe->async_event;

	if (async_event == ISCSI_ASYNC_MSG_SCSI_EVENT) {
		iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data,
				  "async: scsi events not supported\n");
		return;
	}

	spin_lock(&session->lock);
	resp_hdr = (struct iscsi_async *) &bnx2i_conn->gen_pdu.resp_hdr;
	memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
	resp_hdr->opcode = async_cqe->op_code;
	resp_hdr->flags = 0x80;

	memcpy(resp_hdr->lun, async_cqe->lun, 8);
	resp_hdr->exp_cmdsn = cpu_to_be32(async_cqe->exp_cmd_sn);
	resp_hdr->max_cmdsn = cpu_to_be32(async_cqe->max_cmd_sn);

	resp_hdr->async_event = async_cqe->async_event;
	resp_hdr->async_vcode = async_cqe->async_vcode;

	resp_hdr->param1 = cpu_to_be16(async_cqe->param1);
	resp_hdr->param2 = cpu_to_be16(async_cqe->param2);
	resp_hdr->param3 = cpu_to_be16(async_cqe->param3);

	__iscsi_complete_pdu(bnx2i_conn->cls_conn->dd_data,
			     (struct iscsi_hdr *)resp_hdr, NULL, 0);
	spin_unlock(&session->lock);
}


/**
 * bnx2i_process_reject_mesg - process iscsi reject pdu
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process iSCSI REJECT message
 */
static void bnx2i_process_reject_mesg(struct iscsi_session *session,
				      struct bnx2i_conn *bnx2i_conn,
				      struct cqe *cqe)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct bnx2i_reject_msg *reject;
	struct iscsi_reject *hdr;

	reject = (struct bnx2i_reject_msg *) cqe;
	if (reject->data_length) {
		bnx2i_get_rq_buf(bnx2i_conn, conn->data, reject->data_length);
		bnx2i_put_rq_buf(bnx2i_conn, 1);
	} else
		bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);

	spin_lock(&session->lock);
	hdr = (struct iscsi_reject *) &bnx2i_conn->gen_pdu.resp_hdr;
	memset(hdr, 0, sizeof(struct iscsi_hdr));
	hdr->opcode = reject->op_code;
	hdr->reason = reject->reason;
	hton24(hdr->dlength, reject->data_length);
	hdr->max_cmdsn = cpu_to_be32(reject->max_cmd_sn);
	hdr->exp_cmdsn = cpu_to_be32(reject->exp_cmd_sn);
	hdr->ffffffff = cpu_to_be32(RESERVED_ITT);
	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, conn->data,
			     reject->data_length);
	spin_unlock(&session->lock);
}

/**
 * bnx2i_process_cmd_cleanup_resp - process scsi command clean-up completion
 * @session:		iscsi session pointer
 * @bnx2i_conn:		iscsi connection pointer
 * @cqe:		pointer to newly DMA'ed CQE entry for processing
 *
 * process command cleanup response CQE during conn shutdown or error recovery
 */
static void bnx2i_process_cmd_cleanup_resp(struct iscsi_session *session,
					   struct bnx2i_conn *bnx2i_conn,
					   struct cqe *cqe)
{
	struct bnx2i_cleanup_response *cmd_clean_rsp;
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_task *task;

	cmd_clean_rsp = (struct bnx2i_cleanup_response *)cqe;
	spin_lock(&session->lock);
	task = iscsi_itt_to_task(conn,
			cmd_clean_rsp->itt & ISCSI_CLEANUP_RESPONSE_INDEX);
	if (!task)
		printk(KERN_ALERT "bnx2i: cmd clean ITT %x not active\n",
			cmd_clean_rsp->itt & ISCSI_CLEANUP_RESPONSE_INDEX);
	spin_unlock(&session->lock);
	complete(&bnx2i_conn->cmd_cleanup_cmpl);
}



/**
 * bnx2i_process_new_cqes - process newly DMA'ed CQE's
 * @bnx2i_conn:		iscsi connection
 *
 * this function is called by generic KCQ handler to process all pending CQE's
 */
static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
{
	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
	struct iscsi_session *session = conn->session;
	struct qp_info *qp = &bnx2i_conn->ep->qp;
	struct bnx2i_nop_in_msg *nopin;
	int tgt_async_msg;

	while (1) {
		nopin = (struct bnx2i_nop_in_msg *) qp->cq_cons_qe;
		if (nopin->cq_req_sn != qp->cqe_exp_seq_sn)
			break;

		if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx))) {
			if (nopin->op_code == ISCSI_OP_NOOP_IN &&
			    nopin->itt == (u16) RESERVED_ITT) {
				printk(KERN_ALERT "bnx2i: Unsolicited "
					"NOP-In detected for suspended "
					"connection dev=%s!\n",
					bnx2i_conn->hba->netdev->name);
				bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
				goto cqe_out;
			}
			break;
		}
		tgt_async_msg = 0;

		switch (nopin->op_code) {
		case ISCSI_OP_SCSI_CMD_RSP:
		case ISCSI_OP_SCSI_DATA_IN:
			bnx2i_process_scsi_cmd_resp(session, bnx2i_conn,
						    qp->cq_cons_qe);
			break;
		case ISCSI_OP_LOGIN_RSP:
			bnx2i_process_login_resp(session, bnx2i_conn,
						 qp->cq_cons_qe);
			break;
		case ISCSI_OP_SCSI_TMFUNC_RSP:
			bnx2i_process_tmf_resp(session, bnx2i_conn,
					       qp->cq_cons_qe);
			break;
		case ISCSI_OP_LOGOUT_RSP:
			bnx2i_process_logout_resp(session, bnx2i_conn,
						  qp->cq_cons_qe);
			break;
		case ISCSI_OP_NOOP_IN:
			if (bnx2i_process_nopin_mesg(session, bnx2i_conn,
						     qp->cq_cons_qe))
				tgt_async_msg = 1;
			break;
		case ISCSI_OPCODE_NOPOUT_LOCAL_COMPLETION:
			bnx2i_process_nopin_local_cmpl(session, bnx2i_conn,
						       qp->cq_cons_qe);
			break;
		case ISCSI_OP_ASYNC_EVENT:
			bnx2i_process_async_mesg(session, bnx2i_conn,
						 qp->cq_cons_qe);
			tgt_async_msg = 1;
			break;
		case ISCSI_OP_REJECT:
			bnx2i_process_reject_mesg(session, bnx2i_conn,
						  qp->cq_cons_qe);
			break;
		case ISCSI_OPCODE_CLEANUP_RESPONSE:
			bnx2i_process_cmd_cleanup_resp(session, bnx2i_conn,
						       qp->cq_cons_qe);
			break;
		default:
			printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n",
					  nopin->op_code);
		}
		if (!tgt_async_msg)
			bnx2i_conn->ep->num_active_cmds--;
cqe_out:
		/* clear out in production version only, till beta keep opcode
		 * field intact, will be helpful in debugging (context dump)
		 * nopin->op_code = 0;
		 */
		qp->cqe_exp_seq_sn++;
		if (qp->cqe_exp_seq_sn == (qp->cqe_size * 2 + 1))
			qp->cqe_exp_seq_sn = ISCSI_INITIAL_SN;

		if (qp->cq_cons_qe == qp->cq_last_qe) {
			qp->cq_cons_qe = qp->cq_first_qe;
			qp->cq_cons_idx = 0;
		} else {
			qp->cq_cons_qe++;
			qp->cq_cons_idx++;
		}
	}
	bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE);
}

/**
 * bnx2i_fastpath_notification - process global event queue (KCQ)
 * @hba:		adapter structure pointer
 * @new_cqe_kcqe:	pointer to newly DMA'ed KCQE entry
 *
 * Fast path event notification handler, KCQ entry carries context id
 *	of the connection that has 1 or more pending CQ entries
 */
static void bnx2i_fastpath_notification(struct bnx2i_hba *hba,
					struct iscsi_kcqe *new_cqe_kcqe)
{
	struct bnx2i_conn *conn;
	u32 iscsi_cid;

	iscsi_cid = new_cqe_kcqe->iscsi_conn_id;
	conn = bnx2i_get_conn_from_id(hba, iscsi_cid);

	if (!conn) {
		printk(KERN_ALERT "cid #%x not valid\n", iscsi_cid);
		return;
	}
	if (!conn->ep) {
		printk(KERN_ALERT "cid #%x - ep not bound\n", iscsi_cid);
		return;
	}

	bnx2i_process_new_cqes(conn);
}


/**
 * bnx2i_process_update_conn_cmpl - process iscsi conn update completion KCQE
 * @hba:		adapter structure pointer
 * @update_kcqe:	kcqe pointer
 *
 * CONN_UPDATE completion handler, this completes iSCSI connection FFP migration
 */
static void bnx2i_process_update_conn_cmpl(struct bnx2i_hba *hba,
					   struct iscsi_kcqe *update_kcqe)
{
	struct bnx2i_conn *conn;
	u32 iscsi_cid;

	iscsi_cid = update_kcqe->iscsi_conn_id;
	conn = bnx2i_get_conn_from_id(hba, iscsi_cid);

	if (!conn) {
		printk(KERN_ALERT "conn_update: cid %x not valid\n", iscsi_cid);
		return;
	}
	if (!conn->ep) {
		printk(KERN_ALERT "cid %x does not have ep bound\n", iscsi_cid);
		return;
	}

	if (update_kcqe->completion_status) {
		printk(KERN_ALERT "request failed cid %x\n", iscsi_cid);
		conn->ep->state = EP_STATE_ULP_UPDATE_FAILED;
	} else
		conn->ep->state = EP_STATE_ULP_UPDATE_COMPL;

	wake_up_interruptible(&conn->ep->ofld_wait);
}


/**
 * bnx2i_recovery_que_add_conn - add connection to recovery queue
 * @hba:		adapter structure pointer
 * @bnx2i_conn:		iscsi connection
 *
 * Add connection to recovery queue and schedule adapter eh worker
 */
static void bnx2i_recovery_que_add_conn(struct bnx2i_hba *hba,
					struct bnx2i_conn *bnx2i_conn)
{
	iscsi_conn_failure(bnx2i_conn->cls_conn->dd_data,
			   ISCSI_ERR_CONN_FAILED);
}


/**
 * bnx2i_process_tcp_error - process error notification on a given connection
 *
 * @hba: 		adapter structure pointer
 * @tcp_err: 		tcp error kcqe pointer
 *
 * handles tcp level error notifications from FW.
 */
static void bnx2i_process_tcp_error(struct bnx2i_hba *hba,
				    struct iscsi_kcqe *tcp_err)
{
	struct bnx2i_conn *bnx2i_conn;
	u32 iscsi_cid;

	iscsi_cid = tcp_err->iscsi_conn_id;
	bnx2i_conn = bnx2i_get_conn_from_id(hba, iscsi_cid);

	if (!bnx2i_conn) {
		printk(KERN_ALERT "bnx2i - cid 0x%x not valid\n", iscsi_cid);
		return;
	}

	printk(KERN_ALERT "bnx2i - cid 0x%x had TCP errors, error code 0x%x\n",
			  iscsi_cid, tcp_err->completion_status);
	bnx2i_recovery_que_add_conn(bnx2i_conn->hba, bnx2i_conn);
}


/**
 * bnx2i_process_iscsi_error - process error notification on a given connection
 * @hba:		adapter structure pointer
 * @iscsi_err:		iscsi error kcqe pointer
 *
 * handles iscsi error notifications from the FW. Firmware based in initial
 *	handshake classifies iscsi protocol / TCP rfc violation into either
 *	warning or error indications. If indication is of "Error" type, driver
 *	will initiate session recovery for that connection/session. For
 *	"Warning" type indication, driver will put out a system log message
 *	(there will be only one message for each type for the life of the
 *	session, this is to avoid un-necessarily overloading the system)
 */
static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba,
				      struct iscsi_kcqe *iscsi_err)
{
	struct bnx2i_conn *bnx2i_conn;
	u32 iscsi_cid;
	char warn_notice[] = "iscsi_warning";
	char error_notice[] = "iscsi_error";
	char additional_notice[64];
	char *message;
	int need_recovery;
	u64 err_mask64;

	iscsi_cid = iscsi_err->iscsi_conn_id;
	bnx2i_conn = bnx2i_get_conn_from_id(hba, iscsi_cid);
	if (!bnx2i_conn) {
		printk(KERN_ALERT "bnx2i - cid 0x%x not valid\n", iscsi_cid);
		return;
	}

	err_mask64 = (0x1ULL << iscsi_err->completion_status);

	if (err_mask64 & iscsi_error_mask) {
		need_recovery = 0;
		message = warn_notice;
	} else {
		need_recovery = 1;
		message = error_notice;
	}

	switch (iscsi_err->completion_status) {
	case ISCSI_KCQE_COMPLETION_STATUS_HDR_DIG_ERR:
		strcpy(additional_notice, "hdr digest err");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_DATA_DIG_ERR:
		strcpy(additional_notice, "data digest err");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_OPCODE:
		strcpy(additional_notice, "wrong opcode rcvd");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_AHS_LEN:
		strcpy(additional_notice, "AHS len > 0 rcvd");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ITT:
		strcpy(additional_notice, "invalid ITT rcvd");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_STATSN:
		strcpy(additional_notice, "wrong StatSN rcvd");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_EXP_DATASN:
		strcpy(additional_notice, "wrong DataSN rcvd");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T:
		strcpy(additional_notice, "pend R2T violation");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_0:
		strcpy(additional_notice, "ERL0, UO");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_1:
		strcpy(additional_notice, "ERL0, U1");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_2:
		strcpy(additional_notice, "ERL0, U2");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_3:
		strcpy(additional_notice, "ERL0, U3");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_4:
		strcpy(additional_notice, "ERL0, U4");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_5:
		strcpy(additional_notice, "ERL0, U5");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_6:
		strcpy(additional_notice, "ERL0, U6");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_RCV_LEN:
		strcpy(additional_notice, "invalid resi len");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_RCV_PDU_LEN:
		strcpy(additional_notice, "MRDSL violation");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_F_BIT_ZERO:
		strcpy(additional_notice, "F-bit not set");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_NOT_RSRV:
		strcpy(additional_notice, "invalid TTT");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATASN:
		strcpy(additional_notice, "invalid DataSN");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_BURST_LEN:
		strcpy(additional_notice, "burst len violation");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_BUFFER_OFF:
		strcpy(additional_notice, "buf offset violation");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_LUN:
		strcpy(additional_notice, "invalid LUN field");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_R2TSN:
		strcpy(additional_notice, "invalid R2TSN field");
		break;
#define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0 	\
	ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_0
	case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0:
		strcpy(additional_notice, "invalid cmd len1");
		break;
#define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1 	\
	ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_1
	case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1:
		strcpy(additional_notice, "invalid cmd len2");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_EXCEED:
		strcpy(additional_notice,
		       "pend r2t exceeds MaxOutstandingR2T value");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_IS_RSRV:
		strcpy(additional_notice, "TTT is rsvd");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_BURST_LEN:
		strcpy(additional_notice, "MBL violation");
		break;
#define BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO 	\
	ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATA_SEG_LEN_NOT_ZERO
	case BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO:
		strcpy(additional_notice, "data seg len != 0");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REJECT_PDU_LEN:
		strcpy(additional_notice, "reject pdu len error");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ASYNC_PDU_LEN:
		strcpy(additional_notice, "async pdu len error");
		break;
	case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_NOPIN_PDU_LEN:
		strcpy(additional_notice, "nopin pdu len error");
		break;
#define BNX2_ERR_PEND_R2T_IN_CLEANUP			\
	ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_IN_CLEANUP
	case BNX2_ERR_PEND_R2T_IN_CLEANUP:
		strcpy(additional_notice, "pend r2t in cleanup");
		break;

	case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_FRAGMENT:
		strcpy(additional_notice, "IP fragments rcvd");
		break;
	case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_OPTIONS:
		strcpy(additional_notice, "IP options error");
		break;
	case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_URGENT_FLAG:
		strcpy(additional_notice, "urgent flag error");
		break;
	default:
		printk(KERN_ALERT "iscsi_err - unknown err %x\n",
				  iscsi_err->completion_status);
	}

	if (need_recovery) {
		iscsi_conn_printk(KERN_ALERT,
				  bnx2i_conn->cls_conn->dd_data,
				  "bnx2i: %s - %s\n",
				  message, additional_notice);

		iscsi_conn_printk(KERN_ALERT,
				  bnx2i_conn->cls_conn->dd_data,
				  "conn_err - hostno %d conn %p, "
				  "iscsi_cid %x cid %x\n",
				  bnx2i_conn->hba->shost->host_no,
				  bnx2i_conn, bnx2i_conn->ep->ep_iscsi_cid,
				  bnx2i_conn->ep->ep_cid);
		bnx2i_recovery_que_add_conn(bnx2i_conn->hba, bnx2i_conn);
	} else
		if (!test_and_set_bit(iscsi_err->completion_status,
				      (void *) &bnx2i_conn->violation_notified))
			iscsi_conn_printk(KERN_ALERT,
					  bnx2i_conn->cls_conn->dd_data,
					  "bnx2i: %s - %s\n",
					  message, additional_notice);
}


/**
 * bnx2i_process_conn_destroy_cmpl - process iscsi conn destroy completion
 * @hba:		adapter structure pointer
 * @conn_destroy:	conn destroy kcqe pointer
 *
 * handles connection destroy completion request.
 */
static void bnx2i_process_conn_destroy_cmpl(struct bnx2i_hba *hba,
					    struct iscsi_kcqe *conn_destroy)
{
	struct bnx2i_endpoint *ep;

	ep = bnx2i_find_ep_in_destroy_list(hba, conn_destroy->iscsi_conn_id);
	if (!ep) {
		printk(KERN_ALERT "bnx2i_conn_destroy_cmpl: no pending "
				  "offload request, unexpected complection\n");
		return;
	}

	if (hba != ep->hba) {
		printk(KERN_ALERT "conn destroy- error hba mis-match\n");
		return;
	}

	if (conn_destroy->completion_status) {
		printk(KERN_ALERT "conn_destroy_cmpl: op failed\n");
		ep->state = EP_STATE_CLEANUP_FAILED;
	} else
		ep->state = EP_STATE_CLEANUP_CMPL;
	wake_up_interruptible(&ep->ofld_wait);
}


/**
 * bnx2i_process_ofld_cmpl - process initial iscsi conn offload completion
 * @hba:		adapter structure pointer
 * @ofld_kcqe:		conn offload kcqe pointer
 *
 * handles initial connection offload completion, ep_connect() thread is
 *	woken-up to continue with LLP connect process
 */
static void bnx2i_process_ofld_cmpl(struct bnx2i_hba *hba,
				    struct iscsi_kcqe *ofld_kcqe)
{
	u32 cid_addr;
	struct bnx2i_endpoint *ep;
	u32 cid_num;

	ep = bnx2i_find_ep_in_ofld_list(hba, ofld_kcqe->iscsi_conn_id);
	if (!ep) {
		printk(KERN_ALERT "ofld_cmpl: no pend offload request\n");
		return;
	}

	if (hba != ep->hba) {
		printk(KERN_ALERT "ofld_cmpl: error hba mis-match\n");
		return;
	}

	if (ofld_kcqe->completion_status) {
		ep->state = EP_STATE_OFLD_FAILED;
		if (ofld_kcqe->completion_status ==
		    ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE)
			printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - unable "
				"to allocate iSCSI context resources\n",
				hba->netdev->name);
		else if (ofld_kcqe->completion_status ==
			 ISCSI_KCQE_COMPLETION_STATUS_INVALID_OPCODE)
			printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
				"opcode\n", hba->netdev->name);
		else if (ofld_kcqe->completion_status ==
			ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY)
			/* error status code valid only for 5771x chipset */
			ep->state = EP_STATE_OFLD_FAILED_CID_BUSY;
		else
			printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
				"error code %d\n", hba->netdev->name,
				ofld_kcqe->completion_status);
	} else {
		ep->state = EP_STATE_OFLD_COMPL;
		cid_addr = ofld_kcqe->iscsi_conn_context_id;
		cid_num = bnx2i_get_cid_num(ep);
		ep->ep_cid = cid_addr;
		ep->qp.ctx_base = NULL;
	}
	wake_up_interruptible(&ep->ofld_wait);
}

/**
 * bnx2i_indicate_kcqe - process iscsi conn update completion KCQE
 * @hba:		adapter structure pointer
 * @update_kcqe:	kcqe pointer
 *
 * Generic KCQ event handler/dispatcher
 */
static void bnx2i_indicate_kcqe(void *context, struct kcqe *kcqe[],
				u32 num_cqe)
{
	struct bnx2i_hba *hba = context;
	int i = 0;
	struct iscsi_kcqe *ikcqe = NULL;

	while (i < num_cqe) {
		ikcqe = (struct iscsi_kcqe *) kcqe[i++];

		if (ikcqe->op_code ==
		    ISCSI_KCQE_OPCODE_CQ_EVENT_NOTIFICATION)
			bnx2i_fastpath_notification(hba, ikcqe);
		else if (ikcqe->op_code == ISCSI_KCQE_OPCODE_OFFLOAD_CONN)
			bnx2i_process_ofld_cmpl(hba, ikcqe);
		else if (ikcqe->op_code == ISCSI_KCQE_OPCODE_UPDATE_CONN)
			bnx2i_process_update_conn_cmpl(hba, ikcqe);
		else if (ikcqe->op_code == ISCSI_KCQE_OPCODE_INIT) {
			if (ikcqe->completion_status !=
			    ISCSI_KCQE_COMPLETION_STATUS_SUCCESS)
				bnx2i_iscsi_license_error(hba, ikcqe->\
							  completion_status);
			else {
				set_bit(ADAPTER_STATE_UP, &hba->adapter_state);
				bnx2i_get_link_state(hba);
				printk(KERN_INFO "bnx2i [%.2x:%.2x.%.2x]: "
						 "ISCSI_INIT passed\n",
						 (u8)hba->pcidev->bus->number,
						 hba->pci_devno,
						 (u8)hba->pci_func);


			}
		} else if (ikcqe->op_code == ISCSI_KCQE_OPCODE_DESTROY_CONN)
			bnx2i_process_conn_destroy_cmpl(hba, ikcqe);
		else if (ikcqe->op_code == ISCSI_KCQE_OPCODE_ISCSI_ERROR)
			bnx2i_process_iscsi_error(hba, ikcqe);
		else if (ikcqe->op_code == ISCSI_KCQE_OPCODE_TCP_ERROR)
			bnx2i_process_tcp_error(hba, ikcqe);
		else
			printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n",
					  ikcqe->op_code);
	}
}


/**
 * bnx2i_indicate_netevent - Generic netdev event handler
 * @context:	adapter structure pointer
 * @event:	event type
 *
 * Handles four netdev events, NETDEV_UP, NETDEV_DOWN,
 *	NETDEV_GOING_DOWN and NETDEV_CHANGE
 */
static void bnx2i_indicate_netevent(void *context, unsigned long event)
{
	struct bnx2i_hba *hba = context;

	switch (event) {
	case NETDEV_UP:
		if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
			bnx2i_send_fw_iscsi_init_msg(hba);
		break;
	case NETDEV_DOWN:
		clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
		clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
		break;
	case NETDEV_GOING_DOWN:
		set_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
		iscsi_host_for_each_session(hba->shost,
					    bnx2i_drop_session);
		break;
	case NETDEV_CHANGE:
		bnx2i_get_link_state(hba);
		break;
	default:
		;
	}
}


/**
 * bnx2i_cm_connect_cmpl - process iscsi conn establishment completion
 * @cm_sk: 		cnic sock structure pointer
 *
 * function callback exported via bnx2i - cnic driver interface to
 *	indicate completion of option-2 TCP connect request.
 */
static void bnx2i_cm_connect_cmpl(struct cnic_sock *cm_sk)
{
	struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;

	if (test_bit(ADAPTER_STATE_GOING_DOWN, &ep->hba->adapter_state))
		ep->state = EP_STATE_CONNECT_FAILED;
	else if (test_bit(SK_F_OFFLD_COMPLETE, &cm_sk->flags))
		ep->state = EP_STATE_CONNECT_COMPL;
	else
		ep->state = EP_STATE_CONNECT_FAILED;

	wake_up_interruptible(&ep->ofld_wait);
}


/**
 * bnx2i_cm_close_cmpl - process tcp conn close completion
 * @cm_sk:	cnic sock structure pointer
 *
 * function callback exported via bnx2i - cnic driver interface to
 *	indicate completion of option-2 graceful TCP connect shutdown
 */
static void bnx2i_cm_close_cmpl(struct cnic_sock *cm_sk)
{
	struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;

	ep->state = EP_STATE_DISCONN_COMPL;
	wake_up_interruptible(&ep->ofld_wait);
}


/**
 * bnx2i_cm_abort_cmpl - process abortive tcp conn teardown completion
 * @cm_sk:	cnic sock structure pointer
 *
 * function callback exported via bnx2i - cnic driver interface to
 *	indicate completion of option-2 abortive TCP connect termination
 */
static void bnx2i_cm_abort_cmpl(struct cnic_sock *cm_sk)
{
	struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;

	ep->state = EP_STATE_DISCONN_COMPL;
	wake_up_interruptible(&ep->ofld_wait);
}


/**
 * bnx2i_cm_remote_close - process received TCP FIN
 * @hba:		adapter structure pointer
 * @update_kcqe:	kcqe pointer
 *
 * function callback exported via bnx2i - cnic driver interface to indicate
 *	async TCP events such as FIN
 */
static void bnx2i_cm_remote_close(struct cnic_sock *cm_sk)
{
	struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;

	ep->state = EP_STATE_TCP_FIN_RCVD;
	if (ep->conn)
		bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
}

/**
 * bnx2i_cm_remote_abort - process TCP RST and start conn cleanup
 * @hba:		adapter structure pointer
 * @update_kcqe:	kcqe pointer
 *
 * function callback exported via bnx2i - cnic driver interface to
 *	indicate async TCP events (RST) sent by the peer.
 */
static void bnx2i_cm_remote_abort(struct cnic_sock *cm_sk)
{
	struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;
	u32 old_state = ep->state;

	ep->state = EP_STATE_TCP_RST_RCVD;
	if (old_state == EP_STATE_DISCONN_START)
		wake_up_interruptible(&ep->ofld_wait);
	else
		if (ep->conn)
			bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
}


static int bnx2i_send_nl_mesg(void *context, u32 msg_type,
			       char *buf, u16 buflen)
{
	struct bnx2i_hba *hba = context;
	int rc;

	if (!hba)
		return -ENODEV;

	rc = iscsi_offload_mesg(hba->shost, &bnx2i_iscsi_transport,
				msg_type, buf, buflen);
	if (rc)
		printk(KERN_ALERT "bnx2i: private nl message send error\n");

	return rc;
}


/**
 * bnx2i_cnic_cb - global template of bnx2i - cnic driver interface structure
 *			carrying callback function pointers
 *
 */
struct cnic_ulp_ops bnx2i_cnic_cb = {
	.cnic_init = bnx2i_ulp_init,
	.cnic_exit = bnx2i_ulp_exit,
	.cnic_start = bnx2i_start,
	.cnic_stop = bnx2i_stop,
	.indicate_kcqes = bnx2i_indicate_kcqe,
	.indicate_netevent = bnx2i_indicate_netevent,
	.cm_connect_complete = bnx2i_cm_connect_cmpl,
	.cm_close_complete = bnx2i_cm_close_cmpl,
	.cm_abort_complete = bnx2i_cm_abort_cmpl,
	.cm_remote_close = bnx2i_cm_remote_close,
	.cm_remote_abort = bnx2i_cm_remote_abort,
	.iscsi_nl_send_msg = bnx2i_send_nl_mesg,
	.owner = THIS_MODULE
};


/**
 * bnx2i_map_ep_dbell_regs - map connection doorbell registers
 * @ep: bnx2i endpoint
 *
 * maps connection's SQ and RQ doorbell registers, 5706/5708/5709 hosts these
 *	register in BAR #0. Whereas in 57710 these register are accessed by
 *	mapping BAR #1
 */
int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep)
{
	u32 cid_num;
	u32 reg_off;
	u32 first_l4l5;
	u32 ctx_sz;
	u32 config2;
	resource_size_t reg_base;

	cid_num = bnx2i_get_cid_num(ep);

	if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) {
		reg_base = pci_resource_start(ep->hba->pcidev,
					      BNX2X_DOORBELL_PCI_BAR);
		reg_off = BNX2I_5771X_DBELL_PAGE_SIZE * (cid_num & 0x1FFFF) +
			  DPM_TRIGER_TYPE;
		ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, 4);
		goto arm_cq;
	}

	reg_base = ep->hba->netdev->base_addr;
	if ((test_bit(BNX2I_NX2_DEV_5709, &ep->hba->cnic_dev_type)) &&
	    (ep->hba->mail_queue_access == BNX2I_MQ_BIN_MODE)) {
		config2 = REG_RD(ep->hba, BNX2_MQ_CONFIG2);
		first_l4l5 = config2 & BNX2_MQ_CONFIG2_FIRST_L4L5;
		ctx_sz = (config2 & BNX2_MQ_CONFIG2_CONT_SZ) >> 3;
		if (ctx_sz)
			reg_off = CTX_OFFSET + MAX_CID_CNT * MB_KERNEL_CTX_SIZE
				  + BNX2I_570X_PAGE_SIZE_DEFAULT *
				  (((cid_num - first_l4l5) / ctx_sz) + 256);
		else
			reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num);
	} else
		/* 5709 device in normal node and 5706/5708 devices */
		reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num);

	ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off,
					  MB_KERNEL_CTX_SIZE);
	if (!ep->qp.ctx_base)
		return -ENOMEM;

arm_cq:
	bnx2i_arm_cq_event_coalescing(ep, CNIC_ARM_CQE);
	return 0;
}
