[SCSI] lpfc 8.3.31: Correct point-to-point mode discovery errors on LPe16xxx
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:
Родитель
27aa1b7353
Коммит
939723a4a6
|
@ -230,27 +230,43 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pbuflist->list);
|
INIT_LIST_HEAD(&pbuflist->list);
|
||||||
|
|
||||||
icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
|
|
||||||
icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
|
|
||||||
icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
|
||||||
icmd->un.elsreq64.remoteID = did; /* DID */
|
|
||||||
if (expectRsp) {
|
if (expectRsp) {
|
||||||
|
icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
|
||||||
|
icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
|
||||||
|
icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||||
icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
|
icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
|
||||||
|
|
||||||
|
icmd->un.elsreq64.remoteID = did; /* DID */
|
||||||
icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
|
icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
|
||||||
icmd->ulpTimeout = phba->fc_ratov * 2;
|
icmd->ulpTimeout = phba->fc_ratov * 2;
|
||||||
} else {
|
} else {
|
||||||
icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64);
|
icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
|
||||||
|
icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
|
||||||
|
icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||||
|
icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64);
|
||||||
|
icmd->un.xseq64.xmit_els_remoteID = did; /* DID */
|
||||||
icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
|
icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
|
||||||
}
|
}
|
||||||
icmd->ulpBdeCount = 1;
|
icmd->ulpBdeCount = 1;
|
||||||
icmd->ulpLe = 1;
|
icmd->ulpLe = 1;
|
||||||
icmd->ulpClass = CLASS3;
|
icmd->ulpClass = CLASS3;
|
||||||
|
|
||||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
|
/*
|
||||||
icmd->un.elsreq64.myID = vport->fc_myDID;
|
* If we have NPIV enabled, we want to send ELS traffic by VPI.
|
||||||
|
* For SLI4, since the driver controls VPIs we also want to include
|
||||||
|
* all ELS pt2pt protocol traffic as well.
|
||||||
|
*/
|
||||||
|
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) ||
|
||||||
|
((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||||
|
(vport->fc_flag & FC_PT2PT))) {
|
||||||
|
|
||||||
|
if (expectRsp) {
|
||||||
|
icmd->un.elsreq64.myID = vport->fc_myDID;
|
||||||
|
|
||||||
|
/* For ELS_REQUEST64_CR, use the VPI by default */
|
||||||
|
icmd->ulpContext = phba->vpi_ids[vport->vpi];
|
||||||
|
}
|
||||||
|
|
||||||
/* For ELS_REQUEST64_CR, use the VPI by default */
|
|
||||||
icmd->ulpContext = phba->vpi_ids[vport->vpi];
|
|
||||||
icmd->ulpCt_h = 0;
|
icmd->ulpCt_h = 0;
|
||||||
/* The CT field must be 0=INVALID_RPI for the ECHO cmd */
|
/* The CT field must be 0=INVALID_RPI for the ECHO cmd */
|
||||||
if (elscmd == ELS_CMD_ECHO)
|
if (elscmd == ELS_CMD_ECHO)
|
||||||
|
@ -438,9 +454,10 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
sp = &phba->fc_fabparam;
|
sp = &phba->fc_fabparam;
|
||||||
/* move forward in case of SLI4 FC port loopback test */
|
/* move forward in case of SLI4 FC port loopback test and pt2pt mode */
|
||||||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||||
!(phba->link_flag & LS_LOOPBACK_MODE)) {
|
!(phba->link_flag & LS_LOOPBACK_MODE) &&
|
||||||
|
!(vport->fc_flag & FC_PT2PT)) {
|
||||||
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
ndlp = lpfc_findnode_did(vport, Fabric_DID);
|
||||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
|
@ -820,6 +837,17 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
mempool_free(mbox, phba->mbox_mem_pool);
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For SLI4, the VFI/VPI are registered AFTER the
|
||||||
|
* Nport with the higher WWPN sends the PLOGI with
|
||||||
|
* an assigned NPortId.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* not equal */
|
||||||
|
if ((phba->sli_rev == LPFC_SLI_REV4) && rc)
|
||||||
|
lpfc_issue_reg_vfi(vport);
|
||||||
|
|
||||||
/* Decrement ndlp reference count indicating that ndlp can be
|
/* Decrement ndlp reference count indicating that ndlp can be
|
||||||
* safely released when other references to it are done.
|
* safely released when other references to it are done.
|
||||||
*/
|
*/
|
||||||
|
@ -4940,8 +4968,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
did = Fabric_DID;
|
|
||||||
|
|
||||||
if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
|
if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
|
||||||
/* For a FLOGI we accept, then if our portname is greater
|
/* For a FLOGI we accept, then if our portname is greater
|
||||||
* then the remote portname we initiate Nport login.
|
* then the remote portname we initiate Nport login.
|
||||||
|
@ -4980,29 +5006,64 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
vport->fc_flag |= FC_PT2PT_PLOGI;
|
vport->fc_flag |= FC_PT2PT_PLOGI;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
|
||||||
|
/* If we have the high WWPN we can assign our own
|
||||||
|
* myDID; otherwise, we have to WAIT for a PLOGI
|
||||||
|
* from the remote NPort to find out what it
|
||||||
|
* will be.
|
||||||
|
*/
|
||||||
vport->fc_myDID = PT2PT_LocalID;
|
vport->fc_myDID = PT2PT_LocalID;
|
||||||
} else
|
}
|
||||||
vport->fc_myDID = PT2PT_RemoteID;
|
|
||||||
vport->port_state = LPFC_FLOGI;
|
/*
|
||||||
|
* The vport state should go to LPFC_FLOGI only
|
||||||
|
* AFTER we issue a FLOGI, not receive one.
|
||||||
|
*/
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
vport->fc_flag |= FC_PT2PT;
|
vport->fc_flag |= FC_PT2PT;
|
||||||
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
|
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We temporarily set fc_myDID to make it look like we are
|
||||||
|
* a Fabric. This is done just so we end up with the right
|
||||||
|
* did / sid on the FLOGI ACC rsp.
|
||||||
|
*/
|
||||||
|
did = vport->fc_myDID;
|
||||||
|
vport->fc_myDID = Fabric_DID;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Reject this request because invalid parameters */
|
/* Reject this request because invalid parameters */
|
||||||
stat.un.b.lsRjtRsvd0 = 0;
|
stat.un.b.lsRjtRsvd0 = 0;
|
||||||
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
||||||
stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
|
stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
|
||||||
stat.un.b.vendorUnique = 0;
|
stat.un.b.vendorUnique = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We temporarily set fc_myDID to make it look like we are
|
||||||
|
* a Fabric. This is done just so we end up with the right
|
||||||
|
* did / sid on the FLOGI LS_RJT rsp.
|
||||||
|
*/
|
||||||
|
did = vport->fc_myDID;
|
||||||
|
vport->fc_myDID = Fabric_DID;
|
||||||
|
|
||||||
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* Now lets put fc_myDID back to what its supposed to be */
|
||||||
|
vport->fc_myDID = did;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send back ACC */
|
/* Send back ACC */
|
||||||
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
|
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
|
||||||
|
|
||||||
|
/* Now lets put fc_myDID back to what its supposed to be */
|
||||||
|
vport->fc_myDID = did;
|
||||||
|
|
||||||
if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
||||||
|
|
||||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||||
if (!mbox)
|
if (!mbox)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -2882,9 +2882,14 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
|
if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
|
||||||
/* For private loop just start discovery and we are done. */
|
/*
|
||||||
if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
|
* For private loop or for NPort pt2pt,
|
||||||
!(vport->fc_flag & FC_PUBLIC_LOOP)) {
|
* just start discovery and we are done.
|
||||||
|
*/
|
||||||
|
if ((vport->fc_flag & FC_PT2PT) ||
|
||||||
|
((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
|
||||||
|
!(vport->fc_flag & FC_PUBLIC_LOOP))) {
|
||||||
|
|
||||||
/* Use loop map to make discovery list */
|
/* Use loop map to make discovery list */
|
||||||
lpfc_disc_list_loopmap(vport);
|
lpfc_disc_list_loopmap(vport);
|
||||||
/* Start discovery */
|
/* Start discovery */
|
||||||
|
@ -5491,9 +5496,9 @@ lpfc_nlp_release(struct kref *kref)
|
||||||
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
|
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
|
||||||
|
|
||||||
lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
|
lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
|
||||||
"0279 lpfc_nlp_release: ndlp:x%p "
|
"0279 lpfc_nlp_release: ndlp:x%p did %x "
|
||||||
"usgmap:x%x refcnt:%d\n",
|
"usgmap:x%x refcnt:%d\n",
|
||||||
(void *)ndlp, ndlp->nlp_usg_map,
|
(void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map,
|
||||||
atomic_read(&ndlp->kref.refcount));
|
atomic_read(&ndlp->kref.refcount));
|
||||||
|
|
||||||
/* remove ndlp from action. */
|
/* remove ndlp from action. */
|
||||||
|
|
|
@ -3374,6 +3374,9 @@ typedef struct {
|
||||||
WORD5 w5; /* Header control/status word */
|
WORD5 w5; /* Header control/status word */
|
||||||
} XMT_SEQ_FIELDS64;
|
} XMT_SEQ_FIELDS64;
|
||||||
|
|
||||||
|
/* This word is remote ports D_ID for XMIT_ELS_RSP64 */
|
||||||
|
#define xmit_els_remoteID xrsqRo
|
||||||
|
|
||||||
/* IOCB Command template for 64 bit RCV_SEQUENCE64 */
|
/* IOCB Command template for 64 bit RCV_SEQUENCE64 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct ulp_bde64 rcvBde;
|
struct ulp_bde64 rcvBde;
|
||||||
|
|
|
@ -3295,7 +3295,13 @@ struct els_request64_wqe {
|
||||||
struct xmit_els_rsp64_wqe {
|
struct xmit_els_rsp64_wqe {
|
||||||
struct ulp_bde64 bde;
|
struct ulp_bde64 bde;
|
||||||
uint32_t response_payload_len;
|
uint32_t response_payload_len;
|
||||||
uint32_t rsvd4;
|
uint32_t word4;
|
||||||
|
#define els_rsp64_sid_SHIFT 0
|
||||||
|
#define els_rsp64_sid_MASK 0x00FFFFFF
|
||||||
|
#define els_rsp64_sid_WORD word4
|
||||||
|
#define els_rsp64_sp_SHIFT 24
|
||||||
|
#define els_rsp64_sp_MASK 0x00000001
|
||||||
|
#define els_rsp64_sp_WORD word4
|
||||||
struct wqe_did wqe_dest;
|
struct wqe_did wqe_dest;
|
||||||
struct wqe_common wqe_com; /* words 6-11 */
|
struct wqe_common wqe_com; /* words 6-11 */
|
||||||
uint32_t word12;
|
uint32_t word12;
|
||||||
|
|
|
@ -367,8 +367,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for Nport to NPort pt2pt protocol */
|
||||||
if ((vport->fc_flag & FC_PT2PT) &&
|
if ((vport->fc_flag & FC_PT2PT) &&
|
||||||
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
||||||
|
|
||||||
/* rcv'ed PLOGI decides what our NPortId will be */
|
/* rcv'ed PLOGI decides what our NPortId will be */
|
||||||
vport->fc_myDID = icmd->un.rcvels.parmRo;
|
vport->fc_myDID = icmd->un.rcvels.parmRo;
|
||||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||||
|
@ -382,6 +384,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
mempool_free(mbox, phba->mbox_mem_pool);
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* For SLI4, the VFI/VPI are registered AFTER the
|
||||||
|
* Nport with the higher WWPN sends us a PLOGI with
|
||||||
|
* our assigned NPortId.
|
||||||
|
*/
|
||||||
|
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||||
|
lpfc_issue_reg_vfi(vport);
|
||||||
|
|
||||||
lpfc_can_disctmo(vport);
|
lpfc_can_disctmo(vport);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7907,6 +7907,10 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
||||||
bf_set(els_req64_sp, &wqe->els_req, 1);
|
bf_set(els_req64_sp, &wqe->els_req, 1);
|
||||||
bf_set(els_req64_sid, &wqe->els_req,
|
bf_set(els_req64_sid, &wqe->els_req,
|
||||||
iocbq->vport->fc_myDID);
|
iocbq->vport->fc_myDID);
|
||||||
|
if ((*pcmd == ELS_CMD_FLOGI) &&
|
||||||
|
!(phba->fc_topology ==
|
||||||
|
LPFC_TOPOLOGY_LOOP))
|
||||||
|
bf_set(els_req64_sid, &wqe->els_req, 0);
|
||||||
bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
|
bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
|
||||||
bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
|
bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
|
||||||
phba->vpi_ids[iocbq->vport->vpi]);
|
phba->vpi_ids[iocbq->vport->vpi]);
|
||||||
|
@ -8064,11 +8068,25 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
||||||
/* words0-2 BDE memcpy */
|
/* words0-2 BDE memcpy */
|
||||||
/* word3 iocb=iotag32 wqe=response_payload_len */
|
/* word3 iocb=iotag32 wqe=response_payload_len */
|
||||||
wqe->xmit_els_rsp.response_payload_len = xmit_len;
|
wqe->xmit_els_rsp.response_payload_len = xmit_len;
|
||||||
/* word4 iocb=did wge=rsvd. */
|
/* word4 */
|
||||||
wqe->xmit_els_rsp.rsvd4 = 0;
|
wqe->xmit_els_rsp.word4 = 0;
|
||||||
/* word5 iocb=rsvd wge=did */
|
/* word5 iocb=rsvd wge=did */
|
||||||
bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
|
bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
|
||||||
iocbq->iocb.un.elsreq64.remoteID);
|
iocbq->iocb.un.xseq64.xmit_els_remoteID);
|
||||||
|
|
||||||
|
if_type = bf_get(lpfc_sli_intf_if_type,
|
||||||
|
&phba->sli4_hba.sli_intf);
|
||||||
|
if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
|
||||||
|
if (iocbq->vport->fc_flag & FC_PT2PT) {
|
||||||
|
bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
|
||||||
|
bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
|
||||||
|
iocbq->vport->fc_myDID);
|
||||||
|
if (iocbq->vport->fc_myDID == Fabric_DID) {
|
||||||
|
bf_set(wqe_els_did,
|
||||||
|
&wqe->xmit_els_rsp.wqe_dest, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com,
|
bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com,
|
||||||
((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
|
((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
|
||||||
bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU);
|
bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU);
|
||||||
|
@ -8088,11 +8106,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
||||||
pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
|
pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
|
||||||
iocbq->context2)->virt);
|
iocbq->context2)->virt);
|
||||||
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
|
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
|
||||||
bf_set(els_req64_sp, &wqe->els_req, 1);
|
bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
|
||||||
bf_set(els_req64_sid, &wqe->els_req,
|
bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
|
||||||
iocbq->vport->fc_myDID);
|
iocbq->vport->fc_myDID);
|
||||||
bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
|
bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 1);
|
||||||
bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
|
bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
|
||||||
phba->vpi_ids[phba->pport->vpi]);
|
phba->vpi_ids[phba->pport->vpi]);
|
||||||
}
|
}
|
||||||
command_type = OTHER_COMMAND;
|
command_type = OTHER_COMMAND;
|
||||||
|
@ -13636,8 +13654,13 @@ lpfc_fc_frame_to_vport(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr,
|
||||||
uint32_t did = (fc_hdr->fh_d_id[0] << 16 |
|
uint32_t did = (fc_hdr->fh_d_id[0] << 16 |
|
||||||
fc_hdr->fh_d_id[1] << 8 |
|
fc_hdr->fh_d_id[1] << 8 |
|
||||||
fc_hdr->fh_d_id[2]);
|
fc_hdr->fh_d_id[2]);
|
||||||
|
|
||||||
if (did == Fabric_DID)
|
if (did == Fabric_DID)
|
||||||
return phba->pport;
|
return phba->pport;
|
||||||
|
if ((phba->pport->fc_flag & FC_PT2PT) &&
|
||||||
|
!(phba->link_state == LPFC_HBA_READY))
|
||||||
|
return phba->pport;
|
||||||
|
|
||||||
vports = lpfc_create_vport_work_array(phba);
|
vports = lpfc_create_vport_work_array(phba);
|
||||||
if (vports != NULL)
|
if (vports != NULL)
|
||||||
for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||||
|
@ -14174,7 +14197,15 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
||||||
/* Initialize the first IOCB. */
|
/* Initialize the first IOCB. */
|
||||||
first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
|
first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
|
||||||
first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
|
first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
|
||||||
first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
|
|
||||||
|
/* Check FC Header to see what TYPE of frame we are rcv'ing */
|
||||||
|
if (sli4_type_from_fc_hdr(fc_hdr) == FC_TYPE_ELS) {
|
||||||
|
first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_ELS64_CX;
|
||||||
|
first_iocbq->iocb.un.rcvels.parmRo =
|
||||||
|
sli4_did_from_fc_hdr(fc_hdr);
|
||||||
|
first_iocbq->iocb.ulpPU = PARM_NPIV_DID;
|
||||||
|
} else
|
||||||
|
first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
|
||||||
first_iocbq->iocb.ulpContext = NO_XRI;
|
first_iocbq->iocb.ulpContext = NO_XRI;
|
||||||
first_iocbq->iocb.unsli3.rcvsli3.ox_id =
|
first_iocbq->iocb.unsli3.rcvsli3.ox_id =
|
||||||
be16_to_cpu(fc_hdr->fh_ox_id);
|
be16_to_cpu(fc_hdr->fh_ox_id);
|
||||||
|
@ -14304,6 +14335,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
|
||||||
struct fc_frame_header *fc_hdr;
|
struct fc_frame_header *fc_hdr;
|
||||||
struct lpfc_vport *vport;
|
struct lpfc_vport *vport;
|
||||||
uint32_t fcfi;
|
uint32_t fcfi;
|
||||||
|
uint32_t did;
|
||||||
|
|
||||||
/* Process each received buffer */
|
/* Process each received buffer */
|
||||||
fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
|
fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
|
||||||
|
@ -14319,12 +14351,32 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
|
||||||
else
|
else
|
||||||
fcfi = bf_get(lpfc_rcqe_fcf_id,
|
fcfi = bf_get(lpfc_rcqe_fcf_id,
|
||||||
&dmabuf->cq_event.cqe.rcqe_cmpl);
|
&dmabuf->cq_event.cqe.rcqe_cmpl);
|
||||||
|
|
||||||
vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
|
vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
|
||||||
if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) {
|
if (!vport) {
|
||||||
/* throw out the frame */
|
/* throw out the frame */
|
||||||
lpfc_in_buf_free(phba, &dmabuf->dbuf);
|
lpfc_in_buf_free(phba, &dmabuf->dbuf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* d_id this frame is directed to */
|
||||||
|
did = sli4_did_from_fc_hdr(fc_hdr);
|
||||||
|
|
||||||
|
/* vport is registered unless we rcv a FLOGI directed to Fabric_DID */
|
||||||
|
if (!(vport->vpi_state & LPFC_VPI_REGISTERED) &&
|
||||||
|
(did != Fabric_DID)) {
|
||||||
|
/*
|
||||||
|
* Throw out the frame if we are not pt2pt.
|
||||||
|
* The pt2pt protocol allows for discovery frames
|
||||||
|
* to be received without a registered VPI.
|
||||||
|
*/
|
||||||
|
if (!(vport->fc_flag & FC_PT2PT) ||
|
||||||
|
(phba->link_state == LPFC_HBA_READY)) {
|
||||||
|
lpfc_in_buf_free(phba, &dmabuf->dbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle the basic abort sequence (BA_ABTS) event */
|
/* Handle the basic abort sequence (BA_ABTS) event */
|
||||||
if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
|
if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
|
||||||
lpfc_sli4_handle_unsol_abort(vport, dmabuf);
|
lpfc_sli4_handle_unsol_abort(vport, dmabuf);
|
||||||
|
|
|
@ -75,11 +75,19 @@
|
||||||
(fc_hdr)->fh_s_id[1] << 8 | \
|
(fc_hdr)->fh_s_id[1] << 8 | \
|
||||||
(fc_hdr)->fh_s_id[2])
|
(fc_hdr)->fh_s_id[2])
|
||||||
|
|
||||||
|
#define sli4_did_from_fc_hdr(fc_hdr) \
|
||||||
|
((fc_hdr)->fh_d_id[0] << 16 | \
|
||||||
|
(fc_hdr)->fh_d_id[1] << 8 | \
|
||||||
|
(fc_hdr)->fh_d_id[2])
|
||||||
|
|
||||||
#define sli4_fctl_from_fc_hdr(fc_hdr) \
|
#define sli4_fctl_from_fc_hdr(fc_hdr) \
|
||||||
((fc_hdr)->fh_f_ctl[0] << 16 | \
|
((fc_hdr)->fh_f_ctl[0] << 16 | \
|
||||||
(fc_hdr)->fh_f_ctl[1] << 8 | \
|
(fc_hdr)->fh_f_ctl[1] << 8 | \
|
||||||
(fc_hdr)->fh_f_ctl[2])
|
(fc_hdr)->fh_f_ctl[2])
|
||||||
|
|
||||||
|
#define sli4_type_from_fc_hdr(fc_hdr) \
|
||||||
|
((fc_hdr)->fh_type)
|
||||||
|
|
||||||
#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000
|
#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000
|
||||||
|
|
||||||
enum lpfc_sli4_queue_type {
|
enum lpfc_sli4_queue_type {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче