Created
June 27, 2024 06:13
-
-
Save qosmio/b6dc81c5716ab95d653f324b6519085b to your computer and use it in GitHub Desktop.
Add mac80211 based AQL support in ath11k
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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