[SCSI] lpfc 8.3.3 : FC/FCOE discovery fixes
Contains the following changes: - Force vport to send LOGO to fabric controller when deleting vport - Fixed driver failing to register login when a PLOGI is received - Fixes for FIP discovery - Added stricter checks for FCF addressing mode - Added code to send only FLOGI, FDISC and LOGO to Fabric controller as FIP - Fixed handling of LOGO from Fabric port - Fixed consecutive link up events skipped link_down processing Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
f112668880
commit
0c2875893e
8 changed files with 59 additions and 26 deletions
|
@ -168,6 +168,19 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
if (elsiocb == NULL)
|
if (elsiocb == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this command is for fabric controller and HBA running
|
||||||
|
* in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
|
||||||
|
*/
|
||||||
|
if ((did == Fabric_DID) &&
|
||||||
|
bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) &&
|
||||||
|
((elscmd == ELS_CMD_FLOGI) ||
|
||||||
|
(elscmd == ELS_CMD_FDISC) ||
|
||||||
|
(elscmd == ELS_CMD_LOGO)))
|
||||||
|
elsiocb->iocb_flag |= LPFC_FIP_ELS;
|
||||||
|
else
|
||||||
|
elsiocb->iocb_flag &= ~LPFC_FIP_ELS;
|
||||||
|
|
||||||
icmd = &elsiocb->iocb;
|
icmd = &elsiocb->iocb;
|
||||||
|
|
||||||
/* fill in BDEs for command */
|
/* fill in BDEs for command */
|
||||||
|
|
|
@ -1197,6 +1197,11 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
|
||||||
{
|
{
|
||||||
struct lpfc_fcf_conn_entry *conn_entry;
|
struct lpfc_fcf_conn_entry *conn_entry;
|
||||||
|
|
||||||
|
/* If FCF not available return 0 */
|
||||||
|
if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) ||
|
||||||
|
!bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!phba->cfg_enable_fip) {
|
if (!phba->cfg_enable_fip) {
|
||||||
*boot_flag = 0;
|
*boot_flag = 0;
|
||||||
*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
|
*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
|
||||||
|
@ -1216,6 +1221,14 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
|
||||||
*boot_flag = 0;
|
*boot_flag = 0;
|
||||||
*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
|
*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
|
||||||
new_fcf_record);
|
new_fcf_record);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When there are no FCF connect entries, use driver's default
|
||||||
|
* addressing mode - FPMA.
|
||||||
|
*/
|
||||||
|
if (*addr_mode & LPFC_FCF_FPMA)
|
||||||
|
*addr_mode = LPFC_FCF_FPMA;
|
||||||
|
|
||||||
*vlan_id = 0xFFFF;
|
*vlan_id = 0xFFFF;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1240,6 +1253,14 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If connection record does not support any addressing mode,
|
||||||
|
* skip the FCF record.
|
||||||
|
*/
|
||||||
|
if (!(bf_get(lpfc_fcf_record_mac_addr_prov, new_fcf_record)
|
||||||
|
& (LPFC_FCF_FPMA | LPFC_FCF_SPMA)))
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the connection record specifies a required
|
* Check if the connection record specifies a required
|
||||||
* addressing mode.
|
* addressing mode.
|
||||||
|
@ -1272,6 +1293,11 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
|
||||||
else
|
else
|
||||||
*boot_flag = 0;
|
*boot_flag = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If user did not specify any addressing mode, or if the
|
||||||
|
* prefered addressing mode specified by user is not supported
|
||||||
|
* by FCF, allow fabric to pick the addressing mode.
|
||||||
|
*/
|
||||||
*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
|
*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
|
||||||
new_fcf_record);
|
new_fcf_record);
|
||||||
/*
|
/*
|
||||||
|
@ -1297,12 +1323,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
|
||||||
!(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) &&
|
!(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) &&
|
||||||
(*addr_mode & LPFC_FCF_FPMA))
|
(*addr_mode & LPFC_FCF_FPMA))
|
||||||
*addr_mode = LPFC_FCF_FPMA;
|
*addr_mode = LPFC_FCF_FPMA;
|
||||||
/*
|
|
||||||
* If user did not specify any addressing mode, use FPMA if
|
|
||||||
* possible else use SPMA.
|
|
||||||
*/
|
|
||||||
else if (*addr_mode & LPFC_FCF_FPMA)
|
|
||||||
*addr_mode = LPFC_FCF_FPMA;
|
|
||||||
|
|
||||||
if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID)
|
if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID)
|
||||||
*vlan_id = conn_entry->conn_rec.vlan_tag;
|
*vlan_id = conn_entry->conn_rec.vlan_tag;
|
||||||
|
@ -1864,7 +1884,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
vport->fc_flag &= ~FC_BYPASSED_MODE;
|
vport->fc_flag &= ~FC_BYPASSED_MODE;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
|
||||||
if (((phba->fc_eventTag + 1) < la->eventTag) ||
|
if ((phba->fc_eventTag < la->eventTag) ||
|
||||||
(phba->fc_eventTag == la->eventTag)) {
|
(phba->fc_eventTag == la->eventTag)) {
|
||||||
phba->fc_stat.LinkMultiEvent++;
|
phba->fc_stat.LinkMultiEvent++;
|
||||||
if (la->attType == AT_LINK_UP)
|
if (la->attType == AT_LINK_UP)
|
||||||
|
@ -2925,6 +2945,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||||
lpfc_no_rpi(phba, ndlp);
|
lpfc_no_rpi(phba, ndlp);
|
||||||
ndlp->nlp_rpi = 0;
|
ndlp->nlp_rpi = 0;
|
||||||
ndlp->nlp_flag &= ~NLP_RPI_VALID;
|
ndlp->nlp_flag &= ~NLP_RPI_VALID;
|
||||||
|
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1128,7 +1128,7 @@ struct fcf_record {
|
||||||
#define lpfc_fcf_record_mac_5_WORD word4
|
#define lpfc_fcf_record_mac_5_WORD word4
|
||||||
#define lpfc_fcf_record_fcf_avail_SHIFT 16
|
#define lpfc_fcf_record_fcf_avail_SHIFT 16
|
||||||
#define lpfc_fcf_record_fcf_avail_MASK 0x000000FF
|
#define lpfc_fcf_record_fcf_avail_MASK 0x000000FF
|
||||||
#define lpfc_fcf_record_fc_avail_WORD word4
|
#define lpfc_fcf_record_fcf_avail_WORD word4
|
||||||
#define lpfc_fcf_record_mac_addr_prov_SHIFT 24
|
#define lpfc_fcf_record_mac_addr_prov_SHIFT 24
|
||||||
#define lpfc_fcf_record_mac_addr_prov_MASK 0x000000FF
|
#define lpfc_fcf_record_mac_addr_prov_MASK 0x000000FF
|
||||||
#define lpfc_fcf_record_mac_addr_prov_WORD word4
|
#define lpfc_fcf_record_mac_addr_prov_WORD word4
|
||||||
|
|
|
@ -1715,8 +1715,10 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
|
||||||
/* Set up host requested features. */
|
/* Set up host requested features. */
|
||||||
bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
|
bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
|
||||||
|
|
||||||
/* Virtual fabrics and FIPs are not supported yet. */
|
if (phba->cfg_enable_fip)
|
||||||
bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0);
|
bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0);
|
||||||
|
else
|
||||||
|
bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 1);
|
||||||
|
|
||||||
/* Enable DIF (block guard) only if configured to do so. */
|
/* Enable DIF (block guard) only if configured to do so. */
|
||||||
if (phba->cfg_enable_bg)
|
if (phba->cfg_enable_bg)
|
||||||
|
|
|
@ -497,7 +497,7 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
|
lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
|
||||||
else
|
else
|
||||||
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
|
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
|
||||||
if ((ndlp->nlp_type & NLP_FABRIC) &&
|
if ((ndlp->nlp_DID == Fabric_DID) &&
|
||||||
vport->port_type == LPFC_NPIV_PORT) {
|
vport->port_type == LPFC_NPIV_PORT) {
|
||||||
lpfc_linkdown_port(vport);
|
lpfc_linkdown_port(vport);
|
||||||
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
|
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
|
||||||
|
|
|
@ -4491,8 +4491,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
goto out_free_vpd;
|
goto out_free_vpd;
|
||||||
}
|
}
|
||||||
/* Temporary initialization of lpfc_fip_flag to non-fip */
|
if (phba->cfg_enable_fip)
|
||||||
bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 0);
|
bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 1);
|
||||||
|
else
|
||||||
|
bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 0);
|
||||||
|
|
||||||
/* Set up all the queues to the device */
|
/* Set up all the queues to the device */
|
||||||
rc = lpfc_sli4_queue_setup(phba);
|
rc = lpfc_sli4_queue_setup(phba);
|
||||||
|
@ -5856,18 +5858,13 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
||||||
|
|
||||||
fip = bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags);
|
fip = bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags);
|
||||||
/* The fcp commands will set command type */
|
/* The fcp commands will set command type */
|
||||||
if ((!(iocbq->iocb_flag & LPFC_IO_FCP)) && (!fip))
|
if (iocbq->iocb_flag & LPFC_IO_FCP)
|
||||||
command_type = ELS_COMMAND_NON_FIP;
|
|
||||||
else if (!(iocbq->iocb_flag & LPFC_IO_FCP))
|
|
||||||
command_type = ELS_COMMAND_FIP;
|
|
||||||
else if (iocbq->iocb_flag & LPFC_IO_FCP)
|
|
||||||
command_type = FCP_COMMAND;
|
command_type = FCP_COMMAND;
|
||||||
else {
|
else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS))
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
command_type = ELS_COMMAND_FIP;
|
||||||
"2019 Invalid cmd 0x%x\n",
|
else
|
||||||
iocbq->iocb.ulpCommand);
|
command_type = ELS_COMMAND_NON_FIP;
|
||||||
return IOCB_ERROR;
|
|
||||||
}
|
|
||||||
/* Some of the fields are in the right position already */
|
/* Some of the fields are in the right position already */
|
||||||
memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
|
memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
|
||||||
abort_tag = (uint32_t) iocbq->iotag;
|
abort_tag = (uint32_t) iocbq->iotag;
|
||||||
|
@ -11467,6 +11464,7 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba,
|
||||||
bf_set(lpfc_fcf_record_fc_map_1, fcf_record, phba->fc_map[1]);
|
bf_set(lpfc_fcf_record_fc_map_1, fcf_record, phba->fc_map[1]);
|
||||||
bf_set(lpfc_fcf_record_fc_map_2, fcf_record, phba->fc_map[2]);
|
bf_set(lpfc_fcf_record_fc_map_2, fcf_record, phba->fc_map[2]);
|
||||||
bf_set(lpfc_fcf_record_fcf_valid, fcf_record, 1);
|
bf_set(lpfc_fcf_record_fcf_valid, fcf_record, 1);
|
||||||
|
bf_set(lpfc_fcf_record_fcf_avail, fcf_record, 1);
|
||||||
bf_set(lpfc_fcf_record_fcf_index, fcf_record, fcf_index);
|
bf_set(lpfc_fcf_record_fcf_index, fcf_record, fcf_index);
|
||||||
bf_set(lpfc_fcf_record_mac_addr_prov, fcf_record,
|
bf_set(lpfc_fcf_record_mac_addr_prov, fcf_record,
|
||||||
LPFC_FCF_FPMA | LPFC_FCF_SPMA);
|
LPFC_FCF_FPMA | LPFC_FCF_SPMA);
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct lpfc_iocbq {
|
||||||
#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
|
#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
|
||||||
#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
|
#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
|
||||||
#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
|
#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
|
||||||
|
#define LPFC_FIP_ELS 0x40
|
||||||
|
|
||||||
uint8_t abort_count;
|
uint8_t abort_count;
|
||||||
uint8_t rsvd2;
|
uint8_t rsvd2;
|
||||||
|
|
|
@ -695,8 +695,6 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
||||||
}
|
}
|
||||||
vport->unreg_vpi_cmpl = VPORT_INVAL;
|
vport->unreg_vpi_cmpl = VPORT_INVAL;
|
||||||
timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
|
timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
|
||||||
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
|
|
||||||
goto skip_logo;
|
|
||||||
if (!lpfc_issue_els_npiv_logo(vport, ndlp))
|
if (!lpfc_issue_els_npiv_logo(vport, ndlp))
|
||||||
while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
|
while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
|
||||||
timeout = schedule_timeout(timeout);
|
timeout = schedule_timeout(timeout);
|
||||||
|
|
Loading…
Add table
Reference in a new issue