static void lpfc_disc_timeout_handler(struct lpfc_vport *);
 static void lpfc_disc_flush_list(struct lpfc_vport *vport);
+static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 
 void
 lpfc_terminate_rport_io(struct fc_rport *rport)
        spin_lock_irqsave(&phba->hbalock, flags);
        phba->fcf.fcf_flag |= FCF_REGISTERED;
        spin_unlock_irqrestore(&phba->hbalock, flags);
+       /* If there is a pending FCoE event, restart FCF table scan. */
+       if (lpfc_check_pending_fcoe_event(phba, 1)) {
+               mempool_free(mboxq, phba->mbox_mem_pool);
+               return;
+       }
        if (vport->port_state != LPFC_FLOGI) {
                spin_lock_irqsave(&phba->hbalock, flags);
                phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
                spin_unlock_irqrestore(&phba->hbalock, flags);
                lpfc_initial_flogi(vport);
        }
        /* The FCF is already registered, start discovery */
        if (phba->fcf.fcf_flag & FCF_REGISTERED) {
                phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
                spin_unlock_irqrestore(&phba->hbalock, flags);
                if (phba->pport->port_state != LPFC_FLOGI)
                        lpfc_initial_flogi(phba->pport);
        return 0;
 }
 
+/**
+ * lpfc_check_pending_fcoe_event - Check if there is pending fcoe event.
+ * @phba: pointer to lpfc hba data structure.
+ * @unreg_fcf: Unregister FCF if FCF table need to be re-scaned.
+ *
+ * This function check if there is any fcoe event pending while driver
+ * scan FCF entries. If there is any pending event, it will restart the
+ * FCF saning and return 1 else return 0.
+ */
+int
+lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
+{
+       LPFC_MBOXQ_t *mbox;
+       int rc;
+       /*
+        * If the Link is up and no FCoE events while in the
+        * FCF discovery, no need to restart FCF discovery.
+        */
+       if ((phba->link_state  >= LPFC_LINK_UP) &&
+               (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
+               return 0;
+
+       spin_lock_irq(&phba->hbalock);
+       phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
+       spin_unlock_irq(&phba->hbalock);
+
+       if (phba->link_state >= LPFC_LINK_UP)
+               lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+
+       if (unreg_fcf) {
+               spin_lock_irq(&phba->hbalock);
+               phba->fcf.fcf_flag &= ~FCF_REGISTERED;
+               spin_unlock_irq(&phba->hbalock);
+               mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+               if (!mbox) {
+                       lpfc_printf_log(phba, KERN_ERR,
+                               LOG_DISCOVERY|LOG_MBOX,
+                               "2610 UNREG_FCFI mbox allocation failed\n");
+                       return 1;
+               }
+               lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
+               mbox->vport = phba->pport;
+               mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
+               rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+               if (rc == MBX_NOT_FINISHED) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
+                               "2611 UNREG_FCFI issue mbox failed\n");
+                       mempool_free(mbox, phba->mbox_mem_pool);
+               }
+       }
+
+       return 1;
+}
+
 /**
  * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox.
  * @phba: pointer to lpfc hba data structure.
        unsigned long flags;
        uint16_t vlan_id;
 
+       /* If there is pending FCoE event restart FCF table scan */
+       if (lpfc_check_pending_fcoe_event(phba, 0)) {
+               lpfc_sli4_mbox_cmd_free(phba, mboxq);
+               return;
+       }
+
        /* Get the first SGE entry from the non-embedded DMA memory. This
         * routine only uses a single SGE.
         */
                        goto out;
                }
        } else {
+               vport->port_state = LPFC_VPORT_UNKNOWN;
                /*
                 * Add the driver's default FCF record at FCF index 0 now. This
                 * is phase 1 implementation that support FCF index 0 and driver
                 * The driver is expected to do FIP/FCF. Call the port
                 * and get the FCF Table.
                 */
+               spin_lock_irq(&phba->hbalock);
+               if (phba->hba_flag & FCF_DISC_INPROGRESS) {
+                       spin_unlock_irq(&phba->hbalock);
+                       return;
+               }
+               spin_unlock_irq(&phba->hbalock);
                rc = lpfc_sli4_read_fcf_record(phba,
                                        LPFC_FCOE_FCF_GET_FIRST);
                if (rc)
        fcoe_param_hdr = (struct lpfc_fip_param_hdr *)
                buff;
        fcoe_param = (struct lpfc_fcoe_params *)
-               buff + sizeof(struct lpfc_fip_param_hdr);
+               (buff + sizeof(struct lpfc_fip_param_hdr));
 
        if ((fcoe_param_hdr->parm_version != FIPP_VERSION) ||
                (fcoe_param_hdr->length != FCOE_PARAM_LENGTH))
 
        att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
        if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
                return;
+       phba->fcoe_eventtag = acqe_link->event_tag;
        pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!pmb) {
                lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
        uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
        int rc;
 
+       phba->fcoe_eventtag = acqe_fcoe->event_tag;
        switch (event_type) {
        case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
                lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
                        acqe_fcoe->fcf_index,
                        acqe_fcoe->event_tag);
                /*
-                * If the current FCF is in discovered state,
-                * do nothing.
+                * If the current FCF is in discovered state, or
+                * FCF discovery is in progress do nothing.
                 */
                spin_lock_irq(&phba->hbalock);
-               if (phba->fcf.fcf_flag & FCF_DISCOVERED) {
+               if ((phba->fcf.fcf_flag & FCF_DISCOVERED) ||
+                  (phba->hba_flag & FCF_DISC_INPROGRESS)) {
                        spin_unlock_irq(&phba->hbalock);
                        break;
                }