[PATCH] ath10k: add recalc RTS/CTS protection method

Subsystems: atheros ath generic utilities, qualcomm atheros ath10k wireless driver, the rest

STALE4543d

3 messages, 2 authors, 2014-03-03 · open the first message on its own page

[PATCH] ath10k: add recalc RTS/CTS protection method

From: <hidden>
Date: 2014-02-28 07:18:55

From: Marek Kwaczynski <redacted>

Add recalculation of RTS/CTS protection when one or more legacy
stations are connected to ath10k. In this case enable RTS/CTS
protection and set sw retry profile are needed in the FW.
Without this change legacy station is starved and has very low
throughput.

Signed-off-by: Marek Kwaczynski <redacted>
---
 drivers/net/wireless/ath/ath10k/core.h |    3 ++
 drivers/net/wireless/ath/ath10k/mac.c  |   57 +++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath10k/wmi.h  |   13 ++++++++
 3 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index d1c5e7a..c0e4fae 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -289,6 +289,9 @@ struct ath10k_vif {
 	u8 fixed_rate;
 	u8 fixed_nss;
 	u8 force_sgi;
+
+	bool use_cts_prot;
+	int num_legacy_stations;
 };
 
 struct ath10k_vif_iter {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 239357f..96b0f59 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -723,6 +723,26 @@ static int ath10k_monitor_destroy(struct ath10k *ar)
 	return ret;
 }
 
+static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
+{
+	struct ath10k *ar = arvif->ar;
+	u32 vdev_param, rts_cts = 0;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	vdev_param = ar->wmi.vdev_param->enable_rtscts;
+
+	if (arvif->use_cts_prot || arvif->num_legacy_stations > 0)
+		rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
+
+	if (arvif->num_legacy_stations > 0)
+		rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
+			      WMI_RTSCTS_PROFILE);
+
+	return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+					 rts_cts);
+}
+
 static int ath10k_start_cac(struct ath10k *ar)
 {
 	int ret;
@@ -1532,6 +1552,16 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
 		return ret;
 	}
 
+	if (!sta->wme) {
+		arvif->num_legacy_stations++;
+		ret = ath10k_recalc_rtscts_prot(arvif);
+		if (ret) {
+			ath10k_warn("Failed to recalculate RTS/CTS: %d\n",
+				    ret);
+			return ret;
+		}
+	}
+
 	ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
 	if (ret) {
 		ath10k_warn("could not install peer wep keys (%d)\n", ret);
@@ -1555,6 +1585,16 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif,
 
 	lockdep_assert_held(&ar->conf_mutex);
 
+	if (!sta->wme) {
+		arvif->num_legacy_stations--;
+		ret = ath10k_recalc_rtscts_prot(arvif);
+		if (ret) {
+			ath10k_warn("failed to recalc RTS/CTS %d\n",
+				    ret);
+			return ret;
+		}
+	}
+
 	ret = ath10k_clear_peer_keys(arvif, sta->addr);
 	if (ret) {
 		ath10k_warn("could not clear all peer wep keys (%d)\n", ret);
@@ -2838,21 +2878,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 		ath10k_control_beaconing(arvif, info);
 
 	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-		u32 cts_prot;
-		if (info->use_cts_prot)
-			cts_prot = 1;
-		else
-			cts_prot = 0;
-
+		arvif->use_cts_prot = info->use_cts_prot;
 		ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
-			   arvif->vdev_id, cts_prot);
+			   arvif->vdev_id, info->use_cts_prot);
 
-		vdev_param = ar->wmi.vdev_param->enable_rtscts;
-		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-						cts_prot);
+		ret = ath10k_recalc_rtscts_prot(arvif);
 		if (ret)
-			ath10k_warn("Failed to set CTS prot for VDEV: %d\n",
-				    arvif->vdev_id);
+			ath10k_warn("failed to recalc RTS/CTS prot %d\n",
+				    ret);
 	}
 
 	if (changed & BSS_CHANGED_ERP_SLOT) {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 4fcc96a..e78a7ad 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2210,6 +2210,19 @@ enum ath10k_protmode {
 	ATH10K_PROT_RTSCTS   = 2,    /* RTS-CTS */
 };
 
+enum wmi_rtscts_profile {
+	WMI_RTSCTS_FOR_NO_RATESERIES = 0,
+	WMI_RTSCTS_FOR_SECOND_RATESERIES,
+	WMI_RTSCTS_ACROSS_SW_RETRIES
+};
+
+#define WMI_RTSCTS_ENABLED		1
+#define WMI_RTSCTS_SET_MASK		0x0f
+#define WMI_RTSCTS_SET_LSB		0
+
+#define WMI_RTSCTS_PROFILE_MASK		0xf0
+#define WMI_RTSCTS_PROFILE_LSB		4
+
 enum wmi_beacon_gen_mode {
 	WMI_BEACON_STAGGERED_MODE = 0,
 	WMI_BEACON_BURST_MODE = 1
-- 
1.7.10

Re: [PATCH] ath10k: add recalc RTS/CTS protection method

From: Ben Greear <hidden>
Date: 2014-02-28 17:46:58

On 02/27/2014 11:18 PM, bartosz.markowski@tieto.com wrote:
From: Marek Kwaczynski <redacted>

Add recalculation of RTS/CTS protection when one or more legacy
stations are connected to ath10k. In this case enable RTS/CTS
protection and set sw retry profile are needed in the FW.
Without this change legacy station is starved and has very low
throughput.
-			ath10k_warn("Failed to set CTS prot for VDEV: %d\n",
-				    arvif->vdev_id);
+			ath10k_warn("failed to recalc RTS/CTS prot %d\n",
+				    ret);
Did you remove the vdev ID from the logging message on purpose?

I find having vdev ID in logging messages helps, especially when
trying to compare firmware logs with the driver logs...

Thanks,
Ben


-- 
Ben Greear [off-list ref]
Candela Technologies Inc  http://www.candelatech.com

Re: [PATCH] ath10k: add recalc RTS/CTS protection method

From: Bartosz Markowski <hidden>
Date: 2014-03-03 07:35:50

On 28 February 2014 18:46, Ben Greear [off-list ref] wrote:
On 02/27/2014 11:18 PM, bartosz.markowski@tieto.com wrote:
quoted
From: Marek Kwaczynski <redacted>

Add recalculation of RTS/CTS protection when one or more legacy
stations are connected to ath10k. In this case enable RTS/CTS
protection and set sw retry profile are needed in the FW.
Without this change legacy station is starved and has very low
throughput.
quoted
-                     ath10k_warn("Failed to set CTS prot for VDEV: %d\n",
-                                 arvif->vdev_id);
+                     ath10k_warn("failed to recalc RTS/CTS prot %d\n",
+                                 ret);
Did you remove the vdev ID from the logging message on purpose?

I find having vdev ID in logging messages helps, especially when
trying to compare firmware logs with the driver logs...
Not on purpose. Thanks for pointing it out.
Kalle, please ignore this patch, there'll be v2.

-- 
Bartosz
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help