Commit 3cafdbe6 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach

iwlwifi: allow to wait for a subset of the queues

This will be used later to flush / wait for queues that are
related to a specific vif.
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent d13c8dca
...@@ -180,7 +180,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) ...@@ -180,7 +180,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
goto done; goto done;
} }
IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n"); IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(priv->trans); iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
done: done:
ieee80211_wake_queues(priv->hw); ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
......
...@@ -1119,7 +1119,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) ...@@ -1119,7 +1119,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
} }
} }
IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(priv->trans); iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
done: done:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
......
...@@ -437,8 +437,7 @@ struct iwl_trans; ...@@ -437,8 +437,7 @@ struct iwl_trans;
* this one. The op_mode must not configure the HCMD queue. May sleep. * this one. The op_mode must not configure the HCMD queue. May sleep.
* @txq_disable: de-configure a Tx queue to send AMPDUs * @txq_disable: de-configure a Tx queue to send AMPDUs
* Must be atomic * Must be atomic
* @wait_tx_queue_empty: wait until all tx queues are empty * @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
* May sleep
* @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.
* @write8: write a u8 to a register at offset ofs from the BAR * @write8: write a u8 to a register at offset ofs from the BAR
...@@ -490,7 +489,7 @@ struct iwl_trans_ops { ...@@ -490,7 +489,7 @@ struct iwl_trans_ops {
void (*txq_disable)(struct iwl_trans *trans, int queue); void (*txq_disable)(struct iwl_trans *trans, int queue);
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 (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
...@@ -759,12 +758,13 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, ...@@ -759,12 +758,13 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0);
} }
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
u32 txq_bm)
{ {
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
return trans->ops->wait_tx_queue_empty(trans); return trans->ops->wait_tx_queue_empty(trans, txq_bm);
} }
static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
......
...@@ -1257,7 +1257,7 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, ...@@ -1257,7 +1257,7 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
#define IWL_FLUSH_WAIT_MS 2000 #define IWL_FLUSH_WAIT_MS 2000
static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq; struct iwl_txq *txq;
...@@ -1272,6 +1272,10 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) ...@@ -1272,6 +1272,10 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) { for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
if (cnt == trans_pcie->cmd_queue) if (cnt == trans_pcie->cmd_queue)
continue; continue;
if (!test_bit(cnt, trans_pcie->queue_used))
continue;
if (!(BIT(cnt) & txq_bm))
continue;
txq = &trans_pcie->txq[cnt]; txq = &trans_pcie->txq[cnt];
q = &txq->q; q = &txq->q;
while (q->read_ptr != q->write_ptr && !time_after(jiffies, while (q->read_ptr != q->write_ptr && !time_after(jiffies,
......
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