mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 22:54:05 +08:00
scsi: lpfc: SLI path split: Refactor CT paths
This patch refactors the CT paths to use SLI-4 as the primary interface. - Introduce generic lpfc_sli_prep_gen_req jump table routine - Introduce generic lpfc_sli_prep_xmit_seq64 jump table routine - Rename lpfcdiag_loop_post_rxbufs to lpfcdiag_sli3_loop_post_rxbufs to indicate that it is an SLI3 only path - Create new prep_wqe routine for unsolicited ELS rsp WQEs. - Conversion away from using SLI-3 iocb structures to set/access fields in common routines. Use the new generic get/set routines that were added. This move changes code from indirect structure references to using local variables with the generic routines. - Refactor routines when setting non-generic fields, to have both SLI3 and SLI4 specific sections. This replaces the set-as-SLI3 then translate to SLI4 behavior of the past. Link: https://lore.kernel.org/r/20220225022308.16486-13-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:
parent
2d1928c57d
commit
61910d6a52
@ -968,6 +968,13 @@ struct lpfc_hba {
|
||||
struct lpfc_dmabuf *bmp,
|
||||
u16 cmd_size, u32 did, u32 elscmd,
|
||||
u8 tmo, u8 expect_rsp);
|
||||
void (*__lpfc_sli_prep_gen_req)(struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi,
|
||||
u32 num_entry, u8 tmo);
|
||||
void (*__lpfc_sli_prep_xmit_seq64)(struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi,
|
||||
u16 ox_id, u32 num_entry, u8 rctl,
|
||||
u8 last_seq, u8 cr_cx_cmd);
|
||||
|
||||
/* expedite pool */
|
||||
struct lpfc_epd_pool epd_pool;
|
||||
@ -1849,6 +1856,15 @@ u16 get_job_rcvoxid(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
|
||||
return iocbq->iocb.unsli3.rcvsli3.ox_id;
|
||||
}
|
||||
|
||||
static inline
|
||||
u32 get_job_data_placed(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
|
||||
{
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
return iocbq->wcqe_cmpl.total_data_placed;
|
||||
else
|
||||
return iocbq->iocb.un.genreq64.bdl.bdeSize;
|
||||
}
|
||||
|
||||
static inline
|
||||
u32 get_job_els_rsp64_did(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
|
||||
{
|
||||
|
@ -303,13 +303,12 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||
struct bsg_job_data *dd_data;
|
||||
struct bsg_job *job;
|
||||
struct fc_bsg_reply *bsg_reply;
|
||||
IOCB_t *rsp;
|
||||
struct lpfc_dmabuf *bmp, *cmp, *rmp;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
struct lpfc_bsg_iocb *iocb;
|
||||
unsigned long flags;
|
||||
unsigned int rsp_size;
|
||||
int rc = 0;
|
||||
u32 ulp_status, ulp_word4, total_data_placed;
|
||||
|
||||
dd_data = cmdiocbq->context1;
|
||||
|
||||
@ -333,14 +332,16 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||
rmp = iocb->rmp;
|
||||
cmp = cmdiocbq->context2;
|
||||
bmp = cmdiocbq->context3;
|
||||
rsp = &rspiocbq->iocb;
|
||||
ulp_status = get_job_ulpstatus(phba, rspiocbq);
|
||||
ulp_word4 = get_job_word4(phba, rspiocbq);
|
||||
total_data_placed = get_job_data_placed(phba, rspiocbq);
|
||||
|
||||
/* Copy the completed data or set the error status */
|
||||
|
||||
if (job) {
|
||||
if (rsp->ulpStatus) {
|
||||
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
|
||||
switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
|
||||
if (ulp_status) {
|
||||
if (ulp_status == IOSTAT_LOCAL_REJECT) {
|
||||
switch (ulp_word4 & IOERR_PARAM_MASK) {
|
||||
case IOERR_SEQUENCE_TIMEOUT:
|
||||
rc = -ETIMEDOUT;
|
||||
break;
|
||||
@ -355,10 +356,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||
rc = -EACCES;
|
||||
}
|
||||
} else {
|
||||
rsp_size = rsp->un.genreq64.bdl.bdeSize;
|
||||
bsg_reply->reply_payload_rcv_len =
|
||||
lpfc_bsg_copy_data(rmp, &job->reply_payload,
|
||||
rsp_size, 0);
|
||||
total_data_placed, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,22 +388,21 @@ static int
|
||||
lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
{
|
||||
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_rport_data *rdata = fc_bsg_to_rport(job)->dd_data;
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_nodelist *ndlp = rdata->pnode;
|
||||
struct fc_bsg_reply *bsg_reply = job->reply;
|
||||
struct ulp_bde64 *bpl = NULL;
|
||||
uint32_t timeout;
|
||||
struct lpfc_iocbq *cmdiocbq = NULL;
|
||||
IOCB_t *cmd;
|
||||
struct lpfc_dmabuf *bmp = NULL, *cmp = NULL, *rmp = NULL;
|
||||
int request_nseg;
|
||||
int reply_nseg;
|
||||
int request_nseg, reply_nseg;
|
||||
u32 num_entry;
|
||||
struct bsg_job_data *dd_data;
|
||||
unsigned long flags;
|
||||
uint32_t creg_val;
|
||||
int rc = 0;
|
||||
int iocb_stat;
|
||||
u16 ulp_context;
|
||||
|
||||
/* in case no data is transferred */
|
||||
bsg_reply->reply_payload_rcv_len = 0;
|
||||
@ -426,8 +425,6 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
goto free_dd;
|
||||
}
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
|
||||
bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
|
||||
if (!bmp) {
|
||||
rc = -ENOMEM;
|
||||
@ -461,29 +458,21 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
|
||||
goto free_cmp;
|
||||
}
|
||||
|
||||
cmd->un.genreq64.bdl.ulpIoTag32 = 0;
|
||||
cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
|
||||
cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
|
||||
cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
cmd->un.genreq64.bdl.bdeSize =
|
||||
(request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
|
||||
cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
|
||||
cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
|
||||
cmd->un.genreq64.w5.hcsw.Dfctl = 0;
|
||||
cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
|
||||
cmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
cmd->ulpBdeCount = 1;
|
||||
cmd->ulpLe = 1;
|
||||
cmd->ulpClass = CLASS3;
|
||||
cmd->ulpContext = ndlp->nlp_rpi;
|
||||
num_entry = request_nseg + reply_nseg;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
cmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
cmd->ulpOwner = OWN_CHIP;
|
||||
ulp_context = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
else
|
||||
ulp_context = ndlp->nlp_rpi;
|
||||
|
||||
lpfc_sli_prep_gen_req(phba, cmdiocbq, bmp, ulp_context, num_entry,
|
||||
phba->fc_ratov * 2);
|
||||
|
||||
cmdiocbq->num_bdes = num_entry;
|
||||
cmdiocbq->vport = phba->pport;
|
||||
cmdiocbq->context2 = cmp;
|
||||
cmdiocbq->context3 = bmp;
|
||||
cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
|
||||
timeout = phba->fc_ratov * 2;
|
||||
cmd->ulpTimeout = timeout;
|
||||
|
||||
cmdiocbq->cmd_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
|
||||
cmdiocbq->context1 = dd_data;
|
||||
@ -916,6 +905,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
struct lpfc_bsg_event *evt;
|
||||
struct event_data *evt_dat = NULL;
|
||||
struct lpfc_iocbq *iocbq;
|
||||
IOCB_t *iocb = NULL;
|
||||
size_t offset = 0;
|
||||
struct list_head head;
|
||||
struct ulp_bde64 *bde;
|
||||
@ -923,13 +913,13 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
int i;
|
||||
struct lpfc_dmabuf *bdeBuf1 = piocbq->context2;
|
||||
struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
|
||||
struct lpfc_hbq_entry *hbqe;
|
||||
struct lpfc_sli_ct_request *ct_req;
|
||||
struct bsg_job *job = NULL;
|
||||
struct fc_bsg_reply *bsg_reply;
|
||||
struct bsg_job_data *dd_data = NULL;
|
||||
unsigned long flags;
|
||||
int size = 0;
|
||||
u32 bde_count = 0;
|
||||
|
||||
INIT_LIST_HEAD(&head);
|
||||
list_add_tail(&head, &piocbq->list);
|
||||
@ -959,12 +949,17 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
/* take accumulated byte count from the last iocbq */
|
||||
iocbq = list_entry(head.prev, typeof(*iocbq), list);
|
||||
evt_dat->len = iocbq->iocb.unsli3.rcvsli3.acc_len;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
evt_dat->len = iocbq->wcqe_cmpl.total_data_placed;
|
||||
else
|
||||
evt_dat->len = iocbq->iocb.unsli3.rcvsli3.acc_len;
|
||||
} else {
|
||||
list_for_each_entry(iocbq, &head, list) {
|
||||
for (i = 0; i < iocbq->iocb.ulpBdeCount; i++)
|
||||
iocb = &iocbq->iocb;
|
||||
for (i = 0; i < iocb->ulpBdeCount;
|
||||
i++)
|
||||
evt_dat->len +=
|
||||
iocbq->iocb.un.cont64[i].tus.f.bdeSize;
|
||||
iocb->un.cont64[i].tus.f.bdeSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -986,20 +981,20 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
bdeBuf1 = iocbq->context2;
|
||||
bdeBuf2 = iocbq->context3;
|
||||
|
||||
}
|
||||
for (i = 0; i < iocbq->iocb.ulpBdeCount; i++) {
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
bde_count = iocbq->wcqe_cmpl.word3;
|
||||
else
|
||||
bde_count = iocbq->iocb.ulpBdeCount;
|
||||
for (i = 0; i < bde_count; i++) {
|
||||
if (phba->sli3_options &
|
||||
LPFC_SLI3_HBQ_ENABLED) {
|
||||
if (i == 0) {
|
||||
hbqe = (struct lpfc_hbq_entry *)
|
||||
&iocbq->iocb.un.ulpWord[0];
|
||||
size = hbqe->bde.tus.f.bdeSize;
|
||||
size = iocbq->wqe.gen_req.bde.tus.f.bdeSize;
|
||||
dmabuf = bdeBuf1;
|
||||
} else if (i == 1) {
|
||||
hbqe = (struct lpfc_hbq_entry *)
|
||||
&iocbq->iocb.unsli3.
|
||||
sli3Words[4];
|
||||
size = hbqe->bde.tus.f.bdeSize;
|
||||
size = iocbq->unsol_rcv_len;
|
||||
dmabuf = bdeBuf2;
|
||||
}
|
||||
if ((offset + size) > evt_dat->len)
|
||||
@ -1054,16 +1049,16 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
dmabuf);
|
||||
} else {
|
||||
lpfc_sli3_post_buffer(phba,
|
||||
pring,
|
||||
1);
|
||||
pring,
|
||||
1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!(phba->sli3_options &
|
||||
LPFC_SLI3_HBQ_ENABLED))
|
||||
lpfc_sli3_post_buffer(phba,
|
||||
pring,
|
||||
1);
|
||||
pring,
|
||||
1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1086,14 +1081,15 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
phba->ct_ctx[
|
||||
evt_dat->immed_dat].SID);
|
||||
phba->ct_ctx[evt_dat->immed_dat].rxid =
|
||||
piocbq->iocb.ulpContext;
|
||||
get_job_ulpcontext(phba, piocbq);
|
||||
phba->ct_ctx[evt_dat->immed_dat].oxid =
|
||||
piocbq->iocb.unsli3.rcvsli3.ox_id;
|
||||
get_job_rcvoxid(phba, piocbq);
|
||||
phba->ct_ctx[evt_dat->immed_dat].SID =
|
||||
piocbq->iocb.un.rcvels.remoteID;
|
||||
bf_get(wqe_els_did,
|
||||
&piocbq->wqe.xmit_els_rsp.wqe_dest);
|
||||
phba->ct_ctx[evt_dat->immed_dat].valid = UNSOL_VALID;
|
||||
} else
|
||||
evt_dat->immed_dat = piocbq->iocb.ulpContext;
|
||||
evt_dat->immed_dat = get_job_ulpcontext(phba, piocbq);
|
||||
|
||||
evt_dat->type = FC_REG_CT_EVENT;
|
||||
list_add(&evt_dat->node, &evt->events_to_see);
|
||||
@ -1459,13 +1455,13 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
|
||||
struct lpfc_dmabuf *cmp, struct lpfc_dmabuf *bmp,
|
||||
int num_entry)
|
||||
{
|
||||
IOCB_t *icmd;
|
||||
struct lpfc_iocbq *ctiocb = NULL;
|
||||
int rc = 0;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
struct bsg_job_data *dd_data;
|
||||
unsigned long flags;
|
||||
uint32_t creg_val;
|
||||
u16 ulp_context, iotag;
|
||||
|
||||
ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
|
||||
if (!ndlp) {
|
||||
@ -1492,62 +1488,36 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
|
||||
goto no_ctiocb;
|
||||
}
|
||||
|
||||
icmd = &ctiocb->iocb;
|
||||
icmd->un.xseq64.bdl.ulpIoTag32 = 0;
|
||||
icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
|
||||
icmd->un.xseq64.bdl.addrLow = putPaddrLow(bmp->phys);
|
||||
icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
icmd->un.xseq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
|
||||
icmd->un.xseq64.w5.hcsw.Fctl = (LS | LA);
|
||||
icmd->un.xseq64.w5.hcsw.Dfctl = 0;
|
||||
icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_SOL_CTL;
|
||||
icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
|
||||
/* Fill in rest of iocb */
|
||||
icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
|
||||
icmd->ulpBdeCount = 1;
|
||||
icmd->ulpLe = 1;
|
||||
icmd->ulpClass = CLASS3;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
/* Do not issue unsol response if oxid not marked as valid */
|
||||
if (phba->ct_ctx[tag].valid != UNSOL_VALID) {
|
||||
rc = IOCB_ERROR;
|
||||
goto issue_ct_rsp_exit;
|
||||
}
|
||||
icmd->ulpContext = phba->ct_ctx[tag].rxid;
|
||||
icmd->unsli3.rcvsli3.ox_id = phba->ct_ctx[tag].oxid;
|
||||
ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
|
||||
if (!ndlp) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
|
||||
"2721 ndlp null for oxid %x SID %x\n",
|
||||
icmd->ulpContext,
|
||||
phba->ct_ctx[tag].SID);
|
||||
rc = IOCB_ERROR;
|
||||
goto issue_ct_rsp_exit;
|
||||
}
|
||||
|
||||
/* get a refernece count so the ndlp doesn't go away while
|
||||
* we respond
|
||||
*/
|
||||
if (!lpfc_nlp_get(ndlp)) {
|
||||
rc = IOCB_ERROR;
|
||||
goto issue_ct_rsp_exit;
|
||||
}
|
||||
|
||||
icmd->un.ulpWord[3] =
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
lpfc_sli_prep_xmit_seq64(phba, ctiocb, bmp,
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi],
|
||||
phba->ct_ctx[tag].oxid, num_entry,
|
||||
FC_RCTL_DD_SOL_CTL, 1,
|
||||
CMD_XMIT_SEQUENCE64_WQE);
|
||||
|
||||
/* The exchange is done, mark the entry as invalid */
|
||||
phba->ct_ctx[tag].valid = UNSOL_INVALID;
|
||||
} else
|
||||
icmd->ulpContext = (ushort) tag;
|
||||
iotag = get_wqe_reqtag(ctiocb);
|
||||
} else {
|
||||
lpfc_sli_prep_xmit_seq64(phba, ctiocb, bmp, 0, tag, num_entry,
|
||||
FC_RCTL_DD_SOL_CTL, 1,
|
||||
CMD_XMIT_SEQUENCE64_CX);
|
||||
ctiocb->num_bdes = num_entry;
|
||||
iotag = ctiocb->iocb.ulpIoTag;
|
||||
}
|
||||
|
||||
icmd->ulpTimeout = phba->fc_ratov * 2;
|
||||
ulp_context = get_job_ulpcontext(phba, ctiocb);
|
||||
|
||||
/* Xmit CT response on exchange <xid> */
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n",
|
||||
icmd->ulpContext, icmd->ulpIoTag, tag, phba->link_state);
|
||||
"2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n",
|
||||
ulp_context, iotag, tag, phba->link_state);
|
||||
|
||||
ctiocb->cmd_flag |= LPFC_IO_LIBDFC;
|
||||
ctiocb->vport = phba->pport;
|
||||
@ -2633,7 +2603,6 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
|
||||
{
|
||||
struct lpfc_bsg_event *evt;
|
||||
struct lpfc_iocbq *cmdiocbq, *rspiocbq;
|
||||
IOCB_t *cmd, *rsp;
|
||||
struct lpfc_dmabuf *dmabuf;
|
||||
struct ulp_bde64 *bpl = NULL;
|
||||
struct lpfc_sli_ct_request *ctreq = NULL;
|
||||
@ -2641,6 +2610,7 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
|
||||
int time_left;
|
||||
int iocb_stat = IOCB_SUCCESS;
|
||||
unsigned long flags;
|
||||
u32 status;
|
||||
|
||||
*txxri = 0;
|
||||
*rxxri = 0;
|
||||
@ -2684,9 +2654,6 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
|
||||
goto err_get_xri_exit;
|
||||
}
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
rsp = &rspiocbq->iocb;
|
||||
|
||||
memset(ctreq, 0, ELX_LOOPBACK_HEADER_SZ);
|
||||
|
||||
ctreq->RevisionId.bits.Revision = SLI_CT_REVISION;
|
||||
@ -2696,36 +2663,24 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
|
||||
ctreq->CommandResponse.bits.CmdRsp = ELX_LOOPBACK_XRI_SETUP;
|
||||
ctreq->CommandResponse.bits.Size = 0;
|
||||
|
||||
|
||||
cmd->un.xseq64.bdl.addrHigh = putPaddrHigh(dmabuf->phys);
|
||||
cmd->un.xseq64.bdl.addrLow = putPaddrLow(dmabuf->phys);
|
||||
cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
cmd->un.xseq64.bdl.bdeSize = sizeof(*bpl);
|
||||
|
||||
cmd->un.xseq64.w5.hcsw.Fctl = LA;
|
||||
cmd->un.xseq64.w5.hcsw.Dfctl = 0;
|
||||
cmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
|
||||
cmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
|
||||
cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CR;
|
||||
cmd->ulpBdeCount = 1;
|
||||
cmd->ulpLe = 1;
|
||||
cmd->ulpClass = CLASS3;
|
||||
cmd->ulpContext = rpi;
|
||||
|
||||
cmdiocbq->context3 = dmabuf;
|
||||
cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
|
||||
cmdiocbq->vport = phba->pport;
|
||||
cmdiocbq->cmd_cmpl = NULL;
|
||||
|
||||
lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, dmabuf, rpi, 0, 1,
|
||||
FC_RCTL_DD_SOL_CTL, 0, CMD_XMIT_SEQUENCE64_CR);
|
||||
|
||||
iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
|
||||
rspiocbq,
|
||||
(phba->fc_ratov * 2)
|
||||
+ LPFC_DRVR_TIMEOUT);
|
||||
if ((iocb_stat != IOCB_SUCCESS) || (rsp->ulpStatus != IOSTAT_SUCCESS)) {
|
||||
rspiocbq, (phba->fc_ratov * 2)
|
||||
+ LPFC_DRVR_TIMEOUT);
|
||||
|
||||
status = get_job_ulpstatus(phba, rspiocbq);
|
||||
if (iocb_stat != IOCB_SUCCESS || status != IOCB_SUCCESS) {
|
||||
ret_val = -EIO;
|
||||
goto err_get_xri_exit;
|
||||
}
|
||||
*txxri = rsp->ulpContext;
|
||||
*txxri = get_job_ulpcontext(phba, rspiocbq);
|
||||
|
||||
evt->waiting = 1;
|
||||
evt->wait_time_stamp = jiffies;
|
||||
@ -2926,7 +2881,7 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfcdiag_loop_post_rxbufs - post the receive buffers for an unsol CT cmd
|
||||
* lpfcdiag_sli3_loop_post_rxbufs - post the receive buffers for an unsol CT cmd
|
||||
* @phba: Pointer to HBA context object
|
||||
* @rxxri: Receive exchange id
|
||||
* @len: Number of data bytes
|
||||
@ -2934,8 +2889,8 @@ out:
|
||||
* This function allocates and posts a data buffer of sufficient size to receive
|
||||
* an unsolicted CT command.
|
||||
**/
|
||||
static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
|
||||
size_t len)
|
||||
static int lpfcdiag_sli3_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
|
||||
size_t len)
|
||||
{
|
||||
struct lpfc_sli_ring *pring;
|
||||
struct lpfc_iocbq *cmdiocbq;
|
||||
@ -2972,7 +2927,6 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
|
||||
/* Queue buffers for the receive exchange */
|
||||
num_bde = (uint32_t)rxbuffer->flag;
|
||||
dmp = &rxbuffer->dma;
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
i = 0;
|
||||
|
||||
@ -3040,7 +2994,6 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
|
||||
ret_val = -EIO;
|
||||
goto err_post_rxbufs_exit;
|
||||
}
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
i = 0;
|
||||
}
|
||||
@ -3092,7 +3045,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
|
||||
size_t segment_len = 0, segment_offset = 0, current_offset = 0;
|
||||
uint16_t rpi = 0;
|
||||
struct lpfc_iocbq *cmdiocbq, *rspiocbq = NULL;
|
||||
IOCB_t *cmd, *rsp = NULL;
|
||||
union lpfc_wqe128 *cmdwqe, *rspwqe;
|
||||
struct lpfc_sli_ct_request *ctreq;
|
||||
struct lpfc_dmabuf *txbmp;
|
||||
struct ulp_bde64 *txbpl = NULL;
|
||||
@ -3185,7 +3138,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
|
||||
goto loopback_test_exit;
|
||||
}
|
||||
|
||||
rc = lpfcdiag_loop_post_rxbufs(phba, rxxri, full_size);
|
||||
rc = lpfcdiag_sli3_loop_post_rxbufs(phba, rxxri, full_size);
|
||||
if (rc) {
|
||||
lpfcdiag_loop_self_unreg(phba, rpi);
|
||||
goto loopback_test_exit;
|
||||
@ -3228,9 +3181,12 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
|
||||
goto err_loopback_test_exit;
|
||||
}
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
rsp = &rspiocbq->iocb;
|
||||
cmdwqe = &cmdiocbq->wqe;
|
||||
memset(cmdwqe, 0, sizeof(union lpfc_wqe));
|
||||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
rspwqe = &rspiocbq->wqe;
|
||||
memset(rspwqe, 0, sizeof(union lpfc_wqe));
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&head);
|
||||
list_add_tail(&head, &txbuffer->dma.list);
|
||||
@ -3262,42 +3218,32 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
|
||||
/* Build the XMIT_SEQUENCE iocb */
|
||||
num_bde = (uint32_t)txbuffer->flag;
|
||||
|
||||
cmd->un.xseq64.bdl.addrHigh = putPaddrHigh(txbmp->phys);
|
||||
cmd->un.xseq64.bdl.addrLow = putPaddrLow(txbmp->phys);
|
||||
cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
cmd->un.xseq64.bdl.bdeSize = (num_bde * sizeof(struct ulp_bde64));
|
||||
|
||||
cmd->un.xseq64.w5.hcsw.Fctl = (LS | LA);
|
||||
cmd->un.xseq64.w5.hcsw.Dfctl = 0;
|
||||
cmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
|
||||
cmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
|
||||
cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
|
||||
cmd->ulpBdeCount = 1;
|
||||
cmd->ulpLe = 1;
|
||||
cmd->ulpClass = CLASS3;
|
||||
|
||||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
cmd->ulpContext = txxri;
|
||||
} else {
|
||||
cmd->un.xseq64.bdl.ulpIoTag32 = 0;
|
||||
cmd->un.ulpWord[3] = phba->sli4_hba.rpi_ids[rpi];
|
||||
cmdiocbq->context3 = txbmp;
|
||||
cmdiocbq->sli4_xritag = NO_XRI;
|
||||
cmd->unsli3.rcvsli3.ox_id = 0xffff;
|
||||
}
|
||||
cmdiocbq->num_bdes = num_bde;
|
||||
cmdiocbq->cmd_flag |= LPFC_IO_LIBDFC;
|
||||
cmdiocbq->cmd_flag |= LPFC_IO_LOOPBACK;
|
||||
cmdiocbq->vport = phba->pport;
|
||||
cmdiocbq->cmd_cmpl = NULL;
|
||||
cmdiocbq->context3 = txbmp;
|
||||
|
||||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, txbmp, 0, txxri,
|
||||
num_bde, FC_RCTL_DD_UNSOL_CTL, 1,
|
||||
CMD_XMIT_SEQUENCE64_CX);
|
||||
|
||||
} else {
|
||||
lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, txbmp,
|
||||
phba->sli4_hba.rpi_ids[rpi], 0xffff,
|
||||
full_size, FC_RCTL_DD_UNSOL_CTL, 1,
|
||||
CMD_XMIT_SEQUENCE64_WQE);
|
||||
cmdiocbq->sli4_xritag = NO_XRI;
|
||||
}
|
||||
|
||||
iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
|
||||
rspiocbq, (phba->fc_ratov * 2) +
|
||||
LPFC_DRVR_TIMEOUT);
|
||||
|
||||
if ((iocb_stat != IOCB_SUCCESS) ||
|
||||
((phba->sli_rev < LPFC_SLI_REV4) &&
|
||||
(rsp->ulpStatus != IOSTAT_SUCCESS))) {
|
||||
if (iocb_stat != IOCB_SUCCESS ||
|
||||
(phba->sli_rev < LPFC_SLI_REV4 &&
|
||||
(get_job_ulpstatus(phba, rspiocbq) != IOSTAT_SUCCESS))) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
|
||||
"3126 Failed loopback test issue iocb: "
|
||||
"iocb_stat:x%x\n", iocb_stat);
|
||||
|
@ -358,6 +358,14 @@ void lpfc_sli_prep_els_req_rsp(struct lpfc_hba *phba,
|
||||
struct lpfc_vport *vport,
|
||||
struct lpfc_dmabuf *bmp, u16 cmd_size, u32 did,
|
||||
u32 elscmd, u8 tmo, u8 expect_rsp);
|
||||
void lpfc_sli_prep_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi, u32 num_entry,
|
||||
u8 tmo);
|
||||
void lpfc_sli_prep_xmit_seq64(struct lpfc_hba *phba,
|
||||
struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
|
||||
u32 num_entry, u8 rctl, u8 last_seq,
|
||||
u8 cr_cx_cmd);
|
||||
struct lpfc_sglq *__lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xri);
|
||||
struct lpfc_sglq *__lpfc_sli_get_nvmet_sglq(struct lpfc_hba *phba,
|
||||
struct lpfc_iocbq *piocbq);
|
||||
|
@ -87,12 +87,12 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"0146 Ignoring unsolicited CT No HBQ "
|
||||
"status = x%x\n",
|
||||
piocbq->iocb.ulpStatus);
|
||||
get_job_ulpstatus(phba, piocbq));
|
||||
}
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"0145 Ignoring unsolicted CT HBQ Size:%d "
|
||||
"status = x%x\n",
|
||||
size, piocbq->iocb.ulpStatus);
|
||||
size, get_job_ulpstatus(phba, piocbq));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -143,7 +143,7 @@ lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
* lpfc_ct_reject_event - Issue reject for unhandled CT MIB commands
|
||||
* @ndlp: pointer to a node-list data structure.
|
||||
* @ct_req: pointer to the CT request data structure.
|
||||
* @rx_id: rx_id of the received UNSOL CT command
|
||||
* @ulp_context: context of received UNSOL CT command
|
||||
* @ox_id: ox_id of the UNSOL CT command
|
||||
*
|
||||
* This routine is invoked by the lpfc_ct_handle_mibreq routine for sending
|
||||
@ -152,7 +152,7 @@ lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
static void
|
||||
lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
|
||||
struct lpfc_sli_ct_request *ct_req,
|
||||
u16 rx_id, u16 ox_id)
|
||||
u16 ulp_context, u16 ox_id)
|
||||
{
|
||||
struct lpfc_vport *vport = ndlp->vport;
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
@ -161,8 +161,8 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
|
||||
struct lpfc_dmabuf *bmp = NULL;
|
||||
struct lpfc_dmabuf *mp = NULL;
|
||||
struct ulp_bde64 *bpl;
|
||||
IOCB_t *icmd;
|
||||
u8 rc = 0;
|
||||
u32 tmo;
|
||||
|
||||
/* fill in BDEs for command */
|
||||
mp = kmalloc(sizeof(*mp), GFP_KERNEL);
|
||||
@ -220,43 +220,41 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
|
||||
goto ct_free_bmpvirt;
|
||||
}
|
||||
|
||||
icmd = &cmdiocbq->iocb;
|
||||
icmd->un.genreq64.bdl.ulpIoTag32 = 0;
|
||||
icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
|
||||
icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
|
||||
icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
icmd->un.genreq64.bdl.bdeSize = sizeof(struct ulp_bde64);
|
||||
icmd->un.genreq64.w5.hcsw.Fctl = (LS | LA);
|
||||
icmd->un.genreq64.w5.hcsw.Dfctl = 0;
|
||||
icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_SOL_CTL;
|
||||
icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
|
||||
icmd->ulpBdeCount = 1;
|
||||
icmd->ulpLe = 1;
|
||||
icmd->ulpClass = CLASS3;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, bmp,
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi],
|
||||
ox_id, 1, FC_RCTL_DD_SOL_CTL, 1,
|
||||
CMD_XMIT_SEQUENCE64_WQE);
|
||||
} else {
|
||||
lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, bmp, 0, ulp_context, 1,
|
||||
FC_RCTL_DD_SOL_CTL, 1,
|
||||
CMD_XMIT_SEQUENCE64_CX);
|
||||
}
|
||||
|
||||
/* Save for completion so we can release these resources */
|
||||
cmdiocbq->context1 = lpfc_nlp_get(ndlp);
|
||||
cmdiocbq->context2 = (uint8_t *)mp;
|
||||
cmdiocbq->context3 = (uint8_t *)bmp;
|
||||
cmdiocbq->cmd_cmpl = lpfc_ct_unsol_cmpl;
|
||||
icmd->ulpContext = rx_id; /* Xri / rx_id */
|
||||
icmd->unsli3.rcvsli3.ox_id = ox_id;
|
||||
icmd->un.ulpWord[3] =
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
icmd->ulpTimeout = (3 * phba->fc_ratov);
|
||||
tmo = (3 * phba->fc_ratov);
|
||||
|
||||
cmdiocbq->retry = 0;
|
||||
cmdiocbq->vport = vport;
|
||||
cmdiocbq->context_un.ndlp = NULL;
|
||||
cmdiocbq->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
|
||||
cmdiocbq->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT;
|
||||
|
||||
cmdiocbq->context1 = lpfc_nlp_get(ndlp);
|
||||
if (!cmdiocbq->context1)
|
||||
goto ct_no_ndlp;
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
|
||||
if (!rc)
|
||||
return;
|
||||
if (rc) {
|
||||
lpfc_nlp_put(ndlp);
|
||||
goto ct_no_ndlp;
|
||||
}
|
||||
return;
|
||||
|
||||
ct_no_ndlp:
|
||||
rc = 6;
|
||||
lpfc_nlp_put(ndlp);
|
||||
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||
ct_free_bmpvirt:
|
||||
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
||||
@ -286,25 +284,17 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)
|
||||
{
|
||||
struct lpfc_sli_ct_request *ct_req;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
struct lpfc_vport *vport = NULL;
|
||||
IOCB_t *icmd = &ctiocbq->iocb;
|
||||
u32 mi_cmd, vpi;
|
||||
u32 did = 0;
|
||||
struct lpfc_vport *vport = ctiocbq->vport;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, ctiocbq);
|
||||
u32 ulp_word4 = get_job_word4(phba, ctiocbq);
|
||||
u32 did;
|
||||
u32 mi_cmd;
|
||||
|
||||
vpi = ctiocbq->iocb.unsli3.rcvsli3.vpi;
|
||||
vport = lpfc_find_vport_by_vpid(phba, vpi);
|
||||
if (!vport) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"6437 Unsol CT: VPORT NULL vpi : x%x\n",
|
||||
vpi);
|
||||
return;
|
||||
}
|
||||
|
||||
did = ctiocbq->iocb.un.rcvels.remoteID;
|
||||
if (icmd->ulpStatus) {
|
||||
did = bf_get(els_rsp64_sid, &ctiocbq->wqe.xmit_els_rsp);
|
||||
if (ulp_status) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"6438 Unsol CT: status:x%x/x%x did : x%x\n",
|
||||
icmd->ulpStatus, icmd->un.ulpWord[4], did);
|
||||
ulp_status, ulp_word4, did);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -322,13 +312,14 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)
|
||||
|
||||
ct_req = ((struct lpfc_sli_ct_request *)
|
||||
(((struct lpfc_dmabuf *)ctiocbq->context2)->virt));
|
||||
|
||||
mi_cmd = ct_req->CommandResponse.bits.CmdRsp;
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"6442 : MI Cmd : x%x Not Supported\n", mi_cmd);
|
||||
lpfc_ct_reject_event(ndlp, ct_req,
|
||||
ctiocbq->iocb.ulpContext,
|
||||
ctiocbq->iocb.unsli3.rcvsli3.ox_id);
|
||||
bf_get(wqe_ctxt_tag,
|
||||
&ctiocbq->wqe.xmit_els_rsp.wqe_com),
|
||||
bf_get(wqe_rcvoxid,
|
||||
&ctiocbq->wqe.xmit_els_rsp.wqe_com));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,21 +342,32 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
IOCB_t *icmd = &ctiocbq->iocb;
|
||||
int i;
|
||||
struct lpfc_iocbq *iocbq;
|
||||
struct lpfc_iocbq *iocb;
|
||||
dma_addr_t dma_addr;
|
||||
uint32_t size;
|
||||
struct list_head head;
|
||||
struct lpfc_sli_ct_request *ct_req;
|
||||
struct lpfc_dmabuf *bdeBuf1 = ctiocbq->context2;
|
||||
struct lpfc_dmabuf *bdeBuf2 = ctiocbq->context3;
|
||||
u32 status, parameter, bde_count = 0;
|
||||
struct lpfc_wcqe_complete *wcqe_cmpl = NULL;
|
||||
|
||||
ctiocbq->context1 = NULL;
|
||||
ctiocbq->context2 = NULL;
|
||||
ctiocbq->context3 = NULL;
|
||||
|
||||
if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
|
||||
wcqe_cmpl = &ctiocbq->wcqe_cmpl;
|
||||
status = get_job_ulpstatus(phba, ctiocbq);
|
||||
parameter = get_job_word4(phba, ctiocbq);
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
bde_count = wcqe_cmpl->word3;
|
||||
else
|
||||
bde_count = icmd->ulpBdeCount;
|
||||
|
||||
if (unlikely(status == IOSTAT_NEED_BUFFER)) {
|
||||
lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
|
||||
} else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
|
||||
((icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
|
||||
} else if ((status == IOSTAT_LOCAL_REJECT) &&
|
||||
((parameter & IOERR_PARAM_MASK) ==
|
||||
IOERR_RCV_BUFFER_WAITING)) {
|
||||
/* Not enough posted buffers; Try posting more buffers */
|
||||
phba->fc_stat.NoRcvBuf++;
|
||||
@ -377,26 +379,12 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
/* If there are no BDEs associated
|
||||
* with this IOCB, there is nothing to do.
|
||||
*/
|
||||
if (icmd->ulpBdeCount == 0)
|
||||
if (bde_count == 0)
|
||||
return;
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
ctiocbq->context2 = bdeBuf1;
|
||||
if (icmd->ulpBdeCount == 2)
|
||||
ctiocbq->context3 = bdeBuf2;
|
||||
} else {
|
||||
dma_addr = getPaddr(icmd->un.cont64[0].addrHigh,
|
||||
icmd->un.cont64[0].addrLow);
|
||||
ctiocbq->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
|
||||
dma_addr);
|
||||
if (icmd->ulpBdeCount == 2) {
|
||||
dma_addr = getPaddr(icmd->un.cont64[1].addrHigh,
|
||||
icmd->un.cont64[1].addrLow);
|
||||
ctiocbq->context3 = lpfc_sli_ringpostbuf_get(phba,
|
||||
pring,
|
||||
dma_addr);
|
||||
}
|
||||
}
|
||||
ctiocbq->context2 = bdeBuf1;
|
||||
if (bde_count == 2)
|
||||
ctiocbq->context3 = bdeBuf2;
|
||||
|
||||
ct_req = ((struct lpfc_sli_ct_request *)
|
||||
(((struct lpfc_dmabuf *)ctiocbq->context2)->virt));
|
||||
@ -412,19 +400,29 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
INIT_LIST_HEAD(&head);
|
||||
list_add_tail(&head, &ctiocbq->list);
|
||||
list_for_each_entry(iocbq, &head, list) {
|
||||
icmd = &iocbq->iocb;
|
||||
if (icmd->ulpBdeCount == 0)
|
||||
list_for_each_entry(iocb, &head, list) {
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
bde_count = iocb->wcqe_cmpl.word3;
|
||||
else
|
||||
bde_count = iocb->iocb.ulpBdeCount;
|
||||
|
||||
if (!bde_count)
|
||||
continue;
|
||||
bdeBuf1 = iocbq->context2;
|
||||
iocbq->context2 = NULL;
|
||||
size = icmd->un.cont64[0].tus.f.bdeSize;
|
||||
bdeBuf1 = iocb->context2;
|
||||
iocb->context2 = NULL;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
size = iocb->wqe.gen_req.bde.tus.f.bdeSize;
|
||||
else
|
||||
size = iocb->iocb.un.cont64[0].tus.f.bdeSize;
|
||||
lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf1, size);
|
||||
lpfc_in_buf_free(phba, bdeBuf1);
|
||||
if (icmd->ulpBdeCount == 2) {
|
||||
bdeBuf2 = iocbq->context3;
|
||||
iocbq->context3 = NULL;
|
||||
size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
|
||||
if (bde_count == 2) {
|
||||
bdeBuf2 = iocb->context3;
|
||||
iocb->context3 = NULL;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
size = iocb->unsol_rcv_len;
|
||||
else
|
||||
size = iocb->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize;
|
||||
lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf2,
|
||||
size);
|
||||
lpfc_in_buf_free(phba, bdeBuf2);
|
||||
@ -588,15 +586,15 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
|
||||
static int
|
||||
lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
|
||||
void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
|
||||
struct lpfc_iocbq *),
|
||||
void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
|
||||
struct lpfc_iocbq *),
|
||||
struct lpfc_nodelist *ndlp, uint32_t event_tag, uint32_t num_entry,
|
||||
uint32_t tmo, uint8_t retry)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
IOCB_t *icmd;
|
||||
struct lpfc_iocbq *geniocb;
|
||||
int rc;
|
||||
u16 ulp_context;
|
||||
|
||||
/* Allocate buffer for command iocb */
|
||||
geniocb = lpfc_sli_get_iocbq(phba);
|
||||
@ -604,12 +602,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
if (geniocb == NULL)
|
||||
return 1;
|
||||
|
||||
icmd = &geniocb->iocb;
|
||||
icmd->un.genreq64.bdl.ulpIoTag32 = 0;
|
||||
icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
|
||||
icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
|
||||
icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
|
||||
/* Update the num_entry bde count */
|
||||
geniocb->num_bdes = num_entry;
|
||||
|
||||
geniocb->context3 = (uint8_t *) bmp;
|
||||
|
||||
@ -619,41 +613,26 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
|
||||
geniocb->event_tag = event_tag;
|
||||
|
||||
/* Fill in payload, bp points to frame payload */
|
||||
icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
|
||||
|
||||
/* Fill in rest of iocb */
|
||||
icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
|
||||
icmd->un.genreq64.w5.hcsw.Dfctl = 0;
|
||||
icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
|
||||
icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
|
||||
if (!tmo) {
|
||||
/* FC spec states we need 3 * ratov for CT requests */
|
||||
tmo = (3 * phba->fc_ratov);
|
||||
}
|
||||
icmd->ulpTimeout = tmo;
|
||||
icmd->ulpBdeCount = 1;
|
||||
icmd->ulpLe = 1;
|
||||
icmd->ulpClass = CLASS3;
|
||||
icmd->ulpContext = ndlp->nlp_rpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
|
||||
/* For GEN_REQUEST64_CR, use the RPI */
|
||||
icmd->ulpCt_h = 0;
|
||||
icmd->ulpCt_l = 0;
|
||||
}
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
ulp_context = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
else
|
||||
ulp_context = ndlp->nlp_rpi;
|
||||
|
||||
lpfc_sli_prep_gen_req(phba, geniocb, bmp, ulp_context, num_entry, tmo);
|
||||
|
||||
/* Issue GEN REQ IOCB for NPORT <did> */
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"0119 Issue GEN REQ IOCB to NPORT x%x "
|
||||
"Data: x%x x%x\n",
|
||||
ndlp->nlp_DID, icmd->ulpIoTag,
|
||||
ndlp->nlp_DID, geniocb->iotag,
|
||||
vport->port_state);
|
||||
geniocb->cmd_cmpl = cmpl;
|
||||
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
|
||||
geniocb->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT;
|
||||
geniocb->vport = vport;
|
||||
geniocb->retry = retry;
|
||||
geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
|
||||
@ -661,9 +640,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
goto out;
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
|
||||
|
||||
if (rc == IOCB_ERROR) {
|
||||
geniocb->context_un.ndlp = NULL;
|
||||
lpfc_nlp_put(ndlp);
|
||||
goto out;
|
||||
}
|
||||
@ -939,12 +916,13 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
{
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
IOCB_t *irsp;
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_dmabuf *inp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
struct lpfc_sli_ct_request *CTreq;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
u32 ulp_word4 = get_job_word4(phba, rspiocb);
|
||||
int rc, type;
|
||||
|
||||
/* First save ndlp, before we overwrite it */
|
||||
@ -952,13 +930,13 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
|
||||
/* we pass cmdiocb to state machine which needs rspiocb as well */
|
||||
cmdiocb->context_un.rsp_iocb = rspiocb;
|
||||
|
||||
inp = (struct lpfc_dmabuf *) cmdiocb->context1;
|
||||
outp = (struct lpfc_dmabuf *) cmdiocb->context2;
|
||||
irsp = &rspiocb->iocb;
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
|
||||
"GID_FT cmpl: status:x%x/x%x rtry:%d",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
|
||||
ulp_status, ulp_word4, vport->fc_ns_retry);
|
||||
|
||||
/* Ignore response if link flipped after this request was made */
|
||||
if (cmdiocb->event_tag != phba->fc_eventTag) {
|
||||
@ -982,7 +960,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
goto out;
|
||||
}
|
||||
if (lpfc_error_lost_link(irsp->ulpStatus, irsp->un.ulpWord[4])) {
|
||||
if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0226 NS query failed due to link event\n");
|
||||
if (vport->fc_flag & FC_RSCN_MODE)
|
||||
@ -1014,11 +992,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
}
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
if (irsp->ulpStatus) {
|
||||
if (ulp_status) {
|
||||
/* Check for retry */
|
||||
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
|
||||
if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
|
||||
(irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
|
||||
if (ulp_status != IOSTAT_LOCAL_REJECT ||
|
||||
(ulp_word4 & IOERR_PARAM_MASK) !=
|
||||
IOERR_NO_RESOURCES)
|
||||
vport->fc_ns_retry++;
|
||||
|
||||
@ -1041,7 +1019,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0257 GID_FT Query error: 0x%x 0x%x\n",
|
||||
irsp->ulpStatus, vport->fc_ns_retry);
|
||||
ulp_status, vport->fc_ns_retry);
|
||||
} else {
|
||||
/* Good status, continue checking */
|
||||
CTreq = (struct lpfc_sli_ct_request *) inp->virt;
|
||||
@ -1055,12 +1033,12 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
CTreq->un.gid.Fc4Type,
|
||||
vport->num_disc_nodes,
|
||||
vport->gidft_inp,
|
||||
irsp->un.genreq64.bdl.bdeSize);
|
||||
get_job_data_placed(phba, rspiocb));
|
||||
|
||||
lpfc_ns_rsp(vport,
|
||||
outp,
|
||||
CTreq->un.gid.Fc4Type,
|
||||
(uint32_t) (irsp->un.genreq64.bdl.bdeSize));
|
||||
get_job_data_placed(phba, rspiocb));
|
||||
} else if (CTrsp->CommandResponse.bits.CmdRsp ==
|
||||
be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
|
||||
/* NameServer Rsp Error */
|
||||
@ -1155,12 +1133,13 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
{
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
IOCB_t *irsp;
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_dmabuf *inp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
struct lpfc_sli_ct_request *CTreq;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
u32 ulp_word4 = get_job_word4(phba, rspiocb);
|
||||
int rc;
|
||||
|
||||
/* First save ndlp, before we overwrite it */
|
||||
@ -1170,11 +1149,10 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
cmdiocb->context_un.rsp_iocb = rspiocb;
|
||||
inp = (struct lpfc_dmabuf *)cmdiocb->context1;
|
||||
outp = (struct lpfc_dmabuf *)cmdiocb->context2;
|
||||
irsp = &rspiocb->iocb;
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
|
||||
"GID_PT cmpl: status:x%x/x%x rtry:%d",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4],
|
||||
ulp_status, ulp_word4,
|
||||
vport->fc_ns_retry);
|
||||
|
||||
/* Ignore response if link flipped after this request was made */
|
||||
@ -1199,7 +1177,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
goto out;
|
||||
}
|
||||
if (lpfc_error_lost_link(irsp->ulpStatus, irsp->un.ulpWord[4])) {
|
||||
if (lpfc_error_lost_link(ulp_status, ulp_word4)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"4166 NS query failed due to link event\n");
|
||||
if (vport->fc_flag & FC_RSCN_MODE)
|
||||
@ -1231,11 +1209,11 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
}
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
if (irsp->ulpStatus) {
|
||||
if (ulp_status) {
|
||||
/* Check for retry */
|
||||
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
|
||||
if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
|
||||
(irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
|
||||
if (ulp_status != IOSTAT_LOCAL_REJECT ||
|
||||
(ulp_word4 & IOERR_PARAM_MASK) !=
|
||||
IOERR_NO_RESOURCES)
|
||||
vport->fc_ns_retry++;
|
||||
|
||||
@ -1254,7 +1232,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"4103 GID_FT Query error: 0x%x 0x%x\n",
|
||||
irsp->ulpStatus, vport->fc_ns_retry);
|
||||
ulp_status, vport->fc_ns_retry);
|
||||
} else {
|
||||
/* Good status, continue checking */
|
||||
CTreq = (struct lpfc_sli_ct_request *)inp->virt;
|
||||
@ -1268,12 +1246,12 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
CTreq->un.gid.Fc4Type,
|
||||
vport->num_disc_nodes,
|
||||
vport->gidft_inp,
|
||||
irsp->un.genreq64.bdl.bdeSize);
|
||||
get_job_data_placed(phba, rspiocb));
|
||||
|
||||
lpfc_ns_rsp(vport,
|
||||
outp,
|
||||
CTreq->un.gid.Fc4Type,
|
||||
(uint32_t)(irsp->un.genreq64.bdl.bdeSize));
|
||||
get_job_data_placed(phba, rspiocb));
|
||||
} else if (CTrsp->CommandResponse.bits.CmdRsp ==
|
||||
be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
|
||||
/* NameServer Rsp Error */
|
||||
@ -1368,20 +1346,21 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
{
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
|
||||
struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
int did, rc, retry;
|
||||
uint8_t fbits;
|
||||
struct lpfc_nodelist *ndlp = NULL, *free_ndlp = NULL;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
u32 ulp_word4 = get_job_word4(phba, rspiocb);
|
||||
|
||||
did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
|
||||
did = be32_to_cpu(did);
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
|
||||
"GFF_ID cmpl: status:x%x/x%x did:x%x",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4], did);
|
||||
ulp_status, ulp_word4, did);
|
||||
|
||||
/* Ignore response if link flipped after this request was made */
|
||||
if (cmdiocb->event_tag != phba->fc_eventTag) {
|
||||
@ -1390,7 +1369,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
goto iocb_free;
|
||||
}
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
/* Good status, continue checking */
|
||||
CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
|
||||
fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET];
|
||||
@ -1420,8 +1399,8 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
/* Check for retry */
|
||||
if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
|
||||
retry = 1;
|
||||
if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
|
||||
switch ((irsp->un.ulpWord[4] &
|
||||
if (ulp_status == IOSTAT_LOCAL_REJECT) {
|
||||
switch ((ulp_word4 &
|
||||
IOERR_PARAM_MASK)) {
|
||||
|
||||
case IOERR_NO_RESOURCES:
|
||||
@ -1457,7 +1436,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0267 NameServer GFF Rsp "
|
||||
"x%x Error (%d %d) Data: x%x x%x\n",
|
||||
did, irsp->ulpStatus, irsp->un.ulpWord[4],
|
||||
did, ulp_status, ulp_word4,
|
||||
vport->fc_flag, vport->fc_rscn_id_cnt);
|
||||
}
|
||||
|
||||
@ -1512,10 +1491,9 @@ iocb_free:
|
||||
|
||||
static void
|
||||
lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *)cmdiocb->context1;
|
||||
struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *)cmdiocb->context2;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
@ -1523,13 +1501,15 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
struct lpfc_nodelist *ns_ndlp = NULL;
|
||||
uint32_t fc4_data_0, fc4_data_1;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
u32 ulp_word4 = get_job_word4(phba, rspiocb);
|
||||
|
||||
did = ((struct lpfc_sli_ct_request *)inp->virt)->un.gft.PortId;
|
||||
did = be32_to_cpu(did);
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
|
||||
"GFT_ID cmpl: status:x%x/x%x did:x%x",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4], did);
|
||||
ulp_status, ulp_word4, did);
|
||||
|
||||
/* Ignore response if link flipped after this request was made */
|
||||
if ((uint32_t) cmdiocb->event_tag != phba->fc_eventTag) {
|
||||
@ -1541,7 +1521,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
/* Preserve the nameserver node to release the reference. */
|
||||
ns_ndlp = cmdiocb->context_un.ndlp;
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
/* Good status, continue checking */
|
||||
CTrsp = (struct lpfc_sli_ct_request *)outp->virt;
|
||||
fc4_data_0 = be32_to_cpu(CTrsp->un.gft_acc.fc4_types[0]);
|
||||
@ -1602,7 +1582,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
}
|
||||
} else
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"3065 GFT_ID failed x%08x\n", irsp->ulpStatus);
|
||||
"3065 GFT_ID failed x%08x\n", ulp_status);
|
||||
|
||||
out:
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
@ -1616,12 +1596,13 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
struct lpfc_dmabuf *inp;
|
||||
struct lpfc_dmabuf *outp;
|
||||
IOCB_t *irsp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
int cmdcode, rc;
|
||||
uint8_t retry;
|
||||
uint32_t latt;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
u32 ulp_word4 = get_job_word4(phba, rspiocb);
|
||||
|
||||
/* First save ndlp, before we overwrite it */
|
||||
ndlp = cmdiocb->context_un.ndlp;
|
||||
@ -1631,7 +1612,6 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
|
||||
inp = (struct lpfc_dmabuf *) cmdiocb->context1;
|
||||
outp = (struct lpfc_dmabuf *) cmdiocb->context2;
|
||||
irsp = &rspiocb->iocb;
|
||||
|
||||
cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
|
||||
CommandResponse.bits.CmdRsp);
|
||||
@ -1639,28 +1619,28 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
|
||||
latt = lpfc_els_chk_latt(vport);
|
||||
|
||||
/* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
|
||||
/* RFT request completes status <ulp_status> CmdRsp <CmdRsp> */
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0209 CT Request completes, latt %d, "
|
||||
"ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
|
||||
latt, irsp->ulpStatus,
|
||||
"ulp_status x%x CmdRsp x%x, Context x%x, Tag x%x\n",
|
||||
latt, ulp_status,
|
||||
CTrsp->CommandResponse.bits.CmdRsp,
|
||||
cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
|
||||
get_job_ulpcontext(phba, cmdiocb), cmdiocb->iotag);
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
|
||||
"CT cmd cmpl: status:x%x/x%x cmd:x%x",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
|
||||
ulp_status, ulp_word4, cmdcode);
|
||||
|
||||
if (irsp->ulpStatus) {
|
||||
if (ulp_status) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0268 NS cmd x%x Error (x%x x%x)\n",
|
||||
cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
|
||||
cmdcode, ulp_status, ulp_word4);
|
||||
|
||||
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
|
||||
(((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
|
||||
IOERR_SLI_DOWN) ||
|
||||
((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
|
||||
IOERR_SLI_ABORTED)))
|
||||
if (ulp_status == IOSTAT_LOCAL_REJECT &&
|
||||
(((ulp_word4 & IOERR_PARAM_MASK) ==
|
||||
IOERR_SLI_DOWN) ||
|
||||
((ulp_word4 & IOERR_PARAM_MASK) ==
|
||||
IOERR_SLI_ABORTED)))
|
||||
goto out;
|
||||
|
||||
retry = cmdiocb->retry;
|
||||
@ -1685,10 +1665,10 @@ static void
|
||||
lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
|
||||
@ -1706,10 +1686,10 @@ static void
|
||||
lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
|
||||
@ -1727,10 +1707,10 @@ static void
|
||||
lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
|
||||
@ -1748,10 +1728,10 @@ static void
|
||||
lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
|
||||
@ -1781,10 +1761,10 @@ static void
|
||||
lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_vport *vport = cmdiocb->vport;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
|
||||
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
|
||||
if (ulp_status == IOSTAT_SUCCESS) {
|
||||
struct lpfc_dmabuf *outp;
|
||||
struct lpfc_sli_ct_request *CTrsp;
|
||||
|
||||
@ -2195,20 +2175,21 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_sli_ct_request *CTrsp = outp->virt;
|
||||
uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
|
||||
uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
struct lpfc_nodelist *ndlp, *free_ndlp = NULL;
|
||||
uint32_t latt, cmd, err;
|
||||
u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
u32 ulp_word4 = get_job_word4(phba, rspiocb);
|
||||
|
||||
latt = lpfc_els_chk_latt(vport);
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
|
||||
"FDMI cmpl: status:x%x/x%x latt:%d",
|
||||
irsp->ulpStatus, irsp->un.ulpWord[4], latt);
|
||||
ulp_status, ulp_word4, latt);
|
||||
|
||||
if (latt || irsp->ulpStatus) {
|
||||
if (latt || ulp_status) {
|
||||
|
||||
/* Look for a retryable error */
|
||||
if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
|
||||
switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
|
||||
if (ulp_status == IOSTAT_LOCAL_REJECT) {
|
||||
switch ((ulp_word4 & IOERR_PARAM_MASK)) {
|
||||
case IOERR_SLI_ABORTED:
|
||||
case IOERR_SLI_DOWN:
|
||||
/* Driver aborted this IO. No retry as error
|
||||
@ -2238,9 +2219,9 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"0229 FDMI cmd %04x failed, latt = %d "
|
||||
"ulpStatus: x%x, rid x%x\n",
|
||||
be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
|
||||
irsp->un.ulpWord[4]);
|
||||
"ulp_status: x%x, rid x%x\n",
|
||||
be16_to_cpu(fdmi_cmd), latt, ulp_status,
|
||||
ulp_word4);
|
||||
}
|
||||
|
||||
free_ndlp = cmdiocb->context_un.ndlp;
|
||||
|
@ -1255,20 +1255,15 @@ __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
|
||||
struct lpfc_sglq *start_sglq = NULL;
|
||||
struct lpfc_io_buf *lpfc_cmd;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
struct lpfc_sli_ring *pring = NULL;
|
||||
int found = 0;
|
||||
u8 cmnd;
|
||||
|
||||
if (piocbq->cmd_flag & LPFC_IO_NVME_LS)
|
||||
pring = phba->sli4_hba.nvmels_wq->pring;
|
||||
else
|
||||
pring = lpfc_phba_elsring(phba);
|
||||
|
||||
lockdep_assert_held(&pring->ring_lock);
|
||||
cmnd = get_job_cmnd(phba, piocbq);
|
||||
|
||||
if (piocbq->cmd_flag & LPFC_IO_FCP) {
|
||||
lpfc_cmd = (struct lpfc_io_buf *) piocbq->context1;
|
||||
ndlp = lpfc_cmd->rdata->pnode;
|
||||
} else if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) &&
|
||||
} else if ((cmnd == CMD_GEN_REQUEST64_CR) &&
|
||||
!(piocbq->cmd_flag & LPFC_IO_LIBDFC)) {
|
||||
ndlp = piocbq->context_un.ndlp;
|
||||
} else if (piocbq->cmd_flag & LPFC_IO_LIBDFC) {
|
||||
@ -3367,6 +3362,56 @@ lpfc_complete_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_sli_prep_unsol_wqe(struct lpfc_hba *phba,
|
||||
struct lpfc_iocbq *saveq)
|
||||
{
|
||||
IOCB_t *irsp;
|
||||
union lpfc_wqe128 *wqe;
|
||||
u16 i = 0;
|
||||
|
||||
irsp = &saveq->iocb;
|
||||
wqe = &saveq->wqe;
|
||||
|
||||
/* Fill wcqe with the IOCB status fields */
|
||||
bf_set(lpfc_wcqe_c_status, &saveq->wcqe_cmpl, irsp->ulpStatus);
|
||||
saveq->wcqe_cmpl.word3 = irsp->ulpBdeCount;
|
||||
saveq->wcqe_cmpl.parameter = irsp->un.ulpWord[4];
|
||||
saveq->wcqe_cmpl.total_data_placed = irsp->unsli3.rcvsli3.acc_len;
|
||||
|
||||
/* Source ID */
|
||||
bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, irsp->un.rcvels.parmRo);
|
||||
|
||||
/* rx-id of the response frame */
|
||||
bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com, irsp->ulpContext);
|
||||
|
||||
/* ox-id of the frame */
|
||||
bf_set(wqe_rcvoxid, &wqe->xmit_els_rsp.wqe_com,
|
||||
irsp->unsli3.rcvsli3.ox_id);
|
||||
|
||||
/* DID */
|
||||
bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
|
||||
irsp->un.rcvels.remoteID);
|
||||
|
||||
/* unsol data len */
|
||||
for (i = 0; i < irsp->ulpBdeCount; i++) {
|
||||
struct lpfc_hbq_entry *hbqe = NULL;
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
if (i == 0) {
|
||||
hbqe = (struct lpfc_hbq_entry *)
|
||||
&irsp->un.ulpWord[0];
|
||||
saveq->wqe.gen_req.bde.tus.f.bdeSize =
|
||||
hbqe->bde.tus.f.bdeSize;
|
||||
} else if (i == 1) {
|
||||
hbqe = (struct lpfc_hbq_entry *)
|
||||
&irsp->unsli3.sli3Words[4];
|
||||
saveq->unsol_rcv_len = hbqe->bde.tus.f.bdeSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_process_unsol_iocb - Unsolicited iocb handler
|
||||
* @phba: Pointer to HBA context object.
|
||||
@ -3387,11 +3432,13 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
{
|
||||
IOCB_t * irsp;
|
||||
WORD5 * w5p;
|
||||
dma_addr_t paddr;
|
||||
uint32_t Rctl, Type;
|
||||
struct lpfc_iocbq *iocbq;
|
||||
struct lpfc_dmabuf *dmzbuf;
|
||||
|
||||
irsp = &(saveq->iocb);
|
||||
irsp = &saveq->iocb;
|
||||
saveq->vport = phba->pport;
|
||||
|
||||
if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
|
||||
if (pring->lpfc_sli_rcv_async_status)
|
||||
@ -3409,22 +3456,22 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
}
|
||||
|
||||
if ((irsp->ulpCommand == CMD_IOCB_RET_XRI64_CX) &&
|
||||
(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) {
|
||||
(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) {
|
||||
if (irsp->ulpBdeCount > 0) {
|
||||
dmzbuf = lpfc_sli_get_buff(phba, pring,
|
||||
irsp->un.ulpWord[3]);
|
||||
irsp->un.ulpWord[3]);
|
||||
lpfc_in_buf_free(phba, dmzbuf);
|
||||
}
|
||||
|
||||
if (irsp->ulpBdeCount > 1) {
|
||||
dmzbuf = lpfc_sli_get_buff(phba, pring,
|
||||
irsp->unsli3.sli3Words[3]);
|
||||
irsp->unsli3.sli3Words[3]);
|
||||
lpfc_in_buf_free(phba, dmzbuf);
|
||||
}
|
||||
|
||||
if (irsp->ulpBdeCount > 2) {
|
||||
dmzbuf = lpfc_sli_get_buff(phba, pring,
|
||||
irsp->unsli3.sli3Words[7]);
|
||||
irsp->unsli3.sli3Words[7]);
|
||||
lpfc_in_buf_free(phba, dmzbuf);
|
||||
}
|
||||
|
||||
@ -3457,9 +3504,10 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
irsp->unsli3.sli3Words[7]);
|
||||
}
|
||||
list_for_each_entry(iocbq, &saveq->list, list) {
|
||||
irsp = &(iocbq->iocb);
|
||||
irsp = &iocbq->iocb;
|
||||
if (irsp->ulpBdeCount != 0) {
|
||||
iocbq->context2 = lpfc_sli_get_buff(phba, pring,
|
||||
iocbq->context2 = lpfc_sli_get_buff(phba,
|
||||
pring,
|
||||
irsp->un.ulpWord[3]);
|
||||
if (!iocbq->context2)
|
||||
lpfc_printf_log(phba,
|
||||
@ -3471,7 +3519,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
irsp->un.ulpWord[3]);
|
||||
}
|
||||
if (irsp->ulpBdeCount == 2) {
|
||||
iocbq->context3 = lpfc_sli_get_buff(phba, pring,
|
||||
iocbq->context3 = lpfc_sli_get_buff(phba,
|
||||
pring,
|
||||
irsp->unsli3.sli3Words[7]);
|
||||
if (!iocbq->context3)
|
||||
lpfc_printf_log(phba,
|
||||
@ -3484,7 +3533,20 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
irsp->unsli3.sli3Words[7]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
paddr = getPaddr(irsp->un.cont64[0].addrHigh,
|
||||
irsp->un.cont64[0].addrLow);
|
||||
saveq->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
|
||||
paddr);
|
||||
if (irsp->ulpBdeCount == 2) {
|
||||
paddr = getPaddr(irsp->un.cont64[1].addrHigh,
|
||||
irsp->un.cont64[1].addrLow);
|
||||
saveq->context3 = lpfc_sli_ringpostbuf_get(phba,
|
||||
pring,
|
||||
paddr);
|
||||
}
|
||||
}
|
||||
|
||||
if (irsp->ulpBdeCount != 0 &&
|
||||
(irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX ||
|
||||
irsp->ulpStatus == IOSTAT_INTERMED_RSP)) {
|
||||
@ -3502,12 +3564,14 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
if (!found)
|
||||
list_add_tail(&saveq->clist,
|
||||
&pring->iocb_continue_saveq);
|
||||
|
||||
if (saveq->iocb.ulpStatus != IOSTAT_INTERMED_RSP) {
|
||||
list_del_init(&iocbq->clist);
|
||||
saveq = iocbq;
|
||||
irsp = &(saveq->iocb);
|
||||
} else
|
||||
irsp = &saveq->iocb;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) ||
|
||||
(irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) ||
|
||||
@ -3530,6 +3594,19 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
}
|
||||
}
|
||||
|
||||
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
|
||||
(irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX ||
|
||||
irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
|
||||
if (irsp->unsli3.rcvsli3.vpi == 0xffff)
|
||||
saveq->vport = phba->pport;
|
||||
else
|
||||
saveq->vport = lpfc_find_vport_by_vpid(phba,
|
||||
irsp->unsli3.rcvsli3.vpi);
|
||||
}
|
||||
|
||||
/* Prepare WQE with Unsol frame */
|
||||
lpfc_sli_prep_unsol_wqe(phba, saveq);
|
||||
|
||||
if (!lpfc_complete_unsol_iocb(phba, pring, saveq, Rctl, Type))
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
||||
"0313 Ring %d handler: unexpected Rctl x%x "
|
||||
@ -10570,6 +10647,195 @@ lpfc_sli_prep_els_req_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
|
||||
elscmd, tmo, expect_rsp);
|
||||
}
|
||||
|
||||
static void
|
||||
__lpfc_sli_prep_gen_req_s3(struct lpfc_iocbq *cmdiocbq, struct lpfc_dmabuf *bmp,
|
||||
u16 rpi, u32 num_entry, u8 tmo)
|
||||
{
|
||||
IOCB_t *cmd;
|
||||
|
||||
cmd = &cmdiocbq->iocb;
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
|
||||
cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
|
||||
cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
cmd->un.genreq64.bdl.bdeSize = num_entry * sizeof(struct ulp_bde64);
|
||||
|
||||
cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
|
||||
cmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
|
||||
|
||||
cmd->ulpContext = rpi;
|
||||
cmd->ulpClass = CLASS3;
|
||||
cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
|
||||
cmd->ulpBdeCount = 1;
|
||||
cmd->ulpLe = 1;
|
||||
cmd->ulpOwner = OWN_CHIP;
|
||||
cmd->ulpTimeout = tmo;
|
||||
}
|
||||
|
||||
static void
|
||||
__lpfc_sli_prep_gen_req_s4(struct lpfc_iocbq *cmdiocbq, struct lpfc_dmabuf *bmp,
|
||||
u16 rpi, u32 num_entry, u8 tmo)
|
||||
{
|
||||
union lpfc_wqe128 *cmdwqe;
|
||||
struct ulp_bde64_le *bde, *bpl;
|
||||
u32 xmit_len = 0, total_len = 0, size, type, i;
|
||||
|
||||
cmdwqe = &cmdiocbq->wqe;
|
||||
memset(cmdwqe, 0, sizeof(*cmdwqe));
|
||||
|
||||
/* Calculate total_len and xmit_len */
|
||||
bpl = (struct ulp_bde64_le *)bmp->virt;
|
||||
for (i = 0; i < num_entry; i++) {
|
||||
size = le32_to_cpu(bpl[i].type_size) & ULP_BDE64_SIZE_MASK;
|
||||
total_len += size;
|
||||
}
|
||||
for (i = 0; i < num_entry; i++) {
|
||||
size = le32_to_cpu(bpl[i].type_size) & ULP_BDE64_SIZE_MASK;
|
||||
type = le32_to_cpu(bpl[i].type_size) & ULP_BDE64_TYPE_MASK;
|
||||
if (type != ULP_BDE64_TYPE_BDE_64)
|
||||
break;
|
||||
xmit_len += size;
|
||||
}
|
||||
|
||||
/* Words 0 - 2 */
|
||||
bde = (struct ulp_bde64_le *)&cmdwqe->generic.bde;
|
||||
bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys));
|
||||
bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys));
|
||||
bde->type_size = cpu_to_le32(xmit_len);
|
||||
bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BLP_64);
|
||||
|
||||
/* Word 3 */
|
||||
cmdwqe->gen_req.request_payload_len = xmit_len;
|
||||
|
||||
/* Word 5 */
|
||||
bf_set(wqe_type, &cmdwqe->gen_req.wge_ctl, FC_TYPE_CT);
|
||||
bf_set(wqe_rctl, &cmdwqe->gen_req.wge_ctl, FC_RCTL_DD_UNSOL_CTL);
|
||||
bf_set(wqe_si, &cmdwqe->gen_req.wge_ctl, 1);
|
||||
bf_set(wqe_la, &cmdwqe->gen_req.wge_ctl, 1);
|
||||
|
||||
/* Word 6 */
|
||||
bf_set(wqe_ctxt_tag, &cmdwqe->gen_req.wqe_com, rpi);
|
||||
|
||||
/* Word 7 */
|
||||
bf_set(wqe_tmo, &cmdwqe->gen_req.wqe_com, tmo);
|
||||
bf_set(wqe_class, &cmdwqe->gen_req.wqe_com, CLASS3);
|
||||
bf_set(wqe_cmnd, &cmdwqe->gen_req.wqe_com, CMD_GEN_REQUEST64_CR);
|
||||
bf_set(wqe_ct, &cmdwqe->gen_req.wqe_com, SLI4_CT_RPI);
|
||||
|
||||
/* Word 12 */
|
||||
cmdwqe->gen_req.max_response_payload_len = total_len - xmit_len;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_sli_prep_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi, u32 num_entry, u8 tmo)
|
||||
{
|
||||
phba->__lpfc_sli_prep_gen_req(cmdiocbq, bmp, rpi, num_entry, tmo);
|
||||
}
|
||||
|
||||
static void
|
||||
__lpfc_sli_prep_xmit_seq64_s3(struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
|
||||
u32 num_entry, u8 rctl, u8 last_seq, u8 cr_cx_cmd)
|
||||
{
|
||||
IOCB_t *icmd;
|
||||
|
||||
icmd = &cmdiocbq->iocb;
|
||||
memset(icmd, 0, sizeof(*icmd));
|
||||
|
||||
icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
|
||||
icmd->un.xseq64.bdl.addrLow = putPaddrLow(bmp->phys);
|
||||
icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
|
||||
icmd->un.xseq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
|
||||
icmd->un.xseq64.w5.hcsw.Fctl = LA;
|
||||
if (last_seq)
|
||||
icmd->un.xseq64.w5.hcsw.Fctl |= LS;
|
||||
icmd->un.xseq64.w5.hcsw.Dfctl = 0;
|
||||
icmd->un.xseq64.w5.hcsw.Rctl = rctl;
|
||||
icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
|
||||
|
||||
icmd->ulpBdeCount = 1;
|
||||
icmd->ulpLe = 1;
|
||||
icmd->ulpClass = CLASS3;
|
||||
|
||||
switch (cr_cx_cmd) {
|
||||
case CMD_XMIT_SEQUENCE64_CR:
|
||||
icmd->ulpContext = rpi;
|
||||
icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CR;
|
||||
break;
|
||||
case CMD_XMIT_SEQUENCE64_CX:
|
||||
icmd->ulpContext = ox_id;
|
||||
icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__lpfc_sli_prep_xmit_seq64_s4(struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
|
||||
u32 full_size, u8 rctl, u8 last_seq, u8 cr_cx_cmd)
|
||||
{
|
||||
union lpfc_wqe128 *wqe;
|
||||
struct ulp_bde64 *bpl;
|
||||
struct ulp_bde64_le *bde;
|
||||
|
||||
wqe = &cmdiocbq->wqe;
|
||||
memset(wqe, 0, sizeof(*wqe));
|
||||
|
||||
/* Words 0 - 2 */
|
||||
bpl = (struct ulp_bde64 *)bmp->virt;
|
||||
if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK)) {
|
||||
wqe->xmit_sequence.bde.addrHigh = bpl->addrHigh;
|
||||
wqe->xmit_sequence.bde.addrLow = bpl->addrLow;
|
||||
wqe->xmit_sequence.bde.tus.w = bpl->tus.w;
|
||||
} else {
|
||||
bde = (struct ulp_bde64_le *)&wqe->xmit_sequence.bde;
|
||||
bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys));
|
||||
bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys));
|
||||
bde->type_size = cpu_to_le32(bpl->tus.f.bdeSize);
|
||||
bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BDE_64);
|
||||
}
|
||||
|
||||
/* Word 5 */
|
||||
bf_set(wqe_ls, &wqe->xmit_sequence.wge_ctl, last_seq);
|
||||
bf_set(wqe_la, &wqe->xmit_sequence.wge_ctl, 1);
|
||||
bf_set(wqe_dfctl, &wqe->xmit_sequence.wge_ctl, 0);
|
||||
bf_set(wqe_rctl, &wqe->xmit_sequence.wge_ctl, rctl);
|
||||
bf_set(wqe_type, &wqe->xmit_sequence.wge_ctl, FC_TYPE_CT);
|
||||
|
||||
/* Word 6 */
|
||||
bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com, rpi);
|
||||
|
||||
bf_set(wqe_cmnd, &wqe->xmit_sequence.wqe_com,
|
||||
CMD_XMIT_SEQUENCE64_WQE);
|
||||
|
||||
/* Word 7 */
|
||||
bf_set(wqe_class, &wqe->xmit_sequence.wqe_com, CLASS3);
|
||||
|
||||
/* Word 9 */
|
||||
bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com, ox_id);
|
||||
|
||||
/* Word 12 */
|
||||
if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK))
|
||||
wqe->xmit_sequence.xmit_len = full_size;
|
||||
else
|
||||
wqe->xmit_sequence.xmit_len =
|
||||
wqe->xmit_sequence.bde.tus.f.bdeSize;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_sli_prep_xmit_seq64(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocbq,
|
||||
struct lpfc_dmabuf *bmp, u16 rpi, u16 ox_id,
|
||||
u32 num_entry, u8 rctl, u8 last_seq, u8 cr_cx_cmd)
|
||||
{
|
||||
phba->__lpfc_sli_prep_xmit_seq64(cmdiocbq, bmp, rpi, ox_id, num_entry,
|
||||
rctl, last_seq, cr_cx_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_api_table_setup - Set up sli api function jump table
|
||||
* @phba: The hba struct for which this call is being executed.
|
||||
@ -10589,12 +10855,16 @@ lpfc_sli_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
|
||||
phba->__lpfc_sli_release_iocbq = __lpfc_sli_release_iocbq_s3;
|
||||
phba->__lpfc_sli_issue_fcp_io = __lpfc_sli_issue_fcp_io_s3;
|
||||
phba->__lpfc_sli_prep_els_req_rsp = __lpfc_sli_prep_els_req_rsp_s3;
|
||||
phba->__lpfc_sli_prep_gen_req = __lpfc_sli_prep_gen_req_s3;
|
||||
phba->__lpfc_sli_prep_xmit_seq64 = __lpfc_sli_prep_xmit_seq64_s3;
|
||||
break;
|
||||
case LPFC_PCI_DEV_OC:
|
||||
phba->__lpfc_sli_issue_iocb = __lpfc_sli_issue_iocb_s4;
|
||||
phba->__lpfc_sli_release_iocbq = __lpfc_sli_release_iocbq_s4;
|
||||
phba->__lpfc_sli_issue_fcp_io = __lpfc_sli_issue_fcp_io_s4;
|
||||
phba->__lpfc_sli_prep_els_req_rsp = __lpfc_sli_prep_els_req_rsp_s4;
|
||||
phba->__lpfc_sli_prep_gen_req = __lpfc_sli_prep_gen_req_s4;
|
||||
phba->__lpfc_sli_prep_xmit_seq64 = __lpfc_sli_prep_xmit_seq64_s4;
|
||||
break;
|
||||
default:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
@ -18469,7 +18739,6 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
||||
struct fc_frame_header *fc_hdr;
|
||||
uint32_t sid;
|
||||
uint32_t len, tot_len;
|
||||
struct ulp_bde64 *pbde;
|
||||
|
||||
fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
|
||||
/* remove from receive buffer list */
|
||||
@ -18482,40 +18751,40 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
||||
first_iocbq = lpfc_sli_get_iocbq(vport->phba);
|
||||
if (first_iocbq) {
|
||||
/* Initialize the first IOCB. */
|
||||
first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
|
||||
first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
|
||||
first_iocbq->wcqe_cmpl.total_data_placed = 0;
|
||||
bf_set(lpfc_wcqe_c_status, &first_iocbq->wcqe_cmpl,
|
||||
IOSTAT_SUCCESS);
|
||||
first_iocbq->vport = vport;
|
||||
|
||||
/* 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.unsli3.rcvsli3.ox_id =
|
||||
be16_to_cpu(fc_hdr->fh_ox_id);
|
||||
/* iocbq is prepped for internal consumption. Physical vpi. */
|
||||
first_iocbq->iocb.unsli3.rcvsli3.vpi =
|
||||
vport->phba->vpi_ids[vport->vpi];
|
||||
/* put the first buffer into the first IOCBq */
|
||||
bf_set(els_rsp64_sid, &first_iocbq->wqe.xmit_els_rsp,
|
||||
sli4_did_from_fc_hdr(fc_hdr));
|
||||
}
|
||||
|
||||
bf_set(wqe_ctxt_tag, &first_iocbq->wqe.xmit_els_rsp.wqe_com,
|
||||
NO_XRI);
|
||||
bf_set(wqe_rcvoxid, &first_iocbq->wqe.xmit_els_rsp.wqe_com,
|
||||
be16_to_cpu(fc_hdr->fh_ox_id));
|
||||
|
||||
/* put the first buffer into the first iocb */
|
||||
tot_len = bf_get(lpfc_rcqe_length,
|
||||
&seq_dmabuf->cq_event.cqe.rcqe_cmpl);
|
||||
&seq_dmabuf->cq_event.cqe.rcqe_cmpl);
|
||||
|
||||
first_iocbq->context2 = &seq_dmabuf->dbuf;
|
||||
first_iocbq->context3 = NULL;
|
||||
first_iocbq->iocb.ulpBdeCount = 1;
|
||||
/* Keep track of the BDE count */
|
||||
first_iocbq->wcqe_cmpl.word3 = 1;
|
||||
|
||||
if (tot_len > LPFC_DATA_BUF_SIZE)
|
||||
first_iocbq->iocb.un.cont64[0].tus.f.bdeSize =
|
||||
LPFC_DATA_BUF_SIZE;
|
||||
first_iocbq->wqe.gen_req.bde.tus.f.bdeSize =
|
||||
LPFC_DATA_BUF_SIZE;
|
||||
else
|
||||
first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = tot_len;
|
||||
first_iocbq->wqe.gen_req.bde.tus.f.bdeSize = tot_len;
|
||||
|
||||
first_iocbq->iocb.un.rcvels.remoteID = sid;
|
||||
|
||||
first_iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
|
||||
first_iocbq->wcqe_cmpl.total_data_placed = tot_len;
|
||||
bf_set(wqe_els_did, &first_iocbq->wqe.xmit_els_rsp.wqe_dest,
|
||||
sid);
|
||||
}
|
||||
iocbq = first_iocbq;
|
||||
/*
|
||||
@ -18529,28 +18798,23 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
||||
}
|
||||
if (!iocbq->context3) {
|
||||
iocbq->context3 = d_buf;
|
||||
iocbq->iocb.ulpBdeCount++;
|
||||
iocbq->wcqe_cmpl.word3++;
|
||||
/* We need to get the size out of the right CQE */
|
||||
hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
|
||||
len = bf_get(lpfc_rcqe_length,
|
||||
&hbq_buf->cq_event.cqe.rcqe_cmpl);
|
||||
pbde = (struct ulp_bde64 *)
|
||||
&iocbq->iocb.unsli3.sli3Words[4];
|
||||
if (len > LPFC_DATA_BUF_SIZE)
|
||||
pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE;
|
||||
else
|
||||
pbde->tus.f.bdeSize = len;
|
||||
|
||||
iocbq->iocb.unsli3.rcvsli3.acc_len += len;
|
||||
iocbq->unsol_rcv_len = len;
|
||||
iocbq->wcqe_cmpl.total_data_placed += len;
|
||||
tot_len += len;
|
||||
} else {
|
||||
iocbq = lpfc_sli_get_iocbq(vport->phba);
|
||||
if (!iocbq) {
|
||||
if (first_iocbq) {
|
||||
first_iocbq->iocb.ulpStatus =
|
||||
IOSTAT_FCP_RSP_ERROR;
|
||||
first_iocbq->iocb.un.ulpWord[4] =
|
||||
IOERR_NO_RESOURCES;
|
||||
bf_set(lpfc_wcqe_c_status,
|
||||
&first_iocbq->wcqe_cmpl,
|
||||
IOSTAT_SUCCESS);
|
||||
first_iocbq->wcqe_cmpl.parameter =
|
||||
IOERR_NO_RESOURCES;
|
||||
}
|
||||
lpfc_in_buf_free(vport->phba, d_buf);
|
||||
continue;
|
||||
@ -18561,17 +18825,19 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
||||
&hbq_buf->cq_event.cqe.rcqe_cmpl);
|
||||
iocbq->context2 = d_buf;
|
||||
iocbq->context3 = NULL;
|
||||
iocbq->iocb.ulpBdeCount = 1;
|
||||
iocbq->wcqe_cmpl.word3 = 1;
|
||||
|
||||
if (len > LPFC_DATA_BUF_SIZE)
|
||||
iocbq->iocb.un.cont64[0].tus.f.bdeSize =
|
||||
LPFC_DATA_BUF_SIZE;
|
||||
iocbq->wqe.xmit_els_rsp.bde.tus.f.bdeSize =
|
||||
LPFC_DATA_BUF_SIZE;
|
||||
else
|
||||
iocbq->iocb.un.cont64[0].tus.f.bdeSize = len;
|
||||
iocbq->wqe.xmit_els_rsp.bde.tus.f.bdeSize =
|
||||
len;
|
||||
|
||||
tot_len += len;
|
||||
iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
|
||||
|
||||
iocbq->iocb.un.rcvels.remoteID = sid;
|
||||
iocbq->wcqe_cmpl.total_data_placed = tot_len;
|
||||
bf_set(wqe_els_did, &iocbq->wqe.xmit_els_rsp.wqe_dest,
|
||||
sid);
|
||||
list_add_tail(&iocbq->list, &first_iocbq->list);
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ struct lpfc_iocbq {
|
||||
IOCB_t iocb; /* SLI-3 */
|
||||
struct lpfc_wcqe_complete wcqe_cmpl; /* WQE cmpl */
|
||||
|
||||
u32 unsol_rcv_len; /* Receive len in usol path */
|
||||
uint8_t num_bdes;
|
||||
uint8_t abort_bls; /* ABTS by initiator or responder */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user