diff options
Diffstat (limited to 'package/kernel/mac80211/patches/ath11k/0006-wifi-ath11k-fix-firmware-assert-during-bandwidth-cha.patch')
-rw-r--r-- | package/kernel/mac80211/patches/ath11k/0006-wifi-ath11k-fix-firmware-assert-during-bandwidth-cha.patch | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/package/kernel/mac80211/patches/ath11k/0006-wifi-ath11k-fix-firmware-assert-during-bandwidth-cha.patch b/package/kernel/mac80211/patches/ath11k/0006-wifi-ath11k-fix-firmware-assert-during-bandwidth-cha.patch deleted file mode 100644 index f4fedb46cc..0000000000 --- a/package/kernel/mac80211/patches/ath11k/0006-wifi-ath11k-fix-firmware-assert-during-bandwidth-cha.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 3ff51d7416ee1ea2d771051a0ffa1ec8be054768 Mon Sep 17 00:00:00 2001 -From: Aditya Kumar Singh <quic_adisi@quicinc.com> -Date: Wed, 5 Oct 2022 15:24:30 +0530 -Subject: [PATCH 6/9] wifi: ath11k: fix firmware assert during bandwidth change - 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 are connected, this could -lead to firmware buffer getting overflowed leading to a 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. - -Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 - -Fixes: f187fe8e3bc65 ("ath11k: fix firmware crash during channel switch") -Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com> -Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> -Link: https://lore.kernel.org/r/20221005095430.19890-1-quic_adisi@quicinc.com ---- - drivers/net/wireless/ath/ath11k/core.h | 2 + - drivers/net/wireless/ath/ath11k/mac.c | 122 +++++++++++++++++-------- - 2 files changed, 87 insertions(+), 37 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -505,6 +505,8 @@ struct ath11k_sta { - u64 ps_start_jiffies; - u64 ps_total_duration; - bool peer_current_ps_valid; -+ -+ u32 bw_prev; - }; - - #define ATH11K_MIN_5G_FREQ 4150 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4215,10 +4215,11 @@ static void ath11k_sta_rc_update_wk(stru - 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_prev; - int err, num_vht_rates, num_he_rates; - const struct cfg80211_bitrate_mask *mask; - struct peer_assoc_params peer_arg; -+ 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); -@@ -4239,6 +4240,7 @@ static void ath11k_sta_rc_update_wk(stru - arsta->changed = 0; - - bw = arsta->bw; -+ bw_prev = arsta->bw_prev; - nss = arsta->nss; - smps = arsta->smps; - -@@ -4252,26 +4254,57 @@ static void ath11k_sta_rc_update_wk(stru - 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. -- */ -- ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true); -+ /* Get the peer phymode */ -+ ath11k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg); -+ peer_phymode = peer_arg.peer_phymode; -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n", -+ sta->addr, bw, peer_phymode); -+ -+ if (bw > bw_prev) { -+ /* 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_prev); -+ -+ 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); -+ goto err_rc_bw_changed; -+ } - -- peer_arg.is_assoc = false; -- err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg); -- 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)) { - 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_prev); -+ -+ 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); - } - } - -@@ -4352,6 +4385,7 @@ static void ath11k_sta_rc_update_wk(stru - } - } - -+err_rc_bw_changed: - mutex_unlock(&ar->conf_mutex); - } - -@@ -4505,6 +4539,34 @@ exit: - return ret; - } - -+static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, -+ struct ieee80211_sta *sta) -+{ -+ u32 bw = WMI_PEER_CHWIDTH_20MHZ; -+ -+ switch (sta->deflink.bandwidth) { -+ case IEEE80211_STA_RX_BW_20: -+ bw = WMI_PEER_CHWIDTH_20MHZ; -+ break; -+ case IEEE80211_STA_RX_BW_40: -+ bw = WMI_PEER_CHWIDTH_40MHZ; -+ break; -+ case IEEE80211_STA_RX_BW_80: -+ bw = WMI_PEER_CHWIDTH_80MHZ; -+ break; -+ case IEEE80211_STA_RX_BW_160: -+ bw = WMI_PEER_CHWIDTH_160MHZ; -+ break; -+ default: -+ ath11k_warn(ar->ab, "Invalid bandwidth %d for %pM\n", -+ sta->deflink.bandwidth, sta->addr); -+ bw = WMI_PEER_CHWIDTH_20MHZ; -+ break; -+ } -+ -+ return bw; -+} -+ - static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, -@@ -4590,6 +4652,12 @@ static int ath11k_mac_op_sta_state(struc - if (ret) - ath11k_warn(ar->ab, "Failed to associate station: %pM\n", - sta->addr); -+ -+ spin_lock_bh(&ar->data_lock); -+ /* Set arsta bw and prev bw */ -+ arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); -+ arsta->bw_prev = arsta->bw; -+ spin_unlock_bh(&ar->data_lock); - } else if (old_state == IEEE80211_STA_ASSOC && - new_state == IEEE80211_STA_AUTHORIZED) { - spin_lock_bh(&ar->ab->base_lock); -@@ -4713,28 +4781,8 @@ static void ath11k_mac_op_sta_rc_update( - spin_lock_bh(&ar->data_lock); - - if (changed & IEEE80211_RC_BW_CHANGED) { -- bw = WMI_PEER_CHWIDTH_20MHZ; -- -- switch (sta->deflink.bandwidth) { -- case IEEE80211_STA_RX_BW_20: -- bw = WMI_PEER_CHWIDTH_20MHZ; -- break; -- case IEEE80211_STA_RX_BW_40: -- bw = WMI_PEER_CHWIDTH_40MHZ; -- break; -- case IEEE80211_STA_RX_BW_80: -- bw = WMI_PEER_CHWIDTH_80MHZ; -- break; -- case IEEE80211_STA_RX_BW_160: -- bw = WMI_PEER_CHWIDTH_160MHZ; -- break; -- default: -- ath11k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n", -- sta->deflink.bandwidth, sta->addr); -- bw = WMI_PEER_CHWIDTH_20MHZ; -- break; -- } -- -+ bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); -+ arsta->bw_prev = arsta->bw; - arsta->bw = bw; - } - |