iwlagn: move check_stuck_queue to transport layer
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Fri, 26 Aug 2011 06:11:30 +0000 (23:11 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 29 Aug 2011 19:33:01 +0000 (15:33 -0400)
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>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-trans.c
drivers/net/wireless/iwlwifi/iwl-trans.h

index 5d0888a7fbc00101a3135c039278287411ad0996..5fdf9b10b470034465bf0066fd121be5ee9869c5 100644 (file)
@@ -3191,8 +3191,8 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
                priv->cfg->base_params->num_of_ampdu_queues;
        hw_params(priv).shadow_reg_enable =
                priv->cfg->base_params->shadow_reg_enable;
-       hw_params(priv).sku =
-               priv->cfg->sku;
+       hw_params(priv).sku = priv->cfg->sku;
+       hw_params(priv).wd_timeout = priv->cfg->base_params->wd_timeout;
 
        /* Device-specific setup */
        return priv->cfg->lib->set_hw_params(priv);
index c6f8e682d03c1c3676bae958f14cc2aa1cd346cc..20dd1a5506ed82762bac0011c9c9919426fd9562 100644 (file)
@@ -1724,32 +1724,12 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        return err;
 }
 
-/*
- * 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)
+static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
 {
-       struct iwl_tx_queue *txq = &priv->txq[cnt];
-       struct iwl_queue *q = &txq->q;
-       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);
+       if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
+               int ret = iwl_force_reset(priv, IWL_FW_RESET, false);
                return (ret == -EAGAIN) ? 0 : 1;
        }
-
        return 0;
 }
 
index 0bd6f7d54433a9ea69196d403a51b5ac2654c32b..17a02a76f8b220928384d3b5952f2e9f3ab587b4 100644 (file)
@@ -147,6 +147,7 @@ struct iwl_mod_params {
  * @sw_crypto: 0 for hw, 1 for sw
  * @max_xxx_size: for ucode uses
  * @ct_kill_threshold: temperature threshold
+ * @wd_timeout: TX queues watchdog timeout
  * @calib_init_cfg: setup initial calibrations for the hw
  * @calib_rt_cfg: setup runtime calibrations for the hw
  * @struct iwl_sensitivity_ranges: range of sensitivity values
@@ -169,6 +170,8 @@ struct iwl_hw_params {
        u32 ct_kill_threshold; /* value in hw-dependent units */
        u32 ct_kill_exit_threshold; /* value in hw-dependent units */
                                    /* for 1000, 6000 series and up */
+       unsigned int wd_timeout;
+
        u32 calib_init_cfg;
        u32 calib_rt_cfg;
        const struct iwl_sensitivity_ranges *sens;
index 7b868c7b523a4910a9586de7107d1b614716d4b8..646170400e16cb6156ac5928df5e3f88cd41fbf7 100644 (file)
@@ -1475,6 +1475,33 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
        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
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                      \
@@ -2055,6 +2082,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .dbgfs_register = iwl_trans_pcie_dbgfs_register,
 
        .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,
        .resume = iwl_trans_pcie_resume,
index 45d6dff47ebba0582894a7a2087b2e8b0b657255..6edf2e0dadab709563c4f962a1134ac3235e3d91 100644 (file)
@@ -101,6 +101,7 @@ struct iwl_device_cmd;
  * @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
  *        irq, tasklet etc...
+ * @check_stuck_queue: check if a specific queue is stuck
  * @wait_tx_queue_empty: wait until all tx queues are empty
  * @dbgfs_register: add the dbgfs files under this directory. Files will be
  *     automatically deleted.
@@ -143,6 +144,7 @@ struct iwl_trans_ops {
        void (*free)(struct iwl_trans *trans);
 
        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 (*suspend)(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);
 }
 
+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,
                                            struct dentry *dir)
 {