aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c93
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h8
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c70
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h8
7 files changed, 175 insertions, 31 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 95cff9909eff..379397d17aca 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -230,27 +230,43 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
230 230
231 INIT_LIST_HEAD(&pbuflist->list); 231 INIT_LIST_HEAD(&pbuflist->list);
232 232
233 icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
234 icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
235 icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
236 icmd->un.elsreq64.remoteID = did; /* DID */
237 if (expectRsp) { 233 if (expectRsp) {
234 icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
235 icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
236 icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
238 icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64)); 237 icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
238
239 icmd->un.elsreq64.remoteID = did; /* DID */
239 icmd->ulpCommand = CMD_ELS_REQUEST64_CR; 240 icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
240 icmd->ulpTimeout = phba->fc_ratov * 2; 241 icmd->ulpTimeout = phba->fc_ratov * 2;
241 } else { 242 } else {
242 icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64); 243 icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
244 icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
245 icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
246 icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64);
247 icmd->un.xseq64.xmit_els_remoteID = did; /* DID */
243 icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; 248 icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
244 } 249 }
245 icmd->ulpBdeCount = 1; 250 icmd->ulpBdeCount = 1;
246 icmd->ulpLe = 1; 251 icmd->ulpLe = 1;
247 icmd->ulpClass = CLASS3; 252 icmd->ulpClass = CLASS3;
248 253
249 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { 254 /*
250 icmd->un.elsreq64.myID = vport->fc_myDID; 255 * If we have NPIV enabled, we want to send ELS traffic by VPI.
256 * For SLI4, since the driver controls VPIs we also want to include
257 * all ELS pt2pt protocol traffic as well.
258 */
259 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) ||
260 ((phba->sli_rev == LPFC_SLI_REV4) &&
261 (vport->fc_flag & FC_PT2PT))) {
262
263 if (expectRsp) {
264 icmd->un.elsreq64.myID = vport->fc_myDID;
265
266 /* For ELS_REQUEST64_CR, use the VPI by default */
267 icmd->ulpContext = phba->vpi_ids[vport->vpi];
268 }
251 269
252 /* For ELS_REQUEST64_CR, use the VPI by default */
253 icmd->ulpContext = phba->vpi_ids[vport->vpi];
254 icmd->ulpCt_h = 0; 270 icmd->ulpCt_h = 0;
255 /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ 271 /* The CT field must be 0=INVALID_RPI for the ECHO cmd */
256 if (elscmd == ELS_CMD_ECHO) 272 if (elscmd == ELS_CMD_ECHO)
@@ -438,9 +454,10 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
438 int rc = 0; 454 int rc = 0;
439 455
440 sp = &phba->fc_fabparam; 456 sp = &phba->fc_fabparam;
441 /* move forward in case of SLI4 FC port loopback test */ 457 /* move forward in case of SLI4 FC port loopback test and pt2pt mode */
442 if ((phba->sli_rev == LPFC_SLI_REV4) && 458 if ((phba->sli_rev == LPFC_SLI_REV4) &&
443 !(phba->link_flag & LS_LOOPBACK_MODE)) { 459 !(phba->link_flag & LS_LOOPBACK_MODE) &&
460 !(vport->fc_flag & FC_PT2PT)) {
444 ndlp = lpfc_findnode_did(vport, Fabric_DID); 461 ndlp = lpfc_findnode_did(vport, Fabric_DID);
445 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { 462 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
446 rc = -ENODEV; 463 rc = -ENODEV;
@@ -820,6 +837,17 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
820 mempool_free(mbox, phba->mbox_mem_pool); 837 mempool_free(mbox, phba->mbox_mem_pool);
821 goto fail; 838 goto fail;
822 } 839 }
840
841 /*
842 * For SLI4, the VFI/VPI are registered AFTER the
843 * Nport with the higher WWPN sends the PLOGI with
844 * an assigned NPortId.
845 */
846
847 /* not equal */
848 if ((phba->sli_rev == LPFC_SLI_REV4) && rc)
849 lpfc_issue_reg_vfi(vport);
850
823 /* Decrement ndlp reference count indicating that ndlp can be 851 /* Decrement ndlp reference count indicating that ndlp can be
824 * safely released when other references to it are done. 852 * safely released when other references to it are done.
825 */ 853 */
@@ -4940,8 +4968,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4940 return 1; 4968 return 1;
4941 } 4969 }
4942 4970
4943 did = Fabric_DID;
4944
4945 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) { 4971 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
4946 /* For a FLOGI we accept, then if our portname is greater 4972 /* For a FLOGI we accept, then if our portname is greater
4947 * then the remote portname we initiate Nport login. 4973 * then the remote portname we initiate Nport login.
@@ -4980,29 +5006,64 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4980 spin_lock_irq(shost->host_lock); 5006 spin_lock_irq(shost->host_lock);
4981 vport->fc_flag |= FC_PT2PT_PLOGI; 5007 vport->fc_flag |= FC_PT2PT_PLOGI;
4982 spin_unlock_irq(shost->host_lock); 5008 spin_unlock_irq(shost->host_lock);
5009
5010 /* If we have the high WWPN we can assign our own
5011 * myDID; otherwise, we have to WAIT for a PLOGI
5012 * from the remote NPort to find out what it
5013 * will be.
5014 */
4983 vport->fc_myDID = PT2PT_LocalID; 5015 vport->fc_myDID = PT2PT_LocalID;
4984 } else 5016 }
4985 vport->fc_myDID = PT2PT_RemoteID; 5017
4986 vport->port_state = LPFC_FLOGI; 5018 /*
5019 * The vport state should go to LPFC_FLOGI only
5020 * AFTER we issue a FLOGI, not receive one.
5021 */
4987 spin_lock_irq(shost->host_lock); 5022 spin_lock_irq(shost->host_lock);
4988 vport->fc_flag |= FC_PT2PT; 5023 vport->fc_flag |= FC_PT2PT;
4989 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); 5024 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
4990 spin_unlock_irq(shost->host_lock); 5025 spin_unlock_irq(shost->host_lock);
5026
5027 /*
5028 * We temporarily set fc_myDID to make it look like we are
5029 * a Fabric. This is done just so we end up with the right
5030 * did / sid on the FLOGI ACC rsp.
5031 */
5032 did = vport->fc_myDID;
5033 vport->fc_myDID = Fabric_DID;
5034
4991 } else { 5035 } else {
4992 /* Reject this request because invalid parameters */ 5036 /* Reject this request because invalid parameters */
4993 stat.un.b.lsRjtRsvd0 = 0; 5037 stat.un.b.lsRjtRsvd0 = 0;
4994 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 5038 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
4995 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; 5039 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
4996 stat.un.b.vendorUnique = 0; 5040 stat.un.b.vendorUnique = 0;
5041
5042 /*
5043 * We temporarily set fc_myDID to make it look like we are
5044 * a Fabric. This is done just so we end up with the right
5045 * did / sid on the FLOGI LS_RJT rsp.
5046 */
5047 did = vport->fc_myDID;
5048 vport->fc_myDID = Fabric_DID;
5049
4997 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, 5050 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
4998 NULL); 5051 NULL);
5052
5053 /* Now lets put fc_myDID back to what its supposed to be */
5054 vport->fc_myDID = did;
5055
4999 return 1; 5056 return 1;
5000 } 5057 }
5001 5058
5002 /* Send back ACC */ 5059 /* Send back ACC */
5003 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); 5060 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
5004 5061
5062 /* Now lets put fc_myDID back to what its supposed to be */
5063 vport->fc_myDID = did;
5064
5005 if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { 5065 if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
5066
5006 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 5067 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
5007 if (!mbox) 5068 if (!mbox)
5008 goto fail; 5069 goto fail;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 3986165b0275..5bb269e224f6 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -2882,9 +2882,14 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
2882 } 2882 }
2883 2883
2884 if (vport->port_state == LPFC_FABRIC_CFG_LINK) { 2884 if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
2885 /* For private loop just start discovery and we are done. */ 2885 /*
2886 if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && 2886 * For private loop or for NPort pt2pt,
2887 !(vport->fc_flag & FC_PUBLIC_LOOP)) { 2887 * just start discovery and we are done.
2888 */
2889 if ((vport->fc_flag & FC_PT2PT) ||
2890 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
2891 !(vport->fc_flag & FC_PUBLIC_LOOP))) {
2892
2888 /* Use loop map to make discovery list */ 2893 /* Use loop map to make discovery list */
2889 lpfc_disc_list_loopmap(vport); 2894 lpfc_disc_list_loopmap(vport);
2890 /* Start discovery */ 2895 /* Start discovery */
@@ -5491,9 +5496,9 @@ lpfc_nlp_release(struct kref *kref)
5491 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); 5496 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
5492 5497
5493 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, 5498 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
5494 "0279 lpfc_nlp_release: ndlp:x%p " 5499 "0279 lpfc_nlp_release: ndlp:x%p did %x "
5495 "usgmap:x%x refcnt:%d\n", 5500 "usgmap:x%x refcnt:%d\n",
5496 (void *)ndlp, ndlp->nlp_usg_map, 5501 (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map,
5497 atomic_read(&ndlp->kref.refcount)); 5502 atomic_read(&ndlp->kref.refcount));
5498 5503
5499 /* remove ndlp from action. */ 5504 /* remove ndlp from action. */
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 5f280b5ae3db..41bb1d2fb625 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -3374,6 +3374,9 @@ typedef struct {
3374 WORD5 w5; /* Header control/status word */ 3374 WORD5 w5; /* Header control/status word */
3375} XMT_SEQ_FIELDS64; 3375} XMT_SEQ_FIELDS64;
3376 3376
3377/* This word is remote ports D_ID for XMIT_ELS_RSP64 */
3378#define xmit_els_remoteID xrsqRo
3379
3377/* IOCB Command template for 64 bit RCV_SEQUENCE64 */ 3380/* IOCB Command template for 64 bit RCV_SEQUENCE64 */
3378typedef struct { 3381typedef struct {
3379 struct ulp_bde64 rcvBde; 3382 struct ulp_bde64 rcvBde;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 24344c1fab5a..f1946dfda5b4 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3295,7 +3295,13 @@ struct els_request64_wqe {
3295struct xmit_els_rsp64_wqe { 3295struct xmit_els_rsp64_wqe {
3296 struct ulp_bde64 bde; 3296 struct ulp_bde64 bde;
3297 uint32_t response_payload_len; 3297 uint32_t response_payload_len;
3298 uint32_t rsvd4; 3298 uint32_t word4;
3299#define els_rsp64_sid_SHIFT 0
3300#define els_rsp64_sid_MASK 0x00FFFFFF
3301#define els_rsp64_sid_WORD word4
3302#define els_rsp64_sp_SHIFT 24
3303#define els_rsp64_sp_MASK 0x00000001
3304#define els_rsp64_sp_WORD word4
3299 struct wqe_did wqe_dest; 3305 struct wqe_did wqe_dest;
3300 struct wqe_common wqe_com; /* words 6-11 */ 3306 struct wqe_common wqe_com; /* words 6-11 */
3301 uint32_t word12; 3307 uint32_t word12;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 15ca2a9a0cdd..9133a97f045f 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -367,8 +367,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
367 return 1; 367 return 1;
368 } 368 }
369 369
370 /* Check for Nport to NPort pt2pt protocol */
370 if ((vport->fc_flag & FC_PT2PT) && 371 if ((vport->fc_flag & FC_PT2PT) &&
371 !(vport->fc_flag & FC_PT2PT_PLOGI)) { 372 !(vport->fc_flag & FC_PT2PT_PLOGI)) {
373
372 /* rcv'ed PLOGI decides what our NPortId will be */ 374 /* rcv'ed PLOGI decides what our NPortId will be */
373 vport->fc_myDID = icmd->un.rcvels.parmRo; 375 vport->fc_myDID = icmd->un.rcvels.parmRo;
374 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 376 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -382,6 +384,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
382 mempool_free(mbox, phba->mbox_mem_pool); 384 mempool_free(mbox, phba->mbox_mem_pool);
383 goto out; 385 goto out;
384 } 386 }
387 /*
388 * For SLI4, the VFI/VPI are registered AFTER the
389 * Nport with the higher WWPN sends us a PLOGI with
390 * our assigned NPortId.
391 */
392 if (phba->sli_rev == LPFC_SLI_REV4)
393 lpfc_issue_reg_vfi(vport);
385 394
386 lpfc_can_disctmo(vport); 395 lpfc_can_disctmo(vport);
387 } 396 }
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index b035e5badd52..e84dd32553bc 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -7907,6 +7907,10 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
7907 bf_set(els_req64_sp, &wqe->els_req, 1); 7907 bf_set(els_req64_sp, &wqe->els_req, 1);
7908 bf_set(els_req64_sid, &wqe->els_req, 7908 bf_set(els_req64_sid, &wqe->els_req,
7909 iocbq->vport->fc_myDID); 7909 iocbq->vport->fc_myDID);
7910 if ((*pcmd == ELS_CMD_FLOGI) &&
7911 !(phba->fc_topology ==
7912 LPFC_TOPOLOGY_LOOP))
7913 bf_set(els_req64_sid, &wqe->els_req, 0);
7910 bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); 7914 bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
7911 bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, 7915 bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
7912 phba->vpi_ids[iocbq->vport->vpi]); 7916 phba->vpi_ids[iocbq->vport->vpi]);
@@ -8064,11 +8068,25 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8064 /* words0-2 BDE memcpy */ 8068 /* words0-2 BDE memcpy */
8065 /* word3 iocb=iotag32 wqe=response_payload_len */ 8069 /* word3 iocb=iotag32 wqe=response_payload_len */
8066 wqe->xmit_els_rsp.response_payload_len = xmit_len; 8070 wqe->xmit_els_rsp.response_payload_len = xmit_len;
8067 /* word4 iocb=did wge=rsvd. */ 8071 /* word4 */
8068 wqe->xmit_els_rsp.rsvd4 = 0; 8072 wqe->xmit_els_rsp.word4 = 0;
8069 /* word5 iocb=rsvd wge=did */ 8073 /* word5 iocb=rsvd wge=did */
8070 bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest, 8074 bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
8071 iocbq->iocb.un.elsreq64.remoteID); 8075 iocbq->iocb.un.xseq64.xmit_els_remoteID);
8076
8077 if_type = bf_get(lpfc_sli_intf_if_type,
8078 &phba->sli4_hba.sli_intf);
8079 if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
8080 if (iocbq->vport->fc_flag & FC_PT2PT) {
8081 bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
8082 bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
8083 iocbq->vport->fc_myDID);
8084 if (iocbq->vport->fc_myDID == Fabric_DID) {
8085 bf_set(wqe_els_did,
8086 &wqe->xmit_els_rsp.wqe_dest, 0);
8087 }
8088 }
8089 }
8072 bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 8090 bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com,
8073 ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l)); 8091 ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
8074 bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU); 8092 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,
8088 pcmd = (uint32_t *) (((struct lpfc_dmabuf *) 8106 pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
8089 iocbq->context2)->virt); 8107 iocbq->context2)->virt);
8090 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { 8108 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
8091 bf_set(els_req64_sp, &wqe->els_req, 1); 8109 bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
8092 bf_set(els_req64_sid, &wqe->els_req, 8110 bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
8093 iocbq->vport->fc_myDID); 8111 iocbq->vport->fc_myDID);
8094 bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); 8112 bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 1);
8095 bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, 8113 bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
8096 phba->vpi_ids[phba->pport->vpi]); 8114 phba->vpi_ids[phba->pport->vpi]);
8097 } 8115 }
8098 command_type = OTHER_COMMAND; 8116 command_type = OTHER_COMMAND;
@@ -13636,8 +13654,13 @@ lpfc_fc_frame_to_vport(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr,
13636 uint32_t did = (fc_hdr->fh_d_id[0] << 16 | 13654 uint32_t did = (fc_hdr->fh_d_id[0] << 16 |
13637 fc_hdr->fh_d_id[1] << 8 | 13655 fc_hdr->fh_d_id[1] << 8 |
13638 fc_hdr->fh_d_id[2]); 13656 fc_hdr->fh_d_id[2]);
13657
13639 if (did == Fabric_DID) 13658 if (did == Fabric_DID)
13640 return phba->pport; 13659 return phba->pport;
13660 if ((phba->pport->fc_flag & FC_PT2PT) &&
13661 !(phba->link_state == LPFC_HBA_READY))
13662 return phba->pport;
13663
13641 vports = lpfc_create_vport_work_array(phba); 13664 vports = lpfc_create_vport_work_array(phba);
13642 if (vports != NULL) 13665 if (vports != NULL)
13643 for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { 13666 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)
14174 /* Initialize the first IOCB. */ 14197 /* Initialize the first IOCB. */
14175 first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0; 14198 first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
14176 first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; 14199 first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
14177 first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; 14200
14201 /* Check FC Header to see what TYPE of frame we are rcv'ing */
14202 if (sli4_type_from_fc_hdr(fc_hdr) == FC_TYPE_ELS) {
14203 first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_ELS64_CX;
14204 first_iocbq->iocb.un.rcvels.parmRo =
14205 sli4_did_from_fc_hdr(fc_hdr);
14206 first_iocbq->iocb.ulpPU = PARM_NPIV_DID;
14207 } else
14208 first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
14178 first_iocbq->iocb.ulpContext = NO_XRI; 14209 first_iocbq->iocb.ulpContext = NO_XRI;
14179 first_iocbq->iocb.unsli3.rcvsli3.ox_id = 14210 first_iocbq->iocb.unsli3.rcvsli3.ox_id =
14180 be16_to_cpu(fc_hdr->fh_ox_id); 14211 be16_to_cpu(fc_hdr->fh_ox_id);
@@ -14304,6 +14335,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
14304 struct fc_frame_header *fc_hdr; 14335 struct fc_frame_header *fc_hdr;
14305 struct lpfc_vport *vport; 14336 struct lpfc_vport *vport;
14306 uint32_t fcfi; 14337 uint32_t fcfi;
14338 uint32_t did;
14307 14339
14308 /* Process each received buffer */ 14340 /* Process each received buffer */
14309 fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; 14341 fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
@@ -14319,12 +14351,32 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
14319 else 14351 else
14320 fcfi = bf_get(lpfc_rcqe_fcf_id, 14352 fcfi = bf_get(lpfc_rcqe_fcf_id,
14321 &dmabuf->cq_event.cqe.rcqe_cmpl); 14353 &dmabuf->cq_event.cqe.rcqe_cmpl);
14354
14322 vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi); 14355 vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
14323 if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) { 14356 if (!vport) {
14324 /* throw out the frame */ 14357 /* throw out the frame */
14325 lpfc_in_buf_free(phba, &dmabuf->dbuf); 14358 lpfc_in_buf_free(phba, &dmabuf->dbuf);
14326 return; 14359 return;
14327 } 14360 }
14361
14362 /* d_id this frame is directed to */
14363 did = sli4_did_from_fc_hdr(fc_hdr);
14364
14365 /* vport is registered unless we rcv a FLOGI directed to Fabric_DID */
14366 if (!(vport->vpi_state & LPFC_VPI_REGISTERED) &&
14367 (did != Fabric_DID)) {
14368 /*
14369 * Throw out the frame if we are not pt2pt.
14370 * The pt2pt protocol allows for discovery frames
14371 * to be received without a registered VPI.
14372 */
14373 if (!(vport->fc_flag & FC_PT2PT) ||
14374 (phba->link_state == LPFC_HBA_READY)) {
14375 lpfc_in_buf_free(phba, &dmabuf->dbuf);
14376 return;
14377 }
14378 }
14379
14328 /* Handle the basic abort sequence (BA_ABTS) event */ 14380 /* Handle the basic abort sequence (BA_ABTS) event */
14329 if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) { 14381 if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
14330 lpfc_sli4_handle_unsol_abort(vport, dmabuf); 14382 lpfc_sli4_handle_unsol_abort(vport, dmabuf);
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index f097382d7b91..a4a77080091b 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -75,11 +75,19 @@
75 (fc_hdr)->fh_s_id[1] << 8 | \ 75 (fc_hdr)->fh_s_id[1] << 8 | \
76 (fc_hdr)->fh_s_id[2]) 76 (fc_hdr)->fh_s_id[2])
77 77
78#define sli4_did_from_fc_hdr(fc_hdr) \
79 ((fc_hdr)->fh_d_id[0] << 16 | \
80 (fc_hdr)->fh_d_id[1] << 8 | \
81 (fc_hdr)->fh_d_id[2])
82
78#define sli4_fctl_from_fc_hdr(fc_hdr) \ 83#define sli4_fctl_from_fc_hdr(fc_hdr) \
79 ((fc_hdr)->fh_f_ctl[0] << 16 | \ 84 ((fc_hdr)->fh_f_ctl[0] << 16 | \
80 (fc_hdr)->fh_f_ctl[1] << 8 | \ 85 (fc_hdr)->fh_f_ctl[1] << 8 | \
81 (fc_hdr)->fh_f_ctl[2]) 86 (fc_hdr)->fh_f_ctl[2])
82 87
88#define sli4_type_from_fc_hdr(fc_hdr) \
89 ((fc_hdr)->fh_type)
90
83#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000 91#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000
84 92
85enum lpfc_sli4_queue_type { 93enum lpfc_sli4_queue_type {