diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_sup.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 149 |
1 files changed, 140 insertions, 9 deletions
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 8b3de4e54c28..de92504d7585 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -423,9 +423,6 @@ qla2x00_set_nvram_protection(struct qla_hw_data *ha, int stat) | |||
423 | /* Flash Manipulation Routines */ | 423 | /* Flash Manipulation Routines */ |
424 | /*****************************************************************************/ | 424 | /*****************************************************************************/ |
425 | 425 | ||
426 | #define OPTROM_BURST_SIZE 0x1000 | ||
427 | #define OPTROM_BURST_DWORDS (OPTROM_BURST_SIZE / 4) | ||
428 | |||
429 | static inline uint32_t | 426 | static inline uint32_t |
430 | flash_conf_addr(struct qla_hw_data *ha, uint32_t faddr) | 427 | flash_conf_addr(struct qla_hw_data *ha, uint32_t faddr) |
431 | { | 428 | { |
@@ -565,6 +562,10 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) | |||
565 | *start = FA_FLASH_LAYOUT_ADDR; | 562 | *start = FA_FLASH_LAYOUT_ADDR; |
566 | else if (IS_QLA81XX(ha)) | 563 | else if (IS_QLA81XX(ha)) |
567 | *start = FA_FLASH_LAYOUT_ADDR_81; | 564 | *start = FA_FLASH_LAYOUT_ADDR_81; |
565 | else if (IS_QLA82XX(ha)) { | ||
566 | *start = FA_FLASH_LAYOUT_ADDR_82; | ||
567 | goto end; | ||
568 | } | ||
568 | /* Begin with first PCI expansion ROM header. */ | 569 | /* Begin with first PCI expansion ROM header. */ |
569 | buf = (uint8_t *)req->ring; | 570 | buf = (uint8_t *)req->ring; |
570 | dcode = (uint32_t *)req->ring; | 571 | dcode = (uint32_t *)req->ring; |
@@ -648,6 +649,12 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
648 | const uint32_t def_npiv_conf1[] = | 649 | const uint32_t def_npiv_conf1[] = |
649 | { FA_NPIV_CONF1_ADDR_24, FA_NPIV_CONF1_ADDR, | 650 | { FA_NPIV_CONF1_ADDR_24, FA_NPIV_CONF1_ADDR, |
650 | FA_NPIV_CONF1_ADDR_81 }; | 651 | FA_NPIV_CONF1_ADDR_81 }; |
652 | const uint32_t fcp_prio_cfg0[] = | ||
653 | { FA_FCP_PRIO0_ADDR, FA_FCP_PRIO0_ADDR_25, | ||
654 | 0 }; | ||
655 | const uint32_t fcp_prio_cfg1[] = | ||
656 | { FA_FCP_PRIO1_ADDR, FA_FCP_PRIO1_ADDR_25, | ||
657 | 0 }; | ||
651 | uint32_t def; | 658 | uint32_t def; |
652 | uint16_t *wptr; | 659 | uint16_t *wptr; |
653 | uint16_t cnt, chksum; | 660 | uint16_t cnt, chksum; |
@@ -703,10 +710,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
703 | break; | 710 | break; |
704 | case FLT_REG_VPD_0: | 711 | case FLT_REG_VPD_0: |
705 | ha->flt_region_vpd_nvram = start; | 712 | ha->flt_region_vpd_nvram = start; |
713 | if (IS_QLA82XX(ha)) | ||
714 | break; | ||
706 | if (ha->flags.port0) | 715 | if (ha->flags.port0) |
707 | ha->flt_region_vpd = start; | 716 | ha->flt_region_vpd = start; |
708 | break; | 717 | break; |
709 | case FLT_REG_VPD_1: | 718 | case FLT_REG_VPD_1: |
719 | if (IS_QLA82XX(ha)) | ||
720 | break; | ||
710 | if (!ha->flags.port0) | 721 | if (!ha->flags.port0) |
711 | ha->flt_region_vpd = start; | 722 | ha->flt_region_vpd = start; |
712 | break; | 723 | break; |
@@ -732,6 +743,29 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
732 | case FLT_REG_GOLD_FW: | 743 | case FLT_REG_GOLD_FW: |
733 | ha->flt_region_gold_fw = start; | 744 | ha->flt_region_gold_fw = start; |
734 | break; | 745 | break; |
746 | case FLT_REG_FCP_PRIO_0: | ||
747 | if (ha->flags.port0) | ||
748 | ha->flt_region_fcp_prio = start; | ||
749 | break; | ||
750 | case FLT_REG_FCP_PRIO_1: | ||
751 | if (!ha->flags.port0) | ||
752 | ha->flt_region_fcp_prio = start; | ||
753 | break; | ||
754 | case FLT_REG_BOOT_CODE_82XX: | ||
755 | ha->flt_region_boot = start; | ||
756 | break; | ||
757 | case FLT_REG_FW_82XX: | ||
758 | ha->flt_region_fw = start; | ||
759 | break; | ||
760 | case FLT_REG_GOLD_FW_82XX: | ||
761 | ha->flt_region_gold_fw = start; | ||
762 | break; | ||
763 | case FLT_REG_BOOTLOAD_82XX: | ||
764 | ha->flt_region_bootload = start; | ||
765 | break; | ||
766 | case FLT_REG_VPD_82XX: | ||
767 | ha->flt_region_vpd = start; | ||
768 | break; | ||
735 | } | 769 | } |
736 | } | 770 | } |
737 | goto done; | 771 | goto done; |
@@ -750,12 +784,14 @@ no_flash_data: | |||
750 | ha->flt_region_boot = def_boot[def]; | 784 | ha->flt_region_boot = def_boot[def]; |
751 | ha->flt_region_vpd_nvram = def_vpd_nvram[def]; | 785 | ha->flt_region_vpd_nvram = def_vpd_nvram[def]; |
752 | ha->flt_region_vpd = ha->flags.port0 ? | 786 | ha->flt_region_vpd = ha->flags.port0 ? |
753 | def_vpd0[def]: def_vpd1[def]; | 787 | def_vpd0[def] : def_vpd1[def]; |
754 | ha->flt_region_nvram = ha->flags.port0 ? | 788 | ha->flt_region_nvram = ha->flags.port0 ? |
755 | def_nvram0[def]: def_nvram1[def]; | 789 | def_nvram0[def] : def_nvram1[def]; |
756 | ha->flt_region_fdt = def_fdt[def]; | 790 | ha->flt_region_fdt = def_fdt[def]; |
757 | ha->flt_region_npiv_conf = ha->flags.port0 ? | 791 | ha->flt_region_npiv_conf = ha->flags.port0 ? |
758 | def_npiv_conf0[def]: def_npiv_conf1[def]; | 792 | def_npiv_conf0[def] : def_npiv_conf1[def]; |
793 | ha->flt_region_fcp_prio = ha->flags.port0 ? | ||
794 | fcp_prio_cfg0[def] : fcp_prio_cfg1[def]; | ||
759 | done: | 795 | done: |
760 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " | 796 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " |
761 | "vpd_nvram=0x%x vpd=0x%x nvram=0x%x fdt=0x%x flt=0x%x " | 797 | "vpd_nvram=0x%x vpd=0x%x nvram=0x%x fdt=0x%x flt=0x%x " |
@@ -775,7 +811,7 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha) | |||
775 | uint16_t *wptr; | 811 | uint16_t *wptr; |
776 | struct qla_fdt_layout *fdt; | 812 | struct qla_fdt_layout *fdt; |
777 | uint8_t man_id, flash_id; | 813 | uint8_t man_id, flash_id; |
778 | uint16_t mid, fid; | 814 | uint16_t mid = 0, fid = 0; |
779 | struct qla_hw_data *ha = vha->hw; | 815 | struct qla_hw_data *ha = vha->hw; |
780 | struct req_que *req = ha->req_q_map[0]; | 816 | struct req_que *req = ha->req_q_map[0]; |
781 | 817 | ||
@@ -816,6 +852,10 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha) | |||
816 | goto done; | 852 | goto done; |
817 | no_flash_data: | 853 | no_flash_data: |
818 | loc = locations[0]; | 854 | loc = locations[0]; |
855 | if (IS_QLA82XX(ha)) { | ||
856 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; | ||
857 | goto done; | ||
858 | } | ||
819 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | 859 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); |
820 | mid = man_id; | 860 | mid = man_id; |
821 | fid = flash_id; | 861 | fid = flash_id; |
@@ -853,6 +893,31 @@ done: | |||
853 | ha->fdt_block_size)); | 893 | ha->fdt_block_size)); |
854 | } | 894 | } |
855 | 895 | ||
896 | static void | ||
897 | qla2xxx_get_idc_param(scsi_qla_host_t *vha) | ||
898 | { | ||
899 | #define QLA82XX_IDC_PARAM_ADDR 0x003e885c | ||
900 | uint32_t *wptr; | ||
901 | struct qla_hw_data *ha = vha->hw; | ||
902 | struct req_que *req = ha->req_q_map[0]; | ||
903 | |||
904 | if (!IS_QLA82XX(ha)) | ||
905 | return; | ||
906 | |||
907 | wptr = (uint32_t *)req->ring; | ||
908 | ha->isp_ops->read_optrom(vha, (uint8_t *)req->ring, | ||
909 | QLA82XX_IDC_PARAM_ADDR , 8); | ||
910 | |||
911 | if (*wptr == __constant_cpu_to_le32(0xffffffff)) { | ||
912 | ha->nx_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT; | ||
913 | ha->nx_reset_timeout = QLA82XX_ROM_DRV_RESET_ACK_TIMEOUT; | ||
914 | } else { | ||
915 | ha->nx_dev_init_timeout = le32_to_cpu(*wptr++); | ||
916 | ha->nx_reset_timeout = le32_to_cpu(*wptr); | ||
917 | } | ||
918 | return; | ||
919 | } | ||
920 | |||
856 | int | 921 | int |
857 | qla2xxx_get_flash_info(scsi_qla_host_t *vha) | 922 | qla2xxx_get_flash_info(scsi_qla_host_t *vha) |
858 | { | 923 | { |
@@ -860,7 +925,7 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha) | |||
860 | uint32_t flt_addr; | 925 | uint32_t flt_addr; |
861 | struct qla_hw_data *ha = vha->hw; | 926 | struct qla_hw_data *ha = vha->hw; |
862 | 927 | ||
863 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA81XX(ha)) | 928 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA8XXX_TYPE(ha)) |
864 | return QLA_SUCCESS; | 929 | return QLA_SUCCESS; |
865 | 930 | ||
866 | ret = qla2xxx_find_flt_start(vha, &flt_addr); | 931 | ret = qla2xxx_find_flt_start(vha, &flt_addr); |
@@ -869,6 +934,7 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha) | |||
869 | 934 | ||
870 | qla2xxx_get_flt_info(vha, flt_addr); | 935 | qla2xxx_get_flt_info(vha, flt_addr); |
871 | qla2xxx_get_fdt_info(vha); | 936 | qla2xxx_get_fdt_info(vha); |
937 | qla2xxx_get_idc_param(vha); | ||
872 | 938 | ||
873 | return QLA_SUCCESS; | 939 | return QLA_SUCCESS; |
874 | } | 940 | } |
@@ -885,7 +951,7 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha) | |||
885 | struct qla_npiv_entry *entry; | 951 | struct qla_npiv_entry *entry; |
886 | struct qla_hw_data *ha = vha->hw; | 952 | struct qla_hw_data *ha = vha->hw; |
887 | 953 | ||
888 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA81XX(ha)) | 954 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA8XXX_TYPE(ha)) |
889 | return; | 955 | return; |
890 | 956 | ||
891 | ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, | 957 | ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, |
@@ -1178,6 +1244,9 @@ qla24xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | |||
1178 | uint32_t *dwptr; | 1244 | uint32_t *dwptr; |
1179 | struct qla_hw_data *ha = vha->hw; | 1245 | struct qla_hw_data *ha = vha->hw; |
1180 | 1246 | ||
1247 | if (IS_QLA82XX(ha)) | ||
1248 | return buf; | ||
1249 | |||
1181 | /* Dword reads to flash. */ | 1250 | /* Dword reads to flash. */ |
1182 | dwptr = (uint32_t *)buf; | 1251 | dwptr = (uint32_t *)buf; |
1183 | for (i = 0; i < bytes >> 2; i++, naddr++) | 1252 | for (i = 0; i < bytes >> 2; i++, naddr++) |
@@ -1233,6 +1302,9 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | |||
1233 | 1302 | ||
1234 | ret = QLA_SUCCESS; | 1303 | ret = QLA_SUCCESS; |
1235 | 1304 | ||
1305 | if (IS_QLA82XX(ha)) | ||
1306 | return ret; | ||
1307 | |||
1236 | /* Enable flash write. */ | 1308 | /* Enable flash write. */ |
1237 | WRT_REG_DWORD(®->ctrl_status, | 1309 | WRT_REG_DWORD(®->ctrl_status, |
1238 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 1310 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
@@ -1344,6 +1416,9 @@ qla2x00_beacon_blink(struct scsi_qla_host *vha) | |||
1344 | struct qla_hw_data *ha = vha->hw; | 1416 | struct qla_hw_data *ha = vha->hw; |
1345 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1417 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
1346 | 1418 | ||
1419 | if (IS_QLA82XX(ha)) | ||
1420 | return; | ||
1421 | |||
1347 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1422 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1348 | 1423 | ||
1349 | /* Save the Original GPIOE. */ | 1424 | /* Save the Original GPIOE. */ |
@@ -1525,6 +1600,9 @@ qla24xx_beacon_on(struct scsi_qla_host *vha) | |||
1525 | struct qla_hw_data *ha = vha->hw; | 1600 | struct qla_hw_data *ha = vha->hw; |
1526 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1601 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1527 | 1602 | ||
1603 | if (IS_QLA82XX(ha)) | ||
1604 | return QLA_SUCCESS; | ||
1605 | |||
1528 | if (ha->beacon_blink_led == 0) { | 1606 | if (ha->beacon_blink_led == 0) { |
1529 | /* Enable firmware for update */ | 1607 | /* Enable firmware for update */ |
1530 | ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL; | 1608 | ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL; |
@@ -1567,6 +1645,9 @@ qla24xx_beacon_off(struct scsi_qla_host *vha) | |||
1567 | struct qla_hw_data *ha = vha->hw; | 1645 | struct qla_hw_data *ha = vha->hw; |
1568 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1646 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1569 | 1647 | ||
1648 | if (IS_QLA82XX(ha)) | ||
1649 | return QLA_SUCCESS; | ||
1650 | |||
1570 | ha->beacon_blink_led = 0; | 1651 | ha->beacon_blink_led = 0; |
1571 | ha->beacon_color_state = QLA_LED_ALL_ON; | 1652 | ha->beacon_color_state = QLA_LED_ALL_ON; |
1572 | 1653 | ||
@@ -2576,6 +2657,9 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2576 | int i; | 2657 | int i; |
2577 | struct qla_hw_data *ha = vha->hw; | 2658 | struct qla_hw_data *ha = vha->hw; |
2578 | 2659 | ||
2660 | if (IS_QLA82XX(ha)) | ||
2661 | return ret; | ||
2662 | |||
2579 | if (!mbuf) | 2663 | if (!mbuf) |
2580 | return QLA_FUNCTION_FAILED; | 2664 | return QLA_FUNCTION_FAILED; |
2581 | 2665 | ||
@@ -2722,3 +2806,50 @@ qla2xxx_get_vpd_field(scsi_qla_host_t *vha, char *key, char *str, size_t size) | |||
2722 | 2806 | ||
2723 | return 0; | 2807 | return 0; |
2724 | } | 2808 | } |
2809 | |||
2810 | int | ||
2811 | qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *vha) | ||
2812 | { | ||
2813 | int len, max_len; | ||
2814 | uint32_t fcp_prio_addr; | ||
2815 | struct qla_hw_data *ha = vha->hw; | ||
2816 | |||
2817 | if (!ha->fcp_prio_cfg) { | ||
2818 | ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE); | ||
2819 | if (!ha->fcp_prio_cfg) { | ||
2820 | qla_printk(KERN_WARNING, ha, | ||
2821 | "Unable to allocate memory for fcp priority data " | ||
2822 | "(%x).\n", FCP_PRIO_CFG_SIZE); | ||
2823 | return QLA_FUNCTION_FAILED; | ||
2824 | } | ||
2825 | } | ||
2826 | memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE); | ||
2827 | |||
2828 | fcp_prio_addr = ha->flt_region_fcp_prio; | ||
2829 | |||
2830 | /* first read the fcp priority data header from flash */ | ||
2831 | ha->isp_ops->read_optrom(vha, (uint8_t *)ha->fcp_prio_cfg, | ||
2832 | fcp_prio_addr << 2, FCP_PRIO_CFG_HDR_SIZE); | ||
2833 | |||
2834 | if (!qla24xx_fcp_prio_cfg_valid(ha->fcp_prio_cfg, 0)) | ||
2835 | goto fail; | ||
2836 | |||
2837 | /* read remaining FCP CMD config data from flash */ | ||
2838 | fcp_prio_addr += (FCP_PRIO_CFG_HDR_SIZE >> 2); | ||
2839 | len = ha->fcp_prio_cfg->num_entries * FCP_PRIO_CFG_ENTRY_SIZE; | ||
2840 | max_len = FCP_PRIO_CFG_SIZE - FCP_PRIO_CFG_HDR_SIZE; | ||
2841 | |||
2842 | ha->isp_ops->read_optrom(vha, (uint8_t *)&ha->fcp_prio_cfg->entry[0], | ||
2843 | fcp_prio_addr << 2, (len < max_len ? len : max_len)); | ||
2844 | |||
2845 | /* revalidate the entire FCP priority config data, including entries */ | ||
2846 | if (!qla24xx_fcp_prio_cfg_valid(ha->fcp_prio_cfg, 1)) | ||
2847 | goto fail; | ||
2848 | |||
2849 | ha->flags.fcp_prio_enabled = 1; | ||
2850 | return QLA_SUCCESS; | ||
2851 | fail: | ||
2852 | vfree(ha->fcp_prio_cfg); | ||
2853 | ha->fcp_prio_cfg = NULL; | ||
2854 | return QLA_FUNCTION_FAILED; | ||
2855 | } | ||