Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save qosmio/b6dc81c5716ab95d653f324b6519085b to your computer and use it in GitHub Desktop.
Save qosmio/b6dc81c5716ab95d653f324b6519085b to your computer and use it in GitHub Desktop.
Add mac80211 based AQL support in ath11k
From: Tamizh Chelvam Raja <[email protected]>
To: <[email protected]>
CC: <[email protected]>
Subject: [PATCH] ath11k: Add mac80211 based AQL support in ath11k
Date: Mon, 1 May 2023 18:37:25 +0530
Add wake_tx_queue mac op to support AQL and support
txq dequeueing from mac80211. Also implement a
simple scheduler for pulling all skbs from txqs
of all AC's at the end of tx completion NAPI.
Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
Signed-off-by: Tamizh Chelvam Raja <[email protected]>
---
drivers/net/wireless/ath/ath11k/dp_tx.c | 11 ++++
drivers/net/wireless/ath/ath11k/mac.c | 70 ++++++++++++++++++++++---
drivers/net/wireless/ath/ath11k/mac.h | 1 +
3 files changed, 76 insertions(+), 6 deletions(-)
base-commit: 12f167f02a1abe2c8817496a902de00758285b92
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -847,6 +847,7 @@ void ath11k_dp_tx_completion_handler(str
u32 msdu_id, desc_id;
u8 mac_id;
struct hal_wbm_release_ring *tx_status;
+ bool mac_id_scheduled[MAX_RADIOS];
spin_lock_bh(&status_ring->lock);
@@ -921,6 +922,15 @@ void ath11k_dp_tx_completion_handler(str
wake_up(&ar->dp.tx_empty_waitq);
ath11k_dp_tx_complete_msdu(ar, msdu, tx_status, buf_rel_source);
+ mac_id_scheduled[mac_id] = true;
+ }
+
+ /* Schedule remaining Tx packets for the radio */
+ for (i = 0; i < MAX_RADIOS; i++) {
+ if (!mac_id_scheduled[i])
+ continue;
+ ar = ab->pdevs[i].ar;
+ ath11k_mac_tx_push_pending(ar);
}
}
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6317,9 +6317,9 @@ static int ath11k_mac_tx_over_wmi(struct
return 0;
}
-static void ath11k_mac_op_tx(struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control,
- struct sk_buff *skb)
+static void ath11k_mac_tx(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
{
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
struct ath11k *ar = hw->priv;
@@ -6379,8 +6379,8 @@ static void ath11k_mac_op_tx(struct ieee
return;
}
- if (control->sta)
- arsta = ath11k_sta_to_arsta(control->sta);
+ if (sta)
+ arsta = ath11k_sta_to_arsta(sta);
/* Must call mac80211 tx status handler, else when stats is disabled we free
* the skb from driver. Own tx packets on monitor will also be disabled.
@@ -6403,6 +6403,62 @@ static void ath11k_mac_op_tx(struct ieee
}
}
+static void ath11k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
+{
+ struct ieee80211_txq *txq;
+ struct sk_buff *skb;
+
+ ieee80211_txq_schedule_start(hw, ac);
+ while ((txq = ieee80211_next_txq(hw, ac))) {
+ while ((skb = ieee80211_tx_dequeue_ni(hw, txq)))
+ ath11k_mac_tx(hw, txq->sta, skb);
+
+ ieee80211_return_txq(hw, txq, false);
+ }
+ ieee80211_txq_schedule_end(hw, ac);
+}
+
+void ath11k_mac_tx_push_pending(struct ath11k *ar)
+{
+ struct ieee80211_hw *hw = ar->hw;
+ u32 ac;
+
+ rcu_read_lock();
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
+ ath11k_mac_schedule_txq(hw, ac);
+
+ rcu_read_unlock();
+}
+
+static void ath11k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
+{
+ u8 ac;
+ struct sk_buff *skb;
+
+ ac = txq->ac;
+ ieee80211_txq_schedule_start(hw, ac);
+ txq = ieee80211_next_txq(hw, ac);
+
+ if (!txq)
+ goto out;
+
+ while ((skb = ieee80211_tx_dequeue_ni(hw, txq)))
+ ath11k_mac_tx(hw, txq->sta, skb);
+
+ ieee80211_return_txq(hw, txq, false);
+
+out:
+ ieee80211_txq_schedule_end(hw, ac);
+}
+
+static void ath11k_mac_op_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
+{
+ ath11k_mac_tx(hw, control->sta, skb);
+}
+
void ath11k_mac_drain_tx(struct ath11k *ar)
{
/* make sure rcu-protected mac80211 tx path itself is drained */
@@ -9746,7 +9802,7 @@ static int ath11k_mac_op_sta_state(struc
static const struct ieee80211_ops ath11k_ops = {
.tx = ath11k_mac_op_tx,
- .wake_tx_queue = ieee80211_handle_wake_tx_queue,
+ .wake_tx_queue = ath11k_mac_op_wake_tx_queue,
.start = ath11k_mac_op_start,
.stop = ath11k_mac_op_stop,
.reconfig_complete = ath11k_mac_op_reconfig_complete,
@@ -10274,6 +10330,8 @@ static int __ath11k_mac_register(struct
ieee80211_hw_set(ar->hw, SUPPORTS_MESH_NSS_OFFLOAD);
}
+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);
+
ret = ieee80211_register_hw(ar->hw);
if (ret) {
ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret);
--- a/drivers/net/wireless/ath/ath11k/mac.h
+++ b/drivers/net/wireless/ath/ath11k/mac.h
@@ -174,4 +174,5 @@ int ath11k_mac_wait_tx_complete(struct a
int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif,
enum wmi_sta_keepalive_method method,
u32 interval);
+void ath11k_mac_tx_push_pending(struct ath11k *ar);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment