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

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