| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * QLogic Fibre Channel HBA Driver |
|---|
| 3 | 4 | * Copyright (c) 2003-2014 QLogic Corporation |
|---|
| 4 | | - * |
|---|
| 5 | | - * See LICENSE.qla2xxx for copyright and licensing details. |
|---|
| 6 | 5 | */ |
|---|
| 7 | 6 | #include "qla_def.h" |
|---|
| 8 | 7 | #include "qla_target.h" |
|---|
| .. | .. |
|---|
| 26 | 25 | struct qla_hw_data *ha = vha->hw; |
|---|
| 27 | 26 | int rval = 0; |
|---|
| 28 | 27 | |
|---|
| 29 | | - if (!(ha->fw_dump_reading || ha->mctp_dump_reading)) |
|---|
| 28 | + if (!(ha->fw_dump_reading || ha->mctp_dump_reading || |
|---|
| 29 | + ha->mpi_fw_dump_reading)) |
|---|
| 30 | 30 | return 0; |
|---|
| 31 | 31 | |
|---|
| 32 | + mutex_lock(&ha->optrom_mutex); |
|---|
| 32 | 33 | if (IS_P3P_TYPE(ha)) { |
|---|
| 33 | 34 | if (off < ha->md_template_size) { |
|---|
| 34 | 35 | rval = memory_read_from_buffer(buf, count, |
|---|
| 35 | 36 | &off, ha->md_tmplt_hdr, ha->md_template_size); |
|---|
| 36 | | - return rval; |
|---|
| 37 | + } else { |
|---|
| 38 | + off -= ha->md_template_size; |
|---|
| 39 | + rval = memory_read_from_buffer(buf, count, |
|---|
| 40 | + &off, ha->md_dump, ha->md_dump_size); |
|---|
| 37 | 41 | } |
|---|
| 38 | | - off -= ha->md_template_size; |
|---|
| 39 | | - rval = memory_read_from_buffer(buf, count, |
|---|
| 40 | | - &off, ha->md_dump, ha->md_dump_size); |
|---|
| 41 | | - return rval; |
|---|
| 42 | | - } else if (ha->mctp_dumped && ha->mctp_dump_reading) |
|---|
| 43 | | - return memory_read_from_buffer(buf, count, &off, ha->mctp_dump, |
|---|
| 42 | + } else if (ha->mctp_dumped && ha->mctp_dump_reading) { |
|---|
| 43 | + rval = memory_read_from_buffer(buf, count, &off, ha->mctp_dump, |
|---|
| 44 | 44 | MCTP_DUMP_SIZE); |
|---|
| 45 | | - else if (ha->fw_dump_reading) |
|---|
| 46 | | - return memory_read_from_buffer(buf, count, &off, ha->fw_dump, |
|---|
| 45 | + } else if (ha->mpi_fw_dumped && ha->mpi_fw_dump_reading) { |
|---|
| 46 | + rval = memory_read_from_buffer(buf, count, &off, |
|---|
| 47 | + ha->mpi_fw_dump, |
|---|
| 48 | + ha->mpi_fw_dump_len); |
|---|
| 49 | + } else if (ha->fw_dump_reading) { |
|---|
| 50 | + rval = memory_read_from_buffer(buf, count, &off, ha->fw_dump, |
|---|
| 47 | 51 | ha->fw_dump_len); |
|---|
| 48 | | - else |
|---|
| 49 | | - return 0; |
|---|
| 52 | + } else { |
|---|
| 53 | + rval = 0; |
|---|
| 54 | + } |
|---|
| 55 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 56 | + return rval; |
|---|
| 50 | 57 | } |
|---|
| 51 | 58 | |
|---|
| 52 | 59 | static ssize_t |
|---|
| .. | .. |
|---|
| 76 | 83 | qla82xx_md_prep(vha); |
|---|
| 77 | 84 | } |
|---|
| 78 | 85 | ha->fw_dump_reading = 0; |
|---|
| 79 | | - ha->fw_dumped = 0; |
|---|
| 86 | + ha->fw_dumped = false; |
|---|
| 80 | 87 | break; |
|---|
| 81 | 88 | case 1: |
|---|
| 82 | 89 | if (ha->fw_dumped && !ha->fw_dump_reading) { |
|---|
| .. | .. |
|---|
| 99 | 106 | qla8044_idc_lock(ha); |
|---|
| 100 | 107 | qla82xx_set_reset_owner(vha); |
|---|
| 101 | 108 | qla8044_idc_unlock(ha); |
|---|
| 102 | | - } else |
|---|
| 109 | + } else { |
|---|
| 103 | 110 | qla2x00_system_error(vha); |
|---|
| 111 | + } |
|---|
| 104 | 112 | break; |
|---|
| 105 | 113 | case 4: |
|---|
| 106 | 114 | if (IS_P3P_TYPE(ha)) { |
|---|
| .. | .. |
|---|
| 132 | 140 | vha->host_no); |
|---|
| 133 | 141 | } |
|---|
| 134 | 142 | break; |
|---|
| 143 | + case 8: |
|---|
| 144 | + if (!ha->mpi_fw_dump_reading) |
|---|
| 145 | + break; |
|---|
| 146 | + ql_log(ql_log_info, vha, 0x70e7, |
|---|
| 147 | + "MPI firmware dump cleared on (%ld).\n", vha->host_no); |
|---|
| 148 | + ha->mpi_fw_dump_reading = 0; |
|---|
| 149 | + ha->mpi_fw_dumped = 0; |
|---|
| 150 | + break; |
|---|
| 151 | + case 9: |
|---|
| 152 | + if (ha->mpi_fw_dumped && !ha->mpi_fw_dump_reading) { |
|---|
| 153 | + ha->mpi_fw_dump_reading = 1; |
|---|
| 154 | + ql_log(ql_log_info, vha, 0x70e8, |
|---|
| 155 | + "Raw MPI firmware dump ready for read on (%ld).\n", |
|---|
| 156 | + vha->host_no); |
|---|
| 157 | + } |
|---|
| 158 | + break; |
|---|
| 159 | + case 10: |
|---|
| 160 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
|---|
| 161 | + ql_log(ql_log_info, vha, 0x70e9, |
|---|
| 162 | + "Issuing MPI firmware dump on host#%ld.\n", |
|---|
| 163 | + vha->host_no); |
|---|
| 164 | + ha->isp_ops->mpi_fw_dump(vha, 0); |
|---|
| 165 | + } |
|---|
| 166 | + break; |
|---|
| 135 | 167 | } |
|---|
| 136 | 168 | return count; |
|---|
| 137 | 169 | } |
|---|
| .. | .. |
|---|
| 154 | 186 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
|---|
| 155 | 187 | struct device, kobj))); |
|---|
| 156 | 188 | struct qla_hw_data *ha = vha->hw; |
|---|
| 189 | + uint32_t faddr; |
|---|
| 190 | + struct active_regions active_regions = { }; |
|---|
| 157 | 191 | |
|---|
| 158 | 192 | if (!capable(CAP_SYS_ADMIN)) |
|---|
| 159 | 193 | return 0; |
|---|
| 160 | 194 | |
|---|
| 161 | | - if (IS_NOCACHE_VPD_TYPE(ha)) |
|---|
| 162 | | - ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2, |
|---|
| 163 | | - ha->nvram_size); |
|---|
| 195 | + mutex_lock(&ha->optrom_mutex); |
|---|
| 196 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 197 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 198 | + return -EAGAIN; |
|---|
| 199 | + } |
|---|
| 200 | + |
|---|
| 201 | + if (!IS_NOCACHE_VPD_TYPE(ha)) { |
|---|
| 202 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 203 | + goto skip; |
|---|
| 204 | + } |
|---|
| 205 | + |
|---|
| 206 | + faddr = ha->flt_region_nvram; |
|---|
| 207 | + if (IS_QLA28XX(ha)) { |
|---|
| 208 | + qla28xx_get_aux_images(vha, &active_regions); |
|---|
| 209 | + if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) |
|---|
| 210 | + faddr = ha->flt_region_nvram_sec; |
|---|
| 211 | + } |
|---|
| 212 | + ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size); |
|---|
| 213 | + |
|---|
| 214 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 215 | + |
|---|
| 216 | +skip: |
|---|
| 164 | 217 | return memory_read_from_buffer(buf, count, &off, ha->nvram, |
|---|
| 165 | 218 | ha->nvram_size); |
|---|
| 166 | 219 | } |
|---|
| .. | .. |
|---|
| 181 | 234 | |
|---|
| 182 | 235 | /* Checksum NVRAM. */ |
|---|
| 183 | 236 | if (IS_FWI2_CAPABLE(ha)) { |
|---|
| 184 | | - uint32_t *iter; |
|---|
| 237 | + __le32 *iter = (__force __le32 *)buf; |
|---|
| 185 | 238 | uint32_t chksum; |
|---|
| 186 | 239 | |
|---|
| 187 | | - iter = (uint32_t *)buf; |
|---|
| 188 | 240 | chksum = 0; |
|---|
| 189 | 241 | for (cnt = 0; cnt < ((count >> 2) - 1); cnt++, iter++) |
|---|
| 190 | 242 | chksum += le32_to_cpu(*iter); |
|---|
| .. | .. |
|---|
| 208 | 260 | return -EAGAIN; |
|---|
| 209 | 261 | } |
|---|
| 210 | 262 | |
|---|
| 263 | + mutex_lock(&ha->optrom_mutex); |
|---|
| 264 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 265 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 266 | + return -EAGAIN; |
|---|
| 267 | + } |
|---|
| 268 | + |
|---|
| 211 | 269 | /* Write NVRAM. */ |
|---|
| 212 | | - ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count); |
|---|
| 213 | | - ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base, |
|---|
| 270 | + ha->isp_ops->write_nvram(vha, buf, ha->nvram_base, count); |
|---|
| 271 | + ha->isp_ops->read_nvram(vha, ha->nvram, ha->nvram_base, |
|---|
| 214 | 272 | count); |
|---|
| 273 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 215 | 274 | |
|---|
| 216 | 275 | ql_dbg(ql_dbg_user, vha, 0x7060, |
|---|
| 217 | 276 | "Setting ISP_ABORT_NEEDED\n"); |
|---|
| .. | .. |
|---|
| 322 | 381 | size = ha->optrom_size - start; |
|---|
| 323 | 382 | |
|---|
| 324 | 383 | mutex_lock(&ha->optrom_mutex); |
|---|
| 384 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 385 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 386 | + return -EAGAIN; |
|---|
| 387 | + } |
|---|
| 325 | 388 | switch (val) { |
|---|
| 326 | 389 | case 0: |
|---|
| 327 | 390 | if (ha->optrom_state != QLA_SREADING && |
|---|
| .. | .. |
|---|
| 348 | 411 | ha->optrom_region_size = size; |
|---|
| 349 | 412 | |
|---|
| 350 | 413 | ha->optrom_state = QLA_SREADING; |
|---|
| 351 | | - ha->optrom_buffer = vmalloc(ha->optrom_region_size); |
|---|
| 414 | + ha->optrom_buffer = vzalloc(ha->optrom_region_size); |
|---|
| 352 | 415 | if (ha->optrom_buffer == NULL) { |
|---|
| 353 | 416 | ql_log(ql_log_warn, vha, 0x7062, |
|---|
| 354 | 417 | "Unable to allocate memory for optrom retrieval " |
|---|
| .. | .. |
|---|
| 370 | 433 | "Reading flash region -- 0x%x/0x%x.\n", |
|---|
| 371 | 434 | ha->optrom_region_start, ha->optrom_region_size); |
|---|
| 372 | 435 | |
|---|
| 373 | | - memset(ha->optrom_buffer, 0, ha->optrom_region_size); |
|---|
| 374 | 436 | ha->isp_ops->read_optrom(vha, ha->optrom_buffer, |
|---|
| 375 | 437 | ha->optrom_region_start, ha->optrom_region_size); |
|---|
| 376 | 438 | break; |
|---|
| .. | .. |
|---|
| 399 | 461 | * 0x000000 -> 0x07ffff -- Boot code. |
|---|
| 400 | 462 | * 0x080000 -> 0x0fffff -- Firmware. |
|---|
| 401 | 463 | * 0x120000 -> 0x12ffff -- VPD and HBA parameters. |
|---|
| 464 | + * |
|---|
| 465 | + * > ISP25xx type boards: |
|---|
| 466 | + * |
|---|
| 467 | + * None -- should go through BSG. |
|---|
| 402 | 468 | */ |
|---|
| 403 | 469 | valid = 0; |
|---|
| 404 | 470 | if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) |
|---|
| 405 | 471 | valid = 1; |
|---|
| 406 | | - else if (start == (ha->flt_region_boot * 4) || |
|---|
| 407 | | - start == (ha->flt_region_fw * 4)) |
|---|
| 408 | | - valid = 1; |
|---|
| 409 | | - else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) |
|---|
| 410 | | - || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) |
|---|
| 411 | | - || IS_QLA27XX(ha)) |
|---|
| 472 | + else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) |
|---|
| 412 | 473 | valid = 1; |
|---|
| 413 | 474 | if (!valid) { |
|---|
| 414 | 475 | ql_log(ql_log_warn, vha, 0x7065, |
|---|
| .. | .. |
|---|
| 421 | 482 | ha->optrom_region_size = size; |
|---|
| 422 | 483 | |
|---|
| 423 | 484 | ha->optrom_state = QLA_SWRITING; |
|---|
| 424 | | - ha->optrom_buffer = vmalloc(ha->optrom_region_size); |
|---|
| 485 | + ha->optrom_buffer = vzalloc(ha->optrom_region_size); |
|---|
| 425 | 486 | if (ha->optrom_buffer == NULL) { |
|---|
| 426 | 487 | ql_log(ql_log_warn, vha, 0x7066, |
|---|
| 427 | 488 | "Unable to allocate memory for optrom update " |
|---|
| .. | .. |
|---|
| 436 | 497 | "Staging flash region write -- 0x%x/0x%x.\n", |
|---|
| 437 | 498 | ha->optrom_region_start, ha->optrom_region_size); |
|---|
| 438 | 499 | |
|---|
| 439 | | - memset(ha->optrom_buffer, 0, ha->optrom_region_size); |
|---|
| 440 | 500 | break; |
|---|
| 441 | 501 | case 3: |
|---|
| 442 | 502 | if (ha->optrom_state != QLA_SWRITING) { |
|---|
| .. | .. |
|---|
| 455 | 515 | "Writing flash region -- 0x%x/0x%x.\n", |
|---|
| 456 | 516 | ha->optrom_region_start, ha->optrom_region_size); |
|---|
| 457 | 517 | |
|---|
| 458 | | - ha->isp_ops->write_optrom(vha, ha->optrom_buffer, |
|---|
| 518 | + rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer, |
|---|
| 459 | 519 | ha->optrom_region_start, ha->optrom_region_size); |
|---|
| 520 | + if (rval) |
|---|
| 521 | + rval = -EIO; |
|---|
| 460 | 522 | break; |
|---|
| 461 | 523 | default: |
|---|
| 462 | 524 | rval = -EINVAL; |
|---|
| .. | .. |
|---|
| 485 | 547 | struct device, kobj))); |
|---|
| 486 | 548 | struct qla_hw_data *ha = vha->hw; |
|---|
| 487 | 549 | uint32_t faddr; |
|---|
| 550 | + struct active_regions active_regions = { }; |
|---|
| 488 | 551 | |
|---|
| 489 | 552 | if (unlikely(pci_channel_offline(ha->pdev))) |
|---|
| 490 | 553 | return -EAGAIN; |
|---|
| .. | .. |
|---|
| 492 | 555 | if (!capable(CAP_SYS_ADMIN)) |
|---|
| 493 | 556 | return -EINVAL; |
|---|
| 494 | 557 | |
|---|
| 495 | | - if (IS_NOCACHE_VPD_TYPE(ha)) { |
|---|
| 496 | | - faddr = ha->flt_region_vpd << 2; |
|---|
| 558 | + if (!IS_NOCACHE_VPD_TYPE(ha)) |
|---|
| 559 | + goto skip; |
|---|
| 497 | 560 | |
|---|
| 498 | | - if (IS_QLA27XX(ha) && |
|---|
| 499 | | - qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE) |
|---|
| 561 | + faddr = ha->flt_region_vpd << 2; |
|---|
| 562 | + |
|---|
| 563 | + if (IS_QLA28XX(ha)) { |
|---|
| 564 | + qla28xx_get_aux_images(vha, &active_regions); |
|---|
| 565 | + if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) |
|---|
| 500 | 566 | faddr = ha->flt_region_vpd_sec << 2; |
|---|
| 501 | 567 | |
|---|
| 502 | | - ha->isp_ops->read_optrom(vha, ha->vpd, faddr, |
|---|
| 503 | | - ha->vpd_size); |
|---|
| 568 | + ql_dbg(ql_dbg_init, vha, 0x7070, |
|---|
| 569 | + "Loading %s nvram image.\n", |
|---|
| 570 | + active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ? |
|---|
| 571 | + "primary" : "secondary"); |
|---|
| 504 | 572 | } |
|---|
| 573 | + |
|---|
| 574 | + mutex_lock(&ha->optrom_mutex); |
|---|
| 575 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 576 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 577 | + return -EAGAIN; |
|---|
| 578 | + } |
|---|
| 579 | + |
|---|
| 580 | + ha->isp_ops->read_optrom(vha, ha->vpd, faddr, ha->vpd_size); |
|---|
| 581 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 582 | + |
|---|
| 583 | + ha->isp_ops->read_optrom(vha, ha->vpd, faddr, ha->vpd_size); |
|---|
| 584 | +skip: |
|---|
| 505 | 585 | return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); |
|---|
| 506 | 586 | } |
|---|
| 507 | 587 | |
|---|
| .. | .. |
|---|
| 531 | 611 | return -EAGAIN; |
|---|
| 532 | 612 | } |
|---|
| 533 | 613 | |
|---|
| 614 | + mutex_lock(&ha->optrom_mutex); |
|---|
| 615 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 616 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 617 | + return -EAGAIN; |
|---|
| 618 | + } |
|---|
| 619 | + |
|---|
| 534 | 620 | /* Write NVRAM. */ |
|---|
| 535 | | - ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count); |
|---|
| 536 | | - ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count); |
|---|
| 621 | + ha->isp_ops->write_nvram(vha, buf, ha->vpd_base, count); |
|---|
| 622 | + ha->isp_ops->read_nvram(vha, ha->vpd, ha->vpd_base, count); |
|---|
| 537 | 623 | |
|---|
| 538 | 624 | /* Update flash version information for 4Gb & above. */ |
|---|
| 539 | | - if (!IS_FWI2_CAPABLE(ha)) |
|---|
| 625 | + if (!IS_FWI2_CAPABLE(ha)) { |
|---|
| 626 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 540 | 627 | return -EINVAL; |
|---|
| 628 | + } |
|---|
| 541 | 629 | |
|---|
| 542 | 630 | tmp_data = vmalloc(256); |
|---|
| 543 | 631 | if (!tmp_data) { |
|---|
| 632 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 544 | 633 | ql_log(ql_log_warn, vha, 0x706b, |
|---|
| 545 | 634 | "Unable to allocate memory for VPD information update.\n"); |
|---|
| 546 | 635 | return -ENOMEM; |
|---|
| 547 | 636 | } |
|---|
| 548 | 637 | ha->isp_ops->get_flash_version(vha, tmp_data); |
|---|
| 549 | 638 | vfree(tmp_data); |
|---|
| 639 | + |
|---|
| 640 | + mutex_unlock(&ha->optrom_mutex); |
|---|
| 550 | 641 | |
|---|
| 551 | 642 | return count; |
|---|
| 552 | 643 | } |
|---|
| .. | .. |
|---|
| 573 | 664 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count < SFP_DEV_SIZE) |
|---|
| 574 | 665 | return 0; |
|---|
| 575 | 666 | |
|---|
| 576 | | - if (qla2x00_chip_is_down(vha)) |
|---|
| 667 | + mutex_lock(&vha->hw->optrom_mutex); |
|---|
| 668 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 669 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 577 | 670 | return 0; |
|---|
| 671 | + } |
|---|
| 578 | 672 | |
|---|
| 579 | 673 | rval = qla2x00_read_sfp_dev(vha, buf, count); |
|---|
| 674 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 675 | + |
|---|
| 580 | 676 | if (rval) |
|---|
| 581 | 677 | return -EIO; |
|---|
| 582 | 678 | |
|---|
| .. | .. |
|---|
| 604 | 700 | int type; |
|---|
| 605 | 701 | uint32_t idc_control; |
|---|
| 606 | 702 | uint8_t *tmp_data = NULL; |
|---|
| 703 | + |
|---|
| 607 | 704 | if (off != 0) |
|---|
| 608 | 705 | return -EINVAL; |
|---|
| 609 | 706 | |
|---|
| .. | .. |
|---|
| 635 | 732 | scsi_unblock_requests(vha->host); |
|---|
| 636 | 733 | break; |
|---|
| 637 | 734 | case 0x2025d: |
|---|
| 638 | | - if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) |
|---|
| 735 | + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
|---|
| 736 | + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 639 | 737 | return -EPERM; |
|---|
| 640 | 738 | |
|---|
| 641 | 739 | ql_log(ql_log_info, vha, 0x706f, |
|---|
| 642 | 740 | "Issuing MPI reset.\n"); |
|---|
| 643 | 741 | |
|---|
| 644 | | - if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
|---|
| 742 | + if (IS_QLA83XX(ha)) { |
|---|
| 645 | 743 | uint32_t idc_control; |
|---|
| 646 | 744 | |
|---|
| 647 | 745 | qla83xx_idc_lock(vha, 0); |
|---|
| .. | .. |
|---|
| 666 | 764 | scsi_unblock_requests(vha->host); |
|---|
| 667 | 765 | break; |
|---|
| 668 | 766 | } |
|---|
| 767 | + break; |
|---|
| 669 | 768 | case 0x2025e: |
|---|
| 670 | 769 | if (!IS_P3P_TYPE(ha) || vha != base_vha) { |
|---|
| 671 | 770 | ql_log(ql_log_info, vha, 0x7071, |
|---|
| .. | .. |
|---|
| 786 | 885 | |
|---|
| 787 | 886 | if (unlikely(pci_channel_offline(ha->pdev))) |
|---|
| 788 | 887 | return 0; |
|---|
| 789 | | - |
|---|
| 790 | | - if (qla2x00_chip_is_down(vha)) |
|---|
| 888 | + mutex_lock(&vha->hw->optrom_mutex); |
|---|
| 889 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 890 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 791 | 891 | return 0; |
|---|
| 892 | + } |
|---|
| 792 | 893 | |
|---|
| 793 | 894 | if (ha->xgmac_data) |
|---|
| 794 | 895 | goto do_read; |
|---|
| .. | .. |
|---|
| 796 | 897 | ha->xgmac_data = dma_alloc_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, |
|---|
| 797 | 898 | &ha->xgmac_data_dma, GFP_KERNEL); |
|---|
| 798 | 899 | if (!ha->xgmac_data) { |
|---|
| 900 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 799 | 901 | ql_log(ql_log_warn, vha, 0x7076, |
|---|
| 800 | 902 | "Unable to allocate memory for XGMAC read-data.\n"); |
|---|
| 801 | 903 | return 0; |
|---|
| .. | .. |
|---|
| 807 | 909 | |
|---|
| 808 | 910 | rval = qla2x00_get_xgmac_stats(vha, ha->xgmac_data_dma, |
|---|
| 809 | 911 | XGMAC_DATA_SIZE, &actual_size); |
|---|
| 912 | + |
|---|
| 913 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 810 | 914 | if (rval != QLA_SUCCESS) { |
|---|
| 811 | 915 | ql_log(ql_log_warn, vha, 0x7077, |
|---|
| 812 | 916 | "Unable to read XGMAC data (%x).\n", rval); |
|---|
| 813 | 917 | count = 0; |
|---|
| 814 | 918 | } |
|---|
| 815 | 919 | |
|---|
| 816 | | - count = actual_size > count ? count: actual_size; |
|---|
| 920 | + count = actual_size > count ? count : actual_size; |
|---|
| 817 | 921 | memcpy(buf, ha->xgmac_data, count); |
|---|
| 818 | 922 | |
|---|
| 819 | 923 | return count; |
|---|
| .. | .. |
|---|
| 843 | 947 | |
|---|
| 844 | 948 | if (ha->dcbx_tlv) |
|---|
| 845 | 949 | goto do_read; |
|---|
| 846 | | - |
|---|
| 847 | | - if (qla2x00_chip_is_down(vha)) |
|---|
| 950 | + mutex_lock(&vha->hw->optrom_mutex); |
|---|
| 951 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 952 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 848 | 953 | return 0; |
|---|
| 954 | + } |
|---|
| 849 | 955 | |
|---|
| 850 | 956 | ha->dcbx_tlv = dma_alloc_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, |
|---|
| 851 | 957 | &ha->dcbx_tlv_dma, GFP_KERNEL); |
|---|
| 852 | 958 | if (!ha->dcbx_tlv) { |
|---|
| 959 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 853 | 960 | ql_log(ql_log_warn, vha, 0x7078, |
|---|
| 854 | 961 | "Unable to allocate memory for DCBX TLV read-data.\n"); |
|---|
| 855 | 962 | return -ENOMEM; |
|---|
| .. | .. |
|---|
| 860 | 967 | |
|---|
| 861 | 968 | rval = qla2x00_get_dcbx_params(vha, ha->dcbx_tlv_dma, |
|---|
| 862 | 969 | DCBX_TLV_DATA_SIZE); |
|---|
| 970 | + |
|---|
| 971 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 972 | + |
|---|
| 863 | 973 | if (rval != QLA_SUCCESS) { |
|---|
| 864 | 974 | ql_log(ql_log_warn, vha, 0x7079, |
|---|
| 865 | 975 | "Unable to read DCBX TLV (%x).\n", rval); |
|---|
| .. | .. |
|---|
| 883 | 993 | static struct sysfs_entry { |
|---|
| 884 | 994 | char *name; |
|---|
| 885 | 995 | struct bin_attribute *attr; |
|---|
| 886 | | - int is4GBp_only; |
|---|
| 996 | + int type; |
|---|
| 887 | 997 | } bin_file_entries[] = { |
|---|
| 888 | 998 | { "fw_dump", &sysfs_fw_dump_attr, }, |
|---|
| 889 | 999 | { "nvram", &sysfs_nvram_attr, }, |
|---|
| .. | .. |
|---|
| 906 | 1016 | int ret; |
|---|
| 907 | 1017 | |
|---|
| 908 | 1018 | for (iter = bin_file_entries; iter->name; iter++) { |
|---|
| 909 | | - if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw)) |
|---|
| 1019 | + if (iter->type && !IS_FWI2_CAPABLE(vha->hw)) |
|---|
| 910 | 1020 | continue; |
|---|
| 911 | | - if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) |
|---|
| 1021 | + if (iter->type == 2 && !IS_QLA25XX(vha->hw)) |
|---|
| 912 | 1022 | continue; |
|---|
| 913 | | - if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
|---|
| 1023 | + if (iter->type == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
|---|
| 914 | 1024 | continue; |
|---|
| 915 | 1025 | |
|---|
| 916 | 1026 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
|---|
| .. | .. |
|---|
| 934 | 1044 | struct qla_hw_data *ha = vha->hw; |
|---|
| 935 | 1045 | |
|---|
| 936 | 1046 | for (iter = bin_file_entries; iter->name; iter++) { |
|---|
| 937 | | - if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) |
|---|
| 1047 | + if (iter->type && !IS_FWI2_CAPABLE(ha)) |
|---|
| 938 | 1048 | continue; |
|---|
| 939 | | - if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) |
|---|
| 1049 | + if (iter->type == 2 && !IS_QLA25XX(ha)) |
|---|
| 940 | 1050 | continue; |
|---|
| 941 | | - if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
|---|
| 942 | | - continue; |
|---|
| 943 | | - if (iter->is4GBp_only == 0x27 && !IS_QLA27XX(vha->hw)) |
|---|
| 1051 | + if (iter->type == 3 && !(IS_CNA_CAPABLE(ha))) |
|---|
| 944 | 1052 | continue; |
|---|
| 945 | 1053 | |
|---|
| 946 | 1054 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
|---|
| .. | .. |
|---|
| 954 | 1062 | /* Scsi_Host attributes. */ |
|---|
| 955 | 1063 | |
|---|
| 956 | 1064 | static ssize_t |
|---|
| 957 | | -qla2x00_drvr_version_show(struct device *dev, |
|---|
| 1065 | +qla2x00_driver_version_show(struct device *dev, |
|---|
| 958 | 1066 | struct device_attribute *attr, char *buf) |
|---|
| 959 | 1067 | { |
|---|
| 960 | 1068 | return scnprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str); |
|---|
| .. | .. |
|---|
| 998 | 1106 | char *buf) |
|---|
| 999 | 1107 | { |
|---|
| 1000 | 1108 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1109 | + |
|---|
| 1001 | 1110 | return scnprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device); |
|---|
| 1002 | 1111 | } |
|---|
| 1003 | 1112 | |
|---|
| .. | .. |
|---|
| 1031 | 1140 | char *buf) |
|---|
| 1032 | 1141 | { |
|---|
| 1033 | 1142 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1143 | + |
|---|
| 1034 | 1144 | return scnprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_desc); |
|---|
| 1035 | 1145 | } |
|---|
| 1036 | 1146 | |
|---|
| .. | .. |
|---|
| 1042 | 1152 | char pci_info[30]; |
|---|
| 1043 | 1153 | |
|---|
| 1044 | 1154 | return scnprintf(buf, PAGE_SIZE, "%s\n", |
|---|
| 1045 | | - vha->hw->isp_ops->pci_info_str(vha, pci_info)); |
|---|
| 1155 | + vha->hw->isp_ops->pci_info_str(vha, pci_info, |
|---|
| 1156 | + sizeof(pci_info))); |
|---|
| 1046 | 1157 | } |
|---|
| 1047 | 1158 | |
|---|
| 1048 | 1159 | static ssize_t |
|---|
| .. | .. |
|---|
| 1160 | 1271 | } |
|---|
| 1161 | 1272 | |
|---|
| 1162 | 1273 | static ssize_t |
|---|
| 1274 | +qla_zio_threshold_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1275 | + char *buf) |
|---|
| 1276 | +{ |
|---|
| 1277 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1278 | + |
|---|
| 1279 | + return scnprintf(buf, PAGE_SIZE, "%d exchanges\n", |
|---|
| 1280 | + vha->hw->last_zio_threshold); |
|---|
| 1281 | +} |
|---|
| 1282 | + |
|---|
| 1283 | +static ssize_t |
|---|
| 1284 | +qla_zio_threshold_store(struct device *dev, struct device_attribute *attr, |
|---|
| 1285 | + const char *buf, size_t count) |
|---|
| 1286 | +{ |
|---|
| 1287 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1288 | + int val = 0; |
|---|
| 1289 | + |
|---|
| 1290 | + if (vha->hw->zio_mode != QLA_ZIO_MODE_6) |
|---|
| 1291 | + return -EINVAL; |
|---|
| 1292 | + if (sscanf(buf, "%d", &val) != 1) |
|---|
| 1293 | + return -EINVAL; |
|---|
| 1294 | + if (val < 0 || val > 256) |
|---|
| 1295 | + return -ERANGE; |
|---|
| 1296 | + |
|---|
| 1297 | + atomic_set(&vha->hw->zio_threshold, val); |
|---|
| 1298 | + return strlen(buf); |
|---|
| 1299 | +} |
|---|
| 1300 | + |
|---|
| 1301 | +static ssize_t |
|---|
| 1163 | 1302 | qla2x00_beacon_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1164 | 1303 | char *buf) |
|---|
| 1165 | 1304 | { |
|---|
| .. | .. |
|---|
| 1185 | 1324 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
|---|
| 1186 | 1325 | return -EPERM; |
|---|
| 1187 | 1326 | |
|---|
| 1327 | + if (sscanf(buf, "%d", &val) != 1) |
|---|
| 1328 | + return -EINVAL; |
|---|
| 1329 | + |
|---|
| 1330 | + mutex_lock(&vha->hw->optrom_mutex); |
|---|
| 1188 | 1331 | if (qla2x00_chip_is_down(vha)) { |
|---|
| 1332 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1189 | 1333 | ql_log(ql_log_warn, vha, 0x707a, |
|---|
| 1190 | 1334 | "Abort ISP active -- ignoring beacon request.\n"); |
|---|
| 1191 | 1335 | return -EBUSY; |
|---|
| 1192 | 1336 | } |
|---|
| 1193 | | - |
|---|
| 1194 | | - if (sscanf(buf, "%d", &val) != 1) |
|---|
| 1195 | | - return -EINVAL; |
|---|
| 1196 | 1337 | |
|---|
| 1197 | 1338 | if (val) |
|---|
| 1198 | 1339 | rval = ha->isp_ops->beacon_on(vha); |
|---|
| .. | .. |
|---|
| 1201 | 1342 | |
|---|
| 1202 | 1343 | if (rval != QLA_SUCCESS) |
|---|
| 1203 | 1344 | count = 0; |
|---|
| 1345 | + |
|---|
| 1346 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1347 | + |
|---|
| 1348 | + return count; |
|---|
| 1349 | +} |
|---|
| 1350 | + |
|---|
| 1351 | +static ssize_t |
|---|
| 1352 | +qla2x00_beacon_config_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1353 | + char *buf) |
|---|
| 1354 | +{ |
|---|
| 1355 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1356 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 1357 | + uint16_t led[3] = { 0 }; |
|---|
| 1358 | + |
|---|
| 1359 | + if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1360 | + return -EPERM; |
|---|
| 1361 | + |
|---|
| 1362 | + if (ql26xx_led_config(vha, 0, led)) |
|---|
| 1363 | + return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1364 | + |
|---|
| 1365 | + return scnprintf(buf, PAGE_SIZE, "%#04hx %#04hx %#04hx\n", |
|---|
| 1366 | + led[0], led[1], led[2]); |
|---|
| 1367 | +} |
|---|
| 1368 | + |
|---|
| 1369 | +static ssize_t |
|---|
| 1370 | +qla2x00_beacon_config_store(struct device *dev, struct device_attribute *attr, |
|---|
| 1371 | + const char *buf, size_t count) |
|---|
| 1372 | +{ |
|---|
| 1373 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1374 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 1375 | + uint16_t options = BIT_0; |
|---|
| 1376 | + uint16_t led[3] = { 0 }; |
|---|
| 1377 | + uint16_t word[4]; |
|---|
| 1378 | + int n; |
|---|
| 1379 | + |
|---|
| 1380 | + if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1381 | + return -EPERM; |
|---|
| 1382 | + |
|---|
| 1383 | + n = sscanf(buf, "%hx %hx %hx %hx", word+0, word+1, word+2, word+3); |
|---|
| 1384 | + if (n == 4) { |
|---|
| 1385 | + if (word[0] == 3) { |
|---|
| 1386 | + options |= BIT_3|BIT_2|BIT_1; |
|---|
| 1387 | + led[0] = word[1]; |
|---|
| 1388 | + led[1] = word[2]; |
|---|
| 1389 | + led[2] = word[3]; |
|---|
| 1390 | + goto write; |
|---|
| 1391 | + } |
|---|
| 1392 | + return -EINVAL; |
|---|
| 1393 | + } |
|---|
| 1394 | + |
|---|
| 1395 | + if (n == 2) { |
|---|
| 1396 | + /* check led index */ |
|---|
| 1397 | + if (word[0] == 0) { |
|---|
| 1398 | + options |= BIT_2; |
|---|
| 1399 | + led[0] = word[1]; |
|---|
| 1400 | + goto write; |
|---|
| 1401 | + } |
|---|
| 1402 | + if (word[0] == 1) { |
|---|
| 1403 | + options |= BIT_3; |
|---|
| 1404 | + led[1] = word[1]; |
|---|
| 1405 | + goto write; |
|---|
| 1406 | + } |
|---|
| 1407 | + if (word[0] == 2) { |
|---|
| 1408 | + options |= BIT_1; |
|---|
| 1409 | + led[2] = word[1]; |
|---|
| 1410 | + goto write; |
|---|
| 1411 | + } |
|---|
| 1412 | + return -EINVAL; |
|---|
| 1413 | + } |
|---|
| 1414 | + |
|---|
| 1415 | + return -EINVAL; |
|---|
| 1416 | + |
|---|
| 1417 | +write: |
|---|
| 1418 | + if (ql26xx_led_config(vha, options, led)) |
|---|
| 1419 | + return -EFAULT; |
|---|
| 1204 | 1420 | |
|---|
| 1205 | 1421 | return count; |
|---|
| 1206 | 1422 | } |
|---|
| .. | .. |
|---|
| 1211 | 1427 | { |
|---|
| 1212 | 1428 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1213 | 1429 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1430 | + |
|---|
| 1214 | 1431 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], |
|---|
| 1215 | 1432 | ha->bios_revision[0]); |
|---|
| 1216 | 1433 | } |
|---|
| .. | .. |
|---|
| 1221 | 1438 | { |
|---|
| 1222 | 1439 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1223 | 1440 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1441 | + |
|---|
| 1224 | 1442 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], |
|---|
| 1225 | 1443 | ha->efi_revision[0]); |
|---|
| 1226 | 1444 | } |
|---|
| .. | .. |
|---|
| 1231 | 1449 | { |
|---|
| 1232 | 1450 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1233 | 1451 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1452 | + |
|---|
| 1234 | 1453 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], |
|---|
| 1235 | 1454 | ha->fcode_revision[0]); |
|---|
| 1236 | 1455 | } |
|---|
| .. | .. |
|---|
| 1241 | 1460 | { |
|---|
| 1242 | 1461 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1243 | 1462 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1463 | + |
|---|
| 1244 | 1464 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", |
|---|
| 1245 | 1465 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], |
|---|
| 1246 | 1466 | ha->fw_revision[3]); |
|---|
| .. | .. |
|---|
| 1253 | 1473 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1254 | 1474 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1255 | 1475 | |
|---|
| 1256 | | - if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha)) |
|---|
| 1476 | + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
|---|
| 1477 | + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1257 | 1478 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1258 | 1479 | |
|---|
| 1259 | 1480 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", |
|---|
| .. | .. |
|---|
| 1266 | 1487 | struct device_attribute *attr, char *buf) |
|---|
| 1267 | 1488 | { |
|---|
| 1268 | 1489 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1490 | + |
|---|
| 1269 | 1491 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
|---|
| 1270 | 1492 | vha->qla_stats.total_isp_aborts); |
|---|
| 1271 | 1493 | } |
|---|
| .. | .. |
|---|
| 1275 | 1497 | struct device_attribute *attr, char *buf) |
|---|
| 1276 | 1498 | { |
|---|
| 1277 | 1499 | int rval = QLA_SUCCESS; |
|---|
| 1278 | | - uint16_t status[2] = {0, 0}; |
|---|
| 1500 | + uint16_t status[2] = { 0 }; |
|---|
| 1279 | 1501 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1280 | 1502 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1281 | 1503 | |
|---|
| 1282 | 1504 | if (!IS_QLA84XX(ha)) |
|---|
| 1283 | 1505 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1284 | 1506 | |
|---|
| 1285 | | - if (ha->cs84xx->op_fw_version == 0) |
|---|
| 1507 | + if (!ha->cs84xx->op_fw_version) { |
|---|
| 1286 | 1508 | rval = qla84xx_verify_chip(vha, status); |
|---|
| 1287 | 1509 | |
|---|
| 1288 | | - if ((rval == QLA_SUCCESS) && (status[0] == 0)) |
|---|
| 1289 | | - return scnprintf(buf, PAGE_SIZE, "%u\n", |
|---|
| 1290 | | - (uint32_t)ha->cs84xx->op_fw_version); |
|---|
| 1510 | + if (!rval && !status[0]) |
|---|
| 1511 | + return scnprintf(buf, PAGE_SIZE, "%u\n", |
|---|
| 1512 | + (uint32_t)ha->cs84xx->op_fw_version); |
|---|
| 1513 | + } |
|---|
| 1291 | 1514 | |
|---|
| 1292 | 1515 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1516 | +} |
|---|
| 1517 | + |
|---|
| 1518 | +static ssize_t |
|---|
| 1519 | +qla2x00_serdes_version_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1520 | + char *buf) |
|---|
| 1521 | +{ |
|---|
| 1522 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1523 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 1524 | + |
|---|
| 1525 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1526 | + return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1527 | + |
|---|
| 1528 | + return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", |
|---|
| 1529 | + ha->serdes_version[0], ha->serdes_version[1], |
|---|
| 1530 | + ha->serdes_version[2]); |
|---|
| 1293 | 1531 | } |
|---|
| 1294 | 1532 | |
|---|
| 1295 | 1533 | static ssize_t |
|---|
| .. | .. |
|---|
| 1300 | 1538 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1301 | 1539 | |
|---|
| 1302 | 1540 | if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha) && |
|---|
| 1303 | | - !IS_QLA27XX(ha)) |
|---|
| 1541 | + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1304 | 1542 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1305 | 1543 | |
|---|
| 1306 | 1544 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", |
|---|
| .. | .. |
|---|
| 1371 | 1609 | { |
|---|
| 1372 | 1610 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1373 | 1611 | uint16_t temp = 0; |
|---|
| 1612 | + int rc; |
|---|
| 1374 | 1613 | |
|---|
| 1614 | + mutex_lock(&vha->hw->optrom_mutex); |
|---|
| 1375 | 1615 | if (qla2x00_chip_is_down(vha)) { |
|---|
| 1616 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1376 | 1617 | ql_log(ql_log_warn, vha, 0x70dc, "ISP reset active.\n"); |
|---|
| 1377 | 1618 | goto done; |
|---|
| 1378 | 1619 | } |
|---|
| 1379 | 1620 | |
|---|
| 1380 | 1621 | if (vha->hw->flags.eeh_busy) { |
|---|
| 1622 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1381 | 1623 | ql_log(ql_log_warn, vha, 0x70dd, "PCI EEH busy.\n"); |
|---|
| 1382 | 1624 | goto done; |
|---|
| 1383 | 1625 | } |
|---|
| 1384 | 1626 | |
|---|
| 1385 | | - if (qla2x00_get_thermal_temp(vha, &temp) == QLA_SUCCESS) |
|---|
| 1627 | + rc = qla2x00_get_thermal_temp(vha, &temp); |
|---|
| 1628 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1629 | + if (rc == QLA_SUCCESS) |
|---|
| 1386 | 1630 | return scnprintf(buf, PAGE_SIZE, "%d\n", temp); |
|---|
| 1387 | 1631 | |
|---|
| 1388 | 1632 | done: |
|---|
| .. | .. |
|---|
| 1403 | 1647 | return scnprintf(buf, PAGE_SIZE, "0x%x\n", pstate); |
|---|
| 1404 | 1648 | } |
|---|
| 1405 | 1649 | |
|---|
| 1406 | | - if (qla2x00_chip_is_down(vha)) |
|---|
| 1650 | + mutex_lock(&vha->hw->optrom_mutex); |
|---|
| 1651 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 1652 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1407 | 1653 | ql_log(ql_log_warn, vha, 0x707c, |
|---|
| 1408 | 1654 | "ISP reset active.\n"); |
|---|
| 1409 | | - else if (!vha->hw->flags.eeh_busy) |
|---|
| 1410 | | - rval = qla2x00_get_firmware_state(vha, state); |
|---|
| 1411 | | - if (rval != QLA_SUCCESS) |
|---|
| 1655 | + goto out; |
|---|
| 1656 | + } else if (vha->hw->flags.eeh_busy) { |
|---|
| 1657 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1658 | + goto out; |
|---|
| 1659 | + } |
|---|
| 1660 | + |
|---|
| 1661 | + rval = qla2x00_get_firmware_state(vha, state); |
|---|
| 1662 | + mutex_unlock(&vha->hw->optrom_mutex); |
|---|
| 1663 | +out: |
|---|
| 1664 | + if (rval != QLA_SUCCESS) { |
|---|
| 1412 | 1665 | memset(state, -1, sizeof(state)); |
|---|
| 1666 | + rval = qla2x00_get_firmware_state(vha, state); |
|---|
| 1667 | + } |
|---|
| 1413 | 1668 | |
|---|
| 1414 | 1669 | return scnprintf(buf, PAGE_SIZE, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
|---|
| 1415 | 1670 | state[0], state[1], state[2], state[3], state[4], state[5]); |
|---|
| .. | .. |
|---|
| 1496 | 1751 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1497 | 1752 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1498 | 1753 | |
|---|
| 1499 | | - if (!IS_QLA27XX(ha)) |
|---|
| 1754 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1500 | 1755 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1501 | 1756 | |
|---|
| 1502 | 1757 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", |
|---|
| .. | .. |
|---|
| 1504 | 1759 | } |
|---|
| 1505 | 1760 | |
|---|
| 1506 | 1761 | static ssize_t |
|---|
| 1507 | | -qla2x00_min_link_speed_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1508 | | - char *buf) |
|---|
| 1762 | +qla2x00_min_supported_speed_show(struct device *dev, |
|---|
| 1763 | + struct device_attribute *attr, char *buf) |
|---|
| 1509 | 1764 | { |
|---|
| 1510 | 1765 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1511 | 1766 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1512 | 1767 | |
|---|
| 1513 | | - if (!IS_QLA27XX(ha)) |
|---|
| 1768 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1514 | 1769 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1515 | 1770 | |
|---|
| 1516 | 1771 | return scnprintf(buf, PAGE_SIZE, "%s\n", |
|---|
| 1517 | | - ha->min_link_speed == 5 ? "32Gps" : |
|---|
| 1518 | | - ha->min_link_speed == 4 ? "16Gps" : |
|---|
| 1519 | | - ha->min_link_speed == 3 ? "8Gps" : |
|---|
| 1520 | | - ha->min_link_speed == 2 ? "4Gps" : |
|---|
| 1521 | | - ha->min_link_speed != 0 ? "unknown" : ""); |
|---|
| 1772 | + ha->min_supported_speed == 6 ? "64Gps" : |
|---|
| 1773 | + ha->min_supported_speed == 5 ? "32Gps" : |
|---|
| 1774 | + ha->min_supported_speed == 4 ? "16Gps" : |
|---|
| 1775 | + ha->min_supported_speed == 3 ? "8Gps" : |
|---|
| 1776 | + ha->min_supported_speed == 2 ? "4Gps" : |
|---|
| 1777 | + ha->min_supported_speed != 0 ? "unknown" : ""); |
|---|
| 1522 | 1778 | } |
|---|
| 1523 | 1779 | |
|---|
| 1524 | 1780 | static ssize_t |
|---|
| 1525 | | -qla2x00_max_speed_sup_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1526 | | - char *buf) |
|---|
| 1781 | +qla2x00_max_supported_speed_show(struct device *dev, |
|---|
| 1782 | + struct device_attribute *attr, char *buf) |
|---|
| 1527 | 1783 | { |
|---|
| 1528 | 1784 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1529 | 1785 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1530 | 1786 | |
|---|
| 1531 | | - if (!IS_QLA27XX(ha)) |
|---|
| 1787 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 1532 | 1788 | return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 1533 | 1789 | |
|---|
| 1534 | 1790 | return scnprintf(buf, PAGE_SIZE, "%s\n", |
|---|
| 1535 | | - ha->max_speed_sup ? "32Gps" : "16Gps"); |
|---|
| 1791 | + ha->max_supported_speed == 2 ? "64Gps" : |
|---|
| 1792 | + ha->max_supported_speed == 1 ? "32Gps" : |
|---|
| 1793 | + ha->max_supported_speed == 0 ? "16Gps" : "unknown"); |
|---|
| 1536 | 1794 | } |
|---|
| 1537 | 1795 | |
|---|
| 1538 | | -static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); |
|---|
| 1796 | +static ssize_t |
|---|
| 1797 | +qla2x00_port_speed_store(struct device *dev, struct device_attribute *attr, |
|---|
| 1798 | + const char *buf, size_t count) |
|---|
| 1799 | +{ |
|---|
| 1800 | + struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); |
|---|
| 1801 | + ulong type, speed; |
|---|
| 1802 | + int oldspeed, rval; |
|---|
| 1803 | + int mode = QLA_SET_DATA_RATE_LR; |
|---|
| 1804 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 1805 | + |
|---|
| 1806 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) { |
|---|
| 1807 | + ql_log(ql_log_warn, vha, 0x70d8, |
|---|
| 1808 | + "Speed setting not supported \n"); |
|---|
| 1809 | + return -EINVAL; |
|---|
| 1810 | + } |
|---|
| 1811 | + |
|---|
| 1812 | + rval = kstrtol(buf, 10, &type); |
|---|
| 1813 | + if (rval) |
|---|
| 1814 | + return rval; |
|---|
| 1815 | + speed = type; |
|---|
| 1816 | + if (type == 40 || type == 80 || type == 160 || |
|---|
| 1817 | + type == 320) { |
|---|
| 1818 | + ql_dbg(ql_dbg_user, vha, 0x70d9, |
|---|
| 1819 | + "Setting will be affected after a loss of sync\n"); |
|---|
| 1820 | + type = type/10; |
|---|
| 1821 | + mode = QLA_SET_DATA_RATE_NOLR; |
|---|
| 1822 | + } |
|---|
| 1823 | + |
|---|
| 1824 | + oldspeed = ha->set_data_rate; |
|---|
| 1825 | + |
|---|
| 1826 | + switch (type) { |
|---|
| 1827 | + case 0: |
|---|
| 1828 | + ha->set_data_rate = PORT_SPEED_AUTO; |
|---|
| 1829 | + break; |
|---|
| 1830 | + case 4: |
|---|
| 1831 | + ha->set_data_rate = PORT_SPEED_4GB; |
|---|
| 1832 | + break; |
|---|
| 1833 | + case 8: |
|---|
| 1834 | + ha->set_data_rate = PORT_SPEED_8GB; |
|---|
| 1835 | + break; |
|---|
| 1836 | + case 16: |
|---|
| 1837 | + ha->set_data_rate = PORT_SPEED_16GB; |
|---|
| 1838 | + break; |
|---|
| 1839 | + case 32: |
|---|
| 1840 | + ha->set_data_rate = PORT_SPEED_32GB; |
|---|
| 1841 | + break; |
|---|
| 1842 | + default: |
|---|
| 1843 | + ql_log(ql_log_warn, vha, 0x1199, |
|---|
| 1844 | + "Unrecognized speed setting:%lx. Setting Autoneg\n", |
|---|
| 1845 | + speed); |
|---|
| 1846 | + ha->set_data_rate = PORT_SPEED_AUTO; |
|---|
| 1847 | + } |
|---|
| 1848 | + |
|---|
| 1849 | + if (qla2x00_chip_is_down(vha) || (oldspeed == ha->set_data_rate)) |
|---|
| 1850 | + return -EINVAL; |
|---|
| 1851 | + |
|---|
| 1852 | + ql_log(ql_log_info, vha, 0x70da, |
|---|
| 1853 | + "Setting speed to %lx Gbps \n", type); |
|---|
| 1854 | + |
|---|
| 1855 | + rval = qla2x00_set_data_rate(vha, mode); |
|---|
| 1856 | + if (rval != QLA_SUCCESS) |
|---|
| 1857 | + return -EIO; |
|---|
| 1858 | + |
|---|
| 1859 | + return strlen(buf); |
|---|
| 1860 | +} |
|---|
| 1861 | + |
|---|
| 1862 | +static const struct { |
|---|
| 1863 | + u16 rate; |
|---|
| 1864 | + char *str; |
|---|
| 1865 | +} port_speed_str[] = { |
|---|
| 1866 | + { PORT_SPEED_4GB, "4" }, |
|---|
| 1867 | + { PORT_SPEED_8GB, "8" }, |
|---|
| 1868 | + { PORT_SPEED_16GB, "16" }, |
|---|
| 1869 | + { PORT_SPEED_32GB, "32" }, |
|---|
| 1870 | + { PORT_SPEED_64GB, "64" }, |
|---|
| 1871 | + { PORT_SPEED_10GB, "10" }, |
|---|
| 1872 | +}; |
|---|
| 1873 | + |
|---|
| 1874 | +static ssize_t |
|---|
| 1875 | +qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, |
|---|
| 1876 | + char *buf) |
|---|
| 1877 | +{ |
|---|
| 1878 | + struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); |
|---|
| 1879 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 1880 | + ssize_t rval; |
|---|
| 1881 | + u16 i; |
|---|
| 1882 | + char *speed = "Unknown"; |
|---|
| 1883 | + |
|---|
| 1884 | + rval = qla2x00_get_data_rate(vha); |
|---|
| 1885 | + if (rval != QLA_SUCCESS) { |
|---|
| 1886 | + ql_log(ql_log_warn, vha, 0x70db, |
|---|
| 1887 | + "Unable to get port speed rval:%zd\n", rval); |
|---|
| 1888 | + return -EINVAL; |
|---|
| 1889 | + } |
|---|
| 1890 | + |
|---|
| 1891 | + for (i = 0; i < ARRAY_SIZE(port_speed_str); i++) { |
|---|
| 1892 | + if (port_speed_str[i].rate != ha->link_data_rate) |
|---|
| 1893 | + continue; |
|---|
| 1894 | + speed = port_speed_str[i].str; |
|---|
| 1895 | + break; |
|---|
| 1896 | + } |
|---|
| 1897 | + |
|---|
| 1898 | + return scnprintf(buf, PAGE_SIZE, "%s\n", speed); |
|---|
| 1899 | +} |
|---|
| 1900 | + |
|---|
| 1901 | +/* ----- */ |
|---|
| 1902 | + |
|---|
| 1903 | +static ssize_t |
|---|
| 1904 | +qlini_mode_show(struct device *dev, struct device_attribute *attr, char *buf) |
|---|
| 1905 | +{ |
|---|
| 1906 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 1907 | + int len = 0; |
|---|
| 1908 | + |
|---|
| 1909 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 1910 | + "Supported options: enabled | disabled | dual | exclusive\n"); |
|---|
| 1911 | + |
|---|
| 1912 | + /* --- */ |
|---|
| 1913 | + len += scnprintf(buf + len, PAGE_SIZE-len, "Current selection: "); |
|---|
| 1914 | + |
|---|
| 1915 | + switch (vha->qlini_mode) { |
|---|
| 1916 | + case QLA2XXX_INI_MODE_EXCLUSIVE: |
|---|
| 1917 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 1918 | + QLA2XXX_INI_MODE_STR_EXCLUSIVE); |
|---|
| 1919 | + break; |
|---|
| 1920 | + case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 1921 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 1922 | + QLA2XXX_INI_MODE_STR_DISABLED); |
|---|
| 1923 | + break; |
|---|
| 1924 | + case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 1925 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 1926 | + QLA2XXX_INI_MODE_STR_ENABLED); |
|---|
| 1927 | + break; |
|---|
| 1928 | + case QLA2XXX_INI_MODE_DUAL: |
|---|
| 1929 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 1930 | + QLA2XXX_INI_MODE_STR_DUAL); |
|---|
| 1931 | + break; |
|---|
| 1932 | + } |
|---|
| 1933 | + len += scnprintf(buf + len, PAGE_SIZE-len, "\n"); |
|---|
| 1934 | + |
|---|
| 1935 | + return len; |
|---|
| 1936 | +} |
|---|
| 1937 | + |
|---|
| 1938 | +static char *mode_to_str[] = { |
|---|
| 1939 | + "exclusive", |
|---|
| 1940 | + "disabled", |
|---|
| 1941 | + "enabled", |
|---|
| 1942 | + "dual", |
|---|
| 1943 | +}; |
|---|
| 1944 | + |
|---|
| 1945 | +#define NEED_EXCH_OFFLOAD(_exchg) ((_exchg) > FW_DEF_EXCHANGES_CNT) |
|---|
| 1946 | +static void qla_set_ini_mode(scsi_qla_host_t *vha, int op) |
|---|
| 1947 | +{ |
|---|
| 1948 | + enum { |
|---|
| 1949 | + NO_ACTION, |
|---|
| 1950 | + MODE_CHANGE_ACCEPT, |
|---|
| 1951 | + MODE_CHANGE_NO_ACTION, |
|---|
| 1952 | + TARGET_STILL_ACTIVE, |
|---|
| 1953 | + }; |
|---|
| 1954 | + int action = NO_ACTION; |
|---|
| 1955 | + int set_mode = 0; |
|---|
| 1956 | + u8 eo_toggle = 0; /* exchange offload flipped */ |
|---|
| 1957 | + |
|---|
| 1958 | + switch (vha->qlini_mode) { |
|---|
| 1959 | + case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 1960 | + switch (op) { |
|---|
| 1961 | + case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 1962 | + if (qla_tgt_mode_enabled(vha)) { |
|---|
| 1963 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) != |
|---|
| 1964 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 1965 | + eo_toggle = 1; |
|---|
| 1966 | + if (((vha->ql2xexchoffld != |
|---|
| 1967 | + vha->u_ql2xexchoffld) && |
|---|
| 1968 | + NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) || |
|---|
| 1969 | + eo_toggle) { |
|---|
| 1970 | + /* |
|---|
| 1971 | + * The number of exchange to be offload |
|---|
| 1972 | + * was tweaked or offload option was |
|---|
| 1973 | + * flipped |
|---|
| 1974 | + */ |
|---|
| 1975 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 1976 | + } else { |
|---|
| 1977 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 1978 | + } |
|---|
| 1979 | + } else { |
|---|
| 1980 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 1981 | + } |
|---|
| 1982 | + break; |
|---|
| 1983 | + case QLA2XXX_INI_MODE_EXCLUSIVE: |
|---|
| 1984 | + if (qla_tgt_mode_enabled(vha)) { |
|---|
| 1985 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) != |
|---|
| 1986 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 1987 | + eo_toggle = 1; |
|---|
| 1988 | + if (((vha->ql2xexchoffld != |
|---|
| 1989 | + vha->u_ql2xexchoffld) && |
|---|
| 1990 | + NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) || |
|---|
| 1991 | + eo_toggle) { |
|---|
| 1992 | + /* |
|---|
| 1993 | + * The number of exchange to be offload |
|---|
| 1994 | + * was tweaked or offload option was |
|---|
| 1995 | + * flipped |
|---|
| 1996 | + */ |
|---|
| 1997 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 1998 | + } else { |
|---|
| 1999 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2000 | + } |
|---|
| 2001 | + } else { |
|---|
| 2002 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2003 | + } |
|---|
| 2004 | + break; |
|---|
| 2005 | + case QLA2XXX_INI_MODE_DUAL: |
|---|
| 2006 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2007 | + /* active_mode is target only, reset it to dual */ |
|---|
| 2008 | + if (qla_tgt_mode_enabled(vha)) { |
|---|
| 2009 | + set_mode = 1; |
|---|
| 2010 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2011 | + } else { |
|---|
| 2012 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2013 | + } |
|---|
| 2014 | + break; |
|---|
| 2015 | + |
|---|
| 2016 | + case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 2017 | + if (qla_tgt_mode_enabled(vha)) |
|---|
| 2018 | + action = TARGET_STILL_ACTIVE; |
|---|
| 2019 | + else { |
|---|
| 2020 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2021 | + set_mode = 1; |
|---|
| 2022 | + } |
|---|
| 2023 | + break; |
|---|
| 2024 | + } |
|---|
| 2025 | + break; |
|---|
| 2026 | + |
|---|
| 2027 | + case QLA2XXX_INI_MODE_EXCLUSIVE: |
|---|
| 2028 | + switch (op) { |
|---|
| 2029 | + case QLA2XXX_INI_MODE_EXCLUSIVE: |
|---|
| 2030 | + if (qla_tgt_mode_enabled(vha)) { |
|---|
| 2031 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) != |
|---|
| 2032 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 2033 | + eo_toggle = 1; |
|---|
| 2034 | + if (((vha->ql2xexchoffld != |
|---|
| 2035 | + vha->u_ql2xexchoffld) && |
|---|
| 2036 | + NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) || |
|---|
| 2037 | + eo_toggle) |
|---|
| 2038 | + /* |
|---|
| 2039 | + * The number of exchange to be offload |
|---|
| 2040 | + * was tweaked or offload option was |
|---|
| 2041 | + * flipped |
|---|
| 2042 | + */ |
|---|
| 2043 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2044 | + else |
|---|
| 2045 | + action = NO_ACTION; |
|---|
| 2046 | + } else |
|---|
| 2047 | + action = NO_ACTION; |
|---|
| 2048 | + |
|---|
| 2049 | + break; |
|---|
| 2050 | + |
|---|
| 2051 | + case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 2052 | + if (qla_tgt_mode_enabled(vha)) { |
|---|
| 2053 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) != |
|---|
| 2054 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 2055 | + eo_toggle = 1; |
|---|
| 2056 | + if (((vha->ql2xexchoffld != |
|---|
| 2057 | + vha->u_ql2xexchoffld) && |
|---|
| 2058 | + NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) || |
|---|
| 2059 | + eo_toggle) |
|---|
| 2060 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2061 | + else |
|---|
| 2062 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2063 | + } else |
|---|
| 2064 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2065 | + break; |
|---|
| 2066 | + |
|---|
| 2067 | + case QLA2XXX_INI_MODE_DUAL: /* exclusive -> dual */ |
|---|
| 2068 | + if (qla_tgt_mode_enabled(vha)) { |
|---|
| 2069 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2070 | + set_mode = 1; |
|---|
| 2071 | + } else |
|---|
| 2072 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2073 | + break; |
|---|
| 2074 | + |
|---|
| 2075 | + case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 2076 | + if (qla_tgt_mode_enabled(vha)) |
|---|
| 2077 | + action = TARGET_STILL_ACTIVE; |
|---|
| 2078 | + else { |
|---|
| 2079 | + if (vha->hw->flags.fw_started) |
|---|
| 2080 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2081 | + else |
|---|
| 2082 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2083 | + } |
|---|
| 2084 | + break; |
|---|
| 2085 | + } |
|---|
| 2086 | + break; |
|---|
| 2087 | + |
|---|
| 2088 | + case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 2089 | + switch (op) { |
|---|
| 2090 | + case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 2091 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg) != |
|---|
| 2092 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 2093 | + eo_toggle = 1; |
|---|
| 2094 | + if (((vha->ql2xiniexchg != vha->u_ql2xiniexchg) && |
|---|
| 2095 | + NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg)) || |
|---|
| 2096 | + eo_toggle) |
|---|
| 2097 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2098 | + else |
|---|
| 2099 | + action = NO_ACTION; |
|---|
| 2100 | + break; |
|---|
| 2101 | + case QLA2XXX_INI_MODE_DUAL: |
|---|
| 2102 | + case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 2103 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2104 | + break; |
|---|
| 2105 | + default: |
|---|
| 2106 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2107 | + break; |
|---|
| 2108 | + } |
|---|
| 2109 | + break; |
|---|
| 2110 | + |
|---|
| 2111 | + case QLA2XXX_INI_MODE_DUAL: |
|---|
| 2112 | + switch (op) { |
|---|
| 2113 | + case QLA2XXX_INI_MODE_DUAL: |
|---|
| 2114 | + if (qla_tgt_mode_enabled(vha) || |
|---|
| 2115 | + qla_dual_mode_enabled(vha)) { |
|---|
| 2116 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld + |
|---|
| 2117 | + vha->u_ql2xiniexchg) != |
|---|
| 2118 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 2119 | + eo_toggle = 1; |
|---|
| 2120 | + |
|---|
| 2121 | + if ((((vha->ql2xexchoffld + |
|---|
| 2122 | + vha->ql2xiniexchg) != |
|---|
| 2123 | + (vha->u_ql2xiniexchg + |
|---|
| 2124 | + vha->u_ql2xexchoffld)) && |
|---|
| 2125 | + NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg + |
|---|
| 2126 | + vha->u_ql2xexchoffld)) || eo_toggle) |
|---|
| 2127 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2128 | + else |
|---|
| 2129 | + action = NO_ACTION; |
|---|
| 2130 | + } else { |
|---|
| 2131 | + if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld + |
|---|
| 2132 | + vha->u_ql2xiniexchg) != |
|---|
| 2133 | + vha->hw->flags.exchoffld_enabled) |
|---|
| 2134 | + eo_toggle = 1; |
|---|
| 2135 | + |
|---|
| 2136 | + if ((((vha->ql2xexchoffld + vha->ql2xiniexchg) |
|---|
| 2137 | + != (vha->u_ql2xiniexchg + |
|---|
| 2138 | + vha->u_ql2xexchoffld)) && |
|---|
| 2139 | + NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg + |
|---|
| 2140 | + vha->u_ql2xexchoffld)) || eo_toggle) |
|---|
| 2141 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2142 | + else |
|---|
| 2143 | + action = NO_ACTION; |
|---|
| 2144 | + } |
|---|
| 2145 | + break; |
|---|
| 2146 | + |
|---|
| 2147 | + case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 2148 | + if (qla_tgt_mode_enabled(vha) || |
|---|
| 2149 | + qla_dual_mode_enabled(vha)) { |
|---|
| 2150 | + /* turning off initiator mode */ |
|---|
| 2151 | + set_mode = 1; |
|---|
| 2152 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2153 | + } else { |
|---|
| 2154 | + action = MODE_CHANGE_NO_ACTION; |
|---|
| 2155 | + } |
|---|
| 2156 | + break; |
|---|
| 2157 | + |
|---|
| 2158 | + case QLA2XXX_INI_MODE_EXCLUSIVE: |
|---|
| 2159 | + if (qla_tgt_mode_enabled(vha) || |
|---|
| 2160 | + qla_dual_mode_enabled(vha)) { |
|---|
| 2161 | + set_mode = 1; |
|---|
| 2162 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2163 | + } else { |
|---|
| 2164 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2165 | + } |
|---|
| 2166 | + break; |
|---|
| 2167 | + |
|---|
| 2168 | + case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 2169 | + if (qla_tgt_mode_enabled(vha) || |
|---|
| 2170 | + qla_dual_mode_enabled(vha)) { |
|---|
| 2171 | + action = TARGET_STILL_ACTIVE; |
|---|
| 2172 | + } else { |
|---|
| 2173 | + action = MODE_CHANGE_ACCEPT; |
|---|
| 2174 | + } |
|---|
| 2175 | + } |
|---|
| 2176 | + break; |
|---|
| 2177 | + } |
|---|
| 2178 | + |
|---|
| 2179 | + switch (action) { |
|---|
| 2180 | + case MODE_CHANGE_ACCEPT: |
|---|
| 2181 | + ql_log(ql_log_warn, vha, 0xffff, |
|---|
| 2182 | + "Mode change accepted. From %s to %s, Tgt exchg %d|%d. ini exchg %d|%d\n", |
|---|
| 2183 | + mode_to_str[vha->qlini_mode], mode_to_str[op], |
|---|
| 2184 | + vha->ql2xexchoffld, vha->u_ql2xexchoffld, |
|---|
| 2185 | + vha->ql2xiniexchg, vha->u_ql2xiniexchg); |
|---|
| 2186 | + |
|---|
| 2187 | + vha->qlini_mode = op; |
|---|
| 2188 | + vha->ql2xexchoffld = vha->u_ql2xexchoffld; |
|---|
| 2189 | + vha->ql2xiniexchg = vha->u_ql2xiniexchg; |
|---|
| 2190 | + if (set_mode) |
|---|
| 2191 | + qlt_set_mode(vha); |
|---|
| 2192 | + vha->flags.online = 1; |
|---|
| 2193 | + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
|---|
| 2194 | + break; |
|---|
| 2195 | + |
|---|
| 2196 | + case MODE_CHANGE_NO_ACTION: |
|---|
| 2197 | + ql_log(ql_log_warn, vha, 0xffff, |
|---|
| 2198 | + "Mode is set. No action taken. From %s to %s, Tgt exchg %d|%d. ini exchg %d|%d\n", |
|---|
| 2199 | + mode_to_str[vha->qlini_mode], mode_to_str[op], |
|---|
| 2200 | + vha->ql2xexchoffld, vha->u_ql2xexchoffld, |
|---|
| 2201 | + vha->ql2xiniexchg, vha->u_ql2xiniexchg); |
|---|
| 2202 | + vha->qlini_mode = op; |
|---|
| 2203 | + vha->ql2xexchoffld = vha->u_ql2xexchoffld; |
|---|
| 2204 | + vha->ql2xiniexchg = vha->u_ql2xiniexchg; |
|---|
| 2205 | + break; |
|---|
| 2206 | + |
|---|
| 2207 | + case TARGET_STILL_ACTIVE: |
|---|
| 2208 | + ql_log(ql_log_warn, vha, 0xffff, |
|---|
| 2209 | + "Target Mode is active. Unable to change Mode.\n"); |
|---|
| 2210 | + break; |
|---|
| 2211 | + |
|---|
| 2212 | + case NO_ACTION: |
|---|
| 2213 | + default: |
|---|
| 2214 | + ql_log(ql_log_warn, vha, 0xffff, |
|---|
| 2215 | + "Mode unchange. No action taken. %d|%d pct %d|%d.\n", |
|---|
| 2216 | + vha->qlini_mode, op, |
|---|
| 2217 | + vha->ql2xexchoffld, vha->u_ql2xexchoffld); |
|---|
| 2218 | + break; |
|---|
| 2219 | + } |
|---|
| 2220 | +} |
|---|
| 2221 | + |
|---|
| 2222 | +static ssize_t |
|---|
| 2223 | +qlini_mode_store(struct device *dev, struct device_attribute *attr, |
|---|
| 2224 | + const char *buf, size_t count) |
|---|
| 2225 | +{ |
|---|
| 2226 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2227 | + int ini; |
|---|
| 2228 | + |
|---|
| 2229 | + if (!buf) |
|---|
| 2230 | + return -EINVAL; |
|---|
| 2231 | + |
|---|
| 2232 | + if (strncasecmp(QLA2XXX_INI_MODE_STR_EXCLUSIVE, buf, |
|---|
| 2233 | + strlen(QLA2XXX_INI_MODE_STR_EXCLUSIVE)) == 0) |
|---|
| 2234 | + ini = QLA2XXX_INI_MODE_EXCLUSIVE; |
|---|
| 2235 | + else if (strncasecmp(QLA2XXX_INI_MODE_STR_DISABLED, buf, |
|---|
| 2236 | + strlen(QLA2XXX_INI_MODE_STR_DISABLED)) == 0) |
|---|
| 2237 | + ini = QLA2XXX_INI_MODE_DISABLED; |
|---|
| 2238 | + else if (strncasecmp(QLA2XXX_INI_MODE_STR_ENABLED, buf, |
|---|
| 2239 | + strlen(QLA2XXX_INI_MODE_STR_ENABLED)) == 0) |
|---|
| 2240 | + ini = QLA2XXX_INI_MODE_ENABLED; |
|---|
| 2241 | + else if (strncasecmp(QLA2XXX_INI_MODE_STR_DUAL, buf, |
|---|
| 2242 | + strlen(QLA2XXX_INI_MODE_STR_DUAL)) == 0) |
|---|
| 2243 | + ini = QLA2XXX_INI_MODE_DUAL; |
|---|
| 2244 | + else |
|---|
| 2245 | + return -EINVAL; |
|---|
| 2246 | + |
|---|
| 2247 | + qla_set_ini_mode(vha, ini); |
|---|
| 2248 | + return strlen(buf); |
|---|
| 2249 | +} |
|---|
| 2250 | + |
|---|
| 2251 | +static ssize_t |
|---|
| 2252 | +ql2xexchoffld_show(struct device *dev, struct device_attribute *attr, |
|---|
| 2253 | + char *buf) |
|---|
| 2254 | +{ |
|---|
| 2255 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2256 | + int len = 0; |
|---|
| 2257 | + |
|---|
| 2258 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 2259 | + "target exchange: new %d : current: %d\n\n", |
|---|
| 2260 | + vha->u_ql2xexchoffld, vha->ql2xexchoffld); |
|---|
| 2261 | + |
|---|
| 2262 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 2263 | + "Please (re)set operating mode via \"/sys/class/scsi_host/host%ld/qlini_mode\" to load new setting.\n", |
|---|
| 2264 | + vha->host_no); |
|---|
| 2265 | + |
|---|
| 2266 | + return len; |
|---|
| 2267 | +} |
|---|
| 2268 | + |
|---|
| 2269 | +static ssize_t |
|---|
| 2270 | +ql2xexchoffld_store(struct device *dev, struct device_attribute *attr, |
|---|
| 2271 | + const char *buf, size_t count) |
|---|
| 2272 | +{ |
|---|
| 2273 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2274 | + int val = 0; |
|---|
| 2275 | + |
|---|
| 2276 | + if (sscanf(buf, "%d", &val) != 1) |
|---|
| 2277 | + return -EINVAL; |
|---|
| 2278 | + |
|---|
| 2279 | + if (val > FW_MAX_EXCHANGES_CNT) |
|---|
| 2280 | + val = FW_MAX_EXCHANGES_CNT; |
|---|
| 2281 | + else if (val < 0) |
|---|
| 2282 | + val = 0; |
|---|
| 2283 | + |
|---|
| 2284 | + vha->u_ql2xexchoffld = val; |
|---|
| 2285 | + return strlen(buf); |
|---|
| 2286 | +} |
|---|
| 2287 | + |
|---|
| 2288 | +static ssize_t |
|---|
| 2289 | +ql2xiniexchg_show(struct device *dev, struct device_attribute *attr, |
|---|
| 2290 | + char *buf) |
|---|
| 2291 | +{ |
|---|
| 2292 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2293 | + int len = 0; |
|---|
| 2294 | + |
|---|
| 2295 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 2296 | + "target exchange: new %d : current: %d\n\n", |
|---|
| 2297 | + vha->u_ql2xiniexchg, vha->ql2xiniexchg); |
|---|
| 2298 | + |
|---|
| 2299 | + len += scnprintf(buf + len, PAGE_SIZE-len, |
|---|
| 2300 | + "Please (re)set operating mode via \"/sys/class/scsi_host/host%ld/qlini_mode\" to load new setting.\n", |
|---|
| 2301 | + vha->host_no); |
|---|
| 2302 | + |
|---|
| 2303 | + return len; |
|---|
| 2304 | +} |
|---|
| 2305 | + |
|---|
| 2306 | +static ssize_t |
|---|
| 2307 | +ql2xiniexchg_store(struct device *dev, struct device_attribute *attr, |
|---|
| 2308 | + const char *buf, size_t count) |
|---|
| 2309 | +{ |
|---|
| 2310 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2311 | + int val = 0; |
|---|
| 2312 | + |
|---|
| 2313 | + if (sscanf(buf, "%d", &val) != 1) |
|---|
| 2314 | + return -EINVAL; |
|---|
| 2315 | + |
|---|
| 2316 | + if (val > FW_MAX_EXCHANGES_CNT) |
|---|
| 2317 | + val = FW_MAX_EXCHANGES_CNT; |
|---|
| 2318 | + else if (val < 0) |
|---|
| 2319 | + val = 0; |
|---|
| 2320 | + |
|---|
| 2321 | + vha->u_ql2xiniexchg = val; |
|---|
| 2322 | + return strlen(buf); |
|---|
| 2323 | +} |
|---|
| 2324 | + |
|---|
| 2325 | +static ssize_t |
|---|
| 2326 | +qla2x00_dif_bundle_statistics_show(struct device *dev, |
|---|
| 2327 | + struct device_attribute *attr, char *buf) |
|---|
| 2328 | +{ |
|---|
| 2329 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2330 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 2331 | + |
|---|
| 2332 | + return scnprintf(buf, PAGE_SIZE, |
|---|
| 2333 | + "cross=%llu read=%llu write=%llu kalloc=%llu dma_alloc=%llu unusable=%u\n", |
|---|
| 2334 | + ha->dif_bundle_crossed_pages, ha->dif_bundle_reads, |
|---|
| 2335 | + ha->dif_bundle_writes, ha->dif_bundle_kallocs, |
|---|
| 2336 | + ha->dif_bundle_dma_allocs, ha->pool.unusable.count); |
|---|
| 2337 | +} |
|---|
| 2338 | + |
|---|
| 2339 | +static ssize_t |
|---|
| 2340 | +qla2x00_fw_attr_show(struct device *dev, |
|---|
| 2341 | + struct device_attribute *attr, char *buf) |
|---|
| 2342 | +{ |
|---|
| 2343 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2344 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 2345 | + |
|---|
| 2346 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 2347 | + return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 2348 | + |
|---|
| 2349 | + return scnprintf(buf, PAGE_SIZE, "%llx\n", |
|---|
| 2350 | + (uint64_t)ha->fw_attributes_ext[1] << 48 | |
|---|
| 2351 | + (uint64_t)ha->fw_attributes_ext[0] << 32 | |
|---|
| 2352 | + (uint64_t)ha->fw_attributes_h << 16 | |
|---|
| 2353 | + (uint64_t)ha->fw_attributes); |
|---|
| 2354 | +} |
|---|
| 2355 | + |
|---|
| 2356 | +static ssize_t |
|---|
| 2357 | +qla2x00_port_no_show(struct device *dev, struct device_attribute *attr, |
|---|
| 2358 | + char *buf) |
|---|
| 2359 | +{ |
|---|
| 2360 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2361 | + |
|---|
| 2362 | + return scnprintf(buf, PAGE_SIZE, "%u\n", vha->hw->port_no); |
|---|
| 2363 | +} |
|---|
| 2364 | + |
|---|
| 2365 | +static ssize_t |
|---|
| 2366 | +qla2x00_dport_diagnostics_show(struct device *dev, |
|---|
| 2367 | + struct device_attribute *attr, char *buf) |
|---|
| 2368 | +{ |
|---|
| 2369 | + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
|---|
| 2370 | + |
|---|
| 2371 | + if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && |
|---|
| 2372 | + !IS_QLA28XX(vha->hw)) |
|---|
| 2373 | + return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 2374 | + |
|---|
| 2375 | + if (!*vha->dport_data) |
|---|
| 2376 | + return scnprintf(buf, PAGE_SIZE, "\n"); |
|---|
| 2377 | + |
|---|
| 2378 | + return scnprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", |
|---|
| 2379 | + vha->dport_data[0], vha->dport_data[1], |
|---|
| 2380 | + vha->dport_data[2], vha->dport_data[3]); |
|---|
| 2381 | +} |
|---|
| 2382 | +static DEVICE_ATTR(dport_diagnostics, 0444, |
|---|
| 2383 | + qla2x00_dport_diagnostics_show, NULL); |
|---|
| 2384 | + |
|---|
| 2385 | +static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL); |
|---|
| 1539 | 2386 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); |
|---|
| 1540 | 2387 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); |
|---|
| 1541 | 2388 | static DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL); |
|---|
| .. | .. |
|---|
| 1549 | 2396 | qla2x00_zio_timer_store); |
|---|
| 1550 | 2397 | static DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, |
|---|
| 1551 | 2398 | qla2x00_beacon_store); |
|---|
| 2399 | +static DEVICE_ATTR(beacon_config, 0644, qla2x00_beacon_config_show, |
|---|
| 2400 | + qla2x00_beacon_config_store); |
|---|
| 1552 | 2401 | static DEVICE_ATTR(optrom_bios_version, S_IRUGO, |
|---|
| 1553 | 2402 | qla2x00_optrom_bios_version_show, NULL); |
|---|
| 1554 | 2403 | static DEVICE_ATTR(optrom_efi_version, S_IRUGO, |
|---|
| .. | .. |
|---|
| 1563 | 2412 | NULL); |
|---|
| 1564 | 2413 | static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, |
|---|
| 1565 | 2414 | NULL); |
|---|
| 2415 | +static DEVICE_ATTR(serdes_version, 0444, qla2x00_serdes_version_show, NULL); |
|---|
| 1566 | 2416 | static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL); |
|---|
| 1567 | 2417 | static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL); |
|---|
| 1568 | 2418 | static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show, |
|---|
| .. | .. |
|---|
| 1580 | 2430 | qla2x00_allow_cna_fw_dump_show, |
|---|
| 1581 | 2431 | qla2x00_allow_cna_fw_dump_store); |
|---|
| 1582 | 2432 | static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL); |
|---|
| 1583 | | -static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL); |
|---|
| 1584 | | -static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL); |
|---|
| 2433 | +static DEVICE_ATTR(min_supported_speed, 0444, |
|---|
| 2434 | + qla2x00_min_supported_speed_show, NULL); |
|---|
| 2435 | +static DEVICE_ATTR(max_supported_speed, 0444, |
|---|
| 2436 | + qla2x00_max_supported_speed_show, NULL); |
|---|
| 2437 | +static DEVICE_ATTR(zio_threshold, 0644, |
|---|
| 2438 | + qla_zio_threshold_show, |
|---|
| 2439 | + qla_zio_threshold_store); |
|---|
| 2440 | +static DEVICE_ATTR_RW(qlini_mode); |
|---|
| 2441 | +static DEVICE_ATTR_RW(ql2xexchoffld); |
|---|
| 2442 | +static DEVICE_ATTR_RW(ql2xiniexchg); |
|---|
| 2443 | +static DEVICE_ATTR(dif_bundle_statistics, 0444, |
|---|
| 2444 | + qla2x00_dif_bundle_statistics_show, NULL); |
|---|
| 2445 | +static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show, |
|---|
| 2446 | + qla2x00_port_speed_store); |
|---|
| 2447 | +static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL); |
|---|
| 2448 | +static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL); |
|---|
| 2449 | + |
|---|
| 1585 | 2450 | |
|---|
| 1586 | 2451 | struct device_attribute *qla2x00_host_attrs[] = { |
|---|
| 1587 | 2452 | &dev_attr_driver_version, |
|---|
| .. | .. |
|---|
| 1596 | 2461 | &dev_attr_zio, |
|---|
| 1597 | 2462 | &dev_attr_zio_timer, |
|---|
| 1598 | 2463 | &dev_attr_beacon, |
|---|
| 2464 | + &dev_attr_beacon_config, |
|---|
| 1599 | 2465 | &dev_attr_optrom_bios_version, |
|---|
| 1600 | 2466 | &dev_attr_optrom_efi_version, |
|---|
| 1601 | 2467 | &dev_attr_optrom_fcode_version, |
|---|
| 1602 | 2468 | &dev_attr_optrom_fw_version, |
|---|
| 1603 | 2469 | &dev_attr_84xx_fw_version, |
|---|
| 1604 | 2470 | &dev_attr_total_isp_aborts, |
|---|
| 2471 | + &dev_attr_serdes_version, |
|---|
| 1605 | 2472 | &dev_attr_mpi_version, |
|---|
| 1606 | 2473 | &dev_attr_phy_version, |
|---|
| 1607 | 2474 | &dev_attr_flash_block_size, |
|---|
| .. | .. |
|---|
| 1616 | 2483 | &dev_attr_fw_dump_size, |
|---|
| 1617 | 2484 | &dev_attr_allow_cna_fw_dump, |
|---|
| 1618 | 2485 | &dev_attr_pep_version, |
|---|
| 1619 | | - &dev_attr_min_link_speed, |
|---|
| 1620 | | - &dev_attr_max_speed_sup, |
|---|
| 2486 | + &dev_attr_min_supported_speed, |
|---|
| 2487 | + &dev_attr_max_supported_speed, |
|---|
| 2488 | + &dev_attr_zio_threshold, |
|---|
| 2489 | + &dev_attr_dif_bundle_statistics, |
|---|
| 2490 | + &dev_attr_port_speed, |
|---|
| 2491 | + &dev_attr_port_no, |
|---|
| 2492 | + &dev_attr_fw_attr, |
|---|
| 2493 | + &dev_attr_dport_diagnostics, |
|---|
| 2494 | + NULL, /* reserve for qlini_mode */ |
|---|
| 2495 | + NULL, /* reserve for ql2xiniexchg */ |
|---|
| 2496 | + NULL, /* reserve for ql2xexchoffld */ |
|---|
| 1621 | 2497 | NULL, |
|---|
| 1622 | 2498 | }; |
|---|
| 2499 | + |
|---|
| 2500 | +void qla_insert_tgt_attrs(void) |
|---|
| 2501 | +{ |
|---|
| 2502 | + struct device_attribute **attr; |
|---|
| 2503 | + |
|---|
| 2504 | + /* advance to empty slot */ |
|---|
| 2505 | + for (attr = &qla2x00_host_attrs[0]; *attr; ++attr) |
|---|
| 2506 | + continue; |
|---|
| 2507 | + |
|---|
| 2508 | + *attr = &dev_attr_qlini_mode; |
|---|
| 2509 | + attr++; |
|---|
| 2510 | + *attr = &dev_attr_ql2xiniexchg; |
|---|
| 2511 | + attr++; |
|---|
| 2512 | + *attr = &dev_attr_ql2xexchoffld; |
|---|
| 2513 | +} |
|---|
| 1623 | 2514 | |
|---|
| 1624 | 2515 | /* Host attributes. */ |
|---|
| 1625 | 2516 | |
|---|
| .. | .. |
|---|
| 1635 | 2526 | static void |
|---|
| 1636 | 2527 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
|---|
| 1637 | 2528 | { |
|---|
| 1638 | | - struct qla_hw_data *ha = ((struct scsi_qla_host *) |
|---|
| 1639 | | - (shost_priv(shost)))->hw; |
|---|
| 1640 | | - u32 speed = FC_PORTSPEED_UNKNOWN; |
|---|
| 2529 | + scsi_qla_host_t *vha = shost_priv(shost); |
|---|
| 2530 | + u32 speed; |
|---|
| 1641 | 2531 | |
|---|
| 1642 | | - if (IS_QLAFX00(ha)) { |
|---|
| 2532 | + if (IS_QLAFX00(vha->hw)) { |
|---|
| 1643 | 2533 | qlafx00_get_host_speed(shost); |
|---|
| 1644 | 2534 | return; |
|---|
| 1645 | 2535 | } |
|---|
| 1646 | 2536 | |
|---|
| 1647 | | - switch (ha->link_data_rate) { |
|---|
| 2537 | + switch (vha->hw->link_data_rate) { |
|---|
| 1648 | 2538 | case PORT_SPEED_1GB: |
|---|
| 1649 | 2539 | speed = FC_PORTSPEED_1GBIT; |
|---|
| 1650 | 2540 | break; |
|---|
| .. | .. |
|---|
| 1666 | 2556 | case PORT_SPEED_32GB: |
|---|
| 1667 | 2557 | speed = FC_PORTSPEED_32GBIT; |
|---|
| 1668 | 2558 | break; |
|---|
| 2559 | + case PORT_SPEED_64GB: |
|---|
| 2560 | + speed = FC_PORTSPEED_64GBIT; |
|---|
| 2561 | + break; |
|---|
| 2562 | + default: |
|---|
| 2563 | + speed = FC_PORTSPEED_UNKNOWN; |
|---|
| 2564 | + break; |
|---|
| 1669 | 2565 | } |
|---|
| 2566 | + |
|---|
| 1670 | 2567 | fc_host_speed(shost) = speed; |
|---|
| 1671 | 2568 | } |
|---|
| 1672 | 2569 | |
|---|
| .. | .. |
|---|
| 1674 | 2571 | qla2x00_get_host_port_type(struct Scsi_Host *shost) |
|---|
| 1675 | 2572 | { |
|---|
| 1676 | 2573 | scsi_qla_host_t *vha = shost_priv(shost); |
|---|
| 1677 | | - uint32_t port_type = FC_PORTTYPE_UNKNOWN; |
|---|
| 2574 | + uint32_t port_type; |
|---|
| 1678 | 2575 | |
|---|
| 1679 | 2576 | if (vha->vp_idx) { |
|---|
| 1680 | 2577 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; |
|---|
| .. | .. |
|---|
| 1693 | 2590 | case ISP_CFG_F: |
|---|
| 1694 | 2591 | port_type = FC_PORTTYPE_NPORT; |
|---|
| 1695 | 2592 | break; |
|---|
| 2593 | + default: |
|---|
| 2594 | + port_type = FC_PORTTYPE_UNKNOWN; |
|---|
| 2595 | + break; |
|---|
| 1696 | 2596 | } |
|---|
| 2597 | + |
|---|
| 1697 | 2598 | fc_host_port_type(shost) = port_type; |
|---|
| 1698 | 2599 | } |
|---|
| 1699 | 2600 | |
|---|
| .. | .. |
|---|
| 1755 | 2656 | fc_starget_port_id(starget) = port_id; |
|---|
| 1756 | 2657 | } |
|---|
| 1757 | 2658 | |
|---|
| 1758 | | -static void |
|---|
| 2659 | +static inline void |
|---|
| 1759 | 2660 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
|---|
| 1760 | 2661 | { |
|---|
| 1761 | | - if (timeout) |
|---|
| 1762 | | - rport->dev_loss_tmo = timeout; |
|---|
| 1763 | | - else |
|---|
| 1764 | | - rport->dev_loss_tmo = 1; |
|---|
| 2662 | + rport->dev_loss_tmo = timeout ? timeout : 1; |
|---|
| 1765 | 2663 | } |
|---|
| 1766 | 2664 | |
|---|
| 1767 | 2665 | static void |
|---|
| .. | .. |
|---|
| 1800 | 2698 | qla2x00_terminate_rport_io(struct fc_rport *rport) |
|---|
| 1801 | 2699 | { |
|---|
| 1802 | 2700 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; |
|---|
| 2701 | + scsi_qla_host_t *vha; |
|---|
| 1803 | 2702 | |
|---|
| 1804 | 2703 | if (!fcport) |
|---|
| 1805 | 2704 | return; |
|---|
| .. | .. |
|---|
| 1809 | 2708 | |
|---|
| 1810 | 2709 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) |
|---|
| 1811 | 2710 | return; |
|---|
| 2711 | + vha = fcport->vha; |
|---|
| 1812 | 2712 | |
|---|
| 1813 | 2713 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { |
|---|
| 1814 | 2714 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
|---|
| 2715 | + qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, |
|---|
| 2716 | + 0, WAIT_TARGET); |
|---|
| 1815 | 2717 | return; |
|---|
| 1816 | 2718 | } |
|---|
| 1817 | 2719 | /* |
|---|
| .. | .. |
|---|
| 1825 | 2727 | fcport->d_id.b.area, fcport->d_id.b.al_pa); |
|---|
| 1826 | 2728 | else |
|---|
| 1827 | 2729 | qla2x00_port_logout(fcport->vha, fcport); |
|---|
| 2730 | + } |
|---|
| 2731 | + |
|---|
| 2732 | + /* check for any straggling io left behind */ |
|---|
| 2733 | + if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) { |
|---|
| 2734 | + ql_log(ql_log_warn, vha, 0x300b, |
|---|
| 2735 | + "IO not return. Resetting. \n"); |
|---|
| 2736 | + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
|---|
| 2737 | + qla2xxx_wake_dpc(vha); |
|---|
| 2738 | + qla2x00_wait_for_chip_reset(vha); |
|---|
| 1828 | 2739 | } |
|---|
| 1829 | 2740 | } |
|---|
| 1830 | 2741 | |
|---|
| .. | .. |
|---|
| 1850 | 2761 | struct link_statistics *stats; |
|---|
| 1851 | 2762 | dma_addr_t stats_dma; |
|---|
| 1852 | 2763 | struct fc_host_statistics *p = &vha->fc_host_stat; |
|---|
| 2764 | + struct qla_qpair *qpair; |
|---|
| 2765 | + int i; |
|---|
| 2766 | + u64 ib = 0, ob = 0, ir = 0, or = 0; |
|---|
| 1853 | 2767 | |
|---|
| 1854 | 2768 | memset(p, -1, sizeof(*p)); |
|---|
| 1855 | 2769 | |
|---|
| .. | .. |
|---|
| 1865 | 2779 | if (qla2x00_chip_is_down(vha)) |
|---|
| 1866 | 2780 | goto done; |
|---|
| 1867 | 2781 | |
|---|
| 1868 | | - stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats), |
|---|
| 1869 | | - &stats_dma, GFP_KERNEL); |
|---|
| 2782 | + stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma, |
|---|
| 2783 | + GFP_KERNEL); |
|---|
| 1870 | 2784 | if (!stats) { |
|---|
| 1871 | 2785 | ql_log(ql_log_warn, vha, 0x707d, |
|---|
| 1872 | 2786 | "Failed to allocate memory for stats.\n"); |
|---|
| .. | .. |
|---|
| 1886 | 2800 | if (rval != QLA_SUCCESS) |
|---|
| 1887 | 2801 | goto done_free; |
|---|
| 1888 | 2802 | |
|---|
| 1889 | | - p->link_failure_count = stats->link_fail_cnt; |
|---|
| 1890 | | - p->loss_of_sync_count = stats->loss_sync_cnt; |
|---|
| 1891 | | - p->loss_of_signal_count = stats->loss_sig_cnt; |
|---|
| 1892 | | - p->prim_seq_protocol_err_count = stats->prim_seq_err_cnt; |
|---|
| 1893 | | - p->invalid_tx_word_count = stats->inval_xmit_word_cnt; |
|---|
| 1894 | | - p->invalid_crc_count = stats->inval_crc_cnt; |
|---|
| 1895 | | - if (IS_FWI2_CAPABLE(ha)) { |
|---|
| 1896 | | - p->lip_count = stats->lip_cnt; |
|---|
| 1897 | | - p->tx_frames = stats->tx_frames; |
|---|
| 1898 | | - p->rx_frames = stats->rx_frames; |
|---|
| 1899 | | - p->dumped_frames = stats->discarded_frames; |
|---|
| 1900 | | - p->nos_count = stats->nos_rcvd; |
|---|
| 1901 | | - p->error_frames = |
|---|
| 1902 | | - stats->dropped_frames + stats->discarded_frames; |
|---|
| 1903 | | - p->rx_words = vha->qla_stats.input_bytes; |
|---|
| 1904 | | - p->tx_words = vha->qla_stats.output_bytes; |
|---|
| 2803 | + /* --- */ |
|---|
| 2804 | + for (i = 0; i < vha->hw->max_qpairs; i++) { |
|---|
| 2805 | + qpair = vha->hw->queue_pair_map[i]; |
|---|
| 2806 | + if (!qpair) |
|---|
| 2807 | + continue; |
|---|
| 2808 | + ir += qpair->counters.input_requests; |
|---|
| 2809 | + or += qpair->counters.output_requests; |
|---|
| 2810 | + ib += qpair->counters.input_bytes; |
|---|
| 2811 | + ob += qpair->counters.output_bytes; |
|---|
| 1905 | 2812 | } |
|---|
| 2813 | + ir += ha->base_qpair->counters.input_requests; |
|---|
| 2814 | + or += ha->base_qpair->counters.output_requests; |
|---|
| 2815 | + ib += ha->base_qpair->counters.input_bytes; |
|---|
| 2816 | + ob += ha->base_qpair->counters.output_bytes; |
|---|
| 2817 | + |
|---|
| 2818 | + ir += vha->qla_stats.input_requests; |
|---|
| 2819 | + or += vha->qla_stats.output_requests; |
|---|
| 2820 | + ib += vha->qla_stats.input_bytes; |
|---|
| 2821 | + ob += vha->qla_stats.output_bytes; |
|---|
| 2822 | + /* --- */ |
|---|
| 2823 | + |
|---|
| 2824 | + p->link_failure_count = le32_to_cpu(stats->link_fail_cnt); |
|---|
| 2825 | + p->loss_of_sync_count = le32_to_cpu(stats->loss_sync_cnt); |
|---|
| 2826 | + p->loss_of_signal_count = le32_to_cpu(stats->loss_sig_cnt); |
|---|
| 2827 | + p->prim_seq_protocol_err_count = le32_to_cpu(stats->prim_seq_err_cnt); |
|---|
| 2828 | + p->invalid_tx_word_count = le32_to_cpu(stats->inval_xmit_word_cnt); |
|---|
| 2829 | + p->invalid_crc_count = le32_to_cpu(stats->inval_crc_cnt); |
|---|
| 2830 | + if (IS_FWI2_CAPABLE(ha)) { |
|---|
| 2831 | + p->lip_count = le32_to_cpu(stats->lip_cnt); |
|---|
| 2832 | + p->tx_frames = le32_to_cpu(stats->tx_frames); |
|---|
| 2833 | + p->rx_frames = le32_to_cpu(stats->rx_frames); |
|---|
| 2834 | + p->dumped_frames = le32_to_cpu(stats->discarded_frames); |
|---|
| 2835 | + p->nos_count = le32_to_cpu(stats->nos_rcvd); |
|---|
| 2836 | + p->error_frames = |
|---|
| 2837 | + le32_to_cpu(stats->dropped_frames) + |
|---|
| 2838 | + le32_to_cpu(stats->discarded_frames); |
|---|
| 2839 | + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
|---|
| 2840 | + p->rx_words = le64_to_cpu(stats->fpm_recv_word_cnt); |
|---|
| 2841 | + p->tx_words = le64_to_cpu(stats->fpm_xmit_word_cnt); |
|---|
| 2842 | + } else { |
|---|
| 2843 | + p->rx_words = ib >> 2; |
|---|
| 2844 | + p->tx_words = ob >> 2; |
|---|
| 2845 | + } |
|---|
| 2846 | + } |
|---|
| 2847 | + |
|---|
| 1906 | 2848 | p->fcp_control_requests = vha->qla_stats.control_requests; |
|---|
| 1907 | | - p->fcp_input_requests = vha->qla_stats.input_requests; |
|---|
| 1908 | | - p->fcp_output_requests = vha->qla_stats.output_requests; |
|---|
| 1909 | | - p->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20; |
|---|
| 1910 | | - p->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20; |
|---|
| 2849 | + p->fcp_input_requests = ir; |
|---|
| 2850 | + p->fcp_output_requests = or; |
|---|
| 2851 | + p->fcp_input_megabytes = ib >> 20; |
|---|
| 2852 | + p->fcp_output_megabytes = ob >> 20; |
|---|
| 1911 | 2853 | p->seconds_since_last_reset = |
|---|
| 1912 | | - get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset; |
|---|
| 2854 | + get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset; |
|---|
| 1913 | 2855 | do_div(p->seconds_since_last_reset, HZ); |
|---|
| 1914 | 2856 | |
|---|
| 1915 | 2857 | done_free: |
|---|
| .. | .. |
|---|
| 1927 | 2869 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
|---|
| 1928 | 2870 | struct link_statistics *stats; |
|---|
| 1929 | 2871 | dma_addr_t stats_dma; |
|---|
| 2872 | + int i; |
|---|
| 2873 | + struct qla_qpair *qpair; |
|---|
| 1930 | 2874 | |
|---|
| 1931 | 2875 | memset(&vha->qla_stats, 0, sizeof(vha->qla_stats)); |
|---|
| 1932 | 2876 | memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat)); |
|---|
| 2877 | + for (i = 0; i < vha->hw->max_qpairs; i++) { |
|---|
| 2878 | + qpair = vha->hw->queue_pair_map[i]; |
|---|
| 2879 | + if (!qpair) |
|---|
| 2880 | + continue; |
|---|
| 2881 | + memset(&qpair->counters, 0, sizeof(qpair->counters)); |
|---|
| 2882 | + } |
|---|
| 2883 | + memset(&ha->base_qpair->counters, 0, sizeof(qpair->counters)); |
|---|
| 1933 | 2884 | |
|---|
| 1934 | 2885 | vha->qla_stats.jiffies_at_last_reset = get_jiffies_64(); |
|---|
| 1935 | 2886 | |
|---|
| .. | .. |
|---|
| 1977 | 2928 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) |
|---|
| 1978 | 2929 | { |
|---|
| 1979 | 2930 | scsi_qla_host_t *vha = shost_priv(shost); |
|---|
| 1980 | | - uint8_t node_name[WWN_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, \ |
|---|
| 1981 | | - 0xFF, 0xFF, 0xFF, 0xFF}; |
|---|
| 2931 | + static const uint8_t node_name[WWN_SIZE] = { |
|---|
| 2932 | + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
|---|
| 2933 | + }; |
|---|
| 1982 | 2934 | u64 fabric_name = wwn_to_u64(node_name); |
|---|
| 1983 | 2935 | |
|---|
| 1984 | 2936 | if (vha->device_flags & SWITCH_FOUND) |
|---|
| .. | .. |
|---|
| 2056 | 3008 | |
|---|
| 2057 | 3009 | /* initialized vport states */ |
|---|
| 2058 | 3010 | atomic_set(&vha->loop_state, LOOP_DOWN); |
|---|
| 2059 | | - vha->vp_err_state= VP_ERR_PORTDWN; |
|---|
| 2060 | | - vha->vp_prev_err_state= VP_ERR_UNKWN; |
|---|
| 3011 | + vha->vp_err_state = VP_ERR_PORTDWN; |
|---|
| 3012 | + vha->vp_prev_err_state = VP_ERR_UNKWN; |
|---|
| 2061 | 3013 | /* Check if physical ha port is Up */ |
|---|
| 2062 | 3014 | if (atomic_read(&base_vha->loop_state) == LOOP_DOWN || |
|---|
| 2063 | 3015 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
|---|
| .. | .. |
|---|
| 2072 | 3024 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
|---|
| 2073 | 3025 | if (ha->fw_attributes & BIT_4) { |
|---|
| 2074 | 3026 | int prot = 0, guard; |
|---|
| 3027 | + |
|---|
| 2075 | 3028 | vha->flags.difdix_supported = 1; |
|---|
| 2076 | 3029 | ql_dbg(ql_dbg_user, vha, 0x7082, |
|---|
| 2077 | 3030 | "Registered for DIF/DIX type 1 and 3 protection.\n"); |
|---|
| 2078 | | - if (ql2xenabledif == 1) |
|---|
| 2079 | | - prot = SHOST_DIX_TYPE0_PROTECTION; |
|---|
| 2080 | 3031 | scsi_host_set_prot(vha->host, |
|---|
| 2081 | 3032 | prot | SHOST_DIF_TYPE1_PROTECTION |
|---|
| 2082 | 3033 | | SHOST_DIF_TYPE2_PROTECTION |
|---|
| .. | .. |
|---|
| 2163 | 3114 | scsi_qla_host_t *vha = fc_vport->dd_data; |
|---|
| 2164 | 3115 | struct qla_hw_data *ha = vha->hw; |
|---|
| 2165 | 3116 | uint16_t id = vha->vp_idx; |
|---|
| 3117 | + |
|---|
| 3118 | + set_bit(VPORT_DELETE, &vha->dpc_flags); |
|---|
| 2166 | 3119 | |
|---|
| 2167 | 3120 | while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) || |
|---|
| 2168 | 3121 | test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) |
|---|
| .. | .. |
|---|
| 2320 | 3273 | .bsg_timeout = qla24xx_bsg_timeout, |
|---|
| 2321 | 3274 | }; |
|---|
| 2322 | 3275 | |
|---|
| 3276 | +static uint |
|---|
| 3277 | +qla2x00_get_host_supported_speeds(scsi_qla_host_t *vha, uint speeds) |
|---|
| 3278 | +{ |
|---|
| 3279 | + uint supported_speeds = FC_PORTSPEED_UNKNOWN; |
|---|
| 3280 | + |
|---|
| 3281 | + if (speeds & FDMI_PORT_SPEED_64GB) |
|---|
| 3282 | + supported_speeds |= FC_PORTSPEED_64GBIT; |
|---|
| 3283 | + if (speeds & FDMI_PORT_SPEED_32GB) |
|---|
| 3284 | + supported_speeds |= FC_PORTSPEED_32GBIT; |
|---|
| 3285 | + if (speeds & FDMI_PORT_SPEED_16GB) |
|---|
| 3286 | + supported_speeds |= FC_PORTSPEED_16GBIT; |
|---|
| 3287 | + if (speeds & FDMI_PORT_SPEED_8GB) |
|---|
| 3288 | + supported_speeds |= FC_PORTSPEED_8GBIT; |
|---|
| 3289 | + if (speeds & FDMI_PORT_SPEED_4GB) |
|---|
| 3290 | + supported_speeds |= FC_PORTSPEED_4GBIT; |
|---|
| 3291 | + if (speeds & FDMI_PORT_SPEED_2GB) |
|---|
| 3292 | + supported_speeds |= FC_PORTSPEED_2GBIT; |
|---|
| 3293 | + if (speeds & FDMI_PORT_SPEED_1GB) |
|---|
| 3294 | + supported_speeds |= FC_PORTSPEED_1GBIT; |
|---|
| 3295 | + |
|---|
| 3296 | + return supported_speeds; |
|---|
| 3297 | +} |
|---|
| 3298 | + |
|---|
| 2323 | 3299 | void |
|---|
| 2324 | 3300 | qla2x00_init_host_attr(scsi_qla_host_t *vha) |
|---|
| 2325 | 3301 | { |
|---|
| 2326 | 3302 | struct qla_hw_data *ha = vha->hw; |
|---|
| 2327 | | - u32 speed = FC_PORTSPEED_UNKNOWN; |
|---|
| 3303 | + u32 speeds = 0, fdmi_speed = 0; |
|---|
| 2328 | 3304 | |
|---|
| 2329 | 3305 | fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; |
|---|
| 2330 | 3306 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); |
|---|
| .. | .. |
|---|
| 2334 | 3310 | fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; |
|---|
| 2335 | 3311 | fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; |
|---|
| 2336 | 3312 | |
|---|
| 2337 | | - if (IS_CNA_CAPABLE(ha)) |
|---|
| 2338 | | - speed = FC_PORTSPEED_10GBIT; |
|---|
| 2339 | | - else if (IS_QLA2031(ha)) |
|---|
| 2340 | | - speed = FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT | |
|---|
| 2341 | | - FC_PORTSPEED_4GBIT; |
|---|
| 2342 | | - else if (IS_QLA25XX(ha)) |
|---|
| 2343 | | - speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | |
|---|
| 2344 | | - FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; |
|---|
| 2345 | | - else if (IS_QLA24XX_TYPE(ha)) |
|---|
| 2346 | | - speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | |
|---|
| 2347 | | - FC_PORTSPEED_1GBIT; |
|---|
| 2348 | | - else if (IS_QLA23XX(ha)) |
|---|
| 2349 | | - speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; |
|---|
| 2350 | | - else if (IS_QLAFX00(ha)) |
|---|
| 2351 | | - speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | |
|---|
| 2352 | | - FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; |
|---|
| 2353 | | - else if (IS_QLA27XX(ha)) |
|---|
| 2354 | | - speed = FC_PORTSPEED_32GBIT | FC_PORTSPEED_16GBIT | |
|---|
| 2355 | | - FC_PORTSPEED_8GBIT; |
|---|
| 2356 | | - else |
|---|
| 2357 | | - speed = FC_PORTSPEED_1GBIT; |
|---|
| 2358 | | - fc_host_supported_speeds(vha->host) = speed; |
|---|
| 3313 | + fdmi_speed = qla25xx_fdmi_port_speed_capability(ha); |
|---|
| 3314 | + speeds = qla2x00_get_host_supported_speeds(vha, fdmi_speed); |
|---|
| 3315 | + |
|---|
| 3316 | + fc_host_supported_speeds(vha->host) = speeds; |
|---|
| 2359 | 3317 | } |
|---|