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>

authored by Sarveshwar Bandi and committed by David S. Miller dd131e76 563b0467

+20 -2
+2
drivers/net/benet/be.h
··· 283 u8 port_type; 284 u8 transceiver; 285 u8 generation; /* BladeEngine ASIC generation */ 286 287 bool sriov_enabled; 288 u32 vf_if_handle[BE_MAX_VF];
··· 283 u8 port_type; 284 u8 transceiver; 285 u8 generation; /* BladeEngine ASIC generation */ 286 + u32 flash_status; 287 + struct completion flash_compl; 288 289 bool sriov_enabled; 290 u32 vf_if_handle[BE_MAX_VF];
+17 -2
drivers/net/benet/be_cmds.c
··· 59 60 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & 61 CQE_STATUS_COMPL_MASK; 62 if (compl_status == MCC_STATUS_SUCCESS) { 63 if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { 64 struct be_cmd_resp_get_stats *resp = ··· 1424 int status; 1425 1426 spin_lock_bh(&adapter->mcc_lock); 1427 1428 wrb = wrb_from_mccq(adapter); 1429 if (!wrb) { ··· 1436 1437 be_wrb_hdr_prepare(wrb, cmd->size, false, 1, 1438 OPCODE_COMMON_WRITE_FLASHROM); 1439 1440 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 1441 OPCODE_COMMON_WRITE_FLASHROM, cmd->size); ··· 1448 req->params.op_code = cpu_to_le32(flash_opcode); 1449 req->params.data_buf_size = cpu_to_le32(buf_size); 1450 1451 - status = be_mcc_notify_wait(adapter); 1452 1453 err: 1454 - spin_unlock_bh(&adapter->mcc_lock); 1455 return status; 1456 } 1457
··· 59 60 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & 61 CQE_STATUS_COMPL_MASK; 62 + 63 + if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) && 64 + (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { 65 + adapter->flash_status = compl_status; 66 + complete(&adapter->flash_compl); 67 + } 68 + 69 if (compl_status == MCC_STATUS_SUCCESS) { 70 if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { 71 struct be_cmd_resp_get_stats *resp = ··· 1417 int status; 1418 1419 spin_lock_bh(&adapter->mcc_lock); 1420 + adapter->flash_status = 0; 1421 1422 wrb = wrb_from_mccq(adapter); 1423 if (!wrb) { ··· 1428 1429 be_wrb_hdr_prepare(wrb, cmd->size, false, 1, 1430 OPCODE_COMMON_WRITE_FLASHROM); 1431 + wrb->tag1 = CMD_SUBSYSTEM_COMMON; 1432 1433 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 1434 OPCODE_COMMON_WRITE_FLASHROM, cmd->size); ··· 1439 req->params.op_code = cpu_to_le32(flash_opcode); 1440 req->params.data_buf_size = cpu_to_le32(buf_size); 1441 1442 + be_mcc_notify(adapter); 1443 + spin_unlock_bh(&adapter->mcc_lock); 1444 + 1445 + if (!wait_for_completion_timeout(&adapter->flash_compl, 1446 + msecs_to_jiffies(12000))) 1447 + status = -1; 1448 + else 1449 + status = adapter->flash_status; 1450 1451 err: 1452 return status; 1453 } 1454
+1
drivers/net/benet/be_main.c
··· 2319 spin_lock_init(&adapter->mcc_lock); 2320 spin_lock_init(&adapter->mcc_cq_lock); 2321 2322 pci_save_state(adapter->pdev); 2323 return 0; 2324
··· 2319 spin_lock_init(&adapter->mcc_lock); 2320 spin_lock_init(&adapter->mcc_cq_lock); 2321 2322 + init_completion(&adapter->flash_compl); 2323 pci_save_state(adapter->pdev); 2324 return 0; 2325