|
@@ -61,6 +61,7 @@ static uint8_t lpfcAlpaArray[] = {
|
|
|
|
|
|
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)
|
|
@@ -1009,9 +1010,15 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|
|
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);
|
|
|
}
|
|
@@ -1199,6 +1206,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
|
|
|
/* 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);
|
|
@@ -1387,6 +1395,60 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
|
|
|
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.
|
|
@@ -1419,6 +1481,12 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|
|
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.
|
|
|
*/
|
|
@@ -1823,6 +1891,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
|
|
|
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
|
|
@@ -1858,6 +1927,12 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
|
|
|
* 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)
|
|
@@ -4414,7 +4489,7 @@ lpfc_read_fcoe_param(struct lpfc_hba *phba,
|
|
|
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))
|