aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c439
1 files changed, 382 insertions, 57 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index e6ca12f6c6cb..884f4d321799 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -177,15 +177,18 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
177 (elscmd == ELS_CMD_LOGO))) 177 (elscmd == ELS_CMD_LOGO)))
178 switch (elscmd) { 178 switch (elscmd) {
179 case ELS_CMD_FLOGI: 179 case ELS_CMD_FLOGI:
180 elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT) 180 elsiocb->iocb_flag |=
181 ((LPFC_ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
181 & LPFC_FIP_ELS_ID_MASK); 182 & LPFC_FIP_ELS_ID_MASK);
182 break; 183 break;
183 case ELS_CMD_FDISC: 184 case ELS_CMD_FDISC:
184 elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT) 185 elsiocb->iocb_flag |=
186 ((LPFC_ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
185 & LPFC_FIP_ELS_ID_MASK); 187 & LPFC_FIP_ELS_ID_MASK);
186 break; 188 break;
187 case ELS_CMD_LOGO: 189 case ELS_CMD_LOGO:
188 elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT) 190 elsiocb->iocb_flag |=
191 ((LPFC_ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
189 & LPFC_FIP_ELS_ID_MASK); 192 & LPFC_FIP_ELS_ID_MASK);
190 break; 193 break;
191 } 194 }
@@ -517,18 +520,13 @@ 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 */ 520 if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */
518 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000; 521 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
519 522
523 phba->fc_edtovResol = sp->cmn.edtovResolution;
520 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000; 524 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
521 525
522 if (phba->fc_topology == TOPOLOGY_LOOP) { 526 if (phba->fc_topology == TOPOLOGY_LOOP) {
523 spin_lock_irq(shost->host_lock); 527 spin_lock_irq(shost->host_lock);
524 vport->fc_flag |= FC_PUBLIC_LOOP; 528 vport->fc_flag |= FC_PUBLIC_LOOP;
525 spin_unlock_irq(shost->host_lock); 529 spin_unlock_irq(shost->host_lock);
526 } else {
527 /*
528 * If we are a N-port connected to a Fabric, fixup sparam's so
529 * logins to devices on remote loops work.
530 */
531 vport->fc_sparam.cmn.altBbCredit = 1;
532 } 530 }
533 531
534 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; 532 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
@@ -585,6 +583,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
585 lpfc_unreg_rpi(vport, np); 583 lpfc_unreg_rpi(vport, np);
586 } 584 }
587 lpfc_cleanup_pending_mbox(vport); 585 lpfc_cleanup_pending_mbox(vport);
586
587 if (phba->sli_rev == LPFC_SLI_REV4)
588 lpfc_sli4_unreg_all_rpis(vport);
589
588 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { 590 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
589 lpfc_mbx_unreg_vpi(vport); 591 lpfc_mbx_unreg_vpi(vport);
590 spin_lock_irq(shost->host_lock); 592 spin_lock_irq(shost->host_lock);
@@ -800,7 +802,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
800 802
801 if (irsp->ulpStatus) { 803 if (irsp->ulpStatus) {
802 /* 804 /*
803 * In case of FIP mode, perform round robin FCF failover 805 * In case of FIP mode, perform roundrobin FCF failover
804 * due to new FCF discovery 806 * due to new FCF discovery
805 */ 807 */
806 if ((phba->hba_flag & HBA_FIP_SUPPORT) && 808 if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
@@ -808,48 +810,16 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
808 (irsp->ulpStatus != IOSTAT_LOCAL_REJECT) && 810 (irsp->ulpStatus != IOSTAT_LOCAL_REJECT) &&
809 (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) { 811 (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) {
810 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, 812 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
811 "2611 FLOGI failed on registered " 813 "2611 FLOGI failed on FCF (x%x), "
812 "FCF record fcf_index(%d), status: " 814 "status:x%x/x%x, tmo:x%x, perform "
813 "x%x/x%x, tmo:x%x, trying to perform " 815 "roundrobin FCF failover\n",
814 "round robin failover\n",
815 phba->fcf.current_rec.fcf_indx, 816 phba->fcf.current_rec.fcf_indx,
816 irsp->ulpStatus, irsp->un.ulpWord[4], 817 irsp->ulpStatus, irsp->un.ulpWord[4],
817 irsp->ulpTimeout); 818 irsp->ulpTimeout);
818 fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); 819 fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
819 if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { 820 rc = lpfc_sli4_fcf_rr_next_proc(vport, fcf_index);
820 /* 821 if (rc)
821 * Exhausted the eligible FCF record list, 822 goto out;
822 * fail through to retry FLOGI on current
823 * FCF record.
824 */
825 lpfc_printf_log(phba, KERN_WARNING,
826 LOG_FIP | LOG_ELS,
827 "2760 Completed one round "
828 "of FLOGI FCF round robin "
829 "failover list, retry FLOGI "
830 "on currently registered "
831 "FCF index:%d\n",
832 phba->fcf.current_rec.fcf_indx);
833 } else {
834 lpfc_printf_log(phba, KERN_INFO,
835 LOG_FIP | LOG_ELS,
836 "2794 FLOGI FCF round robin "
837 "failover to FCF index x%x\n",
838 fcf_index);
839 rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
840 fcf_index);
841 if (rc)
842 lpfc_printf_log(phba, KERN_WARNING,
843 LOG_FIP | LOG_ELS,
844 "2761 FLOGI round "
845 "robin FCF failover "
846 "read FCF failed "
847 "rc:x%x, fcf_index:"
848 "%d\n", rc,
849 phba->fcf.current_rec.fcf_indx);
850 else
851 goto out;
852 }
853 } 823 }
854 824
855 /* FLOGI failure */ 825 /* FLOGI failure */
@@ -939,6 +909,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
939 lpfc_nlp_put(ndlp); 909 lpfc_nlp_put(ndlp);
940 spin_lock_irq(&phba->hbalock); 910 spin_lock_irq(&phba->hbalock);
941 phba->fcf.fcf_flag &= ~FCF_DISCOVERY; 911 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
912 phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
942 spin_unlock_irq(&phba->hbalock); 913 spin_unlock_irq(&phba->hbalock);
943 goto out; 914 goto out;
944 } 915 }
@@ -947,13 +918,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
947 if (phba->hba_flag & HBA_FIP_SUPPORT) 918 if (phba->hba_flag & HBA_FIP_SUPPORT)
948 lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | 919 lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP |
949 LOG_ELS, 920 LOG_ELS,
950 "2769 FLOGI successful on FCF " 921 "2769 FLOGI to FCF (x%x) "
951 "record: current_fcf_index:" 922 "completed successfully\n",
952 "x%x, terminate FCF round "
953 "robin failover process\n",
954 phba->fcf.current_rec.fcf_indx); 923 phba->fcf.current_rec.fcf_indx);
955 spin_lock_irq(&phba->hbalock); 924 spin_lock_irq(&phba->hbalock);
956 phba->fcf.fcf_flag &= ~FCF_DISCOVERY; 925 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
926 phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
957 spin_unlock_irq(&phba->hbalock); 927 spin_unlock_irq(&phba->hbalock);
958 goto out; 928 goto out;
959 } 929 }
@@ -1175,12 +1145,13 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
1175 return 0; 1145 return 0;
1176 } 1146 }
1177 1147
1178 if (lpfc_issue_els_flogi(vport, ndlp, 0)) 1148 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
1179 /* This decrement of reference count to node shall kick off 1149 /* This decrement of reference count to node shall kick off
1180 * the release of the node. 1150 * the release of the node.
1181 */ 1151 */
1182 lpfc_nlp_put(ndlp); 1152 lpfc_nlp_put(ndlp);
1183 1153 return 0;
1154 }
1184 return 1; 1155 return 1;
1185} 1156}
1186 1157
@@ -1645,6 +1616,13 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
1645 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm)); 1616 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
1646 sp = (struct serv_parm *) pcmd; 1617 sp = (struct serv_parm *) pcmd;
1647 1618
1619 /*
1620 * If we are a N-port connected to a Fabric, fix-up paramm's so logins
1621 * to device on remote loops work.
1622 */
1623 if ((vport->fc_flag & FC_FABRIC) && !(vport->fc_flag & FC_PUBLIC_LOOP))
1624 sp->cmn.altBbCredit = 1;
1625
1648 if (sp->cmn.fcphLow < FC_PH_4_3) 1626 if (sp->cmn.fcphLow < FC_PH_4_3)
1649 sp->cmn.fcphLow = FC_PH_4_3; 1627 sp->cmn.fcphLow = FC_PH_4_3;
1650 1628
@@ -3926,6 +3904,64 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
3926} 3904}
3927 3905
3928/** 3906/**
3907 * lpfc_els_rsp_echo_acc - Issue echo acc response
3908 * @vport: pointer to a virtual N_Port data structure.
3909 * @data: pointer to echo data to return in the accept.
3910 * @oldiocb: pointer to the original lpfc command iocb data structure.
3911 * @ndlp: pointer to a node-list data structure.
3912 *
3913 * Return code
3914 * 0 - Successfully issued acc echo response
3915 * 1 - Failed to issue acc echo response
3916 **/
3917static int
3918lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
3919 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
3920{
3921 struct lpfc_hba *phba = vport->phba;
3922 struct lpfc_iocbq *elsiocb;
3923 struct lpfc_sli *psli;
3924 uint8_t *pcmd;
3925 uint16_t cmdsize;
3926 int rc;
3927
3928 psli = &phba->sli;
3929 cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
3930
3931 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3932 ndlp->nlp_DID, ELS_CMD_ACC);
3933 if (!elsiocb)
3934 return 1;
3935
3936 elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext; /* Xri */
3937 /* Xmit ECHO ACC response tag <ulpIoTag> */
3938 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3939 "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
3940 elsiocb->iotag, elsiocb->iocb.ulpContext);
3941 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3942 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3943 pcmd += sizeof(uint32_t);
3944 memcpy(pcmd, data, cmdsize - sizeof(uint32_t));
3945
3946 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3947 "Issue ACC ECHO: did:x%x flg:x%x",
3948 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3949
3950 phba->fc_stat.elsXmitACC++;
3951 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3952 lpfc_nlp_put(ndlp);
3953 elsiocb->context1 = NULL; /* Don't need ndlp for cmpl,
3954 * it could be freed */
3955
3956 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
3957 if (rc == IOCB_ERROR) {
3958 lpfc_els_free_iocb(phba, elsiocb);
3959 return 1;
3960 }
3961 return 0;
3962}
3963
3964/**
3929 * lpfc_els_disc_adisc - Issue remaining adisc iocbs to npr nodes of a vport 3965 * lpfc_els_disc_adisc - Issue remaining adisc iocbs to npr nodes of a vport
3930 * @vport: pointer to a host virtual N_Port data structure. 3966 * @vport: pointer to a host virtual N_Port data structure.
3931 * 3967 *
@@ -4684,6 +4720,30 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4684} 4720}
4685 4721
4686/** 4722/**
4723 * lpfc_els_rcv_echo - Process an unsolicited echo iocb
4724 * @vport: pointer to a host virtual N_Port data structure.
4725 * @cmdiocb: pointer to lpfc command iocb data structure.
4726 * @ndlp: pointer to a node-list data structure.
4727 *
4728 * Return code
4729 * 0 - Successfully processed echo iocb (currently always return 0)
4730 **/
4731static int
4732lpfc_els_rcv_echo(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4733 struct lpfc_nodelist *ndlp)
4734{
4735 uint8_t *pcmd;
4736
4737 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
4738
4739 /* skip over first word of echo command to find echo data */
4740 pcmd += sizeof(uint32_t);
4741
4742 lpfc_els_rsp_echo_acc(vport, pcmd, cmdiocb, ndlp);
4743 return 0;
4744}
4745
4746/**
4687 * lpfc_els_rcv_lirr - Process an unsolicited lirr iocb 4747 * lpfc_els_rcv_lirr - Process an unsolicited lirr iocb
4688 * @vport: pointer to a host virtual N_Port data structure. 4748 * @vport: pointer to a host virtual N_Port data structure.
4689 * @cmdiocb: pointer to lpfc command iocb data structure. 4749 * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -4735,6 +4795,89 @@ lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4735} 4795}
4736 4796
4737/** 4797/**
4798 * lpfc_els_rsp_rls_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4799 * @phba: pointer to lpfc hba data structure.
4800 * @pmb: pointer to the driver internal queue element for mailbox command.
4801 *
4802 * This routine is the completion callback function for the MBX_READ_LNK_STAT
4803 * mailbox command. This callback function is to actually send the Accept
4804 * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It
4805 * collects the link statistics from the completion of the MBX_READ_LNK_STAT
4806 * mailbox command, constructs the RPS response with the link statistics
4807 * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC
4808 * response to the RPS.
4809 *
4810 * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
4811 * will be incremented by 1 for holding the ndlp and the reference to ndlp
4812 * will be stored into the context1 field of the IOCB for the completion
4813 * callback function to the RPS Accept Response ELS IOCB command.
4814 *
4815 **/
4816static void
4817lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4818{
4819 MAILBOX_t *mb;
4820 IOCB_t *icmd;
4821 struct RLS_RSP *rls_rsp;
4822 uint8_t *pcmd;
4823 struct lpfc_iocbq *elsiocb;
4824 struct lpfc_nodelist *ndlp;
4825 uint16_t xri;
4826 uint32_t cmdsize;
4827
4828 mb = &pmb->u.mb;
4829
4830 ndlp = (struct lpfc_nodelist *) pmb->context2;
4831 xri = (uint16_t) ((unsigned long)(pmb->context1));
4832 pmb->context1 = NULL;
4833 pmb->context2 = NULL;
4834
4835 if (mb->mbxStatus) {
4836 mempool_free(pmb, phba->mbox_mem_pool);
4837 return;
4838 }
4839
4840 cmdsize = sizeof(struct RLS_RSP) + sizeof(uint32_t);
4841 mempool_free(pmb, phba->mbox_mem_pool);
4842 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
4843 lpfc_max_els_tries, ndlp,
4844 ndlp->nlp_DID, ELS_CMD_ACC);
4845
4846 /* Decrement the ndlp reference count from previous mbox command */
4847 lpfc_nlp_put(ndlp);
4848
4849 if (!elsiocb)
4850 return;
4851
4852 icmd = &elsiocb->iocb;
4853 icmd->ulpContext = xri;
4854
4855 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4856 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4857 pcmd += sizeof(uint32_t); /* Skip past command */
4858 rls_rsp = (struct RLS_RSP *)pcmd;
4859
4860 rls_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
4861 rls_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
4862 rls_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
4863 rls_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
4864 rls_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
4865 rls_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
4866
4867 /* Xmit ELS RLS ACC response tag <ulpIoTag> */
4868 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
4869 "2874 Xmit ELS RLS ACC response tag x%x xri x%x, "
4870 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
4871 elsiocb->iotag, elsiocb->iocb.ulpContext,
4872 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4873 ndlp->nlp_rpi);
4874 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4875 phba->fc_stat.elsXmitACC++;
4876 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
4877 lpfc_els_free_iocb(phba, elsiocb);
4878}
4879
4880/**
4738 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd 4881 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4739 * @phba: pointer to lpfc hba data structure. 4882 * @phba: pointer to lpfc hba data structure.
4740 * @pmb: pointer to the driver internal queue element for mailbox command. 4883 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -4827,7 +4970,155 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4827} 4970}
4828 4971
4829/** 4972/**
4830 * lpfc_els_rcv_rps - Process an unsolicited rps iocb 4973 * lpfc_els_rcv_rls - Process an unsolicited rls iocb
4974 * @vport: pointer to a host virtual N_Port data structure.
4975 * @cmdiocb: pointer to lpfc command iocb data structure.
4976 * @ndlp: pointer to a node-list data structure.
4977 *
4978 * This routine processes Read Port Status (RPL) IOCB received as an
4979 * ELS unsolicited event. It first checks the remote port state. If the
4980 * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
4981 * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
4982 * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command
4983 * for reading the HBA link statistics. It is for the callback function,
4984 * lpfc_els_rsp_rls_acc(), set to the MBX_READ_LNK_STAT mailbox command
4985 * to actually sending out RPL Accept (ACC) response.
4986 *
4987 * Return codes
4988 * 0 - Successfully processed rls iocb (currently always return 0)
4989 **/
4990static int
4991lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4992 struct lpfc_nodelist *ndlp)
4993{
4994 struct lpfc_hba *phba = vport->phba;
4995 LPFC_MBOXQ_t *mbox;
4996 struct lpfc_dmabuf *pcmd;
4997 struct ls_rjt stat;
4998
4999 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5000 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5001 /* reject the unsolicited RPS request and done with it */
5002 goto reject_out;
5003
5004 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5005
5006 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
5007 if (mbox) {
5008 lpfc_read_lnk_stat(phba, mbox);
5009 mbox->context1 =
5010 (void *)((unsigned long) cmdiocb->iocb.ulpContext);
5011 mbox->context2 = lpfc_nlp_get(ndlp);
5012 mbox->vport = vport;
5013 mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
5014 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
5015 != MBX_NOT_FINISHED)
5016 /* Mbox completion will send ELS Response */
5017 return 0;
5018 /* Decrement reference count used for the failed mbox
5019 * command.
5020 */
5021 lpfc_nlp_put(ndlp);
5022 mempool_free(mbox, phba->mbox_mem_pool);
5023 }
5024reject_out:
5025 /* issue rejection response */
5026 stat.un.b.lsRjtRsvd0 = 0;
5027 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5028 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5029 stat.un.b.vendorUnique = 0;
5030 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5031 return 0;
5032}
5033
5034/**
5035 * lpfc_els_rcv_rtv - Process an unsolicited rtv iocb
5036 * @vport: pointer to a host virtual N_Port data structure.
5037 * @cmdiocb: pointer to lpfc command iocb data structure.
5038 * @ndlp: pointer to a node-list data structure.
5039 *
5040 * This routine processes Read Timout Value (RTV) IOCB received as an
5041 * ELS unsolicited event. It first checks the remote port state. If the
5042 * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
5043 * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
5044 * response. Otherwise, it sends the Accept(ACC) response to a Read Timeout
5045 * Value (RTV) unsolicited IOCB event.
5046 *
5047 * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
5048 * will be incremented by 1 for holding the ndlp and the reference to ndlp
5049 * will be stored into the context1 field of the IOCB for the completion
5050 * callback function to the RPS Accept Response ELS IOCB command.
5051 *
5052 * Return codes
5053 * 0 - Successfully processed rtv iocb (currently always return 0)
5054 **/
5055static int
5056lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5057 struct lpfc_nodelist *ndlp)
5058{
5059 struct lpfc_hba *phba = vport->phba;
5060 struct ls_rjt stat;
5061 struct RTV_RSP *rtv_rsp;
5062 uint8_t *pcmd;
5063 struct lpfc_iocbq *elsiocb;
5064 uint32_t cmdsize;
5065
5066
5067 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5068 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5069 /* reject the unsolicited RPS request and done with it */
5070 goto reject_out;
5071
5072 cmdsize = sizeof(struct RTV_RSP) + sizeof(uint32_t);
5073 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
5074 lpfc_max_els_tries, ndlp,
5075 ndlp->nlp_DID, ELS_CMD_ACC);
5076
5077 if (!elsiocb)
5078 return 1;
5079
5080 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5081 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
5082 pcmd += sizeof(uint32_t); /* Skip past command */
5083
5084 /* use the command's xri in the response */
5085 elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;
5086
5087 rtv_rsp = (struct RTV_RSP *)pcmd;
5088
5089 /* populate RTV payload */
5090 rtv_rsp->ratov = cpu_to_be32(phba->fc_ratov * 1000); /* report msecs */
5091 rtv_rsp->edtov = cpu_to_be32(phba->fc_edtov);
5092 bf_set(qtov_edtovres, rtv_rsp, phba->fc_edtovResol ? 1 : 0);
5093 bf_set(qtov_rttov, rtv_rsp, 0); /* Field is for FC ONLY */
5094 rtv_rsp->qtov = cpu_to_be32(rtv_rsp->qtov);
5095
5096 /* Xmit ELS RLS ACC response tag <ulpIoTag> */
5097 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
5098 "2875 Xmit ELS RTV ACC response tag x%x xri x%x, "
5099 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x, "
5100 "Data: x%x x%x x%x\n",
5101 elsiocb->iotag, elsiocb->iocb.ulpContext,
5102 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
5103 ndlp->nlp_rpi,
5104 rtv_rsp->ratov, rtv_rsp->edtov, rtv_rsp->qtov);
5105 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
5106 phba->fc_stat.elsXmitACC++;
5107 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
5108 lpfc_els_free_iocb(phba, elsiocb);
5109 return 0;
5110
5111reject_out:
5112 /* issue rejection response */
5113 stat.un.b.lsRjtRsvd0 = 0;
5114 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5115 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5116 stat.un.b.vendorUnique = 0;
5117 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5118 return 0;
5119}
5120
5121/* lpfc_els_rcv_rps - Process an unsolicited rps iocb
4831 * @vport: pointer to a host virtual N_Port data structure. 5122 * @vport: pointer to a host virtual N_Port data structure.
4832 * @cmdiocb: pointer to lpfc command iocb data structure. 5123 * @cmdiocb: pointer to lpfc command iocb data structure.
4833 * @ndlp: pointer to a node-list data structure. 5124 * @ndlp: pointer to a node-list data structure.
@@ -5017,7 +5308,6 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5017 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; 5308 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5018 lp = (uint32_t *) pcmd->virt; 5309 lp = (uint32_t *) pcmd->virt;
5019 rpl = (RPL *) (lp + 1); 5310 rpl = (RPL *) (lp + 1);
5020
5021 maxsize = be32_to_cpu(rpl->maxsize); 5311 maxsize = be32_to_cpu(rpl->maxsize);
5022 5312
5023 /* We support only one port */ 5313 /* We support only one port */
@@ -5836,6 +6126,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5836 if (newnode) 6126 if (newnode)
5837 lpfc_nlp_put(ndlp); 6127 lpfc_nlp_put(ndlp);
5838 break; 6128 break;
6129 case ELS_CMD_RLS:
6130 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6131 "RCV RLS: did:x%x/ste:x%x flg:x%x",
6132 did, vport->port_state, ndlp->nlp_flag);
6133
6134 phba->fc_stat.elsRcvRLS++;
6135 lpfc_els_rcv_rls(vport, elsiocb, ndlp);
6136 if (newnode)
6137 lpfc_nlp_put(ndlp);
6138 break;
5839 case ELS_CMD_RPS: 6139 case ELS_CMD_RPS:
5840 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6140 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5841 "RCV RPS: did:x%x/ste:x%x flg:x%x", 6141 "RCV RPS: did:x%x/ste:x%x flg:x%x",
@@ -5866,6 +6166,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5866 if (newnode) 6166 if (newnode)
5867 lpfc_nlp_put(ndlp); 6167 lpfc_nlp_put(ndlp);
5868 break; 6168 break;
6169 case ELS_CMD_RTV:
6170 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6171 "RCV RTV: did:x%x/ste:x%x flg:x%x",
6172 did, vport->port_state, ndlp->nlp_flag);
6173 phba->fc_stat.elsRcvRTV++;
6174 lpfc_els_rcv_rtv(vport, elsiocb, ndlp);
6175 if (newnode)
6176 lpfc_nlp_put(ndlp);
6177 break;
5869 case ELS_CMD_RRQ: 6178 case ELS_CMD_RRQ:
5870 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6179 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5871 "RCV RRQ: did:x%x/ste:x%x flg:x%x", 6180 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
@@ -5876,6 +6185,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5876 if (newnode) 6185 if (newnode)
5877 lpfc_nlp_put(ndlp); 6186 lpfc_nlp_put(ndlp);
5878 break; 6187 break;
6188 case ELS_CMD_ECHO:
6189 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6190 "RCV ECHO: did:x%x/ste:x%x flg:x%x",
6191 did, vport->port_state, ndlp->nlp_flag);
6192
6193 phba->fc_stat.elsRcvECHO++;
6194 lpfc_els_rcv_echo(vport, elsiocb, ndlp);
6195 if (newnode)
6196 lpfc_nlp_put(ndlp);
6197 break;
5879 default: 6198 default:
5880 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6199 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5881 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", 6200 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
@@ -6170,6 +6489,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
6170 6489
6171 default: 6490 default:
6172 /* Try to recover from this error */ 6491 /* Try to recover from this error */
6492 if (phba->sli_rev == LPFC_SLI_REV4)
6493 lpfc_sli4_unreg_all_rpis(vport);
6173 lpfc_mbx_unreg_vpi(vport); 6494 lpfc_mbx_unreg_vpi(vport);
6174 spin_lock_irq(shost->host_lock); 6495 spin_lock_irq(shost->host_lock);
6175 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6496 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
@@ -6437,6 +6758,10 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6437 lpfc_unreg_rpi(vport, np); 6758 lpfc_unreg_rpi(vport, np);
6438 } 6759 }
6439 lpfc_cleanup_pending_mbox(vport); 6760 lpfc_cleanup_pending_mbox(vport);
6761
6762 if (phba->sli_rev == LPFC_SLI_REV4)
6763 lpfc_sli4_unreg_all_rpis(vport);
6764
6440 lpfc_mbx_unreg_vpi(vport); 6765 lpfc_mbx_unreg_vpi(vport);
6441 spin_lock_irq(shost->host_lock); 6766 spin_lock_irq(shost->host_lock);
6442 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6767 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
@@ -6452,7 +6777,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6452 * to update the MAC address. 6777 * to update the MAC address.
6453 */ 6778 */
6454 lpfc_register_new_vport(phba, vport, ndlp); 6779 lpfc_register_new_vport(phba, vport, ndlp);
6455 return ; 6780 goto out;
6456 } 6781 }
6457 6782
6458 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI) 6783 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)