aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPraveen Madhavan <praveenm@chelsio.com>2015-01-07 08:46:28 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-08 23:11:35 -0500
commitf40e74ffa3de44f7ef4c09653b070dd115ab7fbe (patch)
tree91504fbb931ed85ab919975616f3983e47d28b7c
parent3552c319493c5a4ccfd6b767a3878e472aa27984 (diff)
csiostor:firmware upgrade fix
This patch fixes removes older means of upgrading Firmware using MAJOR version and adds newer interface version checking mechanism. Please apply this patch on net-next since it depends on previous commits. Signed-off-by: Praveen Madhavan <praveenm@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/scsi/csiostor/csio_hw.c277
-rw-r--r--drivers/scsi/csiostor/csio_hw.h5
-rw-r--r--drivers/scsi/csiostor/csio_hw_chip.h47
3 files changed, 247 insertions, 82 deletions
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index 660283528ada..b70c15fb1e97 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -682,43 +682,6 @@ csio_hw_get_tp_version(struct csio_hw *hw, u32 *vers)
682} 682}
683 683
684/* 684/*
685 * csio_hw_check_fw_version - check if the FW is compatible with
686 * this driver
687 * @hw: HW module
688 *
689 * Checks if an adapter's FW is compatible with the driver. Returns 0
690 * if there's exact match, a negative error if the version could not be
691 * read or there's a major/minor version mismatch/minor.
692 */
693static int
694csio_hw_check_fw_version(struct csio_hw *hw)
695{
696 int ret, major, minor, micro;
697
698 ret = csio_hw_get_fw_version(hw, &hw->fwrev);
699 if (!ret)
700 ret = csio_hw_get_tp_version(hw, &hw->tp_vers);
701 if (ret)
702 return ret;
703
704 major = FW_HDR_FW_VER_MAJOR_G(hw->fwrev);
705 minor = FW_HDR_FW_VER_MINOR_G(hw->fwrev);
706 micro = FW_HDR_FW_VER_MICRO_G(hw->fwrev);
707
708 if (major != FW_VERSION_MAJOR(hw)) { /* major mismatch - fail */
709 csio_err(hw, "card FW has major version %u, driver wants %u\n",
710 major, FW_VERSION_MAJOR(hw));
711 return -EINVAL;
712 }
713
714 if (minor == FW_VERSION_MINOR(hw) && micro == FW_VERSION_MICRO(hw))
715 return 0; /* perfect match */
716
717 /* Minor/micro version mismatch */
718 return -EINVAL;
719}
720
721/*
722 * csio_hw_fw_dload - download firmware. 685 * csio_hw_fw_dload - download firmware.
723 * @hw: HW module 686 * @hw: HW module
724 * @fw_data: firmware image to write. 687 * @fw_data: firmware image to write.
@@ -1967,6 +1930,170 @@ out:
1967 return rv; 1930 return rv;
1968} 1931}
1969 1932
1933/* Is the given firmware API compatible with the one the driver was compiled
1934 * with?
1935 */
1936static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2)
1937{
1938
1939 /* short circuit if it's the exact same firmware version */
1940 if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver)
1941 return 1;
1942
1943#define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x)
1944 if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) &&
1945 SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe))
1946 return 1;
1947#undef SAME_INTF
1948
1949 return 0;
1950}
1951
1952/* The firmware in the filesystem is usable, but should it be installed?
1953 * This routine explains itself in detail if it indicates the filesystem
1954 * firmware should be installed.
1955 */
1956static int csio_should_install_fs_fw(struct csio_hw *hw, int card_fw_usable,
1957 int k, int c)
1958{
1959 const char *reason;
1960
1961 if (!card_fw_usable) {
1962 reason = "incompatible or unusable";
1963 goto install;
1964 }
1965
1966 if (k > c) {
1967 reason = "older than the version supported with this driver";
1968 goto install;
1969 }
1970
1971 return 0;
1972
1973install:
1974 csio_err(hw, "firmware on card (%u.%u.%u.%u) is %s, "
1975 "installing firmware %u.%u.%u.%u on card.\n",
1976 FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
1977 FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), reason,
1978 FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
1979 FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
1980
1981 return 1;
1982}
1983
1984static struct fw_info fw_info_array[] = {
1985 {
1986 .chip = CHELSIO_T5,
1987 .fs_name = FW_CFG_NAME_T5,
1988 .fw_mod_name = FW_FNAME_T5,
1989 .fw_hdr = {
1990 .chip = FW_HDR_CHIP_T5,
1991 .fw_ver = __cpu_to_be32(FW_VERSION(T5)),
1992 .intfver_nic = FW_INTFVER(T5, NIC),
1993 .intfver_vnic = FW_INTFVER(T5, VNIC),
1994 .intfver_ri = FW_INTFVER(T5, RI),
1995 .intfver_iscsi = FW_INTFVER(T5, ISCSI),
1996 .intfver_fcoe = FW_INTFVER(T5, FCOE),
1997 },
1998 }
1999};
2000
2001static struct fw_info *find_fw_info(int chip)
2002{
2003 int i;
2004
2005 for (i = 0; i < ARRAY_SIZE(fw_info_array); i++) {
2006 if (fw_info_array[i].chip == chip)
2007 return &fw_info_array[i];
2008 }
2009 return NULL;
2010}
2011
2012int csio_hw_prep_fw(struct csio_hw *hw, struct fw_info *fw_info,
2013 const u8 *fw_data, unsigned int fw_size,
2014 struct fw_hdr *card_fw, enum csio_dev_state state,
2015 int *reset)
2016{
2017 int ret, card_fw_usable, fs_fw_usable;
2018 const struct fw_hdr *fs_fw;
2019 const struct fw_hdr *drv_fw;
2020
2021 drv_fw = &fw_info->fw_hdr;
2022
2023 /* Read the header of the firmware on the card */
2024 ret = csio_hw_read_flash(hw, FLASH_FW_START,
2025 sizeof(*card_fw) / sizeof(uint32_t),
2026 (uint32_t *)card_fw, 1);
2027 if (ret == 0) {
2028 card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw);
2029 } else {
2030 csio_err(hw,
2031 "Unable to read card's firmware header: %d\n", ret);
2032 card_fw_usable = 0;
2033 }
2034
2035 if (fw_data != NULL) {
2036 fs_fw = (const void *)fw_data;
2037 fs_fw_usable = fw_compatible(drv_fw, fs_fw);
2038 } else {
2039 fs_fw = NULL;
2040 fs_fw_usable = 0;
2041 }
2042
2043 if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver &&
2044 (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) {
2045 /* Common case: the firmware on the card is an exact match and
2046 * the filesystem one is an exact match too, or the filesystem
2047 * one is absent/incompatible.
2048 */
2049 } else if (fs_fw_usable && state == CSIO_DEV_STATE_UNINIT &&
2050 csio_should_install_fs_fw(hw, card_fw_usable,
2051 be32_to_cpu(fs_fw->fw_ver),
2052 be32_to_cpu(card_fw->fw_ver))) {
2053 ret = csio_hw_fw_upgrade(hw, hw->pfn, fw_data,
2054 fw_size, 0);
2055 if (ret != 0) {
2056 csio_err(hw,
2057 "failed to install firmware: %d\n", ret);
2058 goto bye;
2059 }
2060
2061 /* Installed successfully, update the cached header too. */
2062 memcpy(card_fw, fs_fw, sizeof(*card_fw));
2063 card_fw_usable = 1;
2064 *reset = 0; /* already reset as part of load_fw */
2065 }
2066
2067 if (!card_fw_usable) {
2068 uint32_t d, c, k;
2069
2070 d = be32_to_cpu(drv_fw->fw_ver);
2071 c = be32_to_cpu(card_fw->fw_ver);
2072 k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0;
2073
2074 csio_err(hw, "Cannot find a usable firmware: "
2075 "chip state %d, "
2076 "driver compiled with %d.%d.%d.%d, "
2077 "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n",
2078 state,
2079 FW_HDR_FW_VER_MAJOR_G(d), FW_HDR_FW_VER_MINOR_G(d),
2080 FW_HDR_FW_VER_MICRO_G(d), FW_HDR_FW_VER_BUILD_G(d),
2081 FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
2082 FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c),
2083 FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
2084 FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
2085 ret = EINVAL;
2086 goto bye;
2087 }
2088
2089 /* We're using whatever's on the card and it's known to be good. */
2090 hw->fwrev = be32_to_cpu(card_fw->fw_ver);
2091 hw->tp_vers = be32_to_cpu(card_fw->tp_microcode_ver);
2092
2093bye:
2094 return ret;
2095}
2096
1970/* 2097/*
1971 * Returns -EINVAL if attempts to flash the firmware failed 2098 * Returns -EINVAL if attempts to flash the firmware failed
1972 * else returns 0, 2099 * else returns 0,
@@ -1974,14 +2101,27 @@ out:
1974 * latest firmware ECANCELED is returned 2101 * latest firmware ECANCELED is returned
1975 */ 2102 */
1976static int 2103static int
1977csio_hw_flash_fw(struct csio_hw *hw) 2104csio_hw_flash_fw(struct csio_hw *hw, int *reset)
1978{ 2105{
1979 int ret = -ECANCELED; 2106 int ret = -ECANCELED;
1980 const struct firmware *fw; 2107 const struct firmware *fw;
1981 const struct fw_hdr *hdr; 2108 struct fw_info *fw_info;
1982 u32 fw_ver; 2109 struct fw_hdr *card_fw;
1983 struct pci_dev *pci_dev = hw->pdev; 2110 struct pci_dev *pci_dev = hw->pdev;
1984 struct device *dev = &pci_dev->dev ; 2111 struct device *dev = &pci_dev->dev ;
2112 const u8 *fw_data = NULL;
2113 unsigned int fw_size = 0;
2114
2115 /* This is the firmware whose headers the driver was compiled
2116 * against
2117 */
2118 fw_info = find_fw_info(CHELSIO_CHIP_VERSION(hw->chip_id));
2119 if (fw_info == NULL) {
2120 csio_err(hw,
2121 "unable to get firmware info for chip %d.\n",
2122 CHELSIO_CHIP_VERSION(hw->chip_id));
2123 return -EINVAL;
2124 }
1985 2125
1986 if (request_firmware(&fw, CSIO_FW_FNAME(hw), dev) < 0) { 2126 if (request_firmware(&fw, CSIO_FW_FNAME(hw), dev) < 0) {
1987 csio_err(hw, "could not find firmware image %s, err: %d\n", 2127 csio_err(hw, "could not find firmware image %s, err: %d\n",
@@ -1989,33 +2129,25 @@ csio_hw_flash_fw(struct csio_hw *hw)
1989 return -EINVAL; 2129 return -EINVAL;
1990 } 2130 }
1991 2131
1992 hdr = (const struct fw_hdr *)fw->data; 2132 /* allocate memory to read the header of the firmware on the
1993 fw_ver = ntohl(hdr->fw_ver); 2133 * card
1994 if (FW_HDR_FW_VER_MAJOR_G(fw_ver) != FW_VERSION_MAJOR(hw))
1995 return -EINVAL; /* wrong major version, won't do */
1996
1997 /*
1998 * If the flash FW is unusable or we found something newer, load it.
1999 */ 2134 */
2000 if (FW_HDR_FW_VER_MAJOR_G(hw->fwrev) != FW_VERSION_MAJOR(hw) || 2135 card_fw = kmalloc(sizeof(*card_fw), GFP_KERNEL);
2001 fw_ver > hw->fwrev) {
2002 ret = csio_hw_fw_upgrade(hw, hw->pfn, fw->data, fw->size,
2003 /*force=*/false);
2004 if (!ret)
2005 csio_info(hw,
2006 "firmware upgraded to version %pI4 from %s\n",
2007 &hdr->fw_ver, CSIO_FW_FNAME(hw));
2008 else
2009 csio_err(hw, "firmware upgrade failed! err=%d\n", ret);
2010 } else
2011 ret = -EINVAL;
2012 2136
2013 release_firmware(fw); 2137 fw_data = fw->data;
2138 fw_size = fw->size;
2014 2139
2140 /* upgrade FW logic */
2141 ret = csio_hw_prep_fw(hw, fw_info, fw_data, fw_size, card_fw,
2142 hw->fw_state, reset);
2143
2144 /* Cleaning up */
2145 if (fw != NULL)
2146 release_firmware(fw);
2147 kfree(card_fw);
2015 return ret; 2148 return ret;
2016} 2149}
2017 2150
2018
2019/* 2151/*
2020 * csio_hw_configure - Configure HW 2152 * csio_hw_configure - Configure HW
2021 * @hw - HW module 2153 * @hw - HW module
@@ -2071,25 +2203,18 @@ csio_hw_configure(struct csio_hw *hw)
2071 if (rv != 0) 2203 if (rv != 0)
2072 goto out; 2204 goto out;
2073 2205
2206 csio_hw_get_fw_version(hw, &hw->fwrev);
2207 csio_hw_get_tp_version(hw, &hw->tp_vers);
2074 if (csio_is_hw_master(hw) && hw->fw_state != CSIO_DEV_STATE_INIT) { 2208 if (csio_is_hw_master(hw) && hw->fw_state != CSIO_DEV_STATE_INIT) {
2075 rv = csio_hw_check_fw_version(hw);
2076 if (rv == -EINVAL) {
2077 2209
2078 /* Do firmware update */ 2210 /* Do firmware update */
2079 spin_unlock_irq(&hw->lock); 2211 spin_unlock_irq(&hw->lock);
2080 rv = csio_hw_flash_fw(hw); 2212 rv = csio_hw_flash_fw(hw, &reset);
2081 spin_lock_irq(&hw->lock); 2213 spin_lock_irq(&hw->lock);
2214
2215 if (rv != 0)
2216 goto out;
2082 2217
2083 if (rv == 0) {
2084 reset = 0;
2085 /*
2086 * Note that the chip was reset as part of the
2087 * firmware upgrade so we don't reset it again
2088 * below and grab the new firmware version.
2089 */
2090 rv = csio_hw_check_fw_version(hw);
2091 }
2092 }
2093 /* 2218 /*
2094 * If the firmware doesn't support Configuration 2219 * If the firmware doesn't support Configuration
2095 * Files, use the old Driver-based, hard-wired 2220 * Files, use the old Driver-based, hard-wired
diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h
index bd9720467aa3..1fe8fdee70fa 100644
--- a/drivers/scsi/csiostor/csio_hw.h
+++ b/drivers/scsi/csiostor/csio_hw.h
@@ -201,9 +201,8 @@ enum {
201 SF_ERASE_SECTOR = 0xd8, /* erase sector */ 201 SF_ERASE_SECTOR = 0xd8, /* erase sector */
202 202
203 FW_START_SEC = 8, /* first flash sector for FW */ 203 FW_START_SEC = 8, /* first flash sector for FW */
204 FW_END_SEC = 15, /* last flash sector for FW */
205 FW_IMG_START = FW_START_SEC * SF_SEC_SIZE, 204 FW_IMG_START = FW_START_SEC * SF_SEC_SIZE,
206 FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE, 205 FW_MAX_SIZE = 16 * SF_SEC_SIZE,
207 206
208 FLASH_CFG_MAX_SIZE = 0x10000 , /* max size of the flash config file*/ 207 FLASH_CFG_MAX_SIZE = 0x10000 , /* max size of the flash config file*/
209 FLASH_CFG_OFFSET = 0x1f0000, 208 FLASH_CFG_OFFSET = 0x1f0000,
@@ -221,7 +220,7 @@ enum {
221 * Location of firmware image in FLASH. 220 * Location of firmware image in FLASH.
222 */ 221 */
223 FLASH_FW_START_SEC = 8, 222 FLASH_FW_START_SEC = 8,
224 FLASH_FW_NSECS = 8, 223 FLASH_FW_NSECS = 16,
225 FLASH_FW_START = FLASH_START(FLASH_FW_START_SEC), 224 FLASH_FW_START = FLASH_START(FLASH_FW_START_SEC),
226 FLASH_FW_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FW_NSECS), 225 FLASH_FW_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FW_NSECS),
227 226
diff --git a/drivers/scsi/csiostor/csio_hw_chip.h b/drivers/scsi/csiostor/csio_hw_chip.h
index 70c0bdd7c796..eec98f523ec9 100644
--- a/drivers/scsi/csiostor/csio_hw_chip.h
+++ b/drivers/scsi/csiostor/csio_hw_chip.h
@@ -50,6 +50,36 @@
50#define FW_CFG_NAME_T4 "cxgb4/t4-config.txt" 50#define FW_CFG_NAME_T4 "cxgb4/t4-config.txt"
51#define FW_CFG_NAME_T5 "cxgb4/t5-config.txt" 51#define FW_CFG_NAME_T5 "cxgb4/t5-config.txt"
52 52
53#define T4FW_VERSION_MAJOR 0x01
54#define T4FW_VERSION_MINOR 0x0B
55#define T4FW_VERSION_MICRO 0x1B
56#define T4FW_VERSION_BUILD 0x00
57
58#define T5FW_VERSION_MAJOR 0x01
59#define T5FW_VERSION_MINOR 0x0B
60#define T5FW_VERSION_MICRO 0x1B
61#define T5FW_VERSION_BUILD 0x00
62
63#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
64#define CHELSIO_CHIP_FPGA 0x100
65#define CHELSIO_CHIP_VERSION(code) (((code) >> 12) & 0xf)
66#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf)
67
68#define CHELSIO_T4 0x4
69#define CHELSIO_T5 0x5
70
71enum chip_type {
72 T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
73 T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
74 T4_FIRST_REV = T4_A1,
75 T4_LAST_REV = T4_A2,
76
77 T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
78 T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1),
79 T5_FIRST_REV = T5_A0,
80 T5_LAST_REV = T5_A1,
81};
82
53/* Define static functions */ 83/* Define static functions */
54static inline int csio_is_t4(uint16_t chip) 84static inline int csio_is_t4(uint16_t chip)
55{ 85{
@@ -80,10 +110,21 @@ static inline int csio_is_t5(uint16_t chip)
80 (csio_is_t4(hw->chip_id) ? (PORT_REG(port, XGMAC_PORT_INT_CAUSE_A)) : \ 110 (csio_is_t4(hw->chip_id) ? (PORT_REG(port, XGMAC_PORT_INT_CAUSE_A)) : \
81 (T5_PORT_REG(port, MAC_PORT_INT_CAUSE_A))) 111 (T5_PORT_REG(port, MAC_PORT_INT_CAUSE_A)))
82 112
83#define FW_VERSION_MAJOR(hw) (csio_is_t4(hw->chip_id) ? 1 : 0) 113#include "t4fw_api.h"
84#define FW_VERSION_MINOR(hw) (csio_is_t4(hw->chip_id) ? 2 : 0)
85#define FW_VERSION_MICRO(hw) (csio_is_t4(hw->chip_id) ? 8 : 0)
86 114
115#define FW_VERSION(chip) ( \
116 FW_HDR_FW_VER_MAJOR_G(chip##FW_VERSION_MAJOR) | \
117 FW_HDR_FW_VER_MINOR_G(chip##FW_VERSION_MINOR) | \
118 FW_HDR_FW_VER_MICRO_G(chip##FW_VERSION_MICRO) | \
119 FW_HDR_FW_VER_BUILD_G(chip##FW_VERSION_BUILD))
120#define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf)
121
122struct fw_info {
123 u8 chip;
124 char *fs_name;
125 char *fw_mod_name;
126 struct fw_hdr fw_hdr;
127};
87#define CSIO_FW_FNAME(hw) \ 128#define CSIO_FW_FNAME(hw) \
88 (csio_is_t4(hw->chip_id) ? FW_FNAME_T4 : FW_FNAME_T5) 129 (csio_is_t4(hw->chip_id) ? FW_FNAME_T4 : FW_FNAME_T5)
89 130