// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 */

/*
 * This file implements remote node state machines for:
 * - Fabric logins.
 * - Fabric controller events.
 * - Name/directory services interaction.
 * - Point-to-point logins.
 */

/*
 * fabric_sm Node State Machine: Fabric States
 * ns_sm Node State Machine: Name/Directory Services States
 * p2p_sm Node State Machine: Point-to-Point Node States
 */

#include "efc.h"

static void
efc_fabric_initiate_shutdown(struct efc_node *node)
{
	struct efc *efc = node->efc;

	node->els_io_enabled = false;

	if (node->attached) {
		int rc;

		/* issue hw node free; don't care if succeeds right away
		 * or sometime later, will check node->attached later in
		 * shutdown process
		 */
		rc = efc_cmd_node_detach(efc, &node->rnode);
		if (rc < 0) {
			node_printf(node, "Failed freeing HW node, rc=%d\n",
				    rc);
		}
	}
	/*
	 * node has either been detached or is in the process of being detached,
	 * call common node's initiate cleanup function
	 */
	efc_node_initiate_cleanup(node);
}

static void
__efc_fabric_common(const char *funcname, struct efc_sm_ctx *ctx,
		    enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = NULL;

	node = ctx->app;

	switch (evt) {
	case EFC_EVT_DOMAIN_ATTACH_OK:
		break;
	case EFC_EVT_SHUTDOWN:
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;

	default:
		/* call default event handler common to all nodes */
		__efc_node_common(funcname, ctx, evt, arg);
	}
}

void
__efc_fabric_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
		  void *arg)
{
	struct efc_node *node = ctx->app;
	struct efc *efc = node->efc;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_REENTER:
		efc_log_debug(efc, ">>> reenter !!\n");
		fallthrough;

	case EFC_EVT_ENTER:
		/* send FLOGI */
		efc_send_flogi(node);
		efc_node_transition(node, __efc_fabric_flogi_wait_rsp, NULL);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
efc_fabric_set_topology(struct efc_node *node,
			enum efc_nport_topology topology)
{
	node->nport->topology = topology;
}

void
efc_fabric_notify_topology(struct efc_node *node)
{
	struct efc_node *tmp_node;
	enum efc_nport_topology topology = node->nport->topology;
	unsigned long index;

	/*
	 * now loop through the nodes in the nport
	 * and send topology notification
	 */
	xa_for_each(&node->nport->lookup, index, tmp_node) {
		if (tmp_node != node) {
			efc_node_post_event(tmp_node,
					    EFC_EVT_NPORT_TOPOLOGY_NOTIFY,
					    (void *)topology);
		}
	}
}

static bool efc_rnode_is_nport(struct fc_els_flogi *rsp)
{
	return !(ntohs(rsp->fl_csp.sp_features) & FC_SP_FT_FPORT);
}

void
__efc_fabric_flogi_wait_rsp(struct efc_sm_ctx *ctx,
			    enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK: {
		if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;

		memcpy(node->nport->domain->flogi_service_params,
		       cbdata->els_rsp.virt,
		       sizeof(struct fc_els_flogi));

		/* Check to see if the fabric is an F_PORT or and N_PORT */
		if (!efc_rnode_is_nport(cbdata->els_rsp.virt)) {
			/* sm: if not nport / efc_domain_attach */
			/* ext_status has the fc_id, attach domain */
			efc_fabric_set_topology(node, EFC_NPORT_TOPO_FABRIC);
			efc_fabric_notify_topology(node);
			WARN_ON(node->nport->domain->attached);
			efc_domain_attach(node->nport->domain,
					  cbdata->ext_status);
			efc_node_transition(node,
					    __efc_fabric_wait_domain_attach,
					    NULL);
			break;
		}

		/*  sm: if nport and p2p_winner / efc_domain_attach */
		efc_fabric_set_topology(node, EFC_NPORT_TOPO_P2P);
		if (efc_p2p_setup(node->nport)) {
			node_printf(node,
				    "p2p setup failed, shutting down node\n");
			node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
			efc_fabric_initiate_shutdown(node);
			break;
		}

		if (node->nport->p2p_winner) {
			efc_node_transition(node,
					    __efc_p2p_wait_domain_attach,
					     NULL);
			if (node->nport->domain->attached &&
			    !node->nport->domain->domain_notify_pend) {
				/*
				 * already attached,
				 * just send ATTACH_OK
				 */
				node_printf(node,
					    "p2p winner, domain already attached\n");
				efc_node_post_event(node,
						    EFC_EVT_DOMAIN_ATTACH_OK,
						    NULL);
			}
		} else {
			/*
			 * peer is p2p winner;
			 * PLOGI will be received on the
			 * remote SID=1 node;
			 * this node has served its purpose
			 */
			node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
			efc_fabric_initiate_shutdown(node);
		}

		break;
	}

	case EFC_EVT_ELS_REQ_ABORTED:
	case EFC_EVT_SRRS_ELS_REQ_RJT:
	case EFC_EVT_SRRS_ELS_REQ_FAIL: {
		struct efc_nport *nport = node->nport;
		/*
		 * with these errors, we have no recovery,
		 * so shutdown the nport, leave the link
		 * up and the domain ready
		 */
		if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		node_printf(node,
			    "FLOGI failed evt=%s, shutting down nport [%s]\n",
			    efc_sm_event_name(evt), nport->display_name);
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		efc_sm_post_event(&nport->sm, EFC_EVT_SHUTDOWN, NULL);
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_vport_fabric_init(struct efc_sm_ctx *ctx,
			enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		/* sm: / send FDISC */
		efc_send_fdisc(node);
		efc_node_transition(node, __efc_fabric_fdisc_wait_rsp, NULL);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_fabric_fdisc_wait_rsp(struct efc_sm_ctx *ctx,
			    enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK: {
		/* fc_id is in ext_status */
		if (efc_node_check_els_req(ctx, evt, arg, ELS_FDISC,
					   __efc_fabric_common, __func__)) {
			return;
		}

		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		/* sm: / efc_nport_attach */
		efc_nport_attach(node->nport, cbdata->ext_status);
		efc_node_transition(node, __efc_fabric_wait_domain_attach,
				    NULL);
		break;
	}

	case EFC_EVT_SRRS_ELS_REQ_RJT:
	case EFC_EVT_SRRS_ELS_REQ_FAIL: {
		if (efc_node_check_els_req(ctx, evt, arg, ELS_FDISC,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		efc_log_err(node->efc, "FDISC failed, shutting down nport\n");
		/* sm: / shutdown nport */
		efc_sm_post_event(&node->nport->sm, EFC_EVT_SHUTDOWN, NULL);
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

static int
efc_start_ns_node(struct efc_nport *nport)
{
	struct efc_node *ns;

	/* Instantiate a name services node */
	ns = efc_node_find(nport, FC_FID_DIR_SERV);
	if (!ns) {
		ns = efc_node_alloc(nport, FC_FID_DIR_SERV, false, false);
		if (!ns)
			return -EIO;
	}
	/*
	 * for found ns, should we be transitioning from here?
	 * breaks transition only
	 *  1. from within state machine or
	 *  2. if after alloc
	 */
	if (ns->efc->nodedb_mask & EFC_NODEDB_PAUSE_NAMESERVER)
		efc_node_pause(ns, __efc_ns_init);
	else
		efc_node_transition(ns, __efc_ns_init, NULL);
	return 0;
}

static int
efc_start_fabctl_node(struct efc_nport *nport)
{
	struct efc_node *fabctl;

	fabctl = efc_node_find(nport, FC_FID_FCTRL);
	if (!fabctl) {
		fabctl = efc_node_alloc(nport, FC_FID_FCTRL,
					false, false);
		if (!fabctl)
			return -EIO;
	}
	/*
	 * for found ns, should we be transitioning from here?
	 * breaks transition only
	 *  1. from within state machine or
	 *  2. if after alloc
	 */
	efc_node_transition(fabctl, __efc_fabctl_init, NULL);
	return 0;
}

void
__efc_fabric_wait_domain_attach(struct efc_sm_ctx *ctx,
				enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;
	case EFC_EVT_DOMAIN_ATTACH_OK:
	case EFC_EVT_NPORT_ATTACH_OK: {
		int rc;

		rc = efc_start_ns_node(node->nport);
		if (rc)
			return;

		/* sm: if enable_ini / start fabctl node */
		/* Instantiate the fabric controller (sends SCR) */
		if (node->nport->enable_rscn) {
			rc = efc_start_fabctl_node(node->nport);
			if (rc)
				return;
		}
		efc_node_transition(node, __efc_fabric_idle, NULL);
		break;
	}
	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_fabric_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
		  void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_DOMAIN_ATTACH_OK:
		break;
	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_ns_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		/* sm: / send PLOGI */
		efc_send_plogi(node);
		efc_node_transition(node, __efc_ns_plogi_wait_rsp, NULL);
		break;
	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_ns_plogi_wait_rsp(struct efc_sm_ctx *ctx,
			enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK: {
		int rc;

		/* Save service parameters */
		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		/* sm: / save sparams, efc_node_attach */
		efc_node_save_sparms(node, cbdata->els_rsp.virt);
		rc = efc_node_attach(node);
		efc_node_transition(node, __efc_ns_wait_node_attach, NULL);
		if (rc < 0)
			efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
					    NULL);
		break;
	}
	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_ns_wait_node_attach(struct efc_sm_ctx *ctx,
			  enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	case EFC_EVT_NODE_ATTACH_OK:
		node->attached = true;
		/* sm: / send RFTID */
		efc_ns_send_rftid(node);
		efc_node_transition(node, __efc_ns_rftid_wait_rsp, NULL);
		break;

	case EFC_EVT_NODE_ATTACH_FAIL:
		/* node attach failed, shutdown the node */
		node->attached = false;
		node_printf(node, "Node attach failed\n");
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;

	case EFC_EVT_SHUTDOWN:
		node_printf(node, "Shutdown event received\n");
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_node_transition(node,
				    __efc_fabric_wait_attach_evt_shutdown,
				     NULL);
		break;

	/*
	 * if receive RSCN just ignore,
	 * we haven't sent GID_PT yet (ACC sent by fabctl node)
	 */
	case EFC_EVT_RSCN_RCVD:
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_fabric_wait_attach_evt_shutdown(struct efc_sm_ctx *ctx,
				      enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	/* wait for any of these attach events and then shutdown */
	case EFC_EVT_NODE_ATTACH_OK:
		node->attached = true;
		node_printf(node, "Attach evt=%s, proceed to shutdown\n",
			    efc_sm_event_name(evt));
		efc_fabric_initiate_shutdown(node);
		break;

	case EFC_EVT_NODE_ATTACH_FAIL:
		node->attached = false;
		node_printf(node, "Attach evt=%s, proceed to shutdown\n",
			    efc_sm_event_name(evt));
		efc_fabric_initiate_shutdown(node);
		break;

	/* ignore shutdown event as we're already in shutdown path */
	case EFC_EVT_SHUTDOWN:
		node_printf(node, "Shutdown event received\n");
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_ns_rftid_wait_rsp(struct efc_sm_ctx *ctx,
			enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK:
		if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_RFT_ID,
					  __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		/* sm: / send RFFID */
		efc_ns_send_rffid(node);
		efc_node_transition(node, __efc_ns_rffid_wait_rsp, NULL);
		break;

	/*
	 * if receive RSCN just ignore,
	 * we haven't sent GID_PT yet (ACC sent by fabctl node)
	 */
	case EFC_EVT_RSCN_RCVD:
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_ns_rffid_wait_rsp(struct efc_sm_ctx *ctx,
			enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	/*
	 * Waits for an RFFID response event;
	 * if rscn enabled, a GIDPT name services request is issued.
	 */
	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK:	{
		if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_RFF_ID,
					  __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		if (node->nport->enable_rscn) {
			/* sm: if enable_rscn / send GIDPT */
			efc_ns_send_gidpt(node);

			efc_node_transition(node, __efc_ns_gidpt_wait_rsp,
					    NULL);
		} else {
			/* if 'T' only, we're done, go to idle */
			efc_node_transition(node, __efc_ns_idle, NULL);
		}
		break;
	}
	/*
	 * if receive RSCN just ignore,
	 * we haven't sent GID_PT yet (ACC sent by fabctl node)
	 */
	case EFC_EVT_RSCN_RCVD:
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

static int
efc_process_gidpt_payload(struct efc_node *node,
			  void *data, u32 gidpt_len)
{
	u32 i, j;
	struct efc_node *newnode;
	struct efc_nport *nport = node->nport;
	struct efc *efc = node->efc;
	u32 port_id = 0, port_count, plist_count;
	struct efc_node *n;
	struct efc_node **active_nodes;
	int residual;
	struct {
		struct fc_ct_hdr hdr;
		struct fc_gid_pn_resp pn_rsp;
	} *rsp;
	struct fc_gid_pn_resp *gidpt;
	unsigned long index;

	rsp = data;
	gidpt = &rsp->pn_rsp;
	residual = be16_to_cpu(rsp->hdr.ct_mr_size);

	if (residual != 0)
		efc_log_debug(node->efc, "residual is %u words\n", residual);

	if (be16_to_cpu(rsp->hdr.ct_cmd) == FC_FS_RJT) {
		node_printf(node,
			    "GIDPT request failed: rsn x%x rsn_expl x%x\n",
			    rsp->hdr.ct_reason, rsp->hdr.ct_explan);
		return -EIO;
	}

	plist_count = (gidpt_len - sizeof(struct fc_ct_hdr)) / sizeof(*gidpt);

	/* Count the number of nodes */
	port_count = 0;
	xa_for_each(&nport->lookup, index, n) {
		port_count++;
	}

	/* Allocate a buffer for all nodes */
	active_nodes = kzalloc(port_count * sizeof(*active_nodes), GFP_ATOMIC);
	if (!active_nodes) {
		node_printf(node, "efc_malloc failed\n");
		return -EIO;
	}

	/* Fill buffer with fc_id of active nodes */
	i = 0;
	xa_for_each(&nport->lookup, index, n) {
		port_id = n->rnode.fc_id;
		switch (port_id) {
		case FC_FID_FLOGI:
		case FC_FID_FCTRL:
		case FC_FID_DIR_SERV:
			break;
		default:
			if (port_id != FC_FID_DOM_MGR)
				active_nodes[i++] = n;
			break;
		}
	}

	/* update the active nodes buffer */
	for (i = 0; i < plist_count; i++) {
		hton24(gidpt[i].fp_fid, port_id);

		for (j = 0; j < port_count; j++) {
			if (active_nodes[j] &&
			    port_id == active_nodes[j]->rnode.fc_id) {
				active_nodes[j] = NULL;
			}
		}

		if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
			break;
	}

	/* Those remaining in the active_nodes[] are now gone ! */
	for (i = 0; i < port_count; i++) {
		/*
		 * if we're an initiator and the remote node
		 * is a target, then post the node missing event.
		 * if we're target and we have enabled
		 * target RSCN, then post the node missing event.
		 */
		if (!active_nodes[i])
			continue;

		if ((node->nport->enable_ini && active_nodes[i]->targ) ||
		    (node->nport->enable_tgt && enable_target_rscn(efc))) {
			efc_node_post_event(active_nodes[i],
					    EFC_EVT_NODE_MISSING, NULL);
		} else {
			node_printf(node,
				    "GID_PT: skipping non-tgt port_id x%06x\n",
				    active_nodes[i]->rnode.fc_id);
		}
	}
	kfree(active_nodes);

	for (i = 0; i < plist_count; i++) {
		hton24(gidpt[i].fp_fid, port_id);

		/* Don't create node for ourselves */
		if (port_id == node->rnode.nport->fc_id) {
			if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
				break;
			continue;
		}

		newnode = efc_node_find(nport, port_id);
		if (!newnode) {
			if (!node->nport->enable_ini)
				continue;

			newnode = efc_node_alloc(nport, port_id, false, false);
			if (!newnode) {
				efc_log_err(efc, "efc_node_alloc() failed\n");
				return -EIO;
			}
			/*
			 * send PLOGI automatically
			 * if initiator
			 */
			efc_node_init_device(newnode, true);
		}

		if (node->nport->enable_ini && newnode->targ) {
			efc_node_post_event(newnode, EFC_EVT_NODE_REFOUND,
					    NULL);
		}

		if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
			break;
	}
	return 0;
}

void
__efc_ns_gidpt_wait_rsp(struct efc_sm_ctx *ctx,
			enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();
	/*
	 * Wait for a GIDPT response from the name server. Process the FC_IDs
	 * that are reported by creating new remote ports, as needed.
	 */

	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK:	{
		if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_GID_PT,
					  __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		/* sm: / process GIDPT payload */
		efc_process_gidpt_payload(node, cbdata->els_rsp.virt,
					  cbdata->els_rsp.len);
		efc_node_transition(node, __efc_ns_idle, NULL);
		break;
	}

	case EFC_EVT_SRRS_ELS_REQ_FAIL:	{
		/* not much we can do; will retry with the next RSCN */
		node_printf(node, "GID_PT failed to complete\n");
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		efc_node_transition(node, __efc_ns_idle, NULL);
		break;
	}

	/* if receive RSCN here, queue up another discovery processing */
	case EFC_EVT_RSCN_RCVD: {
		node_printf(node, "RSCN received during GID_PT processing\n");
		node->rscn_pending = true;
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_ns_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;
	struct efc *efc = node->efc;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	/*
	 * Wait for RSCN received events (posted from the fabric controller)
	 * and restart the GIDPT name services query and processing.
	 */

	switch (evt) {
	case EFC_EVT_ENTER:
		if (!node->rscn_pending)
			break;

		node_printf(node, "RSCN pending, restart discovery\n");
		node->rscn_pending = false;
		fallthrough;

	case EFC_EVT_RSCN_RCVD: {
		/* sm: / send GIDPT */
		/*
		 * If target RSCN processing is enabled,
		 * and this is target only (not initiator),
		 * and tgt_rscn_delay is non-zero,
		 * then we delay issuing the GID_PT
		 */
		if (efc->tgt_rscn_delay_msec != 0 &&
		    !node->nport->enable_ini && node->nport->enable_tgt &&
		    enable_target_rscn(efc)) {
			efc_node_transition(node, __efc_ns_gidpt_delay, NULL);
		} else {
			efc_ns_send_gidpt(node);
			efc_node_transition(node, __efc_ns_gidpt_wait_rsp,
					    NULL);
		}
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

static void
gidpt_delay_timer_cb(struct timer_list *t)
{
	struct efc_node *node = from_timer(node, t, gidpt_delay_timer);

	del_timer(&node->gidpt_delay_timer);

	efc_node_post_event(node, EFC_EVT_GIDPT_DELAY_EXPIRED, NULL);
}

void
__efc_ns_gidpt_delay(struct efc_sm_ctx *ctx,
		     enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;
	struct efc *efc = node->efc;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER: {
		u64 delay_msec, tmp;

		/*
		 * Compute the delay time.
		 * Set to tgt_rscn_delay, if the time since last GIDPT
		 * is less than tgt_rscn_period, then use tgt_rscn_period.
		 */
		delay_msec = efc->tgt_rscn_delay_msec;
		tmp = jiffies_to_msecs(jiffies) - node->time_last_gidpt_msec;
		if (tmp < efc->tgt_rscn_period_msec)
			delay_msec = efc->tgt_rscn_period_msec;

		timer_setup(&node->gidpt_delay_timer, &gidpt_delay_timer_cb,
			    0);
		mod_timer(&node->gidpt_delay_timer,
			  jiffies + msecs_to_jiffies(delay_msec));

		break;
	}

	case EFC_EVT_GIDPT_DELAY_EXPIRED:
		node->time_last_gidpt_msec = jiffies_to_msecs(jiffies);

		efc_ns_send_gidpt(node);
		efc_node_transition(node, __efc_ns_gidpt_wait_rsp, NULL);
		break;

	case EFC_EVT_RSCN_RCVD: {
		efc_log_debug(efc,
			      "RSCN received while in GIDPT delay - no action\n");
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_fabctl_init(struct efc_sm_ctx *ctx,
		  enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		/* no need to login to fabric controller, just send SCR */
		efc_send_scr(node);
		efc_node_transition(node, __efc_fabctl_wait_scr_rsp, NULL);
		break;

	case EFC_EVT_NODE_ATTACH_OK:
		node->attached = true;
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_fabctl_wait_scr_rsp(struct efc_sm_ctx *ctx,
			  enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	/*
	 * Fabric controller node state machine:
	 * Wait for an SCR response from the fabric controller.
	 */
	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK:
		if (efc_node_check_els_req(ctx, evt, arg, ELS_SCR,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		efc_node_transition(node, __efc_fabctl_ready, NULL);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

static void
efc_process_rscn(struct efc_node *node, struct efc_node_cb *cbdata)
{
	struct efc *efc = node->efc;
	struct efc_nport *nport = node->nport;
	struct efc_node *ns;

	/* Forward this event to the name-services node */
	ns = efc_node_find(nport, FC_FID_DIR_SERV);
	if (ns)
		efc_node_post_event(ns, EFC_EVT_RSCN_RCVD, cbdata);
	else
		efc_log_warn(efc, "can't find name server node\n");
}

void
__efc_fabctl_ready(struct efc_sm_ctx *ctx,
		   enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	/*
	 * Fabric controller node state machine: Ready.
	 * In this state, the fabric controller sends a RSCN, which is received
	 * by this node and is forwarded to the name services node object; and
	 * the RSCN LS_ACC is sent.
	 */
	switch (evt) {
	case EFC_EVT_RSCN_RCVD: {
		struct fc_frame_header *hdr = cbdata->header->dma.virt;

		/*
		 * sm: / process RSCN (forward to name services node),
		 * send LS_ACC
		 */
		efc_process_rscn(node, cbdata);
		efc_send_ls_acc(node, be16_to_cpu(hdr->fh_ox_id));
		efc_node_transition(node, __efc_fabctl_wait_ls_acc_cmpl,
				    NULL);
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_fabctl_wait_ls_acc_cmpl(struct efc_sm_ctx *ctx,
			      enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	case EFC_EVT_SRRS_ELS_CMPL_OK:
		WARN_ON(!node->els_cmpl_cnt);
		node->els_cmpl_cnt--;
		efc_node_transition(node, __efc_fabctl_ready, NULL);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

static uint64_t
efc_get_wwpn(struct fc_els_flogi *sp)
{
	return be64_to_cpu(sp->fl_wwnn);
}

static int
efc_rnode_is_winner(struct efc_nport *nport)
{
	struct fc_els_flogi *remote_sp;
	u64 remote_wwpn;
	u64 local_wwpn = nport->wwpn;
	u64 wwn_bump = 0;

	remote_sp = (struct fc_els_flogi *)nport->domain->flogi_service_params;
	remote_wwpn = efc_get_wwpn(remote_sp);

	local_wwpn ^= wwn_bump;

	efc_log_debug(nport->efc, "r: %llx\n",
		      be64_to_cpu(remote_sp->fl_wwpn));
	efc_log_debug(nport->efc, "l: %llx\n", local_wwpn);

	if (remote_wwpn == local_wwpn) {
		efc_log_warn(nport->efc,
			     "WWPN of remote node [%08x %08x] matches local WWPN\n",
			     (u32)(local_wwpn >> 32ll),
			     (u32)local_wwpn);
		return -1;
	}

	return (remote_wwpn > local_wwpn);
}

void
__efc_p2p_wait_domain_attach(struct efc_sm_ctx *ctx,
			     enum efc_sm_event evt, void *arg)
{
	struct efc_node *node = ctx->app;
	struct efc *efc = node->efc;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	case EFC_EVT_DOMAIN_ATTACH_OK: {
		struct efc_nport *nport = node->nport;
		struct efc_node *rnode;

		/*
		 * this transient node (SID=0 (recv'd FLOGI)
		 * or DID=fabric (sent FLOGI))
		 * is the p2p winner, will use a separate node
		 * to send PLOGI to peer
		 */
		WARN_ON(!node->nport->p2p_winner);

		rnode = efc_node_find(nport, node->nport->p2p_remote_port_id);
		if (rnode) {
			/*
			 * the "other" transient p2p node has
			 * already kicked off the
			 * new node from which PLOGI is sent
			 */
			node_printf(node,
				    "Node with fc_id x%x already exists\n",
				    rnode->rnode.fc_id);
		} else {
			/*
			 * create new node (SID=1, DID=2)
			 * from which to send PLOGI
			 */
			rnode = efc_node_alloc(nport,
					       nport->p2p_remote_port_id,
						false, false);
			if (!rnode) {
				efc_log_err(efc, "node alloc failed\n");
				return;
			}

			efc_fabric_notify_topology(node);
			/* sm: / allocate p2p remote node */
			efc_node_transition(rnode, __efc_p2p_rnode_init,
					    NULL);
		}

		/*
		 * the transient node (SID=0 or DID=fabric)
		 * has served its purpose
		 */
		if (node->rnode.fc_id == 0) {
			/*
			 * if this is the SID=0 node,
			 * move to the init state in case peer
			 * has restarted FLOGI discovery and FLOGI is pending
			 */
			/* don't send PLOGI on efc_d_init entry */
			efc_node_init_device(node, false);
		} else {
			/*
			 * if this is the DID=fabric node
			 * (we initiated FLOGI), shut it down
			 */
			node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
			efc_fabric_initiate_shutdown(node);
		}
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_p2p_rnode_init(struct efc_sm_ctx *ctx,
		     enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		/* sm: / send PLOGI */
		efc_send_plogi(node);
		efc_node_transition(node, __efc_p2p_wait_plogi_rsp, NULL);
		break;

	case EFC_EVT_ABTS_RCVD:
		/* sm: send BA_ACC */
		efc_send_bls_acc(node, cbdata->header->dma.virt);

		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_p2p_wait_flogi_acc_cmpl(struct efc_sm_ctx *ctx,
			      enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	case EFC_EVT_SRRS_ELS_CMPL_OK:
		WARN_ON(!node->els_cmpl_cnt);
		node->els_cmpl_cnt--;

		/* sm: if p2p_winner / domain_attach */
		if (node->nport->p2p_winner) {
			efc_node_transition(node,
					    __efc_p2p_wait_domain_attach,
					NULL);
			if (!node->nport->domain->attached) {
				node_printf(node, "Domain not attached\n");
				efc_domain_attach(node->nport->domain,
						  node->nport->p2p_port_id);
			} else {
				node_printf(node, "Domain already attached\n");
				efc_node_post_event(node,
						    EFC_EVT_DOMAIN_ATTACH_OK,
						    NULL);
			}
		} else {
			/* this node has served its purpose;
			 * we'll expect a PLOGI on a separate
			 * node (remote SID=0x1); return this node
			 * to init state in case peer
			 * restarts discovery -- it may already
			 * have (pending frames may exist).
			 */
			/* don't send PLOGI on efc_d_init entry */
			efc_node_init_device(node, false);
		}
		break;

	case EFC_EVT_SRRS_ELS_CMPL_FAIL:
		/*
		 * LS_ACC failed, possibly due to link down;
		 * shutdown node and wait
		 * for FLOGI discovery to restart
		 */
		node_printf(node, "FLOGI LS_ACC failed, shutting down\n");
		WARN_ON(!node->els_cmpl_cnt);
		node->els_cmpl_cnt--;
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;

	case EFC_EVT_ABTS_RCVD: {
		/* sm: / send BA_ACC */
		efc_send_bls_acc(node, cbdata->header->dma.virt);
		break;
	}

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_p2p_wait_plogi_rsp(struct efc_sm_ctx *ctx,
			 enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_SRRS_ELS_REQ_OK: {
		int rc;

		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		/* sm: / save sparams, efc_node_attach */
		efc_node_save_sparms(node, cbdata->els_rsp.virt);
		rc = efc_node_attach(node);
		efc_node_transition(node, __efc_p2p_wait_node_attach, NULL);
		if (rc < 0)
			efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
					    NULL);
		break;
	}
	case EFC_EVT_SRRS_ELS_REQ_FAIL: {
		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		node_printf(node, "PLOGI failed, shutting down\n");
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;
	}

	case EFC_EVT_PLOGI_RCVD: {
		struct fc_frame_header *hdr = cbdata->header->dma.virt;
		/* if we're in external loopback mode, just send LS_ACC */
		if (node->efc->external_loopback) {
			efc_send_plogi_acc(node, be16_to_cpu(hdr->fh_ox_id));
		} else {
			/*
			 * if this isn't external loopback,
			 * pass to default handler
			 */
			__efc_fabric_common(__func__, ctx, evt, arg);
		}
		break;
	}
	case EFC_EVT_PRLI_RCVD:
		/* I, or I+T */
		/* sent PLOGI and before completion was seen, received the
		 * PRLI from the remote node (WCQEs and RCQEs come in on
		 * different queues and order of processing cannot be assumed)
		 * Save OXID so PRLI can be sent after the attach and continue
		 * to wait for PLOGI response
		 */
		efc_process_prli_payload(node, cbdata->payload->dma.virt);
		efc_send_ls_acc_after_attach(node,
					     cbdata->header->dma.virt,
					     EFC_NODE_SEND_LS_ACC_PRLI);
		efc_node_transition(node, __efc_p2p_wait_plogi_rsp_recvd_prli,
				    NULL);
		break;
	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_p2p_wait_plogi_rsp_recvd_prli(struct efc_sm_ctx *ctx,
				    enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		/*
		 * Since we've received a PRLI, we have a port login and will
		 * just need to wait for the PLOGI response to do the node
		 * attach and then we can send the LS_ACC for the PRLI. If,
		 * during this time, we receive FCP_CMNDs (which is possible
		 * since we've already sent a PRLI and our peer may have
		 * accepted).
		 * At this time, we are not waiting on any other unsolicited
		 * frames to continue with the login process. Thus, it will not
		 * hurt to hold frames here.
		 */
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	case EFC_EVT_SRRS_ELS_REQ_OK: {	/* PLOGI response received */
		int rc;

		/* Completion from PLOGI sent */
		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		/* sm: / save sparams, efc_node_attach */
		efc_node_save_sparms(node, cbdata->els_rsp.virt);
		rc = efc_node_attach(node);
		efc_node_transition(node, __efc_p2p_wait_node_attach, NULL);
		if (rc < 0)
			efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
					    NULL);
		break;
	}
	case EFC_EVT_SRRS_ELS_REQ_FAIL:	/* PLOGI response received */
	case EFC_EVT_SRRS_ELS_REQ_RJT:
		/* PLOGI failed, shutdown the node */
		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
					   __efc_fabric_common, __func__)) {
			return;
		}
		WARN_ON(!node->els_req_cnt);
		node->els_req_cnt--;
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

void
__efc_p2p_wait_node_attach(struct efc_sm_ctx *ctx,
			   enum efc_sm_event evt, void *arg)
{
	struct efc_node_cb *cbdata = arg;
	struct efc_node *node = ctx->app;

	efc_node_evt_set(ctx, evt, __func__);

	node_sm_trace();

	switch (evt) {
	case EFC_EVT_ENTER:
		efc_node_hold_frames(node);
		break;

	case EFC_EVT_EXIT:
		efc_node_accept_frames(node);
		break;

	case EFC_EVT_NODE_ATTACH_OK:
		node->attached = true;
		switch (node->send_ls_acc) {
		case EFC_NODE_SEND_LS_ACC_PRLI: {
			efc_d_send_prli_rsp(node->ls_acc_io,
					    node->ls_acc_oxid);
			node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
			node->ls_acc_io = NULL;
			break;
		}
		case EFC_NODE_SEND_LS_ACC_PLOGI: /* Can't happen in P2P */
		case EFC_NODE_SEND_LS_ACC_NONE:
		default:
			/* Normal case for I */
			/* sm: send_plogi_acc is not set / send PLOGI acc */
			efc_node_transition(node, __efc_d_port_logged_in,
					    NULL);
			break;
		}
		break;

	case EFC_EVT_NODE_ATTACH_FAIL:
		/* node attach failed, shutdown the node */
		node->attached = false;
		node_printf(node, "Node attach failed\n");
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_fabric_initiate_shutdown(node);
		break;

	case EFC_EVT_SHUTDOWN:
		node_printf(node, "%s received\n", efc_sm_event_name(evt));
		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
		efc_node_transition(node,
				    __efc_fabric_wait_attach_evt_shutdown,
				     NULL);
		break;
	case EFC_EVT_PRLI_RCVD:
		node_printf(node, "%s: PRLI received before node is attached\n",
			    efc_sm_event_name(evt));
		efc_process_prli_payload(node, cbdata->payload->dma.virt);
		efc_send_ls_acc_after_attach(node,
					     cbdata->header->dma.virt,
				EFC_NODE_SEND_LS_ACC_PRLI);
		break;

	default:
		__efc_fabric_common(__func__, ctx, evt, arg);
	}
}

int
efc_p2p_setup(struct efc_nport *nport)
{
	struct efc *efc = nport->efc;
	int rnode_winner;

	rnode_winner = efc_rnode_is_winner(nport);

	/* set nport flags to indicate p2p "winner" */
	if (rnode_winner == 1) {
		nport->p2p_remote_port_id = 0;
		nport->p2p_port_id = 0;
		nport->p2p_winner = false;
	} else if (rnode_winner == 0) {
		nport->p2p_remote_port_id = 2;
		nport->p2p_port_id = 1;
		nport->p2p_winner = true;
	} else {
		/* no winner; only okay if external loopback enabled */
		if (nport->efc->external_loopback) {
			/*
			 * External loopback mode enabled;
			 * local nport and remote node
			 * will be registered with an NPortID = 1;
			 */
			efc_log_debug(efc,
				      "External loopback mode enabled\n");
			nport->p2p_remote_port_id = 1;
			nport->p2p_port_id = 1;
			nport->p2p_winner = true;
		} else {
			efc_log_warn(efc,
				     "failed to determine p2p winner\n");
			return rnode_winner;
		}
	}
	return 0;
}
