From 39948de22e9e79f0b8a3fbd6ca56a8eae2cc30ad Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 8 Feb 2019 21:32:07 +0100 Subject: [PATCH] ath10k/ath10k-ct: support 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 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. --- ...ulticast-and-management-rate-control.patch | 420 ++++++++++++++++++ ...ulticast-and-management-rate-control.patch | 316 +++++++++++++ 2 files changed, 736 insertions(+) create mode 100644 patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch create mode 100644 patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch diff --git a/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch b/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch new file mode 100644 index 00000000..e03d9042 --- /dev/null +++ b/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch @@ -0,0 +1,420 @@ +From: Sven Eckelmann +Date: Fri, 8 Feb 2019 21:20:20 +0100 +Subject: mac80211: ath10k: 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 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 + +diff --git a/package/kernel/mac80211/patches/975-mac80211-notify-driver-for-change-in-multicast-rates.patch b/package/kernel/mac80211/patches/975-mac80211-notify-driver-for-change-in-multicast-rates.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..fb07fa23ecc0518d69eef1f5064328f5c5968360 +--- /dev/null ++++ b/package/kernel/mac80211/patches/975-mac80211-notify-driver-for-change-in-multicast-rates.patch +@@ -0,0 +1,98 @@ ++From: Pradeep Kumar Chitrapu ++Date: Thu, 22 Mar 2018 12:18:03 -0700 ++Subject: [PATCH] mac80211: notify driver for change in multicast rates ++ ++With drivers implementing rate control in driver or firmware ++rate_control_send_low() may not get called, and thus the ++driver needs to know about changes in the multicast rate. ++ ++Add and use a new BSS change flag for this. ++ ++Signed-off-by: Pradeep Kumar Chitrapu ++[rewrite commit message] ++Signed-off-by: Johannes Berg ++ ++Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=dcbe73ca55a42712bfd0e9966cd2d5a48355ace3 ++--- ++ include/net/mac80211.h | 3 +++ ++ net/mac80211/cfg.c | 2 ++ ++ net/mac80211/ibss.c | 2 +- ++ net/mac80211/mesh.c | 3 ++- ++ net/mac80211/util.c | 3 ++- ++ 5 files changed, 10 insertions(+), 3 deletions(-) ++ ++diff --git a/include/net/mac80211.h b/include/net/mac80211.h ++index 885690fa39c8d8f4a48f2fa25447646d3d0a7856..48cfee4e26bdf3c7b7dbaaeecd6520492fa375a9 100644 ++--- a/include/net/mac80211.h +++++ b/include/net/mac80211.h ++@@ -301,6 +301,8 @@ struct ieee80211_vif_chanctx_switch { ++ * @BSS_CHANGED_MU_GROUPS: VHT MU-MIMO group id or user position changed ++ * @BSS_CHANGED_KEEP_ALIVE: keep alive options (idle period or protected ++ * keep alive) changed. +++ * @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface +++ * ++ */ ++ enum ieee80211_bss_change { ++ BSS_CHANGED_ASSOC = 1<<0, ++@@ -328,6 +330,7 @@ enum ieee80211_bss_change { ++ BSS_CHANGED_OCB = 1<<22, ++ BSS_CHANGED_MU_GROUPS = 1<<23, ++ BSS_CHANGED_KEEP_ALIVE = 1<<24, +++ BSS_CHANGED_MCAST_RATE = 1<<25, ++ ++ /* when adding here, make sure to change ieee80211_reconfig */ ++ }; ++diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c ++index fb15d3b97cb214078f1533f880350fe280b57c69..0b1984b8e3ab4184b009b6423c73dd0b6959d777 100644 ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -2310,6 +2310,8 @@ static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, ++ memcpy(sdata->vif.bss_conf.mcast_rate, rate, ++ sizeof(int) * NUM_NL80211_BANDS); ++ +++ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MCAST_RATE); +++ ++ return 0; ++ } ++ ++diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c ++index e9c6aa3ed05b8ddb8cf03decce82c00e59b4c0a7..f4b0634b80dedecfc3c05998132bdb6dcd043ed1 100644 ++--- a/net/mac80211/ibss.c +++++ b/net/mac80211/ibss.c ++@@ -1840,7 +1840,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, ++ IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED ++ | IEEE80211_HT_PARAM_RIFS_MODE; ++ ++- changed |= BSS_CHANGED_HT; +++ changed |= BSS_CHANGED_HT | BSS_CHANGED_MCAST_RATE; ++ ieee80211_bss_info_change_notify(sdata, changed); ++ ++ sdata->smps_mode = IEEE80211_SMPS_OFF; ++diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c ++index a550c707cd8a6130ef5756cedf2fa4738ae9a0e7..e9f5c2ae46a7bd83907d0b5ca1ceb0b8d6afd3fe 100644 ++--- a/net/mac80211/mesh.c +++++ b/net/mac80211/mesh.c ++@@ -880,7 +880,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) ++ BSS_CHANGED_BEACON_ENABLED | ++ BSS_CHANGED_HT | ++ BSS_CHANGED_BASIC_RATES | ++- BSS_CHANGED_BEACON_INT; +++ BSS_CHANGED_BEACON_INT | +++ BSS_CHANGED_MCAST_RATE; ++ ++ local->fif_other_bss++; ++ /* mesh ifaces must set allmulti to forward mcast traffic */ ++diff --git a/net/mac80211/util.c b/net/mac80211/util.c ++index 6aef6793d05236c19afe00a51f4ddc91bc060a39..6594df0c3e7afe90cf103bac89580e0ad71ed045 100644 ++--- a/net/mac80211/util.c +++++ b/net/mac80211/util.c ++@@ -1971,7 +1971,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) ++ BSS_CHANGED_CQM | ++ BSS_CHANGED_QOS | ++ BSS_CHANGED_IDLE | ++- BSS_CHANGED_TXPOWER; +++ BSS_CHANGED_TXPOWER | +++ BSS_CHANGED_MCAST_RATE; ++ ++ if (sdata->vif.mu_mimo_owner) ++ changed |= BSS_CHANGED_MU_GROUPS; +diff --git a/package/kernel/mac80211/patches/976-ath10k-support-for-multicast-rate-control.patch b/package/kernel/mac80211/patches/976-ath10k-support-for-multicast-rate-control.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..94bc108fb2e1a99f716135d842e0959f8c7cb602 +--- /dev/null ++++ b/package/kernel/mac80211/patches/976-ath10k-support-for-multicast-rate-control.patch +@@ -0,0 +1,112 @@ ++From: Pradeep Kumar Chitrapu ++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 ++Signed-off-by: Kalle Valo ++ ++Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cd93b83ad927b2c7979e0add0343ace59328b461 ++--- ++ drivers/net/wireless/ath/ath10k/mac.c | 54 +++++++++++++++++++++++++-- ++ 1 file changed, 50 insertions(+), 4 deletions(-) ++ ++diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c ++index 5683f1a5330eedae677aad5bf2621a6232781346..1937526c8c18da85f7730429759391d47e12cf81 100644 ++--- a/drivers/net/wireless/ath/ath10k/mac.c +++++ b/drivers/net/wireless/ath/ath10k/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/mac80211/patches/977-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/mac80211/patches/977-ath10k-add-support-for-configuring-management-packet.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..4b2aa5effdb19141178a5bb71eb9488ee7575b93 +--- /dev/null ++++ b/package/kernel/mac80211/patches/977-ath10k-add-support-for-configuring-management-packet.patch +@@ -0,0 +1,94 @@ ++From: Sriram R ++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 ++Signed-off-by: Kalle Valo ++ ++Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f279294e9ee22a8f306fdc8e4181cf555e6f0f70 ++--- ++ drivers/net/wireless/ath/ath10k/mac.c | 45 +++++++++++++++++++++++++-- ++ 1 file changed, 43 insertions(+), 2 deletions(-) ++ ++diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c ++index 1937526c8c18da85f7730429759391d47e12cf81..47e5992afcd7564743f513eb250b57381aba3233 100644 ++--- a/drivers/net/wireless/ath/ath10k/mac.c +++++ b/drivers/net/wireless/ath/ath10k/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/mac80211/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/mac80211/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..b496332574f93b1f6474226e8c09970d6fe0e2fe +--- /dev/null ++++ b/package/kernel/mac80211/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch +@@ -0,0 +1,70 @@ ++From: Sriram R ++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 ++Signed-off-by: Kalle Valo ++ ++Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e141eea7dd8525dd1ef7a925459e455b4d307f ++--- ++ drivers/net/wireless/ath/ath10k/mac.c | 30 +++++++++++++-------------- ++ 1 file changed, 15 insertions(+), 15 deletions(-) ++ ++diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c ++index 47e5992afcd7564743f513eb250b57381aba3233..e93b04c8e6fb2fa7968b910e0cc97ad8144bd7e8 100644 ++--- a/drivers/net/wireless/ath/ath10k/mac.c +++++ b/drivers/net/wireless/ath/ath10k/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); diff --git a/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch b/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch new file mode 100644 index 00000000..8b2a6777 --- /dev/null +++ b/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch @@ -0,0 +1,316 @@ +From: Sven Eckelmann +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 + +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 ++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 ++Signed-off-by: Kalle Valo ++ ++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 ++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 ++Signed-off-by: Kalle Valo ++ ++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 ++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 ++Signed-off-by: Kalle Valo ++ ++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);