wlan_scan_api.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * Copyright (c) 2017-2020 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: This file contains all SCAN component's APIs
  20. */
  21. #include "cfg_ucfg_api.h"
  22. #include "wlan_scan_api.h"
  23. #include "../../core/src/wlan_scan_manager.h"
  24. void wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  25. uint32_t *dwell_time)
  26. {
  27. struct wlan_scan_obj *scan_obj;
  28. scan_obj = wlan_psoc_get_scan_obj(psoc);
  29. if (!scan_obj)
  30. return;
  31. *dwell_time = scan_obj->scan_def.passive_dwell;
  32. }
  33. void wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  34. uint32_t dwell_time)
  35. {
  36. struct wlan_scan_obj *scan_obj;
  37. scan_obj = wlan_psoc_get_scan_obj(psoc);
  38. if (!scan_obj)
  39. return;
  40. scan_obj->scan_def.passive_dwell = dwell_time;
  41. }
  42. void wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  43. uint32_t *dwell_time)
  44. {
  45. struct wlan_scan_obj *scan_obj;
  46. scan_obj = wlan_psoc_get_scan_obj(psoc);
  47. if (!scan_obj)
  48. return;
  49. *dwell_time = scan_obj->scan_def.active_dwell;
  50. }
  51. void wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  52. uint32_t dwell_time)
  53. {
  54. struct wlan_scan_obj *scan_obj;
  55. scan_obj = wlan_psoc_get_scan_obj(psoc);
  56. if (!scan_obj)
  57. return;
  58. scan_obj->scan_def.active_dwell = dwell_time;
  59. }
  60. void wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
  61. uint32_t *dwell_time)
  62. {
  63. struct wlan_scan_obj *scan_obj;
  64. scan_obj = wlan_psoc_get_scan_obj(psoc);
  65. if (!scan_obj)
  66. return;
  67. *dwell_time = scan_obj->scan_def.active_dwell_2g;
  68. }
  69. void wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
  70. uint32_t dwell_time)
  71. {
  72. struct wlan_scan_obj *scan_obj;
  73. scan_obj = wlan_psoc_get_scan_obj(psoc);
  74. if (!scan_obj)
  75. return;
  76. scan_obj->scan_def.active_dwell_2g = dwell_time;
  77. }
  78. void wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  79. uint32_t *dwell_time)
  80. {
  81. struct wlan_scan_obj *scan_obj;
  82. scan_obj = wlan_psoc_get_scan_obj(psoc);
  83. if (!scan_obj)
  84. return;
  85. *dwell_time = scan_obj->scan_def.conc_active_dwell;
  86. }
  87. void wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  88. uint32_t dwell_time)
  89. {
  90. struct wlan_scan_obj *scan_obj;
  91. scan_obj = wlan_psoc_get_scan_obj(psoc);
  92. if (!scan_obj)
  93. return;
  94. scan_obj->scan_def.conc_active_dwell = dwell_time;
  95. }
  96. void wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  97. uint32_t *dwell_time)
  98. {
  99. struct wlan_scan_obj *scan_obj;
  100. scan_obj = wlan_psoc_get_scan_obj(psoc);
  101. if (!scan_obj)
  102. return;
  103. *dwell_time = scan_obj->scan_def.conc_passive_dwell;
  104. }
  105. void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  106. uint32_t dwell_time)
  107. {
  108. struct wlan_scan_obj *scan_obj;
  109. scan_obj = wlan_psoc_get_scan_obj(psoc);
  110. if (!scan_obj)
  111. return;
  112. scan_obj->scan_def.conc_passive_dwell = dwell_time;
  113. }
  114. void
  115. wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
  116. bool *enable_dfs_scan)
  117. {
  118. struct wlan_scan_obj *scan_obj;
  119. scan_obj = wlan_psoc_get_scan_obj(psoc);
  120. if (!scan_obj)
  121. return;
  122. *enable_dfs_scan = scan_obj->scan_def.allow_dfs_chan_in_scan;
  123. }
  124. void
  125. wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
  126. bool enable_dfs_scan)
  127. {
  128. struct wlan_scan_obj *scan_obj;
  129. scan_obj = wlan_psoc_get_scan_obj(psoc);
  130. if (!scan_obj)
  131. return;
  132. scan_obj->scan_def.allow_dfs_chan_in_scan = enable_dfs_scan;
  133. }
  134. bool wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc *psoc)
  135. {
  136. struct wlan_scan_obj *scan_obj;
  137. scan_obj = wlan_psoc_get_scan_obj(psoc);
  138. if (!scan_obj)
  139. return false;
  140. return scan_obj->scan_def.honour_nl_scan_policy_flags;
  141. }
  142. void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc,
  143. uint32_t *rest_time)
  144. {
  145. struct wlan_scan_obj *scan_obj;
  146. scan_obj = wlan_psoc_get_scan_obj(psoc);
  147. if (!scan_obj)
  148. return;
  149. *rest_time = scan_obj->scan_def.conc_max_rest_time;
  150. }
  151. void wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc *psoc,
  152. uint32_t *rest_time)
  153. {
  154. struct wlan_scan_obj *scan_obj;
  155. scan_obj = wlan_psoc_get_scan_obj(psoc);
  156. if (!scan_obj)
  157. return;
  158. *rest_time = scan_obj->scan_def.conc_min_rest_time;
  159. }
  160. bool wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc *psoc)
  161. {
  162. struct wlan_scan_obj *scan_obj;
  163. scan_obj = wlan_psoc_get_scan_obj(psoc);
  164. if (!scan_obj)
  165. return cfg_default(CFG_ENABLE_SNR_MONITORING);
  166. return scan_obj->scan_def.scan_f_chan_stat_evnt;
  167. }
  168. QDF_STATUS
  169. wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc,
  170. qdf_nbuf_t buf,
  171. struct mgmt_rx_event_params *rx_param,
  172. enum mgmt_frame_type frm_type)
  173. {
  174. struct scan_bcn_probe_event *bcn = NULL;
  175. QDF_STATUS status;
  176. if ((frm_type != MGMT_PROBE_RESP) &&
  177. (frm_type != MGMT_BEACON)) {
  178. scm_err("frame is not beacon or probe resp");
  179. status = QDF_STATUS_E_INVAL;
  180. goto free;
  181. }
  182. bcn = qdf_mem_malloc_atomic(sizeof(*bcn));
  183. if (!bcn) {
  184. status = QDF_STATUS_E_NOMEM;
  185. goto free;
  186. }
  187. bcn->rx_data =
  188. qdf_mem_malloc_atomic(sizeof(*rx_param));
  189. if (!bcn->rx_data) {
  190. status = QDF_STATUS_E_NOMEM;
  191. goto free;
  192. }
  193. if (frm_type == MGMT_PROBE_RESP)
  194. bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP;
  195. else
  196. bcn->frm_type = MGMT_SUBTYPE_BEACON;
  197. status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID);
  198. if (QDF_IS_STATUS_ERROR(status)) {
  199. scm_info("unable to get reference");
  200. goto free;
  201. }
  202. bcn->psoc = psoc;
  203. bcn->buf = buf;
  204. qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param));
  205. return __scm_handle_bcn_probe(bcn);
  206. free:
  207. if (bcn && bcn->rx_data)
  208. qdf_mem_free(bcn->rx_data);
  209. if (bcn)
  210. qdf_mem_free(bcn);
  211. if (buf)
  212. qdf_nbuf_free(buf);
  213. return status;
  214. }
  215. qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc)
  216. {
  217. struct wlan_scan_obj *scan_obj;
  218. scan_obj = wlan_psoc_get_scan_obj(psoc);
  219. if (!scan_obj)
  220. return cfg_default(CFG_SCAN_AGING_TIME) * 1000;
  221. return scan_obj->scan_def.scan_cache_aging_time;
  222. }
  223. QDF_STATUS wlan_scan_start(struct scan_start_request *req)
  224. {
  225. struct scheduler_msg msg = {0};
  226. QDF_STATUS status;
  227. if (!req || !req->vdev) {
  228. scm_err("req or vdev within req is NULL");
  229. if (req)
  230. scm_scan_free_scan_request_mem(req);
  231. return QDF_STATUS_E_NULL_VALUE;
  232. }
  233. if (!scm_is_scan_allowed(req->vdev)) {
  234. scm_err_rl("scan disabled, rejecting the scan req");
  235. scm_scan_free_scan_request_mem(req);
  236. return QDF_STATUS_E_AGAIN;
  237. }
  238. /*
  239. * Try to get vdev reference. Return if reference could
  240. * not be taken. Reference will be released once scan
  241. * request handling completes along with free of @req.
  242. */
  243. status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
  244. if (QDF_IS_STATUS_ERROR(status)) {
  245. scm_info("unable to get reference");
  246. scm_scan_free_scan_request_mem(req);
  247. return status;
  248. }
  249. msg.bodyptr = req;
  250. msg.callback = scm_scan_start_req;
  251. msg.flush_callback = scm_scan_start_flush_callback;
  252. status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
  253. QDF_MODULE_ID_SCAN,
  254. QDF_MODULE_ID_OS_IF, &msg);
  255. if (QDF_IS_STATUS_ERROR(status)) {
  256. wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
  257. scm_scan_free_scan_request_mem(req);
  258. }
  259. return status;
  260. }
  261. QDF_STATUS wlan_scan_cancel(struct scan_cancel_request *req)
  262. {
  263. struct scheduler_msg msg = {0};
  264. QDF_STATUS status;
  265. if (!req || !req->vdev) {
  266. scm_err("req or vdev within req is NULL");
  267. if (req)
  268. qdf_mem_free(req);
  269. return QDF_STATUS_E_NULL_VALUE;
  270. }
  271. status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID);
  272. if (QDF_IS_STATUS_ERROR(status)) {
  273. scm_info("Failed to get vdev ref; status:%d", status);
  274. goto req_free;
  275. }
  276. msg.bodyptr = req;
  277. msg.callback = scm_scan_cancel_req;
  278. msg.flush_callback = scm_scan_cancel_flush_callback;
  279. status = scheduler_post_message(QDF_MODULE_ID_OS_IF,
  280. QDF_MODULE_ID_SCAN,
  281. QDF_MODULE_ID_OS_IF, &msg);
  282. if (QDF_IS_STATUS_ERROR(status))
  283. goto vdev_put;
  284. return QDF_STATUS_SUCCESS;
  285. vdev_put:
  286. wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
  287. req_free:
  288. qdf_mem_free(req);
  289. return status;
  290. }