target_if_scan.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * Copyright (c) 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. /**
  19. * DOC: offload lmac interface APIs definitions for scan
  20. */
  21. #include <qdf_mem.h>
  22. #include <qdf_status.h>
  23. #include <target_if_scan.h>
  24. #include <wmi_unified_priv.h>
  25. #include <wmi_unified_param.h>
  26. #include <wlan_objmgr_psoc_obj.h>
  27. #include <wlan_scan_tgt_api.h>
  28. #include <target_if.h>
  29. static inline struct wlan_lmac_if_scan_rx_ops *
  30. target_if_scan_get_rx_ops(struct wlan_objmgr_psoc *psoc)
  31. {
  32. return &psoc->soc_cb.rx_ops.scan;
  33. }
  34. static int
  35. target_if_scan_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen)
  36. {
  37. struct scan_event_info *event_info;
  38. struct wlan_objmgr_psoc *psoc;
  39. struct wmi_unified *wmi_handle;
  40. struct wlan_lmac_if_scan_rx_ops *scan_rx_ops;
  41. QDF_STATUS status;
  42. if (!scn || !data) {
  43. target_if_err("scn: 0x%pK, data: 0x%pK\n", scn, data);
  44. return -EINVAL;
  45. }
  46. psoc = target_if_get_psoc_from_scn_hdl(scn);
  47. if (!psoc) {
  48. target_if_err("null psoc\n");
  49. return -EINVAL;
  50. }
  51. wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
  52. event_info = qdf_mem_malloc(sizeof(*event_info));
  53. if (!event_info) {
  54. target_if_err("unable to allocate scan_event");
  55. return -ENOMEM;
  56. }
  57. if (wmi_extract_vdev_scan_ev_param(wmi_handle, data,
  58. &(event_info->event))) {
  59. target_if_err("Failed to extract wmi scan event");
  60. qdf_mem_free(event_info);
  61. return -EINVAL;
  62. }
  63. scan_rx_ops = target_if_scan_get_rx_ops(psoc);
  64. if (scan_rx_ops->scan_ev_handler) {
  65. status = scan_rx_ops->scan_ev_handler(psoc, event_info);
  66. if (status != QDF_STATUS_SUCCESS) {
  67. qdf_mem_free(event_info);
  68. return -EINVAL;
  69. }
  70. } else {
  71. qdf_mem_free(event_info);
  72. return -EINVAL;
  73. }
  74. return 0;
  75. }
  76. #ifdef FEATURE_WLAN_SCAN_PNO
  77. int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data,
  78. uint32_t len)
  79. {
  80. wmi_nlo_event *nlo_event;
  81. struct scan_event_info *event_info;
  82. struct wlan_objmgr_psoc *psoc;
  83. struct wlan_lmac_if_scan_rx_ops *scan_rx_ops;
  84. WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf =
  85. (WMI_NLO_MATCH_EVENTID_param_tlvs *) data;
  86. QDF_STATUS status;
  87. if (!scn || !data) {
  88. target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
  89. return -EINVAL;
  90. }
  91. psoc = target_if_get_psoc_from_scn_hdl(scn);
  92. if (!psoc) {
  93. target_if_err("null psoc");
  94. return -EINVAL;
  95. }
  96. event_info = qdf_mem_malloc(sizeof(*event_info));
  97. if (!event_info) {
  98. target_if_err("unable to allocate scan_event");
  99. return -ENOMEM;
  100. }
  101. nlo_event = param_buf->fixed_param;
  102. target_if_info("PNO complete event received for vdev %d",
  103. nlo_event->vdev_id);
  104. event_info->event.type = SCAN_EVENT_TYPE_NLO_COMPLETE;
  105. event_info->event.vdev_id = nlo_event->vdev_id;
  106. scan_rx_ops = target_if_scan_get_rx_ops(psoc);
  107. if (scan_rx_ops->scan_ev_handler) {
  108. status = scan_rx_ops->scan_ev_handler(psoc, event_info);
  109. if (status != QDF_STATUS_SUCCESS) {
  110. qdf_mem_free(event_info);
  111. return -EINVAL;
  112. }
  113. } else {
  114. qdf_mem_free(event_info);
  115. return -EINVAL;
  116. }
  117. return 0;
  118. }
  119. int target_if_nlo_match_event_handler(ol_scn_t scn, uint8_t *data,
  120. uint32_t len)
  121. {
  122. wmi_nlo_event *nlo_event;
  123. struct scan_event_info *event_info;
  124. struct wlan_objmgr_psoc *psoc;
  125. struct wlan_lmac_if_scan_rx_ops *scan_rx_ops;
  126. WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf =
  127. (WMI_NLO_MATCH_EVENTID_param_tlvs *) data;
  128. QDF_STATUS status;
  129. if (!scn || !data) {
  130. target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
  131. return -EINVAL;
  132. }
  133. psoc = target_if_get_psoc_from_scn_hdl(scn);
  134. if (!psoc) {
  135. target_if_err("null psoc");
  136. return -EINVAL;
  137. }
  138. event_info = qdf_mem_malloc(sizeof(*event_info));
  139. if (!event_info) {
  140. target_if_err("unable to allocate scan_event");
  141. return -ENOMEM;
  142. }
  143. nlo_event = param_buf->fixed_param;
  144. target_if_info("PNO match event received for vdev %d",
  145. nlo_event->vdev_id);
  146. event_info->event.type = SCAN_EVENT_TYPE_NLO_MATCH;
  147. event_info->event.vdev_id = nlo_event->vdev_id;
  148. scan_rx_ops = target_if_scan_get_rx_ops(psoc);
  149. if (scan_rx_ops->scan_ev_handler) {
  150. status = scan_rx_ops->scan_ev_handler(psoc, event_info);
  151. if (status != QDF_STATUS_SUCCESS) {
  152. qdf_mem_free(event_info);
  153. return -EINVAL;
  154. }
  155. } else {
  156. qdf_mem_free(event_info);
  157. return -EINVAL;
  158. }
  159. return 0;
  160. }
  161. static QDF_STATUS
  162. target_if_scan_register_pno_event_handler(struct wlan_objmgr_psoc *psoc,
  163. void *arg)
  164. {
  165. QDF_STATUS status;
  166. status = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
  167. wmi_nlo_match_event_id,
  168. target_if_nlo_match_event_handler);
  169. if (status) {
  170. target_if_err("Failed to register nlo match event cb");
  171. return QDF_STATUS_E_FAILURE;
  172. }
  173. status = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
  174. wmi_nlo_scan_complete_event_id,
  175. target_if_nlo_complete_handler);
  176. if (status) {
  177. target_if_err("Failed to register nlo scan comp event cb");
  178. return QDF_STATUS_E_FAILURE;
  179. }
  180. return QDF_STATUS_SUCCESS;
  181. }
  182. static QDF_STATUS
  183. target_if_scan_unregister_pno_event_handler(struct wlan_objmgr_psoc *psoc,
  184. void *arg)
  185. {
  186. QDF_STATUS status;
  187. status = wmi_unified_unregister_event(GET_WMI_HDL_FROM_PSOC(psoc),
  188. wmi_nlo_match_event_id);
  189. if (status) {
  190. target_if_err("Failed to unregister nlo match event cb");
  191. return QDF_STATUS_E_FAILURE;
  192. }
  193. status = wmi_unified_unregister_event(GET_WMI_HDL_FROM_PSOC(psoc),
  194. wmi_nlo_scan_complete_event_id);
  195. if (status) {
  196. target_if_err("Failed to unregister nlo scan comp event cb");
  197. return QDF_STATUS_E_FAILURE;
  198. }
  199. return QDF_STATUS_SUCCESS;
  200. }
  201. static QDF_STATUS
  202. target_if_pno_start(struct wlan_objmgr_psoc *psoc,
  203. struct pno_scan_req_params *req)
  204. {
  205. QDF_STATUS status;
  206. status = wmi_unified_pno_start_cmd(GET_WMI_HDL_FROM_PSOC(psoc), req);
  207. if (status == QDF_STATUS_SUCCESS) {
  208. if (req->mawc_params.enable)
  209. status = wmi_unified_nlo_mawc_cmd(
  210. GET_WMI_HDL_FROM_PSOC(psoc),
  211. &req->mawc_params);
  212. }
  213. return status;
  214. }
  215. static QDF_STATUS
  216. target_if_pno_stop(struct wlan_objmgr_psoc *psoc,
  217. uint8_t vdev_id)
  218. {
  219. return wmi_unified_pno_stop_cmd(GET_WMI_HDL_FROM_PSOC(psoc), vdev_id);
  220. }
  221. #else
  222. static inline QDF_STATUS
  223. target_if_scan_register_pno_event_handler(struct wlan_objmgr_psoc *psoc,
  224. void *arg)
  225. {
  226. return QDF_STATUS_SUCCESS;
  227. }
  228. static inline QDF_STATUS
  229. target_if_scan_unregister_pno_event_handler(struct wlan_objmgr_psoc *psoc,
  230. void *arg)
  231. {
  232. return QDF_STATUS_SUCCESS;
  233. }
  234. static inline QDF_STATUS
  235. target_if_pno_start(struct wlan_objmgr_psoc *psoc,
  236. struct pno_scan_req_params *req)
  237. {
  238. return QDF_STATUS_SUCCESS;
  239. }
  240. static inline QDF_STATUS
  241. target_if_pno_stop(struct wlan_objmgr_psoc *psoc,
  242. uint8_t vdev_id)
  243. {
  244. return QDF_STATUS_SUCCESS;
  245. }
  246. #endif
  247. QDF_STATUS
  248. target_if_scan_register_event_handler(struct wlan_objmgr_psoc *psoc, void *arg)
  249. {
  250. QDF_STATUS status;
  251. status = wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc),
  252. wmi_scan_event_id, target_if_scan_event_handler);
  253. if (status) {
  254. target_if_err("Failed to register Scan match event cb");
  255. return QDF_STATUS_E_FAILURE;
  256. }
  257. status = target_if_scan_register_pno_event_handler(psoc, arg);
  258. return status;
  259. }
  260. QDF_STATUS
  261. target_if_scan_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
  262. void *arg)
  263. {
  264. QDF_STATUS status;
  265. status = wmi_unified_unregister_event(GET_WMI_HDL_FROM_PSOC(psoc),
  266. wmi_scan_event_id);
  267. if (status) {
  268. target_if_err("Failed to unregister Scan match event cb");
  269. return QDF_STATUS_E_FAILURE;
  270. }
  271. status = target_if_scan_unregister_pno_event_handler(psoc, arg);
  272. return status;
  273. }
  274. QDF_STATUS
  275. target_if_scan_start(struct wlan_objmgr_psoc *psoc,
  276. struct scan_start_request *req)
  277. {
  278. return wmi_unified_scan_start_cmd_send(GET_WMI_HDL_FROM_PSOC(psoc),
  279. &req->scan_req);
  280. }
  281. QDF_STATUS
  282. target_if_scan_cancel(struct wlan_objmgr_psoc *psoc,
  283. struct scan_cancel_param *req)
  284. {
  285. return wmi_unified_scan_stop_cmd_send(GET_WMI_HDL_FROM_PSOC(psoc), req);
  286. }
  287. QDF_STATUS
  288. target_if_register_scan_tx_ops(struct wlan_lmac_if_scan_tx_ops *scan)
  289. {
  290. scan->scan_start = target_if_scan_start;
  291. scan->scan_cancel = target_if_scan_cancel;
  292. scan->pno_start = target_if_pno_start;
  293. scan->pno_stop = target_if_pno_stop;
  294. scan->scan_reg_ev_handler = target_if_scan_register_event_handler;
  295. scan->scan_unreg_ev_handler = target_if_scan_unregister_event_handler;
  296. return QDF_STATUS_SUCCESS;
  297. }
  298. QDF_STATUS
  299. target_if_scan_set_max_active_scans(struct wlan_objmgr_psoc *psoc,
  300. uint32_t max_active_scans)
  301. {
  302. struct wlan_lmac_if_scan_rx_ops *scan_rx_ops;
  303. QDF_STATUS status;
  304. scan_rx_ops = target_if_scan_get_rx_ops(psoc);
  305. if (scan_rx_ops->scan_set_max_active_scans) {
  306. status = scan_rx_ops->scan_set_max_active_scans(psoc,
  307. max_active_scans);
  308. } else {
  309. target_if_err("scan_set_max_active_scans uninitialized");
  310. status = QDF_STATUS_E_FAULT;
  311. }
  312. return status;
  313. }