diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2017-02-15 12:25:11 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2017-03-08 18:05:53 +0300 |
commit | 9d7a7a4d2b02bcd30fb5fe4270278212353cc332 (patch) | |
tree | 98257566cfdc8f90750d80b161497d5a7be7b2fb /drivers/net/wireless/ralink/rt2x00/rt2800lib.c | |
parent | 293dff78ee058ec1e0b90e05a803c512b6a2097f (diff) | |
download | linux-9d7a7a4d2b02bcd30fb5fe4270278212353cc332.tar.xz |
rt2800: status based rate flags for nomatch case
We use skb_desc->tx_rate_flags from entry as rate[].flags even if
skb does not match status. Patch corrects flags and also fixes
mcs for legacy rates.
rt2800_rate_from_status() is based on Felix's mt76
mt76x2_mac_process_tx_rate() function.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ralink/rt2x00/rt2800lib.c')
-rw-r--r-- | drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 4a7bec708a13..8d00c599e47a 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -852,6 +852,39 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); +static void rt2800_rate_from_status(struct skb_frame_desc *skbdesc, + u32 status, enum nl80211_band band) +{ + u8 flags = 0; + u8 idx = rt2x00_get_field32(status, TX_STA_FIFO_MCS); + + switch (rt2x00_get_field32(status, TX_STA_FIFO_PHYMODE)) { + case RATE_MODE_HT_GREENFIELD: + flags |= IEEE80211_TX_RC_GREEN_FIELD; + /* fall through */ + case RATE_MODE_HT_MIX: + flags |= IEEE80211_TX_RC_MCS; + break; + case RATE_MODE_OFDM: + if (band == NL80211_BAND_2GHZ) + idx += 4; + break; + case RATE_MODE_CCK: + if (idx >= 8) + idx -= 8; + break; + } + + if (rt2x00_get_field32(status, TX_STA_FIFO_BW)) + flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + + if (rt2x00_get_field32(status, TX_STA_FIFO_SGI)) + flags |= IEEE80211_TX_RC_SHORT_GI; + + skbdesc->tx_rate_idx = idx; + skbdesc->tx_rate_flags = flags; +} + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, bool match) { @@ -898,7 +931,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, * and provide retry count. */ if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) { - skbdesc->tx_rate_idx = real_mcs; + rt2800_rate_from_status(skbdesc, status, rt2x00dev->curr_band); mcs = real_mcs; } |