Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
0004  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
0005  */
0006 
0007 /*
0008  * device_sm Node State Machine: Remote Device States
0009  */
0010 
0011 #include "efc.h"
0012 #include "efc_device.h"
0013 #include "efc_fabric.h"
0014 
0015 void
0016 efc_d_send_prli_rsp(struct efc_node *node, u16 ox_id)
0017 {
0018     int rc = EFC_SCSI_CALL_COMPLETE;
0019     struct efc *efc = node->efc;
0020 
0021     node->ls_acc_oxid = ox_id;
0022     node->send_ls_acc = EFC_NODE_SEND_LS_ACC_PRLI;
0023 
0024     /*
0025      * Wait for backend session registration
0026      * to complete before sending PRLI resp
0027      */
0028 
0029     if (node->init) {
0030         efc_log_info(efc, "[%s] found(initiator) WWPN:%s WWNN:%s\n",
0031                  node->display_name, node->wwpn, node->wwnn);
0032         if (node->nport->enable_tgt)
0033             rc = efc->tt.scsi_new_node(efc, node);
0034     }
0035 
0036     if (rc < 0)
0037         efc_node_post_event(node, EFC_EVT_NODE_SESS_REG_FAIL, NULL);
0038 
0039     if (rc == EFC_SCSI_CALL_COMPLETE)
0040         efc_node_post_event(node, EFC_EVT_NODE_SESS_REG_OK, NULL);
0041 }
0042 
0043 static void
0044 __efc_d_common(const char *funcname, struct efc_sm_ctx *ctx,
0045            enum efc_sm_event evt, void *arg)
0046 {
0047     struct efc_node *node = NULL;
0048     struct efc *efc = NULL;
0049 
0050     node = ctx->app;
0051     efc = node->efc;
0052 
0053     switch (evt) {
0054     /* Handle shutdown events */
0055     case EFC_EVT_SHUTDOWN:
0056         efc_log_debug(efc, "[%s] %-20s %-20s\n", node->display_name,
0057                   funcname, efc_sm_event_name(evt));
0058         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
0059         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
0060         break;
0061     case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO:
0062         efc_log_debug(efc, "[%s] %-20s %-20s\n",
0063                   node->display_name, funcname,
0064                 efc_sm_event_name(evt));
0065         node->shutdown_reason = EFC_NODE_SHUTDOWN_EXPLICIT_LOGO;
0066         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
0067         break;
0068     case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
0069         efc_log_debug(efc, "[%s] %-20s %-20s\n", node->display_name,
0070                   funcname, efc_sm_event_name(evt));
0071         node->shutdown_reason = EFC_NODE_SHUTDOWN_IMPLICIT_LOGO;
0072         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
0073         break;
0074 
0075     default:
0076         /* call default event handler common to all nodes */
0077         __efc_node_common(funcname, ctx, evt, arg);
0078     }
0079 }
0080 
0081 static void
0082 __efc_d_wait_del_node(struct efc_sm_ctx *ctx,
0083               enum efc_sm_event evt, void *arg)
0084 {
0085     struct efc_node *node = ctx->app;
0086 
0087     efc_node_evt_set(ctx, evt, __func__);
0088 
0089     /*
0090      * State is entered when a node sends a delete initiator/target call
0091      * to the target-server/initiator-client and needs to wait for that
0092      * work to complete.
0093      */
0094     node_sm_trace();
0095 
0096     switch (evt) {
0097     case EFC_EVT_ENTER:
0098         efc_node_hold_frames(node);
0099         fallthrough;
0100 
0101     case EFC_EVT_NODE_ACTIVE_IO_LIST_EMPTY:
0102     case EFC_EVT_ALL_CHILD_NODES_FREE:
0103         /* These are expected events. */
0104         break;
0105 
0106     case EFC_EVT_NODE_DEL_INI_COMPLETE:
0107     case EFC_EVT_NODE_DEL_TGT_COMPLETE:
0108         /*
0109          * node has either been detached or is in the process
0110          * of being detached,
0111          * call common node's initiate cleanup function
0112          */
0113         efc_node_initiate_cleanup(node);
0114         break;
0115 
0116     case EFC_EVT_EXIT:
0117         efc_node_accept_frames(node);
0118         break;
0119 
0120     case EFC_EVT_SRRS_ELS_REQ_FAIL:
0121         /* Can happen as ELS IO IO's complete */
0122         WARN_ON(!node->els_req_cnt);
0123         node->els_req_cnt--;
0124         break;
0125 
0126     /* ignore shutdown events as we're already in shutdown path */
0127     case EFC_EVT_SHUTDOWN:
0128         /* have default shutdown event take precedence */
0129         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
0130         fallthrough;
0131 
0132     case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO:
0133     case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
0134         node_printf(node, "%s received\n", efc_sm_event_name(evt));
0135         break;
0136     case EFC_EVT_DOMAIN_ATTACH_OK:
0137         /* don't care about domain_attach_ok */
0138         break;
0139     default:
0140         __efc_d_common(__func__, ctx, evt, arg);
0141     }
0142 }
0143 
0144 static void
0145 __efc_d_wait_del_ini_tgt(struct efc_sm_ctx *ctx,
0146              enum efc_sm_event evt, void *arg)
0147 {
0148     struct efc_node *node = ctx->app;
0149 
0150     efc_node_evt_set(ctx, evt, __func__);
0151 
0152     node_sm_trace();
0153 
0154     switch (evt) {
0155     case EFC_EVT_ENTER:
0156         efc_node_hold_frames(node);
0157         fallthrough;
0158 
0159     case EFC_EVT_NODE_ACTIVE_IO_LIST_EMPTY:
0160     case EFC_EVT_ALL_CHILD_NODES_FREE:
0161         /* These are expected events. */
0162         break;
0163 
0164     case EFC_EVT_NODE_DEL_INI_COMPLETE:
0165     case EFC_EVT_NODE_DEL_TGT_COMPLETE:
0166         efc_node_transition(node, __efc_d_wait_del_node, NULL);
0167         break;
0168 
0169     case EFC_EVT_EXIT:
0170         efc_node_accept_frames(node);
0171         break;
0172 
0173     case EFC_EVT_SRRS_ELS_REQ_FAIL:
0174         /* Can happen as ELS IO IO's complete */
0175         WARN_ON(!node->els_req_cnt);
0176         node->els_req_cnt--;
0177         break;
0178 
0179     /* ignore shutdown events as we're already in shutdown path */
0180     case EFC_EVT_SHUTDOWN:
0181         /* have default shutdown event take precedence */
0182         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
0183         fallthrough;
0184 
0185     case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO:
0186     case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
0187         node_printf(node, "%s received\n", efc_sm_event_name(evt));
0188         break;
0189     case EFC_EVT_DOMAIN_ATTACH_OK:
0190         /* don't care about domain_attach_ok */
0191         break;
0192     default:
0193         __efc_d_common(__func__, ctx, evt, arg);
0194     }
0195 }
0196 
0197 void
0198 __efc_d_initiate_shutdown(struct efc_sm_ctx *ctx,
0199               enum efc_sm_event evt, void *arg)
0200 {
0201     struct efc_node *node = ctx->app;
0202     struct efc *efc = node->efc;
0203 
0204     efc_node_evt_set(ctx, evt, __func__);
0205 
0206     node_sm_trace();
0207 
0208     switch (evt) {
0209     case EFC_EVT_ENTER: {
0210         int rc = EFC_SCSI_CALL_COMPLETE;
0211 
0212         /* assume no wait needed */
0213         node->els_io_enabled = false;
0214 
0215         /* make necessary delete upcall(s) */
0216         if (node->init && !node->targ) {
0217             efc_log_info(node->efc,
0218                      "[%s] delete (initiator) WWPN %s WWNN %s\n",
0219                 node->display_name,
0220                 node->wwpn, node->wwnn);
0221             efc_node_transition(node,
0222                         __efc_d_wait_del_node,
0223                          NULL);
0224             if (node->nport->enable_tgt)
0225                 rc = efc->tt.scsi_del_node(efc, node,
0226                     EFC_SCSI_INITIATOR_DELETED);
0227 
0228             if (rc == EFC_SCSI_CALL_COMPLETE || rc < 0)
0229                 efc_node_post_event(node,
0230                     EFC_EVT_NODE_DEL_INI_COMPLETE, NULL);
0231 
0232         } else if (node->targ && !node->init) {
0233             efc_log_info(node->efc,
0234                      "[%s] delete (target) WWPN %s WWNN %s\n",
0235                 node->display_name,
0236                 node->wwpn, node->wwnn);
0237             efc_node_transition(node,
0238                         __efc_d_wait_del_node,
0239                          NULL);
0240             if (node->nport->enable_ini)
0241                 rc = efc->tt.scsi_del_node(efc, node,
0242                     EFC_SCSI_TARGET_DELETED);
0243 
0244             if (rc == EFC_SCSI_CALL_COMPLETE)
0245                 efc_node_post_event(node,
0246                     EFC_EVT_NODE_DEL_TGT_COMPLETE, NULL);
0247 
0248         } else if (node->init && node->targ) {
0249             efc_log_info(node->efc,
0250                      "[%s] delete (I+T) WWPN %s WWNN %s\n",
0251                 node->display_name, node->wwpn, node->wwnn);
0252             efc_node_transition(node, __efc_d_wait_del_ini_tgt,
0253                         NULL);
0254             if (node->nport->enable_tgt)
0255                 rc = efc->tt.scsi_del_node(efc, node,
0256                         EFC_SCSI_INITIATOR_DELETED);
0257 
0258             if (rc == EFC_SCSI_CALL_COMPLETE)
0259                 efc_node_post_event(node,
0260                     EFC_EVT_NODE_DEL_INI_COMPLETE, NULL);
0261             /* assume no wait needed */
0262             rc = EFC_SCSI_CALL_COMPLETE;
0263             if (node->nport->enable_ini)
0264                 rc = efc->tt.scsi_del_node(efc, node,
0265                         EFC_SCSI_TARGET_DELETED);
0266 
0267             if (rc == EFC_SCSI_CALL_COMPLETE)
0268                 efc_node_post_event(node,
0269                     EFC_EVT_NODE_DEL_TGT_COMPLETE, NULL);
0270         }
0271 
0272         /* we've initiated the upcalls as needed, now kick off the node
0273          * detach to precipitate the aborting of outstanding exchanges
0274          * associated with said node
0275          *
0276          * Beware: if we've made upcall(s), we've already transitioned
0277          * to a new state by the time we execute this.
0278          * consider doing this before the upcalls?
0279          */
0280         if (node->attached) {
0281             /* issue hw node free; don't care if succeeds right
0282              * away or sometime later, will check node->attached
0283              * later in shutdown process
0284              */
0285             rc = efc_cmd_node_detach(efc, &node->rnode);
0286             if (rc < 0)
0287                 node_printf(node,
0288                         "Failed freeing HW node, rc=%d\n",
0289                     rc);
0290         }
0291 
0292         /* if neither initiator nor target, proceed to cleanup */
0293         if (!node->init && !node->targ) {
0294             /*
0295              * node has either been detached or is in
0296              * the process of being detached,
0297              * call common node's initiate cleanup function
0298              */
0299             efc_node_initiate_cleanup(node);
0300         }
0301         break;
0302     }
0303     case EFC_EVT_ALL_CHILD_NODES_FREE:
0304         /* Ignore, this can happen if an ELS is
0305          * aborted while in a delay/retry state
0306          */
0307         break;
0308     default:
0309         __efc_d_common(__func__, ctx, evt, arg);
0310     }
0311 }
0312 
0313 void
0314 __efc_d_wait_loop(struct efc_sm_ctx *ctx,
0315           enum efc_sm_event evt, void *arg)
0316 {
0317     struct efc_node *node = ctx->app;
0318 
0319     efc_node_evt_set(ctx, evt, __func__);
0320 
0321     node_sm_trace();
0322 
0323     switch (evt) {
0324     case EFC_EVT_ENTER:
0325         efc_node_hold_frames(node);
0326         break;
0327 
0328     case EFC_EVT_EXIT:
0329         efc_node_accept_frames(node);
0330         break;
0331 
0332     case EFC_EVT_DOMAIN_ATTACH_OK: {
0333         /* send PLOGI automatically if initiator */
0334         efc_node_init_device(node, true);
0335         break;
0336     }
0337     default:
0338         __efc_d_common(__func__, ctx, evt, arg);
0339     }
0340 }
0341 
0342 void
0343 efc_send_ls_acc_after_attach(struct efc_node *node,
0344                  struct fc_frame_header *hdr,
0345                  enum efc_node_send_ls_acc ls)
0346 {
0347     u16 ox_id = be16_to_cpu(hdr->fh_ox_id);
0348 
0349     /* Save the OX_ID for sending LS_ACC sometime later */
0350     WARN_ON(node->send_ls_acc != EFC_NODE_SEND_LS_ACC_NONE);
0351 
0352     node->ls_acc_oxid = ox_id;
0353     node->send_ls_acc = ls;
0354     node->ls_acc_did = ntoh24(hdr->fh_d_id);
0355 }
0356 
0357 void
0358 efc_process_prli_payload(struct efc_node *node, void *prli)
0359 {
0360     struct {
0361         struct fc_els_prli prli;
0362         struct fc_els_spp sp;
0363     } *pp;
0364 
0365     pp = prli;
0366     node->init = (pp->sp.spp_flags & FCP_SPPF_INIT_FCN) != 0;
0367     node->targ = (pp->sp.spp_flags & FCP_SPPF_TARG_FCN) != 0;
0368 }
0369 
0370 void
0371 __efc_d_wait_plogi_acc_cmpl(struct efc_sm_ctx *ctx,
0372                 enum efc_sm_event evt, void *arg)
0373 {
0374     struct efc_node *node = ctx->app;
0375 
0376     efc_node_evt_set(ctx, evt, __func__);
0377 
0378     node_sm_trace();
0379 
0380     switch (evt) {
0381     case EFC_EVT_ENTER:
0382         efc_node_hold_frames(node);
0383         break;
0384 
0385     case EFC_EVT_EXIT:
0386         efc_node_accept_frames(node);
0387         break;
0388 
0389     case EFC_EVT_SRRS_ELS_CMPL_FAIL:
0390         WARN_ON(!node->els_cmpl_cnt);
0391         node->els_cmpl_cnt--;
0392         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
0393         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
0394         break;
0395 
0396     case EFC_EVT_SRRS_ELS_CMPL_OK:  /* PLOGI ACC completions */
0397         WARN_ON(!node->els_cmpl_cnt);
0398         node->els_cmpl_cnt--;
0399         efc_node_transition(node, __efc_d_port_logged_in, NULL);
0400         break;
0401 
0402     default:
0403         __efc_d_common(__func__, ctx, evt, arg);
0404     }
0405 }
0406 
0407 void
0408 __efc_d_wait_logo_rsp(struct efc_sm_ctx *ctx,
0409               enum efc_sm_event evt, void *arg)
0410 {
0411     struct efc_node *node = ctx->app;
0412 
0413     efc_node_evt_set(ctx, evt, __func__);
0414 
0415     node_sm_trace();
0416 
0417     switch (evt) {
0418     case EFC_EVT_ENTER:
0419         efc_node_hold_frames(node);
0420         break;
0421 
0422     case EFC_EVT_EXIT:
0423         efc_node_accept_frames(node);
0424         break;
0425 
0426     case EFC_EVT_SRRS_ELS_REQ_OK:
0427     case EFC_EVT_SRRS_ELS_REQ_RJT:
0428     case EFC_EVT_SRRS_ELS_REQ_FAIL:
0429         /* LOGO response received, sent shutdown */
0430         if (efc_node_check_els_req(ctx, evt, arg, ELS_LOGO,
0431                        __efc_d_common, __func__))
0432             return;
0433 
0434         WARN_ON(!node->els_req_cnt);
0435         node->els_req_cnt--;
0436         node_printf(node,
0437                 "LOGO sent (evt=%s), shutdown node\n",
0438             efc_sm_event_name(evt));
0439         /* sm: / post explicit logout */
0440         efc_node_post_event(node, EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
0441                     NULL);
0442         break;
0443 
0444     default:
0445         __efc_d_common(__func__, ctx, evt, arg);
0446     }
0447 }
0448 
0449 void
0450 efc_node_init_device(struct efc_node *node, bool send_plogi)
0451 {
0452     node->send_plogi = send_plogi;
0453     if ((node->efc->nodedb_mask & EFC_NODEDB_PAUSE_NEW_NODES) &&
0454         (node->rnode.fc_id != FC_FID_DOM_MGR)) {
0455         node->nodedb_state = __efc_d_init;
0456         efc_node_transition(node, __efc_node_paused, NULL);
0457     } else {
0458         efc_node_transition(node, __efc_d_init, NULL);
0459     }
0460 }
0461 
0462 static void
0463 efc_d_check_plogi_topology(struct efc_node *node, u32 d_id)
0464 {
0465     switch (node->nport->topology) {
0466     case EFC_NPORT_TOPO_P2P:
0467         /* we're not attached and nport is p2p,
0468          * need to attach
0469          */
0470         efc_domain_attach(node->nport->domain, d_id);
0471         efc_node_transition(node, __efc_d_wait_domain_attach, NULL);
0472         break;
0473     case EFC_NPORT_TOPO_FABRIC:
0474         /* we're not attached and nport is fabric, domain
0475          * attach should have already been requested as part
0476          * of the fabric state machine, wait for it
0477          */
0478         efc_node_transition(node, __efc_d_wait_domain_attach, NULL);
0479         break;
0480     case EFC_NPORT_TOPO_UNKNOWN:
0481         /* Two possibilities:
0482          * 1. received a PLOGI before our FLOGI has completed
0483          *    (possible since completion comes in on another
0484          *    CQ), thus we don't know what we're connected to
0485          *    yet; transition to a state to wait for the
0486          *    fabric node to tell us;
0487          * 2. PLOGI received before link went down and we
0488          * haven't performed domain attach yet.
0489          * Note: we cannot distinguish between 1. and 2.
0490          * so have to assume PLOGI
0491          * was received after link back up.
0492          */
0493         node_printf(node, "received PLOGI, unknown topology did=0x%x\n",
0494                 d_id);
0495         efc_node_transition(node, __efc_d_wait_topology_notify, NULL);
0496         break;
0497     default:
0498         node_printf(node, "received PLOGI, unexpected topology %d\n",
0499                 node->nport->topology);
0500     }
0501 }
0502 
0503 void
0504 __efc_d_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg)
0505 {
0506     struct efc_node_cb *cbdata = arg;
0507     struct efc_node *node = ctx->app;
0508 
0509     efc_node_evt_set(ctx, evt, __func__);
0510 
0511     node_sm_trace();
0512 
0513     /*
0514      * This state is entered when a node is instantiated,
0515      * either having been discovered from a name services query,
0516      * or having received a PLOGI/FLOGI.
0517      */
0518     switch (evt) {
0519     case EFC_EVT_ENTER:
0520         if (!node->send_plogi)
0521             break;
0522         /* only send if we have initiator capability,
0523          * and domain is attached
0524          */
0525         if (node->nport->enable_ini &&
0526             node->nport->domain->attached) {
0527             efc_send_plogi(node);
0528 
0529             efc_node_transition(node, __efc_d_wait_plogi_rsp, NULL);
0530         } else {
0531             node_printf(node, "not sending plogi nport.ini=%d,",
0532                     node->nport->enable_ini);
0533             node_printf(node, "domain attached=%d\n",
0534                     node->nport->domain->attached);
0535         }
0536         break;
0537     case EFC_EVT_PLOGI_RCVD: {
0538         /* T, or I+T */
0539         struct fc_frame_header *hdr = cbdata->header->dma.virt;
0540         int rc;
0541 
0542         efc_node_save_sparms(node, cbdata->payload->dma.virt);
0543         efc_send_ls_acc_after_attach(node,
0544                          cbdata->header->dma.virt,
0545                          EFC_NODE_SEND_LS_ACC_PLOGI);
0546 
0547         /* domain not attached; several possibilities: */
0548         if (!node->nport->domain->attached) {
0549             efc_d_check_plogi_topology(node, ntoh24(hdr->fh_d_id));
0550             break;
0551         }
0552 
0553         /* domain already attached */
0554         rc = efc_node_attach(node);
0555         efc_node_transition(node, __efc_d_wait_node_attach, NULL);
0556         if (rc < 0)
0557             efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL, NULL);
0558 
0559         break;
0560     }
0561 
0562     case EFC_EVT_FDISC_RCVD: {
0563         __efc_d_common(__func__, ctx, evt, arg);
0564         break;
0565     }
0566 
0567     case EFC_EVT_FLOGI_RCVD: {
0568         struct fc_frame_header *hdr = cbdata->header->dma.virt;
0569         u32 d_id = ntoh24(hdr->fh_d_id);
0570 
0571         /* sm: / save sparams, send FLOGI acc */
0572         memcpy(node->nport->domain->flogi_service_params,
0573                cbdata->payload->dma.virt,
0574                sizeof(struct fc_els_flogi));
0575 
0576         /* send FC LS_ACC response, override s_id */
0577         efc_fabric_set_topology(node, EFC_NPORT_TOPO_P2P);
0578 
0579         efc_send_flogi_p2p_acc(node, be16_to_cpu(hdr->fh_ox_id), d_id);
0580 
0581         if (efc_p2p_setup(node->nport)) {
0582             node_printf(node, "p2p failed, shutting down node\n");
0583             efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
0584             break;
0585         }
0586 
0587         efc_node_transition(node,  __efc_p2p_wait_flogi_acc_cmpl, NULL);
0588         break;
0589     }
0590 
0591     case EFC_EVT_LOGO_RCVD: {
0592         struct fc_frame_header *hdr = cbdata->header->dma.virt;
0593 
0594         if (!node->nport->domain->attached) {
0595             /* most likely a frame left over from before a link
0596              * down; drop and
0597              * shut node down w/ "explicit logout" so pending
0598              * frames are processed
0599              */
0600             node_printf(node, "%s domain not attached, dropping\n",
0601                     efc_sm_event_name(evt));
0602             efc_node_post_event(node,
0603                     EFC_EVT_SHUTDOWN_EXPLICIT_LOGO, NULL);
0604             break;
0605         }
0606 
0607         efc_send_logo_acc(node, be16_to_cpu(hdr->fh_ox_id));
0608         efc_node_transition(node, __efc_d_wait_logo_acc_cmpl, NULL);
0609         break;
0610     }
0611 
0612     case EFC_EVT_PRLI_RCVD:
0613     case EFC_EVT_PRLO_RCVD:
0614     case EFC_EVT_PDISC_RCVD:
0615     case EFC_EVT_ADISC_RCVD:
0616     case EFC_EVT_RSCN_RCVD: {
0617         struct fc_frame_header *hdr = cbdata->header->dma.virt;
0618 
0619         if (!node->nport->domain->attached) {
0620             /* most likely a frame left over from before a link
0621              * down; drop and shut node down w/ "explicit logout"
0622              * so pending frames are processed
0623              */
0624             node_printf(node, "%s domain not attached, dropping\n",
0625                     efc_sm_event_name(evt));
0626 
0627             efc_node_post_event(node,
0628                         EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
0629                         NULL);
0630             break;
0631         }
0632         node_printf(node, "%s received, sending reject\n",
0633                 efc_sm_event_name(evt));
0634 
0635         efc_send_ls_rjt(node, be16_to_cpu(hdr->fh_ox_id),
0636                 ELS_RJT_UNAB, ELS_EXPL_PLOGI_REQD, 0);
0637 
0638         break;
0639     }
0640 
0641     case EFC_EVT_FCP_CMD_RCVD: {
0642         /* note: problem, we're now expecting an ELS REQ completion
0643          * from both the LOGO and PLOGI
0644          */
0645         if (!node->nport->domain->attached) {
0646             /* most likely a frame left over from before a
0647              * link down; drop and
0648              * shut node down w/ "explicit logout" so pending
0649              * frames are processed
0650              */
0651             node_printf(node, "%s domain not attached, dropping\n",
0652                     efc_sm_event_name(evt));
0653             efc_node_post_event(node,
0654                         EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
0655                         NULL);
0656             break;
0657         }
0658 
0659         /* Send LOGO */
0660         node_printf(node, "FCP_CMND received, send LOGO\n");
0661         if (efc_send_logo(node)) {
0662             /*
0663              * failed to send LOGO, go ahead and cleanup node
0664              * anyways
0665              */
0666             node_printf(node, "Failed to send LOGO\n");
0667             efc_node_post_event(node,
0668                         EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
0669                         NULL);
0670         } else {
0671             /* sent LOGO, wait for response */
0672             efc_node_transition(node,
0673                         __efc_d_wait_logo_rsp, NULL);
0674         }
0675         break;
0676     }
0677     case EFC_EVT_DOMAIN_ATTACH_OK:
0678         /* don't care about domain_attach_ok */
0679         break;
0680 
0681     default:
0682         __efc_d_common(__func__, ctx, evt, arg);
0683     }
0684 }
0685 
0686 void
0687 __efc_d_wait_plogi_rsp(struct efc_sm_ctx *ctx,
0688                enum efc_sm_event evt, void *arg)
0689 {
0690     int rc;
0691     struct efc_node_cb *cbdata = arg;
0692     struct efc_node *node = ctx->app;
0693 
0694     efc_node_evt_set(ctx, evt, __func__);
0695 
0696     node_sm_trace();
0697 
0698     switch (evt) {
0699     case EFC_EVT_PLOGI_RCVD: {
0700         /* T, or I+T */
0701         /* received PLOGI with svc parms, go ahead and attach node
0702          * when PLOGI that was sent ultimately completes, it'll be a
0703          * no-op
0704          *
0705          * If there is an outstanding PLOGI sent, can we set a flag
0706          * to indicate that we don't want to retry it if it times out?
0707          */
0708         efc_node_save_sparms(node, cbdata->payload->dma.virt);
0709         efc_send_ls_acc_after_attach(node,
0710                          cbdata->header->dma.virt,
0711                 EFC_NODE_SEND_LS_ACC_PLOGI);
0712         /* sm: domain->attached / efc_node_attach */
0713         rc = efc_node_attach(node);
0714         efc_node_transition(node, __efc_d_wait_node_attach, NULL);
0715         if (rc < 0)
0716             efc_node_post_event(node,
0717                         EFC_EVT_NODE_ATTACH_FAIL, NULL);
0718 
0719         break;
0720     }
0721 
0722     case EFC_EVT_PRLI_RCVD:
0723         /* I, or I+T */
0724         /* sent PLOGI and before completion was seen, received the
0725          * PRLI from the remote node (WCQEs and RCQEs come in on
0726          * different queues and order of processing cannot be assumed)
0727          * Save OXID so PRLI can be sent after the attach and continue
0728          * to wait for PLOGI response
0729          */
0730         efc_process_prli_payload(node, cbdata->payload->dma.virt);
0731         efc_send_ls_acc_after_attach(node,
0732                          cbdata->header->dma.virt,
0733                 EFC_NODE_SEND_LS_ACC_PRLI);
0734         efc_node_transition(node, __efc_d_wait_plogi_rsp_recvd_prli,
0735                     NULL);
0736         break;
0737 
0738     case EFC_EVT_LOGO_RCVD: /* why don't we do a shutdown here?? */
0739     case EFC_EVT_PRLO_RCVD:
0740     case EFC_EVT_PDISC_RCVD:
0741     case EFC_EVT_FDISC_RCVD:
0742     case EFC_EVT_ADISC_RCVD:
0743     case EFC_EVT_RSCN_RCVD:
0744     case EFC_EVT_SCR_RCVD: {
0745         struct fc_frame_header *hdr = cbdata->header->dma.virt;
0746 
0747         node_printf(node, "%s received, sending reject\n",
0748                 efc_sm_event_name(evt));
0749 
0750         efc_send_ls_rjt(node, be16_to_cpu(hdr->fh_ox_id),
0751                 ELS_RJT_UNAB, ELS_EXPL_PLOGI_REQD, 0);
0752 
0753         break;
0754     }
0755 
0756     case EFC_EVT_SRRS_ELS_REQ_OK:   /* PLOGI response received */
0757         /* Completion from PLOGI sent */
0758         if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
0759                        __efc_d_common, __func__))
0760             return;
0761 
0762         WARN_ON(!node->els_req_cnt);
0763         node->els_req_cnt--;
0764         /* sm: / save sparams, efc_node_attach */
0765         efc_node_save_sparms(node, cbdata->els_rsp.virt);
0766         rc = efc_node_attach(node);
0767         efc_node_transition(node, __efc_d_wait_node_attach, NULL);
0768         if (rc < 0)
0769             efc_node_post_event(node,
0770                         EFC_EVT_NODE_ATTACH_FAIL, NULL);
0771 
0772         break;
0773 
0774     case EFC_EVT_SRRS_ELS_REQ_FAIL: /* PLOGI response received */
0775         /* PLOGI failed, shutdown the node */
0776         if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
0777                        __efc_d_common, __func__))
0778             return;
0779 
0780         WARN_ON(!node->els_req_cnt);
0781         node->els_req_cnt--;
0782         efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
0783         break;
0784 
0785     case EFC_EVT_SRRS_ELS_REQ_RJT:
0786         /* Our PLOGI was rejected, this is ok in some cases */
0787         if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
0788                        __efc_d_common, __func__))
0789             return;
0790 
0791         WARN_ON(!node->els_req_cnt);
0792         node->els_req_cnt--;
0793         break;
0794 
0795     case EFC_EVT_FCP_CMD_RCVD: {
0796         /* not logged in yet and outstanding PLOGI so don't send LOGO,
0797          * just drop
0798          */
0799         node_printf(node, "FCP_CMND received, drop\n");
0800         break;
0801     }
0802 
0803     default:
0804         __efc_d_common(__func__, ctx, evt, arg);
0805     }
0806 }
0807 
0808 void
0809 __efc_d_wait_plogi_rsp_recvd_prli(struct efc_sm_ctx *ctx,
0810                   enum efc_sm_event evt, void *arg)
0811 {
0812     int rc;
0813     struct efc_node_cb *cbdata = arg;
0814     struct efc_node *node = ctx->app;
0815 
0816     efc_node_evt_set(ctx, evt, __func__);
0817 
0818     node_sm_trace();
0819 
0820     switch (evt) {
0821     case EFC_EVT_ENTER:
0822         /*
0823          * Since we've received a PRLI, we have a port login and will
0824          * just need to wait for the PLOGI response to do the node
0825          * attach and then we can send the LS_ACC for the PRLI. If,
0826          * during this time, we receive FCP_CMNDs (which is possible
0827          * since we've already sent a PRLI and our peer may have
0828          * accepted). At this time, we are not waiting on any other
0829          * unsolicited frames to continue with the login process. Thus,
0830          * it will not hurt to hold frames here.
0831          */
0832         efc_node_hold_frames(node);
0833         break;
0834 
0835     case EFC_EVT_EXIT:
0836         efc_node_accept_frames(node);
0837         break;
0838 
0839     case EFC_EVT_SRRS_ELS_REQ_OK:   /* PLOGI response received */
0840         /* Completion from PLOGI sent */
0841         if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
0842                        __efc_d_common, __func__))
0843             return;
0844 
0845         WARN_ON(!node->els_req_cnt);
0846         node->els_req_cnt--;
0847         /* sm: / save sparams, efc_node_attach */
0848         efc_node_save_sparms(node, cbdata->els_rsp.virt);
0849         rc = efc_node_attach(node);
0850         efc_node_transition(node, __efc_d_wait_node_attach, NULL);
0851         if (rc < 0)
0852             efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
0853                         NULL);
0854 
0855         break;
0856 
0857     case EFC_EVT_SRRS_ELS_REQ_FAIL: /* PLOGI response received */
0858     case EFC_EVT_SRRS_ELS_REQ_RJT:
0859         /* PLOGI failed, shutdown the node */
0860         if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
0861                        __efc_d_common, __func__))
0862             return;
0863 
0864         WARN_ON(!node->els_req_cnt);
0865         node->els_req_cnt--;
0866         efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
0867         break;
0868 
0869     default:
0870         __efc_d_common(__func__, ctx, evt, arg);
0871     }
0872 }
0873 
0874 void
0875 __efc_d_wait_domain_attach(struct efc_sm_ctx *ctx,
0876                enum efc_sm_event evt, void *arg)
0877 {
0878     int rc;
0879     struct efc_node *node = ctx->app;
0880 
0881     efc_node_evt_set(ctx, evt, __func__);
0882 
0883     node_sm_trace();
0884 
0885     switch (evt) {
0886     case EFC_EVT_ENTER:
0887         efc_node_hold_frames(node);
0888         break;
0889 
0890     case EFC_EVT_EXIT:
0891         efc_node_accept_frames(node);
0892         break;
0893 
0894     case EFC_EVT_DOMAIN_ATTACH_OK:
0895         WARN_ON(!node->nport->domain->attached);
0896         /* sm: / efc_node_attach */
0897         rc = efc_node_attach(node);
0898         efc_node_transition(node, __efc_d_wait_node_attach, NULL);
0899         if (rc < 0)
0900             efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL,
0901                         NULL);
0902 
0903         break;
0904 
0905     default:
0906         __efc_d_common(__func__, ctx, evt, arg);
0907     }
0908 }
0909 
0910 void
0911 __efc_d_wait_topology_notify(struct efc_sm_ctx *ctx,
0912                  enum efc_sm_event evt, void *arg)
0913 {
0914     int rc;
0915     struct efc_node *node = ctx->app;
0916 
0917     efc_node_evt_set(ctx, evt, __func__);
0918 
0919     node_sm_trace();
0920 
0921     switch (evt) {
0922     case EFC_EVT_ENTER:
0923         efc_node_hold_frames(node);
0924         break;
0925 
0926     case EFC_EVT_EXIT:
0927         efc_node_accept_frames(node);
0928         break;
0929 
0930     case EFC_EVT_NPORT_TOPOLOGY_NOTIFY: {
0931         enum efc_nport_topology *topology = arg;
0932 
0933         WARN_ON(node->nport->domain->attached);
0934 
0935         WARN_ON(node->send_ls_acc != EFC_NODE_SEND_LS_ACC_PLOGI);
0936 
0937         node_printf(node, "topology notification, topology=%d\n",
0938                 *topology);
0939 
0940         /* At the time the PLOGI was received, the topology was unknown,
0941          * so we didn't know which node would perform the domain attach:
0942          * 1. The node from which the PLOGI was sent (p2p) or
0943          * 2. The node to which the FLOGI was sent (fabric).
0944          */
0945         if (*topology == EFC_NPORT_TOPO_P2P) {
0946             /* if this is p2p, need to attach to the domain using
0947              * the d_id from the PLOGI received
0948              */
0949             efc_domain_attach(node->nport->domain,
0950                       node->ls_acc_did);
0951         }
0952         /* else, if this is fabric, the domain attach
0953          * should be performed by the fabric node (node sending FLOGI);
0954          * just wait for attach to complete
0955          */
0956 
0957         efc_node_transition(node, __efc_d_wait_domain_attach, NULL);
0958         break;
0959     }
0960     case EFC_EVT_DOMAIN_ATTACH_OK:
0961         WARN_ON(!node->nport->domain->attached);
0962         node_printf(node, "domain attach ok\n");
0963         /* sm: / efc_node_attach */
0964         rc = efc_node_attach(node);
0965         efc_node_transition(node, __efc_d_wait_node_attach, NULL);
0966         if (rc < 0)
0967             efc_node_post_event(node,
0968                         EFC_EVT_NODE_ATTACH_FAIL, NULL);
0969 
0970         break;
0971 
0972     default:
0973         __efc_d_common(__func__, ctx, evt, arg);
0974     }
0975 }
0976 
0977 void
0978 __efc_d_wait_node_attach(struct efc_sm_ctx *ctx,
0979              enum efc_sm_event evt, void *arg)
0980 {
0981     struct efc_node *node = ctx->app;
0982 
0983     efc_node_evt_set(ctx, evt, __func__);
0984 
0985     node_sm_trace();
0986 
0987     switch (evt) {
0988     case EFC_EVT_ENTER:
0989         efc_node_hold_frames(node);
0990         break;
0991 
0992     case EFC_EVT_EXIT:
0993         efc_node_accept_frames(node);
0994         break;
0995 
0996     case EFC_EVT_NODE_ATTACH_OK:
0997         node->attached = true;
0998         switch (node->send_ls_acc) {
0999         case EFC_NODE_SEND_LS_ACC_PLOGI: {
1000             /* sm: send_plogi_acc is set / send PLOGI acc */
1001             /* Normal case for T, or I+T */
1002             efc_send_plogi_acc(node, node->ls_acc_oxid);
1003             efc_node_transition(node, __efc_d_wait_plogi_acc_cmpl,
1004                         NULL);
1005             node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
1006             node->ls_acc_io = NULL;
1007             break;
1008         }
1009         case EFC_NODE_SEND_LS_ACC_PRLI: {
1010             efc_d_send_prli_rsp(node, node->ls_acc_oxid);
1011             node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
1012             node->ls_acc_io = NULL;
1013             break;
1014         }
1015         case EFC_NODE_SEND_LS_ACC_NONE:
1016         default:
1017             /* Normal case for I */
1018             /* sm: send_plogi_acc is not set / send PLOGI acc */
1019             efc_node_transition(node,
1020                         __efc_d_port_logged_in, NULL);
1021             break;
1022         }
1023         break;
1024 
1025     case EFC_EVT_NODE_ATTACH_FAIL:
1026         /* node attach failed, shutdown the node */
1027         node->attached = false;
1028         node_printf(node, "node attach failed\n");
1029         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
1030         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
1031         break;
1032 
1033     /* Handle shutdown events */
1034     case EFC_EVT_SHUTDOWN:
1035         node_printf(node, "%s received\n", efc_sm_event_name(evt));
1036         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
1037         efc_node_transition(node, __efc_d_wait_attach_evt_shutdown,
1038                     NULL);
1039         break;
1040     case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO:
1041         node_printf(node, "%s received\n", efc_sm_event_name(evt));
1042         node->shutdown_reason = EFC_NODE_SHUTDOWN_EXPLICIT_LOGO;
1043         efc_node_transition(node, __efc_d_wait_attach_evt_shutdown,
1044                     NULL);
1045         break;
1046     case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
1047         node_printf(node, "%s received\n", efc_sm_event_name(evt));
1048         node->shutdown_reason = EFC_NODE_SHUTDOWN_IMPLICIT_LOGO;
1049         efc_node_transition(node,
1050                     __efc_d_wait_attach_evt_shutdown, NULL);
1051         break;
1052     default:
1053         __efc_d_common(__func__, ctx, evt, arg);
1054     }
1055 }
1056 
1057 void
1058 __efc_d_wait_attach_evt_shutdown(struct efc_sm_ctx *ctx,
1059                  enum efc_sm_event evt, void *arg)
1060 {
1061     struct efc_node *node = ctx->app;
1062 
1063     efc_node_evt_set(ctx, evt, __func__);
1064 
1065     node_sm_trace();
1066 
1067     switch (evt) {
1068     case EFC_EVT_ENTER:
1069         efc_node_hold_frames(node);
1070         break;
1071 
1072     case EFC_EVT_EXIT:
1073         efc_node_accept_frames(node);
1074         break;
1075 
1076     /* wait for any of these attach events and then shutdown */
1077     case EFC_EVT_NODE_ATTACH_OK:
1078         node->attached = true;
1079         node_printf(node, "Attach evt=%s, proceed to shutdown\n",
1080                 efc_sm_event_name(evt));
1081         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
1082         break;
1083 
1084     case EFC_EVT_NODE_ATTACH_FAIL:
1085         /* node attach failed, shutdown the node */
1086         node->attached = false;
1087         node_printf(node, "Attach evt=%s, proceed to shutdown\n",
1088                 efc_sm_event_name(evt));
1089         efc_node_transition(node, __efc_d_initiate_shutdown, NULL);
1090         break;
1091 
1092     /* ignore shutdown events as we're already in shutdown path */
1093     case EFC_EVT_SHUTDOWN:
1094         /* have default shutdown event take precedence */
1095         node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
1096         fallthrough;
1097 
1098     case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO:
1099     case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
1100         node_printf(node, "%s received\n", efc_sm_event_name(evt));
1101         break;
1102 
1103     default:
1104         __efc_d_common(__func__, ctx, evt, arg);
1105     }
1106 }
1107 
1108 void
1109 __efc_d_port_logged_in(struct efc_sm_ctx *ctx,
1110                enum efc_sm_event evt, void *arg)
1111 {
1112     struct efc_node_cb *cbdata = arg;
1113     struct efc_node *node = ctx->app;
1114 
1115     efc_node_evt_set(ctx, evt, __func__);
1116 
1117     node_sm_trace();
1118 
1119     switch (evt) {
1120     case EFC_EVT_ENTER:
1121         /* Normal case for I or I+T */
1122         if (node->nport->enable_ini &&
1123             !(node->rnode.fc_id != FC_FID_DOM_MGR)) {
1124             /* sm: if enable_ini / send PRLI */
1125             efc_send_prli(node);
1126             /* can now expect ELS_REQ_OK/FAIL/RJT */
1127         }
1128         break;
1129 
1130     case EFC_EVT_FCP_CMD_RCVD: {
1131         break;
1132     }
1133 
1134     case EFC_EVT_PRLI_RCVD: {
1135         /* Normal case for T or I+T */
1136         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1137         struct {
1138             struct fc_els_prli prli;
1139             struct fc_els_spp sp;
1140         } *pp;
1141 
1142         pp = cbdata->payload->dma.virt;
1143         if (pp->sp.spp_type != FC_TYPE_FCP) {
1144             /*Only FCP is supported*/
1145             efc_send_ls_rjt(node, be16_to_cpu(hdr->fh_ox_id),
1146                     ELS_RJT_UNAB, ELS_EXPL_UNSUPR, 0);
1147             break;
1148         }
1149 
1150         efc_process_prli_payload(node, cbdata->payload->dma.virt);
1151         efc_d_send_prli_rsp(node, be16_to_cpu(hdr->fh_ox_id));
1152         break;
1153     }
1154 
1155     case EFC_EVT_NODE_SESS_REG_OK:
1156         if (node->send_ls_acc == EFC_NODE_SEND_LS_ACC_PRLI)
1157             efc_send_prli_acc(node, node->ls_acc_oxid);
1158 
1159         node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
1160         efc_node_transition(node, __efc_d_device_ready, NULL);
1161         break;
1162 
1163     case EFC_EVT_NODE_SESS_REG_FAIL:
1164         efc_send_ls_rjt(node, node->ls_acc_oxid, ELS_RJT_UNAB,
1165                 ELS_EXPL_UNSUPR, 0);
1166         node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
1167         break;
1168 
1169     case EFC_EVT_SRRS_ELS_REQ_OK: { /* PRLI response */
1170         /* Normal case for I or I+T */
1171         if (efc_node_check_els_req(ctx, evt, arg, ELS_PRLI,
1172                        __efc_d_common, __func__))
1173             return;
1174 
1175         WARN_ON(!node->els_req_cnt);
1176         node->els_req_cnt--;
1177         /* sm: / process PRLI payload */
1178         efc_process_prli_payload(node, cbdata->els_rsp.virt);
1179         efc_node_transition(node, __efc_d_device_ready, NULL);
1180         break;
1181     }
1182 
1183     case EFC_EVT_SRRS_ELS_REQ_FAIL: {   /* PRLI response failed */
1184         /* I, I+T, assume some link failure, shutdown node */
1185         if (efc_node_check_els_req(ctx, evt, arg, ELS_PRLI,
1186                        __efc_d_common, __func__))
1187             return;
1188 
1189         WARN_ON(!node->els_req_cnt);
1190         node->els_req_cnt--;
1191         efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
1192         break;
1193     }
1194 
1195     case EFC_EVT_SRRS_ELS_REQ_RJT: {
1196         /* PRLI rejected by remote
1197          * Normal for I, I+T (connected to an I)
1198          * Node doesn't want to be a target, stay here and wait for a
1199          * PRLI from the remote node
1200          * if it really wants to connect to us as target
1201          */
1202         if (efc_node_check_els_req(ctx, evt, arg, ELS_PRLI,
1203                        __efc_d_common, __func__))
1204             return;
1205 
1206         WARN_ON(!node->els_req_cnt);
1207         node->els_req_cnt--;
1208         break;
1209     }
1210 
1211     case EFC_EVT_SRRS_ELS_CMPL_OK: {
1212         /* Normal T, I+T, target-server rejected the process login */
1213         /* This would be received only in the case where we sent
1214          * LS_RJT for the PRLI, so
1215          * do nothing.   (note: as T only we could shutdown the node)
1216          */
1217         WARN_ON(!node->els_cmpl_cnt);
1218         node->els_cmpl_cnt--;
1219         break;
1220     }
1221 
1222     case EFC_EVT_PLOGI_RCVD: {
1223         /*sm: / save sparams, set send_plogi_acc,
1224          *post implicit logout
1225          * Save plogi parameters
1226          */
1227         efc_node_save_sparms(node, cbdata->payload->dma.virt);
1228         efc_send_ls_acc_after_attach(node,
1229                          cbdata->header->dma.virt,
1230                 EFC_NODE_SEND_LS_ACC_PLOGI);
1231 
1232         /* Restart node attach with new service parameters,
1233          * and send ACC
1234          */
1235         efc_node_post_event(node, EFC_EVT_SHUTDOWN_IMPLICIT_LOGO,
1236                     NULL);
1237         break;
1238     }
1239 
1240     case EFC_EVT_LOGO_RCVD: {
1241         /* I, T, I+T */
1242         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1243 
1244         node_printf(node, "%s received attached=%d\n",
1245                 efc_sm_event_name(evt),
1246                     node->attached);
1247         /* sm: / send LOGO acc */
1248         efc_send_logo_acc(node, be16_to_cpu(hdr->fh_ox_id));
1249         efc_node_transition(node, __efc_d_wait_logo_acc_cmpl, NULL);
1250         break;
1251     }
1252 
1253     default:
1254         __efc_d_common(__func__, ctx, evt, arg);
1255     }
1256 }
1257 
1258 void
1259 __efc_d_wait_logo_acc_cmpl(struct efc_sm_ctx *ctx,
1260                enum efc_sm_event evt, void *arg)
1261 {
1262     struct efc_node *node = ctx->app;
1263 
1264     efc_node_evt_set(ctx, evt, __func__);
1265 
1266     node_sm_trace();
1267 
1268     switch (evt) {
1269     case EFC_EVT_ENTER:
1270         efc_node_hold_frames(node);
1271         break;
1272 
1273     case EFC_EVT_EXIT:
1274         efc_node_accept_frames(node);
1275         break;
1276 
1277     case EFC_EVT_SRRS_ELS_CMPL_OK:
1278     case EFC_EVT_SRRS_ELS_CMPL_FAIL:
1279         /* sm: / post explicit logout */
1280         WARN_ON(!node->els_cmpl_cnt);
1281         node->els_cmpl_cnt--;
1282         efc_node_post_event(node,
1283                     EFC_EVT_SHUTDOWN_EXPLICIT_LOGO, NULL);
1284         break;
1285     default:
1286         __efc_d_common(__func__, ctx, evt, arg);
1287     }
1288 }
1289 
1290 void
1291 __efc_d_device_ready(struct efc_sm_ctx *ctx,
1292              enum efc_sm_event evt, void *arg)
1293 {
1294     struct efc_node_cb *cbdata = arg;
1295     struct efc_node *node = ctx->app;
1296     struct efc *efc = node->efc;
1297 
1298     efc_node_evt_set(ctx, evt, __func__);
1299 
1300     if (evt != EFC_EVT_FCP_CMD_RCVD)
1301         node_sm_trace();
1302 
1303     switch (evt) {
1304     case EFC_EVT_ENTER:
1305         node->fcp_enabled = true;
1306         if (node->targ) {
1307             efc_log_info(efc,
1308                      "[%s] found (target) WWPN %s WWNN %s\n",
1309                 node->display_name,
1310                 node->wwpn, node->wwnn);
1311             if (node->nport->enable_ini)
1312                 efc->tt.scsi_new_node(efc, node);
1313         }
1314         break;
1315 
1316     case EFC_EVT_EXIT:
1317         node->fcp_enabled = false;
1318         break;
1319 
1320     case EFC_EVT_PLOGI_RCVD: {
1321         /* sm: / save sparams, set send_plogi_acc, post implicit
1322          * logout
1323          * Save plogi parameters
1324          */
1325         efc_node_save_sparms(node, cbdata->payload->dma.virt);
1326         efc_send_ls_acc_after_attach(node,
1327                          cbdata->header->dma.virt,
1328                 EFC_NODE_SEND_LS_ACC_PLOGI);
1329 
1330         /*
1331          * Restart node attach with new service parameters,
1332          * and send ACC
1333          */
1334         efc_node_post_event(node,
1335                     EFC_EVT_SHUTDOWN_IMPLICIT_LOGO, NULL);
1336         break;
1337     }
1338 
1339     case EFC_EVT_PRLI_RCVD: {
1340         /* T, I+T: remote initiator is slow to get started */
1341         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1342         struct {
1343             struct fc_els_prli prli;
1344             struct fc_els_spp sp;
1345         } *pp;
1346 
1347         pp = cbdata->payload->dma.virt;
1348         if (pp->sp.spp_type != FC_TYPE_FCP) {
1349             /*Only FCP is supported*/
1350             efc_send_ls_rjt(node, be16_to_cpu(hdr->fh_ox_id),
1351                     ELS_RJT_UNAB, ELS_EXPL_UNSUPR, 0);
1352             break;
1353         }
1354 
1355         efc_process_prli_payload(node, cbdata->payload->dma.virt);
1356         efc_send_prli_acc(node, be16_to_cpu(hdr->fh_ox_id));
1357         break;
1358     }
1359 
1360     case EFC_EVT_PRLO_RCVD: {
1361         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1362         /* sm: / send PRLO acc */
1363         efc_send_prlo_acc(node, be16_to_cpu(hdr->fh_ox_id));
1364         /* need implicit logout? */
1365         break;
1366     }
1367 
1368     case EFC_EVT_LOGO_RCVD: {
1369         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1370 
1371         node_printf(node, "%s received attached=%d\n",
1372                 efc_sm_event_name(evt), node->attached);
1373         /* sm: / send LOGO acc */
1374         efc_send_logo_acc(node, be16_to_cpu(hdr->fh_ox_id));
1375         efc_node_transition(node, __efc_d_wait_logo_acc_cmpl, NULL);
1376         break;
1377     }
1378 
1379     case EFC_EVT_ADISC_RCVD: {
1380         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1381         /* sm: / send ADISC acc */
1382         efc_send_adisc_acc(node, be16_to_cpu(hdr->fh_ox_id));
1383         break;
1384     }
1385 
1386     case EFC_EVT_ABTS_RCVD:
1387         /* sm: / process ABTS */
1388         efc_log_err(efc, "Unexpected event:%s\n",
1389                 efc_sm_event_name(evt));
1390         break;
1391 
1392     case EFC_EVT_NODE_ACTIVE_IO_LIST_EMPTY:
1393         break;
1394 
1395     case EFC_EVT_NODE_REFOUND:
1396         break;
1397 
1398     case EFC_EVT_NODE_MISSING:
1399         if (node->nport->enable_rscn)
1400             efc_node_transition(node, __efc_d_device_gone, NULL);
1401 
1402         break;
1403 
1404     case EFC_EVT_SRRS_ELS_CMPL_OK:
1405         /* T, or I+T, PRLI accept completed ok */
1406         WARN_ON(!node->els_cmpl_cnt);
1407         node->els_cmpl_cnt--;
1408         break;
1409 
1410     case EFC_EVT_SRRS_ELS_CMPL_FAIL:
1411         /* T, or I+T, PRLI accept failed to complete */
1412         WARN_ON(!node->els_cmpl_cnt);
1413         node->els_cmpl_cnt--;
1414         node_printf(node, "Failed to send PRLI LS_ACC\n");
1415         break;
1416 
1417     default:
1418         __efc_d_common(__func__, ctx, evt, arg);
1419     }
1420 }
1421 
1422 void
1423 __efc_d_device_gone(struct efc_sm_ctx *ctx,
1424             enum efc_sm_event evt, void *arg)
1425 {
1426     struct efc_node_cb *cbdata = arg;
1427     struct efc_node *node = ctx->app;
1428     struct efc *efc = node->efc;
1429 
1430     efc_node_evt_set(ctx, evt, __func__);
1431 
1432     node_sm_trace();
1433 
1434     switch (evt) {
1435     case EFC_EVT_ENTER: {
1436         int rc = EFC_SCSI_CALL_COMPLETE;
1437         int rc_2 = EFC_SCSI_CALL_COMPLETE;
1438         static const char * const labels[] = {
1439             "none", "initiator", "target", "initiator+target"
1440         };
1441 
1442         efc_log_info(efc, "[%s] missing (%s)    WWPN %s WWNN %s\n",
1443                  node->display_name,
1444                 labels[(node->targ << 1) | (node->init)],
1445                         node->wwpn, node->wwnn);
1446 
1447         switch (efc_node_get_enable(node)) {
1448         case EFC_NODE_ENABLE_T_TO_T:
1449         case EFC_NODE_ENABLE_I_TO_T:
1450         case EFC_NODE_ENABLE_IT_TO_T:
1451             rc = efc->tt.scsi_del_node(efc, node,
1452                 EFC_SCSI_TARGET_MISSING);
1453             break;
1454 
1455         case EFC_NODE_ENABLE_T_TO_I:
1456         case EFC_NODE_ENABLE_I_TO_I:
1457         case EFC_NODE_ENABLE_IT_TO_I:
1458             rc = efc->tt.scsi_del_node(efc, node,
1459                 EFC_SCSI_INITIATOR_MISSING);
1460             break;
1461 
1462         case EFC_NODE_ENABLE_T_TO_IT:
1463             rc = efc->tt.scsi_del_node(efc, node,
1464                 EFC_SCSI_INITIATOR_MISSING);
1465             break;
1466 
1467         case EFC_NODE_ENABLE_I_TO_IT:
1468             rc = efc->tt.scsi_del_node(efc, node,
1469                           EFC_SCSI_TARGET_MISSING);
1470             break;
1471 
1472         case EFC_NODE_ENABLE_IT_TO_IT:
1473             rc = efc->tt.scsi_del_node(efc, node,
1474                 EFC_SCSI_INITIATOR_MISSING);
1475             rc_2 = efc->tt.scsi_del_node(efc, node,
1476                 EFC_SCSI_TARGET_MISSING);
1477             break;
1478 
1479         default:
1480             rc = EFC_SCSI_CALL_COMPLETE;
1481             break;
1482         }
1483 
1484         if (rc == EFC_SCSI_CALL_COMPLETE &&
1485             rc_2 == EFC_SCSI_CALL_COMPLETE)
1486             efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
1487 
1488         break;
1489     }
1490     case EFC_EVT_NODE_REFOUND:
1491         /* two approaches, reauthenticate with PLOGI/PRLI, or ADISC */
1492 
1493         /* reauthenticate with PLOGI/PRLI */
1494         /* efc_node_transition(node, __efc_d_discovered, NULL); */
1495 
1496         /* reauthenticate with ADISC */
1497         /* sm: / send ADISC */
1498         efc_send_adisc(node);
1499         efc_node_transition(node, __efc_d_wait_adisc_rsp, NULL);
1500         break;
1501 
1502     case EFC_EVT_PLOGI_RCVD: {
1503         /* sm: / save sparams, set send_plogi_acc, post implicit
1504          * logout
1505          * Save plogi parameters
1506          */
1507         efc_node_save_sparms(node, cbdata->payload->dma.virt);
1508         efc_send_ls_acc_after_attach(node,
1509                          cbdata->header->dma.virt,
1510                 EFC_NODE_SEND_LS_ACC_PLOGI);
1511 
1512         /*
1513          * Restart node attach with new service parameters, and send
1514          * ACC
1515          */
1516         efc_node_post_event(node, EFC_EVT_SHUTDOWN_IMPLICIT_LOGO,
1517                     NULL);
1518         break;
1519     }
1520 
1521     case EFC_EVT_FCP_CMD_RCVD: {
1522         /* most likely a stale frame (received prior to link down),
1523          * if attempt to send LOGO, will probably timeout and eat
1524          * up 20s; thus, drop FCP_CMND
1525          */
1526         node_printf(node, "FCP_CMND received, drop\n");
1527         break;
1528     }
1529     case EFC_EVT_LOGO_RCVD: {
1530         /* I, T, I+T */
1531         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1532 
1533         node_printf(node, "%s received attached=%d\n",
1534                 efc_sm_event_name(evt), node->attached);
1535         /* sm: / send LOGO acc */
1536         efc_send_logo_acc(node, be16_to_cpu(hdr->fh_ox_id));
1537         efc_node_transition(node, __efc_d_wait_logo_acc_cmpl, NULL);
1538         break;
1539     }
1540     default:
1541         __efc_d_common(__func__, ctx, evt, arg);
1542     }
1543 }
1544 
1545 void
1546 __efc_d_wait_adisc_rsp(struct efc_sm_ctx *ctx,
1547                enum efc_sm_event evt, void *arg)
1548 {
1549     struct efc_node_cb *cbdata = arg;
1550     struct efc_node *node = ctx->app;
1551 
1552     efc_node_evt_set(ctx, evt, __func__);
1553 
1554     node_sm_trace();
1555 
1556     switch (evt) {
1557     case EFC_EVT_SRRS_ELS_REQ_OK:
1558         if (efc_node_check_els_req(ctx, evt, arg, ELS_ADISC,
1559                        __efc_d_common, __func__))
1560             return;
1561 
1562         WARN_ON(!node->els_req_cnt);
1563         node->els_req_cnt--;
1564         efc_node_transition(node, __efc_d_device_ready, NULL);
1565         break;
1566 
1567     case EFC_EVT_SRRS_ELS_REQ_RJT:
1568         /* received an LS_RJT, in this case, send shutdown
1569          * (explicit logo) event which will unregister the node,
1570          * and start over with PLOGI
1571          */
1572         if (efc_node_check_els_req(ctx, evt, arg, ELS_ADISC,
1573                        __efc_d_common, __func__))
1574             return;
1575 
1576         WARN_ON(!node->els_req_cnt);
1577         node->els_req_cnt--;
1578         /* sm: / post explicit logout */
1579         efc_node_post_event(node,
1580                     EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
1581                      NULL);
1582         break;
1583 
1584     case EFC_EVT_LOGO_RCVD: {
1585         /* In this case, we have the equivalent of an LS_RJT for
1586          * the ADISC, so we need to abort the ADISC, and re-login
1587          * with PLOGI
1588          */
1589         /* sm: / request abort, send LOGO acc */
1590         struct fc_frame_header *hdr = cbdata->header->dma.virt;
1591 
1592         node_printf(node, "%s received attached=%d\n",
1593                 efc_sm_event_name(evt), node->attached);
1594 
1595         efc_send_logo_acc(node, be16_to_cpu(hdr->fh_ox_id));
1596         efc_node_transition(node, __efc_d_wait_logo_acc_cmpl, NULL);
1597         break;
1598     }
1599     default:
1600         __efc_d_common(__func__, ctx, evt, arg);
1601     }
1602 }