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

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