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.c76
1 files changed, 61 insertions, 15 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 45337cd23fe..a079bbc03cf 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -173,13 +173,26 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
173 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames. 173 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
174 */ 174 */
175 if ((did == Fabric_DID) && 175 if ((did == Fabric_DID) &&
176 bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) && 176 (phba->hba_flag & HBA_FIP_SUPPORT) &&
177 ((elscmd == ELS_CMD_FLOGI) || 177 ((elscmd == ELS_CMD_FLOGI) ||
178 (elscmd == ELS_CMD_FDISC) || 178 (elscmd == ELS_CMD_FDISC) ||
179 (elscmd == ELS_CMD_LOGO))) 179 (elscmd == ELS_CMD_LOGO)))
180 elsiocb->iocb_flag |= LPFC_FIP_ELS; 180 switch (elscmd) {
181 case ELS_CMD_FLOGI:
182 elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
183 & LPFC_FIP_ELS_ID_MASK);
184 break;
185 case ELS_CMD_FDISC:
186 elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
187 & LPFC_FIP_ELS_ID_MASK);
188 break;
189 case ELS_CMD_LOGO:
190 elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
191 & LPFC_FIP_ELS_ID_MASK);
192 break;
193 }
181 else 194 else
182 elsiocb->iocb_flag &= ~LPFC_FIP_ELS; 195 elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
183 196
184 icmd = &elsiocb->iocb; 197 icmd = &elsiocb->iocb;
185 198
@@ -591,7 +604,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
591 } else { 604 } else {
592 ndlp->nlp_type |= NLP_FABRIC; 605 ndlp->nlp_type |= NLP_FABRIC;
593 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 606 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
594 if (vport->vfi_state & LPFC_VFI_REGISTERED) { 607 if (vport->vpi_state & LPFC_VPI_REGISTERED) {
595 lpfc_start_fdiscs(phba); 608 lpfc_start_fdiscs(phba);
596 lpfc_do_scr_ns_plogi(phba, vport); 609 lpfc_do_scr_ns_plogi(phba, vport);
597 } else 610 } else
@@ -2452,6 +2465,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
2452 */ 2465 */
2453 del_timer_sync(&ndlp->nlp_delayfunc); 2466 del_timer_sync(&ndlp->nlp_delayfunc);
2454 retry = ndlp->nlp_retry; 2467 retry = ndlp->nlp_retry;
2468 ndlp->nlp_retry = 0;
2455 2469
2456 switch (cmd) { 2470 switch (cmd) {
2457 case ELS_CMD_FLOGI: 2471 case ELS_CMD_FLOGI:
@@ -2711,12 +2725,16 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2711 !lpfc_error_lost_link(irsp)) { 2725 !lpfc_error_lost_link(irsp)) {
2712 /* FLOGI retry policy */ 2726 /* FLOGI retry policy */
2713 retry = 1; 2727 retry = 1;
2714 maxretry = 48; 2728 /* retry forever */
2715 if (cmdiocb->retry >= 32) 2729 maxretry = 0;
2730 if (cmdiocb->retry >= 100)
2731 delay = 5000;
2732 else if (cmdiocb->retry >= 32)
2716 delay = 1000; 2733 delay = 1000;
2717 } 2734 }
2718 2735
2719 if ((++cmdiocb->retry) >= maxretry) { 2736 cmdiocb->retry++;
2737 if (maxretry && (cmdiocb->retry >= maxretry)) {
2720 phba->fc_stat.elsRetryExceeded++; 2738 phba->fc_stat.elsRetryExceeded++;
2721 retry = 0; 2739 retry = 0;
2722 } 2740 }
@@ -4503,6 +4521,29 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4503} 4521}
4504 4522
4505/** 4523/**
4524 * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
4525 * @vport: pointer to a host virtual N_Port data structure.
4526 * @cmdiocb: pointer to lpfc command iocb data structure.
4527 * @ndlp: pointer to a node-list data structure.
4528 *
4529 * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
4530 * received as an ELS unsolicited event. A request to RRQ shall only
4531 * be accepted if the Originator Nx_Port N_Port_ID or the Responder
4532 * Nx_Port N_Port_ID of the target Exchange is the same as the
4533 * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
4534 * not accepted, an LS_RJT with reason code "Unable to perform
4535 * command request" and reason code explanation "Invalid Originator
4536 * S_ID" shall be returned. For now, we just unconditionally accept
4537 * RRQ from the target.
4538 **/
4539static void
4540lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4541 struct lpfc_nodelist *ndlp)
4542{
4543 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4544}
4545
4546/**
4506 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd 4547 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4507 * @phba: pointer to lpfc hba data structure. 4548 * @phba: pointer to lpfc hba data structure.
4508 * @pmb: pointer to the driver internal queue element for mailbox command. 4549 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -5396,7 +5437,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5396 if (lpfc_els_chk_latt(vport)) 5437 if (lpfc_els_chk_latt(vport))
5397 goto dropit; 5438 goto dropit;
5398 5439
5399 /* Ignore traffic recevied during vport shutdown. */ 5440 /* Ignore traffic received during vport shutdown. */
5400 if (vport->load_flag & FC_UNLOADING) 5441 if (vport->load_flag & FC_UNLOADING)
5401 goto dropit; 5442 goto dropit;
5402 5443
@@ -5618,6 +5659,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5618 if (newnode) 5659 if (newnode)
5619 lpfc_nlp_put(ndlp); 5660 lpfc_nlp_put(ndlp);
5620 break; 5661 break;
5662 case ELS_CMD_RRQ:
5663 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5664 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
5665 did, vport->port_state, ndlp->nlp_flag);
5666
5667 phba->fc_stat.elsRcvRRQ++;
5668 lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
5669 if (newnode)
5670 lpfc_nlp_put(ndlp);
5671 break;
5621 default: 5672 default:
5622 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 5673 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5623 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", 5674 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
@@ -5670,7 +5721,7 @@ dropit:
5670 * NULL - No vport with the matching @vpi found 5721 * NULL - No vport with the matching @vpi found
5671 * Otherwise - Address to the vport with the matching @vpi. 5722 * Otherwise - Address to the vport with the matching @vpi.
5672 **/ 5723 **/
5673static struct lpfc_vport * 5724struct lpfc_vport *
5674lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) 5725lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
5675{ 5726{
5676 struct lpfc_vport *vport; 5727 struct lpfc_vport *vport;
@@ -6024,11 +6075,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6024 irsp->ulpStatus, irsp->un.ulpWord[4]); 6075 irsp->ulpStatus, irsp->un.ulpWord[4]);
6025 goto fdisc_failed; 6076 goto fdisc_failed;
6026 } 6077 }
6027 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
6028 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
6029 lpfc_nlp_put(ndlp);
6030 /* giving up on FDISC. Cancel discovery timer */
6031 lpfc_can_disctmo(vport);
6032 spin_lock_irq(shost->host_lock); 6078 spin_lock_irq(shost->host_lock);
6033 vport->fc_flag |= FC_FABRIC; 6079 vport->fc_flag |= FC_FABRIC;
6034 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6080 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
@@ -6107,6 +6153,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6107 int did = ndlp->nlp_DID; 6153 int did = ndlp->nlp_DID;
6108 int rc; 6154 int rc;
6109 6155
6156 vport->port_state = LPFC_FDISC;
6110 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); 6157 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
6111 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, 6158 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
6112 ELS_CMD_FDISC); 6159 ELS_CMD_FDISC);
@@ -6172,7 +6219,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6172 return 1; 6219 return 1;
6173 } 6220 }
6174 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING); 6221 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
6175 vport->port_state = LPFC_FDISC;
6176 return 0; 6222 return 0;
6177} 6223}
6178 6224