[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>
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 9244aa6..da9ba06 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3300,10 +3300,10 @@
 		if (!ndlp)
 			return 0;
 	}
-	if (phba->pport->port_state <= LPFC_FLOGI)
+	if (phba->pport->port_state < LPFC_FLOGI)
 		return NULL;
 	/* If virtual link is not yet instantiated ignore CVL */
-	if (vport->port_state <= LPFC_FDISC)
+	if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC))
 		return NULL;
 	shost = lpfc_shost_from_vport(vport);
 	if (!shost)
@@ -3376,21 +3376,7 @@
 					"evt_tag:x%x, fcf_index:x%x\n",
 					acqe_fcoe->event_tag,
 					acqe_fcoe->index);
-		/* If the FCF discovery is in progress, do nothing. */
-		spin_lock_irq(&phba->hbalock);
-		if (phba->hba_flag & FCF_DISC_INPROGRESS) {
-			spin_unlock_irq(&phba->hbalock);
-			break;
-		}
-		/* If fast FCF failover rescan event is pending, do nothing */
-		if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
-			spin_unlock_irq(&phba->hbalock);
-			break;
-		}
-		spin_unlock_irq(&phba->hbalock);
-
-		if ((phba->fcf.fcf_flag & FCF_DISCOVERY) &&
-		    !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
+		if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
 			/*
 			 * During period of FCF discovery, read the FCF
 			 * table record indexed by the event to update
@@ -3404,13 +3390,26 @@
 					acqe_fcoe->index);
 			rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
 		}
-		/* If the FCF has been in discovered state, do nothing. */
+
+		/* If the FCF discovery is in progress, do nothing. */
 		spin_lock_irq(&phba->hbalock);
+		if (phba->hba_flag & FCF_DISC_INPROGRESS) {
+			spin_unlock_irq(&phba->hbalock);
+			break;
+		}
+		/* If fast FCF failover rescan event is pending, do nothing */
+		if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
+			spin_unlock_irq(&phba->hbalock);
+			break;
+		}
+
+		/* If the FCF has been in discovered state, do nothing. */
 		if (phba->fcf.fcf_flag & FCF_SCAN_DONE) {
 			spin_unlock_irq(&phba->hbalock);
 			break;
 		}
 		spin_unlock_irq(&phba->hbalock);
+
 		/* Otherwise, scan the entire FCF table and re-discover SAN */
 		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
 				"2770 Start FCF table scan due to new FCF "
@@ -3436,13 +3435,9 @@
 			"2549 FCF disconnected from network index 0x%x"
 			" tag 0x%x\n", acqe_fcoe->index,
 			acqe_fcoe->event_tag);
-		/* If the event is not for currently used fcf do nothing */
-		if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
-			break;
-		/* We request port to rediscover the entire FCF table for
-		 * a fast recovery from case that the current FCF record
-		 * is no longer valid if we are not in the middle of FCF
-		 * failover process already.
+		/*
+		 * If we are in the middle of FCF failover process, clear
+		 * the corresponding FCF bit in the roundrobin bitmap.
 		 */
 		spin_lock_irq(&phba->hbalock);
 		if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
@@ -3451,9 +3446,23 @@
 			lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index);
 			break;
 		}
+		spin_unlock_irq(&phba->hbalock);
+
+		/* If the event is not for currently used fcf do nothing */
+		if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
+			break;
+
+		/*
+		 * Otherwise, request the port to rediscover the entire FCF
+		 * table for a fast recovery from case that the current FCF
+		 * is no longer valid as we are not in the middle of FCF
+		 * failover process already.
+		 */
+		spin_lock_irq(&phba->hbalock);
 		/* Mark the fast failover process in progress */
 		phba->fcf.fcf_flag |= FCF_DEAD_DISC;
 		spin_unlock_irq(&phba->hbalock);
+
 		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
 				"2771 Start FCF fast failover process due to "
 				"FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
@@ -3473,12 +3482,16 @@
 			 * as a link down to FCF registration.
 			 */
 			lpfc_sli4_fcf_dead_failthrough(phba);
-		} else
-			/* Handling fast FCF failover to a DEAD FCF event
-			 * is considered equalivant to receiving CVL to all
-			 * vports.
+		} else {
+			/* Reset FCF roundrobin bmask for new discovery */
+			memset(phba->fcf.fcf_rr_bmask, 0,
+			       sizeof(*phba->fcf.fcf_rr_bmask));
+			/*
+			 * Handling fast FCF failover to a DEAD FCF event is
+			 * considered equalivant to receiving CVL to all vports.
 			 */
 			lpfc_sli4_perform_all_vport_cvl(phba);
+		}
 		break;
 	case LPFC_FCOE_EVENT_TYPE_CVL:
 		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
@@ -3553,7 +3566,13 @@
 				 * the current registered FCF entry.
 				 */
 				lpfc_retry_pport_discovery(phba);
-			}
+			} else
+				/*
+				 * Reset FCF roundrobin bmask for new
+				 * discovery.
+				 */
+				memset(phba->fcf.fcf_rr_bmask, 0,
+				       sizeof(*phba->fcf.fcf_rr_bmask));
 		}
 		break;
 	default: