|
@@ -560,7 +560,7 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
|
|
|
rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
|
|
|
if (rrq) {
|
|
|
rrq->send_rrq = send_rrq;
|
|
|
- rrq->xritag = phba->sli4_hba.xri_ids[xritag];
|
|
|
+ rrq->xritag = xritag;
|
|
|
rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
|
|
|
rrq->ndlp = ndlp;
|
|
|
rrq->nlp_DID = ndlp->nlp_DID;
|
|
@@ -2452,7 +2452,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|
|
|
|
|
/* search continue save q for same XRI */
|
|
|
list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) {
|
|
|
- if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) {
|
|
|
+ if (iocbq->iocb.unsli3.rcvsli3.ox_id ==
|
|
|
+ saveq->iocb.unsli3.rcvsli3.ox_id) {
|
|
|
list_add_tail(&saveq->list, &iocbq->list);
|
|
|
found = 1;
|
|
|
break;
|
|
@@ -3355,6 +3356,7 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba,
|
|
|
irspiocbq);
|
|
|
break;
|
|
|
case CQE_CODE_RECEIVE:
|
|
|
+ case CQE_CODE_RECEIVE_V1:
|
|
|
dmabuf = container_of(cq_event, struct hbq_dmabuf,
|
|
|
cq_event);
|
|
|
lpfc_sli4_handle_received_buffer(phba, dmabuf);
|
|
@@ -7318,12 +7320,12 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
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;
|
|
|
+ break;
|
|
|
case CMD_XMIT_SEQUENCE64_CX:
|
|
|
bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com,
|
|
|
iocbq->iocb.un.ulpWord[3]);
|
|
|
bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com,
|
|
|
- iocbq->iocb.ulpContext);
|
|
|
+ iocbq->iocb.unsli3.rcvsli3.ox_id);
|
|
|
/* The entire sequence is transmitted for this IOCB */
|
|
|
xmit_len = total_len;
|
|
|
cmnd = CMD_XMIT_SEQUENCE64_CR;
|
|
@@ -7341,7 +7343,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
bf_set(wqe_ebde_cnt, &wqe->xmit_sequence.wqe_com, 0);
|
|
|
wqe->xmit_sequence.xmit_len = xmit_len;
|
|
|
command_type = OTHER_COMMAND;
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_XMIT_BCAST64_CN:
|
|
|
/* word3 iocb=iotag32 wqe=seq_payload_len */
|
|
|
wqe->xmit_bcast64.seq_payload_len = xmit_len;
|
|
@@ -7355,7 +7357,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
bf_set(wqe_lenloc, &wqe->xmit_bcast64.wqe_com,
|
|
|
LPFC_WQE_LENLOC_WORD3);
|
|
|
bf_set(wqe_ebde_cnt, &wqe->xmit_bcast64.wqe_com, 0);
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_FCP_IWRITE64_CR:
|
|
|
command_type = FCP_COMMAND_DATA_OUT;
|
|
|
/* word3 iocb=iotag wqe=payload_offset_len */
|
|
@@ -7375,7 +7377,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
LPFC_WQE_LENLOC_WORD4);
|
|
|
bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0);
|
|
|
bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU);
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_FCP_IREAD64_CR:
|
|
|
/* word3 iocb=iotag wqe=payload_offset_len */
|
|
|
/* Add the FCP_CMD and FCP_RSP sizes to get the offset */
|
|
@@ -7394,7 +7396,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
LPFC_WQE_LENLOC_WORD4);
|
|
|
bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0);
|
|
|
bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU);
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_FCP_ICMND64_CR:
|
|
|
/* word3 iocb=IO_TAG wqe=reserved */
|
|
|
wqe->fcp_icmd.rsrvd3 = 0;
|
|
@@ -7407,7 +7409,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com,
|
|
|
LPFC_WQE_LENLOC_NONE);
|
|
|
bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_GEN_REQUEST64_CR:
|
|
|
/* For this command calculate the xmit length of the
|
|
|
* request bde.
|
|
@@ -7442,7 +7444,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
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;
|
|
|
+ break;
|
|
|
case CMD_XMIT_ELS_RSP64_CX:
|
|
|
ndlp = (struct lpfc_nodelist *)iocbq->context1;
|
|
|
/* words0-2 BDE memcpy */
|
|
@@ -7457,7 +7459,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
((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_rcvoxid, &wqe->xmit_els_rsp.wqe_com,
|
|
|
- iocbq->iocb.ulpContext);
|
|
|
+ iocbq->iocb.unsli3.rcvsli3.ox_id);
|
|
|
if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l)
|
|
|
bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
|
|
|
phba->vpi_ids[iocbq->vport->vpi]);
|
|
@@ -7470,7 +7472,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp,
|
|
|
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
|
|
|
command_type = OTHER_COMMAND;
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_CLOSE_XRI_CN:
|
|
|
case CMD_ABORT_XRI_CN:
|
|
|
case CMD_ABORT_XRI_CX:
|
|
@@ -7509,7 +7511,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
cmnd = CMD_ABORT_XRI_CX;
|
|
|
command_type = OTHER_COMMAND;
|
|
|
xritag = 0;
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_XMIT_BLS_RSP64_CX:
|
|
|
/* As BLS ABTS RSP WQE is very different from other WQEs,
|
|
|
* we re-construct this WQE here based on information in
|
|
@@ -7553,7 +7555,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
bf_get(lpfc_rsn_code, &iocbq->iocb.un.bls_rsp));
|
|
|
}
|
|
|
|
|
|
- break;
|
|
|
+ break;
|
|
|
case CMD_XRI_ABORTED_CX:
|
|
|
case CMD_CREATE_XRI_CR: /* Do we expect to use this? */
|
|
|
case CMD_IOCB_FCP_IBIDIR64_CR: /* bidirectional xfer */
|
|
@@ -7565,7 +7567,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
"2014 Invalid command 0x%x\n",
|
|
|
iocbq->iocb.ulpCommand);
|
|
|
return IOCB_ERROR;
|
|
|
- break;
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag);
|
|
@@ -10481,10 +10483,14 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
|
|
|
struct lpfc_queue *hrq = phba->sli4_hba.hdr_rq;
|
|
|
struct lpfc_queue *drq = phba->sli4_hba.dat_rq;
|
|
|
struct hbq_dmabuf *dma_buf;
|
|
|
- uint32_t status;
|
|
|
+ uint32_t status, rq_id;
|
|
|
unsigned long iflags;
|
|
|
|
|
|
- if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id)
|
|
|
+ if (bf_get(lpfc_cqe_code, rcqe) == CQE_CODE_RECEIVE_V1)
|
|
|
+ rq_id = bf_get(lpfc_rcqe_rq_id_v1, rcqe);
|
|
|
+ else
|
|
|
+ rq_id = bf_get(lpfc_rcqe_rq_id, rcqe);
|
|
|
+ if (rq_id != hrq->queue_id)
|
|
|
goto out;
|
|
|
|
|
|
status = bf_get(lpfc_rcqe_status, rcqe);
|
|
@@ -10563,6 +10569,7 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|
|
(struct sli4_wcqe_xri_aborted *)&cqevt);
|
|
|
break;
|
|
|
case CQE_CODE_RECEIVE:
|
|
|
+ case CQE_CODE_RECEIVE_V1:
|
|
|
/* Process the RQ event */
|
|
|
phba->last_completion_time = jiffies;
|
|
|
workposted = lpfc_sli4_sp_handle_rcqe(phba,
|
|
@@ -13405,7 +13412,7 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba,
|
|
|
* This function validates the xri maps to the known range of XRIs allocated an
|
|
|
* used by the driver.
|
|
|
**/
|
|
|
-static uint16_t
|
|
|
+uint16_t
|
|
|
lpfc_sli4_xri_inrange(struct lpfc_hba *phba,
|
|
|
uint16_t xri)
|
|
|
{
|
|
@@ -13642,10 +13649,12 @@ lpfc_seq_complete(struct hbq_dmabuf *dmabuf)
|
|
|
static struct lpfc_iocbq *
|
|
|
lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
{
|
|
|
+ struct hbq_dmabuf *hbq_buf;
|
|
|
struct lpfc_dmabuf *d_buf, *n_buf;
|
|
|
struct lpfc_iocbq *first_iocbq, *iocbq;
|
|
|
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;
|
|
@@ -13654,6 +13663,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
lpfc_update_rcv_time_stamp(vport);
|
|
|
/* get the Remote Port's SID */
|
|
|
sid = sli4_sid_from_fc_hdr(fc_hdr);
|
|
|
+ tot_len = 0;
|
|
|
/* Get an iocbq struct to fill in. */
|
|
|
first_iocbq = lpfc_sli_get_iocbq(vport->phba);
|
|
|
if (first_iocbq) {
|
|
@@ -13661,9 +13671,12 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
|
|
|
first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
|
|
|
first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
|
|
|
- first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id);
|
|
|
- /* iocbq is prepped for internal consumption. Logical vpi. */
|
|
|
- first_iocbq->iocb.unsli3.rcvsli3.vpi = vport->vpi;
|
|
|
+ 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 */
|
|
|
first_iocbq->context2 = &seq_dmabuf->dbuf;
|
|
|
first_iocbq->context3 = NULL;
|
|
@@ -13671,9 +13684,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
first_iocbq->iocb.un.cont64[0].tus.f.bdeSize =
|
|
|
LPFC_DATA_BUF_SIZE;
|
|
|
first_iocbq->iocb.un.rcvels.remoteID = sid;
|
|
|
- first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
|
|
|
- bf_get(lpfc_rcqe_length,
|
|
|
+ tot_len = bf_get(lpfc_rcqe_length,
|
|
|
&seq_dmabuf->cq_event.cqe.rcqe_cmpl);
|
|
|
+ first_iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
|
|
|
}
|
|
|
iocbq = first_iocbq;
|
|
|
/*
|
|
@@ -13691,9 +13704,13 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
pbde = (struct ulp_bde64 *)
|
|
|
&iocbq->iocb.unsli3.sli3Words[4];
|
|
|
pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE;
|
|
|
- first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
|
|
|
- bf_get(lpfc_rcqe_length,
|
|
|
- &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
|
|
|
+
|
|
|
+ /* 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);
|
|
|
+ iocbq->iocb.unsli3.rcvsli3.acc_len += len;
|
|
|
+ tot_len += len;
|
|
|
} else {
|
|
|
iocbq = lpfc_sli_get_iocbq(vport->phba);
|
|
|
if (!iocbq) {
|
|
@@ -13711,9 +13728,14 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
iocbq->iocb.ulpBdeCount = 1;
|
|
|
iocbq->iocb.un.cont64[0].tus.f.bdeSize =
|
|
|
LPFC_DATA_BUF_SIZE;
|
|
|
- first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
|
|
|
- bf_get(lpfc_rcqe_length,
|
|
|
- &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
|
|
|
+
|
|
|
+ /* 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);
|
|
|
+ tot_len += len;
|
|
|
+ iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
|
|
|
+
|
|
|
iocbq->iocb.un.rcvels.remoteID = sid;
|
|
|
list_add_tail(&iocbq->list, &first_iocbq->list);
|
|
|
}
|
|
@@ -13786,7 +13808,13 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
|
|
|
lpfc_in_buf_free(phba, &dmabuf->dbuf);
|
|
|
return;
|
|
|
}
|
|
|
- fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl);
|
|
|
+ if ((bf_get(lpfc_cqe_code,
|
|
|
+ &dmabuf->cq_event.cqe.rcqe_cmpl) == CQE_CODE_RECEIVE_V1))
|
|
|
+ fcfi = bf_get(lpfc_rcqe_fcf_id_v1,
|
|
|
+ &dmabuf->cq_event.cqe.rcqe_cmpl);
|
|
|
+ else
|
|
|
+ fcfi = bf_get(lpfc_rcqe_fcf_id,
|
|
|
+ &dmabuf->cq_event.cqe.rcqe_cmpl);
|
|
|
vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
|
|
|
if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) {
|
|
|
/* throw out the frame */
|