hal_rx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * Copyright (c) 2016-2017 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. /* TODO: See if the following definition is available in HW headers */
  20. #define HAL_REO_OWNED 4
  21. #define HAL_REO_QUEUE_DESC 8
  22. #define HAL_REO_QUEUE_EXT_DESC 9
  23. #define PN_SIZE_24 0
  24. #define PN_SIZE_48 1
  25. #define PN_SIZE_128 2
  26. /* TODO: Using associated link desc counter 1 for Rx. Check with FW on
  27. * how these counters are assigned
  28. */
  29. #define HAL_RX_LINK_DESC_CNTR 1
  30. /* TODO: Following definition should be from HW headers */
  31. #define HAL_DESC_REO_OWNED 4
  32. /* TODO: Move this to common header file */
  33. static inline void hal_uniform_desc_hdr_setup(uint32_t *desc, uint32_t owner,
  34. uint32_t buffer_type)
  35. {
  36. HAL_DESC_SET_FIELD(desc, UNIFORM_DESCRIPTOR_HEADER_0, OWNER,
  37. owner);
  38. HAL_DESC_SET_FIELD(desc, UNIFORM_DESCRIPTOR_HEADER_0, BUFFER_TYPE,
  39. buffer_type);
  40. }
  41. #ifndef TID_TO_WME_AC
  42. #define WME_AC_BE 0 /* best effort */
  43. #define WME_AC_BK 1 /* background */
  44. #define WME_AC_VI 2 /* video */
  45. #define WME_AC_VO 3 /* voice */
  46. #define TID_TO_WME_AC(_tid) ( \
  47. (((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
  48. (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
  49. (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
  50. WME_AC_VO)
  51. #endif
  52. #define HAL_NON_QOS_TID 16
  53. /**
  54. * When hash based routing is enabled, routing of the rx packet
  55. * is done based on the following value: 1 _ _ _ _ The last 4
  56. * bits are based on hash[3:0]. This means the possible values
  57. * are 0x10 to 0x1f. This value is used to look-up the
  58. * ring ID configured in Destination_Ring_Ctrl_IX_* register.
  59. * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3
  60. * registers need to be configured to set-up the 16 entries to
  61. * map the hash values to a ring number. There are 3 bits per
  62. * hash entry – which are mapped as follows:
  63. * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI),
  64. * 7: NOT_USED.
  65. */
  66. #ifdef IPA_OFFLOAD
  67. /**
  68. * When IPA is enabled, there will be 3 available rings.
  69. * Otherwise there will be 4.
  70. */
  71. #define REO_REMAP_REGISTER_2 ( \
  72. ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x1 << 9) | \
  73. (0x2 << 12) | (0x3 << 15) | (0x1 << 18) | (0x2 << 21)) << 8)
  74. #define REO_REMAP_REGISTER_3 ( \
  75. ((0x3 << 0) | (0x1 << 3) | (0x2 << 6) | (0x3 << 9) | \
  76. (0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x1 << 21)) << 8)
  77. #else
  78. #define REO_REMAP_REGISTER_2 ( \
  79. ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x4 << 9) | \
  80. (0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x4 << 21)) << 8)
  81. #define REO_REMAP_REGISTER_3 ( \
  82. ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x4 << 9) | \
  83. (0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x4 << 21)) << 8)
  84. #endif
  85. /**
  86. * hal_reo_qdesc_setup - Setup HW REO queue descriptor
  87. *
  88. * @hal_soc: Opaque HAL SOC handle
  89. * @ba_window_size: BlockAck window size
  90. * @start_seq: Starting sequence number
  91. * @hw_qdesc_vaddr: Virtual address of REO queue descriptor memory
  92. * @hw_qdesc_paddr: Physical address of REO queue descriptor memory
  93. * @tid: TID
  94. *
  95. */
  96. void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size,
  97. uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr,
  98. int pn_type)
  99. {
  100. uint32_t *reo_queue_desc = (uint32_t *)hw_qdesc_vaddr;
  101. uint32_t *reo_queue_ext_desc;
  102. uint32_t reg_val;
  103. uint32_t pn_enable, pn_size;
  104. qdf_mem_zero(hw_qdesc_vaddr, sizeof(struct rx_reo_queue));
  105. hal_uniform_desc_hdr_setup(reo_queue_desc, HAL_DESC_REO_OWNED,
  106. HAL_REO_QUEUE_DESC);
  107. /* This a just a SW meta data and will be copied to REO destination
  108. * descriptors indicated by hardware.
  109. * TODO: Setting TID in this field. See if we should set something else.
  110. */
  111. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_1,
  112. RECEIVE_QUEUE_NUMBER, tid);
  113. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  114. VLD, 1);
  115. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  116. ASSOCIATED_LINK_DESCRIPTOR_COUNTER, HAL_RX_LINK_DESC_CNTR);
  117. /*
  118. * Fields DISABLE_DUPLICATE_DETECTION and SOFT_REORDER_ENABLE will be 0
  119. */
  120. reg_val = TID_TO_WME_AC(tid);
  121. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, AC, reg_val);
  122. /* Set RTY bit for non-BA case. Duplicate detection is currently not
  123. * done by HW in non-BA case if RTY bit is not set.
  124. * TODO: This is a temporary War and should be removed once HW fix is
  125. * made to check and discard duplicates even if RTY bit is not set.
  126. */
  127. if (ba_window_size == 1)
  128. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, RTY, 1);
  129. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, BA_WINDOW_SIZE,
  130. ba_window_size - 1);
  131. switch (pn_type) {
  132. case HAL_PN_WPA:
  133. pn_enable = 1;
  134. pn_size = PN_SIZE_48;
  135. case HAL_PN_WAPI_EVEN:
  136. case HAL_PN_WAPI_UNEVEN:
  137. pn_enable = 1;
  138. pn_size = PN_SIZE_128;
  139. default:
  140. pn_enable = 0;
  141. }
  142. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_CHECK_NEEDED,
  143. pn_enable);
  144. if (pn_type == HAL_PN_WAPI_EVEN)
  145. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  146. PN_SHALL_BE_EVEN, 1);
  147. else if (pn_type == HAL_PN_WAPI_UNEVEN)
  148. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  149. PN_SHALL_BE_UNEVEN, 1);
  150. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_HANDLING_ENABLE,
  151. pn_enable);
  152. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_SIZE,
  153. pn_size);
  154. /* TODO: Check if RX_REO_QUEUE_2_IGNORE_AMPDU_FLAG need to be set
  155. * based on BA window size and/or AMPDU capabilities
  156. */
  157. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2,
  158. IGNORE_AMPDU_FLAG, 1);
  159. if (start_seq <= 0xfff)
  160. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_3, SSN,
  161. start_seq);
  162. /* TODO: SVLD should be set to 1 if a valid SSN is received in ADDBA,
  163. * but REO is not delivering packets if we set it to 1. Need to enable
  164. * this once the issue is resolved */
  165. HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_3, SVLD, 0);
  166. /* TODO: Check if we should set start PN for WAPI */
  167. #ifdef notyet
  168. /* Setup first queue extension if BA window size is more than 1 */
  169. if (ba_window_size > 1) {
  170. reo_queue_ext_desc =
  171. (uint32_t *)(((struct rx_reo_queue *)reo_queue_desc) +
  172. 1);
  173. qdf_mem_zero(reo_queue_ext_desc,
  174. sizeof(struct rx_reo_queue_ext));
  175. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  176. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  177. }
  178. /* Setup second queue extension if BA window size is more than 105 */
  179. if (ba_window_size > 105) {
  180. reo_queue_ext_desc = (uint32_t *)
  181. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  182. qdf_mem_zero(reo_queue_ext_desc,
  183. sizeof(struct rx_reo_queue_ext));
  184. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  185. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  186. }
  187. /* Setup third queue extension if BA window size is more than 210 */
  188. if (ba_window_size > 210) {
  189. reo_queue_ext_desc = (uint32_t *)
  190. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  191. qdf_mem_zero(reo_queue_ext_desc,
  192. sizeof(struct rx_reo_queue_ext));
  193. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  194. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  195. }
  196. #else
  197. /* TODO: HW queue descriptors are currently allocated for max BA
  198. * window size for all QOS TIDs so that same descriptor can be used
  199. * later when ADDBA request is recevied. This should be changed to
  200. * allocate HW queue descriptors based on BA window size being
  201. * negotiated (0 for non BA cases), and reallocate when BA window
  202. * size changes and also send WMI message to FW to change the REO
  203. * queue descriptor in Rx peer entry as part of dp_rx_tid_update.
  204. */
  205. if (tid != HAL_NON_QOS_TID) {
  206. reo_queue_ext_desc = (uint32_t *)
  207. (((struct rx_reo_queue *)reo_queue_desc) + 1);
  208. qdf_mem_zero(reo_queue_ext_desc, 3 *
  209. sizeof(struct rx_reo_queue_ext));
  210. /* Initialize first reo queue extension descriptor */
  211. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  212. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  213. /* Initialize second reo queue extension descriptor */
  214. reo_queue_ext_desc = (uint32_t *)
  215. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  216. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  217. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  218. /* Initialize third reo queue extension descriptor */
  219. reo_queue_ext_desc = (uint32_t *)
  220. (((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
  221. hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
  222. HAL_DESC_REO_OWNED, HAL_REO_QUEUE_EXT_DESC);
  223. }
  224. #endif
  225. }
  226. /**
  227. * hal_reo_setup - Initialize HW REO block
  228. *
  229. * @hal_soc: Opaque HAL SOC handle
  230. * @reo_params: parameters needed by HAL for REO config
  231. */
  232. void hal_reo_setup(void *hal_soc,
  233. struct hal_reo_params *reo_params)
  234. {
  235. struct hal_soc *soc = (struct hal_soc *)hal_soc;
  236. HAL_REG_WRITE(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
  237. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  238. HAL_SM(HWIO_REO_R0_GENERAL_ENABLE,
  239. FRAGMENT_DEST_RING, HAL_SRNG_REO_EXCEPTION) |
  240. HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_LIST_ENABLE, 1) |
  241. HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_FLUSH_ENABLE, 1));
  242. /* Other ring enable bits and REO_ENABLE will be set by FW */
  243. /* TODO: Setup destination ring mapping if enabled */
  244. /* TODO: Error destination ring setting is left to default.
  245. * Default setting is to send all errors to release ring.
  246. */
  247. HAL_REG_WRITE(soc,
  248. HWIO_REO_R0_AGING_THRESHOLD_IX_0_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_1_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_2_ADDR(
  257. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  258. (HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
  259. HAL_REG_WRITE(soc,
  260. HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(
  261. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  262. (HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
  263. if (reo_params->rx_hash_enabled) {
  264. HAL_REG_WRITE(soc,
  265. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
  266. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  267. REO_REMAP_REGISTER_2);
  268. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  269. FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x\n"),
  270. HAL_REG_READ(soc,
  271. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
  272. SEQ_WCSS_UMAC_REO_REG_OFFSET)));
  273. HAL_REG_WRITE(soc,
  274. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
  275. SEQ_WCSS_UMAC_REO_REG_OFFSET),
  276. REO_REMAP_REGISTER_3);
  277. QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
  278. FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x\n"),
  279. HAL_REG_READ(soc,
  280. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
  281. SEQ_WCSS_UMAC_REO_REG_OFFSET)));
  282. }
  283. /* TODO: Check if the following registers shoould be setup by host:
  284. * AGING_CONTROL
  285. * HIGH_MEMORY_THRESHOLD
  286. * GLOBAL_LINK_DESC_COUNT_THRESH_IX_0[1,2]
  287. * GLOBAL_LINK_DESC_COUNT_CTRL
  288. */
  289. }