Oliver Neukum ebc237
From c6522a5076e1a65877c51cfee313a74ef61cabf8 Mon Sep 17 00:00:00 2001
Oliver Neukum ebc237
From: Loic Poulain <loic.poulain@linaro.org>
Oliver Neukum ebc237
Date: Tue, 25 Aug 2020 15:45:27 +0200
Oliver Neukum ebc237
Subject: [PATCH] wcn36xx: Disable bmps when encryption is disabled
Oliver Neukum ebc237
Git-commit: c6522a5076e1a65877c51cfee313a74ef61cabf8
Oliver Neukum ebc237
References: git-fixes
Oliver Neukum ebc237
Patch-mainline: v5.10-rc1
Oliver Neukum ebc237
Oliver Neukum ebc237
For whatever reason, when connected to an open/no-security BSS,
Oliver Neukum ebc237
the wcn36xx controller in bmps mode does not forward 'wake-up'
Oliver Neukum ebc237
beacons despite AP sends DTIM with station AID.
Oliver Neukum ebc237
Oliver Neukum ebc237
Meaning that AP is not able to wakeup the station and needs to wait
Oliver Neukum ebc237
for the station to wakeup by its own (TX data, keep alive pkt...),
Oliver Neukum ebc237
causing serious latency issues and unexpected deauth.
Oliver Neukum ebc237
Oliver Neukum ebc237
When connected to AP with encryption enabled, this issue does not occur.
Oliver Neukum ebc237
So a simple workaround is to only enable bmps support in that case.
Oliver Neukum ebc237
Oliver Neukum ebc237
Ideally, it should be propertly fixed to allow bmps support with open
Oliver Neukum ebc237
BSS, whatever the issue is at driver or firmware level.
Oliver Neukum ebc237
Oliver Neukum ebc237
Tested on wcn3620 and wcn3680.
Oliver Neukum ebc237
Oliver Neukum ebc237
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Oliver Neukum ebc237
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Oliver Neukum ebc237
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Oliver Neukum ebc237
Link: https://lore.kernel.org/r/1598363127-26066-1-git-send-email-loic.poulain@linaro.org
Oliver Neukum ebc237
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Oliver Neukum ebc237
---
Oliver Neukum ebc237
 drivers/net/wireless/ath/wcn36xx/main.c    | 10 ++++++++++
Oliver Neukum ebc237
 drivers/net/wireless/ath/wcn36xx/pmc.c     |  5 ++++-
Oliver Neukum ebc237
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  1 +
Oliver Neukum ebc237
 3 files changed, 15 insertions(+), 1 deletion(-)
Oliver Neukum ebc237
Oliver Neukum ebc237
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
Oliver Neukum ebc237
index 2c3e68646fe4..8becd667fe7b 100644
Oliver Neukum ebc237
--- a/drivers/net/wireless/ath/wcn36xx/main.c
Oliver Neukum ebc237
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
Oliver Neukum ebc237
@@ -610,6 +610,15 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
Oliver Neukum ebc237
 				}
Oliver Neukum ebc237
 			}
Oliver Neukum ebc237
 		}
Oliver Neukum ebc237
+		/* FIXME: Only enable bmps support when encryption is enabled.
Oliver Neukum ebc237
+		 * For any reasons, when connected to open/no-security BSS,
Oliver Neukum ebc237
+		 * the wcn36xx controller in bmps mode does not forward
Oliver Neukum ebc237
+		 * 'wake-up' beacons despite AP sends DTIM with station AID.
Oliver Neukum ebc237
+		 * It could be due to a firmware issue or to the way driver
Oliver Neukum ebc237
+		 * configure the station.
Oliver Neukum ebc237
+		 */
Oliver Neukum ebc237
+		if (vif->type == NL80211_IFTYPE_STATION)
Oliver Neukum ebc237
+			vif_priv->allow_bmps = true;
Oliver Neukum ebc237
 		break;
Oliver Neukum ebc237
 	case DISABLE_KEY:
Oliver Neukum ebc237
 		if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) {
Oliver Neukum ebc237
@@ -891,6 +900,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
Oliver Neukum ebc237
 				    vif->addr,
Oliver Neukum ebc237
 				    bss_conf->aid);
Oliver Neukum ebc237
 			vif_priv->sta_assoc = false;
Oliver Neukum ebc237
+			vif_priv->allow_bmps = false;
Oliver Neukum ebc237
 			wcn36xx_smd_set_link_st(wcn,
Oliver Neukum ebc237
 						bss_conf->bssid,
Oliver Neukum ebc237
 						vif->addr,
Oliver Neukum ebc237
diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c
Oliver Neukum ebc237
index 1976b80c235f..8441031b667c 100644
Oliver Neukum ebc237
--- a/drivers/net/wireless/ath/wcn36xx/pmc.c
Oliver Neukum ebc237
+++ b/drivers/net/wireless/ath/wcn36xx/pmc.c
Oliver Neukum ebc237
@@ -23,7 +23,10 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
Oliver Neukum ebc237
 {
Oliver Neukum ebc237
 	int ret = 0;
Oliver Neukum ebc237
 	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
Oliver Neukum ebc237
-	/* TODO: Make sure the TX chain clean */
Oliver Neukum ebc237
+
Oliver Neukum ebc237
+	if (!vif_priv->allow_bmps)
Oliver Neukum ebc237
+		return -ENOTSUPP;
Oliver Neukum ebc237
+
Oliver Neukum ebc237
 	ret = wcn36xx_smd_enter_bmps(wcn, vif);
Oliver Neukum ebc237
 	if (!ret) {
Oliver Neukum ebc237
 		wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n");
Oliver Neukum ebc237
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
Oliver Neukum ebc237
index 3221fed15620..719a6daf9298 100644
Oliver Neukum ebc237
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
Oliver Neukum ebc237
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
Oliver Neukum ebc237
@@ -122,6 +122,7 @@ struct wcn36xx_vif {
Oliver Neukum ebc237
 	enum wcn36xx_hal_bss_type bss_type;
Oliver Neukum ebc237
 
Oliver Neukum ebc237
 	/* Power management */
Oliver Neukum ebc237
+	bool allow_bmps;
Oliver Neukum ebc237
 	enum wcn36xx_power_state pw_state;
Oliver Neukum ebc237
 
Oliver Neukum ebc237
 	u8 bss_index;
Oliver Neukum ebc237
-- 
Oliver Neukum ebc237
2.40.1
Oliver Neukum ebc237