mac80211: ath10k: support for management rate control
authorSven Eckelmann <sven@narfation.org>
Fri, 8 Feb 2019 20:20:20 +0000 (21:20 +0100)
committerChristian Lamparter <chunkeey@gmail.com>
Mon, 11 Feb 2019 18:02:42 +0000 (19:02 +0100)
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.

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.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/ath/977-ath10k-add-support-for-configuring-management-packet.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch [new file with mode: 0644]

index 6b23ec5a24aebeeaa69dda934bc8409f1bd4c85d..48ec5f1c490ca5485652ae90d6e8e66ce566182e 100644 (file)
@@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
 PKG_NAME:=mac80211
 
 PKG_VERSION:=4.19.7-1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.7/
 PKG_HASH:=86650a02f36b0d39059be343d4bad3be14adece699723713a69c94cc64d456ef
 
diff --git a/package/kernel/mac80211/patches/ath/977-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/mac80211/patches/ath/977-ath10k-add-support-for-configuring-management-packet.patch
new file mode 100644 (file)
index 0000000..4f2f64a
--- /dev/null
@@ -0,0 +1,89 @@
+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
+---
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -158,6 +158,22 @@ u8 ath10k_mac_bitrate_to_idx(const struc
+       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) {
+@@ -5468,9 +5484,10 @@ static void ath10k_bss_info_changed(stru
+       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);
+@@ -5676,6 +5693,30 @@ static void ath10k_bss_info_changed(stru
+                                   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/mac80211/patches/ath/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/mac80211/patches/ath/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
new file mode 100644 (file)
index 0000000..b82b16a
--- /dev/null
@@ -0,0 +1,66 @@
+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
+---
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -166,7 +166,7 @@ static int ath10k_mac_get_rate_hw_value(
+       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;
+       }
+@@ -5699,22 +5699,22 @@ static void ath10k_bss_info_changed(stru
+                       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;
+-      }
++              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);
++              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);