aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-08-04 16:11:39 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-08-06 13:11:44 -0400
commit38b92ef89b0d5a255f2f812c623fcdec4e63a21c (patch)
tree974498b393ebc3ef8ac67dcb2b2969e58c2b32ca /drivers
parentbc73905abf7701920fe687564ecd3c6b316b9a2e (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.c76
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c79
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c7
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 6201mbox_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
5097lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) 5098lpfc_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 {
2291typedef struct { 2291typedef 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
815lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) 815lpfc_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 }
12306fail_fcf_scan: 12303fail_fcf_scan: