@@ -3085,6 +3085,95 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
30853085 lpfc_nlp_put (free_ndlp );
30863086}
30873087
3088+ /**
3089+ * lpfc_reg_fab_ctrl_node - RPI register the fabric controller node.
3090+ * @vport: pointer to lpfc_vport data structure.
3091+ * @fc_ndlp: pointer to the fabric controller (0xfffffd) node.
3092+ *
3093+ * This routine registers the rpi assigned to the fabric controller
3094+ * NPort_ID (0xfffffd) with the port and moves the node to UNMAPPED
3095+ * state triggering a registration with the SCSI transport.
3096+ *
3097+ * This routine is single out because the fabric controller node
3098+ * does not receive a PLOGI. This routine is consumed by the
3099+ * SCR and RDF ELS commands. Callers are expected to qualify
3100+ * with SLI4 first.
3101+ **/
3102+ static int
3103+ lpfc_reg_fab_ctrl_node (struct lpfc_vport * vport , struct lpfc_nodelist * fc_ndlp )
3104+ {
3105+ int rc = 0 ;
3106+ struct lpfc_hba * phba = vport -> phba ;
3107+ struct lpfc_nodelist * ns_ndlp ;
3108+ LPFC_MBOXQ_t * mbox ;
3109+ struct lpfc_dmabuf * mp ;
3110+
3111+ if (fc_ndlp -> nlp_flag & NLP_RPI_REGISTERED )
3112+ return rc ;
3113+
3114+ ns_ndlp = lpfc_findnode_did (vport , NameServer_DID );
3115+ if (!ns_ndlp )
3116+ return - ENODEV ;
3117+
3118+ lpfc_printf_vlog (vport , KERN_INFO , LOG_NODE ,
3119+ "0935 %s: Reg FC RPI x%x on FC DID x%x NSSte: x%x\n" ,
3120+ __func__ , fc_ndlp -> nlp_rpi , fc_ndlp -> nlp_DID ,
3121+ ns_ndlp -> nlp_state );
3122+ if (ns_ndlp -> nlp_state != NLP_STE_UNMAPPED_NODE )
3123+ return - ENODEV ;
3124+
3125+ mbox = mempool_alloc (phba -> mbox_mem_pool , GFP_KERNEL );
3126+ if (!mbox ) {
3127+ lpfc_printf_vlog (vport , KERN_ERR , LOG_NODE ,
3128+ "0936 %s: no memory for reg_login "
3129+ "Data: x%x x%x x%x x%x\n" , __func__ ,
3130+ fc_ndlp -> nlp_DID , fc_ndlp -> nlp_state ,
3131+ fc_ndlp -> nlp_flag , fc_ndlp -> nlp_rpi );
3132+ return - ENOMEM ;
3133+ }
3134+ rc = lpfc_reg_rpi (phba , vport -> vpi , fc_ndlp -> nlp_DID ,
3135+ (u8 * )& vport -> fc_sparam , mbox , fc_ndlp -> nlp_rpi );
3136+ if (rc ) {
3137+ rc = - EACCES ;
3138+ goto out ;
3139+ }
3140+
3141+ fc_ndlp -> nlp_flag |= NLP_REG_LOGIN_SEND ;
3142+ mbox -> mbox_cmpl = lpfc_mbx_cmpl_fc_reg_login ;
3143+ mbox -> ctx_ndlp = lpfc_nlp_get (fc_ndlp );
3144+ if (!mbox -> ctx_ndlp ) {
3145+ rc = - ENOMEM ;
3146+ goto out_mem ;
3147+ }
3148+
3149+ mbox -> vport = vport ;
3150+ rc = lpfc_sli_issue_mbox (phba , mbox , MBX_NOWAIT );
3151+ if (rc == MBX_NOT_FINISHED ) {
3152+ rc = - ENODEV ;
3153+ lpfc_nlp_put (fc_ndlp );
3154+ goto out_mem ;
3155+ }
3156+ /* Success path. Exit. */
3157+ lpfc_nlp_set_state (vport , fc_ndlp ,
3158+ NLP_STE_REG_LOGIN_ISSUE );
3159+ return 0 ;
3160+
3161+ out_mem :
3162+ fc_ndlp -> nlp_flag &= ~NLP_REG_LOGIN_SEND ;
3163+ mp = (struct lpfc_dmabuf * )mbox -> ctx_buf ;
3164+ lpfc_mbuf_free (phba , mp -> virt , mp -> phys );
3165+ kfree (mp );
3166+
3167+ out :
3168+ mempool_free (mbox , phba -> mbox_mem_pool );
3169+ lpfc_printf_vlog (vport , KERN_ERR , LOG_NODE ,
3170+ "0938 %s: failed to format reg_login "
3171+ "Data: x%x x%x x%x x%x\n" , __func__ ,
3172+ fc_ndlp -> nlp_DID , fc_ndlp -> nlp_state ,
3173+ fc_ndlp -> nlp_flag , fc_ndlp -> nlp_rpi );
3174+ return rc ;
3175+ }
3176+
30883177/**
30893178 * lpfc_cmpl_els_disc_cmd - Completion callback function for Discovery ELS cmd
30903179 * @phba: pointer to lpfc hba data structure.
@@ -3231,10 +3320,18 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
32313320
32323321 elsiocb = lpfc_prep_els_iocb (vport , 1 , cmdsize , retry , ndlp ,
32333322 ndlp -> nlp_DID , ELS_CMD_SCR );
3234-
32353323 if (!elsiocb )
32363324 return 1 ;
32373325
3326+ if (phba -> sli_rev == LPFC_SLI_REV4 ) {
3327+ rc = lpfc_reg_fab_ctrl_node (vport , ndlp );
3328+ if (rc ) {
3329+ lpfc_printf_vlog (vport , KERN_ERR , LOG_NODE ,
3330+ "0937 %s: Failed to reg fc node, rc %d\n" ,
3331+ __func__ , rc );
3332+ return 1 ;
3333+ }
3334+ }
32383335 pcmd = (uint8_t * ) (((struct lpfc_dmabuf * ) elsiocb -> context2 )-> virt );
32393336
32403337 * ((uint32_t * ) (pcmd )) = ELS_CMD_SCR ;
@@ -3522,6 +3619,17 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
35223619 if (!elsiocb )
35233620 return - ENOMEM ;
35243621
3622+ if (phba -> sli_rev == LPFC_SLI_REV4 &&
3623+ !(ndlp -> nlp_flag & NLP_RPI_REGISTERED )) {
3624+ lpfc_printf_vlog (vport , KERN_ERR , LOG_NODE ,
3625+ "0939 %s: FC_NODE x%x RPI x%x flag x%x "
3626+ "ste x%x type x%x Not registered\n" ,
3627+ __func__ , ndlp -> nlp_DID , ndlp -> nlp_rpi ,
3628+ ndlp -> nlp_flag , ndlp -> nlp_state ,
3629+ ndlp -> nlp_type );
3630+ return - ENODEV ;
3631+ }
3632+
35253633 /* Configure the payload for the supported FPIN events. */
35263634 prdf = (struct lpfc_els_rdf_req * )
35273635 (((struct lpfc_dmabuf * )elsiocb -> context2 )-> virt );
@@ -4396,7 +4504,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
43964504 struct lpfc_nodelist * ndlp = (struct lpfc_nodelist * ) cmdiocb -> context1 ;
43974505 struct lpfc_vport * vport = cmdiocb -> vport ;
43984506 IOCB_t * irsp ;
4399- u32 xpt_flags = 0 , did_mask = 0 ;
44004507
44014508 irsp = & rspiocb -> iocb ;
44024509 lpfc_debugfs_disc_trc (vport , LPFC_DISC_TRC_ELS_RSP ,
@@ -4409,23 +4516,27 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
44094516 ndlp -> nlp_DID , kref_read (& ndlp -> kref ), ndlp -> nlp_flag ,
44104517 ndlp -> nlp_state , ndlp -> nlp_rpi );
44114518
4519+ /* This clause allows the LOGO ACC to complete and free resources
4520+ * for the Fabric Domain Controller. It does deliberately skip
4521+ * the unreg_rpi and release rpi because some fabrics send RDP
4522+ * requests after logging out from the initiator.
4523+ */
4524+ if (ndlp -> nlp_type & NLP_FABRIC &&
4525+ ((ndlp -> nlp_DID & WELL_KNOWN_DID_MASK ) != WELL_KNOWN_DID_MASK ))
4526+ goto out ;
4527+
44124528 if (ndlp -> nlp_state == NLP_STE_NPR_NODE ) {
44134529 /* NPort Recovery mode or node is just allocated */
44144530 if (!lpfc_nlp_not_used (ndlp )) {
44154531 /* A LOGO is completing and the node is in NPR state.
44164532 * If this a fabric node that cleared its transport
44174533 * registration, release the rpi.
44184534 */
4419- xpt_flags = SCSI_XPT_REGD | NVME_XPT_REGD ;
4420- did_mask = ndlp -> nlp_DID & Fabric_DID_MASK ;
4421- if (did_mask == Fabric_DID_MASK &&
4422- !(ndlp -> fc4_xpt_flags & xpt_flags )) {
4423- spin_lock_irq (& ndlp -> lock );
4424- ndlp -> nlp_flag &= ~NLP_NPR_2B_DISC ;
4425- if (phba -> sli_rev == LPFC_SLI_REV4 )
4426- ndlp -> nlp_flag |= NLP_RELEASE_RPI ;
4427- spin_unlock_irq (& ndlp -> lock );
4428- }
4535+ spin_lock_irq (& ndlp -> lock );
4536+ ndlp -> nlp_flag &= ~NLP_NPR_2B_DISC ;
4537+ if (phba -> sli_rev == LPFC_SLI_REV4 )
4538+ ndlp -> nlp_flag |= NLP_RELEASE_RPI ;
4539+ spin_unlock_irq (& ndlp -> lock );
44294540 lpfc_unreg_rpi (vport , ndlp );
44304541 } else {
44314542 /* Indicate the node has already released, should
@@ -4434,7 +4545,7 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
44344545 cmdiocb -> context1 = NULL ;
44354546 }
44364547 }
4437-
4548+ out :
44384549 /*
44394550 * The driver received a LOGO from the rport and has ACK'd it.
44404551 * At this point, the driver is done so release the IOCB
0 commit comments