[PATCH 10/13] ath10k: implement flushing of pending frames in txqs
Michal Kazior
michal.kazior at tieto.com
Thu Jan 21 05:46:43 PST 2016
Firmware supporting pull-push tx model may request
a switch between modes. When switching from
pull-push to push-only it will be necessary to
flush all pending frames. The code will do that
once other bits that actually trigger it are added.
Signed-off-by: Michal Kazior <michal.kazior at tieto.com>
---
drivers/net/wireless/ath/ath10k/core.h | 1 +
drivers/net/wireless/ath/ath10k/htt_rx.c | 3 ++
drivers/net/wireless/ath/ath10k/mac.c | 82 ++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/mac.h | 1 +
4 files changed, 87 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index d09d6fdf1149..38ed4bbd220b 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -607,6 +607,7 @@ static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state)
enum ath10k_tx_pause_reason {
ATH10K_TX_PAUSE_Q_FULL,
+ ATH10K_TX_PAUSE_Q_FLUSH_PENDING,
ATH10K_TX_PAUSE_MAX,
};
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index be7dc88b3316..6e3d95c95568 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2244,6 +2244,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
}
ath10k_txrx_tx_unref(htt, &tx_done);
+ ath10k_mac_tx_push_pending(ar);
break;
}
case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
@@ -2370,6 +2371,8 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
dev_kfree_skb_any(skb);
}
+ ath10k_mac_tx_push_pending(ar);
+
spin_lock_bh(&htt->rx_ring.lock);
while ((skb = __skb_dequeue(&htt->rx_compl_q))) {
resp = (struct htt_resp *)skb->data;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 205ccf3760a3..42020c22eaed 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3710,6 +3710,88 @@ static void ath10k_mac_tx_wake(struct ieee80211_hw *hw,
ath10k_htt_tx_txq_update(hw, txq);
}
+struct ath10k_mac_tx_push_arg {
+ struct ieee80211_hw *hw;
+ bool more;
+};
+
+static void ath10k_mac_tx_push_pending_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq,
+ struct ath10k_mac_tx_push_arg *arg)
+{
+ bool can_push;
+ bool has_more;
+ int ret;
+
+ if (!txq)
+ return;
+
+ while (txq->qdepth > 0) {
+ if (!ath10k_mac_tx_can_push(hw, txq))
+ break;
+
+ ret = ath10k_mac_tx_push_txq(hw, txq);
+ if (ret)
+ break;
+ }
+
+ can_push = ath10k_mac_tx_can_push(hw, txq);
+ has_more = txq->qdepth > 0;
+
+ if (can_push && has_more)
+ arg->more = true;
+}
+
+static void ath10k_mac_tx_push_pending_vif_iter(void *data,
+ u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct ath10k_mac_tx_push_arg *arg = data;
+ struct ieee80211_hw *hw = arg->hw;
+
+ ath10k_mac_tx_push_pending_txq(hw, vif->txq, arg);
+}
+
+static void ath10k_mac_tx_push_pending_sta_iter(void *data,
+ struct ieee80211_sta *sta)
+{
+ struct ath10k_mac_tx_push_arg *arg = data;
+ struct ieee80211_hw *hw = arg->hw;
+ int tid;
+
+ for (tid = 0; tid < ARRAY_SIZE(sta->txq); tid++)
+ ath10k_mac_tx_push_pending_txq(hw, sta->txq[tid], arg);
+}
+
+void ath10k_mac_tx_push_pending(struct ath10k *ar)
+{
+ struct ieee80211_hw *hw = ar->hw;
+ struct ath10k_mac_tx_push_arg arg = {};
+
+ if (likely(!(ar->tx_paused & BIT(ATH10K_TX_PAUSE_Q_FLUSH_PENDING))))
+ return;
+
+ arg.hw = hw;
+ arg.more = false;
+
+ ieee80211_iterate_active_interfaces_atomic(hw,
+ IEEE80211_IFACE_ITER_NORMAL,
+ ath10k_mac_tx_push_pending_vif_iter,
+ &arg);
+ if (arg.more)
+ return;
+
+ ieee80211_iterate_stations_atomic(hw,
+ ath10k_mac_tx_push_pending_sta_iter,
+ &arg);
+ if (arg.more)
+ return;
+
+ spin_lock_bh(&ar->htt.tx_lock);
+ ath10k_mac_tx_unlock(ar, ATH10K_TX_PAUSE_Q_FLUSH_PENDING);
+ spin_unlock_bh(&ar->htt.tx_lock);
+}
+
/************/
/* Scanning */
/************/
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index 53091588090d..453f606a250e 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -75,6 +75,7 @@ void ath10k_mac_tx_unlock(struct ath10k *ar, int reason);
void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason);
void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason);
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar);
+void ath10k_mac_tx_push_pending(struct ath10k *ar);
static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
{
--
2.1.4
More information about the ath10k
mailing list