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 0000000000000000000000000000000000000000..e03d9042af56e8b3c631b42df0b7bd8eb9f06076
--- /dev/null
+++ b/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch
@@ -0,0 +1,420 @@
+From: Sven Eckelmann <sven@narfation.org>
+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 <sven@narfation.org>
+
+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 <pradeepc@codeaurora.org>
++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 <pradeepc@codeaurora.org>
++[rewrite commit message]
++Signed-off-by: Johannes Berg <johannes.berg@intel.com>
++
++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 <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
++---
++ 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 <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
++---
++ 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 <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
++---
++ 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 0000000000000000000000000000000000000000..8b2a6777826913dd756a91ec0cd254a4ca3f464e
--- /dev/null
+++ b/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch
@@ -0,0 +1,316 @@
+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);