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>
This commit is contained in:
Pradeep Kumar Chitrapu 2018-07-25 10:59:39 +03:00 committed by Kalle Valo
parent 1e3c43a7f1
commit cd93b83ad9

View File

@ -101,6 +101,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) {
@ -5439,8 +5441,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);
@ -5608,6 +5614,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);
}
@ -6935,7 +6979,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;
@ -6945,8 +6988,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;