dp_mlo.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <wlan_utility.h>
  17. #include <dp_internal.h>
  18. #include <dp_htt.h>
  19. #include <hal_be_api.h>
  20. #include "dp_mlo.h"
  21. #include <dp_be.h>
  22. #include <dp_htt.h>
  23. #include <dp_internal.h>
  24. /*
  25. * dp_mlo_ctxt_attach_wifi3 () – Attach DP MLO context
  26. *
  27. * Return: DP MLO context handle on success, NULL on failure
  28. */
  29. struct cdp_mlo_ctxt *
  30. dp_mlo_ctxt_attach_wifi3(struct cdp_ctrl_mlo_mgr *ctrl_ctxt)
  31. {
  32. struct dp_mlo_ctxt *mlo_ctxt =
  33. qdf_mem_malloc(sizeof(struct dp_mlo_ctxt));
  34. if (!mlo_ctxt) {
  35. dp_err("Failed to allocate DP MLO Context");
  36. return NULL;
  37. }
  38. mlo_ctxt->ctrl_ctxt = ctrl_ctxt;
  39. if (dp_mlo_peer_find_hash_attach_be
  40. (mlo_ctxt, DP_MAX_MLO_PEER) != QDF_STATUS_SUCCESS) {
  41. dp_err("Failed to allocate peer hash");
  42. qdf_mem_free(mlo_ctxt);
  43. return NULL;
  44. }
  45. qdf_spinlock_create(&mlo_ctxt->ml_soc_list_lock);
  46. return dp_mlo_ctx_to_cdp(mlo_ctxt);
  47. }
  48. qdf_export_symbol(dp_mlo_ctxt_attach_wifi3);
  49. /*
  50. * dp_mlo_ctxt_detach_wifi3 () – Detach DP MLO context
  51. *
  52. * @ml_ctxt: pointer to DP MLO context
  53. *
  54. * Return: void
  55. */
  56. void dp_mlo_ctxt_detach_wifi3(struct cdp_mlo_ctxt *cdp_ml_ctxt)
  57. {
  58. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  59. if (!cdp_ml_ctxt)
  60. return;
  61. qdf_spinlock_destroy(&mlo_ctxt->ml_soc_list_lock);
  62. dp_mlo_peer_find_hash_detach_be(mlo_ctxt);
  63. qdf_mem_free(mlo_ctxt);
  64. }
  65. qdf_export_symbol(dp_mlo_ctxt_detach_wifi3);
  66. /*
  67. * dp_mlo_set_soc_by_chip_id() – Add DP soc to ML context soc list
  68. *
  69. * @ml_ctxt: DP ML context handle
  70. * @soc: DP soc handle
  71. * @chip_id: MLO chip id
  72. *
  73. * Return: void
  74. */
  75. void dp_mlo_set_soc_by_chip_id(struct dp_mlo_ctxt *ml_ctxt,
  76. struct dp_soc *soc,
  77. uint8_t chip_id)
  78. {
  79. qdf_spin_lock_bh(&ml_ctxt->ml_soc_list_lock);
  80. ml_ctxt->ml_soc_list[chip_id] = soc;
  81. qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
  82. }
  83. /*
  84. * dp_mlo_get_soc_ref_by_chip_id() – Get DP soc from DP ML context.
  85. * This API will increment a reference count for DP soc. Caller has
  86. * to take care for decrementing refcount.
  87. *
  88. * @ml_ctxt: DP ML context handle
  89. * @chip_id: MLO chip id
  90. *
  91. * Return: dp_soc
  92. */
  93. struct dp_soc*
  94. dp_mlo_get_soc_ref_by_chip_id(struct dp_mlo_ctxt *ml_ctxt,
  95. uint8_t chip_id)
  96. {
  97. struct dp_soc *soc = NULL;
  98. qdf_spin_lock_bh(&ml_ctxt->ml_soc_list_lock);
  99. soc = ml_ctxt->ml_soc_list[chip_id];
  100. if (!soc) {
  101. qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
  102. return NULL;
  103. }
  104. qdf_atomic_inc(&soc->ref_count);
  105. qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
  106. return soc;
  107. }
  108. static void dp_mlo_soc_setup(struct cdp_soc_t *soc_hdl,
  109. struct cdp_mlo_ctxt *cdp_ml_ctxt)
  110. {
  111. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  112. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  113. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  114. if (!cdp_ml_ctxt)
  115. return;
  116. dp_mlo_set_soc_by_chip_id(mlo_ctxt, soc, be_soc->mlo_chip_id);
  117. }
  118. static void dp_mlo_soc_teardown(struct cdp_soc_t *soc_hdl,
  119. struct cdp_mlo_ctxt *cdp_ml_ctxt)
  120. {
  121. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  122. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  123. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  124. if (!cdp_ml_ctxt)
  125. return;
  126. dp_mlo_set_soc_by_chip_id(mlo_ctxt, NULL, be_soc->mlo_chip_id);
  127. }
  128. static struct cdp_mlo_ops dp_mlo_ops = {
  129. .mlo_soc_setup = dp_mlo_soc_setup,
  130. .mlo_soc_teardown = dp_mlo_soc_teardown,
  131. };
  132. void dp_soc_mlo_fill_params(struct dp_soc *soc,
  133. struct cdp_soc_attach_params *params)
  134. {
  135. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  136. if (!params->mlo_enabled) {
  137. dp_warn("MLO not enabled on SOC");
  138. return;
  139. }
  140. be_soc->mlo_chip_id = params->mlo_chip_id;
  141. be_soc->ml_ctxt = cdp_mlo_ctx_to_dp(params->ml_context);
  142. be_soc->mlo_enabled = 1;
  143. soc->cdp_soc.ops->mlo_ops = &dp_mlo_ops;
  144. }
  145. void dp_pdev_mlo_fill_params(struct dp_pdev *pdev,
  146. struct cdp_pdev_attach_params *params)
  147. {
  148. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(pdev->soc);
  149. struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
  150. if (!be_soc->mlo_enabled) {
  151. dp_info("MLO not enabled on SOC");
  152. return;
  153. }
  154. be_pdev->mlo_link_id = params->mlo_link_id;
  155. }
  156. void dp_mlo_partner_chips_map(struct dp_soc *soc,
  157. struct dp_peer *peer,
  158. uint16_t peer_id)
  159. {
  160. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  161. struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
  162. bool is_ml_peer_id = peer_id & HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S;
  163. uint8_t chip_id;
  164. struct dp_soc *temp_soc;
  165. if (!mlo_ctxt)
  166. return;
  167. /* for non ML peer dont map on partner chips*/
  168. if (!is_ml_peer_id)
  169. return;
  170. qdf_spin_lock_bh(&mlo_ctxt->ml_soc_list_lock);
  171. for (chip_id = 0; chip_id < DP_MAX_MLO_CHIPS; chip_id++) {
  172. temp_soc = mlo_ctxt->ml_soc_list[chip_id];
  173. if (!temp_soc)
  174. continue;
  175. /* skip if this is current soc */
  176. if (temp_soc == soc)
  177. continue;
  178. dp_peer_find_id_to_obj_add(temp_soc, peer, peer_id);
  179. }
  180. qdf_spin_unlock_bh(&mlo_ctxt->ml_soc_list_lock);
  181. }
  182. qdf_export_symbol(dp_mlo_partner_chips_map);
  183. void dp_mlo_partner_chips_unmap(struct dp_soc *soc,
  184. uint16_t peer_id)
  185. {
  186. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  187. struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
  188. bool is_ml_peer_id = peer_id & HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S;
  189. uint8_t chip_id;
  190. struct dp_soc *temp_soc;
  191. if (!is_ml_peer_id)
  192. return;
  193. if (!mlo_ctxt)
  194. return;
  195. qdf_spin_lock_bh(&mlo_ctxt->ml_soc_list_lock);
  196. for (chip_id = 0; chip_id < DP_MAX_MLO_CHIPS; chip_id++) {
  197. temp_soc = mlo_ctxt->ml_soc_list[chip_id];
  198. if (!temp_soc)
  199. continue;
  200. /* skip if this is current soc */
  201. if (temp_soc == soc)
  202. continue;
  203. dp_peer_find_id_to_obj_remove(temp_soc, peer_id);
  204. }
  205. qdf_spin_unlock_bh(&mlo_ctxt->ml_soc_list_lock);
  206. }
  207. qdf_export_symbol(dp_mlo_partner_chips_unmap);
  208. uint8_t dp_mlo_get_chip_id(struct dp_soc *soc)
  209. {
  210. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  211. return be_soc->mlo_chip_id;
  212. }
  213. qdf_export_symbol(dp_mlo_get_chip_id);
  214. struct dp_peer *
  215. dp_link_peer_hash_find_by_chip_id(struct dp_soc *soc,
  216. uint8_t *peer_mac_addr,
  217. int mac_addr_is_aligned,
  218. uint8_t vdev_id,
  219. uint8_t chip_id,
  220. enum dp_mod_id mod_id)
  221. {
  222. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  223. struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
  224. struct dp_soc *link_peer_soc = NULL;
  225. struct dp_peer *peer = NULL;
  226. if (!mlo_ctxt)
  227. return NULL;
  228. link_peer_soc = dp_mlo_get_soc_ref_by_chip_id(mlo_ctxt, chip_id);
  229. if (!link_peer_soc)
  230. return NULL;
  231. peer = dp_peer_find_hash_find(link_peer_soc, peer_mac_addr,
  232. mac_addr_is_aligned, vdev_id,
  233. mod_id);
  234. qdf_atomic_dec(&link_peer_soc->ref_count);
  235. return peer;
  236. }
  237. qdf_export_symbol(dp_link_peer_hash_find_by_chip_id);