diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-08-26 02:11:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 15:33:01 -0400 |
commit | f22be624c29b7f714e5a82ad13dc33a0cd1443a2 (patch) | |
tree | c601ad06c781e30cc2973e6c712d88278b3c7975 | |
parent | 5f178cd2ebe8ac196b245428c574f1def1964b14 (diff) |
iwlagn: move check_stuck_queue to transport layer
This one is really transport related.
==== moves Stanislaw's code to BSD area ====
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-shared.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 6 |
5 files changed, 42 insertions, 25 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5d0888a7fbc0..5fdf9b10b470 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3191,8 +3191,8 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
3191 | priv->cfg->base_params->num_of_ampdu_queues; | 3191 | priv->cfg->base_params->num_of_ampdu_queues; |
3192 | hw_params(priv).shadow_reg_enable = | 3192 | hw_params(priv).shadow_reg_enable = |
3193 | priv->cfg->base_params->shadow_reg_enable; | 3193 | priv->cfg->base_params->shadow_reg_enable; |
3194 | hw_params(priv).sku = | 3194 | hw_params(priv).sku = priv->cfg->sku; |
3195 | priv->cfg->sku; | 3195 | hw_params(priv).wd_timeout = priv->cfg->base_params->wd_timeout; |
3196 | 3196 | ||
3197 | /* Device-specific setup */ | 3197 | /* Device-specific setup */ |
3198 | return priv->cfg->lib->set_hw_params(priv); | 3198 | return priv->cfg->lib->set_hw_params(priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c6f8e682d03c..20dd1a5506ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1724,32 +1724,12 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1724 | return err; | 1724 | return err; |
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | /* | 1727 | static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq) |
1728 | * On every watchdog tick we check (latest) time stamp. If it does not | ||
1729 | * change during timeout period and queue is not empty we reset firmware. | ||
1730 | */ | ||
1731 | static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) | ||
1732 | { | 1728 | { |
1733 | struct iwl_tx_queue *txq = &priv->txq[cnt]; | 1729 | if (iwl_trans_check_stuck_queue(trans(priv), txq)) { |
1734 | struct iwl_queue *q = &txq->q; | 1730 | int ret = iwl_force_reset(priv, IWL_FW_RESET, false); |
1735 | unsigned long timeout; | ||
1736 | int ret; | ||
1737 | |||
1738 | if (q->read_ptr == q->write_ptr) { | ||
1739 | txq->time_stamp = jiffies; | ||
1740 | return 0; | ||
1741 | } | ||
1742 | |||
1743 | timeout = txq->time_stamp + | ||
1744 | msecs_to_jiffies(priv->cfg->base_params->wd_timeout); | ||
1745 | |||
1746 | if (time_after(jiffies, timeout)) { | ||
1747 | IWL_ERR(priv, "Queue %d stuck for %u ms.\n", | ||
1748 | q->id, priv->cfg->base_params->wd_timeout); | ||
1749 | ret = iwl_force_reset(priv, IWL_FW_RESET, false); | ||
1750 | return (ret == -EAGAIN) ? 0 : 1; | 1731 | return (ret == -EAGAIN) ? 0 : 1; |
1751 | } | 1732 | } |
1752 | |||
1753 | return 0; | 1733 | return 0; |
1754 | } | 1734 | } |
1755 | 1735 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 0bd6f7d54433..17a02a76f8b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -147,6 +147,7 @@ struct iwl_mod_params { | |||
147 | * @sw_crypto: 0 for hw, 1 for sw | 147 | * @sw_crypto: 0 for hw, 1 for sw |
148 | * @max_xxx_size: for ucode uses | 148 | * @max_xxx_size: for ucode uses |
149 | * @ct_kill_threshold: temperature threshold | 149 | * @ct_kill_threshold: temperature threshold |
150 | * @wd_timeout: TX queues watchdog timeout | ||
150 | * @calib_init_cfg: setup initial calibrations for the hw | 151 | * @calib_init_cfg: setup initial calibrations for the hw |
151 | * @calib_rt_cfg: setup runtime calibrations for the hw | 152 | * @calib_rt_cfg: setup runtime calibrations for the hw |
152 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 153 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
@@ -169,6 +170,8 @@ struct iwl_hw_params { | |||
169 | u32 ct_kill_threshold; /* value in hw-dependent units */ | 170 | u32 ct_kill_threshold; /* value in hw-dependent units */ |
170 | u32 ct_kill_exit_threshold; /* value in hw-dependent units */ | 171 | u32 ct_kill_exit_threshold; /* value in hw-dependent units */ |
171 | /* for 1000, 6000 series and up */ | 172 | /* for 1000, 6000 series and up */ |
173 | unsigned int wd_timeout; | ||
174 | |||
172 | u32 calib_init_cfg; | 175 | u32 calib_init_cfg; |
173 | u32 calib_rt_cfg; | 176 | u32 calib_rt_cfg; |
174 | const struct iwl_sensitivity_ranges *sens; | 177 | const struct iwl_sensitivity_ranges *sens; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 7b868c7b523a..646170400e16 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c | |||
@@ -1475,6 +1475,33 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | |||
1475 | return ret; | 1475 | return ret; |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | /* | ||
1479 | * On every watchdog tick we check (latest) time stamp. If it does not | ||
1480 | * change during timeout period and queue is not empty we reset firmware. | ||
1481 | */ | ||
1482 | static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) | ||
1483 | { | ||
1484 | struct iwl_tx_queue *txq = &priv(trans)->txq[cnt]; | ||
1485 | struct iwl_queue *q = &txq->q; | ||
1486 | unsigned long timeout; | ||
1487 | |||
1488 | if (q->read_ptr == q->write_ptr) { | ||
1489 | txq->time_stamp = jiffies; | ||
1490 | return 0; | ||
1491 | } | ||
1492 | |||
1493 | timeout = txq->time_stamp + | ||
1494 | msecs_to_jiffies(hw_params(trans).wd_timeout); | ||
1495 | |||
1496 | if (time_after(jiffies, timeout)) { | ||
1497 | IWL_ERR(trans, "Queue %d stuck for %u ms.\n", q->id, | ||
1498 | hw_params(trans).wd_timeout); | ||
1499 | return 1; | ||
1500 | } | ||
1501 | |||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1478 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1505 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1479 | /* create and remove of files */ | 1506 | /* create and remove of files */ |
1480 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ | 1507 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
@@ -2055,6 +2082,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2055 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2082 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2056 | 2083 | ||
2057 | .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, | 2084 | .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, |
2085 | .check_stuck_queue = iwl_trans_pcie_check_stuck_queue, | ||
2058 | 2086 | ||
2059 | .suspend = iwl_trans_pcie_suspend, | 2087 | .suspend = iwl_trans_pcie_suspend, |
2060 | .resume = iwl_trans_pcie_resume, | 2088 | .resume = iwl_trans_pcie_resume, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 45d6dff47ebb..6edf2e0dadab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -101,6 +101,7 @@ struct iwl_device_cmd; | |||
101 | * @kick_nic: remove the RESET from the embedded CPU and let it run | 101 | * @kick_nic: remove the RESET from the embedded CPU and let it run |
102 | * @free: release all the ressource for the transport layer itself such as | 102 | * @free: release all the ressource for the transport layer itself such as |
103 | * irq, tasklet etc... | 103 | * irq, tasklet etc... |
104 | * @check_stuck_queue: check if a specific queue is stuck | ||
104 | * @wait_tx_queue_empty: wait until all tx queues are empty | 105 | * @wait_tx_queue_empty: wait until all tx queues are empty |
105 | * @dbgfs_register: add the dbgfs files under this directory. Files will be | 106 | * @dbgfs_register: add the dbgfs files under this directory. Files will be |
106 | * automatically deleted. | 107 | * automatically deleted. |
@@ -143,6 +144,7 @@ struct iwl_trans_ops { | |||
143 | void (*free)(struct iwl_trans *trans); | 144 | void (*free)(struct iwl_trans *trans); |
144 | 145 | ||
145 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 146 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
147 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | ||
146 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 148 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
147 | 149 | ||
148 | int (*suspend)(struct iwl_trans *trans); | 150 | int (*suspend)(struct iwl_trans *trans); |
@@ -259,6 +261,10 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | |||
259 | return trans->ops->wait_tx_queue_empty(trans); | 261 | return trans->ops->wait_tx_queue_empty(trans); |
260 | } | 262 | } |
261 | 263 | ||
264 | static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) | ||
265 | { | ||
266 | return trans->ops->check_stuck_queue(trans, q); | ||
267 | } | ||
262 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, | 268 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, |
263 | struct dentry *dir) | 269 | struct dentry *dir) |
264 | { | 270 | { |