• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 static void
efc_fabric_initiate_shutdown(struct efc_node * node)24 efc_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 
50 static void
__efc_fabric_common(const char * funcname,struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
72 void
__efc_fabric_init(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
99 void
efc_fabric_set_topology(struct efc_node * node,enum efc_nport_topology topology)100 efc_fabric_set_topology(struct efc_node *node,
101 			enum efc_nport_topology topology)
102 {
103 	node->nport->topology = topology;
104 }
105 
106 void
efc_fabric_notify_topology(struct efc_node * node)107 efc_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 
efc_rnode_is_nport(struct fc_els_flogi * rsp)125 static 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 
130 void
__efc_fabric_flogi_wait_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
236 void
__efc_vport_fabric_init(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
258 void
__efc_fabric_fdisc_wait_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
305 static int
efc_start_ns_node(struct efc_nport * nport)306 efc_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 
330 static int
efc_start_fabctl_node(struct efc_nport * nport)331 efc_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 
352 void
__efc_fabric_wait_domain_attach(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
393 void
__efc_fabric_idle(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
411 void
__efc_ns_init(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
431 void
__efc_ns_plogi_wait_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
467 void
__efc_ns_wait_node_attach(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
521 void
__efc_fabric_wait_attach_evt_shutdown(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
565 void
__efc_ns_rftid_wait_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
600 void
__efc_ns_rffid_wait_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
646 static int
efc_process_gidpt_payload(struct efc_node * node,void * data,u32 gidpt_len)647 efc_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 
786 void
__efc_ns_gidpt_wait_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
837 void
__efc_ns_idle(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
886 static void
gidpt_delay_timer_cb(struct timer_list * t)887 gidpt_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 
896 void
__efc_ns_gidpt_delay(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
947 void
__efc_fabctl_init(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
971 void
__efc_fabctl_wait_scr_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1001 static void
efc_process_rscn(struct efc_node * node,struct efc_node_cb * cbdata)1002 efc_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 
1016 void
__efc_fabctl_ready(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1053 void
__efc_fabctl_wait_ls_acc_cmpl(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1083 static uint64_t
efc_get_wwpn(struct fc_els_flogi * sp)1084 efc_get_wwpn(struct fc_els_flogi *sp)
1085 {
1086 	return be64_to_cpu(sp->fl_wwnn);
1087 }
1088 
1089 static int
efc_rnode_is_winner(struct efc_nport * nport)1090 efc_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 
1117 void
__efc_p2p_wait_domain_attach(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1206 void
__efc_p2p_rnode_init(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1235 void
__efc_p2p_wait_flogi_acc_cmpl(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1311 void
__efc_p2p_wait_plogi_rsp(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1388 void
__efc_p2p_wait_plogi_rsp_recvd_prli(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1456 void
__efc_p2p_wait_node_attach(struct efc_sm_ctx * ctx,enum efc_sm_event evt,void * arg)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 
1526 int
efc_p2p_setup(struct efc_nport * nport)1527 efc_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 }
1564