|
@@ -7907,6 +7907,10 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
bf_set(els_req64_sp, &wqe->els_req, 1);
|
|
|
bf_set(els_req64_sid, &wqe->els_req,
|
|
|
iocbq->vport->fc_myDID);
|
|
|
+ if ((*pcmd == ELS_CMD_FLOGI) &&
|
|
|
+ !(phba->fc_topology ==
|
|
|
+ LPFC_TOPOLOGY_LOOP))
|
|
|
+ bf_set(els_req64_sid, &wqe->els_req, 0);
|
|
|
bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
|
|
|
bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
|
|
|
phba->vpi_ids[iocbq->vport->vpi]);
|
|
@@ -8064,11 +8068,25 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
/* words0-2 BDE memcpy */
|
|
|
/* word3 iocb=iotag32 wqe=response_payload_len */
|
|
|
wqe->xmit_els_rsp.response_payload_len = xmit_len;
|
|
|
- /* word4 iocb=did wge=rsvd. */
|
|
|
- wqe->xmit_els_rsp.rsvd4 = 0;
|
|
|
+ /* word4 */
|
|
|
+ wqe->xmit_els_rsp.word4 = 0;
|
|
|
/* word5 iocb=rsvd wge=did */
|
|
|
bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
|
|
|
- iocbq->iocb.un.elsreq64.remoteID);
|
|
|
+ iocbq->iocb.un.xseq64.xmit_els_remoteID);
|
|
|
+
|
|
|
+ if_type = bf_get(lpfc_sli_intf_if_type,
|
|
|
+ &phba->sli4_hba.sli_intf);
|
|
|
+ if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
|
|
|
+ if (iocbq->vport->fc_flag & FC_PT2PT) {
|
|
|
+ bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
|
|
|
+ bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
|
|
|
+ iocbq->vport->fc_myDID);
|
|
|
+ if (iocbq->vport->fc_myDID == Fabric_DID) {
|
|
|
+ bf_set(wqe_els_did,
|
|
|
+ &wqe->xmit_els_rsp.wqe_dest, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com,
|
|
|
((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
|
|
|
bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU);
|
|
@@ -8088,11 +8106,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
|
|
|
pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
|
|
|
iocbq->context2)->virt);
|
|
|
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
|
|
|
- bf_set(els_req64_sp, &wqe->els_req, 1);
|
|
|
- bf_set(els_req64_sid, &wqe->els_req,
|
|
|
+ bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
|
|
|
+ bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
|
|
|
iocbq->vport->fc_myDID);
|
|
|
- bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
|
|
|
- bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
|
|
|
+ bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 1);
|
|
|
+ bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
|
|
|
phba->vpi_ids[phba->pport->vpi]);
|
|
|
}
|
|
|
command_type = OTHER_COMMAND;
|
|
@@ -13636,8 +13654,13 @@ lpfc_fc_frame_to_vport(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr,
|
|
|
uint32_t did = (fc_hdr->fh_d_id[0] << 16 |
|
|
|
fc_hdr->fh_d_id[1] << 8 |
|
|
|
fc_hdr->fh_d_id[2]);
|
|
|
+
|
|
|
if (did == Fabric_DID)
|
|
|
return phba->pport;
|
|
|
+ if ((phba->pport->fc_flag & FC_PT2PT) &&
|
|
|
+ !(phba->link_state == LPFC_HBA_READY))
|
|
|
+ return phba->pport;
|
|
|
+
|
|
|
vports = lpfc_create_vport_work_array(phba);
|
|
|
if (vports != NULL)
|
|
|
for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
|
@@ -14174,7 +14197,15 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
|
|
|
/* Initialize the first IOCB. */
|
|
|
first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
|
|
|
first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
|
|
|
- first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
|
|
|
+
|
|
|
+ /* Check FC Header to see what TYPE of frame we are rcv'ing */
|
|
|
+ if (sli4_type_from_fc_hdr(fc_hdr) == FC_TYPE_ELS) {
|
|
|
+ first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_ELS64_CX;
|
|
|
+ first_iocbq->iocb.un.rcvels.parmRo =
|
|
|
+ sli4_did_from_fc_hdr(fc_hdr);
|
|
|
+ first_iocbq->iocb.ulpPU = PARM_NPIV_DID;
|
|
|
+ } else
|
|
|
+ first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
|
|
|
first_iocbq->iocb.ulpContext = NO_XRI;
|
|
|
first_iocbq->iocb.unsli3.rcvsli3.ox_id =
|
|
|
be16_to_cpu(fc_hdr->fh_ox_id);
|
|
@@ -14304,6 +14335,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
|
|
|
struct fc_frame_header *fc_hdr;
|
|
|
struct lpfc_vport *vport;
|
|
|
uint32_t fcfi;
|
|
|
+ uint32_t did;
|
|
|
|
|
|
/* Process each received buffer */
|
|
|
fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
|
|
@@ -14319,12 +14351,32 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
|
|
|
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)) {
|
|
|
+ if (!vport) {
|
|
|
/* throw out the frame */
|
|
|
lpfc_in_buf_free(phba, &dmabuf->dbuf);
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ /* d_id this frame is directed to */
|
|
|
+ did = sli4_did_from_fc_hdr(fc_hdr);
|
|
|
+
|
|
|
+ /* vport is registered unless we rcv a FLOGI directed to Fabric_DID */
|
|
|
+ if (!(vport->vpi_state & LPFC_VPI_REGISTERED) &&
|
|
|
+ (did != Fabric_DID)) {
|
|
|
+ /*
|
|
|
+ * Throw out the frame if we are not pt2pt.
|
|
|
+ * The pt2pt protocol allows for discovery frames
|
|
|
+ * to be received without a registered VPI.
|
|
|
+ */
|
|
|
+ if (!(vport->fc_flag & FC_PT2PT) ||
|
|
|
+ (phba->link_state == LPFC_HBA_READY)) {
|
|
|
+ lpfc_in_buf_free(phba, &dmabuf->dbuf);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* Handle the basic abort sequence (BA_ABTS) event */
|
|
|
if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
|
|
|
lpfc_sli4_handle_unsol_abort(vport, dmabuf);
|