summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c249
1 files changed, 174 insertions, 75 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index b71db7d7d747..02b6d31b9ad9 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -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 */