2
0

701-rt2800-move-usb-specific-txdone-txstatus-routines-to.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. From 0381bfbc400ce4c3000b0b31c577ad9e8071e4f6 Mon Sep 17 00:00:00 2001
  2. From: Stanislaw Gruszka <[email protected]>
  3. Date: Fri, 18 May 2018 12:25:08 +0200
  4. Subject: [PATCH 1/5] rt2800: move usb specific txdone/txstatus routines to
  5. rt2800lib
  6. In order to reuse usb txdone/txstatus routines for mmio, move them
  7. to common rt2800lib.c file.
  8. Signed-off-by: Stanislaw Gruszka <[email protected]>
  9. ---
  10. .../net/wireless/ralink/rt2x00/rt2800lib.c | 138 +++++++++++++++++
  11. .../net/wireless/ralink/rt2x00/rt2800lib.h | 3 +
  12. .../net/wireless/ralink/rt2x00/rt2800usb.c | 143 +-----------------
  13. 3 files changed, 145 insertions(+), 139 deletions(-)
  14. --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
  15. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
  16. @@ -960,6 +960,47 @@ static void rt2800_rate_from_status(stru
  17. skbdesc->tx_rate_flags = flags;
  18. }
  19. +static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
  20. +{
  21. + __le32 *txwi;
  22. + u32 word;
  23. + int wcid, ack, pid;
  24. + int tx_wcid, tx_ack, tx_pid, is_agg;
  25. +
  26. + /*
  27. + * This frames has returned with an IO error,
  28. + * so the status report is not intended for this
  29. + * frame.
  30. + */
  31. + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
  32. + return false;
  33. +
  34. + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
  35. + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
  36. + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
  37. + is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE);
  38. +
  39. + /*
  40. + * Validate if this TX status report is intended for
  41. + * this entry by comparing the WCID/ACK/PID fields.
  42. + */
  43. + txwi = rt2800_drv_get_txwi(entry);
  44. +
  45. + word = rt2x00_desc_read(txwi, 1);
  46. + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
  47. + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
  48. + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
  49. +
  50. + if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) {
  51. + rt2x00_dbg(entry->queue->rt2x00dev,
  52. + "TX status report missed for queue %d entry %d\n",
  53. + entry->queue->qid, entry->entry_idx);
  54. + return false;
  55. + }
  56. +
  57. + return true;
  58. +}
  59. +
  60. void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
  61. bool match)
  62. {
  63. @@ -1062,6 +1103,103 @@ void rt2800_txdone_entry(struct queue_en
  64. }
  65. EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
  66. +void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
  67. +{
  68. + struct data_queue *queue;
  69. + struct queue_entry *entry;
  70. + u32 reg;
  71. + u8 qid;
  72. + bool match;
  73. +
  74. + while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
  75. + /*
  76. + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
  77. + * guaranteed to be one of the TX QIDs .
  78. + */
  79. + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
  80. + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
  81. +
  82. + if (unlikely(rt2x00queue_empty(queue))) {
  83. + rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n",
  84. + qid);
  85. + break;
  86. + }
  87. +
  88. + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
  89. +
  90. + if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
  91. + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) {
  92. + rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n",
  93. + entry->entry_idx, qid);
  94. + break;
  95. + }
  96. +
  97. + match = rt2800_txdone_entry_check(entry, reg);
  98. + rt2800_txdone_entry(entry, reg, rt2800_drv_get_txwi(entry), match);
  99. + }
  100. +}
  101. +EXPORT_SYMBOL_GPL(rt2800_txdone);
  102. +
  103. +static inline bool rt2800_entry_txstatus_timeout(struct queue_entry *entry)
  104. +{
  105. + bool tout;
  106. +
  107. + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
  108. + return false;
  109. +
  110. + tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500));
  111. + if (unlikely(tout))
  112. + rt2x00_dbg(entry->queue->rt2x00dev,
  113. + "TX status timeout for entry %d in queue %d\n",
  114. + entry->entry_idx, entry->queue->qid);
  115. + return tout;
  116. +
  117. +}
  118. +
  119. +bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev)
  120. +{
  121. + struct data_queue *queue;
  122. + struct queue_entry *entry;
  123. +
  124. + tx_queue_for_each(rt2x00dev, queue) {
  125. + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
  126. + if (rt2800_entry_txstatus_timeout(entry))
  127. + return true;
  128. + }
  129. + return false;
  130. +}
  131. +EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout);
  132. +
  133. +void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
  134. +{
  135. + struct data_queue *queue;
  136. + struct queue_entry *entry;
  137. +
  138. + /*
  139. + * Process any trailing TX status reports for IO failures,
  140. + * we loop until we find the first non-IO error entry. This
  141. + * can either be a frame which is free, is being uploaded,
  142. + * or has completed the upload but didn't have an entry
  143. + * in the TX_STAT_FIFO register yet.
  144. + */
  145. + tx_queue_for_each(rt2x00dev, queue) {
  146. + while (!rt2x00queue_empty(queue)) {
  147. + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
  148. +
  149. + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
  150. + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
  151. + break;
  152. +
  153. + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) ||
  154. + rt2800_entry_txstatus_timeout(entry))
  155. + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
  156. + else
  157. + break;
  158. + }
  159. + }
  160. +}
  161. +EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus);
  162. +
  163. static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
  164. unsigned int index)
  165. {
  166. --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
  167. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
  168. @@ -206,6 +206,9 @@ void rt2800_process_rxwi(struct queue_en
  169. void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
  170. bool match);
  171. +void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
  172. +void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev);
  173. +bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev);
  174. void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
  175. void rt2800_clear_beacon(struct queue_entry *entry);
  176. --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
  177. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
  178. @@ -116,35 +116,6 @@ static bool rt2800usb_txstatus_pending(s
  179. return false;
  180. }
  181. -static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry)
  182. -{
  183. - bool tout;
  184. -
  185. - if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
  186. - return false;
  187. -
  188. - tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500));
  189. - if (unlikely(tout))
  190. - rt2x00_dbg(entry->queue->rt2x00dev,
  191. - "TX status timeout for entry %d in queue %d\n",
  192. - entry->entry_idx, entry->queue->qid);
  193. - return tout;
  194. -
  195. -}
  196. -
  197. -static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev)
  198. -{
  199. - struct data_queue *queue;
  200. - struct queue_entry *entry;
  201. -
  202. - tx_queue_for_each(rt2x00dev, queue) {
  203. - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
  204. - if (rt2800usb_entry_txstatus_timeout(entry))
  205. - return true;
  206. - }
  207. - return false;
  208. -}
  209. -
  210. #define TXSTATUS_READ_INTERVAL 1000000
  211. static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
  212. @@ -171,7 +142,7 @@ static bool rt2800usb_tx_sta_fifo_read_c
  213. }
  214. /* Check if there is any entry that timedout waiting on TX status */
  215. - if (rt2800usb_txstatus_timeout(rt2x00dev))
  216. + if (rt2800_txstatus_timeout(rt2x00dev))
  217. queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
  218. if (rt2800usb_txstatus_pending(rt2x00dev)) {
  219. @@ -501,123 +472,17 @@ static int rt2800usb_get_tx_data_len(str
  220. /*
  221. * TX control handlers
  222. */
  223. -static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
  224. -{
  225. - __le32 *txwi;
  226. - u32 word;
  227. - int wcid, ack, pid;
  228. - int tx_wcid, tx_ack, tx_pid, is_agg;
  229. -
  230. - /*
  231. - * This frames has returned with an IO error,
  232. - * so the status report is not intended for this
  233. - * frame.
  234. - */
  235. - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
  236. - return false;
  237. -
  238. - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
  239. - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
  240. - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
  241. - is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE);
  242. -
  243. - /*
  244. - * Validate if this TX status report is intended for
  245. - * this entry by comparing the WCID/ACK/PID fields.
  246. - */
  247. - txwi = rt2800usb_get_txwi(entry);
  248. -
  249. - word = rt2x00_desc_read(txwi, 1);
  250. - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
  251. - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
  252. - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
  253. -
  254. - if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) {
  255. - rt2x00_dbg(entry->queue->rt2x00dev,
  256. - "TX status report missed for queue %d entry %d\n",
  257. - entry->queue->qid, entry->entry_idx);
  258. - return false;
  259. - }
  260. -
  261. - return true;
  262. -}
  263. -
  264. -static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
  265. -{
  266. - struct data_queue *queue;
  267. - struct queue_entry *entry;
  268. - u32 reg;
  269. - u8 qid;
  270. - bool match;
  271. -
  272. - while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
  273. - /*
  274. - * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
  275. - * guaranteed to be one of the TX QIDs .
  276. - */
  277. - qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
  278. - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
  279. -
  280. - if (unlikely(rt2x00queue_empty(queue))) {
  281. - rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n",
  282. - qid);
  283. - break;
  284. - }
  285. -
  286. - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
  287. -
  288. - if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
  289. - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) {
  290. - rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n",
  291. - entry->entry_idx, qid);
  292. - break;
  293. - }
  294. -
  295. - match = rt2800usb_txdone_entry_check(entry, reg);
  296. - rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match);
  297. - }
  298. -}
  299. -
  300. -static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
  301. -{
  302. - struct data_queue *queue;
  303. - struct queue_entry *entry;
  304. -
  305. - /*
  306. - * Process any trailing TX status reports for IO failures,
  307. - * we loop until we find the first non-IO error entry. This
  308. - * can either be a frame which is free, is being uploaded,
  309. - * or has completed the upload but didn't have an entry
  310. - * in the TX_STAT_FIFO register yet.
  311. - */
  312. - tx_queue_for_each(rt2x00dev, queue) {
  313. - while (!rt2x00queue_empty(queue)) {
  314. - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
  315. -
  316. - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
  317. - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
  318. - break;
  319. -
  320. - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) ||
  321. - rt2800usb_entry_txstatus_timeout(entry))
  322. - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
  323. - else
  324. - break;
  325. - }
  326. - }
  327. -}
  328. -
  329. static void rt2800usb_work_txdone(struct work_struct *work)
  330. {
  331. struct rt2x00_dev *rt2x00dev =
  332. container_of(work, struct rt2x00_dev, txdone_work);
  333. while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
  334. - rt2800usb_txstatus_timeout(rt2x00dev)) {
  335. + rt2800_txstatus_timeout(rt2x00dev)) {
  336. - rt2800usb_txdone(rt2x00dev);
  337. + rt2800_txdone(rt2x00dev);
  338. - rt2800usb_txdone_nostatus(rt2x00dev);
  339. + rt2800_txdone_nostatus(rt2x00dev);
  340. /*
  341. * The hw may delay sending the packet after DMA complete