aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c91
1 files changed, 82 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index a81d43306d17..d807f36ba4f9 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -771,6 +771,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
771 struct lpfc_nodelist *ndlp = cmdiocb->context1; 771 struct lpfc_nodelist *ndlp = cmdiocb->context1;
772 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; 772 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
773 struct serv_parm *sp; 773 struct serv_parm *sp;
774 uint16_t fcf_index;
774 int rc; 775 int rc;
775 776
776 /* Check to see if link went down during discovery */ 777 /* Check to see if link went down during discovery */
@@ -788,6 +789,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
788 vport->port_state); 789 vport->port_state);
789 790
790 if (irsp->ulpStatus) { 791 if (irsp->ulpStatus) {
792 /*
793 * In case of FIP mode, perform round robin FCF failover
794 * due to new FCF discovery
795 */
796 if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
797 (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
798 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
799 "2611 FLOGI failed on registered "
800 "FCF record fcf_index:%d, trying "
801 "to perform round robin failover\n",
802 phba->fcf.current_rec.fcf_indx);
803 fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
804 if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
805 /*
806 * Exhausted the eligible FCF record list,
807 * fail through to retry FLOGI on current
808 * FCF record.
809 */
810 lpfc_printf_log(phba, KERN_WARNING,
811 LOG_FIP | LOG_ELS,
812 "2760 FLOGI exhausted FCF "
813 "round robin failover list, "
814 "retry FLOGI on the current "
815 "registered FCF index:%d\n",
816 phba->fcf.current_rec.fcf_indx);
817 spin_lock_irq(&phba->hbalock);
818 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
819 spin_unlock_irq(&phba->hbalock);
820 } else {
821 rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
822 fcf_index);
823 if (rc) {
824 lpfc_printf_log(phba, KERN_WARNING,
825 LOG_FIP | LOG_ELS,
826 "2761 FLOGI round "
827 "robin FCF failover "
828 "read FCF failed "
829 "rc:x%x, fcf_index:"
830 "%d\n", rc,
831 phba->fcf.current_rec.fcf_indx);
832 spin_lock_irq(&phba->hbalock);
833 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
834 spin_unlock_irq(&phba->hbalock);
835 } else
836 goto out;
837 }
838 }
839
791 /* Check for retry */ 840 /* Check for retry */
792 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 841 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
793 goto out; 842 goto out;
@@ -841,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
841 else 890 else
842 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); 891 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
843 892
844 if (!rc) 893 if (!rc) {
894 /* Mark the FCF discovery process done */
895 lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
896 "2769 FLOGI successful on FCF record: "
897 "current_fcf_index:x%x, terminate FCF "
898 "round robin failover process\n",
899 phba->fcf.current_rec.fcf_indx);
900 spin_lock_irq(&phba->hbalock);
901 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
902 spin_unlock_irq(&phba->hbalock);
845 goto out; 903 goto out;
904 }
846 } 905 }
847 906
848flogifail: 907flogifail:
@@ -6075,21 +6134,18 @@ mbox_err_exit:
6075} 6134}
6076 6135
6077/** 6136/**
6078 * lpfc_retry_pport_discovery - Start timer to retry FLOGI. 6137 * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
6079 * @phba: pointer to lpfc hba data structure. 6138 * @phba: pointer to lpfc hba data structure.
6080 * 6139 *
6081 * This routine abort all pending discovery commands and 6140 * This routine cancels the retry delay timers to all the vports.
6082 * start a timer to retry FLOGI for the physical port
6083 * discovery.
6084 **/ 6141 **/
6085void 6142void
6086lpfc_retry_pport_discovery(struct lpfc_hba *phba) 6143lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
6087{ 6144{
6088 struct lpfc_vport **vports; 6145 struct lpfc_vport **vports;
6089 struct lpfc_nodelist *ndlp; 6146 struct lpfc_nodelist *ndlp;
6090 struct Scsi_Host *shost;
6091 int i;
6092 uint32_t link_state; 6147 uint32_t link_state;
6148 int i;
6093 6149
6094 /* Treat this failure as linkdown for all vports */ 6150 /* Treat this failure as linkdown for all vports */
6095 link_state = phba->link_state; 6151 link_state = phba->link_state;
@@ -6107,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6107 } 6163 }
6108 lpfc_destroy_vport_work_array(phba, vports); 6164 lpfc_destroy_vport_work_array(phba, vports);
6109 } 6165 }
6166}
6167
6168/**
6169 * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
6170 * @phba: pointer to lpfc hba data structure.
6171 *
6172 * This routine abort all pending discovery commands and
6173 * start a timer to retry FLOGI for the physical port
6174 * discovery.
6175 **/
6176void
6177lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6178{
6179 struct lpfc_nodelist *ndlp;
6180 struct Scsi_Host *shost;
6181
6182 /* Cancel the all vports retry delay retry timers */
6183 lpfc_cancel_all_vport_retry_delay_timer(phba);
6110 6184
6111 /* If fabric require FLOGI, then re-instantiate physical login */ 6185 /* If fabric require FLOGI, then re-instantiate physical login */
6112 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); 6186 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
6113 if (!ndlp) 6187 if (!ndlp)
6114 return; 6188 return;
6115 6189
6116
6117 shost = lpfc_shost_from_vport(phba->pport); 6190 shost = lpfc_shost_from_vport(phba->pport);
6118 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); 6191 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
6119 spin_lock_irq(shost->host_lock); 6192 spin_lock_irq(shost->host_lock);