diff options
author | James Smart <james.smart@emulex.com> | 2010-08-04 16:11:39 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-08-06 13:11:44 -0400 |
commit | 38b92ef89b0d5a255f2f812c623fcdec4e63a21c (patch) | |
tree | 974498b393ebc3ef8ac67dcb2b2969e58c2b32ca /drivers | |
parent | bc73905abf7701920fe687564ecd3c6b316b9a2e (diff) |
[SCSI] lpfc 8.3.16: FCoE Discovery and Failover Fixes
- Add support for re-reg'ing changed VPI w/o unregister VPI
- Copy WWN and state from old nodelist when target DID change.
- Clean up old nodelist rport and put the nodelist when target DID change.
- Clear the VFI_REGISTERED flag when UNREG_VFI completes.
- Made both checks of port_state against LPFC_FLOGI and LPFC_FDISC
non-inclusive for ignoring CVL events.
- Added logic to stop retrying of the ongoing PLOGI and FDISC if
transitioned back to the FCF rediscovery state in reaction to CVL.
- Removed the dependency of scanning of all the available FCF table
entries for bulding round-robin bitmap.
- Use the lpfc_sli4_fcf_rr_read_fcf_rec() in responding to
individual New FCF found event.
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 76 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 15 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 79 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 8 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 7 |
6 files changed, 144 insertions, 47 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index afbed6bc31f0..8d09191c327e 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -600,6 +600,14 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
600 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 600 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; |
601 | spin_unlock_irq(shost->host_lock); | 601 | spin_unlock_irq(shost->host_lock); |
602 | } | 602 | } |
603 | } else if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
604 | !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) { | ||
605 | /* | ||
606 | * Driver needs to re-reg VPI in order for f/w | ||
607 | * to update the MAC address. | ||
608 | */ | ||
609 | lpfc_register_new_vport(phba, vport, ndlp); | ||
610 | return 0; | ||
603 | } | 611 | } |
604 | 612 | ||
605 | if (phba->sli_rev < LPFC_SLI_REV4) { | 613 | if (phba->sli_rev < LPFC_SLI_REV4) { |
@@ -801,9 +809,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
801 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) { | 809 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) { |
802 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, | 810 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, |
803 | "2611 FLOGI failed on registered " | 811 | "2611 FLOGI failed on registered " |
804 | "FCF record fcf_index:%d, trying " | 812 | "FCF record fcf_index(%d), status: " |
805 | "to perform round robin failover\n", | 813 | "x%x/x%x, tmo:x%x, trying to perform " |
806 | phba->fcf.current_rec.fcf_indx); | 814 | "round robin failover\n", |
815 | phba->fcf.current_rec.fcf_indx, | ||
816 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
817 | irsp->ulpTimeout); | ||
807 | fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); | 818 | fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); |
808 | if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { | 819 | if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { |
809 | /* | 820 | /* |
@@ -841,6 +852,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
841 | } | 852 | } |
842 | } | 853 | } |
843 | 854 | ||
855 | /* FLOGI failure */ | ||
856 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
857 | "2858 FLOGI failure Status:x%x/x%x TMO:x%x\n", | ||
858 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
859 | irsp->ulpTimeout); | ||
860 | |||
844 | /* Check for retry */ | 861 | /* Check for retry */ |
845 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) | 862 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
846 | goto out; | 863 | goto out; |
@@ -1291,6 +1308,8 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
1291 | struct serv_parm *sp; | 1308 | struct serv_parm *sp; |
1292 | uint8_t name[sizeof(struct lpfc_name)]; | 1309 | uint8_t name[sizeof(struct lpfc_name)]; |
1293 | uint32_t rc, keepDID = 0; | 1310 | uint32_t rc, keepDID = 0; |
1311 | int put_node; | ||
1312 | int put_rport; | ||
1294 | 1313 | ||
1295 | /* Fabric nodes can have the same WWPN so we don't bother searching | 1314 | /* Fabric nodes can have the same WWPN so we don't bother searching |
1296 | * by WWPN. Just return the ndlp that was given to us. | 1315 | * by WWPN. Just return the ndlp that was given to us. |
@@ -1379,6 +1398,28 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
1379 | /* Two ndlps cannot have the same did */ | 1398 | /* Two ndlps cannot have the same did */ |
1380 | ndlp->nlp_DID = keepDID; | 1399 | ndlp->nlp_DID = keepDID; |
1381 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 1400 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1401 | /* Since we are swapping the ndlp passed in with the new one | ||
1402 | * and the did has already been swapped, copy over the | ||
1403 | * state and names. | ||
1404 | */ | ||
1405 | memcpy(&new_ndlp->nlp_portname, &ndlp->nlp_portname, | ||
1406 | sizeof(struct lpfc_name)); | ||
1407 | memcpy(&new_ndlp->nlp_nodename, &ndlp->nlp_nodename, | ||
1408 | sizeof(struct lpfc_name)); | ||
1409 | new_ndlp->nlp_state = ndlp->nlp_state; | ||
1410 | /* Fix up the rport accordingly */ | ||
1411 | rport = ndlp->rport; | ||
1412 | if (rport) { | ||
1413 | rdata = rport->dd_data; | ||
1414 | put_node = rdata->pnode != NULL; | ||
1415 | put_rport = ndlp->rport != NULL; | ||
1416 | rdata->pnode = NULL; | ||
1417 | ndlp->rport = NULL; | ||
1418 | if (put_node) | ||
1419 | lpfc_nlp_put(ndlp); | ||
1420 | if (put_rport) | ||
1421 | put_device(&rport->dev); | ||
1422 | } | ||
1382 | } | 1423 | } |
1383 | return new_ndlp; | 1424 | return new_ndlp; |
1384 | } | 1425 | } |
@@ -2880,6 +2921,17 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2880 | retry = 0; | 2921 | retry = 0; |
2881 | 2922 | ||
2882 | if (retry) { | 2923 | if (retry) { |
2924 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_FDISC)) { | ||
2925 | /* Stop retrying PLOGI and FDISC if in FCF discovery */ | ||
2926 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) { | ||
2927 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | ||
2928 | "2849 Stop retry ELS command " | ||
2929 | "x%x to remote NPORT x%x, " | ||
2930 | "Data: x%x x%x\n", cmd, did, | ||
2931 | cmdiocb->retry, delay); | ||
2932 | return 0; | ||
2933 | } | ||
2934 | } | ||
2883 | 2935 | ||
2884 | /* Retry ELS command <elsCmd> to remote NPORT <did> */ | 2936 | /* Retry ELS command <elsCmd> to remote NPORT <did> */ |
2885 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 2937 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, |
@@ -6076,8 +6128,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
6076 | 6128 | ||
6077 | if (mb->mbxStatus) { | 6129 | if (mb->mbxStatus) { |
6078 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 6130 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
6079 | "0915 Register VPI failed: 0x%x\n", | 6131 | "0915 Register VPI failed : Status: x%x" |
6080 | mb->mbxStatus); | 6132 | " upd bit: x%x \n", mb->mbxStatus, |
6133 | mb->un.varRegVpi.upd); | ||
6134 | if (phba->sli_rev == LPFC_SLI_REV4 && | ||
6135 | mb->un.varRegVpi.upd) | ||
6136 | goto mbox_err_exit ; | ||
6081 | 6137 | ||
6082 | switch (mb->mbxStatus) { | 6138 | switch (mb->mbxStatus) { |
6083 | case 0x11: /* unsupported feature */ | 6139 | case 0x11: /* unsupported feature */ |
@@ -6142,7 +6198,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
6142 | } else | 6198 | } else |
6143 | lpfc_do_scr_ns_plogi(phba, vport); | 6199 | lpfc_do_scr_ns_plogi(phba, vport); |
6144 | } | 6200 | } |
6145 | 6201 | mbox_err_exit: | |
6146 | /* Now, we decrement the ndlp reference count held for this | 6202 | /* Now, we decrement the ndlp reference count held for this |
6147 | * callback function | 6203 | * callback function |
6148 | */ | 6204 | */ |
@@ -6387,6 +6443,14 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
6387 | else | 6443 | else |
6388 | vport->fc_flag |= FC_LOGO_RCVD_DID_CHNG; | 6444 | vport->fc_flag |= FC_LOGO_RCVD_DID_CHNG; |
6389 | spin_unlock_irq(shost->host_lock); | 6445 | spin_unlock_irq(shost->host_lock); |
6446 | } else if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
6447 | !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) { | ||
6448 | /* | ||
6449 | * Driver needs to re-reg VPI in order for f/w | ||
6450 | * to update the MAC address. | ||
6451 | */ | ||
6452 | lpfc_register_new_vport(phba, vport, ndlp); | ||
6453 | return ; | ||
6390 | } | 6454 | } |
6391 | 6455 | ||
6392 | if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI) | 6456 | if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI) |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index efba65b368a8..1f62ea8c165d 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1852,8 +1852,7 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1852 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | 1852 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); |
1853 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) | 1853 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) |
1854 | /* If in fast failover, mark it's completed */ | 1854 | /* If in fast failover, mark it's completed */ |
1855 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | | 1855 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; |
1856 | FCF_DISCOVERY); | ||
1857 | spin_unlock_irq(&phba->hbalock); | 1856 | spin_unlock_irq(&phba->hbalock); |
1858 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | 1857 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, |
1859 | "2836 The new FCF record (x%x) " | 1858 | "2836 The new FCF record (x%x) " |
@@ -2651,7 +2650,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2651 | spin_unlock_irq(&phba->hbalock); | 2650 | spin_unlock_irq(&phba->hbalock); |
2652 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | 2651 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
2653 | "2778 Start FCF table scan at linkup\n"); | 2652 | "2778 Start FCF table scan at linkup\n"); |
2654 | |||
2655 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, | 2653 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, |
2656 | LPFC_FCOE_FCF_GET_FIRST); | 2654 | LPFC_FCOE_FCF_GET_FIRST); |
2657 | if (rc) { | 2655 | if (rc) { |
@@ -2660,6 +2658,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2660 | spin_unlock_irq(&phba->hbalock); | 2658 | spin_unlock_irq(&phba->hbalock); |
2661 | goto out; | 2659 | goto out; |
2662 | } | 2660 | } |
2661 | /* Reset FCF roundrobin bmask for new discovery */ | ||
2662 | memset(phba->fcf.fcf_rr_bmask, 0, | ||
2663 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
2663 | } | 2664 | } |
2664 | 2665 | ||
2665 | return; | 2666 | return; |
@@ -5097,6 +5098,7 @@ static void | |||
5097 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 5098 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) |
5098 | { | 5099 | { |
5099 | struct lpfc_vport *vport = mboxq->vport; | 5100 | struct lpfc_vport *vport = mboxq->vport; |
5101 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
5100 | 5102 | ||
5101 | if (mboxq->u.mb.mbxStatus) { | 5103 | if (mboxq->u.mb.mbxStatus) { |
5102 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 5104 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
@@ -5104,6 +5106,9 @@ lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
5104 | "HBA state x%x\n", | 5106 | "HBA state x%x\n", |
5105 | mboxq->u.mb.mbxStatus, vport->port_state); | 5107 | mboxq->u.mb.mbxStatus, vport->port_state); |
5106 | } | 5108 | } |
5109 | spin_lock_irq(shost->host_lock); | ||
5110 | phba->pport->fc_flag &= ~FC_VFI_REGISTERED; | ||
5111 | spin_unlock_irq(shost->host_lock); | ||
5107 | mempool_free(mboxq, phba->mbox_mem_pool); | 5112 | mempool_free(mboxq, phba->mbox_mem_pool); |
5108 | return; | 5113 | return; |
5109 | } | 5114 | } |
@@ -5285,6 +5290,10 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | |||
5285 | spin_lock_irq(&phba->hbalock); | 5290 | spin_lock_irq(&phba->hbalock); |
5286 | phba->fcf.fcf_flag |= FCF_INIT_DISC; | 5291 | phba->fcf.fcf_flag |= FCF_INIT_DISC; |
5287 | spin_unlock_irq(&phba->hbalock); | 5292 | spin_unlock_irq(&phba->hbalock); |
5293 | |||
5294 | /* Reset FCF roundrobin bmask for new discovery */ | ||
5295 | memset(phba->fcf.fcf_rr_bmask, 0, sizeof(*phba->fcf.fcf_rr_bmask)); | ||
5296 | |||
5288 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | 5297 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); |
5289 | 5298 | ||
5290 | if (rc) { | 5299 | if (rc) { |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 897caa05e94d..1676f61291e7 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -2291,7 +2291,8 @@ typedef struct { | |||
2291 | typedef struct { | 2291 | typedef struct { |
2292 | #ifdef __BIG_ENDIAN_BITFIELD | 2292 | #ifdef __BIG_ENDIAN_BITFIELD |
2293 | uint32_t rsvd1; | 2293 | uint32_t rsvd1; |
2294 | uint32_t rsvd2:8; | 2294 | uint32_t rsvd2:7; |
2295 | uint32_t upd:1; | ||
2295 | uint32_t sid:24; | 2296 | uint32_t sid:24; |
2296 | uint32_t wwn[2]; | 2297 | uint32_t wwn[2]; |
2297 | uint32_t rsvd5; | 2298 | uint32_t rsvd5; |
@@ -2300,7 +2301,8 @@ typedef struct { | |||
2300 | #else /* __LITTLE_ENDIAN */ | 2301 | #else /* __LITTLE_ENDIAN */ |
2301 | uint32_t rsvd1; | 2302 | uint32_t rsvd1; |
2302 | uint32_t sid:24; | 2303 | uint32_t sid:24; |
2303 | uint32_t rsvd2:8; | 2304 | uint32_t upd:1; |
2305 | uint32_t rsvd2:7; | ||
2304 | uint32_t wwn[2]; | 2306 | uint32_t wwn[2]; |
2305 | uint32_t rsvd5; | 2307 | uint32_t rsvd5; |
2306 | uint16_t vpi; | 2308 | uint16_t vpi; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 9244aa64b3be..da9ba06ad583 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3300,10 +3300,10 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport) | |||
3300 | if (!ndlp) | 3300 | if (!ndlp) |
3301 | return 0; | 3301 | return 0; |
3302 | } | 3302 | } |
3303 | if (phba->pport->port_state <= LPFC_FLOGI) | 3303 | if (phba->pport->port_state < LPFC_FLOGI) |
3304 | return NULL; | 3304 | return NULL; |
3305 | /* If virtual link is not yet instantiated ignore CVL */ | 3305 | /* If virtual link is not yet instantiated ignore CVL */ |
3306 | if (vport->port_state <= LPFC_FDISC) | 3306 | if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC)) |
3307 | return NULL; | 3307 | return NULL; |
3308 | shost = lpfc_shost_from_vport(vport); | 3308 | shost = lpfc_shost_from_vport(vport); |
3309 | if (!shost) | 3309 | if (!shost) |
@@ -3376,21 +3376,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3376 | "evt_tag:x%x, fcf_index:x%x\n", | 3376 | "evt_tag:x%x, fcf_index:x%x\n", |
3377 | acqe_fcoe->event_tag, | 3377 | acqe_fcoe->event_tag, |
3378 | acqe_fcoe->index); | 3378 | acqe_fcoe->index); |
3379 | /* If the FCF discovery is in progress, do nothing. */ | 3379 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) { |
3380 | spin_lock_irq(&phba->hbalock); | ||
3381 | if (phba->hba_flag & FCF_DISC_INPROGRESS) { | ||
3382 | spin_unlock_irq(&phba->hbalock); | ||
3383 | break; | ||
3384 | } | ||
3385 | /* If fast FCF failover rescan event is pending, do nothing */ | ||
3386 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { | ||
3387 | spin_unlock_irq(&phba->hbalock); | ||
3388 | break; | ||
3389 | } | ||
3390 | spin_unlock_irq(&phba->hbalock); | ||
3391 | |||
3392 | if ((phba->fcf.fcf_flag & FCF_DISCOVERY) && | ||
3393 | !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { | ||
3394 | /* | 3380 | /* |
3395 | * During period of FCF discovery, read the FCF | 3381 | * During period of FCF discovery, read the FCF |
3396 | * table record indexed by the event to update | 3382 | * table record indexed by the event to update |
@@ -3404,13 +3390,26 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3404 | acqe_fcoe->index); | 3390 | acqe_fcoe->index); |
3405 | rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index); | 3391 | rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index); |
3406 | } | 3392 | } |
3407 | /* If the FCF has been in discovered state, do nothing. */ | 3393 | |
3394 | /* If the FCF discovery is in progress, do nothing. */ | ||
3408 | spin_lock_irq(&phba->hbalock); | 3395 | spin_lock_irq(&phba->hbalock); |
3396 | if (phba->hba_flag & FCF_DISC_INPROGRESS) { | ||
3397 | spin_unlock_irq(&phba->hbalock); | ||
3398 | break; | ||
3399 | } | ||
3400 | /* If fast FCF failover rescan event is pending, do nothing */ | ||
3401 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { | ||
3402 | spin_unlock_irq(&phba->hbalock); | ||
3403 | break; | ||
3404 | } | ||
3405 | |||
3406 | /* If the FCF has been in discovered state, do nothing. */ | ||
3409 | if (phba->fcf.fcf_flag & FCF_SCAN_DONE) { | 3407 | if (phba->fcf.fcf_flag & FCF_SCAN_DONE) { |
3410 | spin_unlock_irq(&phba->hbalock); | 3408 | spin_unlock_irq(&phba->hbalock); |
3411 | break; | 3409 | break; |
3412 | } | 3410 | } |
3413 | spin_unlock_irq(&phba->hbalock); | 3411 | spin_unlock_irq(&phba->hbalock); |
3412 | |||
3414 | /* Otherwise, scan the entire FCF table and re-discover SAN */ | 3413 | /* Otherwise, scan the entire FCF table and re-discover SAN */ |
3415 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | 3414 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
3416 | "2770 Start FCF table scan due to new FCF " | 3415 | "2770 Start FCF table scan due to new FCF " |
@@ -3436,13 +3435,9 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3436 | "2549 FCF disconnected from network index 0x%x" | 3435 | "2549 FCF disconnected from network index 0x%x" |
3437 | " tag 0x%x\n", acqe_fcoe->index, | 3436 | " tag 0x%x\n", acqe_fcoe->index, |
3438 | acqe_fcoe->event_tag); | 3437 | acqe_fcoe->event_tag); |
3439 | /* If the event is not for currently used fcf do nothing */ | 3438 | /* |
3440 | if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) | 3439 | * If we are in the middle of FCF failover process, clear |
3441 | break; | 3440 | * the corresponding FCF bit in the roundrobin bitmap. |
3442 | /* We request port to rediscover the entire FCF table for | ||
3443 | * a fast recovery from case that the current FCF record | ||
3444 | * is no longer valid if we are not in the middle of FCF | ||
3445 | * failover process already. | ||
3446 | */ | 3441 | */ |
3447 | spin_lock_irq(&phba->hbalock); | 3442 | spin_lock_irq(&phba->hbalock); |
3448 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) { | 3443 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) { |
@@ -3451,9 +3446,23 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3451 | lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index); | 3446 | lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index); |
3452 | break; | 3447 | break; |
3453 | } | 3448 | } |
3449 | spin_unlock_irq(&phba->hbalock); | ||
3450 | |||
3451 | /* If the event is not for currently used fcf do nothing */ | ||
3452 | if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) | ||
3453 | break; | ||
3454 | |||
3455 | /* | ||
3456 | * Otherwise, request the port to rediscover the entire FCF | ||
3457 | * table for a fast recovery from case that the current FCF | ||
3458 | * is no longer valid as we are not in the middle of FCF | ||
3459 | * failover process already. | ||
3460 | */ | ||
3461 | spin_lock_irq(&phba->hbalock); | ||
3454 | /* Mark the fast failover process in progress */ | 3462 | /* Mark the fast failover process in progress */ |
3455 | phba->fcf.fcf_flag |= FCF_DEAD_DISC; | 3463 | phba->fcf.fcf_flag |= FCF_DEAD_DISC; |
3456 | spin_unlock_irq(&phba->hbalock); | 3464 | spin_unlock_irq(&phba->hbalock); |
3465 | |||
3457 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | 3466 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
3458 | "2771 Start FCF fast failover process due to " | 3467 | "2771 Start FCF fast failover process due to " |
3459 | "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " | 3468 | "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " |
@@ -3473,12 +3482,16 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3473 | * as a link down to FCF registration. | 3482 | * as a link down to FCF registration. |
3474 | */ | 3483 | */ |
3475 | lpfc_sli4_fcf_dead_failthrough(phba); | 3484 | lpfc_sli4_fcf_dead_failthrough(phba); |
3476 | } else | 3485 | } else { |
3477 | /* Handling fast FCF failover to a DEAD FCF event | 3486 | /* Reset FCF roundrobin bmask for new discovery */ |
3478 | * is considered equalivant to receiving CVL to all | 3487 | memset(phba->fcf.fcf_rr_bmask, 0, |
3479 | * vports. | 3488 | sizeof(*phba->fcf.fcf_rr_bmask)); |
3489 | /* | ||
3490 | * Handling fast FCF failover to a DEAD FCF event is | ||
3491 | * considered equalivant to receiving CVL to all vports. | ||
3480 | */ | 3492 | */ |
3481 | lpfc_sli4_perform_all_vport_cvl(phba); | 3493 | lpfc_sli4_perform_all_vport_cvl(phba); |
3494 | } | ||
3482 | break; | 3495 | break; |
3483 | case LPFC_FCOE_EVENT_TYPE_CVL: | 3496 | case LPFC_FCOE_EVENT_TYPE_CVL: |
3484 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, | 3497 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
@@ -3553,7 +3566,13 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3553 | * the current registered FCF entry. | 3566 | * the current registered FCF entry. |
3554 | */ | 3567 | */ |
3555 | lpfc_retry_pport_discovery(phba); | 3568 | lpfc_retry_pport_discovery(phba); |
3556 | } | 3569 | } else |
3570 | /* | ||
3571 | * Reset FCF roundrobin bmask for new | ||
3572 | * discovery. | ||
3573 | */ | ||
3574 | memset(phba->fcf.fcf_rr_bmask, 0, | ||
3575 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
3557 | } | 3576 | } |
3558 | break; | 3577 | break; |
3559 | default: | 3578 | default: |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 9c2c7c7140c7..0dfa310cd609 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -815,9 +815,15 @@ void | |||
815 | lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) | 815 | lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) |
816 | { | 816 | { |
817 | MAILBOX_t *mb = &pmb->u.mb; | 817 | MAILBOX_t *mb = &pmb->u.mb; |
818 | struct lpfc_hba *phba = vport->phba; | ||
818 | 819 | ||
819 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 820 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
820 | 821 | /* | |
822 | * Set the re-reg VPI bit for f/w to update the MAC address. | ||
823 | */ | ||
824 | if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
825 | !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) | ||
826 | mb->un.varRegVpi.upd = 1; | ||
821 | mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; | 827 | mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; |
822 | mb->un.varRegVpi.sid = vport->fc_myDID; | 828 | mb->un.varRegVpi.sid = vport->fc_myDID; |
823 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; | 829 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 0ce9eb7ca4ee..fb8905f893f5 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -12295,12 +12295,9 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) | |||
12295 | spin_lock_irq(&phba->hbalock); | 12295 | spin_lock_irq(&phba->hbalock); |
12296 | phba->hba_flag |= FCF_DISC_INPROGRESS; | 12296 | phba->hba_flag |= FCF_DISC_INPROGRESS; |
12297 | spin_unlock_irq(&phba->hbalock); | 12297 | spin_unlock_irq(&phba->hbalock); |
12298 | /* Reset FCF round robin index bmask for new scan */ | 12298 | /* Reset eligible FCF count for new scan */ |
12299 | if (fcf_index == LPFC_FCOE_FCF_GET_FIRST) { | 12299 | if (fcf_index == LPFC_FCOE_FCF_GET_FIRST) |
12300 | memset(phba->fcf.fcf_rr_bmask, 0, | ||
12301 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
12302 | phba->fcf.eligible_fcf_cnt = 0; | 12300 | phba->fcf.eligible_fcf_cnt = 0; |
12303 | } | ||
12304 | error = 0; | 12301 | error = 0; |
12305 | } | 12302 | } |
12306 | fail_fcf_scan: | 12303 | fail_fcf_scan: |