Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: lpfc: Add EDC ELS support

When congestion management is enabled, issue EDC ELS to register congestion
signaling capabilities with the fabric. The response handling will process
the fabric parameters and set the reporting parameters.

Similarly, add support for receiving an EDC request from the fabric
generating a corresponding response.

Implement handlers for congestion signals from the fabric and maintain
statistics for them.

Link: https://lore.kernel.org/r/20210816162901.121235-6-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

James Smart and committed by
Martin K. Petersen
9064aeb2 428569e6

+988 -11
+35
drivers/scsi/lpfc/lpfc.h
··· 403 403 link3; 404 404 }; 405 405 406 + struct lpfc_cgn_acqe_stat { 407 + atomic64_t alarm; 408 + atomic64_t warn; 409 + }; 410 + 406 411 struct lpfc_vport { 407 412 struct lpfc_hba *phba; 408 413 struct list_head listentry; ··· 1348 1343 uint64_t ktime_seg10_min; 1349 1344 uint64_t ktime_seg10_max; 1350 1345 #endif 1346 + /* CMF objects */ 1347 + u32 cmf_active_mode; 1348 + #define LPFC_CFG_OFF 0 1349 + 1350 + /* Signal / FPIN handling for Congestion Mgmt */ 1351 + u8 cgn_reg_fpin; /* Negotiated value from RDF */ 1352 + u8 cgn_init_reg_fpin; /* Initial value from READ_CONFIG */ 1353 + #define LPFC_CGN_FPIN_NONE 0x0 1354 + #define LPFC_CGN_FPIN_WARN 0x1 1355 + #define LPFC_CGN_FPIN_ALARM 0x2 1356 + #define LPFC_CGN_FPIN_BOTH (LPFC_CGN_FPIN_WARN | LPFC_CGN_FPIN_ALARM) 1357 + 1358 + u8 cgn_reg_signal; /* Negotiated value from EDC */ 1359 + u8 cgn_init_reg_signal; /* Initial value from READ_CONFIG */ 1360 + /* cgn_reg_signal and cgn_init_reg_signal use 1361 + * enum fc_edc_cg_signal_cap_types 1362 + */ 1363 + u16 cgn_fpin_frequency; 1364 + #define LPFC_FPIN_INIT_FREQ 0xffff 1365 + u32 cgn_sig_freq; 1366 + u32 cgn_acqe_cnt; 1367 + 1368 + /* Statistics counter for ACQE cgn alarms and warnings */ 1369 + struct lpfc_cgn_acqe_stat cgn_acqe_stat; 1370 + 1371 + /* Congestion buffer information */ 1372 + atomic_t cgn_fabric_warn_cnt; /* Total warning cgn events for info */ 1373 + atomic_t cgn_fabric_alarm_cnt; /* Total alarm cgn events for info */ 1374 + atomic_t cgn_sync_warn_cnt; /* Total warning events for SYNC wqe */ 1375 + atomic_t cgn_sync_alarm_cnt; /* Total alarm events for SYNC wqe */ 1351 1376 1352 1377 struct hlist_node cpuhp; /* used for cpuhp per hba callback */ 1353 1378 struct timer_list cpuhp_poll_timer;
+27
drivers/scsi/lpfc/lpfc_attr.c
··· 6150 6150 */ 6151 6151 LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery"); 6152 6152 6153 + /* Signaling module parameters */ 6154 + int lpfc_fabric_cgn_frequency = 100; /* 100 ms default */ 6155 + module_param(lpfc_fabric_cgn_frequency, int, 0444); 6156 + MODULE_PARM_DESC(lpfc_fabric_cgn_frequency, "Congestion signaling fabric freq"); 6157 + 6158 + int lpfc_acqe_cgn_frequency = 10; /* 10 sec default */ 6159 + module_param(lpfc_acqe_cgn_frequency, int, 0444); 6160 + MODULE_PARM_DESC(lpfc_acqe_cgn_frequency, "Congestion signaling ACQE freq"); 6161 + 6162 + int lpfc_use_cgn_signal = 1; /* 0 - only use FPINs, 1 - Use signals if avail */ 6163 + module_param(lpfc_use_cgn_signal, int, 0444); 6164 + MODULE_PARM_DESC(lpfc_use_cgn_signal, "Use Congestion signaling if available"); 6165 + 6153 6166 /* 6154 6167 * lpfc_enable_dpp: Enable DPP on G7 6155 6168 * 0 = DPP on G7 disabled ··· 6928 6915 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; 6929 6916 hs->error_frames = pmb->un.varRdLnk.crcCnt; 6930 6917 6918 + hs->cn_sig_warn = atomic64_read(&phba->cgn_acqe_stat.warn); 6919 + hs->cn_sig_alarm = atomic64_read(&phba->cgn_acqe_stat.alarm); 6920 + 6931 6921 hs->link_failure_count -= lso->link_failure_count; 6932 6922 hs->loss_of_sync_count -= lso->loss_of_sync_count; 6933 6923 hs->loss_of_signal_count -= lso->loss_of_signal_count; ··· 7041 7025 lso->link_events = (phba->link_events >> 1); 7042 7026 else 7043 7027 lso->link_events = (phba->fc_eventTag >> 1); 7028 + 7029 + atomic64_set(&phba->cgn_acqe_stat.warn, 0); 7030 + atomic64_set(&phba->cgn_acqe_stat.alarm, 0); 7031 + 7032 + memset(&shost_to_fc_host(shost)->fpin_stats, 0, 7033 + sizeof(shost_to_fc_host(shost)->fpin_stats)); 7044 7034 7045 7035 psli->stats_start = ktime_get_seconds(); 7046 7036 ··· 7480 7458 lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr); 7481 7459 lpfc_enable_dpp_init(phba, lpfc_enable_dpp); 7482 7460 lpfc_enable_mi_init(phba, lpfc_enable_mi); 7461 + 7462 + phba->cmf_active_mode = LPFC_CFG_OFF; 7463 + if (lpfc_fabric_cgn_frequency > EDC_CG_SIGFREQ_CNT_MAX || 7464 + lpfc_fabric_cgn_frequency < EDC_CG_SIGFREQ_CNT_MIN) 7465 + lpfc_fabric_cgn_frequency = 100; /* 100 ms default */ 7483 7466 7484 7467 if (phba->sli_rev != LPFC_SLI_REV4) { 7485 7468 /* NVME only supported on SLI4 */
+6
drivers/scsi/lpfc/lpfc_crtn.h
··· 74 74 void lpfc_free_iocb_list(struct lpfc_hba *phba); 75 75 int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, 76 76 struct lpfc_queue *drq, int count, int idx); 77 + int lpfc_config_cgn_signal(struct lpfc_hba *phba); 77 78 78 79 void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); 79 80 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); ··· 144 143 int lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry); 145 144 int lpfc_issue_fabric_reglogin(struct lpfc_vport *); 146 145 int lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry); 146 + int lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry); 147 147 int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); 148 148 int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); 149 149 int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, ··· 609 607 extern unsigned long long lpfc_enable_nvmet[]; 610 608 extern int lpfc_no_hba_reset_cnt; 611 609 extern unsigned long lpfc_no_hba_reset[]; 610 + extern int lpfc_acqe_cgn_frequency; 611 + extern int lpfc_fabric_cgn_frequency; 612 + extern int lpfc_use_cgn_signal; 613 + 612 614 extern union lpfc_wqe128 lpfc_iread_cmd_template; 613 615 extern union lpfc_wqe128 lpfc_iwrite_cmd_template; 614 616 extern union lpfc_wqe128 lpfc_icmnd_cmd_template;
+2
drivers/scsi/lpfc/lpfc_ct.c
··· 2288 2288 /* No retry on Vendor, RPA only done on physical port */ 2289 2289 if (phba->link_flag & LS_CT_VEN_RPA) { 2290 2290 phba->link_flag &= ~LS_CT_VEN_RPA; 2291 + if (phba->cmf_active_mode == LPFC_CFG_OFF) 2292 + return; 2291 2293 lpfc_printf_log(phba, KERN_ERR, 2292 2294 LOG_DISCOVERY | LOG_ELS, 2293 2295 "6460 VEN FDMI RPA failure\n");
+633 -4
drivers/scsi/lpfc/lpfc_els.c
··· 56 56 struct lpfc_nodelist *ndlp, uint8_t retry); 57 57 static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba, 58 58 struct lpfc_iocbq *iocb); 59 + static void lpfc_cmpl_els_edc(struct lpfc_hba *phba, 60 + struct lpfc_iocbq *cmdiocb, 61 + struct lpfc_iocbq *rspiocb); 59 62 static void lpfc_cmpl_els_uvem(struct lpfc_hba *, struct lpfc_iocbq *, 60 63 struct lpfc_iocbq *); 61 64 ··· 3289 3286 case ELS_CMD_SCR: 3290 3287 lpfc_issue_els_scr(vport, cmdiocb->retry); 3291 3288 break; 3289 + case ELS_CMD_EDC: 3290 + lpfc_issue_els_edc(vport, cmdiocb->retry); 3291 + break; 3292 3292 case ELS_CMD_RDF: 3293 3293 cmdiocb->context1 = NULL; /* save ndlp refcnt */ 3294 3294 lpfc_issue_els_rdf(vport, cmdiocb->retry); ··· 3300 3294 goto out; 3301 3295 } 3302 3296 phba->fc_stat.elsRetryExceeded++; 3297 + } 3298 + if (cmd == ELS_CMD_EDC) { 3299 + /* must be called before checking uplStatus and returning */ 3300 + lpfc_cmpl_els_edc(phba, cmdiocb, rspiocb); 3301 + return; 3303 3302 } 3304 3303 if (irsp->ulpStatus) { 3305 3304 /* ELS discovery cmd completes with error */ ··· 3760 3749 } 3761 3750 3762 3751 return 0; 3752 + } 3753 + 3754 + /** 3755 + * lpfc_least_capable_settings - helper function for EDC rsp processing 3756 + * @phba: pointer to lpfc hba data structure. 3757 + * @pcgd: pointer to congestion detection descriptor in EDC rsp. 3758 + * 3759 + * This helper routine determines the least capable setting for 3760 + * congestion signals, signal freq, including scale, from the 3761 + * congestion detection descriptor in the EDC rsp. The routine 3762 + * sets @phba values in preparation for a set_featues mailbox. 3763 + **/ 3764 + static void 3765 + lpfc_least_capable_settings(struct lpfc_hba *phba, 3766 + struct fc_diag_cg_sig_desc *pcgd) 3767 + { 3768 + u32 rsp_sig_cap = 0, drv_sig_cap = 0; 3769 + u32 rsp_sig_freq_cyc = 0, rsp_sig_freq_scale = 0; 3770 + 3771 + /* Get rsp signal and frequency capabilities. */ 3772 + rsp_sig_cap = be32_to_cpu(pcgd->xmt_signal_capability); 3773 + rsp_sig_freq_cyc = be16_to_cpu(pcgd->xmt_signal_frequency.count); 3774 + rsp_sig_freq_scale = be16_to_cpu(pcgd->xmt_signal_frequency.units); 3775 + 3776 + /* If the Fport does not support signals. Set FPIN only */ 3777 + if (rsp_sig_cap == EDC_CG_SIG_NOTSUPPORTED) 3778 + goto out_no_support; 3779 + 3780 + /* Apply the xmt scale to the xmt cycle to get the correct frequency. 3781 + * Adapter default is 100 millisSeconds. Convert all xmt cycle values 3782 + * to milliSeconds. 3783 + */ 3784 + switch (rsp_sig_freq_scale) { 3785 + case EDC_CG_SIGFREQ_SEC: 3786 + rsp_sig_freq_cyc *= MSEC_PER_SEC; 3787 + break; 3788 + case EDC_CG_SIGFREQ_MSEC: 3789 + rsp_sig_freq_cyc = 1; 3790 + break; 3791 + default: 3792 + goto out_no_support; 3793 + } 3794 + 3795 + /* Convenient shorthand. */ 3796 + drv_sig_cap = phba->cgn_reg_signal; 3797 + 3798 + /* Choose the least capable frequency. */ 3799 + if (rsp_sig_freq_cyc > phba->cgn_sig_freq) 3800 + phba->cgn_sig_freq = rsp_sig_freq_cyc; 3801 + 3802 + /* Should be some common signals support. Settle on least capable 3803 + * signal and adjust FPIN values. Initialize defaults to ease the 3804 + * decision. 3805 + */ 3806 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_WARN | LPFC_CGN_FPIN_ALARM; 3807 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 3808 + if (rsp_sig_cap == EDC_CG_SIG_WARN_ONLY && 3809 + (drv_sig_cap == EDC_CG_SIG_WARN_ONLY || 3810 + drv_sig_cap == EDC_CG_SIG_WARN_ALARM)) { 3811 + phba->cgn_reg_signal = EDC_CG_SIG_WARN_ONLY; 3812 + phba->cgn_reg_fpin &= ~LPFC_CGN_FPIN_WARN; 3813 + } 3814 + if (rsp_sig_cap == EDC_CG_SIG_WARN_ALARM) { 3815 + if (drv_sig_cap == EDC_CG_SIG_WARN_ALARM) { 3816 + phba->cgn_reg_signal = EDC_CG_SIG_WARN_ALARM; 3817 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_NONE; 3818 + } 3819 + if (drv_sig_cap == EDC_CG_SIG_WARN_ONLY) { 3820 + phba->cgn_reg_signal = EDC_CG_SIG_WARN_ONLY; 3821 + phba->cgn_reg_fpin &= ~LPFC_CGN_FPIN_WARN; 3822 + } 3823 + } 3824 + return; 3825 + 3826 + out_no_support: 3827 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 3828 + phba->cgn_sig_freq = 0; 3829 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_ALARM | LPFC_CGN_FPIN_WARN; 3830 + } 3831 + 3832 + DECLARE_ENUM2STR_LOOKUP(lpfc_get_tlv_dtag_nm, fc_ls_tlv_dtag, 3833 + FC_LS_TLV_DTAG_INIT); 3834 + 3835 + /** 3836 + * lpfc_cmpl_els_edc - Completion callback function for EDC 3837 + * @phba: pointer to lpfc hba data structure. 3838 + * @cmdiocb: pointer to lpfc command iocb data structure. 3839 + * @rspiocb: pointer to lpfc response iocb data structure. 3840 + * 3841 + * This routine is the completion callback function for issuing the Exchange 3842 + * Diagnostic Capabilities (EDC) command. The driver issues an EDC to 3843 + * notify the FPort of its Congestion and Link Fault capabilities. This 3844 + * routine parses the FPort's response and decides on the least common 3845 + * values applicable to both FPort and NPort for Warnings and Alarms that 3846 + * are communicated via hardware signals. 3847 + **/ 3848 + static void 3849 + lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 3850 + struct lpfc_iocbq *rspiocb) 3851 + { 3852 + IOCB_t *irsp; 3853 + struct fc_els_edc_resp *edc_rsp; 3854 + struct fc_tlv_desc *tlv; 3855 + struct fc_diag_cg_sig_desc *pcgd; 3856 + struct fc_diag_lnkflt_desc *plnkflt; 3857 + struct lpfc_dmabuf *pcmd, *prsp; 3858 + const char *dtag_nm; 3859 + u32 *pdata, dtag; 3860 + int desc_cnt = 0, bytes_remain; 3861 + bool rcv_cap_desc = false; 3862 + struct lpfc_nodelist *ndlp; 3863 + 3864 + irsp = &rspiocb->iocb; 3865 + ndlp = cmdiocb->context1; 3866 + 3867 + lpfc_debugfs_disc_trc(phba->pport, LPFC_DISC_TRC_ELS_CMD, 3868 + "EDC cmpl: status:x%x/x%x did:x%x", 3869 + irsp->ulpStatus, irsp->un.ulpWord[4], 3870 + irsp->un.elsreq64.remoteID); 3871 + 3872 + /* ELS cmd tag <ulpIoTag> completes */ 3873 + lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 3874 + "4201 EDC cmd tag x%x completes Data: x%x x%x x%x\n", 3875 + irsp->ulpIoTag, irsp->ulpStatus, 3876 + irsp->un.ulpWord[4], irsp->ulpTimeout); 3877 + 3878 + pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; 3879 + if (!pcmd) 3880 + goto out; 3881 + 3882 + pdata = (u32 *)pcmd->virt; 3883 + if (!pdata) 3884 + goto out; 3885 + 3886 + /* Need to clear signal values, send features MB and RDF with FPIN. */ 3887 + if (irsp->ulpStatus) 3888 + goto out; 3889 + 3890 + prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); 3891 + if (!prsp) 3892 + goto out; 3893 + 3894 + edc_rsp = prsp->virt; 3895 + if (!edc_rsp) 3896 + goto out; 3897 + 3898 + /* ELS cmd tag <ulpIoTag> completes */ 3899 + lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 3900 + "4676 Fabric EDC Rsp: " 3901 + "0x%02x, 0x%08x\n", 3902 + edc_rsp->acc_hdr.la_cmd, 3903 + be32_to_cpu(edc_rsp->desc_list_len)); 3904 + 3905 + /* 3906 + * Payload length in bytes is the response descriptor list 3907 + * length minus the 12 bytes of Link Service Request 3908 + * Information descriptor in the reply. 3909 + */ 3910 + bytes_remain = be32_to_cpu(edc_rsp->desc_list_len) - 3911 + sizeof(struct fc_els_lsri_desc); 3912 + if (bytes_remain <= 0) 3913 + goto out; 3914 + 3915 + tlv = edc_rsp->desc; 3916 + 3917 + /* 3918 + * cycle through EDC diagnostic descriptors to find the 3919 + * congestion signaling capability descriptor 3920 + */ 3921 + while (bytes_remain) { 3922 + if (bytes_remain < FC_TLV_DESC_HDR_SZ) { 3923 + lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, 3924 + "6461 Truncated TLV hdr on " 3925 + "Diagnostic descriptor[%d]\n", 3926 + desc_cnt); 3927 + goto out; 3928 + } 3929 + 3930 + dtag = be32_to_cpu(tlv->desc_tag); 3931 + switch (dtag) { 3932 + case ELS_DTAG_LNK_FAULT_CAP: 3933 + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || 3934 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != 3935 + sizeof(struct fc_diag_lnkflt_desc)) { 3936 + lpfc_printf_log( 3937 + phba, KERN_WARNING, LOG_CGN_MGMT, 3938 + "6462 Truncated Link Fault Diagnostic " 3939 + "descriptor[%d]: %d vs 0x%zx 0x%zx\n", 3940 + desc_cnt, bytes_remain, 3941 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv), 3942 + sizeof(struct fc_diag_cg_sig_desc)); 3943 + goto out; 3944 + } 3945 + plnkflt = (struct fc_diag_lnkflt_desc *)tlv; 3946 + lpfc_printf_log( 3947 + phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 3948 + "4617 Link Fault Desc Data: 0x%08x 0x%08x " 3949 + "0x%08x 0x%08x 0x%08x\n", 3950 + be32_to_cpu(plnkflt->desc_tag), 3951 + be32_to_cpu(plnkflt->desc_len), 3952 + be32_to_cpu( 3953 + plnkflt->degrade_activate_threshold), 3954 + be32_to_cpu( 3955 + plnkflt->degrade_deactivate_threshold), 3956 + be32_to_cpu(plnkflt->fec_degrade_interval)); 3957 + break; 3958 + case ELS_DTAG_CG_SIGNAL_CAP: 3959 + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || 3960 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != 3961 + sizeof(struct fc_diag_cg_sig_desc)) { 3962 + lpfc_printf_log( 3963 + phba, KERN_WARNING, LOG_CGN_MGMT, 3964 + "6463 Truncated Cgn Signal Diagnostic " 3965 + "descriptor[%d]: %d vs 0x%zx 0x%zx\n", 3966 + desc_cnt, bytes_remain, 3967 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv), 3968 + sizeof(struct fc_diag_cg_sig_desc)); 3969 + goto out; 3970 + } 3971 + 3972 + pcgd = (struct fc_diag_cg_sig_desc *)tlv; 3973 + lpfc_printf_log( 3974 + phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 3975 + "4616 CGN Desc Data: 0x%08x 0x%08x " 3976 + "0x%08x 0x%04x 0x%04x 0x%08x 0x%04x 0x%04x\n", 3977 + be32_to_cpu(pcgd->desc_tag), 3978 + be32_to_cpu(pcgd->desc_len), 3979 + be32_to_cpu(pcgd->xmt_signal_capability), 3980 + be32_to_cpu(pcgd->xmt_signal_frequency.count), 3981 + be32_to_cpu(pcgd->xmt_signal_frequency.units), 3982 + be32_to_cpu(pcgd->rcv_signal_capability), 3983 + be32_to_cpu(pcgd->rcv_signal_frequency.count), 3984 + be32_to_cpu(pcgd->rcv_signal_frequency.units)); 3985 + 3986 + /* Compare driver and Fport capabilities and choose 3987 + * least common. 3988 + */ 3989 + lpfc_least_capable_settings(phba, pcgd); 3990 + rcv_cap_desc = true; 3991 + break; 3992 + default: 3993 + dtag_nm = lpfc_get_tlv_dtag_nm(dtag); 3994 + lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, 3995 + "4919 unknown Diagnostic " 3996 + "Descriptor[%d]: tag x%x (%s)\n", 3997 + desc_cnt, dtag, dtag_nm); 3998 + } 3999 + 4000 + bytes_remain -= FC_TLV_DESC_SZ_FROM_LENGTH(tlv); 4001 + tlv = fc_tlv_next_desc(tlv); 4002 + desc_cnt++; 4003 + } 4004 + 4005 + out: 4006 + if (!rcv_cap_desc) { 4007 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_ALARM | LPFC_CGN_FPIN_WARN; 4008 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 4009 + phba->cgn_sig_freq = 0; 4010 + lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_CGN_MGMT, 4011 + "4202 EDC rsp error - sending RDF " 4012 + "for FPIN only.\n"); 4013 + } 4014 + 4015 + lpfc_config_cgn_signal(phba); 4016 + 4017 + /* Check to see if link went down during discovery */ 4018 + lpfc_els_chk_latt(phba->pport); 4019 + lpfc_debugfs_disc_trc(phba->pport, LPFC_DISC_TRC_ELS_CMD, 4020 + "EDC Cmpl: did:x%x refcnt %d", 4021 + ndlp->nlp_DID, kref_read(&ndlp->kref), 0); 4022 + lpfc_els_free_iocb(phba, cmdiocb); 4023 + lpfc_nlp_put(ndlp); 4024 + } 4025 + 4026 + static void 4027 + lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_diag_cg_sig_desc *cgd) 4028 + { 4029 + /* We are assuming cgd was zero'ed before calling this routine */ 4030 + 4031 + /* Configure the congestion detection capability */ 4032 + cgd->desc_tag = cpu_to_be32(ELS_DTAG_CG_SIGNAL_CAP); 4033 + 4034 + /* Descriptor len doesn't include the tag or len fields. */ 4035 + cgd->desc_len = cpu_to_be32( 4036 + FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_diag_cg_sig_desc)); 4037 + 4038 + /* xmt_signal_capability already set to EDC_CG_SIG_NOTSUPPORTED. 4039 + * xmt_signal_frequency.count already set to 0. 4040 + * xmt_signal_frequency.units already set to 0. 4041 + */ 4042 + 4043 + if (phba->cmf_active_mode == LPFC_CFG_OFF) { 4044 + /* rcv_signal_capability already set to EDC_CG_SIG_NOTSUPPORTED. 4045 + * rcv_signal_frequency.count already set to 0. 4046 + * rcv_signal_frequency.units already set to 0. 4047 + */ 4048 + phba->cgn_sig_freq = 0; 4049 + return; 4050 + } 4051 + switch (phba->cgn_reg_signal) { 4052 + case EDC_CG_SIG_WARN_ONLY: 4053 + cgd->rcv_signal_capability = cpu_to_be32(EDC_CG_SIG_WARN_ONLY); 4054 + break; 4055 + case EDC_CG_SIG_WARN_ALARM: 4056 + cgd->rcv_signal_capability = cpu_to_be32(EDC_CG_SIG_WARN_ALARM); 4057 + break; 4058 + default: 4059 + /* rcv_signal_capability left 0 thus no support */ 4060 + break; 4061 + } 4062 + 4063 + /* We start negotiation with lpfc_fabric_cgn_frequency, after 4064 + * the completion we settle on the higher frequency. 4065 + */ 4066 + cgd->rcv_signal_frequency.count = 4067 + cpu_to_be16(lpfc_fabric_cgn_frequency); 4068 + cgd->rcv_signal_frequency.units = 4069 + cpu_to_be16(EDC_CG_SIGFREQ_MSEC); 4070 + } 4071 + 4072 + /** 4073 + * lpfc_issue_els_edc - Exchange Diagnostic Capabilities with the fabric. 4074 + * @vport: pointer to a host virtual N_Port data structure. 4075 + * @retry: retry counter for the command iocb. 4076 + * 4077 + * This routine issues an ELS EDC to the F-Port Controller to communicate 4078 + * this N_Port's support of hardware signals in its Congestion 4079 + * Capabilities Descriptor. 4080 + * 4081 + * Note: This routine does not check if one or more signals are 4082 + * set in the cgn_reg_signal parameter. The caller makes the 4083 + * decision to enforce cgn_reg_signal as nonzero or zero depending 4084 + * on the conditions. During Fabric requests, the driver 4085 + * requires cgn_reg_signals to be nonzero. But a dynamic request 4086 + * to set the congestion mode to OFF from Monitor or Manage 4087 + * would correctly issue an EDC with no signals enabled to 4088 + * turn off switch functionality and then update the FW. 4089 + * 4090 + * Return code 4091 + * 0 - Successfully issued edc command 4092 + * 1 - Failed to issue edc command 4093 + **/ 4094 + int 4095 + lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry) 4096 + { 4097 + struct lpfc_hba *phba = vport->phba; 4098 + struct lpfc_iocbq *elsiocb; 4099 + struct lpfc_els_edc_req *edc_req; 4100 + struct fc_diag_cg_sig_desc *cgn_desc; 4101 + u16 cmdsize; 4102 + struct lpfc_nodelist *ndlp; 4103 + u8 *pcmd = NULL; 4104 + u32 edc_req_size, cgn_desc_size; 4105 + int rc; 4106 + 4107 + if (vport->port_type == LPFC_NPIV_PORT) 4108 + return -EACCES; 4109 + 4110 + ndlp = lpfc_findnode_did(vport, Fabric_DID); 4111 + if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) 4112 + return -ENODEV; 4113 + 4114 + /* If HBA doesn't support signals, drop into RDF */ 4115 + if (!phba->cgn_init_reg_signal) 4116 + goto try_rdf; 4117 + 4118 + edc_req_size = sizeof(struct fc_els_edc); 4119 + cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc); 4120 + cmdsize = edc_req_size + cgn_desc_size; 4121 + elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, 4122 + ndlp->nlp_DID, ELS_CMD_EDC); 4123 + if (!elsiocb) 4124 + goto try_rdf; 4125 + 4126 + /* Configure the payload for the supported Diagnostics capabilities. */ 4127 + pcmd = (u8 *)(((struct lpfc_dmabuf *)elsiocb->context2)->virt); 4128 + memset(pcmd, 0, cmdsize); 4129 + edc_req = (struct lpfc_els_edc_req *)pcmd; 4130 + edc_req->edc.desc_len = cpu_to_be32(cgn_desc_size); 4131 + edc_req->edc.edc_cmd = ELS_EDC; 4132 + 4133 + cgn_desc = &edc_req->cgn_desc; 4134 + 4135 + lpfc_format_edc_cgn_desc(phba, cgn_desc); 4136 + 4137 + phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; 4138 + 4139 + lpfc_printf_vlog(vport, KERN_INFO, LOG_CGN_MGMT, 4140 + "4623 Xmit EDC to remote " 4141 + "NPORT x%x reg_sig x%x reg_fpin:x%x\n", 4142 + ndlp->nlp_DID, phba->cgn_reg_signal, 4143 + phba->cgn_reg_fpin); 4144 + 4145 + elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd; 4146 + elsiocb->context1 = lpfc_nlp_get(ndlp); 4147 + if (!elsiocb->context1) { 4148 + lpfc_els_free_iocb(phba, elsiocb); 4149 + return -EIO; 4150 + } 4151 + 4152 + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, 4153 + "Issue EDC: did:x%x refcnt %d", 4154 + ndlp->nlp_DID, kref_read(&ndlp->kref), 0); 4155 + rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); 4156 + if (rc == IOCB_ERROR) { 4157 + /* The additional lpfc_nlp_put will cause the following 4158 + * lpfc_els_free_iocb routine to trigger the rlease of 4159 + * the node. 4160 + */ 4161 + lpfc_els_free_iocb(phba, elsiocb); 4162 + lpfc_nlp_put(ndlp); 4163 + goto try_rdf; 4164 + } 4165 + return 0; 4166 + try_rdf: 4167 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_WARN | LPFC_CGN_FPIN_ALARM; 4168 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 4169 + rc = lpfc_issue_els_rdf(vport, 0); 4170 + return rc; 3763 4171 } 3764 4172 3765 4173 /** ··· 4945 4515 { 4946 4516 struct lpfc_dmabuf *buf_ptr, *buf_ptr1; 4947 4517 4948 - /* The I/O job is complete. Clear the context1 data. */ 4518 + /* The I/O iocb is complete. Clear the context1 data. */ 4949 4519 elsiocb->context1 = NULL; 4950 4520 4951 4521 /* context2 = cmd, context2->next = rsp, context3 = bpl */ ··· 5588 5158 lpfc_nlp_put(ndlp); 5589 5159 return 1; 5590 5160 } 5161 + 5162 + return 0; 5163 + } 5164 + 5165 + /** 5166 + * lpfc_issue_els_edc_rsp - Exchange Diagnostic Capabilities with the fabric. 5167 + * @vport: pointer to a host virtual N_Port data structure. 5168 + * @cmdiocb: pointer to the original lpfc command iocb data structure. 5169 + * @ndlp: NPort to where rsp is directed 5170 + * 5171 + * This routine issues an EDC ACC RSP to the F-Port Controller to communicate 5172 + * this N_Port's support of hardware signals in its Congestion 5173 + * Capabilities Descriptor. 5174 + * 5175 + * Return code 5176 + * 0 - Successfully issued edc rsp command 5177 + * 1 - Failed to issue edc rsp command 5178 + **/ 5179 + static int 5180 + lpfc_issue_els_edc_rsp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, 5181 + struct lpfc_nodelist *ndlp) 5182 + { 5183 + struct lpfc_hba *phba = vport->phba; 5184 + struct lpfc_els_edc_rsp *edc_rsp; 5185 + struct lpfc_iocbq *elsiocb; 5186 + IOCB_t *icmd, *cmd; 5187 + uint8_t *pcmd; 5188 + int cmdsize, rc; 5189 + 5190 + cmdsize = sizeof(struct lpfc_els_edc_rsp); 5191 + elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, cmdiocb->retry, 5192 + ndlp, ndlp->nlp_DID, ELS_CMD_ACC); 5193 + if (!elsiocb) 5194 + return 1; 5195 + 5196 + icmd = &elsiocb->iocb; 5197 + cmd = &cmdiocb->iocb; 5198 + icmd->ulpContext = cmd->ulpContext; /* Xri / rx_id */ 5199 + icmd->unsli3.rcvsli3.ox_id = cmd->unsli3.rcvsli3.ox_id; 5200 + pcmd = (((struct lpfc_dmabuf *)elsiocb->context2)->virt); 5201 + memset(pcmd, 0, cmdsize); 5202 + 5203 + edc_rsp = (struct lpfc_els_edc_rsp *)pcmd; 5204 + edc_rsp->edc_rsp.acc_hdr.la_cmd = ELS_LS_ACC; 5205 + edc_rsp->edc_rsp.desc_list_len = cpu_to_be32( 5206 + FC_TLV_DESC_LENGTH_FROM_SZ(struct lpfc_els_edc_rsp)); 5207 + edc_rsp->edc_rsp.lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO); 5208 + edc_rsp->edc_rsp.lsri.desc_len = cpu_to_be32( 5209 + FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_els_lsri_desc)); 5210 + edc_rsp->edc_rsp.lsri.rqst_w0.cmd = ELS_EDC; 5211 + lpfc_format_edc_cgn_desc(phba, &edc_rsp->cgn_desc); 5212 + 5213 + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, 5214 + "Issue EDC ACC: did:x%x flg:x%x refcnt %d", 5215 + ndlp->nlp_DID, ndlp->nlp_flag, 5216 + kref_read(&ndlp->kref)); 5217 + elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; 5218 + 5219 + phba->fc_stat.elsXmitACC++; 5220 + elsiocb->context1 = lpfc_nlp_get(ndlp); 5221 + if (!elsiocb->context1) { 5222 + lpfc_els_free_iocb(phba, elsiocb); 5223 + return 1; 5224 + } 5225 + 5226 + rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); 5227 + if (rc == IOCB_ERROR) { 5228 + lpfc_els_free_iocb(phba, elsiocb); 5229 + lpfc_nlp_put(ndlp); 5230 + return 1; 5231 + } 5232 + 5233 + /* Xmit ELS ACC response tag <ulpIoTag> */ 5234 + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 5235 + "0152 Xmit EDC ACC response Status: x%x, IoTag: x%x, " 5236 + "XRI: x%x, DID: x%x, nlp_flag: x%x nlp_state: x%x " 5237 + "RPI: x%x, fc_flag x%x\n", 5238 + rc, elsiocb->iotag, elsiocb->sli4_xritag, 5239 + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, 5240 + ndlp->nlp_rpi, vport->fc_flag); 5591 5241 5592 5242 return 0; 5593 5243 } ··· 8742 8232 } 8743 8233 8744 8234 /** 8235 + * lpfc_els_rcv_edc - Process an unsolicited EDC iocb 8236 + * @vport: pointer to a host virtual N_Port data structure. 8237 + * @cmdiocb: pointer to lpfc command iocb data structure. 8238 + * @ndlp: pointer to a node-list data structure. 8239 + * 8240 + * Return code 8241 + * 0 - Successfully processed echo iocb (currently always return 0) 8242 + **/ 8243 + static int 8244 + lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, 8245 + struct lpfc_nodelist *ndlp) 8246 + { 8247 + struct lpfc_hba *phba = vport->phba; 8248 + struct fc_els_edc *edc_req; 8249 + struct fc_tlv_desc *tlv; 8250 + uint8_t *payload; 8251 + uint32_t *ptr, dtag; 8252 + const char *dtag_nm; 8253 + int desc_cnt = 0, bytes_remain; 8254 + bool rcv_cap_desc = false; 8255 + 8256 + payload = ((struct lpfc_dmabuf *)cmdiocb->context2)->virt; 8257 + 8258 + edc_req = (struct fc_els_edc *)payload; 8259 + bytes_remain = be32_to_cpu(edc_req->desc_len); 8260 + 8261 + ptr = (uint32_t *)payload; 8262 + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 8263 + "3319 Rcv EDC payload len %d: x%x x%x x%x\n", 8264 + bytes_remain, be32_to_cpu(*ptr), 8265 + be32_to_cpu(*(ptr + 1)), be32_to_cpu(*(ptr + 2))); 8266 + 8267 + /* No signal support unless there is a congestion descriptor */ 8268 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 8269 + phba->cgn_sig_freq = 0; 8270 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_ALARM | LPFC_CGN_FPIN_WARN; 8271 + 8272 + if (bytes_remain <= 0) 8273 + goto out; 8274 + 8275 + tlv = edc_req->desc; 8276 + 8277 + /* 8278 + * cycle through EDC diagnostic descriptors to find the 8279 + * congestion signaling capability descriptor 8280 + */ 8281 + while (bytes_remain && !rcv_cap_desc) { 8282 + if (bytes_remain < FC_TLV_DESC_HDR_SZ) { 8283 + lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, 8284 + "6464 Truncated TLV hdr on " 8285 + "Diagnostic descriptor[%d]\n", 8286 + desc_cnt); 8287 + goto out; 8288 + } 8289 + 8290 + dtag = be32_to_cpu(tlv->desc_tag); 8291 + switch (dtag) { 8292 + case ELS_DTAG_LNK_FAULT_CAP: 8293 + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || 8294 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != 8295 + sizeof(struct fc_diag_lnkflt_desc)) { 8296 + lpfc_printf_log( 8297 + phba, KERN_WARNING, LOG_CGN_MGMT, 8298 + "6465 Truncated Link Fault Diagnostic " 8299 + "descriptor[%d]: %d vs 0x%zx 0x%zx\n", 8300 + desc_cnt, bytes_remain, 8301 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv), 8302 + sizeof(struct fc_diag_cg_sig_desc)); 8303 + goto out; 8304 + } 8305 + /* No action for Link Fault descriptor for now */ 8306 + break; 8307 + case ELS_DTAG_CG_SIGNAL_CAP: 8308 + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || 8309 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != 8310 + sizeof(struct fc_diag_cg_sig_desc)) { 8311 + lpfc_printf_log( 8312 + phba, KERN_WARNING, LOG_CGN_MGMT, 8313 + "6466 Truncated cgn signal Diagnostic " 8314 + "descriptor[%d]: %d vs 0x%zx 0x%zx\n", 8315 + desc_cnt, bytes_remain, 8316 + FC_TLV_DESC_SZ_FROM_LENGTH(tlv), 8317 + sizeof(struct fc_diag_cg_sig_desc)); 8318 + goto out; 8319 + } 8320 + 8321 + phba->cgn_reg_fpin = phba->cgn_init_reg_fpin; 8322 + phba->cgn_reg_signal = phba->cgn_init_reg_signal; 8323 + 8324 + /* We start negotiation with lpfc_fabric_cgn_frequency. 8325 + * When we process the EDC, we will settle on the 8326 + * higher frequency. 8327 + */ 8328 + phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; 8329 + 8330 + lpfc_least_capable_settings( 8331 + phba, (struct fc_diag_cg_sig_desc *)tlv); 8332 + rcv_cap_desc = true; 8333 + break; 8334 + default: 8335 + dtag_nm = lpfc_get_tlv_dtag_nm(dtag); 8336 + lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, 8337 + "6467 unknown Diagnostic " 8338 + "Descriptor[%d]: tag x%x (%s)\n", 8339 + desc_cnt, dtag, dtag_nm); 8340 + } 8341 + bytes_remain -= FC_TLV_DESC_SZ_FROM_LENGTH(tlv); 8342 + tlv = fc_tlv_next_desc(tlv); 8343 + desc_cnt++; 8344 + } 8345 + out: 8346 + /* Need to send back an ACC */ 8347 + lpfc_issue_els_edc_rsp(vport, cmdiocb, ndlp); 8348 + 8349 + lpfc_config_cgn_signal(phba); 8350 + return 0; 8351 + } 8352 + 8353 + /** 8745 8354 * lpfc_els_timeout - Handler funciton to the els timer 8746 8355 * @t: timer context used to obtain the vport. 8747 8356 * ··· 9316 8687 return; 9317 8688 } 9318 8689 9319 - 9320 - DECLARE_ENUM2STR_LOOKUP(lpfc_get_tlv_dtag_nm, fc_ls_tlv_dtag, 9321 - FC_LS_TLV_DTAG_INIT); 9322 8690 9323 8691 DECLARE_ENUM2STR_LOOKUP(lpfc_get_fpin_li_event_nm, fc_fpin_li_event_types, 9324 8692 FC_FPIN_LI_EVT_TYPES_INIT); ··· 10051 9425 payload_len); 10052 9426 10053 9427 /* There are no replies, so no rjt codes */ 9428 + break; 9429 + case ELS_CMD_EDC: 9430 + lpfc_els_rcv_edc(vport, elsiocb, ndlp); 10054 9431 break; 10055 9432 case ELS_CMD_RDF: 10056 9433 phba->fc_stat.elsRcvRDF++;
+17 -2
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 4209 4209 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf); 4210 4210 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp; 4211 4211 struct lpfc_vport *vport = pmb->vport; 4212 + int rc; 4212 4213 4213 4214 pmb->ctx_buf = NULL; 4214 4215 pmb->ctx_ndlp = NULL; ··· 4285 4284 /* Issue SCR just before NameServer GID_FT Query */ 4286 4285 lpfc_issue_els_scr(vport, 0); 4287 4286 4288 - if (!phba->cfg_enable_mi || 4289 - phba->sli4_hba.pc_sli4_params.mi_ver < LPFC_MIB3_SUPPORT) 4287 + /* Link was bounced or a Fabric LOGO occurred. Start EDC 4288 + * with initial FW values provided the congestion mode is 4289 + * not off. Note that signals may or may not be supported 4290 + * by the adapter but FPIN is provided by default for 1 4291 + * or both missing signals support. 4292 + */ 4293 + if (phba->cmf_active_mode != LPFC_CFG_OFF) { 4294 + phba->cgn_reg_fpin = phba->cgn_init_reg_fpin; 4295 + phba->cgn_reg_signal = phba->cgn_init_reg_signal; 4296 + rc = lpfc_issue_els_edc(vport, 0); 4297 + lpfc_printf_log(phba, KERN_INFO, 4298 + LOG_INIT | LOG_ELS | LOG_DISCOVERY, 4299 + "4220 EDC issue error x%x, Data: x%x\n", 4300 + rc, phba->cgn_init_reg_signal); 4301 + } else { 4290 4302 lpfc_issue_els_rdf(vport, 0); 4303 + } 4291 4304 } 4292 4305 4293 4306 vport->fc_ns_retry = 0;
+2
drivers/scsi/lpfc/lpfc_hw.h
··· 608 608 #define ELS_CMD_LIRR 0x7A000000 609 609 #define ELS_CMD_LCB 0x81000000 610 610 #define ELS_CMD_FPIN 0x16000000 611 + #define ELS_CMD_EDC 0x17000000 611 612 #define ELS_CMD_QFPA 0xB0000000 612 613 #define ELS_CMD_UVEM 0xB1000000 613 614 #else /* __LITTLE_ENDIAN_BITFIELD */ ··· 653 652 #define ELS_CMD_LIRR 0x7A 654 653 #define ELS_CMD_LCB 0x81 655 654 #define ELS_CMD_FPIN ELS_FPIN 655 + #define ELS_CMD_EDC ELS_EDC 656 656 #define ELS_CMD_QFPA 0xB0 657 657 #define ELS_CMD_UVEM 0xB1 658 658 #endif
+58
drivers/scsi/lpfc/lpfc_hw4.h
··· 2813 2813 #define lpfc_mbx_rd_conf_extnts_inuse_SHIFT 31 2814 2814 #define lpfc_mbx_rd_conf_extnts_inuse_MASK 0x00000001 2815 2815 #define lpfc_mbx_rd_conf_extnts_inuse_WORD word1 2816 + #define lpfc_mbx_rd_conf_wcs_SHIFT 28 /* warning signaling */ 2817 + #define lpfc_mbx_rd_conf_wcs_MASK 0x00000001 2818 + #define lpfc_mbx_rd_conf_wcs_WORD word1 2819 + #define lpfc_mbx_rd_conf_acs_SHIFT 27 /* alarm signaling */ 2820 + #define lpfc_mbx_rd_conf_acs_MASK 0x00000001 2821 + #define lpfc_mbx_rd_conf_acs_WORD word1 2816 2822 uint32_t word2; 2817 2823 #define lpfc_mbx_rd_conf_lnk_numb_SHIFT 0 2818 2824 #define lpfc_mbx_rd_conf_lnk_numb_MASK 0x0000003F ··· 3399 3393 3400 3394 #define LPFC_SET_UE_RECOVERY 0x10 3401 3395 #define LPFC_SET_MDS_DIAGS 0x12 3396 + #define LPFC_SET_CGN_SIGNAL 0x1f 3402 3397 #define LPFC_SET_DUAL_DUMP 0x1e 3403 3398 #define LPFC_SET_ENABLE_MI 0x21 3404 3399 struct lpfc_mbx_set_feature { ··· 3416 3409 #define lpfc_mbx_set_feature_mds_deep_loopbk_SHIFT 1 3417 3410 #define lpfc_mbx_set_feature_mds_deep_loopbk_MASK 0x00000001 3418 3411 #define lpfc_mbx_set_feature_mds_deep_loopbk_WORD word6 3412 + #define lpfc_mbx_set_feature_CGN_warn_freq_SHIFT 0 3413 + #define lpfc_mbx_set_feature_CGN_warn_freq_MASK 0x0000ffff 3414 + #define lpfc_mbx_set_feature_CGN_warn_freq_WORD word6 3419 3415 #define lpfc_mbx_set_feature_dd_SHIFT 0 3420 3416 #define lpfc_mbx_set_feature_dd_MASK 0x00000001 3421 3417 #define lpfc_mbx_set_feature_dd_WORD word6 ··· 3441 3431 #define lpfc_mbx_set_feature_UESR_SHIFT 16 3442 3432 #define lpfc_mbx_set_feature_UESR_MASK 0x0000ffff 3443 3433 #define lpfc_mbx_set_feature_UESR_WORD word7 3434 + #define lpfc_mbx_set_feature_CGN_alarm_freq_SHIFT 0 3435 + #define lpfc_mbx_set_feature_CGN_alarm_freq_MASK 0x0000ffff 3436 + #define lpfc_mbx_set_feature_CGN_alarm_freq_WORD word7 3437 + u32 word8; 3438 + #define lpfc_mbx_set_feature_CGN_acqe_freq_SHIFT 0 3439 + #define lpfc_mbx_set_feature_CGN_acqe_freq_MASK 0x000000ff 3440 + #define lpfc_mbx_set_feature_CGN_acqe_freq_WORD word8 3444 3441 }; 3445 3442 3446 3443 ··· 4190 4173 #define LPFC_SLI_EVENT_STATUS_UNCERTIFIED 0x05 4191 4174 }; 4192 4175 4176 + struct lpfc_acqe_cgn_signal { 4177 + u32 word0; 4178 + #define lpfc_warn_acqe_SHIFT 0 4179 + #define lpfc_warn_acqe_MASK 0x7FFFFFFF 4180 + #define lpfc_warn_acqe_WORD word0 4181 + #define lpfc_imm_acqe_SHIFT 31 4182 + #define lpfc_imm_acqe_MASK 0x1 4183 + #define lpfc_imm_acqe_WORD word0 4184 + u32 alarm_cnt; 4185 + u32 word2; 4186 + u32 trailer; 4187 + }; 4188 + 4193 4189 struct lpfc_acqe_sli { 4194 4190 uint32_t event_data1; 4195 4191 uint32_t event_data2; ··· 4217 4187 #define LPFC_SLI_EVENT_TYPE_REMOTE_DPORT 0xA 4218 4188 #define LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN 0xF 4219 4189 #define LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE 0x10 4190 + #define LPFC_SLI_EVENT_TYPE_CGN_SIGNAL 0x11 4220 4191 }; 4221 4192 4222 4193 /* ··· 4846 4815 #define LPFC_FW_RESET 2 4847 4816 #define LPFC_DV_RESET 3 4848 4817 4818 + /* On some kernels, enum fc_ls_tlv_dtag does not have 4819 + * these 2 enums defined, on other kernels it does. 4820 + * To get aound this we need to add these 2 defines here. 4821 + */ 4822 + #ifndef ELS_DTAG_LNK_FAULT_CAP 4823 + #define ELS_DTAG_LNK_FAULT_CAP 0x0001000D 4824 + #endif 4825 + #ifndef ELS_DTAG_CG_SIGNAL_CAP 4826 + #define ELS_DTAG_CG_SIGNAL_CAP 0x0001000F 4827 + #endif 4828 + 4849 4829 /* 4850 4830 * Initializer useful for decoding FPIN string table. 4851 4831 */ ··· 4864 4822 { FPIN_CONGN_SEVERITY_WARNING, "Warning" }, \ 4865 4823 { FPIN_CONGN_SEVERITY_ERROR, "Alarm" }, \ 4866 4824 } 4825 + 4826 + /* EDC supports two descriptors. When allocated, it is the 4827 + * size of this structure plus each supported descriptor. 4828 + */ 4829 + struct lpfc_els_edc_req { 4830 + struct fc_els_edc edc; /* hdr up to descriptors */ 4831 + struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */ 4832 + }; 4833 + 4834 + /* Minimum structure defines for the EDC response. 4835 + * Balance is in buffer. 4836 + */ 4837 + struct lpfc_els_edc_rsp { 4838 + struct fc_els_edc_resp edc_rsp; /* hdr up to descriptors */ 4839 + struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */ 4840 + }; 4867 4841 4868 4842 /* Used for logging FPIN messages */ 4869 4843 #define LPFC_FPIN_WWPN_LINE_SZ 128
+84 -2
drivers/scsi/lpfc/lpfc_init.c
··· 1243 1243 return; 1244 1244 1245 1245 if (phba->link_state == LPFC_HBA_ERROR || 1246 - phba->pport->fc_flag & FC_OFFLINE_MODE) 1246 + phba->pport->fc_flag & FC_OFFLINE_MODE || 1247 + phba->cmf_active_mode != LPFC_CFG_OFF) 1247 1248 goto requeue; 1248 1249 1249 1250 for_each_present_cpu(i) { ··· 5529 5528 uint8_t operational = 0; 5530 5529 struct temp_event temp_event_data; 5531 5530 struct lpfc_acqe_misconfigured_event *misconfigured; 5531 + struct lpfc_acqe_cgn_signal *cgn_signal; 5532 5532 struct Scsi_Host *shost; 5533 5533 struct lpfc_vport **vports; 5534 - int rc, i; 5534 + int rc, i, cnt; 5535 5535 5536 5536 evt_type = bf_get(lpfc_trailer_type, acqe_sli); 5537 5537 ··· 5704 5702 "2518 EEPROM failure - " 5705 5703 "Event Data1: x%08x Event Data2: x%08x\n", 5706 5704 acqe_sli->event_data1, acqe_sli->event_data2); 5705 + break; 5706 + case LPFC_SLI_EVENT_TYPE_CGN_SIGNAL: 5707 + if (phba->cmf_active_mode == LPFC_CFG_OFF) 5708 + break; 5709 + cgn_signal = (struct lpfc_acqe_cgn_signal *) 5710 + &acqe_sli->event_data1; 5711 + phba->cgn_acqe_cnt++; 5712 + 5713 + cnt = bf_get(lpfc_warn_acqe, cgn_signal); 5714 + atomic64_add(cnt, &phba->cgn_acqe_stat.warn); 5715 + atomic64_add(cgn_signal->alarm_cnt, &phba->cgn_acqe_stat.alarm); 5716 + 5717 + /* no threshold for CMF, even 1 signal will trigger an event */ 5718 + 5719 + /* Alarm overrides warning, so check that first */ 5720 + if (cgn_signal->alarm_cnt) { 5721 + if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) { 5722 + /* Keep track of alarm cnt for cgn_info */ 5723 + atomic_add(cgn_signal->alarm_cnt, 5724 + &phba->cgn_fabric_alarm_cnt); 5725 + /* Keep track of alarm cnt for CMF_SYNC_WQE */ 5726 + atomic_add(cgn_signal->alarm_cnt, 5727 + &phba->cgn_sync_alarm_cnt); 5728 + } 5729 + } else if (cnt) { 5730 + /* signal action needs to be taken */ 5731 + if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY || 5732 + phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) { 5733 + /* Keep track of warning cnt for cgn_info */ 5734 + atomic_add(cnt, &phba->cgn_fabric_warn_cnt); 5735 + /* Keep track of warning cnt for CMF_SYNC_WQE */ 5736 + atomic_add(cnt, &phba->cgn_sync_warn_cnt); 5737 + } 5738 + } 5707 5739 break; 5708 5740 default: 5709 5741 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, ··· 8738 8702 phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ? 8739 8703 (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0; 8740 8704 phba->max_vports = phba->max_vpi; 8705 + 8706 + /* Next decide on FPIN or Signal E2E CGN support 8707 + * For congestion alarms and warnings valid combination are: 8708 + * 1. FPIN alarms / FPIN warnings 8709 + * 2. Signal alarms / Signal warnings 8710 + * 3. FPIN alarms / Signal warnings 8711 + * 4. Signal alarms / FPIN warnings 8712 + * 8713 + * Initialize the adapter frequency to 100 mSecs 8714 + */ 8715 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_BOTH; 8716 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 8717 + phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; 8718 + 8719 + if (lpfc_use_cgn_signal) { 8720 + if (bf_get(lpfc_mbx_rd_conf_wcs, rd_config)) { 8721 + phba->cgn_reg_signal = EDC_CG_SIG_WARN_ONLY; 8722 + phba->cgn_reg_fpin &= ~LPFC_CGN_FPIN_WARN; 8723 + } 8724 + if (bf_get(lpfc_mbx_rd_conf_acs, rd_config)) { 8725 + /* MUST support both alarm and warning 8726 + * because EDC does not support alarm alone. 8727 + */ 8728 + if (phba->cgn_reg_signal != 8729 + EDC_CG_SIG_WARN_ONLY) { 8730 + /* Must support both or none */ 8731 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_BOTH; 8732 + phba->cgn_reg_signal = 8733 + EDC_CG_SIG_NOTSUPPORTED; 8734 + } else { 8735 + phba->cgn_reg_signal = 8736 + EDC_CG_SIG_WARN_ALARM; 8737 + phba->cgn_reg_fpin = 8738 + LPFC_CGN_FPIN_NONE; 8739 + } 8740 + } 8741 + } 8742 + 8743 + /* Set the congestion initial signal and fpin values. */ 8744 + phba->cgn_init_reg_fpin = phba->cgn_reg_fpin; 8745 + phba->cgn_init_reg_signal = phba->cgn_reg_signal; 8746 + 8747 + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 8748 + "6446 READ_CONFIG reg_sig x%x reg_fpin:x%x\n", 8749 + phba->cgn_reg_signal, phba->cgn_reg_fpin); 8750 + 8741 8751 lpfc_map_topology(phba, rd_config); 8742 8752 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 8743 8753 "2003 cfg params Extents? %d "
+124 -3
drivers/scsi/lpfc/lpfc_sli.c
··· 6417 6417 uint32_t feature) 6418 6418 { 6419 6419 uint32_t len; 6420 + u32 sig_freq = 0; 6420 6421 6421 6422 len = sizeof(struct lpfc_mbx_set_feature) - 6422 6423 sizeof(struct lpfc_sli4_cfg_mhdr); ··· 6439 6438 &mbox->u.mqe.un.set_feature, 1); 6440 6439 mbox->u.mqe.un.set_feature.feature = LPFC_SET_MDS_DIAGS; 6441 6440 mbox->u.mqe.un.set_feature.param_len = 8; 6441 + break; 6442 + case LPFC_SET_CGN_SIGNAL: 6443 + if (phba->cmf_active_mode == LPFC_CFG_OFF) 6444 + sig_freq = 0; 6445 + else 6446 + sig_freq = phba->cgn_sig_freq; 6447 + 6448 + if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) { 6449 + bf_set(lpfc_mbx_set_feature_CGN_alarm_freq, 6450 + &mbox->u.mqe.un.set_feature, sig_freq); 6451 + bf_set(lpfc_mbx_set_feature_CGN_warn_freq, 6452 + &mbox->u.mqe.un.set_feature, sig_freq); 6453 + } 6454 + 6455 + if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY) 6456 + bf_set(lpfc_mbx_set_feature_CGN_warn_freq, 6457 + &mbox->u.mqe.un.set_feature, sig_freq); 6458 + 6459 + if (phba->cmf_active_mode == LPFC_CFG_OFF || 6460 + phba->cgn_reg_signal == EDC_CG_SIG_NOTSUPPORTED) 6461 + sig_freq = 0; 6462 + else 6463 + sig_freq = lpfc_acqe_cgn_frequency; 6464 + 6465 + bf_set(lpfc_mbx_set_feature_CGN_acqe_freq, 6466 + &mbox->u.mqe.un.set_feature, sig_freq); 6467 + 6468 + mbox->u.mqe.un.set_feature.feature = LPFC_SET_CGN_SIGNAL; 6469 + mbox->u.mqe.un.set_feature.param_len = 12; 6442 6470 break; 6443 6471 case LPFC_SET_DUAL_DUMP: 6444 6472 bf_set(lpfc_mbx_set_feature_dd, ··· 7475 7445 return 1; 7476 7446 } 7477 7447 7448 + static void 7449 + lpfc_mbx_cmpl_cgn_set_ftrs(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) 7450 + { 7451 + struct lpfc_vport *vport = pmb->vport; 7452 + union lpfc_sli4_cfg_shdr *shdr; 7453 + u32 shdr_status, shdr_add_status; 7454 + u32 sig, acqe; 7455 + 7456 + /* Two outcomes. (1) Set featurs was successul and EDC negotiation 7457 + * is done. (2) Mailbox failed and send FPIN support only. 7458 + */ 7459 + shdr = (union lpfc_sli4_cfg_shdr *) 7460 + &pmb->u.mqe.un.sli4_config.header.cfg_shdr; 7461 + shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); 7462 + shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); 7463 + if (shdr_status || shdr_add_status || pmb->u.mb.mbxStatus) { 7464 + lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_CGN_MGMT, 7465 + "2516 CGN SET_FEATURE mbox failed with " 7466 + "status x%x add_status x%x, mbx status x%x " 7467 + "Reset Congestion to FPINs only\n", 7468 + shdr_status, shdr_add_status, 7469 + pmb->u.mb.mbxStatus); 7470 + /* If there is a mbox error, move on to RDF */ 7471 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 7472 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_WARN | LPFC_CGN_FPIN_ALARM; 7473 + goto out; 7474 + } 7475 + 7476 + /* Zero out Congestion Signal ACQE counter */ 7477 + phba->cgn_acqe_cnt = 0; 7478 + atomic64_set(&phba->cgn_acqe_stat.warn, 0); 7479 + atomic64_set(&phba->cgn_acqe_stat.alarm, 0); 7480 + 7481 + acqe = bf_get(lpfc_mbx_set_feature_CGN_acqe_freq, 7482 + &pmb->u.mqe.un.set_feature); 7483 + sig = bf_get(lpfc_mbx_set_feature_CGN_warn_freq, 7484 + &pmb->u.mqe.un.set_feature); 7485 + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 7486 + "4620 SET_FEATURES Success: Freq: %ds %dms " 7487 + " Reg: x%x x%x\n", acqe, sig, 7488 + phba->cgn_reg_signal, phba->cgn_reg_fpin); 7489 + out: 7490 + mempool_free(pmb, phba->mbox_mem_pool); 7491 + 7492 + /* Register for FPIN events from the fabric now that the 7493 + * EDC common_set_features has completed. 7494 + */ 7495 + lpfc_issue_els_rdf(vport, 0); 7496 + } 7497 + 7498 + int 7499 + lpfc_config_cgn_signal(struct lpfc_hba *phba) 7500 + { 7501 + LPFC_MBOXQ_t *mboxq; 7502 + u32 rc; 7503 + 7504 + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 7505 + if (!mboxq) 7506 + goto out_rdf; 7507 + 7508 + lpfc_set_features(phba, mboxq, LPFC_SET_CGN_SIGNAL); 7509 + mboxq->vport = phba->pport; 7510 + mboxq->mbox_cmpl = lpfc_mbx_cmpl_cgn_set_ftrs; 7511 + 7512 + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 7513 + "4621 SET_FEATURES: FREQ sig x%x acqe x%x: " 7514 + "Reg: x%x x%x\n", 7515 + phba->cgn_sig_freq, lpfc_acqe_cgn_frequency, 7516 + phba->cgn_reg_signal, phba->cgn_reg_fpin); 7517 + 7518 + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); 7519 + if (rc == MBX_NOT_FINISHED) 7520 + goto out; 7521 + return 0; 7522 + 7523 + out: 7524 + mempool_free(mboxq, phba->mbox_mem_pool); 7525 + out_rdf: 7526 + /* If there is a mbox error, move on to RDF */ 7527 + phba->cgn_reg_fpin = LPFC_CGN_FPIN_WARN | LPFC_CGN_FPIN_ALARM; 7528 + phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED; 7529 + lpfc_issue_els_rdf(phba->pport, 0); 7530 + return -EIO; 7531 + } 7532 + 7478 7533 /** 7479 7534 * lpfc_init_idle_stat_hb - Initialize idle_stat tracking 7480 7535 * @phba: pointer to lpfc hba data structure. ··· 7591 7476 idle_stat->prev_idle = get_cpu_idle_time(i, &wall, 1); 7592 7477 idle_stat->prev_wall = wall; 7593 7478 7594 - if (phba->nvmet_support) 7479 + if (phba->nvmet_support || 7480 + phba->cmf_active_mode != LPFC_CFG_OFF) 7595 7481 cq->poll_mode = LPFC_QUEUE_WORK; 7596 7482 else 7597 7483 cq->poll_mode = LPFC_IRQ_POLL; ··· 10063 9947 if (pcmd && (*pcmd == ELS_CMD_FLOGI || 10064 9948 *pcmd == ELS_CMD_SCR || 10065 9949 *pcmd == ELS_CMD_RDF || 9950 + *pcmd == ELS_CMD_EDC || 10066 9951 *pcmd == ELS_CMD_RSCN_XMT || 10067 9952 *pcmd == ELS_CMD_FDISC || 10068 9953 *pcmd == ELS_CMD_LOGO || ··· 14931 14814 14932 14815 switch (cq->poll_mode) { 14933 14816 case LPFC_IRQ_POLL: 14934 - irq_poll_sched(&cq->iop); 14935 - break; 14817 + /* CGN mgmt is mutually exclusive from softirq processing */ 14818 + if (phba->cmf_active_mode == LPFC_CFG_OFF) { 14819 + irq_poll_sched(&cq->iop); 14820 + break; 14821 + } 14822 + fallthrough; 14936 14823 case LPFC_QUEUE_WORK: 14937 14824 default: 14938 14825 if (is_kdump_kernel())