wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/751-ath12k-Add-framework-to-use-different-hashmap-for-ML.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

195 lines
7.4 KiB
Diff

From 6c058117bdd85caa6ad5e4e842e1cc869bd478da Mon Sep 17 00:00:00 2001
From: P Praneesh <quic_ppranees@quicinc.com>
Date: Sun, 19 Mar 2023 13:19:02 +0530
Subject: [PATCH] ath12k: Add framework to use different hashmap for
MLO/NON-MLO peers
Currently driver specifies the same rx hash value in
HAL_REO1_DEST_RING_CTRL_IX_2 and HAL_REO1_DEST_RING_CTRL_IX_3
registers. Based on this value, driver's rx reo destination rings are
utilised by the HW. Using same rx ring mask across the ML and non ML
peer degrades the performance.
To handle both type of peers, adding framework to optimise the
performance of a system that includes both ML and Non ML peers.
For non ML peers, value written in IX2 registers are used and for ML
peers, value wirtten in IX3 registers are used.
Default routing configuration inside the ath12k_dp_peer_setup() doesnt
help to detect the ML peer due to sta->valid_links missed to have other links
in the first link STA state change from NONE to AUTH state. so it failed to
configure ATH12K_DP_LMAC_PEER_ID_MLO instead it configured as
ATH12K_DP_LMAC_PEER_ID_LEGACY. which lead to fetch the ix2 register for REO
indication. so low throughput seen in ML KPI testcases. So fix this issue by
configuring the same peer default routing configuration again when the STA
move from AUTH to ASSOC state. Now we able to get the correct valid links
from sta->valid_links.
With this change, Observed 400Mbps improvement with SLO clients.
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp.c | 39 +++++++++++++++++++++++----
drivers/net/wireless/ath/ath12k/dp.h | 3 ++-
drivers/net/wireless/ath/ath12k/mac.c | 2 +-
3 files changed, 37 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -14,6 +14,10 @@
#include "peer.h"
#include "dp_mon.h"
+#define ATH12K_DP_LMAC_PEER_ID_LEGACY 2
+#define ATH12K_DP_LMAC_PEER_ID_MLO 3
+#define ATH12K_DP_PEER_ROUTING_LMAC_ID_MASK GENMASK(7,6)
+
static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab,
struct sk_buff *skb)
{
@@ -47,30 +51,55 @@ void ath12k_dp_peer_cleanup(struct ath12
spin_unlock_bh(&ab->base_lock);
}
-int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr)
+int ath12k_dp_peer_default_route_setup(struct ath12k *ar, struct ath12k_link_vif *arvif,
+ struct ath12k_link_sta *arsta)
{
struct ath12k_base *ab = ar->ab;
- struct ath12k_peer *peer;
- u32 reo_dest;
- int ret = 0, tid;
+ struct ieee80211_sta *sta;
+ u32 reo_dest, param_value;
+ u32 lmac_peer_routing_id = ATH12K_DP_LMAC_PEER_ID_LEGACY;
+ int ret;
- /* TODO setup resources only for primary link peer for ML case */
+ sta = container_of((void *)arsta->ahsta, struct ieee80211_sta, drv_priv);
/* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */
reo_dest = ar->dp.mac_id + 1;
- ret = ath12k_wmi_set_peer_param(ar, addr, vdev_id,
- WMI_PEER_SET_DEFAULT_ROUTING,
- DP_RX_HASH_ENABLE | (reo_dest << 1));
+ param_value = (reo_dest << 1 | DP_RX_HASH_ENABLE);
+
+ /* For MLO supported peers and it has multi link capablity, use MLO conf */
+ if (hweight16(sta->valid_links) > 1)
+ lmac_peer_routing_id = ATH12K_DP_LMAC_PEER_ID_MLO;
+ param_value |= FIELD_PREP(ATH12K_DP_PEER_ROUTING_LMAC_ID_MASK,
+ lmac_peer_routing_id);
+
+ ret = ath12k_wmi_set_peer_param(ar, arsta->addr, arvif->vdev_id,
+ WMI_PEER_SET_DEFAULT_ROUTING, param_value);
if (ret) {
ath12k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n",
- ret, addr, vdev_id);
+ ret, arsta->addr, arvif->vdev_id);
return ret;
}
+ ath12k_dbg(ab, ATH12K_DBG_DP_RX, "peer %pM set def route id %d sta_link %d\n",
+ arsta->addr, lmac_peer_routing_id,
+ hweight16(sta->valid_links));
+
+ return 0;
+}
+
+int ath12k_dp_peer_setup(struct ath12k *ar, struct ath12k_link_vif *arvif,
+ struct ath12k_link_sta *arsta)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_peer *peer;
+ int ret = 0, tid;
+
+ /* TODO setup resources only for primary link peer for ML case */
+
for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
- ret = ath12k_dp_rx_peer_tid_setup(ar, addr, vdev_id, tid, 1, 0,
- HAL_PN_TYPE_NONE);
+ ret = ath12k_dp_rx_peer_tid_setup(ar, arsta->addr, arvif->vdev_id,
+ tid, 1, 0, HAL_PN_TYPE_NONE);
if (ret) {
ath12k_warn(ab, "failed to setup rxd tid queue for tid %d: %d\n",
tid, ret);
@@ -78,7 +107,7 @@ int ath12k_dp_peer_setup(struct ath12k *
}
}
- ret = ath12k_dp_rx_peer_frag_setup(ar, addr, vdev_id);
+ ret = ath12k_dp_rx_peer_frag_setup(ar, arsta->addr, arvif->vdev_id);
if (ret) {
ath12k_warn(ab, "failed to setup rx defrag context\n");
tid--;
@@ -92,7 +121,7 @@ int ath12k_dp_peer_setup(struct ath12k *
peer_clean:
spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find(ab, vdev_id, addr);
+ peer = ath12k_peer_find(ab, arvif->vdev_id, arsta->addr);
if (!peer) {
ath12k_warn(ab, "failed to find the peer to del rx tid\n");
spin_unlock_bh(&ab->base_lock);
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -16,6 +16,7 @@ struct ath12k_base;
struct ath12k_peer;
struct ath12k_dp;
struct ath12k_link_vif;
+struct ath12k_link_sta;
struct hal_tcl_status_ring;
struct ath12k_ext_irq_grp;
@@ -2172,7 +2173,11 @@ void ath12k_dp_pdev_pre_alloc(struct ath
void ath12k_dp_pdev_free(struct ath12k_base *ab);
int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
int mac_id, enum hal_ring_type ring_type);
-int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr);
+int ath12k_dp_peer_default_route_setup(struct ath12k *ar,
+ struct ath12k_link_vif *arvif,
+ struct ath12k_link_sta *arsta);
+int ath12k_dp_peer_setup(struct ath12k *ar, struct ath12k_link_vif *arvif,
+ struct ath12k_link_sta *arsta);
void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr);
void ath12k_dp_srng_cleanup(struct ath12k_base *ab, struct dp_srng *ring);
int ath12k_dp_srng_setup(struct ath12k_base *ab, struct dp_srng *ring,
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -6620,7 +6620,7 @@ static int ath12k_mac_station_add(struct
}
}
- ret = ath12k_dp_peer_setup(ar, arvif->vdev_id, arsta->addr);
+ ret = ath12k_dp_peer_setup(ar, arvif, arsta);
if (ret) {
ath12k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n",
arsta->addr, arvif->vdev_id, ret);
@@ -6871,14 +6871,18 @@ static int ath12k_mac_handle_link_sta_st
ath12k_mac_free_unassign_link_sta(arvif->ahvif->ah,
arsta->ahsta, arsta->link_id);
} else if (old_state == IEEE80211_STA_AUTH &&
- new_state == IEEE80211_STA_ASSOC &&
- (vif->type == NL80211_IFTYPE_AP ||
+ new_state == IEEE80211_STA_ASSOC) {
+
+ ath12k_dp_peer_default_route_setup(ar, arvif, arsta);
+
+ if (vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_MESH_POINT ||
- vif->type == NL80211_IFTYPE_ADHOC)) {
- ret = ath12k_station_assoc(ar, arvif, arsta, false);
- if (ret)
- ath12k_warn(ar->ab, "Failed to associate station: %pM\n",
- arsta->addr);
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ ret = ath12k_station_assoc(ar, arvif, arsta, false);
+ if (ret)
+ ath12k_warn(ar->ab, "Failed to associate station: %pM\n",
+ arsta->addr);
+ }
} else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTHORIZED) {
ret = ath12k_station_authorize(ar, arvif, arsta);