wlan_tdls_tgt_api.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Copyright (c) 2017-2018 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. /**
  19. * DOC: wlan_tdls_tgt_api.c
  20. *
  21. * TDLS south bound interface definitions
  22. */
  23. #include "qdf_status.h"
  24. #include <wlan_tdls_tgt_api.h>
  25. #include "../../core/src/wlan_tdls_main.h"
  26. #include "../../core/src/wlan_tdls_cmds_process.h"
  27. #include "../../core/src/wlan_tdls_mgmt.h"
  28. static inline struct wlan_lmac_if_tdls_tx_ops *
  29. wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc)
  30. {
  31. return &psoc->soc_cb.tx_ops.tdls_tx_ops;
  32. }
  33. static inline struct wlan_lmac_if_tdls_rx_ops *
  34. wlan_psoc_get_tdls_rxops(struct wlan_objmgr_psoc *psoc)
  35. {
  36. return &psoc->soc_cb.rx_ops.tdls_rx_ops;
  37. }
  38. QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc,
  39. struct tdls_info *tdls_param)
  40. {
  41. struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
  42. tdls_ops = wlan_psoc_get_tdls_txops(psoc);
  43. if (tdls_ops && tdls_ops->update_fw_state)
  44. return tdls_ops->update_fw_state(psoc, tdls_param);
  45. else
  46. return QDF_STATUS_SUCCESS;
  47. }
  48. QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc,
  49. struct tdls_peer_update_state *peer_param)
  50. {
  51. struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
  52. tdls_ops = wlan_psoc_get_tdls_txops(psoc);
  53. if (tdls_ops && tdls_ops->update_peer_state)
  54. return tdls_ops->update_peer_state(psoc, peer_param);
  55. else
  56. return QDF_STATUS_SUCCESS;
  57. }
  58. QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
  59. struct tdls_channel_switch_params *param)
  60. {
  61. struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
  62. tdls_ops = wlan_psoc_get_tdls_txops(psoc);
  63. if (tdls_ops && tdls_ops->set_offchan_mode)
  64. return tdls_ops->set_offchan_mode(psoc, param);
  65. else
  66. return QDF_STATUS_SUCCESS;
  67. }
  68. QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc,
  69. struct sta_uapsd_trig_params *params)
  70. {
  71. struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
  72. tdls_ops = wlan_psoc_get_tdls_txops(psoc);
  73. if (tdls_ops && tdls_ops->tdls_set_uapsd)
  74. return tdls_ops->tdls_set_uapsd(psoc, params);
  75. else
  76. return QDF_STATUS_SUCCESS;
  77. }
  78. QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg)
  79. {
  80. QDF_STATUS status = QDF_STATUS_SUCCESS;
  81. if (!pmsg || !pmsg->bodyptr) {
  82. tdls_err("msg: 0x%pK", pmsg);
  83. QDF_ASSERT(0);
  84. return QDF_STATUS_E_NULL_VALUE;
  85. }
  86. status = tdls_send_mgmt_tx_completion(pmsg->bodyptr);
  87. return status;
  88. }
  89. QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg)
  90. {
  91. QDF_STATUS status = QDF_STATUS_SUCCESS;
  92. if (!pmsg || !pmsg->bodyptr) {
  93. tdls_err("msg: 0x%pK", pmsg);
  94. QDF_ASSERT(0);
  95. return QDF_STATUS_E_NULL_VALUE;
  96. }
  97. status = tdls_process_send_mgmt_rsp(pmsg->bodyptr);
  98. return status;
  99. }
  100. QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg)
  101. {
  102. QDF_STATUS status = QDF_STATUS_SUCCESS;
  103. if (!pmsg || !pmsg->bodyptr) {
  104. tdls_err("msg: 0x%pK", pmsg);
  105. QDF_ASSERT(0);
  106. return QDF_STATUS_E_NULL_VALUE;
  107. }
  108. status = tdls_process_add_peer_rsp(pmsg->bodyptr);
  109. return status;
  110. }
  111. QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg)
  112. {
  113. QDF_STATUS status = QDF_STATUS_SUCCESS;
  114. if (!pmsg || !pmsg->bodyptr) {
  115. tdls_err("msg: 0x%pK", pmsg);
  116. QDF_ASSERT(0);
  117. return QDF_STATUS_E_NULL_VALUE;
  118. }
  119. status = tdls_process_del_peer_rsp(pmsg->bodyptr);
  120. return status;
  121. }
  122. QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc)
  123. {
  124. struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
  125. tdls_ops = wlan_psoc_get_tdls_txops(psoc);
  126. if (tdls_ops && tdls_ops->tdls_reg_ev_handler)
  127. return tdls_ops->tdls_reg_ev_handler(psoc, NULL);
  128. else
  129. return QDF_STATUS_SUCCESS;
  130. }
  131. QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
  132. {
  133. struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
  134. tdls_ops = wlan_psoc_get_tdls_txops(psoc);
  135. if (tdls_ops->tdls_unreg_ev_handler)
  136. return tdls_ops->tdls_unreg_ev_handler(psoc, NULL);
  137. else
  138. return QDF_STATUS_SUCCESS;
  139. }
  140. static QDF_STATUS tgt_tdls_event_flush_cb(struct scheduler_msg *msg)
  141. {
  142. struct tdls_event_notify *notify;
  143. notify = msg->bodyptr;
  144. if (notify && notify->vdev) {
  145. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID);
  146. qdf_mem_free(notify);
  147. }
  148. return QDF_STATUS_SUCCESS;
  149. }
  150. QDF_STATUS
  151. tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc,
  152. struct tdls_event_info *info)
  153. {
  154. struct scheduler_msg msg = {0,};
  155. struct tdls_event_notify *notify;
  156. uint8_t vdev_id;
  157. QDF_STATUS status;
  158. if (!psoc || !info) {
  159. tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info);
  160. return QDF_STATUS_E_NULL_VALUE;
  161. }
  162. tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_STR,
  163. info->vdev_id, info->message_type, info->peer_reason,
  164. QDF_MAC_ADDR_ARRAY(info->peermac.bytes));
  165. notify = qdf_mem_malloc(sizeof(*notify));
  166. if (!notify) {
  167. tdls_err("mem allocate fail");
  168. return QDF_STATUS_E_NOMEM;
  169. }
  170. vdev_id = info->vdev_id;
  171. notify->vdev =
  172. wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
  173. vdev_id, WLAN_TDLS_SB_ID);
  174. if (!notify->vdev) {
  175. tdls_err("null vdev, vdev_id: %d, psoc: 0x%pK", vdev_id, psoc);
  176. return QDF_STATUS_E_INVAL;
  177. }
  178. qdf_mem_copy(&notify->event, info, sizeof(*info));
  179. msg.bodyptr = notify;
  180. msg.callback = tdls_process_evt;
  181. msg.flush_callback = tgt_tdls_event_flush_cb;
  182. status = scheduler_post_message(QDF_MODULE_ID_TDLS,
  183. QDF_MODULE_ID_TDLS,
  184. QDF_MODULE_ID_TARGET_IF, &msg);
  185. if (QDF_IS_STATUS_ERROR(status)) {
  186. tdls_err("can't post msg to handle tdls event");
  187. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID);
  188. qdf_mem_free(notify);
  189. }
  190. return status;
  191. }
  192. static QDF_STATUS tgt_tdls_mgmt_frame_rx_flush_cb(struct scheduler_msg *msg)
  193. {
  194. struct tdls_rx_mgmt_event *rx_mgmt_event;
  195. rx_mgmt_event = msg->bodyptr;
  196. if (rx_mgmt_event) {
  197. if (rx_mgmt_event->rx_mgmt)
  198. qdf_mem_free(rx_mgmt_event->rx_mgmt);
  199. qdf_mem_free(rx_mgmt_event);
  200. }
  201. msg->bodyptr = NULL;
  202. return QDF_STATUS_SUCCESS;
  203. }
  204. static
  205. QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb(
  206. struct wlan_objmgr_psoc *psoc,
  207. struct wlan_objmgr_peer *peer,
  208. qdf_nbuf_t buf,
  209. struct mgmt_rx_event_params *mgmt_rx_params,
  210. enum mgmt_frame_type frm_type)
  211. {
  212. struct tdls_rx_mgmt_frame *rx_mgmt;
  213. struct tdls_rx_mgmt_event *rx_mgmt_event;
  214. struct tdls_soc_priv_obj *tdls_soc_obj;
  215. struct scheduler_msg msg = {0};
  216. struct wlan_objmgr_vdev *vdev;
  217. uint32_t vdev_id;
  218. uint8_t *pdata;
  219. QDF_STATUS status;
  220. tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
  221. WLAN_UMAC_COMP_TDLS);
  222. if (!tdls_soc_obj) {
  223. tdls_err("tdls ctx is NULL, drop this frame");
  224. return QDF_STATUS_E_FAILURE;
  225. }
  226. if (!peer) {
  227. vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID);
  228. if (!vdev) {
  229. tdls_err("current tdls vdev is null, can't get vdev id");
  230. return QDF_STATUS_E_FAILURE;
  231. }
  232. vdev_id = wlan_vdev_get_id(vdev);
  233. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
  234. } else {
  235. vdev = wlan_peer_get_vdev(peer);
  236. if (!vdev) {
  237. tdls_err("vdev is NULL in peer, drop this frame");
  238. return QDF_STATUS_E_FAILURE;
  239. }
  240. vdev_id = wlan_vdev_get_id(vdev);
  241. }
  242. rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event));
  243. if (!rx_mgmt_event) {
  244. tdls_err("Failed to allocate rx mgmt event");
  245. return QDF_STATUS_E_NOMEM;
  246. }
  247. rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) +
  248. mgmt_rx_params->buf_len);
  249. if (!rx_mgmt) {
  250. tdls_err("Failed to allocate rx mgmt frame");
  251. qdf_mem_free(rx_mgmt_event);
  252. return QDF_STATUS_E_NOMEM;
  253. }
  254. pdata = (uint8_t *)qdf_nbuf_data(buf);
  255. rx_mgmt->frame_len = mgmt_rx_params->buf_len;
  256. rx_mgmt->rx_chan = mgmt_rx_params->channel;
  257. rx_mgmt->vdev_id = vdev_id;
  258. rx_mgmt->frm_type = frm_type;
  259. rx_mgmt->rx_rssi = mgmt_rx_params->rssi;
  260. rx_mgmt_event->rx_mgmt = rx_mgmt;
  261. rx_mgmt_event->tdls_soc_obj = tdls_soc_obj;
  262. qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len);
  263. msg.type = TDLS_EVENT_RX_MGMT;
  264. msg.bodyptr = rx_mgmt_event;
  265. msg.callback = tdls_process_rx_frame;
  266. msg.flush_callback = tgt_tdls_mgmt_frame_rx_flush_cb;
  267. status = scheduler_post_message(QDF_MODULE_ID_TDLS,
  268. QDF_MODULE_ID_TDLS,
  269. QDF_MODULE_ID_TARGET_IF, &msg);
  270. if (QDF_IS_STATUS_ERROR(status)) {
  271. qdf_mem_free(rx_mgmt);
  272. qdf_mem_free(rx_mgmt_event);
  273. }
  274. qdf_nbuf_free(buf);
  275. return status;
  276. }
  277. QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(
  278. struct wlan_objmgr_psoc *psoc,
  279. struct wlan_objmgr_peer *peer,
  280. qdf_nbuf_t buf,
  281. struct mgmt_rx_event_params *mgmt_rx_params,
  282. enum mgmt_frame_type frm_type)
  283. {
  284. QDF_STATUS status;
  285. tdls_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type);
  286. if (!buf) {
  287. tdls_err("rx frame buff is null buf:%pK", buf);
  288. return QDF_STATUS_E_INVAL;
  289. }
  290. if (!mgmt_rx_params || !psoc) {
  291. tdls_err("input is NULL mgmt_rx_params:%pK psoc:%pK, peer:%pK",
  292. mgmt_rx_params, psoc, peer);
  293. status = QDF_STATUS_E_INVAL;
  294. goto release_nbuf;
  295. }
  296. status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID);
  297. if (QDF_STATUS_SUCCESS != status)
  298. goto release_nbuf;
  299. status = tgt_tdls_mgmt_frame_process_rx_cb(psoc, peer, buf,
  300. mgmt_rx_params, frm_type);
  301. wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
  302. if (QDF_STATUS_SUCCESS != status)
  303. release_nbuf:
  304. qdf_nbuf_free(buf);
  305. return status;
  306. }
  307. void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
  308. uint32_t session_id)
  309. {
  310. tdls_peers_deleted_notification(psoc, session_id);
  311. }
  312. void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
  313. uint32_t session_id)
  314. {
  315. tdls_delete_all_peers_indication(psoc, session_id);
  316. }