Blob Blame History Raw
From 24b6fe7240e15b6df53b0ace61a70f58e09f6fc6 Mon Sep 17 00:00:00 2001
From: Ryan Hsu <ryanhsu@codeaurora.org>
Date: Fri, 8 Jun 2018 11:32:39 -0700
Subject: [PATCH] ath10k: Update the phymode along with bandwidth change
 request

In the case of Station connects to AP with narrower bandwidth at beginning.
And later the AP changes the bandwidth to winder bandwidth, the AP will
beacon with wider bandwidth IE, eg VHT20->VHT40->VHT80 or VHT40->VHT80.

Since the supported BANDWIDTH will be limited by the PHYMODE, so while
Station receives the bandwidth change request, it will also need to
reconfigure the PHYMODE setting to firmware instead of just configuring
the BANDWIDTH info, otherwise it'll trigger a firmware crash with
non-support bandwidth.

The issue was observed in WLAN.RM.4.4.1-00051-QCARMSWP-1, QCA6174 with
below scenario.

Reported-by: Rouven Czerwinski <rouven@czerwinskis.de>
Signed-off-by: Ryan Hsu <ryanhsu@codeaurora.org>
Signed-off-by: Jeremy Cline <jcline@redhat.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 16 ++++++++++++++--
 drivers/net/wireless/ath/ath10k/wmi.h |  1 +
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 2d7ef7460780..72d61ca3cb42 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -5996,8 +5996,19 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
 			   ath10k_mac_max_vht_nss(vht_mcs_mask)));
 
 	if (changed & IEEE80211_RC_BW_CHANGED) {
-		ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
-			   sta->addr, bw);
+		enum wmi_phy_mode mode;
+
+		mode = chan_to_phymode(&def);
+		ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n",
+				sta->addr, bw, mode);
+
+		err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
+				WMI_PEER_PHYMODE, mode);
+		if (err) {
+			ath10k_warn(ar, "failed to update STA %pM peer phymode %d: %d\n",
+					sta->addr, mode, err);
+			goto exit;
+		}
 
 		err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
 						WMI_PEER_CHAN_WIDTH, bw);
@@ -6038,6 +6049,7 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
 				    sta->addr);
 	}
 
+exit:
 	mutex_unlock(&ar->conf_mutex);
 }
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index c7b30ed9015d..930a0e1b1163 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -6010,6 +6010,7 @@ enum wmi_peer_param {
 	WMI_PEER_NSS        = 0x5,
 	WMI_PEER_USE_4ADDR  = 0x6,
 	WMI_PEER_DEBUG      = 0xa,
+	WMI_PEER_PHYMODE    = 0xd,
 	WMI_PEER_DUMMY_VAR  = 0xff, /* dummy parameter for STA PS workaround */
 };
 
-- 
2.17.1