aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2014-11-20 07:36:26 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-12-01 05:04:41 -0500
commit804d4c5a811c616a111938bd04b41df83a753c74 (patch)
tree3cc8bd2f96efa0e74f8e15826bcc78918384c7c7
parent160acc0e8da09f6fb9d8181484729c4718e52330 (diff)
iwlwifi: pcie: refactor cmd_in_flight set/clear code
A following patche will use trans_pcie->cmd_in_flight for reference accounting as well. get ready for it. Signed-off-by: Eliad Peller <eliadx.peller@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c102
1 files changed, 66 insertions, 36 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 4a4104eda9b8..8a6c7a084aa1 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -989,6 +989,65 @@ out:
989 spin_unlock_bh(&txq->lock); 989 spin_unlock_bh(&txq->lock);
990} 990}
991 991
992static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans)
993{
994 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
995 int ret;
996
997 lockdep_assert_held(&trans_pcie->reg_lock);
998
999 if (trans_pcie->cmd_in_flight)
1000 return 0;
1001
1002 trans_pcie->cmd_in_flight = true;
1003
1004 /*
1005 * wake up the NIC to make sure that the firmware will see the host
1006 * command - we will let the NIC sleep once all the host commands
1007 * returned. This needs to be done only on NICs that have
1008 * apmg_wake_up_wa set.
1009 */
1010 if (trans->cfg->base_params->apmg_wake_up_wa) {
1011 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1012 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1013 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
1014 udelay(2);
1015
1016 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1017 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1018 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1019 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1020 15000);
1021 if (ret < 0) {
1022 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1023 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1024 trans_pcie->cmd_in_flight = false;
1025 IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1026 return -EIO;
1027 }
1028 }
1029
1030 return 0;
1031}
1032
1033static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
1034{
1035 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1036
1037 lockdep_assert_held(&trans_pcie->reg_lock);
1038
1039 if (WARN_ON(!trans_pcie->cmd_in_flight))
1040 return 0;
1041
1042 trans_pcie->cmd_in_flight = false;
1043
1044 if (trans->cfg->base_params->apmg_wake_up_wa)
1045 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1046 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1047
1048 return 0;
1049}
1050
992/* 1051/*
993 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd 1052 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
994 * 1053 *
@@ -1024,14 +1083,9 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1024 } 1083 }
1025 } 1084 }
1026 1085
1027 if (trans->cfg->base_params->apmg_wake_up_wa && 1086 if (q->read_ptr == q->write_ptr) {
1028 q->read_ptr == q->write_ptr) {
1029 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1087 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1030 WARN_ON(!trans_pcie->cmd_in_flight); 1088 iwl_pcie_clear_cmd_in_flight(trans);
1031 trans_pcie->cmd_in_flight = false;
1032 __iwl_trans_pcie_clear_bit(trans,
1033 CSR_GP_CNTRL,
1034 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1035 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1089 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1036 } 1090 }
1037 1091
@@ -1419,35 +1473,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1419 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1473 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1420 1474
1421 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1475 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1422 1476 ret = iwl_pcie_set_cmd_in_flight(trans);
1423 /* 1477 if (ret < 0) {
1424 * wake up the NIC to make sure that the firmware will see the host 1478 idx = ret;
1425 * command - we will let the NIC sleep once all the host commands 1479 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1426 * returned. This needs to be done only on NICs that have 1480 goto out;
1427 * apmg_wake_up_wa set.
1428 */
1429 if (trans->cfg->base_params->apmg_wake_up_wa &&
1430 !trans_pcie->cmd_in_flight) {
1431 trans_pcie->cmd_in_flight = true;
1432 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1433 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1434 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
1435 udelay(2);
1436
1437 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1438 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1439 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1440 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1441 15000);
1442 if (ret < 0) {
1443 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1444 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1445 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1446 trans_pcie->cmd_in_flight = false;
1447 IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1448 idx = -EIO;
1449 goto out;
1450 }
1451 } 1481 }
1452 1482
1453 /* Increment and update queue's write index */ 1483 /* Increment and update queue's write index */