diff options
| -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: |
