// 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;
	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,
					    &node->nport->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;
}
