[SCSI] lpfc 8.3.28: Add Loopback support for SLI4 adapters
- Add Basic support for SLI4 Loopback. (CR 124951, 125766, 124951, 125843, 125832, 125843) - Added missing protection in setting/clearing of phba->link_flag bit field (CR 125994) - Use link type and link number obtained from READ_CONFIG mailbox command. (CR 126264) Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:

committed by
James Bottomley

parent
2e90f4b5a2
commit
1b51197d0f
@@ -421,13 +421,13 @@ fail:
|
||||
* @vport: pointer to a host virtual N_Port data structure.
|
||||
*
|
||||
* This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for
|
||||
* the @vport. This mailbox command is necessary for FCoE only.
|
||||
* the @vport. This mailbox command is necessary for SLI4 port only.
|
||||
*
|
||||
* Return code
|
||||
* 0 - successfully issued REG_VFI for @vport
|
||||
* A failure code otherwise.
|
||||
**/
|
||||
static int
|
||||
int
|
||||
lpfc_issue_reg_vfi(struct lpfc_vport *vport)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
@@ -438,10 +438,14 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
|
||||
int rc = 0;
|
||||
|
||||
sp = &phba->fc_fabparam;
|
||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
||||
rc = -ENODEV;
|
||||
goto fail;
|
||||
/* move forward in case of SLI4 FC port loopback test */
|
||||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||
!(phba->link_flag & LS_LOOPBACK_MODE)) {
|
||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
||||
rc = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
|
||||
@@ -486,6 +490,54 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_issue_unreg_vfi - Unregister VFI for this vport's fabric login
|
||||
* @vport: pointer to a host virtual N_Port data structure.
|
||||
*
|
||||
* This routine issues a UNREG_VFI mailbox with the vfi, vpi, fcfi triplet for
|
||||
* the @vport. This mailbox command is necessary for SLI4 port only.
|
||||
*
|
||||
* Return code
|
||||
* 0 - successfully issued REG_VFI for @vport
|
||||
* A failure code otherwise.
|
||||
**/
|
||||
int
|
||||
lpfc_issue_unreg_vfi(struct lpfc_vport *vport)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct Scsi_Host *shost;
|
||||
LPFC_MBOXQ_t *mboxq;
|
||||
int rc;
|
||||
|
||||
mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mboxq) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
|
||||
"2556 UNREG_VFI mbox allocation failed"
|
||||
"HBA state x%x\n", phba->pport->port_state);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lpfc_unreg_vfi(mboxq, vport);
|
||||
mboxq->vport = vport;
|
||||
mboxq->mbox_cmpl = lpfc_unregister_vfi_cmpl;
|
||||
|
||||
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
|
||||
"2557 UNREG_VFI issue mbox failed rc x%x "
|
||||
"HBA state x%x\n",
|
||||
rc, phba->pport->port_state);
|
||||
mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
shost = lpfc_shost_from_vport(vport);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_VFI_REGISTERED;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_check_clean_addr_bit - Check whether assigned FCID is clean.
|
||||
* @vport: pointer to a host virtual N_Port data structure.
|
||||
@@ -615,7 +667,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
"1816 FLOGI NPIV supported, "
|
||||
"response data 0x%x\n",
|
||||
sp->cmn.response_multiple_NPort);
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
} else {
|
||||
/* Because we asked f/w for NPIV it still expects us
|
||||
to call reg_vnpid atleast for the physcial host */
|
||||
@@ -623,7 +677,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
LOG_ELS | LOG_VPORT,
|
||||
"1817 Fabric does not support NPIV "
|
||||
"- configuring single port mode.\n");
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,11 +742,16 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
lpfc_do_scr_ns_plogi(phba, vport);
|
||||
} else if (vport->fc_flag & FC_VFI_REGISTERED)
|
||||
lpfc_issue_init_vpi(vport);
|
||||
else
|
||||
else {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3135 Need register VFI: (x%x/%x)\n",
|
||||
vport->fc_prevDID, vport->fc_myDID);
|
||||
lpfc_issue_reg_vfi(vport);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port
|
||||
* @vport: pointer to a host virtual N_Port data structure.
|
||||
@@ -907,9 +968,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
* LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
|
||||
* alpa map would take too long otherwise.
|
||||
*/
|
||||
if (phba->alpa_map[0] == 0) {
|
||||
if (phba->alpa_map[0] == 0)
|
||||
vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
|
||||
}
|
||||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||
(!(vport->fc_flag & FC_VFI_REGISTERED) ||
|
||||
(vport->fc_prevDID != vport->fc_myDID))) {
|
||||
@@ -1164,8 +1224,7 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
|
||||
icmd = &iocb->iocb;
|
||||
if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
|
||||
icmd->un.elsreq64.bdl.ulpIoTag32) {
|
||||
if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
|
||||
ndlp = (struct lpfc_nodelist *)(iocb->context1);
|
||||
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
|
||||
(ndlp->nlp_DID == Fabric_DID))
|
||||
@@ -4879,23 +4938,31 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
sizeof(struct lpfc_name));
|
||||
|
||||
if (!rc) {
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mbox)
|
||||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool,
|
||||
GFP_KERNEL);
|
||||
if (!mbox)
|
||||
return 1;
|
||||
lpfc_linkdown(phba);
|
||||
lpfc_init_link(phba, mbox,
|
||||
phba->cfg_topology,
|
||||
phba->cfg_link_speed);
|
||||
mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox,
|
||||
MBX_NOWAIT);
|
||||
lpfc_set_loopback_flag(phba);
|
||||
if (rc == MBX_NOT_FINISHED)
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
return 1;
|
||||
|
||||
lpfc_linkdown(phba);
|
||||
lpfc_init_link(phba, mbox,
|
||||
phba->cfg_topology,
|
||||
phba->cfg_link_speed);
|
||||
mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
||||
lpfc_set_loopback_flag(phba);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
} else {
|
||||
/* abort the flogi coming back to ourselves
|
||||
* due to external loopback on the port.
|
||||
*/
|
||||
lpfc_els_abort_flogi(phba);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (rc > 0) { /* greater than */
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_PT2PT_PLOGI;
|
||||
@@ -5850,8 +5917,12 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
vport->fc_myDID = vport->fc_prevDID;
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
lpfc_issue_fabric_reglogin(vport);
|
||||
else
|
||||
else {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3138 Need register VFI: (x%x/%x)\n",
|
||||
vport->fc_prevDID, vport->fc_myDID);
|
||||
lpfc_issue_reg_vfi(vport);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user