iwlagn: move wait_for_tx_queue_empty to transport layer
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Fri, 26 Aug 2011 06:11:29 +0000 (23:11 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 29 Aug 2011 19:33:00 +0000 (15:33 -0400)
This one is really transport related.

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-lib.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-trans.c
drivers/net/wireless/iwlwifi/iwl-trans.h

index 359bd90..7c036b9 100644 (file)
@@ -634,37 +634,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
                                  vif->bss_conf.bssid);
 }
 
-#define IWL_FLUSH_WAIT_MS      2000
-
-int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
-{
-       struct iwl_tx_queue *txq;
-       struct iwl_queue *q;
-       int cnt;
-       unsigned long now = jiffies;
-       int ret = 0;
-
-       /* waiting for all the tx frames complete might take a while */
-       for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
-               if (cnt == priv->shrd->cmd_queue)
-                       continue;
-               txq = &priv->txq[cnt];
-               q = &txq->q;
-               while (q->read_ptr != q->write_ptr && !time_after(jiffies,
-                      now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
-                               msleep(1);
-
-               if (q->read_ptr != q->write_ptr) {
-                       IWL_ERR(priv, "fail to flush all tx fifo queues\n");
-                       ret = -ETIMEDOUT;
-                       break;
-               }
-       }
-       return ret;
-}
-
-#define IWL_TX_QUEUE_MSK       0xfffff
-
 /**
  * iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode
  *
@@ -715,7 +684,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
                goto done;
        }
        IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
-       iwlagn_wait_tx_queue_empty(priv);
+       iwl_trans_wait_tx_queue_empty(trans(priv));
 done:
        ieee80211_wake_queues(priv->hw);
        mutex_unlock(&priv->shrd->mutex);
index 724c50a..5d0888a 100644 (file)
@@ -2833,7 +2833,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
                }
        }
        IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
-       iwlagn_wait_tx_queue_empty(priv);
+       iwl_trans_wait_tx_queue_empty(trans(priv));
 done:
        mutex_unlock(&priv->shrd->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
index 2b94a10..a7b4948 100644 (file)
@@ -102,7 +102,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
 int iwlagn_send_tx_power(struct iwl_priv *priv);
 void iwlagn_temperature(struct iwl_priv *priv);
 u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
-int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
 int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
index 9b0ecd4..7b868c7 100644 (file)
@@ -1446,6 +1446,35 @@ static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
        return iwl_trans;
 }
 
+#define IWL_FLUSH_WAIT_MS      2000
+
+static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
+{
+       struct iwl_tx_queue *txq;
+       struct iwl_queue *q;
+       int cnt;
+       unsigned long now = jiffies;
+       int ret = 0;
+
+       /* waiting for all the tx frames complete might take a while */
+       for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) {
+               if (cnt == trans->shrd->cmd_queue)
+                       continue;
+               txq = &priv(trans)->txq[cnt];
+               q = &txq->q;
+               while (q->read_ptr != q->write_ptr && !time_after(jiffies,
+                      now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
+                       msleep(1);
+
+               if (q->read_ptr != q->write_ptr) {
+                       IWL_ERR(trans, "fail to flush all tx fifo queues\n");
+                       ret = -ETIMEDOUT;
+                       break;
+               }
+       }
+       return ret;
+}
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                      \
@@ -2024,6 +2053,9 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .free = iwl_trans_pcie_free,
 
        .dbgfs_register = iwl_trans_pcie_dbgfs_register,
+
+       .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty,
+
        .suspend = iwl_trans_pcie_suspend,
        .resume = iwl_trans_pcie_resume,
 };
index c92c9fe..45d6dff 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...
+ * @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.
  * @suspend: stop the device unless WoWLAN is configured
@@ -142,6 +143,8 @@ struct iwl_trans_ops {
        void (*free)(struct iwl_trans *trans);
 
        int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
+       int (*wait_tx_queue_empty)(struct iwl_trans *trans);
+
        int (*suspend)(struct iwl_trans *trans);
        int (*resume)(struct iwl_trans *trans);
 };
@@ -251,6 +254,11 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
        trans->ops->free(trans);
 }
 
+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_dbgfs_register(struct iwl_trans *trans,
                                            struct dentry *dir)
 {