@@ -1099,8 +1099,10 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
10991099 sp -> cmn .priority_tagging , kref_read (& ndlp -> kref ));
11001100
11011101 /* reinitialize the VMID datastructure before returning */
1102- if (lpfc_is_vmid_enabled (phba ))
1102+ if (lpfc_is_vmid_enabled (phba )) {
11031103 lpfc_reinit_vmid (vport );
1104+ vport -> vmid_flag = 0 ;
1105+ }
11041106 if (sp -> cmn .priority_tagging )
11051107 vport -> phba -> pport -> vmid_flag |= (LPFC_VMID_ISSUE_QFPA |
11061108 LPFC_VMID_TYPE_PRIO );
@@ -1390,7 +1392,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
13901392 phba -> link_flag &= ~LS_EXTERNAL_LOOPBACK ;
13911393
13921394 /* Check for a deferred FLOGI ACC condition */
1393- if (phba -> defer_flogi_acc_flag ) {
1395+ if (phba -> defer_flogi_acc . flag ) {
13941396 /* lookup ndlp for received FLOGI */
13951397 ndlp = lpfc_findnode_did (vport , 0 );
13961398 if (!ndlp )
@@ -1404,34 +1406,38 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
14041406 if (phba -> sli_rev == LPFC_SLI_REV4 ) {
14051407 bf_set (wqe_ctxt_tag ,
14061408 & defer_flogi_acc .wqe .xmit_els_rsp .wqe_com ,
1407- phba -> defer_flogi_acc_rx_id );
1409+ phba -> defer_flogi_acc . rx_id );
14081410 bf_set (wqe_rcvoxid ,
14091411 & defer_flogi_acc .wqe .xmit_els_rsp .wqe_com ,
1410- phba -> defer_flogi_acc_ox_id );
1412+ phba -> defer_flogi_acc . ox_id );
14111413 } else {
14121414 icmd = & defer_flogi_acc .iocb ;
1413- icmd -> ulpContext = phba -> defer_flogi_acc_rx_id ;
1415+ icmd -> ulpContext = phba -> defer_flogi_acc . rx_id ;
14141416 icmd -> unsli3 .rcvsli3 .ox_id =
1415- phba -> defer_flogi_acc_ox_id ;
1417+ phba -> defer_flogi_acc . ox_id ;
14161418 }
14171419
14181420 lpfc_printf_vlog (vport , KERN_INFO , LOG_ELS ,
14191421 "3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
14201422 " ox_id: x%x, hba_flag x%lx\n" ,
1421- phba -> defer_flogi_acc_rx_id ,
1422- phba -> defer_flogi_acc_ox_id , phba -> hba_flag );
1423+ phba -> defer_flogi_acc . rx_id ,
1424+ phba -> defer_flogi_acc . ox_id , phba -> hba_flag );
14231425
14241426 /* Send deferred FLOGI ACC */
14251427 lpfc_els_rsp_acc (vport , ELS_CMD_FLOGI , & defer_flogi_acc ,
14261428 ndlp , NULL );
14271429
1428- phba -> defer_flogi_acc_flag = false;
1429- vport -> fc_myDID = did ;
1430+ phba -> defer_flogi_acc .flag = false;
14301431
1431- /* Decrement ndlp reference count to indicate the node can be
1432- * released when other references are removed .
1432+ /* Decrement the held ndlp that was incremented when the
1433+ * deferred flogi acc flag was set .
14331434 */
1434- lpfc_nlp_put (ndlp );
1435+ if (phba -> defer_flogi_acc .ndlp ) {
1436+ lpfc_nlp_put (phba -> defer_flogi_acc .ndlp );
1437+ phba -> defer_flogi_acc .ndlp = NULL ;
1438+ }
1439+
1440+ vport -> fc_myDID = did ;
14351441 }
14361442
14371443 return 0 ;
@@ -5240,9 +5246,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
52405246 /* ACC to LOGO completes to NPort <nlp_DID> */
52415247 lpfc_printf_vlog (vport , KERN_INFO , LOG_ELS ,
52425248 "0109 ACC to LOGO completes to NPort x%x refcnt %d "
5243- "Data: x%x x%x x%x\n" ,
5244- ndlp -> nlp_DID , kref_read (& ndlp -> kref ), ndlp -> nlp_flag ,
5245- ndlp -> nlp_state , ndlp -> nlp_rpi );
5249+ "last els x%x Data: x%x x%x x%x\n" ,
5250+ ndlp -> nlp_DID , kref_read (& ndlp -> kref ),
5251+ ndlp -> nlp_last_elscmd , ndlp -> nlp_flag , ndlp -> nlp_state ,
5252+ ndlp -> nlp_rpi );
52465253
52475254 /* This clause allows the LOGO ACC to complete and free resources
52485255 * for the Fabric Domain Controller. It does deliberately skip
@@ -5254,18 +5261,22 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
52545261 goto out ;
52555262
52565263 if (ndlp -> nlp_state == NLP_STE_NPR_NODE ) {
5257- /* If PLOGI is being retried, PLOGI completion will cleanup the
5258- * node. The NLP_NPR_2B_DISC flag needs to be retained to make
5259- * progress on nodes discovered from last RSCN.
5260- */
5261- if ((ndlp -> nlp_flag & NLP_DELAY_TMO ) &&
5262- (ndlp -> nlp_last_elscmd == ELS_CMD_PLOGI ))
5263- goto out ;
5264-
52655264 if (ndlp -> nlp_flag & NLP_RPI_REGISTERED )
52665265 lpfc_unreg_rpi (vport , ndlp );
52675266
5267+ /* If came from PRLO, then PRLO_ACC is done.
5268+ * Start rediscovery now.
5269+ */
5270+ if (ndlp -> nlp_last_elscmd == ELS_CMD_PRLO ) {
5271+ spin_lock_irq (& ndlp -> lock );
5272+ ndlp -> nlp_flag |= NLP_NPR_2B_DISC ;
5273+ spin_unlock_irq (& ndlp -> lock );
5274+ ndlp -> nlp_prev_state = ndlp -> nlp_state ;
5275+ lpfc_nlp_set_state (vport , ndlp , NLP_STE_PLOGI_ISSUE );
5276+ lpfc_issue_els_plogi (vport , ndlp -> nlp_DID , 0 );
5277+ }
52685278 }
5279+
52695280 out :
52705281 /*
52715282 * The driver received a LOGO from the rport and has ACK'd it.
@@ -8454,21 +8465,27 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
84548465
84558466 /* Defer ACC response until AFTER we issue a FLOGI */
84568467 if (!test_bit (HBA_FLOGI_ISSUED , & phba -> hba_flag )) {
8457- phba -> defer_flogi_acc_rx_id = bf_get (wqe_ctxt_tag ,
8468+ phba -> defer_flogi_acc . rx_id = bf_get (wqe_ctxt_tag ,
84588469 & wqe -> xmit_els_rsp .wqe_com );
8459- phba -> defer_flogi_acc_ox_id = bf_get (wqe_rcvoxid ,
8470+ phba -> defer_flogi_acc . ox_id = bf_get (wqe_rcvoxid ,
84608471 & wqe -> xmit_els_rsp .wqe_com );
84618472
84628473 vport -> fc_myDID = did ;
84638474
84648475 lpfc_printf_vlog (vport , KERN_INFO , LOG_ELS ,
84658476 "3344 Deferring FLOGI ACC: rx_id: x%x,"
84668477 " ox_id: x%x, hba_flag x%lx\n" ,
8467- phba -> defer_flogi_acc_rx_id ,
8468- phba -> defer_flogi_acc_ox_id , phba -> hba_flag );
8478+ phba -> defer_flogi_acc . rx_id ,
8479+ phba -> defer_flogi_acc . ox_id , phba -> hba_flag );
84698480
8470- phba -> defer_flogi_acc_flag = true;
8481+ phba -> defer_flogi_acc . flag = true;
84718482
8483+ /* This nlp_get is paired with nlp_puts that reset the
8484+ * defer_flogi_acc.flag back to false. We need to retain
8485+ * a kref on the ndlp until the deferred FLOGI ACC is
8486+ * processed or cancelled.
8487+ */
8488+ phba -> defer_flogi_acc .ndlp = lpfc_nlp_get (ndlp );
84728489 return 0 ;
84738490 }
84748491
@@ -10504,7 +10521,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1050410521
1050510522 lpfc_els_rcv_flogi (vport , elsiocb , ndlp );
1050610523 /* retain node if our response is deferred */
10507- if (phba -> defer_flogi_acc_flag )
10524+ if (phba -> defer_flogi_acc . flag )
1050810525 break ;
1050910526 if (newnode )
1051010527 lpfc_disc_state_machine (vport , ndlp , NULL ,
@@ -10742,7 +10759,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1074210759 rjt_exp = LSEXP_NOTHING_MORE ;
1074310760
1074410761 /* Unknown ELS command <elsCmd> received from NPORT <did> */
10745- lpfc_printf_vlog (vport , KERN_ERR , LOG_TRACE_EVENT ,
10762+ lpfc_printf_vlog (vport , KERN_ERR , LOG_ELS ,
1074610763 "0115 Unknown ELS command x%x "
1074710764 "received from NPORT x%x\n" , cmd , did );
1074810765 if (newnode )
0 commit comments