dp_htt.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  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 <htt.h>
  19. #include <hal_api.h>
  20. #include "dp_htt.h"
  21. #include "dp_peer.h"
  22. #include "dp_types.h"
  23. #include "dp_internal.h"
  24. #include "dp_rx_mon.h"
  25. #define HTT_HTC_PKT_POOL_INIT_SIZE 64
  26. #define HTT_MSG_BUF_SIZE(msg_bytes) \
  27. ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING)
  28. /*
  29. * htt_htc_pkt_alloc() - Allocate HTC packet buffer
  30. * @htt_soc: HTT SOC handle
  31. *
  32. * Return: Pointer to htc packet buffer
  33. */
  34. static struct dp_htt_htc_pkt *
  35. htt_htc_pkt_alloc(struct htt_soc *soc)
  36. {
  37. struct dp_htt_htc_pkt_union *pkt = NULL;
  38. HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
  39. if (soc->htt_htc_pkt_freelist) {
  40. pkt = soc->htt_htc_pkt_freelist;
  41. soc->htt_htc_pkt_freelist = soc->htt_htc_pkt_freelist->u.next;
  42. }
  43. HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
  44. if (pkt == NULL)
  45. pkt = qdf_mem_malloc(sizeof(*pkt));
  46. return &pkt->u.pkt; /* not actually a dereference */
  47. }
  48. /*
  49. * htt_htc_pkt_free() - Free HTC packet buffer
  50. * @htt_soc: HTT SOC handle
  51. */
  52. static void
  53. htt_htc_pkt_free(struct htt_soc *soc, struct dp_htt_htc_pkt *pkt)
  54. {
  55. struct dp_htt_htc_pkt_union *u_pkt =
  56. (struct dp_htt_htc_pkt_union *)pkt;
  57. HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
  58. u_pkt->u.next = soc->htt_htc_pkt_freelist;
  59. soc->htt_htc_pkt_freelist = u_pkt;
  60. HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
  61. }
  62. /*
  63. * htt_htc_pkt_pool_free() - Free HTC packet pool
  64. * @htt_soc: HTT SOC handle
  65. */
  66. static void
  67. htt_htc_pkt_pool_free(struct htt_soc *soc)
  68. {
  69. struct dp_htt_htc_pkt_union *pkt, *next;
  70. pkt = soc->htt_htc_pkt_freelist;
  71. while (pkt) {
  72. next = pkt->u.next;
  73. qdf_mem_free(pkt);
  74. pkt = next;
  75. }
  76. soc->htt_htc_pkt_freelist = NULL;
  77. }
  78. /*
  79. * htt_t2h_mac_addr_deswizzle() - Swap MAC addr bytes if FW endianess differ
  80. * @tgt_mac_addr: Target MAC
  81. * @buffer: Output buffer
  82. */
  83. static u_int8_t *
  84. htt_t2h_mac_addr_deswizzle(u_int8_t *tgt_mac_addr, u_int8_t *buffer)
  85. {
  86. #ifdef BIG_ENDIAN_HOST
  87. /*
  88. * The host endianness is opposite of the target endianness.
  89. * To make u_int32_t elements come out correctly, the target->host
  90. * upload has swizzled the bytes in each u_int32_t element of the
  91. * message.
  92. * For byte-array message fields like the MAC address, this
  93. * upload swizzling puts the bytes in the wrong order, and needs
  94. * to be undone.
  95. */
  96. buffer[0] = tgt_mac_addr[3];
  97. buffer[1] = tgt_mac_addr[2];
  98. buffer[2] = tgt_mac_addr[1];
  99. buffer[3] = tgt_mac_addr[0];
  100. buffer[4] = tgt_mac_addr[7];
  101. buffer[5] = tgt_mac_addr[6];
  102. return buffer;
  103. #else
  104. /*
  105. * The host endianness matches the target endianness -
  106. * we can use the mac addr directly from the message buffer.
  107. */
  108. return tgt_mac_addr;
  109. #endif
  110. }
  111. /*
  112. * dp_htt_h2t_send_complete_free_netbuf() - Free completed buffer
  113. * @soc: SOC handle
  114. * @status: Completion status
  115. * @netbuf: HTT buffer
  116. */
  117. static void
  118. dp_htt_h2t_send_complete_free_netbuf(
  119. void *soc, A_STATUS status, qdf_nbuf_t netbuf)
  120. {
  121. qdf_nbuf_free(netbuf);
  122. }
  123. /*
  124. * dp_htt_h2t_send_complete() - H2T completion handler
  125. * @context: Opaque context (HTT SOC handle)
  126. * @htc_pkt: HTC packet
  127. */
  128. static void
  129. dp_htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
  130. {
  131. void (*send_complete_part2)(
  132. void *soc, A_STATUS status, qdf_nbuf_t msdu);
  133. struct htt_soc *soc = (struct htt_soc *) context;
  134. struct dp_htt_htc_pkt *htt_pkt;
  135. qdf_nbuf_t netbuf;
  136. send_complete_part2 = htc_pkt->pPktContext;
  137. htt_pkt = container_of(htc_pkt, struct dp_htt_htc_pkt, htc_pkt);
  138. /* process (free or keep) the netbuf that held the message */
  139. netbuf = (qdf_nbuf_t) htc_pkt->pNetBufContext;
  140. /*
  141. * adf sendcomplete is required for windows only
  142. */
  143. /* qdf_nbuf_set_sendcompleteflag(netbuf, TRUE); */
  144. if (send_complete_part2 != NULL) {
  145. send_complete_part2(
  146. htt_pkt->soc_ctxt, htc_pkt->Status, netbuf);
  147. }
  148. /* free the htt_htc_pkt / HTC_PACKET object */
  149. htt_htc_pkt_free(soc, htt_pkt);
  150. }
  151. /*
  152. * htt_h2t_ver_req_msg() - Send HTT version request message to target
  153. * @htt_soc: HTT SOC handle
  154. *
  155. * Return: 0 on success; error code on failure
  156. */
  157. static int htt_h2t_ver_req_msg(struct htt_soc *soc)
  158. {
  159. struct dp_htt_htc_pkt *pkt;
  160. qdf_nbuf_t msg;
  161. uint32_t *msg_word;
  162. msg = qdf_nbuf_alloc(
  163. soc->osdev,
  164. HTT_MSG_BUF_SIZE(HTT_VER_REQ_BYTES),
  165. /* reserve room for the HTC header */
  166. HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
  167. if (!msg)
  168. return QDF_STATUS_E_NOMEM;
  169. /*
  170. * Set the length of the message.
  171. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
  172. * separately during the below call to qdf_nbuf_push_head.
  173. * The contribution from the HTC header is added separately inside HTC.
  174. */
  175. if (qdf_nbuf_put_tail(msg, HTT_VER_REQ_BYTES) == NULL) {
  176. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  177. "%s: Failed to expand head for HTT_H2T_MSG_TYPE_VERSION_REQ msg\n",
  178. __func__);
  179. return QDF_STATUS_E_FAILURE;
  180. }
  181. /* fill in the message contents */
  182. msg_word = (u_int32_t *) qdf_nbuf_data(msg);
  183. /* rewind beyond alignment pad to get to the HTC header reserved area */
  184. qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
  185. *msg_word = 0;
  186. HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ);
  187. pkt = htt_htc_pkt_alloc(soc);
  188. if (!pkt) {
  189. qdf_nbuf_free(msg);
  190. return QDF_STATUS_E_FAILURE;
  191. }
  192. pkt->soc_ctxt = NULL; /* not used during send-done callback */
  193. SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
  194. dp_htt_h2t_send_complete_free_netbuf, qdf_nbuf_data(msg),
  195. qdf_nbuf_len(msg), soc->htc_endpoint,
  196. 1); /* tag - not relevant here */
  197. SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
  198. htc_send_pkt(soc->htc_soc, &pkt->htc_pkt);
  199. return 0;
  200. }
  201. /*
  202. * htt_srng_setup() - Send SRNG setup message to target
  203. * @htt_soc: HTT SOC handle
  204. * @mac_id: MAC Id
  205. * @hal_srng: Opaque HAL SRNG pointer
  206. * @hal_ring_type: SRNG ring type
  207. *
  208. * Return: 0 on success; error code on failure
  209. */
  210. int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng,
  211. int hal_ring_type)
  212. {
  213. struct htt_soc *soc = (struct htt_soc *)htt_soc;
  214. struct dp_htt_htc_pkt *pkt;
  215. qdf_nbuf_t htt_msg;
  216. uint32_t *msg_word;
  217. struct hal_srng_params srng_params;
  218. qdf_dma_addr_t hp_addr, tp_addr;
  219. uint32_t ring_entry_size =
  220. hal_srng_get_entrysize(soc->hal_soc, hal_ring_type);
  221. int htt_ring_type, htt_ring_id;
  222. /* Sizes should be set in 4-byte words */
  223. ring_entry_size = ring_entry_size >> 2;
  224. htt_msg = qdf_nbuf_alloc(soc->osdev,
  225. HTT_MSG_BUF_SIZE(HTT_SRING_SETUP_SZ),
  226. /* reserve room for the HTC header */
  227. HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
  228. if (!htt_msg)
  229. goto fail0;
  230. hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params);
  231. hp_addr = hal_srng_get_hp_addr(soc->hal_soc, hal_srng);
  232. tp_addr = hal_srng_get_tp_addr(soc->hal_soc, hal_srng);
  233. switch (hal_ring_type) {
  234. case RXDMA_BUF:
  235. #ifdef QCA_HOST2FW_RXBUF_RING
  236. if (srng_params.ring_id ==
  237. (HAL_SRNG_WMAC1_SW2RXDMA0_BUF)) {
  238. htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
  239. htt_ring_type = HTT_SW_TO_SW_RING;
  240. #else
  241. if (srng_params.ring_id ==
  242. (HAL_SRNG_WMAC1_SW2RXDMA0_BUF +
  243. (mac_id * HAL_MAX_RINGS_PER_LMAC))) {
  244. htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
  245. htt_ring_type = HTT_SW_TO_HW_RING;
  246. #endif
  247. } else if (srng_params.ring_id ==
  248. (HAL_SRNG_WMAC1_SW2RXDMA1_BUF +
  249. (mac_id * HAL_MAX_RINGS_PER_LMAC))) {
  250. htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
  251. htt_ring_type = HTT_SW_TO_HW_RING;
  252. } else {
  253. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  254. "%s: Ring %d currently not supported\n",
  255. __func__, srng_params.ring_id);
  256. goto fail1;
  257. }
  258. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  259. "%s: ring_type %d ring_id %d\n",
  260. __func__, hal_ring_type, srng_params.ring_id);
  261. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  262. "%s: hp_addr 0x%llx tp_addr 0x%llx\n",
  263. __func__, (uint64_t)hp_addr, (uint64_t)tp_addr);
  264. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  265. "%s: htt_ring_id %d\n", __func__, htt_ring_id);
  266. break;
  267. case RXDMA_MONITOR_BUF:
  268. htt_ring_id = HTT_RXDMA_MONITOR_BUF_RING;
  269. htt_ring_type = HTT_SW_TO_HW_RING;
  270. break;
  271. case RXDMA_MONITOR_STATUS:
  272. htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
  273. htt_ring_type = HTT_SW_TO_HW_RING;
  274. break;
  275. case RXDMA_MONITOR_DST:
  276. htt_ring_id = HTT_RXDMA_MONITOR_DEST_RING;
  277. htt_ring_type = HTT_HW_TO_SW_RING;
  278. break;
  279. case RXDMA_MONITOR_DESC:
  280. htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
  281. htt_ring_type = HTT_SW_TO_HW_RING;
  282. break;
  283. default:
  284. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  285. "%s: Ring currently not supported\n", __func__);
  286. goto fail1;
  287. }
  288. /*
  289. * Set the length of the message.
  290. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
  291. * separately during the below call to qdf_nbuf_push_head.
  292. * The contribution from the HTC header is added separately inside HTC.
  293. */
  294. if (qdf_nbuf_put_tail(htt_msg, HTT_SRING_SETUP_SZ) == NULL) {
  295. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  296. "%s: Failed to expand head for SRING_SETUP msg\n",
  297. __func__);
  298. return QDF_STATUS_E_FAILURE;
  299. }
  300. msg_word = (uint32_t *)qdf_nbuf_data(htt_msg);
  301. /* rewind beyond alignment pad to get to the HTC header reserved area */
  302. qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING);
  303. /* word 0 */
  304. *msg_word = 0;
  305. HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SRING_SETUP);
  306. if (htt_ring_type == HTT_SW_TO_HW_RING)
  307. HTT_SRING_SETUP_PDEV_ID_SET(*msg_word,
  308. DP_SW2HW_MACID(mac_id));
  309. else
  310. HTT_SRING_SETUP_PDEV_ID_SET(*msg_word, mac_id);
  311. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  312. "%s: mac_id %d\n", __func__, mac_id);
  313. HTT_SRING_SETUP_RING_TYPE_SET(*msg_word, htt_ring_type);
  314. /* TODO: Discuss with FW on changing this to unique ID and using
  315. * htt_ring_type to send the type of ring
  316. */
  317. HTT_SRING_SETUP_RING_ID_SET(*msg_word, htt_ring_id);
  318. /* word 1 */
  319. msg_word++;
  320. *msg_word = 0;
  321. HTT_SRING_SETUP_RING_BASE_ADDR_LO_SET(*msg_word,
  322. srng_params.ring_base_paddr & 0xffffffff);
  323. /* word 2 */
  324. msg_word++;
  325. *msg_word = 0;
  326. HTT_SRING_SETUP_RING_BASE_ADDR_HI_SET(*msg_word,
  327. (uint64_t)srng_params.ring_base_paddr >> 32);
  328. /* word 3 */
  329. msg_word++;
  330. *msg_word = 0;
  331. HTT_SRING_SETUP_ENTRY_SIZE_SET(*msg_word, ring_entry_size);
  332. HTT_SRING_SETUP_RING_SIZE_SET(*msg_word,
  333. (ring_entry_size * srng_params.num_entries));
  334. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  335. "%s: entry_size %d\n", __func__,
  336. ring_entry_size);
  337. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  338. "%s: num_entries %d\n", __func__,
  339. srng_params.num_entries);
  340. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  341. "%s: ring_size %d\n", __func__,
  342. (ring_entry_size * srng_params.num_entries));
  343. if (htt_ring_type == HTT_SW_TO_HW_RING)
  344. HTT_SRING_SETUP_RING_MISC_CFG_FLAG_LOOPCOUNT_DISABLE_SET(
  345. *msg_word, 1);
  346. HTT_SRING_SETUP_RING_MISC_CFG_FLAG_MSI_SWAP_SET(*msg_word,
  347. !!(srng_params.flags & HAL_SRNG_MSI_SWAP));
  348. HTT_SRING_SETUP_RING_MISC_CFG_FLAG_TLV_SWAP_SET(*msg_word,
  349. !!(srng_params.flags & HAL_SRNG_DATA_TLV_SWAP));
  350. HTT_SRING_SETUP_RING_MISC_CFG_FLAG_HOST_FW_SWAP_SET(*msg_word,
  351. !!(srng_params.flags & HAL_SRNG_RING_PTR_SWAP));
  352. /* word 4 */
  353. msg_word++;
  354. *msg_word = 0;
  355. HTT_SRING_SETUP_HEAD_OFFSET32_REMOTE_BASE_ADDR_LO_SET(*msg_word,
  356. hp_addr & 0xffffffff);
  357. /* word 5 */
  358. msg_word++;
  359. *msg_word = 0;
  360. HTT_SRING_SETUP_HEAD_OFFSET32_REMOTE_BASE_ADDR_HI_SET(*msg_word,
  361. (uint64_t)hp_addr >> 32);
  362. /* word 6 */
  363. msg_word++;
  364. *msg_word = 0;
  365. HTT_SRING_SETUP_TAIL_OFFSET32_REMOTE_BASE_ADDR_LO_SET(*msg_word,
  366. tp_addr & 0xffffffff);
  367. /* word 7 */
  368. msg_word++;
  369. *msg_word = 0;
  370. HTT_SRING_SETUP_TAIL_OFFSET32_REMOTE_BASE_ADDR_HI_SET(*msg_word,
  371. (uint64_t)tp_addr >> 32);
  372. /* word 8 */
  373. msg_word++;
  374. *msg_word = 0;
  375. HTT_SRING_SETUP_RING_MSI_ADDR_LO_SET(*msg_word,
  376. srng_params.msi_addr & 0xffffffff);
  377. /* word 9 */
  378. msg_word++;
  379. *msg_word = 0;
  380. HTT_SRING_SETUP_RING_MSI_ADDR_HI_SET(*msg_word,
  381. (uint64_t)(srng_params.msi_addr) >> 32);
  382. /* word 10 */
  383. msg_word++;
  384. *msg_word = 0;
  385. HTT_SRING_SETUP_RING_MSI_DATA_SET(*msg_word,
  386. srng_params.msi_data);
  387. /* word 11 */
  388. msg_word++;
  389. *msg_word = 0;
  390. HTT_SRING_SETUP_INTR_BATCH_COUNTER_TH_SET(*msg_word,
  391. srng_params.intr_batch_cntr_thres_entries *
  392. ring_entry_size);
  393. HTT_SRING_SETUP_INTR_TIMER_TH_SET(*msg_word,
  394. srng_params.intr_timer_thres_us >> 3);
  395. /* word 12 */
  396. msg_word++;
  397. *msg_word = 0;
  398. if (srng_params.flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
  399. /* TODO: Setting low threshold to 1/8th of ring size - see
  400. * if this needs to be configurable
  401. */
  402. HTT_SRING_SETUP_INTR_LOW_TH_SET(*msg_word,
  403. srng_params.low_threshold);
  404. }
  405. /* "response_required" field should be set if a HTT response message is
  406. * required after setting up the ring.
  407. */
  408. pkt = htt_htc_pkt_alloc(soc);
  409. if (!pkt)
  410. goto fail1;
  411. pkt->soc_ctxt = NULL; /* not used during send-done callback */
  412. SET_HTC_PACKET_INFO_TX(
  413. &pkt->htc_pkt,
  414. dp_htt_h2t_send_complete_free_netbuf,
  415. qdf_nbuf_data(htt_msg),
  416. qdf_nbuf_len(htt_msg),
  417. soc->htc_endpoint,
  418. 1); /* tag - not relevant here */
  419. SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg);
  420. htc_send_pkt(soc->htc_soc, &pkt->htc_pkt);
  421. return QDF_STATUS_SUCCESS;
  422. fail1:
  423. qdf_nbuf_free(htt_msg);
  424. fail0:
  425. return QDF_STATUS_E_FAILURE;
  426. }
  427. /*
  428. * htt_h2t_rx_ring_cfg() - Send SRNG packet and TLV filter
  429. * config message to target
  430. * @htt_soc: HTT SOC handle
  431. * @pdev_id: PDEV Id
  432. * @hal_srng: Opaque HAL SRNG pointer
  433. * @hal_ring_type: SRNG ring type
  434. * @ring_buf_size: SRNG buffer size
  435. * @htt_tlv_filter: Rx SRNG TLV and filter setting
  436. * Return: 0 on success; error code on failure
  437. */
  438. int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
  439. int hal_ring_type, int ring_buf_size,
  440. struct htt_rx_ring_tlv_filter *htt_tlv_filter)
  441. {
  442. struct htt_soc *soc = (struct htt_soc *)htt_soc;
  443. struct dp_htt_htc_pkt *pkt;
  444. qdf_nbuf_t htt_msg;
  445. uint32_t *msg_word;
  446. struct hal_srng_params srng_params;
  447. uint32_t htt_ring_type, htt_ring_id;
  448. uint32_t tlv_filter;
  449. htt_msg = qdf_nbuf_alloc(soc->osdev,
  450. HTT_MSG_BUF_SIZE(HTT_RX_RING_SELECTION_CFG_SZ),
  451. /* reserve room for the HTC header */
  452. HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
  453. if (!htt_msg)
  454. goto fail0;
  455. hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params);
  456. switch (hal_ring_type) {
  457. case RXDMA_BUF:
  458. #if QCA_HOST2FW_RXBUF_RING
  459. htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
  460. htt_ring_type = HTT_SW_TO_SW_RING;
  461. #else
  462. htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
  463. htt_ring_type = HTT_SW_TO_HW_RING;
  464. #endif
  465. break;
  466. case RXDMA_MONITOR_BUF:
  467. htt_ring_id = HTT_RXDMA_MONITOR_BUF_RING;
  468. htt_ring_type = HTT_SW_TO_HW_RING;
  469. break;
  470. case RXDMA_MONITOR_STATUS:
  471. htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
  472. htt_ring_type = HTT_SW_TO_HW_RING;
  473. break;
  474. case RXDMA_MONITOR_DST:
  475. htt_ring_id = HTT_RXDMA_MONITOR_DEST_RING;
  476. htt_ring_type = HTT_HW_TO_SW_RING;
  477. break;
  478. case RXDMA_MONITOR_DESC:
  479. htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
  480. htt_ring_type = HTT_SW_TO_HW_RING;
  481. break;
  482. default:
  483. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  484. "%s: Ring currently not supported\n", __func__);
  485. goto fail1;
  486. }
  487. /*
  488. * Set the length of the message.
  489. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
  490. * separately during the below call to qdf_nbuf_push_head.
  491. * The contribution from the HTC header is added separately inside HTC.
  492. */
  493. if (qdf_nbuf_put_tail(htt_msg, HTT_RX_RING_SELECTION_CFG_SZ) == NULL) {
  494. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
  495. "%s: Failed to expand head for RX Ring Cfg msg\n",
  496. __func__);
  497. goto fail1; /* failure */
  498. }
  499. msg_word = (uint32_t *)qdf_nbuf_data(htt_msg);
  500. /* rewind beyond alignment pad to get to the HTC header reserved area */
  501. qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING);
  502. /* word 0 */
  503. *msg_word = 0;
  504. HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG);
  505. HTT_RX_RING_SELECTION_CFG_PDEV_ID_SET(*msg_word, pdev_id);
  506. /* TODO: Discuss with FW on changing this to unique ID and using
  507. * htt_ring_type to send the type of ring
  508. */
  509. HTT_RX_RING_SELECTION_CFG_RING_ID_SET(*msg_word, htt_ring_id);
  510. HTT_RX_RING_SELECTION_CFG_STATUS_TLV_SET(*msg_word,
  511. !!(srng_params.flags & HAL_SRNG_MSI_SWAP));
  512. HTT_RX_RING_SELECTION_CFG_PKT_TLV_SET(*msg_word,
  513. !!(srng_params.flags & HAL_SRNG_DATA_TLV_SWAP));
  514. /* word 1 */
  515. msg_word++;
  516. *msg_word = 0;
  517. HTT_RX_RING_SELECTION_CFG_RING_BUFFER_SIZE_SET(*msg_word,
  518. ring_buf_size);
  519. /* word 2 */
  520. msg_word++;
  521. *msg_word = 0;
  522. if (htt_tlv_filter->enable_fp) {
  523. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  524. MGMT, 0000, 1);
  525. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  526. MGMT, 0001, 1);
  527. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  528. MGMT, 0010, 1);
  529. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  530. MGMT, 0011, 1);
  531. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  532. MGMT, 0100, 1);
  533. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  534. MGMT, 0101, 1);
  535. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  536. MGMT, 0110, 1);
  537. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  538. MGMT, 1000, 1);
  539. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
  540. MGMT, 1001, 1);
  541. }
  542. if (htt_tlv_filter->enable_md) {
  543. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  544. MGMT, 0000, 1);
  545. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  546. MGMT, 0001, 1);
  547. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  548. MGMT, 0010, 1);
  549. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  550. MGMT, 0011, 1);
  551. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  552. MGMT, 0100, 1);
  553. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  554. MGMT, 0101, 1);
  555. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  556. MGMT, 0110, 1);
  557. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  558. MGMT, 1000, 1);
  559. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
  560. MGMT, 1001, 1);
  561. }
  562. if (htt_tlv_filter->enable_mo) {
  563. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  564. MGMT, 0000, 1);
  565. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  566. MGMT, 0001, 1);
  567. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  568. MGMT, 0010, 1);
  569. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  570. MGMT, 0011, 1);
  571. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  572. MGMT, 0100, 1);
  573. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  574. MGMT, 0101, 1);
  575. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  576. MGMT, 0110, 1);
  577. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  578. MGMT, 1000, 1);
  579. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
  580. MGMT, 1001, 1);
  581. }
  582. /* word 3 */
  583. msg_word++;
  584. *msg_word = 0;
  585. if (htt_tlv_filter->enable_fp) {
  586. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
  587. MGMT, 1010, 1);
  588. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
  589. MGMT, 1011, 1);
  590. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
  591. MGMT, 1100, 1);
  592. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
  593. MGMT, 1101, 1);
  594. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
  595. MGMT, 1110, 1);
  596. }
  597. if (htt_tlv_filter->enable_md) {
  598. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
  599. MGMT, 1010, 1);
  600. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
  601. MGMT, 1011, 1);
  602. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
  603. MGMT, 1100, 1);
  604. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
  605. MGMT, 1101, 1);
  606. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
  607. MGMT, 1110, 1);
  608. }
  609. if (htt_tlv_filter->enable_mo) {
  610. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
  611. MGMT, 1010, 1);
  612. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
  613. MGMT, 1011, 1);
  614. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
  615. MGMT, 1100, 1);
  616. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
  617. MGMT, 1101, 1);
  618. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
  619. MGMT, 1110, 1);
  620. }
  621. /* word 4 */
  622. msg_word++;
  623. *msg_word = 0;
  624. if (htt_tlv_filter->enable_fp) {
  625. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
  626. CTRL, 0111, 1);
  627. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
  628. CTRL, 1000, 1);
  629. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
  630. CTRL, 1001, 1);
  631. }
  632. if (htt_tlv_filter->enable_md) {
  633. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
  634. CTRL, 0111, 1);
  635. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
  636. CTRL, 1000, 1);
  637. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
  638. CTRL, 1001, 1);
  639. }
  640. if (htt_tlv_filter->enable_mo) {
  641. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
  642. CTRL, 0111, 1);
  643. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
  644. CTRL, 1000, 1);
  645. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
  646. CTRL, 1001, 1);
  647. }
  648. /* word 5 */
  649. msg_word++;
  650. *msg_word = 0;
  651. if (htt_tlv_filter->enable_fp) {
  652. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  653. CTRL, 1010, 1);
  654. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  655. CTRL, 1011, 1);
  656. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  657. CTRL, 1100, 1);
  658. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  659. CTRL, 1101, 1);
  660. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  661. CTRL, 1110, 1);
  662. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  663. CTRL, 1111, 1);
  664. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  665. CTRL, 1111, 1);
  666. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  667. DATA, MCAST, 1);
  668. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  669. DATA, UCAST, 1);
  670. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
  671. DATA, NULL, 1);
  672. }
  673. if (htt_tlv_filter->enable_md) {
  674. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  675. CTRL, 1010, 1);
  676. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  677. CTRL, 1011, 1);
  678. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  679. CTRL, 1100, 1);
  680. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  681. CTRL, 1101, 1);
  682. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  683. CTRL, 1110, 1);
  684. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  685. CTRL, 1111, 1);
  686. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  687. CTRL, 1111, 1);
  688. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  689. DATA, MCAST, 1);
  690. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  691. DATA, UCAST, 1);
  692. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
  693. DATA, NULL, 1);
  694. }
  695. if (htt_tlv_filter->enable_mo) {
  696. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  697. CTRL, 1010, 1);
  698. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  699. CTRL, 1011, 1);
  700. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  701. CTRL, 1100, 1);
  702. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  703. CTRL, 1101, 1);
  704. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  705. CTRL, 1110, 1);
  706. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  707. CTRL, 1111, 1);
  708. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  709. CTRL, 1111, 1);
  710. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  711. DATA, MCAST, 1);
  712. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  713. DATA, UCAST, 1);
  714. htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
  715. DATA, NULL, 1);
  716. }
  717. /* word 6 */
  718. msg_word++;
  719. *msg_word = 0;
  720. tlv_filter = 0;
  721. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MPDU_START,
  722. htt_tlv_filter->mpdu_start);
  723. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MSDU_START,
  724. htt_tlv_filter->msdu_start);
  725. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PACKET,
  726. htt_tlv_filter->packet);
  727. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MSDU_END,
  728. htt_tlv_filter->msdu_end);
  729. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MPDU_END,
  730. htt_tlv_filter->mpdu_end);
  731. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PACKET_HEADER,
  732. htt_tlv_filter->packet_header);
  733. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, ATTENTION,
  734. htt_tlv_filter->ppdu_end_status_done);
  735. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_START,
  736. htt_tlv_filter->ppdu_start);
  737. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END,
  738. htt_tlv_filter->ppdu_end);
  739. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END_USER_STATS,
  740. htt_tlv_filter->ppdu_end_user_stats);
  741. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter,
  742. PPDU_END_USER_STATS_EXT,
  743. htt_tlv_filter->ppdu_end_user_stats_ext);
  744. htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END_STATUS_DONE,
  745. htt_tlv_filter->ppdu_end_status_done);
  746. HTT_RX_RING_SELECTION_CFG_TLV_FILTER_IN_FLAG_SET(*msg_word, tlv_filter);
  747. /* "response_required" field should be set if a HTT response message is
  748. * required after setting up the ring.
  749. */
  750. pkt = htt_htc_pkt_alloc(soc);
  751. if (!pkt)
  752. goto fail1;
  753. pkt->soc_ctxt = NULL; /* not used during send-done callback */
  754. SET_HTC_PACKET_INFO_TX(
  755. &pkt->htc_pkt,
  756. dp_htt_h2t_send_complete_free_netbuf,
  757. qdf_nbuf_data(htt_msg),
  758. qdf_nbuf_len(htt_msg),
  759. soc->htc_endpoint,
  760. 1); /* tag - not relevant here */
  761. SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg);
  762. htc_send_pkt(soc->htc_soc, &pkt->htc_pkt);
  763. return QDF_STATUS_SUCCESS;
  764. fail1:
  765. qdf_nbuf_free(htt_msg);
  766. fail0:
  767. return QDF_STATUS_E_FAILURE;
  768. }
  769. /*
  770. * htt_soc_attach_target() - SOC level HTT setup
  771. * @htt_soc: HTT SOC handle
  772. *
  773. * Return: 0 on success; error code on failure
  774. */
  775. int htt_soc_attach_target(void *htt_soc)
  776. {
  777. struct htt_soc *soc = (struct htt_soc *)htt_soc;
  778. return htt_h2t_ver_req_msg(soc);
  779. }
  780. /*
  781. * dp_htt_t2h_msg_handler() - Generic Target to host Msg/event handler
  782. * @context: Opaque context (HTT SOC handle)
  783. * @pkt: HTC packet
  784. */
  785. static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
  786. {
  787. struct htt_soc *soc = (struct htt_soc *) context;
  788. qdf_nbuf_t htt_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
  789. u_int32_t *msg_word;
  790. enum htt_t2h_msg_type msg_type;
  791. /* check for successful message reception */
  792. if (pkt->Status != A_OK) {
  793. if (pkt->Status != A_ECANCELED)
  794. soc->stats.htc_err_cnt++;
  795. qdf_nbuf_free(htt_t2h_msg);
  796. return;
  797. }
  798. /* TODO: Check if we should pop the HTC/HTT header alignment padding */
  799. msg_word = (u_int32_t *) qdf_nbuf_data(htt_t2h_msg);
  800. msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
  801. switch (msg_type) {
  802. case HTT_T2H_MSG_TYPE_PEER_MAP:
  803. {
  804. u_int8_t mac_addr_deswizzle_buf[HTT_MAC_ADDR_LEN];
  805. u_int8_t *peer_mac_addr;
  806. u_int16_t peer_id;
  807. u_int16_t hw_peer_id;
  808. u_int8_t vdev_id;
  809. peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word);
  810. hw_peer_id =
  811. HTT_RX_PEER_MAP_HW_PEER_ID_GET(*(msg_word+2));
  812. vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word);
  813. peer_mac_addr = htt_t2h_mac_addr_deswizzle(
  814. (u_int8_t *) (msg_word+1),
  815. &mac_addr_deswizzle_buf[0]);
  816. QDF_TRACE(QDF_MODULE_ID_TXRX,
  817. QDF_TRACE_LEVEL_INFO,
  818. "HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n",
  819. peer_id, vdev_id);
  820. dp_rx_peer_map_handler(soc->dp_soc, peer_id, hw_peer_id,
  821. vdev_id, peer_mac_addr);
  822. break;
  823. }
  824. case HTT_T2H_MSG_TYPE_PEER_UNMAP:
  825. {
  826. u_int16_t peer_id;
  827. peer_id = HTT_RX_PEER_UNMAP_PEER_ID_GET(*msg_word);
  828. dp_rx_peer_unmap_handler(soc->dp_soc, peer_id);
  829. break;
  830. }
  831. case HTT_T2H_MSG_TYPE_SEC_IND:
  832. {
  833. u_int16_t peer_id;
  834. enum htt_sec_type sec_type;
  835. int is_unicast;
  836. peer_id = HTT_SEC_IND_PEER_ID_GET(*msg_word);
  837. sec_type = HTT_SEC_IND_SEC_TYPE_GET(*msg_word);
  838. is_unicast = HTT_SEC_IND_UNICAST_GET(*msg_word);
  839. /* point to the first part of the Michael key */
  840. msg_word++;
  841. dp_rx_sec_ind_handler(
  842. soc->dp_soc, peer_id, sec_type, is_unicast,
  843. msg_word, msg_word + 2);
  844. break;
  845. }
  846. #ifdef notyet
  847. #ifndef REMOVE_PKT_LOG
  848. case HTT_T2H_MSG_TYPE_PKTLOG:
  849. {
  850. u_int32_t *pl_hdr;
  851. pl_hdr = (msg_word + 1);
  852. wdi_event_handler(WDI_EVENT_OFFLOAD_ALL, soc->dp_soc,
  853. pl_hdr, HTT_INVALID_PEER, WDI_NO_VAL);
  854. break;
  855. }
  856. #endif
  857. #endif /* notyet */
  858. case HTT_T2H_MSG_TYPE_VERSION_CONF:
  859. {
  860. soc->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
  861. soc->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
  862. QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
  863. "target uses HTT version %d.%d; host uses %d.%d\n",
  864. soc->tgt_ver.major, soc->tgt_ver.minor,
  865. HTT_CURRENT_VERSION_MAJOR,
  866. HTT_CURRENT_VERSION_MINOR);
  867. if (soc->tgt_ver.major != HTT_CURRENT_VERSION_MAJOR) {
  868. QDF_TRACE(QDF_MODULE_ID_TXRX,
  869. QDF_TRACE_LEVEL_ERROR,
  870. "*** Incompatible host/target HTT versions!\n");
  871. }
  872. /* abort if the target is incompatible with the host */
  873. qdf_assert(soc->tgt_ver.major ==
  874. HTT_CURRENT_VERSION_MAJOR);
  875. if (soc->tgt_ver.minor != HTT_CURRENT_VERSION_MINOR) {
  876. QDF_TRACE(QDF_MODULE_ID_TXRX,
  877. QDF_TRACE_LEVEL_WARN,
  878. "*** Warning: host/target HTT versions"
  879. " are different, though compatible!\n");
  880. }
  881. break;
  882. }
  883. case HTT_T2H_MSG_TYPE_RX_ADDBA:
  884. {
  885. uint16_t peer_id;
  886. uint8_t tid;
  887. uint8_t win_sz;
  888. uint16_t status;
  889. struct dp_peer *peer;
  890. /*
  891. * Update REO Queue Desc with new values
  892. */
  893. peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word);
  894. tid = HTT_RX_ADDBA_TID_GET(*msg_word);
  895. win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word);
  896. peer = dp_peer_find_by_id(soc->dp_soc, peer_id);
  897. /*
  898. * Window size needs to be incremented by 1
  899. * since fw needs to represent a value of 256
  900. * using just 8 bits
  901. */
  902. if (peer) {
  903. status = dp_addba_requestprocess_wifi3(peer,
  904. 0, tid, 0, win_sz + 1, 0xffff);
  905. QDF_TRACE(QDF_MODULE_ID_TXRX,
  906. QDF_TRACE_LEVEL_INFO,
  907. FL("PeerID %d BAW %d TID %d stat %d\n"),
  908. peer_id, win_sz, tid, status);
  909. } else {
  910. QDF_TRACE(QDF_MODULE_ID_TXRX,
  911. QDF_TRACE_LEVEL_ERROR,
  912. FL("Peer not found peer id %d\n"),
  913. peer_id);
  914. }
  915. break;
  916. }
  917. default:
  918. break;
  919. };
  920. /* Free the indication buffer */
  921. qdf_nbuf_free(htt_t2h_msg);
  922. }
  923. /*
  924. * dp_htt_h2t_full() - Send full handler (called from HTC)
  925. * @context: Opaque context (HTT SOC handle)
  926. * @pkt: HTC packet
  927. *
  928. * Return: HTC_SEND_FULL_ACTION
  929. */
  930. static HTC_SEND_FULL_ACTION
  931. dp_htt_h2t_full(void *context, HTC_PACKET *pkt)
  932. {
  933. return HTC_SEND_FULL_KEEP;
  934. }
  935. /*
  936. * htt_htc_soc_attach() - Register SOC level HTT instance with HTC
  937. * @htt_soc: HTT SOC handle
  938. *
  939. * Return: 0 on success; error code on failure
  940. */
  941. static int
  942. htt_htc_soc_attach(struct htt_soc *soc)
  943. {
  944. HTC_SERVICE_CONNECT_REQ connect;
  945. HTC_SERVICE_CONNECT_RESP response;
  946. A_STATUS status;
  947. qdf_mem_set(&connect, sizeof(connect), 0);
  948. qdf_mem_set(&response, sizeof(response), 0);
  949. connect.pMetaData = NULL;
  950. connect.MetaDataLength = 0;
  951. connect.EpCallbacks.pContext = soc;
  952. connect.EpCallbacks.EpTxComplete = dp_htt_h2t_send_complete;
  953. connect.EpCallbacks.EpTxCompleteMultiple = NULL;
  954. connect.EpCallbacks.EpRecv = dp_htt_t2h_msg_handler;
  955. /* rx buffers currently are provided by HIF, not by EpRecvRefill */
  956. connect.EpCallbacks.EpRecvRefill = NULL;
  957. /* N/A, fill is done by HIF */
  958. connect.EpCallbacks.RecvRefillWaterMark = 1;
  959. connect.EpCallbacks.EpSendFull = dp_htt_h2t_full;
  960. /*
  961. * Specify how deep to let a queue get before htc_send_pkt will
  962. * call the EpSendFull function due to excessive send queue depth.
  963. */
  964. connect.MaxSendQueueDepth = DP_HTT_MAX_SEND_QUEUE_DEPTH;
  965. /* disable flow control for HTT data message service */
  966. connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
  967. /* connect to control service */
  968. connect.service_id = HTT_DATA_MSG_SVC;
  969. status = htc_connect_service(soc->htc_soc, &connect, &response);
  970. if (status != A_OK)
  971. return QDF_STATUS_E_FAILURE;
  972. soc->htc_endpoint = response.Endpoint;
  973. return 0; /* success */
  974. }
  975. /*
  976. * htt_soc_attach() - SOC level HTT initialization
  977. * @dp_soc: Opaque Data path SOC handle
  978. * @osif_soc: Opaque OSIF SOC handle
  979. * @htc_soc: SOC level HTC handle
  980. * @hal_soc: Opaque HAL SOC handle
  981. * @osdev: QDF device
  982. *
  983. * Return: HTT handle on success; NULL on failure
  984. */
  985. void *
  986. htt_soc_attach(void *dp_soc, void *osif_soc, HTC_HANDLE htc_soc,
  987. void *hal_soc, qdf_device_t osdev)
  988. {
  989. struct htt_soc *soc;
  990. int i;
  991. soc = qdf_mem_malloc(sizeof(*soc));
  992. if (!soc)
  993. goto fail1;
  994. soc->osdev = osdev;
  995. soc->osif_soc = osif_soc;
  996. soc->dp_soc = dp_soc;
  997. soc->htc_soc = htc_soc;
  998. soc->hal_soc = hal_soc;
  999. /* TODO: See if any NSS related context is requred in htt_soc */
  1000. soc->htt_htc_pkt_freelist = NULL;
  1001. if (htt_htc_soc_attach(soc))
  1002. goto fail2;
  1003. /* TODO: See if any Rx data specific intialization is required. For
  1004. * MCL use cases, the data will be received as single packet and
  1005. * should not required any descriptor or reorder handling
  1006. */
  1007. HTT_TX_MUTEX_INIT(&soc->htt_tx_mutex);
  1008. /* pre-allocate some HTC_PACKET objects */
  1009. for (i = 0; i < HTT_HTC_PKT_POOL_INIT_SIZE; i++) {
  1010. struct dp_htt_htc_pkt_union *pkt;
  1011. pkt = qdf_mem_malloc(sizeof(*pkt));
  1012. if (!pkt)
  1013. break;
  1014. htt_htc_pkt_free(soc, &pkt->u.pkt);
  1015. }
  1016. return soc;
  1017. fail2:
  1018. qdf_mem_free(soc);
  1019. fail1:
  1020. return NULL;
  1021. }
  1022. /*
  1023. * htt_soc_detach() - Detach SOC level HTT
  1024. * @htt_soc: HTT SOC handle
  1025. */
  1026. void
  1027. htt_soc_detach(void *htt_soc)
  1028. {
  1029. struct htt_soc *soc = (struct htt_soc *)htt_soc;
  1030. htt_htc_pkt_pool_free(soc);
  1031. HTT_TX_MUTEX_DESTROY(&soc->htt_tx_mutex);
  1032. qdf_mem_free(soc);
  1033. }