be2net: Bug fix to avoid disabling bottom half during firmware upgrade.
authorSarveshwar Bandi <sarveshwarb@serverengines.com>
Tue, 25 May 2010 23:16:32 +0000 (16:16 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 25 May 2010 23:16:32 +0000 (16:16 -0700)
Certain firmware commands/operations to upgrade firmware could take several
seconds to complete. The code presently disables bottom half during these
operations which could lead to unpredictable behaviour in certain cases. This
patch now does all firmware upgrade operations asynchronously using a
completion variable.

Signed-off-by: Sarveshwar Bandi <sarveshwarb@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/benet/be.h
drivers/net/benet/be_cmds.c
drivers/net/benet/be_main.c

index 373c1a563474d9540c43ae315bcab0185b813ddd..b46be490cd2aab76bf5cf84a496d18632b10cb59 100644 (file)
@@ -283,6 +283,8 @@ struct be_adapter {
        u8 port_type;
        u8 transceiver;
        u8 generation;          /* BladeEngine ASIC generation */
+       u32 flash_status;
+       struct completion flash_compl;
 
        bool sriov_enabled;
        u32 vf_if_handle[BE_MAX_VF];
index e79bf8b9af3bc5e0a3034d9b3c9ab7d6f9dfef39..c911bfb55b1955238565620377906ea42e84b0ce 100644 (file)
@@ -59,6 +59,13 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
 
        compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
                                CQE_STATUS_COMPL_MASK;
+
+       if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) &&
+               (compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
+               adapter->flash_status = compl_status;
+               complete(&adapter->flash_compl);
+       }
+
        if (compl_status == MCC_STATUS_SUCCESS) {
                if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
                        struct be_cmd_resp_get_stats *resp =
@@ -1417,6 +1424,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
        int status;
 
        spin_lock_bh(&adapter->mcc_lock);
+       adapter->flash_status = 0;
 
        wrb = wrb_from_mccq(adapter);
        if (!wrb) {
@@ -1428,6 +1436,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
 
        be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
                        OPCODE_COMMON_WRITE_FLASHROM);
+       wrb->tag1 = CMD_SUBSYSTEM_COMMON;
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
@@ -1439,10 +1448,16 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
        req->params.op_code = cpu_to_le32(flash_opcode);
        req->params.data_buf_size = cpu_to_le32(buf_size);
 
-       status = be_mcc_notify_wait(adapter);
+       be_mcc_notify(adapter);
+       spin_unlock_bh(&adapter->mcc_lock);
+
+       if (!wait_for_completion_timeout(&adapter->flash_compl,
+                       msecs_to_jiffies(12000)))
+               status = -1;
+       else
+               status = adapter->flash_status;
 
 err:
-       spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
 
index 1c79c2009e40cf35e92167ab84df1bbd1d8ea2c6..aa065c71ddd8647655fd992d635e48c1cf45c749 100644 (file)
@@ -2319,6 +2319,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
        spin_lock_init(&adapter->mcc_lock);
        spin_lock_init(&adapter->mcc_cq_lock);
 
+       init_completion(&adapter->flash_compl);
        pci_save_state(adapter->pdev);
        return 0;