1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
4 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
8 * This file implements remote node state machines for:
10 * - Fabric controller events.
11 * - Name/directory services interaction.
12 * - Point-to-point logins.
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
24 efc_fabric_initiate_shutdown(struct efc_node *node)
26 struct efc *efc = node->efc;
28 node->els_io_enabled = false;
33 /* issue hw node free; don't care if succeeds right away
34 * or sometime later, will check node->attached later in
37 rc = efc_cmd_node_detach(efc, &node->rnode);
39 node_printf(node, "Failed freeing HW node, rc=%d\n",
44 * node has either been detached or is in the process of being detached,
45 * call common node's initiate cleanup function
47 efc_node_initiate_cleanup(node);
51 __efc_fabric_common(const char *funcname, struct efc_sm_ctx *ctx,
52 enum efc_sm_event evt, void *arg)
54 struct efc_node *node = NULL;
59 case EFC_EVT_DOMAIN_ATTACH_OK:
61 case EFC_EVT_SHUTDOWN:
62 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
63 efc_fabric_initiate_shutdown(node);
67 /* call default event handler common to all nodes */
68 __efc_node_common(funcname, ctx, evt, arg);
73 __efc_fabric_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
76 struct efc_node *node = ctx->app;
77 struct efc *efc = node->efc;
79 efc_node_evt_set(ctx, evt, __func__);
85 efc_log_debug(efc, ">>> reenter !!\n");
91 efc_node_transition(node, __efc_fabric_flogi_wait_rsp, NULL);
95 __efc_fabric_common(__func__, ctx, evt, arg);
100 efc_fabric_set_topology(struct efc_node *node,
101 enum efc_nport_topology topology)
103 node->nport->topology = topology;
107 efc_fabric_notify_topology(struct efc_node *node)
109 struct efc_node *tmp_node;
113 * now loop through the nodes in the nport
114 * and send topology notification
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);
125 static bool efc_rnode_is_nport(struct fc_els_flogi *rsp)
127 return !(ntohs(rsp->fl_csp.sp_features) & FC_SP_FT_FPORT);
131 __efc_fabric_flogi_wait_rsp(struct efc_sm_ctx *ctx,
132 enum efc_sm_event evt, void *arg)
134 struct efc_node_cb *cbdata = arg;
135 struct efc_node *node = ctx->app;
137 efc_node_evt_set(ctx, evt, __func__);
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__)) {
147 WARN_ON(!node->els_req_cnt);
150 memcpy(node->nport->domain->flogi_service_params,
151 cbdata->els_rsp.virt,
152 sizeof(struct fc_els_flogi));
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,
163 efc_node_transition(node,
164 __efc_fabric_wait_domain_attach,
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)) {
173 "p2p setup failed, shutting down node\n");
174 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
175 efc_fabric_initiate_shutdown(node);
179 if (node->nport->p2p_winner) {
180 efc_node_transition(node,
181 __efc_p2p_wait_domain_attach,
183 if (node->nport->domain->attached &&
184 !node->nport->domain->domain_notify_pend) {
187 * just send ATTACH_OK
190 "p2p winner, domain already attached\n");
191 efc_node_post_event(node,
192 EFC_EVT_DOMAIN_ATTACH_OK,
197 * peer is p2p winner;
198 * PLOGI will be received on the
200 * this node has served its purpose
202 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
203 efc_fabric_initiate_shutdown(node);
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;
214 * with these errors, we have no recovery,
215 * so shutdown the nport, leave the link
216 * up and the domain ready
218 if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI,
219 __efc_fabric_common, __func__)) {
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);
227 efc_sm_post_event(&nport->sm, EFC_EVT_SHUTDOWN, NULL);
232 __efc_fabric_common(__func__, ctx, evt, arg);
237 __efc_vport_fabric_init(struct efc_sm_ctx *ctx,
238 enum efc_sm_event evt, void *arg)
240 struct efc_node *node = ctx->app;
242 efc_node_evt_set(ctx, evt, __func__);
248 /* sm: / send FDISC */
249 efc_send_fdisc(node);
250 efc_node_transition(node, __efc_fabric_fdisc_wait_rsp, NULL);
254 __efc_fabric_common(__func__, ctx, evt, arg);
259 __efc_fabric_fdisc_wait_rsp(struct efc_sm_ctx *ctx,
260 enum efc_sm_event evt, void *arg)
262 struct efc_node_cb *cbdata = arg;
263 struct efc_node *node = ctx->app;
265 efc_node_evt_set(ctx, evt, __func__);
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__)) {
277 WARN_ON(!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,
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__)) {
292 WARN_ON(!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);
301 __efc_fabric_common(__func__, ctx, evt, arg);
306 efc_start_ns_node(struct efc_nport *nport)
310 /* Instantiate a name services node */
311 ns = efc_node_find(nport, FC_FID_DIR_SERV);
313 ns = efc_node_alloc(nport, FC_FID_DIR_SERV, false, false);
318 * for found ns, should we be transitioning from here?
319 * breaks transition only
320 * 1. from within state machine or
323 if (ns->efc->nodedb_mask & EFC_NODEDB_PAUSE_NAMESERVER)
324 efc_node_pause(ns, __efc_ns_init);
326 efc_node_transition(ns, __efc_ns_init, NULL);
331 efc_start_fabctl_node(struct efc_nport *nport)
333 struct efc_node *fabctl;
335 fabctl = efc_node_find(nport, FC_FID_FCTRL);
337 fabctl = efc_node_alloc(nport, FC_FID_FCTRL,
343 * for found ns, should we be transitioning from here?
344 * breaks transition only
345 * 1. from within state machine or
348 efc_node_transition(fabctl, __efc_fabctl_init, NULL);
353 __efc_fabric_wait_domain_attach(struct efc_sm_ctx *ctx,
354 enum efc_sm_event evt, void *arg)
356 struct efc_node *node = ctx->app;
358 efc_node_evt_set(ctx, evt, __func__);
364 efc_node_hold_frames(node);
368 efc_node_accept_frames(node);
370 case EFC_EVT_DOMAIN_ATTACH_OK:
371 case EFC_EVT_NPORT_ATTACH_OK: {
374 rc = efc_start_ns_node(node->nport);
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);
385 efc_node_transition(node, __efc_fabric_idle, NULL);
389 __efc_fabric_common(__func__, ctx, evt, arg);
394 __efc_fabric_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt,
397 struct efc_node *node = ctx->app;
399 efc_node_evt_set(ctx, evt, __func__);
404 case EFC_EVT_DOMAIN_ATTACH_OK:
407 __efc_fabric_common(__func__, ctx, evt, arg);
412 __efc_ns_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
414 struct efc_node *node = ctx->app;
416 efc_node_evt_set(ctx, evt, __func__);
422 /* sm: / send PLOGI */
423 efc_send_plogi(node);
424 efc_node_transition(node, __efc_ns_plogi_wait_rsp, NULL);
427 __efc_fabric_common(__func__, ctx, evt, arg);
432 __efc_ns_plogi_wait_rsp(struct efc_sm_ctx *ctx,
433 enum efc_sm_event evt, void *arg)
435 struct efc_node_cb *cbdata = arg;
436 struct efc_node *node = ctx->app;
438 efc_node_evt_set(ctx, evt, __func__);
443 case EFC_EVT_SRRS_ELS_REQ_OK: {
446 /* Save service parameters */
447 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
448 __efc_fabric_common, __func__)) {
451 WARN_ON(!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);
458 efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
463 __efc_fabric_common(__func__, ctx, evt, arg);
468 __efc_ns_wait_node_attach(struct efc_sm_ctx *ctx,
469 enum efc_sm_event evt, void *arg)
471 struct efc_node *node = ctx->app;
473 efc_node_evt_set(ctx, evt, __func__);
479 efc_node_hold_frames(node);
483 efc_node_accept_frames(node);
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);
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);
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,
510 * if receive RSCN just ignore,
511 * we haven't sent GID_PT yet (ACC sent by fabctl node)
513 case EFC_EVT_RSCN_RCVD:
517 __efc_fabric_common(__func__, ctx, evt, arg);
522 __efc_fabric_wait_attach_evt_shutdown(struct efc_sm_ctx *ctx,
523 enum efc_sm_event evt, void *arg)
525 struct efc_node *node = ctx->app;
527 efc_node_evt_set(ctx, evt, __func__);
533 efc_node_hold_frames(node);
537 efc_node_accept_frames(node);
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);
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);
555 /* ignore shutdown event as we're already in shutdown path */
556 case EFC_EVT_SHUTDOWN:
557 node_printf(node, "Shutdown event received\n");
561 __efc_fabric_common(__func__, ctx, evt, arg);
566 __efc_ns_rftid_wait_rsp(struct efc_sm_ctx *ctx,
567 enum efc_sm_event evt, void *arg)
569 struct efc_node *node = ctx->app;
571 efc_node_evt_set(ctx, evt, __func__);
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__)) {
581 WARN_ON(!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);
589 * if receive RSCN just ignore,
590 * we haven't sent GID_PT yet (ACC sent by fabctl node)
592 case EFC_EVT_RSCN_RCVD:
596 __efc_fabric_common(__func__, ctx, evt, arg);
601 __efc_ns_rffid_wait_rsp(struct efc_sm_ctx *ctx,
602 enum efc_sm_event evt, void *arg)
604 struct efc_node *node = ctx->app;
606 efc_node_evt_set(ctx, evt, __func__);
611 * Waits for an RFFID response event;
612 * if rscn enabled, a GIDPT name services request is issued.
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__)) {
620 WARN_ON(!node->els_req_cnt);
622 if (node->nport->enable_rscn) {
623 /* sm: if enable_rscn / send GIDPT */
624 efc_ns_send_gidpt(node);
626 efc_node_transition(node, __efc_ns_gidpt_wait_rsp,
629 /* if 'T' only, we're done, go to idle */
630 efc_node_transition(node, __efc_ns_idle, NULL);
635 * if receive RSCN just ignore,
636 * we haven't sent GID_PT yet (ACC sent by fabctl node)
638 case EFC_EVT_RSCN_RCVD:
642 __efc_fabric_common(__func__, ctx, evt, arg);
647 efc_process_gidpt_payload(struct efc_node *node,
648 void *data, u32 gidpt_len)
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;
656 struct efc_node **active_nodes;
659 struct fc_ct_hdr hdr;
660 struct fc_gid_pn_resp pn_rsp;
662 struct fc_gid_pn_resp *gidpt;
666 gidpt = &rsp->pn_rsp;
667 residual = be16_to_cpu(rsp->hdr.ct_mr_size);
670 efc_log_debug(node->efc, "residual is %u words\n", residual);
672 if (be16_to_cpu(rsp->hdr.ct_cmd) == FC_FS_RJT) {
674 "GIDPT request failed: rsn x%x rsn_expl x%x\n",
675 rsp->hdr.ct_reason, rsp->hdr.ct_explan);
679 plist_count = (gidpt_len - sizeof(struct fc_ct_hdr)) / sizeof(*gidpt);
681 /* Count the number of nodes */
683 xa_for_each(&nport->lookup, index, n) {
687 /* Allocate a buffer for all nodes */
688 active_nodes = kcalloc(port_count, sizeof(*active_nodes), GFP_ATOMIC);
690 node_printf(node, "efc_malloc failed\n");
694 /* Fill buffer with fc_id of active nodes */
696 xa_for_each(&nport->lookup, index, n) {
697 port_id = n->rnode.fc_id;
701 case FC_FID_DIR_SERV:
704 if (port_id != FC_FID_DOM_MGR)
705 active_nodes[i++] = n;
710 /* update the active nodes buffer */
711 for (i = 0; i < plist_count; i++) {
712 hton24(gidpt[i].fp_fid, port_id);
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;
721 if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
725 /* Those remaining in the active_nodes[] are now gone ! */
726 for (i = 0; i < port_count; i++) {
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.
733 if (!active_nodes[i])
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);
742 "GID_PT: skipping non-tgt port_id x%06x\n",
743 active_nodes[i]->rnode.fc_id);
748 for (i = 0; i < plist_count; i++) {
749 hton24(gidpt[i].fp_fid, port_id);
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)
758 newnode = efc_node_find(nport, port_id);
760 if (!node->nport->enable_ini)
763 newnode = efc_node_alloc(nport, port_id, false, false);
765 efc_log_err(efc, "efc_node_alloc() failed\n");
769 * send PLOGI automatically
772 efc_node_init_device(newnode, true);
775 if (node->nport->enable_ini && newnode->targ) {
776 efc_node_post_event(newnode, EFC_EVT_NODE_REFOUND,
780 if (gidpt[i].fp_resvd & FC_NS_FID_LAST)
787 __efc_ns_gidpt_wait_rsp(struct efc_sm_ctx *ctx,
788 enum efc_sm_event evt, void *arg)
790 struct efc_node_cb *cbdata = arg;
791 struct efc_node *node = ctx->app;
793 efc_node_evt_set(ctx, evt, __func__);
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.
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__)) {
807 WARN_ON(!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);
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);
821 efc_node_transition(node, __efc_ns_idle, NULL);
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;
833 __efc_fabric_common(__func__, ctx, evt, arg);
838 __efc_ns_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
840 struct efc_node *node = ctx->app;
841 struct efc *efc = node->efc;
843 efc_node_evt_set(ctx, evt, __func__);
848 * Wait for RSCN received events (posted from the fabric controller)
849 * and restart the GIDPT name services query and processing.
854 if (!node->rscn_pending)
857 node_printf(node, "RSCN pending, restart discovery\n");
858 node->rscn_pending = false;
861 case EFC_EVT_RSCN_RCVD: {
862 /* sm: / send GIDPT */
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
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);
874 efc_ns_send_gidpt(node);
875 efc_node_transition(node, __efc_ns_gidpt_wait_rsp,
882 __efc_fabric_common(__func__, ctx, evt, arg);
887 gidpt_delay_timer_cb(struct timer_list *t)
889 struct efc_node *node = from_timer(node, t, gidpt_delay_timer);
891 del_timer(&node->gidpt_delay_timer);
893 efc_node_post_event(node, EFC_EVT_GIDPT_DELAY_EXPIRED, NULL);
897 __efc_ns_gidpt_delay(struct efc_sm_ctx *ctx,
898 enum efc_sm_event evt, void *arg)
900 struct efc_node *node = ctx->app;
901 struct efc *efc = node->efc;
903 efc_node_evt_set(ctx, evt, __func__);
908 case EFC_EVT_ENTER: {
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.
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;
921 timer_setup(&node->gidpt_delay_timer, &gidpt_delay_timer_cb,
923 mod_timer(&node->gidpt_delay_timer,
924 jiffies + msecs_to_jiffies(delay_msec));
929 case EFC_EVT_GIDPT_DELAY_EXPIRED:
930 node->time_last_gidpt_msec = jiffies_to_msecs(jiffies);
932 efc_ns_send_gidpt(node);
933 efc_node_transition(node, __efc_ns_gidpt_wait_rsp, NULL);
936 case EFC_EVT_RSCN_RCVD: {
938 "RSCN received while in GIDPT delay - no action\n");
943 __efc_fabric_common(__func__, ctx, evt, arg);
948 __efc_fabctl_init(struct efc_sm_ctx *ctx,
949 enum efc_sm_event evt, void *arg)
951 struct efc_node *node = ctx->app;
957 /* no need to login to fabric controller, just send SCR */
959 efc_node_transition(node, __efc_fabctl_wait_scr_rsp, NULL);
962 case EFC_EVT_NODE_ATTACH_OK:
963 node->attached = true;
967 __efc_fabric_common(__func__, ctx, evt, arg);
972 __efc_fabctl_wait_scr_rsp(struct efc_sm_ctx *ctx,
973 enum efc_sm_event evt, void *arg)
975 struct efc_node *node = ctx->app;
977 efc_node_evt_set(ctx, evt, __func__);
982 * Fabric controller node state machine:
983 * Wait for an SCR response from the fabric controller.
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__)) {
991 WARN_ON(!node->els_req_cnt);
993 efc_node_transition(node, __efc_fabctl_ready, NULL);
997 __efc_fabric_common(__func__, ctx, evt, arg);
1002 efc_process_rscn(struct efc_node *node, struct efc_node_cb *cbdata)
1004 struct efc *efc = node->efc;
1005 struct efc_nport *nport = node->nport;
1006 struct efc_node *ns;
1008 /* Forward this event to the name-services node */
1009 ns = efc_node_find(nport, FC_FID_DIR_SERV);
1011 efc_node_post_event(ns, EFC_EVT_RSCN_RCVD, cbdata);
1013 efc_log_warn(efc, "can't find name server node\n");
1017 __efc_fabctl_ready(struct efc_sm_ctx *ctx,
1018 enum efc_sm_event evt, void *arg)
1020 struct efc_node_cb *cbdata = arg;
1021 struct efc_node *node = ctx->app;
1023 efc_node_evt_set(ctx, evt, __func__);
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.
1034 case EFC_EVT_RSCN_RCVD: {
1035 struct fc_frame_header *hdr = cbdata->header->dma.virt;
1038 * sm: / process RSCN (forward to name services node),
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,
1049 __efc_fabric_common(__func__, ctx, evt, arg);
1054 __efc_fabctl_wait_ls_acc_cmpl(struct efc_sm_ctx *ctx,
1055 enum efc_sm_event evt, void *arg)
1057 struct efc_node *node = ctx->app;
1059 efc_node_evt_set(ctx, evt, __func__);
1065 efc_node_hold_frames(node);
1069 efc_node_accept_frames(node);
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);
1079 __efc_fabric_common(__func__, ctx, evt, arg);
1084 efc_get_wwpn(struct fc_els_flogi *sp)
1086 return be64_to_cpu(sp->fl_wwnn);
1090 efc_rnode_is_winner(struct efc_nport *nport)
1092 struct fc_els_flogi *remote_sp;
1094 u64 local_wwpn = nport->wwpn;
1097 remote_sp = (struct fc_els_flogi *)nport->domain->flogi_service_params;
1098 remote_wwpn = efc_get_wwpn(remote_sp);
1100 local_wwpn ^= wwn_bump;
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);
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),
1114 return (remote_wwpn > local_wwpn);
1118 __efc_p2p_wait_domain_attach(struct efc_sm_ctx *ctx,
1119 enum efc_sm_event evt, void *arg)
1121 struct efc_node *node = ctx->app;
1122 struct efc *efc = node->efc;
1124 efc_node_evt_set(ctx, evt, __func__);
1130 efc_node_hold_frames(node);
1134 efc_node_accept_frames(node);
1137 case EFC_EVT_DOMAIN_ATTACH_OK: {
1138 struct efc_nport *nport = node->nport;
1139 struct efc_node *rnode;
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
1147 WARN_ON(!node->nport->p2p_winner);
1149 rnode = efc_node_find(nport, node->nport->p2p_remote_port_id);
1152 * the "other" transient p2p node has
1153 * already kicked off the
1154 * new node from which PLOGI is sent
1157 "Node with fc_id x%x already exists\n",
1158 rnode->rnode.fc_id);
1161 * create new node (SID=1, DID=2)
1162 * from which to send PLOGI
1164 rnode = efc_node_alloc(nport,
1165 nport->p2p_remote_port_id,
1168 efc_log_err(efc, "node alloc failed\n");
1172 efc_fabric_notify_topology(node);
1173 /* sm: / allocate p2p remote node */
1174 efc_node_transition(rnode, __efc_p2p_rnode_init,
1179 * the transient node (SID=0 or DID=fabric)
1180 * has served its purpose
1182 if (node->rnode.fc_id == 0) {
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
1188 /* don't send PLOGI on efc_d_init entry */
1189 efc_node_init_device(node, false);
1192 * if this is the DID=fabric node
1193 * (we initiated FLOGI), shut it down
1195 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
1196 efc_fabric_initiate_shutdown(node);
1202 __efc_fabric_common(__func__, ctx, evt, arg);
1207 __efc_p2p_rnode_init(struct efc_sm_ctx *ctx,
1208 enum efc_sm_event evt, void *arg)
1210 struct efc_node_cb *cbdata = arg;
1211 struct efc_node *node = ctx->app;
1213 efc_node_evt_set(ctx, evt, __func__);
1219 /* sm: / send PLOGI */
1220 efc_send_plogi(node);
1221 efc_node_transition(node, __efc_p2p_wait_plogi_rsp, NULL);
1224 case EFC_EVT_ABTS_RCVD:
1225 /* sm: send BA_ACC */
1226 efc_send_bls_acc(node, cbdata->header->dma.virt);
1231 __efc_fabric_common(__func__, ctx, evt, arg);
1236 __efc_p2p_wait_flogi_acc_cmpl(struct efc_sm_ctx *ctx,
1237 enum efc_sm_event evt, void *arg)
1239 struct efc_node_cb *cbdata = arg;
1240 struct efc_node *node = ctx->app;
1242 efc_node_evt_set(ctx, evt, __func__);
1248 efc_node_hold_frames(node);
1252 efc_node_accept_frames(node);
1255 case EFC_EVT_SRRS_ELS_CMPL_OK:
1256 WARN_ON(!node->els_cmpl_cnt);
1257 node->els_cmpl_cnt--;
1259 /* sm: if p2p_winner / domain_attach */
1260 if (node->nport->p2p_winner) {
1261 efc_node_transition(node,
1262 __efc_p2p_wait_domain_attach,
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);
1269 node_printf(node, "Domain already attached\n");
1270 efc_node_post_event(node,
1271 EFC_EVT_DOMAIN_ATTACH_OK,
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).
1282 /* don't send PLOGI on efc_d_init entry */
1283 efc_node_init_device(node, false);
1287 case EFC_EVT_SRRS_ELS_CMPL_FAIL:
1289 * LS_ACC failed, possibly due to link down;
1290 * shutdown node and wait
1291 * for FLOGI discovery to restart
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);
1300 case EFC_EVT_ABTS_RCVD: {
1301 /* sm: / send BA_ACC */
1302 efc_send_bls_acc(node, cbdata->header->dma.virt);
1307 __efc_fabric_common(__func__, ctx, evt, arg);
1312 __efc_p2p_wait_plogi_rsp(struct efc_sm_ctx *ctx,
1313 enum efc_sm_event evt, void *arg)
1315 struct efc_node_cb *cbdata = arg;
1316 struct efc_node *node = ctx->app;
1318 efc_node_evt_set(ctx, evt, __func__);
1323 case EFC_EVT_SRRS_ELS_REQ_OK: {
1326 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
1327 __efc_fabric_common, __func__)) {
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);
1337 efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
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__)) {
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);
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));
1361 * if this isn't external loopback,
1362 * pass to default handler
1364 __efc_fabric_common(__func__, ctx, evt, arg);
1368 case EFC_EVT_PRLI_RCVD:
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
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,
1384 __efc_fabric_common(__func__, ctx, evt, arg);
1389 __efc_p2p_wait_plogi_rsp_recvd_prli(struct efc_sm_ctx *ctx,
1390 enum efc_sm_event evt, void *arg)
1392 struct efc_node_cb *cbdata = arg;
1393 struct efc_node *node = ctx->app;
1395 efc_node_evt_set(ctx, evt, __func__);
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
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.
1412 efc_node_hold_frames(node);
1416 efc_node_accept_frames(node);
1419 case EFC_EVT_SRRS_ELS_REQ_OK: { /* PLOGI response received */
1422 /* Completion from PLOGI sent */
1423 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
1424 __efc_fabric_common, __func__)) {
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);
1434 efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
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__)) {
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);
1452 __efc_fabric_common(__func__, ctx, evt, arg);
1457 __efc_p2p_wait_node_attach(struct efc_sm_ctx *ctx,
1458 enum efc_sm_event evt, void *arg)
1460 struct efc_node_cb *cbdata = arg;
1461 struct efc_node *node = ctx->app;
1463 efc_node_evt_set(ctx, evt, __func__);
1469 efc_node_hold_frames(node);
1473 efc_node_accept_frames(node);
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,
1482 node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
1483 node->ls_acc_io = NULL;
1486 case EFC_NODE_SEND_LS_ACC_PLOGI: /* Can't happen in P2P */
1487 case EFC_NODE_SEND_LS_ACC_NONE:
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,
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);
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,
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);
1522 __efc_fabric_common(__func__, ctx, evt, arg);
1527 efc_p2p_setup(struct efc_nport *nport)
1529 struct efc *efc = nport->efc;
1532 rnode_winner = efc_rnode_is_winner(nport);
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;
1544 /* no winner; only okay if external loopback enabled */
1545 if (nport->efc->external_loopback) {
1547 * External loopback mode enabled;
1548 * local nport and remote node
1549 * will be registered with an NPortID = 1;
1552 "External loopback mode enabled\n");
1553 nport->p2p_remote_port_id = 1;
1554 nport->p2p_port_id = 1;
1555 nport->p2p_winner = true;
1558 "failed to determine p2p winner\n");
1559 return rnode_winner;