mac80211: rt2x00: import upstream changes and rebase our patches
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / 020-14-rt2x00-use-txdone_nomatch-on-rt2800usb.patch
1 From 293dff78ee058ec1e0b90e05a803c512b6a2097f Mon Sep 17 00:00:00 2001
2 From: Stanislaw Gruszka <sgruszka@redhat.com>
3 Date: Wed, 15 Feb 2017 10:25:10 +0100
4 Subject: [PATCH 14/19] rt2x00: use txdone_nomatch on rt2800usb
5
6 If we do not match skb entry, provide tx status via nomatch procedure.
7
8 Currently in that case we do rt2x00lib_txdone_noinfo(TXDONE_NOINFO),
9 which actually assume that entry->skb was posted without retries and
10 provide rate saved in skb desc as successful. Patch changed that to
11 rate read from TX_STAT_FIFO, however still do not provide correct
12 number of retries.
13
14 On SoC/PCI devices we keep providing status via standard txdone
15 procedure, no change in those devices, though we should thing about it.
16
17 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
18 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
19 ---
20 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 31 ++++++++++++++++++++-----
21 drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 3 ++-
22 drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 2 +-
23 drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 18 ++++++--------
24 4 files changed, 35 insertions(+), 19 deletions(-)
25
26 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
27 index 46405cce35e0..4a7bec708a13 100644
28 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
29 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
30 @@ -852,7 +852,8 @@ void rt2800_process_rxwi(struct queue_entry *entry,
31 }
32 EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
33
34 -void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
35 +void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
36 + bool match)
37 {
38 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
39 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
40 @@ -860,8 +861,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
41 struct txdone_entry_desc txdesc;
42 u32 word;
43 u16 mcs, real_mcs;
44 - int aggr, ampdu;
45 - int wcid;
46 + int aggr, ampdu, wcid, ack_req;
47
48 /*
49 * Obtain the status about this packet.
50 @@ -875,6 +875,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
51 real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
52 aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
53 wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
54 + ack_req = rt2x00_get_field32(status, TX_STA_FIFO_TX_ACK_REQUIRED);
55
56 /*
57 * If a frame was meant to be sent as a single non-aggregated MPDU
58 @@ -891,8 +892,12 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
59 * Hence, replace the requested rate with the real tx rate to not
60 * confuse the rate control algortihm by providing clearly wrong
61 * data.
62 - */
63 - if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) {
64 + *
65 + * FIXME: if we do not find matching entry, we tell that frame was
66 + * posted without any retries. We need to find a way to fix that
67 + * and provide retry count.
68 + */
69 + if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) {
70 skbdesc->tx_rate_idx = real_mcs;
71 mcs = real_mcs;
72 }
73 @@ -900,6 +905,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
74 if (aggr == 1 || ampdu == 1)
75 __set_bit(TXDONE_AMPDU, &txdesc.flags);
76
77 + if (!ack_req)
78 + __set_bit(TXDONE_NO_ACK_REQ, &txdesc.flags);
79 +
80 /*
81 * Ralink has a retry mechanism using a global fallback
82 * table. We setup this fallback table to try the immediate
83 @@ -931,7 +939,18 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
84 if (txdesc.retry)
85 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
86
87 - rt2x00lib_txdone(entry, &txdesc);
88 + if (!match) {
89 + /* RCU assures non-null sta will not be freed by mac80211. */
90 + rcu_read_lock();
91 + if (likely(wcid >= WCID_START && wcid <= WCID_END))
92 + skbdesc->sta = drv_data->wcid_to_sta[wcid - WCID_START];
93 + else
94 + skbdesc->sta = NULL;
95 + rt2x00lib_txdone_nomatch(entry, &txdesc);
96 + rcu_read_unlock();
97 + } else {
98 + rt2x00lib_txdone(entry, &txdesc);
99 + }
100 }
101 EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
102
103 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
104 index 6811d677a6e7..d9ef260d542a 100644
105 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
106 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
107 @@ -191,7 +191,8 @@ void rt2800_write_tx_data(struct queue_entry *entry,
108 struct txentry_desc *txdesc);
109 void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
110
111 -void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi);
112 +void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
113 + bool match);
114
115 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
116 void rt2800_clear_beacon(struct queue_entry *entry);
117 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
118 index de4790b41be7..3ab3b5323897 100644
119 --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
120 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
121 @@ -239,7 +239,7 @@ static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry,
122 {
123 if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
124 rt2800_txdone_entry(entry, entry->status,
125 - rt2800mmio_get_txwi(entry));
126 + rt2800mmio_get_txwi(entry), true);
127 return false;
128 }
129
130 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
131 index 205a7b8ac8a7..f11e3f532a84 100644
132 --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
133 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
134 @@ -501,8 +501,7 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
135 /*
136 * TX control handlers
137 */
138 -static enum txdone_entry_desc_flags
139 -rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
140 +static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
141 {
142 __le32 *txwi;
143 u32 word;
144 @@ -515,7 +514,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
145 * frame.
146 */
147 if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
148 - return TXDONE_FAILURE;
149 + return false;
150
151 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
152 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
153 @@ -537,10 +536,10 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
154 rt2x00_dbg(entry->queue->rt2x00dev,
155 "TX status report missed for queue %d entry %d\n",
156 entry->queue->qid, entry->entry_idx);
157 - return TXDONE_UNKNOWN;
158 + return false;
159 }
160
161 - return TXDONE_SUCCESS;
162 + return true;
163 }
164
165 static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
166 @@ -549,7 +548,7 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
167 struct queue_entry *entry;
168 u32 reg;
169 u8 qid;
170 - enum txdone_entry_desc_flags done_status;
171 + bool match;
172
173 while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
174 /*
175 @@ -574,11 +573,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
176 break;
177 }
178
179 - done_status = rt2800usb_txdone_entry_check(entry, reg);
180 - if (likely(done_status == TXDONE_SUCCESS))
181 - rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry));
182 - else
183 - rt2x00lib_txdone_noinfo(entry, done_status);
184 + match = rt2800usb_txdone_entry_check(entry, reg);
185 + rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match);
186 }
187 }
188
189 --
190 2.12.1
191