020-14-rt2x00-use-txdone_nomatch-on-rt2800usb.patch 6.3 KB

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