/*
 * 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/kernel.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/utsname.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_transport_fc.h>
#include <asm/unaligned.h>
#include <scsi/fc/fc_els.h>
#include <scsi/fc/fc_fs.h>
#include <scsi/fc/fc_gs.h>
#include <scsi/fc/fc_ms.h>

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

int csio_fcoe_rnodes = 1024;
int csio_fdmi_enable = 1;

#define PORT_ID_PTR(_x)         ((uint8_t *)(&_x) + 1)

/* Lnode SM declarations */
static void csio_lns_uninit(struct csio_lnode *, enum csio_ln_ev);
static void csio_lns_online(struct csio_lnode *, enum csio_ln_ev);
static void csio_lns_ready(struct csio_lnode *, enum csio_ln_ev);
static void csio_lns_offline(struct csio_lnode *, enum csio_ln_ev);

static int csio_ln_mgmt_submit_req(struct csio_ioreq *,
		void (*io_cbfn) (struct csio_hw *, struct csio_ioreq *),
		enum fcoe_cmn_type, struct csio_dma_buf *, uint32_t);

/* LN event mapping */
static enum csio_ln_ev fwevt_to_lnevt[] = {
	CSIO_LNE_NONE,		/* None */
	CSIO_LNE_NONE,		/* PLOGI_ACC_RCVD  */
	CSIO_LNE_NONE,		/* PLOGI_RJT_RCVD  */
	CSIO_LNE_NONE,		/* PLOGI_RCVD	   */
	CSIO_LNE_NONE,		/* PLOGO_RCVD	   */
	CSIO_LNE_NONE,		/* PRLI_ACC_RCVD   */
	CSIO_LNE_NONE,		/* PRLI_RJT_RCVD   */
	CSIO_LNE_NONE,		/* PRLI_RCVD	   */
	CSIO_LNE_NONE,		/* PRLO_RCVD	   */
	CSIO_LNE_NONE,		/* NPORT_ID_CHGD   */
	CSIO_LNE_LOGO,		/* FLOGO_RCVD	   */
	CSIO_LNE_LOGO,		/* CLR_VIRT_LNK_RCVD */
	CSIO_LNE_FAB_INIT_DONE,/* FLOGI_ACC_RCVD   */
	CSIO_LNE_NONE,		/* FLOGI_RJT_RCVD   */
	CSIO_LNE_FAB_INIT_DONE,/* FDISC_ACC_RCVD   */
	CSIO_LNE_NONE,		/* FDISC_RJT_RCVD   */
	CSIO_LNE_NONE,		/* FLOGI_TMO_MAX_RETRY */
	CSIO_LNE_NONE,		/* IMPL_LOGO_ADISC_ACC */
	CSIO_LNE_NONE,		/* IMPL_LOGO_ADISC_RJT */
	CSIO_LNE_NONE,		/* IMPL_LOGO_ADISC_CNFLT */
	CSIO_LNE_NONE,		/* PRLI_TMO		*/
	CSIO_LNE_NONE,		/* ADISC_TMO		*/
	CSIO_LNE_NONE,		/* RSCN_DEV_LOST */
	CSIO_LNE_NONE,		/* SCR_ACC_RCVD */
	CSIO_LNE_NONE,		/* ADISC_RJT_RCVD */
	CSIO_LNE_NONE,		/* LOGO_SNT */
	CSIO_LNE_NONE,		/* PROTO_ERR_IMPL_LOGO */
};

#define CSIO_FWE_TO_LNE(_evt)	((_evt > PROTO_ERR_IMPL_LOGO) ?		\
						CSIO_LNE_NONE :	\
						fwevt_to_lnevt[_evt])

#define csio_ct_rsp(cp)		(((struct fc_ct_hdr *)cp)->ct_cmd)
#define csio_ct_reason(cp)	(((struct fc_ct_hdr *)cp)->ct_reason)
#define csio_ct_expl(cp)	(((struct fc_ct_hdr *)cp)->ct_explan)
#define csio_ct_get_pld(cp)	((void *)(((uint8_t *)cp) + FC_CT_HDR_LEN))

/*
 * csio_ln_match_by_portid - lookup lnode using given portid.
 * @hw: HW module
 * @portid: port-id.
 *
 * If found, returns lnode matching given portid otherwise returns NULL.
 */
static struct csio_lnode *
csio_ln_lookup_by_portid(struct csio_hw *hw, uint8_t portid)
{
	struct csio_lnode *ln = hw->rln;
	struct list_head *tmp;

	/* Match siblings lnode with portid */
	list_for_each(tmp, &hw->sln_head) {
		ln = (struct csio_lnode *) tmp;
		if (ln->portid == portid)
			return ln;
	}

	return NULL;
}

/*
 * csio_ln_lookup_by_vnpi - Lookup lnode using given vnp id.
 * @hw - HW module
 * @vnpi - vnp index.
 * Returns - If found, returns lnode matching given vnp id
 * otherwise returns NULL.
 */
static struct csio_lnode *
csio_ln_lookup_by_vnpi(struct csio_hw *hw, uint32_t vnp_id)
{
	struct list_head *tmp1, *tmp2;
	struct csio_lnode *sln = NULL, *cln = NULL;

	if (list_empty(&hw->sln_head)) {
		CSIO_INC_STATS(hw, n_lnlkup_miss);
		return NULL;
	}
	/* Traverse sibling lnodes */
	list_for_each(tmp1, &hw->sln_head) {
		sln = (struct csio_lnode *) tmp1;

		/* Match sibling lnode */
		if (sln->vnp_flowid == vnp_id)
			return sln;

		if (list_empty(&sln->cln_head))
			continue;

		/* Traverse children lnodes */
		list_for_each(tmp2, &sln->cln_head) {
			cln = (struct csio_lnode *) tmp2;

			if (cln->vnp_flowid == vnp_id)
				return cln;
		}
	}
	CSIO_INC_STATS(hw, n_lnlkup_miss);
	return NULL;
}

/**
 * csio_lnode_lookup_by_wwpn - Lookup lnode using given wwpn.
 * @hw:		HW module.
 * @wwpn:	WWPN.
 *
 * If found, returns lnode matching given wwpn, returns NULL otherwise.
 */
struct csio_lnode *
csio_lnode_lookup_by_wwpn(struct csio_hw *hw, uint8_t *wwpn)
{
	struct list_head *tmp1, *tmp2;
	struct csio_lnode *sln = NULL, *cln = NULL;

	if (list_empty(&hw->sln_head)) {
		CSIO_INC_STATS(hw, n_lnlkup_miss);
		return NULL;
	}
	/* Traverse sibling lnodes */
	list_for_each(tmp1, &hw->sln_head) {
		sln = (struct csio_lnode *) tmp1;

		/* Match sibling lnode */
		if (!memcmp(csio_ln_wwpn(sln), wwpn, 8))
			return sln;

		if (list_empty(&sln->cln_head))
			continue;

		/* Traverse children lnodes */
		list_for_each(tmp2, &sln->cln_head) {
			cln = (struct csio_lnode *) tmp2;

			if (!memcmp(csio_ln_wwpn(cln), wwpn, 8))
				return cln;
		}
	}
	return NULL;
}

/* FDMI */
static void
csio_fill_ct_iu(void *buf, uint8_t type, uint8_t sub_type, uint16_t op)
{
	struct fc_ct_hdr *cmd = (struct fc_ct_hdr *)buf;
	cmd->ct_rev = FC_CT_REV;
	cmd->ct_fs_type = type;
	cmd->ct_fs_subtype = sub_type;
	cmd->ct_cmd = htons(op);
}

static int
csio_hostname(uint8_t *buf, size_t buf_len)
{
	if (snprintf(buf, buf_len, "%s", init_utsname()->nodename) > 0)
		return 0;
	return -1;
}

static int
csio_osname(uint8_t *buf, size_t buf_len)
{
	if (snprintf(buf, buf_len, "%s %s %s",
		     init_utsname()->sysname,
		     init_utsname()->release,
		     init_utsname()->version) > 0)
		return 0;

	return -1;
}

static inline void
csio_append_attrib(uint8_t **ptr, uint16_t type, uint8_t *val, uint16_t len)
{
	struct fc_fdmi_attr_entry *ae = (struct fc_fdmi_attr_entry *)*ptr;
	ae->type = htons(type);
	len += 4;		/* includes attribute type and length */
	len = (len + 3) & ~3;	/* should be multiple of 4 bytes */
	ae->len = htons(len);
	memcpy(ae->value, val, len);
	*ptr += len;
}

/*
 * csio_ln_fdmi_done - FDMI registeration completion
 * @hw: HW context
 * @fdmi_req: fdmi request
 */
static void
csio_ln_fdmi_done(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
{
	void *cmd;
	struct csio_lnode *ln = fdmi_req->lnode;

	if (fdmi_req->wr_status != FW_SUCCESS) {
		csio_ln_dbg(ln, "WR error:%x in processing fdmi rpa cmd\n",
			    fdmi_req->wr_status);
		CSIO_INC_STATS(ln, n_fdmi_err);
	}

	cmd = fdmi_req->dma_buf.vaddr;
	if (ntohs(csio_ct_rsp(cmd)) != FC_FS_ACC) {
		csio_ln_dbg(ln, "fdmi rpa cmd rejected reason %x expl %x\n",
			    csio_ct_reason(cmd), csio_ct_expl(cmd));
	}
}

/*
 * csio_ln_fdmi_rhba_cbfn - RHBA completion
 * @hw: HW context
 * @fdmi_req: fdmi request
 */
static void
csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
{
	void *cmd;
	uint8_t *pld;
	uint32_t len = 0;
	__be32 val;
	__be16 mfs;
	uint32_t numattrs = 0;
	struct csio_lnode *ln = fdmi_req->lnode;
	struct fs_fdmi_attrs *attrib_blk;
	struct fc_fdmi_port_name *port_name;
	uint8_t buf[64];
	uint8_t *fc4_type;

	if (fdmi_req->wr_status != FW_SUCCESS) {
		csio_ln_dbg(ln, "WR error:%x in processing fdmi rhba cmd\n",
			    fdmi_req->wr_status);
		CSIO_INC_STATS(ln, n_fdmi_err);
	}

	cmd = fdmi_req->dma_buf.vaddr;
	if (ntohs(csio_ct_rsp(cmd)) != FC_FS_ACC) {
		csio_ln_dbg(ln, "fdmi rhba cmd rejected reason %x expl %x\n",
			    csio_ct_reason(cmd), csio_ct_expl(cmd));
	}

	if (!csio_is_rnode_ready(fdmi_req->rnode)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		return;
	}

	/* Prepare CT hdr for RPA cmd */
	memset(cmd, 0, FC_CT_HDR_LEN);
	csio_fill_ct_iu(cmd, FC_FST_MGMT, FC_FDMI_SUBTYPE, FC_FDMI_RPA);

	/* Prepare RPA payload */
	pld = (uint8_t *)csio_ct_get_pld(cmd);
	port_name = (struct fc_fdmi_port_name *)pld;
	memcpy(&port_name->portname, csio_ln_wwpn(ln), 8);
	pld += sizeof(*port_name);

	/* Start appending Port attributes */
	attrib_blk = (struct fs_fdmi_attrs *)pld;
	attrib_blk->numattrs = 0;
	len += sizeof(attrib_blk->numattrs);
	pld += sizeof(attrib_blk->numattrs);

	fc4_type = &buf[0];
	memset(fc4_type, 0, FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
	fc4_type[2] = 1;
	fc4_type[7] = 1;
	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_FC4TYPES,
			   fc4_type, FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
	numattrs++;
	val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
			   (uint8_t *)&val,
			   FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
	numattrs++;

	if (hw->pport[ln->portid].link_speed == FW_PORT_CAP_SPEED_1G)
		val = htonl(FC_PORTSPEED_1GBIT);
	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP_SPEED_10G)
		val = htonl(FC_PORTSPEED_10GBIT);
	else
		val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN);
	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
			   (uint8_t *)&val,
			   FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
	numattrs++;

	mfs = ln->ln_sparm.csp.sp_bb_data;
	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
			   (uint8_t *)&mfs, FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
	numattrs++;

	strcpy(buf, "csiostor");
	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf,
			   (uint16_t)strlen(buf));
	numattrs++;

	if (!csio_hostname(buf, sizeof(buf))) {
		csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME,
				   buf, (uint16_t)strlen(buf));
		numattrs++;
	}
	attrib_blk->numattrs = htonl(numattrs);
	len = (uint32_t)(pld - (uint8_t *)cmd);

	/* Submit FDMI RPA request */
	spin_lock_irq(&hw->lock);
	if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_done,
				FCOE_CT, &fdmi_req->dma_buf, len)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		csio_ln_dbg(ln, "Failed to issue fdmi rpa req\n");
	}
	spin_unlock_irq(&hw->lock);
}

/*
 * csio_ln_fdmi_dprt_cbfn - DPRT completion
 * @hw: HW context
 * @fdmi_req: fdmi request
 */
static void
csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
{
	void *cmd;
	uint8_t *pld;
	uint32_t len = 0;
	uint32_t numattrs = 0;
	__be32  maxpayload = htonl(65536);
	struct fc_fdmi_hba_identifier *hbaid;
	struct csio_lnode *ln = fdmi_req->lnode;
	struct fc_fdmi_rpl *reg_pl;
	struct fs_fdmi_attrs *attrib_blk;
	uint8_t buf[64];

	if (fdmi_req->wr_status != FW_SUCCESS) {
		csio_ln_dbg(ln, "WR error:%x in processing fdmi dprt cmd\n",
			    fdmi_req->wr_status);
		CSIO_INC_STATS(ln, n_fdmi_err);
	}

	if (!csio_is_rnode_ready(fdmi_req->rnode)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		return;
	}
	cmd = fdmi_req->dma_buf.vaddr;
	if (ntohs(csio_ct_rsp(cmd)) != FC_FS_ACC) {
		csio_ln_dbg(ln, "fdmi dprt cmd rejected reason %x expl %x\n",
			    csio_ct_reason(cmd), csio_ct_expl(cmd));
	}

	/* Prepare CT hdr for RHBA cmd */
	memset(cmd, 0, FC_CT_HDR_LEN);
	csio_fill_ct_iu(cmd, FC_FST_MGMT, FC_FDMI_SUBTYPE, FC_FDMI_RHBA);
	len = FC_CT_HDR_LEN;

	/* Prepare RHBA payload */
	pld = (uint8_t *)csio_ct_get_pld(cmd);
	hbaid = (struct fc_fdmi_hba_identifier *)pld;
	memcpy(&hbaid->id, csio_ln_wwpn(ln), 8); /* HBA identifer */
	pld += sizeof(*hbaid);

	/* Register one port per hba */
	reg_pl = (struct fc_fdmi_rpl *)pld;
	reg_pl->numport = htonl(1);
	memcpy(&reg_pl->port[0].portname, csio_ln_wwpn(ln), 8);
	pld += sizeof(*reg_pl);

	/* Start appending HBA attributes hba */
	attrib_blk = (struct fs_fdmi_attrs *)pld;
	attrib_blk->numattrs = 0;
	len += sizeof(attrib_blk->numattrs);
	pld += sizeof(attrib_blk->numattrs);

	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_NODENAME, csio_ln_wwnn(ln),
			   FC_FDMI_HBA_ATTR_NODENAME_LEN);
	numattrs++;

	memset(buf, 0, sizeof(buf));

	strcpy(buf, "Chelsio Communications");
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf,
			   (uint16_t)strlen(buf));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER,
			   hw->vpd.sn, (uint16_t)sizeof(hw->vpd.sn));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id,
			   (uint16_t)sizeof(hw->vpd.id));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
			   hw->model_desc, (uint16_t)strlen(hw->model_desc));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION,
			   hw->hw_ver, (uint16_t)sizeof(hw->hw_ver));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
			   hw->fwrev_str, (uint16_t)strlen(hw->fwrev_str));
	numattrs++;

	if (!csio_osname(buf, sizeof(buf))) {
		csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION,
				   buf, (uint16_t)strlen(buf));
		numattrs++;
	}

	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
			   (uint8_t *)&maxpayload,
			   FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
	len = (uint32_t)(pld - (uint8_t *)cmd);
	numattrs++;
	attrib_blk->numattrs = htonl(numattrs);

	/* Submit FDMI RHBA request */
	spin_lock_irq(&hw->lock);
	if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_rhba_cbfn,
				FCOE_CT, &fdmi_req->dma_buf, len)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		csio_ln_dbg(ln, "Failed to issue fdmi rhba req\n");
	}
	spin_unlock_irq(&hw->lock);
}

/*
 * csio_ln_fdmi_dhba_cbfn - DHBA completion
 * @hw: HW context
 * @fdmi_req: fdmi request
 */
static void
csio_ln_fdmi_dhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
{
	struct csio_lnode *ln = fdmi_req->lnode;
	void *cmd;
	struct fc_fdmi_port_name *port_name;
	uint32_t len;

	if (fdmi_req->wr_status != FW_SUCCESS) {
		csio_ln_dbg(ln, "WR error:%x in processing fdmi dhba cmd\n",
			    fdmi_req->wr_status);
		CSIO_INC_STATS(ln, n_fdmi_err);
	}

	if (!csio_is_rnode_ready(fdmi_req->rnode)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		return;
	}
	cmd = fdmi_req->dma_buf.vaddr;
	if (ntohs(csio_ct_rsp(cmd)) != FC_FS_ACC) {
		csio_ln_dbg(ln, "fdmi dhba cmd rejected reason %x expl %x\n",
			    csio_ct_reason(cmd), csio_ct_expl(cmd));
	}

	/* Send FDMI cmd to de-register any Port attributes if registered
	 * before
	 */

	/* Prepare FDMI DPRT cmd */
	memset(cmd, 0, FC_CT_HDR_LEN);
	csio_fill_ct_iu(cmd, FC_FST_MGMT, FC_FDMI_SUBTYPE, FC_FDMI_DPRT);
	len = FC_CT_HDR_LEN;
	port_name = (struct fc_fdmi_port_name *)csio_ct_get_pld(cmd);
	memcpy(&port_name->portname, csio_ln_wwpn(ln), 8);
	len += sizeof(*port_name);

	/* Submit FDMI request */
	spin_lock_irq(&hw->lock);
	if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_dprt_cbfn,
				FCOE_CT, &fdmi_req->dma_buf, len)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		csio_ln_dbg(ln, "Failed to issue fdmi dprt req\n");
	}
	spin_unlock_irq(&hw->lock);
}

/**
 * csio_ln_fdmi_start - Start an FDMI request.
 * @ln:		lnode
 * @context:	session context
 *
 * Issued with lock held.
 */
int
csio_ln_fdmi_start(struct csio_lnode *ln, void *context)
{
	struct csio_ioreq *fdmi_req;
	struct csio_rnode *fdmi_rn = (struct csio_rnode *)context;
	void *cmd;
	struct fc_fdmi_hba_identifier *hbaid;
	uint32_t len;

	if (!(ln->flags & CSIO_LNF_FDMI_ENABLE))
		return -EPROTONOSUPPORT;

	if (!csio_is_rnode_ready(fdmi_rn))
		CSIO_INC_STATS(ln, n_fdmi_err);

	/* Send FDMI cmd to de-register any HBA attributes if registered
	 * before
	 */

	fdmi_req = ln->mgmt_req;
	fdmi_req->lnode = ln;
	fdmi_req->rnode = fdmi_rn;

	/* Prepare FDMI DHBA cmd */
	cmd = fdmi_req->dma_buf.vaddr;
	memset(cmd, 0, FC_CT_HDR_LEN);
	csio_fill_ct_iu(cmd, FC_FST_MGMT, FC_FDMI_SUBTYPE, FC_FDMI_DHBA);
	len = FC_CT_HDR_LEN;

	hbaid = (struct fc_fdmi_hba_identifier *)csio_ct_get_pld(cmd);
	memcpy(&hbaid->id, csio_ln_wwpn(ln), 8);
	len += sizeof(*hbaid);

	/* Submit FDMI request */
	if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_dhba_cbfn,
					FCOE_CT, &fdmi_req->dma_buf, len)) {
		CSIO_INC_STATS(ln, n_fdmi_err);
		csio_ln_dbg(ln, "Failed to issue fdmi dhba req\n");
	}

	return 0;
}

/*
 * csio_ln_vnp_read_cbfn - vnp read completion handler.
 * @hw: HW lnode
 * @cbfn: Completion handler.
 *
 * Reads vnp response and updates ln parameters.
 */
static void
csio_ln_vnp_read_cbfn(struct csio_hw *hw, struct csio_mb *mbp)
{
	struct csio_lnode *ln = ((struct csio_lnode *)mbp->priv);
	struct fw_fcoe_vnp_cmd *rsp = (struct fw_fcoe_vnp_cmd *)(mbp->mb);
	struct fc_els_csp *csp;
	struct fc_els_cssp *clsp;
	enum fw_retval retval;
	__be32 nport_id;

	retval = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16));
	if (retval != FW_SUCCESS) {
		csio_err(hw, "FCOE VNP read cmd returned error:0x%x\n", retval);
		mempool_free(mbp, hw->mb_mempool);
		return;
	}

	spin_lock_irq(&hw->lock);

	memcpy(ln->mac, rsp->vnport_mac, sizeof(ln->mac));
	memcpy(&nport_id, &rsp->vnport_mac[3], sizeof(uint8_t)*3);
	ln->nport_id = ntohl(nport_id);
	ln->nport_id = ln->nport_id >> 8;

	/* Update WWNs */
	/*
	 * This may look like a duplication of what csio_fcoe_enable_link()
	 * does, but is absolutely necessary if the vnpi changes between
	 * a FCOE LINK UP and FCOE LINK DOWN.
	 */
	memcpy(csio_ln_wwnn(ln), rsp->vnport_wwnn, 8);
	memcpy(csio_ln_wwpn(ln), rsp->vnport_wwpn, 8);

	/* Copy common sparam */
	csp = (struct fc_els_csp *)rsp->cmn_srv_parms;
	ln->ln_sparm.csp.sp_hi_ver = csp->sp_hi_ver;
	ln->ln_sparm.csp.sp_lo_ver = csp->sp_lo_ver;
	ln->ln_sparm.csp.sp_bb_cred = csp->sp_bb_cred;
	ln->ln_sparm.csp.sp_features = csp->sp_features;
	ln->ln_sparm.csp.sp_bb_data = csp->sp_bb_data;
	ln->ln_sparm.csp.sp_r_a_tov = csp->sp_r_a_tov;
	ln->ln_sparm.csp.sp_e_d_tov = csp->sp_e_d_tov;

	/* Copy word 0 & word 1 of class sparam */
	clsp = (struct fc_els_cssp *)rsp->clsp_word_0_1;
	ln->ln_sparm.clsp[2].cp_class = clsp->cp_class;
	ln->ln_sparm.clsp[2].cp_init = clsp->cp_init;
	ln->ln_sparm.clsp[2].cp_recip = clsp->cp_recip;
	ln->ln_sparm.clsp[2].cp_rdfs = clsp->cp_rdfs;

	spin_unlock_irq(&hw->lock);

	mempool_free(mbp, hw->mb_mempool);

	/* Send an event to update local attribs */
	csio_lnode_async_event(ln, CSIO_LN_FC_ATTRIB_UPDATE);
}

/*
 * csio_ln_vnp_read - Read vnp params.
 * @ln: lnode
 * @cbfn: Completion handler.
 *
 * Issued with lock held.
 */
static int
csio_ln_vnp_read(struct csio_lnode *ln,
		void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct csio_hw *hw = ln->hwp;
	struct csio_mb  *mbp;

	/* Allocate Mbox request */
	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp) {
		CSIO_INC_STATS(hw, n_err_nomem);
		return -ENOMEM;
	}

	/* Prepare VNP Command */
	csio_fcoe_vnp_read_init_mb(ln, mbp,
				    CSIO_MB_DEFAULT_TMO,
				    ln->fcf_flowid,
				    ln->vnp_flowid,
				    cbfn);

	/* Issue MBOX cmd */
	if (csio_mb_issue(hw, mbp)) {
		csio_err(hw, "Failed to issue mbox FCoE VNP command\n");
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	return 0;
}

/*
 * csio_fcoe_enable_link - Enable fcoe link.
 * @ln: lnode
 * @enable: enable/disable
 * Issued with lock held.
 * Issues mbox cmd to bring up FCOE link on port associated with given ln.
 */
static int
csio_fcoe_enable_link(struct csio_lnode *ln, bool enable)
{
	struct csio_hw *hw = ln->hwp;
	struct csio_mb  *mbp;
	enum fw_retval retval;
	uint8_t portid;
	uint8_t sub_op;
	struct fw_fcoe_link_cmd *lcmd;
	int i;

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp) {
		CSIO_INC_STATS(hw, n_err_nomem);
		return -ENOMEM;
	}

	portid = ln->portid;
	sub_op = enable ? FCOE_LINK_UP : FCOE_LINK_DOWN;

	csio_dbg(hw, "bringing FCOE LINK %s on Port:%d\n",
		 sub_op ? "UP" : "DOWN", portid);

	csio_write_fcoe_link_cond_init_mb(ln, mbp, CSIO_MB_DEFAULT_TMO,
					  portid, sub_op, 0, 0, 0, NULL);

	if (csio_mb_issue(hw, mbp)) {
		csio_err(hw, "failed to issue FCOE LINK cmd on port[%d]\n",
			portid);
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	retval = csio_mb_fw_retval(mbp);
	if (retval != FW_SUCCESS) {
		csio_err(hw,
			 "FCOE LINK %s cmd on port[%d] failed with "
			 "ret:x%x\n", sub_op ? "UP" : "DOWN", portid, retval);
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	if (!enable)
		goto out;

	lcmd = (struct fw_fcoe_link_cmd *)mbp->mb;

	memcpy(csio_ln_wwnn(ln), lcmd->vnport_wwnn, 8);
	memcpy(csio_ln_wwpn(ln), lcmd->vnport_wwpn, 8);

	for (i = 0; i < CSIO_MAX_PPORTS; i++)
		if (hw->pport[i].portid == portid)
			memcpy(hw->pport[i].mac, lcmd->phy_mac, 6);

out:
	mempool_free(mbp, hw->mb_mempool);
	return 0;
}

/*
 * csio_ln_read_fcf_cbfn - Read fcf parameters
 * @ln: lnode
 *
 * read fcf response and Update ln fcf information.
 */
static void
csio_ln_read_fcf_cbfn(struct csio_hw *hw, struct csio_mb *mbp)
{
	struct csio_lnode *ln = (struct csio_lnode *)mbp->priv;
	struct csio_fcf_info	*fcf_info;
	struct fw_fcoe_fcf_cmd *rsp =
				(struct fw_fcoe_fcf_cmd *)(mbp->mb);
	enum fw_retval retval;

	retval = FW_CMD_RETVAL_G(ntohl(rsp->retval_len16));
	if (retval != FW_SUCCESS) {
		csio_ln_err(ln, "FCOE FCF cmd failed with ret x%x\n",
				retval);
		mempool_free(mbp, hw->mb_mempool);
		return;
	}

	spin_lock_irq(&hw->lock);
	fcf_info = ln->fcfinfo;
	fcf_info->priority = FW_FCOE_FCF_CMD_PRIORITY_GET(
					ntohs(rsp->priority_pkd));
	fcf_info->vf_id = ntohs(rsp->vf_id);
	fcf_info->vlan_id = rsp->vlan_id;
	fcf_info->max_fcoe_size = ntohs(rsp->max_fcoe_size);
	fcf_info->fka_adv = be32_to_cpu(rsp->fka_adv);
	fcf_info->fcfi = FW_FCOE_FCF_CMD_FCFI_GET(ntohl(rsp->op_to_fcfi));
	fcf_info->fpma = FW_FCOE_FCF_CMD_FPMA_GET(rsp->fpma_to_portid);
	fcf_info->spma = FW_FCOE_FCF_CMD_SPMA_GET(rsp->fpma_to_portid);
	fcf_info->login = FW_FCOE_FCF_CMD_LOGIN_GET(rsp->fpma_to_portid);
	fcf_info->portid = FW_FCOE_FCF_CMD_PORTID_GET(rsp->fpma_to_portid);
	memcpy(fcf_info->fc_map, rsp->fc_map, sizeof(fcf_info->fc_map));
	memcpy(fcf_info->mac, rsp->mac, sizeof(fcf_info->mac));
	memcpy(fcf_info->name_id, rsp->name_id, sizeof(fcf_info->name_id));
	memcpy(fcf_info->fabric, rsp->fabric, sizeof(fcf_info->fabric));
	memcpy(fcf_info->spma_mac, rsp->spma_mac, sizeof(fcf_info->spma_mac));

	spin_unlock_irq(&hw->lock);

	mempool_free(mbp, hw->mb_mempool);
}

/*
 * csio_ln_read_fcf_entry - Read fcf entry.
 * @ln: lnode
 * @cbfn: Completion handler.
 *
 * Issued with lock held.
 */
static int
csio_ln_read_fcf_entry(struct csio_lnode *ln,
			void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct csio_hw *hw = ln->hwp;
	struct csio_mb  *mbp;

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp) {
		CSIO_INC_STATS(hw, n_err_nomem);
		return -ENOMEM;
	}

	/* Get FCoE FCF information */
	csio_fcoe_read_fcf_init_mb(ln, mbp, CSIO_MB_DEFAULT_TMO,
				      ln->portid, ln->fcf_flowid, cbfn);

	if (csio_mb_issue(hw, mbp)) {
		csio_err(hw, "failed to issue FCOE FCF cmd\n");
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	return 0;
}

/*
 * csio_handle_link_up - Logical Linkup event.
 * @hw - HW module.
 * @portid - Physical port number
 * @fcfi - FCF index.
 * @vnpi - VNP index.
 * Returns - none.
 *
 * This event is received from FW, when virtual link is established between
 * Physical port[ENode] and FCF. If its new vnpi, then local node object is
 * created on this FCF and set to [ONLINE] state.
 * Lnode waits for FW_RDEV_CMD event to be received indicating that
 * Fabric login is completed and lnode moves to [READY] state.
 *
 * This called with hw lock held
 */
static void
csio_handle_link_up(struct csio_hw *hw, uint8_t portid, uint32_t fcfi,
		    uint32_t vnpi)
{
	struct csio_lnode *ln = NULL;

	/* Lookup lnode based on vnpi */
	ln = csio_ln_lookup_by_vnpi(hw, vnpi);
	if (!ln) {
		/* Pick lnode based on portid */
		ln = csio_ln_lookup_by_portid(hw, portid);
		if (!ln) {
			csio_err(hw, "failed to lookup fcoe lnode on port:%d\n",
				portid);
			CSIO_DB_ASSERT(0);
			return;
		}

		/* Check if lnode has valid vnp flowid */
		if (ln->vnp_flowid != CSIO_INVALID_IDX) {
			/* New VN-Port */
			spin_unlock_irq(&hw->lock);
			csio_lnode_alloc(hw);
			spin_lock_irq(&hw->lock);
			if (!ln) {
				csio_err(hw,
					 "failed to allocate fcoe lnode"
					 "for port:%d vnpi:x%x\n",
					 portid, vnpi);
				CSIO_DB_ASSERT(0);
				return;
			}
			ln->portid = portid;
		}
		ln->vnp_flowid = vnpi;
		ln->dev_num &= ~0xFFFF;
		ln->dev_num |= vnpi;
	}

	/*Initialize fcfi */
	ln->fcf_flowid = fcfi;

	csio_info(hw, "Port:%d - FCOE LINK UP\n", portid);

	CSIO_INC_STATS(ln, n_link_up);

	/* Send LINKUP event to SM */
	csio_post_event(&ln->sm, CSIO_LNE_LINKUP);
}

/*
 * csio_post_event_rns
 * @ln - FCOE lnode
 * @evt - Given rnode event
 * Returns - none
 *
 * Posts given rnode event to all FCOE rnodes connected with given Lnode.
 * This routine is invoked when lnode receives LINK_DOWN/DOWN_LINK/CLOSE
 * event.
 *
 * This called with hw lock held
 */
static void
csio_post_event_rns(struct csio_lnode *ln, enum csio_rn_ev evt)
{
	struct csio_rnode *rnhead = (struct csio_rnode *) &ln->rnhead;
	struct list_head *tmp, *next;
	struct csio_rnode *rn;

	list_for_each_safe(tmp, next, &rnhead->sm.sm_list) {
		rn = (struct csio_rnode *) tmp;
		csio_post_event(&rn->sm, evt);
	}
}

/*
 * csio_cleanup_rns
 * @ln - FCOE lnode
 * Returns - none
 *
 * Frees all FCOE rnodes connected with given Lnode.
 *
 * This called with hw lock held
 */
static void
csio_cleanup_rns(struct csio_lnode *ln)
{
	struct csio_rnode *rnhead = (struct csio_rnode *) &ln->rnhead;
	struct list_head *tmp, *next_rn;
	struct csio_rnode *rn;

	list_for_each_safe(tmp, next_rn, &rnhead->sm.sm_list) {
		rn = (struct csio_rnode *) tmp;
		csio_put_rnode(ln, rn);
	}

}

/*
 * csio_post_event_lns
 * @ln - FCOE lnode
 * @evt - Given lnode event
 * Returns - none
 *
 * Posts given lnode event to all FCOE lnodes connected with given Lnode.
 * This routine is invoked when lnode receives LINK_DOWN/DOWN_LINK/CLOSE
 * event.
 *
 * This called with hw lock held
 */
static void
csio_post_event_lns(struct csio_lnode *ln, enum csio_ln_ev evt)
{
	struct list_head *tmp;
	struct csio_lnode *cln, *sln;

	/* If NPIV lnode, send evt only to that and return */
	if (csio_is_npiv_ln(ln)) {
		csio_post_event(&ln->sm, evt);
		return;
	}

	sln = ln;
	/* Traverse children lnodes list and send evt */
	list_for_each(tmp, &sln->cln_head) {
		cln = (struct csio_lnode *) tmp;
		csio_post_event(&cln->sm, evt);
	}

	/* Send evt to parent lnode */
	csio_post_event(&ln->sm, evt);
}

/*
 * csio_ln_down - Lcoal nport is down
 * @ln - FCOE Lnode
 * Returns - none
 *
 * Sends LINK_DOWN events to Lnode and its associated NPIVs lnodes.
 *
 * This called with hw lock held
 */
static void
csio_ln_down(struct csio_lnode *ln)
{
	csio_post_event_lns(ln, CSIO_LNE_LINK_DOWN);
}

/*
 * csio_handle_link_down - Logical Linkdown event.
 * @hw - HW module.
 * @portid - Physical port number
 * @fcfi - FCF index.
 * @vnpi - VNP index.
 * Returns - none
 *
 * This event is received from FW, when virtual link goes down between
 * Physical port[ENode] and FCF. Lnode and its associated NPIVs lnode hosted on
 * this vnpi[VN-Port] will be de-instantiated.
 *
 * This called with hw lock held
 */
static void
csio_handle_link_down(struct csio_hw *hw, uint8_t portid, uint32_t fcfi,
		      uint32_t vnpi)
{
	struct csio_fcf_info *fp;
	struct csio_lnode *ln;

	/* Lookup lnode based on vnpi */
	ln = csio_ln_lookup_by_vnpi(hw, vnpi);
	if (ln) {
		fp = ln->fcfinfo;
		CSIO_INC_STATS(ln, n_link_down);

		/*Warn if linkdown received if lnode is not in ready state */
		if (!csio_is_lnode_ready(ln)) {
			csio_ln_warn(ln,
				"warn: FCOE link is already in offline "
				"Ignoring Fcoe linkdown event on portid %d\n",
				 portid);
			CSIO_INC_STATS(ln, n_evt_drop);
			return;
		}

		/* Verify portid */
		if (fp->portid != portid) {
			csio_ln_warn(ln,
				"warn: FCOE linkdown recv with "
				"invalid port %d\n", portid);
			CSIO_INC_STATS(ln, n_evt_drop);
			return;
		}

		/* verify fcfi */
		if (ln->fcf_flowid != fcfi) {
			csio_ln_warn(ln,
				"warn: FCOE linkdown recv with "
				"invalid fcfi x%x\n", fcfi);
			CSIO_INC_STATS(ln, n_evt_drop);
			return;
		}

		csio_info(hw, "Port:%d - FCOE LINK DOWN\n", portid);

		/* Send LINK_DOWN event to lnode s/m */
		csio_ln_down(ln);

		return;
	} else {
		csio_warn(hw,
			  "warn: FCOE linkdown recv with invalid vnpi x%x\n",
			  vnpi);
		CSIO_INC_STATS(hw, n_evt_drop);
	}
}

/*
 * csio_is_lnode_ready - Checks FCOE lnode is in ready state.
 * @ln: Lnode module
 *
 * Returns True if FCOE lnode is in ready state.
 */
int
csio_is_lnode_ready(struct csio_lnode *ln)
{
	return (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready));
}

/*****************************************************************************/
/* START: Lnode SM                                                           */
/*****************************************************************************/
/*
 * csio_lns_uninit - The request in uninit state.
 * @ln - FCOE lnode.
 * @evt - Event to be processed.
 *
 * Process the given lnode event which is currently in "uninit" state.
 * Invoked with HW lock held.
 * Return - none.
 */
static void
csio_lns_uninit(struct csio_lnode *ln, enum csio_ln_ev evt)
{
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	struct csio_lnode *rln = hw->rln;
	int rv;

	CSIO_INC_STATS(ln, n_evt_sm[evt]);
	switch (evt) {
	case CSIO_LNE_LINKUP:
		csio_set_state(&ln->sm, csio_lns_online);
		/* Read FCF only for physical lnode */
		if (csio_is_phys_ln(ln)) {
			rv = csio_ln_read_fcf_entry(ln,
					csio_ln_read_fcf_cbfn);
			if (rv != 0) {
				/* TODO: Send HW RESET event */
				CSIO_INC_STATS(ln, n_err);
				break;
			}

			/* Add FCF record */
			list_add_tail(&ln->fcfinfo->list, &rln->fcf_lsthead);
		}

		rv = csio_ln_vnp_read(ln, csio_ln_vnp_read_cbfn);
		if (rv != 0) {
			/* TODO: Send HW RESET event */
			CSIO_INC_STATS(ln, n_err);
		}
		break;

	case CSIO_LNE_DOWN_LINK:
		break;

	default:
		csio_ln_dbg(ln,
			    "unexp ln event %d recv from did:x%x in "
			    "ln state[uninit].\n", evt, ln->nport_id);
		CSIO_INC_STATS(ln, n_evt_unexp);
		break;
	} /* switch event */
}

/*
 * csio_lns_online - The request in online state.
 * @ln - FCOE lnode.
 * @evt - Event to be processed.
 *
 * Process the given lnode event which is currently in "online" state.
 * Invoked with HW lock held.
 * Return - none.
 */
static void
csio_lns_online(struct csio_lnode *ln, enum csio_ln_ev evt)
{
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	CSIO_INC_STATS(ln, n_evt_sm[evt]);
	switch (evt) {
	case CSIO_LNE_LINKUP:
		csio_ln_warn(ln,
			     "warn: FCOE link is up already "
			     "Ignoring linkup on port:%d\n", ln->portid);
		CSIO_INC_STATS(ln, n_evt_drop);
		break;

	case CSIO_LNE_FAB_INIT_DONE:
		csio_set_state(&ln->sm, csio_lns_ready);

		spin_unlock_irq(&hw->lock);
		csio_lnode_async_event(ln, CSIO_LN_FC_LINKUP);
		spin_lock_irq(&hw->lock);

		break;

	case CSIO_LNE_LINK_DOWN:
		/* Fall through */
	case CSIO_LNE_DOWN_LINK:
		csio_set_state(&ln->sm, csio_lns_uninit);
		if (csio_is_phys_ln(ln)) {
			/* Remove FCF entry */
			list_del_init(&ln->fcfinfo->list);
		}
		break;

	default:
		csio_ln_dbg(ln,
			    "unexp ln event %d recv from did:x%x in "
			    "ln state[uninit].\n", evt, ln->nport_id);
		CSIO_INC_STATS(ln, n_evt_unexp);

		break;
	} /* switch event */
}

/*
 * csio_lns_ready - The request in ready state.
 * @ln - FCOE lnode.
 * @evt - Event to be processed.
 *
 * Process the given lnode event which is currently in "ready" state.
 * Invoked with HW lock held.
 * Return - none.
 */
static void
csio_lns_ready(struct csio_lnode *ln, enum csio_ln_ev evt)
{
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	CSIO_INC_STATS(ln, n_evt_sm[evt]);
	switch (evt) {
	case CSIO_LNE_FAB_INIT_DONE:
		csio_ln_dbg(ln,
			    "ignoring event %d recv from did x%x"
			    "in ln state[ready].\n", evt, ln->nport_id);
		CSIO_INC_STATS(ln, n_evt_drop);
		break;

	case CSIO_LNE_LINK_DOWN:
		csio_set_state(&ln->sm, csio_lns_offline);
		csio_post_event_rns(ln, CSIO_RNFE_DOWN);

		spin_unlock_irq(&hw->lock);
		csio_lnode_async_event(ln, CSIO_LN_FC_LINKDOWN);
		spin_lock_irq(&hw->lock);

		if (csio_is_phys_ln(ln)) {
			/* Remove FCF entry */
			list_del_init(&ln->fcfinfo->list);
		}
		break;

	case CSIO_LNE_DOWN_LINK:
		csio_set_state(&ln->sm, csio_lns_offline);
		csio_post_event_rns(ln, CSIO_RNFE_DOWN);

		/* Host need to issue aborts in case if FW has not returned
		 * WRs with status "ABORTED"
		 */
		spin_unlock_irq(&hw->lock);
		csio_lnode_async_event(ln, CSIO_LN_FC_LINKDOWN);
		spin_lock_irq(&hw->lock);

		if (csio_is_phys_ln(ln)) {
			/* Remove FCF entry */
			list_del_init(&ln->fcfinfo->list);
		}
		break;

	case CSIO_LNE_CLOSE:
		csio_set_state(&ln->sm, csio_lns_uninit);
		csio_post_event_rns(ln, CSIO_RNFE_CLOSE);
		break;

	case CSIO_LNE_LOGO:
		csio_set_state(&ln->sm, csio_lns_offline);
		csio_post_event_rns(ln, CSIO_RNFE_DOWN);
		break;

	default:
		csio_ln_dbg(ln,
			    "unexp ln event %d recv from did:x%x in "
			    "ln state[uninit].\n", evt, ln->nport_id);
		CSIO_INC_STATS(ln, n_evt_unexp);
		CSIO_DB_ASSERT(0);
		break;
	} /* switch event */
}

/*
 * csio_lns_offline - The request in offline state.
 * @ln - FCOE lnode.
 * @evt - Event to be processed.
 *
 * Process the given lnode event which is currently in "offline" state.
 * Invoked with HW lock held.
 * Return - none.
 */
static void
csio_lns_offline(struct csio_lnode *ln, enum csio_ln_ev evt)
{
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	struct csio_lnode *rln = hw->rln;
	int rv;

	CSIO_INC_STATS(ln, n_evt_sm[evt]);
	switch (evt) {
	case CSIO_LNE_LINKUP:
		csio_set_state(&ln->sm, csio_lns_online);
		/* Read FCF only for physical lnode */
		if (csio_is_phys_ln(ln)) {
			rv = csio_ln_read_fcf_entry(ln,
					csio_ln_read_fcf_cbfn);
			if (rv != 0) {
				/* TODO: Send HW RESET event */
				CSIO_INC_STATS(ln, n_err);
				break;
			}

			/* Add FCF record */
			list_add_tail(&ln->fcfinfo->list, &rln->fcf_lsthead);
		}

		rv = csio_ln_vnp_read(ln, csio_ln_vnp_read_cbfn);
		if (rv != 0) {
			/* TODO: Send HW RESET event */
			CSIO_INC_STATS(ln, n_err);
		}
		break;

	case CSIO_LNE_LINK_DOWN:
	case CSIO_LNE_DOWN_LINK:
	case CSIO_LNE_LOGO:
		csio_ln_dbg(ln,
			    "ignoring event %d recv from did x%x"
			    "in ln state[offline].\n", evt, ln->nport_id);
		CSIO_INC_STATS(ln, n_evt_drop);
		break;

	case CSIO_LNE_CLOSE:
		csio_set_state(&ln->sm, csio_lns_uninit);
		csio_post_event_rns(ln, CSIO_RNFE_CLOSE);
		break;

	default:
		csio_ln_dbg(ln,
			    "unexp ln event %d recv from did:x%x in "
			    "ln state[offline]\n", evt, ln->nport_id);
		CSIO_INC_STATS(ln, n_evt_unexp);
		CSIO_DB_ASSERT(0);
		break;
	} /* switch event */
}

/*****************************************************************************/
/* END: Lnode SM                                                             */
/*****************************************************************************/

static void
csio_free_fcfinfo(struct kref *kref)
{
	struct csio_fcf_info *fcfinfo = container_of(kref,
						struct csio_fcf_info, kref);
	kfree(fcfinfo);
}

/* Helper routines for attributes  */
/*
 * csio_lnode_state_to_str - Get current state of FCOE lnode.
 * @ln - lnode
 * @str - state of lnode.
 *
 */
void
csio_lnode_state_to_str(struct csio_lnode *ln, int8_t *str)
{
	if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_uninit)) {
		strcpy(str, "UNINIT");
		return;
	}
	if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)) {
		strcpy(str, "READY");
		return;
	}
	if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_offline)) {
		strcpy(str, "OFFLINE");
		return;
	}
	strcpy(str, "UNKNOWN");
} /* csio_lnode_state_to_str */


int
csio_get_phy_port_stats(struct csio_hw *hw, uint8_t portid,
			struct fw_fcoe_port_stats *port_stats)
{
	struct csio_mb  *mbp;
	struct fw_fcoe_port_cmd_params portparams;
	enum fw_retval retval;
	int idx;

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp) {
		csio_err(hw, "FCoE FCF PARAMS command out of memory!\n");
		return -EINVAL;
	}
	portparams.portid = portid;

	for (idx = 1; idx <= 3; idx++) {
		portparams.idx = (idx-1)*6 + 1;
		portparams.nstats = 6;
		if (idx == 3)
			portparams.nstats = 4;
		csio_fcoe_read_portparams_init_mb(hw, mbp, CSIO_MB_DEFAULT_TMO,
							&portparams, NULL);
		if (csio_mb_issue(hw, mbp)) {
			csio_err(hw, "Issue of FCoE port params failed!\n");
			mempool_free(mbp, hw->mb_mempool);
			return -EINVAL;
		}
		csio_mb_process_portparams_rsp(hw, mbp, &retval,
						&portparams, port_stats);
	}

	mempool_free(mbp, hw->mb_mempool);
	return 0;
}

/*
 * csio_ln_mgmt_wr_handler -Mgmt Work Request handler.
 * @wr - WR.
 * @len - WR len.
 * This handler is invoked when an outstanding mgmt WR is completed.
 * Its invoked in the context of FW event worker thread for every
 * mgmt event received.
 * Return - none.
 */

static void
csio_ln_mgmt_wr_handler(struct csio_hw *hw, void *wr, uint32_t len)
{
	struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);
	struct csio_ioreq *io_req = NULL;
	struct fw_fcoe_els_ct_wr *wr_cmd;


	wr_cmd = (struct fw_fcoe_els_ct_wr *) wr;

	if (len < sizeof(struct fw_fcoe_els_ct_wr)) {
		csio_err(mgmtm->hw,
			 "Invalid ELS CT WR length recvd, len:%x\n", len);
		mgmtm->stats.n_err++;
		return;
	}

	io_req = (struct csio_ioreq *) ((uintptr_t) wr_cmd->cookie);
	io_req->wr_status = csio_wr_status(wr_cmd);

	/* lookup ioreq exists in our active Q */
	spin_lock_irq(&hw->lock);
	if (csio_mgmt_req_lookup(mgmtm, io_req) != 0) {
		csio_err(mgmtm->hw,
			"Error- Invalid IO handle recv in WR. handle: %p\n",
			io_req);
		mgmtm->stats.n_err++;
		spin_unlock_irq(&hw->lock);
		return;
	}

	mgmtm = csio_hw_to_mgmtm(hw);

	/* Dequeue from active queue */
	list_del_init(&io_req->sm.sm_list);
	mgmtm->stats.n_active--;
	spin_unlock_irq(&hw->lock);

	/* io_req will be freed by completion handler */
	if (io_req->io_cbfn)
		io_req->io_cbfn(hw, io_req);
}

/**
 * csio_fcoe_fwevt_handler - Event handler for Firmware FCoE events.
 * @hw:		HW module
 * @cpl_op:	CPL opcode
 * @cmd:	FW cmd/WR.
 *
 * Process received FCoE cmd/WR event from FW.
 */
void
csio_fcoe_fwevt_handler(struct csio_hw *hw, __u8 cpl_op, __be64 *cmd)
{
	struct csio_lnode *ln;
	struct csio_rnode *rn;
	uint8_t portid, opcode = *(uint8_t *)cmd;
	struct fw_fcoe_link_cmd *lcmd;
	struct fw_wr_hdr *wr;
	struct fw_rdev_wr *rdev_wr;
	enum fw_fcoe_link_status lstatus;
	uint32_t fcfi, rdev_flowid, vnpi;
	enum csio_ln_ev evt;

	if (cpl_op == CPL_FW6_MSG && opcode == FW_FCOE_LINK_CMD) {

		lcmd = (struct fw_fcoe_link_cmd *)cmd;
		lstatus = lcmd->lstatus;
		portid = FW_FCOE_LINK_CMD_PORTID_GET(
					ntohl(lcmd->op_to_portid));
		fcfi = FW_FCOE_LINK_CMD_FCFI_GET(ntohl(lcmd->sub_opcode_fcfi));
		vnpi = FW_FCOE_LINK_CMD_VNPI_GET(ntohl(lcmd->vnpi_pkd));

		if (lstatus == FCOE_LINKUP) {

			/* HW lock here */
			spin_lock_irq(&hw->lock);
			csio_handle_link_up(hw, portid, fcfi, vnpi);
			spin_unlock_irq(&hw->lock);
			/* HW un lock here */

		} else if (lstatus == FCOE_LINKDOWN) {

			/* HW lock here */
			spin_lock_irq(&hw->lock);
			csio_handle_link_down(hw, portid, fcfi, vnpi);
			spin_unlock_irq(&hw->lock);
			/* HW un lock here */
		} else {
			csio_warn(hw, "Unexpected FCOE LINK status:0x%x\n",
				  lcmd->lstatus);
			CSIO_INC_STATS(hw, n_cpl_unexp);
		}
	} else if (cpl_op == CPL_FW6_PLD) {
		wr = (struct fw_wr_hdr *) (cmd + 4);
		if (FW_WR_OP_G(be32_to_cpu(wr->hi))
			== FW_RDEV_WR) {

			rdev_wr = (struct fw_rdev_wr *) (cmd + 4);

			rdev_flowid = FW_RDEV_WR_FLOWID_GET(
					ntohl(rdev_wr->alloc_to_len16));
			vnpi = FW_RDEV_WR_ASSOC_FLOWID_GET(
				    ntohl(rdev_wr->flags_to_assoc_flowid));

			csio_dbg(hw,
				"FW_RDEV_WR: flowid:x%x ev_cause:x%x "
				"vnpi:0x%x\n", rdev_flowid,
				rdev_wr->event_cause, vnpi);

			if (rdev_wr->protocol != PROT_FCOE) {
				csio_err(hw,
					"FW_RDEV_WR: invalid proto:x%x "
					"received with flowid:x%x\n",
					rdev_wr->protocol,
					rdev_flowid);
				CSIO_INC_STATS(hw, n_evt_drop);
				return;
			}

			/* HW lock here */
			spin_lock_irq(&hw->lock);
			ln = csio_ln_lookup_by_vnpi(hw, vnpi);
			if (!ln) {
				csio_err(hw,
					"FW_DEV_WR: invalid vnpi:x%x received "
					"with flowid:x%x\n", vnpi, rdev_flowid);
				CSIO_INC_STATS(hw, n_evt_drop);
				goto out_pld;
			}

			rn = csio_confirm_rnode(ln, rdev_flowid,
					&rdev_wr->u.fcoe_rdev);
			if (!rn) {
				csio_ln_dbg(ln,
					"Failed to confirm rnode "
					"for flowid:x%x\n", rdev_flowid);
				CSIO_INC_STATS(hw, n_evt_drop);
				goto out_pld;
			}

			/* save previous event for debugging */
			ln->prev_evt = ln->cur_evt;
			ln->cur_evt = rdev_wr->event_cause;
			CSIO_INC_STATS(ln, n_evt_fw[rdev_wr->event_cause]);

			/* Translate all the fabric events to lnode SM events */
			evt = CSIO_FWE_TO_LNE(rdev_wr->event_cause);
			if (evt) {
				csio_ln_dbg(ln,
					"Posting event to lnode event:%d "
					"cause:%d flowid:x%x\n", evt,
					rdev_wr->event_cause, rdev_flowid);
				csio_post_event(&ln->sm, evt);
			}

			/* Handover event to rn SM here. */
			csio_rnode_fwevt_handler(rn, rdev_wr->event_cause);
out_pld:
			spin_unlock_irq(&hw->lock);
			return;
		} else {
			csio_warn(hw, "unexpected WR op(0x%x) recv\n",
				  FW_WR_OP_G(be32_to_cpu((wr->hi))));
			CSIO_INC_STATS(hw, n_cpl_unexp);
		}
	} else if (cpl_op == CPL_FW6_MSG) {
		wr = (struct fw_wr_hdr *) (cmd);
		if (FW_WR_OP_G(be32_to_cpu(wr->hi)) == FW_FCOE_ELS_CT_WR) {
			csio_ln_mgmt_wr_handler(hw, wr,
					sizeof(struct fw_fcoe_els_ct_wr));
		} else {
			csio_warn(hw, "unexpected WR op(0x%x) recv\n",
				  FW_WR_OP_G(be32_to_cpu((wr->hi))));
			CSIO_INC_STATS(hw, n_cpl_unexp);
		}
	} else {
		csio_warn(hw, "unexpected CPL op(0x%x) recv\n", opcode);
		CSIO_INC_STATS(hw, n_cpl_unexp);
	}
}

/**
 * csio_lnode_start - Kickstart lnode discovery.
 * @ln:		lnode
 *
 * This routine kickstarts the discovery by issuing an FCOE_LINK (up) command.
 */
int
csio_lnode_start(struct csio_lnode *ln)
{
	int rv = 0;
	if (csio_is_phys_ln(ln) && !(ln->flags & CSIO_LNF_LINK_ENABLE)) {
		rv = csio_fcoe_enable_link(ln, 1);
		ln->flags |= CSIO_LNF_LINK_ENABLE;
	}

	return rv;
}

/**
 * csio_lnode_stop - Stop the lnode.
 * @ln:		lnode
 *
 * This routine is invoked by HW module to stop lnode and its associated NPIV
 * lnodes.
 */
void
csio_lnode_stop(struct csio_lnode *ln)
{
	csio_post_event_lns(ln, CSIO_LNE_DOWN_LINK);
	if (csio_is_phys_ln(ln) && (ln->flags & CSIO_LNF_LINK_ENABLE)) {
		csio_fcoe_enable_link(ln, 0);
		ln->flags &= ~CSIO_LNF_LINK_ENABLE;
	}
	csio_ln_dbg(ln, "stopping ln :%p\n", ln);
}

/**
 * csio_lnode_close - Close an lnode.
 * @ln:		lnode
 *
 * This routine is invoked by HW module to close an lnode and its
 * associated NPIV lnodes. Lnode and its associated NPIV lnodes are
 * set to uninitialized state.
 */
void
csio_lnode_close(struct csio_lnode *ln)
{
	csio_post_event_lns(ln, CSIO_LNE_CLOSE);
	if (csio_is_phys_ln(ln))
		ln->vnp_flowid = CSIO_INVALID_IDX;

	csio_ln_dbg(ln, "closed ln :%p\n", ln);
}

/*
 * csio_ln_prep_ecwr - Prepare ELS/CT WR.
 * @io_req - IO request.
 * @wr_len - WR len
 * @immd_len - WR immediate data
 * @sub_op - Sub opcode
 * @sid - source portid.
 * @did - destination portid
 * @flow_id - flowid
 * @fw_wr - ELS/CT WR to be prepared.
 * Returns: 0 - on success
 */
static int
csio_ln_prep_ecwr(struct csio_ioreq *io_req, uint32_t wr_len,
		      uint32_t immd_len, uint8_t sub_op, uint32_t sid,
		      uint32_t did, uint32_t flow_id, uint8_t *fw_wr)
{
	struct fw_fcoe_els_ct_wr *wr;
	__be32 port_id;

	wr  = (struct fw_fcoe_els_ct_wr *)fw_wr;
	wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_FCOE_ELS_CT_WR) |
				     FW_FCOE_ELS_CT_WR_IMMDLEN(immd_len));

	wr_len =  DIV_ROUND_UP(wr_len, 16);
	wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(flow_id) |
				       FW_WR_LEN16_V(wr_len));
	wr->els_ct_type = sub_op;
	wr->ctl_pri = 0;
	wr->cp_en_class = 0;
	wr->cookie = io_req->fw_handle;
	wr->iqid = cpu_to_be16(csio_q_physiqid(
					io_req->lnode->hwp, io_req->iq_idx));
	wr->fl_to_sp =  FW_FCOE_ELS_CT_WR_SP(1);
	wr->tmo_val = (uint8_t) io_req->tmo;
	port_id = htonl(sid);
	memcpy(wr->l_id, PORT_ID_PTR(port_id), 3);
	port_id = htonl(did);
	memcpy(wr->r_id, PORT_ID_PTR(port_id), 3);

	/* Prepare RSP SGL */
	wr->rsp_dmalen = cpu_to_be32(io_req->dma_buf.len);
	wr->rsp_dmaaddr = cpu_to_be64(io_req->dma_buf.paddr);
	return 0;
}

/*
 * csio_ln_mgmt_submit_wr - Post elsct work request.
 * @mgmtm - mgmtm
 * @io_req - io request.
 * @sub_op - ELS or CT request type
 * @pld - Dma Payload buffer
 * @pld_len - Payload len
 * Prepares ELSCT Work request and sents it to FW.
 * Returns: 0 - on success
 */
static int
csio_ln_mgmt_submit_wr(struct csio_mgmtm *mgmtm, struct csio_ioreq *io_req,
		uint8_t sub_op, struct csio_dma_buf *pld,
		uint32_t pld_len)
{
	struct csio_wr_pair wrp;
	struct csio_lnode *ln = io_req->lnode;
	struct csio_rnode *rn = io_req->rnode;
	struct	csio_hw	*hw = mgmtm->hw;
	uint8_t fw_wr[64];
	struct ulptx_sgl dsgl;
	uint32_t wr_size = 0;
	uint8_t im_len = 0;
	uint32_t wr_off = 0;

	int ret = 0;

	/* Calculate WR Size for this ELS REQ */
	wr_size = sizeof(struct fw_fcoe_els_ct_wr);

	/* Send as immediate data if pld < 256 */
	if (pld_len < 256) {
		wr_size += ALIGN(pld_len, 8);
		im_len = (uint8_t)pld_len;
	} else
		wr_size += sizeof(struct ulptx_sgl);

	/* Roundup WR size in units of 16 bytes */
	wr_size = ALIGN(wr_size, 16);

	/* Get WR to send ELS REQ */
	ret = csio_wr_get(hw, mgmtm->eq_idx, wr_size, &wrp);
	if (ret != 0) {
		csio_err(hw, "Failed to get WR for ec_req %p ret:%d\n",
			io_req, ret);
		return ret;
	}

	/* Prepare Generic WR used by all ELS/CT cmd */
	csio_ln_prep_ecwr(io_req, wr_size, im_len, sub_op,
				ln->nport_id, rn->nport_id,
				csio_rn_flowid(rn),
				&fw_wr[0]);

	/* Copy ELS/CT WR CMD */
	csio_wr_copy_to_wrp(&fw_wr[0], &wrp, wr_off,
			sizeof(struct fw_fcoe_els_ct_wr));
	wr_off += sizeof(struct fw_fcoe_els_ct_wr);

	/* Copy payload to Immediate section of WR */
	if (im_len)
		csio_wr_copy_to_wrp(pld->vaddr, &wrp, wr_off, im_len);
	else {
		/* Program DSGL to dma payload */
		dsgl.cmd_nsge = htonl(ULPTX_CMD_V(ULP_TX_SC_DSGL) |
					ULPTX_MORE_F | ULPTX_NSGE_V(1));
		dsgl.len0 = cpu_to_be32(pld_len);
		dsgl.addr0 = cpu_to_be64(pld->paddr);
		csio_wr_copy_to_wrp(&dsgl, &wrp, ALIGN(wr_off, 8),
				   sizeof(struct ulptx_sgl));
	}

	/* Issue work request to xmit ELS/CT req to FW */
	csio_wr_issue(mgmtm->hw, mgmtm->eq_idx, false);
	return ret;
}

/*
 * csio_ln_mgmt_submit_req - Submit FCOE Mgmt request.
 * @io_req - IO Request
 * @io_cbfn - Completion handler.
 * @req_type - ELS or CT request type
 * @pld - Dma Payload buffer
 * @pld_len - Payload len
 *
 *
 * This API used submit managment ELS/CT request.
 * This called with hw lock held
 * Returns: 0 - on success
 *	    -ENOMEM	- on error.
 */
static int
csio_ln_mgmt_submit_req(struct csio_ioreq *io_req,
		void (*io_cbfn) (struct csio_hw *, struct csio_ioreq *),
		enum fcoe_cmn_type req_type, struct csio_dma_buf *pld,
		uint32_t pld_len)
{
	struct csio_hw *hw = csio_lnode_to_hw(io_req->lnode);
	struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);
	int rv;

	io_req->io_cbfn = io_cbfn;	/* Upper layer callback handler */
	io_req->fw_handle = (uintptr_t) (io_req);
	io_req->eq_idx = mgmtm->eq_idx;
	io_req->iq_idx = mgmtm->iq_idx;

	rv = csio_ln_mgmt_submit_wr(mgmtm, io_req, req_type, pld, pld_len);
	if (rv == 0) {
		list_add_tail(&io_req->sm.sm_list, &mgmtm->active_q);
		mgmtm->stats.n_active++;
	}
	return rv;
}

/*
 * csio_ln_fdmi_init - FDMI Init entry point.
 * @ln: lnode
 */
static int
csio_ln_fdmi_init(struct csio_lnode *ln)
{
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	struct csio_dma_buf	*dma_buf;

	/* Allocate MGMT request required for FDMI */
	ln->mgmt_req = kzalloc(sizeof(struct csio_ioreq), GFP_KERNEL);
	if (!ln->mgmt_req) {
		csio_ln_err(ln, "Failed to alloc ioreq for FDMI\n");
		CSIO_INC_STATS(hw, n_err_nomem);
		return -ENOMEM;
	}

	/* Allocate Dma buffers for FDMI response Payload */
	dma_buf = &ln->mgmt_req->dma_buf;
	dma_buf->len = 2048;
	dma_buf->vaddr = pci_alloc_consistent(hw->pdev, dma_buf->len,
						&dma_buf->paddr);
	if (!dma_buf->vaddr) {
		csio_err(hw, "Failed to alloc DMA buffer for FDMI!\n");
		kfree(ln->mgmt_req);
		ln->mgmt_req = NULL;
		return -ENOMEM;
	}

	ln->flags |= CSIO_LNF_FDMI_ENABLE;
	return 0;
}

/*
 * csio_ln_fdmi_exit - FDMI exit entry point.
 * @ln: lnode
 */
static int
csio_ln_fdmi_exit(struct csio_lnode *ln)
{
	struct csio_dma_buf *dma_buf;
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	if (!ln->mgmt_req)
		return 0;

	dma_buf = &ln->mgmt_req->dma_buf;
	if (dma_buf->vaddr)
		pci_free_consistent(hw->pdev, dma_buf->len, dma_buf->vaddr,
				    dma_buf->paddr);

	kfree(ln->mgmt_req);
	return 0;
}

int
csio_scan_done(struct csio_lnode *ln, unsigned long ticks,
		unsigned long time, unsigned long max_scan_ticks,
		unsigned long delta_scan_ticks)
{
	int rv = 0;

	if (time >= max_scan_ticks)
		return 1;

	if (!ln->tgt_scan_tick)
		ln->tgt_scan_tick = ticks;

	if (((ticks - ln->tgt_scan_tick) >= delta_scan_ticks)) {
		if (!ln->last_scan_ntgts)
			ln->last_scan_ntgts = ln->n_scsi_tgts;
		else {
			if (ln->last_scan_ntgts == ln->n_scsi_tgts)
				return 1;

			ln->last_scan_ntgts = ln->n_scsi_tgts;
		}
		ln->tgt_scan_tick = ticks;
	}
	return rv;
}

/*
 * csio_notify_lnodes:
 * @hw: HW module
 * @note: Notification
 *
 * Called from the HW SM to fan out notifications to the
 * Lnode SM. Since the HW SM is entered with lock held,
 * there is no need to hold locks here.
 *
 */
void
csio_notify_lnodes(struct csio_hw *hw, enum csio_ln_notify note)
{
	struct list_head *tmp;
	struct csio_lnode *ln;

	csio_dbg(hw, "Notifying all nodes of event %d\n", note);

	/* Traverse children lnodes list and send evt */
	list_for_each(tmp, &hw->sln_head) {
		ln = (struct csio_lnode *) tmp;

		switch (note) {
		case CSIO_LN_NOTIFY_HWREADY:
			csio_lnode_start(ln);
			break;

		case CSIO_LN_NOTIFY_HWRESET:
		case CSIO_LN_NOTIFY_HWREMOVE:
			csio_lnode_close(ln);
			break;

		case CSIO_LN_NOTIFY_HWSTOP:
			csio_lnode_stop(ln);
			break;

		default:
			break;

		}
	}
}

/*
 * csio_disable_lnodes:
 * @hw: HW module
 * @portid:port id
 * @disable: disable/enable flag.
 * If disable=1, disables all lnode hosted on given physical port.
 * otherwise enables all the lnodes on given phsysical port.
 * This routine need to called with hw lock held.
 */
void
csio_disable_lnodes(struct csio_hw *hw, uint8_t portid, bool disable)
{
	struct list_head *tmp;
	struct csio_lnode *ln;

	csio_dbg(hw, "Notifying event to all nodes of port:%d\n", portid);

	/* Traverse sibling lnodes list and send evt */
	list_for_each(tmp, &hw->sln_head) {
		ln = (struct csio_lnode *) tmp;
		if (ln->portid != portid)
			continue;

		if (disable)
			csio_lnode_stop(ln);
		else
			csio_lnode_start(ln);
	}
}

/*
 * csio_ln_init - Initialize an lnode.
 * @ln:		lnode
 *
 */
static int
csio_ln_init(struct csio_lnode *ln)
{
	int rv = -EINVAL;
	struct csio_lnode *rln, *pln;
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	csio_init_state(&ln->sm, csio_lns_uninit);
	ln->vnp_flowid = CSIO_INVALID_IDX;
	ln->fcf_flowid = CSIO_INVALID_IDX;

	if (csio_is_root_ln(ln)) {

		/* This is the lnode used during initialization */

		ln->fcfinfo = kzalloc(sizeof(struct csio_fcf_info), GFP_KERNEL);
		if (!ln->fcfinfo) {
			csio_ln_err(ln, "Failed to alloc FCF record\n");
			CSIO_INC_STATS(hw, n_err_nomem);
			goto err;
		}

		INIT_LIST_HEAD(&ln->fcf_lsthead);
		kref_init(&ln->fcfinfo->kref);

		if (csio_fdmi_enable && csio_ln_fdmi_init(ln))
			goto err;

	} else { /* Either a non-root physical or a virtual lnode */

		/*
		 * THe rest is common for non-root physical and NPIV lnodes.
		 * Just get references to all other modules
		 */
		rln = csio_root_lnode(ln);

		if (csio_is_npiv_ln(ln)) {
			/* NPIV */
			pln = csio_parent_lnode(ln);
			kref_get(&pln->fcfinfo->kref);
			ln->fcfinfo = pln->fcfinfo;
		} else {
			/* Another non-root physical lnode (FCF) */
			ln->fcfinfo = kzalloc(sizeof(struct csio_fcf_info),
								GFP_KERNEL);
			if (!ln->fcfinfo) {
				csio_ln_err(ln, "Failed to alloc FCF info\n");
				CSIO_INC_STATS(hw, n_err_nomem);
				goto err;
			}

			kref_init(&ln->fcfinfo->kref);

			if (csio_fdmi_enable && csio_ln_fdmi_init(ln))
				goto err;
		}

	} /* if (!csio_is_root_ln(ln)) */

	return 0;
err:
	return rv;
}

static void
csio_ln_exit(struct csio_lnode *ln)
{
	struct csio_lnode *pln;

	csio_cleanup_rns(ln);
	if (csio_is_npiv_ln(ln)) {
		pln = csio_parent_lnode(ln);
		kref_put(&pln->fcfinfo->kref, csio_free_fcfinfo);
	} else {
		kref_put(&ln->fcfinfo->kref, csio_free_fcfinfo);
		if (csio_fdmi_enable)
			csio_ln_fdmi_exit(ln);
	}
	ln->fcfinfo = NULL;
}

/**
 * csio_lnode_init - Initialize the members of an lnode.
 * @ln:		lnode
 *
 */
int
csio_lnode_init(struct csio_lnode *ln, struct csio_hw *hw,
		struct csio_lnode *pln)
{
	int rv = -EINVAL;

	/* Link this lnode to hw */
	csio_lnode_to_hw(ln)	= hw;

	/* Link child to parent if child lnode */
	if (pln)
		ln->pln = pln;
	else
		ln->pln = NULL;

	/* Initialize scsi_tgt and timers to zero */
	ln->n_scsi_tgts = 0;
	ln->last_scan_ntgts = 0;
	ln->tgt_scan_tick = 0;

	/* Initialize rnode list */
	INIT_LIST_HEAD(&ln->rnhead);
	INIT_LIST_HEAD(&ln->cln_head);

	/* Initialize log level for debug */
	ln->params.log_level	= hw->params.log_level;

	if (csio_ln_init(ln))
		goto err;

	/* Add lnode to list of sibling or children lnodes */
	spin_lock_irq(&hw->lock);
	list_add_tail(&ln->sm.sm_list, pln ? &pln->cln_head : &hw->sln_head);
	if (pln)
		pln->num_vports++;
	spin_unlock_irq(&hw->lock);

	hw->num_lns++;

	return 0;
err:
	csio_lnode_to_hw(ln) = NULL;
	return rv;
}

/**
 * csio_lnode_exit - De-instantiate an lnode.
 * @ln:		lnode
 *
 */
void
csio_lnode_exit(struct csio_lnode *ln)
{
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	csio_ln_exit(ln);

	/* Remove this lnode from hw->sln_head */
	spin_lock_irq(&hw->lock);

	list_del_init(&ln->sm.sm_list);

	/* If it is children lnode, decrement the
	 * counter in its parent lnode
	 */
	if (ln->pln)
		ln->pln->num_vports--;

	/* Update root lnode pointer */
	if (list_empty(&hw->sln_head))
		hw->rln = NULL;
	else
		hw->rln = (struct csio_lnode *)csio_list_next(&hw->sln_head);

	spin_unlock_irq(&hw->lock);

	csio_lnode_to_hw(ln)	= NULL;
	hw->num_lns--;
}
