brintos

brintos / linux-shallow public Read only

0
0
Text · 35.6 KiB · 9661eea Raw
1564 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term4 * “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 States17 * ns_sm Node State Machine: Name/Directory Services States18 * p2p_sm Node State Machine: Point-to-Point Node States19 */20 21#include "efc.h"22 23static void24efc_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 away34		 * or sometime later, will check node->attached later in35		 * shutdown process36		 */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 function46	 */47	efc_node_initiate_cleanup(node);48}49 50static void51__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 72void73__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 99void100efc_fabric_set_topology(struct efc_node *node,101			enum efc_nport_topology topology)102{103	node->nport->topology = topology;104}105 106void107efc_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 nport114	 * and send topology notification115	 */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 130void131__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_OK188				 */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 the199			 * remote SID=1 node;200			 * this node has served its purpose201			 */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 link216		 * up and the domain ready217		 */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 236void237__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 258void259__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 int306efc_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 only320	 *  1. from within state machine or321	 *  2. if after alloc322	 */323	if (ns->efc->nodedb_mask & EFC_NODEDB_PAUSE_NAMESERVER)324		efc_node_pause(ns, __efc_ns_init);325	else326		efc_node_transition(ns, __efc_ns_init, NULL);327	return 0;328}329 330static int331efc_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 only345	 *  1. from within state machine or346	 *  2. if after alloc347	 */348	efc_node_transition(fabctl, __efc_fabctl_init, NULL);349	return 0;350}351 352void353__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 393void394__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 411void412__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 431void432__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 467void468__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 521void522__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 565void566__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 600void601__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 int647efc_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 node729		 * is a target, then post the node missing event.730		 * if we're target and we have enabled731		 * 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 automatically770			 * if initiator771			 */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 786void787__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_IDs798	 * 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 837void838__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_PT868		 */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 void887gidpt_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 896void897__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 GIDPT914		 * 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 947void948__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 971void972__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 void1002efc_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	else1013		efc_log_warn(efc, "can't find name server node\n");1014}1015 1016void1017__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 received1030	 * by this node and is forwarded to the name services node object; and1031	 * 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_ACC1040		 */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 1053void1054__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_t1084efc_get_wwpn(struct fc_els_flogi *sp)1085{1086	return be64_to_cpu(sp->fl_wwnn);1087}1088 1089static int1090efc_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 1117void1118__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 node1145		 * to send PLOGI to peer1146		 */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 has1153			 * already kicked off the1154			 * new node from which PLOGI is sent1155			 */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 PLOGI1163			 */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 purpose1181		 */1182		if (node->rnode.fc_id == 0) {1183			/*1184			 * if this is the SID=0 node,1185			 * move to the init state in case peer1186			 * has restarted FLOGI discovery and FLOGI is pending1187			 */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 node1193			 * (we initiated FLOGI), shut it down1194			 */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 1206void1207__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 1235void1236__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 separate1277			 * node (remote SID=0x1); return this node1278			 * to init state in case peer1279			 * restarts discovery -- it may already1280			 * 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 wait1291		 * for FLOGI discovery to restart1292		 */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 1311void1312__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 handler1363			 */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 the1371		 * PRLI from the remote node (WCQEs and RCQEs come in on1372		 * different queues and order of processing cannot be assumed)1373		 * Save OXID so PRLI can be sent after the attach and continue1374		 * to wait for PLOGI response1375		 */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 1388void1389__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 will1403		 * just need to wait for the PLOGI response to do the node1404		 * attach and then we can send the LS_ACC for the PRLI. If,1405		 * during this time, we receive FCP_CMNDs (which is possible1406		 * since we've already sent a PRLI and our peer may have1407		 * accepted).1408		 * At this time, we are not waiting on any other unsolicited1409		 * frames to continue with the login process. Thus, it will not1410		 * 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 1456void1457__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 1526int1527efc_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 node1549			 * 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}1564