Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxgb4: Fix FW flash logic using ethtool

Use t4_fw_upgrade instead of t4_load_fw to write firmware into FLASH, since
t4_load_fw doesn't co-ordinate with the firmware and the adapter can get hosed
enough to require a power cycle of the system.

Based on original work by Casey Leedom <leedom@chelsio.com>

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Hariprasad Shenai and committed by
David S. Miller
22c0b963 6e36145d

+16 -6
+2
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
··· 986 986 int t4_seeprom_wp(struct adapter *adapter, bool enable); 987 987 int get_vpd_params(struct adapter *adapter, struct vpd_params *p); 988 988 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); 989 + int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, 990 + const u8 *fw_data, unsigned int size, int force); 989 991 unsigned int t4_flash_cfg_addr(struct adapter *adapter); 990 992 int t4_get_fw_version(struct adapter *adapter, u32 *vers); 991 993 int t4_get_tp_version(struct adapter *adapter, u32 *vers);
+12 -2
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
··· 2929 2929 int ret; 2930 2930 const struct firmware *fw; 2931 2931 struct adapter *adap = netdev2adap(netdev); 2932 + unsigned int mbox = FW_PCIE_FW_MASTER_MASK + 1; 2932 2933 2933 2934 ef->data[sizeof(ef->data) - 1] = '\0'; 2934 2935 ret = request_firmware(&fw, ef->data, adap->pdev_dev); 2935 2936 if (ret < 0) 2936 2937 return ret; 2937 2938 2938 - ret = t4_load_fw(adap, fw->data, fw->size); 2939 + /* If the adapter has been fully initialized then we'll go ahead and 2940 + * try to get the firmware's cooperation in upgrading to the new 2941 + * firmware image otherwise we'll try to do the entire job from the 2942 + * host ... and we always "force" the operation in this path. 2943 + */ 2944 + if (adap->flags & FULL_INIT_DONE) 2945 + mbox = adap->mbox; 2946 + 2947 + ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1); 2939 2948 release_firmware(fw); 2940 2949 if (!ret) 2941 - dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data); 2950 + dev_info(adap->pdev_dev, "loaded firmware %s," 2951 + " reload cxgb4 driver\n", ef->data); 2942 2952 return ret; 2943 2953 } 2944 2954
+2 -4
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
··· 37 37 #include "t4_regs.h" 38 38 #include "t4fw_api.h" 39 39 40 - static int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, 41 - const u8 *fw_data, unsigned int size, int force); 42 40 /** 43 41 * t4_wait_op_done_val - wait until an operation is completed 44 42 * @adapter: the adapter performing the operation ··· 3074 3076 * positive errno indicates that the adapter is ~probably~ intact, a 3075 3077 * negative errno indicates that things are looking bad ... 3076 3078 */ 3077 - static int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, 3078 - const u8 *fw_data, unsigned int size, int force) 3079 + int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, 3080 + const u8 *fw_data, unsigned int size, int force) 3079 3081 { 3080 3082 const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data; 3081 3083 int reset, ret;