hal_be_generic_api.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. /*
  2. * Copyright (c) 2016-2021 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 <qdf_module.h>
  19. #include "hal_be_api.h"
  20. #include "hal_be_hw_headers.h"
  21. #include "hal_be_reo.h"
  22. #include "hal_tx.h" //HAL_SET_FLD
  23. #include "hal_be_rx.h" //HAL_RX_BUF_RBM_GET
  24. #include "hal_be_rx_tlv.h"
  25. #if defined(QDF_BIG_ENDIAN_MACHINE)
  26. /**
  27. * hal_setup_reo_swap() - Set the swap flag for big endian machines
  28. * @soc: HAL soc handle
  29. *
  30. * Return: None
  31. */
  32. static void hal_setup_reo_swap(struct hal_soc *soc)
  33. {
  34. uint32_t reg_val;
  35. reg_val = HAL_REG_READ(soc, HWIO_REO_R0_CACHE_CTL_CONFIG_ADDR(
  36. REO_REG_REG_BASE));
  37. reg_val |= HAL_SM(HWIO_REO_R0_CACHE_CTL_CONFIG, WRITE_STRUCT_SWAP, 1);
  38. reg_val |= HAL_SM(HWIO_REO_R0_CACHE_CTL_CONFIG, READ_STRUCT_SWAP, 1);
  39. HAL_REG_WRITE(soc, HWIO_REO_R0_CACHE_CTL_CONFIG_ADDR(
  40. REO_REG_REG_BASE), reg_val);
  41. }
  42. #else
  43. static inline void hal_setup_reo_swap(struct hal_soc *soc)
  44. {
  45. }
  46. #endif
  47. /**
  48. * hal_tx_init_data_ring_be() - Initialize all the TCL Descriptors in SRNG
  49. * @hal_soc_hdl: Handle to HAL SoC structure
  50. * @hal_srng: Handle to HAL SRNG structure
  51. *
  52. * Return: none
  53. */
  54. static void
  55. hal_tx_init_data_ring_be(hal_soc_handle_t hal_soc_hdl,
  56. hal_ring_handle_t hal_ring_hdl)
  57. {
  58. }
  59. void hal_reo_setup_generic_be(struct hal_soc *soc, void *reoparams)
  60. {
  61. uint32_t reg_val;
  62. struct hal_reo_params *reo_params = (struct hal_reo_params *)reoparams;
  63. reg_val = HAL_REG_READ(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
  64. REO_REG_REG_BASE));
  65. hal_reo_config(soc, reg_val, reo_params);
  66. /* Other ring enable bits and REO_ENABLE will be set by FW */
  67. /* TODO: Setup destination ring mapping if enabled */
  68. /* TODO: Error destination ring setting is left to default.
  69. * Default setting is to send all errors to release ring.
  70. */
  71. /* Set the reo descriptor swap bits in case of BIG endian platform */
  72. hal_setup_reo_swap(soc);
  73. HAL_REG_WRITE(soc,
  74. HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR(REO_REG_REG_BASE),
  75. HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS * 1000);
  76. HAL_REG_WRITE(soc,
  77. HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR(REO_REG_REG_BASE),
  78. (HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS * 1000));
  79. HAL_REG_WRITE(soc,
  80. HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR(REO_REG_REG_BASE),
  81. (HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS * 1000));
  82. HAL_REG_WRITE(soc,
  83. HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(REO_REG_REG_BASE),
  84. (HAL_DEFAULT_VO_REO_TIMEOUT_MS * 1000));
  85. /*
  86. * When hash based routing is enabled, routing of the rx packet
  87. * is done based on the following value: 1 _ _ _ _ The last 4
  88. * bits are based on hash[3:0]. This means the possible values
  89. * are 0x10 to 0x1f. This value is used to look-up the
  90. * ring ID configured in Destination_Ring_Ctrl_IX_* register.
  91. * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3
  92. * registers need to be configured to set-up the 16 entries to
  93. * map the hash values to a ring number. There are 3 bits per
  94. * hash entry – which are mapped as follows:
  95. * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI),
  96. * 7: NOT_USED.
  97. */
  98. if (reo_params->rx_hash_enabled) {
  99. HAL_REG_WRITE(soc,
  100. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
  101. REO_REG_REG_BASE),
  102. reo_params->remap1);
  103. hal_debug("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x",
  104. HAL_REG_READ(soc,
  105. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
  106. REO_REG_REG_BASE)));
  107. HAL_REG_WRITE(soc,
  108. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
  109. REO_REG_REG_BASE),
  110. reo_params->remap2);
  111. hal_debug("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x",
  112. HAL_REG_READ(soc,
  113. HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
  114. REO_REG_REG_BASE)));
  115. }
  116. /* TODO: Check if the following registers shoould be setup by host:
  117. * AGING_CONTROL
  118. * HIGH_MEMORY_THRESHOLD
  119. * GLOBAL_LINK_DESC_COUNT_THRESH_IX_0[1,2]
  120. * GLOBAL_LINK_DESC_COUNT_CTRL
  121. */
  122. }
  123. void hal_set_link_desc_addr_be(void *desc, uint32_t cookie,
  124. qdf_dma_addr_t link_desc_paddr)
  125. {
  126. uint32_t *buf_addr = (uint32_t *)desc;
  127. HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO, BUFFER_ADDR_31_0,
  128. link_desc_paddr & 0xffffffff);
  129. HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO, BUFFER_ADDR_39_32,
  130. (uint64_t)link_desc_paddr >> 32);
  131. HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO, RETURN_BUFFER_MANAGER,
  132. WBM_IDLE_DESC_LIST);
  133. HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO, SW_BUFFER_COOKIE,
  134. cookie);
  135. }
  136. static uint32_t hal_get_reo_qdesc_size_be(uint32_t ba_window_size, int tid)
  137. {
  138. /* Return descriptor size corresponding to window size of 2 since
  139. * we set ba_window_size to 2 while setting up REO descriptors as
  140. * a WAR to get 2k jump exception aggregates are received without
  141. * a BA session.
  142. */
  143. if (ba_window_size <= 1) {
  144. if (tid != HAL_NON_QOS_TID)
  145. return sizeof(struct rx_reo_queue) +
  146. sizeof(struct rx_reo_queue_ext);
  147. else
  148. return sizeof(struct rx_reo_queue);
  149. }
  150. if (ba_window_size <= 105)
  151. return sizeof(struct rx_reo_queue) +
  152. sizeof(struct rx_reo_queue_ext);
  153. if (ba_window_size <= 210)
  154. return sizeof(struct rx_reo_queue) +
  155. (2 * sizeof(struct rx_reo_queue_ext));
  156. return sizeof(struct rx_reo_queue) +
  157. (3 * sizeof(struct rx_reo_queue_ext));
  158. }
  159. void *hal_rx_msdu_ext_desc_info_get_ptr_be(void *msdu_details_ptr)
  160. {
  161. return HAL_RX_MSDU_EXT_DESC_INFO_GET(msdu_details_ptr);
  162. }
  163. #ifdef TCL_DATA_CMD_SEARCH_INDEX_OFFSET
  164. void hal_tx_desc_set_search_index_generic_be(void *desc, uint32_t search_index)
  165. {
  166. HAL_SET_FLD(desc, TCL_DATA_CMD, SEARCH_INDEX) |=
  167. HAL_TX_SM(TCL_DATA_CMD, SEARCH_INDEX, search_index);
  168. }
  169. #else
  170. void hal_tx_desc_set_search_index_generic_be(void *desc, uint32_t search_index)
  171. {
  172. }
  173. #endif
  174. #ifdef TCL_DATA_CMD_CACHE_SET_NUM_OFFSET
  175. void hal_tx_desc_set_cache_set_num_generic_be(void *desc, uint8_t cache_num)
  176. {
  177. HAL_SET_FLD(desc, TCL_DATA_CMD, CACHE_SET_NUM) |=
  178. HAL_TX_SM(TCL_DATA_CMD, CACHE_SET_NUM, cache_num);
  179. }
  180. #else
  181. void hal_tx_desc_set_cache_set_num_generic_be(void *desc, uint8_t cache_num)
  182. {
  183. }
  184. #endif
  185. static inline uint32_t
  186. hal_wbm2sw_release_source_get(void *hal_desc, enum hal_be_wbm_release_dir dir)
  187. {
  188. uint32_t buf_src;
  189. buf_src = HAL_WBM2SW_RELEASE_SRC_GET(hal_desc);
  190. switch (buf_src) {
  191. case HAL_BE_RX_WBM_ERR_SRC_RXDMA:
  192. return HAL_RX_WBM_ERR_SRC_RXDMA;
  193. case HAL_BE_RX_WBM_ERR_SRC_REO:
  194. return HAL_RX_WBM_ERR_SRC_REO;
  195. case HAL_BE_RX_WBM_ERR_SRC_FW_RX:
  196. if (dir != HAL_BE_WBM_RELEASE_DIR_RX)
  197. qdf_assert_always(0);
  198. return HAL_RX_WBM_ERR_SRC_FW;
  199. case HAL_BE_RX_WBM_ERR_SRC_SW_RX:
  200. if (dir != HAL_BE_WBM_RELEASE_DIR_RX)
  201. qdf_assert_always(0);
  202. return HAL_RX_WBM_ERR_SRC_SW;
  203. case HAL_BE_RX_WBM_ERR_SRC_TQM:
  204. return HAL_RX_WBM_ERR_SRC_TQM;
  205. case HAL_BE_RX_WBM_ERR_SRC_FW_TX:
  206. if (dir != HAL_BE_WBM_RELEASE_DIR_TX)
  207. qdf_assert_always(0);
  208. return HAL_RX_WBM_ERR_SRC_FW;
  209. case HAL_BE_RX_WBM_ERR_SRC_SW_TX:
  210. if (dir != HAL_BE_WBM_RELEASE_DIR_TX)
  211. qdf_assert_always(0);
  212. return HAL_RX_WBM_ERR_SRC_SW;
  213. default:
  214. qdf_assert_always(0);
  215. }
  216. return buf_src;
  217. }
  218. uint32_t hal_tx_comp_get_buffer_source_generic_be(void *hal_desc)
  219. {
  220. return hal_wbm2sw_release_source_get(hal_desc,
  221. HAL_BE_WBM_RELEASE_DIR_TX);
  222. }
  223. /**
  224. * hal_setup_link_idle_list_generic_be - Setup scattered idle list using the
  225. * buffer list provided
  226. *
  227. * @hal_soc: Opaque HAL SOC handle
  228. * @scatter_bufs_base_paddr: Array of physical base addresses
  229. * @scatter_bufs_base_vaddr: Array of virtual base addresses
  230. * @num_scatter_bufs: Number of scatter buffers in the above lists
  231. * @scatter_buf_size: Size of each scatter buffer
  232. * @last_buf_end_offset: Offset to the last entry
  233. * @num_entries: Total entries of all scatter bufs
  234. *
  235. * Return: None
  236. */
  237. static void
  238. hal_setup_link_idle_list_generic_be(struct hal_soc *soc,
  239. qdf_dma_addr_t scatter_bufs_base_paddr[],
  240. void *scatter_bufs_base_vaddr[],
  241. uint32_t num_scatter_bufs,
  242. uint32_t scatter_buf_size,
  243. uint32_t last_buf_end_offset,
  244. uint32_t num_entries)
  245. {
  246. int i;
  247. uint32_t *prev_buf_link_ptr = NULL;
  248. uint32_t reg_scatter_buf_size, reg_tot_scatter_buf_size;
  249. uint32_t val;
  250. /* Link the scatter buffers */
  251. for (i = 0; i < num_scatter_bufs; i++) {
  252. if (i > 0) {
  253. prev_buf_link_ptr[0] =
  254. scatter_bufs_base_paddr[i] & 0xffffffff;
  255. prev_buf_link_ptr[1] = HAL_SM(
  256. HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
  257. BASE_ADDRESS_39_32,
  258. ((uint64_t)(scatter_bufs_base_paddr[i])
  259. >> 32)) | HAL_SM(
  260. HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
  261. ADDRESS_MATCH_TAG,
  262. ADDRESS_MATCH_TAG_VAL);
  263. }
  264. prev_buf_link_ptr = (uint32_t *)(scatter_bufs_base_vaddr[i] +
  265. scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE);
  266. }
  267. /* TBD: Register programming partly based on MLD & the rest based on
  268. * inputs from HW team. Not complete yet.
  269. */
  270. reg_scatter_buf_size = (scatter_buf_size -
  271. WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) / 64;
  272. reg_tot_scatter_buf_size = ((scatter_buf_size -
  273. WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) * num_scatter_bufs) / 64;
  274. HAL_REG_WRITE(soc,
  275. HWIO_WBM_R0_IDLE_LIST_CONTROL_ADDR(
  276. WBM_REG_REG_BASE),
  277. HAL_SM(HWIO_WBM_R0_IDLE_LIST_CONTROL, SCATTER_BUFFER_SIZE,
  278. reg_scatter_buf_size) |
  279. HAL_SM(HWIO_WBM_R0_IDLE_LIST_CONTROL, LINK_DESC_IDLE_LIST_MODE,
  280. 0x1));
  281. HAL_REG_WRITE(soc,
  282. HWIO_WBM_R0_IDLE_LIST_SIZE_ADDR(
  283. WBM_REG_REG_BASE),
  284. HAL_SM(HWIO_WBM_R0_IDLE_LIST_SIZE,
  285. SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST,
  286. reg_tot_scatter_buf_size));
  287. HAL_REG_WRITE(soc,
  288. HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_LSB_ADDR(
  289. WBM_REG_REG_BASE),
  290. scatter_bufs_base_paddr[0] & 0xffffffff);
  291. HAL_REG_WRITE(soc,
  292. HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_ADDR(
  293. WBM_REG_REG_BASE),
  294. ((uint64_t)(scatter_bufs_base_paddr[0]) >> 32) &
  295. HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_BASE_ADDRESS_39_32_BMSK);
  296. HAL_REG_WRITE(soc,
  297. HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_ADDR(
  298. WBM_REG_REG_BASE),
  299. HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
  300. BASE_ADDRESS_39_32, ((uint64_t)(scatter_bufs_base_paddr[0])
  301. >> 32)) |
  302. HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
  303. ADDRESS_MATCH_TAG, ADDRESS_MATCH_TAG_VAL));
  304. /* ADDRESS_MATCH_TAG field in the above register is expected to match
  305. * with the upper bits of link pointer. The above write sets this field
  306. * to zero and we are also setting the upper bits of link pointers to
  307. * zero while setting up the link list of scatter buffers above
  308. */
  309. /* Setup head and tail pointers for the idle list */
  310. HAL_REG_WRITE(soc,
  311. HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX0_ADDR(
  312. WBM_REG_REG_BASE),
  313. scatter_bufs_base_paddr[num_scatter_bufs - 1] & 0xffffffff);
  314. HAL_REG_WRITE(soc,
  315. HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1_ADDR(
  316. WBM_REG_REG_BASE),
  317. HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1,
  318. BUFFER_ADDRESS_39_32,
  319. ((uint64_t)(scatter_bufs_base_paddr[num_scatter_bufs - 1])
  320. >> 32)) |
  321. HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1,
  322. HEAD_POINTER_OFFSET, last_buf_end_offset >> 2));
  323. HAL_REG_WRITE(soc,
  324. HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX0_ADDR(
  325. WBM_REG_REG_BASE),
  326. scatter_bufs_base_paddr[0] & 0xffffffff);
  327. HAL_REG_WRITE(soc,
  328. HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX0_ADDR(
  329. WBM_REG_REG_BASE),
  330. scatter_bufs_base_paddr[0] & 0xffffffff);
  331. HAL_REG_WRITE(soc,
  332. HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1_ADDR(
  333. WBM_REG_REG_BASE),
  334. HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1,
  335. BUFFER_ADDRESS_39_32,
  336. ((uint64_t)(scatter_bufs_base_paddr[0]) >>
  337. 32)) | HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1,
  338. TAIL_POINTER_OFFSET, 0));
  339. HAL_REG_WRITE(soc,
  340. HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HP_ADDR(
  341. WBM_REG_REG_BASE),
  342. 2 * num_entries);
  343. /* Set RING_ID_DISABLE */
  344. val = HAL_SM(HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC, RING_ID_DISABLE, 1);
  345. /*
  346. * SRNG_ENABLE bit is not available in HWK v1 (QCA8074v1). Hence
  347. * check the presence of the bit before toggling it.
  348. */
  349. #ifdef HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE_BMSK
  350. val |= HAL_SM(HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC, SRNG_ENABLE, 1);
  351. #endif
  352. HAL_REG_WRITE(soc,
  353. HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC_ADDR(WBM_REG_REG_BASE),
  354. val);
  355. }
  356. /**
  357. * hal_rx_wbm_err_src_get_be() - Get WBM error source from descriptor
  358. * @ring_desc: ring descriptor
  359. *
  360. * Return: wbm error source
  361. */
  362. static uint32_t hal_rx_wbm_err_src_get_be(hal_ring_desc_t ring_desc)
  363. {
  364. return hal_wbm2sw_release_source_get(ring_desc,
  365. HAL_BE_WBM_RELEASE_DIR_RX);
  366. }
  367. /**
  368. * hal_rx_ret_buf_manager_get_be() - Get return buffer manager from ring desc
  369. * @ring_desc: ring descriptor
  370. *
  371. * Return: rbm
  372. */
  373. uint8_t hal_rx_ret_buf_manager_get_be(hal_ring_desc_t ring_desc)
  374. {
  375. /*
  376. * The following macro takes buf_addr_info as argument,
  377. * but since buf_addr_info is the first field in ring_desc
  378. * Hence the following call is OK
  379. */
  380. return HAL_RX_BUF_RBM_GET(ring_desc);
  381. }
  382. #define HAL_RX_WBM_REO_PUSH_REASON_GET(wbm_desc) (((*(((uint32_t *)wbm_desc) + \
  383. (WBM2SW_COMPLETION_RING_RX_REO_PUSH_REASON_OFFSET >> 2))) & \
  384. WBM2SW_COMPLETION_RING_RX_REO_PUSH_REASON_MASK) >> \
  385. WBM2SW_COMPLETION_RING_RX_REO_PUSH_REASON_LSB)
  386. #define HAL_RX_WBM_REO_ERROR_CODE_GET(wbm_desc) (((*(((uint32_t *)wbm_desc) + \
  387. (WBM2SW_COMPLETION_RING_RX_REO_ERROR_CODE_OFFSET >> 2))) & \
  388. WBM2SW_COMPLETION_RING_RX_REO_ERROR_CODE_MASK) >> \
  389. WBM2SW_COMPLETION_RING_RX_REO_ERROR_CODE_LSB)
  390. #define HAL_RX_WBM_RXDMA_PUSH_REASON_GET(wbm_desc) \
  391. (((*(((uint32_t *)wbm_desc) + \
  392. (WBM2SW_COMPLETION_RING_RX_RXDMA_PUSH_REASON_OFFSET >> 2))) & \
  393. WBM2SW_COMPLETION_RING_RX_RXDMA_PUSH_REASON_MASK) >> \
  394. WBM2SW_COMPLETION_RING_RX_RXDMA_PUSH_REASON_LSB)
  395. #define HAL_RX_WBM_RXDMA_ERROR_CODE_GET(wbm_desc) \
  396. (((*(((uint32_t *)wbm_desc) + \
  397. (WBM2SW_COMPLETION_RING_RX_RXDMA_ERROR_CODE_OFFSET >> 2))) & \
  398. WBM2SW_COMPLETION_RING_RX_RXDMA_ERROR_CODE_MASK) >> \
  399. WBM2SW_COMPLETION_RING_RX_RXDMA_ERROR_CODE_LSB)
  400. /**
  401. * hal_rx_wbm_err_info_get_generic_be(): Retrieves WBM error code and reason and
  402. * save it to hal_wbm_err_desc_info structure passed by caller
  403. * @wbm_desc: wbm ring descriptor
  404. * @wbm_er_info1: hal_wbm_err_desc_info structure, output parameter.
  405. * Return: void
  406. */
  407. void hal_rx_wbm_err_info_get_generic_be(void *wbm_desc, void *wbm_er_info1)
  408. {
  409. struct hal_wbm_err_desc_info *wbm_er_info =
  410. (struct hal_wbm_err_desc_info *)wbm_er_info1;
  411. wbm_er_info->wbm_err_src = hal_rx_wbm_err_src_get_be(wbm_desc);
  412. wbm_er_info->reo_psh_rsn = HAL_RX_WBM_REO_PUSH_REASON_GET(wbm_desc);
  413. wbm_er_info->reo_err_code = HAL_RX_WBM_REO_ERROR_CODE_GET(wbm_desc);
  414. wbm_er_info->rxdma_psh_rsn = HAL_RX_WBM_RXDMA_PUSH_REASON_GET(wbm_desc);
  415. wbm_er_info->rxdma_err_code = HAL_RX_WBM_RXDMA_ERROR_CODE_GET(wbm_desc);
  416. }
  417. static void hal_rx_reo_buf_paddr_get_be(hal_ring_desc_t rx_desc,
  418. struct hal_buf_info *buf_info)
  419. {
  420. struct reo_destination_ring *reo_ring =
  421. (struct reo_destination_ring *)rx_desc;
  422. buf_info->paddr =
  423. (HAL_RX_REO_BUFFER_ADDR_31_0_GET(reo_ring) |
  424. ((uint64_t)(HAL_RX_REO_BUFFER_ADDR_39_32_GET(reo_ring)) << 32));
  425. buf_info->sw_cookie = HAL_RX_REO_BUF_COOKIE_GET(reo_ring);
  426. }
  427. static void hal_rx_msdu_link_desc_set_be(hal_soc_handle_t hal_soc_hdl,
  428. void *src_srng_desc,
  429. hal_buff_addrinfo_t buf_addr_info,
  430. uint8_t bm_action)
  431. {
  432. /*
  433. * The offsets for fields used in this function are same in
  434. * wbm_release_ring for Lithium and wbm_release_ring_tx
  435. * for Beryllium. hence we can use wbm_release_ring directly.
  436. */
  437. struct wbm_release_ring *wbm_rel_srng =
  438. (struct wbm_release_ring *)src_srng_desc;
  439. uint32_t addr_31_0;
  440. uint8_t addr_39_32;
  441. /* Structure copy !!! */
  442. wbm_rel_srng->released_buff_or_desc_addr_info =
  443. *((struct buffer_addr_info *)buf_addr_info);
  444. addr_31_0 =
  445. wbm_rel_srng->released_buff_or_desc_addr_info.buffer_addr_31_0;
  446. addr_39_32 =
  447. wbm_rel_srng->released_buff_or_desc_addr_info.buffer_addr_39_32;
  448. HAL_DESC_SET_FIELD(src_srng_desc, HAL_SW2WBM_RELEASE_RING,
  449. RELEASE_SOURCE_MODULE, HAL_RX_WBM_ERR_SRC_SW);
  450. HAL_DESC_SET_FIELD(src_srng_desc, HAL_SW2WBM_RELEASE_RING, BM_ACTION,
  451. bm_action);
  452. HAL_DESC_SET_FIELD(src_srng_desc, HAL_SW2WBM_RELEASE_RING,
  453. BUFFER_OR_DESC_TYPE,
  454. HAL_RX_WBM_BUF_TYPE_MSDU_LINK_DESC);
  455. /* WBM error is indicated when any of the link descriptors given to
  456. * WBM has a NULL address, and one those paths is the link descriptors
  457. * released from host after processing RXDMA errors,
  458. * or from Rx defrag path, and we want to add an assert here to ensure
  459. * host is not releasing descriptors with NULL address.
  460. */
  461. if (qdf_unlikely(!addr_31_0 && !addr_39_32)) {
  462. hal_dump_wbm_rel_desc(src_srng_desc);
  463. qdf_assert_always(0);
  464. }
  465. }
  466. /**
  467. * hal_rx_reo_ent_buf_paddr_get_be: Gets the physical address and
  468. * cookie from the REO entrance ring element
  469. *
  470. * @ hal_rx_desc_cookie: Opaque cookie pointer used by HAL to get to
  471. * the current descriptor
  472. * @ buf_info: structure to return the buffer information
  473. * @ msdu_cnt: pointer to msdu count in MPDU
  474. * Return: void
  475. */
  476. static
  477. void hal_rx_buf_cookie_rbm_get_be(uint32_t *buf_addr_info_hdl,
  478. hal_buf_info_t buf_info_hdl)
  479. {
  480. struct hal_buf_info *buf_info =
  481. (struct hal_buf_info *)buf_info_hdl;
  482. struct buffer_addr_info *buf_addr_info =
  483. (struct buffer_addr_info *)buf_addr_info_hdl;
  484. buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
  485. /*
  486. * buffer addr info is the first member of ring desc, so the typecast
  487. * can be done.
  488. */
  489. buf_info->rbm = hal_rx_ret_buf_manager_get_be(
  490. (hal_ring_desc_t)buf_addr_info);
  491. }
  492. /*
  493. * hal_rxdma_buff_addr_info_set_be() - set the buffer_addr_info of the
  494. * rxdma ring entry.
  495. * @rxdma_entry: descriptor entry
  496. * @paddr: physical address of nbuf data pointer.
  497. * @cookie: SW cookie used as a index to SW rx desc.
  498. * @manager: who owns the nbuf (host, NSS, etc...).
  499. *
  500. */
  501. static inline void
  502. hal_rxdma_buff_addr_info_set_be(void *rxdma_entry,
  503. qdf_dma_addr_t paddr, uint32_t cookie,
  504. uint8_t manager)
  505. {
  506. uint32_t paddr_lo = ((u64)paddr & 0x00000000ffffffff);
  507. uint32_t paddr_hi = ((u64)paddr & 0xffffffff00000000) >> 32;
  508. HAL_RXDMA_PADDR_LO_SET(rxdma_entry, paddr_lo);
  509. HAL_RXDMA_PADDR_HI_SET(rxdma_entry, paddr_hi);
  510. HAL_RXDMA_COOKIE_SET(rxdma_entry, cookie);
  511. HAL_RXDMA_MANAGER_SET(rxdma_entry, manager);
  512. }
  513. /**
  514. * hal_rx_get_reo_error_code_be() - Get REO error code from ring desc
  515. * @rx_desc: rx descriptor
  516. *
  517. * Return: REO error code
  518. */
  519. static uint32_t hal_rx_get_reo_error_code_be(hal_ring_desc_t rx_desc)
  520. {
  521. struct reo_destination_ring *reo_desc =
  522. (struct reo_destination_ring *)rx_desc;
  523. return HAL_RX_REO_ERROR_GET(reo_desc);
  524. }
  525. /**
  526. * hal_gen_reo_remap_val_generic_be() - Generate the reo map value
  527. * @ix0_map: mapping values for reo
  528. *
  529. * Return: IX0 reo remap register value to be written
  530. */
  531. static uint32_t
  532. hal_gen_reo_remap_val_generic_be(enum hal_reo_remap_reg remap_reg,
  533. uint8_t *ix0_map)
  534. {
  535. uint32_t ix_val = 0;
  536. switch (remap_reg) {
  537. case HAL_REO_REMAP_REG_IX0:
  538. ix_val = HAL_REO_REMAP_IX0(ix0_map[0], 0) |
  539. HAL_REO_REMAP_IX0(ix0_map[1], 1) |
  540. HAL_REO_REMAP_IX0(ix0_map[2], 2) |
  541. HAL_REO_REMAP_IX0(ix0_map[3], 3) |
  542. HAL_REO_REMAP_IX0(ix0_map[4], 4) |
  543. HAL_REO_REMAP_IX0(ix0_map[5], 5) |
  544. HAL_REO_REMAP_IX0(ix0_map[6], 6) |
  545. HAL_REO_REMAP_IX0(ix0_map[7], 7);
  546. break;
  547. case HAL_REO_REMAP_REG_IX2:
  548. ix_val = HAL_REO_REMAP_IX2(ix0_map[0], 16) |
  549. HAL_REO_REMAP_IX2(ix0_map[1], 17) |
  550. HAL_REO_REMAP_IX2(ix0_map[2], 18) |
  551. HAL_REO_REMAP_IX2(ix0_map[3], 19) |
  552. HAL_REO_REMAP_IX2(ix0_map[4], 20) |
  553. HAL_REO_REMAP_IX2(ix0_map[5], 21) |
  554. HAL_REO_REMAP_IX2(ix0_map[6], 22) |
  555. HAL_REO_REMAP_IX2(ix0_map[7], 23);
  556. break;
  557. default:
  558. break;
  559. }
  560. return ix_val;
  561. }
  562. static uint8_t hal_rx_err_status_get_be(hal_ring_desc_t rx_desc)
  563. {
  564. return HAL_RX_ERROR_STATUS_GET(rx_desc);
  565. }
  566. static QDF_STATUS hal_reo_status_update_be(hal_soc_handle_t hal_soc_hdl,
  567. hal_ring_desc_t reo_desc,
  568. void *st_handle,
  569. uint32_t tlv, int *num_ref)
  570. {
  571. union hal_reo_status *reo_status_ref;
  572. reo_status_ref = (union hal_reo_status *)st_handle;
  573. switch (tlv) {
  574. case HAL_REO_QUEUE_STATS_STATUS_TLV:
  575. hal_reo_queue_stats_status_be(reo_desc,
  576. &reo_status_ref->queue_status,
  577. hal_soc_hdl);
  578. *num_ref = reo_status_ref->queue_status.header.cmd_num;
  579. break;
  580. case HAL_REO_FLUSH_QUEUE_STATUS_TLV:
  581. hal_reo_flush_queue_status_be(reo_desc,
  582. &reo_status_ref->fl_queue_status,
  583. hal_soc_hdl);
  584. *num_ref = reo_status_ref->fl_queue_status.header.cmd_num;
  585. break;
  586. case HAL_REO_FLUSH_CACHE_STATUS_TLV:
  587. hal_reo_flush_cache_status_be(reo_desc,
  588. &reo_status_ref->fl_cache_status,
  589. hal_soc_hdl);
  590. *num_ref = reo_status_ref->fl_cache_status.header.cmd_num;
  591. break;
  592. case HAL_REO_UNBLK_CACHE_STATUS_TLV:
  593. hal_reo_unblock_cache_status_be
  594. (reo_desc, hal_soc_hdl,
  595. &reo_status_ref->unblk_cache_status);
  596. *num_ref = reo_status_ref->unblk_cache_status.header.cmd_num;
  597. break;
  598. case HAL_REO_TIMOUT_LIST_STATUS_TLV:
  599. hal_reo_flush_timeout_list_status_be(
  600. reo_desc,
  601. &reo_status_ref->fl_timeout_status,
  602. hal_soc_hdl);
  603. *num_ref = reo_status_ref->fl_timeout_status.header.cmd_num;
  604. break;
  605. case HAL_REO_DESC_THRES_STATUS_TLV:
  606. hal_reo_desc_thres_reached_status_be(
  607. reo_desc,
  608. &reo_status_ref->thres_status,
  609. hal_soc_hdl);
  610. *num_ref = reo_status_ref->thres_status.header.cmd_num;
  611. break;
  612. case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV:
  613. hal_reo_rx_update_queue_status_be(
  614. reo_desc,
  615. &reo_status_ref->rx_queue_status,
  616. hal_soc_hdl);
  617. *num_ref = reo_status_ref->rx_queue_status.header.cmd_num;
  618. break;
  619. default:
  620. QDF_TRACE(QDF_MODULE_ID_DP_REO, QDF_TRACE_LEVEL_WARN,
  621. "hal_soc %pK: no handler for TLV:%d",
  622. hal_soc_hdl, tlv);
  623. return QDF_STATUS_E_FAILURE;
  624. } /* switch */
  625. return QDF_STATUS_SUCCESS;
  626. }
  627. static uint8_t hal_rx_reo_buf_type_get_be(hal_ring_desc_t rx_desc)
  628. {
  629. return HAL_RX_REO_BUF_TYPE_GET(rx_desc);
  630. }
  631. #ifdef DP_HW_COOKIE_CONVERT_EXCEPTION
  632. #define HAL_WBM_MISC_CONTROL_SPARE_CONTROL_FIELD_BIT15 0x8000
  633. #endif
  634. void hal_cookie_conversion_reg_cfg_be(hal_soc_handle_t hal_soc_hdl,
  635. struct hal_hw_cc_config *cc_cfg)
  636. {
  637. uint32_t reg_addr, reg_val = 0;
  638. struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl;
  639. /* REO CFG */
  640. reg_addr = HWIO_REO_R0_SW_COOKIE_CFG0_ADDR(REO_REG_REG_BASE);
  641. reg_val = cc_cfg->lut_base_addr_31_0;
  642. HAL_REG_WRITE(soc, reg_addr, reg_val);
  643. reg_addr = HWIO_REO_R0_SW_COOKIE_CFG1_ADDR(REO_REG_REG_BASE);
  644. reg_val = 0;
  645. reg_val |= HAL_SM(HWIO_REO_R0_SW_COOKIE_CFG1,
  646. SW_COOKIE_CONVERT_GLOBAL_ENABLE,
  647. cc_cfg->cc_global_en);
  648. reg_val |= HAL_SM(HWIO_REO_R0_SW_COOKIE_CFG1,
  649. SW_COOKIE_CONVERT_ENABLE,
  650. cc_cfg->cc_global_en);
  651. reg_val |= HAL_SM(HWIO_REO_R0_SW_COOKIE_CFG1,
  652. PAGE_ALIGNMENT,
  653. cc_cfg->page_4k_align);
  654. reg_val |= HAL_SM(HWIO_REO_R0_SW_COOKIE_CFG1,
  655. COOKIE_OFFSET_MSB,
  656. cc_cfg->cookie_offset_msb);
  657. reg_val |= HAL_SM(HWIO_REO_R0_SW_COOKIE_CFG1,
  658. COOKIE_PAGE_MSB,
  659. cc_cfg->cookie_page_msb);
  660. reg_val |= HAL_SM(HWIO_REO_R0_SW_COOKIE_CFG1,
  661. CMEM_LUT_BASE_ADDR_39_32,
  662. cc_cfg->lut_base_addr_39_32);
  663. HAL_REG_WRITE(soc, reg_addr, reg_val);
  664. /* WBM CFG */
  665. reg_addr = HWIO_WBM_R0_SW_COOKIE_CFG0_ADDR(WBM_REG_REG_BASE);
  666. reg_val = cc_cfg->lut_base_addr_31_0;
  667. HAL_REG_WRITE(soc, reg_addr, reg_val);
  668. reg_addr = HWIO_WBM_R0_SW_COOKIE_CFG1_ADDR(WBM_REG_REG_BASE);
  669. reg_val = 0;
  670. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CFG1,
  671. PAGE_ALIGNMENT,
  672. cc_cfg->page_4k_align);
  673. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CFG1,
  674. COOKIE_OFFSET_MSB,
  675. cc_cfg->cookie_offset_msb);
  676. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CFG1,
  677. COOKIE_PAGE_MSB,
  678. cc_cfg->cookie_page_msb);
  679. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CFG1,
  680. CMEM_LUT_BASE_ADDR_39_32,
  681. cc_cfg->lut_base_addr_39_32);
  682. HAL_REG_WRITE(soc, reg_addr, reg_val);
  683. /*
  684. * WCSS_UMAC_WBM_R0_SW_COOKIE_CONVERT_CFG default value is 0x1FE,
  685. */
  686. reg_addr = HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG_ADDR(WBM_REG_REG_BASE);
  687. reg_val = 0;
  688. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  689. WBM_COOKIE_CONV_GLOBAL_ENABLE,
  690. cc_cfg->cc_global_en);
  691. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  692. WBM2SW6_COOKIE_CONVERSION_EN,
  693. cc_cfg->wbm2sw6_cc_en);
  694. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  695. WBM2SW5_COOKIE_CONVERSION_EN,
  696. cc_cfg->wbm2sw5_cc_en);
  697. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  698. WBM2SW4_COOKIE_CONVERSION_EN,
  699. cc_cfg->wbm2sw4_cc_en);
  700. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  701. WBM2SW3_COOKIE_CONVERSION_EN,
  702. cc_cfg->wbm2sw3_cc_en);
  703. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  704. WBM2SW2_COOKIE_CONVERSION_EN,
  705. cc_cfg->wbm2sw2_cc_en);
  706. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  707. WBM2SW1_COOKIE_CONVERSION_EN,
  708. cc_cfg->wbm2sw1_cc_en);
  709. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  710. WBM2SW0_COOKIE_CONVERSION_EN,
  711. cc_cfg->wbm2sw0_cc_en);
  712. reg_val |= HAL_SM(HWIO_WBM_R0_SW_COOKIE_CONVERT_CFG,
  713. WBM2FW_COOKIE_CONVERSION_EN,
  714. cc_cfg->wbm2fw_cc_en);
  715. HAL_REG_WRITE(soc, reg_addr, reg_val);
  716. #ifdef DP_HW_COOKIE_CONVERT_EXCEPTION
  717. /*
  718. * To enable indication for HW cookie conversion done or not for
  719. * WBM, WCSS_UMAC_WBM_R0_MISC_CONTROL spare_control field 15th
  720. * bit spare_control[15] should be set.
  721. */
  722. reg_addr = HWIO_WBM_R0_MISC_CONTROL_ADDR(WBM_REG_REG_BASE);
  723. reg_val = HAL_REG_READ(soc, reg_addr);
  724. reg_val |= HAL_SM(HWIO_WCSS_UMAC_WBM_R0_MISC_CONTROL,
  725. SPARE_CONTROL,
  726. HAL_WBM_MISC_CONTROL_SPARE_CONTROL_FIELD_BIT15);
  727. HAL_REG_WRITE(soc, reg_addr, reg_val);
  728. #endif
  729. }
  730. qdf_export_symbol(hal_cookie_conversion_reg_cfg_be);
  731. /**
  732. * hal_hw_txrx_default_ops_attach_be() - Attach the default hal ops for
  733. * beryllium chipsets.
  734. * @hal_soc_hdl: HAL soc handle
  735. *
  736. * Return: None
  737. */
  738. void hal_hw_txrx_default_ops_attach_be(struct hal_soc *hal_soc)
  739. {
  740. hal_soc->ops->hal_get_reo_qdesc_size = hal_get_reo_qdesc_size_be;
  741. hal_soc->ops->hal_set_link_desc_addr = hal_set_link_desc_addr_be;
  742. hal_soc->ops->hal_tx_init_data_ring = hal_tx_init_data_ring_be;
  743. hal_soc->ops->hal_get_ba_aging_timeout = hal_get_ba_aging_timeout_be;
  744. hal_soc->ops->hal_set_ba_aging_timeout = hal_set_ba_aging_timeout_be;
  745. hal_soc->ops->hal_get_reo_reg_base_offset =
  746. hal_get_reo_reg_base_offset_be;
  747. hal_soc->ops->hal_setup_link_idle_list =
  748. hal_setup_link_idle_list_generic_be;
  749. hal_soc->ops->hal_rx_reo_buf_paddr_get = hal_rx_reo_buf_paddr_get_be;
  750. hal_soc->ops->hal_rx_msdu_link_desc_set = hal_rx_msdu_link_desc_set_be;
  751. hal_soc->ops->hal_rx_buf_cookie_rbm_get = hal_rx_buf_cookie_rbm_get_be;
  752. hal_soc->ops->hal_rx_ret_buf_manager_get =
  753. hal_rx_ret_buf_manager_get_be;
  754. hal_soc->ops->hal_rxdma_buff_addr_info_set =
  755. hal_rxdma_buff_addr_info_set_be;
  756. hal_soc->ops->hal_rx_msdu_flags_get = hal_rx_msdu_flags_get_be;
  757. hal_soc->ops->hal_rx_get_reo_error_code = hal_rx_get_reo_error_code_be;
  758. hal_soc->ops->hal_gen_reo_remap_val =
  759. hal_gen_reo_remap_val_generic_be;
  760. hal_soc->ops->hal_tx_comp_get_buffer_source =
  761. hal_tx_comp_get_buffer_source_generic_be;
  762. hal_soc->ops->hal_rx_mpdu_desc_info_get =
  763. hal_rx_mpdu_desc_info_get_be;
  764. hal_soc->ops->hal_rx_err_status_get = hal_rx_err_status_get_be;
  765. hal_soc->ops->hal_rx_reo_buf_type_get = hal_rx_reo_buf_type_get_be;
  766. hal_soc->ops->hal_rx_wbm_err_src_get = hal_rx_wbm_err_src_get_be;
  767. hal_soc->ops->hal_reo_send_cmd = hal_reo_send_cmd_be;
  768. hal_soc->ops->hal_reo_qdesc_setup = hal_reo_qdesc_setup_be;
  769. hal_soc->ops->hal_reo_status_update = hal_reo_status_update_be;
  770. hal_soc->ops->hal_get_tlv_hdr_size = hal_get_tlv_hdr_size_be;
  771. hal_soc->ops->hal_rx_tlv_get_pn_num = hal_rx_tlv_get_pn_num_be;
  772. }