scsi: lpfc: SLI path split: Introduce lpfc_prep_wqe
Introduce lpfc_prep_wqe routine. The lpfc_prep_wqe() routine is used with lpfc_sli_issue_iocb() and lpfc_sli_issue_iocb_wait(). The routine performs additional SLI-4 wqe field setting that the generic routines did not perform as they kept their actions compatible with both SLI3 and SLI4. Link: https://lore.kernel.org/r/20220225022308.16486-4-jsmart2021@gmail.com Co-developed-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Родитель
1b64aa9eae
Коммит
561341425b
|
@ -3290,6 +3290,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
|
|||
cmdiocbq->cmd_flag |= LPFC_IO_LOOPBACK;
|
||||
cmdiocbq->vport = phba->pport;
|
||||
cmdiocbq->cmd_cmpl = NULL;
|
||||
|
||||
iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
|
||||
rspiocbq, (phba->fc_ratov * 2) +
|
||||
LPFC_DRVR_TIMEOUT);
|
||||
|
|
|
@ -191,6 +191,7 @@ void lpfc_els_timeout_handler(struct lpfc_vport *);
|
|||
struct lpfc_iocbq *lpfc_prep_els_iocb(struct lpfc_vport *, uint8_t, uint16_t,
|
||||
uint8_t, struct lpfc_nodelist *,
|
||||
uint32_t, uint32_t);
|
||||
void lpfc_sli_prep_wqe(struct lpfc_hba *phba, struct lpfc_iocbq *job);
|
||||
void lpfc_hb_timeout_handler(struct lpfc_hba *);
|
||||
|
||||
void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
|
|
|
@ -659,6 +659,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
|||
geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!geniocb->context_un.ndlp)
|
||||
goto out;
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
|
||||
|
||||
if (rc == IOCB_ERROR) {
|
||||
|
|
|
@ -2861,6 +2861,7 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
"Issue ADISC: 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);
|
||||
|
@ -3085,6 +3086,7 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
"Issue LOGO: 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);
|
||||
|
|
|
@ -11251,6 +11251,8 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,
|
|||
int rc;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
lpfc_sli_prep_wqe(phba, piocb);
|
||||
|
||||
eq = phba->sli4_hba.hdwq[piocb->hba_wqidx].hba_eq;
|
||||
|
||||
pring = lpfc_sli4_calc_ring(phba, piocb);
|
||||
|
@ -13074,9 +13076,11 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
|
|||
unsigned long iflags;
|
||||
bool iocb_completed = true;
|
||||
|
||||
if (phba->sli_rev >= LPFC_SLI_REV4)
|
||||
if (phba->sli_rev >= LPFC_SLI_REV4) {
|
||||
lpfc_sli_prep_wqe(phba, piocb);
|
||||
|
||||
pring = lpfc_sli4_calc_ring(phba, piocb);
|
||||
else
|
||||
} else
|
||||
pring = &phba->sli.sli3_ring[ring_number];
|
||||
/*
|
||||
* If the caller has provided a response iocbq buffer, then context2
|
||||
|
@ -22448,3 +22452,192 @@ lpfc_free_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba,
|
|||
|
||||
spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_prep_wqe - Prepare WQE for the command to be posted
|
||||
* @phba: phba object
|
||||
* @job: job entry of the command to be posted.
|
||||
*
|
||||
* Fill the common fields of the wqe for each of the command.
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
**/
|
||||
void
|
||||
lpfc_sli_prep_wqe(struct lpfc_hba *phba, struct lpfc_iocbq *job)
|
||||
{
|
||||
u8 cmnd;
|
||||
u32 *pcmd;
|
||||
u32 if_type = 0;
|
||||
u32 fip, abort_tag;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
union lpfc_wqe128 *wqe = &job->wqe;
|
||||
struct lpfc_dmabuf *context2;
|
||||
u32 els_id = LPFC_ELS_ID_DEFAULT;
|
||||
u8 command_type = ELS_COMMAND_NON_FIP;
|
||||
|
||||
fip = phba->hba_flag & HBA_FIP_SUPPORT;
|
||||
/* The fcp commands will set command type */
|
||||
if (job->cmd_flag & LPFC_IO_FCP)
|
||||
command_type = FCP_COMMAND;
|
||||
else if (fip && (job->cmd_flag & LPFC_FIP_ELS_ID_MASK))
|
||||
command_type = ELS_COMMAND_FIP;
|
||||
else
|
||||
command_type = ELS_COMMAND_NON_FIP;
|
||||
|
||||
abort_tag = job->iotag;
|
||||
cmnd = bf_get(wqe_cmnd, &wqe->els_req.wqe_com);
|
||||
|
||||
switch (cmnd) {
|
||||
case CMD_ELS_REQUEST64_WQE:
|
||||
if (job->cmd_flag & LPFC_IO_LIBDFC)
|
||||
ndlp = job->context_un.ndlp;
|
||||
else
|
||||
ndlp = (struct lpfc_nodelist *)job->context1;
|
||||
|
||||
/* CCP CCPE PV PRI in word10 were set in the memcpy */
|
||||
if (command_type == ELS_COMMAND_FIP)
|
||||
els_id = ((job->cmd_flag & LPFC_FIP_ELS_ID_MASK)
|
||||
>> LPFC_FIP_ELS_ID_SHIFT);
|
||||
|
||||
if_type = bf_get(lpfc_sli_intf_if_type,
|
||||
&phba->sli4_hba.sli_intf);
|
||||
if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
|
||||
context2 = (struct lpfc_dmabuf *)job->context2;
|
||||
pcmd = (u32 *)context2->virt;
|
||||
if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
|
||||
*pcmd == ELS_CMD_SCR ||
|
||||
*pcmd == ELS_CMD_RDF ||
|
||||
*pcmd == ELS_CMD_EDC ||
|
||||
*pcmd == ELS_CMD_RSCN_XMT ||
|
||||
*pcmd == ELS_CMD_FDISC ||
|
||||
*pcmd == ELS_CMD_LOGO ||
|
||||
*pcmd == ELS_CMD_QFPA ||
|
||||
*pcmd == ELS_CMD_UVEM ||
|
||||
*pcmd == ELS_CMD_PLOGI)) {
|
||||
bf_set(els_req64_sp, &wqe->els_req, 1);
|
||||
bf_set(els_req64_sid, &wqe->els_req,
|
||||
job->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_ctxt_tag, &wqe->els_req.wqe_com,
|
||||
phba->vpi_ids[job->vport->vpi]);
|
||||
} else if (pcmd) {
|
||||
bf_set(wqe_ct, &wqe->els_req.wqe_com, 0);
|
||||
bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
|
||||
}
|
||||
}
|
||||
|
||||
bf_set(wqe_temp_rpi, &wqe->els_req.wqe_com,
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
|
||||
|
||||
bf_set(wqe_els_id, &wqe->els_req.wqe_com, els_id);
|
||||
bf_set(wqe_dbde, &wqe->els_req.wqe_com, 1);
|
||||
bf_set(wqe_iod, &wqe->els_req.wqe_com, LPFC_WQE_IOD_READ);
|
||||
bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1);
|
||||
bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE);
|
||||
bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0);
|
||||
break;
|
||||
case CMD_XMIT_ELS_RSP64_WQE:
|
||||
ndlp = (struct lpfc_nodelist *)job->context1;
|
||||
|
||||
/* word4 */
|
||||
wqe->xmit_els_rsp.word4 = 0;
|
||||
|
||||
if_type = bf_get(lpfc_sli_intf_if_type,
|
||||
&phba->sli4_hba.sli_intf);
|
||||
if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
|
||||
if (job->vport->fc_flag & FC_PT2PT) {
|
||||
bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
|
||||
bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
|
||||
job->vport->fc_myDID);
|
||||
if (job->vport->fc_myDID == Fabric_DID) {
|
||||
bf_set(wqe_els_did,
|
||||
&wqe->xmit_els_rsp.wqe_dest, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bf_set(wqe_dbde, &wqe->xmit_els_rsp.wqe_com, 1);
|
||||
bf_set(wqe_iod, &wqe->xmit_els_rsp.wqe_com, LPFC_WQE_IOD_WRITE);
|
||||
bf_set(wqe_qosd, &wqe->xmit_els_rsp.wqe_com, 1);
|
||||
bf_set(wqe_lenloc, &wqe->xmit_els_rsp.wqe_com,
|
||||
LPFC_WQE_LENLOC_WORD3);
|
||||
bf_set(wqe_ebde_cnt, &wqe->xmit_els_rsp.wqe_com, 0);
|
||||
|
||||
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
|
||||
bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
|
||||
bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
|
||||
job->vport->fc_myDID);
|
||||
bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 1);
|
||||
}
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp,
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
|
||||
|
||||
if (bf_get(wqe_ct, &wqe->xmit_els_rsp.wqe_com))
|
||||
bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
|
||||
phba->vpi_ids[job->vport->vpi]);
|
||||
}
|
||||
command_type = OTHER_COMMAND;
|
||||
break;
|
||||
case CMD_GEN_REQUEST64_WQE:
|
||||
/* Word 10 */
|
||||
bf_set(wqe_dbde, &wqe->gen_req.wqe_com, 1);
|
||||
bf_set(wqe_iod, &wqe->gen_req.wqe_com, LPFC_WQE_IOD_READ);
|
||||
bf_set(wqe_qosd, &wqe->gen_req.wqe_com, 1);
|
||||
bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE);
|
||||
bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0);
|
||||
command_type = OTHER_COMMAND;
|
||||
break;
|
||||
case CMD_XMIT_SEQUENCE64_WQE:
|
||||
if (phba->link_flag & LS_LOOPBACK_MODE)
|
||||
bf_set(wqe_xo, &wqe->xmit_sequence.wge_ctl, 1);
|
||||
|
||||
wqe->xmit_sequence.rsvd3 = 0;
|
||||
bf_set(wqe_pu, &wqe->xmit_sequence.wqe_com, 0);
|
||||
bf_set(wqe_dbde, &wqe->xmit_sequence.wqe_com, 1);
|
||||
bf_set(wqe_iod, &wqe->xmit_sequence.wqe_com,
|
||||
LPFC_WQE_IOD_WRITE);
|
||||
bf_set(wqe_lenloc, &wqe->xmit_sequence.wqe_com,
|
||||
LPFC_WQE_LENLOC_WORD12);
|
||||
bf_set(wqe_ebde_cnt, &wqe->xmit_sequence.wqe_com, 0);
|
||||
command_type = OTHER_COMMAND;
|
||||
break;
|
||||
case CMD_XMIT_BLS_RSP64_WQE:
|
||||
bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff);
|
||||
bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
|
||||
bf_set(wqe_ct, &wqe->xmit_bls_rsp.wqe_com, 1);
|
||||
bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
|
||||
phba->vpi_ids[phba->pport->vpi]);
|
||||
bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1);
|
||||
bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com,
|
||||
LPFC_WQE_LENLOC_NONE);
|
||||
/* Overwrite the pre-set comnd type with OTHER_COMMAND */
|
||||
command_type = OTHER_COMMAND;
|
||||
break;
|
||||
case CMD_FCP_ICMND64_WQE: /* task mgmt commands */
|
||||
case CMD_ABORT_XRI_WQE: /* abort iotag */
|
||||
case CMD_SEND_FRAME: /* mds loopback */
|
||||
/* cases already formatted for sli4 wqe - no chgs necessary */
|
||||
return;
|
||||
default:
|
||||
dump_stack();
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"6207 Invalid command 0x%x\n",
|
||||
cmnd);
|
||||
break;
|
||||
}
|
||||
|
||||
wqe->generic.wqe_com.abort_tag = abort_tag;
|
||||
bf_set(wqe_reqtag, &wqe->generic.wqe_com, job->iotag);
|
||||
bf_set(wqe_cmd_type, &wqe->generic.wqe_com, command_type);
|
||||
bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче