hal_be_generic_api.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. /*
  2. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. #ifndef _HAL_BE_GENERIC_API_H_
  20. #define _HAL_BE_GENERIC_API_H_
  21. #include <hal_be_hw_headers.h>
  22. #include "hal_be_tx.h"
  23. #include "hal_be_reo.h"
  24. #include <hal_api_mon.h>
  25. #include <hal_generic_api.h>
  26. #include <hal_be_api_mon.h>
  27. /**
  28. * hal_tx_comp_get_status() - TQM Release reason
  29. * @hal_desc: completion ring Tx status
  30. *
  31. * This function will parse the WBM completion descriptor and populate in
  32. * HAL structure
  33. *
  34. * Return: none
  35. */
  36. static inline void
  37. hal_tx_comp_get_status_generic_be(void *desc, void *ts1,
  38. struct hal_soc *hal)
  39. {
  40. uint8_t rate_stats_valid = 0;
  41. uint32_t rate_stats = 0;
  42. struct hal_tx_completion_status *ts =
  43. (struct hal_tx_completion_status *)ts1;
  44. ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX,
  45. TQM_STATUS_NUMBER);
  46. ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX,
  47. ACK_FRAME_RSSI);
  48. ts->first_msdu = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX,
  49. FIRST_MSDU);
  50. ts->last_msdu = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX,
  51. LAST_MSDU);
  52. #if 0
  53. // TODO - This has to be calculated form first and last msdu
  54. ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc,
  55. WBM2SW_COMPLETION_RING_TX,
  56. MSDU_PART_OF_AMSDU);
  57. #endif
  58. ts->peer_id = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX,
  59. SW_PEER_ID);
  60. ts->tid = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX, TID);
  61. ts->transmit_cnt = HAL_TX_DESC_GET(desc, WBM2SW_COMPLETION_RING_TX,
  62. TRANSMIT_COUNT);
  63. rate_stats = HAL_TX_DESC_GET(desc, HAL_TX_COMP, TX_RATE_STATS);
  64. rate_stats_valid = HAL_TX_MS(TX_RATE_STATS_INFO,
  65. TX_RATE_STATS_INFO_VALID, rate_stats);
  66. ts->valid = rate_stats_valid;
  67. if (rate_stats_valid) {
  68. ts->bw = HAL_TX_MS(TX_RATE_STATS_INFO, TRANSMIT_BW,
  69. rate_stats);
  70. ts->pkt_type = HAL_TX_MS(TX_RATE_STATS_INFO,
  71. TRANSMIT_PKT_TYPE, rate_stats);
  72. ts->stbc = HAL_TX_MS(TX_RATE_STATS_INFO,
  73. TRANSMIT_STBC, rate_stats);
  74. ts->ldpc = HAL_TX_MS(TX_RATE_STATS_INFO, TRANSMIT_LDPC,
  75. rate_stats);
  76. ts->sgi = HAL_TX_MS(TX_RATE_STATS_INFO, TRANSMIT_SGI,
  77. rate_stats);
  78. ts->mcs = HAL_TX_MS(TX_RATE_STATS_INFO, TRANSMIT_MCS,
  79. rate_stats);
  80. ts->ofdma = HAL_TX_MS(TX_RATE_STATS_INFO, OFDMA_TRANSMISSION,
  81. rate_stats);
  82. ts->tones_in_ru = HAL_TX_MS(TX_RATE_STATS_INFO, TONES_IN_RU,
  83. rate_stats);
  84. }
  85. ts->release_src = hal_tx_comp_get_buffer_source_generic_be(desc);
  86. ts->status = hal_tx_comp_get_release_reason(
  87. desc,
  88. hal_soc_to_hal_soc_handle(hal));
  89. ts->tsf = HAL_TX_DESC_GET(desc, UNIFIED_WBM_RELEASE_RING_6,
  90. TX_RATE_STATS_INFO_TX_RATE_STATS);
  91. }
  92. /**
  93. * hal_tx_set_pcp_tid_map_generic_be() - Configure default PCP to TID map table
  94. * @soc: HAL SoC context
  95. * @map: PCP-TID mapping table
  96. *
  97. * PCP are mapped to 8 TID values using TID values programmed
  98. * in one set of mapping registers PCP_TID_MAP_<0 to 6>
  99. * The mapping register has TID mapping for 8 PCP values
  100. *
  101. * Return: none
  102. */
  103. static void hal_tx_set_pcp_tid_map_generic_be(struct hal_soc *soc, uint8_t *map)
  104. {
  105. uint32_t addr, value;
  106. addr = HWIO_TCL_R0_PCP_TID_MAP_ADDR(
  107. MAC_TCL_REG_REG_BASE);
  108. value = (map[0] |
  109. (map[1] << HWIO_TCL_R0_PCP_TID_MAP_PCP_1_SHFT) |
  110. (map[2] << HWIO_TCL_R0_PCP_TID_MAP_PCP_2_SHFT) |
  111. (map[3] << HWIO_TCL_R0_PCP_TID_MAP_PCP_3_SHFT) |
  112. (map[4] << HWIO_TCL_R0_PCP_TID_MAP_PCP_4_SHFT) |
  113. (map[5] << HWIO_TCL_R0_PCP_TID_MAP_PCP_5_SHFT) |
  114. (map[6] << HWIO_TCL_R0_PCP_TID_MAP_PCP_6_SHFT) |
  115. (map[7] << HWIO_TCL_R0_PCP_TID_MAP_PCP_7_SHFT));
  116. HAL_REG_WRITE(soc, addr, (value & HWIO_TCL_R0_PCP_TID_MAP_RMSK));
  117. }
  118. /**
  119. * hal_tx_update_pcp_tid_generic_be() - Update the pcp tid map table with
  120. * value received from user-space
  121. * @soc: HAL SoC context
  122. * @pcp: pcp value
  123. * @tid : tid value
  124. *
  125. * Return: void
  126. */
  127. static void
  128. hal_tx_update_pcp_tid_generic_be(struct hal_soc *soc,
  129. uint8_t pcp, uint8_t tid)
  130. {
  131. uint32_t addr, value, regval;
  132. addr = HWIO_TCL_R0_PCP_TID_MAP_ADDR(
  133. MAC_TCL_REG_REG_BASE);
  134. value = (uint32_t)tid << (HAL_TX_BITS_PER_TID * pcp);
  135. /* Read back previous PCP TID config and update
  136. * with new config.
  137. */
  138. regval = HAL_REG_READ(soc, addr);
  139. regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * pcp));
  140. regval |= value;
  141. HAL_REG_WRITE(soc, addr,
  142. (regval & HWIO_TCL_R0_PCP_TID_MAP_RMSK));
  143. }
  144. /**
  145. * hal_tx_update_tidmap_prty_generic_be() - Update the tid map priority
  146. * @soc: HAL SoC context
  147. * @val: priority value
  148. *
  149. * Return: void
  150. */
  151. static
  152. void hal_tx_update_tidmap_prty_generic_be(struct hal_soc *soc, uint8_t value)
  153. {
  154. uint32_t addr;
  155. addr = HWIO_TCL_R0_TID_MAP_PRTY_ADDR(
  156. MAC_TCL_REG_REG_BASE);
  157. HAL_REG_WRITE(soc, addr,
  158. (value & HWIO_TCL_R0_TID_MAP_PRTY_RMSK));
  159. }
  160. /**
  161. * hal_rx_get_tlv_size_generic_be() - Get rx packet tlv size
  162. * @rx_pkt_tlv_size: TLV size for regular RX packets
  163. * @rx_mon_pkt_tlv_size: TLV size for monitor mode packets
  164. *
  165. * Return: size of rx pkt tlv before the actual data
  166. */
  167. static void hal_rx_get_tlv_size_generic_be(uint16_t *rx_pkt_tlv_size,
  168. uint16_t *rx_mon_pkt_tlv_size)
  169. {
  170. *rx_pkt_tlv_size = RX_PKT_TLVS_LEN;
  171. /* For now mon pkt tlv is same as rx pkt tlv */
  172. *rx_mon_pkt_tlv_size = RX_PKT_TLVS_LEN;
  173. }
  174. /**
  175. * hal_rx_flow_get_tuple_info_be() - Setup a flow search entry in HW FST
  176. * @fst: Pointer to the Rx Flow Search Table
  177. * @hal_hash: HAL 5 tuple hash
  178. * @tuple_info: 5-tuple info of the flow returned to the caller
  179. *
  180. * Return: Success/Failure
  181. */
  182. static void *
  183. hal_rx_flow_get_tuple_info_be(uint8_t *rx_fst, uint32_t hal_hash,
  184. uint8_t *flow_tuple_info)
  185. {
  186. struct hal_rx_fst *fst = (struct hal_rx_fst *)rx_fst;
  187. void *hal_fse = NULL;
  188. struct hal_flow_tuple_info *tuple_info
  189. = (struct hal_flow_tuple_info *)flow_tuple_info;
  190. hal_fse = (uint8_t *)fst->base_vaddr +
  191. (hal_hash * HAL_RX_FST_ENTRY_SIZE);
  192. if (!hal_fse || !tuple_info)
  193. return NULL;
  194. if (!HAL_GET_FLD(hal_fse, RX_FLOW_SEARCH_ENTRY, VALID))
  195. return NULL;
  196. tuple_info->src_ip_127_96 =
  197. qdf_ntohl(HAL_GET_FLD(hal_fse,
  198. RX_FLOW_SEARCH_ENTRY,
  199. SRC_IP_127_96));
  200. tuple_info->src_ip_95_64 =
  201. qdf_ntohl(HAL_GET_FLD(hal_fse,
  202. RX_FLOW_SEARCH_ENTRY,
  203. SRC_IP_95_64));
  204. tuple_info->src_ip_63_32 =
  205. qdf_ntohl(HAL_GET_FLD(hal_fse,
  206. RX_FLOW_SEARCH_ENTRY,
  207. SRC_IP_63_32));
  208. tuple_info->src_ip_31_0 =
  209. qdf_ntohl(HAL_GET_FLD(hal_fse,
  210. RX_FLOW_SEARCH_ENTRY,
  211. SRC_IP_31_0));
  212. tuple_info->dest_ip_127_96 =
  213. qdf_ntohl(HAL_GET_FLD(hal_fse,
  214. RX_FLOW_SEARCH_ENTRY,
  215. DEST_IP_127_96));
  216. tuple_info->dest_ip_95_64 =
  217. qdf_ntohl(HAL_GET_FLD(hal_fse,
  218. RX_FLOW_SEARCH_ENTRY,
  219. DEST_IP_95_64));
  220. tuple_info->dest_ip_63_32 =
  221. qdf_ntohl(HAL_GET_FLD(hal_fse,
  222. RX_FLOW_SEARCH_ENTRY,
  223. DEST_IP_63_32));
  224. tuple_info->dest_ip_31_0 =
  225. qdf_ntohl(HAL_GET_FLD(hal_fse,
  226. RX_FLOW_SEARCH_ENTRY,
  227. DEST_IP_31_0));
  228. tuple_info->dest_port = HAL_GET_FLD(hal_fse,
  229. RX_FLOW_SEARCH_ENTRY,
  230. DEST_PORT);
  231. tuple_info->src_port = HAL_GET_FLD(hal_fse,
  232. RX_FLOW_SEARCH_ENTRY,
  233. SRC_PORT);
  234. tuple_info->l4_protocol = HAL_GET_FLD(hal_fse,
  235. RX_FLOW_SEARCH_ENTRY,
  236. L4_PROTOCOL);
  237. return hal_fse;
  238. }
  239. /**
  240. * hal_rx_flow_delete_entry_be() - Setup a flow search entry in HW FST
  241. * @fst: Pointer to the Rx Flow Search Table
  242. * @hal_rx_fse: Pointer to the Rx Flow that is to be deleted from the FST
  243. *
  244. * Return: Success/Failure
  245. */
  246. static QDF_STATUS
  247. hal_rx_flow_delete_entry_be(uint8_t *rx_fst, void *hal_rx_fse)
  248. {
  249. uint8_t *fse = (uint8_t *)hal_rx_fse;
  250. if (!HAL_GET_FLD(fse, RX_FLOW_SEARCH_ENTRY, VALID))
  251. return QDF_STATUS_E_NOENT;
  252. HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY, VALID);
  253. return QDF_STATUS_SUCCESS;
  254. }
  255. /**
  256. * hal_rx_fst_get_fse_size_be() - Retrieve the size of each entry in Rx FST
  257. *
  258. * Return: size of each entry/flow in Rx FST
  259. */
  260. static inline uint32_t
  261. hal_rx_fst_get_fse_size_be(void)
  262. {
  263. return HAL_RX_FST_ENTRY_SIZE;
  264. }
  265. /*
  266. * TX MONITOR
  267. */
  268. #ifdef QCA_MONITOR_2_0_SUPPORT
  269. /**
  270. * hal_txmon_get_buffer_addr_generic_be() - api to get buffer address
  271. * @tx_tlv: pointer to TLV header
  272. * @status: hal mon buffer address status
  273. *
  274. * Return: Address to qdf_frag_t
  275. */
  276. static inline qdf_frag_t
  277. hal_txmon_get_buffer_addr_generic_be(void *tx_tlv,
  278. struct hal_mon_buf_addr_status *status)
  279. {
  280. struct mon_buffer_addr *hal_buffer_addr =
  281. (struct mon_buffer_addr *)((uint8_t *)tx_tlv +
  282. HAL_RX_TLV32_HDR_SIZE);
  283. qdf_frag_t buf_addr = NULL;
  284. buf_addr = (qdf_frag_t)(uintptr_t)((hal_buffer_addr->buffer_virt_addr_31_0 |
  285. ((unsigned long long)hal_buffer_addr->buffer_virt_addr_63_32 <<
  286. 32)));
  287. /* qdf_frag_t is derived from buffer address tlv */
  288. if (qdf_unlikely(status)) {
  289. qdf_mem_copy(status,
  290. (uint8_t *)tx_tlv + HAL_RX_TLV32_HDR_SIZE,
  291. sizeof(struct hal_mon_buf_addr_status));
  292. /* update hal_mon_buf_addr_status */
  293. }
  294. return buf_addr;
  295. }
  296. #if defined(TX_MONITOR_WORD_MASK)
  297. /**
  298. * hal_txmon_get_num_users() - get num users from tx_fes_setup tlv
  299. *
  300. * @tx_tlv: pointer to tx_fes_setup tlv header
  301. *
  302. * Return: number of users
  303. */
  304. static inline uint8_t
  305. hal_txmon_get_num_users(void *tx_tlv)
  306. {
  307. hal_tx_fes_setup_t *tx_fes_setup = (hal_tx_fes_setup_t *)tx_tlv;
  308. return tx_fes_setup->number_of_users;
  309. }
  310. /**
  311. * hal_txmon_parse_tx_fes_setup() - parse tx_fes_setup tlv
  312. *
  313. * @tx_tlv: pointer to tx_fes_setup tlv header
  314. * @ppdu_info: pointer to hal_tx_ppdu_info
  315. *
  316. * Return: void
  317. */
  318. static inline void
  319. hal_txmon_parse_tx_fes_setup(void *tx_tlv,
  320. struct hal_tx_ppdu_info *tx_ppdu_info)
  321. {
  322. hal_tx_fes_setup_t *tx_fes_setup = (hal_tx_fes_setup_t *)tx_tlv;
  323. tx_ppdu_info->num_users = tx_fes_setup->number_of_users;
  324. }
  325. #else
  326. /**
  327. * hal_txmon_get_num_users() - get num users from tx_fes_setup tlv
  328. *
  329. * @tx_tlv: pointer to tx_fes_setup tlv header
  330. *
  331. * Return: number of users
  332. */
  333. static inline uint8_t
  334. hal_txmon_get_num_users(void *tx_tlv)
  335. {
  336. uint8_t num_users = HAL_TX_DESC_GET(tx_tlv,
  337. TX_FES_SETUP, NUMBER_OF_USERS);
  338. return num_users;
  339. }
  340. /**
  341. * hal_txmon_parse_tx_fes_setup() - parse tx_fes_setup tlv
  342. *
  343. * @tx_tlv: pointer to tx_fes_setup tlv header
  344. * @ppdu_info: pointer to hal_tx_ppdu_info
  345. *
  346. * Return: void
  347. */
  348. static inline void
  349. hal_txmon_parse_tx_fes_setup(void *tx_tlv,
  350. struct hal_tx_ppdu_info *tx_ppdu_info)
  351. {
  352. tx_ppdu_info->num_users = HAL_TX_DESC_GET(tx_tlv,
  353. TX_FES_SETUP,
  354. NUMBER_OF_USERS);
  355. }
  356. #endif
  357. /**
  358. * hal_txmon_status_get_num_users_generic_be() - api to get num users
  359. * from start of fes window
  360. *
  361. * @tx_tlv_hdr: pointer to TLV header
  362. * @num_users: reference to number of user
  363. *
  364. * Return: status
  365. */
  366. static inline uint32_t
  367. hal_txmon_status_get_num_users_generic_be(void *tx_tlv_hdr, uint8_t *num_users)
  368. {
  369. uint32_t tlv_tag, user_id, tlv_len;
  370. uint32_t tlv_status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
  371. void *tx_tlv;
  372. tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(tx_tlv_hdr);
  373. user_id = HAL_RX_GET_USER_TLV32_USERID(tx_tlv_hdr);
  374. tlv_len = HAL_RX_GET_USER_TLV32_LEN(tx_tlv_hdr);
  375. tx_tlv = (uint8_t *)tx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
  376. /* window starts with either initiator or response */
  377. switch (tlv_tag) {
  378. case WIFITX_FES_SETUP_E:
  379. {
  380. *num_users = hal_txmon_get_num_users(tx_tlv);
  381. tlv_status = HAL_MON_TX_FES_SETUP;
  382. break;
  383. }
  384. case WIFIRX_RESPONSE_REQUIRED_INFO_E:
  385. {
  386. *num_users = HAL_TX_DESC_GET(tx_tlv,
  387. RX_RESPONSE_REQUIRED_INFO,
  388. RESPONSE_STA_COUNT);
  389. tlv_status = HAL_MON_RX_RESPONSE_REQUIRED_INFO;
  390. break;
  391. }
  392. };
  393. return tlv_status;
  394. }
  395. /**
  396. * hal_txmon_free_status_buffer() - api to free status buffer
  397. * @pdev_handle: DP_PDEV handle
  398. * @status_frag: qdf_frag_t buffer
  399. *
  400. * Return void
  401. */
  402. static inline void
  403. hal_txmon_status_free_buffer_generic_be(qdf_frag_t status_frag)
  404. {
  405. uint32_t tlv_tag, tlv_len;
  406. uint32_t tlv_status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
  407. uint8_t *tx_tlv;
  408. uint8_t *tx_tlv_start;
  409. qdf_frag_t frag_buf = NULL;
  410. tx_tlv = (uint8_t *)status_frag;
  411. tx_tlv_start = tx_tlv;
  412. /* parse tlv and populate tx_ppdu_info */
  413. do {
  414. /* TODO: check config_length is full monitor mode */
  415. tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(tx_tlv);
  416. tlv_len = HAL_RX_GET_USER_TLV32_LEN(tx_tlv);
  417. if (tlv_tag == WIFIMON_BUFFER_ADDR_E) {
  418. frag_buf = hal_txmon_get_buffer_addr_generic_be(tx_tlv,
  419. NULL);
  420. if (frag_buf)
  421. qdf_frag_free(frag_buf);
  422. frag_buf = NULL;
  423. }
  424. /* need api definition for hal_tx_status_get_next_tlv */
  425. tx_tlv = hal_tx_status_get_next_tlv(tx_tlv);
  426. if ((tx_tlv - tx_tlv_start) >= TX_MON_STATUS_BUF_SIZE)
  427. break;
  428. } while (tlv_status == HAL_MON_TX_STATUS_PPDU_NOT_DONE);
  429. }
  430. /**
  431. * hal_tx_get_ppdu_info() - api to get tx ppdu info
  432. * @pdev_handle: DP_PDEV handle
  433. * @prot_ppdu_info: populate dp_ppdu_info protection
  434. * @tx_data_ppdu_info: populate dp_ppdu_info data
  435. * @tlv_tag: Tag
  436. *
  437. * Return: dp_tx_ppdu_info pointer
  438. */
  439. static inline void *
  440. hal_tx_get_ppdu_info(void *data_info, void *prot_info, uint32_t tlv_tag)
  441. {
  442. struct hal_tx_ppdu_info *prot_ppdu_info = prot_info;
  443. switch (tlv_tag) {
  444. case WIFITX_FES_SETUP_E:/* DOWNSTREAM */
  445. case WIFITX_FLUSH_E:/* DOWNSTREAM */
  446. case WIFIPCU_PPDU_SETUP_INIT_E:/* DOWNSTREAM */
  447. case WIFITX_PEER_ENTRY_E:/* DOWNSTREAM */
  448. case WIFITX_QUEUE_EXTENSION_E:/* DOWNSTREAM */
  449. case WIFITX_MPDU_START_E:/* DOWNSTREAM */
  450. case WIFITX_MSDU_START_E:/* DOWNSTREAM */
  451. case WIFITX_DATA_E:/* DOWNSTREAM */
  452. case WIFIMON_BUFFER_ADDR_E:/* DOWNSTREAM */
  453. case WIFITX_MPDU_END_E:/* DOWNSTREAM */
  454. case WIFITX_MSDU_END_E:/* DOWNSTREAM */
  455. case WIFITX_LAST_MPDU_FETCHED_E:/* DOWNSTREAM */
  456. case WIFITX_LAST_MPDU_END_E:/* DOWNSTREAM */
  457. case WIFICOEX_TX_REQ_E:/* DOWNSTREAM */
  458. case WIFITX_RAW_OR_NATIVE_FRAME_SETUP_E:/* DOWNSTREAM */
  459. case WIFINDP_PREAMBLE_DONE_E:/* DOWNSTREAM */
  460. case WIFISCH_CRITICAL_TLV_REFERENCE_E:/* DOWNSTREAM */
  461. case WIFITX_LOOPBACK_SETUP_E:/* DOWNSTREAM */
  462. case WIFITX_FES_SETUP_COMPLETE_E:/* DOWNSTREAM */
  463. case WIFITQM_MPDU_GLOBAL_START_E:/* DOWNSTREAM */
  464. case WIFITX_WUR_DATA_E:/* DOWNSTREAM */
  465. case WIFISCHEDULER_END_E:/* DOWNSTREAM */
  466. {
  467. return data_info;
  468. }
  469. }
  470. /*
  471. * check current prot_tlv_status is start protection
  472. * check current tlv_tag is either start protection or end protection
  473. */
  474. if (TXMON_HAL(prot_ppdu_info,
  475. prot_tlv_status) == WIFITX_FES_STATUS_START_PROT_E) {
  476. return prot_info;
  477. } else if (tlv_tag == WIFITX_FES_STATUS_PROT_E ||
  478. tlv_tag == WIFITX_FES_STATUS_START_PROT_E) {
  479. TXMON_HAL(prot_ppdu_info, prot_tlv_status) = tlv_tag;
  480. return prot_info;
  481. } else {
  482. return data_info;
  483. }
  484. return data_info;
  485. }
  486. /**
  487. * hal_txmon_status_parse_tlv_generic_be() - api to parse status tlv.
  488. * @data_ppdu_info: hal_txmon data ppdu info
  489. * @prot_ppdu_info: hal_txmon prot ppdu info
  490. * @data_status_info: pointer to data status info
  491. * @prot_status_info: pointer to prot status info
  492. * @tx_tlv_hdr: fragment of tx_tlv_hdr
  493. * @status_frag: qdf_frag_t buffer
  494. *
  495. * Return: status
  496. */
  497. static inline uint32_t
  498. hal_txmon_status_parse_tlv_generic_be(void *data_ppdu_info,
  499. void *prot_ppdu_info,
  500. void *data_status_info,
  501. void *prot_status_info,
  502. void *tx_tlv_hdr,
  503. qdf_frag_t status_frag)
  504. {
  505. struct hal_tx_ppdu_info *tx_ppdu_info;
  506. struct hal_tx_status_info *tx_status_info;
  507. uint32_t tlv_tag, user_id, tlv_len;
  508. qdf_frag_t frag_buf = NULL;
  509. uint32_t status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
  510. void *tx_tlv;
  511. tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(tx_tlv_hdr);
  512. user_id = HAL_RX_GET_USER_TLV32_USERID(tx_tlv_hdr);
  513. tlv_len = HAL_RX_GET_USER_TLV32_LEN(tx_tlv_hdr);
  514. tx_tlv = (uint8_t *)tx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
  515. tx_ppdu_info = hal_tx_get_ppdu_info(data_ppdu_info,
  516. prot_ppdu_info, tlv_tag);
  517. tx_status_info = (tx_ppdu_info->is_data ? data_status_info :
  518. prot_status_info);
  519. /* parse tlv and populate tx_ppdu_info */
  520. switch (tlv_tag) {
  521. case WIFIMON_BUFFER_ADDR_E:
  522. {
  523. frag_buf = hal_txmon_get_buffer_addr_generic_be(tx_tlv, NULL);
  524. if (frag_buf)
  525. qdf_frag_free(frag_buf);
  526. frag_buf = NULL;
  527. status = HAL_MON_TX_BUFFER_ADDR;
  528. break;
  529. }
  530. case WIFITX_FES_STATUS_START_PROT_E:
  531. {
  532. TXMON_HAL(tx_ppdu_info, prot_tlv_status) = tlv_tag;
  533. break;
  534. }
  535. }
  536. return status;
  537. }
  538. #endif /* QCA_MONITOR_2_0_SUPPORT */
  539. #ifdef REO_SHARED_QREF_TABLE_EN
  540. /* hal_reo_shared_qaddr_write(): Write REO tid queue addr
  541. * LUT shared by SW and HW at the index given by peer id
  542. * and tid.
  543. *
  544. * @hal_soc: hal soc pointer
  545. * @reo_qref_addr: pointer to index pointed to be peer_id
  546. * and tid
  547. * @tid: tid queue number
  548. * @hw_qdesc_paddr: reo queue addr
  549. */
  550. static void hal_reo_shared_qaddr_write_be(hal_soc_handle_t hal_soc_hdl,
  551. uint16_t peer_id,
  552. int tid,
  553. qdf_dma_addr_t hw_qdesc_paddr)
  554. {
  555. struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
  556. struct rx_reo_queue_reference *reo_qref;
  557. uint32_t peer_tid_idx;
  558. /* Plug hw_desc_addr in Host reo queue reference table */
  559. if (HAL_PEER_ID_IS_MLO(peer_id)) {
  560. peer_tid_idx = ((peer_id - HAL_ML_PEER_ID_START) *
  561. DP_MAX_TIDS) + tid;
  562. reo_qref = (struct rx_reo_queue_reference *)
  563. &hal->reo_qref.mlo_reo_qref_table_vaddr[peer_tid_idx];
  564. } else {
  565. peer_tid_idx = (peer_id * DP_MAX_TIDS) + tid;
  566. reo_qref = (struct rx_reo_queue_reference *)
  567. &hal->reo_qref.non_mlo_reo_qref_table_vaddr[peer_tid_idx];
  568. }
  569. reo_qref->rx_reo_queue_desc_addr_31_0 =
  570. hw_qdesc_paddr & 0xffffffff;
  571. reo_qref->rx_reo_queue_desc_addr_39_32 =
  572. (hw_qdesc_paddr & 0xff00000000) >> 32;
  573. if (hw_qdesc_paddr != 0)
  574. reo_qref->receive_queue_number = tid;
  575. else
  576. reo_qref->receive_queue_number = 0;
  577. hal_verbose_debug("hw_qdesc_paddr: %llx, tid: %d, reo_qref:%pK,"
  578. "rx_reo_queue_desc_addr_31_0: %x,"
  579. "rx_reo_queue_desc_addr_39_32: %x",
  580. hw_qdesc_paddr, tid, reo_qref,
  581. reo_qref->rx_reo_queue_desc_addr_31_0,
  582. reo_qref->rx_reo_queue_desc_addr_39_32);
  583. }
  584. /**
  585. * hal_reo_shared_qaddr_setup() - Allocate MLO and Non MLO reo queue
  586. * reference table shared between SW and HW and initialize in Qdesc Base0
  587. * base1 registers provided by HW.
  588. *
  589. * @hal_soc: HAL Soc handle
  590. *
  591. * Return: None
  592. */
  593. static void hal_reo_shared_qaddr_setup_be(hal_soc_handle_t hal_soc_hdl)
  594. {
  595. struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
  596. hal->reo_qref.reo_qref_table_en = 1;
  597. hal->reo_qref.mlo_reo_qref_table_vaddr =
  598. (uint64_t *)qdf_mem_alloc_consistent(
  599. hal->qdf_dev, hal->qdf_dev->dev,
  600. REO_QUEUE_REF_ML_TABLE_SIZE,
  601. &hal->reo_qref.mlo_reo_qref_table_paddr);
  602. hal->reo_qref.non_mlo_reo_qref_table_vaddr =
  603. (uint64_t *)qdf_mem_alloc_consistent(
  604. hal->qdf_dev, hal->qdf_dev->dev,
  605. REO_QUEUE_REF_NON_ML_TABLE_SIZE,
  606. &hal->reo_qref.non_mlo_reo_qref_table_paddr);
  607. hal_verbose_debug("MLO table start paddr:%llx,"
  608. "Non-MLO table start paddr:%llx,"
  609. "MLO table start vaddr: %pK,"
  610. "Non MLO table start vaddr: %pK",
  611. hal->reo_qref.mlo_reo_qref_table_paddr,
  612. hal->reo_qref.non_mlo_reo_qref_table_paddr,
  613. hal->reo_qref.mlo_reo_qref_table_vaddr,
  614. hal->reo_qref.non_mlo_reo_qref_table_vaddr);
  615. }
  616. /**
  617. * hal_reo_shared_qaddr_init() - Zero out REO qref LUT and
  618. * write start addr of MLO and Non MLO table in HW
  619. *
  620. * @hal_soc: HAL Soc handle
  621. *
  622. * Return: None
  623. */
  624. static void hal_reo_shared_qaddr_init_be(hal_soc_handle_t hal_soc_hdl)
  625. {
  626. struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
  627. qdf_mem_zero(hal->reo_qref.mlo_reo_qref_table_vaddr,
  628. REO_QUEUE_REF_ML_TABLE_SIZE);
  629. qdf_mem_zero(hal->reo_qref.non_mlo_reo_qref_table_vaddr,
  630. REO_QUEUE_REF_NON_ML_TABLE_SIZE);
  631. /* LUT_BASE0 and BASE1 registers expect upper 32bits of LUT base address
  632. * and lower 8 bits to be 0. Shift the physical address by 8 to plug
  633. * upper 32bits only
  634. */
  635. HAL_REG_WRITE(hal,
  636. HWIO_REO_R0_QDESC_LUT_BASE0_ADDR_ADDR(REO_REG_REG_BASE),
  637. hal->reo_qref.non_mlo_reo_qref_table_paddr >> 8);
  638. HAL_REG_WRITE(hal,
  639. HWIO_REO_R0_QDESC_LUT_BASE1_ADDR_ADDR(REO_REG_REG_BASE),
  640. hal->reo_qref.mlo_reo_qref_table_paddr >> 8);
  641. HAL_REG_WRITE(hal,
  642. HWIO_REO_R0_QDESC_ADDR_READ_ADDR(REO_REG_REG_BASE),
  643. HAL_SM(HWIO_REO_R0_QDESC_ADDR_READ, LUT_FEATURE_ENABLE,
  644. 1));
  645. HAL_REG_WRITE(hal,
  646. HWIO_REO_R0_QDESC_MAX_SW_PEER_ID_ADDR(REO_REG_REG_BASE),
  647. HAL_MS(HWIO_REO_R0_QDESC, MAX_SW_PEER_ID_MAX_SUPPORTED,
  648. 0x1fff));
  649. }
  650. /**
  651. * hal_reo_shared_qaddr_detach() - Free MLO and Non MLO reo queue
  652. * reference table shared between SW and HW
  653. *
  654. * @hal_soc: HAL Soc handle
  655. *
  656. * Return: None
  657. */
  658. static void hal_reo_shared_qaddr_detach_be(hal_soc_handle_t hal_soc_hdl)
  659. {
  660. struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
  661. HAL_REG_WRITE(hal,
  662. HWIO_REO_R0_QDESC_LUT_BASE0_ADDR_ADDR(REO_REG_REG_BASE),
  663. 0);
  664. HAL_REG_WRITE(hal,
  665. HWIO_REO_R0_QDESC_LUT_BASE1_ADDR_ADDR(REO_REG_REG_BASE),
  666. 0);
  667. qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev,
  668. REO_QUEUE_REF_ML_TABLE_SIZE,
  669. hal->reo_qref.mlo_reo_qref_table_vaddr,
  670. hal->reo_qref.mlo_reo_qref_table_paddr, 0);
  671. qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev,
  672. REO_QUEUE_REF_NON_ML_TABLE_SIZE,
  673. hal->reo_qref.non_mlo_reo_qref_table_vaddr,
  674. hal->reo_qref.non_mlo_reo_qref_table_paddr, 0);
  675. }
  676. #endif
  677. #endif /* _HAL_BE_GENERIC_API_H_ */