wlan_tdls_api.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * Copyright (c) 2020, The Linux Foundation. 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. /*
  17. * DOC: contains tdls link teardown definitions
  18. */
  19. #include "wlan_objmgr_psoc_obj.h"
  20. #include "wlan_objmgr_pdev_obj.h"
  21. #include "wlan_objmgr_vdev_obj.h"
  22. #include "wlan_tdls_api.h"
  23. #include "../../core/src/wlan_tdls_main.h"
  24. #include "../../core/src/wlan_tdls_ct.h"
  25. #include "../../core/src/wlan_tdls_mgmt.h"
  26. #include <wlan_objmgr_global_obj.h>
  27. #include <wlan_objmgr_cmn.h>
  28. static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg)
  29. {
  30. struct tdls_link_teardown *tdls_teardown = msg->bodyptr;
  31. struct wlan_objmgr_psoc *psoc = tdls_teardown->psoc;
  32. wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID);
  33. qdf_mem_free(tdls_teardown);
  34. return QDF_STATUS_SUCCESS;
  35. }
  36. QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc)
  37. {
  38. QDF_STATUS status;
  39. struct scheduler_msg msg = {0, };
  40. struct tdls_link_teardown *link_teardown;
  41. link_teardown = qdf_mem_malloc(sizeof(*link_teardown));
  42. if (!link_teardown)
  43. return QDF_STATUS_E_NOMEM;
  44. wlan_objmgr_psoc_get_ref(psoc, WLAN_TDLS_SB_ID);
  45. link_teardown->psoc = psoc;
  46. msg.bodyptr = link_teardown;
  47. msg.callback = tdls_process_cmd;
  48. msg.flush_callback = tdls_teardown_flush_cb;
  49. msg.type = TDLS_CMD_TEARDOWN_LINKS;
  50. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  51. QDF_MODULE_ID_TDLS,
  52. QDF_MODULE_ID_OS_IF, &msg);
  53. if (QDF_IS_STATUS_ERROR(status)) {
  54. tdls_err("post msg fail, %d", status);
  55. wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID);
  56. qdf_mem_free(link_teardown);
  57. }
  58. return status;
  59. }
  60. void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
  61. {
  62. struct tdls_vdev_priv_obj *vdev_priv_obj;
  63. QDF_STATUS status;
  64. struct wlan_objmgr_vdev *vdev;
  65. vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
  66. if (!vdev)
  67. return;
  68. vdev_priv_obj = wlan_vdev_get_tdls_vdev_obj(vdev);
  69. if (!vdev_priv_obj) {
  70. tdls_err("vdev priv is NULL");
  71. goto release_ref;
  72. }
  73. qdf_event_reset(&vdev_priv_obj->tdls_teardown_comp);
  74. status = wlan_tdls_teardown_links(psoc);
  75. if (QDF_IS_STATUS_ERROR(status)) {
  76. tdls_err("wlan_tdls_teardown_links failed err %d", status);
  77. goto release_ref;
  78. }
  79. tdls_debug("Wait for tdls teardown completion. Timeout %u ms",
  80. WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
  81. status = qdf_wait_for_event_completion(
  82. &vdev_priv_obj->tdls_teardown_comp,
  83. WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
  84. if (QDF_IS_STATUS_ERROR(status)) {
  85. tdls_err(" Teardown Completion timed out %d", status);
  86. goto release_ref;
  87. }
  88. tdls_debug("TDLS teardown completion status %d ", status);
  89. release_ref:
  90. wlan_objmgr_vdev_release_ref(vdev,
  91. WLAN_TDLS_NB_ID);
  92. }
  93. static QDF_STATUS tdls_notify_flush_cb(struct scheduler_msg *msg)
  94. {
  95. struct tdls_sta_notify_params *notify = msg->bodyptr;
  96. struct wlan_objmgr_vdev *vdev = notify->vdev;
  97. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  98. qdf_mem_free(notify);
  99. return QDF_STATUS_SUCCESS;
  100. }
  101. static QDF_STATUS
  102. tdls_notify_disconnect(struct tdls_sta_notify_params *notify_info)
  103. {
  104. struct scheduler_msg msg = {0, };
  105. struct tdls_sta_notify_params *notify;
  106. QDF_STATUS status;
  107. if (!notify_info || !notify_info->vdev) {
  108. tdls_err("notify_info %pK", notify_info);
  109. return QDF_STATUS_E_NULL_VALUE;
  110. }
  111. tdls_debug("Enter ");
  112. notify = qdf_mem_malloc(sizeof(*notify));
  113. if (!notify) {
  114. wlan_objmgr_vdev_release_ref(notify_info->vdev, WLAN_TDLS_NB_ID);
  115. return QDF_STATUS_E_NULL_VALUE;
  116. }
  117. *notify = *notify_info;
  118. msg.bodyptr = notify;
  119. msg.callback = tdls_process_cmd;
  120. msg.type = TDLS_NOTIFY_STA_DISCONNECTION;
  121. msg.flush_callback = tdls_notify_flush_cb;
  122. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  123. QDF_MODULE_ID_TDLS,
  124. QDF_MODULE_ID_TARGET_IF, &msg);
  125. if (QDF_IS_STATUS_ERROR(status)) {
  126. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
  127. qdf_mem_free(notify);
  128. }
  129. tdls_debug("Exit ");
  130. return QDF_STATUS_SUCCESS;
  131. }
  132. void wlan_tdls_notify_sta_disconnect(uint8_t vdev_id,
  133. bool lfr_roam, bool user_disconnect,
  134. struct wlan_objmgr_vdev *vdev)
  135. {
  136. struct tdls_sta_notify_params notify_info = {0};
  137. QDF_STATUS status;
  138. if (!vdev) {
  139. tdls_err("vdev is NULL");
  140. return;
  141. }
  142. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  143. if (QDF_IS_STATUS_ERROR(status)) {
  144. tdls_err("can't get vdev");
  145. return;
  146. }
  147. notify_info.session_id = vdev_id;
  148. notify_info.lfr_roam = lfr_roam;
  149. notify_info.tdls_chan_swit_prohibited = false;
  150. notify_info.tdls_prohibited = false;
  151. notify_info.vdev = vdev;
  152. notify_info.user_disconnect = user_disconnect;
  153. tdls_notify_disconnect(&notify_info);
  154. }
  155. static QDF_STATUS
  156. tdls_notify_connect(struct tdls_sta_notify_params *notify_info)
  157. {
  158. struct scheduler_msg msg = {0, };
  159. struct tdls_sta_notify_params *notify;
  160. QDF_STATUS status;
  161. if (!notify_info || !notify_info->vdev) {
  162. tdls_err("notify_info %pK", notify_info);
  163. return QDF_STATUS_E_NULL_VALUE;
  164. }
  165. tdls_debug("Enter ");
  166. notify = qdf_mem_malloc(sizeof(*notify));
  167. if (!notify) {
  168. wlan_objmgr_vdev_release_ref(notify_info->vdev,
  169. WLAN_TDLS_NB_ID);
  170. return QDF_STATUS_E_NULL_VALUE;
  171. }
  172. *notify = *notify_info;
  173. msg.bodyptr = notify;
  174. msg.callback = tdls_process_cmd;
  175. msg.type = TDLS_NOTIFY_STA_CONNECTION;
  176. msg.flush_callback = tdls_notify_flush_cb;
  177. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  178. QDF_MODULE_ID_TDLS,
  179. QDF_MODULE_ID_TARGET_IF, &msg);
  180. if (QDF_IS_STATUS_ERROR(status)) {
  181. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
  182. qdf_mem_free(notify);
  183. }
  184. tdls_debug("Exit ");
  185. return status;
  186. }
  187. void
  188. wlan_tdls_notify_sta_connect(uint8_t session_id,
  189. bool tdls_chan_swit_prohibited,
  190. bool tdls_prohibited,
  191. struct wlan_objmgr_vdev *vdev)
  192. {
  193. struct tdls_sta_notify_params notify_info = {0};
  194. QDF_STATUS status;
  195. if (!vdev) {
  196. tdls_err("vdev is NULL");
  197. return;
  198. }
  199. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  200. if (QDF_IS_STATUS_ERROR(status)) {
  201. tdls_err("can't get vdev");
  202. return;
  203. }
  204. notify_info.session_id = session_id;
  205. notify_info.vdev = vdev;
  206. notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited;
  207. notify_info.tdls_prohibited = tdls_prohibited;
  208. tdls_notify_connect(&notify_info);
  209. }