Yu Wang <[email protected]> writes:
> When working in station mode, after connected to a legacy
> AP, 11g only, for example, the tx bitrate is incorrect in
> output of command 'iw wlan0 link'.
>
> That's because the legacy tx bitrate value reported by
> firmware is not well handled:
> For QCA6174, the value represents rate index, but treated
> as a real rate;
> For QCA9888, the value is real rate, with unit 'Mbps', but
> treated as '100kbps'.
>
> To fix this issue:
> 1. Translate the rate index to real rate for QCA6174;
> 2. Translate the rate from 'Mbps' to 'kbps' for QCA9888.
>
> Tested with:
> QCA6174 PCIe with firmware WLAN.RM.4.4.1.c3-00031.
> QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00029.
> QCA9888 PCIe with firmware 10.4-3.9.0.2-00040.
>
> Signed-off-by: Yu Wang <[email protected]>
[...]
> @@ -3723,6 +3729,74 @@ static void ath10k_htt_rx_sec_ind_handler(struct
> ath10k *ar,
> spin_unlock_bh(&ar->data_lock);
> }
>
> +static int
> +ath10k_htt_update_ratecode(struct ath10k *ar, struct ath10k_sta *arsta,
> + u8 *ratecode)
> +{
> + u8 hw_rate, preamble;
> + u16 bitrate;
> + int i;
> + const struct ieee80211_rate *bitrates;
> + bool cck;
> + struct ieee80211_chanctx_conf *conf = NULL;
> + enum nl80211_band band;
> + struct ieee80211_supported_band *sband;
> +
> + if (!ratecode)
> + return -EINVAL;
> +
> + /* only for legacy ratecode */
> + preamble = ATH10K_HW_PREAMBLE(*ratecode);
> + if (preamble != WMI_RATE_PREAMBLE_CCK &&
> + preamble != WMI_RATE_PREAMBLE_OFDM)
> + return 0;
> +
> + if (!arsta->arvif || !arsta->arvif->vif)
> + return -EINVAL;
> +
> + WARN_ON(!rcu_read_lock_held());
> + conf = rcu_dereference(arsta->arvif->vif->chanctx_conf);
> + if (!conf)
> + return -EINVAL;
> +
> + band = conf->def.chan->band;
> + sband = &ar->mac.sbands[band];
> + if (!sband->bitrates)
> + return -EINVAL;
> +
> + if (WARN_ON_ONCE(sband->n_bitrates > S8_MAX))
> + return -EINVAL;
> +
> + cck = (preamble == WMI_RATE_PREAMBLE_CCK);
> + hw_rate = ATH10K_HW_LEGACY_RATE(*ratecode);
> + for (i = 0; i < sband->n_bitrates; i++) {
> + bitrates = &sband->bitrates[i];
> + if (ath10k_mac_bitrate_is_cck(bitrates->bitrate) != cck)
> + continue;
> +
> + if (bitrates->hw_value == hw_rate ||
> + (bitrates->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
> + bitrates->hw_value_short == hw_rate)) {
> + bitrate = bitrates->bitrate;
> +
> + /* The bitrate will be recovered in
> + * ath10k_update_per_peer_tx_stats().
> + */
> + if (bitrate == 55)
> + bitrate = 60;
> +
> + bitrate = bitrate / 10;
Here you use magic value 60 but in ath10k_update_per_peer_tx_stats() you
use magic value 50:
> + /* from 1Mbps to 100Kbps */
> + rate = rate * 10;
> + if (rate == 50)
> + rate = 55;
Am I missing something or how is this supposed to work?
--
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
_______________________________________________
ath10k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath10k