|
|
@@ -1997,6 +1997,18 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
|
|
|
+{
|
|
|
+ /* FIXME: Not really sure since when the behaviour changed. At some
|
|
|
+ * point new firmware stopped requiring creation of peer entries for
|
|
|
+ * offchannel tx (and actually creating them causes issues with wmi-htc
|
|
|
+ * tx credit replenishment and reliability). Assuming it's at least 3.4
|
|
|
+ * because that's when the `freq` was introduced to TX_FRM HTT command.
|
|
|
+ */
|
|
|
+ return !(ar->htt.target_version_major >= 3 &&
|
|
|
+ ar->htt.target_version_minor >= 4);
|
|
|
+}
|
|
|
+
|
|
|
static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
|
|
|
{
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
|
|
@@ -2341,16 +2353,21 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
|
|
|
|
|
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
|
|
|
spin_lock_bh(&ar->data_lock);
|
|
|
- ATH10K_SKB_CB(skb)->htt.is_offchan = true;
|
|
|
+ ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
|
|
|
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
|
|
|
spin_unlock_bh(&ar->data_lock);
|
|
|
|
|
|
- ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
|
|
|
- skb);
|
|
|
+ if (ath10k_mac_need_offchan_tx_work(ar)) {
|
|
|
+ ATH10K_SKB_CB(skb)->htt.freq = 0;
|
|
|
+ ATH10K_SKB_CB(skb)->htt.is_offchan = true;
|
|
|
|
|
|
- skb_queue_tail(&ar->offchan_tx_queue, skb);
|
|
|
- ieee80211_queue_work(hw, &ar->offchan_tx_work);
|
|
|
- return;
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
|
|
|
+ skb);
|
|
|
+
|
|
|
+ skb_queue_tail(&ar->offchan_tx_queue, skb);
|
|
|
+ ieee80211_queue_work(hw, &ar->offchan_tx_work);
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
ath10k_tx_htt(ar, skb);
|