diff options
Diffstat (limited to 'package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch')
-rw-r--r-- | package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch b/package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch new file mode 100644 index 0000000000..4e18dc8e2a --- /dev/null +++ b/package/kernel/mac80211/patches/020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch @@ -0,0 +1,88 @@ +From 9d7a7a4d2b02bcd30fb5fe4270278212353cc332 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka <sgruszka@redhat.com> +Date: Wed, 15 Feb 2017 10:25:11 +0100 +Subject: [PATCH 15/19] 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> +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 2 ++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 35 +++++++++++++++++++++++++- + 2 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h +index 0e7051d8132f..480b08601785 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -1760,6 +1760,8 @@ + #define TX_STA_FIFO_WCID FIELD32(0x0000ff00) + #define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000) + #define TX_STA_FIFO_MCS FIELD32(0x007f0000) ++#define TX_STA_FIFO_BW FIELD32(0x00800000) ++#define TX_STA_FIFO_SGI FIELD32(0x01000000) + #define TX_STA_FIFO_PHYMODE FIELD32(0xc0000000) + + /* +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; + } + +-- +2.12.1 + |