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