qcu.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. /*
  2. * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
  3. * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. *
  17. */
  18. /********************************************\
  19. Queue Control Unit, DCF Control Unit Functions
  20. \********************************************/
  21. #include "ath5k.h"
  22. #include "reg.h"
  23. #include "debug.h"
  24. #include <linux/log2.h>
  25. /**
  26. * DOC: Queue Control Unit (QCU)/DCF Control Unit (DCU) functions
  27. *
  28. * Here we setup parameters for the 12 available TX queues. Note that
  29. * on the various registers we can usually only map the first 10 of them so
  30. * basically we have 10 queues to play with. Each queue has a matching
  31. * QCU that controls when the queue will get triggered and multiple QCUs
  32. * can be mapped to a single DCU that controls the various DFS parameters
  33. * for the various queues. In our setup we have a 1:1 mapping between QCUs
  34. * and DCUs allowing us to have different DFS settings for each queue.
  35. *
  36. * When a frame goes into a TX queue, QCU decides when it'll trigger a
  37. * transmission based on various criteria (such as how many data we have inside
  38. * it's buffer or -if it's a beacon queue- if it's time to fire up the queue
  39. * based on TSF etc), DCU adds backoff, IFSes etc and then a scheduler
  40. * (arbitrator) decides the priority of each QCU based on it's configuration
  41. * (e.g. beacons are always transmitted when they leave DCU bypassing all other
  42. * frames from other queues waiting to be transmitted). After a frame leaves
  43. * the DCU it goes to PCU for further processing and then to PHY for
  44. * the actual transmission.
  45. */
  46. /******************\
  47. * Helper functions *
  48. \******************/
  49. /**
  50. * ath5k_hw_num_tx_pending() - Get number of pending frames for a given queue
  51. * @ah: The &struct ath5k_hw
  52. * @queue: One of enum ath5k_tx_queue_id
  53. */
  54. u32
  55. ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
  56. {
  57. u32 pending;
  58. AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
  59. /* Return if queue is declared inactive */
  60. if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
  61. return false;
  62. /* XXX: How about AR5K_CFG_TXCNT ? */
  63. if (ah->ah_version == AR5K_AR5210)
  64. return false;
  65. pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
  66. pending &= AR5K_QCU_STS_FRMPENDCNT;
  67. /* It's possible to have no frames pending even if TXE
  68. * is set. To indicate that q has not stopped return
  69. * true */
  70. if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
  71. return true;
  72. return pending;
  73. }
  74. /**
  75. * ath5k_hw_release_tx_queue() - Set a transmit queue inactive
  76. * @ah: The &struct ath5k_hw
  77. * @queue: One of enum ath5k_tx_queue_id
  78. */
  79. void
  80. ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
  81. {
  82. if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
  83. return;
  84. /* This queue will be skipped in further operations */
  85. ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
  86. /*For SIMR setup*/
  87. AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
  88. }
  89. /**
  90. * ath5k_cw_validate() - Make sure the given cw is valid
  91. * @cw_req: The contention window value to check
  92. *
  93. * Make sure cw is a power of 2 minus 1 and smaller than 1024
  94. */
  95. static u16
  96. ath5k_cw_validate(u16 cw_req)
  97. {
  98. cw_req = min(cw_req, (u16)1023);
  99. /* Check if cw_req + 1 a power of 2 */
  100. if (is_power_of_2(cw_req + 1))
  101. return cw_req;
  102. /* Check if cw_req is a power of 2 */
  103. if (is_power_of_2(cw_req))
  104. return cw_req - 1;
  105. /* If none of the above is correct
  106. * find the closest power of 2 */
  107. cw_req = (u16) roundup_pow_of_two(cw_req) - 1;
  108. return cw_req;
  109. }
  110. /**
  111. * ath5k_hw_get_tx_queueprops() - Get properties for a transmit queue
  112. * @ah: The &struct ath5k_hw
  113. * @queue: One of enum ath5k_tx_queue_id
  114. * @queue_info: The &struct ath5k_txq_info to fill
  115. */
  116. int
  117. ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
  118. struct ath5k_txq_info *queue_info)
  119. {
  120. memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
  121. return 0;
  122. }
  123. /**
  124. * ath5k_hw_set_tx_queueprops() - Set properties for a transmit queue
  125. * @ah: The &struct ath5k_hw
  126. * @queue: One of enum ath5k_tx_queue_id
  127. * @qinfo: The &struct ath5k_txq_info to use
  128. *
  129. * Returns 0 on success or -EIO if queue is inactive
  130. */
  131. int
  132. ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
  133. const struct ath5k_txq_info *qinfo)
  134. {
  135. struct ath5k_txq_info *qi;
  136. AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
  137. qi = &ah->ah_txq[queue];
  138. if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE)
  139. return -EIO;
  140. /* copy and validate values */
  141. qi->tqi_type = qinfo->tqi_type;
  142. qi->tqi_subtype = qinfo->tqi_subtype;
  143. qi->tqi_flags = qinfo->tqi_flags;
  144. /*
  145. * According to the docs: Although the AIFS field is 8 bit wide,
  146. * the maximum supported value is 0xFC. Setting it higher than that
  147. * will cause the DCU to hang.
  148. */
  149. qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC);
  150. qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min);
  151. qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max);
  152. qi->tqi_cbr_period = qinfo->tqi_cbr_period;
  153. qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit;
  154. qi->tqi_burst_time = qinfo->tqi_burst_time;
  155. qi->tqi_ready_time = qinfo->tqi_ready_time;
  156. /*XXX: Is this supported on 5210 ?*/
  157. /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/
  158. if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA &&
  159. ((qinfo->tqi_subtype == AR5K_WME_AC_VI) ||
  160. (qinfo->tqi_subtype == AR5K_WME_AC_VO))) ||
  161. qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD)
  162. qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
  163. return 0;
  164. }
  165. /**
  166. * ath5k_hw_setup_tx_queue() - Initialize a transmit queue
  167. * @ah: The &struct ath5k_hw
  168. * @queue_type: One of enum ath5k_tx_queue
  169. * @queue_info: The &struct ath5k_txq_info to use
  170. *
  171. * Returns 0 on success, -EINVAL on invalid arguments
  172. */
  173. int
  174. ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
  175. struct ath5k_txq_info *queue_info)
  176. {
  177. unsigned int queue;
  178. int ret;
  179. /*
  180. * Get queue by type
  181. */
  182. /* 5210 only has 2 queues */
  183. if (ah->ah_capabilities.cap_queues.q_tx_num == 2) {
  184. switch (queue_type) {
  185. case AR5K_TX_QUEUE_DATA:
  186. queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
  187. break;
  188. case AR5K_TX_QUEUE_BEACON:
  189. case AR5K_TX_QUEUE_CAB:
  190. queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
  191. break;
  192. default:
  193. return -EINVAL;
  194. }
  195. } else {
  196. switch (queue_type) {
  197. case AR5K_TX_QUEUE_DATA:
  198. for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
  199. ah->ah_txq[queue].tqi_type !=
  200. AR5K_TX_QUEUE_INACTIVE; queue++) {
  201. if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
  202. return -EINVAL;
  203. }
  204. break;
  205. case AR5K_TX_QUEUE_UAPSD:
  206. queue = AR5K_TX_QUEUE_ID_UAPSD;
  207. break;
  208. case AR5K_TX_QUEUE_BEACON:
  209. queue = AR5K_TX_QUEUE_ID_BEACON;
  210. break;
  211. case AR5K_TX_QUEUE_CAB:
  212. queue = AR5K_TX_QUEUE_ID_CAB;
  213. break;
  214. default:
  215. return -EINVAL;
  216. }
  217. }
  218. /*
  219. * Setup internal queue structure
  220. */
  221. memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
  222. ah->ah_txq[queue].tqi_type = queue_type;
  223. if (queue_info != NULL) {
  224. queue_info->tqi_type = queue_type;
  225. ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
  226. if (ret)
  227. return ret;
  228. }
  229. /*
  230. * We use ah_txq_status to hold a temp value for
  231. * the Secondary interrupt mask registers on 5211+
  232. * check out ath5k_hw_reset_tx_queue
  233. */
  234. AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
  235. return queue;
  236. }
  237. /*******************************\
  238. * Single QCU/DCU initialization *
  239. \*******************************/
  240. /**
  241. * ath5k_hw_set_tx_retry_limits() - Set tx retry limits on DCU
  242. * @ah: The &struct ath5k_hw
  243. * @queue: One of enum ath5k_tx_queue_id
  244. *
  245. * This function is used when initializing a queue, to set
  246. * retry limits based on ah->ah_retry_* and the chipset used.
  247. */
  248. void
  249. ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
  250. unsigned int queue)
  251. {
  252. /* Single data queue on AR5210 */
  253. if (ah->ah_version == AR5K_AR5210) {
  254. struct ath5k_txq_info *tq = &ah->ah_txq[queue];
  255. if (queue > 0)
  256. return;
  257. ath5k_hw_reg_write(ah,
  258. (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
  259. | AR5K_REG_SM(ah->ah_retry_long,
  260. AR5K_NODCU_RETRY_LMT_SLG_RETRY)
  261. | AR5K_REG_SM(ah->ah_retry_short,
  262. AR5K_NODCU_RETRY_LMT_SSH_RETRY)
  263. | AR5K_REG_SM(ah->ah_retry_long,
  264. AR5K_NODCU_RETRY_LMT_LG_RETRY)
  265. | AR5K_REG_SM(ah->ah_retry_short,
  266. AR5K_NODCU_RETRY_LMT_SH_RETRY),
  267. AR5K_NODCU_RETRY_LMT);
  268. /* DCU on AR5211+ */
  269. } else {
  270. ath5k_hw_reg_write(ah,
  271. AR5K_REG_SM(ah->ah_retry_long,
  272. AR5K_DCU_RETRY_LMT_RTS)
  273. | AR5K_REG_SM(ah->ah_retry_long,
  274. AR5K_DCU_RETRY_LMT_STA_RTS)
  275. | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short),
  276. AR5K_DCU_RETRY_LMT_STA_DATA),
  277. AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
  278. }
  279. }
  280. /**
  281. * ath5k_hw_reset_tx_queue() - Initialize a single hw queue
  282. * @ah: The &struct ath5k_hw
  283. * @queue: One of enum ath5k_tx_queue_id
  284. *
  285. * Set DCF properties for the given transmit queue on DCU
  286. * and configures all queue-specific parameters.
  287. */
  288. int
  289. ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
  290. {
  291. struct ath5k_txq_info *tq = &ah->ah_txq[queue];
  292. AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
  293. tq = &ah->ah_txq[queue];
  294. /* Skip if queue inactive or if we are on AR5210
  295. * that doesn't have QCU/DCU */
  296. if ((ah->ah_version == AR5K_AR5210) ||
  297. (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
  298. return 0;
  299. /*
  300. * Set contention window (cw_min/cw_max)
  301. * and arbitrated interframe space (aifs)...
  302. */
  303. ath5k_hw_reg_write(ah,
  304. AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
  305. AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
  306. AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
  307. AR5K_QUEUE_DFS_LOCAL_IFS(queue));
  308. /*
  309. * Set tx retry limits for this queue
  310. */
  311. ath5k_hw_set_tx_retry_limits(ah, queue);
  312. /*
  313. * Set misc registers
  314. */
  315. /* Enable DCU to wait for next fragment from QCU */
  316. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
  317. AR5K_DCU_MISC_FRAG_WAIT);
  318. /* On Maui and Spirit use the global seqnum on DCU */
  319. if (ah->ah_mac_version < AR5K_SREV_AR5211)
  320. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
  321. AR5K_DCU_MISC_SEQNUM_CTL);
  322. /* Constant bit rate period */
  323. if (tq->tqi_cbr_period) {
  324. ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
  325. AR5K_QCU_CBRCFG_INTVAL) |
  326. AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
  327. AR5K_QCU_CBRCFG_ORN_THRES),
  328. AR5K_QUEUE_CBRCFG(queue));
  329. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
  330. AR5K_QCU_MISC_FRSHED_CBR);
  331. if (tq->tqi_cbr_overflow_limit)
  332. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
  333. AR5K_QCU_MISC_CBR_THRES_ENABLE);
  334. }
  335. /* Ready time interval */
  336. if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
  337. ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
  338. AR5K_QCU_RDYTIMECFG_INTVAL) |
  339. AR5K_QCU_RDYTIMECFG_ENABLE,
  340. AR5K_QUEUE_RDYTIMECFG(queue));
  341. if (tq->tqi_burst_time) {
  342. ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
  343. AR5K_DCU_CHAN_TIME_DUR) |
  344. AR5K_DCU_CHAN_TIME_ENABLE,
  345. AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
  346. if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
  347. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
  348. AR5K_QCU_MISC_RDY_VEOL_POLICY);
  349. }
  350. /* Enable/disable Post frame backoff */
  351. if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
  352. ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
  353. AR5K_QUEUE_DFS_MISC(queue));
  354. /* Enable/disable fragmentation burst backoff */
  355. if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
  356. ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
  357. AR5K_QUEUE_DFS_MISC(queue));
  358. /*
  359. * Set registers by queue type
  360. */
  361. switch (tq->tqi_type) {
  362. case AR5K_TX_QUEUE_BEACON:
  363. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
  364. AR5K_QCU_MISC_FRSHED_DBA_GT |
  365. AR5K_QCU_MISC_CBREXP_BCN_DIS |
  366. AR5K_QCU_MISC_BCN_ENABLE);
  367. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
  368. (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
  369. AR5K_DCU_MISC_ARBLOCK_CTL_S) |
  370. AR5K_DCU_MISC_ARBLOCK_IGNORE |
  371. AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
  372. AR5K_DCU_MISC_BCN_ENABLE);
  373. break;
  374. case AR5K_TX_QUEUE_CAB:
  375. /* XXX: use BCN_SENT_GT, if we can figure out how */
  376. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
  377. AR5K_QCU_MISC_FRSHED_DBA_GT |
  378. AR5K_QCU_MISC_CBREXP_DIS |
  379. AR5K_QCU_MISC_CBREXP_BCN_DIS);
  380. ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
  381. (AR5K_TUNE_SW_BEACON_RESP -
  382. AR5K_TUNE_DMA_BEACON_RESP) -
  383. AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
  384. AR5K_QCU_RDYTIMECFG_ENABLE,
  385. AR5K_QUEUE_RDYTIMECFG(queue));
  386. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
  387. (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
  388. AR5K_DCU_MISC_ARBLOCK_CTL_S));
  389. break;
  390. case AR5K_TX_QUEUE_UAPSD:
  391. AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
  392. AR5K_QCU_MISC_CBREXP_DIS);
  393. break;
  394. case AR5K_TX_QUEUE_DATA:
  395. default:
  396. break;
  397. }
  398. /* TODO: Handle frame compression */
  399. /*
  400. * Enable interrupts for this tx queue
  401. * in the secondary interrupt mask registers
  402. */
  403. if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
  404. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
  405. if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
  406. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
  407. if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
  408. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
  409. if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
  410. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
  411. if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
  412. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
  413. if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
  414. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
  415. if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
  416. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
  417. if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
  418. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
  419. if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
  420. AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
  421. /* Update secondary interrupt mask registers */
  422. /* Filter out inactive queues */
  423. ah->ah_txq_imr_txok &= ah->ah_txq_status;
  424. ah->ah_txq_imr_txerr &= ah->ah_txq_status;
  425. ah->ah_txq_imr_txurn &= ah->ah_txq_status;
  426. ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
  427. ah->ah_txq_imr_txeol &= ah->ah_txq_status;
  428. ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
  429. ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
  430. ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
  431. ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
  432. ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
  433. AR5K_SIMR0_QCU_TXOK) |
  434. AR5K_REG_SM(ah->ah_txq_imr_txdesc,
  435. AR5K_SIMR0_QCU_TXDESC),
  436. AR5K_SIMR0);
  437. ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
  438. AR5K_SIMR1_QCU_TXERR) |
  439. AR5K_REG_SM(ah->ah_txq_imr_txeol,
  440. AR5K_SIMR1_QCU_TXEOL),
  441. AR5K_SIMR1);
  442. /* Update SIMR2 but don't overwrite rest simr2 settings */
  443. AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
  444. AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
  445. AR5K_REG_SM(ah->ah_txq_imr_txurn,
  446. AR5K_SIMR2_QCU_TXURN));
  447. ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
  448. AR5K_SIMR3_QCBRORN) |
  449. AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
  450. AR5K_SIMR3_QCBRURN),
  451. AR5K_SIMR3);
  452. ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
  453. AR5K_SIMR4_QTRIG), AR5K_SIMR4);
  454. /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
  455. ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
  456. AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
  457. /* No queue has TXNOFRM enabled, disable the interrupt
  458. * by setting AR5K_TXNOFRM to zero */
  459. if (ah->ah_txq_imr_nofrm == 0)
  460. ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
  461. /* Set QCU mask for this DCU to save power */
  462. AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
  463. return 0;
  464. }
  465. /**************************\
  466. * Global QCU/DCU functions *
  467. \**************************/
  468. /**
  469. * ath5k_hw_set_ifs_intervals() - Set global inter-frame spaces on DCU
  470. * @ah: The &struct ath5k_hw
  471. * @slot_time: Slot time in us
  472. *
  473. * Sets the global IFS intervals on DCU (also works on AR5210) for
  474. * the given slot time and the current bwmode.
  475. */
  476. int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
  477. {
  478. struct ieee80211_channel *channel = ah->ah_current_channel;
  479. struct ieee80211_rate *rate;
  480. u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
  481. u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
  482. if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
  483. return -EINVAL;
  484. sifs = ath5k_hw_get_default_sifs(ah);
  485. sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);
  486. /* EIFS
  487. * Txtime of ack at lowest rate + SIFS + DIFS
  488. * (DIFS = SIFS + 2 * Slot time)
  489. *
  490. * Note: HAL has some predefined values for EIFS
  491. * Turbo: (37 + 2 * 6)
  492. * Default: (74 + 2 * 9)
  493. * Half: (149 + 2 * 13)
  494. * Quarter: (298 + 2 * 21)
  495. *
  496. * (74 + 2 * 6) for AR5210 default and turbo !
  497. *
  498. * According to the formula we have
  499. * ack_tx_time = 25 for turbo and
  500. * ack_tx_time = 42.5 * clock multiplier
  501. * for default/half/quarter.
  502. *
  503. * This can't be right, 42 is what we would get
  504. * from ath5k_hw_get_frame_dur_for_bwmode or
  505. * ieee80211_generic_frame_duration for zero frame
  506. * length and without SIFS !
  507. *
  508. * Also we have different lowest rate for 802.11a
  509. */
  510. if (channel->band == IEEE80211_BAND_5GHZ)
  511. rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
  512. else
  513. rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
  514. ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
  515. /* ack_tx_time includes an SIFS already */
  516. eifs = ack_tx_time + sifs + 2 * slot_time;
  517. eifs_clock = ath5k_hw_htoclock(ah, eifs);
  518. /* Set IFS settings on AR5210 */
  519. if (ah->ah_version == AR5K_AR5210) {
  520. u32 pifs, pifs_clock, difs, difs_clock;
  521. /* Set slot time */
  522. ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
  523. /* Set EIFS */
  524. eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
  525. /* PIFS = Slot time + SIFS */
  526. pifs = slot_time + sifs;
  527. pifs_clock = ath5k_hw_htoclock(ah, pifs);
  528. pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
  529. /* DIFS = SIFS + 2 * Slot time */
  530. difs = sifs + 2 * slot_time;
  531. difs_clock = ath5k_hw_htoclock(ah, difs);
  532. /* Set SIFS/DIFS */
  533. ath5k_hw_reg_write(ah, (difs_clock <<
  534. AR5K_IFS0_DIFS_S) | sifs_clock,
  535. AR5K_IFS0);
  536. /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
  537. ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
  538. (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
  539. AR5K_IFS1);
  540. return 0;
  541. }
  542. /* Set IFS slot time */
  543. ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
  544. /* Set EIFS interval */
  545. ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
  546. /* Set SIFS interval in usecs */
  547. AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
  548. AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
  549. sifs);
  550. /* Set SIFS interval in clock cycles */
  551. ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
  552. return 0;
  553. }
  554. /**
  555. * ath5k_hw_init_queues() - Initialize tx queues
  556. * @ah: The &struct ath5k_hw
  557. *
  558. * Initializes all tx queues based on information on
  559. * ah->ah_txq* set by the driver
  560. */
  561. int
  562. ath5k_hw_init_queues(struct ath5k_hw *ah)
  563. {
  564. int i, ret;
  565. /* TODO: HW Compression support for data queues */
  566. /* TODO: Burst prefetch for data queues */
  567. /*
  568. * Reset queues and start beacon timers at the end of the reset routine
  569. * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
  570. * Note: If we want we can assign multiple qcus on one dcu.
  571. */
  572. if (ah->ah_version != AR5K_AR5210)
  573. for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
  574. ret = ath5k_hw_reset_tx_queue(ah, i);
  575. if (ret) {
  576. ATH5K_ERR(ah,
  577. "failed to reset TX queue #%d\n", i);
  578. return ret;
  579. }
  580. }
  581. else
  582. /* No QCU/DCU on AR5210, just set tx
  583. * retry limits. We set IFS parameters
  584. * on ath5k_hw_set_ifs_intervals */
  585. ath5k_hw_set_tx_retry_limits(ah, 0);
  586. /* Set the turbo flag when operating on 40MHz */
  587. if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
  588. AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
  589. AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);
  590. /* If we didn't set IFS timings through
  591. * ath5k_hw_set_coverage_class make sure
  592. * we set them here */
  593. if (!ah->ah_coverage_class) {
  594. unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
  595. ath5k_hw_set_ifs_intervals(ah, slot_time);
  596. }
  597. return 0;
  598. }