mac80211: rt2x00: import upstream changes and rebase our patches
[openwrt/staging/lynxis.git] / package / kernel / mac80211 / patches / 020-15-rt2800-status-based-rate-flags-for-nomatch-case.patch
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 (file)
index 0000000..4e18dc8
--- /dev/null
@@ -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
+