/*
 * This file is part of the Chelsio FCoE driver for Linux.
 *
 * Copyright (c) 2008-2012 Chelsio Communications, Inc. 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
 * OpenIB.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 <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/string.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_transport_fc.h>

#include "csio_hw.h"
#include "csio_lnode.h"
#include "csio_rnode.h"
#include "csio_mb.h"
#include "csio_wr.h"

#define csio_mb_is_host_owner(__owner)		((__owner) == CSIO_MBOWNER_PL)

/* MB Command/Response Helpers */
/*
 * csio_mb_fw_retval - FW return value from a mailbox response.
 * @mbp: Mailbox structure
 *
 */
enum fw_retval
csio_mb_fw_retval(struct csio_mb *mbp)
{
	struct fw_cmd_hdr *hdr;

	hdr = (struct fw_cmd_hdr *)(mbp->mb);

	return FW_CMD_RETVAL_GET(ntohl(hdr->lo));
}

/*
 * csio_mb_hello - FW HELLO command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @m_mbox: Master mailbox number, if any.
 * @a_mbox: Mailbox number for asycn notifications.
 * @master: Device mastership.
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_hello(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
	      uint32_t m_mbox, uint32_t a_mbox, enum csio_dev_master master,
	      void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_hello_cmd *cmdp = (struct fw_hello_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_write = htonl(FW_CMD_OP(FW_HELLO_CMD) |
				       FW_CMD_REQUEST | FW_CMD_WRITE);
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->err_to_clearinit = htonl(
		FW_HELLO_CMD_MASTERDIS(master == CSIO_MASTER_CANT)	|
		FW_HELLO_CMD_MASTERFORCE(master == CSIO_MASTER_MUST)	|
		FW_HELLO_CMD_MBMASTER(master == CSIO_MASTER_MUST ?
				m_mbox : FW_HELLO_CMD_MBMASTER_MASK)	|
		FW_HELLO_CMD_MBASYNCNOT(a_mbox) |
		FW_HELLO_CMD_STAGE(fw_hello_cmd_stage_os) |
		FW_HELLO_CMD_CLEARINIT);

}

/*
 * csio_mb_process_hello_rsp - FW HELLO response processing helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @retval: Mailbox return value from Firmware
 * @state: State that the function is in.
 * @mpfn: Master pfn
 *
 */
void
csio_mb_process_hello_rsp(struct csio_hw *hw, struct csio_mb *mbp,
			  enum fw_retval *retval, enum csio_dev_state *state,
			  uint8_t *mpfn)
{
	struct fw_hello_cmd *rsp = (struct fw_hello_cmd *)(mbp->mb);
	uint32_t value;

	*retval = FW_CMD_RETVAL_GET(ntohl(rsp->retval_len16));

	if (*retval == FW_SUCCESS) {
		hw->fwrev = ntohl(rsp->fwrev);

		value = ntohl(rsp->err_to_clearinit);
		*mpfn = FW_HELLO_CMD_MBMASTER_GET(value);

		if (value & FW_HELLO_CMD_INIT)
			*state = CSIO_DEV_STATE_INIT;
		else if (value & FW_HELLO_CMD_ERR)
			*state = CSIO_DEV_STATE_ERR;
		else
			*state = CSIO_DEV_STATE_UNINIT;
	}
}

/*
 * csio_mb_bye - FW BYE command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_bye(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
	    void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_bye_cmd *cmdp = (struct fw_bye_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_write = htonl(FW_CMD_OP(FW_BYE_CMD) |
				       FW_CMD_REQUEST | FW_CMD_WRITE);
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

}

/*
 * csio_mb_reset - FW RESET command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @reset: Type of reset.
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_reset(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
	      int reset, int halt,
	      void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_reset_cmd *cmdp = (struct fw_reset_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_write = htonl(FW_CMD_OP(FW_RESET_CMD) |
				  FW_CMD_REQUEST | FW_CMD_WRITE);
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->val = htonl(reset);
	cmdp->halt_pkd = htonl(halt);

}

/*
 * csio_mb_params - FW PARAMS command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @tmo: Command timeout.
 * @pf: PF number.
 * @vf: VF number.
 * @nparams: Number of parameters
 * @params: Parameter mnemonic array.
 * @val: Parameter value array.
 * @wr: Write/Read PARAMS.
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_params(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
	       unsigned int pf, unsigned int vf, unsigned int nparams,
	       const u32 *params, u32 *val, bool wr,
	       void (*cbfn)(struct csio_hw *, struct csio_mb *))
{
	uint32_t i;
	uint32_t temp_params = 0, temp_val = 0;
	struct fw_params_cmd *cmdp = (struct fw_params_cmd *)(mbp->mb);
	__be32 *p = &cmdp->param[0].mnem;

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD)		|
				FW_CMD_REQUEST				|
				(wr ? FW_CMD_WRITE : FW_CMD_READ)	|
				FW_PARAMS_CMD_PFN(pf)			|
				FW_PARAMS_CMD_VFN(vf));
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

	/* Write Params */
	if (wr) {
		while (nparams--) {
			temp_params = *params++;
			temp_val = *val++;

			*p++ = htonl(temp_params);
			*p++ = htonl(temp_val);
		}
	} else {
		for (i = 0; i < nparams; i++, p += 2) {
			temp_params = *params++;
			*p = htonl(temp_params);
		}
	}

}

/*
 * csio_mb_process_read_params_rsp - FW PARAMS response processing helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @retval: Mailbox return value from Firmware
 * @nparams: Number of parameters
 * @val: Parameter value array.
 *
 */
void
csio_mb_process_read_params_rsp(struct csio_hw *hw, struct csio_mb *mbp,
			   enum fw_retval *retval, unsigned int nparams,
			   u32 *val)
{
	struct fw_params_cmd *rsp = (struct fw_params_cmd *)(mbp->mb);
	uint32_t i;
	__be32 *p = &rsp->param[0].val;

	*retval = FW_CMD_RETVAL_GET(ntohl(rsp->retval_len16));

	if (*retval == FW_SUCCESS)
		for (i = 0; i < nparams; i++, p += 2)
			*val++ = ntohl(*p);
}

/*
 * csio_mb_ldst - FW LDST command
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @tmo: timeout
 * @reg: register
 *
 */
void
csio_mb_ldst(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, int reg)
{
	struct fw_ldst_cmd *ldst_cmd = (struct fw_ldst_cmd *)(mbp->mb);
	CSIO_INIT_MBP(mbp, ldst_cmd, tmo, hw, NULL, 1);

	/*
	 * Construct and send the Firmware LDST Command to retrieve the
	 * specified PCI-E Configuration Space register.
	 */
	ldst_cmd->op_to_addrspace =
			htonl(FW_CMD_OP(FW_LDST_CMD)	|
			FW_CMD_REQUEST			|
			FW_CMD_READ			|
			FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE));
	ldst_cmd->cycles_to_len16 = htonl(FW_LEN16(struct fw_ldst_cmd));
	ldst_cmd->u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1);
	ldst_cmd->u.pcie.ctrl_to_fn =
		(FW_LDST_CMD_LC | FW_LDST_CMD_FN(hw->pfn));
	ldst_cmd->u.pcie.r = (uint8_t)reg;
}

/*
 *
 * csio_mb_caps_config - FW Read/Write Capabilities command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @wr: Write if 1, Read if 0
 * @init: Turn on initiator mode.
 * @tgt: Turn on target mode.
 * @cofld:  If 1, Control Offload for FCoE
 * @cbfn: Callback, if any.
 *
 * This helper assumes that cmdp has MB payload from a previous CAPS
 * read command.
 */
void
csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
		    bool wr, bool init, bool tgt, bool cofld,
		    void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_caps_config_cmd *cmdp =
				(struct fw_caps_config_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, wr ? 0 : 1);

	cmdp->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
				  FW_CMD_REQUEST		|
				  (wr ? FW_CMD_WRITE : FW_CMD_READ));
	cmdp->cfvalid_to_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

	/* Read config */
	if (!wr)
		return;

	/* Write config */
	cmdp->fcoecaps = 0;

	if (cofld)
		cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_CTRL_OFLD);
	if (init)
		cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_INITIATOR);
	if (tgt)
		cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET);
}

void
csio_rss_glb_config(struct csio_hw *hw, struct csio_mb *mbp,
		    uint32_t tmo, uint8_t mode, unsigned int flags,
		    void (*cbfn)(struct csio_hw *, struct csio_mb *))
{
	struct fw_rss_glb_config_cmd *cmdp =
				(struct fw_rss_glb_config_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
				  FW_CMD_REQUEST | FW_CMD_WRITE);
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

	if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
		cmdp->u.manual.mode_pkd =
			htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
	} else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
		cmdp->u.basicvirtual.mode_pkd =
			htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
		cmdp->u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags);
	}
}


/*
 * csio_mb_pfvf - FW Write PF/VF capabilities command helper.
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @pf:
 * @vf:
 * @txq:
 * @txq_eht_ctrl:
 * @rxqi:
 * @rxq:
 * @tc:
 * @vi:
 * @pmask:
 * @rcaps:
 * @wxcaps:
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_pfvf(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
	     unsigned int pf, unsigned int vf, unsigned int txq,
	     unsigned int txq_eth_ctrl, unsigned int rxqi,
	     unsigned int rxq, unsigned int tc, unsigned int vi,
	     unsigned int cmask, unsigned int pmask, unsigned int nexactf,
	     unsigned int rcaps, unsigned int wxcaps,
	     void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_pfvf_cmd *cmdp = (struct fw_pfvf_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD)			|
				FW_CMD_REQUEST				|
				FW_CMD_WRITE				|
				FW_PFVF_CMD_PFN(pf)			|
				FW_PFVF_CMD_VFN(vf));
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi)		|
					     FW_PFVF_CMD_NIQ(rxq));

	cmdp->type_to_neq = htonl(FW_PFVF_CMD_TYPE			|
				  FW_PFVF_CMD_CMASK(cmask)		|
				  FW_PFVF_CMD_PMASK(pmask)		|
				  FW_PFVF_CMD_NEQ(txq));
	cmdp->tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc)			|
				    FW_PFVF_CMD_NVI(vi)			|
				    FW_PFVF_CMD_NEXACTF(nexactf));
	cmdp->r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps)	|
					 FW_PFVF_CMD_WX_CAPS(wxcaps)	|
					 FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl));
}

#define CSIO_ADVERT_MASK     (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
			      FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG)

/*
 * csio_mb_port- FW PORT command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @tmo: COmmand timeout
 * @portid: Port ID to get/set info
 * @wr: Write/Read PORT information.
 * @fc: Flow control
 * @caps: Port capabilites to set.
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
	     uint8_t portid, bool wr, uint32_t fc, uint16_t caps,
	     void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_port_cmd *cmdp = (struct fw_port_cmd *)(mbp->mb);
	unsigned int lfc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn,  1);

	cmdp->op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD)		|
				   FW_CMD_REQUEST			|
				   (wr ? FW_CMD_EXEC : FW_CMD_READ)	|
				   FW_PORT_CMD_PORTID(portid));
	if (!wr) {
		cmdp->action_to_len16 = htonl(
			FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) |
			FW_CMD_LEN16(sizeof(*cmdp) / 16));
		return;
	}

	/* Set port */
	cmdp->action_to_len16 = htonl(
			FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
			FW_CMD_LEN16(sizeof(*cmdp) / 16));

	if (fc & PAUSE_RX)
		lfc |= FW_PORT_CAP_FC_RX;
	if (fc & PAUSE_TX)
		lfc |= FW_PORT_CAP_FC_TX;

	if (!(caps & FW_PORT_CAP_ANEG))
		cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) | lfc);
	else
		cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) |
								lfc | mdi);
}

/*
 * csio_mb_process_read_port_rsp - FW PORT command response processing helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @retval: Mailbox return value from Firmware
 * @caps: port capabilities
 *
 */
void
csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp,
			 enum fw_retval *retval, uint16_t *caps)
{
	struct fw_port_cmd *rsp = (struct fw_port_cmd *)(mbp->mb);

	*retval = FW_CMD_RETVAL_GET(ntohl(rsp->action_to_len16));

	if (*retval == FW_SUCCESS)
		*caps = ntohs(rsp->u.info.pcap);
}

/*
 * csio_mb_initialize - FW INITIALIZE command helper
 * @hw: The HW structure
 * @mbp: Mailbox structure
 * @tmo: COmmand timeout
 * @cbfn: Callback, if any.
 *
 */
void
csio_mb_initialize(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
		   void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_initialize_cmd *cmdp = (struct fw_initialize_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);

	cmdp->op_to_write = htonl(FW_CMD_OP(FW_INITIALIZE_CMD)	|
				  FW_CMD_REQUEST | FW_CMD_WRITE);
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

}

/*
 * csio_mb_iq_alloc - Initializes the mailbox to allocate an
 *				Ingress DMA queue in the firmware.
 *
 * @hw: The hw structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private object
 * @mb_tmo: Mailbox time-out period (in ms).
 * @iq_params: Ingress queue params needed for allocation.
 * @cbfn: The call-back function
 *
 *
 */
static void
csio_mb_iq_alloc(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		 uint32_t mb_tmo, struct csio_iq_params *iq_params,
		 void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_iq_cmd *cmdp = (struct fw_iq_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1);

	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD)		|
				FW_CMD_REQUEST | FW_CMD_EXEC	|
				FW_IQ_CMD_PFN(iq_params->pfn)	|
				FW_IQ_CMD_VFN(iq_params->vfn));

	cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC		|
				FW_CMD_LEN16(sizeof(*cmdp) / 16));

	cmdp->type_to_iqandstindex = htonl(
				FW_IQ_CMD_VIID(iq_params->viid)	|
				FW_IQ_CMD_TYPE(iq_params->type)	|
				FW_IQ_CMD_IQASYNCH(iq_params->iqasynch));

	cmdp->fl0size = htons(iq_params->fl0size);
	cmdp->fl0size = htons(iq_params->fl1size);

} /* csio_mb_iq_alloc */

/*
 * csio_mb_iq_write - Initializes the mailbox for writing into an
 *				Ingress DMA Queue.
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private object
 * @mb_tmo: Mailbox time-out period (in ms).
 * @cascaded_req: TRUE - if this request is cascased with iq-alloc request.
 * @iq_params: Ingress queue params needed for writing.
 * @cbfn: The call-back function
 *
 * NOTE: We OR relevant bits with cmdp->XXX, instead of just equating,
 * because this IQ write request can be cascaded with a previous
 * IQ alloc request, and we dont want to over-write the bits set by
 * that request. This logic will work even in a non-cascaded case, since the
 * cmdp structure is zeroed out by CSIO_INIT_MBP.
 */
static void
csio_mb_iq_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		 uint32_t mb_tmo, bool cascaded_req,
		 struct csio_iq_params *iq_params,
		 void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_iq_cmd *cmdp = (struct fw_iq_cmd *)(mbp->mb);

	uint32_t iq_start_stop = (iq_params->iq_start)	?
					FW_IQ_CMD_IQSTART(1) :
					FW_IQ_CMD_IQSTOP(1);

	/*
	 * If this IQ write is cascaded with IQ alloc request, do not
	 * re-initialize with 0's.
	 *
	 */
	if (!cascaded_req)
		CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1);

	cmdp->op_to_vfn |= htonl(FW_CMD_OP(FW_IQ_CMD)		|
				FW_CMD_REQUEST | FW_CMD_WRITE	|
				FW_IQ_CMD_PFN(iq_params->pfn)	|
				FW_IQ_CMD_VFN(iq_params->vfn));
	cmdp->alloc_to_len16 |= htonl(iq_start_stop |
				FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->iqid |= htons(iq_params->iqid);
	cmdp->fl0id |= htons(iq_params->fl0id);
	cmdp->fl1id |= htons(iq_params->fl1id);
	cmdp->type_to_iqandstindex |= htonl(
			FW_IQ_CMD_IQANDST(iq_params->iqandst)	|
			FW_IQ_CMD_IQANUS(iq_params->iqanus)	|
			FW_IQ_CMD_IQANUD(iq_params->iqanud)	|
			FW_IQ_CMD_IQANDSTINDEX(iq_params->iqandstindex));
	cmdp->iqdroprss_to_iqesize |= htons(
			FW_IQ_CMD_IQPCIECH(iq_params->iqpciech)		|
			FW_IQ_CMD_IQDCAEN(iq_params->iqdcaen)		|
			FW_IQ_CMD_IQDCACPU(iq_params->iqdcacpu)		|
			FW_IQ_CMD_IQINTCNTTHRESH(iq_params->iqintcntthresh) |
			FW_IQ_CMD_IQCPRIO(iq_params->iqcprio)		|
			FW_IQ_CMD_IQESIZE(iq_params->iqesize));

	cmdp->iqsize |= htons(iq_params->iqsize);
	cmdp->iqaddr |= cpu_to_be64(iq_params->iqaddr);

	if (iq_params->type == 0) {
		cmdp->iqns_to_fl0congen |= htonl(
			FW_IQ_CMD_IQFLINTIQHSEN(iq_params->iqflintiqhsen)|
			FW_IQ_CMD_IQFLINTCONGEN(iq_params->iqflintcongen));
	}

	if (iq_params->fl0size && iq_params->fl0addr &&
	    (iq_params->fl0id != 0xFFFF)) {

		cmdp->iqns_to_fl0congen |= htonl(
			FW_IQ_CMD_FL0HOSTFCMODE(iq_params->fl0hostfcmode)|
			FW_IQ_CMD_FL0CPRIO(iq_params->fl0cprio)		|
			FW_IQ_CMD_FL0PADEN(iq_params->fl0paden)		|
			FW_IQ_CMD_FL0PACKEN(iq_params->fl0packen));
		cmdp->fl0dcaen_to_fl0cidxfthresh |= htons(
			FW_IQ_CMD_FL0DCAEN(iq_params->fl0dcaen)		|
			FW_IQ_CMD_FL0DCACPU(iq_params->fl0dcacpu)	|
			FW_IQ_CMD_FL0FBMIN(iq_params->fl0fbmin)		|
			FW_IQ_CMD_FL0FBMAX(iq_params->fl0fbmax)		|
			FW_IQ_CMD_FL0CIDXFTHRESH(iq_params->fl0cidxfthresh));
		cmdp->fl0size |= htons(iq_params->fl0size);
		cmdp->fl0addr |= cpu_to_be64(iq_params->fl0addr);
	}
} /* csio_mb_iq_write */

/*
 * csio_mb_iq_alloc_write - Initializes the mailbox for allocating an
 *				Ingress DMA Queue.
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private data.
 * @mb_tmo: Mailbox time-out period (in ms).
 * @iq_params: Ingress queue params needed for allocation & writing.
 * @cbfn: The call-back function
 *
 *
 */
void
csio_mb_iq_alloc_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		       uint32_t mb_tmo, struct csio_iq_params *iq_params,
		       void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	csio_mb_iq_alloc(hw, mbp, priv, mb_tmo, iq_params, cbfn);
	csio_mb_iq_write(hw, mbp, priv, mb_tmo, true, iq_params, cbfn);
} /* csio_mb_iq_alloc_write */

/*
 * csio_mb_iq_alloc_write_rsp - Process the allocation & writing
 *				of ingress DMA queue mailbox's response.
 *
 * @hw: The HW structure.
 * @mbp: Mailbox structure to initialize.
 * @retval: Firmware return value.
 * @iq_params: Ingress queue parameters, after allocation and write.
 *
 */
void
csio_mb_iq_alloc_write_rsp(struct csio_hw *hw, struct csio_mb *mbp,
			   enum fw_retval *ret_val,
			   struct csio_iq_params *iq_params)
{
	struct fw_iq_cmd *rsp = (struct fw_iq_cmd *)(mbp->mb);

	*ret_val = FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16));
	if (*ret_val == FW_SUCCESS) {
		iq_params->physiqid = ntohs(rsp->physiqid);
		iq_params->iqid = ntohs(rsp->iqid);
		iq_params->fl0id = ntohs(rsp->fl0id);
		iq_params->fl1id = ntohs(rsp->fl1id);
	} else {
		iq_params->physiqid = iq_params->iqid =
		iq_params->fl0id = iq_params->fl1id = 0;
	}
} /* csio_mb_iq_alloc_write_rsp */

/*
 * csio_mb_iq_free - Initializes the mailbox for freeing a
 *				specified Ingress DMA Queue.
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private data
 * @mb_tmo: Mailbox time-out period (in ms).
 * @iq_params: Parameters of ingress queue, that is to be freed.
 * @cbfn: The call-back function
 *
 *
 */
void
csio_mb_iq_free(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		uint32_t mb_tmo, struct csio_iq_params *iq_params,
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_iq_cmd *cmdp = (struct fw_iq_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1);

	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD)		|
				FW_CMD_REQUEST | FW_CMD_EXEC	|
				FW_IQ_CMD_PFN(iq_params->pfn)	|
				FW_IQ_CMD_VFN(iq_params->vfn));
	cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_FREE		|
				FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iq_params->type));

	cmdp->iqid = htons(iq_params->iqid);
	cmdp->fl0id = htons(iq_params->fl0id);
	cmdp->fl1id = htons(iq_params->fl1id);

} /* csio_mb_iq_free */

/*
 * csio_mb_eq_ofld_alloc - Initializes the mailbox for allocating
 *				an offload-egress queue.
 *
 * @hw: The HW  structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private data
 * @mb_tmo: Mailbox time-out period (in ms).
 * @eq_ofld_params: (Offload) Egress queue parameters.
 * @cbfn: The call-back function
 *
 *
 */
static void
csio_mb_eq_ofld_alloc(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		uint32_t mb_tmo, struct csio_eq_params *eq_ofld_params,
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_eq_ofld_cmd *cmdp = (struct fw_eq_ofld_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1);
	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD)		|
				FW_CMD_REQUEST | FW_CMD_EXEC		|
				FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) |
				FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn));
	cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC	|
				FW_CMD_LEN16(sizeof(*cmdp) / 16));

} /* csio_mb_eq_ofld_alloc */

/*
 * csio_mb_eq_ofld_write - Initializes the mailbox for writing
 *				an alloacted offload-egress queue.
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private data
 * @mb_tmo: Mailbox time-out period (in ms).
 * @cascaded_req: TRUE - if this request is cascased with Eq-alloc request.
 * @eq_ofld_params: (Offload) Egress queue parameters.
 * @cbfn: The call-back function
 *
 *
 * NOTE: We OR relevant bits with cmdp->XXX, instead of just equating,
 * because this EQ write request can be cascaded with a previous
 * EQ alloc request, and we dont want to over-write the bits set by
 * that request. This logic will work even in a non-cascaded case, since the
 * cmdp structure is zeroed out by CSIO_INIT_MBP.
 */
static void
csio_mb_eq_ofld_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		      uint32_t mb_tmo, bool cascaded_req,
		      struct csio_eq_params *eq_ofld_params,
		      void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_eq_ofld_cmd *cmdp = (struct fw_eq_ofld_cmd *)(mbp->mb);

	uint32_t eq_start_stop = (eq_ofld_params->eqstart)	?
				FW_EQ_OFLD_CMD_EQSTART	: FW_EQ_OFLD_CMD_EQSTOP;

	/*
	 * If this EQ write is cascaded with EQ alloc request, do not
	 * re-initialize with 0's.
	 *
	 */
	if (!cascaded_req)
		CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1);

	cmdp->op_to_vfn |= htonl(FW_CMD_OP(FW_EQ_OFLD_CMD)	|
				FW_CMD_REQUEST | FW_CMD_WRITE	|
				FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) |
				FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn));
	cmdp->alloc_to_len16 |= htonl(eq_start_stop		|
				      FW_CMD_LEN16(sizeof(*cmdp) / 16));

	cmdp->eqid_pkd |= htonl(FW_EQ_OFLD_CMD_EQID(eq_ofld_params->eqid));

	cmdp->fetchszm_to_iqid |= htonl(
		FW_EQ_OFLD_CMD_HOSTFCMODE(eq_ofld_params->hostfcmode)	|
		FW_EQ_OFLD_CMD_CPRIO(eq_ofld_params->cprio)		|
		FW_EQ_OFLD_CMD_PCIECHN(eq_ofld_params->pciechn)		|
		FW_EQ_OFLD_CMD_IQID(eq_ofld_params->iqid));

	cmdp->dcaen_to_eqsize |= htonl(
		FW_EQ_OFLD_CMD_DCAEN(eq_ofld_params->dcaen)		|
		FW_EQ_OFLD_CMD_DCACPU(eq_ofld_params->dcacpu)		|
		FW_EQ_OFLD_CMD_FBMIN(eq_ofld_params->fbmin)		|
		FW_EQ_OFLD_CMD_FBMAX(eq_ofld_params->fbmax)		|
		FW_EQ_OFLD_CMD_CIDXFTHRESHO(eq_ofld_params->cidxfthresho) |
		FW_EQ_OFLD_CMD_CIDXFTHRESH(eq_ofld_params->cidxfthresh) |
		FW_EQ_OFLD_CMD_EQSIZE(eq_ofld_params->eqsize));

	cmdp->eqaddr |= cpu_to_be64(eq_ofld_params->eqaddr);

} /* csio_mb_eq_ofld_write */

/*
 * csio_mb_eq_ofld_alloc_write - Initializes the mailbox for allocation
 *				writing into an Engress DMA Queue.
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private data.
 * @mb_tmo: Mailbox time-out period (in ms).
 * @eq_ofld_params: (Offload) Egress queue parameters.
 * @cbfn: The call-back function
 *
 *
 */
void
csio_mb_eq_ofld_alloc_write(struct csio_hw *hw, struct csio_mb *mbp,
			    void *priv, uint32_t mb_tmo,
			    struct csio_eq_params *eq_ofld_params,
			    void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	csio_mb_eq_ofld_alloc(hw, mbp, priv, mb_tmo, eq_ofld_params, cbfn);
	csio_mb_eq_ofld_write(hw, mbp, priv, mb_tmo, true,
			      eq_ofld_params, cbfn);
} /* csio_mb_eq_ofld_alloc_write */

/*
 * csio_mb_eq_ofld_alloc_write_rsp - Process the allocation
 *				& write egress DMA queue mailbox's response.
 *
 * @hw: The HW structure.
 * @mbp: Mailbox structure to initialize.
 * @retval: Firmware return value.
 * @eq_ofld_params: (Offload) Egress queue parameters.
 *
 */
void
csio_mb_eq_ofld_alloc_write_rsp(struct csio_hw *hw,
				struct csio_mb *mbp, enum fw_retval *ret_val,
				struct csio_eq_params *eq_ofld_params)
{
	struct fw_eq_ofld_cmd *rsp = (struct fw_eq_ofld_cmd *)(mbp->mb);

	*ret_val = FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16));

	if (*ret_val == FW_SUCCESS) {
		eq_ofld_params->eqid = FW_EQ_OFLD_CMD_EQID_GET(
						ntohl(rsp->eqid_pkd));
		eq_ofld_params->physeqid = FW_EQ_OFLD_CMD_PHYSEQID_GET(
						ntohl(rsp->physeqid_pkd));
	} else
		eq_ofld_params->eqid = 0;

} /* csio_mb_eq_ofld_alloc_write_rsp */

/*
 * csio_mb_eq_ofld_free - Initializes the mailbox for freeing a
 *				specified Engress DMA Queue.
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @priv: Private data area.
 * @mb_tmo: Mailbox time-out period (in ms).
 * @eq_ofld_params: (Offload) Egress queue parameters, that is to be freed.
 * @cbfn: The call-back function
 *
 *
 */
void
csio_mb_eq_ofld_free(struct csio_hw *hw, struct csio_mb *mbp, void *priv,
		     uint32_t mb_tmo, struct csio_eq_params *eq_ofld_params,
		     void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_eq_ofld_cmd *cmdp = (struct fw_eq_ofld_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1);

	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD)	|
				FW_CMD_REQUEST | FW_CMD_EXEC	|
				FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) |
				FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn));
	cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE |
				FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eq_ofld_params->eqid));

} /* csio_mb_eq_ofld_free */

/*
 * csio_write_fcoe_link_cond_init_mb - Initialize Mailbox to write FCoE link
 *				 condition.
 *
 * @ln: The Lnode structure
 * @mbp: Mailbox structure to initialize
 * @mb_tmo: Mailbox time-out period (in ms).
 * @cbfn: The call back function.
 *
 *
 */
void
csio_write_fcoe_link_cond_init_mb(struct csio_lnode *ln, struct csio_mb *mbp,
			uint32_t mb_tmo, uint8_t port_id, uint32_t sub_opcode,
			uint8_t cos, bool link_status, uint32_t fcfi,
			void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_fcoe_link_cmd *cmdp =
				(struct fw_fcoe_link_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1);

	cmdp->op_to_portid = htonl((
			FW_CMD_OP(FW_FCOE_LINK_CMD)		|
			FW_CMD_REQUEST				|
			FW_CMD_WRITE				|
			FW_FCOE_LINK_CMD_PORTID(port_id)));
	cmdp->sub_opcode_fcfi = htonl(
			FW_FCOE_LINK_CMD_SUB_OPCODE(sub_opcode)	|
			FW_FCOE_LINK_CMD_FCFI(fcfi));
	cmdp->lstatus = link_status;
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

} /* csio_write_fcoe_link_cond_init_mb */

/*
 * csio_fcoe_read_res_info_init_mb - Initializes the mailbox for reading FCoE
 *				resource information(FW_GET_RES_INFO_CMD).
 *
 * @hw: The HW structure
 * @mbp: Mailbox structure to initialize
 * @mb_tmo: Mailbox time-out period (in ms).
 * @cbfn: The call-back function
 *
 *
 */
void
csio_fcoe_read_res_info_init_mb(struct csio_hw *hw, struct csio_mb *mbp,
			uint32_t mb_tmo,
			void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_fcoe_res_info_cmd *cmdp =
			(struct fw_fcoe_res_info_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, hw, cbfn, 1);

	cmdp->op_to_read = htonl((FW_CMD_OP(FW_FCOE_RES_INFO_CMD)	|
				  FW_CMD_REQUEST			|
				  FW_CMD_READ));

	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

} /* csio_fcoe_read_res_info_init_mb */

/*
 * csio_fcoe_vnp_alloc_init_mb - Initializes the mailbox for allocating VNP
 *				in the firmware (FW_FCOE_VNP_CMD).
 *
 * @ln: The Lnode structure.
 * @mbp: Mailbox structure to initialize.
 * @mb_tmo: Mailbox time-out period (in ms).
 * @fcfi: FCF Index.
 * @vnpi: vnpi
 * @iqid: iqid
 * @vnport_wwnn: vnport WWNN
 * @vnport_wwpn: vnport WWPN
 * @cbfn: The call-back function.
 *
 *
 */
void
csio_fcoe_vnp_alloc_init_mb(struct csio_lnode *ln, struct csio_mb *mbp,
		uint32_t mb_tmo, uint32_t fcfi, uint32_t vnpi, uint16_t iqid,
		uint8_t vnport_wwnn[8],	uint8_t vnport_wwpn[8],
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_fcoe_vnp_cmd *cmdp =
			(struct fw_fcoe_vnp_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1);

	cmdp->op_to_fcfi = htonl((FW_CMD_OP(FW_FCOE_VNP_CMD)		|
				  FW_CMD_REQUEST			|
				  FW_CMD_EXEC				|
				  FW_FCOE_VNP_CMD_FCFI(fcfi)));

	cmdp->alloc_to_len16 = htonl(FW_FCOE_VNP_CMD_ALLOC		|
				     FW_CMD_LEN16(sizeof(*cmdp) / 16));

	cmdp->gen_wwn_to_vnpi = htonl(FW_FCOE_VNP_CMD_VNPI(vnpi));

	cmdp->iqid = htons(iqid);

	if (!wwn_to_u64(vnport_wwnn) && !wwn_to_u64(vnport_wwpn))
		cmdp->gen_wwn_to_vnpi |= htonl(FW_FCOE_VNP_CMD_GEN_WWN);

	if (vnport_wwnn)
		memcpy(cmdp->vnport_wwnn, vnport_wwnn, 8);
	if (vnport_wwpn)
		memcpy(cmdp->vnport_wwpn, vnport_wwpn, 8);

} /* csio_fcoe_vnp_alloc_init_mb */

/*
 * csio_fcoe_vnp_read_init_mb - Prepares VNP read cmd.
 * @ln: The Lnode structure.
 * @mbp: Mailbox structure to initialize.
 * @mb_tmo: Mailbox time-out period (in ms).
 * @fcfi: FCF Index.
 * @vnpi: vnpi
 * @cbfn: The call-back handler.
 */
void
csio_fcoe_vnp_read_init_mb(struct csio_lnode *ln, struct csio_mb *mbp,
		uint32_t mb_tmo, uint32_t fcfi, uint32_t vnpi,
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_fcoe_vnp_cmd *cmdp =
			(struct fw_fcoe_vnp_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1);
	cmdp->op_to_fcfi = htonl(FW_CMD_OP(FW_FCOE_VNP_CMD)	|
				 FW_CMD_REQUEST			|
				 FW_CMD_READ			|
				 FW_FCOE_VNP_CMD_FCFI(fcfi));
	cmdp->alloc_to_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->gen_wwn_to_vnpi = htonl(FW_FCOE_VNP_CMD_VNPI(vnpi));
}

/*
 * csio_fcoe_vnp_free_init_mb - Initializes the mailbox for freeing an
 *			alloacted VNP in the firmware (FW_FCOE_VNP_CMD).
 *
 * @ln: The Lnode structure.
 * @mbp: Mailbox structure to initialize.
 * @mb_tmo: Mailbox time-out period (in ms).
 * @fcfi: FCF flow id
 * @vnpi: VNP flow id
 * @cbfn: The call-back function.
 * Return: None
 */
void
csio_fcoe_vnp_free_init_mb(struct csio_lnode *ln, struct csio_mb *mbp,
		uint32_t mb_tmo, uint32_t fcfi, uint32_t vnpi,
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_fcoe_vnp_cmd *cmdp =
			(struct fw_fcoe_vnp_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1);

	cmdp->op_to_fcfi = htonl(FW_CMD_OP(FW_FCOE_VNP_CMD)	|
				 FW_CMD_REQUEST			|
				 FW_CMD_EXEC			|
				 FW_FCOE_VNP_CMD_FCFI(fcfi));
	cmdp->alloc_to_len16 = htonl(FW_FCOE_VNP_CMD_FREE	|
				     FW_CMD_LEN16(sizeof(*cmdp) / 16));
	cmdp->gen_wwn_to_vnpi = htonl(FW_FCOE_VNP_CMD_VNPI(vnpi));
}

/*
 * csio_fcoe_read_fcf_init_mb - Initializes the mailbox to read the
 *				FCF records.
 *
 * @ln: The Lnode structure
 * @mbp: Mailbox structure to initialize
 * @mb_tmo: Mailbox time-out period (in ms).
 * @fcf_params: FC-Forwarder parameters.
 * @cbfn: The call-back function
 *
 *
 */
void
csio_fcoe_read_fcf_init_mb(struct csio_lnode *ln, struct csio_mb *mbp,
		uint32_t mb_tmo, uint32_t portid, uint32_t fcfi,
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct fw_fcoe_fcf_cmd *cmdp =
			(struct fw_fcoe_fcf_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1);

	cmdp->op_to_fcfi = htonl(FW_CMD_OP(FW_FCOE_FCF_CMD)	|
				 FW_CMD_REQUEST			|
				 FW_CMD_READ			|
				 FW_FCOE_FCF_CMD_FCFI(fcfi));
	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));

} /* csio_fcoe_read_fcf_init_mb */

void
csio_fcoe_read_portparams_init_mb(struct csio_hw *hw, struct csio_mb *mbp,
				uint32_t mb_tmo,
				struct fw_fcoe_port_cmd_params *portparams,
				void (*cbfn)(struct csio_hw *,
					     struct csio_mb *))
{
	struct fw_fcoe_stats_cmd *cmdp = (struct fw_fcoe_stats_cmd *)(mbp->mb);

	CSIO_INIT_MBP(mbp, cmdp, mb_tmo, hw, cbfn, 1);
	mbp->mb_size = 64;

	cmdp->op_to_flowid = htonl(FW_CMD_OP(FW_FCOE_STATS_CMD)         |
				   FW_CMD_REQUEST | FW_CMD_READ);
	cmdp->free_to_len16 = htonl(FW_CMD_LEN16(CSIO_MAX_MB_SIZE/16));

	cmdp->u.ctl.nstats_port = FW_FCOE_STATS_CMD_NSTATS(portparams->nstats) |
				  FW_FCOE_STATS_CMD_PORT(portparams->portid);

	cmdp->u.ctl.port_valid_ix = FW_FCOE_STATS_CMD_IX(portparams->idx)    |
				    FW_FCOE_STATS_CMD_PORT_VALID;

} /* csio_fcoe_read_portparams_init_mb */

void
csio_mb_process_portparams_rsp(struct csio_hw *hw,
				struct csio_mb *mbp,
				enum fw_retval *retval,
				struct fw_fcoe_port_cmd_params *portparams,
				struct fw_fcoe_port_stats *portstats)
{
	struct fw_fcoe_stats_cmd *rsp = (struct fw_fcoe_stats_cmd *)(mbp->mb);
	struct fw_fcoe_port_stats stats;
	uint8_t *src;
	uint8_t *dst;

	*retval = FW_CMD_RETVAL_GET(ntohl(rsp->free_to_len16));

	memset(&stats, 0, sizeof(struct fw_fcoe_port_stats));

	if (*retval == FW_SUCCESS) {
		dst = (uint8_t *)(&stats) + ((portparams->idx - 1) * 8);
		src = (uint8_t *)rsp + (CSIO_STATS_OFFSET * 8);
		memcpy(dst, src, (portparams->nstats * 8));
		if (portparams->idx == 1) {
			/* Get the first 6 flits from the Mailbox */
			portstats->tx_bcast_bytes = stats.tx_bcast_bytes;
			portstats->tx_bcast_frames = stats.tx_bcast_frames;
			portstats->tx_mcast_bytes = stats.tx_mcast_bytes;
			portstats->tx_mcast_frames = stats.tx_mcast_frames;
			portstats->tx_ucast_bytes = stats.tx_ucast_bytes;
			portstats->tx_ucast_frames = stats.tx_ucast_frames;
		}
		if (portparams->idx == 7) {
			/* Get the second 6 flits from the Mailbox */
			portstats->tx_drop_frames = stats.tx_drop_frames;
			portstats->tx_offload_bytes = stats.tx_offload_bytes;
			portstats->tx_offload_frames = stats.tx_offload_frames;
#if 0
			portstats->rx_pf_bytes = stats.rx_pf_bytes;
			portstats->rx_pf_frames	= stats.rx_pf_frames;
#endif
			portstats->rx_bcast_bytes = stats.rx_bcast_bytes;
			portstats->rx_bcast_frames = stats.rx_bcast_frames;
			portstats->rx_mcast_bytes = stats.rx_mcast_bytes;
		}
		if (portparams->idx == 13) {
			/* Get the last 4 flits from the Mailbox */
			portstats->rx_mcast_frames = stats.rx_mcast_frames;
			portstats->rx_ucast_bytes = stats.rx_ucast_bytes;
			portstats->rx_ucast_frames = stats.rx_ucast_frames;
			portstats->rx_err_frames = stats.rx_err_frames;
		}
	}
}

/* Entry points/APIs for MB module					     */
/*
 * csio_mb_intr_enable - Enable Interrupts from mailboxes.
 * @hw: The HW structure
 *
 * Enables CIM interrupt bit in appropriate INT_ENABLE registers.
 */
void
csio_mb_intr_enable(struct csio_hw *hw)
{
	csio_wr_reg32(hw, MBMSGRDYINTEN(1), MYPF_REG(CIM_PF_HOST_INT_ENABLE));
	csio_rd_reg32(hw, MYPF_REG(CIM_PF_HOST_INT_ENABLE));
}

/*
 * csio_mb_intr_disable - Disable Interrupts from mailboxes.
 * @hw: The HW structure
 *
 * Disable bit in HostInterruptEnable CIM register.
 */
void
csio_mb_intr_disable(struct csio_hw *hw)
{
	csio_wr_reg32(hw, MBMSGRDYINTEN(0), MYPF_REG(CIM_PF_HOST_INT_ENABLE));
	csio_rd_reg32(hw, MYPF_REG(CIM_PF_HOST_INT_ENABLE));
}

static void
csio_mb_dump_fw_dbg(struct csio_hw *hw, __be64 *cmd)
{
	struct fw_debug_cmd *dbg = (struct fw_debug_cmd *)cmd;

	if ((FW_DEBUG_CMD_TYPE_GET(ntohl(dbg->op_type))) == 1) {
		csio_info(hw, "FW print message:\n");
		csio_info(hw, "\tdebug->dprtstridx = %d\n",
			    ntohs(dbg->u.prt.dprtstridx));
		csio_info(hw, "\tdebug->dprtstrparam0 = 0x%x\n",
			    ntohl(dbg->u.prt.dprtstrparam0));
		csio_info(hw, "\tdebug->dprtstrparam1 = 0x%x\n",
			    ntohl(dbg->u.prt.dprtstrparam1));
		csio_info(hw, "\tdebug->dprtstrparam2 = 0x%x\n",
			    ntohl(dbg->u.prt.dprtstrparam2));
		csio_info(hw, "\tdebug->dprtstrparam3 = 0x%x\n",
			    ntohl(dbg->u.prt.dprtstrparam3));
	} else {
		/* This is a FW assertion */
		csio_fatal(hw, "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
			    dbg->u.assert.filename_0_7,
			    ntohl(dbg->u.assert.line),
			    ntohl(dbg->u.assert.x),
			    ntohl(dbg->u.assert.y));
	}
}

static void
csio_mb_debug_cmd_handler(struct csio_hw *hw)
{
	int i;
	__be64 cmd[CSIO_MB_MAX_REGS];
	uint32_t ctl_reg = PF_REG(hw->pfn, CIM_PF_MAILBOX_CTRL);
	uint32_t data_reg = PF_REG(hw->pfn, CIM_PF_MAILBOX_DATA);
	int size = sizeof(struct fw_debug_cmd);

	/* Copy mailbox data */
	for (i = 0; i < size; i += 8)
		cmd[i / 8] = cpu_to_be64(csio_rd_reg64(hw, data_reg + i));

	csio_mb_dump_fw_dbg(hw, cmd);

	/* Notify FW of mailbox by setting owner as UP */
	csio_wr_reg32(hw, MBMSGVALID | MBINTREQ | MBOWNER(CSIO_MBOWNER_FW),
		      ctl_reg);

	csio_rd_reg32(hw, ctl_reg);
	wmb();
}

/*
 * csio_mb_issue - generic routine for issuing Mailbox commands.
 * @hw: The HW structure
 * @mbp: Mailbox command to issue
 *
 *  Caller should hold hw lock across this call.
 */
int
csio_mb_issue(struct csio_hw *hw, struct csio_mb *mbp)
{
	uint32_t owner, ctl;
	int i;
	uint32_t ii;
	__be64 *cmd = mbp->mb;
	__be64 hdr;
	struct csio_mbm	*mbm = &hw->mbm;
	uint32_t ctl_reg = PF_REG(hw->pfn, CIM_PF_MAILBOX_CTRL);
	uint32_t data_reg = PF_REG(hw->pfn, CIM_PF_MAILBOX_DATA);
	int size = mbp->mb_size;
	int rv = -EINVAL;
	struct fw_cmd_hdr *fw_hdr;

	/* Determine mode */
	if (mbp->mb_cbfn == NULL) {
		/* Need to issue/get results in the same context */
		if (mbp->tmo < CSIO_MB_POLL_FREQ) {
			csio_err(hw, "Invalid tmo: 0x%x\n", mbp->tmo);
			goto error_out;
		}
	} else if (!csio_is_host_intr_enabled(hw) ||
		   !csio_is_hw_intr_enabled(hw)) {
		csio_err(hw, "Cannot issue mailbox in interrupt mode 0x%x\n",
			 *((uint8_t *)mbp->mb));
			goto error_out;
	}

	if (mbm->mcurrent != NULL) {
		/* Queue mbox cmd, if another mbox cmd is active */
		if (mbp->mb_cbfn == NULL) {
			rv = -EBUSY;
			csio_dbg(hw, "Couldnt own Mailbox %x op:0x%x\n",
				    hw->pfn, *((uint8_t *)mbp->mb));

			goto error_out;
		} else {
			list_add_tail(&mbp->list, &mbm->req_q);
			CSIO_INC_STATS(mbm, n_activeq);

			return 0;
		}
	}

	/* Now get ownership of mailbox */
	owner = MBOWNER_GET(csio_rd_reg32(hw, ctl_reg));

	if (!csio_mb_is_host_owner(owner)) {

		for (i = 0; (owner == CSIO_MBOWNER_NONE) && (i < 3); i++)
			owner = MBOWNER_GET(csio_rd_reg32(hw, ctl_reg));
		/*
		 * Mailbox unavailable. In immediate mode, fail the command.
		 * In other modes, enqueue the request.
		 */
		if (!csio_mb_is_host_owner(owner)) {
			if (mbp->mb_cbfn == NULL) {
				rv = owner ? -EBUSY : -ETIMEDOUT;

				csio_dbg(hw,
					 "Couldnt own Mailbox %x op:0x%x "
					 "owner:%x\n",
					 hw->pfn, *((uint8_t *)mbp->mb), owner);
				goto error_out;
			} else {
				if (mbm->mcurrent == NULL) {
					csio_err(hw,
						 "Couldnt own Mailbox %x "
						 "op:0x%x owner:%x\n",
						 hw->pfn, *((uint8_t *)mbp->mb),
						 owner);
					csio_err(hw,
						 "No outstanding driver"
						 " mailbox as well\n");
					goto error_out;
				}
			}
		}
	}

	/* Mailbox is available, copy mailbox data into it */
	for (i = 0; i < size; i += 8) {
		csio_wr_reg64(hw, be64_to_cpu(*cmd), data_reg + i);
		cmd++;
	}

	CSIO_DUMP_MB(hw, hw->pfn, data_reg);

	/* Start completion timers in non-immediate modes and notify FW */
	if (mbp->mb_cbfn != NULL) {
		mbm->mcurrent = mbp;
		mod_timer(&mbm->timer, jiffies + msecs_to_jiffies(mbp->tmo));
		csio_wr_reg32(hw, MBMSGVALID | MBINTREQ |
			      MBOWNER(CSIO_MBOWNER_FW), ctl_reg);
	} else
		csio_wr_reg32(hw, MBMSGVALID | MBOWNER(CSIO_MBOWNER_FW),
			      ctl_reg);

	/* Flush posted writes */
	csio_rd_reg32(hw, ctl_reg);
	wmb();

	CSIO_INC_STATS(mbm, n_req);

	if (mbp->mb_cbfn)
		return 0;

	/* Poll for completion in immediate mode */
	cmd = mbp->mb;

	for (ii = 0; ii < mbp->tmo; ii += CSIO_MB_POLL_FREQ) {
		mdelay(CSIO_MB_POLL_FREQ);

		/* Check for response */
		ctl = csio_rd_reg32(hw, ctl_reg);
		if (csio_mb_is_host_owner(MBOWNER_GET(ctl))) {

			if (!(ctl & MBMSGVALID)) {
				csio_wr_reg32(hw, 0, ctl_reg);
				continue;
			}

			CSIO_DUMP_MB(hw, hw->pfn, data_reg);

			hdr = cpu_to_be64(csio_rd_reg64(hw, data_reg));
			fw_hdr = (struct fw_cmd_hdr *)&hdr;

			switch (FW_CMD_OP_GET(ntohl(fw_hdr->hi))) {
			case FW_DEBUG_CMD:
				csio_mb_debug_cmd_handler(hw);
				continue;
			}

			/* Copy response */
			for (i = 0; i < size; i += 8)
				*cmd++ = cpu_to_be64(csio_rd_reg64
							  (hw, data_reg + i));
			csio_wr_reg32(hw, 0, ctl_reg);

			if (csio_mb_fw_retval(mbp) != FW_SUCCESS)
				CSIO_INC_STATS(mbm, n_err);

			CSIO_INC_STATS(mbm, n_rsp);
			return 0;
		}
	}

	CSIO_INC_STATS(mbm, n_tmo);

	csio_err(hw, "Mailbox %x op:0x%x timed out!\n",
		 hw->pfn, *((uint8_t *)cmd));

	return -ETIMEDOUT;

error_out:
	CSIO_INC_STATS(mbm, n_err);
	return rv;
}

/*
 * csio_mb_completions - Completion handler for Mailbox commands
 * @hw: The HW structure
 * @cbfn_q: Completion queue.
 *
 */
void
csio_mb_completions(struct csio_hw *hw, struct list_head *cbfn_q)
{
	struct csio_mb *mbp;
	struct csio_mbm *mbm = &hw->mbm;
	enum fw_retval rv;

	while (!list_empty(cbfn_q)) {
		mbp = list_first_entry(cbfn_q, struct csio_mb, list);
		list_del_init(&mbp->list);

		rv = csio_mb_fw_retval(mbp);
		if ((rv != FW_SUCCESS) && (rv != FW_HOSTERROR))
			CSIO_INC_STATS(mbm, n_err);
		else if (rv != FW_HOSTERROR)
			CSIO_INC_STATS(mbm, n_rsp);

		if (mbp->mb_cbfn)
			mbp->mb_cbfn(hw, mbp);
	}
}

static void
csio_mb_portmod_changed(struct csio_hw *hw, uint8_t port_id)
{
	static char *mod_str[] = {
		NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM"
	};

	struct csio_pport *port = &hw->pport[port_id];

	if (port->mod_type == FW_PORT_MOD_TYPE_NONE)
		csio_info(hw, "Port:%d - port module unplugged\n", port_id);
	else if (port->mod_type < ARRAY_SIZE(mod_str))
		csio_info(hw, "Port:%d - %s port module inserted\n", port_id,
			  mod_str[port->mod_type]);
	else if (port->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
		csio_info(hw,
			  "Port:%d - unsupported optical port module "
			  "inserted\n", port_id);
	else if (port->mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
		csio_info(hw,
			  "Port:%d - unknown port module inserted, forcing "
			  "TWINAX\n", port_id);
	else if (port->mod_type == FW_PORT_MOD_TYPE_ERROR)
		csio_info(hw, "Port:%d - transceiver module error\n", port_id);
	else
		csio_info(hw, "Port:%d - unknown module type %d inserted\n",
			  port_id, port->mod_type);
}

int
csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd)
{
	uint8_t opcode = *(uint8_t *)cmd;
	struct fw_port_cmd *pcmd;
	uint8_t port_id;
	uint32_t link_status;
	uint16_t action;
	uint8_t mod_type;

	if (opcode == FW_PORT_CMD) {
		pcmd = (struct fw_port_cmd *)cmd;
		port_id = FW_PORT_CMD_PORTID_GET(
				ntohl(pcmd->op_to_portid));
		action = FW_PORT_CMD_ACTION_GET(
				ntohl(pcmd->action_to_len16));
		if (action != FW_PORT_ACTION_GET_PORT_INFO) {
			csio_err(hw, "Unhandled FW_PORT_CMD action: %u\n",
				action);
			return -EINVAL;
		}

		link_status = ntohl(pcmd->u.info.lstatus_to_modtype);
		mod_type = FW_PORT_CMD_MODTYPE_GET(link_status);

		hw->pport[port_id].link_status =
			FW_PORT_CMD_LSTATUS_GET(link_status);
		hw->pport[port_id].link_speed =
			FW_PORT_CMD_LSPEED_GET(link_status);

		csio_info(hw, "Port:%x - LINK %s\n", port_id,
			FW_PORT_CMD_LSTATUS_GET(link_status) ? "UP" : "DOWN");

		if (mod_type != hw->pport[port_id].mod_type) {
			hw->pport[port_id].mod_type = mod_type;
			csio_mb_portmod_changed(hw, port_id);
		}
	} else if (opcode == FW_DEBUG_CMD) {
		csio_mb_dump_fw_dbg(hw, cmd);
	} else {
		csio_dbg(hw, "Gen MB can't handle op:0x%x on evtq.\n", opcode);
		return -EINVAL;
	}

	return 0;
}

/*
 * csio_mb_isr_handler - Handle mailboxes related interrupts.
 * @hw: The HW structure
 *
 * Called from the ISR to handle Mailbox related interrupts.
 * HW Lock should be held across this call.
 */
int
csio_mb_isr_handler(struct csio_hw *hw)
{
	struct csio_mbm		*mbm = &hw->mbm;
	struct csio_mb		*mbp =  mbm->mcurrent;
	__be64			*cmd;
	uint32_t		ctl, cim_cause, pl_cause;
	int			i;
	uint32_t		ctl_reg = PF_REG(hw->pfn, CIM_PF_MAILBOX_CTRL);
	uint32_t		data_reg = PF_REG(hw->pfn, CIM_PF_MAILBOX_DATA);
	int			size;
	__be64			hdr;
	struct fw_cmd_hdr	*fw_hdr;

	pl_cause = csio_rd_reg32(hw, MYPF_REG(PL_PF_INT_CAUSE));
	cim_cause = csio_rd_reg32(hw, MYPF_REG(CIM_PF_HOST_INT_CAUSE));

	if (!(pl_cause & PFCIM) || !(cim_cause & MBMSGRDYINT)) {
		CSIO_INC_STATS(hw, n_mbint_unexp);
		return -EINVAL;
	}

	/*
	 * The cause registers below HAVE to be cleared in the SAME
	 * order as below: The low level cause register followed by
	 * the upper level cause register. In other words, CIM-cause
	 * first followed by PL-Cause next.
	 */
	csio_wr_reg32(hw, MBMSGRDYINT, MYPF_REG(CIM_PF_HOST_INT_CAUSE));
	csio_wr_reg32(hw, PFCIM, MYPF_REG(PL_PF_INT_CAUSE));

	ctl = csio_rd_reg32(hw, ctl_reg);

	if (csio_mb_is_host_owner(MBOWNER_GET(ctl))) {

		CSIO_DUMP_MB(hw, hw->pfn, data_reg);

		if (!(ctl & MBMSGVALID)) {
			csio_warn(hw,
				  "Stray mailbox interrupt recvd,"
				  " mailbox data not valid\n");
			csio_wr_reg32(hw, 0, ctl_reg);
			/* Flush */
			csio_rd_reg32(hw, ctl_reg);
			return -EINVAL;
		}

		hdr = cpu_to_be64(csio_rd_reg64(hw, data_reg));
		fw_hdr = (struct fw_cmd_hdr *)&hdr;

		switch (FW_CMD_OP_GET(ntohl(fw_hdr->hi))) {
		case FW_DEBUG_CMD:
			csio_mb_debug_cmd_handler(hw);
			return -EINVAL;
#if 0
		case FW_ERROR_CMD:
		case FW_INITIALIZE_CMD: /* When we are not master */
#endif
		}

		CSIO_ASSERT(mbp != NULL);

		cmd = mbp->mb;
		size = mbp->mb_size;
		/* Get response */
		for (i = 0; i < size; i += 8)
			*cmd++ = cpu_to_be64(csio_rd_reg64
						  (hw, data_reg + i));

		csio_wr_reg32(hw, 0, ctl_reg);
		/* Flush */
		csio_rd_reg32(hw, ctl_reg);

		mbm->mcurrent = NULL;

		/* Add completion to tail of cbfn queue */
		list_add_tail(&mbp->list, &mbm->cbfn_q);
		CSIO_INC_STATS(mbm, n_cbfnq);

		/*
		 * Enqueue event to EventQ. Events processing happens
		 * in Event worker thread context
		 */
		if (csio_enqueue_evt(hw, CSIO_EVT_MBX, mbp, sizeof(mbp)))
			CSIO_INC_STATS(hw, n_evt_drop);

		return 0;

	} else {
		/*
		 * We can get here if mailbox MSIX vector is shared,
		 * or in INTx case. Or a stray interrupt.
		 */
		csio_dbg(hw, "Host not owner, no mailbox interrupt\n");
		CSIO_INC_STATS(hw, n_int_stray);
		return -EINVAL;
	}
}

/*
 * csio_mb_tmo_handler - Timeout handler
 * @hw: The HW structure
 *
 */
struct csio_mb *
csio_mb_tmo_handler(struct csio_hw *hw)
{
	struct csio_mbm *mbm = &hw->mbm;
	struct csio_mb *mbp =  mbm->mcurrent;
	struct fw_cmd_hdr *fw_hdr;

	/*
	 * Could be a race b/w the completion handler and the timer
	 * and the completion handler won that race.
	 */
	if (mbp == NULL) {
		CSIO_DB_ASSERT(0);
		return NULL;
	}

	fw_hdr = (struct fw_cmd_hdr *)(mbp->mb);

	csio_dbg(hw, "Mailbox num:%x op:0x%x timed out\n", hw->pfn,
		    FW_CMD_OP_GET(ntohl(fw_hdr->hi)));

	mbm->mcurrent = NULL;
	CSIO_INC_STATS(mbm, n_tmo);
	fw_hdr->lo = htonl(FW_CMD_RETVAL(FW_ETIMEDOUT));

	return mbp;
}

/*
 * csio_mb_cancel_all - Cancel all waiting commands.
 * @hw: The HW structure
 * @cbfn_q: The callback queue.
 *
 * Caller should hold hw lock across this call.
 */
void
csio_mb_cancel_all(struct csio_hw *hw, struct list_head *cbfn_q)
{
	struct csio_mb *mbp;
	struct csio_mbm *mbm = &hw->mbm;
	struct fw_cmd_hdr *hdr;
	struct list_head *tmp;

	if (mbm->mcurrent) {
		mbp = mbm->mcurrent;

		/* Stop mailbox completion timer */
		del_timer_sync(&mbm->timer);

		/* Add completion to tail of cbfn queue */
		list_add_tail(&mbp->list, cbfn_q);
		mbm->mcurrent = NULL;
	}

	if (!list_empty(&mbm->req_q)) {
		list_splice_tail_init(&mbm->req_q, cbfn_q);
		mbm->stats.n_activeq = 0;
	}

	if (!list_empty(&mbm->cbfn_q)) {
		list_splice_tail_init(&mbm->cbfn_q, cbfn_q);
		mbm->stats.n_cbfnq = 0;
	}

	if (list_empty(cbfn_q))
		return;

	list_for_each(tmp, cbfn_q) {
		mbp = (struct csio_mb *)tmp;
		hdr = (struct fw_cmd_hdr *)(mbp->mb);

		csio_dbg(hw, "Cancelling pending mailbox num %x op:%x\n",
			    hw->pfn, FW_CMD_OP_GET(ntohl(hdr->hi)));

		CSIO_INC_STATS(mbm, n_cancel);
		hdr->lo = htonl(FW_CMD_RETVAL(FW_HOSTERROR));
	}
}

/*
 * csio_mbm_init - Initialize Mailbox module
 * @mbm: Mailbox module
 * @hw: The HW structure
 * @timer: Timing function for interrupting mailboxes
 *
 * Initialize timer and the request/response queues.
 */
int
csio_mbm_init(struct csio_mbm *mbm, struct csio_hw *hw,
	      void (*timer_fn)(uintptr_t))
{
	struct timer_list *timer = &mbm->timer;

	init_timer(timer);
	timer->function = timer_fn;
	timer->data = (unsigned long)hw;

	INIT_LIST_HEAD(&mbm->req_q);
	INIT_LIST_HEAD(&mbm->cbfn_q);
	csio_set_mb_intr_idx(mbm, -1);

	return 0;
}

/*
 * csio_mbm_exit - Uninitialize mailbox module
 * @mbm: Mailbox module
 *
 * Stop timer.
 */
void
csio_mbm_exit(struct csio_mbm *mbm)
{
	del_timer_sync(&mbm->timer);

	CSIO_DB_ASSERT(mbm->mcurrent == NULL);
	CSIO_DB_ASSERT(list_empty(&mbm->req_q));
	CSIO_DB_ASSERT(list_empty(&mbm->cbfn_q));
}
