aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarveshwar Bandi <sarveshwarb@serverengines.com>2010-05-25 16:16:32 -0700
committerDavid S. Miller <davem@davemloft.net>2010-05-25 16:16:32 -0700
commitdd131e76e562fa0c6f9dd53130e8d08d39a0b62c (patch)
treee53896ebd88874385459f1c60e19156f96c462d2
parentproc_dointvec: write a single value (diff)
downloadlinux-dev-dd131e76e562fa0c6f9dd53130e8d08d39a0b62c.tar.xz
linux-dev-dd131e76e562fa0c6f9dd53130e8d08d39a0b62c.zip
be2net: Bug fix to avoid disabling bottom half during firmware upgrade.
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>
-rw-r--r--drivers/net/benet/be.h2
-rw-r--r--drivers/net/benet/be_cmds.c19
-rw-r--r--drivers/net/benet/be_main.c1
3 files changed, 20 insertions, 2 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 373c1a563474..b46be490cd2a 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -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];
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index e79bf8b9af3b..c911bfb55b19 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -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;
}
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 1c79c2009e40..aa065c71ddd8 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -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;