1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /*=========================================================================== 21 22 s a p A p i L i n k C n t l . C 23 24 OVERVIEW: 25 26 This software unit holds the implementation of the WLAN SAP modules 27 Link Control functions. 28 29 The functions externalized by this module are to be called ONLY by other 30 WLAN modules (HDD) 31 32 DEPENDENCIES: 33 34 Are listed for each API below. 35 ===========================================================================*/ 36 37 /*---------------------------------------------------------------------------- 38 * Include Files 39 * -------------------------------------------------------------------------*/ 40 #include "qdf_trace.h" 41 /* Pick up the CSR callback definition */ 42 #include "csr_api.h" 43 #include "ani_global.h" 44 #include "csr_inside_api.h" 45 #include "sme_api.h" 46 /* SAP Internal API header file */ 47 #include "sap_internal.h" 48 #include "wlan_policy_mgr_api.h" 49 #include "wma.h" 50 #include <wlan_objmgr_vdev_obj.h> 51 #include <wlan_objmgr_pdev_obj.h> 52 #include "wlan_reg_services_api.h" 53 #include <wlan_scan_api.h> 54 #include <wlan_scan_utils_api.h> 55 #include "wlan_pre_cac_api.h" 56 #include <wlan_cfg80211_scan.h> 57 #include <wlan_hdd_hostapd.h> 58 59 /* IF MGR API header file */ 60 #include "wlan_if_mgr_ucfg_api.h" 61 62 /*---------------------------------------------------------------------------- 63 * Preprocessor Definitions and Constants 64 * -------------------------------------------------------------------------*/ 65 #define SAP_DEBUG 66 67 /*---------------------------------------------------------------------------- 68 * Type Declarations 69 * -------------------------------------------------------------------------*/ 70 71 /*---------------------------------------------------------------------------- 72 * Global Data Definitions 73 * -------------------------------------------------------------------------*/ 74 75 /*---------------------------------------------------------------------------- 76 * Static Variable Definitions 77 * -------------------------------------------------------------------------*/ 78 79 /*---------------------------------------------------------------------------- 80 * Static Function Declarations and Definitions 81 * -------------------------------------------------------------------------*/ 82 83 /*---------------------------------------------------------------------------- 84 * Externalized Function Definitions 85 * -------------------------------------------------------------------------*/ 86 87 /*---------------------------------------------------------------------------- 88 * Function Declarations and Documentation 89 * -------------------------------------------------------------------------*/ 90 91 #if defined(WLAN_FEATURE_11BE) 92 static inline bool sap_acs_cfg_is_chwidth_320mhz(uint16_t width) 93 { 94 return width == CH_WIDTH_320MHZ; 95 } 96 #else 97 static inline bool sap_acs_cfg_is_chwidth_320mhz(uint16_t width) 98 { 99 return false; 100 } 101 #endif 102 103 #ifdef WLAN_FEATURE_11BE 104 static void sap_acs_set_puncture_bitmap(struct sap_context *sap_ctx, 105 struct ch_params *ch_params) 106 { 107 sap_debug("ccfs0 %d ch_width %d, punct 0x%x", 108 ch_params->center_freq_seg0, 109 ch_params->ch_width, 110 ch_params->reg_punc_bitmap); 111 sap_ctx->acs_cfg->acs_puncture_bitmap = ch_params->reg_punc_bitmap; 112 } 113 #else 114 static void sap_acs_set_puncture_bitmap(struct sap_context *sap_ctx, 115 struct ch_params *ch_params) 116 { 117 } 118 #endif /* WLAN_FEATURE_11BE */ 119 120 /** 121 * sap_config_acs_result : Generate ACS result params based on ch constraints 122 * @sap_ctx: pointer to SAP context data struct 123 * @mac_handle: Opaque handle to the global MAC context 124 * @sec_ch_freq: Secondary channel frequency 125 * 126 * This function calculates the ACS result params: ht sec channel, vht channel 127 * information and channel bonding based on selected ACS channel. 128 * 129 * Return: None 130 */ 131 132 void sap_config_acs_result(mac_handle_t mac_handle, 133 struct sap_context *sap_ctx, 134 uint32_t sec_ch_freq) 135 { 136 struct ch_params ch_params = {0}; 137 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 138 enum phy_ch_width new_ch_width; 139 140 ch_params.ch_width = sap_ctx->acs_cfg->ch_width; 141 if (sap_phymode_is_eht(sap_ctx->phyMode)) 142 wlan_reg_set_create_punc_bitmap(&ch_params, true); 143 144 new_ch_width = 145 wlan_sap_get_concurrent_bw(mac_ctx->pdev, mac_ctx->psoc, 146 sap_ctx->acs_cfg->pri_ch_freq, 147 ch_params.ch_width); 148 sap_debug("new_ch_width:%d", new_ch_width); 149 ch_params.ch_width = new_ch_width; 150 151 wlan_reg_set_channel_params_for_pwrmode( 152 mac_ctx->pdev, sap_ctx->acs_cfg->pri_ch_freq, 153 sec_ch_freq, &ch_params, REG_CURRENT_PWR_MODE); 154 sap_ctx->acs_cfg->ch_width = ch_params.ch_width; 155 if (sap_ctx->acs_cfg->ch_width > CH_WIDTH_40MHZ || 156 WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->acs_cfg->pri_ch_freq)) 157 sap_ctx->acs_cfg->vht_seg0_center_ch_freq = 158 ch_params.mhz_freq_seg0; 159 else 160 sap_ctx->acs_cfg->vht_seg0_center_ch_freq = 0; 161 162 if (sap_ctx->acs_cfg->ch_width == CH_WIDTH_80P80MHZ || 163 (sap_ctx->acs_cfg->ch_width == CH_WIDTH_160MHZ) || 164 sap_acs_cfg_is_chwidth_320mhz(sap_ctx->acs_cfg->ch_width)) 165 sap_ctx->acs_cfg->vht_seg1_center_ch_freq = 166 ch_params.mhz_freq_seg1; 167 else 168 sap_ctx->acs_cfg->vht_seg1_center_ch_freq = 0; 169 170 if (ch_params.sec_ch_offset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) 171 sap_ctx->acs_cfg->ht_sec_ch_freq = 172 sap_ctx->acs_cfg->pri_ch_freq - 20; 173 else if (ch_params.sec_ch_offset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) 174 sap_ctx->acs_cfg->ht_sec_ch_freq = 175 sap_ctx->acs_cfg->pri_ch_freq + 20; 176 else 177 sap_ctx->acs_cfg->ht_sec_ch_freq = 0; 178 179 sap_acs_set_puncture_bitmap(sap_ctx, &ch_params); 180 } 181 182 /** 183 * sap_hdd_signal_event_handler() - routine to inform hostapd via callback 184 * @ctx: pointer to sap context which was passed to callback 185 * 186 * this routine will be registered as callback to sme_close_session, so upon 187 * closure of sap session it notifies the hostapd 188 * 189 * Return: QDF_STATUS 190 */ 191 static QDF_STATUS sap_hdd_signal_event_handler(void *ctx) 192 { 193 struct sap_context *sap_ctx = ctx; 194 QDF_STATUS status; 195 196 if (!sap_ctx) { 197 sap_err("sap context is not valid"); 198 return QDF_STATUS_E_FAILURE; 199 } 200 status = sap_signal_hdd_event(sap_ctx, NULL, 201 sap_ctx->sap_state, 202 (void *) sap_ctx->sap_status); 203 return status; 204 } 205 206 /** 207 * acs_scan_done_status_str() - parse scan status to string 208 * @status: scan status 209 * 210 * This function parse scan status to string 211 * 212 * Return: status string 213 * 214 */ 215 static const char *acs_scan_done_status_str(eCsrScanStatus status) 216 { 217 switch (status) { 218 case eCSR_SCAN_SUCCESS: 219 return "Success"; 220 case eCSR_SCAN_FAILURE: 221 return "Failure"; 222 case eCSR_SCAN_ABORT: 223 return "Abort"; 224 case eCSR_SCAN_FOUND_PEER: 225 return "Found peer"; 226 default: 227 return "Unknown"; 228 } 229 } 230 231 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 232 static void wlansap_send_acs_success_event(struct sap_context *sap_ctx, 233 uint32_t scan_id) 234 { 235 if (scan_id) { 236 sap_debug("Sending ACS Scan skip event"); 237 sap_signal_hdd_event(sap_ctx, NULL, 238 eSAP_ACS_SCAN_SUCCESS_EVENT, 239 (void *)eSAP_STATUS_SUCCESS); 240 } else { 241 sap_debug("ACS scanid: %d (skipped ACS SCAN)", scan_id); 242 } 243 } 244 #else 245 static inline void wlansap_send_acs_success_event(struct sap_context *sap_ctx, 246 uint32_t scan_id) 247 { 248 } 249 #endif 250 251 static uint32_t 252 wlansap_calculate_chan_from_scan_result(mac_handle_t mac_handle, 253 struct sap_context *sap_ctx, 254 uint32_t scan_id) 255 { 256 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 257 qdf_list_t *list = NULL; 258 struct scan_filter *filter; 259 uint32_t oper_channel = SAP_CHANNEL_NOT_SELECTED; 260 261 filter = qdf_mem_malloc(sizeof(*filter)); 262 263 if (filter) { 264 if (sap_ctx->partial_acs_scan) 265 filter->age_threshold = 266 sap_ctx->acs_cfg->last_scan_ageout_time; 267 else 268 filter->age_threshold = qdf_get_time_of_the_day_ms() - 269 sap_ctx->acs_req_timestamp; 270 } 271 272 list = wlan_scan_get_result(mac_ctx->pdev, filter); 273 274 if (filter) 275 qdf_mem_free(filter); 276 277 if (list) 278 sap_debug("num_entries %d", qdf_list_size(list)); 279 280 wlansap_send_acs_success_event(sap_ctx, scan_id); 281 282 oper_channel = sap_select_channel(mac_handle, sap_ctx, list); 283 wlan_scan_purge_results(list); 284 285 return oper_channel; 286 } 287 288 static void 289 wlansap_filter_unsafe_ch(struct wlan_objmgr_psoc *psoc, 290 struct sap_context *sap_ctx) 291 { 292 uint16_t i; 293 uint16_t num_safe_ch = 0; 294 uint32_t freq; 295 296 /* 297 * There are two channel list, one acs cfg channel list, and one 298 * sap_ctx->freq_list, the unsafe channels for acs cfg is updated here 299 * and the sap_ctx->freq list would be handled in sap_chan_sel_init 300 * which would consider more params other than unsafe channels. 301 * So the two lists now would be in sync. But in case the ACS weight 302 * calculation does not get through due to no scan result or no chan 303 * selected, or any other reason, the default channel is chosen which 304 * would contain the channels in acs cfg. Now since the scan takes time 305 * there could be channels present in acs cfg that could become unsafe 306 * in the mean time, so it is better to filter out those channels from 307 * the acs channel list before choosing one of them as a default channel 308 */ 309 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) { 310 freq = sap_ctx->acs_cfg->freq_list[i]; 311 if (!policy_mgr_is_sap_freq_allowed(psoc, freq)) { 312 sap_debug("remove freq %d from acs list", freq); 313 continue; 314 } 315 /* Add only allowed channels to the acs cfg ch list */ 316 sap_ctx->acs_cfg->freq_list[num_safe_ch++] = 317 sap_ctx->acs_cfg->freq_list[i]; 318 } 319 320 sap_debug("Updated ACS ch list len %d", num_safe_ch); 321 sap_ctx->acs_cfg->ch_list_count = num_safe_ch; 322 } 323 324 static void 325 wlan_sap_filter_non_preferred_channels(struct wlan_objmgr_pdev *pdev, 326 struct sap_context *sap_ctx) 327 { 328 uint16_t i; 329 uint16_t num_ch = 0; 330 bool preferred_freq_found = false; 331 332 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) { 333 if (sap_ctx->acs_cfg->freq_list[i] == 2467 || 334 sap_ctx->acs_cfg->freq_list[i] == 2472 || 335 sap_ctx->acs_cfg->freq_list[i] == 2477) { 336 sap_debug("Skip freq %d if preferred freq present", 337 sap_ctx->acs_cfg->freq_list[i]); 338 continue; 339 } 340 sap_ctx->acs_cfg->freq_list[num_ch++] = 341 sap_ctx->acs_cfg->freq_list[i]; 342 preferred_freq_found = true; 343 } 344 345 if (!preferred_freq_found) { 346 sap_debug("No preferred freq, list unchanged"); 347 return; 348 } 349 sap_debug("preferred frequencies found updated ACS ch list len %d", 350 num_ch); 351 sap_ctx->acs_cfg->ch_list_count = num_ch; 352 } 353 354 QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle, 355 struct sap_context *sap_ctx, 356 uint8_t sessionid, 357 uint32_t scanid, 358 eCsrScanStatus scan_status) 359 { 360 uint32_t oper_channel = SAP_CHANNEL_NOT_SELECTED; 361 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 362 363 host_log_acs_scan_done(acs_scan_done_status_str(scan_status), 364 sessionid, scanid); 365 366 if (sap_ctx->optimize_acs_chan_selected) { 367 sap_debug("SAP channel selected using first clean channel, ignore scan complete event"); 368 return QDF_STATUS_SUCCESS; 369 } 370 371 /* This has to be done before the ACS selects default channel */ 372 wlansap_filter_unsafe_ch(mac_ctx->psoc, sap_ctx); 373 374 wlan_sap_filter_non_preferred_channels(mac_ctx->pdev, sap_ctx); 375 if (!sap_ctx->acs_cfg->ch_list_count) { 376 oper_channel = 377 sap_select_default_oper_chan(mac_ctx, 378 sap_ctx->acs_cfg); 379 sap_ctx->chan_freq = oper_channel; 380 sap_ctx->acs_cfg->pri_ch_freq = oper_channel; 381 sap_config_acs_result(mac_handle, sap_ctx, 382 sap_ctx->acs_cfg->ht_sec_ch_freq); 383 sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; 384 sap_ctx->sap_status = eSAP_STATUS_SUCCESS; 385 goto close_session; 386 } 387 if (eCSR_SCAN_SUCCESS != scan_status) { 388 sap_err("CSR scan_status = eCSR_SCAN_ABORT/FAILURE (%d), choose default channel", 389 scan_status); 390 oper_channel = 391 sap_select_default_oper_chan(mac_ctx, 392 sap_ctx->acs_cfg); 393 wlansap_set_acs_ch_freq(sap_ctx, oper_channel); 394 sap_ctx->acs_cfg->pri_ch_freq = oper_channel; 395 sap_config_acs_result(mac_handle, sap_ctx, 396 sap_ctx->acs_cfg->ht_sec_ch_freq); 397 sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; 398 sap_ctx->sap_status = eSAP_STATUS_SUCCESS; 399 goto close_session; 400 } 401 sap_debug("CSR scan_status = eCSR_SCAN_SUCCESS (%d)", scan_status); 402 403 oper_channel = wlansap_calculate_chan_from_scan_result(mac_handle, 404 sap_ctx, scanid); 405 406 if (oper_channel == SAP_CHANNEL_NOT_SELECTED) { 407 sap_info("No suitable channel, so select default channel"); 408 oper_channel = sap_select_default_oper_chan(mac_ctx, 409 sap_ctx->acs_cfg); 410 } 411 412 wlansap_set_acs_ch_freq(sap_ctx, oper_channel); 413 sap_ctx->acs_cfg->pri_ch_freq = oper_channel; 414 sap_config_acs_result(mac_handle, sap_ctx, 415 sap_ctx->acs_cfg->ht_sec_ch_freq); 416 417 wlansap_dump_acs_ch_freq(sap_ctx); 418 419 sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; 420 sap_ctx->sap_status = eSAP_STATUS_SUCCESS; 421 close_session: 422 #ifdef SOFTAP_CHANNEL_RANGE 423 if (sap_ctx->freq_list) { 424 /* 425 * Always free up the memory for 426 * channel selection whatever 427 * the result 428 */ 429 qdf_mem_free(sap_ctx->freq_list); 430 sap_ctx->freq_list = NULL; 431 sap_ctx->num_of_channel = 0; 432 } 433 #endif 434 sap_hdd_signal_event_handler(sap_ctx); 435 436 return QDF_STATUS_SUCCESS; 437 } 438 439 /** 440 * wlansap_roam_process_ch_change_success() - handles the case for 441 * eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS in function wlansap_roam_callback() 442 * 443 * @mac_ctx: mac global context 444 * @sap_ctx: sap context 445 * @csr_roam_info: raom info struct 446 * @ret_status: update return status 447 * 448 * Return: void 449 */ 450 static void 451 wlansap_roam_process_ch_change_success(struct mac_context *mac_ctx, 452 struct sap_context *sap_ctx, 453 struct csr_roam_info *csr_roam_info, 454 QDF_STATUS *ret_status) 455 { 456 struct sap_sm_event sap_event; 457 QDF_STATUS qdf_status; 458 bool is_ch_dfs = false; 459 uint32_t target_chan_freq; 460 eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; 461 462 /* 463 * Channel change is successful. If the new channel is a DFS channel, 464 * then we will to perform channel availability check for 60 seconds 465 */ 466 sap_nofl_debug("sap_fsm: vdev %d: sapdfs: SAP CSA: freq %d state %d", 467 sap_ctx->vdev_id, 468 mac_ctx->sap.SapDfsInfo.target_chan_freq, 469 sap_ctx->fsm_state); 470 target_chan_freq = mac_ctx->sap.SapDfsInfo.target_chan_freq; 471 472 /* If SAP is not in starting or started state don't proceed further */ 473 if (sap_ctx->fsm_state == SAP_INIT || 474 sap_ctx->fsm_state == SAP_STOPPING) { 475 sap_info("sap_fsm: vdev %d: sapdfs: state %d, not starting SAP after channel change", 476 sap_ctx->vdev_id, sap_ctx->fsm_state); 477 return; 478 } 479 480 if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { 481 struct ch_params ch_params = {0}; 482 483 wlan_reg_set_create_punc_bitmap(&ch_params, true); 484 ch_params.ch_width = sap_ctx->ch_params.ch_width; 485 if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev, 486 target_chan_freq, 487 &ch_params, 488 REG_CURRENT_PWR_MODE) == 489 CHANNEL_STATE_DFS) 490 is_ch_dfs = true; 491 } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { 492 if (wlan_reg_get_channel_state_for_pwrmode( 493 mac_ctx->pdev, 494 target_chan_freq, 495 REG_CURRENT_PWR_MODE) == 496 CHANNEL_STATE_DFS || 497 wlan_reg_get_channel_state_for_pwrmode( 498 mac_ctx->pdev, 499 sap_ctx->ch_params.mhz_freq_seg1, 500 REG_CURRENT_PWR_MODE) == 501 CHANNEL_STATE_DFS) 502 is_ch_dfs = true; 503 } else { 504 /* Indoor channels are also marked DFS, therefore 505 * check if the channel has REGULATORY_CHAN_RADAR 506 * channel flag to identify if the channel is DFS 507 */ 508 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, target_chan_freq)) 509 is_ch_dfs = true; 510 } 511 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) 512 is_ch_dfs = false; 513 514 sap_ctx->fsm_state = SAP_STARTING; 515 sap_debug("sap_fsm: vdev %d: => SAP_STARTING", sap_ctx->vdev_id); 516 sap_ctx->chan_freq = target_chan_freq; 517 /* check if currently selected channel is a DFS channel */ 518 if (is_ch_dfs && wlan_pre_cac_complete_get(sap_ctx->vdev)) { 519 sap_ctx->sap_radar_found_status = false; 520 sap_event.event = eSAP_MAC_START_BSS_SUCCESS; 521 sap_event.params = csr_roam_info; 522 sap_event.u1 = eCSR_ROAM_INFRA_IND; 523 sap_event.u2 = eCSR_ROAM_RESULT_INFRA_STARTED; 524 } else if (is_ch_dfs) { 525 if (sap_plus_sap_cac_skip(mac_ctx, sap_ctx, 526 sap_ctx->chan_freq)) 527 cac_state = eSAP_DFS_SKIP_CAC; 528 if ((false == mac_ctx->sap.SapDfsInfo.ignore_cac) && 529 (cac_state == eSAP_DFS_DO_NOT_SKIP_CAC) && 530 policy_mgr_get_dfs_master_dynamic_enabled( 531 mac_ctx->psoc, 532 sap_ctx->sessionId)) { 533 /* DFS Channel */ 534 sap_event.event = eSAP_DFS_CHANNEL_CAC_START; 535 sap_event.params = csr_roam_info; 536 sap_event.u1 = 0; 537 sap_event.u2 = 0; 538 } else { 539 sap_ctx->sap_radar_found_status = false; 540 sap_event.event = eSAP_MAC_START_BSS_SUCCESS; 541 sap_event.params = csr_roam_info; 542 sap_event.u1 = eCSR_ROAM_INFRA_IND; 543 sap_event.u2 = eCSR_ROAM_RESULT_INFRA_STARTED; 544 } 545 } else { 546 /* non-DFS channel */ 547 sap_ctx->sap_radar_found_status = false; 548 sap_event.event = eSAP_MAC_START_BSS_SUCCESS; 549 sap_event.params = csr_roam_info; 550 sap_event.u1 = eCSR_ROAM_INFRA_IND; 551 sap_event.u2 = eCSR_ROAM_RESULT_INFRA_STARTED; 552 } 553 554 /* Handle the event */ 555 qdf_status = sap_fsm(sap_ctx, &sap_event); 556 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 557 *ret_status = QDF_STATUS_E_FAILURE; 558 } 559 560 /** 561 * wlansap_roam_process_dfs_chansw_update() - handles the case for 562 * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS in wlansap_roam_callback() 563 * 564 * @mac_handle: opaque handle to the global MAC context 565 * @sap_ctx: sap context 566 * @ret_status: update return status 567 * 568 * Return: void 569 */ 570 static void 571 wlansap_roam_process_dfs_chansw_update(mac_handle_t mac_handle, 572 struct sap_context *sap_ctx, 573 QDF_STATUS *ret_status) 574 { 575 uint8_t intf; 576 QDF_STATUS qdf_status; 577 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 578 uint8_t dfs_beacon_start_req = 0; 579 bool sap_scc_dfs; 580 581 if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) { 582 sap_err("sapdfs: DFS channel switch disabled"); 583 /* 584 * Send a beacon start request to PE. CSA IE required flag from 585 * beacon template will be cleared by now. A new beacon template 586 * with no CSA IE will be sent to firmware. 587 */ 588 dfs_beacon_start_req = true; 589 wlan_pre_cac_complete_set(sap_ctx->vdev, false); 590 *ret_status = sme_roam_start_beacon_req(mac_handle, 591 sap_ctx->bssid, 592 dfs_beacon_start_req); 593 return; 594 } 595 /* 596 * Irrespective of whether the channel switch IE was sent out 597 * successfully or not, SAP should still vacate the channel immediately 598 */ 599 if (sap_ctx->fsm_state != SAP_STARTED) { 600 /* Further actions to be taken here */ 601 sap_warn("eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in (%d) state", 602 sap_ctx->fsm_state); 603 return; 604 } 605 sap_ctx->is_chan_change_inprogress = true; 606 /* 607 * The associated stations have been informed to move to a different 608 * channel. However, the AP may not always select the advertised channel 609 * for operation if the radar is seen. In that case, the stations will 610 * experience link-loss and return back through scanning if they wish to 611 */ 612 613 /* 614 * Send channel change request. From spec it is required that the AP 615 * should continue to operate in the same mode as it is operating 616 * currently. For e.g. 20/40/80 MHz operation 617 */ 618 if (mac_ctx->sap.SapDfsInfo.target_chan_freq) { 619 if (sap_phymode_is_eht(sap_ctx->phyMode)) 620 wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params, 621 true); 622 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, 623 mac_ctx->sap.SapDfsInfo.target_chan_freq, 624 0, &sap_ctx->ch_params, REG_CURRENT_PWR_MODE); 625 } 626 627 /* 628 * Fetch the number of SAP interfaces. If the number of sap Interface 629 * more than one then we will make is_sap_ready_for_chnl_chng to true 630 * for that sapctx. If there is only one SAP interface then process 631 * immediately. If Dual BAND SAP OR SBS in different mac, is enabled 632 * then also process immediately, as in this case the both SAP will be 633 * in different band and channel change on one SAP doesn't mean channel 634 * change on other interface. 635 * 636 * For example, 637 * Let's say SAP(2G) + SAP(5G-DFS) is initial connection which triggered 638 * DualBand HW mode and if SAP(5G-DFS) is moving to some channel then 639 * SAP(2G) doesn't need to move. 640 * 641 * If both SAPs are not doing SCC DFS then each of them can change the 642 * channel independently. Channel change of one SAP became dependent 643 * second SAP's channel change due to some previous platform's single 644 * radio limitation. 645 * 646 * For DCS case, SAP will do channel switch one by one. 647 * 648 */ 649 sap_scc_dfs = sap_is_conc_sap_doing_scc_dfs(mac_handle, sap_ctx); 650 if (sap_get_total_number_sap_intf(mac_handle) <= 1 || 651 policy_mgr_is_current_hwmode_dbs(mac_ctx->psoc) || 652 policy_mgr_is_current_hwmode_sbs(mac_ctx->psoc) || 653 sap_ctx->csa_reason == CSA_REASON_DCS || 654 !sap_scc_dfs) { 655 /* 656 * Most likely, radar has been detected and SAP wants to 657 * change the channel 658 */ 659 qdf_status = wlansap_channel_change_request(sap_ctx, 660 mac_ctx->sap.SapDfsInfo.target_chan_freq); 661 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 662 *ret_status = QDF_STATUS_E_FAILURE; 663 return; 664 } 665 666 sap_ctx->is_sap_ready_for_chnl_chng = true; 667 /* 668 * now check if the con-current sap interface is ready 669 * for channel change. If yes then we issue channel change for 670 * both the SAPs. If no then simply return success & we will 671 * issue channel change when second AP's 5 CSA beacon Tx is 672 * completed. 673 * 674 * This check is added to take care of following scenario: 675 * if SAP1 + SAP2 is doing DFS SCC and radar is detected on that channel 676 * then SAP1 sends 5 beacons with CSA/ECSA IE and wait for SAP2 to 677 * finish sending 5 beacons. if SAP1 changes channel before SAP2 finish 678 * sending beacons then it ends up in 679 * (SAP1 new channel + SAP2 old channel) MCC with DFS scenario 680 * which causes some of the stability issues in old platforms. 681 */ 682 if (false == 683 is_concurrent_sap_ready_for_channel_change(mac_handle, sap_ctx)) { 684 sap_debug("sapdfs: sapctx[%pK] ready but not concurrent sap", 685 sap_ctx); 686 *ret_status = QDF_STATUS_SUCCESS; 687 return; 688 } 689 690 /* Issue channel change req for each sapctx */ 691 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 692 struct sap_context *sap_context; 693 694 if (!((QDF_SAP_MODE == mac_ctx->sap.sapCtxList[intf].sapPersona || 695 QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[intf].sapPersona) 696 && (mac_ctx->sap.sapCtxList[intf].sap_context))) 697 continue; 698 sap_context = mac_ctx->sap.sapCtxList[intf].sap_context; 699 sap_debug("sapdfs:issue chnl change for sapctx[%pK]", 700 sap_context); 701 /* 702 * Most likely, radar has been detected and SAP wants to 703 * change the channel 704 */ 705 qdf_status = wlansap_channel_change_request(sap_context, 706 mac_ctx->sap.SapDfsInfo.target_chan_freq); 707 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 708 sap_err("post chnl chng req failed, sap[%pK]", sap_ctx); 709 *ret_status = QDF_STATUS_E_FAILURE; 710 } else { 711 sap_context->is_sap_ready_for_chnl_chng = false; 712 } 713 } 714 return; 715 } 716 717 /** 718 * wlansap_roam_process_dfs_radar_found() - handles the case for 719 * eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND in wlansap_roam_callback() 720 * 721 * @mac_ctx: mac global context 722 * @sap_ctx: sap context 723 * @ret_status: update return status 724 * 725 * Return: result of operation 726 */ 727 static void 728 wlansap_roam_process_dfs_radar_found(struct mac_context *mac_ctx, 729 struct sap_context *sap_ctx, 730 QDF_STATUS *ret_status) 731 { 732 QDF_STATUS qdf_status; 733 struct sap_sm_event sap_event; 734 735 if (sap_is_dfs_cac_wait_state(sap_ctx)) { 736 if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) { 737 sap_err("sapdfs: DFS channel switch disabled"); 738 return; 739 } 740 if (!sap_ctx->sap_radar_found_status) { 741 sap_err("sapdfs: sap_radar_found_status is false"); 742 return; 743 } 744 745 sap_debug("sapdfs:Posting event eSAP_DFS_CHANNEL_CAC_RADAR_FOUND"); 746 /* 747 * If Radar is found, while in DFS CAC WAIT State then post stop 748 * and destroy the CAC timer and post a 749 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND to sapFsm. 750 */ 751 if (!sap_ctx->dfs_cac_offload) { 752 qdf_mc_timer_stop(&mac_ctx-> 753 sap.SapDfsInfo.sap_dfs_cac_timer); 754 qdf_mc_timer_destroy(&mac_ctx-> 755 sap.SapDfsInfo.sap_dfs_cac_timer); 756 } 757 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 758 mac_ctx->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 759 760 /* 761 * User space is already indicated the CAC start and if 762 * CAC end on this channel is not indicated, the user 763 * space will be in some undefined state (e.g., UI frozen) 764 */ 765 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 766 eSAP_DFS_CAC_INTERRUPTED, 767 (void *) eSAP_STATUS_SUCCESS); 768 if (QDF_STATUS_SUCCESS != qdf_status) { 769 sap_err("Failed to send CAC end"); 770 /* Want to still proceed and try to switch channel. 771 * Lets try not to be on the DFS channel 772 */ 773 } 774 775 sap_event.event = eSAP_DFS_CHANNEL_CAC_RADAR_FOUND; 776 sap_event.params = 0; 777 sap_event.u1 = 0; 778 sap_event.u2 = 0; 779 qdf_status = sap_fsm(sap_ctx, &sap_event); 780 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 781 *ret_status = QDF_STATUS_E_FAILURE; 782 return; 783 } 784 if (sap_ctx->fsm_state == SAP_STARTED) { 785 sap_debug("sapdfs:Posting event eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START"); 786 787 /* 788 * Radar found on the operating channel in STARTED state, 789 * new operating channel has already been selected. Send 790 * request to SME-->PE for sending CSA IE 791 */ 792 sap_event.event = eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START; 793 sap_event.params = 0; 794 sap_event.u1 = 0; 795 sap_event.u2 = 0; 796 qdf_status = sap_fsm(sap_ctx, &sap_event); 797 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 798 *ret_status = QDF_STATUS_E_FAILURE; 799 return; 800 } 801 /* Further actions to be taken here */ 802 sap_err("eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in (%d) state", 803 sap_ctx->fsm_state); 804 805 return; 806 } 807 808 /** 809 * wlansap_roam_process_infra_assoc_ind() - handles the case for 810 * eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND in wlansap_roam_callback() 811 * 812 * @sap_ctx: sap context 813 * @roam_result: roam result 814 * @csr_roam_info: roam info struct 815 * @ret_status: update return status 816 * 817 * Return: result of operation 818 */ 819 static void 820 wlansap_roam_process_infra_assoc_ind(struct sap_context *sap_ctx, 821 eCsrRoamResult roam_result, 822 struct csr_roam_info *csr_roam_info, 823 QDF_STATUS *ret_status) 824 { 825 QDF_STATUS qdf_status; 826 827 sap_debug("CSR roam_result = eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND (%d)", 828 roam_result); 829 sap_ctx->nStaWPARSnReqIeLength = csr_roam_info->rsnIELen; 830 if (sap_ctx->nStaWPARSnReqIeLength) 831 qdf_mem_copy(sap_ctx->pStaWpaRsnReqIE, csr_roam_info->prsnIE, 832 sap_ctx->nStaWPARSnReqIeLength); 833 /* MAC filtering */ 834 qdf_status = sap_is_peer_mac_allowed(sap_ctx, 835 (uint8_t *) csr_roam_info->peerMac.bytes); 836 837 if (QDF_STATUS_SUCCESS == qdf_status) { 838 qdf_status = sap_signal_hdd_event(sap_ctx, 839 csr_roam_info, eSAP_STA_ASSOC_IND, 840 (void *) eSAP_STATUS_SUCCESS); 841 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 842 sap_err("CSR roam_result = (%d) MAC ("QDF_MAC_ADDR_FMT") fail", 843 roam_result, QDF_MAC_ADDR_REF( 844 csr_roam_info->peerMac.bytes)); 845 *ret_status = QDF_STATUS_E_FAILURE; 846 } 847 } else { 848 sap_warn("CSR roam_result = (%d) MAC ("QDF_MAC_ADDR_FMT") not allowed", 849 roam_result, 850 QDF_MAC_ADDR_REF(csr_roam_info->peerMac.bytes)); 851 *ret_status = QDF_STATUS_E_FAILURE; 852 } 853 return; 854 } 855 856 static void wlansap_update_vendor_acs_chan(struct mac_context *mac_ctx, 857 struct sap_context *sap_ctx) 858 { 859 int intf; 860 861 if (!mac_ctx) { 862 sap_err("Invalid MAC context"); 863 return; 864 } 865 866 mac_ctx->sap.SapDfsInfo.target_chan_freq = 867 wlan_reg_legacy_chan_to_freq( 868 mac_ctx->pdev, 869 sap_ctx->dfs_vendor_channel); 870 871 mac_ctx->sap.SapDfsInfo.new_chanWidth = 872 sap_ctx->dfs_vendor_chan_bw; 873 mac_ctx->sap.SapDfsInfo.new_ch_params.ch_width = 874 sap_ctx->dfs_vendor_chan_bw; 875 876 if (mac_ctx->sap.SapDfsInfo.target_chan_freq != 0) { 877 sap_cac_reset_notify(MAC_HANDLE(mac_ctx)); 878 return; 879 } 880 /* App failed to provide new channel, try random channel algo */ 881 sap_warn("Failed to get channel from userspace"); 882 883 /* Issue stopbss for each sapctx */ 884 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 885 struct sap_context *sap_context; 886 887 if (((QDF_SAP_MODE == 888 mac_ctx->sap.sapCtxList[intf].sapPersona) || 889 (QDF_P2P_GO_MODE == 890 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 891 mac_ctx->sap.sapCtxList[intf].sap_context != 892 NULL) { 893 sap_context = 894 mac_ctx->sap.sapCtxList[intf].sap_context; 895 sap_err("sapdfs: no available channel for sapctx[%pK], StopBss", 896 sap_context); 897 wlansap_stop_bss(sap_context); 898 } 899 } 900 } 901 902 #ifdef WLAN_FEATURE_P2P_P2P_STA 903 /** 904 * sap_check_and_process_forcescc_for_go_plus_go() - find if other p2p 905 * go is there and needs to be moved to current p2p go's channel. 906 * 907 * @cur_sap_ctx: current sap context 908 * 909 * Return: None 910 */ 911 static void 912 sap_check_and_process_forcescc_for_go_plus_go( 913 struct sap_context *cur_sap_ctx) 914 { 915 struct sap_context *sap_ctx; 916 struct mac_context *mac_ctx; 917 uint8_t i; 918 919 mac_ctx = sap_get_mac_context(); 920 if (!mac_ctx) { 921 sap_err("Invalid MAC context"); 922 return; 923 } 924 925 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 926 sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context; 927 if (sap_ctx && 928 QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona && 929 sap_ctx->is_forcescc_restart_required && 930 cur_sap_ctx->sessionId != sap_ctx->sessionId) { 931 sap_debug("update chan_freq %d of sessionId %d with chan_freq %d", 932 sap_ctx->chan_freq, sap_ctx->sessionId, 933 cur_sap_ctx->chan_freq); 934 policy_mgr_process_forcescc_for_go( 935 mac_ctx->psoc, sap_ctx->sessionId, 936 cur_sap_ctx->chan_freq, 937 cur_sap_ctx->ch_params.ch_width, 938 PM_P2P_GO_MODE); 939 sap_ctx->is_forcescc_restart_required = false; 940 break; 941 } 942 } 943 } 944 945 /** 946 * sap_check_and_process_go_force_scc() - find if other p2p go/cli/sta 947 * is there and needs force scc. 948 * @sap_ctx: current sap context 949 * 950 * Return: None 951 */ 952 static void 953 sap_check_and_process_go_force_scc(struct sap_context *sap_ctx) 954 { 955 struct mac_context *mac_ctx; 956 uint32_t con_freq; 957 enum phy_ch_width ch_width; 958 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 959 960 mac_ctx = sap_get_mac_context(); 961 if (!mac_ctx) { 962 sap_err("Invalid MAC context"); 963 return; 964 } 965 if (sap_ctx->vdev->vdev_mlme.vdev_opmode == 966 QDF_P2P_GO_MODE && 967 wlan_vdev_get_peer_count(sap_ctx->vdev) == 2 && 968 policy_mgr_mode_specific_connection_count( 969 mac_ctx->psoc, PM_P2P_GO_MODE, NULL) > 1) { 970 sap_check_and_process_forcescc_for_go_plus_go(sap_ctx); 971 return; 972 } 973 policy_mgr_fetch_existing_con_info(mac_ctx->psoc, sap_ctx->sessionId, 974 sap_ctx->chan_freq, 975 &existing_vdev_mode, 976 &con_freq, &ch_width); 977 978 if (sap_ctx->vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE && 979 policy_mgr_go_scc_enforced(mac_ctx->psoc) && 980 !policy_mgr_is_go_scc_strict(mac_ctx->psoc) && 981 wlan_vdev_get_peer_count(sap_ctx->vdev) == 2 && 982 (existing_vdev_mode == PM_P2P_CLIENT_MODE || 983 existing_vdev_mode == PM_STA_MODE)){ 984 policy_mgr_process_forcescc_for_go(mac_ctx->psoc, 985 sap_ctx->sessionId, 986 con_freq, ch_width, 987 existing_vdev_mode); 988 } 989 } 990 #else 991 static inline void 992 sap_check_and_process_forcescc_for_go_plus_go( 993 struct sap_context *cur_sap_ctx) 994 {} 995 static inline void 996 sap_check_and_process_go_force_scc(struct sap_context *sap_ctx) 997 {} 998 #endif 999 1000 /** 1001 * sap_is_csa_restart_state() - check if sap is in csa restart state 1002 * @psoc: PSOC object 1003 * @sap_ctx: sap context to check 1004 * 1005 * Return: true if sap is in csa restart state 1006 */ 1007 static bool sap_is_csa_restart_state(struct wlan_objmgr_psoc *psoc, 1008 struct sap_context *sap_ctx) 1009 { 1010 struct wlan_objmgr_vdev *vdev; 1011 QDF_STATUS status; 1012 1013 if (!psoc || !sap_ctx) { 1014 sap_err("Invalid params"); 1015 return false; 1016 } 1017 1018 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 1019 sap_ctx->sessionId, 1020 WLAN_DFS_ID); 1021 if (!vdev) { 1022 sap_err("vdev is NULL for vdev_id: %u", sap_ctx->sessionId); 1023 return false; 1024 } 1025 1026 status = wlan_vdev_mlme_is_csa_restart(vdev); 1027 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 1028 1029 return QDF_IS_STATUS_SUCCESS(status); 1030 } 1031 1032 #ifdef PRE_CAC_SUPPORT 1033 static void wlan_sap_pre_cac_radar_ind(struct sap_context *sap_ctx, 1034 struct mac_context *mac_ctx) 1035 { 1036 qdf_mc_timer_t *dfs_timer = &mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer; 1037 1038 sap_debug("sapdfs: Radar detect on pre cac:%d", sap_ctx->sessionId); 1039 if (!sap_ctx->dfs_cac_offload) { 1040 qdf_mc_timer_stop(dfs_timer); 1041 qdf_mc_timer_destroy(dfs_timer); 1042 } 1043 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 1044 mac_ctx->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 1045 1046 wlan_pre_cac_handle_radar_ind(sap_ctx->vdev); 1047 } 1048 #else 1049 static inline void 1050 wlan_sap_pre_cac_radar_ind(struct sap_context *sap_ctx, 1051 struct mac_context *mac_ctx) 1052 { 1053 } 1054 #endif 1055 1056 QDF_STATUS wlansap_roam_callback(void *ctx, 1057 struct csr_roam_info *csr_roam_info, 1058 eRoamCmdStatus roam_status, 1059 eCsrRoamResult roam_result) 1060 { 1061 /* sap_ctx value */ 1062 struct sap_context *sap_ctx = ctx; 1063 /* State machine event */ 1064 struct sap_sm_event sap_event; 1065 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1066 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; 1067 mac_handle_t mac_handle; 1068 struct mac_context *mac_ctx; 1069 uint8_t intf; 1070 1071 if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_ctx))) 1072 return QDF_STATUS_E_FAILURE; 1073 1074 mac_ctx = sap_get_mac_context(); 1075 if (!mac_ctx) { 1076 sap_err("Invalid MAC context"); 1077 wlansap_context_put(sap_ctx); 1078 return QDF_STATUS_E_NOMEM; 1079 } 1080 sap_debug("CSR roam_status = %s(%d), roam_result = %s(%d)", 1081 get_e_roam_cmd_status_str(roam_status), roam_status, 1082 get_e_csr_roam_result_str(roam_result), roam_result); 1083 1084 mac_handle = MAC_HANDLE(mac_ctx); 1085 1086 switch (roam_status) { 1087 case eCSR_ROAM_INFRA_IND: 1088 if (roam_result == eCSR_ROAM_RESULT_INFRA_START_FAILED) { 1089 /* Fill in the event structure */ 1090 sap_event.event = eSAP_MAC_START_FAILS; 1091 sap_event.params = csr_roam_info; 1092 sap_event.u1 = roam_status; 1093 sap_event.u2 = roam_result; 1094 /* Handle event */ 1095 qdf_status = sap_fsm(sap_ctx, &sap_event); 1096 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1097 qdf_ret_status = QDF_STATUS_E_FAILURE; 1098 } 1099 break; 1100 case eCSR_ROAM_LOSTLINK: 1101 break; 1102 case eCSR_ROAM_MIC_ERROR_IND: 1103 break; 1104 case eCSR_ROAM_SET_KEY_COMPLETE: 1105 if (roam_result == eCSR_ROAM_RESULT_FAILURE) 1106 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1107 eSAP_STA_SET_KEY_EVENT, 1108 (void *) eSAP_STATUS_FAILURE); 1109 break; 1110 case eCSR_ROAM_WPS_PBC_PROBE_REQ_IND: 1111 break; 1112 case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS: 1113 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1114 eSAP_DISCONNECT_ALL_P2P_CLIENT, 1115 (void *) eSAP_STATUS_SUCCESS); 1116 break; 1117 case eCSR_ROAM_SEND_P2P_STOP_BSS: 1118 sap_debug("Received stopbss"); 1119 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1120 eSAP_MAC_TRIG_STOP_BSS_EVENT, 1121 (void *) eSAP_STATUS_SUCCESS); 1122 break; 1123 case eCSR_ROAM_CHANNEL_COMPLETE_IND: 1124 sap_debug("Received new channel from app"); 1125 wlansap_update_vendor_acs_chan(mac_ctx, sap_ctx); 1126 break; 1127 1128 case eCSR_ROAM_DFS_RADAR_IND: 1129 sap_debug("Rcvd Radar Indication on sap ch freq %d, session %d", 1130 sap_ctx->chan_freq, sap_ctx->sessionId); 1131 1132 if (!policy_mgr_get_dfs_master_dynamic_enabled( 1133 mac_ctx->psoc, sap_ctx->sessionId)) { 1134 sap_debug("Ignore the Radar indication"); 1135 goto EXIT; 1136 } 1137 1138 if (sap_ctx->fsm_state != SAP_STARTED && 1139 !sap_is_dfs_cac_wait_state(sap_ctx)) { 1140 sap_debug("Ignore Radar event in sap state %d cac wait state %d", 1141 sap_ctx->fsm_state, 1142 sap_is_dfs_cac_wait_state(sap_ctx)); 1143 goto EXIT; 1144 } 1145 1146 if (sap_ctx->fsm_state == SAP_STARTED && 1147 sap_is_csa_restart_state(mac_ctx->psoc, sap_ctx)) { 1148 sap_debug("Ignore Radar event in csa restart state"); 1149 goto EXIT; 1150 } 1151 1152 if (!sap_chan_bond_dfs_sub_chan( 1153 sap_ctx, sap_ctx->chan_freq, 1154 PHY_CHANNEL_BONDING_STATE_MAX)) { 1155 sap_debug("Ignore Radar event for sap ch freq: %d", 1156 sap_ctx->chan_freq); 1157 goto EXIT; 1158 } 1159 1160 if (wlan_pre_cac_get_status(mac_ctx->psoc)) { 1161 wlan_sap_pre_cac_radar_ind(sap_ctx, mac_ctx); 1162 break; 1163 } 1164 1165 sap_debug("sapdfs: Indicate eSAP_DFS_RADAR_DETECT to HDD"); 1166 sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_RADAR_DETECT, 1167 (void *) eSAP_STATUS_SUCCESS); 1168 mac_ctx->sap.SapDfsInfo.target_chan_freq = 1169 sap_indicate_radar(sap_ctx); 1170 1171 /* if there is an assigned next channel hopping */ 1172 if (0 < mac_ctx->sap.SapDfsInfo.user_provided_target_chan_freq) { 1173 mac_ctx->sap.SapDfsInfo.target_chan_freq = 1174 mac_ctx->sap.SapDfsInfo.user_provided_target_chan_freq; 1175 mac_ctx->sap.SapDfsInfo.user_provided_target_chan_freq = 1176 0; 1177 } 1178 /* if external acs enabled */ 1179 if (sap_ctx->vendor_acs_dfs_lte_enabled && 1180 !mac_ctx->sap.SapDfsInfo.target_chan_freq) { 1181 /* Return from here, processing will be done later */ 1182 goto EXIT; 1183 } 1184 if (mac_ctx->sap.SapDfsInfo.target_chan_freq != 0) { 1185 sap_cac_reset_notify(mac_handle); 1186 break; 1187 } 1188 /* Issue stopbss for each sapctx */ 1189 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1190 struct sap_context *sap_context; 1191 1192 if (((QDF_SAP_MODE == 1193 mac_ctx->sap.sapCtxList[intf].sapPersona) || 1194 (QDF_P2P_GO_MODE == 1195 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 1196 mac_ctx->sap.sapCtxList[intf].sap_context != 1197 NULL) { 1198 sap_context = 1199 mac_ctx->sap.sapCtxList[intf].sap_context; 1200 if (!wlan_reg_is_passive_or_disable_for_pwrmode( 1201 mac_ctx->pdev, 1202 sap_context->chan_freq, 1203 REG_CURRENT_PWR_MODE)) 1204 continue; 1205 sap_debug("Vdev %d no channel available , stop bss", 1206 sap_context->sessionId); 1207 sap_signal_hdd_event(sap_context, NULL, 1208 eSAP_STOP_BSS_DUE_TO_NO_CHNL, 1209 (void *) eSAP_STATUS_SUCCESS); 1210 } 1211 } 1212 break; 1213 case eCSR_ROAM_DFS_CHAN_SW_NOTIFY: 1214 sap_debug("Received Chan Sw Update Notification"); 1215 break; 1216 case eCSR_ROAM_SET_CHANNEL_RSP: 1217 sap_debug("Received set channel response"); 1218 ucfg_if_mgr_deliver_event(sap_ctx->vdev, 1219 WLAN_IF_MGR_EV_AP_CSA_COMPLETE, 1220 NULL); 1221 break; 1222 case eCSR_ROAM_CAC_COMPLETE_IND: 1223 sap_debug("Received cac complete indication"); 1224 break; 1225 case eCSR_ROAM_EXT_CHG_CHNL_IND: 1226 sap_debug("Received set channel Indication"); 1227 break; 1228 case eCSR_ROAM_CHANNEL_INFO_EVENT_IND: 1229 wlansap_process_chan_info_event(sap_ctx, csr_roam_info); 1230 break; 1231 default: 1232 break; 1233 } 1234 1235 switch (roam_result) { 1236 case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND: 1237 if (csr_roam_info) 1238 wlansap_roam_process_infra_assoc_ind(sap_ctx, 1239 roam_result, 1240 csr_roam_info, &qdf_ret_status); 1241 break; 1242 case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF: 1243 if (!csr_roam_info) { 1244 sap_err("csr_roam_info is NULL"); 1245 qdf_ret_status = QDF_STATUS_E_NULL_VALUE; 1246 break; 1247 } 1248 sap_ctx->nStaWPARSnReqIeLength = csr_roam_info->rsnIELen; 1249 if (sap_ctx->nStaWPARSnReqIeLength) 1250 qdf_mem_copy(sap_ctx->pStaWpaRsnReqIE, 1251 csr_roam_info->prsnIE, 1252 sap_ctx->nStaWPARSnReqIeLength); 1253 1254 /* Fill in the event structure */ 1255 qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, 1256 eSAP_STA_ASSOC_EVENT, 1257 (void *) eSAP_STATUS_SUCCESS); 1258 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1259 qdf_ret_status = QDF_STATUS_E_FAILURE; 1260 break; 1261 case eCSR_ROAM_RESULT_DEAUTH_IND: 1262 case eCSR_ROAM_RESULT_DISASSOC_IND: 1263 /* Fill in the event structure */ 1264 qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, 1265 eSAP_STA_DISASSOC_EVENT, 1266 (void *) eSAP_STATUS_SUCCESS); 1267 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1268 qdf_ret_status = QDF_STATUS_E_FAILURE; 1269 break; 1270 case eCSR_ROAM_RESULT_MIC_ERROR_GROUP: 1271 /* 1272 * Fill in the event structure 1273 * TODO: support for group key MIC failure event to be handled 1274 */ 1275 qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, 1276 eSAP_STA_MIC_FAILURE_EVENT, 1277 (void *) NULL); 1278 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1279 qdf_ret_status = QDF_STATUS_E_FAILURE; 1280 break; 1281 case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST: 1282 /* 1283 * Fill in the event structure 1284 * TODO: support for unicast key MIC failure event to be handled 1285 */ 1286 qdf_status = 1287 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1288 eSAP_STA_MIC_FAILURE_EVENT, 1289 (void *) NULL); 1290 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1291 qdf_ret_status = QDF_STATUS_E_FAILURE; 1292 } 1293 break; 1294 case eCSR_ROAM_RESULT_AUTHENTICATED: 1295 /* Fill in the event structure */ 1296 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1297 eSAP_STA_SET_KEY_EVENT, 1298 (void *) eSAP_STATUS_SUCCESS); 1299 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1300 qdf_ret_status = QDF_STATUS_E_FAILURE; 1301 break; 1302 case eCSR_ROAM_RESULT_INFRA_STARTED: 1303 if (!csr_roam_info) { 1304 sap_err("csr_roam_info is NULL"); 1305 qdf_ret_status = QDF_STATUS_E_NULL_VALUE; 1306 break; 1307 } 1308 /* 1309 * In the current implementation, hostapd is not aware that 1310 * drive will support DFS. Hence, driver should inform 1311 * eSAP_MAC_START_BSS_SUCCESS to upper layers and then perform 1312 * CAC underneath 1313 */ 1314 sap_event.event = eSAP_MAC_START_BSS_SUCCESS; 1315 sap_event.params = csr_roam_info; 1316 sap_ctx->sap_sta_id = csr_roam_info->staId; 1317 sap_event.u1 = roam_status; 1318 sap_event.u2 = roam_result; 1319 qdf_status = sap_fsm(sap_ctx, &sap_event); 1320 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1321 qdf_ret_status = QDF_STATUS_E_FAILURE; 1322 break; 1323 case eCSR_ROAM_RESULT_INFRA_STOPPED: 1324 /* Fill in the event structure */ 1325 sap_event.event = eSAP_MAC_READY_FOR_CONNECTIONS; 1326 sap_event.params = csr_roam_info; 1327 sap_event.u1 = roam_status; 1328 sap_event.u2 = roam_result; 1329 /* Handle event */ 1330 qdf_status = sap_fsm(sap_ctx, &sap_event); 1331 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1332 qdf_ret_status = QDF_STATUS_E_FAILURE; 1333 break; 1334 case eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND: 1335 /* 1336 * Fill in the event structure 1337 * TODO: support for group key MIC failure event to be handled 1338 */ 1339 qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, 1340 eSAP_WPS_PBC_PROBE_REQ_EVENT, 1341 (void *) NULL); 1342 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1343 qdf_ret_status = QDF_STATUS_E_FAILURE; 1344 break; 1345 case eCSR_ROAM_RESULT_FORCED: 1346 /* 1347 * This event can be used to inform hdd about user triggered 1348 * disassoc event 1349 * Fill in the event structure 1350 */ 1351 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1352 eSAP_STA_DISASSOC_EVENT, 1353 (void *) eSAP_STATUS_SUCCESS); 1354 break; 1355 case eCSR_ROAM_RESULT_NONE: 1356 /* 1357 * This event can be used to inform hdd about user triggered 1358 * disassoc event 1359 * Fill in the event structure 1360 */ 1361 if (roam_status == eCSR_ROAM_SET_KEY_COMPLETE) { 1362 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1363 eSAP_STA_SET_KEY_EVENT, 1364 (void *) eSAP_STATUS_SUCCESS); 1365 /* 1366 * After set key if this is the first peer connecting to new GO 1367 * then check for peer count (which is self peer + peer count) 1368 * and take decision for GO+GO, STA+GO and CLI+GO force SCC 1369 */ 1370 sap_check_and_process_go_force_scc(sap_ctx); 1371 } 1372 break; 1373 case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED: 1374 /* Fill in the event structure */ 1375 qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, 1376 eSAP_MAX_ASSOC_EXCEEDED, 1377 NULL); 1378 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1379 qdf_ret_status = QDF_STATUS_E_FAILURE; 1380 1381 break; 1382 case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND: 1383 if (!policy_mgr_get_dfs_master_dynamic_enabled( 1384 mac_ctx->psoc, sap_ctx->sessionId)) 1385 break; 1386 wlansap_roam_process_dfs_radar_found(mac_ctx, sap_ctx, 1387 &qdf_ret_status); 1388 break; 1389 case eCSR_ROAM_RESULT_CSA_RESTART_RSP: 1390 qdf_ret_status = wlansap_dfs_send_csa_ie_request(sap_ctx); 1391 1392 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) 1393 sap_debug("CSR roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP %d", 1394 roam_result); 1395 break; 1396 case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS: 1397 wlansap_roam_process_dfs_chansw_update(mac_handle, sap_ctx, 1398 &qdf_ret_status); 1399 break; 1400 case eCSR_ROAM_RESULT_CAC_END_IND: 1401 sap_dfs_cac_timer_callback(mac_handle); 1402 break; 1403 case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS: 1404 wlansap_roam_process_ch_change_success(mac_ctx, sap_ctx, 1405 csr_roam_info, &qdf_ret_status); 1406 1407 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) 1408 qdf_ret_status = 1409 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1410 eSAP_CHANNEL_CHANGE_RESP, 1411 (void *)eSAP_STATUS_FAILURE); 1412 else 1413 qdf_ret_status = 1414 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1415 eSAP_CHANNEL_CHANGE_RESP, 1416 (void *)eSAP_STATUS_SUCCESS); 1417 break; 1418 case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE: 1419 qdf_ret_status = 1420 sap_signal_hdd_event(sap_ctx, csr_roam_info, 1421 eSAP_CHANNEL_CHANGE_RESP, 1422 (void *)eSAP_STATUS_FAILURE); 1423 break; 1424 case eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND: 1425 qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, 1426 eSAP_ECSA_CHANGE_CHAN_IND, NULL); 1427 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1428 qdf_ret_status = QDF_STATUS_E_FAILURE; 1429 break; 1430 default: 1431 sap_err("CSR roam_result = %s (%d) not handled", 1432 get_e_csr_roam_result_str(roam_result), 1433 roam_result); 1434 break; 1435 } 1436 EXIT: 1437 wlansap_context_put(sap_ctx); 1438 return qdf_ret_status; 1439 } 1440 1441 void sap_scan_event_callback(struct wlan_objmgr_vdev *vdev, 1442 struct scan_event *event, void *arg) 1443 { 1444 uint32_t scan_id; 1445 uint8_t session_id; 1446 bool success = false; 1447 eCsrScanStatus scan_status = eCSR_SCAN_FAILURE; 1448 mac_handle_t mac_handle; 1449 QDF_STATUS status; 1450 1451 /* 1452 * It may happen that the SAP was deleted before the scan 1453 * cb was called. Here the sap context which was passed as an 1454 * arg to the ACS cb is used after free then, and there is no way 1455 * currently to validate the pointer. Now try get vdev ref before 1456 * the weight calculation algo kicks in, and return if the 1457 * reference cannot be taken to avoid use after free for SAP-context 1458 */ 1459 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_SAP_ID); 1460 if (QDF_IS_STATUS_ERROR(status)) { 1461 sap_err("Hotspot fail, vdev ref get error"); 1462 return; 1463 } 1464 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID); 1465 1466 session_id = wlan_vdev_get_id(vdev); 1467 scan_id = event->scan_id; 1468 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 1469 if (!mac_handle) 1470 return; 1471 1472 qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SAP, event->type, 1473 event->vdev_id, event->scan_id); 1474 1475 if (!util_is_scan_completed(event, &success)) 1476 return; 1477 1478 if (success) 1479 scan_status = eCSR_SCAN_SUCCESS; 1480 1481 wlansap_pre_start_bss_acs_scan_callback(mac_handle, 1482 arg, session_id, 1483 scan_id, scan_status); 1484 } 1485 1486 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE 1487 #define WLAN_INVALID_PDEV_ID 0xFFFFFFFF 1488 /** 1489 * sap_mark_freq_as_clean(): This API marks a channel is clean which means 1490 * we didn't see any AP's on this channel 1491 * @clean_channel_array: array of chan enum containing that chan free or not 1492 * @freq: freq for which flag needs to be updated 1493 * 1494 * Return: void 1495 */ 1496 static 1497 void sap_mark_freq_as_clean(bool *clean_channel_array, 1498 qdf_freq_t freq) 1499 { 1500 uint32_t ch_index; 1501 ch_index = wlan_reg_get_chan_enum_for_freq(freq); 1502 if (ch_index >= INVALID_CHANNEL) 1503 return; 1504 clean_channel_array[ch_index] = true; 1505 } 1506 1507 /** 1508 * sap_is_prev_n_freqs_free(): previous frequencies free or not based on channel 1509 * width 1510 * @clean_channel_array: array of chan enum containing that chan free or not 1511 * @curr_index: Chan enum of current scanned channel 1512 * @prev_n_freq_count: no. of freq to be monitored based on BW 1513 * @range: Bonded channel freq range 1514 * 1515 *Return: true if previous channels free else false 1516 */ 1517 static 1518 bool sap_is_prev_n_freqs_free(bool *clean_channel_array, uint32_t curr_index, 1519 uint32_t prev_n_freq_count, 1520 const struct bonded_channel_freq *range) 1521 { 1522 uint32_t index; 1523 uint32_t min_index = wlan_reg_get_chan_enum_for_freq(range->start_freq); 1524 uint32_t max_index = wlan_reg_get_chan_enum_for_freq(range->end_freq); 1525 if (max_index >= INVALID_CHANNEL || 1526 min_index >= INVALID_CHANNEL) 1527 return false; 1528 if (curr_index > max_index || curr_index < min_index) { 1529 sap_debug("invalid chan index %d", curr_index); 1530 return false; 1531 } 1532 /* 1533 * curr_index will be present in range, so bonded freq 1534 * range can be checked to decide curr_index is best 1535 * available channel or not. 1536 */ 1537 for (index = min_index; index > 0 && index <= max_index; 1538 index++) { 1539 if (!clean_channel_array[index]) { 1540 sap_debug("chan_index %d not free", index); 1541 return false; 1542 } 1543 } 1544 if ((index - min_index) < prev_n_freq_count) { 1545 sap_debug("previous %d are not validated", prev_n_freq_count); 1546 return false; 1547 } 1548 1549 return true; 1550 } 1551 1552 /** 1553 * is_freq_allowed_for_sap(): is frequency allowed to start SAP 1554 * @pdev: object manager pdev 1555 * @clean_channel_array: array of chan enum containing that chan free or not 1556 * @freq: Scanned frequency 1557 * @ch_width: phy channel width 1558 * @vdev: object manager vdev 1559 * 1560 * Return: true if frequency is allowed based on BW else false. 1561 */ 1562 static 1563 bool is_freq_allowed_for_sap(struct wlan_objmgr_pdev *pdev, 1564 bool *clean_channel_array, 1565 qdf_freq_t freq, enum phy_ch_width ch_width, 1566 struct wlan_objmgr_vdev *vdev) { 1567 uint16_t min_bw = 0; 1568 uint16_t max_bw = 0; 1569 uint16_t curr_bw; 1570 struct wlan_objmgr_psoc *psoc; 1571 QDF_STATUS status; 1572 const struct bonded_channel_freq *range = NULL; 1573 uint32_t curr_index = wlan_reg_get_chan_enum_for_freq(freq); 1574 if (curr_index >= INVALID_CHANNEL) 1575 return false; 1576 psoc = wlan_pdev_get_psoc(pdev); 1577 if (!psoc) { 1578 sap_err("invalid psoc"); 1579 return false; 1580 } 1581 if (wlan_mlme_get_ap_policy(vdev) == 1582 HOST_CONCURRENT_AP_POLICY_UNSPECIFIED) { 1583 sap_debug("low latency sap is not present"); 1584 return false; 1585 } 1586 /* 1587 * Don't allow frequency that can be shared with 2 GHz frequency 1588 * on same MAC. 1589 */ 1590 if (policy_mgr_2_freq_always_on_same_mac 1591 (psoc, wlan_reg_min_24ghz_chan_freq(), freq)) { 1592 sap_debug("frequency can be shared by 2G MAC"); 1593 return false; 1594 } 1595 1596 status = 1597 wlan_reg_get_min_max_bw_for_chan_index(pdev, curr_index, &min_bw, 1598 &max_bw); 1599 if (status != QDF_STATUS_SUCCESS) { 1600 sap_err("get bw for curr channel failed"); 1601 return false; 1602 } 1603 curr_bw = wlan_reg_get_bw_value(ch_width); 1604 if (curr_bw < min_bw || curr_bw > max_bw) { 1605 sap_debug("frequency doesn't support configured bw"); 1606 return false; 1607 } 1608 range = wlan_reg_get_bonded_chan_entry(freq, ch_width, 0); 1609 if (!range) { 1610 sap_debug("Invalid freq range for freq: %d and ch_width: %d", 1611 freq, ch_width); 1612 return false; 1613 } 1614 sap_debug("freq range for bw %d is %d-%d", ch_width, range->start_freq, 1615 range->end_freq); 1616 1617 switch (ch_width) { 1618 case CH_WIDTH_40MHZ: 1619 return sap_is_prev_n_freqs_free(clean_channel_array, 1620 curr_index, 40/20, 1621 range); 1622 case CH_WIDTH_80MHZ: 1623 return sap_is_prev_n_freqs_free(clean_channel_array, 1624 curr_index, 80/20, 1625 range); 1626 case CH_WIDTH_160MHZ: 1627 return sap_is_prev_n_freqs_free(clean_channel_array, 1628 curr_index, 160/20, 1629 range); 1630 case CH_WIDTH_320MHZ: 1631 return sap_is_prev_n_freqs_free(clean_channel_array, 1632 curr_index, 320/20, 1633 range); 1634 default: 1635 return false; 1636 } 1637 return false; 1638 } 1639 1640 void wlansap_process_chan_info_event(struct sap_context *sap_ctx, 1641 struct csr_roam_info *roam_info) 1642 { 1643 struct mac_context *mac; 1644 struct scan_filter *filter; 1645 qdf_list_t *list = NULL; 1646 enum channel_state state; 1647 1648 mac = sap_get_mac_context(); 1649 if (!mac) { 1650 sap_err("Invalid MAC context"); 1651 return; 1652 } 1653 1654 if (!hdd_sap_is_acs_in_progress(sap_ctx->vdev)) 1655 return; 1656 1657 if (SAP_INIT != sap_ctx->fsm_state) 1658 return; 1659 1660 if (WLAN_REG_IS_24GHZ_CH_FREQ(roam_info->chan_info_freq)) 1661 return; 1662 1663 state = wlan_reg_get_channel_state_for_pwrmode( 1664 mac->pdev, roam_info->chan_info_freq, 1665 REG_CURRENT_PWR_MODE); 1666 if (state != CHANNEL_STATE_ENABLE) 1667 return; 1668 1669 if (sap_ctx->optimize_acs_chan_selected) 1670 return; 1671 1672 if (!sap_ctx->acs_cfg) { 1673 sap_debug("acs_cfg is null"); 1674 return; 1675 } 1676 1677 /* If chan_info_freq is not preferred band's freq 1678 * do not select it as ACS result. 1679 */ 1680 if (sap_ctx->acs_cfg->ch_list_count && 1681 !wlan_reg_is_same_band_freqs( 1682 sap_ctx->acs_cfg->freq_list[ 1683 sap_ctx->acs_cfg->ch_list_count - 1], 1684 roam_info->chan_info_freq)) 1685 return; 1686 /* Confirm the freq is in ACS list. */ 1687 if (!wlansap_is_channel_present_in_acs_list( 1688 roam_info->chan_info_freq, 1689 sap_ctx->acs_cfg->freq_list, 1690 sap_ctx->acs_cfg->ch_list_count)) 1691 return; 1692 /* For 6 GHz, do not select non PSC channel */ 1693 if (wlan_reg_is_6ghz_chan_freq( 1694 roam_info->chan_info_freq) && 1695 !wlan_reg_is_6ghz_psc_chan_freq( 1696 roam_info->chan_info_freq)) 1697 return; 1698 1699 filter = qdf_mem_malloc(sizeof(*filter)); 1700 if (!filter) 1701 return; 1702 1703 filter->age_threshold = qdf_get_time_of_the_day_ms() - 1704 sap_ctx->acs_req_timestamp; 1705 filter->num_of_channels = 1; 1706 filter->chan_freq_list[0] = roam_info->chan_info_freq; 1707 1708 list = ucfg_scan_get_result(mac->pdev, filter); 1709 qdf_mem_free(filter); 1710 if (!list) 1711 return; 1712 1713 if (qdf_list_size(list)) 1714 goto exit; 1715 1716 if (!policy_mgr_is_sap_freq_allowed(mac->psoc, 1717 roam_info->chan_info_freq)) 1718 goto exit; 1719 if (sap_ctx->acs_cfg->ch_width > CH_WIDTH_20MHZ) { 1720 sap_mark_freq_as_clean(sap_ctx->clean_channel_array, 1721 roam_info->chan_info_freq); 1722 if (!is_freq_allowed_for_sap(mac->pdev, 1723 sap_ctx->clean_channel_array, 1724 roam_info->chan_info_freq, 1725 sap_ctx->acs_cfg->ch_width, 1726 sap_ctx->vdev)) { 1727 goto exit; 1728 } 1729 } 1730 1731 sap_debug("ACS Best channel %d as no beacon/probe rsp found\n", 1732 roam_info->chan_info_freq); 1733 1734 sap_ctx->optimize_acs_chan_selected = true; 1735 1736 wlan_abort_scan(mac->pdev, WLAN_INVALID_PDEV_ID, 1737 sap_ctx->sessionId, INVALID_SCAN_ID, false); 1738 1739 wlansap_set_acs_ch_freq(sap_ctx, roam_info->chan_info_freq); 1740 sap_ctx->acs_cfg->pri_ch_freq = roam_info->chan_info_freq; 1741 sap_config_acs_result(MAC_HANDLE(mac), sap_ctx, 1742 sap_ctx->acs_cfg->ht_sec_ch_freq); 1743 1744 wlansap_dump_acs_ch_freq(sap_ctx); 1745 1746 sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; 1747 sap_ctx->sap_status = eSAP_STATUS_SUCCESS; 1748 1749 if (sap_ctx->freq_list) { 1750 qdf_mem_free(sap_ctx->freq_list); 1751 sap_ctx->freq_list = NULL; 1752 sap_ctx->num_of_channel = 0; 1753 } 1754 1755 sap_hdd_signal_event_handler(sap_ctx); 1756 1757 exit: 1758 ucfg_scan_purge_results(list); 1759 } 1760 #endif 1761