/*
 * 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;
	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, void *val, size_t val_len)
{
	uint16_t len;
	struct fc_fdmi_attr_entry *ae = (struct fc_fdmi_attr_entry *)*ptr;

	if (WARN_ON(val_len > U16_MAX))
		return;

	len = val_len;

	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, val_len);
	if (len > val_len)
		memset(ae->value + val_len, 0, len - 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;
	unsigned long flags;

	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,
			   &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 if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_25G)
		val = htonl(FC_PORTSPEED_25GBIT);
	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_40G)
		val = htonl(FC_PORTSPEED_40GBIT);
	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_50G)
		val = htonl(FC_PORTSPEED_50GBIT);
	else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_100G)
		val = htonl(FC_PORTSPEED_100GBIT);
	else
		val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN);
	csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
			   &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,
			   &mfs, sizeof(mfs));
	numattrs++;

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

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

	/* Submit FDMI RPA request */
	spin_lock_irqsave(&hw->lock, flags);
	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_irqrestore(&hw->lock, flags);
}

/*
 * 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];
	unsigned long flags;

	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,
			   strlen(buf));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER,
			   hw->vpd.sn, sizeof(hw->vpd.sn));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id,
			   sizeof(hw->vpd.id));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
			   hw->model_desc, strlen(hw->model_desc));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION,
			   hw->hw_ver, sizeof(hw->hw_ver));
	numattrs++;
	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
			   hw->fwrev_str, strlen(hw->fwrev_str));
	numattrs++;

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

	csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
			   &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_irqsave(&hw->lock, flags);
	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_irqrestore(&hw->lock, flags);
}

/*
 * 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;
	unsigned long flags;

	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_irqsave(&hw->lock, flags);
	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_irqrestore(&hw->lock, flags);
}

/**
 * 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;

	BUG_ON(pld_len > pld->len);

	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--;
}
