diff options
author | James Smart <jsmart2021@gmail.com> | 2017-02-12 16:52:36 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-02-22 18:41:43 -0500 |
commit | 8c258641e01cfcc5620c4fb191300bea224bcc99 (patch) | |
tree | 624fe23d85243c2c8c891fed355901a1c5a532cd | |
parent | 2d7dbc4c2775eb30df97be00090adbfcc7fc5086 (diff) |
scsi: lpfc: NVME Target: Merge into FC discovery
NVME Target: Merge into FC discovery
Adds NVME PRLI handling and Nameserver registrations for NVME
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 8 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 61 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 27 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 75 |
5 files changed, 167 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 2c051369857a..d576da4d3afb 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -1433,7 +1433,13 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1433 | if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | 1433 | if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
1434 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) && | 1434 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) && |
1435 | (context == FC_TYPE_NVME)) { | 1435 | (context == FC_TYPE_NVME)) { |
1436 | lpfc_nvme_update_localport(vport); | 1436 | if ((vport == phba->pport) && phba->nvmet_support) { |
1437 | CtReq->un.rff.fbits = (FC4_FEATURE_TARGET | | ||
1438 | FC4_FEATURE_NVME_DISC); | ||
1439 | /* todo: update targetport attributes */ | ||
1440 | } else { | ||
1441 | lpfc_nvme_update_localport(vport); | ||
1442 | } | ||
1437 | CtReq->un.rff.type_code = context; | 1443 | CtReq->un.rff.type_code = context; |
1438 | 1444 | ||
1439 | } else if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | 1445 | } else if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 23546b3c950c..5ee3ae88a080 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -2001,11 +2001,21 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
2001 | sp->cmn.fcphHigh = FC_PH3; | 2001 | sp->cmn.fcphHigh = FC_PH3; |
2002 | 2002 | ||
2003 | sp->cmn.valid_vendor_ver_level = 0; | 2003 | sp->cmn.valid_vendor_ver_level = 0; |
2004 | memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion)); | ||
2004 | 2005 | ||
2005 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | 2006 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, |
2006 | "Issue PLOGI: did:x%x", | 2007 | "Issue PLOGI: did:x%x", |
2007 | did, 0, 0); | 2008 | did, 0, 0); |
2008 | 2009 | ||
2010 | /* If our firmware supports this feature, convey that | ||
2011 | * information to the target using the vendor specific field. | ||
2012 | */ | ||
2013 | if (phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) { | ||
2014 | sp->cmn.valid_vendor_ver_level = 1; | ||
2015 | sp->un.vv.vid = cpu_to_be32(LPFC_VV_EMLX_ID); | ||
2016 | sp->un.vv.flags = cpu_to_be32(LPFC_VV_SUPPRESS_RSP); | ||
2017 | } | ||
2018 | |||
2009 | phba->fc_stat.elsXmitPLOGI++; | 2019 | phba->fc_stat.elsXmitPLOGI++; |
2010 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; | 2020 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; |
2011 | ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); | 2021 | ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
@@ -2207,7 +2217,13 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2207 | !phba->nvmet_support) | 2217 | !phba->nvmet_support) |
2208 | bf_set(prli_fba, npr_nvme, 1); | 2218 | bf_set(prli_fba, npr_nvme, 1); |
2209 | 2219 | ||
2210 | bf_set(prli_init, npr_nvme, 1); | 2220 | if (phba->nvmet_support) { |
2221 | bf_set(prli_tgt, npr_nvme, 1); | ||
2222 | bf_set(prli_disc, npr_nvme, 1); | ||
2223 | |||
2224 | } else { | ||
2225 | bf_set(prli_init, npr_nvme, 1); | ||
2226 | } | ||
2211 | npr_nvme->word1 = cpu_to_be32(npr_nvme->word1); | 2227 | npr_nvme->word1 = cpu_to_be32(npr_nvme->word1); |
2212 | npr_nvme->word4 = cpu_to_be32(npr_nvme->word4); | 2228 | npr_nvme->word4 = cpu_to_be32(npr_nvme->word4); |
2213 | elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ; | 2229 | elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ; |
@@ -2619,8 +2635,11 @@ out: | |||
2619 | phba->pport->fc_myDID = 0; | 2635 | phba->pport->fc_myDID = 0; |
2620 | 2636 | ||
2621 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | 2637 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
2622 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) | 2638 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { |
2623 | lpfc_nvme_update_localport(phba->pport); | 2639 | if (!phba->nvmet_support) |
2640 | lpfc_nvme_update_localport(phba->pport); | ||
2641 | /* todo: tgt: update targetport attributes */ | ||
2642 | } | ||
2624 | 2643 | ||
2625 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 2644 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2626 | if (mbox) { | 2645 | if (mbox) { |
@@ -4074,10 +4093,25 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
4074 | sizeof(struct lpfc_name)); | 4093 | sizeof(struct lpfc_name)); |
4075 | memcpy(&sp->nodeName, &vport->fc_sparam.nodeName, | 4094 | memcpy(&sp->nodeName, &vport->fc_sparam.nodeName, |
4076 | sizeof(struct lpfc_name)); | 4095 | sizeof(struct lpfc_name)); |
4077 | } else | 4096 | } else { |
4078 | memcpy(pcmd, &vport->fc_sparam, | 4097 | memcpy(pcmd, &vport->fc_sparam, |
4079 | sizeof(struct serv_parm)); | 4098 | sizeof(struct serv_parm)); |
4080 | 4099 | ||
4100 | sp->cmn.valid_vendor_ver_level = 0; | ||
4101 | memset(sp->un.vendorVersion, 0, | ||
4102 | sizeof(sp->un.vendorVersion)); | ||
4103 | |||
4104 | /* If our firmware supports this feature, convey that | ||
4105 | * info to the target using the vendor specific field. | ||
4106 | */ | ||
4107 | if (phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) { | ||
4108 | sp->cmn.valid_vendor_ver_level = 1; | ||
4109 | sp->un.vv.vid = cpu_to_be32(LPFC_VV_EMLX_ID); | ||
4110 | sp->un.vv.flags = | ||
4111 | cpu_to_be32(LPFC_VV_SUPPRESS_RSP); | ||
4112 | } | ||
4113 | } | ||
4114 | |||
4081 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | 4115 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, |
4082 | "Issue ACC FLOGI/PLOGI: did:x%x flg:x%x", | 4116 | "Issue ACC FLOGI/PLOGI: did:x%x flg:x%x", |
4083 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | 4117 | ndlp->nlp_DID, ndlp->nlp_flag, 0); |
@@ -4397,7 +4431,22 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
4397 | bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE); | 4431 | bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE); |
4398 | bf_set(prli_estabImagePair, npr_nvme, 0); /* Should be 0 */ | 4432 | bf_set(prli_estabImagePair, npr_nvme, 0); /* Should be 0 */ |
4399 | bf_set(prli_acc_rsp_code, npr_nvme, PRLI_REQ_EXECUTED); | 4433 | bf_set(prli_acc_rsp_code, npr_nvme, PRLI_REQ_EXECUTED); |
4400 | bf_set(prli_init, npr_nvme, 1); | 4434 | if (phba->nvmet_support) { |
4435 | bf_set(prli_tgt, npr_nvme, 1); | ||
4436 | bf_set(prli_disc, npr_nvme, 1); | ||
4437 | if (phba->cfg_nvme_enable_fb) { | ||
4438 | bf_set(prli_fba, npr_nvme, 1); | ||
4439 | |||
4440 | /* TBD. Target mode needs to post buffers | ||
4441 | * that support the configured first burst | ||
4442 | * byte size. | ||
4443 | */ | ||
4444 | bf_set(prli_fb_sz, npr_nvme, | ||
4445 | phba->cfg_nvmet_fb_size); | ||
4446 | } | ||
4447 | } else { | ||
4448 | bf_set(prli_init, npr_nvme, 1); | ||
4449 | } | ||
4401 | 4450 | ||
4402 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, | 4451 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, |
4403 | "6015 NVME issue PRLI ACC word1 x%08x " | 4452 | "6015 NVME issue PRLI ACC word1 x%08x " |
@@ -5815,6 +5864,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) | |||
5815 | (ndlp->nlp_state == NLP_STE_UNUSED_NODE) || | 5864 | (ndlp->nlp_state == NLP_STE_UNUSED_NODE) || |
5816 | !lpfc_rscn_payload_check(vport, ndlp->nlp_DID)) | 5865 | !lpfc_rscn_payload_check(vport, ndlp->nlp_DID)) |
5817 | continue; | 5866 | continue; |
5867 | if (vport->phba->nvmet_support) | ||
5868 | continue; | ||
5818 | lpfc_disc_state_machine(vport, ndlp, NULL, | 5869 | lpfc_disc_state_machine(vport, ndlp, NULL, |
5819 | NLP_EVT_DEVICE_RECOVERY); | 5870 | NLP_EVT_DEVICE_RECOVERY); |
5820 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | 5871 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 8936f5d91c87..6bbb988dd8da 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -910,8 +910,11 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
910 | vports[i]->fc_myDID = 0; | 910 | vports[i]->fc_myDID = 0; |
911 | 911 | ||
912 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | 912 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
913 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) | 913 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { |
914 | lpfc_nvme_update_localport(vports[i]); | 914 | if (!phba->nvmet_support) |
915 | lpfc_nvme_update_localport(vports[i]); | ||
916 | /* todo: tgt: update targetport attributes */ | ||
917 | } | ||
915 | } | 918 | } |
916 | } | 919 | } |
917 | lpfc_destroy_vport_work_array(phba, vports); | 920 | lpfc_destroy_vport_work_array(phba, vports); |
@@ -3583,8 +3586,11 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3583 | vport->fc_myDID = 0; | 3586 | vport->fc_myDID = 0; |
3584 | 3587 | ||
3585 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | 3588 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
3586 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) | 3589 | (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { |
3587 | lpfc_nvme_update_localport(vport); | 3590 | if (!phba->nvmet_support) |
3591 | lpfc_nvme_update_localport(vport); | ||
3592 | /* todo: update targetport attributes */ | ||
3593 | } | ||
3588 | goto out; | 3594 | goto out; |
3589 | } | 3595 | } |
3590 | 3596 | ||
@@ -4175,6 +4181,11 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4175 | */ | 4181 | */ |
4176 | vport->phba->nport_event_cnt++; | 4182 | vport->phba->nport_event_cnt++; |
4177 | lpfc_nvme_register_port(vport, ndlp); | 4183 | lpfc_nvme_register_port(vport, ndlp); |
4184 | } else { | ||
4185 | /* Just take an NDLP ref count since the | ||
4186 | * target does not register rports. | ||
4187 | */ | ||
4188 | lpfc_nlp_get(ndlp); | ||
4178 | } | 4189 | } |
4179 | } | 4190 | } |
4180 | } | 4191 | } |
@@ -5096,6 +5107,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
5096 | return NULL; | 5107 | return NULL; |
5097 | lpfc_nlp_init(vport, ndlp, did); | 5108 | lpfc_nlp_init(vport, ndlp, did); |
5098 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 5109 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
5110 | if (vport->phba->nvmet_support) | ||
5111 | return ndlp; | ||
5099 | spin_lock_irq(shost->host_lock); | 5112 | spin_lock_irq(shost->host_lock); |
5100 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 5113 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
5101 | spin_unlock_irq(shost->host_lock); | 5114 | spin_unlock_irq(shost->host_lock); |
@@ -5104,6 +5117,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
5104 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE); | 5117 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE); |
5105 | if (!ndlp) | 5118 | if (!ndlp) |
5106 | return NULL; | 5119 | return NULL; |
5120 | if (vport->phba->nvmet_support) | ||
5121 | return ndlp; | ||
5107 | spin_lock_irq(shost->host_lock); | 5122 | spin_lock_irq(shost->host_lock); |
5108 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 5123 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
5109 | spin_unlock_irq(shost->host_lock); | 5124 | spin_unlock_irq(shost->host_lock); |
@@ -5123,6 +5138,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
5123 | * delay timeout is not needed. | 5138 | * delay timeout is not needed. |
5124 | */ | 5139 | */ |
5125 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | 5140 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
5141 | if (vport->phba->nvmet_support) | ||
5142 | return ndlp; | ||
5126 | spin_lock_irq(shost->host_lock); | 5143 | spin_lock_irq(shost->host_lock); |
5127 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 5144 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
5128 | spin_unlock_irq(shost->host_lock); | 5145 | spin_unlock_irq(shost->host_lock); |
@@ -5138,6 +5155,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
5138 | ndlp->nlp_flag & NLP_RCV_PLOGI) | 5155 | ndlp->nlp_flag & NLP_RCV_PLOGI) |
5139 | return NULL; | 5156 | return NULL; |
5140 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 5157 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
5158 | if (vport->phba->nvmet_support) | ||
5159 | return ndlp; | ||
5141 | spin_lock_irq(shost->host_lock); | 5160 | spin_lock_irq(shost->host_lock); |
5142 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 5161 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
5143 | spin_unlock_irq(shost->host_lock); | 5162 | spin_unlock_irq(shost->host_lock); |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 883e6d2a7bc7..c2221377e246 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -515,7 +515,15 @@ struct serv_parm { /* Structure is in Big Endian format */ | |||
515 | struct class_parms cls2; | 515 | struct class_parms cls2; |
516 | struct class_parms cls3; | 516 | struct class_parms cls3; |
517 | struct class_parms cls4; | 517 | struct class_parms cls4; |
518 | uint8_t vendorVersion[16]; | 518 | union { |
519 | uint8_t vendorVersion[16]; | ||
520 | struct { | ||
521 | uint32_t vid; | ||
522 | #define LPFC_VV_EMLX_ID 0x454d4c58 /* EMLX */ | ||
523 | uint32_t flags; | ||
524 | #define LPFC_VV_SUPPRESS_RSP 1 | ||
525 | } vv; | ||
526 | } un; | ||
519 | }; | 527 | }; |
520 | 528 | ||
521 | /* | 529 | /* |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 470f9586192f..0716818f269f 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -288,6 +288,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
288 | uint32_t ed_tov; | 288 | uint32_t ed_tov; |
289 | LPFC_MBOXQ_t *mbox; | 289 | LPFC_MBOXQ_t *mbox; |
290 | struct ls_rjt stat; | 290 | struct ls_rjt stat; |
291 | uint32_t vid, flag; | ||
291 | int rc; | 292 | int rc; |
292 | 293 | ||
293 | memset(&stat, 0, sizeof (struct ls_rjt)); | 294 | memset(&stat, 0, sizeof (struct ls_rjt)); |
@@ -423,6 +424,15 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
423 | lpfc_can_disctmo(vport); | 424 | lpfc_can_disctmo(vport); |
424 | } | 425 | } |
425 | 426 | ||
427 | ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP; | ||
428 | if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) && | ||
429 | sp->cmn.valid_vendor_ver_level) { | ||
430 | vid = be32_to_cpu(sp->un.vv.vid); | ||
431 | flag = be32_to_cpu(sp->un.vv.flags); | ||
432 | if ((vid == LPFC_VV_EMLX_ID) && (flag & LPFC_VV_SUPPRESS_RSP)) | ||
433 | ndlp->nlp_flag |= NLP_SUPPRESS_RSP; | ||
434 | } | ||
435 | |||
426 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 436 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
427 | if (!mbox) | 437 | if (!mbox) |
428 | goto out; | 438 | goto out; |
@@ -744,6 +754,14 @@ lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
744 | } | 754 | } |
745 | if (npr->Retry) | 755 | if (npr->Retry) |
746 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; | 756 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; |
757 | |||
758 | /* If this driver is in nvme target mode, set the ndlp's fc4 | ||
759 | * type to NVME provided the PRLI response claims NVME FC4 | ||
760 | * type. Target mode does not issue gft_id so doesn't get | ||
761 | * the fc4 type set until now. | ||
762 | */ | ||
763 | if ((phba->nvmet_support) && (npr->prliType == PRLI_NVME_TYPE)) | ||
764 | ndlp->nlp_fc4_type |= NLP_FC4_NVME; | ||
747 | } | 765 | } |
748 | if (rport) { | 766 | if (rport) { |
749 | /* We need to update the rport role values */ | 767 | /* We need to update the rport role values */ |
@@ -1041,6 +1059,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
1041 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1059 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1042 | struct lpfc_dmabuf *pcmd, *prsp, *mp; | 1060 | struct lpfc_dmabuf *pcmd, *prsp, *mp; |
1043 | uint32_t *lp; | 1061 | uint32_t *lp; |
1062 | uint32_t vid, flag; | ||
1044 | IOCB_t *irsp; | 1063 | IOCB_t *irsp; |
1045 | struct serv_parm *sp; | 1064 | struct serv_parm *sp; |
1046 | uint32_t ed_tov; | 1065 | uint32_t ed_tov; |
@@ -1109,6 +1128,16 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
1109 | ed_tov = (phba->fc_edtov + 999999) / 1000000; | 1128 | ed_tov = (phba->fc_edtov + 999999) / 1000000; |
1110 | } | 1129 | } |
1111 | 1130 | ||
1131 | ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP; | ||
1132 | if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) && | ||
1133 | sp->cmn.valid_vendor_ver_level) { | ||
1134 | vid = be32_to_cpu(sp->un.vv.vid); | ||
1135 | flag = be32_to_cpu(sp->un.vv.flags); | ||
1136 | if ((vid == LPFC_VV_EMLX_ID) && | ||
1137 | (flag & LPFC_VV_SUPPRESS_RSP)) | ||
1138 | ndlp->nlp_flag |= NLP_SUPPRESS_RSP; | ||
1139 | } | ||
1140 | |||
1112 | /* | 1141 | /* |
1113 | * Use the larger EDTOV | 1142 | * Use the larger EDTOV |
1114 | * RATOV = 2 * EDTOV for pt-to-pt | 1143 | * RATOV = 2 * EDTOV for pt-to-pt |
@@ -1504,9 +1533,37 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport, | |||
1504 | uint32_t evt) | 1533 | uint32_t evt) |
1505 | { | 1534 | { |
1506 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | 1535 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1536 | struct ls_rjt stat; | ||
1507 | 1537 | ||
1508 | /* Initiator mode. */ | 1538 | if (vport->phba->nvmet_support) { |
1509 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); | 1539 | /* NVME Target mode. Handle and respond to the PRLI and |
1540 | * transition to UNMAPPED provided the RPI has completed | ||
1541 | * registration. | ||
1542 | */ | ||
1543 | if (ndlp->nlp_flag & NLP_RPI_REGISTERED) { | ||
1544 | lpfc_rcv_prli(vport, ndlp, cmdiocb); | ||
1545 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); | ||
1546 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | ||
1547 | } else { | ||
1548 | /* RPI registration has not completed. Reject the PRLI | ||
1549 | * to prevent an illegal state transition when the | ||
1550 | * rpi registration does complete. | ||
1551 | */ | ||
1552 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME_DISC, | ||
1553 | "6115 NVMET ndlp rpi %d state " | ||
1554 | "unknown, state x%x flags x%08x\n", | ||
1555 | ndlp->nlp_rpi, ndlp->nlp_state, | ||
1556 | ndlp->nlp_flag); | ||
1557 | memset(&stat, 0, sizeof(struct ls_rjt)); | ||
1558 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
1559 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; | ||
1560 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, | ||
1561 | ndlp, NULL); | ||
1562 | } | ||
1563 | } else { | ||
1564 | /* Initiator mode. */ | ||
1565 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); | ||
1566 | } | ||
1510 | 1567 | ||
1511 | return ndlp->nlp_state; | 1568 | return ndlp->nlp_state; |
1512 | } | 1569 | } |
@@ -1668,7 +1725,12 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1668 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); | 1725 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
1669 | lpfc_issue_els_prli(vport, ndlp, 0); | 1726 | lpfc_issue_els_prli(vport, ndlp, 0); |
1670 | } else { | 1727 | } else { |
1671 | /* Only Fabric ports should transition */ | 1728 | if ((vport->fc_flag & FC_PT2PT) && phba->nvmet_support) |
1729 | phba->targetport->port_id = vport->fc_myDID; | ||
1730 | |||
1731 | /* Only Fabric ports should transition. NVME target | ||
1732 | * must complete PRLI. | ||
1733 | */ | ||
1672 | if (ndlp->nlp_type & NLP_FABRIC) { | 1734 | if (ndlp->nlp_type & NLP_FABRIC) { |
1673 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1735 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1674 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 1736 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
@@ -1714,6 +1776,13 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport, | |||
1714 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 1776 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1715 | spin_lock_irq(shost->host_lock); | 1777 | spin_lock_irq(shost->host_lock); |
1716 | 1778 | ||
1779 | /* If we are a target we won't immediately transition into PRLI, | ||
1780 | * so if REG_LOGIN already completed we don't need to ignore it. | ||
1781 | */ | ||
1782 | if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) || | ||
1783 | !vport->phba->nvmet_support) | ||
1784 | ndlp->nlp_flag |= NLP_IGNR_REG_CMPL; | ||
1785 | |||
1717 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1786 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1718 | spin_unlock_irq(shost->host_lock); | 1787 | spin_unlock_irq(shost->host_lock); |
1719 | lpfc_disc_set_adisc(vport, ndlp); | 1788 | lpfc_disc_set_adisc(vport, ndlp); |