diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 1424335163b9..80f1956b3be3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1465,7 +1465,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, | |||
1465 | spin_unlock_bh(&txq->lock); | 1465 | spin_unlock_bh(&txq->lock); |
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 1468 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
1469 | #define COMMAND_POKE_TIMEOUT (HZ / 10) | ||
1469 | 1470 | ||
1470 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, | 1471 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, |
1471 | struct iwl_host_cmd *cmd) | 1472 | struct iwl_host_cmd *cmd) |
@@ -1493,6 +1494,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1493 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1494 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1494 | int cmd_idx; | 1495 | int cmd_idx; |
1495 | int ret; | 1496 | int ret; |
1497 | int timeout = HOST_COMPLETE_TIMEOUT; | ||
1496 | 1498 | ||
1497 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 1499 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
1498 | get_cmd_string(trans_pcie, cmd->id)); | 1500 | get_cmd_string(trans_pcie, cmd->id)); |
@@ -1517,10 +1519,29 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1517 | return ret; | 1519 | return ret; |
1518 | } | 1520 | } |
1519 | 1521 | ||
1520 | ret = wait_event_timeout(trans_pcie->wait_command_queue, | 1522 | while (timeout > 0) { |
1521 | !test_bit(STATUS_HCMD_ACTIVE, | 1523 | unsigned long flags; |
1522 | &trans_pcie->status), | 1524 | |
1523 | HOST_COMPLETE_TIMEOUT); | 1525 | timeout -= COMMAND_POKE_TIMEOUT; |
1526 | ret = wait_event_timeout(trans_pcie->wait_command_queue, | ||
1527 | !test_bit(STATUS_HCMD_ACTIVE, | ||
1528 | &trans_pcie->status), | ||
1529 | COMMAND_POKE_TIMEOUT); | ||
1530 | if (ret) | ||
1531 | break; | ||
1532 | /* poke the device - it may have lost the command */ | ||
1533 | if (iwl_trans_grab_nic_access(trans, true, &flags)) { | ||
1534 | iwl_trans_release_nic_access(trans, &flags); | ||
1535 | IWL_DEBUG_INFO(trans, | ||
1536 | "Tried to wake NIC for command %s\n", | ||
1537 | get_cmd_string(trans_pcie, cmd->id)); | ||
1538 | } else { | ||
1539 | IWL_ERR(trans, "Failed to poke NIC for command %s\n", | ||
1540 | get_cmd_string(trans_pcie, cmd->id)); | ||
1541 | break; | ||
1542 | } | ||
1543 | } | ||
1544 | |||
1524 | if (!ret) { | 1545 | if (!ret) { |
1525 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 1546 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
1526 | struct iwl_txq *txq = | 1547 | struct iwl_txq *txq = |