|
57 | 57 | #define LPFC_MIN_DEVLOSS_TMO 1
|
58 | 58 | #define LPFC_MAX_DEVLOSS_TMO 255
|
59 | 59 |
|
| 60 | +#define LPFC_MAX_INFO_TMP_LEN 100 |
| 61 | +#define LPFC_INFO_MORE_STR "\nCould be more info...\n" |
60 | 62 | /*
|
61 | 63 | * Write key size should be multiple of 4. If write key is changed
|
62 | 64 | * make sure that library write key is also changed.
|
@@ -112,6 +114,186 @@ lpfc_jedec_to_ascii(int incr, char hdw[])
|
112 | 114 | return;
|
113 | 115 | }
|
114 | 116 |
|
| 117 | +static ssize_t |
| 118 | +lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr, |
| 119 | + char *buf) |
| 120 | +{ |
| 121 | + struct Scsi_Host *shost = class_to_shost(dev); |
| 122 | + struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; |
| 123 | + struct lpfc_hba *phba = vport->phba; |
| 124 | + struct lpfc_cgn_info *cp = NULL; |
| 125 | + struct lpfc_cgn_stat *cgs; |
| 126 | + int len = 0; |
| 127 | + int cpu; |
| 128 | + u64 rcv, total; |
| 129 | + char tmp[LPFC_MAX_INFO_TMP_LEN] = {0}; |
| 130 | + |
| 131 | + if (phba->cgn_i) |
| 132 | + cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; |
| 133 | + |
| 134 | + scnprintf(tmp, sizeof(tmp), |
| 135 | + "Congestion Mgmt Info: E2Eattr %d Ver %d " |
| 136 | + "CMF %d cnt %d\n", |
| 137 | + phba->sli4_hba.pc_sli4_params.mi_ver, |
| 138 | + cp ? cp->cgn_info_version : 0, |
| 139 | + phba->sli4_hba.pc_sli4_params.cmf, phba->cmf_timer_cnt); |
| 140 | + |
| 141 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 142 | + goto buffer_done; |
| 143 | + |
| 144 | + if (!phba->sli4_hba.pc_sli4_params.cmf) |
| 145 | + goto buffer_done; |
| 146 | + |
| 147 | + switch (phba->cgn_init_reg_signal) { |
| 148 | + case EDC_CG_SIG_WARN_ONLY: |
| 149 | + scnprintf(tmp, sizeof(tmp), |
| 150 | + "Register: Init: Signal:WARN "); |
| 151 | + break; |
| 152 | + case EDC_CG_SIG_WARN_ALARM: |
| 153 | + scnprintf(tmp, sizeof(tmp), |
| 154 | + "Register: Init: Signal:WARN|ALARM "); |
| 155 | + break; |
| 156 | + default: |
| 157 | + scnprintf(tmp, sizeof(tmp), |
| 158 | + "Register: Init: Signal:NONE "); |
| 159 | + break; |
| 160 | + } |
| 161 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 162 | + goto buffer_done; |
| 163 | + |
| 164 | + switch (phba->cgn_init_reg_fpin) { |
| 165 | + case LPFC_CGN_FPIN_WARN: |
| 166 | + scnprintf(tmp, sizeof(tmp), |
| 167 | + "FPIN:WARN\n"); |
| 168 | + break; |
| 169 | + case LPFC_CGN_FPIN_ALARM: |
| 170 | + scnprintf(tmp, sizeof(tmp), |
| 171 | + "FPIN:ALARM\n"); |
| 172 | + break; |
| 173 | + case LPFC_CGN_FPIN_BOTH: |
| 174 | + scnprintf(tmp, sizeof(tmp), |
| 175 | + "FPIN:WARN|ALARM\n"); |
| 176 | + break; |
| 177 | + default: |
| 178 | + scnprintf(tmp, sizeof(tmp), |
| 179 | + "FPIN:NONE\n"); |
| 180 | + break; |
| 181 | + } |
| 182 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 183 | + goto buffer_done; |
| 184 | + |
| 185 | + switch (phba->cgn_reg_signal) { |
| 186 | + case EDC_CG_SIG_WARN_ONLY: |
| 187 | + scnprintf(tmp, sizeof(tmp), |
| 188 | + " Current: Signal:WARN "); |
| 189 | + break; |
| 190 | + case EDC_CG_SIG_WARN_ALARM: |
| 191 | + scnprintf(tmp, sizeof(tmp), |
| 192 | + " Current: Signal:WARN|ALARM "); |
| 193 | + break; |
| 194 | + default: |
| 195 | + scnprintf(tmp, sizeof(tmp), |
| 196 | + " Current: Signal:NONE "); |
| 197 | + break; |
| 198 | + } |
| 199 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 200 | + goto buffer_done; |
| 201 | + |
| 202 | + switch (phba->cgn_reg_fpin) { |
| 203 | + case LPFC_CGN_FPIN_WARN: |
| 204 | + scnprintf(tmp, sizeof(tmp), |
| 205 | + "FPIN:WARN ACQEcnt:%d\n", phba->cgn_acqe_cnt); |
| 206 | + break; |
| 207 | + case LPFC_CGN_FPIN_ALARM: |
| 208 | + scnprintf(tmp, sizeof(tmp), |
| 209 | + "FPIN:ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt); |
| 210 | + break; |
| 211 | + case LPFC_CGN_FPIN_BOTH: |
| 212 | + scnprintf(tmp, sizeof(tmp), |
| 213 | + "FPIN:WARN|ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt); |
| 214 | + break; |
| 215 | + default: |
| 216 | + scnprintf(tmp, sizeof(tmp), |
| 217 | + "FPIN:NONE ACQEcnt:%d\n", phba->cgn_acqe_cnt); |
| 218 | + break; |
| 219 | + } |
| 220 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 221 | + goto buffer_done; |
| 222 | + |
| 223 | + if (phba->cmf_active_mode != phba->cgn_p.cgn_param_mode) { |
| 224 | + switch (phba->cmf_active_mode) { |
| 225 | + case LPFC_CFG_OFF: |
| 226 | + scnprintf(tmp, sizeof(tmp), "Active: Mode:Off\n"); |
| 227 | + break; |
| 228 | + case LPFC_CFG_MANAGED: |
| 229 | + scnprintf(tmp, sizeof(tmp), "Active: Mode:Managed\n"); |
| 230 | + break; |
| 231 | + case LPFC_CFG_MONITOR: |
| 232 | + scnprintf(tmp, sizeof(tmp), "Active: Mode:Monitor\n"); |
| 233 | + break; |
| 234 | + default: |
| 235 | + scnprintf(tmp, sizeof(tmp), "Active: Mode:Unknown\n"); |
| 236 | + } |
| 237 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 238 | + goto buffer_done; |
| 239 | + } |
| 240 | + |
| 241 | + switch (phba->cgn_p.cgn_param_mode) { |
| 242 | + case LPFC_CFG_OFF: |
| 243 | + scnprintf(tmp, sizeof(tmp), "Config: Mode:Off "); |
| 244 | + break; |
| 245 | + case LPFC_CFG_MANAGED: |
| 246 | + scnprintf(tmp, sizeof(tmp), "Config: Mode:Managed "); |
| 247 | + break; |
| 248 | + case LPFC_CFG_MONITOR: |
| 249 | + scnprintf(tmp, sizeof(tmp), "Config: Mode:Monitor "); |
| 250 | + break; |
| 251 | + default: |
| 252 | + scnprintf(tmp, sizeof(tmp), "Config: Mode:Unknown "); |
| 253 | + } |
| 254 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 255 | + goto buffer_done; |
| 256 | + |
| 257 | + total = 0; |
| 258 | + rcv = 0; |
| 259 | + for_each_present_cpu(cpu) { |
| 260 | + cgs = per_cpu_ptr(phba->cmf_stat, cpu); |
| 261 | + total += atomic64_read(&cgs->total_bytes); |
| 262 | + rcv += atomic64_read(&cgs->rcv_bytes); |
| 263 | + } |
| 264 | + |
| 265 | + scnprintf(tmp, sizeof(tmp), |
| 266 | + "IObusy:%d Info:%d Bytes: Rcv:x%llx Total:x%llx\n", |
| 267 | + atomic_read(&phba->cmf_busy), |
| 268 | + phba->cmf_active_info, rcv, total); |
| 269 | + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) |
| 270 | + goto buffer_done; |
| 271 | + |
| 272 | + scnprintf(tmp, sizeof(tmp), |
| 273 | + "Port_speed:%d Link_byte_cnt:%ld " |
| 274 | + "Max_byte_per_interval:%ld\n", |
| 275 | + lpfc_sli_port_speed_get(phba), |
| 276 | + (unsigned long)phba->cmf_link_byte_count, |
| 277 | + (unsigned long)phba->cmf_max_bytes_per_interval); |
| 278 | + strlcat(buf, tmp, PAGE_SIZE); |
| 279 | + |
| 280 | +buffer_done: |
| 281 | + len = strnlen(buf, PAGE_SIZE); |
| 282 | + |
| 283 | + if (unlikely(len >= (PAGE_SIZE - 1))) { |
| 284 | + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, |
| 285 | + "6312 Catching potential buffer " |
| 286 | + "overflow > PAGE_SIZE = %lu bytes\n", |
| 287 | + PAGE_SIZE); |
| 288 | + strscpy(buf + PAGE_SIZE - 1 - |
| 289 | + strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1), |
| 290 | + LPFC_INFO_MORE_STR, |
| 291 | + strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1) |
| 292 | + + 1); |
| 293 | + } |
| 294 | + return len; |
| 295 | +} |
| 296 | + |
115 | 297 | /**
|
116 | 298 | * lpfc_drvr_version_show - Return the Emulex driver string with version number
|
117 | 299 | * @dev: class unused variable.
|
@@ -168,7 +350,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
168 | 350 | char *statep;
|
169 | 351 | int i;
|
170 | 352 | int len = 0;
|
171 |
| - char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0}; |
| 353 | + char tmp[LPFC_MAX_INFO_TMP_LEN] = {0}; |
172 | 354 |
|
173 | 355 | if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
|
174 | 356 | len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
|
@@ -512,9 +694,9 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
512 | 694 | "6314 Catching potential buffer "
|
513 | 695 | "overflow > PAGE_SIZE = %lu bytes\n",
|
514 | 696 | PAGE_SIZE);
|
515 |
| - strlcpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_NVME_INFO_MORE_STR), |
516 |
| - LPFC_NVME_INFO_MORE_STR, |
517 |
| - sizeof(LPFC_NVME_INFO_MORE_STR) + 1); |
| 697 | + strscpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_INFO_MORE_STR), |
| 698 | + LPFC_INFO_MORE_STR, |
| 699 | + sizeof(LPFC_INFO_MORE_STR) + 1); |
518 | 700 | }
|
519 | 701 |
|
520 | 702 | return len;
|
@@ -2636,6 +2818,7 @@ static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn);
|
2636 | 2818 | static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
|
2637 | 2819 | static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
|
2638 | 2820 | NULL);
|
| 2821 | +static DEVICE_ATTR(cmf_info, 0444, lpfc_cmf_info_show, NULL); |
2639 | 2822 |
|
2640 | 2823 | static char *lpfc_soft_wwn_key = "C99G71SL8032A";
|
2641 | 2824 | #define WWN_SZ 8
|
@@ -6332,6 +6515,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
|
6332 | 6515 | &dev_attr_lpfc_enable_bbcr,
|
6333 | 6516 | &dev_attr_lpfc_enable_dpp,
|
6334 | 6517 | &dev_attr_lpfc_enable_mi,
|
| 6518 | + &dev_attr_cmf_info, |
6335 | 6519 | &dev_attr_lpfc_max_vmid,
|
6336 | 6520 | &dev_attr_lpfc_vmid_inactivity_timeout,
|
6337 | 6521 | &dev_attr_lpfc_vmid_app_header,
|
@@ -6362,6 +6546,7 @@ struct device_attribute *lpfc_vport_attrs[] = {
|
6362 | 6546 | &dev_attr_lpfc_max_scsicmpl_time,
|
6363 | 6547 | &dev_attr_lpfc_stat_data_ctrl,
|
6364 | 6548 | &dev_attr_lpfc_static_vport,
|
| 6549 | + &dev_attr_cmf_info, |
6365 | 6550 | NULL,
|
6366 | 6551 | };
|
6367 | 6552 |
|
|
0 commit comments