diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2017-02-15 10:25:10 +0100 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2017-03-08 17:05:52 +0200 |
commit | 293dff78ee058ec1e0b90e05a803c512b6a2097f (patch) | |
tree | b2d487a38311040df218132a1ccdf23df0839ed4 /drivers/net/wireless/ralink/rt2x00/rt2800lib.c | |
parent | ec80ad70d778af7665992672896633ebd3b02ac8 (diff) | |
download | linux-stable-293dff78ee058ec1e0b90e05a803c512b6a2097f.tar.gz linux-stable-293dff78ee058ec1e0b90e05a803c512b6a2097f.tar.bz2 linux-stable-293dff78ee058ec1e0b90e05a803c512b6a2097f.zip |
rt2x00: use txdone_nomatch on rt2800usb
If we do not match skb entry, provide tx status via nomatch procedure.
Currently in that case we do rt2x00lib_txdone_noinfo(TXDONE_NOINFO),
which actually assume that entry->skb was posted without retries and
provide rate saved in skb desc as successful. Patch changed that to
rate read from TX_STAT_FIFO, however still do not provide correct
number of retries.
On SoC/PCI devices we keep providing status via standard txdone
procedure, no change in those devices, though we should thing about it.
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 | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 46405cce35e0..4a7bec708a13 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -852,7 +852,8 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); -void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) +void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, + bool match) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; @@ -860,8 +861,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) struct txdone_entry_desc txdesc; u32 word; u16 mcs, real_mcs; - int aggr, ampdu; - int wcid; + int aggr, ampdu, wcid, ack_req; /* * Obtain the status about this packet. @@ -875,6 +875,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); + ack_req = rt2x00_get_field32(status, TX_STA_FIFO_TX_ACK_REQUIRED); /* * If a frame was meant to be sent as a single non-aggregated MPDU @@ -891,8 +892,12 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) * Hence, replace the requested rate with the real tx rate to not * confuse the rate control algortihm by providing clearly wrong * data. - */ - if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) { + * + * FIXME: if we do not find matching entry, we tell that frame was + * posted without any retries. We need to find a way to fix that + * and provide retry count. + */ + if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) { skbdesc->tx_rate_idx = real_mcs; mcs = real_mcs; } @@ -900,6 +905,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) if (aggr == 1 || ampdu == 1) __set_bit(TXDONE_AMPDU, &txdesc.flags); + if (!ack_req) + __set_bit(TXDONE_NO_ACK_REQ, &txdesc.flags); + /* * Ralink has a retry mechanism using a global fallback * table. We setup this fallback table to try the immediate @@ -931,7 +939,18 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) if (txdesc.retry) __set_bit(TXDONE_FALLBACK, &txdesc.flags); - rt2x00lib_txdone(entry, &txdesc); + if (!match) { + /* RCU assures non-null sta will not be freed by mac80211. */ + rcu_read_lock(); + if (likely(wcid >= WCID_START && wcid <= WCID_END)) + skbdesc->sta = drv_data->wcid_to_sta[wcid - WCID_START]; + else + skbdesc->sta = NULL; + rt2x00lib_txdone_nomatch(entry, &txdesc); + rcu_read_unlock(); + } else { + rt2x00lib_txdone(entry, &txdesc); + } } EXPORT_SYMBOL_GPL(rt2800_txdone_entry); |