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

/**
 * @page ns_sm_info VPORT NS State Machine
 *
 * @section ns_sm_interactions VPORT NS State Machine Interactions
 *
 * @section ns_sm VPORT NS State Machine
 * 	img ns_sm.jpg
 */
#include <bfa.h>
#include <bfa_svc.h>
#include <bfa_iocfc.h>
#include "fcs_lport.h"
#include "fcs_rport.h"
#include "fcs_trcmod.h"
#include "fcs_fcxp.h"
#include "fcs.h"
#include "lport_priv.h"

BFA_TRC_FILE(FCS, NS);

/*
 * forward declarations
 */
static void     bfa_fcs_port_ns_send_plogi(void *ns_cbarg,
					   struct bfa_fcxp_s *fcxp_alloced);
static void     bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg,
					     struct bfa_fcxp_s *fcxp_alloced);
static void     bfa_fcs_port_ns_send_rft_id(void *ns_cbarg,
					    struct bfa_fcxp_s *fcxp_alloced);
static void     bfa_fcs_port_ns_send_rff_id(void *ns_cbarg,
					    struct bfa_fcxp_s *fcxp_alloced);
static void     bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg,
					    struct bfa_fcxp_s *fcxp_alloced);
static void     bfa_fcs_port_ns_timeout(void *arg);
static void     bfa_fcs_port_ns_plogi_response(void *fcsarg,
					       struct bfa_fcxp_s *fcxp,
					       void *cbarg,
					       bfa_status_t req_status,
					       u32 rsp_len,
					       u32 resid_len,
					       struct fchs_s *rsp_fchs);
static void     bfa_fcs_port_ns_rspn_id_response(void *fcsarg,
						 struct bfa_fcxp_s *fcxp,
						 void *cbarg,
						 bfa_status_t req_status,
						 u32 rsp_len,
						 u32 resid_len,
						 struct fchs_s *rsp_fchs);
static void     bfa_fcs_port_ns_rft_id_response(void *fcsarg,
						struct bfa_fcxp_s *fcxp,
						void *cbarg,
						bfa_status_t req_status,
						u32 rsp_len,
						u32 resid_len,
						struct fchs_s *rsp_fchs);
static void     bfa_fcs_port_ns_rff_id_response(void *fcsarg,
						struct bfa_fcxp_s *fcxp,
						void *cbarg,
						bfa_status_t req_status,
						u32 rsp_len,
						u32 resid_len,
						struct fchs_s *rsp_fchs);
static void     bfa_fcs_port_ns_gid_ft_response(void *fcsarg,
						struct bfa_fcxp_s *fcxp,
						void *cbarg,
						bfa_status_t req_status,
						u32 rsp_len,
						u32 resid_len,
						struct fchs_s *rsp_fchs);
static void     bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
						   u32 *pid_buf,
						   u32 n_pids);

static void     bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port);
/**
 *  fcs_ns_sm FCS nameserver interface state machine
 */

/**
 * VPort NS State Machine events
 */
enum vport_ns_event {
	NSSM_EVENT_PORT_ONLINE = 1,
	NSSM_EVENT_PORT_OFFLINE = 2,
	NSSM_EVENT_PLOGI_SENT = 3,
	NSSM_EVENT_RSP_OK = 4,
	NSSM_EVENT_RSP_ERROR = 5,
	NSSM_EVENT_TIMEOUT = 6,
	NSSM_EVENT_NS_QUERY = 7,
	NSSM_EVENT_RSPNID_SENT = 8,
	NSSM_EVENT_RFTID_SENT = 9,
	NSSM_EVENT_RFFID_SENT = 10,
	NSSM_EVENT_GIDFT_SENT = 11,
};

static void     bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
					   enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
						 enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
					 enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
					       enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
						   enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
					   enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
						 enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
						  enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
						enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
					  enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
						  enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
						enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
					  enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
						  enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
					  enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
						enum vport_ns_event event);
static void     bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
					  enum vport_ns_event event);
/**
 * 		Start in offline state - awaiting linkup
 */
static void
bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
			   enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_PORT_ONLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
		bfa_fcs_port_ns_send_plogi(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
				 enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_PLOGI_SENT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
				       &ns->fcxp_wqe);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
			 enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RSP_ERROR:
		/*
		 * Start timer for a delayed retry
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_retry);
		ns->port->stats.ns_retries++;
		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
				bfa_fcs_port_ns_timeout, ns,
				BFA_FCS_RETRY_TIMEOUT);
		break;

	case NSSM_EVENT_RSP_OK:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
		bfa_fcs_port_ns_send_rspn_id(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_discard(ns->fcxp);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
			       enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_TIMEOUT:
		/*
		 * Retry Timer Expired. Re-send
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
		bfa_fcs_port_ns_send_plogi(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_timer_stop(&ns->timer);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
				   enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RSPNID_SENT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
				       &ns->fcxp_wqe);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
			   enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RSP_ERROR:
		/*
		 * Start timer for a delayed retry
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id_retry);
		ns->port->stats.ns_retries++;
		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
				bfa_fcs_port_ns_timeout, ns,
				BFA_FCS_RETRY_TIMEOUT);
		break;

	case NSSM_EVENT_RSP_OK:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
		bfa_fcs_port_ns_send_rft_id(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_fcxp_discard(ns->fcxp);
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
				 enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_TIMEOUT:
		/*
		 * Retry Timer Expired. Re-send
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
		bfa_fcs_port_ns_send_rspn_id(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_timer_stop(&ns->timer);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
				  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RFTID_SENT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
				       &ns->fcxp_wqe);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
			  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RSP_OK:
		/*
		 * Now move to register FC4 Features
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
		bfa_fcs_port_ns_send_rff_id(ns, NULL);
		break;

	case NSSM_EVENT_RSP_ERROR:
		/*
		 * Start timer for a delayed retry
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id_retry);
		ns->port->stats.ns_retries++;
		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
				bfa_fcs_port_ns_timeout, ns,
				BFA_FCS_RETRY_TIMEOUT);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_discard(ns->fcxp);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
				enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_TIMEOUT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
		bfa_fcs_port_ns_send_rft_id(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_timer_stop(&ns->timer);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
				  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RFFID_SENT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
				       &ns->fcxp_wqe);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
			  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RSP_OK:

		/*
		 * If min cfg mode is enabled, we donot initiate rport
		 * discovery with the fabric. Instead, we will retrieve the
		 * boot targets from HAL/FW.
		 */
		if (__fcs_min_cfg(ns->port->fcs)) {
			bfa_fcs_port_ns_boot_target_disc(ns->port);
			bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
			return;
		}

		/*
		 * If the port role is Initiator Mode issue NS query.
		 * If it is Target Mode, skip this and go to online.
		 */
		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
			bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
			bfa_fcs_port_ns_send_gid_ft(ns, NULL);
		} else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
			bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
		}
		/*
		 * kick off mgmt srvr state machine
		 */
		bfa_fcs_port_ms_online(ns->port);
		break;

	case NSSM_EVENT_RSP_ERROR:
		/*
		 * Start timer for a delayed retry
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id_retry);
		ns->port->stats.ns_retries++;
		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
				bfa_fcs_port_ns_timeout, ns,
				BFA_FCS_RETRY_TIMEOUT);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_discard(ns->fcxp);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
				enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_TIMEOUT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
		bfa_fcs_port_ns_send_rff_id(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_timer_stop(&ns->timer);
		break;

	default:
		bfa_assert(0);
	}
}
static void
bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
				  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_GIDFT_SENT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
				       &ns->fcxp_wqe);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
			  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_RSP_OK:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
		break;

	case NSSM_EVENT_RSP_ERROR:
		/*
		 * TBD: for certain reject codes, we don't need to retry
		 */
		/*
		 * Start timer for a delayed retry
		 */
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft_retry);
		ns->port->stats.ns_retries++;
		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
				bfa_fcs_port_ns_timeout, ns,
				BFA_FCS_RETRY_TIMEOUT);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_fcxp_discard(ns->fcxp);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
				enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_TIMEOUT:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
		bfa_fcs_port_ns_send_gid_ft(ns, NULL);
		break;

	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		bfa_timer_stop(&ns->timer);
		break;

	default:
		bfa_assert(0);
	}
}

static void
bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
			  enum vport_ns_event event)
{
	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
	bfa_trc(ns->port->fcs, event);

	switch (event) {
	case NSSM_EVENT_PORT_OFFLINE:
		bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
		break;

	case NSSM_EVENT_NS_QUERY:
		/*
		 * If the port role is Initiator Mode issue NS query.
		 * If it is Target Mode, skip this and go to online.
		 */
		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
			bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
			bfa_fcs_port_ns_send_gid_ft(ns, NULL);
		};
		break;

	default:
		bfa_assert(0);
	}
}



/**
 *  ns_pvt Nameserver local functions
 */

static void
bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
{
	struct bfa_fcs_port_ns_s *ns = ns_cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct fchs_s          fchs;
	int             len;
	struct bfa_fcxp_s *fcxp;

	bfa_trc(port->fcs, port->pid);

	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
	if (!fcxp) {
		port->stats.ns_plogi_alloc_wait++;
		bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
				    bfa_fcs_port_ns_send_plogi, ns);
		return;
	}
	ns->fcxp = fcxp;

	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
			     bfa_os_hton3b(FC_NAME_SERVER),
			     bfa_fcs_port_get_fcid(port), 0,
			     port->port_cfg.pwwn, port->port_cfg.nwwn,
			     bfa_pport_get_maxfrsize(port->fcs->bfa));

	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
		      (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
	port->stats.ns_plogi_sent++;

	bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
}

static void
bfa_fcs_port_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
			       void *cbarg, bfa_status_t req_status,
			       u32 rsp_len, u32 resid_len,
			       struct fchs_s *rsp_fchs)
{
	struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	/* struct fc_logi_s *plogi_resp; */
	struct fc_els_cmd_s   *els_cmd;
	struct fc_ls_rjt_s    *ls_rjt;

	bfa_trc(port->fcs, req_status);
	bfa_trc(port->fcs, port->port_cfg.pwwn);

	/*
	 * Sanity Checks
	 */
	if (req_status != BFA_STATUS_OK) {
		bfa_trc(port->fcs, req_status);
		port->stats.ns_plogi_rsp_err++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		return;
	}

	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);

	switch (els_cmd->els_code) {

	case FC_ELS_ACC:
		if (rsp_len < sizeof(struct fc_logi_s)) {
			bfa_trc(port->fcs, rsp_len);
			port->stats.ns_plogi_acc_err++;
			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
			break;
		}
		port->stats.ns_plogi_accepts++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
		break;

	case FC_ELS_LS_RJT:
		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);

		bfa_trc(port->fcs, ls_rjt->reason_code);
		bfa_trc(port->fcs, ls_rjt->reason_code_expl);

		port->stats.ns_rejects++;

		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		break;

	default:
		port->stats.ns_plogi_unknown_rsp++;
		bfa_trc(port->fcs, els_cmd->els_code);
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
	}
}

/**
 * Register the symbolic port name.
 */
static void
bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
{
	struct bfa_fcs_port_ns_s *ns = ns_cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct fchs_s          fchs;
	int             len;
	struct bfa_fcxp_s *fcxp;
	u8         symbl[256];
	u8        *psymbl = &symbl[0];

	bfa_os_memset(symbl, 0, sizeof(symbl));

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
	if (!fcxp) {
		port->stats.ns_rspnid_alloc_wait++;
		bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
				    bfa_fcs_port_ns_send_rspn_id, ns);
		return;
	}
	ns->fcxp = fcxp;

	/*
	 * for V-Port, form a Port Symbolic Name
	 */
	if (port->vport) {
		/**For Vports,
		 *  we append the vport's port symbolic name to that of the base port.
		 */

		strncpy((char *)psymbl,
			(char *)
			&(bfa_fcs_port_get_psym_name
			  (bfa_fcs_get_base_port(port->fcs))),
			strlen((char *)
			       &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port
							   (port->fcs))));

		/*
		 * Ensure we have a null terminating string.
		 */
		((char *)
		 psymbl)[strlen((char *)
				&bfa_fcs_port_get_psym_name
				(bfa_fcs_get_base_port(port->fcs)))] = 0;

		strncat((char *)psymbl,
			(char *)&(bfa_fcs_port_get_psym_name(port)),
			strlen((char *)&bfa_fcs_port_get_psym_name(port)));
	} else {
		psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port));
	}

	len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
			      bfa_fcs_port_get_fcid(port), 0, psymbl);

	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response,
		      (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);

	port->stats.ns_rspnid_sent++;

	bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
}

static void
bfa_fcs_port_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
				 void *cbarg, bfa_status_t req_status,
				 u32 rsp_len, u32 resid_len,
				 struct fchs_s *rsp_fchs)
{
	struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct ct_hdr_s       *cthdr = NULL;

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	/*
	 * Sanity Checks
	 */
	if (req_status != BFA_STATUS_OK) {
		bfa_trc(port->fcs, req_status);
		port->stats.ns_rspnid_rsp_err++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		return;
	}

	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
	cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);

	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
		port->stats.ns_rspnid_accepts++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
		return;
	}

	port->stats.ns_rspnid_rejects++;
	bfa_trc(port->fcs, cthdr->reason_code);
	bfa_trc(port->fcs, cthdr->exp_code);
	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
}

/**
 * Register FC4-Types
 * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ?
 */
static void
bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
{
	struct bfa_fcs_port_ns_s *ns = ns_cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct fchs_s          fchs;
	int             len;
	struct bfa_fcxp_s *fcxp;

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
	if (!fcxp) {
		port->stats.ns_rftid_alloc_wait++;
		bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
				    bfa_fcs_port_ns_send_rft_id, ns);
		return;
	}
	ns->fcxp = fcxp;

	len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
			     bfa_fcs_port_get_fcid(port), 0,
			     port->port_cfg.roles);

	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response,
		      (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);

	port->stats.ns_rftid_sent++;
	bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
}

static void
bfa_fcs_port_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
				void *cbarg, bfa_status_t req_status,
				u32 rsp_len, u32 resid_len,
				struct fchs_s *rsp_fchs)
{
	struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct ct_hdr_s       *cthdr = NULL;

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	/*
	 * Sanity Checks
	 */
	if (req_status != BFA_STATUS_OK) {
		bfa_trc(port->fcs, req_status);
		port->stats.ns_rftid_rsp_err++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		return;
	}

	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
	cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);

	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
		port->stats.ns_rftid_accepts++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
		return;
	}

	port->stats.ns_rftid_rejects++;
	bfa_trc(port->fcs, cthdr->reason_code);
	bfa_trc(port->fcs, cthdr->exp_code);
	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
}

/**
* Register FC4-Features : Should be done after RFT_ID
 */
static void
bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
{
	struct bfa_fcs_port_ns_s *ns = ns_cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct fchs_s          fchs;
	int             len;
	struct bfa_fcxp_s *fcxp;
	u8         fc4_ftrs = 0;

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
	if (!fcxp) {
		port->stats.ns_rffid_alloc_wait++;
		bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
				    bfa_fcs_port_ns_send_rff_id, ns);
		return;
	}
	ns->fcxp = fcxp;

	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
	} else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET;
	}

	len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
			     bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
			     fc4_ftrs);

	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
		      (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);

	port->stats.ns_rffid_sent++;
	bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
}

static void
bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
				void *cbarg, bfa_status_t req_status,
				u32 rsp_len, u32 resid_len,
				struct fchs_s *rsp_fchs)
{
	struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct ct_hdr_s       *cthdr = NULL;

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	/*
	 * Sanity Checks
	 */
	if (req_status != BFA_STATUS_OK) {
		bfa_trc(port->fcs, req_status);
		port->stats.ns_rffid_rsp_err++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		return;
	}

	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
	cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);

	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
		port->stats.ns_rffid_accepts++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
		return;
	}

	port->stats.ns_rffid_rejects++;
	bfa_trc(port->fcs, cthdr->reason_code);
	bfa_trc(port->fcs, cthdr->exp_code);

	if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
		/*
		 * if this command is not supported, we don't retry
		 */
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
	} else {
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
	}
}

/**
 * Query Fabric for FC4-Types Devices.
 *
*  TBD : Need to use a local (FCS private) response buffer, since the response
 * can be larger than 2K.
 */
static void
bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
{
	struct bfa_fcs_port_ns_s *ns = ns_cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct fchs_s          fchs;
	int             len;
	struct bfa_fcxp_s *fcxp;

	bfa_trc(port->fcs, port->pid);

	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
	if (!fcxp) {
		port->stats.ns_gidft_alloc_wait++;
		bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
				    bfa_fcs_port_ns_send_gid_ft, ns);
		return;
	}
	ns->fcxp = fcxp;

	/*
	 * This query is only initiated for FCP initiator mode.
	 */
	len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid,
			      FC_TYPE_FCP);

	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
		      (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
		      FC_RA_TOV);

	port->stats.ns_gidft_sent++;

	bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
}

static void
bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
				void *cbarg, bfa_status_t req_status,
				u32 rsp_len, u32 resid_len,
				struct fchs_s *rsp_fchs)
{
	struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
	struct bfa_fcs_port_s *port = ns->port;
	struct ct_hdr_s       *cthdr = NULL;
	u32        n_pids;

	bfa_trc(port->fcs, port->port_cfg.pwwn);

	/*
	 * Sanity Checks
	 */
	if (req_status != BFA_STATUS_OK) {
		bfa_trc(port->fcs, req_status);
		port->stats.ns_gidft_rsp_err++;
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		return;
	}

	if (resid_len != 0) {
		/*
		 * TBD : we will need to allocate a larger buffer & retry the
		 * command
		 */
		bfa_trc(port->fcs, rsp_len);
		bfa_trc(port->fcs, resid_len);
		return;
	}

	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
	cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);

	switch (cthdr->cmd_rsp_code) {

	case CT_RSP_ACCEPT:

		port->stats.ns_gidft_accepts++;
		n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
		bfa_trc(port->fcs, n_pids);
		bfa_fcs_port_ns_process_gidft_pids(port,
						   (u32 *) (cthdr + 1),
						   n_pids);
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
		break;

	case CT_RSP_REJECT:

		/*
		 * Check the reason code  & explanation.
		 * There may not have been any FC4 devices in the fabric
		 */
		port->stats.ns_gidft_rejects++;
		bfa_trc(port->fcs, cthdr->reason_code);
		bfa_trc(port->fcs, cthdr->exp_code);

		if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
		    && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {

			bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
		} else {
			/*
			 * for all other errors, retry
			 */
			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
		}
		break;

	default:
		port->stats.ns_gidft_unknown_rsp++;
		bfa_trc(port->fcs, cthdr->cmd_rsp_code);
		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
	}
}

/**
 *     This routine will be called by bfa_timer on timer timeouts.
 *
 * 	param[in] 	port 	- pointer to bfa_fcs_port_t.
 *
 * 	return
 * 		void
 *
* 	Special Considerations:
 *
 * 	note
 */
static void
bfa_fcs_port_ns_timeout(void *arg)
{
	struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg;

	ns->port->stats.ns_timeouts++;
	bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
}

/*
 * Process the PID list in GID_FT response
 */
static void
bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
				   u32 *pid_buf, u32 n_pids)
{
	struct fcgs_gidft_resp_s *gidft_entry;
	struct bfa_fcs_rport_s *rport;
	u32        ii;

	for (ii = 0; ii < n_pids; ii++) {
		gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];

		if (gidft_entry->pid == port->pid)
			continue;

		/*
		 * Check if this rport already exists
		 */
		rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
		if (rport == NULL) {
			/*
			 * this is a new device. create rport
			 */
			rport = bfa_fcs_rport_create(port, gidft_entry->pid);
		} else {
			/*
			 * this rport already exists
			 */
			bfa_fcs_rport_scn(rport);
		}

		bfa_trc(port->fcs, gidft_entry->pid);

		/*
		 * if the last entry bit is set, bail out.
		 */
		if (gidft_entry->last)
			return;
	}
}

/**
 *  fcs_ns_public FCS nameserver public interfaces
 */

/*
 * Functions called by port/fab.
 * These will send relevant Events to the ns state machine.
 */
void
bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port)
{
	struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);

	ns->port = port;
	bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
}

void
bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port)
{
	struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);

	ns->port = port;
	bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
}

void
bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port)
{
	struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);

	ns->port = port;
	bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
}

void
bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port)
{
	struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);

	bfa_trc(port->fcs, port->pid);
	bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
}

static void
bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
{

	struct bfa_fcs_rport_s *rport;
	u8         nwwns;
	wwn_t          *wwns;
	int             ii;

	bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);

	for (ii = 0; ii < nwwns; ++ii) {
		rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
		bfa_assert(rport);
	}
}


