1 /* 2 * Copyright (c) 2017-2021 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 /** 20 * DOC: defines driver functions interfacing with linux kernel 21 */ 22 23 #include <qdf_list.h> 24 #include <qdf_status.h> 25 #include <qdf_module.h> 26 #include <linux/wireless.h> 27 #include <linux/netdevice.h> 28 #include <net/cfg80211.h> 29 #include <wlan_scan_utils_api.h> 30 #include <wlan_cfg80211.h> 31 #include <wlan_cfg80211_scan.h> 32 #include <wlan_osif_priv.h> 33 #include <wlan_scan_public_structs.h> 34 #include <wlan_scan_ucfg_api.h> 35 #include <wlan_cfg80211_scan.h> 36 #include <qdf_mem.h> 37 #include <wlan_utility.h> 38 #include "cfg_ucfg_api.h" 39 #ifdef WLAN_POLICY_MGR_ENABLE 40 #include <wlan_policy_mgr_api.h> 41 #endif 42 #include <wlan_reg_services_api.h> 43 #ifdef FEATURE_WLAN_DIAG_SUPPORT 44 #include "host_diag_core_event.h" 45 #endif 46 47 const struct nla_policy cfg80211_scan_policy[ 48 QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = { 49 [QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32}, 50 [QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG}, 51 [QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64}, 52 }; 53 54 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ 55 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 56 /** 57 * wlan_fill_scan_rand_attrs() - Populate the scan randomization attrs 58 * @vdev: pointer to objmgr vdev 59 * @flags: cfg80211 scan flags 60 * @mac_addr: random mac addr from cfg80211 61 * @mac_addr_mask: mac addr mask from cfg80211 62 * @randomize: output variable to check scan randomization status 63 * @addr: output variable to hold random addr 64 * @mask: output variable to hold mac mask 65 * 66 * Return: None 67 */ 68 static void wlan_fill_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, 69 uint32_t flags, 70 uint8_t *mac_addr, 71 uint8_t *mac_addr_mask, 72 bool *randomize, 73 uint8_t *addr, 74 uint8_t *mask) 75 { 76 *randomize = false; 77 if (!(flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) 78 return; 79 80 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 81 return; 82 83 if (wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS) 84 return; 85 86 *randomize = true; 87 memcpy(addr, mac_addr, QDF_MAC_ADDR_SIZE); 88 memcpy(mask, mac_addr_mask, QDF_MAC_ADDR_SIZE); 89 osif_debug("Random mac addr: "QDF_MAC_ADDR_FMT" and Random mac mask: "QDF_FULL_MAC_FMT, 90 QDF_MAC_ADDR_REF(addr), QDF_FULL_MAC_REF(mask)); 91 } 92 93 /** 94 * wlan_scan_rand_attrs() - Wrapper function to fill scan random attrs 95 * @vdev: pointer to objmgr vdev 96 * @request: pointer to cfg80211 scan request 97 * @req: pointer to cmn module scan request 98 * 99 * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() 100 * to fill random attributes of internal scan request with cfg80211_scan_request 101 * 102 * Return: None 103 */ 104 static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, 105 struct cfg80211_scan_request *request, 106 struct scan_start_request *req) 107 { 108 bool *randomize = &req->scan_req.scan_random.randomize; 109 uint8_t *mac_addr = req->scan_req.scan_random.mac_addr; 110 uint8_t *mac_mask = req->scan_req.scan_random.mac_mask; 111 112 wlan_fill_scan_rand_attrs(vdev, request->flags, request->mac_addr, 113 request->mac_addr_mask, randomize, mac_addr, 114 mac_mask); 115 if (!*randomize) 116 return; 117 118 req->scan_req.scan_f_add_spoofed_mac_in_probe = true; 119 req->scan_req.scan_f_add_rand_seq_in_probe = true; 120 } 121 #else 122 /** 123 * wlan_scan_rand_attrs() - Wrapper function to fill scan random attrs 124 * @vdev: pointer to objmgr vdev 125 * @request: pointer to cfg80211 scan request 126 * @req: pointer to cmn module scan request 127 * 128 * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() 129 * to fill random attributes of internal scan request with cfg80211_scan_request 130 * 131 * Return: None 132 */ 133 static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, 134 struct cfg80211_scan_request *request, 135 struct scan_start_request *req) 136 { 137 } 138 #endif 139 140 #ifdef FEATURE_WLAN_SCAN_PNO 141 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \ 142 defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) 143 144 /** 145 * wlan_config_sched_scan_plan() - configures the sched scan plans 146 * from the framework. 147 * @pno_req: pointer to PNO scan request 148 * @request: pointer to scan request from framework 149 * 150 * Return: None 151 */ 152 static void 153 wlan_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc, 154 struct pno_scan_req_params *pno_req, 155 struct cfg80211_sched_scan_request *request) 156 { 157 if (!ucfg_scan_get_user_config_sched_scan_plan(psoc) || 158 request->n_scan_plans == 1) { 159 pno_req->fast_scan_period = 160 request->scan_plans[0].interval * MSEC_PER_SEC; 161 /* 162 * if only one scan plan is configured from framework 163 * then both fast and slow scan should be configured with the 164 * same value that is why fast scan cycles are hardcoded to one 165 */ 166 pno_req->fast_scan_max_cycles = 1; 167 pno_req->slow_scan_period = 168 request->scan_plans[0].interval * MSEC_PER_SEC; 169 } 170 /* 171 * As of now max 2 scan plans were supported by firmware 172 * if number of scan plan supported by firmware increased below logic 173 * must change. 174 */ 175 else if (request->n_scan_plans == SCAN_PNO_MAX_PLAN_REQUEST) { 176 pno_req->fast_scan_period = 177 request->scan_plans[0].interval * MSEC_PER_SEC; 178 pno_req->fast_scan_max_cycles = 179 request->scan_plans[0].iterations; 180 pno_req->slow_scan_period = 181 request->scan_plans[1].interval * MSEC_PER_SEC; 182 } else { 183 osif_err("Invalid number of scan plans %d !!", 184 request->n_scan_plans); 185 } 186 } 187 #else 188 #define wlan_config_sched_scan_plan(psoc, pno_req, request) \ 189 __wlan_config_sched_scan_plan(pno_req, request, psoc) 190 191 static void 192 __wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req, 193 struct cfg80211_sched_scan_request *request, 194 struct wlan_objmgr_psoc *psoc) 195 { 196 uint32_t scan_timer_repeat_value, slow_scan_multiplier; 197 198 scan_timer_repeat_value = ucfg_scan_get_scan_timer_repeat_value(psoc); 199 slow_scan_multiplier = ucfg_scan_get_slow_scan_multiplier(psoc); 200 201 pno_req->fast_scan_period = request->interval; 202 pno_req->fast_scan_max_cycles = scan_timer_repeat_value; 203 pno_req->slow_scan_period = 204 (slow_scan_multiplier * pno_req->fast_scan_period); 205 } 206 #endif 207 208 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) 209 static inline void 210 wlan_cfg80211_sched_scan_results(struct wiphy *wiphy, uint64_t reqid) 211 { 212 cfg80211_sched_scan_results(wiphy); 213 } 214 #else 215 static inline void 216 wlan_cfg80211_sched_scan_results(struct wiphy *wiphy, uint64_t reqid) 217 { 218 cfg80211_sched_scan_results(wiphy, reqid); 219 } 220 #endif 221 222 /** 223 * wlan_cfg80211_pno_callback() - pno callback function to handle 224 * pno events. 225 * @vdev: vdev ptr 226 * @event: scan events 227 * @args: argument 228 * 229 * Return: void 230 */ 231 static void wlan_cfg80211_pno_callback(struct wlan_objmgr_vdev *vdev, 232 struct scan_event *event, 233 void *args) 234 { 235 struct wlan_objmgr_pdev *pdev; 236 struct pdev_osif_priv *pdev_ospriv; 237 238 if (event->type != SCAN_EVENT_TYPE_NLO_COMPLETE) 239 return; 240 241 osif_debug("vdev id = %d", event->vdev_id); 242 243 pdev = wlan_vdev_get_pdev(vdev); 244 if (!pdev) { 245 osif_err("pdev is NULL"); 246 return; 247 } 248 249 pdev_ospriv = wlan_pdev_get_ospriv(pdev); 250 if (!pdev_ospriv) { 251 osif_err("pdev_ospriv is NULL"); 252 return; 253 } 254 wlan_cfg80211_sched_scan_results(pdev_ospriv->wiphy, 0); 255 } 256 257 #ifdef WLAN_POLICY_MGR_ENABLE 258 static bool wlan_cfg80211_is_ap_go_present(struct wlan_objmgr_psoc *psoc) 259 { 260 return policy_mgr_mode_specific_connection_count(psoc, 261 PM_SAP_MODE, 262 NULL) || 263 policy_mgr_mode_specific_connection_count(psoc, 264 PM_P2P_GO_MODE, 265 NULL); 266 } 267 268 static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs( 269 struct wlan_objmgr_psoc *psoc, 270 u16 chan_freq, bool *ok) 271 { 272 QDF_STATUS status = policy_mgr_is_chan_ok_for_dnbs( 273 psoc, chan_freq, ok); 274 275 if (QDF_IS_STATUS_ERROR(status)) { 276 osif_err("DNBS check failed"); 277 return status; 278 } 279 280 return QDF_STATUS_SUCCESS; 281 } 282 #else 283 static bool wlan_cfg80211_is_ap_go_present(struct wlan_objmgr_psoc *psoc) 284 { 285 return false; 286 } 287 288 static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs( 289 struct wlan_objmgr_psoc *psoc, 290 u16 chan_freq, 291 bool *ok) 292 { 293 if (!ok) 294 return QDF_STATUS_E_INVAL; 295 296 *ok = true; 297 return QDF_STATUS_SUCCESS; 298 } 299 #endif 300 301 #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ 302 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 303 /** 304 * wlan_pno_scan_rand_attr() - Wrapper function to fill sched scan random attrs 305 * @vdev: pointer to objmgr vdev 306 * @request: pointer to cfg80211 sched scan request 307 * @req: pointer to cmn module pno scan request 308 * 309 * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() 310 * to fill random attributes of internal pno scan 311 * with cfg80211_sched_scan_request 312 * 313 * Return: None 314 */ 315 static void wlan_pno_scan_rand_attr(struct wlan_objmgr_vdev *vdev, 316 struct cfg80211_sched_scan_request *request, 317 struct pno_scan_req_params *req) 318 { 319 bool *randomize = &req->scan_random.randomize; 320 uint8_t *mac_addr = req->scan_random.mac_addr; 321 uint8_t *mac_mask = req->scan_random.mac_mask; 322 323 wlan_fill_scan_rand_attrs(vdev, request->flags, request->mac_addr, 324 request->mac_addr_mask, randomize, mac_addr, 325 mac_mask); 326 } 327 #else 328 /** 329 * wlan_pno_scan_rand_attr() - Wrapper function to fill sched scan random attrs 330 * @vdev: pointer to objmgr vdev 331 * @request: pointer to cfg80211 sched scan request 332 * @req: pointer to cmn module pno scan request 333 * 334 * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() 335 * to fill random attributes of internal pno scan 336 * with cfg80211_sched_scan_request 337 * 338 * Return: None 339 */ 340 static void wlan_pno_scan_rand_attr(struct wlan_objmgr_vdev *vdev, 341 struct cfg80211_sched_scan_request *request, 342 struct pno_scan_req_params *req) 343 { 344 } 345 #endif 346 347 /** 348 * wlan_hdd_sched_scan_update_relative_rssi() - update CPNO params 349 * @pno_request: pointer to PNO scan request 350 * @request: Pointer to cfg80211 scheduled scan start request 351 * 352 * This function is used to update Connected PNO params sent by kernel 353 * 354 * Return: None 355 */ 356 #if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN) || \ 357 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) 358 static inline void wlan_hdd_sched_scan_update_relative_rssi( 359 struct pno_scan_req_params *pno_request, 360 struct cfg80211_sched_scan_request *request) 361 { 362 pno_request->relative_rssi_set = request->relative_rssi_set; 363 pno_request->relative_rssi = request->relative_rssi; 364 if (NL80211_BAND_2GHZ == request->rssi_adjust.band) 365 pno_request->band_rssi_pref.band = WLAN_BAND_2_4_GHZ; 366 else if (NL80211_BAND_5GHZ == request->rssi_adjust.band) 367 pno_request->band_rssi_pref.band = WLAN_BAND_5_GHZ; 368 pno_request->band_rssi_pref.rssi = request->rssi_adjust.delta; 369 } 370 #else 371 static inline void wlan_hdd_sched_scan_update_relative_rssi( 372 struct pno_scan_req_params *pno_request, 373 struct cfg80211_sched_scan_request *request) 374 { 375 } 376 #endif 377 378 #ifdef FEATURE_WLAN_SCAN_PNO 379 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 380 static uint32_t wlan_config_sched_scan_start_delay( 381 struct cfg80211_sched_scan_request *request) 382 { 383 return request->delay; 384 } 385 #else 386 static uint32_t wlan_config_sched_scan_start_delay( 387 struct cfg80211_sched_scan_request *request) 388 { 389 return 0; 390 } 391 #endif /*(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) */ 392 #endif /* FEATURE_WLAN_SCAN_PNO */ 393 394 int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, 395 struct cfg80211_sched_scan_request *request, 396 uint8_t scan_backoff_multiplier) 397 { 398 struct pno_scan_req_params *req; 399 int i, j, ret = 0; 400 QDF_STATUS status; 401 uint8_t num_chan = 0; 402 uint16_t chan_freq; 403 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 404 struct wlan_objmgr_psoc *psoc; 405 uint32_t valid_ch[SCAN_PNO_MAX_NETW_CHANNELS_EX] = {0}; 406 bool enable_dfs_pno_chnl_scan; 407 408 if (ucfg_scan_get_pno_in_progress(vdev)) { 409 osif_debug("pno is already in progress"); 410 return -EBUSY; 411 } 412 413 if (ucfg_scan_get_pdev_status(pdev) != 414 SCAN_NOT_IN_PROGRESS) { 415 status = wlan_abort_scan(pdev, 416 wlan_objmgr_pdev_get_pdev_id(pdev), 417 INVAL_VDEV_ID, INVAL_SCAN_ID, true); 418 if (QDF_IS_STATUS_ERROR(status)) 419 return -EBUSY; 420 } 421 422 req = qdf_mem_malloc(sizeof(*req)); 423 if (!req) 424 return -ENOMEM; 425 426 wlan_pdev_obj_lock(pdev); 427 psoc = wlan_pdev_get_psoc(pdev); 428 wlan_pdev_obj_unlock(pdev); 429 430 req->networks_cnt = request->n_match_sets; 431 req->vdev_id = wlan_vdev_get_id(vdev); 432 433 if ((!req->networks_cnt) || 434 (req->networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) { 435 osif_err("Network input is not correct %d", 436 req->networks_cnt); 437 ret = -EINVAL; 438 goto error; 439 } 440 441 if (request->n_channels > SCAN_PNO_MAX_NETW_CHANNELS_EX) { 442 osif_err("Incorrect number of channels %d", 443 request->n_channels); 444 ret = -EINVAL; 445 goto error; 446 } 447 448 enable_dfs_pno_chnl_scan = ucfg_scan_is_dfs_chnl_scan_enabled(psoc); 449 if (request->n_channels) { 450 uint32_t buff_len; 451 char *chl; 452 int len = 0; 453 bool ap_or_go_present = wlan_cfg80211_is_ap_go_present(psoc); 454 455 buff_len = (request->n_channels * 5) + 1; 456 chl = qdf_mem_malloc(buff_len); 457 if (!chl) { 458 ret = -ENOMEM; 459 goto error; 460 } 461 for (i = 0; i < request->n_channels; i++) { 462 chan_freq = request->channels[i]->center_freq; 463 if ((!enable_dfs_pno_chnl_scan) && 464 (wlan_reg_is_dfs_for_freq(pdev, chan_freq))) { 465 osif_debug("Dropping DFS channel freq :%d", 466 chan_freq); 467 continue; 468 } 469 if (wlan_reg_is_dsrc_freq(chan_freq)) 470 continue; 471 472 if (ap_or_go_present) { 473 bool ok; 474 475 status = 476 wlan_cfg80211_is_chan_ok_for_dnbs(psoc, 477 chan_freq, 478 &ok); 479 if (QDF_IS_STATUS_ERROR(status)) { 480 osif_err("DNBS check failed"); 481 qdf_mem_free(chl); 482 chl = NULL; 483 ret = -EINVAL; 484 goto error; 485 } 486 if (!ok) 487 continue; 488 } 489 len += qdf_scnprintf(chl + len, buff_len - len, " %d", chan_freq); 490 valid_ch[num_chan++] = chan_freq; 491 } 492 osif_debug("Channel-List[%d]:%s", num_chan, chl); 493 qdf_mem_free(chl); 494 chl = NULL; 495 /* If all channels are DFS and dropped, 496 * then ignore the PNO request 497 */ 498 if (!num_chan) { 499 osif_notice("Channel list empty due to filtering of DSRC"); 500 ret = -EINVAL; 501 goto error; 502 } 503 } 504 505 /* Filling per profile params */ 506 for (i = 0; i < req->networks_cnt; i++) { 507 req->networks_list[i].ssid.length = 508 request->match_sets[i].ssid.ssid_len; 509 510 if ((!req->networks_list[i].ssid.length) || 511 (req->networks_list[i].ssid.length > WLAN_SSID_MAX_LEN)) { 512 osif_err(" SSID Len %d is not correct for network %d", 513 req->networks_list[i].ssid.length, i); 514 ret = -EINVAL; 515 goto error; 516 } 517 518 qdf_mem_copy(req->networks_list[i].ssid.ssid, 519 request->match_sets[i].ssid.ssid, 520 req->networks_list[i].ssid.length); 521 req->networks_list[i].authentication = 0; /*eAUTH_TYPE_ANY */ 522 req->networks_list[i].encryption = 0; /*eED_ANY */ 523 req->networks_list[i].bc_new_type = 0; /*eBCAST_UNKNOWN */ 524 525 /*Copying list of valid channel into request */ 526 qdf_mem_copy(req->networks_list[i].channels, valid_ch, 527 num_chan * sizeof(uint32_t)); 528 req->networks_list[i].channel_cnt = num_chan; 529 req->networks_list[i].rssi_thresh = 530 request->match_sets[i].rssi_thold; 531 } 532 533 /* set scan to passive if no SSIDs are specified in the request */ 534 if (0 == request->n_ssids) 535 req->do_passive_scan = true; 536 else 537 req->do_passive_scan = false; 538 539 for (i = 0; i < request->n_ssids; i++) { 540 j = 0; 541 while (j < req->networks_cnt) { 542 if ((req->networks_list[j].ssid.length == 543 request->ssids[i].ssid_len) && 544 (!qdf_mem_cmp(req->networks_list[j].ssid.ssid, 545 request->ssids[i].ssid, 546 req->networks_list[j].ssid.length))) { 547 req->networks_list[j].bc_new_type = 548 SSID_BC_TYPE_HIDDEN; 549 break; 550 } 551 j++; 552 } 553 } 554 555 /* 556 * Before Kernel 4.4 557 * Driver gets only one time interval which is hard coded in 558 * supplicant for 10000ms. 559 * 560 * After Kernel 4.4 561 * User can configure multiple scan_plans, each scan would have 562 * separate scan cycle and interval. (interval is in unit of second.) 563 * For our use case, we would only have supplicant set one scan_plan, 564 * and firmware also support only one as well, so pick up the first 565 * index. 566 * 567 * Taking power consumption into account 568 * firmware after gPNOScanTimerRepeatValue times fast_scan_period 569 * switches slow_scan_period. This is less frequent scans and firmware 570 * shall be in slow_scan_period mode until next PNO Start. 571 */ 572 wlan_config_sched_scan_plan(psoc, req, request); 573 req->delay_start_time = wlan_config_sched_scan_start_delay(request); 574 req->scan_backoff_multiplier = scan_backoff_multiplier; 575 576 wlan_hdd_sched_scan_update_relative_rssi(req, request); 577 578 psoc = wlan_pdev_get_psoc(pdev); 579 ucfg_scan_register_pno_cb(psoc, 580 wlan_cfg80211_pno_callback, NULL); 581 ucfg_scan_get_pno_def_params(vdev, req); 582 583 if (req->scan_random.randomize) 584 wlan_pno_scan_rand_attr(vdev, request, req); 585 586 if (ucfg_ie_whitelist_enabled(psoc, vdev)) 587 ucfg_copy_ie_whitelist_attrs(psoc, &req->ie_whitelist); 588 589 osif_debug("Network count %d n_ssids %d fast_scan_period: %d msec slow_scan_period: %d msec, fast_scan_max_cycles: %d, relative_rssi %d band_pref %d, rssi_pref %d", 590 req->networks_cnt, request->n_ssids, req->fast_scan_period, 591 req->slow_scan_period, req->fast_scan_max_cycles, 592 req->relative_rssi, req->band_rssi_pref.band, 593 req->band_rssi_pref.rssi); 594 595 for (i = 0; i < req->networks_cnt; i++) 596 osif_debug("[%d] ssid: %.*s, RSSI th %d bc NW type %u", 597 i, req->networks_list[i].ssid.length, 598 req->networks_list[i].ssid.ssid, 599 req->networks_list[i].rssi_thresh, 600 req->networks_list[i].bc_new_type); 601 602 status = ucfg_scan_pno_start(vdev, req); 603 if (QDF_IS_STATUS_ERROR(status)) { 604 osif_err("Failed to enable PNO"); 605 ret = -EINVAL; 606 goto error; 607 } 608 609 error: 610 qdf_mem_free(req); 611 return ret; 612 } 613 614 int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_vdev *vdev) 615 { 616 QDF_STATUS status; 617 618 status = ucfg_scan_pno_stop(vdev); 619 if (QDF_IS_STATUS_ERROR(status)) 620 osif_debug("Failed to disable PNO"); 621 622 return 0; 623 } 624 #endif /*FEATURE_WLAN_SCAN_PNO */ 625 626 /** 627 * wlan_copy_bssid_scan_request() - API to copy the bssid to Scan request 628 * @scan_req: Pointer to scan_start_request 629 * @request: scan request from Supplicant 630 * 631 * This API copies the BSSID in scan request from Supplicant and copies it to 632 * the scan_start_request 633 * 634 * Return: None 635 */ 636 #if defined(CFG80211_SCAN_BSSID) || \ 637 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) 638 static inline void 639 wlan_copy_bssid_scan_request(struct scan_start_request *scan_req, 640 struct cfg80211_scan_request *request) 641 { 642 qdf_mem_copy(scan_req->scan_req.bssid_list[0].bytes, 643 request->bssid, QDF_MAC_ADDR_SIZE); 644 } 645 #else 646 static inline void 647 wlan_copy_bssid_scan_request(struct scan_start_request *scan_req, 648 struct cfg80211_scan_request *request) 649 { 650 651 } 652 #endif 653 654 /** 655 * wlan_schedule_scan_start_request() - Schedule scan start request 656 * @pdev: pointer to pdev object 657 * @req: Pointer to the scan request 658 * @source: source of the scan request 659 * @scan_start_req: pointer to scan start request 660 * 661 * Schedule scan start request and enqueue scan request in the global scan 662 * list. This list stores the active scan request information. 663 * 664 * Return: QDF_STATUS 665 */ 666 static QDF_STATUS 667 wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev, 668 struct cfg80211_scan_request *req, 669 uint8_t source, 670 struct scan_start_request *scan_start_req) 671 { 672 struct scan_req *scan_req; 673 QDF_STATUS status; 674 struct pdev_osif_priv *osif_ctx; 675 struct osif_scan_pdev *osif_scan; 676 677 scan_req = qdf_mem_malloc(sizeof(*scan_req)); 678 if (!scan_req) { 679 ucfg_scm_scan_free_scan_request_mem(scan_start_req); 680 return QDF_STATUS_E_NOMEM; 681 } 682 683 /* Get NL global context from objmgr*/ 684 osif_ctx = wlan_pdev_get_ospriv(pdev); 685 osif_scan = osif_ctx->osif_scan; 686 scan_req->scan_request = req; 687 scan_req->source = source; 688 scan_req->scan_id = scan_start_req->scan_req.scan_id; 689 scan_req->dev = req->wdev->netdev; 690 scan_req->scan_start_timestamp = qdf_get_time_of_the_day_ms(); 691 692 qdf_mutex_acquire(&osif_scan->scan_req_q_lock); 693 if (qdf_list_size(&osif_scan->scan_req_q) < WLAN_MAX_SCAN_COUNT) { 694 status = ucfg_scan_start(scan_start_req); 695 if (QDF_IS_STATUS_SUCCESS(status)) { 696 qdf_list_insert_back(&osif_scan->scan_req_q, 697 &scan_req->node); 698 } else { 699 osif_err("scan req failed with error %d", status); 700 if (status == QDF_STATUS_E_RESOURCES) 701 osif_err("HO is in progress.So defer the scan by informing busy"); 702 } 703 } else { 704 ucfg_scm_scan_free_scan_request_mem(scan_start_req); 705 status = QDF_STATUS_E_RESOURCES; 706 } 707 708 qdf_mutex_release(&osif_scan->scan_req_q_lock); 709 if (QDF_IS_STATUS_ERROR(status)) { 710 osif_rl_debug("Failed to enqueue Scan Req as max scan %d already queued", 711 qdf_list_size(&osif_scan->scan_req_q)); 712 qdf_mem_free(scan_req); 713 } 714 715 return status; 716 } 717 718 /** 719 * wlan_scan_request_dequeue() - dequeue scan request 720 * @nl_ctx: Global HDD context 721 * @scan_id: scan id 722 * @req: scan request 723 * @dev: net device 724 * @source : returns source of the scan request 725 * 726 * Return: QDF_STATUS 727 */ 728 static QDF_STATUS wlan_scan_request_dequeue( 729 struct wlan_objmgr_pdev *pdev, 730 uint32_t scan_id, struct cfg80211_scan_request **req, 731 uint8_t *source, struct net_device **dev, 732 qdf_time_t *scan_start_timestamp) 733 { 734 QDF_STATUS status = QDF_STATUS_E_FAILURE; 735 struct scan_req *scan_req; 736 qdf_list_node_t *node = NULL, *next_node = NULL; 737 struct pdev_osif_priv *osif_ctx; 738 struct osif_scan_pdev *scan_priv; 739 740 if ((!source) || (!req)) { 741 osif_err("source or request is NULL"); 742 return QDF_STATUS_E_NULL_VALUE; 743 } 744 745 /* Get NL global context from objmgr*/ 746 osif_ctx = wlan_pdev_get_ospriv(pdev); 747 if (!osif_ctx) { 748 osif_err("Failed to retrieve osif context"); 749 return status; 750 } 751 scan_priv = osif_ctx->osif_scan; 752 753 qdf_mutex_acquire(&scan_priv->scan_req_q_lock); 754 if (qdf_list_empty(&scan_priv->scan_req_q)) { 755 osif_info("Scan List is empty"); 756 qdf_mutex_release(&scan_priv->scan_req_q_lock); 757 return QDF_STATUS_E_FAILURE; 758 } 759 760 if (QDF_STATUS_SUCCESS != 761 qdf_list_peek_front(&scan_priv->scan_req_q, &next_node)) { 762 qdf_mutex_release(&scan_priv->scan_req_q_lock); 763 osif_err("Failed to remove Scan Req from queue"); 764 return QDF_STATUS_E_FAILURE; 765 } 766 767 do { 768 node = next_node; 769 scan_req = qdf_container_of(node, struct scan_req, node); 770 if (scan_req->scan_id == scan_id) { 771 status = qdf_list_remove_node(&scan_priv->scan_req_q, 772 node); 773 if (status == QDF_STATUS_SUCCESS) { 774 *req = scan_req->scan_request; 775 *source = scan_req->source; 776 *dev = scan_req->dev; 777 *scan_start_timestamp = 778 scan_req->scan_start_timestamp; 779 qdf_mem_free(scan_req); 780 qdf_mutex_release(&scan_priv->scan_req_q_lock); 781 osif_debug("removed Scan id: %d, req = %pK, pending scans %d", 782 scan_id, req, 783 qdf_list_size(&scan_priv->scan_req_q)); 784 return QDF_STATUS_SUCCESS; 785 } else { 786 qdf_mutex_release(&scan_priv->scan_req_q_lock); 787 osif_err("Failed to remove scan id %d, pending scans %d", 788 scan_id, 789 qdf_list_size(&scan_priv->scan_req_q)); 790 return status; 791 } 792 } 793 } while (QDF_STATUS_SUCCESS == 794 qdf_list_peek_next(&scan_priv->scan_req_q, node, &next_node)); 795 qdf_mutex_release(&scan_priv->scan_req_q_lock); 796 osif_debug("Failed to find scan id %d", scan_id); 797 798 return status; 799 } 800 801 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) 802 /** 803 * wlan_cfg80211_scan_done() - Scan completed callback to cfg80211 804 * @netdev: Net device 805 * @req : Scan request 806 * @aborted : true scan aborted false scan success 807 * 808 * This function notifies scan done to cfg80211 809 * 810 * Return: none 811 */ 812 void wlan_cfg80211_scan_done(struct net_device *netdev, 813 struct cfg80211_scan_request *req, 814 bool aborted) 815 { 816 struct cfg80211_scan_info info = { 817 .aborted = aborted 818 }; 819 820 if (netdev->flags & IFF_UP) 821 cfg80211_scan_done(req, &info); 822 } 823 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) 824 /** 825 * wlan_cfg80211_scan_done() - Scan completed callback to cfg80211 826 * @netdev: Net device 827 * @req : Scan request 828 * @aborted : true scan aborted false scan success 829 * 830 * This function notifies scan done to cfg80211 831 * 832 * Return: none 833 */ 834 void wlan_cfg80211_scan_done(struct net_device *netdev, 835 struct cfg80211_scan_request *req, 836 bool aborted) 837 { 838 if (netdev->flags & IFF_UP) 839 cfg80211_scan_done(req, aborted); 840 } 841 #endif 842 843 /** 844 * wlan_vendor_scan_callback() - Scan completed callback event 845 * 846 * @req : Scan request 847 * @aborted : true scan aborted false scan success 848 * 849 * This function sends scan completed callback event to NL. 850 * 851 * Return: none 852 */ 853 static void wlan_vendor_scan_callback(struct cfg80211_scan_request *req, 854 bool aborted) 855 { 856 struct sk_buff *skb; 857 struct nlattr *attr; 858 int i; 859 uint8_t scan_status; 860 uint64_t cookie; 861 int index = QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX; 862 863 skb = wlan_cfg80211_vendor_event_alloc(req->wdev->wiphy, req->wdev, 864 SCAN_DONE_EVENT_BUF_SIZE + 4 + 865 NLMSG_HDRLEN, 866 index, 867 GFP_ATOMIC); 868 869 if (!skb) { 870 osif_err("skb alloc failed"); 871 qdf_mem_free(req); 872 return; 873 } 874 875 cookie = (uintptr_t)req; 876 877 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS); 878 if (!attr) 879 goto nla_put_failure; 880 for (i = 0; i < req->n_ssids; i++) { 881 if (nla_put(skb, i, req->ssids[i].ssid_len, req->ssids[i].ssid)) 882 goto nla_put_failure; 883 } 884 nla_nest_end(skb, attr); 885 886 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES); 887 if (!attr) 888 goto nla_put_failure; 889 for (i = 0; i < req->n_channels; i++) { 890 if (nla_put_u32(skb, i, req->channels[i]->center_freq)) 891 goto nla_put_failure; 892 } 893 nla_nest_end(skb, attr); 894 895 if (req->ie && 896 nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len, 897 req->ie)) 898 goto nla_put_failure; 899 900 if (req->flags && 901 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags)) 902 goto nla_put_failure; 903 904 if (wlan_cfg80211_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE, 905 cookie)) 906 goto nla_put_failure; 907 908 scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED : 909 VENDOR_SCAN_STATUS_NEW_RESULTS; 910 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) 911 goto nla_put_failure; 912 913 wlan_cfg80211_vendor_event(skb, GFP_ATOMIC); 914 qdf_mem_free(req); 915 916 return; 917 918 nla_put_failure: 919 wlan_cfg80211_vendor_free_skb(skb); 920 qdf_mem_free(req); 921 } 922 923 /** 924 * wlan_scan_acquire_wake_lock_timeout() - acquire scan wake lock 925 * @psoc: psoc ptr 926 * @scan_wake_lock: Scan wake lock 927 * @timeout: timeout in ms 928 * 929 * Return: void 930 */ 931 static inline 932 void wlan_scan_acquire_wake_lock_timeout(struct wlan_objmgr_psoc *psoc, 933 qdf_wake_lock_t *scan_wake_lock, 934 uint32_t timeout) 935 { 936 if (!psoc || !scan_wake_lock) 937 return; 938 939 if (ucfg_scan_wake_lock_in_user_scan(psoc)) 940 qdf_wake_lock_timeout_acquire(scan_wake_lock, timeout); 941 } 942 943 944 /** 945 * wlan_scan_release_wake_lock() - release scan wake lock 946 * @psoc: psoc ptr 947 * @scan_wake_lock: Scan wake lock 948 * 949 * Return: void 950 */ 951 #ifdef FEATURE_WLAN_DIAG_SUPPORT 952 static inline 953 void wlan_scan_release_wake_lock(struct wlan_objmgr_psoc *psoc, 954 qdf_wake_lock_t *scan_wake_lock) 955 { 956 if (!psoc || !scan_wake_lock) 957 return; 958 959 if (ucfg_scan_wake_lock_in_user_scan(psoc)) 960 qdf_wake_lock_release(scan_wake_lock, 961 WIFI_POWER_EVENT_WAKELOCK_SCAN); 962 } 963 #else 964 static inline 965 void wlan_scan_release_wake_lock(struct wlan_objmgr_psoc *psoc, 966 qdf_wake_lock_t *scan_wake_lock) 967 { 968 if (!psoc || !scan_wake_lock) 969 return; 970 971 if (ucfg_scan_wake_lock_in_user_scan(psoc)) 972 qdf_wake_lock_release(scan_wake_lock, 0); 973 } 974 #endif 975 976 static 977 uint32_t wlan_scan_get_bss_count_for_scan(struct wlan_objmgr_pdev *pdev, 978 qdf_time_t scan_start_ts) 979 { 980 struct scan_filter *filter; 981 qdf_list_t *list = NULL; 982 uint32_t count = 0; 983 984 if (!scan_start_ts) 985 return count; 986 987 filter = qdf_mem_malloc(sizeof(*filter)); 988 if (!filter) 989 return count; 990 991 filter->ignore_auth_enc_type = true; 992 filter->age_threshold = qdf_get_time_of_the_day_ms() - scan_start_ts; 993 994 list = ucfg_scan_get_result(pdev, filter); 995 996 qdf_mem_free(filter); 997 998 if (list) { 999 count = qdf_list_size(list); 1000 ucfg_scan_purge_results(list); 1001 } 1002 1003 return count; 1004 } 1005 1006 /** 1007 * wlan_cfg80211_scan_done_callback() - scan done callback function called after 1008 * scan is finished 1009 * @vdev: vdev ptr 1010 * @event: Scan event 1011 * @args: Scan cb arg 1012 * 1013 * Return: void 1014 */ 1015 static void wlan_cfg80211_scan_done_callback( 1016 struct wlan_objmgr_vdev *vdev, 1017 struct scan_event *event, 1018 void *args) 1019 { 1020 struct cfg80211_scan_request *req = NULL; 1021 bool success = false; 1022 uint32_t scan_id; 1023 uint8_t source = NL_SCAN; 1024 struct wlan_objmgr_pdev *pdev; 1025 struct pdev_osif_priv *osif_priv; 1026 struct net_device *netdev = NULL; 1027 QDF_STATUS status; 1028 qdf_time_t scan_start_timestamp = 0; 1029 uint32_t unique_bss_count = 0; 1030 1031 if (!event) { 1032 osif_nofl_err("Invalid scan event received"); 1033 return; 1034 } 1035 1036 scan_id = event->scan_id; 1037 1038 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_OS_IF, event->type, 1039 event->vdev_id, scan_id); 1040 1041 if (event->type == SCAN_EVENT_TYPE_STARTED) 1042 osif_nofl_info("scan start scan id %d", scan_id); 1043 1044 if (!util_is_scan_completed(event, &success)) 1045 return; 1046 1047 pdev = wlan_vdev_get_pdev(vdev); 1048 status = wlan_scan_request_dequeue( 1049 pdev, scan_id, &req, &source, &netdev, 1050 &scan_start_timestamp); 1051 if (QDF_IS_STATUS_ERROR(status)) { 1052 osif_err("Dequeue of scan request failed ID: %d", scan_id); 1053 goto allow_suspend; 1054 } 1055 1056 if (!netdev) { 1057 osif_err("net dev is NULL,Drop scan event Id: %d", scan_id); 1058 goto allow_suspend; 1059 } 1060 1061 /* Make sure vdev is active */ 1062 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID); 1063 if (QDF_IS_STATUS_ERROR(status)) { 1064 osif_err("Failed to get vdev reference: scan Id: %d", scan_id); 1065 goto allow_suspend; 1066 } 1067 1068 /* 1069 * Scan can be triggred from NL or vendor scan 1070 * - If scan is triggered from NL then cfg80211 scan done should be 1071 * called to updated scan completion to NL. 1072 * - If scan is triggred through vendor command then 1073 * scan done event will be posted 1074 */ 1075 if (NL_SCAN == source) 1076 wlan_cfg80211_scan_done(netdev, req, !success); 1077 else 1078 wlan_vendor_scan_callback(req, !success); 1079 1080 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 1081 1082 unique_bss_count = wlan_scan_get_bss_count_for_scan(pdev, 1083 scan_start_timestamp); 1084 osif_nofl_info("vdev %d, scan id %d type %s(%d) reason %s(%d) scan found %d bss", 1085 event->vdev_id, scan_id, 1086 util_scan_get_ev_type_name(event->type), event->type, 1087 util_scan_get_ev_reason_name(event->reason), 1088 event->reason, unique_bss_count); 1089 allow_suspend: 1090 osif_priv = wlan_pdev_get_ospriv(pdev); 1091 qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock); 1092 if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) { 1093 struct wlan_objmgr_psoc *psoc; 1094 1095 qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); 1096 qdf_runtime_pm_allow_suspend( 1097 &osif_priv->osif_scan->runtime_pm_lock); 1098 1099 psoc = wlan_pdev_get_psoc(pdev); 1100 wlan_scan_release_wake_lock(psoc, 1101 &osif_priv->osif_scan->scan_wake_lock); 1102 /* 1103 * Acquire wakelock to handle the case where APP's tries 1104 * to suspend immediately after the driver gets connect 1105 * request(i.e after scan) from supplicant, this result in 1106 * app's is suspending and not able to process the connect 1107 * request to AP 1108 */ 1109 wlan_scan_acquire_wake_lock_timeout(psoc, 1110 &osif_priv->osif_scan->scan_wake_lock, 1111 SCAN_WAKE_LOCK_CONNECT_DURATION); 1112 } else { 1113 qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); 1114 } 1115 1116 } 1117 1118 QDF_STATUS wlan_scan_runtime_pm_init(struct wlan_objmgr_pdev *pdev) 1119 { 1120 struct pdev_osif_priv *osif_priv; 1121 struct osif_scan_pdev *scan_priv; 1122 1123 wlan_pdev_obj_lock(pdev); 1124 osif_priv = wlan_pdev_get_ospriv(pdev); 1125 wlan_pdev_obj_unlock(pdev); 1126 1127 scan_priv = osif_priv->osif_scan; 1128 1129 return qdf_runtime_lock_init(&scan_priv->runtime_pm_lock); 1130 } 1131 1132 void wlan_scan_runtime_pm_deinit(struct wlan_objmgr_pdev *pdev) 1133 { 1134 struct pdev_osif_priv *osif_priv; 1135 struct osif_scan_pdev *scan_priv; 1136 1137 wlan_pdev_obj_lock(pdev); 1138 osif_priv = wlan_pdev_get_ospriv(pdev); 1139 wlan_pdev_obj_unlock(pdev); 1140 1141 scan_priv = osif_priv->osif_scan; 1142 qdf_runtime_lock_deinit(&scan_priv->runtime_pm_lock); 1143 } 1144 1145 QDF_STATUS wlan_cfg80211_scan_priv_init(struct wlan_objmgr_pdev *pdev) 1146 { 1147 struct pdev_osif_priv *osif_priv; 1148 struct osif_scan_pdev *scan_priv; 1149 struct wlan_objmgr_psoc *psoc; 1150 wlan_scan_requester req_id; 1151 1152 psoc = wlan_pdev_get_psoc(pdev); 1153 1154 req_id = ucfg_scan_register_requester(psoc, "CFG", 1155 wlan_cfg80211_scan_done_callback, NULL); 1156 1157 osif_priv = wlan_pdev_get_ospriv(pdev); 1158 scan_priv = qdf_mem_malloc(sizeof(*scan_priv)); 1159 if (!scan_priv) 1160 return QDF_STATUS_E_NOMEM; 1161 1162 /* Initialize the scan request queue */ 1163 osif_priv->osif_scan = scan_priv; 1164 scan_priv->req_id = req_id; 1165 qdf_list_create(&scan_priv->scan_req_q, WLAN_MAX_SCAN_COUNT); 1166 qdf_mutex_create(&scan_priv->scan_req_q_lock); 1167 qdf_wake_lock_create(&scan_priv->scan_wake_lock, "scan_wake_lock"); 1168 1169 return QDF_STATUS_SUCCESS; 1170 } 1171 1172 QDF_STATUS wlan_cfg80211_scan_priv_deinit(struct wlan_objmgr_pdev *pdev) 1173 { 1174 struct pdev_osif_priv *osif_priv; 1175 struct osif_scan_pdev *scan_priv; 1176 struct wlan_objmgr_psoc *psoc; 1177 1178 psoc = wlan_pdev_get_psoc(pdev); 1179 osif_priv = wlan_pdev_get_ospriv(pdev); 1180 1181 wlan_cfg80211_cleanup_scan_queue(pdev, NULL); 1182 scan_priv = osif_priv->osif_scan; 1183 qdf_wake_lock_destroy(&scan_priv->scan_wake_lock); 1184 qdf_mutex_destroy(&scan_priv->scan_req_q_lock); 1185 qdf_list_destroy(&scan_priv->scan_req_q); 1186 ucfg_scan_unregister_requester(psoc, scan_priv->req_id); 1187 osif_priv->osif_scan = NULL; 1188 qdf_mem_free(scan_priv); 1189 1190 return QDF_STATUS_SUCCESS; 1191 } 1192 1193 /** 1194 * wlan_cfg80211_enqueue_for_cleanup() - Function to populate scan cleanup queue 1195 * @scan_cleanup_q: Scan cleanup queue to be populated 1196 * @scan_priv: Pointer to scan related data used by cfg80211 scan 1197 * @dev: Netdevice pointer 1198 * 1199 * The function synchrounously iterates through the global scan queue to 1200 * identify entries that have to be cleaned up, copies identified entries 1201 * to another queue(to send scan complete event to NL later) and removes the 1202 * entry from the global scan queue. 1203 * 1204 * Return: None 1205 */ 1206 static void 1207 wlan_cfg80211_enqueue_for_cleanup(qdf_list_t *scan_cleanup_q, 1208 struct osif_scan_pdev *scan_priv, 1209 struct net_device *dev) 1210 { 1211 struct scan_req *scan_req, *scan_cleanup; 1212 qdf_list_node_t *node = NULL, *next_node = NULL; 1213 1214 qdf_mutex_acquire(&scan_priv->scan_req_q_lock); 1215 if (QDF_STATUS_SUCCESS != 1216 qdf_list_peek_front(&scan_priv->scan_req_q, 1217 &node)) { 1218 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1219 return; 1220 } 1221 1222 while (node) { 1223 /* 1224 * Keep track of the next node, to traverse through the list 1225 * in the event of the current node being deleted. 1226 */ 1227 qdf_list_peek_next(&scan_priv->scan_req_q, 1228 node, &next_node); 1229 scan_req = qdf_container_of(node, struct scan_req, node); 1230 if (!dev || (dev == scan_req->dev)) { 1231 scan_cleanup = qdf_mem_malloc(sizeof(struct scan_req)); 1232 if (!scan_cleanup) { 1233 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1234 return; 1235 } 1236 scan_cleanup->scan_request = scan_req->scan_request; 1237 scan_cleanup->scan_id = scan_req->scan_id; 1238 scan_cleanup->source = scan_req->source; 1239 scan_cleanup->dev = scan_req->dev; 1240 qdf_list_insert_back(scan_cleanup_q, 1241 &scan_cleanup->node); 1242 if (QDF_STATUS_SUCCESS != 1243 qdf_list_remove_node(&scan_priv->scan_req_q, 1244 node)) { 1245 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1246 osif_err("Failed to remove scan request"); 1247 return; 1248 } 1249 qdf_mem_free(scan_req); 1250 } 1251 node = next_node; 1252 next_node = NULL; 1253 } 1254 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1255 } 1256 1257 void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev, 1258 struct net_device *dev) 1259 { 1260 struct scan_req *scan_req; 1261 struct cfg80211_scan_request *req; 1262 uint8_t source; 1263 bool aborted = true; 1264 struct pdev_osif_priv *osif_priv; 1265 qdf_list_t scan_cleanup_q; 1266 qdf_list_node_t *node = NULL; 1267 1268 if (!pdev) { 1269 osif_err("pdev is Null"); 1270 return; 1271 } 1272 1273 osif_priv = wlan_pdev_get_ospriv(pdev); 1274 1275 /* 1276 * To avoid any race conditions, create a local list to copy all the 1277 * scan entries to be removed and then send scan complete for each of 1278 * the identified entries to NL. 1279 */ 1280 qdf_list_create(&scan_cleanup_q, WLAN_MAX_SCAN_COUNT); 1281 wlan_cfg80211_enqueue_for_cleanup(&scan_cleanup_q, 1282 osif_priv->osif_scan, dev); 1283 1284 while (!qdf_list_empty(&scan_cleanup_q)) { 1285 if (QDF_STATUS_SUCCESS != qdf_list_remove_front(&scan_cleanup_q, 1286 &node)) { 1287 osif_err("Failed to remove scan request"); 1288 return; 1289 } 1290 scan_req = container_of(node, struct scan_req, node); 1291 req = scan_req->scan_request; 1292 source = scan_req->source; 1293 if (NL_SCAN == source) 1294 wlan_cfg80211_scan_done(scan_req->dev, req, 1295 aborted); 1296 else 1297 wlan_vendor_scan_callback(req, aborted); 1298 1299 qdf_mem_free(scan_req); 1300 } 1301 qdf_list_destroy(&scan_cleanup_q); 1302 1303 return; 1304 } 1305 1306 /** 1307 * wlan_cfg80211_update_scan_policy_type_flags() - Set scan flags according to 1308 * scan request 1309 * @scan_req: Pointer to csr scan req 1310 * 1311 * Return: None 1312 */ 1313 #if defined(CFG80211_SCAN_DBS_CONTROL_SUPPORT) || \ 1314 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)) 1315 static void wlan_cfg80211_update_scan_policy_type_flags( 1316 struct cfg80211_scan_request *req, 1317 struct scan_req_params *scan_req) 1318 { 1319 if (req->flags & NL80211_SCAN_FLAG_HIGH_ACCURACY) 1320 scan_req->scan_policy_high_accuracy = true; 1321 if (req->flags & NL80211_SCAN_FLAG_LOW_SPAN) 1322 scan_req->scan_policy_low_span = true; 1323 if (req->flags & NL80211_SCAN_FLAG_LOW_POWER) 1324 scan_req->scan_policy_low_power = true; 1325 } 1326 #else 1327 static inline void wlan_cfg80211_update_scan_policy_type_flags( 1328 struct cfg80211_scan_request *req, 1329 struct scan_req_params *scan_req) 1330 { 1331 } 1332 #endif 1333 1334 #ifdef WLAN_POLICY_MGR_ENABLE 1335 static bool 1336 wlan_cfg80211_allow_simultaneous_scan(struct wlan_objmgr_psoc *psoc) 1337 { 1338 return policy_mgr_is_scan_simultaneous_capable(psoc); 1339 } 1340 #else 1341 static bool 1342 wlan_cfg80211_allow_simultaneous_scan(struct wlan_objmgr_psoc *psoc) 1343 { 1344 return true; 1345 } 1346 #endif 1347 1348 int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, 1349 struct cfg80211_scan_request *request, 1350 struct scan_params *params) 1351 { 1352 struct scan_start_request *req; 1353 struct wlan_ssid *pssid; 1354 uint8_t i; 1355 int ret = 0; 1356 uint8_t num_chan = 0; 1357 uint32_t c_freq; 1358 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 1359 wlan_scan_requester req_id; 1360 struct pdev_osif_priv *osif_priv; 1361 struct wlan_objmgr_psoc *psoc; 1362 wlan_scan_id scan_id; 1363 bool is_p2p_scan = false; 1364 enum wlan_band band; 1365 QDF_STATUS qdf_status; 1366 enum QDF_OPMODE opmode; 1367 uint32_t extra_ie_len = 0; 1368 1369 psoc = wlan_pdev_get_psoc(pdev); 1370 if (!psoc) { 1371 osif_err("Invalid psoc object"); 1372 return -EINVAL; 1373 } 1374 opmode = wlan_vdev_mlme_get_opmode(vdev); 1375 1376 osif_debug("%s(vdev%d): mode %d", request->wdev->netdev->name, 1377 wlan_vdev_get_id(vdev), opmode); 1378 1379 /* Get NL global context from objmgr*/ 1380 osif_priv = wlan_pdev_get_ospriv(pdev); 1381 if (!osif_priv) { 1382 osif_err("Invalid osif priv object"); 1383 return -EINVAL; 1384 } 1385 1386 /* 1387 * For a non-SAP vdevs, if a scan is already going on i.e the scan queue 1388 * is not empty, and the simultaneous scan is disabled, dont allow 2nd 1389 * scan. 1390 */ 1391 qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock); 1392 if (!wlan_cfg80211_allow_simultaneous_scan(psoc) && 1393 !qdf_list_empty(&osif_priv->osif_scan->scan_req_q) && 1394 opmode != QDF_SAP_MODE) { 1395 qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); 1396 osif_err("Simultaneous scan disabled, reject scan"); 1397 return -EBUSY; 1398 } 1399 qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); 1400 1401 req = qdf_mem_malloc(sizeof(*req)); 1402 if (!req) 1403 return -EINVAL; 1404 1405 /* Initialize the scan global params */ 1406 ucfg_scan_init_default_params(vdev, req); 1407 1408 req_id = osif_priv->osif_scan->req_id; 1409 scan_id = ucfg_scan_get_scan_id(psoc); 1410 if (!scan_id) { 1411 osif_err("Invalid scan id"); 1412 qdf_mem_free(req); 1413 return -EINVAL; 1414 } 1415 1416 /* fill the scan request structure */ 1417 req->vdev = vdev; 1418 req->scan_req.vdev_id = wlan_vdev_get_id(vdev); 1419 req->scan_req.scan_id = scan_id; 1420 req->scan_req.scan_req_id = req_id; 1421 1422 /* Update scan policy type flags according to cfg scan request */ 1423 wlan_cfg80211_update_scan_policy_type_flags(request, 1424 &req->scan_req); 1425 /* 1426 * Even though supplicant doesn't provide any SSIDs, n_ssids is 1427 * set to 1. Because of this, driver is assuming that this is not 1428 * wildcard scan and so is not aging out the scan results. 1429 */ 1430 if ((request->ssids) && (request->n_ssids == 1) && 1431 ('\0' == request->ssids->ssid[0])) { 1432 request->n_ssids = 0; 1433 } 1434 1435 if ((request->ssids) && (0 < request->n_ssids)) { 1436 int j; 1437 req->scan_req.num_ssids = request->n_ssids; 1438 1439 if (req->scan_req.num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 1440 osif_info("number of ssid %d greater than MAX %d", 1441 req->scan_req.num_ssids, 1442 WLAN_SCAN_MAX_NUM_SSID); 1443 req->scan_req.num_ssids = WLAN_SCAN_MAX_NUM_SSID; 1444 } 1445 /* copy all the ssid's and their length */ 1446 for (j = 0; j < req->scan_req.num_ssids; j++) { 1447 pssid = &req->scan_req.ssid[j]; 1448 /* get the ssid length */ 1449 pssid->length = request->ssids[j].ssid_len; 1450 if (pssid->length > WLAN_SSID_MAX_LEN) 1451 pssid->length = WLAN_SSID_MAX_LEN; 1452 qdf_mem_copy(pssid->ssid, 1453 &request->ssids[j].ssid[0], 1454 pssid->length); 1455 } 1456 } 1457 if (request->ssids || 1458 (opmode == QDF_P2P_GO_MODE) || (opmode == QDF_P2P_DEVICE_MODE)) 1459 req->scan_req.scan_f_passive = false; 1460 1461 if (params->half_rate) 1462 req->scan_req.scan_f_half_rate = true; 1463 else if (params->quarter_rate) 1464 req->scan_req.scan_f_quarter_rate = true; 1465 1466 if (params->strict_pscan) 1467 req->scan_req.scan_f_strict_passive_pch = true; 1468 1469 if ((request->n_ssids == 1) && request->ssids && 1470 !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7)) 1471 is_p2p_scan = true; 1472 1473 if (is_p2p_scan && request->no_cck) 1474 req->scan_req.scan_type = SCAN_TYPE_P2P_SEARCH; 1475 1476 if (params->dwell_time_active) 1477 req->scan_req.dwell_time_active = params->dwell_time_active; 1478 1479 if (params->dwell_time_active_2g) 1480 req->scan_req.dwell_time_active_2g = 1481 params->dwell_time_active_2g; 1482 1483 if (params->dwell_time_passive) 1484 req->scan_req.dwell_time_passive = params->dwell_time_passive; 1485 1486 if (params->dwell_time_active_6g) 1487 req->scan_req.dwell_time_active_6g = 1488 params->dwell_time_active_6g; 1489 1490 if (params->dwell_time_passive_6g) 1491 req->scan_req.dwell_time_passive_6g = 1492 params->dwell_time_passive_6g; 1493 1494 /* Set dwell time mode according to scan policy type flags */ 1495 if (ucfg_scan_cfg_honour_nl_scan_policy_flags(psoc)) { 1496 if (req->scan_req.scan_policy_high_accuracy) 1497 req->scan_req.adaptive_dwell_time_mode = 1498 SCAN_DWELL_MODE_STATIC; 1499 if (req->scan_req.scan_policy_low_power || 1500 req->scan_req.scan_policy_low_span) 1501 req->scan_req.adaptive_dwell_time_mode = 1502 SCAN_DWELL_MODE_AGGRESSIVE; 1503 } 1504 1505 /* 1506 * FW require at least 1 MAC to send probe request. 1507 * If MAC is all 0 set it to BC addr as this is the address on 1508 * which fw will send probe req. 1509 */ 1510 req->scan_req.num_bssid = 1; 1511 wlan_copy_bssid_scan_request(req, request); 1512 if (qdf_is_macaddr_zero(&req->scan_req.bssid_list[0])) 1513 qdf_set_macaddr_broadcast(&req->scan_req.bssid_list[0]); 1514 1515 if (params->scan_f_2ghz && !params->scan_f_5ghz) { 1516 req->scan_req.scan_f_2ghz = true; 1517 req->scan_req.scan_f_5ghz = false; 1518 } else if (!params->scan_f_2ghz && params->scan_f_5ghz) { 1519 req->scan_req.scan_f_2ghz = false; 1520 req->scan_req.scan_f_5ghz = true; 1521 } 1522 1523 if (request->n_channels) { 1524 #ifdef WLAN_POLICY_MGR_ENABLE 1525 bool ap_or_go_present = 1526 policy_mgr_mode_specific_connection_count( 1527 psoc, PM_SAP_MODE, NULL) || 1528 policy_mgr_mode_specific_connection_count( 1529 psoc, PM_P2P_GO_MODE, NULL); 1530 #endif 1531 for (i = 0; i < request->n_channels; i++) { 1532 c_freq = request->channels[i]->center_freq; 1533 if (wlan_reg_is_dsrc_freq(c_freq)) 1534 continue; 1535 #ifdef WLAN_POLICY_MGR_ENABLE 1536 if (ap_or_go_present) { 1537 bool ok; 1538 1539 qdf_status = policy_mgr_is_chan_ok_for_dnbs( 1540 psoc, c_freq, &ok); 1541 1542 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1543 osif_err("DNBS check failed"); 1544 ret = -EINVAL; 1545 goto err; 1546 } 1547 if (!ok) 1548 continue; 1549 } 1550 #endif 1551 1552 if ((req->scan_req.scan_f_2ghz && 1553 WLAN_REG_IS_24GHZ_CH_FREQ(c_freq)) || 1554 (req->scan_req.scan_f_5ghz && 1555 (WLAN_REG_IS_5GHZ_CH_FREQ(c_freq) || 1556 WLAN_REG_IS_49GHZ_FREQ(c_freq) || 1557 WLAN_REG_IS_6GHZ_CHAN_FREQ(c_freq)))) { 1558 req->scan_req.chan_list.chan[num_chan].freq = 1559 c_freq; 1560 band = util_scan_scm_freq_to_band(c_freq); 1561 if (band == WLAN_BAND_2_4_GHZ) 1562 req->scan_req.chan_list.chan[num_chan].phymode = 1563 SCAN_PHY_MODE_11G; 1564 else 1565 req->scan_req.chan_list.chan[num_chan].phymode = 1566 SCAN_PHY_MODE_11A; 1567 num_chan++; 1568 if (num_chan >= NUM_CHANNELS) 1569 break; 1570 } 1571 } 1572 } 1573 if (!num_chan) { 1574 osif_err("Received zero non-dsrc channels"); 1575 ret = -EINVAL; 1576 goto err; 1577 } 1578 req->scan_req.chan_list.num_chan = num_chan; 1579 1580 /* P2P increase the scan priority */ 1581 if (is_p2p_scan) 1582 req->scan_req.scan_priority = SCAN_PRIORITY_HIGH; 1583 1584 if (params->priority != SCAN_PRIORITY_COUNT) 1585 req->scan_req.scan_priority = params->priority; 1586 1587 if (request->ie_len) 1588 extra_ie_len = request->ie_len; 1589 else if (params->default_ie.ptr && params->default_ie.len) 1590 extra_ie_len = params->default_ie.len; 1591 1592 if (params->vendor_ie.ptr && params->vendor_ie.len) 1593 extra_ie_len += params->vendor_ie.len; 1594 1595 if (extra_ie_len) { 1596 req->scan_req.extraie.ptr = qdf_mem_malloc(extra_ie_len); 1597 if (!req->scan_req.extraie.ptr) { 1598 ret = -ENOMEM; 1599 goto err; 1600 } 1601 } 1602 1603 if (request->ie_len) { 1604 req->scan_req.extraie.len = request->ie_len; 1605 qdf_mem_copy(req->scan_req.extraie.ptr, request->ie, 1606 request->ie_len); 1607 } else if (params->default_ie.ptr && params->default_ie.len) { 1608 req->scan_req.extraie.len = params->default_ie.len; 1609 qdf_mem_copy(req->scan_req.extraie.ptr, params->default_ie.ptr, 1610 params->default_ie.len); 1611 } 1612 1613 if (params->vendor_ie.ptr && params->vendor_ie.len) { 1614 qdf_mem_copy((req->scan_req.extraie.ptr + 1615 req->scan_req.extraie.len), 1616 params->vendor_ie.ptr, params->vendor_ie.len); 1617 1618 req->scan_req.extraie.len += params->vendor_ie.len; 1619 } 1620 1621 if (!is_p2p_scan) { 1622 if (req->scan_req.scan_random.randomize) 1623 wlan_scan_rand_attrs(vdev, request, req); 1624 if (ucfg_ie_whitelist_enabled(psoc, vdev) && 1625 ucfg_copy_ie_whitelist_attrs(psoc, 1626 &req->scan_req.ie_whitelist)) 1627 req->scan_req.scan_f_en_ie_whitelist_in_probe = true; 1628 } 1629 1630 if (request->flags & NL80211_SCAN_FLAG_FLUSH) 1631 ucfg_scan_flush_results(pdev, NULL); 1632 1633 /* 1634 * Acquire wakelock to handle the case where APP's send scan to connect. 1635 * If suspend is received during scan scan will be aborted and APP will 1636 * not get scan result and not connect. eg if PNO is implemented in 1637 * framework. 1638 */ 1639 wlan_scan_acquire_wake_lock_timeout(psoc, 1640 &osif_priv->osif_scan->scan_wake_lock, 1641 SCAN_WAKE_LOCK_SCAN_DURATION); 1642 1643 qdf_runtime_pm_prevent_suspend( 1644 &osif_priv->osif_scan->runtime_pm_lock); 1645 1646 qdf_status = wlan_schedule_scan_start_request(pdev, request, 1647 params->source, req); 1648 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1649 qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock); 1650 if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) { 1651 qdf_mutex_release( 1652 &osif_priv->osif_scan->scan_req_q_lock); 1653 qdf_runtime_pm_allow_suspend( 1654 &osif_priv->osif_scan->runtime_pm_lock); 1655 wlan_scan_release_wake_lock( 1656 psoc, 1657 &osif_priv->osif_scan->scan_wake_lock); 1658 } else { 1659 qdf_mutex_release( 1660 &osif_priv->osif_scan->scan_req_q_lock); 1661 } 1662 } 1663 1664 return qdf_status_to_os_return(qdf_status); 1665 1666 err: 1667 qdf_mem_free(req); 1668 return ret; 1669 } 1670 1671 /** 1672 * wlan_get_scanid() - API to get the scan id 1673 * from the scan cookie attribute. 1674 * @pdev: Pointer to pdev object 1675 * @scan_id: Pointer to scan id 1676 * @cookie : Scan cookie attribute 1677 * 1678 * API to get the scan id from the scan cookie attribute 1679 * sent from supplicant by matching scan request. 1680 * 1681 * Return: 0 for success, non zero for failure 1682 */ 1683 static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev, 1684 uint32_t *scan_id, uint64_t cookie) 1685 { 1686 struct scan_req *scan_req; 1687 qdf_list_node_t *node = NULL; 1688 qdf_list_node_t *ptr_node = NULL; 1689 int ret = -EINVAL; 1690 struct pdev_osif_priv *osif_ctx; 1691 struct osif_scan_pdev *scan_priv; 1692 1693 /* Get NL global context from objmgr*/ 1694 osif_ctx = wlan_pdev_get_ospriv(pdev); 1695 if (!osif_ctx) { 1696 osif_err("Failed to retrieve osif context"); 1697 return ret; 1698 } 1699 scan_priv = osif_ctx->osif_scan; 1700 qdf_mutex_acquire(&scan_priv->scan_req_q_lock); 1701 if (qdf_list_empty(&scan_priv->scan_req_q)) { 1702 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1703 osif_err("Failed to retrieve scan id"); 1704 return ret; 1705 } 1706 1707 if (QDF_STATUS_SUCCESS != 1708 qdf_list_peek_front(&scan_priv->scan_req_q, 1709 &ptr_node)) { 1710 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1711 return ret; 1712 } 1713 1714 do { 1715 node = ptr_node; 1716 scan_req = qdf_container_of(node, struct scan_req, node); 1717 if (cookie == 1718 (uintptr_t)(scan_req->scan_request)) { 1719 *scan_id = scan_req->scan_id; 1720 ret = 0; 1721 break; 1722 } 1723 } while (QDF_STATUS_SUCCESS == 1724 qdf_list_peek_next(&scan_priv->scan_req_q, 1725 node, &ptr_node)); 1726 1727 qdf_mutex_release(&scan_priv->scan_req_q_lock); 1728 1729 return ret; 1730 } 1731 1732 QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev, 1733 uint32_t pdev_id, uint32_t vdev_id, 1734 wlan_scan_id scan_id, bool sync) 1735 { 1736 struct scan_cancel_request *req; 1737 struct pdev_osif_priv *osif_ctx; 1738 struct osif_scan_pdev *scan_priv; 1739 QDF_STATUS status; 1740 struct wlan_objmgr_vdev *vdev; 1741 1742 req = qdf_mem_malloc(sizeof(*req)); 1743 if (!req) 1744 return QDF_STATUS_E_NOMEM; 1745 1746 /* Get NL global context from objmgr*/ 1747 osif_ctx = wlan_pdev_get_ospriv(pdev); 1748 if (!osif_ctx) { 1749 osif_err("Failed to retrieve osif context"); 1750 qdf_mem_free(req); 1751 return QDF_STATUS_E_FAILURE; 1752 } 1753 if (vdev_id == INVAL_VDEV_ID) 1754 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_OSIF_ID); 1755 else 1756 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, 1757 vdev_id, WLAN_OSIF_ID); 1758 1759 if (!vdev) { 1760 qdf_mem_free(req); 1761 return QDF_STATUS_E_INVAL; 1762 } 1763 scan_priv = osif_ctx->osif_scan; 1764 req->cancel_req.requester = scan_priv->req_id; 1765 req->vdev = vdev; 1766 req->cancel_req.scan_id = scan_id; 1767 req->cancel_req.pdev_id = pdev_id; 1768 req->cancel_req.vdev_id = vdev_id; 1769 if (scan_id != INVAL_SCAN_ID && scan_id != CANCEL_HOST_SCAN_ID) 1770 req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE; 1771 else if (scan_id == CANCEL_HOST_SCAN_ID) 1772 req->cancel_req.req_type = WLAN_SCAN_CANCEL_HOST_VDEV_ALL; 1773 else if (vdev_id == INVAL_VDEV_ID) 1774 req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL; 1775 else 1776 req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL; 1777 1778 osif_debug("Type %d Vdev %d pdev %d scan id %d sync %d", 1779 req->cancel_req.req_type, req->cancel_req.vdev_id, 1780 req->cancel_req.pdev_id, req->cancel_req.scan_id, sync); 1781 1782 if (sync) 1783 status = ucfg_scan_cancel_sync(req); 1784 else 1785 status = ucfg_scan_cancel(req); 1786 if (QDF_IS_STATUS_ERROR(status)) 1787 osif_err("Cancel scan request failed"); 1788 1789 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 1790 1791 return status; 1792 } 1793 1794 qdf_export_symbol(wlan_abort_scan); 1795 1796 int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev) 1797 { 1798 uint8_t pdev_id; 1799 1800 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1801 1802 if (ucfg_scan_get_pdev_status(pdev) != 1803 SCAN_NOT_IN_PROGRESS) 1804 wlan_abort_scan(pdev, pdev_id, 1805 INVAL_VDEV_ID, INVAL_SCAN_ID, true); 1806 1807 return 0; 1808 } 1809 1810 int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev, 1811 const void *data, int data_len) 1812 { 1813 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1]; 1814 int ret = -EINVAL; 1815 wlan_scan_id scan_id; 1816 uint64_t cookie; 1817 uint8_t pdev_id; 1818 1819 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1820 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, data, 1821 data_len, cfg80211_scan_policy)) { 1822 osif_err("Invalid ATTR"); 1823 return ret; 1824 } 1825 1826 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]) { 1827 cookie = nla_get_u64( 1828 tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]); 1829 ret = wlan_get_scanid(pdev, &scan_id, cookie); 1830 if (ret != 0) 1831 return ret; 1832 if (ucfg_scan_get_pdev_status(pdev) != 1833 SCAN_NOT_IN_PROGRESS) 1834 wlan_abort_scan(pdev, INVAL_PDEV_ID, 1835 INVAL_VDEV_ID, scan_id, true); 1836 } 1837 return 0; 1838 } 1839 1840 static inline struct ieee80211_channel * 1841 wlan_get_ieee80211_channel(struct wiphy *wiphy, 1842 struct wlan_objmgr_pdev *pdev, 1843 int chan_freq) 1844 { 1845 struct ieee80211_channel *chan; 1846 1847 chan = ieee80211_get_channel(wiphy, chan_freq); 1848 if (!chan) 1849 osif_err_rl("chan is NULL, freq: %d", chan_freq); 1850 1851 return chan; 1852 } 1853 1854 #ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS 1855 static inline int wlan_get_frame_len(struct scan_cache_entry *scan_params) 1856 { 1857 return util_scan_entry_frame_len(scan_params) + sizeof(qcom_ie_age); 1858 } 1859 1860 static inline void wlan_add_age_ie(uint8_t *mgmt_frame, 1861 struct scan_cache_entry *scan_params) 1862 { 1863 qcom_ie_age *qie_age = NULL; 1864 1865 /* GPS Requirement: need age ie per entry. Using vendor specific. */ 1866 /* Assuming this is the last IE, copy at the end */ 1867 qie_age = (qcom_ie_age *) (mgmt_frame + 1868 util_scan_entry_frame_len(scan_params)); 1869 qie_age->element_id = QCOM_VENDOR_IE_ID; 1870 qie_age->len = QCOM_VENDOR_IE_AGE_LEN; 1871 qie_age->oui_1 = QCOM_OUI1; 1872 qie_age->oui_2 = QCOM_OUI2; 1873 qie_age->oui_3 = QCOM_OUI3; 1874 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE; 1875 /* 1876 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver 1877 * all bss related timestamp is in units of ms. Due to this when scan 1878 * results are sent to lowi the scan age is high.To address this, 1879 * send age in units of 1/10 ms. 1880 */ 1881 qie_age->age = 1882 (uint32_t)(qdf_mc_timer_get_system_time() - 1883 scan_params->scan_entry_time)/10; 1884 qie_age->tsf_delta = scan_params->tsf_delta; 1885 memcpy(&qie_age->beacon_tsf, scan_params->tsf_info.data, 1886 sizeof(qie_age->beacon_tsf)); 1887 memcpy(&qie_age->seq_ctrl, &scan_params->seq_num, 1888 sizeof(qie_age->seq_ctrl)); 1889 } 1890 #else 1891 static inline int wlan_get_frame_len(struct scan_cache_entry *scan_params) 1892 { 1893 return util_scan_entry_frame_len(scan_params); 1894 } 1895 1896 static inline void wlan_add_age_ie(uint8_t *mgmt_frame, 1897 struct scan_cache_entry *scan_params) 1898 { 1899 } 1900 #endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */ 1901 1902 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \ 1903 defined(CFG80211_INFORM_BSS_FRAME_DATA) 1904 /** 1905 * wlan_fill_per_chain_rssi() - fill per chain RSSI in inform bss 1906 * @data: bss data 1907 * @per_chain_snr: per chain RSSI 1908 * 1909 * Return: void 1910 */ 1911 #if defined(CFG80211_SCAN_PER_CHAIN_RSSI_SUPPORT) || \ 1912 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)) 1913 static void wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data, 1914 struct wlan_cfg80211_inform_bss *bss) 1915 { 1916 1917 uint32_t i; 1918 1919 if (!bss || !data) { 1920 osif_err("Received bss is NULL"); 1921 return; 1922 } 1923 for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) { 1924 if (!bss->per_chain_rssi[i] || 1925 (bss->per_chain_rssi[i] == WLAN_INVALID_PER_CHAIN_RSSI)) 1926 continue; 1927 data->chain_signal[i] = bss->per_chain_rssi[i]; 1928 data->chains |= BIT(i); 1929 } 1930 } 1931 #else 1932 static inline void 1933 wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data, 1934 struct wlan_cfg80211_inform_bss *bss) 1935 { 1936 } 1937 #endif 1938 1939 struct cfg80211_bss * 1940 wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy, 1941 struct wlan_cfg80211_inform_bss *bss) 1942 { 1943 struct cfg80211_inform_bss data = {0}; 1944 1945 if (!bss) { 1946 osif_err("bss is null"); 1947 return NULL; 1948 } 1949 wlan_fill_per_chain_rssi(&data, bss); 1950 1951 data.chan = bss->chan; 1952 data.boottime_ns = bss->boottime_ns; 1953 data.signal = bss->rssi; 1954 return cfg80211_inform_bss_frame_data(wiphy, &data, bss->mgmt, 1955 bss->frame_len, GFP_ATOMIC); 1956 } 1957 #else 1958 struct cfg80211_bss * 1959 wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy, 1960 struct wlan_cfg80211_inform_bss *bss) 1961 1962 { 1963 return cfg80211_inform_bss_frame(wiphy, bss->chan, bss->mgmt, 1964 bss->frame_len, 1965 bss->rssi, GFP_ATOMIC); 1966 } 1967 #endif 1968 1969 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) 1970 static inline void wlan_cfg80211_put_bss(struct wiphy *wiphy, 1971 struct cfg80211_bss *bss) 1972 { 1973 cfg80211_put_bss(wiphy, bss); 1974 } 1975 #else 1976 static inline void wlan_cfg80211_put_bss(struct wiphy *wiphy, 1977 struct cfg80211_bss *bss) 1978 { 1979 cfg80211_put_bss(bss); 1980 } 1981 #endif 1982 1983 void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, 1984 struct scan_cache_entry *scan_params) 1985 { 1986 struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev); 1987 struct wiphy *wiphy; 1988 struct cfg80211_bss *bss = NULL; 1989 struct wlan_cfg80211_inform_bss bss_data = {0}; 1990 1991 if (!pdev_ospriv) { 1992 osif_err("os_priv is NULL"); 1993 return; 1994 } 1995 1996 wiphy = pdev_ospriv->wiphy; 1997 1998 bss_data.frame_len = wlan_get_frame_len(scan_params); 1999 bss_data.mgmt = qdf_mem_malloc_atomic(bss_data.frame_len); 2000 if (!bss_data.mgmt) { 2001 osif_err("bss mem alloc failed for seq %d", 2002 scan_params->seq_num); 2003 return; 2004 } 2005 qdf_mem_copy(bss_data.mgmt, 2006 util_scan_entry_frame_ptr(scan_params), 2007 util_scan_entry_frame_len(scan_params)); 2008 /* 2009 * Android does not want the timestamp from the frame. 2010 * Instead it wants a monotonic increasing value 2011 */ 2012 bss_data.mgmt->u.probe_resp.timestamp = qdf_get_monotonic_boottime(); 2013 wlan_add_age_ie((uint8_t *)bss_data.mgmt, scan_params); 2014 /* 2015 * Based on .ini configuration, raw rssi can be reported for bss. 2016 * Raw rssi is typically used for estimating power. 2017 */ 2018 bss_data.rssi = scan_params->rssi_raw; 2019 2020 bss_data.chan = wlan_get_ieee80211_channel(wiphy, pdev, 2021 scan_params->channel.chan_freq); 2022 if (!bss_data.chan) { 2023 osif_err_rl("Channel not found for bss " QDF_MAC_ADDR_FMT " seq %d chan_freq %d", 2024 QDF_MAC_ADDR_REF(bss_data.mgmt->bssid), 2025 scan_params->seq_num, 2026 scan_params->channel.chan_freq); 2027 qdf_mem_free(bss_data.mgmt); 2028 return; 2029 } 2030 2031 /* 2032 * Supplicant takes the signal strength in terms of 2033 * mBm (1 dBm = 100 mBm). 2034 */ 2035 bss_data.rssi = QDF_MIN(bss_data.rssi, 0) * 100; 2036 2037 bss_data.boottime_ns = scan_params->boottime_ns; 2038 2039 qdf_mem_copy(bss_data.per_chain_rssi, scan_params->per_chain_rssi, 2040 WLAN_MGMT_TXRX_HOST_MAX_ANTENNA); 2041 2042 bss = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data); 2043 if (!bss) 2044 osif_err("failed to inform bss "QDF_MAC_ADDR_FMT" seq %d", 2045 QDF_MAC_ADDR_REF(bss_data.mgmt->bssid), 2046 scan_params->seq_num); 2047 else 2048 wlan_cfg80211_put_bss(wiphy, bss); 2049 2050 qdf_mem_free(bss_data.mgmt); 2051 } 2052 2053 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && \ 2054 !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY) 2055 struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy, 2056 struct ieee80211_channel *channel, 2057 const u8 *bssid, const u8 *ssid, 2058 size_t ssid_len) 2059 { 2060 return cfg80211_get_bss(wiphy, channel, bssid, 2061 ssid, ssid_len, 2062 WLAN_CAPABILITY_ESS, 2063 WLAN_CAPABILITY_ESS); 2064 } 2065 #else 2066 struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy, 2067 struct ieee80211_channel *channel, 2068 const u8 *bssid, const u8 *ssid, 2069 size_t ssid_len) 2070 { 2071 return cfg80211_get_bss(wiphy, channel, bssid, 2072 ssid, ssid_len, 2073 IEEE80211_BSS_TYPE_ESS, 2074 IEEE80211_PRIVACY_ANY); 2075 } 2076 #endif 2077 2078 QDF_STATUS __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy, 2079 struct wlan_objmgr_pdev *pdev, 2080 uint8_t *bssid, uint8_t *ssid, 2081 uint8_t ssid_len) 2082 { 2083 struct cfg80211_bss *bss = NULL; 2084 uint8_t vdev_id; 2085 2086 if (bssid && wlan_get_connected_vdev_by_bssid(pdev, bssid, &vdev_id)) { 2087 osif_debug("BSS "QDF_MAC_ADDR_FMT" connected on vdev %d dont unlink", 2088 QDF_MAC_ADDR_REF(bssid), vdev_id); 2089 return QDF_STATUS_E_FAILURE; 2090 } 2091 2092 bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid, 2093 ssid, ssid_len); 2094 if (!bss) { 2095 osif_info("BSS "QDF_MAC_ADDR_FMT" not found", 2096 QDF_MAC_ADDR_REF(bssid)); 2097 } else { 2098 osif_debug("unlink entry for ssid:%.*s and BSSID "QDF_MAC_ADDR_FMT, 2099 ssid_len, ssid, QDF_MAC_ADDR_REF(bssid)); 2100 cfg80211_unlink_bss(wiphy, bss); 2101 wlan_cfg80211_put_bss(wiphy, bss); 2102 } 2103 2104 /* 2105 * Kernel creates separate entries into it's bss list for probe resp 2106 * and beacon for hidden AP. Both have separate ref count and thus 2107 * deleting one will not delete other entry. 2108 * If beacon entry of the hidden AP is not deleted and AP switch to 2109 * broadcasting SSID from Hiding SSID, kernel will reject the beacon 2110 * entry. So unlink the hidden beacon entry (if present) as well from 2111 * kernel, to avoid such issue. 2112 */ 2113 bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0); 2114 if (!bss) { 2115 osif_debug("Hidden bss not found for Ssid:%.*s BSSID: "QDF_MAC_ADDR_FMT" sid_len %d", 2116 ssid_len, ssid, QDF_MAC_ADDR_REF(bssid), ssid_len); 2117 } else { 2118 osif_debug("unlink entry for Hidden ssid:%.*s and BSSID "QDF_MAC_ADDR_FMT, 2119 ssid_len, ssid, QDF_MAC_ADDR_REF(bssid)); 2120 2121 cfg80211_unlink_bss(wiphy, bss); 2122 /* cfg80211_get_bss get bss with ref count so release it */ 2123 wlan_cfg80211_put_bss(wiphy, bss); 2124 } 2125 2126 return QDF_STATUS_SUCCESS; 2127 } 2128 void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev, 2129 struct scan_cache_entry *scan_entry) 2130 { 2131 struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev); 2132 struct wiphy *wiphy; 2133 2134 if (!pdev_ospriv) { 2135 osif_err("os_priv is NULL"); 2136 return; 2137 } 2138 2139 wiphy = pdev_ospriv->wiphy; 2140 2141 __wlan_cfg80211_unlink_bss_list(wiphy, pdev, scan_entry->bssid.bytes, 2142 scan_entry->ssid.ssid, 2143 scan_entry->ssid.length); 2144 } 2145 2146 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) 2147 /* 2148 * wlan_scan_wiphy_set_max_sched_scans() - set maximum number of scheduled scans 2149 * to wiphy. 2150 * @wiphy: pointer to wiphy 2151 * @max_scans: max num scans to be configured 2152 * 2153 */ 2154 static inline void 2155 wlan_scan_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans) 2156 { 2157 if (max_scans == 0) 2158 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 2159 else 2160 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 2161 } 2162 #else 2163 static inline void 2164 wlan_scan_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans) 2165 { 2166 wiphy->max_sched_scan_reqs = max_scans; 2167 } 2168 #endif /* KERNEL_VERSION(4, 12, 0) */ 2169 2170 #if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN) || \ 2171 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) 2172 void wlan_scan_cfg80211_add_connected_pno_support(struct wiphy *wiphy) 2173 { 2174 wiphy_ext_feature_set(wiphy, 2175 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI); 2176 } 2177 #endif 2178 2179 #if ((LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0)) || \ 2180 defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) && \ 2181 defined(FEATURE_WLAN_SCAN_PNO) 2182 void wlan_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy, 2183 struct wlan_objmgr_psoc *psoc) 2184 { 2185 if (ucfg_scan_get_pno_scan_support(psoc)) { 2186 wlan_scan_wiphy_set_max_sched_scans(wiphy, 1); 2187 wiphy->max_sched_scan_ssids = SCAN_PNO_MAX_SUPP_NETWORKS; 2188 wiphy->max_match_sets = SCAN_PNO_MAX_SUPP_NETWORKS; 2189 wiphy->max_sched_scan_ie_len = SCAN_MAX_IE_LENGTH; 2190 wiphy->max_sched_scan_plans = SCAN_PNO_MAX_PLAN_REQUEST; 2191 2192 wiphy->max_sched_scan_plan_interval = 2193 ucfg_scan_get_max_sched_scan_plan_interval(psoc); 2194 2195 wiphy->max_sched_scan_plan_iterations = 2196 ucfg_scan_get_max_sched_scan_plan_iterations(psoc); 2197 } 2198 } 2199 #endif 2200