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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
u8 port_type;
u8 transceiver;
u8 generation; /* BladeEngine ASIC generation */
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];
bool sriov_enabled;
u32 vf_if_handle[BE_MAX_VF];
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
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 =
if (compl_status == MCC_STATUS_SUCCESS) {
if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
struct be_cmd_resp_get_stats *resp =
int status;
spin_lock_bh(&adapter->mcc_lock);
int status;
spin_lock_bh(&adapter->mcc_lock);
+ adapter->flash_status = 0;
wrb = wrb_from_mccq(adapter);
if (!wrb) {
wrb = wrb_from_mccq(adapter);
if (!wrb) {
be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
OPCODE_COMMON_WRITE_FLASHROM);
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);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
req->params.op_code = cpu_to_le32(flash_opcode);
req->params.data_buf_size = cpu_to_le32(buf_size);
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;
- spin_unlock_bh(&adapter->mcc_lock);
spin_lock_init(&adapter->mcc_lock);
spin_lock_init(&adapter->mcc_cq_lock);
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;
pci_save_state(adapter->pdev);
return 0;