Skip to content
Snippets Groups Projects
0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch 12 KiB
Newer Older
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 8 Feb 2019 21:20:20 +0100
Subject: ath10k-ct: support for multicast and management rate control

Drivers with software rate control can directly use the selected multicast
rate for multicast/broadcast frames and the minimal basic rate for
management frames. But drivers with offloaded rate control algorithms must
be informed about such upper layer decisions to configure the
hardware/firmware.

A new BSS_CHANGED_MCAST_RATE is introduced in mac80211 to automatically
inform all drivers. ath10k-ct can detect this event and forward it via WMI
to the driver. The already existing BSS_CHANGED_BASIC_RATES can be used to
select the management rate.

Without the WMI commands, a low rate (not necessarily one from the basic
rates) is used for bcast/mcast/management frames. This means that the
/etc/config/wireless settings basic_rate and mcast_rate would have no
effect on the rates selected by this driver for the mentioned frames.

Signed-off-by: Sven Eckelmann <sven@narfation.org>

diff --git a/package/kernel/ath10k-ct/patches/976-ath10k-support-for-multicast-rate-control.patch b/package/kernel/ath10k-ct/patches/976-ath10k-support-for-multicast-rate-control.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bd60bf317dec3a2eec1fd9263037acc30d272e39
--- /dev/null
+++ b/package/kernel/ath10k-ct/patches/976-ath10k-support-for-multicast-rate-control.patch
@@ -0,0 +1,112 @@
+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+Date: Wed, 25 Jul 2018 10:59:39 +0300
+Subject: [PATCH] ath10k: support for multicast rate control
+
+Issues a wmi command to firmware when multicast rate change is received with the
+new BSS_CHANGED_MCAST_RATE flag.  Also fixes the incorrect fixed_rate setting
+for CCK rates which got introduced with addition of ath10k_rates_rev2 enum.
+
+Tested on QCA9984 with firmware ver 10.4-3.6-00104
+
+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+
+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cd93b83ad927b2c7979e0add0343ace59328b461
+---
+ ath10k-4.13/mac.c | 54 +++++++++++++++++++++++++--
+ 1 file changed, 50 insertions(+), 4 deletions(-)
+
+diff --git a/ath10k-4.13/mac.c b/ath10k-4.13/mac.c
+index 5683f1a5330eedae677aad5bf2621a6232781346..1937526c8c18da85f7730429759391d47e12cf81 100644
+--- a/ath10k-4.13/mac.c
++++ b/ath10k-4.13/mac.c
+@@ -100,6 +100,8 @@ static struct ieee80211_rate ath10k_rates_rev2[] = {
+ #define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
+ #define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
+ 
++#define ath10k_wmi_legacy_rates ath10k_rates
++
+ static bool ath10k_mac_bitrate_is_cck(int bitrate)
+ {
+ 	switch (bitrate) {
+@@ -5389,8 +5391,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
+ {
+ 	struct ath10k *ar = hw->priv;
+ 	struct ath10k_vif *arvif = (void *)vif->drv_priv;
+-	int ret = 0;
++	struct cfg80211_chan_def def;
+ 	u32 vdev_param, pdev_param, slottime, preamble;
++	u16 bitrate, hw_value;
++	u8 rate;
++	int rateidx, ret = 0;
++	enum nl80211_band band;
+ 
+ 	mutex_lock(&ar->conf_mutex);
+ 
+@@ -5558,6 +5564,44 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
+ 				    arvif->vdev_id, ret);
+ 	}
+ 
++	if (changed & BSS_CHANGED_MCAST_RATE &&
++	    !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
++		band = def.chan->band;
++		rateidx = vif->bss_conf.mcast_rate[band] - 1;
++
++		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
++			rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
++
++		bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;
++		hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;
++		if (ath10k_mac_bitrate_is_cck(bitrate))
++			preamble = WMI_RATE_PREAMBLE_CCK;
++		else
++			preamble = WMI_RATE_PREAMBLE_OFDM;
++
++		rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);
++
++		ath10k_dbg(ar, ATH10K_DBG_MAC,
++			   "mac vdev %d mcast_rate %x\n",
++			   arvif->vdev_id, rate);
++
++		vdev_param = ar->wmi.vdev_param->mcast_data_rate;
++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
++						vdev_param, rate);
++		if (ret)
++			ath10k_warn(ar,
++				    "failed to set mcast rate on vdev %i: %d\n",
++				    arvif->vdev_id,  ret);
++
++		vdev_param = ar->wmi.vdev_param->bcast_data_rate;
++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
++						vdev_param, rate);
++		if (ret)
++			ath10k_warn(ar,
++				    "failed to set bcast rate on vdev %i: %d\n",
++				    arvif->vdev_id,  ret);
++	}
++
+ 	mutex_unlock(&ar->conf_mutex);
+ }
+ 
+@@ -6826,7 +6870,6 @@ ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
+ 					const struct cfg80211_bitrate_mask *mask,
+ 					u8 *rate, u8 *nss)
+ {
+-	struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
+ 	int rate_idx;
+ 	int i;
+ 	u16 bitrate;
+@@ -6836,8 +6879,11 @@ ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
+ 	if (hweight32(mask->control[band].legacy) == 1) {
+ 		rate_idx = ffs(mask->control[band].legacy) - 1;
+ 
+-		hw_rate = sband->bitrates[rate_idx].hw_value;
+-		bitrate = sband->bitrates[rate_idx].bitrate;
++		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
++			rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
++
++		hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
++		bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
+ 
+ 		if (ath10k_mac_bitrate_is_cck(bitrate))
+ 			preamble = WMI_RATE_PREAMBLE_CCK;
diff --git a/package/kernel/ath10k-ct/patches/977-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/ath10k-ct/patches/977-ath10k-add-support-for-configuring-management-packet.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6cc6df271fc73431b9467ac9878c360345e0754f
--- /dev/null
+++ b/package/kernel/ath10k-ct/patches/977-ath10k-add-support-for-configuring-management-packet.patch
@@ -0,0 +1,94 @@
+From: Sriram R <srirrama@codeaurora.org>
+Date: Mon, 10 Sep 2018 11:09:40 +0530
+Subject: [PATCH] ath10k: add support for configuring management packet rate
+
+By default the firmware uses 1Mbps and 6Mbps rate for management packets
+in 2G and 5G bands respectively. But when the user selects different
+basic rates from the userspace, we need to send the management
+packets at the lowest basic rate selected by the user.
+
+This change makes use of WMI_VDEV_PARAM_MGMT_RATE param for configuring the
+management packets rate to the firmware.
+
+Chipsets Tested : QCA988X, QCA9887, QCA9984
+FW Tested 	: 10.2.4-1.0-41, 10.4-3.6.104
+
+Signed-off-by: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+
+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f279294e9ee22a8f306fdc8e4181cf555e6f0f70
+---
+ ath10k-4.13/mac.c | 45 +++++++++++++++++++++++++--
+ 1 file changed, 43 insertions(+), 2 deletions(-)
+
+diff --git a/ath10k-4.13/mac.c b/ath10k-4.13/mac.c
+index 1937526c8c18da85f7730429759391d47e12cf81..47e5992afcd7564743f513eb250b57381aba3233 100644
+--- a/ath10k-4.13/mac.c
++++ b/ath10k-4.13/mac.c
+@@ -155,6 +155,22 @@ u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
+ 	return 0;
+ }
+ 
++static int ath10k_mac_get_rate_hw_value(int bitrate)
++{
++	int i;
++	u8 hw_value_prefix = 0;
++
++	if (ath10k_mac_bitrate_is_cck(bitrate))
++		hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
++
++	for (i = 0; i < sizeof(ath10k_rates); i++) {
++		if (ath10k_rates[i].bitrate == bitrate)
++			return hw_value_prefix | ath10k_rates[i].hw_value;
++	}
++
++	return -EINVAL;
++}
++
+ static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
+ {
+ 	switch ((mcs_map >> (2 * nss)) & 0x3) {
+@@ -5394,9 +5410,10 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
+ 	struct cfg80211_chan_def def;
+ 	u32 vdev_param, pdev_param, slottime, preamble;
+ 	u16 bitrate, hw_value;
+-	u8 rate;
+-	int rateidx, ret = 0;
++	u8 rate, basic_rate_idx;
++	int rateidx, ret = 0, hw_rate_code;
+ 	enum nl80211_band band;
++	const struct ieee80211_supported_band *sband;
+ 
+ 	mutex_lock(&ar->conf_mutex);
+ 
+@@ -5602,6 +5619,30 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
+ 				    arvif->vdev_id,  ret);
+ 	}
+ 
++	if (changed & BSS_CHANGED_BASIC_RATES) {
++		if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
++			mutex_unlock(&ar->conf_mutex);
++			return;
++		}
++
++	sband = ar->hw->wiphy->bands[def.chan->band];
++	basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
++	bitrate = sband->bitrates[basic_rate_idx].bitrate;
++
++	hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
++	if (hw_rate_code < 0) {
++		ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
++		mutex_unlock(&ar->conf_mutex);
++		return;
++	}
++
++	vdev_param = ar->wmi.vdev_param->mgmt_rate;
++	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
++					hw_rate_code);
++	if (ret)
++		ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
++	}
++
+ 	mutex_unlock(&ar->conf_mutex);
+ }
+ 
diff --git a/package/kernel/ath10k-ct/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/ath10k-ct/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cc13e547aa7e983fcff6137de9463e0b706651c5
--- /dev/null
+++ b/package/kernel/ath10k-ct/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
@@ -0,0 +1,70 @@
+From: Sriram R <srirrama@codeaurora.org>
+Date: Wed, 3 Oct 2018 08:43:50 +0530
+Subject: [PATCH] ath10k: fix possible out of bound access of ath10k_rates array
+
+While using 'ath10k_mac_get_rate_hw_value()' to obtain the hw value
+from the passed bitrate, there is a chance of out of bound array access
+when wrong bitrate is passed. This is fixed by comparing the bitrates
+within the correct size of the ath10k_rates array.
+
+Fixes commit f279294e9ee2 ("ath10k: add support for configuring management
+packet rate"). Also correction made to some indents used in the above commit.
+
+Signed-off-by: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+
+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e141eea7dd8525dd1ef7a925459e455b4d307f
+---
+ ath10k-4.13/mac.c | 30 +++++++++++++--------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/ath10k-4.13/mac.c b/ath10k-4.13/mac.c
+index 47e5992afcd7564743f513eb250b57381aba3233..e93b04c8e6fb2fa7968b910e0cc97ad8144bd7e8 100644
+--- a/ath10k-4.13/mac.c
++++ b/ath10k-4.13/mac.c
+@@ -163,7 +163,7 @@ static int ath10k_mac_get_rate_hw_value(int bitrate)
+ 	if (ath10k_mac_bitrate_is_cck(bitrate))
+ 		hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
+ 
+-	for (i = 0; i < sizeof(ath10k_rates); i++) {
++	for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
+ 		if (ath10k_rates[i].bitrate == bitrate)
+ 			return hw_value_prefix | ath10k_rates[i].hw_value;
+ 	}
+@@ -5625,22 +5625,22 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
+ 			return;
+ 		}
+ 
+-	sband = ar->hw->wiphy->bands[def.chan->band];
+-	basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
+-	bitrate = sband->bitrates[basic_rate_idx].bitrate;
++		sband = ar->hw->wiphy->bands[def.chan->band];
++		basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
++		bitrate = sband->bitrates[basic_rate_idx].bitrate;
+ 
+-	hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
+-	if (hw_rate_code < 0) {
+-		ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
+-		mutex_unlock(&ar->conf_mutex);
+-		return;
+-	}
++		hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
++		if (hw_rate_code < 0) {
++			ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
++			mutex_unlock(&ar->conf_mutex);
++			return;
++		}
+ 
+-	vdev_param = ar->wmi.vdev_param->mgmt_rate;
+-	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+-					hw_rate_code);
+-	if (ret)
+-		ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
++		vdev_param = ar->wmi.vdev_param->mgmt_rate;
++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
++						hw_rate_code);
++		if (ret)
++			ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
+ 	}
+ 
+ 	mutex_unlock(&ar->conf_mutex);