mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
195 lines
7.4 KiB
Diff
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);
|