Commit f22be624 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by John W. Linville

iwlagn: move check_stuck_queue to transport layer

This one is really transport related.

==== moves Stanislaw's code to BSD area ====
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5f178cd2
...@@ -3191,8 +3191,8 @@ static int iwl_set_hw_params(struct iwl_priv *priv) ...@@ -3191,8 +3191,8 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
priv->cfg->base_params->num_of_ampdu_queues; priv->cfg->base_params->num_of_ampdu_queues;
hw_params(priv).shadow_reg_enable = hw_params(priv).shadow_reg_enable =
priv->cfg->base_params->shadow_reg_enable; priv->cfg->base_params->shadow_reg_enable;
hw_params(priv).sku = hw_params(priv).sku = priv->cfg->sku;
priv->cfg->sku; hw_params(priv).wd_timeout = priv->cfg->base_params->wd_timeout;
/* Device-specific setup */ /* Device-specific setup */
return priv->cfg->lib->set_hw_params(priv); return priv->cfg->lib->set_hw_params(priv);
......
...@@ -1724,32 +1724,12 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -1724,32 +1724,12 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return err; return err;
} }
/* static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
* On every watchdog tick we check (latest) time stamp. If it does not
* change during timeout period and queue is not empty we reset firmware.
*/
static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
{ {
struct iwl_tx_queue *txq = &priv->txq[cnt]; if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
struct iwl_queue *q = &txq->q; int ret = iwl_force_reset(priv, IWL_FW_RESET, false);
unsigned long timeout;
int ret;
if (q->read_ptr == q->write_ptr) {
txq->time_stamp = jiffies;
return 0;
}
timeout = txq->time_stamp +
msecs_to_jiffies(priv->cfg->base_params->wd_timeout);
if (time_after(jiffies, timeout)) {
IWL_ERR(priv, "Queue %d stuck for %u ms.\n",
q->id, priv->cfg->base_params->wd_timeout);
ret = iwl_force_reset(priv, IWL_FW_RESET, false);
return (ret == -EAGAIN) ? 0 : 1; return (ret == -EAGAIN) ? 0 : 1;
} }
return 0; return 0;
} }
......
...@@ -147,6 +147,7 @@ struct iwl_mod_params { ...@@ -147,6 +147,7 @@ struct iwl_mod_params {
* @sw_crypto: 0 for hw, 1 for sw * @sw_crypto: 0 for hw, 1 for sw
* @max_xxx_size: for ucode uses * @max_xxx_size: for ucode uses
* @ct_kill_threshold: temperature threshold * @ct_kill_threshold: temperature threshold
* @wd_timeout: TX queues watchdog timeout
* @calib_init_cfg: setup initial calibrations for the hw * @calib_init_cfg: setup initial calibrations for the hw
* @calib_rt_cfg: setup runtime calibrations for the hw * @calib_rt_cfg: setup runtime calibrations for the hw
* @struct iwl_sensitivity_ranges: range of sensitivity values * @struct iwl_sensitivity_ranges: range of sensitivity values
...@@ -169,6 +170,8 @@ struct iwl_hw_params { ...@@ -169,6 +170,8 @@ struct iwl_hw_params {
u32 ct_kill_threshold; /* value in hw-dependent units */ u32 ct_kill_threshold; /* value in hw-dependent units */
u32 ct_kill_exit_threshold; /* value in hw-dependent units */ u32 ct_kill_exit_threshold; /* value in hw-dependent units */
/* for 1000, 6000 series and up */ /* for 1000, 6000 series and up */
unsigned int wd_timeout;
u32 calib_init_cfg; u32 calib_init_cfg;
u32 calib_rt_cfg; u32 calib_rt_cfg;
const struct iwl_sensitivity_ranges *sens; const struct iwl_sensitivity_ranges *sens;
......
...@@ -1475,6 +1475,33 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) ...@@ -1475,6 +1475,33 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
return ret; return ret;
} }
/*
* On every watchdog tick we check (latest) time stamp. If it does not
* change during timeout period and queue is not empty we reset firmware.
*/
static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt)
{
struct iwl_tx_queue *txq = &priv(trans)->txq[cnt];
struct iwl_queue *q = &txq->q;
unsigned long timeout;
if (q->read_ptr == q->write_ptr) {
txq->time_stamp = jiffies;
return 0;
}
timeout = txq->time_stamp +
msecs_to_jiffies(hw_params(trans).wd_timeout);
if (time_after(jiffies, timeout)) {
IWL_ERR(trans, "Queue %d stuck for %u ms.\n", q->id,
hw_params(trans).wd_timeout);
return 1;
}
return 0;
}
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
/* create and remove of files */ /* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
...@@ -2055,6 +2082,7 @@ const struct iwl_trans_ops trans_ops_pcie = { ...@@ -2055,6 +2082,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
.dbgfs_register = iwl_trans_pcie_dbgfs_register, .dbgfs_register = iwl_trans_pcie_dbgfs_register,
.wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty,
.check_stuck_queue = iwl_trans_pcie_check_stuck_queue,
.suspend = iwl_trans_pcie_suspend, .suspend = iwl_trans_pcie_suspend,
.resume = iwl_trans_pcie_resume, .resume = iwl_trans_pcie_resume,
......
...@@ -101,6 +101,7 @@ struct iwl_device_cmd; ...@@ -101,6 +101,7 @@ struct iwl_device_cmd;
* @kick_nic: remove the RESET from the embedded CPU and let it run * @kick_nic: remove the RESET from the embedded CPU and let it run
* @free: release all the ressource for the transport layer itself such as * @free: release all the ressource for the transport layer itself such as
* irq, tasklet etc... * irq, tasklet etc...
* @check_stuck_queue: check if a specific queue is stuck
* @wait_tx_queue_empty: wait until all tx queues are empty * @wait_tx_queue_empty: wait until all tx queues are empty
* @dbgfs_register: add the dbgfs files under this directory. Files will be * @dbgfs_register: add the dbgfs files under this directory. Files will be
* automatically deleted. * automatically deleted.
...@@ -143,6 +144,7 @@ struct iwl_trans_ops { ...@@ -143,6 +144,7 @@ struct iwl_trans_ops {
void (*free)(struct iwl_trans *trans); void (*free)(struct iwl_trans *trans);
int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
int (*check_stuck_queue)(struct iwl_trans *trans, int q);
int (*wait_tx_queue_empty)(struct iwl_trans *trans); int (*wait_tx_queue_empty)(struct iwl_trans *trans);
int (*suspend)(struct iwl_trans *trans); int (*suspend)(struct iwl_trans *trans);
...@@ -259,6 +261,10 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) ...@@ -259,6 +261,10 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
return trans->ops->wait_tx_queue_empty(trans); return trans->ops->wait_tx_queue_empty(trans);
} }
static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
{
return trans->ops->check_stuck_queue(trans, q);
}
static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
struct dentry *dir) struct dentry *dir)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment