hal_rx.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*
  2. * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include "hal_api.h"
  19. #include "hal_hw_headers.h"
  20. #include "qdf_module.h"
  21. /* TODO: See if the following definition is available in HW headers */
  22. #define HAL_REO_OWNED 4
  23. #define HAL_REO_QUEUE_DESC 8
  24. #define HAL_REO_QUEUE_EXT_DESC 9
  25. /* TODO: Using associated link desc counter 1 for Rx. Check with FW on
  26. * how these counters are assigned
  27. */
  28. #define HAL_RX_LINK_DESC_CNTR 1
  29. /* TODO: Following definition should be from HW headers */
  30. #define HAL_DESC_REO_OWNED 4
  31. /* TODO: Move this to common header file */
  32. static inline void hal_uniform_desc_hdr_setup(uint32_t *desc, uint32_t owner,
  33. uint32_t buffer_type)
  34. {
  35. HAL_DESC_SET_FIELD(desc, UNIFORM_DESCRIPTOR_HEADER_0, OWNER,
  36. owner);
  37. HAL_DESC_SET_FIELD(desc, UNIFORM_DESCRIPTOR_HEADER_0, BUFFER_TYPE,
  38. buffer_type);
  39. }
  40. #ifndef TID_TO_WME_AC
  41. #define WME_AC_BE 0 /* best effort */
  42. #define WME_AC_BK 1 /* background */
  43. #define WME_AC_VI 2 /* video */
  44. #define WME_AC_VO 3 /* voice */
  45. #define TID_TO_WME_AC(_tid) ( \
  46. (((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
  47. (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
  48. (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
  49. WME_AC_VO)
  50. #endif
  51. #define HAL_NON_QOS_TID 16
  52. /**
  53. * hal_reo_qdesc_setup - Setup HW REO queue descriptor
  54. *
  55. * @hal_soc: Opaque HAL SOC handle
  56. * @ba_window_size: BlockAck window size
  57. * @start_seq: Starting sequence number
  58. * @hw_qdesc_vaddr: Virtual address of REO queue descriptor memory
  59. * @hw_qdesc_paddr: Physical address of REO queue descriptor memory
  60. * @tid: TID
  61. *
  62. */
  63. void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size,
  64. uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr,
  65. int pn_type)
  66. {
  67. uint32_t *reo_queue_desc = (uint32_t *)hw_qdesc_vaddr;
  68. uint32_t *reo_queue_ext_desc;
  69. uint32_t reg_val;
  70. uint32_t pn_enable;
  71. uint32_t pn_size = 0;
  72. qdf_mem_zero(hw_qdesc_vaddr, sizeof(struct rx_reo_queue));
  73. hal_uniform_desc_hdr_setup(reo_queue_desc, HAL_DESC_REO_OWNED,
  74. HAL_REO_QUEUE_DESC);
  75. /* Fixed pattern in reserved bits for debugging */
  76. HAL_DESC_SET_FIELD(reo_queue_desc, UNIFORM_DESCRIPTOR_HEADER_0,
  77. RESERVED_0A, 0xDDBEEF);
  78. /* This a just a SW meta data and will be copied to REO destination
  79. * descriptors indicated by hardware.
  80. * TODO: Setting TID in this field. See if we should set something else.
  81. */
  82. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_1,
  83. RECEIVE_QUEUE_NUMBER, tid);
  84. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  85. VLD, 1);
  86. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  87. ASSOCIATED_LINK_DESCRIPTOR_COUNTER, HAL_RX_LINK_DESC_CNTR);
  88. /*
  89. * Fields DISABLE_DUPLICATE_DETECTION and SOFT_REORDER_ENABLE will be 0
  90. */
  91. reg_val = TID_TO_WME_AC(tid);
  92. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, AC, reg_val);
  93. if (ba_window_size < 1)
  94. ba_window_size = 1;
  95. /*
  96. * WAR to get 2k exception in Non BA case.
  97. * Setting window size to 2 to get 2k jump exception
  98. * when we receive aggregates in Non BA case
  99. */
  100. if (ba_window_size == 1)
  101. ba_window_size++;
  102. /* Set RTY bit for non-BA case. Duplicate detection is currently not
  103. * done by HW in non-BA case if RTY bit is not set.
  104. * TODO: This is a temporary War and should be removed once HW fix is
  105. * made to check and discard duplicates even if RTY bit is not set.
  106. */
  107. if (ba_window_size == 1)
  108. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, RTY, 1);
  109. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, BA_WINDOW_SIZE,
  110. ba_window_size - 1);
  111. switch (pn_type) {
  112. case HAL_PN_WPA:
  113. pn_enable = 1;
  114. pn_size = PN_SIZE_48;
  115. case HAL_PN_WAPI_EVEN:
  116. case HAL_PN_WAPI_UNEVEN:
  117. pn_enable = 1;
  118. pn_size = PN_SIZE_128;
  119. default:
  120. pn_enable = 0;
  121. }
  122. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_CHECK_NEEDED,
  123. pn_enable);
  124. if (pn_type == HAL_PN_WAPI_EVEN)
  125. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  126. PN_SHALL_BE_EVEN, 1);
  127. else if (pn_type == HAL_PN_WAPI_UNEVEN)
  128. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  129. PN_SHALL_BE_UNEVEN, 1);
  130. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_HANDLING_ENABLE,
  131. pn_enable);
  132. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_SIZE,
  133. pn_size);
  134. /* TODO: Check if RX_REO_QUEUE_2_IGNORE_AMPDU_FLAG need to be set
  135. * based on BA window size and/or AMPDU capabilities
  136. */
  137. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  138. IGNORE_AMPDU_FLAG, 1);
  139. if (start_seq <= 0xfff)
  140. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_3, SSN,
  141. start_seq);
  142. /* TODO: SVLD should be set to 1 if a valid SSN is received in ADDBA,
  143. * but REO is not delivering packets if we set it to 1. Need to enable
  144. * this once the issue is resolved */
  145. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_3, SVLD, 0);
  146. /* TODO: Check if we should set start PN for WAPI */
  147. #ifdef notyet
  148. /* Setup first queue extension if BA window size is more than 1 */
  149. if (ba_window_size > 1) {
  150. reo_queue_ext_desc =
  151. (uint32_t *)(((struct rx_reo_queue *)reo_queue_desc) +
  152. 1);
  153. qdf_mem_zero(reo_queue_ext_desc,
  154. sizeof(struct rx_reo_queue_ext));
  155. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  156. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  157. }
  158. /* Setup second queue extension if BA window size is more than 105 */
  159. if (ba_window_size > 105) {
  160. reo_queue_ext_desc = (uint32_t *)
  161. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  162. qdf_mem_zero(reo_queue_ext_desc,
  163. sizeof(struct rx_reo_queue_ext));
  164. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  165. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  166. }
  167. /* Setup third queue extension if BA window size is more than 210 */
  168. if (ba_window_size > 210) {
  169. reo_queue_ext_desc = (uint32_t *)
  170. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  171. qdf_mem_zero(reo_queue_ext_desc,
  172. sizeof(struct rx_reo_queue_ext));
  173. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  174. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  175. }
  176. #else
  177. /* TODO: HW queue descriptors are currently allocated for max BA
  178. * window size for all QOS TIDs so that same descriptor can be used
  179. * later when ADDBA request is recevied. This should be changed to
  180. * allocate HW queue descriptors based on BA window size being
  181. * negotiated (0 for non BA cases), and reallocate when BA window
  182. * size changes and also send WMI message to FW to change the REO
  183. * queue descriptor in Rx peer entry as part of dp_rx_tid_update.
  184. */
  185. if (tid != HAL_NON_QOS_TID) {
  186. reo_queue_ext_desc = (uint32_t *)
  187. (((struct rx_reo_queue *)reo_queue_desc) + 1);
  188. qdf_mem_zero(reo_queue_ext_desc, 3 *
  189. sizeof(struct rx_reo_queue_ext));
  190. /* Initialize first reo queue extension descriptor */
  191. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  192. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  193. /* Fixed pattern in reserved bits for debugging */
  194. HAL_DESC_SET_FIELD(reo_queue_ext_desc,
  195. UNIFORM_DESCRIPTOR_HEADER_0, RESERVED_0A, 0xADBEEF);
  196. /* Initialize second reo queue extension descriptor */
  197. reo_queue_ext_desc = (uint32_t *)
  198. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  199. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  200. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  201. /* Fixed pattern in reserved bits for debugging */
  202. HAL_DESC_SET_FIELD(reo_queue_ext_desc,
  203. UNIFORM_DESCRIPTOR_HEADER_0, RESERVED_0A, 0xBDBEEF);
  204. /* Initialize third reo queue extension descriptor */
  205. reo_queue_ext_desc = (uint32_t *)
  206. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  207. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  208. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  209. /* Fixed pattern in reserved bits for debugging */
  210. HAL_DESC_SET_FIELD(reo_queue_ext_desc,
  211. UNIFORM_DESCRIPTOR_HEADER_0, RESERVED_0A, 0xCDBEEF);
  212. }
  213. #endif
  214. }
  215. qdf_export_symbol(hal_reo_qdesc_setup);
  216. /**
  217. * hal_reo_setup - Initialize HW REO block
  218. *
  219. * @hal_soc: Opaque HAL SOC handle
  220. * @reo_params: parameters needed by HAL for REO config
  221. */
  222. void hal_reo_setup(void *hal_soc,
  223. struct hal_reo_params *reo_params)
  224. {
  225. struct hal_soc *soc = (struct hal_soc *)hal_soc;
  226. uint32_t reg_val;
  227. reg_val = HAL_REG_READ(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
  228. SEQ_WCSS_UMAC_REO_REG_OFFSET));
  229. reg_val &= ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |
  230. HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK |
  231. HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK);
  232. reg_val |= HAL_SM(HWIO_REO_R0_GENERAL_ENABLE,
  233. FRAGMENT_DEST_RING, reo_params->frag_dst_ring) |
  234. HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_LIST_ENABLE, 1) |
  235. HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_FLUSH_ENABLE, 1);
  236. HAL_REG_WRITE(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
  237. SEQ_WCSS_UMAC_REO_REG_OFFSET), reg_val);
  238. /* Other ring enable bits and REO_ENABLE will be set by FW */
  239. /* TODO: Setup destination ring mapping if enabled */
  240. /* TODO: Error destination ring setting is left to default.
  241. * Default setting is to send all errors to release ring.
  242. */
  243. HAL_REG_WRITE(soc,
  244. HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR(
  245. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  246. HAL_DEFAULT_REO_TIMEOUT_MS * 1000);
  247. HAL_REG_WRITE(soc,
  248. HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR(
  249. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  250. (HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
  251. HAL_REG_WRITE(soc,
  252. HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR(
  253. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  254. (HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
  255. HAL_REG_WRITE(soc,
  256. HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(
  257. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  258. (HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
  259. /*
  260. * When hash based routing is enabled, routing of the rx packet
  261. * is done based on the following value: 1 _ _ _ _ The last 4
  262. * bits are based on hash[3:0]. This means the possible values
  263. * are 0x10 to 0x1f. This value is used to look-up the
  264. * ring ID configured in Destination_Ring_Ctrl_IX_* register.
  265. * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3
  266. * registers need to be configured to set-up the 16 entries to
  267. * map the hash values to a ring number. There are 3 bits per
  268. * hash entry – which are mapped as follows:
  269. * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI),
  270. * 7: NOT_USED.
  271. */
  272. if (reo_params->rx_hash_enabled) {
  273. HAL_REG_WRITE(soc,
  274. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
  275. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  276. reo_params->remap1);
  277. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  278. FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x"),
  279. HAL_REG_READ(soc,
  280. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
  281. SEQ_WCSS_UMAC_REO_REG_OFFSET)));
  282. HAL_REG_WRITE(soc,
  283. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
  284. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  285. reo_params->remap2);
  286. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  287. FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x"),
  288. HAL_REG_READ(soc,
  289. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
  290. SEQ_WCSS_UMAC_REO_REG_OFFSET)));
  291. }
  292. /* TODO: Check if the following registers shoould be setup by host:
  293. * AGING_CONTROL
  294. * HIGH_MEMORY_THRESHOLD
  295. * GLOBAL_LINK_DESC_COUNT_THRESH_IX_0[1,2]
  296. * GLOBAL_LINK_DESC_COUNT_CTRL
  297. */
  298. }
  299. qdf_export_symbol(hal_reo_setup);
  300. /**
  301. * hal_get_ba_aging_timeout - Get BA Aging timeout
  302. *
  303. * @hal_soc: Opaque HAL SOC handle
  304. * @ac: Access category
  305. * @value: window size to get
  306. */
  307. void hal_get_ba_aging_timeout(void *hal_soc, uint8_t ac,
  308. uint32_t *value)
  309. {
  310. struct hal_soc *soc = (struct hal_soc *)hal_soc;
  311. switch (ac) {
  312. case WME_AC_BE:
  313. *value = HAL_REG_READ(soc,
  314. HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR(
  315. SEQ_WCSS_UMAC_REO_REG_OFFSET)) / 1000;
  316. break;
  317. case WME_AC_BK:
  318. *value = HAL_REG_READ(soc,
  319. HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR(
  320. SEQ_WCSS_UMAC_REO_REG_OFFSET)) / 1000;
  321. break;
  322. case WME_AC_VI:
  323. *value = HAL_REG_READ(soc,
  324. HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR(
  325. SEQ_WCSS_UMAC_REO_REG_OFFSET)) / 1000;
  326. break;
  327. case WME_AC_VO:
  328. *value = HAL_REG_READ(soc,
  329. HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(
  330. SEQ_WCSS_UMAC_REO_REG_OFFSET)) / 1000;
  331. break;
  332. default:
  333. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  334. "Invalid AC: %d\n", ac);
  335. }
  336. }
  337. qdf_export_symbol(hal_get_ba_aging_timeout);
  338. /**
  339. * hal_set_ba_aging_timeout - Set BA Aging timeout
  340. *
  341. * @hal_soc: Opaque HAL SOC handle
  342. * @ac: Access category
  343. * ac: 0 - Background, 1 - Best Effort, 2 - Video, 3 - Voice
  344. * @value: Input value to set
  345. */
  346. void hal_set_ba_aging_timeout(void *hal_soc, uint8_t ac,
  347. uint32_t value)
  348. {
  349. struct hal_soc *soc = (struct hal_soc *)hal_soc;
  350. switch (ac) {
  351. case WME_AC_BE:
  352. HAL_REG_WRITE(soc,
  353. HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR(
  354. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  355. value * 1000);
  356. break;
  357. case WME_AC_BK:
  358. HAL_REG_WRITE(soc,
  359. HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR(
  360. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  361. value * 1000);
  362. break;
  363. case WME_AC_VI:
  364. HAL_REG_WRITE(soc,
  365. HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR(
  366. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  367. value * 1000);
  368. break;
  369. case WME_AC_VO:
  370. HAL_REG_WRITE(soc,
  371. HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(
  372. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  373. value * 1000);
  374. break;
  375. default:
  376. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  377. "Invalid AC: %d\n", ac);
  378. }
  379. }
  380. qdf_export_symbol(hal_set_ba_aging_timeout);