wlan_tdls_api.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /*
  18. * DOC: contains tdls link teardown definitions
  19. */
  20. #include "wlan_objmgr_psoc_obj.h"
  21. #include "wlan_objmgr_pdev_obj.h"
  22. #include "wlan_objmgr_vdev_obj.h"
  23. #include "wlan_tdls_api.h"
  24. #include "../../core/src/wlan_tdls_main.h"
  25. #include "../../core/src/wlan_tdls_ct.h"
  26. #include "../../core/src/wlan_tdls_mgmt.h"
  27. #include <wlan_objmgr_global_obj.h>
  28. #include <wlan_objmgr_cmn.h>
  29. #include "wlan_tdls_cfg_api.h"
  30. static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg)
  31. {
  32. struct tdls_link_teardown *tdls_teardown = msg->bodyptr;
  33. struct wlan_objmgr_psoc *psoc = tdls_teardown->psoc;
  34. wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID);
  35. qdf_mem_free(tdls_teardown);
  36. return QDF_STATUS_SUCCESS;
  37. }
  38. QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc)
  39. {
  40. QDF_STATUS status;
  41. struct scheduler_msg msg = {0, };
  42. struct tdls_link_teardown *link_teardown;
  43. link_teardown = qdf_mem_malloc(sizeof(*link_teardown));
  44. if (!link_teardown)
  45. return QDF_STATUS_E_NOMEM;
  46. wlan_objmgr_psoc_get_ref(psoc, WLAN_TDLS_SB_ID);
  47. link_teardown->psoc = psoc;
  48. msg.bodyptr = link_teardown;
  49. msg.callback = tdls_process_cmd;
  50. msg.flush_callback = tdls_teardown_flush_cb;
  51. msg.type = TDLS_CMD_TEARDOWN_LINKS;
  52. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  53. QDF_MODULE_ID_TDLS,
  54. QDF_MODULE_ID_OS_IF, &msg);
  55. if (QDF_IS_STATUS_ERROR(status)) {
  56. tdls_err("post msg fail, %d", status);
  57. wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID);
  58. qdf_mem_free(link_teardown);
  59. }
  60. return status;
  61. }
  62. void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
  63. {
  64. struct tdls_vdev_priv_obj *vdev_priv_obj;
  65. QDF_STATUS status;
  66. struct wlan_objmgr_vdev *vdev;
  67. vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
  68. if (!vdev)
  69. return;
  70. vdev_priv_obj = wlan_vdev_get_tdls_vdev_obj(vdev);
  71. if (!vdev_priv_obj) {
  72. tdls_err("vdev priv is NULL");
  73. goto release_ref;
  74. }
  75. qdf_event_reset(&vdev_priv_obj->tdls_teardown_comp);
  76. status = wlan_tdls_teardown_links(psoc);
  77. if (QDF_IS_STATUS_ERROR(status)) {
  78. tdls_err("wlan_tdls_teardown_links failed err %d", status);
  79. goto release_ref;
  80. }
  81. tdls_debug("Wait for tdls teardown completion. Timeout %u ms",
  82. WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
  83. status = qdf_wait_for_event_completion(
  84. &vdev_priv_obj->tdls_teardown_comp,
  85. WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
  86. if (QDF_IS_STATUS_ERROR(status)) {
  87. tdls_err(" Teardown Completion timed out %d", status);
  88. goto release_ref;
  89. }
  90. tdls_debug("TDLS teardown completion status %d ", status);
  91. release_ref:
  92. wlan_objmgr_vdev_release_ref(vdev,
  93. WLAN_TDLS_NB_ID);
  94. }
  95. static QDF_STATUS tdls_notify_flush_cb(struct scheduler_msg *msg)
  96. {
  97. struct tdls_sta_notify_params *notify = msg->bodyptr;
  98. struct wlan_objmgr_vdev *vdev = notify->vdev;
  99. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  100. qdf_mem_free(notify);
  101. return QDF_STATUS_SUCCESS;
  102. }
  103. static QDF_STATUS
  104. tdls_notify_disconnect(struct tdls_sta_notify_params *notify_info)
  105. {
  106. struct scheduler_msg msg = {0, };
  107. struct tdls_sta_notify_params *notify;
  108. QDF_STATUS status;
  109. if (!notify_info || !notify_info->vdev) {
  110. tdls_err("notify_info %pK", notify_info);
  111. return QDF_STATUS_E_NULL_VALUE;
  112. }
  113. tdls_debug("Enter ");
  114. notify = qdf_mem_malloc(sizeof(*notify));
  115. if (!notify) {
  116. wlan_objmgr_vdev_release_ref(notify_info->vdev, WLAN_TDLS_NB_ID);
  117. return QDF_STATUS_E_NULL_VALUE;
  118. }
  119. *notify = *notify_info;
  120. msg.bodyptr = notify;
  121. msg.callback = tdls_process_cmd;
  122. msg.type = TDLS_NOTIFY_STA_DISCONNECTION;
  123. msg.flush_callback = tdls_notify_flush_cb;
  124. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  125. QDF_MODULE_ID_TDLS,
  126. QDF_MODULE_ID_TARGET_IF, &msg);
  127. if (QDF_IS_STATUS_ERROR(status)) {
  128. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
  129. qdf_mem_free(notify);
  130. }
  131. tdls_debug("Exit ");
  132. return QDF_STATUS_SUCCESS;
  133. }
  134. void wlan_tdls_notify_sta_disconnect(uint8_t vdev_id,
  135. bool lfr_roam, bool user_disconnect,
  136. struct wlan_objmgr_vdev *vdev)
  137. {
  138. struct tdls_sta_notify_params notify_info = {0};
  139. QDF_STATUS status;
  140. if (!vdev) {
  141. tdls_err("vdev is NULL");
  142. return;
  143. }
  144. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  145. if (QDF_IS_STATUS_ERROR(status)) {
  146. tdls_err("can't get vdev");
  147. return;
  148. }
  149. notify_info.session_id = vdev_id;
  150. notify_info.lfr_roam = lfr_roam;
  151. notify_info.tdls_chan_swit_prohibited = false;
  152. notify_info.tdls_prohibited = false;
  153. notify_info.vdev = vdev;
  154. notify_info.user_disconnect = user_disconnect;
  155. tdls_notify_disconnect(&notify_info);
  156. }
  157. static QDF_STATUS
  158. tdls_notify_connect(struct tdls_sta_notify_params *notify_info)
  159. {
  160. struct scheduler_msg msg = {0, };
  161. struct tdls_sta_notify_params *notify;
  162. QDF_STATUS status;
  163. if (!notify_info || !notify_info->vdev) {
  164. tdls_err("notify_info %pK", notify_info);
  165. return QDF_STATUS_E_NULL_VALUE;
  166. }
  167. tdls_debug("Enter ");
  168. notify = qdf_mem_malloc(sizeof(*notify));
  169. if (!notify) {
  170. wlan_objmgr_vdev_release_ref(notify_info->vdev,
  171. WLAN_TDLS_NB_ID);
  172. return QDF_STATUS_E_NULL_VALUE;
  173. }
  174. *notify = *notify_info;
  175. msg.bodyptr = notify;
  176. msg.callback = tdls_process_cmd;
  177. msg.type = TDLS_NOTIFY_STA_CONNECTION;
  178. msg.flush_callback = tdls_notify_flush_cb;
  179. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  180. QDF_MODULE_ID_TDLS,
  181. QDF_MODULE_ID_TARGET_IF, &msg);
  182. if (QDF_IS_STATUS_ERROR(status)) {
  183. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
  184. qdf_mem_free(notify);
  185. }
  186. tdls_debug("Exit ");
  187. return status;
  188. }
  189. void
  190. wlan_tdls_notify_sta_connect(uint8_t session_id,
  191. bool tdls_chan_swit_prohibited,
  192. bool tdls_prohibited,
  193. struct wlan_objmgr_vdev *vdev)
  194. {
  195. struct tdls_sta_notify_params notify_info = {0};
  196. QDF_STATUS status;
  197. if (!vdev) {
  198. tdls_err("vdev is NULL");
  199. return;
  200. }
  201. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  202. if (QDF_IS_STATUS_ERROR(status)) {
  203. tdls_err("can't get vdev");
  204. return;
  205. }
  206. notify_info.session_id = session_id;
  207. notify_info.vdev = vdev;
  208. notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited;
  209. notify_info.tdls_prohibited = tdls_prohibited;
  210. tdls_notify_connect(&notify_info);
  211. }
  212. #ifdef FEATURE_SET
  213. void wlan_tdls_get_features_info(struct wlan_objmgr_psoc *psoc,
  214. struct wlan_tdls_features *tdls_feature_set)
  215. {
  216. cfg_tdls_get_support_enable(psoc, &tdls_feature_set->enable_tdls);
  217. if (tdls_feature_set->enable_tdls) {
  218. cfg_tdls_get_off_channel_enable(
  219. psoc,
  220. &tdls_feature_set->enable_tdls_offchannel);
  221. tdls_feature_set->max_tdls_peers =
  222. cfg_tdls_get_max_peer_count(psoc);
  223. tdls_feature_set->enable_tdls_capability_enhance = true;
  224. }
  225. }
  226. #endif
  227. void wlan_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
  228. struct qdf_mac_addr *mac_addr)
  229. {
  230. tdls_update_tx_pkt_cnt(vdev, mac_addr);
  231. }
  232. void wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
  233. struct qdf_mac_addr *mac_addr,
  234. struct qdf_mac_addr *dest_mac_addr)
  235. {
  236. tdls_update_rx_pkt_cnt(vdev, mac_addr, dest_mac_addr);
  237. }