/*
 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
 * All rights reserved
 * www.brocade.com
 *
 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License (GPL) Version 2 as
 * published by the Free Software Foundation
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <bfa.h>
#include <bfi/bfi_uf.h>
#include <cs/bfa_debug.h>

BFA_TRC_FILE(HAL, FCXP);
BFA_MODULE(fcxp);

/**
 * forward declarations
 */
static void     __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
static void     hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
				 struct bfi_fcxp_send_rsp_s *fcxp_rsp);
static void     hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
				 struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
static void	bfa_fcxp_qresume(void *cbarg);
static void	bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
			       struct bfi_fcxp_send_req_s *send_req);

/**
 *  fcxp_pvt BFA FCXP private functions
 */

static void
claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
{
	u8        *dm_kva = NULL;
	u64        dm_pa;
	u32        buf_pool_sz;

	dm_kva = bfa_meminfo_dma_virt(mi);
	dm_pa = bfa_meminfo_dma_phys(mi);

	buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;

	/*
	 * Initialize the fcxp req payload list
	 */
	mod->req_pld_list_kva = dm_kva;
	mod->req_pld_list_pa = dm_pa;
	dm_kva += buf_pool_sz;
	dm_pa += buf_pool_sz;
	bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz);

	/*
	 * Initialize the fcxp rsp payload list
	 */
	buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps;
	mod->rsp_pld_list_kva = dm_kva;
	mod->rsp_pld_list_pa = dm_pa;
	dm_kva += buf_pool_sz;
	dm_pa += buf_pool_sz;
	bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);

	bfa_meminfo_dma_virt(mi) = dm_kva;
	bfa_meminfo_dma_phys(mi) = dm_pa;
}

static void
claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
{
	u16        i;
	struct bfa_fcxp_s *fcxp;

	fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
	bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);

	INIT_LIST_HEAD(&mod->fcxp_free_q);
	INIT_LIST_HEAD(&mod->fcxp_active_q);

	mod->fcxp_list = fcxp;

	for (i = 0; i < mod->num_fcxps; i++) {
		fcxp->fcxp_mod = mod;
		fcxp->fcxp_tag = i;

		list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
		bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
		fcxp->reqq_waiting = BFA_FALSE;

		fcxp = fcxp + 1;
	}

	bfa_meminfo_kva(mi) = (void *)fcxp;
}

static void
bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
		u32 *dm_len)
{
	u16        num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;

	if (num_fcxp_reqs == 0)
		return;

	/*
	 * Account for req/rsp payload
	 */
	*dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
	if (cfg->drvcfg.min_cfg)
		*dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
	else
		*dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs;

	/*
	 * Account for fcxp structs
	 */
	*ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
}

static void
bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
		    struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
{
	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);

	bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
	mod->bfa = bfa;
	mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;

	/**
	 * Initialize FCXP request and response payload sizes.
	 */
	mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
	if (!cfg->drvcfg.min_cfg)
		mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;

	INIT_LIST_HEAD(&mod->wait_q);

	claim_fcxp_req_rsp_mem(mod, meminfo);
	claim_fcxps_mem(mod, meminfo);
}

static void
bfa_fcxp_initdone(struct bfa_s *bfa)
{
}

static void
bfa_fcxp_detach(struct bfa_s *bfa)
{
}

static void
bfa_fcxp_start(struct bfa_s *bfa)
{
}

static void
bfa_fcxp_stop(struct bfa_s *bfa)
{
}

static void
bfa_fcxp_iocdisable(struct bfa_s *bfa)
{
	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
	struct bfa_fcxp_s *fcxp;
	struct list_head        *qe, *qen;

	list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
		fcxp = (struct bfa_fcxp_s *) qe;
		if (fcxp->caller == NULL) {
			fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
					BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
			bfa_fcxp_free(fcxp);
		} else {
			fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
			bfa_cb_queue(bfa, &fcxp->hcb_qe,
				      __bfa_fcxp_send_cbfn, fcxp);
		}
	}
}

static struct bfa_fcxp_s *
bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
{
	struct bfa_fcxp_s *fcxp;

	bfa_q_deq(&fm->fcxp_free_q, &fcxp);

	if (fcxp)
		list_add_tail(&fcxp->qe, &fm->fcxp_active_q);

	return fcxp;
}

static void
bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
{
	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
	struct bfa_fcxp_wqe_s *wqe;

	bfa_q_deq(&mod->wait_q, &wqe);
	if (wqe) {
		bfa_trc(mod->bfa, fcxp->fcxp_tag);
		wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
		return;
	}

	bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
	list_del(&fcxp->qe);
	list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
}

static void
bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
		       bfa_status_t req_status, u32 rsp_len,
		       u32 resid_len, struct fchs_s *rsp_fchs)
{
	/**discarded fcxp completion */
}

static void
__bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
{
	struct bfa_fcxp_s *fcxp = cbarg;

	if (complete) {
		fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
				fcxp->rsp_status, fcxp->rsp_len,
				fcxp->residue_len, &fcxp->rsp_fchs);
	} else {
		bfa_fcxp_free(fcxp);
	}
}

static void
hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
{
	struct bfa_fcxp_mod_s	*mod = BFA_FCXP_MOD(bfa);
	struct bfa_fcxp_s 	*fcxp;
	u16		fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);

	bfa_trc(bfa, fcxp_tag);

	fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);

	/**
	 * @todo f/w should not set residue to non-0 when everything
	 *       is received.
	 */
	if (fcxp_rsp->req_status == BFA_STATUS_OK)
		fcxp_rsp->residue_len = 0;
	else
		fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);

	fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);

	bfa_assert(fcxp->send_cbfn != NULL);

	hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);

	if (fcxp->send_cbfn != NULL) {
		if (fcxp->caller == NULL) {
			bfa_trc(mod->bfa, fcxp->fcxp_tag);

			fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
					fcxp_rsp->req_status, fcxp_rsp->rsp_len,
					fcxp_rsp->residue_len, &fcxp_rsp->fchs);
			/*
			 * fcxp automatically freed on return from the callback
			 */
			bfa_fcxp_free(fcxp);
		} else {
			bfa_trc(mod->bfa, fcxp->fcxp_tag);
			fcxp->rsp_status = fcxp_rsp->req_status;
			fcxp->rsp_len = fcxp_rsp->rsp_len;
			fcxp->residue_len = fcxp_rsp->residue_len;
			fcxp->rsp_fchs = fcxp_rsp->fchs;

			bfa_cb_queue(bfa, &fcxp->hcb_qe,
				      __bfa_fcxp_send_cbfn, fcxp);
		}
	} else {
		bfa_trc(bfa, fcxp_tag);
	}
}

static void
hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
{
	union bfi_addr_u      sga_zero = { {0} };

	sge->sg_len = reqlen;
	sge->flags = BFI_SGE_DATA_LAST;
	bfa_dma_addr_set(sge[0].sga, req_pa);
	bfa_sge_to_be(sge);
	sge++;

	sge->sga = sga_zero;
	sge->sg_len = reqlen;
	sge->flags = BFI_SGE_PGDLEN;
	bfa_sge_to_be(sge);
}

static void
hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
		 struct fchs_s *fchs)
{
	/*
	 * TODO: TX ox_id
	 */
	if (reqlen > 0) {
		if (fcxp->use_ireqbuf) {
			u32        pld_w0 =
				*((u32 *) BFA_FCXP_REQ_PLD(fcxp));

			bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
				BFA_PL_EID_TX,
				reqlen + sizeof(struct fchs_s), fchs, pld_w0);
		} else {
			bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
				BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s),
				fchs);
		}
	} else {
		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
			       reqlen + sizeof(struct fchs_s), fchs);
	}
}

static void
hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
		 struct bfi_fcxp_send_rsp_s *fcxp_rsp)
{
	if (fcxp_rsp->rsp_len > 0) {
		if (fcxp->use_irspbuf) {
			u32        pld_w0 =
				*((u32 *) BFA_FCXP_RSP_PLD(fcxp));

			bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
					      BFA_PL_EID_RX,
					      (u16) fcxp_rsp->rsp_len,
					      &fcxp_rsp->fchs, pld_w0);
		} else {
			bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
				       BFA_PL_EID_RX,
				       (u16) fcxp_rsp->rsp_len,
				       &fcxp_rsp->fchs);
		}
	} else {
		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
			       (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
	}
}

/**
 * Handler to resume sending fcxp when space in available in cpe queue.
 */
static void
bfa_fcxp_qresume(void *cbarg)
{
	struct bfa_fcxp_s		*fcxp = cbarg;
	struct bfa_s			*bfa = fcxp->fcxp_mod->bfa;
	struct bfi_fcxp_send_req_s	*send_req;

	fcxp->reqq_waiting = BFA_FALSE;
	send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
	bfa_fcxp_queue(fcxp, send_req);
}

/**
 * Queue fcxp send request to foimrware.
 */
static void
bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
{
	struct bfa_s      		*bfa = fcxp->fcxp_mod->bfa;
	struct bfa_fcxp_req_info_s	*reqi = &fcxp->req_info;
	struct bfa_fcxp_rsp_info_s	*rspi = &fcxp->rsp_info;
	struct bfa_rport_s		*rport = reqi->bfa_rport;

	bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
			bfa_lpuid(bfa));

	send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
	if (rport) {
		send_req->rport_fw_hndl = rport->fw_handle;
		send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
		if (send_req->max_frmsz == 0)
			send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
	} else {
		send_req->rport_fw_hndl = 0;
		send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
	}

	send_req->vf_id = bfa_os_htons(reqi->vf_id);
	send_req->lp_tag = reqi->lp_tag;
	send_req->class = reqi->class;
	send_req->rsp_timeout = rspi->rsp_timeout;
	send_req->cts = reqi->cts;
	send_req->fchs = reqi->fchs;

	send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
	send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);

	/*
	 * setup req sgles
	 */
	if (fcxp->use_ireqbuf == 1) {
		hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
					BFA_FCXP_REQ_PLD_PA(fcxp));
	} else {
		if (fcxp->nreq_sgles > 0) {
			bfa_assert(fcxp->nreq_sgles == 1);
			hal_fcxp_set_local_sges(send_req->req_sge,
						reqi->req_tot_len,
						fcxp->req_sga_cbfn(fcxp->caller,
								   0));
		} else {
			bfa_assert(reqi->req_tot_len == 0);
			hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
		}
	}

	/*
	 * setup rsp sgles
	 */
	if (fcxp->use_irspbuf == 1) {
		bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);

		hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
					BFA_FCXP_RSP_PLD_PA(fcxp));

	} else {
		if (fcxp->nrsp_sgles > 0) {
			bfa_assert(fcxp->nrsp_sgles == 1);
			hal_fcxp_set_local_sges(send_req->rsp_sge,
						rspi->rsp_maxlen,
						fcxp->rsp_sga_cbfn(fcxp->caller,
								   0));
		} else {
			bfa_assert(rspi->rsp_maxlen == 0);
			hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
		}
	}

	hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);

	bfa_reqq_produce(bfa, BFA_REQQ_FCXP);

	bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
	bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
}


/**
 *  hal_fcxp_api BFA FCXP API
 */

/**
 * Allocate an FCXP instance to send a response or to send a request
 * that has a response. Request/response buffers are allocated by caller.
 *
 * @param[in]	bfa		BFA bfa instance
 * @param[in]	nreq_sgles	Number of SG elements required for request
 * 				buffer. 0, if fcxp internal buffers are	used.
 * 				Use bfa_fcxp_get_reqbuf() to get the
 * 				internal req buffer.
 * @param[in]	req_sgles	SG elements describing request buffer. Will be
 * 				copied in by BFA and hence can be freed on
 * 				return from this function.
 * @param[in]	get_req_sga	function ptr to be called to get a request SG
 * 				Address (given the sge index).
 * @param[in]	get_req_sglen	function ptr to be called to get a request SG
 * 				len (given the sge index).
 * @param[in]	get_rsp_sga	function ptr to be called to get a response SG
 * 				Address (given the sge index).
 * @param[in]	get_rsp_sglen	function ptr to be called to get a response SG
 * 				len (given the sge index).
 *
 * @return FCXP instance. NULL on failure.
 */
struct bfa_fcxp_s *
bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
			int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
			bfa_fcxp_get_sglen_t req_sglen_cbfn,
			bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
			bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
{
	struct bfa_fcxp_s *fcxp = NULL;
	u32        nreq_sgpg, nrsp_sgpg;

	bfa_assert(bfa != NULL);

	fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
	if (fcxp == NULL)
		return NULL;

	bfa_trc(bfa, fcxp->fcxp_tag);

	fcxp->caller = caller;

	if (nreq_sgles == 0) {
		fcxp->use_ireqbuf = 1;
	} else {
		bfa_assert(req_sga_cbfn != NULL);
		bfa_assert(req_sglen_cbfn != NULL);

		fcxp->use_ireqbuf = 0;
		fcxp->req_sga_cbfn = req_sga_cbfn;
		fcxp->req_sglen_cbfn = req_sglen_cbfn;

		fcxp->nreq_sgles = nreq_sgles;

		/*
		 * alloc required sgpgs
		 */
		if (nreq_sgles > BFI_SGE_INLINE) {
			nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);

			if (bfa_sgpg_malloc
			    (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
			    != BFA_STATUS_OK) {
				/* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
				nreq_sgpg); */
				/*
				 * TODO
				 */
			}
		}
	}

	if (nrsp_sgles == 0) {
		fcxp->use_irspbuf = 1;
	} else {
		bfa_assert(rsp_sga_cbfn != NULL);
		bfa_assert(rsp_sglen_cbfn != NULL);

		fcxp->use_irspbuf = 0;
		fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
		fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;

		fcxp->nrsp_sgles = nrsp_sgles;
		/*
		 * alloc required sgpgs
		 */
		if (nrsp_sgles > BFI_SGE_INLINE) {
			nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);

			if (bfa_sgpg_malloc
			    (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg)
			    != BFA_STATUS_OK) {
				/* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe,
				nrsp_sgpg); */
				/*
				 * TODO
				 */
			}
		}
	}

	return fcxp;
}

/**
 * Get the internal request buffer pointer
 *
 * @param[in]	fcxp	BFA fcxp pointer
 *
 * @return 		pointer to the internal request buffer
 */
void *
bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
{
	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
	void	*reqbuf;

	bfa_assert(fcxp->use_ireqbuf == 1);
	reqbuf = ((u8 *)mod->req_pld_list_kva) +
			fcxp->fcxp_tag * mod->req_pld_sz;
	return reqbuf;
}

u32
bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
{
	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;

	return mod->req_pld_sz;
}

/**
 * Get the internal response buffer pointer
 *
 * @param[in]	fcxp	BFA fcxp pointer
 *
 * @return		pointer to the internal request buffer
 */
void *
bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
{
	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
	void	*rspbuf;

	bfa_assert(fcxp->use_irspbuf == 1);

	rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
			fcxp->fcxp_tag * mod->rsp_pld_sz;
	return rspbuf;
}

/**
 * 		Free the BFA FCXP
 *
 * @param[in]	fcxp			BFA fcxp pointer
 *
 * @return 		void
 */
void
bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
{
	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;

	bfa_assert(fcxp != NULL);
	bfa_trc(mod->bfa, fcxp->fcxp_tag);
	bfa_fcxp_put(fcxp);
}

/**
 * Send a FCXP request
 *
 * @param[in]	fcxp	BFA fcxp pointer
 * @param[in]	rport	BFA rport pointer. Could be left NULL for WKA rports
 * @param[in]	vf_id	virtual Fabric ID
 * @param[in]	lp_tag  lport tag
 * @param[in]	cts	use Continous sequence
 * @param[in]	cos	fc Class of Service
 * @param[in]	reqlen	request length, does not include FCHS length
 * @param[in]	fchs	fc Header Pointer. The header content will be copied
 *			in by BFA.
 *
 * @param[in]	cbfn	call back function to be called on receiving
 * 								the response
 * @param[in]	cbarg	arg for cbfn
 * @param[in]	rsp_timeout
 *			response timeout
 *
 * @return		bfa_status_t
 */
void
bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
		u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
		u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
		void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
{
	struct bfa_s			*bfa  = fcxp->fcxp_mod->bfa;
	struct bfa_fcxp_req_info_s	*reqi = &fcxp->req_info;
	struct bfa_fcxp_rsp_info_s	*rspi = &fcxp->rsp_info;
	struct bfi_fcxp_send_req_s	*send_req;

	bfa_trc(bfa, fcxp->fcxp_tag);

	/**
	 * setup request/response info
	 */
	reqi->bfa_rport = rport;
	reqi->vf_id = vf_id;
	reqi->lp_tag = lp_tag;
	reqi->class = cos;
	rspi->rsp_timeout = rsp_timeout;
	reqi->cts = cts;
	reqi->fchs = *fchs;
	reqi->req_tot_len = reqlen;
	rspi->rsp_maxlen = rsp_maxlen;
	fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
	fcxp->send_cbarg = cbarg;

	/**
	 * If no room in CPE queue, wait for
	 */
	send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
	if (!send_req) {
		bfa_trc(bfa, fcxp->fcxp_tag);
		fcxp->reqq_waiting = BFA_TRUE;
		bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
		return;
	}

	bfa_fcxp_queue(fcxp, send_req);
}

/**
 * Abort a BFA FCXP
 *
 * @param[in]	fcxp	BFA fcxp pointer
 *
 * @return 		void
 */
bfa_status_t
bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
{
	bfa_assert(0);
	return BFA_STATUS_OK;
}

void
bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
			bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg)
{
	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);

	bfa_assert(list_empty(&mod->fcxp_free_q));

	wqe->alloc_cbfn = alloc_cbfn;
	wqe->alloc_cbarg = alloc_cbarg;
	list_add_tail(&wqe->qe, &mod->wait_q);
}

void
bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
{
	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);

	bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
	list_del(&wqe->qe);
}

void
bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
{
	/**
	 * If waiting for room in request queue, cancel reqq wait
	 * and free fcxp.
	 */
	if (fcxp->reqq_waiting) {
		fcxp->reqq_waiting = BFA_FALSE;
		bfa_reqq_wcancel(&fcxp->reqq_wqe);
		bfa_fcxp_free(fcxp);
		return;
	}

	fcxp->send_cbfn = bfa_fcxp_null_comp;
}



/**
 *  hal_fcxp_public BFA FCXP public functions
 */

void
bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
{
	switch (msg->mhdr.msg_id) {
	case BFI_FCXP_I2H_SEND_RSP:
		hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
		break;

	default:
		bfa_trc(bfa, msg->mhdr.msg_id);
		bfa_assert(0);
	}
}

u32
bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
{
	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);

	return mod->rsp_pld_sz;
}


