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

iwlagn: move wait_for_tx_queue_empty to transport layer

This one is really transport related.
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 c91bd124
...@@ -634,37 +634,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, ...@@ -634,37 +634,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
vif->bss_conf.bssid); 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 * 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) ...@@ -715,7 +684,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
goto done; goto done;
} }
IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n"); 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: done:
ieee80211_wake_queues(priv->hw); ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->shrd->mutex); mutex_unlock(&priv->shrd->mutex);
......
...@@ -2833,7 +2833,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) ...@@ -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"); 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: done:
mutex_unlock(&priv->shrd->mutex); mutex_unlock(&priv->shrd->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
......
...@@ -102,7 +102,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); ...@@ -102,7 +102,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
int iwlagn_send_tx_power(struct iwl_priv *priv); int iwlagn_send_tx_power(struct iwl_priv *priv);
void iwlagn_temperature(struct iwl_priv *priv); void iwlagn_temperature(struct iwl_priv *priv);
u16 iwlagn_eeprom_calib_version(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); int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
void iwlagn_dev_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); int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
......
...@@ -1446,6 +1446,35 @@ static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) ...@@ -1446,6 +1446,35 @@ static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
return iwl_trans; 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 #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 { \
...@@ -2024,6 +2053,9 @@ const struct iwl_trans_ops trans_ops_pcie = { ...@@ -2024,6 +2053,9 @@ const struct iwl_trans_ops trans_ops_pcie = {
.free = iwl_trans_pcie_free, .free = iwl_trans_pcie_free,
.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,
.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...
* @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.
* @suspend: stop the device unless WoWLAN is configured * @suspend: stop the device unless WoWLAN is configured
...@@ -142,6 +143,8 @@ struct iwl_trans_ops { ...@@ -142,6 +143,8 @@ 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 (*wait_tx_queue_empty)(struct iwl_trans *trans);
int (*suspend)(struct iwl_trans *trans); int (*suspend)(struct iwl_trans *trans);
int (*resume)(struct iwl_trans *trans); int (*resume)(struct iwl_trans *trans);
}; };
...@@ -251,6 +254,11 @@ static inline void iwl_trans_free(struct iwl_trans *trans) ...@@ -251,6 +254,11 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
trans->ops->free(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, 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