diff mbox

[10/13] ath10k: implement flushing of pending frames in txqs

Message ID 1453384006-31907-11-git-send-email-michal.kazior@tieto.com (mailing list archive)
State Not Applicable
Delegated to: Kalle Valo
Headers show

Commit Message

Michal Kazior Jan. 21, 2016, 1:46 p.m. UTC
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@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(+)

Comments

Kalle Valo March 4, 2016, 9:17 a.m. UTC | #1
Michal Kazior <michal.kazior@tieto.com> writes:

> 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@tieto.com>

This fails to apply:

fatal: sha1 information is lacking or useless (drivers/net/wireless/ath/ath10k/htt_rx.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0010 ath10k: implement flushing of pending frames in txqs

> @@ -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;

This hunk seems to be the problem. I could try to fix it myself but the
function has changed so I would prefer that you respin.
Michal Kazior March 4, 2016, 9:52 a.m. UTC | #2
On 4 March 2016 at 10:17, Valo, Kalle <kvalo@qca.qualcomm.com> wrote:
> Michal Kazior <michal.kazior@tieto.com> writes:
>
>> 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@tieto.com>
>
> This fails to apply:
>
> fatal: sha1 information is lacking or useless (drivers/net/wireless/ath/ath10k/htt_rx.c).
> Repository lacks necessary blobs to fall back on 3-way merge.
> Cannot fall back to three-way merge.
> Patch failed at 0010 ath10k: implement flushing of pending frames in txqs
>
>> @@ -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;
>
> This hunk seems to be the problem. I could try to fix it myself but the
> function has changed so I would prefer that you respin.

This patch is in v1. It's base included some extra patches that
weren't in ath.git at the time.

The v2 patchset has this patch squashed into wake_tx_queue patch and
the entire v2 patchset is based solely on ath.git without any extra
patches in between. Did patchwork confuse these patchsets?


Micha?
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kalle Valo March 4, 2016, 3:37 p.m. UTC | #3
Michal Kazior <michal.kazior@tieto.com> writes:

> On 4 March 2016 at 10:17, Valo, Kalle <kvalo@qca.qualcomm.com> wrote:
>> Michal Kazior <michal.kazior@tieto.com> writes:
>>
>>> 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@tieto.com>
>>
>> This fails to apply:
>>
>> fatal: sha1 information is lacking or useless (drivers/net/wireless/ath/ath10k/htt_rx.c).
>> Repository lacks necessary blobs to fall back on 3-way merge.
>> Cannot fall back to three-way merge.
>> Patch failed at 0010 ath10k: implement flushing of pending frames in txqs
>>
>>> @@ -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;
>>
>> This hunk seems to be the problem. I could try to fix it myself but the
>> function has changed so I would prefer that you respin.
>
> This patch is in v1. It's base included some extra patches that
> weren't in ath.git at the time.
>
> The v2 patchset has this patch squashed into wake_tx_queue patch and
> the entire v2 patchset is based solely on ath.git without any extra
> patches in between. Did patchwork confuse these patchsets?

No, it was me who got confused :) I was accidentally applying v1 instead
of v2.

But v2 also has conflicts with ath-next. I need to first update my trees
to get latest cfg80211/mac80211 and then I'll try again.
diff mbox

Patch

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)
 {