mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
173 lines
5.7 KiB
Diff
173 lines
5.7 KiB
Diff
From a75917bb593a5bc04b5d2081ae303d17b8095f8b Mon Sep 17 00:00:00 2001
|
|
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
Date: Tue, 17 May 2022 12:26:48 +0530
|
|
Subject: [PATCH] ath11k: fix bandwidth change issue for peer sta
|
|
|
|
Currently, ath11k sends peer assoc command for each peer to
|
|
firmware when bandwidth changes. Peer assoc command is a
|
|
bulky command and if many clients connected, this could lead
|
|
to firmware buffer getting overflowed leading to firmware
|
|
assert.
|
|
|
|
However, during bandwidth change, only phymode and bandwidth
|
|
also can be updated by WMI set peer param command. This makes
|
|
the overall command light when compared to peer assoc and for
|
|
multi-client cases, firmware buffer overflow also does not
|
|
occur.
|
|
|
|
Remove sending peer assoc command during sta bandwidth change
|
|
and instead add sending WMI set peer param command for phymode
|
|
and bandwidth.
|
|
|
|
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/mac.c | 75 ++++++++++++++++++++------
|
|
2 files changed, 60 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
|
|
index bd46279..019347b 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -627,6 +627,7 @@ struct ath11k_sta {
|
|
#ifdef CPTCFG_ATH11K_CFR
|
|
struct ath11k_per_peer_cfr_capture cfr_capture;
|
|
#endif
|
|
+ u32 bw_last;
|
|
};
|
|
|
|
#define ATH11K_HALF_20MHZ_BW 10
|
|
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
|
|
index 1dcfc43..b30c9a1 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -5362,11 +5362,12 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
|
|
const u8 *ht_mcs_mask;
|
|
const u16 *vht_mcs_mask;
|
|
const u16 *he_mcs_mask;
|
|
- u32 changed, bw, nss, smps;
|
|
+ u32 changed, bw, nss, smps, bw_last;
|
|
int err, num_ht_rates, num_vht_rates, num_he_rates;
|
|
const struct cfg80211_bitrate_mask *mask;
|
|
struct peer_assoc_params peer_arg;
|
|
bool peer_dbg_info, debug;
|
|
+ enum wmi_phy_mode peer_phymode;
|
|
|
|
arsta = container_of(wk, struct ath11k_sta, update_wk);
|
|
sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
|
|
@@ -5392,6 +5393,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
|
|
arsta->changed = 0;
|
|
|
|
bw = arsta->bw;
|
|
+ bw_last = arsta->bw_last;
|
|
nss = arsta->nss;
|
|
smps = arsta->smps;
|
|
|
|
@@ -5407,26 +5409,58 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
|
|
ath11k_mac_max_he_nss(he_mcs_mask)));
|
|
|
|
if (changed & IEEE80211_RC_BW_CHANGED) {
|
|
- /* Send peer assoc command before set peer bandwidth param to
|
|
- * avoid the mismatch between the peer phymode and the peer
|
|
- * bandwidth.
|
|
- */
|
|
- debug = ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true);
|
|
-
|
|
- peer_arg.is_assoc = false;
|
|
- err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg, debug);
|
|
- if (err) {
|
|
- ath11k_warn(ar->ab, "failed to send peer assoc for STA %pM vdev %i: %d\n",
|
|
- sta->addr, arvif->vdev_id, err);
|
|
- } else if (wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) {
|
|
+ /* Get the the peer phymode */
|
|
+ ath11k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg);
|
|
+ peer_phymode = peer_arg.peer_phymode;
|
|
+
|
|
+ if (peer_dbg_info)
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER, "mac update sta %pM peer bw %d phymode %d\n",
|
|
+ sta->addr, bw, peer_phymode);
|
|
+
|
|
+ if (bw > bw_last) {
|
|
+ /* BW is upgraded. In this case we send WMI_PEER_PHYMODE
|
|
+ * followed by WMI_PEER_CHWIDTH
|
|
+ */
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW upgrade for sta %pM new BW %d, old BW %d\n",
|
|
+ sta->addr, bw, bw_last);
|
|
+
|
|
err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
|
|
- WMI_PEER_CHWIDTH, bw);
|
|
+ WMI_PEER_PHYMODE, peer_phymode);
|
|
+
|
|
+ if (err) {
|
|
+ ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",
|
|
+ sta->addr, peer_phymode, err);
|
|
+ goto err_rc_bw_changed;
|
|
+ }
|
|
+
|
|
+ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
|
|
+ WMI_PEER_CHWIDTH, bw);
|
|
+
|
|
if (err)
|
|
ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
|
|
sta->addr, bw, err);
|
|
} else {
|
|
- ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",
|
|
- sta->addr, arvif->vdev_id);
|
|
+ /* BW is downgraded. In this case we send WMI_PEER_CHWIDTH
|
|
+ * followed by WMI_PEER_PHYMODE
|
|
+ */
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW downgrade for sta %pM new BW %d,old BW %d\n",
|
|
+ sta->addr, bw, bw_last);
|
|
+
|
|
+ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
|
|
+ WMI_PEER_CHWIDTH, bw);
|
|
+
|
|
+ if (err) {
|
|
+ ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
|
|
+ sta->addr, bw, err);
|
|
+ goto err_rc_bw_changed;
|
|
+ }
|
|
+
|
|
+ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
|
|
+ WMI_PEER_PHYMODE, peer_phymode);
|
|
+
|
|
+ if (err)
|
|
+ ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",
|
|
+ sta->addr, peer_phymode, err);
|
|
}
|
|
}
|
|
|
|
@@ -5518,6 +5552,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
|
|
}
|
|
}
|
|
|
|
+err_rc_bw_changed:
|
|
mutex_unlock(&ar->conf_mutex);
|
|
}
|
|
|
|
@@ -6153,6 +6188,13 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
|
|
|
|
spin_unlock_bh(&ar->ab->base_lock);
|
|
|
|
+ spin_lock_bh(&ar->data_lock);
|
|
+
|
|
+ /* Set arsta bw and last bw */
|
|
+ arsta->bw = arsta->bw_last = sta->deflink.bandwidth;
|
|
+
|
|
+ spin_unlock_bh(&ar->data_lock);
|
|
+
|
|
if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) {
|
|
ret = ath11k_wmi_set_peer_param(ar, sta->addr,
|
|
arvif->vdev_id,
|
|
@@ -6352,6 +6394,7 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
|
|
break;
|
|
}
|
|
|
|
+ arsta->bw_last = arsta->bw;
|
|
arsta->bw = bw;
|
|
}
|
|
|
|
--
|
|
2.17.1
|
|
|