aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-10-22 11:05:53 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-25 17:36:18 -0400
commit12265f68ae925b9dee8099140b4213c28ef54f14 (patch)
tree5f9046cd9a03635955bea6f583585a047028933d
parent5ac6b303834aa74855ecc3db98b4b1d9cad0de2f (diff)
[SCSI] lpfc 8.3.18: Add support of received ELS commands
Add support of received ELS commands - Add support for received RLS ELS command - Add support for received ECHO ELS command - Add support for received RTV ELS command Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/lpfc/lpfc.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c346
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h41
3 files changed, 389 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index a50aa03b8ac..cd4afcf749d 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -202,9 +202,12 @@ struct lpfc_stats {
202 uint32_t elsRcvPRLO; 202 uint32_t elsRcvPRLO;
203 uint32_t elsRcvPRLI; 203 uint32_t elsRcvPRLI;
204 uint32_t elsRcvLIRR; 204 uint32_t elsRcvLIRR;
205 uint32_t elsRcvRLS;
205 uint32_t elsRcvRPS; 206 uint32_t elsRcvRPS;
206 uint32_t elsRcvRPL; 207 uint32_t elsRcvRPL;
207 uint32_t elsRcvRRQ; 208 uint32_t elsRcvRRQ;
209 uint32_t elsRcvRTV;
210 uint32_t elsRcvECHO;
208 uint32_t elsXmitFLOGI; 211 uint32_t elsXmitFLOGI;
209 uint32_t elsXmitFDISC; 212 uint32_t elsXmitFDISC;
210 uint32_t elsXmitPLOGI; 213 uint32_t elsXmitPLOGI;
@@ -573,6 +576,7 @@ struct lpfc_hba {
573 /* These fields used to be binfo */ 576 /* These fields used to be binfo */
574 uint32_t fc_pref_DID; /* preferred D_ID */ 577 uint32_t fc_pref_DID; /* preferred D_ID */
575 uint8_t fc_pref_ALPA; /* preferred AL_PA */ 578 uint8_t fc_pref_ALPA; /* preferred AL_PA */
579 uint32_t fc_edtovResol; /* E_D_TOV timer resolution */
576 uint32_t fc_edtov; /* E_D_TOV timer value */ 580 uint32_t fc_edtov; /* E_D_TOV timer value */
577 uint32_t fc_arbtov; /* ARB_TOV timer value */ 581 uint32_t fc_arbtov; /* ARB_TOV timer value */
578 uint32_t fc_ratov; /* R_A_TOV timer value */ 582 uint32_t fc_ratov; /* R_A_TOV timer value */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index b16311d60c6..ea511d18f0e 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -517,6 +517,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
517 if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */ 517 if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */
518 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000; 518 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
519 519
520 phba->fc_edtovResol = sp->cmn.edtovResolution;
520 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000; 521 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
521 522
522 if (phba->fc_topology == TOPOLOGY_LOOP) { 523 if (phba->fc_topology == TOPOLOGY_LOOP) {
@@ -3928,6 +3929,64 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
3928} 3929}
3929 3930
3930/** 3931/**
3932 * lpfc_els_rsp_echo_acc - Issue echo acc response
3933 * @vport: pointer to a virtual N_Port data structure.
3934 * @data: pointer to echo data to return in the accept.
3935 * @oldiocb: pointer to the original lpfc command iocb data structure.
3936 * @ndlp: pointer to a node-list data structure.
3937 *
3938 * Return code
3939 * 0 - Successfully issued acc echo response
3940 * 1 - Failed to issue acc echo response
3941 **/
3942static int
3943lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
3944 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
3945{
3946 struct lpfc_hba *phba = vport->phba;
3947 struct lpfc_iocbq *elsiocb;
3948 struct lpfc_sli *psli;
3949 uint8_t *pcmd;
3950 uint16_t cmdsize;
3951 int rc;
3952
3953 psli = &phba->sli;
3954 cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
3955
3956 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3957 ndlp->nlp_DID, ELS_CMD_ACC);
3958 if (!elsiocb)
3959 return 1;
3960
3961 elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext; /* Xri */
3962 /* Xmit ECHO ACC response tag <ulpIoTag> */
3963 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3964 "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
3965 elsiocb->iotag, elsiocb->iocb.ulpContext);
3966 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3967 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3968 pcmd += sizeof(uint32_t);
3969 memcpy(pcmd, data, cmdsize - sizeof(uint32_t));
3970
3971 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3972 "Issue ACC ECHO: did:x%x flg:x%x",
3973 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3974
3975 phba->fc_stat.elsXmitACC++;
3976 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3977 lpfc_nlp_put(ndlp);
3978 elsiocb->context1 = NULL; /* Don't need ndlp for cmpl,
3979 * it could be freed */
3980
3981 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
3982 if (rc == IOCB_ERROR) {
3983 lpfc_els_free_iocb(phba, elsiocb);
3984 return 1;
3985 }
3986 return 0;
3987}
3988
3989/**
3931 * lpfc_els_disc_adisc - Issue remaining adisc iocbs to npr nodes of a vport 3990 * lpfc_els_disc_adisc - Issue remaining adisc iocbs to npr nodes of a vport
3932 * @vport: pointer to a host virtual N_Port data structure. 3991 * @vport: pointer to a host virtual N_Port data structure.
3933 * 3992 *
@@ -4686,6 +4745,30 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4686} 4745}
4687 4746
4688/** 4747/**
4748 * lpfc_els_rcv_echo - Process an unsolicited echo iocb
4749 * @vport: pointer to a host virtual N_Port data structure.
4750 * @cmdiocb: pointer to lpfc command iocb data structure.
4751 * @ndlp: pointer to a node-list data structure.
4752 *
4753 * Return code
4754 * 0 - Successfully processed echo iocb (currently always return 0)
4755 **/
4756static int
4757lpfc_els_rcv_echo(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4758 struct lpfc_nodelist *ndlp)
4759{
4760 uint8_t *pcmd;
4761
4762 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
4763
4764 /* skip over first word of echo command to find echo data */
4765 pcmd += sizeof(uint32_t);
4766
4767 lpfc_els_rsp_echo_acc(vport, pcmd, cmdiocb, ndlp);
4768 return 0;
4769}
4770
4771/**
4689 * lpfc_els_rcv_lirr - Process an unsolicited lirr iocb 4772 * lpfc_els_rcv_lirr - Process an unsolicited lirr iocb
4690 * @vport: pointer to a host virtual N_Port data structure. 4773 * @vport: pointer to a host virtual N_Port data structure.
4691 * @cmdiocb: pointer to lpfc command iocb data structure. 4774 * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -4737,6 +4820,89 @@ lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4737} 4820}
4738 4821
4739/** 4822/**
4823 * lpfc_els_rsp_rls_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4824 * @phba: pointer to lpfc hba data structure.
4825 * @pmb: pointer to the driver internal queue element for mailbox command.
4826 *
4827 * This routine is the completion callback function for the MBX_READ_LNK_STAT
4828 * mailbox command. This callback function is to actually send the Accept
4829 * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It
4830 * collects the link statistics from the completion of the MBX_READ_LNK_STAT
4831 * mailbox command, constructs the RPS response with the link statistics
4832 * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC
4833 * response to the RPS.
4834 *
4835 * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
4836 * will be incremented by 1 for holding the ndlp and the reference to ndlp
4837 * will be stored into the context1 field of the IOCB for the completion
4838 * callback function to the RPS Accept Response ELS IOCB command.
4839 *
4840 **/
4841static void
4842lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4843{
4844 MAILBOX_t *mb;
4845 IOCB_t *icmd;
4846 struct RLS_RSP *rls_rsp;
4847 uint8_t *pcmd;
4848 struct lpfc_iocbq *elsiocb;
4849 struct lpfc_nodelist *ndlp;
4850 uint16_t xri;
4851 uint32_t cmdsize;
4852
4853 mb = &pmb->u.mb;
4854
4855 ndlp = (struct lpfc_nodelist *) pmb->context2;
4856 xri = (uint16_t) ((unsigned long)(pmb->context1));
4857 pmb->context1 = NULL;
4858 pmb->context2 = NULL;
4859
4860 if (mb->mbxStatus) {
4861 mempool_free(pmb, phba->mbox_mem_pool);
4862 return;
4863 }
4864
4865 cmdsize = sizeof(struct RLS_RSP) + sizeof(uint32_t);
4866 mempool_free(pmb, phba->mbox_mem_pool);
4867 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
4868 lpfc_max_els_tries, ndlp,
4869 ndlp->nlp_DID, ELS_CMD_ACC);
4870
4871 /* Decrement the ndlp reference count from previous mbox command */
4872 lpfc_nlp_put(ndlp);
4873
4874 if (!elsiocb)
4875 return;
4876
4877 icmd = &elsiocb->iocb;
4878 icmd->ulpContext = xri;
4879
4880 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4881 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4882 pcmd += sizeof(uint32_t); /* Skip past command */
4883 rls_rsp = (struct RLS_RSP *)pcmd;
4884
4885 rls_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
4886 rls_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
4887 rls_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
4888 rls_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
4889 rls_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
4890 rls_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
4891
4892 /* Xmit ELS RLS ACC response tag <ulpIoTag> */
4893 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
4894 "2874 Xmit ELS RLS ACC response tag x%x xri x%x, "
4895 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
4896 elsiocb->iotag, elsiocb->iocb.ulpContext,
4897 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4898 ndlp->nlp_rpi);
4899 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4900 phba->fc_stat.elsXmitACC++;
4901 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
4902 lpfc_els_free_iocb(phba, elsiocb);
4903}
4904
4905/**
4740 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd 4906 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4741 * @phba: pointer to lpfc hba data structure. 4907 * @phba: pointer to lpfc hba data structure.
4742 * @pmb: pointer to the driver internal queue element for mailbox command. 4908 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -4829,7 +4995,155 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4829} 4995}
4830 4996
4831/** 4997/**
4832 * lpfc_els_rcv_rps - Process an unsolicited rps iocb 4998 * lpfc_els_rcv_rls - Process an unsolicited rls iocb
4999 * @vport: pointer to a host virtual N_Port data structure.
5000 * @cmdiocb: pointer to lpfc command iocb data structure.
5001 * @ndlp: pointer to a node-list data structure.
5002 *
5003 * This routine processes Read Port Status (RPL) IOCB received as an
5004 * ELS unsolicited event. It first checks the remote port state. If the
5005 * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
5006 * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
5007 * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command
5008 * for reading the HBA link statistics. It is for the callback function,
5009 * lpfc_els_rsp_rls_acc(), set to the MBX_READ_LNK_STAT mailbox command
5010 * to actually sending out RPL Accept (ACC) response.
5011 *
5012 * Return codes
5013 * 0 - Successfully processed rls iocb (currently always return 0)
5014 **/
5015static int
5016lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5017 struct lpfc_nodelist *ndlp)
5018{
5019 struct lpfc_hba *phba = vport->phba;
5020 LPFC_MBOXQ_t *mbox;
5021 struct lpfc_dmabuf *pcmd;
5022 struct ls_rjt stat;
5023
5024 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5025 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5026 /* reject the unsolicited RPS request and done with it */
5027 goto reject_out;
5028
5029 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5030
5031 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
5032 if (mbox) {
5033 lpfc_read_lnk_stat(phba, mbox);
5034 mbox->context1 =
5035 (void *)((unsigned long) cmdiocb->iocb.ulpContext);
5036 mbox->context2 = lpfc_nlp_get(ndlp);
5037 mbox->vport = vport;
5038 mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
5039 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
5040 != MBX_NOT_FINISHED)
5041 /* Mbox completion will send ELS Response */
5042 return 0;
5043 /* Decrement reference count used for the failed mbox
5044 * command.
5045 */
5046 lpfc_nlp_put(ndlp);
5047 mempool_free(mbox, phba->mbox_mem_pool);
5048 }
5049reject_out:
5050 /* issue rejection response */
5051 stat.un.b.lsRjtRsvd0 = 0;
5052 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5053 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5054 stat.un.b.vendorUnique = 0;
5055 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5056 return 0;
5057}
5058
5059/**
5060 * lpfc_els_rcv_rtv - Process an unsolicited rtv iocb
5061 * @vport: pointer to a host virtual N_Port data structure.
5062 * @cmdiocb: pointer to lpfc command iocb data structure.
5063 * @ndlp: pointer to a node-list data structure.
5064 *
5065 * This routine processes Read Timout Value (RTV) IOCB received as an
5066 * ELS unsolicited event. It first checks the remote port state. If the
5067 * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
5068 * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
5069 * response. Otherwise, it sends the Accept(ACC) response to a Read Timeout
5070 * Value (RTV) unsolicited IOCB event.
5071 *
5072 * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
5073 * will be incremented by 1 for holding the ndlp and the reference to ndlp
5074 * will be stored into the context1 field of the IOCB for the completion
5075 * callback function to the RPS Accept Response ELS IOCB command.
5076 *
5077 * Return codes
5078 * 0 - Successfully processed rtv iocb (currently always return 0)
5079 **/
5080static int
5081lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5082 struct lpfc_nodelist *ndlp)
5083{
5084 struct lpfc_hba *phba = vport->phba;
5085 struct ls_rjt stat;
5086 struct RTV_RSP *rtv_rsp;
5087 uint8_t *pcmd;
5088 struct lpfc_iocbq *elsiocb;
5089 uint32_t cmdsize;
5090
5091
5092 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5093 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5094 /* reject the unsolicited RPS request and done with it */
5095 goto reject_out;
5096
5097 cmdsize = sizeof(struct RTV_RSP) + sizeof(uint32_t);
5098 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
5099 lpfc_max_els_tries, ndlp,
5100 ndlp->nlp_DID, ELS_CMD_ACC);
5101
5102 if (!elsiocb)
5103 return 1;
5104
5105 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5106 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
5107 pcmd += sizeof(uint32_t); /* Skip past command */
5108
5109 /* use the command's xri in the response */
5110 elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;
5111
5112 rtv_rsp = (struct RTV_RSP *)pcmd;
5113
5114 /* populate RTV payload */
5115 rtv_rsp->ratov = cpu_to_be32(phba->fc_ratov * 1000); /* report msecs */
5116 rtv_rsp->edtov = cpu_to_be32(phba->fc_edtov);
5117 bf_set(qtov_edtovres, rtv_rsp, phba->fc_edtovResol ? 1 : 0);
5118 bf_set(qtov_rttov, rtv_rsp, 0); /* Field is for FC ONLY */
5119 rtv_rsp->qtov = cpu_to_be32(rtv_rsp->qtov);
5120
5121 /* Xmit ELS RLS ACC response tag <ulpIoTag> */
5122 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
5123 "2875 Xmit ELS RTV ACC response tag x%x xri x%x, "
5124 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x, "
5125 "Data: x%x x%x x%x\n",
5126 elsiocb->iotag, elsiocb->iocb.ulpContext,
5127 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
5128 ndlp->nlp_rpi,
5129 rtv_rsp->ratov, rtv_rsp->edtov, rtv_rsp->qtov);
5130 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
5131 phba->fc_stat.elsXmitACC++;
5132 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
5133 lpfc_els_free_iocb(phba, elsiocb);
5134 return 0;
5135
5136reject_out:
5137 /* issue rejection response */
5138 stat.un.b.lsRjtRsvd0 = 0;
5139 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5140 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5141 stat.un.b.vendorUnique = 0;
5142 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5143 return 0;
5144}
5145
5146/* lpfc_els_rcv_rps - Process an unsolicited rps iocb
4833 * @vport: pointer to a host virtual N_Port data structure. 5147 * @vport: pointer to a host virtual N_Port data structure.
4834 * @cmdiocb: pointer to lpfc command iocb data structure. 5148 * @cmdiocb: pointer to lpfc command iocb data structure.
4835 * @ndlp: pointer to a node-list data structure. 5149 * @ndlp: pointer to a node-list data structure.
@@ -5019,7 +5333,6 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5019 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; 5333 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5020 lp = (uint32_t *) pcmd->virt; 5334 lp = (uint32_t *) pcmd->virt;
5021 rpl = (RPL *) (lp + 1); 5335 rpl = (RPL *) (lp + 1);
5022
5023 maxsize = be32_to_cpu(rpl->maxsize); 5336 maxsize = be32_to_cpu(rpl->maxsize);
5024 5337
5025 /* We support only one port */ 5338 /* We support only one port */
@@ -5838,6 +6151,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5838 if (newnode) 6151 if (newnode)
5839 lpfc_nlp_put(ndlp); 6152 lpfc_nlp_put(ndlp);
5840 break; 6153 break;
6154 case ELS_CMD_RLS:
6155 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6156 "RCV RLS: did:x%x/ste:x%x flg:x%x",
6157 did, vport->port_state, ndlp->nlp_flag);
6158
6159 phba->fc_stat.elsRcvRLS++;
6160 lpfc_els_rcv_rls(vport, elsiocb, ndlp);
6161 if (newnode)
6162 lpfc_nlp_put(ndlp);
6163 break;
5841 case ELS_CMD_RPS: 6164 case ELS_CMD_RPS:
5842 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6165 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5843 "RCV RPS: did:x%x/ste:x%x flg:x%x", 6166 "RCV RPS: did:x%x/ste:x%x flg:x%x",
@@ -5868,6 +6191,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5868 if (newnode) 6191 if (newnode)
5869 lpfc_nlp_put(ndlp); 6192 lpfc_nlp_put(ndlp);
5870 break; 6193 break;
6194 case ELS_CMD_RTV:
6195 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6196 "RCV RTV: did:x%x/ste:x%x flg:x%x",
6197 did, vport->port_state, ndlp->nlp_flag);
6198 phba->fc_stat.elsRcvRTV++;
6199 lpfc_els_rcv_rtv(vport, elsiocb, ndlp);
6200 if (newnode)
6201 lpfc_nlp_put(ndlp);
6202 break;
5871 case ELS_CMD_RRQ: 6203 case ELS_CMD_RRQ:
5872 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6204 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5873 "RCV RRQ: did:x%x/ste:x%x flg:x%x", 6205 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
@@ -5878,6 +6210,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5878 if (newnode) 6210 if (newnode)
5879 lpfc_nlp_put(ndlp); 6211 lpfc_nlp_put(ndlp);
5880 break; 6212 break;
6213 case ELS_CMD_ECHO:
6214 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6215 "RCV ECHO: did:x%x/ste:x%x flg:x%x",
6216 did, vport->port_state, ndlp->nlp_flag);
6217
6218 phba->fc_stat.elsRcvECHO++;
6219 lpfc_els_rcv_echo(vport, elsiocb, ndlp);
6220 if (newnode)
6221 lpfc_nlp_put(ndlp);
6222 break;
5881 default: 6223 default:
5882 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6224 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5883 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", 6225 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index a631647051d..9b833345646 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -861,6 +861,47 @@ typedef struct _RPS_RSP { /* Structure is in Big Endian format */
861 uint32_t crcCnt; 861 uint32_t crcCnt;
862} RPS_RSP; 862} RPS_RSP;
863 863
864struct RLS { /* Structure is in Big Endian format */
865 uint32_t rls;
866#define rls_rsvd_SHIFT 24
867#define rls_rsvd_MASK 0x000000ff
868#define rls_rsvd_WORD rls
869#define rls_did_SHIFT 0
870#define rls_did_MASK 0x00ffffff
871#define rls_did_WORD rls
872};
873
874struct RLS_RSP { /* Structure is in Big Endian format */
875 uint32_t linkFailureCnt;
876 uint32_t lossSyncCnt;
877 uint32_t lossSignalCnt;
878 uint32_t primSeqErrCnt;
879 uint32_t invalidXmitWord;
880 uint32_t crcCnt;
881};
882
883struct RTV_RSP { /* Structure is in Big Endian format */
884 uint32_t ratov;
885 uint32_t edtov;
886 uint32_t qtov;
887#define qtov_rsvd0_SHIFT 28
888#define qtov_rsvd0_MASK 0x0000000f
889#define qtov_rsvd0_WORD qtov /* reserved */
890#define qtov_edtovres_SHIFT 27
891#define qtov_edtovres_MASK 0x00000001
892#define qtov_edtovres_WORD qtov /* E_D_TOV Resolution */
893#define qtov__rsvd1_SHIFT 19
894#define qtov_rsvd1_MASK 0x0000003f
895#define qtov_rsvd1_WORD qtov /* reserved */
896#define qtov_rttov_SHIFT 18
897#define qtov_rttov_MASK 0x00000001
898#define qtov_rttov_WORD qtov /* R_T_TOV value */
899#define qtov_rsvd2_SHIFT 0
900#define qtov_rsvd2_MASK 0x0003ffff
901#define qtov_rsvd2_WORD qtov /* reserved */
902};
903
904
864typedef struct _RPL { /* Structure is in Big Endian format */ 905typedef struct _RPL { /* Structure is in Big Endian format */
865 uint32_t maxsize; 906 uint32_t maxsize;
866 uint32_t index; 907 uint32_t index;