cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

efc_fabric.c (36455B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
      4 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
      5 */
      6
      7/*
      8 * This file implements remote node state machines for:
      9 * - Fabric logins.
     10 * - Fabric controller events.
     11 * - Name/directory services interaction.
     12 * - Point-to-point logins.
     13 */
     14
     15/*
     16 * fabric_sm Node State Machine: Fabric States
     17 * ns_sm Node State Machine: Name/Directory Services States
     18 * p2p_sm Node State Machine: Point-to-Point Node States
     19 */
     20
     21#include "efc.h"
     22
     23static void
     24efc_fabric_initiate_shutdown(struct efc_node *node)
     25{
     26	struct efc *efc = node->efc;
     27
     28	node->els_io_enabled = false;
     29
     30	if (node->attached) {
     31		int rc;
     32
     33		/* issue hw node free; don't care if succeeds right away
     34		 * or sometime later, will check node->attached later in
     35		 * shutdown process
     36		 */
     37		rc = efc_cmd_node_detach(efc, &node->rnode);
     38		if (rc < 0) {
     39			node_printf(node, "Failed freeing HW node, rc=%d\n",
     40				    rc);
     41		}
     42	}
     43	/*
     44	 * node has either been detached or is in the process of being detached,
     45	 * call common node's initiate cleanup function
     46	 */
     47	efc_node_initiate_cleanup(node);
     48}
     49
     50static void
     51__efc_fabric_common(const char *funcname, struct efc_sm_ctx *ctx,
     52		    enum efc_sm_event evt, void *arg)
     53{
     54	struct efc_node *node = NULL;
     55
     56	node = ctx->app;
     57
     58	switch (evt) {
     59	case EFC_EVT_DOMAIN_ATTACH_OK:
     60		break;
     61	case EFC_EVT_SHUTDOWN:
     62		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
     63		efc_fabric_initiate_shutdown(node);
     64		break;
     65
     66	default:
     67		/* call default event handler common to all nodes */
     68		__efc_node_common(funcname, ctx, evt, arg);
     69	}
     70}
     71
     72void
     73__efc_fabric_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
     74		  void *arg)
     75{
     76	struct efc_node *node = ctx->app;
     77	struct efc *efc = node->efc;
     78
     79	efc_node_evt_set(ctx, evt, __func__);
     80
     81	node_sm_trace();
     82
     83	switch (evt) {
     84	case EFC_EVT_REENTER:
     85		efc_log_debug(efc, ">>> reenter !!\n");
     86		fallthrough;
     87
     88	case EFC_EVT_ENTER:
     89		/* send FLOGI */
     90		efc_send_flogi(node);
     91		efc_node_transition(node, __efc_fabric_flogi_wait_rsp, NULL);
     92		break;
     93
     94	default:
     95		__efc_fabric_common(__func__, ctx, evt, arg);
     96	}
     97}
     98
     99void
    100efc_fabric_set_topology(struct efc_node *node,
    101			enum efc_nport_topology topology)
    102{
    103	node->nport->topology = topology;
    104}
    105
    106void
    107efc_fabric_notify_topology(struct efc_node *node)
    108{
    109	struct efc_node *tmp_node;
    110	unsigned long index;
    111
    112	/*
    113	 * now loop through the nodes in the nport
    114	 * and send topology notification
    115	 */
    116	xa_for_each(&node->nport->lookup, index, tmp_node) {
    117		if (tmp_node != node) {
    118			efc_node_post_event(tmp_node,
    119					    EFC_EVT_NPORT_TOPOLOGY_NOTIFY,
    120					    &node->nport->topology);
    121		}
    122	}
    123}
    124
    125static bool efc_rnode_is_nport(struct fc_els_flogi *rsp)
    126{
    127	return !(ntohs(rsp->fl_csp.sp_features) & FC_SP_FT_FPORT);
    128}
    129
    130void
    131__efc_fabric_flogi_wait_rsp(struct efc_sm_ctx *ctx,
    132			    enum efc_sm_event evt, void *arg)
    133{
    134	struct efc_node_cb *cbdata = arg;
    135	struct efc_node *node = ctx->app;
    136
    137	efc_node_evt_set(ctx, evt, __func__);
    138
    139	node_sm_trace();
    140
    141	switch (evt) {
    142	case EFC_EVT_SRRS_ELS_REQ_OK: {
    143		if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI,
    144					   __efc_fabric_common, __func__)) {
    145			return;
    146		}
    147		WARN_ON(!node->els_req_cnt);
    148		node->els_req_cnt--;
    149
    150		memcpy(node->nport->domain->flogi_service_params,
    151		       cbdata->els_rsp.virt,
    152		       sizeof(struct fc_els_flogi));
    153
    154		/* Check to see if the fabric is an F_PORT or and N_PORT */
    155		if (!efc_rnode_is_nport(cbdata->els_rsp.virt)) {
    156			/* sm: if not nport / efc_domain_attach */
    157			/* ext_status has the fc_id, attach domain */
    158			efc_fabric_set_topology(node, EFC_NPORT_TOPO_FABRIC);
    159			efc_fabric_notify_topology(node);
    160			WARN_ON(node->nport->domain->attached);
    161			efc_domain_attach(node->nport->domain,
    162					  cbdata->ext_status);
    163			efc_node_transition(node,
    164					    __efc_fabric_wait_domain_attach,
    165					    NULL);
    166			break;
    167		}
    168
    169		/*  sm: if nport and p2p_winner / efc_domain_attach */
    170		efc_fabric_set_topology(node, EFC_NPORT_TOPO_P2P);
    171		if (efc_p2p_setup(node->nport)) {
    172			node_printf(node,
    173				    "p2p setup failed, shutting down node\n");
    174			node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
    175			efc_fabric_initiate_shutdown(node);
    176			break;
    177		}
    178
    179		if (node->nport->p2p_winner) {
    180			efc_node_transition(node,
    181					    __efc_p2p_wait_domain_attach,
    182					     NULL);
    183			if (node->nport->domain->attached &&
    184			    !node->nport->domain->domain_notify_pend) {
    185				/*
    186				 * already attached,
    187				 * just send ATTACH_OK
    188				 */
    189				node_printf(node,
    190					    "p2p winner, domain already attached\n");
    191				efc_node_post_event(node,
    192						    EFC_EVT_DOMAIN_ATTACH_OK,
    193						    NULL);
    194			}
    195		} else {
    196			/*
    197			 * peer is p2p winner;
    198			 * PLOGI will be received on the
    199			 * remote SID=1 node;
    200			 * this node has served its purpose
    201			 */
    202			node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
    203			efc_fabric_initiate_shutdown(node);
    204		}
    205
    206		break;
    207	}
    208
    209	case EFC_EVT_ELS_REQ_ABORTED:
    210	case EFC_EVT_SRRS_ELS_REQ_RJT:
    211	case EFC_EVT_SRRS_ELS_REQ_FAIL: {
    212		struct efc_nport *nport = node->nport;
    213		/*
    214		 * with these errors, we have no recovery,
    215		 * so shutdown the nport, leave the link
    216		 * up and the domain ready
    217		 */
    218		if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI,
    219					   __efc_fabric_common, __func__)) {
    220			return;
    221		}
    222		node_printf(node,
    223			    "FLOGI failed evt=%s, shutting down nport [%s]\n",
    224			    efc_sm_event_name(evt), nport->display_name);
    225		WARN_ON(!node->els_req_cnt);
    226		node->els_req_cnt--;
    227		efc_sm_post_event(&nport->sm, EFC_EVT_SHUTDOWN, NULL);
    228		break;
    229	}
    230
    231	default:
    232		__efc_fabric_common(__func__, ctx, evt, arg);
    233	}
    234}
    235
    236void
    237__efc_vport_fabric_init(struct efc_sm_ctx *ctx,
    238			enum efc_sm_event evt, void *arg)
    239{
    240	struct efc_node *node = ctx->app;
    241
    242	efc_node_evt_set(ctx, evt, __func__);
    243
    244	node_sm_trace();
    245
    246	switch (evt) {
    247	case EFC_EVT_ENTER:
    248		/* sm: / send FDISC */
    249		efc_send_fdisc(node);
    250		efc_node_transition(node, __efc_fabric_fdisc_wait_rsp, NULL);
    251		break;
    252
    253	default:
    254		__efc_fabric_common(__func__, ctx, evt, arg);
    255	}
    256}
    257
    258void
    259__efc_fabric_fdisc_wait_rsp(struct efc_sm_ctx *ctx,
    260			    enum efc_sm_event evt, void *arg)
    261{
    262	struct efc_node_cb *cbdata = arg;
    263	struct efc_node *node = ctx->app;
    264
    265	efc_node_evt_set(ctx, evt, __func__);
    266
    267	node_sm_trace();
    268
    269	switch (evt) {
    270	case EFC_EVT_SRRS_ELS_REQ_OK: {
    271		/* fc_id is in ext_status */
    272		if (efc_node_check_els_req(ctx, evt, arg, ELS_FDISC,
    273					   __efc_fabric_common, __func__)) {
    274			return;
    275		}
    276
    277		WARN_ON(!node->els_req_cnt);
    278		node->els_req_cnt--;
    279		/* sm: / efc_nport_attach */
    280		efc_nport_attach(node->nport, cbdata->ext_status);
    281		efc_node_transition(node, __efc_fabric_wait_domain_attach,
    282				    NULL);
    283		break;
    284	}
    285
    286	case EFC_EVT_SRRS_ELS_REQ_RJT:
    287	case EFC_EVT_SRRS_ELS_REQ_FAIL: {
    288		if (efc_node_check_els_req(ctx, evt, arg, ELS_FDISC,
    289					   __efc_fabric_common, __func__)) {
    290			return;
    291		}
    292		WARN_ON(!node->els_req_cnt);
    293		node->els_req_cnt--;
    294		efc_log_err(node->efc, "FDISC failed, shutting down nport\n");
    295		/* sm: / shutdown nport */
    296		efc_sm_post_event(&node->nport->sm, EFC_EVT_SHUTDOWN, NULL);
    297		break;
    298	}
    299
    300	default:
    301		__efc_fabric_common(__func__, ctx, evt, arg);
    302	}
    303}
    304
    305static int
    306efc_start_ns_node(struct efc_nport *nport)
    307{
    308	struct efc_node *ns;
    309
    310	/* Instantiate a name services node */
    311	ns = efc_node_find(nport, FC_FID_DIR_SERV);
    312	if (!ns) {
    313		ns = efc_node_alloc(nport, FC_FID_DIR_SERV, false, false);
    314		if (!ns)
    315			return -EIO;
    316	}
    317	/*
    318	 * for found ns, should we be transitioning from here?
    319	 * breaks transition only
    320	 *  1. from within state machine or
    321	 *  2. if after alloc
    322	 */
    323	if (ns->efc->nodedb_mask & EFC_NODEDB_PAUSE_NAMESERVER)
    324		efc_node_pause(ns, __efc_ns_init);
    325	else
    326		efc_node_transition(ns, __efc_ns_init, NULL);
    327	return 0;
    328}
    329
    330static int
    331efc_start_fabctl_node(struct efc_nport *nport)
    332{
    333	struct efc_node *fabctl;
    334
    335	fabctl = efc_node_find(nport, FC_FID_FCTRL);
    336	if (!fabctl) {
    337		fabctl = efc_node_alloc(nport, FC_FID_FCTRL,
    338					false, false);
    339		if (!fabctl)
    340			return -EIO;
    341	}
    342	/*
    343	 * for found ns, should we be transitioning from here?
    344	 * breaks transition only
    345	 *  1. from within state machine or
    346	 *  2. if after alloc
    347	 */
    348	efc_node_transition(fabctl, __efc_fabctl_init, NULL);
    349	return 0;
    350}
    351
    352void
    353__efc_fabric_wait_domain_attach(struct efc_sm_ctx *ctx,
    354				enum efc_sm_event evt, void *arg)
    355{
    356	struct efc_node *node = ctx->app;
    357
    358	efc_node_evt_set(ctx, evt, __func__);
    359
    360	node_sm_trace();
    361
    362	switch (evt) {
    363	case EFC_EVT_ENTER:
    364		efc_node_hold_frames(node);
    365		break;
    366
    367	case EFC_EVT_EXIT:
    368		efc_node_accept_frames(node);
    369		break;
    370	case EFC_EVT_DOMAIN_ATTACH_OK:
    371	case EFC_EVT_NPORT_ATTACH_OK: {
    372		int rc;
    373
    374		rc = efc_start_ns_node(node->nport);
    375		if (rc)
    376			return;
    377
    378		/* sm: if enable_ini / start fabctl node */
    379		/* Instantiate the fabric controller (sends SCR) */
    380		if (node->nport->enable_rscn) {
    381			rc = efc_start_fabctl_node(node->nport);
    382			if (rc)
    383				return;
    384		}
    385		efc_node_transition(node, __efc_fabric_idle, NULL);
    386		break;
    387	}
    388	default:
    389		__efc_fabric_common(__func__, ctx, evt, arg);
    390	}
    391}
    392
    393void
    394__efc_fabric_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
    395		  void *arg)
    396{
    397	struct efc_node *node = ctx->app;
    398
    399	efc_node_evt_set(ctx, evt, __func__);
    400
    401	node_sm_trace();
    402
    403	switch (evt) {
    404	case EFC_EVT_DOMAIN_ATTACH_OK:
    405		break;
    406	default:
    407		__efc_fabric_common(__func__, ctx, evt, arg);
    408	}
    409}
    410
    411void
    412__efc_ns_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
    413{
    414	struct efc_node *node = ctx->app;
    415
    416	efc_node_evt_set(ctx, evt, __func__);
    417
    418	node_sm_trace();
    419
    420	switch (evt) {
    421	case EFC_EVT_ENTER:
    422		/* sm: / send PLOGI */
    423		efc_send_plogi(node);
    424		efc_node_transition(node, __efc_ns_plogi_wait_rsp, NULL);
    425		break;
    426	default:
    427		__efc_fabric_common(__func__, ctx, evt, arg);
    428	}
    429}
    430
    431void
    432__efc_ns_plogi_wait_rsp(struct efc_sm_ctx *ctx,
    433			enum efc_sm_event evt, void *arg)
    434{
    435	struct efc_node_cb *cbdata = arg;
    436	struct efc_node *node = ctx->app;
    437
    438	efc_node_evt_set(ctx, evt, __func__);
    439
    440	node_sm_trace();
    441
    442	switch (evt) {
    443	case EFC_EVT_SRRS_ELS_REQ_OK: {
    444		int rc;
    445
    446		/* Save service parameters */
    447		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
    448					   __efc_fabric_common, __func__)) {
    449			return;
    450		}
    451		WARN_ON(!node->els_req_cnt);
    452		node->els_req_cnt--;
    453		/* sm: / save sparams, efc_node_attach */
    454		efc_node_save_sparms(node, cbdata->els_rsp.virt);
    455		rc = efc_node_attach(node);
    456		efc_node_transition(node, __efc_ns_wait_node_attach, NULL);
    457		if (rc < 0)
    458			efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
    459					    NULL);
    460		break;
    461	}
    462	default:
    463		__efc_fabric_common(__func__, ctx, evt, arg);
    464	}
    465}
    466
    467void
    468__efc_ns_wait_node_attach(struct efc_sm_ctx *ctx,
    469			  enum efc_sm_event evt, void *arg)
    470{
    471	struct efc_node *node = ctx->app;
    472
    473	efc_node_evt_set(ctx, evt, __func__);
    474
    475	node_sm_trace();
    476
    477	switch (evt) {
    478	case EFC_EVT_ENTER:
    479		efc_node_hold_frames(node);
    480		break;
    481
    482	case EFC_EVT_EXIT:
    483		efc_node_accept_frames(node);
    484		break;
    485
    486	case EFC_EVT_NODE_ATTACH_OK:
    487		node->attached = true;
    488		/* sm: / send RFTID */
    489		efc_ns_send_rftid(node);
    490		efc_node_transition(node, __efc_ns_rftid_wait_rsp, NULL);
    491		break;
    492
    493	case EFC_EVT_NODE_ATTACH_FAIL:
    494		/* node attach failed, shutdown the node */
    495		node->attached = false;
    496		node_printf(node, "Node attach failed\n");
    497		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
    498		efc_fabric_initiate_shutdown(node);
    499		break;
    500
    501	case EFC_EVT_SHUTDOWN:
    502		node_printf(node, "Shutdown event received\n");
    503		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
    504		efc_node_transition(node,
    505				    __efc_fabric_wait_attach_evt_shutdown,
    506				     NULL);
    507		break;
    508
    509	/*
    510	 * if receive RSCN just ignore,
    511	 * we haven't sent GID_PT yet (ACC sent by fabctl node)
    512	 */
    513	case EFC_EVT_RSCN_RCVD:
    514		break;
    515
    516	default:
    517		__efc_fabric_common(__func__, ctx, evt, arg);
    518	}
    519}
    520
    521void
    522__efc_fabric_wait_attach_evt_shutdown(struct efc_sm_ctx *ctx,
    523				      enum efc_sm_event evt, void *arg)
    524{
    525	struct efc_node *node = ctx->app;
    526
    527	efc_node_evt_set(ctx, evt, __func__);
    528
    529	node_sm_trace();
    530
    531	switch (evt) {
    532	case EFC_EVT_ENTER:
    533		efc_node_hold_frames(node);
    534		break;
    535
    536	case EFC_EVT_EXIT:
    537		efc_node_accept_frames(node);
    538		break;
    539
    540	/* wait for any of these attach events and then shutdown */
    541	case EFC_EVT_NODE_ATTACH_OK:
    542		node->attached = true;
    543		node_printf(node, "Attach evt=%s, proceed to shutdown\n",
    544			    efc_sm_event_name(evt));
    545		efc_fabric_initiate_shutdown(node);
    546		break;
    547
    548	case EFC_EVT_NODE_ATTACH_FAIL:
    549		node->attached = false;
    550		node_printf(node, "Attach evt=%s, proceed to shutdown\n",
    551			    efc_sm_event_name(evt));
    552		efc_fabric_initiate_shutdown(node);
    553		break;
    554
    555	/* ignore shutdown event as we're already in shutdown path */
    556	case EFC_EVT_SHUTDOWN:
    557		node_printf(node, "Shutdown event received\n");
    558		break;
    559
    560	default:
    561		__efc_fabric_common(__func__, ctx, evt, arg);
    562	}
    563}
    564
    565void
    566__efc_ns_rftid_wait_rsp(struct efc_sm_ctx *ctx,
    567			enum efc_sm_event evt, void *arg)
    568{
    569	struct efc_node *node = ctx->app;
    570
    571	efc_node_evt_set(ctx, evt, __func__);
    572
    573	node_sm_trace();
    574
    575	switch (evt) {
    576	case EFC_EVT_SRRS_ELS_REQ_OK:
    577		if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_RFT_ID,
    578					  __efc_fabric_common, __func__)) {
    579			return;
    580		}
    581		WARN_ON(!node->els_req_cnt);
    582		node->els_req_cnt--;
    583		/* sm: / send RFFID */
    584		efc_ns_send_rffid(node);
    585		efc_node_transition(node, __efc_ns_rffid_wait_rsp, NULL);
    586		break;
    587
    588	/*
    589	 * if receive RSCN just ignore,
    590	 * we haven't sent GID_PT yet (ACC sent by fabctl node)
    591	 */
    592	case EFC_EVT_RSCN_RCVD:
    593		break;
    594
    595	default:
    596		__efc_fabric_common(__func__, ctx, evt, arg);
    597	}
    598}
    599
    600void
    601__efc_ns_rffid_wait_rsp(struct efc_sm_ctx *ctx,
    602			enum efc_sm_event evt, void *arg)
    603{
    604	struct efc_node *node = ctx->app;
    605
    606	efc_node_evt_set(ctx, evt, __func__);
    607
    608	node_sm_trace();
    609
    610	/*
    611	 * Waits for an RFFID response event;
    612	 * if rscn enabled, a GIDPT name services request is issued.
    613	 */
    614	switch (evt) {
    615	case EFC_EVT_SRRS_ELS_REQ_OK:	{
    616		if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_RFF_ID,
    617					  __efc_fabric_common, __func__)) {
    618			return;
    619		}
    620		WARN_ON(!node->els_req_cnt);
    621		node->els_req_cnt--;
    622		if (node->nport->enable_rscn) {
    623			/* sm: if enable_rscn / send GIDPT */
    624			efc_ns_send_gidpt(node);
    625
    626			efc_node_transition(node, __efc_ns_gidpt_wait_rsp,
    627					    NULL);
    628		} else {
    629			/* if 'T' only, we're done, go to idle */
    630			efc_node_transition(node, __efc_ns_idle, NULL);
    631		}
    632		break;
    633	}
    634	/*
    635	 * if receive RSCN just ignore,
    636	 * we haven't sent GID_PT yet (ACC sent by fabctl node)
    637	 */
    638	case EFC_EVT_RSCN_RCVD:
    639		break;
    640
    641	default:
    642		__efc_fabric_common(__func__, ctx, evt, arg);
    643	}
    644}
    645
    646static int
    647efc_process_gidpt_payload(struct efc_node *node,
    648			  void *data, u32 gidpt_len)
    649{
    650	u32 i, j;
    651	struct efc_node *newnode;
    652	struct efc_nport *nport = node->nport;
    653	struct efc *efc = node->efc;
    654	u32 port_id = 0, port_count, plist_count;
    655	struct efc_node *n;
    656	struct efc_node **active_nodes;
    657	int residual;
    658	struct {
    659		struct fc_ct_hdr hdr;
    660		struct fc_gid_pn_resp pn_rsp;
    661	} *rsp;
    662	struct fc_gid_pn_resp *gidpt;
    663	unsigned long index;
    664
    665	rsp = data;
    666	gidpt = &rsp->pn_rsp;
    667	residual = be16_to_cpu(rsp->hdr.ct_mr_size);
    668
    669	if (residual != 0)
    670		efc_log_debug(node->efc, "residual is %u words\n", residual);
    671
    672	if (be16_to_cpu(rsp->hdr.ct_cmd) == FC_FS_RJT) {
    673		node_printf(node,
    674			    "GIDPT request failed: rsn x%x rsn_expl x%x\n",
    675			    rsp->hdr.ct_reason, rsp->hdr.ct_explan);
    676		return -EIO;
    677	}
    678
    679	plist_count = (gidpt_len - sizeof(struct fc_ct_hdr)) / sizeof(*gidpt);
    680
    681	/* Count the number of nodes */
    682	port_count = 0;
    683	xa_for_each(&nport->lookup, index, n) {
    684		port_count++;
    685	}
    686
    687	/* Allocate a buffer for all nodes */
    688	active_nodes = kcalloc(port_count, sizeof(*active_nodes), GFP_ATOMIC);
    689	if (!active_nodes) {
    690		node_printf(node, "efc_malloc failed\n");
    691		return -EIO;
    692	}
    693
    694	/* Fill buffer with fc_id of active nodes */
    695	i = 0;
    696	xa_for_each(&nport->lookup, index, n) {
    697		port_id = n->rnode.fc_id;
    698		switch (port_id) {
    699		case FC_FID_FLOGI:
    700		case FC_FID_FCTRL:
    701		case FC_FID_DIR_SERV:
    702			break;
    703		default:
    704			if (port_id != FC_FID_DOM_MGR)
    705				active_nodes[i++] = n;
    706			break;
    707		}
    708	}
    709
    710	/* update the active nodes buffer */
    711	for (i = 0; i < plist_count; i++) {
    712		hton24(gidpt[i].fp_fid, port_id);
    713
    714		for (j = 0; j < port_count; j++) {
    715			if (active_nodes[j] &&
    716			    port_id == active_nodes[j]->rnode.fc_id) {
    717				active_nodes[j] = NULL;
    718			}
    719		}
    720
    721		if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
    722			break;
    723	}
    724
    725	/* Those remaining in the active_nodes[] are now gone ! */
    726	for (i = 0; i < port_count; i++) {
    727		/*
    728		 * if we're an initiator and the remote node
    729		 * is a target, then post the node missing event.
    730		 * if we're target and we have enabled
    731		 * target RSCN, then post the node missing event.
    732		 */
    733		if (!active_nodes[i])
    734			continue;
    735
    736		if ((node->nport->enable_ini && active_nodes[i]->targ) ||
    737		    (node->nport->enable_tgt && enable_target_rscn(efc))) {
    738			efc_node_post_event(active_nodes[i],
    739					    EFC_EVT_NODE_MISSING, NULL);
    740		} else {
    741			node_printf(node,
    742				    "GID_PT: skipping non-tgt port_id x%06x\n",
    743				    active_nodes[i]->rnode.fc_id);
    744		}
    745	}
    746	kfree(active_nodes);
    747
    748	for (i = 0; i < plist_count; i++) {
    749		hton24(gidpt[i].fp_fid, port_id);
    750
    751		/* Don't create node for ourselves */
    752		if (port_id == node->rnode.nport->fc_id) {
    753			if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
    754				break;
    755			continue;
    756		}
    757
    758		newnode = efc_node_find(nport, port_id);
    759		if (!newnode) {
    760			if (!node->nport->enable_ini)
    761				continue;
    762
    763			newnode = efc_node_alloc(nport, port_id, false, false);
    764			if (!newnode) {
    765				efc_log_err(efc, "efc_node_alloc() failed\n");
    766				return -EIO;
    767			}
    768			/*
    769			 * send PLOGI automatically
    770			 * if initiator
    771			 */
    772			efc_node_init_device(newnode, true);
    773		}
    774
    775		if (node->nport->enable_ini && newnode->targ) {
    776			efc_node_post_event(newnode, EFC_EVT_NODE_REFOUND,
    777					    NULL);
    778		}
    779
    780		if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
    781			break;
    782	}
    783	return 0;
    784}
    785
    786void
    787__efc_ns_gidpt_wait_rsp(struct efc_sm_ctx *ctx,
    788			enum efc_sm_event evt, void *arg)
    789{
    790	struct efc_node_cb *cbdata = arg;
    791	struct efc_node *node = ctx->app;
    792
    793	efc_node_evt_set(ctx, evt, __func__);
    794
    795	node_sm_trace();
    796	/*
    797	 * Wait for a GIDPT response from the name server. Process the FC_IDs
    798	 * that are reported by creating new remote ports, as needed.
    799	 */
    800
    801	switch (evt) {
    802	case EFC_EVT_SRRS_ELS_REQ_OK:	{
    803		if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_GID_PT,
    804					  __efc_fabric_common, __func__)) {
    805			return;
    806		}
    807		WARN_ON(!node->els_req_cnt);
    808		node->els_req_cnt--;
    809		/* sm: / process GIDPT payload */
    810		efc_process_gidpt_payload(node, cbdata->els_rsp.virt,
    811					  cbdata->els_rsp.len);
    812		efc_node_transition(node, __efc_ns_idle, NULL);
    813		break;
    814	}
    815
    816	case EFC_EVT_SRRS_ELS_REQ_FAIL:	{
    817		/* not much we can do; will retry with the next RSCN */
    818		node_printf(node, "GID_PT failed to complete\n");
    819		WARN_ON(!node->els_req_cnt);
    820		node->els_req_cnt--;
    821		efc_node_transition(node, __efc_ns_idle, NULL);
    822		break;
    823	}
    824
    825	/* if receive RSCN here, queue up another discovery processing */
    826	case EFC_EVT_RSCN_RCVD: {
    827		node_printf(node, "RSCN received during GID_PT processing\n");
    828		node->rscn_pending = true;
    829		break;
    830	}
    831
    832	default:
    833		__efc_fabric_common(__func__, ctx, evt, arg);
    834	}
    835}
    836
    837void
    838__efc_ns_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
    839{
    840	struct efc_node *node = ctx->app;
    841	struct efc *efc = node->efc;
    842
    843	efc_node_evt_set(ctx, evt, __func__);
    844
    845	node_sm_trace();
    846
    847	/*
    848	 * Wait for RSCN received events (posted from the fabric controller)
    849	 * and restart the GIDPT name services query and processing.
    850	 */
    851
    852	switch (evt) {
    853	case EFC_EVT_ENTER:
    854		if (!node->rscn_pending)
    855			break;
    856
    857		node_printf(node, "RSCN pending, restart discovery\n");
    858		node->rscn_pending = false;
    859		fallthrough;
    860
    861	case EFC_EVT_RSCN_RCVD: {
    862		/* sm: / send GIDPT */
    863		/*
    864		 * If target RSCN processing is enabled,
    865		 * and this is target only (not initiator),
    866		 * and tgt_rscn_delay is non-zero,
    867		 * then we delay issuing the GID_PT
    868		 */
    869		if (efc->tgt_rscn_delay_msec != 0 &&
    870		    !node->nport->enable_ini && node->nport->enable_tgt &&
    871		    enable_target_rscn(efc)) {
    872			efc_node_transition(node, __efc_ns_gidpt_delay, NULL);
    873		} else {
    874			efc_ns_send_gidpt(node);
    875			efc_node_transition(node, __efc_ns_gidpt_wait_rsp,
    876					    NULL);
    877		}
    878		break;
    879	}
    880
    881	default:
    882		__efc_fabric_common(__func__, ctx, evt, arg);
    883	}
    884}
    885
    886static void
    887gidpt_delay_timer_cb(struct timer_list *t)
    888{
    889	struct efc_node *node = from_timer(node, t, gidpt_delay_timer);
    890
    891	del_timer(&node->gidpt_delay_timer);
    892
    893	efc_node_post_event(node, EFC_EVT_GIDPT_DELAY_EXPIRED, NULL);
    894}
    895
    896void
    897__efc_ns_gidpt_delay(struct efc_sm_ctx *ctx,
    898		     enum efc_sm_event evt, void *arg)
    899{
    900	struct efc_node *node = ctx->app;
    901	struct efc *efc = node->efc;
    902
    903	efc_node_evt_set(ctx, evt, __func__);
    904
    905	node_sm_trace();
    906
    907	switch (evt) {
    908	case EFC_EVT_ENTER: {
    909		u64 delay_msec, tmp;
    910
    911		/*
    912		 * Compute the delay time.
    913		 * Set to tgt_rscn_delay, if the time since last GIDPT
    914		 * is less than tgt_rscn_period, then use tgt_rscn_period.
    915		 */
    916		delay_msec = efc->tgt_rscn_delay_msec;
    917		tmp = jiffies_to_msecs(jiffies) - node->time_last_gidpt_msec;
    918		if (tmp < efc->tgt_rscn_period_msec)
    919			delay_msec = efc->tgt_rscn_period_msec;
    920
    921		timer_setup(&node->gidpt_delay_timer, &gidpt_delay_timer_cb,
    922			    0);
    923		mod_timer(&node->gidpt_delay_timer,
    924			  jiffies + msecs_to_jiffies(delay_msec));
    925
    926		break;
    927	}
    928
    929	case EFC_EVT_GIDPT_DELAY_EXPIRED:
    930		node->time_last_gidpt_msec = jiffies_to_msecs(jiffies);
    931
    932		efc_ns_send_gidpt(node);
    933		efc_node_transition(node, __efc_ns_gidpt_wait_rsp, NULL);
    934		break;
    935
    936	case EFC_EVT_RSCN_RCVD: {
    937		efc_log_debug(efc,
    938			      "RSCN received while in GIDPT delay - no action\n");
    939		break;
    940	}
    941
    942	default:
    943		__efc_fabric_common(__func__, ctx, evt, arg);
    944	}
    945}
    946
    947void
    948__efc_fabctl_init(struct efc_sm_ctx *ctx,
    949		  enum efc_sm_event evt, void *arg)
    950{
    951	struct efc_node *node = ctx->app;
    952
    953	node_sm_trace();
    954
    955	switch (evt) {
    956	case EFC_EVT_ENTER:
    957		/* no need to login to fabric controller, just send SCR */
    958		efc_send_scr(node);
    959		efc_node_transition(node, __efc_fabctl_wait_scr_rsp, NULL);
    960		break;
    961
    962	case EFC_EVT_NODE_ATTACH_OK:
    963		node->attached = true;
    964		break;
    965
    966	default:
    967		__efc_fabric_common(__func__, ctx, evt, arg);
    968	}
    969}
    970
    971void
    972__efc_fabctl_wait_scr_rsp(struct efc_sm_ctx *ctx,
    973			  enum efc_sm_event evt, void *arg)
    974{
    975	struct efc_node *node = ctx->app;
    976
    977	efc_node_evt_set(ctx, evt, __func__);
    978
    979	node_sm_trace();
    980
    981	/*
    982	 * Fabric controller node state machine:
    983	 * Wait for an SCR response from the fabric controller.
    984	 */
    985	switch (evt) {
    986	case EFC_EVT_SRRS_ELS_REQ_OK:
    987		if (efc_node_check_els_req(ctx, evt, arg, ELS_SCR,
    988					   __efc_fabric_common, __func__)) {
    989			return;
    990		}
    991		WARN_ON(!node->els_req_cnt);
    992		node->els_req_cnt--;
    993		efc_node_transition(node, __efc_fabctl_ready, NULL);
    994		break;
    995
    996	default:
    997		__efc_fabric_common(__func__, ctx, evt, arg);
    998	}
    999}
   1000
   1001static void
   1002efc_process_rscn(struct efc_node *node, struct efc_node_cb *cbdata)
   1003{
   1004	struct efc *efc = node->efc;
   1005	struct efc_nport *nport = node->nport;
   1006	struct efc_node *ns;
   1007
   1008	/* Forward this event to the name-services node */
   1009	ns = efc_node_find(nport, FC_FID_DIR_SERV);
   1010	if (ns)
   1011		efc_node_post_event(ns, EFC_EVT_RSCN_RCVD, cbdata);
   1012	else
   1013		efc_log_warn(efc, "can't find name server node\n");
   1014}
   1015
   1016void
   1017__efc_fabctl_ready(struct efc_sm_ctx *ctx,
   1018		   enum efc_sm_event evt, void *arg)
   1019{
   1020	struct efc_node_cb *cbdata = arg;
   1021	struct efc_node *node = ctx->app;
   1022
   1023	efc_node_evt_set(ctx, evt, __func__);
   1024
   1025	node_sm_trace();
   1026
   1027	/*
   1028	 * Fabric controller node state machine: Ready.
   1029	 * In this state, the fabric controller sends a RSCN, which is received
   1030	 * by this node and is forwarded to the name services node object; and
   1031	 * the RSCN LS_ACC is sent.
   1032	 */
   1033	switch (evt) {
   1034	case EFC_EVT_RSCN_RCVD: {
   1035		struct fc_frame_header *hdr = cbdata->header->dma.virt;
   1036
   1037		/*
   1038		 * sm: / process RSCN (forward to name services node),
   1039		 * send LS_ACC
   1040		 */
   1041		efc_process_rscn(node, cbdata);
   1042		efc_send_ls_acc(node, be16_to_cpu(hdr->fh_ox_id));
   1043		efc_node_transition(node, __efc_fabctl_wait_ls_acc_cmpl,
   1044				    NULL);
   1045		break;
   1046	}
   1047
   1048	default:
   1049		__efc_fabric_common(__func__, ctx, evt, arg);
   1050	}
   1051}
   1052
   1053void
   1054__efc_fabctl_wait_ls_acc_cmpl(struct efc_sm_ctx *ctx,
   1055			      enum efc_sm_event evt, void *arg)
   1056{
   1057	struct efc_node *node = ctx->app;
   1058
   1059	efc_node_evt_set(ctx, evt, __func__);
   1060
   1061	node_sm_trace();
   1062
   1063	switch (evt) {
   1064	case EFC_EVT_ENTER:
   1065		efc_node_hold_frames(node);
   1066		break;
   1067
   1068	case EFC_EVT_EXIT:
   1069		efc_node_accept_frames(node);
   1070		break;
   1071
   1072	case EFC_EVT_SRRS_ELS_CMPL_OK:
   1073		WARN_ON(!node->els_cmpl_cnt);
   1074		node->els_cmpl_cnt--;
   1075		efc_node_transition(node, __efc_fabctl_ready, NULL);
   1076		break;
   1077
   1078	default:
   1079		__efc_fabric_common(__func__, ctx, evt, arg);
   1080	}
   1081}
   1082
   1083static uint64_t
   1084efc_get_wwpn(struct fc_els_flogi *sp)
   1085{
   1086	return be64_to_cpu(sp->fl_wwnn);
   1087}
   1088
   1089static int
   1090efc_rnode_is_winner(struct efc_nport *nport)
   1091{
   1092	struct fc_els_flogi *remote_sp;
   1093	u64 remote_wwpn;
   1094	u64 local_wwpn = nport->wwpn;
   1095	u64 wwn_bump = 0;
   1096
   1097	remote_sp = (struct fc_els_flogi *)nport->domain->flogi_service_params;
   1098	remote_wwpn = efc_get_wwpn(remote_sp);
   1099
   1100	local_wwpn ^= wwn_bump;
   1101
   1102	efc_log_debug(nport->efc, "r: %llx\n",
   1103		      be64_to_cpu(remote_sp->fl_wwpn));
   1104	efc_log_debug(nport->efc, "l: %llx\n", local_wwpn);
   1105
   1106	if (remote_wwpn == local_wwpn) {
   1107		efc_log_warn(nport->efc,
   1108			     "WWPN of remote node [%08x %08x] matches local WWPN\n",
   1109			     (u32)(local_wwpn >> 32ll),
   1110			     (u32)local_wwpn);
   1111		return -1;
   1112	}
   1113
   1114	return (remote_wwpn > local_wwpn);
   1115}
   1116
   1117void
   1118__efc_p2p_wait_domain_attach(struct efc_sm_ctx *ctx,
   1119			     enum efc_sm_event evt, void *arg)
   1120{
   1121	struct efc_node *node = ctx->app;
   1122	struct efc *efc = node->efc;
   1123
   1124	efc_node_evt_set(ctx, evt, __func__);
   1125
   1126	node_sm_trace();
   1127
   1128	switch (evt) {
   1129	case EFC_EVT_ENTER:
   1130		efc_node_hold_frames(node);
   1131		break;
   1132
   1133	case EFC_EVT_EXIT:
   1134		efc_node_accept_frames(node);
   1135		break;
   1136
   1137	case EFC_EVT_DOMAIN_ATTACH_OK: {
   1138		struct efc_nport *nport = node->nport;
   1139		struct efc_node *rnode;
   1140
   1141		/*
   1142		 * this transient node (SID=0 (recv'd FLOGI)
   1143		 * or DID=fabric (sent FLOGI))
   1144		 * is the p2p winner, will use a separate node
   1145		 * to send PLOGI to peer
   1146		 */
   1147		WARN_ON(!node->nport->p2p_winner);
   1148
   1149		rnode = efc_node_find(nport, node->nport->p2p_remote_port_id);
   1150		if (rnode) {
   1151			/*
   1152			 * the "other" transient p2p node has
   1153			 * already kicked off the
   1154			 * new node from which PLOGI is sent
   1155			 */
   1156			node_printf(node,
   1157				    "Node with fc_id x%x already exists\n",
   1158				    rnode->rnode.fc_id);
   1159		} else {
   1160			/*
   1161			 * create new node (SID=1, DID=2)
   1162			 * from which to send PLOGI
   1163			 */
   1164			rnode = efc_node_alloc(nport,
   1165					       nport->p2p_remote_port_id,
   1166						false, false);
   1167			if (!rnode) {
   1168				efc_log_err(efc, "node alloc failed\n");
   1169				return;
   1170			}
   1171
   1172			efc_fabric_notify_topology(node);
   1173			/* sm: / allocate p2p remote node */
   1174			efc_node_transition(rnode, __efc_p2p_rnode_init,
   1175					    NULL);
   1176		}
   1177
   1178		/*
   1179		 * the transient node (SID=0 or DID=fabric)
   1180		 * has served its purpose
   1181		 */
   1182		if (node->rnode.fc_id == 0) {
   1183			/*
   1184			 * if this is the SID=0 node,
   1185			 * move to the init state in case peer
   1186			 * has restarted FLOGI discovery and FLOGI is pending
   1187			 */
   1188			/* don't send PLOGI on efc_d_init entry */
   1189			efc_node_init_device(node, false);
   1190		} else {
   1191			/*
   1192			 * if this is the DID=fabric node
   1193			 * (we initiated FLOGI), shut it down
   1194			 */
   1195			node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
   1196			efc_fabric_initiate_shutdown(node);
   1197		}
   1198		break;
   1199	}
   1200
   1201	default:
   1202		__efc_fabric_common(__func__, ctx, evt, arg);
   1203	}
   1204}
   1205
   1206void
   1207__efc_p2p_rnode_init(struct efc_sm_ctx *ctx,
   1208		     enum efc_sm_event evt, void *arg)
   1209{
   1210	struct efc_node_cb *cbdata = arg;
   1211	struct efc_node *node = ctx->app;
   1212
   1213	efc_node_evt_set(ctx, evt, __func__);
   1214
   1215	node_sm_trace();
   1216
   1217	switch (evt) {
   1218	case EFC_EVT_ENTER:
   1219		/* sm: / send PLOGI */
   1220		efc_send_plogi(node);
   1221		efc_node_transition(node, __efc_p2p_wait_plogi_rsp, NULL);
   1222		break;
   1223
   1224	case EFC_EVT_ABTS_RCVD:
   1225		/* sm: send BA_ACC */
   1226		efc_send_bls_acc(node, cbdata->header->dma.virt);
   1227
   1228		break;
   1229
   1230	default:
   1231		__efc_fabric_common(__func__, ctx, evt, arg);
   1232	}
   1233}
   1234
   1235void
   1236__efc_p2p_wait_flogi_acc_cmpl(struct efc_sm_ctx *ctx,
   1237			      enum efc_sm_event evt, void *arg)
   1238{
   1239	struct efc_node_cb *cbdata = arg;
   1240	struct efc_node *node = ctx->app;
   1241
   1242	efc_node_evt_set(ctx, evt, __func__);
   1243
   1244	node_sm_trace();
   1245
   1246	switch (evt) {
   1247	case EFC_EVT_ENTER:
   1248		efc_node_hold_frames(node);
   1249		break;
   1250
   1251	case EFC_EVT_EXIT:
   1252		efc_node_accept_frames(node);
   1253		break;
   1254
   1255	case EFC_EVT_SRRS_ELS_CMPL_OK:
   1256		WARN_ON(!node->els_cmpl_cnt);
   1257		node->els_cmpl_cnt--;
   1258
   1259		/* sm: if p2p_winner / domain_attach */
   1260		if (node->nport->p2p_winner) {
   1261			efc_node_transition(node,
   1262					    __efc_p2p_wait_domain_attach,
   1263					NULL);
   1264			if (!node->nport->domain->attached) {
   1265				node_printf(node, "Domain not attached\n");
   1266				efc_domain_attach(node->nport->domain,
   1267						  node->nport->p2p_port_id);
   1268			} else {
   1269				node_printf(node, "Domain already attached\n");
   1270				efc_node_post_event(node,
   1271						    EFC_EVT_DOMAIN_ATTACH_OK,
   1272						    NULL);
   1273			}
   1274		} else {
   1275			/* this node has served its purpose;
   1276			 * we'll expect a PLOGI on a separate
   1277			 * node (remote SID=0x1); return this node
   1278			 * to init state in case peer
   1279			 * restarts discovery -- it may already
   1280			 * have (pending frames may exist).
   1281			 */
   1282			/* don't send PLOGI on efc_d_init entry */
   1283			efc_node_init_device(node, false);
   1284		}
   1285		break;
   1286
   1287	case EFC_EVT_SRRS_ELS_CMPL_FAIL:
   1288		/*
   1289		 * LS_ACC failed, possibly due to link down;
   1290		 * shutdown node and wait
   1291		 * for FLOGI discovery to restart
   1292		 */
   1293		node_printf(node, "FLOGI LS_ACC failed, shutting down\n");
   1294		WARN_ON(!node->els_cmpl_cnt);
   1295		node->els_cmpl_cnt--;
   1296		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
   1297		efc_fabric_initiate_shutdown(node);
   1298		break;
   1299
   1300	case EFC_EVT_ABTS_RCVD: {
   1301		/* sm: / send BA_ACC */
   1302		efc_send_bls_acc(node, cbdata->header->dma.virt);
   1303		break;
   1304	}
   1305
   1306	default:
   1307		__efc_fabric_common(__func__, ctx, evt, arg);
   1308	}
   1309}
   1310
   1311void
   1312__efc_p2p_wait_plogi_rsp(struct efc_sm_ctx *ctx,
   1313			 enum efc_sm_event evt, void *arg)
   1314{
   1315	struct efc_node_cb *cbdata = arg;
   1316	struct efc_node *node = ctx->app;
   1317
   1318	efc_node_evt_set(ctx, evt, __func__);
   1319
   1320	node_sm_trace();
   1321
   1322	switch (evt) {
   1323	case EFC_EVT_SRRS_ELS_REQ_OK: {
   1324		int rc;
   1325
   1326		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
   1327					   __efc_fabric_common, __func__)) {
   1328			return;
   1329		}
   1330		WARN_ON(!node->els_req_cnt);
   1331		node->els_req_cnt--;
   1332		/* sm: / save sparams, efc_node_attach */
   1333		efc_node_save_sparms(node, cbdata->els_rsp.virt);
   1334		rc = efc_node_attach(node);
   1335		efc_node_transition(node, __efc_p2p_wait_node_attach, NULL);
   1336		if (rc < 0)
   1337			efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
   1338					    NULL);
   1339		break;
   1340	}
   1341	case EFC_EVT_SRRS_ELS_REQ_FAIL: {
   1342		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
   1343					   __efc_fabric_common, __func__)) {
   1344			return;
   1345		}
   1346		node_printf(node, "PLOGI failed, shutting down\n");
   1347		WARN_ON(!node->els_req_cnt);
   1348		node->els_req_cnt--;
   1349		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
   1350		efc_fabric_initiate_shutdown(node);
   1351		break;
   1352	}
   1353
   1354	case EFC_EVT_PLOGI_RCVD: {
   1355		struct fc_frame_header *hdr = cbdata->header->dma.virt;
   1356		/* if we're in external loopback mode, just send LS_ACC */
   1357		if (node->efc->external_loopback) {
   1358			efc_send_plogi_acc(node, be16_to_cpu(hdr->fh_ox_id));
   1359		} else {
   1360			/*
   1361			 * if this isn't external loopback,
   1362			 * pass to default handler
   1363			 */
   1364			__efc_fabric_common(__func__, ctx, evt, arg);
   1365		}
   1366		break;
   1367	}
   1368	case EFC_EVT_PRLI_RCVD:
   1369		/* I, or I+T */
   1370		/* sent PLOGI and before completion was seen, received the
   1371		 * PRLI from the remote node (WCQEs and RCQEs come in on
   1372		 * different queues and order of processing cannot be assumed)
   1373		 * Save OXID so PRLI can be sent after the attach and continue
   1374		 * to wait for PLOGI response
   1375		 */
   1376		efc_process_prli_payload(node, cbdata->payload->dma.virt);
   1377		efc_send_ls_acc_after_attach(node,
   1378					     cbdata->header->dma.virt,
   1379					     EFC_NODE_SEND_LS_ACC_PRLI);
   1380		efc_node_transition(node, __efc_p2p_wait_plogi_rsp_recvd_prli,
   1381				    NULL);
   1382		break;
   1383	default:
   1384		__efc_fabric_common(__func__, ctx, evt, arg);
   1385	}
   1386}
   1387
   1388void
   1389__efc_p2p_wait_plogi_rsp_recvd_prli(struct efc_sm_ctx *ctx,
   1390				    enum efc_sm_event evt, void *arg)
   1391{
   1392	struct efc_node_cb *cbdata = arg;
   1393	struct efc_node *node = ctx->app;
   1394
   1395	efc_node_evt_set(ctx, evt, __func__);
   1396
   1397	node_sm_trace();
   1398
   1399	switch (evt) {
   1400	case EFC_EVT_ENTER:
   1401		/*
   1402		 * Since we've received a PRLI, we have a port login and will
   1403		 * just need to wait for the PLOGI response to do the node
   1404		 * attach and then we can send the LS_ACC for the PRLI. If,
   1405		 * during this time, we receive FCP_CMNDs (which is possible
   1406		 * since we've already sent a PRLI and our peer may have
   1407		 * accepted).
   1408		 * At this time, we are not waiting on any other unsolicited
   1409		 * frames to continue with the login process. Thus, it will not
   1410		 * hurt to hold frames here.
   1411		 */
   1412		efc_node_hold_frames(node);
   1413		break;
   1414
   1415	case EFC_EVT_EXIT:
   1416		efc_node_accept_frames(node);
   1417		break;
   1418
   1419	case EFC_EVT_SRRS_ELS_REQ_OK: {	/* PLOGI response received */
   1420		int rc;
   1421
   1422		/* Completion from PLOGI sent */
   1423		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
   1424					   __efc_fabric_common, __func__)) {
   1425			return;
   1426		}
   1427		WARN_ON(!node->els_req_cnt);
   1428		node->els_req_cnt--;
   1429		/* sm: / save sparams, efc_node_attach */
   1430		efc_node_save_sparms(node, cbdata->els_rsp.virt);
   1431		rc = efc_node_attach(node);
   1432		efc_node_transition(node, __efc_p2p_wait_node_attach, NULL);
   1433		if (rc < 0)
   1434			efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
   1435					    NULL);
   1436		break;
   1437	}
   1438	case EFC_EVT_SRRS_ELS_REQ_FAIL:	/* PLOGI response received */
   1439	case EFC_EVT_SRRS_ELS_REQ_RJT:
   1440		/* PLOGI failed, shutdown the node */
   1441		if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
   1442					   __efc_fabric_common, __func__)) {
   1443			return;
   1444		}
   1445		WARN_ON(!node->els_req_cnt);
   1446		node->els_req_cnt--;
   1447		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
   1448		efc_fabric_initiate_shutdown(node);
   1449		break;
   1450
   1451	default:
   1452		__efc_fabric_common(__func__, ctx, evt, arg);
   1453	}
   1454}
   1455
   1456void
   1457__efc_p2p_wait_node_attach(struct efc_sm_ctx *ctx,
   1458			   enum efc_sm_event evt, void *arg)
   1459{
   1460	struct efc_node_cb *cbdata = arg;
   1461	struct efc_node *node = ctx->app;
   1462
   1463	efc_node_evt_set(ctx, evt, __func__);
   1464
   1465	node_sm_trace();
   1466
   1467	switch (evt) {
   1468	case EFC_EVT_ENTER:
   1469		efc_node_hold_frames(node);
   1470		break;
   1471
   1472	case EFC_EVT_EXIT:
   1473		efc_node_accept_frames(node);
   1474		break;
   1475
   1476	case EFC_EVT_NODE_ATTACH_OK:
   1477		node->attached = true;
   1478		switch (node->send_ls_acc) {
   1479		case EFC_NODE_SEND_LS_ACC_PRLI: {
   1480			efc_d_send_prli_rsp(node->ls_acc_io,
   1481					    node->ls_acc_oxid);
   1482			node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
   1483			node->ls_acc_io = NULL;
   1484			break;
   1485		}
   1486		case EFC_NODE_SEND_LS_ACC_PLOGI: /* Can't happen in P2P */
   1487		case EFC_NODE_SEND_LS_ACC_NONE:
   1488		default:
   1489			/* Normal case for I */
   1490			/* sm: send_plogi_acc is not set / send PLOGI acc */
   1491			efc_node_transition(node, __efc_d_port_logged_in,
   1492					    NULL);
   1493			break;
   1494		}
   1495		break;
   1496
   1497	case EFC_EVT_NODE_ATTACH_FAIL:
   1498		/* node attach failed, shutdown the node */
   1499		node->attached = false;
   1500		node_printf(node, "Node attach failed\n");
   1501		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
   1502		efc_fabric_initiate_shutdown(node);
   1503		break;
   1504
   1505	case EFC_EVT_SHUTDOWN:
   1506		node_printf(node, "%s received\n", efc_sm_event_name(evt));
   1507		node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
   1508		efc_node_transition(node,
   1509				    __efc_fabric_wait_attach_evt_shutdown,
   1510				     NULL);
   1511		break;
   1512	case EFC_EVT_PRLI_RCVD:
   1513		node_printf(node, "%s: PRLI received before node is attached\n",
   1514			    efc_sm_event_name(evt));
   1515		efc_process_prli_payload(node, cbdata->payload->dma.virt);
   1516		efc_send_ls_acc_after_attach(node,
   1517					     cbdata->header->dma.virt,
   1518				EFC_NODE_SEND_LS_ACC_PRLI);
   1519		break;
   1520
   1521	default:
   1522		__efc_fabric_common(__func__, ctx, evt, arg);
   1523	}
   1524}
   1525
   1526int
   1527efc_p2p_setup(struct efc_nport *nport)
   1528{
   1529	struct efc *efc = nport->efc;
   1530	int rnode_winner;
   1531
   1532	rnode_winner = efc_rnode_is_winner(nport);
   1533
   1534	/* set nport flags to indicate p2p "winner" */
   1535	if (rnode_winner == 1) {
   1536		nport->p2p_remote_port_id = 0;
   1537		nport->p2p_port_id = 0;
   1538		nport->p2p_winner = false;
   1539	} else if (rnode_winner == 0) {
   1540		nport->p2p_remote_port_id = 2;
   1541		nport->p2p_port_id = 1;
   1542		nport->p2p_winner = true;
   1543	} else {
   1544		/* no winner; only okay if external loopback enabled */
   1545		if (nport->efc->external_loopback) {
   1546			/*
   1547			 * External loopback mode enabled;
   1548			 * local nport and remote node
   1549			 * will be registered with an NPortID = 1;
   1550			 */
   1551			efc_log_debug(efc,
   1552				      "External loopback mode enabled\n");
   1553			nport->p2p_remote_port_id = 1;
   1554			nport->p2p_port_id = 1;
   1555			nport->p2p_winner = true;
   1556		} else {
   1557			efc_log_warn(efc,
   1558				     "failed to determine p2p winner\n");
   1559			return rnode_winner;
   1560		}
   1561	}
   1562	return 0;
   1563}