aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorHarish Zunjarrao <harish.zunjarrao@qlogic.com>2010-05-28 18:08:23 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:01:24 -0400
commit9c2b297572bf3cc36d26520cd8f7e7ef4cb857f8 (patch)
treed98ce47df96e627f275a88cfebfc6b18408d834b /drivers/scsi/qla2xxx
parentb0cd579cde8ee0c7ed52239531ba09bcbc5b54c2 (diff)
[SCSI] qla2xxx: Support for loading Unified ROM Image (URI) format firmware file.
Used bootloder address from FLT while loading FW from flash as well. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c184
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h35
3 files changed, 215 insertions, 7 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 2895855adc9a..f0e792a82dde 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2788,6 +2788,9 @@ struct qla_hw_data {
2788 uint16_t gbl_dsd_avail; 2788 uint16_t gbl_dsd_avail;
2789 struct list_head gbl_dsd_list; 2789 struct list_head gbl_dsd_list;
2790#define NUM_DSD_CHAIN 4096 2790#define NUM_DSD_CHAIN 4096
2791
2792 uint8_t fw_type;
2793 __le32 file_prd_off; /* File firmware product offset */
2791}; 2794};
2792 2795
2793/* 2796/*
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index eb12bf260a17..1a9a7343dffa 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1407,7 +1407,8 @@ qla82xx_fw_load_from_flash(struct qla_hw_data *ha)
1407{ 1407{
1408 int i; 1408 int i;
1409 long size = 0; 1409 long size = 0;
1410 long flashaddr = BOOTLD_START, memaddr = BOOTLD_START; 1410 long flashaddr = ha->flt_region_bootload << 2;
1411 long memaddr = BOOTLD_START;
1411 u64 data; 1412 u64 data;
1412 u32 high, low; 1413 u32 high, low;
1413 size = (IMAGE_START - BOOTLD_START) / 8; 1414 size = (IMAGE_START - BOOTLD_START) / 8;
@@ -1677,6 +1678,94 @@ qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,
1677 return ret; 1678 return ret;
1678} 1679}
1679 1680
1681static struct qla82xx_uri_table_desc *
1682qla82xx_get_table_desc(const u8 *unirom, int section)
1683{
1684 uint32_t i;
1685 struct qla82xx_uri_table_desc *directory =
1686 (struct qla82xx_uri_table_desc *)&unirom[0];
1687 __le32 offset;
1688 __le32 tab_type;
1689 __le32 entries = cpu_to_le32(directory->num_entries);
1690
1691 for (i = 0; i < entries; i++) {
1692 offset = cpu_to_le32(directory->findex) +
1693 (i * cpu_to_le32(directory->entry_size));
1694 tab_type = cpu_to_le32(*((u32 *)&unirom[offset] + 8));
1695
1696 if (tab_type == section)
1697 return (struct qla82xx_uri_table_desc *)&unirom[offset];
1698 }
1699
1700 return NULL;
1701}
1702
1703static struct qla82xx_uri_data_desc *
1704qla82xx_get_data_desc(struct qla_hw_data *ha,
1705 u32 section, u32 idx_offset)
1706{
1707 const u8 *unirom = ha->hablob->fw->data;
1708 int idx = cpu_to_le32(*((int *)&unirom[ha->file_prd_off] + idx_offset));
1709 struct qla82xx_uri_table_desc *tab_desc = NULL;
1710 __le32 offset;
1711
1712 tab_desc = qla82xx_get_table_desc(unirom, section);
1713 if (!tab_desc)
1714 return NULL;
1715
1716 offset = cpu_to_le32(tab_desc->findex) +
1717 (cpu_to_le32(tab_desc->entry_size) * idx);
1718
1719 return (struct qla82xx_uri_data_desc *)&unirom[offset];
1720}
1721
1722static u8 *
1723qla82xx_get_bootld_offset(struct qla_hw_data *ha)
1724{
1725 u32 offset = BOOTLD_START;
1726 struct qla82xx_uri_data_desc *uri_desc = NULL;
1727
1728 if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
1729 uri_desc = qla82xx_get_data_desc(ha,
1730 QLA82XX_URI_DIR_SECT_BOOTLD, QLA82XX_URI_BOOTLD_IDX_OFF);
1731 if (uri_desc)
1732 offset = cpu_to_le32(uri_desc->findex);
1733 }
1734
1735 return (u8 *)&ha->hablob->fw->data[offset];
1736}
1737
1738static __le32
1739qla82xx_get_fw_size(struct qla_hw_data *ha)
1740{
1741 struct qla82xx_uri_data_desc *uri_desc = NULL;
1742
1743 if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
1744 uri_desc = qla82xx_get_data_desc(ha, QLA82XX_URI_DIR_SECT_FW,
1745 QLA82XX_URI_FIRMWARE_IDX_OFF);
1746 if (uri_desc)
1747 return cpu_to_le32(uri_desc->size);
1748 }
1749
1750 return cpu_to_le32(*(u32 *)&ha->hablob->fw->data[FW_SIZE_OFFSET]);
1751}
1752
1753static u8 *
1754qla82xx_get_fw_offs(struct qla_hw_data *ha)
1755{
1756 u32 offset = IMAGE_START;
1757 struct qla82xx_uri_data_desc *uri_desc = NULL;
1758
1759 if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
1760 uri_desc = qla82xx_get_data_desc(ha, QLA82XX_URI_DIR_SECT_FW,
1761 QLA82XX_URI_FIRMWARE_IDX_OFF);
1762 if (uri_desc)
1763 offset = cpu_to_le32(uri_desc->findex);
1764 }
1765
1766 return (u8 *)&ha->hablob->fw->data[offset];
1767}
1768
1680/* PCI related functions */ 1769/* PCI related functions */
1681char * 1770char *
1682qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str) 1771qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str)
@@ -1878,19 +1967,19 @@ int qla82xx_fw_load_from_blob(struct qla_hw_data *ha)
1878 1967
1879 size = (IMAGE_START - BOOTLD_START) / 8; 1968 size = (IMAGE_START - BOOTLD_START) / 8;
1880 1969
1881 ptr64 = (u64 *)&ha->hablob->fw->data[BOOTLD_START]; 1970 ptr64 = (u64 *)qla82xx_get_bootld_offset(ha);
1882 flashaddr = BOOTLD_START; 1971 flashaddr = BOOTLD_START;
1883 1972
1884 for (i = 0; i < size; i++) { 1973 for (i = 0; i < size; i++) {
1885 data = cpu_to_le64(ptr64[i]); 1974 data = cpu_to_le64(ptr64[i]);
1886 qla82xx_pci_mem_write_2M(ha, flashaddr, &data, 8); 1975 if (qla82xx_pci_mem_write_2M(ha, flashaddr, &data, 8))
1976 return -EIO;
1887 flashaddr += 8; 1977 flashaddr += 8;
1888 } 1978 }
1889 1979
1890 size = *(u32 *)&ha->hablob->fw->data[FW_SIZE_OFFSET];
1891 size = (__force u32)cpu_to_le32(size) / 8;
1892 ptr64 = (u64 *)&ha->hablob->fw->data[IMAGE_START];
1893 flashaddr = FLASH_ADDR_START; 1980 flashaddr = FLASH_ADDR_START;
1981 size = (__force u32)qla82xx_get_fw_size(ha) / 8;
1982 ptr64 = (u64 *)qla82xx_get_fw_offs(ha);
1894 1983
1895 for (i = 0; i < size; i++) { 1984 for (i = 0; i < size; i++) {
1896 data = cpu_to_le64(ptr64[i]); 1985 data = cpu_to_le64(ptr64[i]);
@@ -1899,19 +1988,88 @@ int qla82xx_fw_load_from_blob(struct qla_hw_data *ha)
1899 return -EIO; 1988 return -EIO;
1900 flashaddr += 8; 1989 flashaddr += 8;
1901 } 1990 }
1991 udelay(100);
1902 1992
1903 /* Write a magic value to CAMRAM register 1993 /* Write a magic value to CAMRAM register
1904 * at a specified offset to indicate 1994 * at a specified offset to indicate
1905 * that all data is written and 1995 * that all data is written and
1906 * ready for firmware to initialize. 1996 * ready for firmware to initialize.
1907 */ 1997 */
1908 qla82xx_wr_32(ha, QLA82XX_CAM_RAM(0x1fc), 0x12345678); 1998 qla82xx_wr_32(ha, QLA82XX_CAM_RAM(0x1fc), QLA82XX_BDINFO_MAGIC);
1909 1999
2000 read_lock(&ha->hw_lock);
1910 if (QLA82XX_IS_REVISION_P3PLUS(ha->chip_revision)) { 2001 if (QLA82XX_IS_REVISION_P3PLUS(ha->chip_revision)) {
1911 qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020); 2002 qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);
1912 qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e); 2003 qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
1913 } else 2004 } else
1914 qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001d); 2005 qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001d);
2006 read_unlock(&ha->hw_lock);
2007 return 0;
2008}
2009
2010static int
2011qla82xx_set_product_offset(struct qla_hw_data *ha)
2012{
2013 struct qla82xx_uri_table_desc *ptab_desc = NULL;
2014 const uint8_t *unirom = ha->hablob->fw->data;
2015 uint32_t i;
2016 __le32 entries;
2017 __le32 flags, file_chiprev, offset;
2018 uint8_t chiprev = ha->chip_revision;
2019 /* Hardcoding mn_present flag for P3P */
2020 int mn_present = 0;
2021 uint32_t flagbit;
2022
2023 ptab_desc = qla82xx_get_table_desc(unirom,
2024 QLA82XX_URI_DIR_SECT_PRODUCT_TBL);
2025 if (!ptab_desc)
2026 return -1;
2027
2028 entries = cpu_to_le32(ptab_desc->num_entries);
2029
2030 for (i = 0; i < entries; i++) {
2031 offset = cpu_to_le32(ptab_desc->findex) +
2032 (i * cpu_to_le32(ptab_desc->entry_size));
2033 flags = cpu_to_le32(*((int *)&unirom[offset] +
2034 QLA82XX_URI_FLAGS_OFF));
2035 file_chiprev = cpu_to_le32(*((int *)&unirom[offset] +
2036 QLA82XX_URI_CHIP_REV_OFF));
2037
2038 flagbit = mn_present ? 1 : 2;
2039
2040 if ((chiprev == file_chiprev) && ((1ULL << flagbit) & flags)) {
2041 ha->file_prd_off = offset;
2042 return 0;
2043 }
2044 }
2045 return -1;
2046}
2047
2048int
2049qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type)
2050{
2051 __le32 val;
2052 uint32_t min_size;
2053 struct qla_hw_data *ha = vha->hw;
2054 const struct firmware *fw = ha->hablob->fw;
2055
2056 ha->fw_type = fw_type;
2057
2058 if (fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
2059 if (qla82xx_set_product_offset(ha))
2060 return -EINVAL;
2061
2062 min_size = QLA82XX_URI_FW_MIN_SIZE;
2063 } else {
2064 val = cpu_to_le32(*(u32 *)&fw->data[QLA82XX_FW_MAGIC_OFFSET]);
2065 if ((__force u32)val != QLA82XX_BDINFO_MAGIC)
2066 return -EINVAL;
2067
2068 min_size = QLA82XX_FW_MIN_SIZE;
2069 }
2070
2071 if (fw->size < min_size)
2072 return -EINVAL;
1915 return 0; 2073 return 0;
1916} 2074}
1917 2075
@@ -2470,6 +2628,18 @@ try_blob_fw:
2470 goto fw_load_failed; 2628 goto fw_load_failed;
2471 } 2629 }
2472 2630
2631 /* Validating firmware blob */
2632 if (qla82xx_validate_firmware_blob(vha,
2633 QLA82XX_FLASH_ROMIMAGE)) {
2634 /* Fallback to URI format */
2635 if (qla82xx_validate_firmware_blob(vha,
2636 QLA82XX_UNIFIED_ROMIMAGE)) {
2637 qla_printk(KERN_ERR, ha,
2638 "No valid firmware image found!!!");
2639 return QLA_FUNCTION_FAILED;
2640 }
2641 }
2642
2473 if (qla82xx_fw_load_from_blob(ha) == QLA_SUCCESS) { 2643 if (qla82xx_fw_load_from_blob(ha) == QLA_SUCCESS) {
2474 qla_printk(KERN_ERR, ha, 2644 qla_printk(KERN_ERR, ha,
2475 "%s: Firmware loaded successfully " 2645 "%s: Firmware loaded successfully "
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index aa95d3816d6c..9a9127efadaf 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -773,13 +773,48 @@ struct qla82xx_legacy_intr_set {
773 .pci_int_reg = ISR_MSI_INT_TRIGGER(7) }, \ 773 .pci_int_reg = ISR_MSI_INT_TRIGGER(7) }, \
774} 774}
775 775
776#define BRDCFG_START 0x4000
776#define BOOTLD_START 0x10000 777#define BOOTLD_START 0x10000
777#define IMAGE_START 0x100000 778#define IMAGE_START 0x100000
778#define FLASH_ADDR_START 0x43000 779#define FLASH_ADDR_START 0x43000
779 780
780/* Magic number to let user know flash is programmed */ 781/* Magic number to let user know flash is programmed */
781#define QLA82XX_BDINFO_MAGIC 0x12345678 782#define QLA82XX_BDINFO_MAGIC 0x12345678
783#define QLA82XX_FW_MAGIC_OFFSET (BRDCFG_START + 0x128)
782#define FW_SIZE_OFFSET (0x3e840c) 784#define FW_SIZE_OFFSET (0x3e840c)
785#define QLA82XX_FW_MIN_SIZE 0x3fffff
786
787/* UNIFIED ROMIMAGE START */
788#define QLA82XX_URI_FW_MIN_SIZE 0xc8000
789#define QLA82XX_URI_DIR_SECT_PRODUCT_TBL 0x0
790#define QLA82XX_URI_DIR_SECT_BOOTLD 0x6
791#define QLA82XX_URI_DIR_SECT_FW 0x7
792
793/* Offsets */
794#define QLA82XX_URI_CHIP_REV_OFF 10
795#define QLA82XX_URI_FLAGS_OFF 11
796#define QLA82XX_URI_BIOS_VERSION_OFF 12
797#define QLA82XX_URI_BOOTLD_IDX_OFF 27
798#define QLA82XX_URI_FIRMWARE_IDX_OFF 29
799
800struct qla82xx_uri_table_desc{
801 uint32_t findex;
802 uint32_t num_entries;
803 uint32_t entry_size;
804 uint32_t reserved[5];
805};
806
807struct qla82xx_uri_data_desc{
808 uint32_t findex;
809 uint32_t size;
810 uint32_t reserved[5];
811};
812
813/* UNIFIED ROMIMAGE END */
814
815#define QLA82XX_UNIFIED_ROMIMAGE 3
816#define QLA82XX_FLASH_ROMIMAGE 4
817#define QLA82XX_UNKNOWN_ROMIMAGE 0xff
783 818
784#define QLA82XX_IS_REVISION_P3PLUS(_rev_) ((_rev_) >= 0x50) 819#define QLA82XX_IS_REVISION_P3PLUS(_rev_) ((_rev_) >= 0x50)
785#define MIU_TEST_AGT_WRDATA_UPPER_LO (0x0b0) 820#define MIU_TEST_AGT_WRDATA_UPPER_LO (0x0b0)