mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge patch series "Update lpfc to revision 14.4.0.12"
Justin Tee <justin.tee@broadcom.com> says: Update lpfc to revision 14.4.0.12 This patch set contains updates to log messaging, revision of outdated comment descriptions, fixes to kref accounting, support for BB credit recovery in point-to-point mode, and introduction of registering unique platform name identifiers with fabrics. The patches were cut against Martin's 6.19/scsi-queue tree. Link: https://patch.msgid.link/20251106224639.139176-1-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
@@ -311,7 +311,6 @@ struct lpfc_defer_flogi_acc {
|
||||
u16 rx_id;
|
||||
u16 ox_id;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
|
||||
};
|
||||
|
||||
#define LPFC_VMID_TIMER 300 /* timer interval in seconds */
|
||||
@@ -634,6 +633,7 @@ struct lpfc_vport {
|
||||
#define FC_CT_RSPN_ID 0x8 /* RSPN_ID accepted by switch */
|
||||
#define FC_CT_RFT_ID 0x10 /* RFT_ID accepted by switch */
|
||||
#define FC_CT_RPRT_DEFER 0x20 /* Defer issuing FDMI RPRT */
|
||||
#define FC_CT_RSPNI_PNI 0x40 /* RSPNI_PNI accepted by switch */
|
||||
|
||||
struct list_head fc_nodes;
|
||||
spinlock_t fc_nodes_list_lock; /* spinlock for fc_nodes list */
|
||||
@@ -1078,6 +1078,8 @@ struct lpfc_hba {
|
||||
|
||||
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
|
||||
|
||||
unsigned long pni; /* 64-bit Platform Name Identifier */
|
||||
|
||||
uint8_t wwnn[8];
|
||||
uint8_t wwpn[8];
|
||||
uint32_t RandomData[7];
|
||||
|
||||
@@ -1742,6 +1742,28 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_cmpl_ct_cmd_rspni_pni(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
struct lpfc_vport *vport;
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *ctrsp;
|
||||
u32 ulp_status;
|
||||
|
||||
vport = cmdiocb->vport;
|
||||
ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
outp = cmdiocb->rsp_dmabuf;
|
||||
ctrsp = (struct lpfc_sli_ct_request *)outp->virt;
|
||||
if (be16_to_cpu(ctrsp->CommandResponse.bits.CmdRsp) ==
|
||||
SLI_CT_RESPONSE_FS_ACC)
|
||||
vport->ct_flags |= FC_CT_RSPNI_PNI;
|
||||
}
|
||||
lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
@@ -1956,6 +1978,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
||||
bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_RSNN_NN)
|
||||
bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_RSPNI_PNI)
|
||||
bpl->tus.f.bdeSize = RSPNI_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_DA_ID)
|
||||
bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_RFF_ID)
|
||||
@@ -2077,6 +2101,18 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
||||
CtReq->un.rsnn.symbname, size);
|
||||
cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
|
||||
break;
|
||||
case SLI_CTNS_RSPNI_PNI:
|
||||
vport->ct_flags &= ~FC_CT_RSPNI_PNI;
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
cpu_to_be16(SLI_CTNS_RSPNI_PNI);
|
||||
CtReq->un.rspni.pni = cpu_to_be64(phba->pni);
|
||||
scnprintf(CtReq->un.rspni.symbname,
|
||||
sizeof(CtReq->un.rspni.symbname), "OS Host Name::%s",
|
||||
phba->os_host_name);
|
||||
CtReq->un.rspni.len = strnlen(CtReq->un.rspni.symbname,
|
||||
sizeof(CtReq->un.rspni.symbname));
|
||||
cmpl = lpfc_cmpl_ct_cmd_rspni_pni;
|
||||
break;
|
||||
case SLI_CTNS_DA_ID:
|
||||
/* Implement DA_ID Nameserver request */
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2013 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
@@ -208,6 +208,7 @@ enum lpfc_nlp_flag {
|
||||
NPR list */
|
||||
NLP_RM_DFLT_RPI = 26, /* need to remove leftover dflt RPI */
|
||||
NLP_NODEV_REMOVE = 27, /* Defer removal till discovery ends */
|
||||
NLP_FLOGI_DFR_ACC = 28, /* FLOGI LS_ACC was Deferred */
|
||||
NLP_SC_REQ = 29, /* Target requires authentication */
|
||||
NLP_FIRSTBURST = 30, /* Target supports FirstBurst */
|
||||
NLP_RPI_REGISTERED = 31 /* nlp_rpi is valid */
|
||||
|
||||
@@ -650,8 +650,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS2;
|
||||
if (sp->cls3.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS3;
|
||||
if (sp->cls4.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS4;
|
||||
ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
|
||||
sp->cmn.bbRcvSizeLsb;
|
||||
|
||||
@@ -934,10 +932,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
/* Check to see if link went down during discovery */
|
||||
if (lpfc_els_chk_latt(vport)) {
|
||||
/* One additional decrement on node reference count to
|
||||
* trigger the release of the node
|
||||
* trigger the release of the node. Make sure the ndlp
|
||||
* is marked NLP_DROPPED.
|
||||
*/
|
||||
if (!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD))
|
||||
if (!test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag) &&
|
||||
!test_bit(NLP_DROPPED, &ndlp->nlp_flag) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
|
||||
set_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -995,9 +998,10 @@ stop_rr_fcf_flogi:
|
||||
IOERR_LOOP_OPEN_FAILURE)))
|
||||
lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
|
||||
"2858 FLOGI Status:x%x/x%x TMO"
|
||||
":x%x Data x%lx x%x\n",
|
||||
":x%x Data x%lx x%x x%lx x%x\n",
|
||||
ulp_status, ulp_word4, tmo,
|
||||
phba->hba_flag, phba->fcf.fcf_flag);
|
||||
phba->hba_flag, phba->fcf.fcf_flag,
|
||||
ndlp->nlp_flag, ndlp->fc4_xpt_flags);
|
||||
|
||||
/* Check for retry */
|
||||
if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
|
||||
@@ -1015,14 +1019,17 @@ stop_rr_fcf_flogi:
|
||||
* reference to trigger node release.
|
||||
*/
|
||||
if (!test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD))
|
||||
!test_bit(NLP_DROPPED, &ndlp->nlp_flag) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
|
||||
set_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
|
||||
"0150 FLOGI Status:x%x/x%x "
|
||||
"xri x%x TMO:x%x refcnt %d\n",
|
||||
"xri x%x iotag x%x TMO:x%x refcnt %d\n",
|
||||
ulp_status, ulp_word4, cmdiocb->sli4_xritag,
|
||||
tmo, kref_read(&ndlp->kref));
|
||||
cmdiocb->iotag, tmo, kref_read(&ndlp->kref));
|
||||
|
||||
/* If this is not a loop open failure, bail out */
|
||||
if (!(ulp_status == IOSTAT_LOCAL_REJECT &&
|
||||
@@ -1279,6 +1286,19 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
uint32_t tmo, did;
|
||||
int rc;
|
||||
|
||||
/* It's possible for lpfc to reissue a FLOGI on an ndlp that is marked
|
||||
* NLP_DROPPED. This happens when the FLOGI completed with the XB bit
|
||||
* set causing lpfc to reference the ndlp until the XRI_ABORTED CQE is
|
||||
* issued. The time window for the XRI_ABORTED CQE can be as much as
|
||||
* 2*2*RA_TOV allowing for ndlp reuse of this type when the link is
|
||||
* cycling quickly. When true, restore the initial reference and remove
|
||||
* the NLP_DROPPED flag as lpfc is retrying.
|
||||
*/
|
||||
if (test_and_clear_bit(NLP_DROPPED, &ndlp->nlp_flag)) {
|
||||
if (!lpfc_nlp_get(ndlp))
|
||||
return 1;
|
||||
}
|
||||
|
||||
cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_FLOGI);
|
||||
@@ -1334,6 +1354,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
/* Can't do SLI4 class2 without support sequence coalescing */
|
||||
sp->cls2.classValid = 0;
|
||||
sp->cls2.seqDelivery = 0;
|
||||
|
||||
/* Fill out Auxiliary Parameter Data */
|
||||
if (phba->pni) {
|
||||
sp->aux.flags =
|
||||
AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
|
||||
sp->aux.pni = cpu_to_be64(phba->pni);
|
||||
sp->aux.npiv_cnt = cpu_to_be16(phba->max_vpi - 1);
|
||||
}
|
||||
} else {
|
||||
/* Historical, setting sequential-delivery bit for SLI3 */
|
||||
sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
|
||||
@@ -1413,11 +1441,12 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
phba->defer_flogi_acc.ox_id;
|
||||
}
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
|
||||
" ox_id: x%x, hba_flag x%lx\n",
|
||||
phba->defer_flogi_acc.rx_id,
|
||||
phba->defer_flogi_acc.ox_id, phba->hba_flag);
|
||||
/* The LS_ACC completion needs to drop the initial reference.
|
||||
* This is a special case for Pt2Pt because both FLOGIs need
|
||||
* to complete and lpfc defers the LS_ACC when the remote
|
||||
* FLOGI arrives before the driver's FLOGI.
|
||||
*/
|
||||
set_bit(NLP_FLOGI_DFR_ACC, &ndlp->nlp_flag);
|
||||
|
||||
/* Send deferred FLOGI ACC */
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, &defer_flogi_acc,
|
||||
@@ -1433,6 +1462,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
phba->defer_flogi_acc.ndlp = NULL;
|
||||
}
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
|
||||
" ox_id: x%x, ndlp x%px hba_flag x%lx\n",
|
||||
phba->defer_flogi_acc.rx_id,
|
||||
phba->defer_flogi_acc.ox_id,
|
||||
phba->defer_flogi_acc.ndlp,
|
||||
phba->hba_flag);
|
||||
|
||||
vport->fc_myDID = did;
|
||||
}
|
||||
|
||||
@@ -2248,7 +2285,8 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
|
||||
|
||||
sp->cmn.valid_vendor_ver_level = 0;
|
||||
memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion));
|
||||
sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
if (!test_bit(FC_PT2PT, &vport->fc_flag))
|
||||
sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
|
||||
/* Check if the destination port supports VMID */
|
||||
ndlp->vmid_support = 0;
|
||||
@@ -2367,7 +2405,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
mode = KERN_INFO;
|
||||
|
||||
/* Warn PRLI status */
|
||||
lpfc_printf_vlog(vport, mode, LOG_ELS,
|
||||
lpfc_vlog_msg(vport, mode, LOG_ELS,
|
||||
"2754 PRLI DID:%06X Status:x%x/x%x, "
|
||||
"data: x%x x%x x%lx\n",
|
||||
ndlp->nlp_DID, ulp_status,
|
||||
@@ -3024,6 +3062,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
ndlp->nlp_DID, ulp_status,
|
||||
ulp_word4);
|
||||
|
||||
/* Call NLP_EVT_DEVICE_RM if link is down or LOGO is aborted */
|
||||
if (lpfc_error_lost_link(vport, ulp_status, ulp_word4))
|
||||
skip_recovery = 1;
|
||||
}
|
||||
@@ -3262,7 +3301,7 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = lpfc_reg_rpi(phba, vport->vpi, fc_ndlp->nlp_DID,
|
||||
(u8 *)&vport->fc_sparam, mbox, fc_ndlp->nlp_rpi);
|
||||
(u8 *)&ns_ndlp->fc_sparam, mbox, fc_ndlp->nlp_rpi);
|
||||
if (rc) {
|
||||
rc = -EACCES;
|
||||
goto out;
|
||||
@@ -3306,7 +3345,8 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
|
||||
*
|
||||
* This routine is a generic completion callback function for Discovery ELS cmd.
|
||||
* Currently used by the ELS command issuing routines for the ELS State Change
|
||||
* Request (SCR), lpfc_issue_els_scr() and the ELS RDF, lpfc_issue_els_rdf().
|
||||
* Request (SCR), lpfc_issue_els_scr(), Exchange Diagnostic Capabilities (EDC),
|
||||
* lpfc_issue_els_edc() and the ELS RDF, lpfc_issue_els_rdf().
|
||||
* These commands will be retried once only for ELS timeout errors.
|
||||
**/
|
||||
static void
|
||||
@@ -3379,11 +3419,21 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_cmpl_els_edc(phba, cmdiocb, rspiocb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ulp_status) {
|
||||
/* ELS discovery cmd completes with error */
|
||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS | LOG_CGN_MGMT,
|
||||
"4203 ELS cmd x%x error: x%x x%X\n", cmd,
|
||||
ulp_status, ulp_word4);
|
||||
|
||||
/* In the case where the ELS cmd completes with an error and
|
||||
* the node does not have RPI registered, the node is
|
||||
* outstanding and should put its initial reference.
|
||||
*/
|
||||
if ((cmd == ELS_CMD_SCR || cmd == ELS_CMD_RDF) &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD) &&
|
||||
!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
lpfc_nlp_put(ndlp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3452,6 +3502,7 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
|
||||
uint8_t *pcmd;
|
||||
uint16_t cmdsize;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
bool node_created = false;
|
||||
|
||||
cmdsize = (sizeof(uint32_t) + sizeof(SCR));
|
||||
|
||||
@@ -3461,21 +3512,21 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
|
||||
if (!ndlp)
|
||||
return 1;
|
||||
lpfc_enqueue_node(vport, ndlp);
|
||||
node_created = true;
|
||||
}
|
||||
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_SCR);
|
||||
if (!elsiocb)
|
||||
return 1;
|
||||
goto out_node_created;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
rc = lpfc_reg_fab_ctrl_node(vport, ndlp);
|
||||
if (rc) {
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
|
||||
"0937 %s: Failed to reg fc node, rc %d\n",
|
||||
__func__, rc);
|
||||
return 1;
|
||||
goto out_free_iocb;
|
||||
}
|
||||
}
|
||||
pcmd = (uint8_t *)elsiocb->cmd_dmabuf->virt;
|
||||
@@ -3494,23 +3545,27 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
|
||||
phba->fc_stat.elsXmitSCR++;
|
||||
elsiocb->cmd_cmpl = lpfc_cmpl_els_disc_cmd;
|
||||
elsiocb->ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!elsiocb->ndlp) {
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
return 1;
|
||||
}
|
||||
if (!elsiocb->ndlp)
|
||||
goto out_free_iocb;
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
"Issue SCR: did:x%x refcnt %d",
|
||||
ndlp->nlp_DID, kref_read(&ndlp->kref), 0);
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
return 1;
|
||||
}
|
||||
if (rc == IOCB_ERROR)
|
||||
goto out_iocb_error;
|
||||
|
||||
return 0;
|
||||
|
||||
out_iocb_error:
|
||||
lpfc_nlp_put(ndlp);
|
||||
out_free_iocb:
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
out_node_created:
|
||||
if (node_created)
|
||||
lpfc_nlp_put(ndlp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3597,8 +3652,8 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry)
|
||||
}
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
"Issue RSCN: did:x%x",
|
||||
ndlp->nlp_DID, 0, 0);
|
||||
"Issue RSCN: did:x%x refcnt %d",
|
||||
ndlp->nlp_DID, kref_read(&ndlp->kref), 0);
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
@@ -3705,10 +3760,7 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||
lpfc_nlp_put(ndlp);
|
||||
return 1;
|
||||
}
|
||||
/* This will cause the callback-function lpfc_cmpl_els_cmd to
|
||||
* trigger the release of the node.
|
||||
*/
|
||||
/* Don't release reference count as RDF is likely outstanding */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3726,7 +3778,12 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||
*
|
||||
* Return code
|
||||
* 0 - Successfully issued rdf command
|
||||
* 1 - Failed to issue rdf command
|
||||
* < 0 - Failed to issue rdf command
|
||||
* -EACCES - RDF not required for NPIV_PORT
|
||||
* -ENODEV - No fabric controller device available
|
||||
* -ENOMEM - No available memory
|
||||
* -EIO - The mailbox failed to complete successfully.
|
||||
*
|
||||
**/
|
||||
int
|
||||
lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
@@ -3737,25 +3794,30 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
struct lpfc_nodelist *ndlp;
|
||||
uint16_t cmdsize;
|
||||
int rc;
|
||||
bool node_created = false;
|
||||
int err;
|
||||
|
||||
cmdsize = sizeof(*prdf);
|
||||
|
||||
/* RDF ELS is not required on an NPIV VN_Port. */
|
||||
if (vport->port_type == LPFC_NPIV_PORT)
|
||||
return -EACCES;
|
||||
|
||||
ndlp = lpfc_findnode_did(vport, Fabric_Cntl_DID);
|
||||
if (!ndlp) {
|
||||
ndlp = lpfc_nlp_init(vport, Fabric_Cntl_DID);
|
||||
if (!ndlp)
|
||||
return -ENODEV;
|
||||
lpfc_enqueue_node(vport, ndlp);
|
||||
node_created = true;
|
||||
}
|
||||
|
||||
/* RDF ELS is not required on an NPIV VN_Port. */
|
||||
if (vport->port_type == LPFC_NPIV_PORT)
|
||||
return -EACCES;
|
||||
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_RDF);
|
||||
if (!elsiocb)
|
||||
return -ENOMEM;
|
||||
if (!elsiocb) {
|
||||
err = -ENOMEM;
|
||||
goto out_node_created;
|
||||
}
|
||||
|
||||
/* Configure the payload for the supported FPIN events. */
|
||||
prdf = (struct lpfc_els_rdf_req *)elsiocb->cmd_dmabuf->virt;
|
||||
@@ -3781,8 +3843,8 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
elsiocb->cmd_cmpl = lpfc_cmpl_els_disc_cmd;
|
||||
elsiocb->ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!elsiocb->ndlp) {
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
return -EIO;
|
||||
err = -EIO;
|
||||
goto out_free_iocb;
|
||||
}
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
@@ -3791,11 +3853,19 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
return -EIO;
|
||||
err = -EIO;
|
||||
goto out_iocb_error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
out_iocb_error:
|
||||
lpfc_nlp_put(ndlp);
|
||||
out_free_iocb:
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
out_node_created:
|
||||
if (node_created)
|
||||
lpfc_nlp_put(ndlp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3816,19 +3886,23 @@ static int
|
||||
lpfc_els_rcv_rdf(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = lpfc_els_rsp_acc(vport, ELS_CMD_RDF, cmdiocb, ndlp, NULL);
|
||||
/* Send LS_ACC */
|
||||
if (lpfc_els_rsp_acc(vport, ELS_CMD_RDF, cmdiocb, ndlp, NULL)) {
|
||||
if (rc) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
"1623 Failed to RDF_ACC from x%x for x%x\n",
|
||||
ndlp->nlp_DID, vport->fc_myDID);
|
||||
"1623 Failed to RDF_ACC from x%x for x%x Data: %d\n",
|
||||
ndlp->nlp_DID, vport->fc_myDID, rc);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = lpfc_issue_els_rdf(vport, 0);
|
||||
/* Issue new RDF for reregistering */
|
||||
if (lpfc_issue_els_rdf(vport, 0)) {
|
||||
if (rc) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
"2623 Failed to re register RDF for x%x\n",
|
||||
vport->fc_myDID);
|
||||
"2623 Failed to re register RDF for x%x Data: %d\n",
|
||||
vport->fc_myDID, rc);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -4299,7 +4373,7 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry)
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
/* The additional lpfc_nlp_put will cause the following
|
||||
* lpfc_els_free_iocb routine to trigger the rlease of
|
||||
* lpfc_els_free_iocb routine to trigger the release of
|
||||
* the node.
|
||||
*/
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
@@ -5127,7 +5201,7 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
|
||||
{
|
||||
struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
|
||||
|
||||
/* The I/O iocb is complete. Clear the node and first dmbuf */
|
||||
/* The I/O iocb is complete. Clear the node and first dmabuf */
|
||||
elsiocb->ndlp = NULL;
|
||||
|
||||
/* cmd_dmabuf = cmd, cmd_dmabuf->next = rsp, bpl_dmabuf = bpl */
|
||||
@@ -5160,14 +5234,12 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
|
||||
} else {
|
||||
buf_ptr1 = elsiocb->cmd_dmabuf;
|
||||
lpfc_els_free_data(phba, buf_ptr1);
|
||||
elsiocb->cmd_dmabuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (elsiocb->bpl_dmabuf) {
|
||||
buf_ptr = elsiocb->bpl_dmabuf;
|
||||
lpfc_els_free_bpl(phba, buf_ptr);
|
||||
elsiocb->bpl_dmabuf = NULL;
|
||||
}
|
||||
lpfc_sli_release_iocbq(phba, elsiocb);
|
||||
return 0;
|
||||
@@ -5305,11 +5377,12 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
IOCB_t *irsp;
|
||||
LPFC_MBOXQ_t *mbox = NULL;
|
||||
u32 ulp_status, ulp_word4, tmo, did, iotag;
|
||||
u32 cmd;
|
||||
|
||||
if (!vport) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
|
||||
"3177 null vport in ELS rsp\n");
|
||||
goto out;
|
||||
goto release;
|
||||
}
|
||||
if (cmdiocb->context_un.mbox)
|
||||
mbox = cmdiocb->context_un.mbox;
|
||||
@@ -5419,7 +5492,7 @@ out:
|
||||
* these conditions because it doesn't need the login.
|
||||
*/
|
||||
if (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||
vport && vport->port_type == LPFC_NPIV_PORT &&
|
||||
vport->port_type == LPFC_NPIV_PORT &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
|
||||
if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE &&
|
||||
ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE &&
|
||||
@@ -5435,6 +5508,27 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
/* The driver's unsolicited deferred FLOGI ACC in Pt2Pt needs to
|
||||
* release the initial reference because the put after the free_iocb
|
||||
* call removes only the reference from the defer logic. This FLOGI
|
||||
* is never registered with the SCSI transport.
|
||||
*/
|
||||
if (test_bit(FC_PT2PT, &vport->fc_flag) &&
|
||||
test_and_clear_bit(NLP_FLOGI_DFR_ACC, &ndlp->nlp_flag)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO,
|
||||
LOG_ELS | LOG_NODE | LOG_DISCOVERY,
|
||||
"3357 Pt2Pt Defer FLOGI ACC ndlp x%px, "
|
||||
"nflags x%lx, fc_flag x%lx\n",
|
||||
ndlp, ndlp->nlp_flag,
|
||||
vport->fc_flag);
|
||||
cmd = *((u32 *)cmdiocb->cmd_dmabuf->virt);
|
||||
if (cmd == ELS_CMD_ACC) {
|
||||
if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
}
|
||||
|
||||
release:
|
||||
/* Release the originating I/O reference. */
|
||||
lpfc_els_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
@@ -5569,7 +5663,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
|
||||
sp->cls1.classValid = 0;
|
||||
sp->cls2.classValid = 0;
|
||||
sp->cls3.classValid = 0;
|
||||
sp->cls4.classValid = 0;
|
||||
|
||||
/* Copy our worldwide names */
|
||||
memcpy(&sp->portName, &vport->fc_sparam.portName,
|
||||
@@ -5583,7 +5676,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
|
||||
sp->cmn.valid_vendor_ver_level = 0;
|
||||
memset(sp->un.vendorVersion, 0,
|
||||
sizeof(sp->un.vendorVersion));
|
||||
sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
if (!test_bit(FC_PT2PT, &vport->fc_flag))
|
||||
sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
|
||||
/* If our firmware supports this feature, convey that
|
||||
* info to the target using the vendor specific field.
|
||||
@@ -8402,13 +8496,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
&wqe->xmit_els_rsp.wqe_com);
|
||||
|
||||
vport->fc_myDID = did;
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3344 Deferring FLOGI ACC: rx_id: x%x,"
|
||||
" ox_id: x%x, hba_flag x%lx\n",
|
||||
phba->defer_flogi_acc.rx_id,
|
||||
phba->defer_flogi_acc.ox_id, phba->hba_flag);
|
||||
|
||||
phba->defer_flogi_acc.flag = true;
|
||||
|
||||
/* This nlp_get is paired with nlp_puts that reset the
|
||||
@@ -8417,6 +8504,14 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
* processed or cancelled.
|
||||
*/
|
||||
phba->defer_flogi_acc.ndlp = lpfc_nlp_get(ndlp);
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3344 Deferring FLOGI ACC: rx_id: x%x,"
|
||||
" ox_id: x%x, ndlp x%px, hba_flag x%lx\n",
|
||||
phba->defer_flogi_acc.rx_id,
|
||||
phba->defer_flogi_acc.ox_id,
|
||||
phba->defer_flogi_acc.ndlp,
|
||||
phba->hba_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8734,7 +8829,7 @@ reject_out:
|
||||
* @cmdiocb: pointer to lpfc command iocb data structure.
|
||||
* @ndlp: pointer to a node-list data structure.
|
||||
*
|
||||
* This routine processes Read Timout Value (RTV) IOCB received as an
|
||||
* This routine processes Read Timeout Value (RTV) IOCB received as an
|
||||
* ELS unsolicited event. It first checks the remote port state. If the
|
||||
* remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
|
||||
* state, it invokes the lpfc_els_rsl_reject() routine to send the reject
|
||||
@@ -10357,11 +10452,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
* Do not process any unsolicited ELS commands
|
||||
* if the ndlp is in DEV_LOSS
|
||||
*/
|
||||
if (test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag)) {
|
||||
if (newnode)
|
||||
lpfc_nlp_put(ndlp);
|
||||
if (test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag))
|
||||
goto dropit;
|
||||
}
|
||||
|
||||
elsiocb->ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!elsiocb->ndlp)
|
||||
@@ -10843,7 +10935,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
|
||||
/*
|
||||
* The different unsolicited event handlers would tell us
|
||||
* if they are done with "mp" by setting cmd_dmabuf to NULL.
|
||||
* if they are done with "mp" by setting cmd_dmabuf/bpl_dmabuf to NULL.
|
||||
*/
|
||||
if (elsiocb->cmd_dmabuf) {
|
||||
lpfc_in_buf_free(phba, elsiocb->cmd_dmabuf);
|
||||
@@ -11423,6 +11515,13 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
sp->cls2.seqDelivery = 1;
|
||||
sp->cls3.seqDelivery = 1;
|
||||
|
||||
/* Fill out Auxiliary Parameter Data */
|
||||
if (phba->pni) {
|
||||
sp->aux.flags =
|
||||
AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
|
||||
sp->aux.pni = cpu_to_be64(phba->pni);
|
||||
}
|
||||
|
||||
pcmd += sizeof(uint32_t); /* CSP Word 2 */
|
||||
pcmd += sizeof(uint32_t); /* CSP Word 3 */
|
||||
pcmd += sizeof(uint32_t); /* CSP Word 4 */
|
||||
|
||||
@@ -424,6 +424,7 @@ lpfc_check_nlp_post_devloss(struct lpfc_vport *vport,
|
||||
struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
if (test_and_clear_bit(NLP_IN_RECOV_POST_DEV_LOSS, &ndlp->save_flags)) {
|
||||
clear_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_get(ndlp);
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_NODE,
|
||||
"8438 Devloss timeout reversed on DID x%x "
|
||||
@@ -566,7 +567,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
|
||||
return fcf_inuse;
|
||||
}
|
||||
|
||||
lpfc_nlp_put(ndlp);
|
||||
if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
lpfc_nlp_put(ndlp);
|
||||
return fcf_inuse;
|
||||
}
|
||||
|
||||
@@ -4371,6 +4373,8 @@ out:
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
|
||||
if (phba->pni)
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSPNI_PNI, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);
|
||||
|
||||
if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
|
||||
@@ -168,6 +168,11 @@ struct lpfc_sli_ct_request {
|
||||
uint8_t len;
|
||||
uint8_t symbname[255];
|
||||
} rspn;
|
||||
struct rspni { /* For RSPNI_PNI requests */
|
||||
__be64 pni;
|
||||
u8 len;
|
||||
u8 symbname[255];
|
||||
} rspni;
|
||||
struct gff {
|
||||
uint32_t PortId;
|
||||
} gff;
|
||||
@@ -213,6 +218,8 @@ struct lpfc_sli_ct_request {
|
||||
sizeof(struct da_id))
|
||||
#define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
|
||||
sizeof(struct rspn))
|
||||
#define RSPNI_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
|
||||
sizeof(struct rspni))
|
||||
|
||||
/*
|
||||
* FsType Definitions
|
||||
@@ -309,6 +316,7 @@ struct lpfc_sli_ct_request {
|
||||
#define SLI_CTNS_RIP_NN 0x0235
|
||||
#define SLI_CTNS_RIPA_NN 0x0236
|
||||
#define SLI_CTNS_RSNN_NN 0x0239
|
||||
#define SLI_CTNS_RSPNI_PNI 0x0240
|
||||
#define SLI_CTNS_DA_ID 0x0300
|
||||
|
||||
/*
|
||||
@@ -512,6 +520,21 @@ struct class_parms {
|
||||
uint8_t word3Reserved2; /* Fc Word 3, bit 0: 7 */
|
||||
};
|
||||
|
||||
enum aux_parm_flags {
|
||||
AUX_PARM_PNI_VALID = 0x20, /* FC Word 0, bit 29 */
|
||||
AUX_PARM_DATA_VALID = 0x40, /* FC Word 0, bit 30 */
|
||||
};
|
||||
|
||||
struct aux_parm {
|
||||
u8 flags; /* FC Word 0, bit 31:24 */
|
||||
u8 ext_feat[3]; /* FC Word 0, bit 23:0 */
|
||||
|
||||
__be64 pni; /* FC Word 1 and 2, platform name identifier */
|
||||
|
||||
__be16 rsvd; /* FC Word 3, bit 31:16 */
|
||||
__be16 npiv_cnt; /* FC Word 3, bit 15:0 */
|
||||
} __packed;
|
||||
|
||||
struct serv_parm { /* Structure is in Big Endian format */
|
||||
struct csp cmn;
|
||||
struct lpfc_name portName;
|
||||
@@ -519,7 +542,7 @@ struct serv_parm { /* Structure is in Big Endian format */
|
||||
struct class_parms cls1;
|
||||
struct class_parms cls2;
|
||||
struct class_parms cls3;
|
||||
struct class_parms cls4;
|
||||
struct aux_parm aux;
|
||||
union {
|
||||
uint8_t vendorVersion[16];
|
||||
struct {
|
||||
|
||||
@@ -3057,12 +3057,6 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
||||
lpfc_vmid_vport_cleanup(vport);
|
||||
|
||||
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
|
||||
if (ndlp->nlp_DID == Fabric_Cntl_DID &&
|
||||
ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
|
||||
lpfc_nlp_put(ndlp);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Fabric Ports not in UNMAPPED state are cleaned up in the
|
||||
* DEVICE_RM event.
|
||||
*/
|
||||
@@ -9082,9 +9076,9 @@ lpfc_setup_fdmi_mask(struct lpfc_vport *vport)
|
||||
vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
|
||||
}
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"6077 Setup FDMI mask: hba x%x port x%x\n",
|
||||
vport->fdmi_hba_mask, vport->fdmi_port_mask);
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"6077 Setup FDMI mask: hba x%x port x%x\n",
|
||||
vport->fdmi_hba_mask, vport->fdmi_port_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -432,8 +432,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS2;
|
||||
if (sp->cls3.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS3;
|
||||
if (sp->cls4.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS4;
|
||||
ndlp->nlp_maxframe =
|
||||
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
|
||||
/* if already logged in, do implicit logout */
|
||||
@@ -452,18 +450,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
*/
|
||||
if (!(ndlp->nlp_type & NLP_FABRIC) &&
|
||||
!(phba->nvmet_support)) {
|
||||
/* Clear ndlp info, since follow up PRLI may have
|
||||
* updated ndlp information
|
||||
*/
|
||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
|
||||
clear_bit(NLP_FIRSTBURST, &ndlp->nlp_flag);
|
||||
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
|
||||
ndlp, NULL);
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
if (nlp_portwwn != 0 &&
|
||||
nlp_portwwn != wwn_to_u64(sp->portName.u.wwn))
|
||||
@@ -485,7 +472,9 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear ndlp info, since follow up processes may have
|
||||
* updated ndlp information
|
||||
*/
|
||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
@@ -1426,8 +1415,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS2;
|
||||
if (sp->cls3.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS3;
|
||||
if (sp->cls4.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS4;
|
||||
ndlp->nlp_maxframe =
|
||||
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
@@ -8446,6 +8448,70 @@ lpfc_set_host_tm(struct lpfc_hba *phba)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_get_platform_uuid - Attempts to extract a platform uuid
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
*
|
||||
* This routine attempts to first read SMBIOS DMI data for the System
|
||||
* Information structure offset 08h called System UUID. Else, no platform
|
||||
* UUID will be advertised.
|
||||
**/
|
||||
static void
|
||||
lpfc_get_platform_uuid(struct lpfc_hba *phba)
|
||||
{
|
||||
int rc;
|
||||
const char *uuid;
|
||||
char pni[17] = {0}; /* 16 characters + '\0' */
|
||||
bool is_ff = true, is_00 = true;
|
||||
u8 i;
|
||||
|
||||
/* First attempt SMBIOS DMI */
|
||||
uuid = dmi_get_system_info(DMI_PRODUCT_UUID);
|
||||
if (uuid) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"2088 SMBIOS UUID %s\n",
|
||||
uuid);
|
||||
} else {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"2099 Could not extract UUID\n");
|
||||
}
|
||||
|
||||
if (uuid && uuid_is_valid(uuid)) {
|
||||
/* Generate PNI from UUID format.
|
||||
*
|
||||
* 1.) Extract lower 64 bits from UUID format.
|
||||
* 2.) Set 3h for NAA Locally Assigned Name Identifier format.
|
||||
*
|
||||
* e.g. xxxxxxxx-xxxx-xxxx-yyyy-yyyyyyyyyyyy
|
||||
*
|
||||
* extract the yyyy-yyyyyyyyyyyy portion
|
||||
* final PNI 3yyyyyyyyyyyyyyy
|
||||
*/
|
||||
scnprintf(pni, sizeof(pni), "3%c%c%c%s",
|
||||
uuid[20], uuid[21], uuid[22], &uuid[24]);
|
||||
|
||||
/* Sanitize the converted PNI */
|
||||
for (i = 1; i < 16 && (is_ff || is_00); i++) {
|
||||
if (pni[i] != '0')
|
||||
is_00 = false;
|
||||
if (pni[i] != 'f' && pni[i] != 'F')
|
||||
is_ff = false;
|
||||
}
|
||||
|
||||
/* Convert from char* to unsigned long */
|
||||
rc = kstrtoul(pni, 16, &phba->pni);
|
||||
if (!rc && !is_ff && !is_00) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"2100 PNI 0x%016lx\n", phba->pni);
|
||||
} else {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"2101 PNI %s generation status %d\n",
|
||||
pni, rc);
|
||||
phba->pni = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_hba_setup - SLI4 device initialization PCI function
|
||||
* @phba: Pointer to HBA context object.
|
||||
@@ -8529,6 +8595,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||
clear_bit(HBA_FCOE_MODE, &phba->hba_flag);
|
||||
}
|
||||
|
||||
/* Obtain platform UUID, only for SLI4 FC adapters */
|
||||
if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag))
|
||||
lpfc_get_platform_uuid(phba);
|
||||
|
||||
if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
|
||||
LPFC_DCBX_CEE_MODE)
|
||||
set_bit(HBA_FIP_SUPPORT, &phba->hba_flag);
|
||||
@@ -19858,13 +19928,15 @@ lpfc_sli4_remove_rpis(struct lpfc_hba *phba)
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_resume_rpi - Remove the rpi bitmask region
|
||||
* lpfc_sli4_resume_rpi - Resume traffic relative to an RPI
|
||||
* @ndlp: pointer to lpfc nodelist data structure.
|
||||
* @cmpl: completion call-back.
|
||||
* @iocbq: data to load as mbox ctx_u information
|
||||
*
|
||||
* This routine is invoked to remove the memory region that
|
||||
* provided rpi via a bitmask.
|
||||
* Return codes
|
||||
* 0 - successful
|
||||
* -ENOMEM - No available memory
|
||||
* -EIO - The mailbox failed to complete successfully.
|
||||
**/
|
||||
int
|
||||
lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp,
|
||||
@@ -19894,7 +19966,6 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Post all rpi memory regions to the port. */
|
||||
lpfc_resume_rpi(mboxq, ndlp);
|
||||
if (cmpl) {
|
||||
mboxq->mbox_cmpl = cmpl;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
#define LPFC_DRIVER_VERSION "14.4.0.11"
|
||||
#define LPFC_DRIVER_VERSION "14.4.0.12"
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
/* Used for SLI 2/3 */
|
||||
|
||||
Reference in New Issue
Block a user