cxgb4: Fix FW flash logic using ethtool
authorHariprasad Shenai <hariprasad@chelsio.com>
Tue, 14 Oct 2014 20:24:14 +0000 (01:54 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 14 Oct 2014 20:55:06 +0000 (16:55 -0400)
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>
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c

index 410ed5805a9a8c46ff23cc0df05a20e3729b3c39..3c481b2607458ad453a975f2842fcce40476c720 100644 (file)
@@ -986,6 +986,8 @@ static inline int t4_memory_write(struct adapter *adap, int mtype, u32 addr,
 int t4_seeprom_wp(struct adapter *adapter, bool enable);
 int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
+int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
+                 const u8 *fw_data, unsigned int size, int force);
 unsigned int t4_flash_cfg_addr(struct adapter *adapter);
 int t4_get_fw_version(struct adapter *adapter, u32 *vers);
 int t4_get_tp_version(struct adapter *adapter, u32 *vers);
index 5b38e955af6ec39b804b333cbbfd9bdf3817db4f..fed8f26ee67bd0e15d171a6f2f2fb7509fb0f039 100644 (file)
@@ -2929,16 +2929,26 @@ static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
        int ret;
        const struct firmware *fw;
        struct adapter *adap = netdev2adap(netdev);
+       unsigned int mbox = FW_PCIE_FW_MASTER_MASK + 1;
 
        ef->data[sizeof(ef->data) - 1] = '\0';
        ret = request_firmware(&fw, ef->data, adap->pdev_dev);
        if (ret < 0)
                return ret;
 
-       ret = t4_load_fw(adap, fw->data, fw->size);
+       /* If the adapter has been fully initialized then we'll go ahead and
+        * try to get the firmware's cooperation in upgrading to the new
+        * firmware image otherwise we'll try to do the entire job from the
+        * host ... and we always "force" the operation in this path.
+        */
+       if (adap->flags & FULL_INIT_DONE)
+               mbox = adap->mbox;
+
+       ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1);
        release_firmware(fw);
        if (!ret)
-               dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data);
+               dev_info(adap->pdev_dev, "loaded firmware %s,"
+                        " reload cxgb4 driver\n", ef->data);
        return ret;
 }
 
index 1fff1495fe31561187e325dedc741a9367cf8c81..a9d9d74e4f092f969c2d58eaf01455b7bca7e257 100644 (file)
@@ -37,8 +37,6 @@
 #include "t4_regs.h"
 #include "t4fw_api.h"
 
-static int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
-                        const u8 *fw_data, unsigned int size, int force);
 /**
  *     t4_wait_op_done_val - wait until an operation is completed
  *     @adapter: the adapter performing the operation
@@ -3076,8 +3074,8 @@ static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset)
  *     positive errno indicates that the adapter is ~probably~ intact, a
  *     negative errno indicates that things are looking bad ...
  */
-static int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
-                        const u8 *fw_data, unsigned int size, int force)
+int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
+                 const u8 *fw_data, unsigned int size, int force)
 {
        const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data;
        int reset, ret;