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 F s m . C 23 24 OVERVIEW: 25 26 This software unit holds the implementation of the WLAN SAP Finite 27 State Machine modules 28 29 DEPENDENCIES: 30 31 Are listed for each API below. 32 ===========================================================================*/ 33 34 /*---------------------------------------------------------------------------- 35 * Include Files 36 * -------------------------------------------------------------------------*/ 37 #include "sap_internal.h" 38 #include <wlan_dfs_tgt_api.h> 39 #include <wlan_dfs_utils_api.h> 40 #include <wlan_dfs_public_struct.h> 41 #include <wlan_reg_services_api.h> 42 /* Pick up the SME API definitions */ 43 #include "sme_api.h" 44 /* Pick up the PMC API definitions */ 45 #include "cds_utils.h" 46 #include "cds_ieee80211_common_i.h" 47 #include "cds_reg_service.h" 48 #include "qdf_util.h" 49 #include "wlan_policy_mgr_api.h" 50 #include <wlan_objmgr_pdev_obj.h> 51 #include <wlan_objmgr_vdev_obj.h> 52 #include <wlan_utility.h> 53 #include <linux/netdevice.h> 54 #include <net/cfg80211.h> 55 #include <qca_vendor.h> 56 #include <wlan_scan_api.h> 57 #include "wlan_reg_services_api.h" 58 #include "wlan_mlme_ucfg_api.h" 59 #include "wlan_policy_mgr_ucfg.h" 60 #include "cfg_ucfg_api.h" 61 #include "wlan_mlme_vdev_mgr_interface.h" 62 #include "wlan_vdev_mgr_utils_api.h" 63 #include "wlan_pre_cac_api.h" 64 #include <wlan_cmn_ieee80211.h> 65 #include <target_if.h> 66 #include "wlan_ll_sap_api.h" 67 68 /*---------------------------------------------------------------------------- 69 * Preprocessor Definitions and Constants 70 * -------------------------------------------------------------------------*/ 71 72 /*---------------------------------------------------------------------------- 73 * Type Declarations 74 * -------------------------------------------------------------------------*/ 75 76 /*---------------------------------------------------------------------------- 77 * Global Data Definitions 78 * -------------------------------------------------------------------------*/ 79 80 /*---------------------------------------------------------------------------- 81 * External declarations for global context 82 * -------------------------------------------------------------------------*/ 83 /*---------------------------------------------------------------------------- 84 * Static Variable Definitions 85 * -------------------------------------------------------------------------*/ 86 87 /*---------------------------------------------------------------------------- 88 * Static Function Declarations and Definitions 89 * -------------------------------------------------------------------------*/ 90 #ifdef SOFTAP_CHANNEL_RANGE 91 static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, 92 uint32_t **freq_list, 93 uint8_t *num_ch); 94 #endif 95 96 /*========================================================================== 97 FUNCTION sapStopDfsCacTimer 98 99 DESCRIPTION 100 Function to sttop the DFS CAC timer when SAP is stopped 101 DEPENDENCIES 102 NA. 103 104 PARAMETERS 105 106 IN 107 sap_ctx: SAP Context 108 RETURN VALUE 109 DFS Timer start status 110 SIDE EFFECTS 111 ============================================================================*/ 112 113 static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx); 114 115 /*========================================================================== 116 FUNCTION sapStartDfsCacTimer 117 118 DESCRIPTION 119 Function to start the DFS CAC timer when SAP is started on DFS Channel 120 DEPENDENCIES 121 NA. 122 123 PARAMETERS 124 125 IN 126 sap_ctx: SAP Context 127 RETURN VALUE 128 DFS Timer start status 129 SIDE EFFECTS 130 ============================================================================*/ 131 132 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx); 133 134 /** sap_hdd_event_to_string() - convert hdd event to string 135 * @event: eSapHddEvent event type 136 * 137 * This function converts eSapHddEvent into string 138 * 139 * Return: string for the @event. 140 */ 141 static uint8_t *sap_hdd_event_to_string(eSapHddEvent event) 142 { 143 switch (event) { 144 CASE_RETURN_STRING(eSAP_START_BSS_EVENT); 145 CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT); 146 CASE_RETURN_STRING(eSAP_STA_ASSOC_IND); 147 CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT); 148 CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT); 149 CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT); 150 CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT); 151 CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT); 152 CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT); 153 CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT); 154 CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT); 155 CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN); 156 CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED); 157 CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT); 158 CASE_RETURN_STRING(eSAP_DFS_CAC_START); 159 CASE_RETURN_STRING(eSAP_DFS_CAC_INTERRUPTED); 160 CASE_RETURN_STRING(eSAP_DFS_CAC_END); 161 CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT); 162 CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL); 163 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 164 CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT); 165 #endif 166 CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED); 167 CASE_RETURN_STRING(eSAP_ECSA_CHANGE_CHAN_IND); 168 default: 169 return "eSAP_HDD_EVENT_UNKNOWN"; 170 } 171 } 172 173 #ifdef QCA_DFS_BW_PUNCTURE 174 /** 175 * sap_is_chan_change_needed() - Check if SAP channel change needed 176 * @sap_ctx: sap context. 177 * 178 * Even some 20 MHz sub channel disabled for nol, if puncture pattern is valid, 179 * SAP still can keep current channel width and primary channel, don't need 180 * change channel. 181 * 182 * Return: bool, true: channel change needed 183 */ 184 static bool 185 sap_is_chan_change_needed(struct sap_context *sap_ctx) 186 { 187 uint8_t ch_wd; 188 uint16_t pri_freq_puncture = 0; 189 struct ch_params *ch_params; 190 QDF_STATUS status; 191 struct mac_context *mac_ctx; 192 193 mac_ctx = sap_get_mac_context(); 194 if (!mac_ctx) { 195 sap_err("Invalid MAC context"); 196 return true; 197 } 198 199 ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params; 200 if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) { 201 ch_wd = sap_ctx->ch_width_orig; 202 mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd; 203 } else { 204 ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; 205 } 206 207 ch_params->ch_width = ch_wd; 208 209 if (sap_phymode_is_eht(sap_ctx->phyMode)) 210 wlan_reg_set_create_punc_bitmap(ch_params, true); 211 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, 212 sap_ctx->chan_freq, 213 0, 214 ch_params, 215 REG_CURRENT_PWR_MODE); 216 if (ch_params->ch_width == sap_ctx->ch_params.ch_width) { 217 status = wlan_reg_extract_puncture_by_bw(ch_params->ch_width, 218 ch_params->reg_punc_bitmap, 219 sap_ctx->chan_freq, 220 ch_params->mhz_freq_seg1, 221 CH_WIDTH_20MHZ, 222 &pri_freq_puncture); 223 if (QDF_IS_STATUS_SUCCESS(status) && !pri_freq_puncture) { 224 sap_debug("Eht valid puncture : 0x%x, keep freq %d", 225 ch_params->reg_punc_bitmap, 226 sap_ctx->chan_freq); 227 mac_ctx->sap.SapDfsInfo.new_chanWidth = 228 ch_params->ch_width; 229 return false; 230 } 231 } 232 233 return true; 234 } 235 #else 236 static inline bool 237 sap_is_chan_change_needed(struct sap_context *sap_ctx) 238 { 239 return true; 240 } 241 #endif 242 243 #ifdef DFS_COMPONENT_ENABLE 244 /** 245 * sap_random_channel_sel() - This function randomly pick up an available 246 * channel 247 * @sap_ctx: sap context. 248 * 249 * This function first eliminates invalid channel, then selects random channel 250 * using following algorithm: 251 * 252 * Return: channel frequency picked 253 */ 254 static qdf_freq_t sap_random_channel_sel(struct sap_context *sap_ctx) 255 { 256 uint16_t chan_freq; 257 uint8_t ch_wd; 258 struct wlan_objmgr_pdev *pdev = NULL; 259 struct ch_params *ch_params; 260 uint32_t hw_mode, flag = 0; 261 struct mac_context *mac_ctx; 262 struct dfs_acs_info acs_info = {0}; 263 264 mac_ctx = sap_get_mac_context(); 265 if (!mac_ctx) { 266 sap_err("Invalid MAC context"); 267 return 0; 268 } 269 270 pdev = mac_ctx->pdev; 271 if (!pdev) { 272 sap_err("null pdev"); 273 return 0; 274 } 275 276 ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params; 277 if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) { 278 ch_wd = sap_ctx->ch_width_orig; 279 mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd; 280 } else { 281 ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; 282 } 283 284 ch_params->ch_width = ch_wd; 285 if (sap_ctx->acs_cfg) { 286 acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode; 287 acs_info.chan_freq_list = sap_ctx->acs_cfg->master_freq_list; 288 acs_info.num_of_channel = 289 sap_ctx->acs_cfg->master_ch_list_count; 290 } else { 291 acs_info.acs_mode = false; 292 } 293 294 if (mac_ctx->mlme_cfg->dfs_cfg.dfs_prefer_non_dfs) 295 flag |= DFS_RANDOM_CH_FLAG_NO_DFS_CH; 296 if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_japan_w53) 297 flag |= DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; 298 if (mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location 299 == 1) 300 flag |= DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; 301 else if (mac_ctx->sap.SapDfsInfo. 302 sap_operating_chan_preferred_location == 2) 303 flag |= DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; 304 305 /* 306 * Dont choose 6ghz channel currently as legacy clients won't be able to 307 * scan them. In future create an ini if any customer wants 6ghz freq 308 * to be prioritize over 5ghz/2.4ghz. 309 * Currently for SAP there is a high chance of 6ghz being selected as 310 * an op frequency as PCL will have only 5, 6ghz freq as preferred for 311 * standalone SAP, and 6ghz channels being high in number. 312 */ 313 flag |= DFS_RANDOM_CH_FLAG_NO_6GHZ_CH; 314 315 if (sap_ctx->candidate_freq && 316 sap_ctx->chan_freq != sap_ctx->candidate_freq && 317 !utils_dfs_is_freq_in_nol(pdev, sap_ctx->candidate_freq)) { 318 chan_freq = sap_ctx->candidate_freq; 319 if (sap_phymode_is_eht(sap_ctx->phyMode)) 320 wlan_reg_set_create_punc_bitmap(ch_params, true); 321 wlan_reg_set_channel_params_for_pwrmode(pdev, chan_freq, 0, 322 ch_params, 323 REG_CURRENT_PWR_MODE); 324 sap_debug("random chan select candidate freq=%d", chan_freq); 325 sap_ctx->candidate_freq = 0; 326 } else if (QDF_IS_STATUS_ERROR( 327 utils_dfs_get_vdev_random_channel_for_freq( 328 pdev, sap_ctx->vdev, flag, ch_params, 329 &hw_mode, &chan_freq, &acs_info))) { 330 /* No available channel found */ 331 sap_err("No available channel found!!!"); 332 sap_signal_hdd_event(sap_ctx, NULL, 333 eSAP_DFS_NO_AVAILABLE_CHANNEL, 334 (void *)eSAP_STATUS_SUCCESS); 335 return 0; 336 } 337 338 mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width; 339 sap_ctx->ch_params.ch_width = ch_params->ch_width; 340 sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset; 341 sap_ctx->ch_params.center_freq_seg0 = ch_params->center_freq_seg0; 342 sap_ctx->ch_params.center_freq_seg1 = ch_params->center_freq_seg1; 343 return chan_freq; 344 } 345 #else 346 static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) 347 { 348 return 0; 349 } 350 #endif 351 352 /** 353 * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding. 354 * @sap_ctx: sap context. 355 * @chan_freq: chan frequency 356 * @ch_params: pointer to ch_params 357 * 358 * Check if given channel and channel params are bonded to weather radar 359 * channel in ETSI domain. 360 * 361 * Return: True if bonded to weather channel in ETSI 362 */ 363 static bool 364 sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx, 365 qdf_freq_t chan_freq, 366 struct ch_params *ch_params) 367 { 368 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(sap_ctx->vdev); 369 370 if (IS_CH_BONDING_WITH_WEATHER_CH(wlan_reg_freq_to_chan(pdev, 371 chan_freq)) && 372 ch_params->ch_width != CH_WIDTH_20MHZ) 373 return true; 374 375 return false; 376 } 377 378 /* 379 * sap_get_bonding_channels() - get bonding channels from primary channel. 380 * @sap_ctx: Handle to SAP context. 381 * @chan_freq: Channel frequency to get bonded channels. 382 * @freq_list: Bonded channel frequency list 383 * @size: Max bonded channels 384 * @chanBondState: The channel bonding mode of the passed channel. 385 * 386 * Return: Number of sub channels 387 */ 388 static uint8_t sap_get_bonding_channels(struct sap_context *sap_ctx, 389 qdf_freq_t chan_freq, 390 qdf_freq_t *freq_list, uint8_t size, 391 ePhyChanBondState chanBondState) 392 { 393 uint8_t num_freq; 394 395 if (!freq_list) 396 return 0; 397 398 if (size < MAX_BONDED_CHANNELS) 399 return 0; 400 401 switch (chanBondState) { 402 case PHY_SINGLE_CHANNEL_CENTERED: 403 num_freq = 1; 404 freq_list[0] = chan_freq; 405 break; 406 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 407 num_freq = 2; 408 freq_list[0] = chan_freq - 20; 409 freq_list[1] = chan_freq; 410 break; 411 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 412 num_freq = 2; 413 freq_list[0] = chan_freq; 414 freq_list[1] = chan_freq + 20; 415 break; 416 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: 417 num_freq = 4; 418 freq_list[0] = chan_freq; 419 freq_list[1] = chan_freq + 20; 420 freq_list[2] = chan_freq + 40; 421 freq_list[3] = chan_freq + 60; 422 break; 423 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: 424 num_freq = 4; 425 freq_list[0] = chan_freq - 20; 426 freq_list[1] = chan_freq; 427 freq_list[2] = chan_freq + 20; 428 freq_list[3] = chan_freq + 40; 429 break; 430 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: 431 num_freq = 4; 432 freq_list[0] = chan_freq - 40; 433 freq_list[1] = chan_freq - 20; 434 freq_list[2] = chan_freq; 435 freq_list[3] = chan_freq + 20; 436 break; 437 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: 438 num_freq = 4; 439 freq_list[0] = chan_freq - 60; 440 freq_list[1] = chan_freq - 40; 441 freq_list[2] = chan_freq - 20; 442 freq_list[3] = chan_freq; 443 break; 444 default: 445 num_freq = 1; 446 freq_list[0] = chan_freq; 447 break; 448 } 449 450 return num_freq; 451 } 452 453 /** 454 * sap_ch_params_to_bonding_channels() - get bonding channels from channel param 455 * @ch_params: channel params ( bw, pri and sec channel info) 456 * @freq_list: bonded channel frequency list 457 * 458 * Return: Number of sub channel frequencies 459 */ 460 static uint8_t sap_ch_params_to_bonding_channels( 461 struct ch_params *ch_params, 462 qdf_freq_t *freq_list) 463 { 464 qdf_freq_t center_freq = ch_params->mhz_freq_seg0; 465 uint8_t num_freq = 0; 466 467 switch (ch_params->ch_width) { 468 case CH_WIDTH_160MHZ: 469 num_freq = 8; 470 center_freq = ch_params->mhz_freq_seg1; 471 freq_list[0] = center_freq - 70; 472 freq_list[1] = center_freq - 50; 473 freq_list[2] = center_freq - 30; 474 freq_list[3] = center_freq - 10; 475 freq_list[4] = center_freq + 10; 476 freq_list[5] = center_freq + 30; 477 freq_list[6] = center_freq + 50; 478 freq_list[7] = center_freq + 70; 479 break; 480 case CH_WIDTH_80P80MHZ: 481 num_freq = 8; 482 freq_list[0] = center_freq - 30; 483 freq_list[1] = center_freq - 10; 484 freq_list[2] = center_freq + 10; 485 freq_list[3] = center_freq + 30; 486 487 center_freq = ch_params->mhz_freq_seg1; 488 freq_list[4] = center_freq - 30; 489 freq_list[5] = center_freq - 10; 490 freq_list[6] = center_freq + 10; 491 freq_list[7] = center_freq + 30; 492 break; 493 case CH_WIDTH_80MHZ: 494 num_freq = 4; 495 freq_list[0] = center_freq - 30; 496 freq_list[1] = center_freq - 10; 497 freq_list[2] = center_freq + 10; 498 freq_list[3] = center_freq + 30; 499 break; 500 case CH_WIDTH_40MHZ: 501 num_freq = 2; 502 freq_list[0] = center_freq - 10; 503 freq_list[1] = center_freq + 10; 504 break; 505 default: 506 num_freq = 1; 507 freq_list[0] = center_freq; 508 break; 509 } 510 511 return num_freq; 512 } 513 514 /** 515 * sap_operating_on_dfs() - check current sap operating on dfs 516 * @mac_ctx: mac ctx 517 * @sap_ctx: SAP context 518 * 519 * Return: true if any sub channel is dfs channel 520 */ 521 static 522 bool sap_operating_on_dfs(struct mac_context *mac_ctx, 523 struct sap_context *sap_ctx) 524 { 525 struct wlan_channel *chan; 526 527 if (!sap_ctx->vdev) { 528 sap_debug("vdev invalid"); 529 return false; 530 } 531 532 chan = wlan_vdev_get_active_channel(sap_ctx->vdev); 533 if (!chan) { 534 sap_debug("Couldn't get vdev active channel"); 535 return false; 536 } 537 538 if (chan->ch_flagext & (IEEE80211_CHAN_DFS | 539 IEEE80211_CHAN_DFS_CFREQ2)) 540 return true; 541 542 return false; 543 } 544 545 bool sap_plus_sap_cac_skip(struct mac_context *mac, 546 struct sap_context *sap_ctx, 547 qdf_freq_t chan_freq) 548 { 549 uint8_t intf; 550 551 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 552 struct sap_context *sap_context = 553 mac->sap.sapCtxList[intf].sap_context; 554 555 if (!sap_context || sap_context == sap_ctx) 556 continue; 557 if (mac->sap.sapCtxList[intf].sapPersona != QDF_SAP_MODE && 558 mac->sap.sapCtxList[intf].sapPersona != QDF_P2P_GO_MODE) 559 continue; 560 if (sap_context->isCacEndNotified && 561 sap_context->chan_freq == chan_freq && 562 sap_operating_on_dfs(mac, sap_context)) { 563 sap_debug("SAP vid %d CAC can skip due to CAC completed on other SAP vid %d", 564 sap_ctx->sessionId, sap_context->sessionId); 565 return true; 566 } 567 } 568 569 return false; 570 } 571 572 /** 573 * is_wlansap_cac_required_for_chan() - Is cac required for given channel 574 * @mac_ctx: mac ctx 575 * @sap_ctx: sap context 576 * @chan_freq: given channel 577 * @ch_params: pointer to ch_params 578 * 579 * Return: True if cac is required for given channel 580 */ 581 static bool 582 is_wlansap_cac_required_for_chan(struct mac_context *mac_ctx, 583 struct sap_context *sap_ctx, 584 qdf_freq_t chan_freq, 585 struct ch_params *ch_params) 586 { 587 bool is_ch_dfs = false; 588 bool cac_required; 589 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 590 uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 591 uint8_t sta_cnt, i; 592 eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; 593 594 if (ch_params->ch_width == CH_WIDTH_160MHZ) { 595 wlan_reg_set_create_punc_bitmap(ch_params, true); 596 if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev, 597 chan_freq, 598 ch_params, 599 REG_CURRENT_PWR_MODE) == 600 CHANNEL_STATE_DFS) 601 is_ch_dfs = true; 602 } else if (ch_params->ch_width == CH_WIDTH_80P80MHZ) { 603 if (wlan_reg_get_channel_state_for_pwrmode( 604 mac_ctx->pdev, 605 chan_freq, 606 REG_CURRENT_PWR_MODE) == 607 CHANNEL_STATE_DFS || 608 wlan_reg_get_channel_state_for_pwrmode( 609 mac_ctx->pdev, 610 ch_params->mhz_freq_seg1, 611 REG_CURRENT_PWR_MODE) == 612 CHANNEL_STATE_DFS) 613 is_ch_dfs = true; 614 } else { 615 /* Indoor channels are also marked DFS, therefore 616 * check if the channel has REGULATORY_CHAN_RADAR 617 * channel flag to identify if the channel is DFS 618 */ 619 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, chan_freq)) 620 is_ch_dfs = true; 621 } 622 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq)) 623 is_ch_dfs = false; 624 if (is_ch_dfs && sap_plus_sap_cac_skip(mac_ctx, sap_ctx, chan_freq)) 625 cac_state = eSAP_DFS_SKIP_CAC; 626 sap_debug("vdev id %d chan %d is_ch_dfs %d pre_cac_complete %d ignore_cac %d cac_state %d", 627 sap_ctx->sessionId, chan_freq, is_ch_dfs, 628 wlan_pre_cac_complete_get(sap_ctx->vdev), 629 mac_ctx->sap.SapDfsInfo.ignore_cac, 630 cac_state); 631 632 if (!is_ch_dfs || wlan_pre_cac_complete_get(sap_ctx->vdev) || 633 mac_ctx->sap.SapDfsInfo.ignore_cac || 634 cac_state == eSAP_DFS_SKIP_CAC) 635 cac_required = false; 636 else 637 cac_required = true; 638 639 if (cac_required) { 640 sta_cnt = 641 policy_mgr_get_mode_specific_conn_info(mac_ctx->psoc, 642 freq_list, 643 vdev_id_list, 644 PM_STA_MODE); 645 646 for (i = 0; i < sta_cnt; i++) { 647 if (chan_freq == freq_list[i]) { 648 sap_debug("STA vdev id %d exists, ignore CAC", 649 vdev_id_list[i]); 650 cac_required = false; 651 } 652 } 653 } 654 655 return cac_required; 656 } 657 658 void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx, 659 uint32_t *cac_duration_ms, 660 uint32_t *dfs_region, 661 qdf_freq_t chan_freq, 662 struct ch_params *ch_params) 663 { 664 int i; 665 qdf_freq_t freq_list[MAX_BONDED_CHANNELS]; 666 uint8_t num_freq; 667 struct mac_context *mac; 668 bool cac_required; 669 670 *cac_duration_ms = 0; 671 if (!sap_ctx) { 672 sap_err("null sap_ctx"); 673 return; 674 } 675 676 mac = sap_get_mac_context(); 677 if (!mac) { 678 sap_err("Invalid MAC context"); 679 return; 680 } 681 682 wlan_reg_get_dfs_region(mac->pdev, dfs_region); 683 cac_required = is_wlansap_cac_required_for_chan(mac, sap_ctx, 684 chan_freq, ch_params); 685 686 if (!cac_required) { 687 sap_debug("cac is not required"); 688 return; 689 } 690 *cac_duration_ms = DEFAULT_CAC_TIMEOUT; 691 692 if (*dfs_region != DFS_ETSI_REGION) { 693 sap_debug("sapdfs: default cac duration"); 694 return; 695 } 696 697 if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx, chan_freq, 698 ch_params)) { 699 *cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT; 700 sap_debug("sapdfs: bonding_etsi_weather_channel"); 701 return; 702 } 703 704 qdf_mem_zero(freq_list, sizeof(freq_list)); 705 num_freq = sap_ch_params_to_bonding_channels(ch_params, freq_list); 706 for (i = 0; i < num_freq; i++) { 707 if (IS_ETSI_WEATHER_FREQ(freq_list[i])) { 708 *cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT; 709 sap_debug("sapdfs: ch freq=%d is etsi weather channel", 710 freq_list[i]); 711 return; 712 } 713 } 714 715 } 716 717 void sap_dfs_set_current_channel(void *ctx) 718 { 719 struct sap_context *sap_ctx = ctx; 720 uint8_t vht_seg0 = sap_ctx->ch_params.center_freq_seg0; 721 uint8_t vht_seg1 = sap_ctx->ch_params.center_freq_seg1; 722 struct wlan_objmgr_pdev *pdev; 723 struct mac_context *mac_ctx; 724 uint32_t use_nol = 0; 725 int error; 726 bool is_dfs; 727 728 mac_ctx = sap_get_mac_context(); 729 if (!mac_ctx) { 730 sap_err("Invalid MAC context"); 731 return; 732 } 733 734 pdev = mac_ctx->pdev; 735 if (!pdev) { 736 sap_err("null pdev"); 737 return; 738 } 739 740 is_dfs = wlan_mlme_check_chan_param_has_dfs(pdev, 741 &sap_ctx->ch_params, 742 sap_ctx->chan_freq); 743 744 sap_debug("freq=%d, dfs %d seg0=%d, seg1=%d, bw %d", 745 sap_ctx->chan_freq, is_dfs, vht_seg0, vht_seg1, 746 sap_ctx->ch_params.ch_width); 747 748 if (is_dfs) { 749 if (policy_mgr_concurrent_beaconing_sessions_running( 750 mac_ctx->psoc)) { 751 uint16_t con_ch_freq; 752 mac_handle_t handle = MAC_HANDLE(mac_ctx); 753 754 con_ch_freq = 755 sme_get_beaconing_concurrent_operation_channel( 756 handle, sap_ctx->sessionId); 757 if (!con_ch_freq || 758 !wlan_reg_is_dfs_for_freq(pdev, 759 con_ch_freq)) 760 tgt_dfs_get_radars(pdev); 761 } else { 762 tgt_dfs_get_radars(pdev); 763 } 764 tgt_dfs_set_phyerr_filter_offload(pdev); 765 766 if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) 767 tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol, 768 sizeof(uint32_t), NULL, NULL, &error); 769 } 770 } 771 772 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 773 /** 774 * sap_check_in_avoid_ch_list() - checks if given channel present is channel 775 * avoidance list 776 * 777 * @sap_ctx: sap context. 778 * @channel: channel to be checked in sap_ctx's avoid ch list 779 * 780 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on 781 * which MDM device's AP with MCC was detected. This function checks if given 782 * channel is present in that list. 783 * 784 * Return: true, if channel was present, false othersie. 785 */ 786 bool sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel) 787 { 788 uint8_t i = 0; 789 struct sap_avoid_channels_info *ie_info = 790 &sap_ctx->sap_detected_avoid_ch_ie; 791 for (i = 0; i < sizeof(ie_info->channels); i++) 792 if (ie_info->channels[i] == channel) 793 return true; 794 return false; 795 } 796 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 797 798 /** 799 * sap_dfs_is_channel_in_nol_list() - given bonded channel is available 800 * @sap_context: Handle to SAP context. 801 * @channel_freq: Channel freq on which availability should be checked. 802 * @chan_bondState: The channel bonding mode of the passed channel. 803 * 804 * This function Checks if a given bonded channel is available or 805 * usable for DFS operation. 806 * 807 * Return: false if channel is available, true if channel is in NOL. 808 */ 809 bool 810 sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context, 811 qdf_freq_t channel_freq, 812 ePhyChanBondState chan_bondState) 813 { 814 int i; 815 struct mac_context *mac_ctx; 816 qdf_freq_t freq_list[MAX_BONDED_CHANNELS]; 817 uint8_t num_ch_freq; 818 struct wlan_objmgr_pdev *pdev = NULL; 819 enum channel_state ch_state; 820 qdf_freq_t ch_freq; 821 822 mac_ctx = sap_get_mac_context(); 823 if (!mac_ctx) { 824 sap_err("Invalid MAC context"); 825 return false; 826 } 827 828 pdev = mac_ctx->pdev; 829 if (!pdev) { 830 sap_err("null pdev"); 831 return false; 832 } 833 834 sap_context->ch_params.mhz_freq_seg0 = 835 wlan_reg_legacy_chan_to_freq( 836 pdev, 837 sap_context->ch_params.center_freq_seg0); 838 sap_context->ch_params.mhz_freq_seg1 = 839 wlan_reg_legacy_chan_to_freq( 840 pdev, 841 sap_context->ch_params.center_freq_seg1); 842 843 /* get the bonded channels */ 844 if (channel_freq == sap_context->chan_freq && 845 chan_bondState >= PHY_CHANNEL_BONDING_STATE_MAX) 846 num_ch_freq = sap_ch_params_to_bonding_channels( 847 &sap_context->ch_params, freq_list); 848 else 849 num_ch_freq = sap_get_bonding_channels( 850 sap_context, channel_freq, 851 freq_list, MAX_BONDED_CHANNELS, 852 chan_bondState); 853 854 /* check for NOL, first on will break the loop */ 855 for (i = 0; i < num_ch_freq; i++) { 856 ch_freq = freq_list[i]; 857 858 ch_state = 859 wlan_reg_get_channel_state_from_secondary_list_for_freq( 860 pdev, ch_freq); 861 if (CHANNEL_STATE_ENABLE != ch_state && 862 CHANNEL_STATE_DFS != ch_state) { 863 sap_err_rl("Invalid ch freq = %d, ch state=%d", ch_freq, 864 ch_state); 865 return true; 866 } 867 } /* loop for bonded channels */ 868 869 return false; 870 } 871 872 bool 873 sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context, 874 qdf_freq_t channel_freq, 875 ePhyChanBondState bond_state) 876 { 877 int i; 878 struct mac_context *mac_ctx; 879 qdf_freq_t freq_list[MAX_BONDED_CHANNELS]; 880 uint8_t num_freq; 881 struct wlan_objmgr_pdev *pdev; 882 883 mac_ctx = sap_get_mac_context(); 884 if (!mac_ctx) { 885 sap_err("Invalid MAC context"); 886 return false; 887 } 888 889 pdev = mac_ctx->pdev; 890 if (!pdev) { 891 sap_err("null pdev"); 892 return false; 893 } 894 895 if (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, channel_freq)) 896 return true; 897 898 /* get the bonded channels */ 899 if (channel_freq == sap_context->chan_freq && 900 bond_state >= PHY_CHANNEL_BONDING_STATE_MAX) 901 num_freq = sap_ch_params_to_bonding_channels( 902 &sap_context->ch_params, freq_list); 903 else 904 num_freq = sap_get_bonding_channels( 905 sap_context, channel_freq, freq_list, 906 MAX_BONDED_CHANNELS, bond_state); 907 908 for (i = 0; i < num_freq; i++) { 909 if (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq_list[i])) { 910 sap_debug("sub ch freq=%d is dfs in %d", 911 freq_list[i], channel_freq); 912 return true; 913 } 914 } 915 916 return false; 917 } 918 919 uint32_t sap_select_default_oper_chan(struct mac_context *mac_ctx, 920 struct sap_acs_cfg *acs_cfg) 921 { 922 uint16_t i; 923 uint32_t freq0 = 0, freq1 = 0, freq2 = 0, default_freq; 924 925 if (!acs_cfg) 926 return 0; 927 928 if (!acs_cfg->ch_list_count || !acs_cfg->freq_list) { 929 if (mac_ctx->mlme_cfg->acs.force_sap_start) { 930 sap_debug("SAP forced, freq selected %d", 931 acs_cfg->master_freq_list[0]); 932 return acs_cfg->master_freq_list[0]; 933 } else { 934 sap_debug("No channel left for operation"); 935 return 0; 936 } 937 } 938 /* 939 * There could be both 2.4Ghz and 5ghz channels present in the list 940 * based upon the Hw mode received from hostapd, it is always better 941 * to chose a default 5ghz operating channel than 2.4ghz, as it can 942 * provide a better throughput, latency than 2.4ghz. Also 40 Mhz is 943 * rare in 2.4ghz band, so 5ghz should be preferred. If we get a 5Ghz 944 * chan in the acs cfg ch list , we should go for that first else the 945 * default channel can be 2.4ghz. 946 * Add check regulatory channel state before select the channel. 947 */ 948 949 for (i = 0; i < acs_cfg->ch_list_count; i++) { 950 enum channel_state state = 951 wlan_reg_get_channel_state_for_pwrmode( 952 mac_ctx->pdev, acs_cfg->freq_list[i], 953 REG_CURRENT_PWR_MODE); 954 if (!freq0 && state == CHANNEL_STATE_ENABLE && 955 WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) { 956 freq0 = acs_cfg->freq_list[i]; 957 break; 958 } else if (!freq1 && state == CHANNEL_STATE_DFS && 959 WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) { 960 freq1 = acs_cfg->freq_list[i]; 961 } else if (!freq2 && state == CHANNEL_STATE_ENABLE) { 962 freq2 = acs_cfg->freq_list[i]; 963 } 964 } 965 default_freq = freq0; 966 if (!default_freq) 967 default_freq = freq1; 968 if (!default_freq) 969 default_freq = freq2; 970 if (!default_freq) 971 default_freq = acs_cfg->freq_list[0]; 972 973 sap_debug("default freq %d chosen from %d %d %d %d", default_freq, 974 freq0, freq1, freq2, acs_cfg->freq_list[0]); 975 976 return default_freq; 977 } 978 979 static bool is_mcc_preferred(struct sap_context *sap_context, 980 uint32_t con_ch_freq) 981 { 982 /* 983 * If SAP ACS channel list is 1-11 and STA is on non-preferred 984 * channel i.e. 12, 13, 14 then MCC is unavoidable. This is because 985 * if SAP is started on 12,13,14 some clients may not be able to 986 * join dependending on their regulatory country. 987 */ 988 if ((con_ch_freq >= 2467) && (con_ch_freq <= 2484) && 989 (sap_context->acs_cfg->start_ch_freq >= 2412 && 990 sap_context->acs_cfg->end_ch_freq <= 2462)) { 991 sap_debug("conc ch freq %d & sap acs ch list is 1-11, prefer mcc", 992 con_ch_freq); 993 return true; 994 } 995 996 return false; 997 } 998 999 /** 1000 * sap_process_force_scc_with_go_start() - Check GO force SCC or not 1001 * @psoc: psoc object 1002 * @sap_context: sap_context 1003 * 1004 * This function checks the current SAP MCC or not with the GO's home channel. 1005 * If it is, skip the GO's force SCC. The SAP will do force SCC after 1006 * GO's started. 1007 * 1008 * Return: true if skip GO's force SCC 1009 */ 1010 static bool 1011 sap_process_force_scc_with_go_start(struct wlan_objmgr_psoc *psoc, 1012 struct sap_context *sap_context) 1013 { 1014 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 1015 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 1016 uint32_t con_freq; 1017 enum phy_ch_width ch_width; 1018 1019 if (sap_context->cc_switch_mode == 1020 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) 1021 return false; 1022 1023 existing_vdev_id = 1024 policy_mgr_fetch_existing_con_info(psoc, 1025 sap_context->sessionId, 1026 sap_context->chan_freq, 1027 &existing_vdev_mode, 1028 &con_freq, &ch_width); 1029 if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX && 1030 existing_vdev_mode == PM_SAP_MODE) { 1031 sap_debug("concurrent sap vdev: %d on freq %d, skip GO force scc", 1032 existing_vdev_id, con_freq); 1033 return true; 1034 } 1035 1036 return false; 1037 } 1038 1039 #ifdef WLAN_FEATURE_P2P_P2P_STA 1040 /** 1041 * sap_set_forcescc_required() - set force scc flag for provided p2p go vdev 1042 * 1043 * @vdev_id: vdev_id for which flag needs to be set 1044 * 1045 * Return: None 1046 */ 1047 static void sap_set_forcescc_required(uint8_t vdev_id) 1048 { 1049 struct mac_context *mac_ctx; 1050 struct sap_context *sap_ctx; 1051 uint8_t i = 0; 1052 1053 mac_ctx = sap_get_mac_context(); 1054 if (!mac_ctx) { 1055 sap_err("Invalid MAC context"); 1056 return; 1057 } 1058 1059 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 1060 sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context; 1061 if (QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona && 1062 sap_ctx->sessionId == vdev_id) { 1063 sap_debug("update forcescc restart for vdev %d", 1064 vdev_id); 1065 sap_ctx->is_forcescc_restart_required = true; 1066 } 1067 } 1068 } 1069 1070 /** 1071 * sap_process_liberal_scc_for_go() - based on existing connections this 1072 * function decides current go should start on provided channel or not and 1073 * sets force scc required bit for existing GO. 1074 * 1075 * @sap_context: sap_context 1076 * 1077 * Return: bool 1078 */ 1079 static bool sap_process_liberal_scc_for_go(struct sap_context *sap_context) 1080 { 1081 uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 1082 enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE; 1083 uint32_t con_freq; 1084 enum phy_ch_width ch_width; 1085 struct mac_context *mac_ctx; 1086 mac_handle_t mac_handle; 1087 1088 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 1089 mac_ctx = MAC_CONTEXT(mac_handle); 1090 if (!mac_ctx) { 1091 sap_alert("invalid MAC handle"); 1092 return true; 1093 } 1094 1095 existing_vdev_id = 1096 policy_mgr_fetch_existing_con_info( 1097 mac_ctx->psoc, 1098 sap_context->sessionId, 1099 sap_context->chan_freq, 1100 &existing_vdev_mode, 1101 &con_freq, &ch_width); 1102 1103 if (existing_vdev_id < 1104 WLAN_UMAC_VDEV_ID_MAX && 1105 existing_vdev_mode == PM_P2P_GO_MODE) { 1106 sap_debug("set forcescc flag for go vdev: %d", 1107 existing_vdev_id); 1108 sap_set_forcescc_required( 1109 existing_vdev_id); 1110 return true; 1111 } 1112 if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX && 1113 (existing_vdev_mode == PM_STA_MODE || 1114 existing_vdev_mode == PM_P2P_CLIENT_MODE)) { 1115 sap_debug("don't override channel, start go on %d", 1116 sap_context->chan_freq); 1117 return true; 1118 } 1119 1120 return false; 1121 } 1122 #else 1123 static bool sap_process_liberal_scc_for_go(struct sap_context *sap_context) 1124 { 1125 return false; 1126 } 1127 #endif 1128 1129 QDF_STATUS 1130 sap_validate_chan(struct sap_context *sap_context, 1131 bool pre_start_bss, 1132 bool check_for_connection_update) 1133 { 1134 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1135 struct mac_context *mac_ctx; 1136 mac_handle_t mac_handle; 1137 uint32_t con_ch_freq; 1138 bool sta_sap_scc_on_dfs_chan; 1139 uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK; 1140 uint32_t sta_sap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK; 1141 uint32_t concurrent_state; 1142 bool go_force_scc; 1143 struct ch_params ch_params = {0}; 1144 bool is_go_scc_strict = false; 1145 bool start_sap_on_provided_freq = false; 1146 1147 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 1148 mac_ctx = MAC_CONTEXT(mac_handle); 1149 if (!mac_ctx) { 1150 /* we have a serious problem */ 1151 sap_alert("invalid MAC handle"); 1152 return QDF_STATUS_E_FAULT; 1153 } 1154 1155 if (!sap_context->chan_freq) { 1156 sap_err("Invalid channel"); 1157 return QDF_STATUS_E_FAILURE; 1158 } 1159 1160 if (policy_mgr_is_vdev_ll_lt_sap(mac_ctx->psoc, sap_context->vdev_id)) { 1161 sap_context->chan_freq = wlan_ll_lt_sap_override_freq( 1162 mac_ctx->psoc, 1163 sap_context->vdev_id, 1164 sap_context->chan_freq); 1165 return QDF_STATUS_SUCCESS; 1166 } 1167 1168 if (sap_context->vdev && 1169 sap_context->vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE) { 1170 /* 1171 * check whether go_force_scc is enabled or not. 1172 * If it not enabled then don't any force scc on existing go and 1173 * new p2p go vdevs. 1174 * Otherwise, if it is enabled then check whether it's in strict 1175 * mode or liberal mode. 1176 * For strict mode, do force scc on newly p2p go to existing vdev 1177 * channel. 1178 * For liberal first form new p2p go on requested channel and 1179 * follow below rules: 1180 * a.) If Existing vdev mode is P2P GO Once set key is done, do 1181 * force scc for existing p2p go and move that go to new p2p 1182 * go's channel. 1183 * 1184 * b.) If Existing vdev mode is P2P CLI/STA Once set key is 1185 * done, do force scc for p2p go and move go to cli/sta channel. 1186 */ 1187 go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc); 1188 sap_debug("go force scc enabled %d", go_force_scc); 1189 1190 if (sap_process_force_scc_with_go_start(mac_ctx->psoc, 1191 sap_context)) 1192 goto validation_done; 1193 1194 if (go_force_scc) { 1195 is_go_scc_strict = 1196 policy_mgr_is_go_scc_strict(mac_ctx->psoc); 1197 if (!is_go_scc_strict) { 1198 sap_debug("liberal mode is enabled"); 1199 start_sap_on_provided_freq = 1200 sap_process_liberal_scc_for_go(sap_context); 1201 if (start_sap_on_provided_freq) 1202 goto validation_done; 1203 } 1204 } else { 1205 goto validation_done; 1206 } 1207 } 1208 1209 concurrent_state = policy_mgr_get_concurrency_mode(mac_ctx->psoc); 1210 if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || 1211 ((concurrent_state & sta_sap_bit_mask) == sta_sap_bit_mask) || 1212 ((concurrent_state & sta_go_bit_mask) == sta_go_bit_mask)) { 1213 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 1214 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 1215 sap_context->chan_freq)) { 1216 sap_warn("DFS not supported in STA_AP Mode"); 1217 return QDF_STATUS_E_ABORTED; 1218 } 1219 #endif 1220 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 1221 if (sap_context->cc_switch_mode != 1222 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 1223 con_ch_freq = sme_check_concurrent_channel_overlap( 1224 mac_handle, 1225 sap_context->chan_freq, 1226 sap_context->phyMode, 1227 sap_context->cc_switch_mode, 1228 sap_context->sessionId); 1229 sap_debug("After check overlap: sap freq %d con freq:%d", 1230 sap_context->chan_freq, con_ch_freq); 1231 /* 1232 * For non-DBS platform, a 2.4Ghz can become a 5Ghz freq 1233 * so lets used max BW in that case, if it remain 2.4Ghz 1234 * then BW will be limited to 20 anyway 1235 */ 1236 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_context->chan_freq)) 1237 ch_params.ch_width = CH_WIDTH_MAX; 1238 else 1239 ch_params = sap_context->ch_params; 1240 1241 if (sap_context->cc_switch_mode != 1242 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) { 1243 if (QDF_IS_STATUS_ERROR( 1244 policy_mgr_valid_sap_conc_channel_check( 1245 mac_ctx->psoc, &con_ch_freq, 1246 sap_context->chan_freq, 1247 sap_context->sessionId, 1248 &ch_params))) { 1249 sap_warn("SAP can't start (no MCC)"); 1250 return QDF_STATUS_E_ABORTED; 1251 } 1252 } 1253 /* if CH width didn't change fallback to original */ 1254 if (ch_params.ch_width == CH_WIDTH_MAX) 1255 ch_params = sap_context->ch_params; 1256 1257 sap_debug("After check concurrency: con freq:%d", 1258 con_ch_freq); 1259 sta_sap_scc_on_dfs_chan = 1260 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( 1261 mac_ctx->psoc); 1262 if (con_ch_freq && 1263 (policy_mgr_sta_sap_scc_on_lte_coex_chan( 1264 mac_ctx->psoc) || 1265 policy_mgr_is_safe_channel( 1266 mac_ctx->psoc, con_ch_freq)) && 1267 (!wlan_mlme_check_chan_param_has_dfs( 1268 mac_ctx->pdev, &ch_params, 1269 con_ch_freq) || 1270 sta_sap_scc_on_dfs_chan)) { 1271 if (is_mcc_preferred(sap_context, con_ch_freq)) 1272 goto validation_done; 1273 1274 sap_debug("Override ch freq %d (bw %d) to %d (bw %d) due to CC Intf", 1275 sap_context->chan_freq, 1276 sap_context->ch_params.ch_width, 1277 con_ch_freq, ch_params.ch_width); 1278 sap_context->chan_freq = con_ch_freq; 1279 sap_context->ch_params = ch_params; 1280 } 1281 } 1282 #endif 1283 } 1284 validation_done: 1285 sap_debug("for configured channel, Ch_freq = %d", 1286 sap_context->chan_freq); 1287 1288 /* 1289 * Don't check if the frequency is allowed or not if SAP is started 1290 * in fixed channel, or WLAN CH AVOID EXT feature explicit restrict 1291 * SAP start on unsafe channel. 1292 */ 1293 1294 if ((sap_context->acs_cfg->acs_mode || 1295 policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc)) && 1296 !policy_mgr_is_sap_freq_allowed(mac_ctx->psoc, 1297 sap_context->chan_freq)) { 1298 sap_warn("Abort SAP start due to unsafe channel"); 1299 return QDF_STATUS_E_ABORTED; 1300 } 1301 1302 if (check_for_connection_update) { 1303 /* This wait happens in the hostapd context. The event 1304 * is set in the MC thread context. 1305 */ 1306 qdf_status = 1307 policy_mgr_update_and_wait_for_connection_update( 1308 mac_ctx->psoc, sap_context->sessionId, 1309 sap_context->chan_freq, 1310 POLICY_MGR_UPDATE_REASON_START_AP); 1311 if (QDF_IS_STATUS_ERROR(qdf_status)) 1312 return qdf_status; 1313 } 1314 1315 if (pre_start_bss) { 1316 sap_info("ACS end due to Ch override. Sel Ch freq = %d", 1317 sap_context->chan_freq); 1318 sap_context->acs_cfg->pri_ch_freq = sap_context->chan_freq; 1319 sap_context->acs_cfg->ch_width = 1320 sap_context->ch_width_orig; 1321 sap_config_acs_result(mac_handle, sap_context, 0); 1322 return QDF_STATUS_E_CANCELED; 1323 } 1324 1325 return QDF_STATUS_SUCCESS; 1326 } 1327 1328 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE 1329 1330 static void sap_sort_freq_list(struct chan_list *list, 1331 uint8_t num_ch) 1332 { 1333 int i, j, temp; 1334 1335 for (i = 0; i < num_ch - 1; i++) { 1336 for (j = 0 ; j < num_ch - i - 1; j++) { 1337 if (list->chan[j].freq < list->chan[j + 1].freq) { 1338 temp = list->chan[j].freq; 1339 list->chan[j].freq = list->chan[j + 1].freq; 1340 list->chan[j + 1].freq = temp; 1341 } 1342 } 1343 } 1344 } 1345 1346 /** 1347 * sap_acs_scan_freq_list_optimize() - optimize the ACS scan freq list based 1348 * on when last scan was performed on particular frequency. If last scan 1349 * performed on particular frequency is less than configured last_scan_ageout 1350 * time, then skip that frequency from ACS scan freq list. 1351 * 1352 * @sap_ctx: sap context 1353 * @list: ACS scan frequency list 1354 * @ch_count: number of frequency in list 1355 * 1356 * Return: None 1357 */ 1358 static void sap_acs_scan_freq_list_optimize(struct sap_context *sap_ctx, 1359 struct chan_list *list, 1360 uint8_t *ch_count) 1361 { 1362 int loop_count = 0, j = 0; 1363 uint32_t ts_last_scan; 1364 1365 sap_ctx->partial_acs_scan = false; 1366 1367 while (loop_count < *ch_count) { 1368 ts_last_scan = scm_get_last_scan_time_per_channel( 1369 sap_ctx->vdev, list->chan[loop_count].freq); 1370 1371 if (qdf_system_time_before( 1372 qdf_get_time_of_the_day_ms(), 1373 ts_last_scan + sap_ctx->acs_cfg->last_scan_ageout_time)) { 1374 sap_info("ACS chan %d skipped from scan as last scan ts %lu\n", 1375 list->chan[loop_count].freq, 1376 qdf_get_time_of_the_day_ms() - ts_last_scan); 1377 1378 for (j = loop_count; j < *ch_count - 1; j++) 1379 list->chan[j].freq = list->chan[j + 1].freq; 1380 1381 (*ch_count)--; 1382 sap_ctx->partial_acs_scan = true; 1383 continue; 1384 } 1385 loop_count++; 1386 } 1387 if (*ch_count == 0) 1388 sap_info("All ACS freq channels are scanned recently, skip ACS scan\n"); 1389 else 1390 sap_sort_freq_list(list, *ch_count); 1391 } 1392 #else 1393 static void sap_acs_scan_freq_list_optimize(struct sap_context *sap_ctx, 1394 struct chan_list *list, 1395 uint8_t *ch_count) 1396 { 1397 } 1398 #endif 1399 1400 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE 1401 /** 1402 * sap_reset_clean_freq_array() - clear freq array that contains info 1403 * channel is free or not 1404 * @sap_context: sap context 1405 * 1406 * Return: void 1407 */ 1408 static 1409 void sap_reset_clean_freq_array(struct sap_context *sap_context) 1410 { 1411 memset(sap_context->clean_channel_array, 0, NUM_CHANNELS); 1412 } 1413 #else 1414 static inline 1415 void sap_reset_clean_freq_array(struct sap_context *sap_context) 1416 {} 1417 #endif 1418 1419 /** 1420 * wlansap_set_aux_scan_ctrl_ext_flag() - update aux scan policy 1421 * @req: pointer to scan request 1422 * 1423 * Set aux scan bits in scan_ctrl_ext_flag value depending on scan type 1424 * 1425 * Return: None 1426 */ 1427 static void wlansap_set_aux_scan_ctrl_ext_flag(struct scan_start_request *req) 1428 { 1429 sap_debug("Set Reliable Scan Flag"); 1430 req->scan_req.scan_ctrl_flags_ext |= 1431 SCAN_FLAG_EXT_AUX_RELIABLE_SCAN; 1432 } 1433 1434 QDF_STATUS sap_channel_sel(struct sap_context *sap_context) 1435 { 1436 QDF_STATUS qdf_ret_status; 1437 struct mac_context *mac_ctx; 1438 struct scan_start_request *req; 1439 struct wlan_objmgr_vdev *vdev = NULL; 1440 uint8_t i, j; 1441 uint32_t *freq_list = NULL; 1442 uint8_t num_of_channels = 0; 1443 mac_handle_t mac_handle; 1444 uint32_t con_ch_freq; 1445 uint8_t vdev_id; 1446 uint32_t scan_id; 1447 uint32_t default_op_freq; 1448 1449 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 1450 if (!mac_handle) 1451 return QDF_STATUS_E_FAULT; 1452 1453 mac_ctx = MAC_CONTEXT(mac_handle); 1454 if (!mac_ctx) { 1455 sap_err("Invalid MAC context"); 1456 return QDF_STATUS_E_FAILURE; 1457 } 1458 if (sap_context->fsm_state != SAP_STARTED && sap_context->chan_freq) 1459 return sap_validate_chan(sap_context, true, false); 1460 1461 if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || 1462 ((sap_context->cc_switch_mode == 1463 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && 1464 (policy_mgr_mode_specific_connection_count(mac_ctx->psoc, 1465 PM_SAP_MODE, NULL) || 1466 policy_mgr_mode_specific_connection_count(mac_ctx->psoc, 1467 PM_P2P_GO_MODE, 1468 NULL)))) { 1469 con_ch_freq = sme_get_beaconing_concurrent_operation_channel( 1470 mac_handle, sap_context->sessionId); 1471 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 1472 if (con_ch_freq) 1473 sap_context->dfs_ch_disable = true; 1474 #endif 1475 } 1476 1477 if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) == 1478 (QDF_STA_MASK | QDF_SAP_MASK)) || 1479 ((sap_context->cc_switch_mode == 1480 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && 1481 (policy_mgr_get_concurrency_mode(mac_ctx->psoc) == 1482 (QDF_STA_MASK | QDF_P2P_GO_MASK)))) { 1483 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 1484 sap_context->dfs_ch_disable = true; 1485 #endif 1486 } 1487 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1488 sap_debug("skip_acs_status = %d", 1489 sap_context->acs_cfg->skip_scan_status); 1490 if (sap_context->acs_cfg->skip_scan_status != 1491 eSAP_SKIP_ACS_SCAN) { 1492 #endif 1493 1494 if (sap_context->freq_list) { 1495 qdf_mem_free(sap_context->freq_list); 1496 sap_context->freq_list = NULL; 1497 sap_context->num_of_channel = 0; 1498 } 1499 1500 sap_get_freq_list(sap_context, &freq_list, &num_of_channels); 1501 if (!num_of_channels || !freq_list) { 1502 sap_err("No freq sutiable for SAP in current list, SAP failed"); 1503 return QDF_STATUS_E_FAILURE; 1504 } 1505 1506 req = qdf_mem_malloc(sizeof(*req)); 1507 if (!req) { 1508 qdf_mem_free(freq_list); 1509 return QDF_STATUS_E_NOMEM; 1510 } 1511 1512 vdev_id = sap_context->sessionId; 1513 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 1514 vdev_id, 1515 WLAN_LEGACY_SME_ID); 1516 if (!vdev) { 1517 sap_err("Invalid vdev objmgr"); 1518 qdf_mem_free(freq_list); 1519 qdf_mem_free(req); 1520 return QDF_STATUS_E_INVAL; 1521 } 1522 1523 /* Initiate a SCAN request */ 1524 wlan_scan_init_default_params(vdev, req); 1525 scan_id = wlan_scan_get_scan_id(mac_ctx->psoc); 1526 req->scan_req.scan_id = scan_id; 1527 req->scan_req.vdev_id = vdev_id; 1528 req->scan_req.scan_f_passive = false; 1529 req->scan_req.scan_req_id = sap_context->req_id; 1530 req->scan_req.scan_priority = SCAN_PRIORITY_HIGH; 1531 req->scan_req.scan_f_bcast_probe = true; 1532 for (i = 0, j = 0; i < num_of_channels; i++) { 1533 if (wlan_reg_is_6ghz_chan_freq(freq_list[i]) && 1534 !wlan_reg_is_6ghz_psc_chan_freq(freq_list[i])) 1535 continue; 1536 req->scan_req.chan_list.chan[j++].freq = freq_list[i]; 1537 } 1538 req->scan_req.chan_list.num_chan = j; 1539 sap_context->freq_list = freq_list; 1540 sap_context->num_of_channel = num_of_channels; 1541 sap_context->optimize_acs_chan_selected = false; 1542 sap_reset_clean_freq_array(sap_context); 1543 /* Set requestType to Full scan */ 1544 1545 /* 1546 * send partial channels to be scanned in SCAN request if 1547 * vendor command included last scan ageout time to be used to 1548 * optimize the SAP bring up time 1549 */ 1550 if (sap_context->acs_cfg->last_scan_ageout_time) 1551 sap_acs_scan_freq_list_optimize( 1552 sap_context, &req->scan_req.chan_list, 1553 &req->scan_req.chan_list.num_chan); 1554 1555 if (!req->scan_req.chan_list.num_chan) { 1556 sap_info("## SKIPPED ACS SCAN"); 1557 sap_context->acs_cfg->skip_acs_scan = true; 1558 wlansap_pre_start_bss_acs_scan_callback( 1559 mac_handle, sap_context, sap_context->sessionId, 1560 0, eCSR_SCAN_SUCCESS); 1561 qdf_mem_free(req); 1562 qdf_ret_status = QDF_STATUS_SUCCESS; 1563 goto release_vdev_ref; 1564 } 1565 1566 sap_context->acs_req_timestamp = qdf_get_time_of_the_day_ms(); 1567 1568 if (wlan_scan_get_aux_support(mac_ctx->psoc)) 1569 wlansap_set_aux_scan_ctrl_ext_flag(req); 1570 qdf_ret_status = wlan_scan_start(req); 1571 if (qdf_ret_status != QDF_STATUS_SUCCESS) { 1572 sap_err("scan request fail %d!!!", qdf_ret_status); 1573 sap_info("SAP Configuring default ch, Ch_freq=%d", 1574 sap_context->chan_freq); 1575 default_op_freq = sap_select_default_oper_chan( 1576 mac_ctx, sap_context->acs_cfg); 1577 wlansap_set_acs_ch_freq(sap_context, default_op_freq); 1578 1579 if (sap_context->freq_list) { 1580 wlansap_set_acs_ch_freq( 1581 sap_context, sap_context->freq_list[0]); 1582 qdf_mem_free(sap_context->freq_list); 1583 sap_context->freq_list = NULL; 1584 sap_context->num_of_channel = 0; 1585 } 1586 /* 1587 * In case of ACS req before start Bss, 1588 * return failure so that the calling 1589 * function can use the default channel. 1590 */ 1591 qdf_ret_status = QDF_STATUS_E_FAILURE; 1592 goto release_vdev_ref; 1593 } else { 1594 wlansap_dump_acs_ch_freq(sap_context); 1595 host_log_acs_scan_start(scan_id, vdev_id); 1596 } 1597 1598 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1599 } else { 1600 sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN; 1601 } 1602 1603 if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) { 1604 sap_err("## SKIPPED ACS SCAN"); 1605 wlansap_pre_start_bss_acs_scan_callback(mac_handle, 1606 sap_context, sap_context->sessionId, 0, 1607 eCSR_SCAN_SUCCESS); 1608 } 1609 #endif 1610 1611 wlansap_dump_acs_ch_freq(sap_context); 1612 1613 qdf_ret_status = QDF_STATUS_SUCCESS; 1614 1615 release_vdev_ref: 1616 if (vdev) 1617 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1618 return qdf_ret_status; 1619 } 1620 1621 /** 1622 * sap_find_valid_concurrent_session() - to find valid concurrent session 1623 * @mac_handle: Opaque handle to the global MAC context 1624 * 1625 * This API will check if any valid concurrent SAP session is present 1626 * 1627 * Return: pointer to sap context of valid concurrent session 1628 */ 1629 static struct sap_context * 1630 sap_find_valid_concurrent_session(mac_handle_t mac_handle) 1631 { 1632 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 1633 uint8_t intf = 0; 1634 struct sap_context *sap_ctx; 1635 1636 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1637 if (((QDF_SAP_MODE == 1638 mac_ctx->sap.sapCtxList[intf].sapPersona) || 1639 (QDF_P2P_GO_MODE == 1640 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 1641 mac_ctx->sap.sapCtxList[intf].sap_context) { 1642 sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context; 1643 if (sap_ctx->fsm_state != SAP_INIT) 1644 return sap_ctx; 1645 } 1646 } 1647 1648 return NULL; 1649 } 1650 1651 QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle, 1652 struct sap_context *sap_ctx) 1653 { 1654 struct sap_context *con_sap_ctx; 1655 1656 con_sap_ctx = sap_find_valid_concurrent_session(mac_handle); 1657 if (con_sap_ctx && WLAN_REG_IS_5GHZ_CH_FREQ(con_sap_ctx->chan_freq)) { 1658 sap_debug("conc session exists, no need to clear dfs struct"); 1659 return QDF_STATUS_SUCCESS; 1660 } 1661 /* 1662 * CAC timer will be initiated and started only when SAP starts 1663 * on DFS channel and it will be stopped and destroyed 1664 * immediately once the radar detected or timedout. So 1665 * as per design CAC timer should be destroyed after stop 1666 */ 1667 wlansap_cleanup_cac_timer(sap_ctx); 1668 sap_cac_reset_notify(mac_handle); 1669 1670 return QDF_STATUS_SUCCESS; 1671 } 1672 1673 QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc, 1674 struct sap_context *sap_ctx, 1675 uint8_t session_id) 1676 { 1677 struct wlan_objmgr_vdev *vdev; 1678 1679 if (sap_ctx->vdev) { 1680 sap_err("Invalid vdev obj in sap context"); 1681 return QDF_STATUS_E_FAULT; 1682 } 1683 1684 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, 1685 WLAN_LEGACY_SAP_ID); 1686 if (!vdev) { 1687 sap_err("vdev is NULL for vdev_id: %u", session_id); 1688 return QDF_STATUS_E_FAILURE; 1689 } 1690 1691 sap_ctx->vdev = vdev; 1692 return QDF_STATUS_SUCCESS; 1693 } 1694 1695 void sap_release_vdev_ref(struct sap_context *sap_ctx) 1696 { 1697 struct wlan_objmgr_vdev *vdev; 1698 1699 if (!sap_ctx) { 1700 sap_debug("Invalid SAP pointer"); 1701 return; 1702 } 1703 1704 vdev = sap_ctx->vdev; 1705 if (vdev) { 1706 sap_ctx->vdev = NULL; 1707 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID); 1708 } 1709 } 1710 1711 QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, 1712 struct sap_context *sapctx, 1713 uint32_t session_id) 1714 { 1715 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 1716 int i; 1717 1718 sapctx->sessionId = session_id; 1719 wlan_pre_cac_set_status(sapctx->vdev, false); 1720 wlan_pre_cac_complete_set(sapctx->vdev, false); 1721 wlan_pre_cac_set_freq_before_pre_cac(sapctx->vdev, 0); 1722 1723 /* When SSR, SAP will restart, clear the old context,sessionId */ 1724 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 1725 if (mac_ctx->sap.sapCtxList[i].sap_context == sapctx) 1726 mac_ctx->sap.sapCtxList[i].sap_context = NULL; 1727 } 1728 1729 mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx; 1730 mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = 1731 wlan_get_opmode_from_vdev_id(mac_ctx->pdev, session_id); 1732 sap_debug("Initializing sap_ctx = %pK with session = %d", 1733 sapctx, session_id); 1734 1735 return QDF_STATUS_SUCCESS; 1736 } 1737 1738 QDF_STATUS sap_clear_session_param(mac_handle_t mac_handle, 1739 struct sap_context *sapctx, 1740 uint32_t session_id) 1741 { 1742 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 1743 1744 if (sapctx->sessionId >= SAP_MAX_NUM_SESSION) 1745 return QDF_STATUS_E_FAILURE; 1746 1747 mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL; 1748 mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = 1749 QDF_MAX_NO_OF_MODE; 1750 sap_clear_global_dfs_param(mac_handle, sapctx); 1751 1752 sap_err("Set sapCtxList null for session %d", sapctx->sessionId); 1753 qdf_mem_zero(sapctx, sizeof(*sapctx)); 1754 sapctx->sessionId = WLAN_UMAC_VDEV_ID_MAX; 1755 1756 return QDF_STATUS_SUCCESS; 1757 } 1758 1759 #ifdef WLAN_FEATURE_11AX 1760 static uint16_t he_mcs_12_13_support(void) 1761 { 1762 struct mac_context *mac_ctx; 1763 1764 mac_ctx = sap_get_mac_context(); 1765 if (!mac_ctx) { 1766 sap_err("Invalid MAC context"); 1767 return 0; 1768 } 1769 1770 return mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_5g; 1771 } 1772 #else 1773 static inline uint16_t he_mcs_12_13_support(void) 1774 { 1775 return 0; 1776 } 1777 #endif 1778 1779 static bool is_mcs13_ch_width(enum phy_ch_width ch_width) 1780 { 1781 if ((ch_width == CH_WIDTH_320MHZ) || 1782 (ch_width == CH_WIDTH_160MHZ) || 1783 (ch_width == CH_WIDTH_80P80MHZ)) 1784 return true; 1785 1786 return false; 1787 } 1788 1789 /** 1790 * sap_update_mcs_rate() - Update SAP MCS rate 1791 * @sap_ctx: pointer to sap Context 1792 * @is_start: Start or stop SAP 1793 * 1794 * Return: QDF_STATUS 1795 */ 1796 static QDF_STATUS 1797 sap_update_mcs_rate(struct sap_context *sap_ctx, bool is_start) 1798 { 1799 uint32_t default_mcs[] = {26, 0x3fff}; 1800 uint32_t fixed_mcs[] = {26, 0x1fff}; 1801 bool disable_mcs13_support = false; 1802 uint16_t he_mcs_12_13_supp; 1803 struct mac_context *mac_ctx; 1804 QDF_STATUS status = QDF_STATUS_SUCCESS; 1805 1806 mac_ctx = sap_get_mac_context(); 1807 if (!mac_ctx) { 1808 sap_err("Invalid MAC context"); 1809 return QDF_STATUS_E_INVAL; 1810 } 1811 1812 he_mcs_12_13_supp = he_mcs_12_13_support(); 1813 disable_mcs13_support = cfg_get(mac_ctx->psoc, 1814 CFG_DISABLE_MCS13_SUPPORT); 1815 sap_debug("session id %d, disable mcs13 support %d, he_mcs_12_13 %d, start %d, disabled_mcs13 %d, ch width %d", 1816 sap_ctx->sessionId, disable_mcs13_support, 1817 he_mcs_12_13_supp, 1818 is_start, sap_ctx->disabled_mcs13, 1819 sap_ctx->ch_params.ch_width); 1820 1821 if (!disable_mcs13_support || 1822 !he_mcs_12_13_supp) 1823 return status; 1824 1825 if (!is_start && !sap_ctx->disabled_mcs13) 1826 return status; 1827 1828 if (!is_mcs13_ch_width(sap_ctx->ch_params.ch_width)) 1829 return status; 1830 1831 if (is_start) { 1832 status = sme_send_unit_test_cmd(sap_ctx->sessionId, 1833 10, 2, fixed_mcs); 1834 if (QDF_IS_STATUS_ERROR(status)) { 1835 sap_err("Set fixed mcs rate failed, session %d", 1836 sap_ctx->sessionId); 1837 } else { 1838 sap_ctx->disabled_mcs13 = true; 1839 } 1840 } else { 1841 status = sme_send_unit_test_cmd(sap_ctx->sessionId, 1842 10, 2, default_mcs); 1843 if (QDF_IS_STATUS_ERROR(status)) { 1844 sap_err("Set default mcs rate failed, session %d", 1845 sap_ctx->sessionId); 1846 } else { 1847 sap_ctx->disabled_mcs13 = false; 1848 } 1849 } 1850 1851 return status; 1852 } 1853 1854 /** 1855 * sap_goto_stopping() - Processing of SAP FSM stopping state 1856 * @sap_ctx: pointer to sap Context 1857 * 1858 * Return: QDF_STATUS code associated with performing the operation 1859 */ 1860 static QDF_STATUS sap_goto_stopping(struct sap_context *sap_ctx) 1861 { 1862 QDF_STATUS status; 1863 struct mac_context *mac_ctx; 1864 1865 mac_ctx = sap_get_mac_context(); 1866 if (!mac_ctx) { 1867 /* we have a serious problem */ 1868 sap_err("Invalid MAC context"); 1869 return QDF_STATUS_E_FAULT; 1870 } 1871 1872 sap_update_mcs_rate(sap_ctx, false); 1873 qdf_mem_zero(&sap_ctx->sap_bss_cfg, sizeof(sap_ctx->sap_bss_cfg)); 1874 1875 status = sme_roam_stop_bss(MAC_HANDLE(mac_ctx), sap_ctx->sessionId); 1876 if (status != QDF_STATUS_SUCCESS) { 1877 sap_err("Calling sme_roam_stop_bss status = %d", status); 1878 return QDF_STATUS_E_FAILURE; 1879 } 1880 1881 return QDF_STATUS_SUCCESS; 1882 } 1883 1884 /** 1885 * sap_goto_init() - Function for setting the SAP FSM to init state 1886 * @sap_ctx: pointer to sap context 1887 * 1888 * Return: QDF_STATUS code associated with performing the operation 1889 */ 1890 static QDF_STATUS sap_goto_init(struct sap_context *sap_ctx) 1891 { 1892 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1893 struct sap_sm_event sap_event; 1894 /* Processing has to be coded */ 1895 1896 /* 1897 * Clean up stations from TL etc as AP BSS is shut down 1898 * then set event 1899 */ 1900 1901 /* hardcoded event */ 1902 sap_event.event = eSAP_MAC_READY_FOR_CONNECTIONS; 1903 sap_event.params = 0; 1904 sap_event.u1 = 0; 1905 sap_event.u2 = 0; 1906 /* Handle event */ 1907 qdf_status = sap_fsm(sap_ctx, &sap_event); 1908 1909 return qdf_status; 1910 } 1911 1912 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1913 /** 1914 * sap_handle_acs_scan_event() - handle acs scan event for SAP 1915 * @sap_context: ptSapContext 1916 * @sap_event: struct sap_event 1917 * @status: status of acs scan 1918 * 1919 * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event. 1920 * 1921 * Return: void 1922 */ 1923 static void sap_handle_acs_scan_event(struct sap_context *sap_context, 1924 struct sap_event *sap_event, eSapStatus status) 1925 { 1926 sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT; 1927 sap_event->sapevt.sap_acs_scan_comp.status = status; 1928 sap_event->sapevt.sap_acs_scan_comp.num_of_channels = 1929 sap_context->num_of_channel; 1930 sap_event->sapevt.sap_acs_scan_comp.freq_list = 1931 sap_context->freq_list; 1932 } 1933 #else 1934 static void sap_handle_acs_scan_event(struct sap_context *sap_context, 1935 struct sap_event *sap_event, eSapStatus status) 1936 { 1937 } 1938 #endif 1939 1940 #define DH_OUI_TYPE "\x20" 1941 #define DH_OUI_TYPE_SIZE (1) 1942 /** 1943 * sap_fill_owe_ie_in_assoc_ind() - Fill OWE IE in assoc indication 1944 * Function to fill OWE IE in assoc indication 1945 * @assoc_ind: SAP STA association indication 1946 * @sme_assoc_ind: SME association indication 1947 * @reassoc: True if it is reassoc frame 1948 * 1949 * This function is to get OWE IEs (RSN IE, DH IE etc) from assoc request 1950 * and fill them in association indication. 1951 * 1952 * Return: true for success and false for failure 1953 */ 1954 static bool sap_fill_owe_ie_in_assoc_ind(tSap_StationAssocIndication *assoc_ind, 1955 struct assoc_ind *sme_assoc_ind, 1956 bool reassoc) 1957 { 1958 uint32_t owe_ie_len, rsn_ie_len, dh_ie_len; 1959 const uint8_t *rsn_ie, *dh_ie; 1960 uint8_t *assoc_req_ie; 1961 uint16_t assoc_req_ie_len; 1962 1963 if (reassoc) { 1964 if (assoc_ind->assocReqLength < WLAN_REASSOC_REQ_IES_OFFSET) { 1965 sap_err("Invalid reassoc req"); 1966 return false; 1967 } 1968 1969 assoc_req_ie = assoc_ind->assocReqPtr + 1970 WLAN_REASSOC_REQ_IES_OFFSET; 1971 assoc_req_ie_len = assoc_ind->assocReqLength - 1972 WLAN_REASSOC_REQ_IES_OFFSET; 1973 } else { 1974 if (assoc_ind->assocReqLength < WLAN_ASSOC_REQ_IES_OFFSET) { 1975 sap_err("Invalid assoc req"); 1976 return false; 1977 } 1978 1979 assoc_req_ie = assoc_ind->assocReqPtr + 1980 WLAN_ASSOC_REQ_IES_OFFSET; 1981 assoc_req_ie_len = assoc_ind->assocReqLength - 1982 WLAN_ASSOC_REQ_IES_OFFSET; 1983 } 1984 rsn_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_RSN, 1985 assoc_req_ie, assoc_req_ie_len); 1986 if (!rsn_ie) { 1987 sap_err("RSN IE is not present"); 1988 return false; 1989 } 1990 rsn_ie_len = rsn_ie[1] + 2; 1991 if (rsn_ie_len < DOT11F_IE_RSN_MIN_LEN || 1992 rsn_ie_len > DOT11F_IE_RSN_MAX_LEN) { 1993 sap_err("Invalid RSN IE len %d", rsn_ie_len); 1994 return false; 1995 } 1996 1997 dh_ie = wlan_get_ext_ie_ptr_from_ext_id(DH_OUI_TYPE, DH_OUI_TYPE_SIZE, 1998 assoc_req_ie, assoc_req_ie_len); 1999 if (!dh_ie) { 2000 sap_err("DH IE is not present"); 2001 return false; 2002 } 2003 dh_ie_len = dh_ie[1] + 2; 2004 if (dh_ie_len < DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN || 2005 dh_ie_len > DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN) { 2006 sap_err("Invalid DH IE len %d", dh_ie_len); 2007 return false; 2008 } 2009 2010 sap_debug("rsn_ie_len = %d, dh_ie_len = %d", rsn_ie_len, dh_ie_len); 2011 2012 owe_ie_len = rsn_ie_len + dh_ie_len; 2013 assoc_ind->owe_ie = qdf_mem_malloc(owe_ie_len); 2014 if (!assoc_ind->owe_ie) 2015 return false; 2016 2017 qdf_mem_copy(assoc_ind->owe_ie, rsn_ie, rsn_ie_len); 2018 qdf_mem_copy(assoc_ind->owe_ie + rsn_ie_len, dh_ie, dh_ie_len); 2019 assoc_ind->owe_ie_len = owe_ie_len; 2020 2021 return true; 2022 } 2023 2024 /** 2025 * sap_save_owe_pending_assoc_ind() - Save pending assoc indication 2026 * Function to save pending assoc indication in SAP context 2027 * @sap_ctx: SAP context 2028 * @sme_assoc_ind: SME association indication 2029 * 2030 * This function is to save pending assoc indication in linked list 2031 * in SAP context. 2032 * 2033 * Return: true for success and false for failure 2034 */ 2035 static bool sap_save_owe_pending_assoc_ind(struct sap_context *sap_ctx, 2036 struct assoc_ind *sme_assoc_ind) 2037 { 2038 struct owe_assoc_ind *assoc_ind; 2039 QDF_STATUS status; 2040 2041 assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind)); 2042 if (!assoc_ind) 2043 return false; 2044 assoc_ind->assoc_ind = sme_assoc_ind; 2045 status = qdf_list_insert_back(&sap_ctx->owe_pending_assoc_ind_list, 2046 &assoc_ind->node); 2047 if (QDF_STATUS_SUCCESS != status) { 2048 qdf_mem_free(assoc_ind); 2049 return false; 2050 } 2051 2052 return true; 2053 } 2054 2055 static bool sap_save_ft_pending_assoc_ind(struct sap_context *sap_ctx, 2056 struct assoc_ind *sme_assoc_ind) 2057 { 2058 struct ft_assoc_ind *assoc_ind; 2059 QDF_STATUS status; 2060 2061 assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind)); 2062 if (!assoc_ind) 2063 return false; 2064 assoc_ind->assoc_ind = sme_assoc_ind; 2065 status = qdf_list_insert_back(&sap_ctx->ft_pending_assoc_ind_list, 2066 &assoc_ind->node); 2067 if (QDF_STATUS_SUCCESS != status) { 2068 qdf_mem_free(assoc_ind); 2069 return false; 2070 } 2071 qdf_event_set(&sap_ctx->ft_pending_event); 2072 2073 return true; 2074 } 2075 2076 #ifdef FEATURE_RADAR_HISTORY 2077 /* Last cac result */ 2078 static struct prev_cac_result prev_cac_history; 2079 2080 /** 2081 * sap_update_cac_history() - record SAP Radar found result in last 2082 * "active" or CAC period 2083 * @mac_ctx: mac context 2084 * @sap_ctx: sap context 2085 * @event_id: sap event 2086 * 2087 * The function is to save the dfs channel information 2088 * If SAP has been "active" or "CAC" on DFS channel for 60s and 2089 * no found radar event. 2090 * 2091 * Return: void 2092 */ 2093 static void 2094 sap_update_cac_history(struct mac_context *mac_ctx, 2095 struct sap_context *sap_ctx, 2096 eSapHddEvent event_id) 2097 { 2098 struct prev_cac_result *cac_result = &sap_ctx->cac_result; 2099 2100 switch (event_id) { 2101 case eSAP_START_BSS_EVENT: 2102 case eSAP_CHANNEL_CHANGE_RESP: 2103 case eSAP_DFS_CAC_START: 2104 if (sap_operating_on_dfs(mac_ctx, sap_ctx)) { 2105 qdf_mem_zero(cac_result, 2106 sizeof(struct prev_cac_result)); 2107 if (!sap_ctx->ch_params.mhz_freq_seg0) { 2108 sap_debug("invalid seq0"); 2109 return; 2110 } 2111 cac_result->ap_start_time = 2112 qdf_get_monotonic_boottime(); 2113 cac_result->cac_ch_param = sap_ctx->ch_params; 2114 sap_debug("ap start(CAC) (%d, %d) bw %d", 2115 cac_result->cac_ch_param.mhz_freq_seg0, 2116 cac_result->cac_ch_param.mhz_freq_seg1, 2117 cac_result->cac_ch_param.ch_width); 2118 } 2119 break; 2120 case eSAP_DFS_RADAR_DETECT: 2121 qdf_mem_zero(cac_result, 2122 sizeof(struct prev_cac_result)); 2123 break; 2124 case eSAP_DFS_CAC_END: 2125 case eSAP_STOP_BSS_EVENT: 2126 if (cac_result->ap_start_time) { 2127 uint64_t diff_ms; 2128 2129 cac_result->ap_end_time = 2130 qdf_get_monotonic_boottime(); 2131 diff_ms = qdf_do_div(cac_result->ap_end_time - 2132 cac_result->ap_start_time, 1000); 2133 if (diff_ms < DEFAULT_CAC_TIMEOUT - 5000) { 2134 if (event_id == eSAP_STOP_BSS_EVENT) 2135 qdf_mem_zero( 2136 cac_result, 2137 sizeof(struct prev_cac_result)); 2138 sap_debug("ap cac dur %llu ms", diff_ms); 2139 break; 2140 } 2141 cac_result->cac_complete = true; 2142 qdf_mem_copy(&prev_cac_history, cac_result, 2143 sizeof(struct prev_cac_result)); 2144 sap_debug("ap cac saved %llu ms %llu (%d, %d) bw %d", 2145 diff_ms, 2146 cac_result->ap_end_time, 2147 cac_result->cac_ch_param.mhz_freq_seg0, 2148 cac_result->cac_ch_param.mhz_freq_seg1, 2149 cac_result->cac_ch_param.ch_width); 2150 if (event_id == eSAP_STOP_BSS_EVENT) 2151 qdf_mem_zero(cac_result, 2152 sizeof(struct prev_cac_result)); 2153 } 2154 break; 2155 default: 2156 break; 2157 } 2158 } 2159 2160 /** 2161 * find_ch_freq_in_radar_hist() - check channel frequency existing 2162 * in radar history buffer 2163 * @radar_result: radar history buffer 2164 * @count: radar history element number 2165 * @ch_freq: channel frequency 2166 * 2167 * Return: bool 2168 */ 2169 static 2170 bool find_ch_freq_in_radar_hist(struct dfs_radar_history *radar_result, 2171 uint32_t count, uint16_t ch_freq) 2172 { 2173 while (count) { 2174 if (radar_result->ch_freq == ch_freq) 2175 return true; 2176 radar_result++; 2177 count--; 2178 } 2179 2180 return false; 2181 } 2182 2183 /** 2184 * sap_append_cac_history() - Add CAC history to list 2185 * @mac_ctx: pointer to mac context 2186 * @radar_result: radar history buffer 2187 * @idx: current radar history element number 2188 * @max_elems: max elements number of radar history buffer. 2189 * 2190 * This function is to add the CAC history to radar history list. 2191 * 2192 * Return: void 2193 */ 2194 static 2195 void sap_append_cac_history(struct mac_context *mac_ctx, 2196 struct dfs_radar_history *radar_result, 2197 uint32_t *idx, uint32_t max_elems) 2198 { 2199 struct prev_cac_result *cac_result = &prev_cac_history; 2200 struct ch_params ch_param = cac_result->cac_ch_param; 2201 uint32_t count = *idx; 2202 2203 if (!cac_result->cac_complete || !cac_result->ap_end_time) { 2204 sap_debug("cac hist empty"); 2205 return; 2206 } 2207 2208 if (ch_param.ch_width <= CH_WIDTH_20MHZ) { 2209 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 2210 ch_param.mhz_freq_seg0) && 2211 !find_ch_freq_in_radar_hist(radar_result, count, 2212 ch_param.mhz_freq_seg0) && 2213 *idx < max_elems) { 2214 radar_result[*idx].ch_freq = ch_param.mhz_freq_seg0; 2215 radar_result[*idx].time = cac_result->ap_end_time; 2216 radar_result[*idx].radar_found = false; 2217 sap_debug("radar hist[%d] freq %d time %llu no radar", 2218 *idx, ch_param.mhz_freq_seg0, 2219 cac_result->ap_end_time); 2220 (*idx)++; 2221 } 2222 } else { 2223 uint16_t chan_cfreq; 2224 enum channel_state state; 2225 const struct bonded_channel_freq *bonded_chan_ptr = NULL; 2226 2227 state = wlan_reg_get_5g_bonded_channel_and_state_for_pwrmode 2228 (mac_ctx->pdev, ch_param.mhz_freq_seg0, 2229 ch_param.ch_width, &bonded_chan_ptr, 2230 REG_CURRENT_PWR_MODE, NO_SCHANS_PUNC); 2231 if (!bonded_chan_ptr || state == CHANNEL_STATE_INVALID) { 2232 sap_debug("invalid freq %d", ch_param.mhz_freq_seg0); 2233 return; 2234 } 2235 2236 chan_cfreq = bonded_chan_ptr->start_freq; 2237 while (chan_cfreq <= bonded_chan_ptr->end_freq) { 2238 state = wlan_reg_get_channel_state_for_pwrmode( 2239 mac_ctx->pdev, chan_cfreq, 2240 REG_CURRENT_PWR_MODE); 2241 if (state == CHANNEL_STATE_INVALID) { 2242 sap_debug("invalid ch freq %d", 2243 chan_cfreq); 2244 chan_cfreq = chan_cfreq + 20; 2245 continue; 2246 } 2247 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 2248 chan_cfreq) && 2249 !find_ch_freq_in_radar_hist(radar_result, count, 2250 chan_cfreq) && 2251 *idx < max_elems) { 2252 radar_result[*idx].ch_freq = chan_cfreq; 2253 radar_result[*idx].time = 2254 cac_result->ap_end_time; 2255 radar_result[*idx].radar_found = false; 2256 sap_debug("radar hist[%d] freq %d time %llu no radar", 2257 *idx, chan_cfreq, 2258 cac_result->ap_end_time); 2259 (*idx)++; 2260 } 2261 chan_cfreq = chan_cfreq + 20; 2262 } 2263 } 2264 } 2265 2266 QDF_STATUS 2267 wlansap_query_radar_history(mac_handle_t mac_handle, 2268 struct dfs_radar_history **radar_history, 2269 uint32_t *count) 2270 { 2271 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 2272 struct dfsreq_nolinfo *nol_info; 2273 uint32_t i; 2274 uint32_t hist_count; 2275 struct dfs_radar_history *radar_result; 2276 2277 nol_info = qdf_mem_malloc(sizeof(struct dfsreq_nolinfo)); 2278 if (!nol_info) 2279 return QDF_STATUS_E_NOMEM; 2280 2281 ucfg_dfs_getnol(mac_ctx->pdev, nol_info); 2282 2283 hist_count = nol_info->dfs_ch_nchans + MAX_NUM_OF_CAC_HISTORY; 2284 radar_result = qdf_mem_malloc(sizeof(struct dfs_radar_history) * 2285 hist_count); 2286 if (!radar_result) { 2287 qdf_mem_free(nol_info); 2288 return QDF_STATUS_E_NOMEM; 2289 } 2290 2291 for (i = 0; i < nol_info->dfs_ch_nchans && i < DFS_CHAN_MAX; i++) { 2292 radar_result[i].ch_freq = nol_info->dfs_nol[i].nol_freq; 2293 radar_result[i].time = nol_info->dfs_nol[i].nol_start_us; 2294 radar_result[i].radar_found = true; 2295 sap_debug("radar hist[%d] freq %d time %llu radar", 2296 i, nol_info->dfs_nol[i].nol_freq, 2297 nol_info->dfs_nol[i].nol_start_us); 2298 } 2299 2300 sap_append_cac_history(mac_ctx, radar_result, &i, hist_count); 2301 sap_debug("hist count %d cur %llu", i, qdf_get_monotonic_boottime()); 2302 2303 *radar_history = radar_result; 2304 *count = i; 2305 qdf_mem_free(nol_info); 2306 2307 return QDF_STATUS_SUCCESS; 2308 } 2309 #else 2310 static inline void 2311 sap_update_cac_history(struct mac_context *mac_ctx, 2312 struct sap_context *sap_ctx, 2313 eSapHddEvent event_id) 2314 { 2315 } 2316 #endif 2317 2318 #ifdef WLAN_FEATURE_11BE_MLO 2319 static inline 2320 bool sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer *peer) 2321 { 2322 if (qdf_is_macaddr_zero((struct qdf_mac_addr *)peer->mldaddr)) 2323 return true; 2324 else 2325 return false; 2326 } 2327 #else 2328 static inline 2329 bool sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer *peer) 2330 { 2331 return true; 2332 } 2333 #endif 2334 2335 static 2336 QDF_STATUS sap_populate_peer_assoc_info(struct mac_context *mac_ctx, 2337 struct csr_roam_info *csr_roaminfo, 2338 struct sap_event *sap_ap_event) 2339 { 2340 struct wlan_objmgr_peer *peer; 2341 tSap_StationAssocReassocCompleteEvent *reassoc_complete; 2342 2343 reassoc_complete = 2344 &sap_ap_event->sapevt.sapStationAssocReassocCompleteEvent; 2345 2346 peer = wlan_objmgr_get_peer_by_mac(mac_ctx->psoc, 2347 csr_roaminfo->peerMac.bytes, 2348 WLAN_LEGACY_MAC_ID); 2349 if (!peer) { 2350 sap_err("Peer object not found"); 2351 return QDF_STATUS_E_FAILURE; 2352 } 2353 2354 sap_debug("mlo peer assoc:%d", wlan_peer_mlme_is_assoc_peer(peer)); 2355 2356 if (sap_check_peer_for_peer_null_mldaddr(peer) || 2357 wlan_peer_mlme_is_assoc_peer(peer)) { 2358 if (csr_roaminfo->assocReqLength < ASSOC_REQ_IE_OFFSET) { 2359 sap_err("Invalid assoc request length:%d", 2360 csr_roaminfo->assocReqLength); 2361 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); 2362 return QDF_STATUS_E_INVAL; 2363 } 2364 reassoc_complete->ies_len = (csr_roaminfo->assocReqLength - 2365 ASSOC_REQ_IE_OFFSET); 2366 reassoc_complete->ies = (csr_roaminfo->assocReqPtr + 2367 ASSOC_REQ_IE_OFFSET); 2368 /* skip current AP address in reassoc frame */ 2369 if (csr_roaminfo->fReassocReq) { 2370 reassoc_complete->ies_len -= QDF_MAC_ADDR_SIZE; 2371 reassoc_complete->ies += QDF_MAC_ADDR_SIZE; 2372 } 2373 } 2374 2375 if (csr_roaminfo->addIELen) { 2376 if (wlan_get_vendor_ie_ptr_from_oui( 2377 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, 2378 csr_roaminfo->paddIE, csr_roaminfo->addIELen)) { 2379 reassoc_complete->staType = eSTA_TYPE_P2P_CLI; 2380 } else { 2381 reassoc_complete->staType = eSTA_TYPE_INFRA; 2382 } 2383 } 2384 2385 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); 2386 2387 return QDF_STATUS_SUCCESS; 2388 } 2389 2390 #ifdef WLAN_FEATURE_11BE_MLO 2391 static void 2392 sap_reassoc_mld_copy(struct csr_roam_info *csr_roaminfo, 2393 tSap_StationAssocReassocCompleteEvent *reassoc_complete) 2394 { 2395 qdf_copy_macaddr(&reassoc_complete->sta_mld, 2396 &csr_roaminfo->peer_mld); 2397 sap_debug("reassoc_complete->staMld: " QDF_MAC_ADDR_FMT, 2398 QDF_MAC_ADDR_REF(reassoc_complete->sta_mld.bytes)); 2399 } 2400 #else /* WLAN_FEATURE_11BE_MLO */ 2401 static inline void 2402 sap_reassoc_mld_copy(struct csr_roam_info *csr_roaminfo, 2403 tSap_StationAssocReassocCompleteEvent *reassoc_complete) 2404 { 2405 } 2406 #endif /* WLAN_FEATURE_11BE_MLO */ 2407 2408 /** 2409 * sap_signal_hdd_event() - send event notification 2410 * @sap_ctx: Sap Context 2411 * @csr_roaminfo: Pointer to CSR roam information 2412 * @sap_hddevent: SAP HDD event 2413 * @context: to pass the element for future support 2414 * 2415 * Function for HDD to send the event notification using callback 2416 * 2417 * Return: QDF_STATUS 2418 */ 2419 QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, 2420 struct csr_roam_info *csr_roaminfo, eSapHddEvent sap_hddevent, 2421 void *context) 2422 { 2423 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 2424 struct sap_event *sap_ap_event; 2425 struct mac_context *mac_ctx; 2426 struct oem_channel_info *chaninfo; 2427 tSap_StationAssocIndication *assoc_ind; 2428 tSap_StartBssCompleteEvent *bss_complete; 2429 struct sap_ch_selected_s *acs_selected; 2430 tSap_StationAssocReassocCompleteEvent *reassoc_complete; 2431 tSap_StationDisassocCompleteEvent *disassoc_comp; 2432 tSap_StationSetKeyCompleteEvent *key_complete; 2433 tSap_StationMICFailureEvent *mic_failure; 2434 2435 /* Format the Start BSS Complete event to return... */ 2436 if (!sap_ctx->sap_event_cb) 2437 return QDF_STATUS_E_FAILURE; 2438 2439 mac_ctx = sap_get_mac_context(); 2440 if (!mac_ctx) { 2441 sap_err("Invalid MAC context"); 2442 return QDF_STATUS_E_FAILURE; 2443 } 2444 2445 sap_ap_event = qdf_mem_malloc(sizeof(*sap_ap_event)); 2446 if (!sap_ap_event) 2447 return QDF_STATUS_E_NOMEM; 2448 2449 sap_debug("SAP event callback event = %s", 2450 sap_hdd_event_to_string(sap_hddevent)); 2451 2452 switch (sap_hddevent) { 2453 case eSAP_STA_ASSOC_IND: 2454 if (!csr_roaminfo) { 2455 sap_debug("Invalid CSR Roam Info"); 2456 qdf_mem_free(sap_ap_event); 2457 return QDF_STATUS_E_INVAL; 2458 } 2459 /* TODO - Indicate the assoc request indication to OS */ 2460 sap_ap_event->sapHddEventCode = eSAP_STA_ASSOC_IND; 2461 assoc_ind = &sap_ap_event->sapevt.sapAssocIndication; 2462 2463 qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac); 2464 assoc_ind->staId = csr_roaminfo->staId; 2465 assoc_ind->status = 0; 2466 /* Required for indicating the frames to upper layer */ 2467 assoc_ind->assocReqLength = csr_roaminfo->assocReqLength; 2468 assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr; 2469 assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta; 2470 assoc_ind->ecsa_capable = csr_roaminfo->ecsa_capable; 2471 if (csr_roaminfo->owe_pending_assoc_ind) { 2472 if (!sap_fill_owe_ie_in_assoc_ind(assoc_ind, 2473 csr_roaminfo->owe_pending_assoc_ind, 2474 csr_roaminfo->fReassocReq)) { 2475 sap_err("Failed to fill OWE IE"); 2476 qdf_mem_free(csr_roaminfo-> 2477 owe_pending_assoc_ind); 2478 csr_roaminfo->owe_pending_assoc_ind = NULL; 2479 qdf_mem_free(sap_ap_event); 2480 return QDF_STATUS_E_INVAL; 2481 } 2482 if (!sap_save_owe_pending_assoc_ind(sap_ctx, 2483 csr_roaminfo->owe_pending_assoc_ind)) { 2484 sap_err("Failed to save assoc ind"); 2485 qdf_mem_free(csr_roaminfo-> 2486 owe_pending_assoc_ind); 2487 csr_roaminfo->owe_pending_assoc_ind = NULL; 2488 qdf_mem_free(sap_ap_event); 2489 return QDF_STATUS_E_INVAL; 2490 } 2491 csr_roaminfo->owe_pending_assoc_ind = NULL; 2492 } 2493 2494 if (csr_roaminfo->ft_pending_assoc_ind) { 2495 if (!sap_save_ft_pending_assoc_ind(sap_ctx, 2496 csr_roaminfo->ft_pending_assoc_ind)) { 2497 sap_err("Failed to save ft assoc ind"); 2498 qdf_mem_free(csr_roaminfo->ft_pending_assoc_ind); 2499 csr_roaminfo->ft_pending_assoc_ind = NULL; 2500 qdf_mem_free(sap_ap_event); 2501 return QDF_STATUS_E_INVAL; 2502 } 2503 csr_roaminfo->ft_pending_assoc_ind = NULL; 2504 } 2505 break; 2506 case eSAP_START_BSS_EVENT: 2507 sap_ap_event->sapHddEventCode = eSAP_START_BSS_EVENT; 2508 bss_complete = &sap_ap_event->sapevt.sapStartBssCompleteEvent; 2509 2510 bss_complete->sessionId = sap_ctx->sessionId; 2511 if (bss_complete->sessionId == WLAN_UMAC_VDEV_ID_MAX) { 2512 sap_err("Invalid sessionId"); 2513 qdf_mem_free(sap_ap_event); 2514 return QDF_STATUS_E_INVAL; 2515 } 2516 2517 bss_complete->status = (eSapStatus) context; 2518 bss_complete->staId = sap_ctx->sap_sta_id; 2519 2520 sap_debug("(eSAP_START_BSS_EVENT): staId = %d", 2521 bss_complete->staId); 2522 2523 bss_complete->operating_chan_freq = sap_ctx->chan_freq; 2524 bss_complete->ch_width = sap_ctx->ch_params.ch_width; 2525 if (QDF_IS_STATUS_SUCCESS(bss_complete->status)) { 2526 sap_update_cac_history(mac_ctx, sap_ctx, 2527 sap_hddevent); 2528 sap_update_mcs_rate(sap_ctx, true); 2529 } 2530 break; 2531 case eSAP_DFS_CAC_START: 2532 case eSAP_DFS_CAC_INTERRUPTED: 2533 case eSAP_DFS_CAC_END: 2534 case eSAP_DFS_RADAR_DETECT: 2535 case eSAP_DFS_NO_AVAILABLE_CHANNEL: 2536 sap_ap_event->sapHddEventCode = sap_hddevent; 2537 sap_ap_event->sapevt.sapStopBssCompleteEvent.status = 2538 (eSapStatus) context; 2539 sap_update_cac_history(mac_ctx, sap_ctx, 2540 sap_hddevent); 2541 break; 2542 case eSAP_ACS_SCAN_SUCCESS_EVENT: 2543 sap_handle_acs_scan_event(sap_ctx, sap_ap_event, 2544 (eSapStatus)context); 2545 break; 2546 case eSAP_ACS_CHANNEL_SELECTED: 2547 sap_ap_event->sapHddEventCode = sap_hddevent; 2548 acs_selected = &sap_ap_event->sapevt.sap_ch_selected; 2549 if (eSAP_STATUS_SUCCESS == (eSapStatus)context) { 2550 acs_selected->pri_ch_freq = 2551 sap_ctx->acs_cfg->pri_ch_freq; 2552 acs_selected->ht_sec_ch_freq = 2553 sap_ctx->acs_cfg->ht_sec_ch_freq; 2554 acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; 2555 acs_selected->vht_seg0_center_ch_freq = 2556 sap_ctx->acs_cfg->vht_seg0_center_ch_freq; 2557 acs_selected->vht_seg1_center_ch_freq = 2558 sap_ctx->acs_cfg->vht_seg1_center_ch_freq; 2559 } else if (eSAP_STATUS_FAILURE == (eSapStatus)context) { 2560 acs_selected->pri_ch_freq = 0; 2561 } 2562 break; 2563 2564 case eSAP_STOP_BSS_EVENT: 2565 sap_ap_event->sapHddEventCode = eSAP_STOP_BSS_EVENT; 2566 sap_ap_event->sapevt.sapStopBssCompleteEvent.status = 2567 (eSapStatus) context; 2568 break; 2569 2570 case eSAP_STA_ASSOC_EVENT: 2571 case eSAP_STA_REASSOC_EVENT: 2572 2573 if (!csr_roaminfo) { 2574 sap_err("Invalid CSR Roam Info"); 2575 qdf_mem_free(sap_ap_event); 2576 return QDF_STATUS_E_INVAL; 2577 } 2578 if (sap_ctx->fsm_state == SAP_STOPPING) { 2579 sap_err("SAP is stopping, not able to handle any incoming (re)assoc req"); 2580 qdf_mem_free(sap_ap_event); 2581 return QDF_STATUS_E_ABORTED; 2582 } 2583 2584 qdf_status = sap_populate_peer_assoc_info(mac_ctx, csr_roaminfo, 2585 sap_ap_event); 2586 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2587 qdf_mem_free(sap_ap_event); 2588 return QDF_STATUS_E_INVAL; 2589 } 2590 2591 reassoc_complete = 2592 &sap_ap_event->sapevt.sapStationAssocReassocCompleteEvent; 2593 2594 if (csr_roaminfo->fReassocReq) 2595 sap_ap_event->sapHddEventCode = eSAP_STA_REASSOC_EVENT; 2596 else 2597 sap_ap_event->sapHddEventCode = eSAP_STA_ASSOC_EVENT; 2598 2599 qdf_copy_macaddr(&reassoc_complete->staMac, 2600 &csr_roaminfo->peerMac); 2601 sap_reassoc_mld_copy(csr_roaminfo, reassoc_complete); 2602 reassoc_complete->staId = csr_roaminfo->staId; 2603 reassoc_complete->status_code = csr_roaminfo->status_code; 2604 2605 /* also fill up the channel info from the csr_roamInfo */ 2606 chaninfo = &reassoc_complete->chan_info; 2607 2608 chaninfo->mhz = csr_roaminfo->chan_info.mhz; 2609 chaninfo->info = csr_roaminfo->chan_info.info; 2610 chaninfo->band_center_freq1 = 2611 csr_roaminfo->chan_info.band_center_freq1; 2612 chaninfo->band_center_freq2 = 2613 csr_roaminfo->chan_info.band_center_freq2; 2614 chaninfo->reg_info_1 = 2615 csr_roaminfo->chan_info.reg_info_1; 2616 chaninfo->reg_info_2 = 2617 csr_roaminfo->chan_info.reg_info_2; 2618 chaninfo->nss = csr_roaminfo->chan_info.nss; 2619 chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags; 2620 2621 reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta; 2622 reassoc_complete->status = (eSapStatus) context; 2623 reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap; 2624 reassoc_complete->ampdu = csr_roaminfo->ampdu; 2625 reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable; 2626 reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc; 2627 reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc; 2628 reassoc_complete->ch_width = csr_roaminfo->ch_width; 2629 reassoc_complete->mode = csr_roaminfo->mode; 2630 reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx; 2631 reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx; 2632 reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx; 2633 reassoc_complete->max_real_mcs_idx = 2634 csr_roaminfo->max_real_mcs_idx; 2635 reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map; 2636 reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map; 2637 reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable; 2638 reassoc_complete->ext_cap = csr_roaminfo->ext_cap; 2639 reassoc_complete->supported_band = csr_roaminfo->supported_band; 2640 if (csr_roaminfo->ht_caps.present) 2641 reassoc_complete->ht_caps = csr_roaminfo->ht_caps; 2642 if (csr_roaminfo->vht_caps.present) 2643 reassoc_complete->vht_caps = csr_roaminfo->vht_caps; 2644 reassoc_complete->he_caps_present = 2645 csr_roaminfo->he_caps_present; 2646 reassoc_complete->eht_caps_present = 2647 csr_roaminfo->eht_caps_present; 2648 reassoc_complete->capability_info = 2649 csr_roaminfo->capability_info; 2650 2651 break; 2652 2653 case eSAP_STA_DISASSOC_EVENT: 2654 if (!csr_roaminfo) { 2655 sap_debug("Invalid CSR Roam Info"); 2656 qdf_mem_free(sap_ap_event); 2657 return QDF_STATUS_E_INVAL; 2658 } 2659 sap_ap_event->sapHddEventCode = eSAP_STA_DISASSOC_EVENT; 2660 disassoc_comp = 2661 &sap_ap_event->sapevt.sapStationDisassocCompleteEvent; 2662 2663 qdf_copy_macaddr(&disassoc_comp->staMac, 2664 &csr_roaminfo->peerMac); 2665 disassoc_comp->staId = csr_roaminfo->staId; 2666 if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED) 2667 disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC; 2668 else 2669 disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC; 2670 2671 disassoc_comp->status_code = csr_roaminfo->status_code; 2672 disassoc_comp->status = (eSapStatus) context; 2673 disassoc_comp->rssi = csr_roaminfo->rssi; 2674 disassoc_comp->rx_rate = csr_roaminfo->rx_rate; 2675 disassoc_comp->tx_rate = csr_roaminfo->tx_rate; 2676 disassoc_comp->rx_mc_bc_cnt = csr_roaminfo->rx_mc_bc_cnt; 2677 disassoc_comp->rx_retry_cnt = csr_roaminfo->rx_retry_cnt; 2678 disassoc_comp->reason_code = csr_roaminfo->disassoc_reason; 2679 break; 2680 2681 case eSAP_STA_SET_KEY_EVENT: 2682 2683 if (!csr_roaminfo) { 2684 sap_debug("Invalid CSR Roam Info"); 2685 qdf_mem_free(sap_ap_event); 2686 return QDF_STATUS_E_INVAL; 2687 } 2688 sap_ap_event->sapHddEventCode = eSAP_STA_SET_KEY_EVENT; 2689 key_complete = 2690 &sap_ap_event->sapevt.sapStationSetKeyCompleteEvent; 2691 key_complete->status = (eSapStatus) context; 2692 qdf_copy_macaddr(&key_complete->peerMacAddr, 2693 &csr_roaminfo->peerMac); 2694 break; 2695 2696 case eSAP_STA_MIC_FAILURE_EVENT: 2697 2698 if (!csr_roaminfo) { 2699 sap_debug("Invalid CSR Roam Info"); 2700 qdf_mem_free(sap_ap_event); 2701 return QDF_STATUS_E_INVAL; 2702 } 2703 sap_ap_event->sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; 2704 mic_failure = &sap_ap_event->sapevt.sapStationMICFailureEvent; 2705 2706 qdf_mem_copy(&mic_failure->srcMacAddr, 2707 csr_roaminfo->u.pMICFailureInfo->srcMacAddr, 2708 sizeof(tSirMacAddr)); 2709 qdf_mem_copy(&mic_failure->staMac.bytes, 2710 csr_roaminfo->u.pMICFailureInfo->taMacAddr, 2711 sizeof(tSirMacAddr)); 2712 qdf_mem_copy(&mic_failure->dstMacAddr.bytes, 2713 csr_roaminfo->u.pMICFailureInfo->dstMacAddr, 2714 sizeof(tSirMacAddr)); 2715 mic_failure->multicast = 2716 csr_roaminfo->u.pMICFailureInfo->multicast; 2717 mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1; 2718 mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId; 2719 qdf_mem_copy(mic_failure->TSC, 2720 csr_roaminfo->u.pMICFailureInfo->TSC, 2721 SIR_CIPHER_SEQ_CTR_SIZE); 2722 break; 2723 2724 case eSAP_WPS_PBC_PROBE_REQ_EVENT: 2725 2726 if (!csr_roaminfo) { 2727 sap_debug("Invalid CSR Roam Info"); 2728 qdf_mem_free(sap_ap_event); 2729 return QDF_STATUS_E_INVAL; 2730 } 2731 sap_ap_event->sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; 2732 2733 qdf_mem_copy(&sap_ap_event->sapevt.sapPBCProbeReqEvent. 2734 WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq, 2735 sizeof(tSirWPSPBCProbeReq)); 2736 break; 2737 2738 case eSAP_DISCONNECT_ALL_P2P_CLIENT: 2739 sap_ap_event->sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; 2740 sap_ap_event->sapevt.sapActionCnf.actionSendSuccess = 2741 (eSapStatus) context; 2742 break; 2743 2744 case eSAP_MAC_TRIG_STOP_BSS_EVENT: 2745 sap_ap_event->sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; 2746 sap_ap_event->sapevt.sapActionCnf.actionSendSuccess = 2747 (eSapStatus) context; 2748 break; 2749 2750 case eSAP_UNKNOWN_STA_JOIN: 2751 sap_ap_event->sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; 2752 qdf_mem_copy((void *)sap_ap_event->sapevt.sapUnknownSTAJoin. 2753 macaddr.bytes, (void *) context, 2754 QDF_MAC_ADDR_SIZE); 2755 break; 2756 2757 case eSAP_MAX_ASSOC_EXCEEDED: 2758 2759 if (!csr_roaminfo) { 2760 sap_debug("Invalid CSR Roam Info"); 2761 qdf_mem_free(sap_ap_event); 2762 return QDF_STATUS_E_INVAL; 2763 } 2764 sap_ap_event->sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; 2765 qdf_copy_macaddr(&sap_ap_event->sapevt. 2766 sapMaxAssocExceeded.macaddr, 2767 &csr_roaminfo->peerMac); 2768 break; 2769 2770 case eSAP_CHANNEL_CHANGE_EVENT: 2771 /* 2772 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS 2773 * follows pri AP 2774 */ 2775 sap_ctx->acs_cfg->pri_ch_freq = sap_ctx->chan_freq; 2776 sap_ctx->acs_cfg->ch_width = 2777 sap_ctx->ch_params.ch_width; 2778 sap_config_acs_result(MAC_HANDLE(mac_ctx), sap_ctx, 2779 sap_ctx->sec_ch_freq); 2780 2781 sap_ap_event->sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; 2782 2783 acs_selected = &sap_ap_event->sapevt.sap_ch_selected; 2784 acs_selected->pri_ch_freq = sap_ctx->chan_freq; 2785 acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq; 2786 acs_selected->ch_width = 2787 sap_ctx->acs_cfg->ch_width; 2788 acs_selected->vht_seg0_center_ch_freq = 2789 sap_ctx->acs_cfg->vht_seg0_center_ch_freq; 2790 acs_selected->vht_seg1_center_ch_freq = 2791 sap_ctx->acs_cfg->vht_seg1_center_ch_freq; 2792 break; 2793 2794 case eSAP_ECSA_CHANGE_CHAN_IND: 2795 2796 if (!csr_roaminfo) { 2797 sap_debug("Invalid CSR Roam Info"); 2798 qdf_mem_free(sap_ap_event); 2799 return QDF_STATUS_E_INVAL; 2800 } 2801 sap_debug("SAP event callback event = %s", 2802 "eSAP_ECSA_CHANGE_CHAN_IND"); 2803 sap_ap_event->sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND; 2804 sap_ap_event->sapevt.sap_chan_cng_ind.new_chan_freq = 2805 csr_roaminfo->target_chan_freq; 2806 break; 2807 case eSAP_DFS_NEXT_CHANNEL_REQ: 2808 sap_debug("SAP event callback event = %s", 2809 "eSAP_DFS_NEXT_CHANNEL_REQ"); 2810 sap_ap_event->sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ; 2811 break; 2812 case eSAP_STOP_BSS_DUE_TO_NO_CHNL: 2813 sap_ap_event->sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL; 2814 sap_debug("stopping session_id:%d, bssid:"QDF_MAC_ADDR_FMT", chan_freq:%d", 2815 sap_ctx->sessionId, 2816 QDF_MAC_ADDR_REF(sap_ctx->self_mac_addr), 2817 sap_ctx->chan_freq); 2818 break; 2819 2820 case eSAP_CHANNEL_CHANGE_RESP: 2821 sap_ap_event->sapHddEventCode = eSAP_CHANNEL_CHANGE_RESP; 2822 sap_ap_event->sapevt.sap_chan_cng_rsp.ch_change_rsp_status = 2823 (eSapStatus)context; 2824 acs_selected = 2825 &sap_ap_event->sapevt.sap_chan_cng_rsp.sap_ch_selected; 2826 acs_selected->pri_ch_freq = sap_ctx->chan_freq; 2827 acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq; 2828 acs_selected->ch_width = 2829 sap_ctx->ch_params.ch_width; 2830 acs_selected->vht_seg0_center_ch_freq = 2831 sap_ctx->ch_params.mhz_freq_seg0; 2832 acs_selected->vht_seg1_center_ch_freq = 2833 sap_ctx->ch_params.mhz_freq_seg1; 2834 sap_update_cac_history(mac_ctx, sap_ctx, 2835 sap_hddevent); 2836 sap_debug("SAP event callback event = %s", 2837 "eSAP_CHANNEL_CHANGE_RESP"); 2838 break; 2839 2840 default: 2841 sap_err("SAP Unknown callback event = %d", sap_hddevent); 2842 break; 2843 } 2844 qdf_status = (*sap_ctx->sap_event_cb) 2845 (sap_ap_event, sap_ctx->user_context); 2846 2847 qdf_mem_free(sap_ap_event); 2848 2849 return qdf_status; 2850 } 2851 2852 bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx) 2853 { 2854 struct wlan_objmgr_vdev *vdev; 2855 QDF_STATUS status; 2856 struct mac_context *mac_ctx; 2857 mac_handle_t mac_handle; 2858 2859 if (!sap_ctx) { 2860 sap_err("Invalid sap context"); 2861 return false; 2862 } 2863 2864 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 2865 if (!mac_handle) 2866 return false; 2867 2868 mac_ctx = MAC_CONTEXT(mac_handle); 2869 if (!mac_ctx) { 2870 sap_err("Invalid MAC context"); 2871 return false; 2872 } 2873 2874 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 2875 sap_ctx->sessionId, 2876 WLAN_DFS_ID); 2877 if (!vdev) { 2878 sap_err("vdev is NULL for vdev_id: %u", sap_ctx->sessionId); 2879 return false; 2880 } 2881 2882 status = wlan_vdev_is_dfs_cac_wait(vdev); 2883 wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); 2884 2885 return QDF_IS_STATUS_SUCCESS(status); 2886 } 2887 2888 /** 2889 * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state 2890 * @handle: Global MAC handle 2891 * 2892 * Finds and gets the context of a SAP session in CAC wait state. 2893 * 2894 * Return: Valid SAP context on success, else NULL 2895 */ 2896 static struct sap_context *sap_find_cac_wait_session(mac_handle_t handle) 2897 { 2898 struct mac_context *mac = MAC_CONTEXT(handle); 2899 uint8_t i = 0; 2900 struct sap_context *sap_ctx; 2901 2902 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 2903 sap_ctx = mac->sap.sapCtxList[i].sap_context; 2904 if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona) 2905 || 2906 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) && 2907 (sap_is_dfs_cac_wait_state(sap_ctx))) { 2908 sap_debug("found SAP in cac wait state"); 2909 return sap_ctx; 2910 } 2911 if (sap_ctx) { 2912 sap_debug("sapdfs: mode:%d intf:%d state:%d", 2913 mac->sap.sapCtxList[i].sapPersona, i, 2914 sap_ctx->fsm_state); 2915 } 2916 } 2917 2918 return NULL; 2919 } 2920 2921 void sap_cac_reset_notify(mac_handle_t mac_handle) 2922 { 2923 uint8_t intf = 0; 2924 struct mac_context *mac = MAC_CONTEXT(mac_handle); 2925 2926 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2927 struct sap_context *sap_context = 2928 mac->sap.sapCtxList[intf].sap_context; 2929 if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona) 2930 || 2931 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona)) 2932 && mac->sap.sapCtxList[intf].sap_context) { 2933 sap_context->isCacStartNotified = false; 2934 sap_context->isCacEndNotified = false; 2935 } 2936 } 2937 } 2938 2939 /** 2940 * sap_cac_start_notify() - Notify CAC start to HDD 2941 * @mac_handle: Opaque handle to the global MAC context 2942 * 2943 * Function will be called to notify eSAP_DFS_CAC_START event to HDD 2944 * 2945 * Return: QDF_STATUS_SUCCESS if the notification was sent, otherwise 2946 * an appropriate QDF_STATUS error 2947 */ 2948 static QDF_STATUS sap_cac_start_notify(mac_handle_t mac_handle) 2949 { 2950 uint8_t intf = 0; 2951 struct mac_context *mac = MAC_CONTEXT(mac_handle); 2952 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2953 2954 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2955 struct sap_context *sap_context = 2956 mac->sap.sapCtxList[intf].sap_context; 2957 2958 if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona) 2959 || 2960 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona)) 2961 && mac->sap.sapCtxList[intf].sap_context && 2962 (false == sap_context->isCacStartNotified)) { 2963 /* Don't start CAC for non-dfs channel, its violation */ 2964 if (!sap_operating_on_dfs( 2965 mac, 2966 mac->sap.sapCtxList[intf].sap_context)) 2967 continue; 2968 sap_debug("sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]", 2969 sap_context); 2970 2971 qdf_status = sap_signal_hdd_event(sap_context, NULL, 2972 eSAP_DFS_CAC_START, 2973 (void *) 2974 eSAP_STATUS_SUCCESS); 2975 if (QDF_STATUS_SUCCESS != qdf_status) { 2976 sap_err("Failed setting isCacStartNotified on interface[%d]", 2977 intf); 2978 return qdf_status; 2979 } 2980 sap_context->isCacStartNotified = true; 2981 } 2982 } 2983 return qdf_status; 2984 } 2985 2986 #ifdef PRE_CAC_SUPPORT 2987 /** 2988 * wlansap_pre_cac_end_notify() - Update pre cac end to upper layer 2989 * @sap_context: SAP context 2990 * @mac: Global MAC structure 2991 * @intf: Interface number 2992 * 2993 * Notifies pre cac end to upper layer 2994 * 2995 * Return: None 2996 */ 2997 static void wlansap_pre_cac_end_notify(struct sap_context *sap_context, 2998 struct mac_context *mac, 2999 uint8_t intf) 3000 { 3001 sap_context->isCacEndNotified = true; 3002 sap_context->sap_radar_found_status = false; 3003 sap_context->fsm_state = SAP_STARTED; 3004 sap_warn("sap_fsm: vdev %d => SAP_STARTED, pre cac end notify on %d", 3005 sap_context->vdev_id, intf); 3006 wlan_pre_cac_handle_cac_end(sap_context->vdev); 3007 } 3008 #endif 3009 3010 QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle, 3011 struct csr_roam_info *roamInfo) 3012 { 3013 uint8_t intf; 3014 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3015 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3016 bool is_acs; 3017 3018 /* 3019 * eSAP_DFS_CHANNEL_CAC_END: 3020 * CAC Period elapsed and there was no radar 3021 * found so, SAP can continue beaconing. 3022 * sap_radar_found_status is set to 0 3023 */ 3024 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3025 struct sap_context *sap_context = 3026 mac->sap.sapCtxList[intf].sap_context; 3027 3028 if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona) 3029 || 3030 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona)) 3031 && mac->sap.sapCtxList[intf].sap_context && 3032 (false == sap_context->isCacEndNotified) && 3033 sap_is_dfs_cac_wait_state(sap_context)) { 3034 sap_context = mac->sap.sapCtxList[intf].sap_context; 3035 /* Don't check CAC for non-dfs channel */ 3036 if (!sap_operating_on_dfs( 3037 mac, 3038 mac->sap.sapCtxList[intf].sap_context)) 3039 continue; 3040 3041 /* If this is an end notification of a pre cac, the 3042 * SAP must not start beaconing and must delete the 3043 * temporary interface created for pre cac and switch 3044 * the original SAP to the pre CAC channel. 3045 */ 3046 if (wlan_pre_cac_get_status(mac->psoc)) { 3047 wlansap_pre_cac_end_notify(sap_context, 3048 mac, intf); 3049 /* pre CAC is not allowed with any concurrency. 3050 * So, we can break from here. 3051 */ 3052 break; 3053 } 3054 3055 qdf_status = sap_signal_hdd_event(sap_context, NULL, 3056 eSAP_DFS_CAC_END, 3057 (void *) 3058 eSAP_STATUS_SUCCESS); 3059 if (QDF_STATUS_SUCCESS != qdf_status) { 3060 sap_err("failed setting isCacEndNotified on interface[%d]", 3061 intf); 3062 return qdf_status; 3063 } 3064 sap_context->isCacEndNotified = true; 3065 sap_context->sap_radar_found_status = false; 3066 sap_debug("sapdfs: Start beacon request on sapctx[%pK]", 3067 sap_context); 3068 3069 /* Start beaconing on the new channel */ 3070 wlansap_start_beacon_req(sap_context); 3071 3072 /* Transition from SAP_STARTING to SAP_STARTED 3073 * (both without substates) 3074 */ 3075 sap_context->fsm_state = SAP_STARTED; 3076 sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED, freq %d", 3077 sap_context->vdev_id, sap_context->chan_freq); 3078 3079 /*Action code for transition */ 3080 qdf_status = sap_signal_hdd_event(sap_context, roamInfo, 3081 eSAP_START_BSS_EVENT, 3082 (void *) 3083 eSAP_STATUS_SUCCESS); 3084 if (QDF_STATUS_SUCCESS != qdf_status) { 3085 sap_err("Failed setting isCacEndNotified on interface[%d]", 3086 intf); 3087 return qdf_status; 3088 } 3089 3090 /* 3091 * CAC wait prevent SAP restart, check if need 3092 * restart SAP after CAC end 3093 */ 3094 is_acs = sap_context->acs_cfg && 3095 sap_context->acs_cfg->acs_mode; 3096 policy_mgr_check_concurrent_intf_and_restart_sap(mac->psoc, 3097 is_acs); 3098 } 3099 } 3100 3101 return qdf_status; 3102 } 3103 3104 /** 3105 * sap_validate_dfs_nol() - Validate SAP channel with NOL list 3106 * @sap_ctx: SAP context 3107 * @mac_ctx: pointer to mac context 3108 * 3109 * Function will be called to validate SAP channel and bonded sub channels 3110 * included in DFS NOL or not. 3111 * 3112 * Return: QDF_STATUS_SUCCESS for NOT in NOL 3113 */ 3114 static QDF_STATUS sap_validate_dfs_nol(struct sap_context *sap_ctx, 3115 struct mac_context *mac_ctx) 3116 { 3117 bool b_leak_chan = false; 3118 uint16_t temp_freq; 3119 uint16_t sap_freq; 3120 enum channel_state ch_state; 3121 bool is_chan_nol = false; 3122 3123 sap_freq = sap_ctx->chan_freq; 3124 temp_freq = sap_freq; 3125 utils_dfs_mark_leaking_chan_for_freq(mac_ctx->pdev, 3126 sap_ctx->ch_params.ch_width, 1, 3127 &temp_freq); 3128 3129 /* 3130 * if selelcted channel has leakage to channels 3131 * in NOL, the temp_freq will be reset 3132 */ 3133 b_leak_chan = (temp_freq != sap_freq); 3134 /* 3135 * check if channel is in DFS_NOL or if the channel 3136 * has leakage to the channels in NOL 3137 */ 3138 3139 if (sap_phymode_is_eht(sap_ctx->phyMode)) { 3140 ch_state = 3141 wlan_reg_get_channel_state_from_secondary_list_for_freq( 3142 mac_ctx->pdev, sap_freq); 3143 if (CHANNEL_STATE_ENABLE != ch_state && 3144 CHANNEL_STATE_DFS != ch_state) { 3145 sap_err_rl("Invalid sap freq = %d, ch state=%d", 3146 sap_freq, ch_state); 3147 is_chan_nol = true; 3148 } 3149 } else { 3150 is_chan_nol = sap_dfs_is_channel_in_nol_list( 3151 sap_ctx, sap_ctx->chan_freq, 3152 PHY_CHANNEL_BONDING_STATE_MAX); 3153 } 3154 3155 if (is_chan_nol || b_leak_chan) { 3156 qdf_freq_t chan_freq; 3157 3158 /* find a new available channel */ 3159 chan_freq = sap_random_channel_sel(sap_ctx); 3160 if (!chan_freq) { 3161 /* No available channel found */ 3162 sap_err("No available channel found!!!"); 3163 sap_signal_hdd_event(sap_ctx, NULL, 3164 eSAP_DFS_NO_AVAILABLE_CHANNEL, 3165 (void *)eSAP_STATUS_SUCCESS); 3166 return QDF_STATUS_E_FAULT; 3167 } 3168 3169 sap_debug("ch_freq %d is in NOL, start bss on new freq %d", 3170 sap_ctx->chan_freq, chan_freq); 3171 3172 sap_ctx->chan_freq = chan_freq; 3173 if (sap_phymode_is_eht(sap_ctx->phyMode)) 3174 wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params, 3175 true); 3176 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, 3177 sap_ctx->chan_freq, 3178 sap_ctx->sec_ch_freq, 3179 &sap_ctx->ch_params, 3180 REG_CURRENT_PWR_MODE); 3181 } 3182 3183 return QDF_STATUS_SUCCESS; 3184 } 3185 3186 static void sap_validate_chanmode_and_chwidth(struct mac_context *mac_ctx, 3187 struct sap_context *sap_ctx) 3188 { 3189 uint32_t orig_phymode; 3190 enum phy_ch_width orig_ch_width; 3191 3192 orig_ch_width = sap_ctx->ch_params.ch_width; 3193 orig_phymode = sap_ctx->phyMode; 3194 3195 if (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq) && 3196 (sap_ctx->phyMode == eCSR_DOT11_MODE_11g || 3197 sap_ctx->phyMode == eCSR_DOT11_MODE_11g_ONLY)) { 3198 sap_ctx->phyMode = eCSR_DOT11_MODE_11a; 3199 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) && 3200 (sap_ctx->phyMode == eCSR_DOT11_MODE_11a)) { 3201 sap_ctx->phyMode = eCSR_DOT11_MODE_11g; 3202 } 3203 3204 if (sap_ctx->ch_params.ch_width > CH_WIDTH_20MHZ && 3205 (sap_ctx->phyMode == eCSR_DOT11_MODE_abg || 3206 sap_ctx->phyMode == eCSR_DOT11_MODE_11a || 3207 sap_ctx->phyMode == eCSR_DOT11_MODE_11g || 3208 sap_ctx->phyMode == eCSR_DOT11_MODE_11b)) { 3209 sap_ctx->ch_params.ch_width = CH_WIDTH_20MHZ; 3210 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, 3211 sap_ctx->chan_freq, 3212 sap_ctx->ch_params.sec_ch_offset, 3213 &sap_ctx->ch_params, 3214 REG_CURRENT_PWR_MODE); 3215 } else if (sap_ctx->ch_params.ch_width > CH_WIDTH_40MHZ && 3216 sap_ctx->phyMode == eCSR_DOT11_MODE_11n) { 3217 sap_ctx->ch_params.ch_width = CH_WIDTH_40MHZ; 3218 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, 3219 sap_ctx->chan_freq, 3220 sap_ctx->ch_params.sec_ch_offset, 3221 &sap_ctx->ch_params, 3222 REG_CURRENT_PWR_MODE); 3223 } 3224 3225 if (orig_ch_width != sap_ctx->ch_params.ch_width || 3226 orig_phymode != sap_ctx->phyMode) 3227 sap_info("Freq %d Updated BW %d -> %d , phymode %d -> %d", 3228 sap_ctx->chan_freq, orig_ch_width, 3229 sap_ctx->ch_params.ch_width, 3230 orig_phymode, sap_ctx->phyMode); 3231 } 3232 3233 static bool 3234 wlansap_is_power_change_required(struct mac_context *mac_ctx, 3235 qdf_freq_t sap_freq) 3236 { 3237 struct wlan_objmgr_vdev *sta_vdev; 3238 uint8_t sta_vdev_id; 3239 enum hw_mode_bandwidth ch_wd; 3240 uint8_t country[CDS_COUNTRY_CODE_LEN + 1]; 3241 enum channel_state state; 3242 uint32_t ap_pwr_type_6g = 0; 3243 bool indoor_ch_support = false; 3244 3245 if (!mac_ctx || !mac_ctx->psoc || !mac_ctx->pdev) 3246 return false; 3247 3248 if (!policy_mgr_is_sta_present_on_freq(mac_ctx->psoc, &sta_vdev_id, 3249 sap_freq, &ch_wd)) { 3250 return false; 3251 } 3252 3253 sta_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 3254 sta_vdev_id, 3255 WLAN_LEGACY_SAP_ID); 3256 if (!sta_vdev) 3257 return false; 3258 3259 ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(sta_vdev); 3260 3261 wlan_objmgr_vdev_release_ref(sta_vdev, WLAN_LEGACY_SAP_ID); 3262 3263 if (ap_pwr_type_6g == REG_VERY_LOW_POWER_AP) 3264 return false; 3265 ucfg_mlme_get_indoor_channel_support(mac_ctx->psoc, &indoor_ch_support); 3266 3267 if (ap_pwr_type_6g == REG_INDOOR_AP && indoor_ch_support) { 3268 sap_debug("STA is connected to Indoor AP and indoor concurrency is supported"); 3269 return false; 3270 } 3271 3272 wlan_reg_read_current_country(mac_ctx->psoc, country); 3273 if (!wlan_reg_ctry_support_vlp(country)) { 3274 sap_debug("Device country doesn't support VLP"); 3275 return false; 3276 } 3277 3278 state = wlan_reg_get_channel_state_for_pwrmode(mac_ctx->pdev, 3279 sap_freq, REG_AP_VLP); 3280 3281 return state & CHANNEL_STATE_ENABLE; 3282 } 3283 3284 /** 3285 * sap_goto_starting() - Trigger softap start 3286 * @sap_ctx: SAP context 3287 * @sap_event: SAP event buffer 3288 * @mac_ctx: global MAC context 3289 * @mac_handle: Opaque handle to the global MAC context 3290 * 3291 * This function triggers start of softap. Before starting, it can select 3292 * new channel if given channel has leakage or if given channel in DFS_NOL. 3293 * 3294 * Return: QDF_STATUS 3295 */ 3296 static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, 3297 struct sap_sm_event *sap_event, 3298 struct mac_context *mac_ctx, 3299 mac_handle_t mac_handle) 3300 { 3301 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3302 struct bss_dot11_config dot11_cfg = {0}; 3303 tSirMacRateSet *opr_rates = &sap_ctx->sap_bss_cfg.operationalRateSet; 3304 tSirMacRateSet *ext_rates = &sap_ctx->sap_bss_cfg.extendedRateSet; 3305 uint8_t h2e; 3306 3307 /* 3308 * check if channel is in DFS_NOL or if the channel 3309 * has leakage to the channels in NOL. 3310 */ 3311 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) { 3312 qdf_status = sap_validate_dfs_nol(sap_ctx, mac_ctx); 3313 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 3314 return qdf_status; 3315 } else if (!policy_mgr_get_ap_6ghz_capable(mac_ctx->psoc, 3316 sap_ctx->sessionId, NULL)) { 3317 return QDF_STATUS_E_FAILURE; 3318 } else if (wlansap_is_power_change_required(mac_ctx, 3319 sap_ctx->chan_freq)) { 3320 wlan_set_tpc_update_required_for_sta(sap_ctx->vdev, true); 3321 } 3322 3323 /* 3324 * when AP2 is started while AP1 is performing ACS, we may not 3325 * have the AP1 channel yet.So here after the completion of AP2 3326 * ACS check if AP1 ACS resulting channel is DFS and if yes 3327 * override AP2 ACS scan result with AP1 DFS channel 3328 */ 3329 if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc)) { 3330 uint32_t con_ch_freq; 3331 uint16_t con_ch; 3332 3333 con_ch_freq = sme_get_beaconing_concurrent_operation_channel( 3334 mac_handle, sap_ctx->sessionId); 3335 con_ch = wlan_reg_freq_to_chan(mac_ctx->pdev, con_ch_freq); 3336 /* Overwrite second AP's channel with first only when: 3337 * 1. If operating mode is single mac 3338 * 2. or if 2nd AP is coming up on 5G band channel 3339 */ 3340 if ((!policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) || 3341 WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq)) && 3342 con_ch && 3343 wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 3344 con_ch_freq)) { 3345 sap_ctx->chan_freq = con_ch_freq; 3346 if (sap_phymode_is_eht(sap_ctx->phyMode)) 3347 wlan_reg_set_create_punc_bitmap( 3348 &sap_ctx->ch_params, true); 3349 wlan_reg_set_channel_params_for_pwrmode( 3350 mac_ctx->pdev, 3351 con_ch_freq, 0, 3352 &sap_ctx->ch_params, 3353 REG_CURRENT_PWR_MODE); 3354 } 3355 } 3356 3357 sap_validate_chanmode_and_chwidth(mac_ctx, sap_ctx); 3358 /* Channel selected. Now can sap_goto_starting */ 3359 sap_ctx->fsm_state = SAP_STARTING; 3360 sap_debug("sap_fsm: vdev %d: SAP_INIT => SAP_STARTING, phyMode %d bw %d", 3361 sap_ctx->vdev_id, sap_ctx->phyMode, 3362 sap_ctx->ch_params.ch_width); 3363 /* Specify the channel */ 3364 sap_get_cac_dur_dfs_region(sap_ctx, 3365 &sap_ctx->sap_bss_cfg.cac_duration_ms, 3366 &sap_ctx->sap_bss_cfg.dfs_regdomain, 3367 sap_ctx->chan_freq, 3368 &sap_ctx->ch_params); 3369 mlme_set_cac_required(sap_ctx->vdev, 3370 !!sap_ctx->sap_bss_cfg.cac_duration_ms); 3371 3372 sap_ctx->sap_bss_cfg.oper_ch_freq = sap_ctx->chan_freq; 3373 sap_ctx->sap_bss_cfg.vht_channel_width = sap_ctx->ch_params.ch_width; 3374 sap_ctx->sap_bss_cfg.center_freq_seg0 = 3375 sap_ctx->ch_params.center_freq_seg0; 3376 sap_ctx->sap_bss_cfg.center_freq_seg1 = 3377 sap_ctx->ch_params.center_freq_seg1; 3378 sap_ctx->sap_bss_cfg.sec_ch_offset = sap_ctx->ch_params.sec_ch_offset; 3379 3380 dot11_cfg.vdev_id = sap_ctx->sessionId; 3381 dot11_cfg.bss_op_ch_freq = sap_ctx->chan_freq; 3382 dot11_cfg.phy_mode = sap_ctx->phyMode; 3383 dot11_cfg.privacy = sap_ctx->sap_bss_cfg.privacy; 3384 3385 qdf_mem_copy(dot11_cfg.opr_rates.rate, 3386 opr_rates->rate, opr_rates->numRates); 3387 dot11_cfg.opr_rates.numRates = opr_rates->numRates; 3388 3389 qdf_mem_copy(dot11_cfg.ext_rates.rate, 3390 ext_rates->rate, ext_rates->numRates); 3391 dot11_cfg.ext_rates.numRates = ext_rates->numRates; 3392 3393 sme_get_network_params(mac_ctx, &dot11_cfg); 3394 3395 sap_ctx->sap_bss_cfg.nwType = dot11_cfg.nw_type; 3396 sap_ctx->sap_bss_cfg.dot11mode = dot11_cfg.dot11_mode; 3397 3398 if (dot11_cfg.opr_rates.numRates) { 3399 qdf_mem_copy(opr_rates->rate, 3400 dot11_cfg.opr_rates.rate, 3401 dot11_cfg.opr_rates.numRates); 3402 opr_rates->numRates = dot11_cfg.opr_rates.numRates; 3403 } else { 3404 qdf_mem_zero(opr_rates, sizeof(tSirMacRateSet)); 3405 } 3406 3407 if (dot11_cfg.ext_rates.numRates) { 3408 qdf_mem_copy(ext_rates->rate, 3409 dot11_cfg.ext_rates.rate, 3410 dot11_cfg.ext_rates.numRates); 3411 ext_rates->numRates = dot11_cfg.ext_rates.numRates; 3412 } else { 3413 qdf_mem_zero(ext_rates, sizeof(tSirMacRateSet)); 3414 } 3415 3416 if (sap_ctx->require_h2e) { 3417 h2e = WLAN_BASIC_RATE_MASK | 3418 WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E; 3419 if (ext_rates->numRates < SIR_MAC_MAX_NUMBER_OF_RATES) { 3420 ext_rates->rate[ext_rates->numRates] = h2e; 3421 ext_rates->numRates++; 3422 sap_debug("H2E bss membership add to ext support rate"); 3423 } else if (opr_rates->numRates < SIR_MAC_MAX_NUMBER_OF_RATES) { 3424 opr_rates->rate[opr_rates->numRates] = h2e; 3425 opr_rates->numRates++; 3426 sap_debug("H2E bss membership add to support rate"); 3427 } else { 3428 sap_err("rates full, can not add H2E bss membership"); 3429 } 3430 } 3431 sap_dfs_set_current_channel(sap_ctx); 3432 /* Reset radar found flag before start sap, the flag will 3433 * be set when radar found in CAC wait. 3434 */ 3435 sap_ctx->sap_radar_found_status = false; 3436 3437 sap_debug("session: %d", sap_ctx->sessionId); 3438 3439 qdf_status = sme_start_bss(mac_handle, sap_ctx->sessionId, 3440 &sap_ctx->sap_bss_cfg); 3441 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 3442 sap_err("Failed to issue sme_roam_connect"); 3443 3444 return qdf_status; 3445 } 3446 3447 /** 3448 * sap_fsm_cac_start() - start cac wait timer 3449 * @sap_ctx: SAP context 3450 * @mac_ctx: global MAC context 3451 * @mac_handle: Opaque handle to the global MAC context 3452 * 3453 * Return: QDF_STATUS 3454 */ 3455 static QDF_STATUS sap_fsm_cac_start(struct sap_context *sap_ctx, 3456 struct mac_context *mac_ctx, 3457 mac_handle_t mac_handle) 3458 { 3459 if (!mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) { 3460 sap_debug("sapdfs: starting dfs cac timer on sapctx[%pK]", 3461 sap_ctx); 3462 sap_start_dfs_cac_timer(sap_ctx); 3463 } 3464 3465 return sap_cac_start_notify(mac_handle); 3466 } 3467 3468 /** 3469 * sap_fsm_state_init() - utility function called from sap fsm 3470 * @sap_ctx: SAP context 3471 * @sap_event: SAP event buffer 3472 * @mac_ctx: global MAC context 3473 * @mac_handle: Opaque handle to the global MAC context 3474 * 3475 * This function is called for state transition from "SAP_INIT" 3476 * 3477 * Return: QDF_STATUS 3478 */ 3479 static QDF_STATUS sap_fsm_state_init(struct sap_context *sap_ctx, 3480 struct sap_sm_event *sap_event, 3481 struct mac_context *mac_ctx, 3482 mac_handle_t mac_handle) 3483 { 3484 uint32_t msg = sap_event->event; 3485 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3486 3487 if (msg == eSAP_HDD_START_INFRA_BSS) { 3488 /* init dfs channel nol */ 3489 sap_init_dfs_channel_nol_list(sap_ctx); 3490 3491 /* 3492 * Perform sme_ScanRequest. This scan request is post start bss 3493 * request so, set the third to false. 3494 */ 3495 qdf_status = sap_validate_chan(sap_ctx, false, true); 3496 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3497 sap_err("vdev %d: channel is not valid!", 3498 sap_ctx->vdev_id); 3499 goto exit; 3500 } 3501 3502 qdf_status = sap_goto_starting(sap_ctx, sap_event, 3503 mac_ctx, mac_handle); 3504 if (QDF_IS_STATUS_ERROR(qdf_status)) 3505 sap_err("vdev %d: sap_goto_starting failed", 3506 sap_ctx->vdev_id); 3507 } else { 3508 sap_err("sap_fsm: vdev %d: SAP_INIT, invalid event %d", 3509 sap_ctx->vdev_id, msg); 3510 } 3511 3512 exit: 3513 return qdf_status; 3514 } 3515 3516 /** 3517 * sap_fsm_handle_radar_during_cac() - uhandle radar event during cac 3518 * @sap_ctx: SAP context 3519 * @mac_ctx: global MAC context 3520 * 3521 * Return: QDF_STATUS 3522 */ 3523 static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx, 3524 struct mac_context *mac_ctx) 3525 { 3526 uint8_t intf; 3527 3528 if (mac_ctx->sap.SapDfsInfo.target_chan_freq) { 3529 if (sap_phymode_is_eht(sap_ctx->phyMode)) 3530 wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params, 3531 true); 3532 wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev, 3533 mac_ctx->sap.SapDfsInfo.target_chan_freq, 0, 3534 &sap_ctx->ch_params, REG_CURRENT_PWR_MODE); 3535 } else { 3536 sap_err("Invalid target channel freq %d", 3537 mac_ctx->sap.SapDfsInfo.target_chan_freq); 3538 return QDF_STATUS_E_FAILURE; 3539 } 3540 3541 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3542 struct sap_context *t_sap_ctx; 3543 3544 t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context; 3545 if (((QDF_SAP_MODE == 3546 mac_ctx->sap.sapCtxList[intf].sapPersona) || 3547 (QDF_P2P_GO_MODE == 3548 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 3549 t_sap_ctx && t_sap_ctx->fsm_state != SAP_INIT) { 3550 if (!sap_operating_on_dfs(mac_ctx, t_sap_ctx)) 3551 continue; 3552 t_sap_ctx->is_chan_change_inprogress = true; 3553 /* 3554 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: 3555 * A Radar is found on current DFS Channel 3556 * while in CAC WAIT period So, do a channel 3557 * switch to randomly selected target channel. 3558 * Send the Channel change message to SME/PE. 3559 * sap_radar_found_status is set to 1 3560 */ 3561 wlansap_channel_change_request(t_sap_ctx, 3562 mac_ctx->sap.SapDfsInfo.target_chan_freq); 3563 } 3564 } 3565 3566 return QDF_STATUS_SUCCESS; 3567 } 3568 3569 /** 3570 * sap_fsm_handle_start_failure() - handle sap start failure 3571 * @sap_ctx: SAP context 3572 * @msg: event msg 3573 * @mac_handle: Opaque handle to the global MAC context 3574 * 3575 * Return: QDF_STATUS 3576 */ 3577 static QDF_STATUS sap_fsm_handle_start_failure(struct sap_context *sap_ctx, 3578 uint32_t msg, 3579 mac_handle_t mac_handle) 3580 { 3581 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3582 3583 if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3584 /* 3585 * Stop the CAC timer only in following conditions 3586 * single AP: if there is a single AP then stop timer 3587 * multiple APs: incase of multiple APs, make sure that 3588 * all APs are down. 3589 */ 3590 if (!sap_find_valid_concurrent_session(mac_handle)) { 3591 sap_debug("sapdfs: no sessions are valid, stopping timer"); 3592 sap_stop_dfs_cac_timer(sap_ctx); 3593 } 3594 /* Transition from SAP_STARTING to SAP_STOPPING */ 3595 sap_ctx->fsm_state = SAP_STOPPING; 3596 sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STOPPING, start is in progress", 3597 sap_ctx->vdev_id); 3598 qdf_status = sap_goto_stopping(sap_ctx); 3599 } else { 3600 /* 3601 * Transition from SAP_STARTING to SAP_INIT 3602 * (both without substates) 3603 */ 3604 sap_ctx->fsm_state = SAP_INIT; 3605 sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_INIT", 3606 sap_ctx->vdev_id); 3607 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3608 eSAP_START_BSS_EVENT, 3609 (void *) 3610 eSAP_STATUS_FAILURE); 3611 qdf_status = sap_goto_init(sap_ctx); 3612 } 3613 3614 return qdf_status; 3615 } 3616 3617 /** 3618 * sap_propagate_cac_events() - Indicate CAC START/END event 3619 * @sap_ctx: SAP context 3620 * 3621 * This function is to indicate CAC START/END event if CAC process 3622 * is skipped. 3623 * 3624 * Return: void 3625 */ 3626 static void sap_propagate_cac_events(struct sap_context *sap_ctx) 3627 { 3628 QDF_STATUS qdf_status; 3629 3630 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3631 eSAP_DFS_CAC_START, 3632 (void *) 3633 eSAP_STATUS_SUCCESS); 3634 if (qdf_status != QDF_STATUS_SUCCESS) { 3635 sap_err("Failed to indicate CAC START vdev %d", 3636 sap_ctx->sessionId); 3637 return; 3638 } 3639 3640 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 3641 eSAP_DFS_CAC_END, 3642 (void *) 3643 eSAP_STATUS_SUCCESS); 3644 if (qdf_status != QDF_STATUS_SUCCESS) { 3645 sap_debug("Failed to indicate CAC End vdev %d", 3646 sap_ctx->sessionId); 3647 } 3648 } 3649 3650 static void sap_check_and_update_vdev_ch_params(struct sap_context *sap_ctx) 3651 { 3652 struct wlan_channel *chan; 3653 enum phy_ch_width orig_ch_width; 3654 3655 chan = wlan_vdev_get_active_channel(sap_ctx->vdev); 3656 if (!chan) { 3657 sap_debug("Couldn't get vdev active channel"); 3658 return; 3659 } 3660 if (sap_ctx->ch_params.ch_width == chan->ch_width) 3661 return; 3662 3663 orig_ch_width = sap_ctx->ch_params.ch_width; 3664 3665 sap_ctx->ch_params.ch_width = chan->ch_width; 3666 sap_ctx->ch_params.center_freq_seg0 = chan->ch_freq_seg1; 3667 sap_ctx->ch_params.center_freq_seg1 = chan->ch_freq_seg2; 3668 sap_ctx->ch_params.mhz_freq_seg0 = chan->ch_cfreq1; 3669 sap_ctx->ch_params.mhz_freq_seg1 = chan->ch_cfreq2; 3670 3671 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) && 3672 (chan->ch_width == CH_WIDTH_40MHZ)) { 3673 if (sap_ctx->chan_freq < chan->ch_freq_seg1) 3674 sap_ctx->ch_params.sec_ch_offset = LOW_PRIMARY_CH; 3675 else 3676 sap_ctx->ch_params.sec_ch_offset = HIGH_PRIMARY_CH; 3677 } 3678 sap_debug("updated BW %d -> %d", orig_ch_width, 3679 sap_ctx->ch_params.ch_width); 3680 } 3681 3682 static qdf_freq_t sap_get_safe_channel_freq(struct sap_context *sap_ctx) 3683 { 3684 qdf_freq_t freq; 3685 3686 freq = wlan_pre_cac_get_freq_before_pre_cac(sap_ctx->vdev); 3687 if (!freq) 3688 freq = wlansap_get_safe_channel_from_pcl_and_acs_range( 3689 sap_ctx, 3690 NULL); 3691 3692 sap_debug("new selected freq %d as target chan as current freq unsafe %d", 3693 freq, sap_ctx->chan_freq); 3694 3695 return freq; 3696 } 3697 3698 /** 3699 * sap_fsm_send_csa_restart_req() - send csa start event 3700 * @mac_ctx: mac ctx 3701 * @sap_ctx: SAP context 3702 * 3703 * Return: QDF_STATUS 3704 */ 3705 static inline QDF_STATUS 3706 sap_fsm_send_csa_restart_req(struct mac_context *mac_ctx, 3707 struct sap_context *sap_ctx) 3708 { 3709 QDF_STATUS status; 3710 3711 status = policy_mgr_check_and_set_hw_mode_for_channel_switch( 3712 mac_ctx->psoc, sap_ctx->sessionId, 3713 mac_ctx->sap.SapDfsInfo.target_chan_freq, 3714 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP); 3715 3716 /* 3717 * If hw_mode_status is QDF_STATUS_E_FAILURE, mean HW 3718 * mode change was required but driver failed to set HW 3719 * mode so ignore CSA for the channel. 3720 */ 3721 if (status == QDF_STATUS_E_FAILURE) { 3722 sap_err("HW change required but failed to set hw mode"); 3723 return status; 3724 } 3725 3726 /* 3727 * If hw_mode_status is QDF_STATUS_SUCCESS mean HW mode 3728 * change was required and was successfully requested so 3729 * the channel switch will continue after HW mode change 3730 * completion. 3731 */ 3732 if (QDF_IS_STATUS_SUCCESS(status)) { 3733 sap_info("Channel change will continue after HW mode change"); 3734 return QDF_STATUS_SUCCESS; 3735 } 3736 3737 return sme_csa_restart(mac_ctx, sap_ctx->sessionId); 3738 } 3739 3740 /** 3741 * sap_fsm_validate_and_change_channel() - handle channel Avoid event event 3742 * or channel list update during cac 3743 * @mac_ctx: global MAC context 3744 * @sap_ctx: SAP context 3745 * 3746 * Return: QDF_STATUS 3747 */ 3748 static void sap_fsm_validate_and_change_channel(struct mac_context *mac_ctx, 3749 struct sap_context *sap_ctx) 3750 { 3751 qdf_freq_t target_chan_freq; 3752 struct ch_params ch_params = {0}; 3753 QDF_STATUS status; 3754 enum phy_ch_width target_bw = sap_ctx->ch_params.ch_width; 3755 3756 if (((!sap_ctx->acs_cfg || !sap_ctx->acs_cfg->acs_mode) && 3757 (!policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc) || 3758 target_psoc_get_sap_coex_fixed_chan_cap( 3759 wlan_psoc_get_tgt_if_handle(mac_ctx->psoc)))) || 3760 (policy_mgr_is_sap_freq_allowed(mac_ctx->psoc, sap_ctx->chan_freq) && 3761 !wlan_reg_is_disable_for_pwrmode(mac_ctx->pdev, sap_ctx->chan_freq, 3762 REG_CURRENT_PWR_MODE))) 3763 return; 3764 3765 /* 3766 * The selected channel is not safe channel. Hence, 3767 * change the sap channel to a safe channel. 3768 */ 3769 target_chan_freq = sap_get_safe_channel_freq(sap_ctx); 3770 ch_params.ch_width = target_bw; 3771 target_bw = wlansap_get_csa_chanwidth_from_phymode( 3772 sap_ctx, target_chan_freq, &ch_params); 3773 sap_debug("sap vdev %d change to safe ch freq %d bw %d from unsafe %d", 3774 sap_ctx->sessionId, target_chan_freq, target_bw, 3775 sap_ctx->chan_freq); 3776 status = wlansap_set_channel_change_with_csa( 3777 sap_ctx, target_chan_freq, target_bw, false); 3778 if (QDF_IS_STATUS_ERROR(status)) 3779 sap_err("SAP set channel failed for freq: %d, bw: %d", 3780 target_chan_freq, target_bw); 3781 } 3782 3783 /** 3784 * sap_fsm_state_starting() - utility function called from sap fsm 3785 * @sap_ctx: SAP context 3786 * @sap_event: SAP event buffer 3787 * @mac_ctx: global MAC context 3788 * @mac_handle: Opaque handle to the global MAC context 3789 * 3790 * This function is called for state transition from "SAP_STARTING" 3791 * 3792 * Return: QDF_STATUS 3793 */ 3794 static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, 3795 struct sap_sm_event *sap_event, 3796 struct mac_context *mac_ctx, 3797 mac_handle_t mac_handle) 3798 { 3799 uint32_t msg = sap_event->event; 3800 struct csr_roam_info *roam_info = 3801 (struct csr_roam_info *) (sap_event->params); 3802 tSapDfsInfo *sap_dfs_info; 3803 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3804 uint8_t is_dfs = false; 3805 uint32_t sap_chan_freq; 3806 uint32_t ch_cfreq1 = 0; 3807 enum reg_wifi_band band; 3808 eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; 3809 3810 if (msg == eSAP_MAC_START_BSS_SUCCESS) { 3811 /* 3812 * Update sap_ctx->ch_params from vdev to make up with any BW 3813 * change in lower layer 3814 */ 3815 sap_check_and_update_vdev_ch_params(sap_ctx); 3816 3817 /* 3818 * Transition from SAP_STARTING to SAP_STARTED 3819 * (both without substates) 3820 */ 3821 sap_ctx->fsm_state = SAP_STARTED; 3822 sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED, freq %d ch_width %d", 3823 sap_ctx->vdev_id, sap_ctx->chan_freq, 3824 sap_ctx->ch_params.ch_width); 3825 3826 if (sap_ctx->is_chan_change_inprogress) { 3827 /* SAP channel change request processing is completed */ 3828 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3829 eSAP_CHANNEL_CHANGE_EVENT, 3830 (void *)eSAP_STATUS_SUCCESS); 3831 sap_ctx->is_chan_change_inprogress = false; 3832 } else { 3833 sap_debug("vdev %d notify hostapd about chan freq selection: %d", 3834 sap_ctx->vdev_id, sap_ctx->chan_freq); 3835 qdf_status = 3836 sap_signal_hdd_event(sap_ctx, roam_info, 3837 eSAP_CHANNEL_CHANGE_EVENT, 3838 (void *)eSAP_STATUS_SUCCESS); 3839 /* Action code for transition */ 3840 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3841 eSAP_START_BSS_EVENT, 3842 (void *) eSAP_STATUS_SUCCESS); 3843 } 3844 sap_chan_freq = sap_ctx->chan_freq; 3845 band = wlan_reg_freq_to_band(sap_ctx->chan_freq); 3846 if (sap_ctx->ch_params.center_freq_seg1) 3847 ch_cfreq1 = wlan_reg_chan_band_to_freq( 3848 mac_ctx->pdev, 3849 sap_ctx->ch_params.center_freq_seg1, 3850 BIT(band)); 3851 3852 /* 3853 * The upper layers have been informed that AP is up and 3854 * running, however, the AP is still not beaconing, until 3855 * CAC is done if the operating channel is DFS 3856 */ 3857 if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { 3858 struct ch_params ch_params = {0}; 3859 3860 wlan_reg_set_create_punc_bitmap(&ch_params, true); 3861 ch_params.ch_width = CH_WIDTH_160MHZ; 3862 is_dfs = 3863 wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev, 3864 sap_chan_freq, 3865 &ch_params, 3866 REG_CURRENT_PWR_MODE) == 3867 CHANNEL_STATE_DFS; 3868 } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { 3869 if (wlan_reg_get_channel_state_for_pwrmode( 3870 mac_ctx->pdev, 3871 sap_chan_freq, 3872 REG_CURRENT_PWR_MODE) == 3873 CHANNEL_STATE_DFS || 3874 wlan_reg_get_channel_state_for_pwrmode( 3875 mac_ctx->pdev, 3876 ch_cfreq1, 3877 REG_CURRENT_PWR_MODE) == 3878 CHANNEL_STATE_DFS) 3879 is_dfs = true; 3880 } else { 3881 /* Indoor channels are also marked DFS, therefore 3882 * check if the channel has REGULATORY_CHAN_RADAR 3883 * channel flag to identify if the channel is DFS 3884 */ 3885 if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 3886 sap_chan_freq)) 3887 is_dfs = true; 3888 } 3889 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) 3890 is_dfs = false; 3891 3892 sap_debug("vdev %d freq %d, is_dfs %d", sap_ctx->vdev_id, 3893 sap_ctx->chan_freq, is_dfs); 3894 if (is_dfs) { 3895 sap_dfs_info = &mac_ctx->sap.SapDfsInfo; 3896 if (sap_plus_sap_cac_skip(mac_ctx, sap_ctx, 3897 sap_chan_freq)) 3898 cac_state = eSAP_DFS_SKIP_CAC; 3899 if ((false == sap_dfs_info->ignore_cac) && 3900 (cac_state == eSAP_DFS_DO_NOT_SKIP_CAC) && 3901 !wlan_pre_cac_complete_get(sap_ctx->vdev) && 3902 policy_mgr_get_dfs_master_dynamic_enabled( 3903 mac_ctx->psoc, 3904 sap_ctx->sessionId)) { 3905 sap_ctx->fsm_state = SAP_STARTING; 3906 sap_debug("sap_fsm: vdev %d: SAP_STARTED => SAP_STARTING to start cac timer", 3907 sap_ctx->vdev_id); 3908 qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx, 3909 mac_handle); 3910 } else { 3911 sap_debug("vdev %d skip cac timer", 3912 sap_ctx->vdev_id); 3913 sap_ctx->sap_radar_found_status = false; 3914 /* 3915 * If hostapd starts AP on dfs channel, 3916 * hostapd will wait for CAC START/CAC END 3917 * event and finish AP start process. 3918 * If we skip CAC timer, we will need to 3919 * indicate the CAC event even though driver 3920 * doesn't perform CAC. 3921 */ 3922 sap_propagate_cac_events(sap_ctx); 3923 3924 wlansap_start_beacon_req(sap_ctx); 3925 } 3926 } 3927 /* 3928 * During CSA, it might be possible that ch avoidance event to 3929 * avoid the sap frequency is received. So, check after CSA, 3930 * whether sap frequency is safe if not restart sap to a safe 3931 * channel. 3932 */ 3933 sap_fsm_validate_and_change_channel(mac_ctx, sap_ctx); 3934 } else if (msg == eSAP_MAC_START_FAILS || 3935 msg == eSAP_HDD_STOP_INFRA_BSS) { 3936 qdf_status = sap_fsm_handle_start_failure(sap_ctx, msg, 3937 mac_handle); 3938 } else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) { 3939 /* The operating channel has changed, update hostapd */ 3940 sap_ctx->chan_freq = mac_ctx->sap.SapDfsInfo.target_chan_freq; 3941 3942 sap_ctx->fsm_state = SAP_STARTED; 3943 sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED", 3944 sap_ctx->vdev_id); 3945 3946 /* Indicate change in the state to upper layers */ 3947 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 3948 eSAP_START_BSS_EVENT, 3949 (void *)eSAP_STATUS_SUCCESS); 3950 } else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) { 3951 qdf_status = sap_fsm_handle_radar_during_cac(sap_ctx, mac_ctx); 3952 } else if (msg == eSAP_DFS_CHANNEL_CAC_END) { 3953 if (sap_ctx->vdev && 3954 wlan_util_vdev_mgr_get_cac_timeout_for_vdev(sap_ctx->vdev)) { 3955 qdf_status = sap_cac_end_notify(mac_handle, roam_info); 3956 } else { 3957 sap_debug("vdev %d cac duration is zero", 3958 sap_ctx->vdev_id); 3959 qdf_status = QDF_STATUS_SUCCESS; 3960 } 3961 } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { 3962 if (sap_ctx->is_chan_change_inprogress) { 3963 sap_signal_hdd_event(sap_ctx, 3964 NULL, 3965 eSAP_CHANNEL_CHANGE_EVENT, 3966 (void *)eSAP_STATUS_SUCCESS); 3967 sap_ctx->is_chan_change_inprogress = false; 3968 } 3969 qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx, mac_handle); 3970 } else { 3971 sap_err("sap_fsm: vdev %d: SAP_STARTING, invalid event %d", 3972 sap_ctx->vdev_id, msg); 3973 } 3974 3975 return qdf_status; 3976 } 3977 3978 /** 3979 * sap_fsm_state_started() - utility function called from sap fsm 3980 * @sap_ctx: SAP context 3981 * @sap_event: SAP event buffer 3982 * @mac_ctx: global MAC context 3983 * 3984 * This function is called for state transition from "SAP_STARTED" 3985 * 3986 * Return: QDF_STATUS 3987 */ 3988 static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, 3989 struct sap_sm_event *sap_event, 3990 struct mac_context *mac_ctx) 3991 { 3992 uint32_t msg = sap_event->event; 3993 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3994 3995 if (msg == eSAP_HDD_STOP_INFRA_BSS) { 3996 /* 3997 * Transition from SAP_STARTED to SAP_STOPPING 3998 * (both without substates) 3999 */ 4000 sap_ctx->fsm_state = SAP_STOPPING; 4001 sap_debug("sap_fsm: vdev %d: SAP_STARTED => SAP_STOPPING", 4002 sap_ctx->vdev_id); 4003 qdf_status = sap_goto_stopping(sap_ctx); 4004 } else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) { 4005 uint8_t intf; 4006 if (!mac_ctx->sap.SapDfsInfo.target_chan_freq) { 4007 sap_err("Invalid target channel freq %d", 4008 mac_ctx->sap.SapDfsInfo.target_chan_freq); 4009 return qdf_status; 4010 } 4011 4012 /* 4013 * Radar is seen on the current operating channel 4014 * send CSA IE for all associated stations 4015 * Request for CSA IE transmission 4016 */ 4017 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 4018 struct sap_context *temp_sap_ctx; 4019 4020 if (((QDF_SAP_MODE == 4021 mac_ctx->sap.sapCtxList[intf].sapPersona) || 4022 (QDF_P2P_GO_MODE == 4023 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 4024 mac_ctx->sap.sapCtxList[intf].sap_context) { 4025 temp_sap_ctx = 4026 mac_ctx->sap.sapCtxList[intf].sap_context; 4027 /* 4028 * Radar won't come on non-dfs channel, so 4029 * no need to move them 4030 */ 4031 if (!sap_operating_on_dfs( 4032 mac_ctx, temp_sap_ctx)) { 4033 sap_debug("vdev %d freq %d (state %d) is not DFS or disabled so continue", 4034 temp_sap_ctx->sessionId, 4035 temp_sap_ctx->chan_freq, 4036 wlan_reg_get_channel_state_for_pwrmode( 4037 mac_ctx->pdev, 4038 temp_sap_ctx->chan_freq, 4039 REG_CURRENT_PWR_MODE)); 4040 continue; 4041 } 4042 sap_debug("vdev %d switch freq %d -> %d", 4043 temp_sap_ctx->sessionId, 4044 temp_sap_ctx->chan_freq, 4045 mac_ctx->sap.SapDfsInfo.target_chan_freq); 4046 qdf_status = 4047 sap_fsm_send_csa_restart_req(mac_ctx, 4048 temp_sap_ctx); 4049 } 4050 } 4051 } else { 4052 sap_err("sap_fsm: vdev %d: SAP_STARTED, invalid event %d", 4053 sap_ctx->vdev_id, msg); 4054 } 4055 4056 return qdf_status; 4057 } 4058 4059 /** 4060 * sap_fsm_state_stopping() - utility function called from sap fsm 4061 * @sap_ctx: SAP context 4062 * @sap_event: SAP event buffer 4063 * @mac_ctx: global MAC context 4064 * @mac_handle: Opaque handle to the global MAC context 4065 * 4066 * This function is called for state transition from "SAP_STOPPING" 4067 * 4068 * Return: QDF_STATUS 4069 */ 4070 static QDF_STATUS 4071 sap_fsm_state_stopping(struct sap_context *sap_ctx, 4072 struct sap_sm_event *sap_event, 4073 struct mac_context *mac_ctx, 4074 mac_handle_t mac_handle) 4075 { 4076 uint32_t msg = sap_event->event; 4077 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 4078 4079 if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) { 4080 /* 4081 * Transition from SAP_STOPPING to SAP_INIT 4082 * (both without substates) 4083 */ 4084 sap_ctx->fsm_state = SAP_INIT; 4085 sap_debug("sap_fsm: vdev %d: SAP_STOPPING => SAP_INIT", 4086 sap_ctx->vdev_id); 4087 4088 /* Close the SME session */ 4089 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 4090 eSAP_STOP_BSS_EVENT, 4091 (void *)eSAP_STATUS_SUCCESS); 4092 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 4093 /* 4094 * In case the SAP is already in stopping case and 4095 * we get a STOP request, return success. 4096 */ 4097 sap_debug("vdev %d SAP already in Stopping state", 4098 sap_ctx->vdev_id); 4099 qdf_status = QDF_STATUS_SUCCESS; 4100 } else { 4101 sap_err("sap_fsm: vdev %d: SAP_STOPPING, invalid event %d", 4102 sap_ctx->vdev_id, msg); 4103 } 4104 4105 return qdf_status; 4106 } 4107 4108 /** 4109 * sap_fsm() - SAP statem machine entry function 4110 * @sap_ctx: SAP context 4111 * @sap_event: SAP event 4112 * 4113 * SAP state machine entry function 4114 * 4115 * Return: QDF_STATUS 4116 */ 4117 QDF_STATUS sap_fsm(struct sap_context *sap_ctx, struct sap_sm_event *sap_event) 4118 { 4119 /* 4120 * Retrieve the phy link state machine structure 4121 * from the sap_ctx value 4122 * state var that keeps track of state machine 4123 */ 4124 enum sap_fsm_state state_var = sap_ctx->fsm_state; 4125 uint32_t msg = sap_event->event; /* State machine input event message */ 4126 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 4127 struct mac_context *mac_ctx; 4128 mac_handle_t mac_handle; 4129 4130 mac_ctx = sap_get_mac_context(); 4131 if (!mac_ctx) { 4132 sap_err("Invalid MAC context"); 4133 return QDF_STATUS_E_FAILURE; 4134 } 4135 mac_handle = MAC_HANDLE(mac_ctx); 4136 4137 sap_debug("vdev %d: state %d event %d", sap_ctx->vdev_id, state_var, 4138 msg); 4139 4140 switch (state_var) { 4141 case SAP_INIT: 4142 qdf_status = sap_fsm_state_init(sap_ctx, sap_event, 4143 mac_ctx, mac_handle); 4144 break; 4145 4146 case SAP_STARTING: 4147 qdf_status = sap_fsm_state_starting(sap_ctx, sap_event, 4148 mac_ctx, mac_handle); 4149 break; 4150 4151 case SAP_STARTED: 4152 qdf_status = sap_fsm_state_started(sap_ctx, sap_event, 4153 mac_ctx); 4154 break; 4155 4156 case SAP_STOPPING: 4157 qdf_status = sap_fsm_state_stopping(sap_ctx, sap_event, 4158 mac_ctx, mac_handle); 4159 break; 4160 } 4161 return qdf_status; 4162 } 4163 4164 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint16_t size) 4165 { 4166 uint16_t outer, inner; 4167 struct qdf_mac_addr temp; 4168 int32_t nRes = -1; 4169 4170 if ((!macList) || (size > MAX_ACL_MAC_ADDRESS)) { 4171 sap_err("either buffer is NULL or size = %d is more", size); 4172 return; 4173 } 4174 4175 for (outer = 0; outer < size; outer++) { 4176 for (inner = 0; inner < size - 1; inner++) { 4177 nRes = 4178 qdf_mem_cmp((macList + inner)->bytes, 4179 (macList + inner + 1)->bytes, 4180 QDF_MAC_ADDR_SIZE); 4181 if (nRes > 0) { 4182 qdf_mem_copy(temp.bytes, 4183 (macList + inner + 1)->bytes, 4184 QDF_MAC_ADDR_SIZE); 4185 qdf_mem_copy((macList + inner + 1)->bytes, 4186 (macList + inner)->bytes, 4187 QDF_MAC_ADDR_SIZE); 4188 qdf_mem_copy((macList + inner)->bytes, 4189 temp.bytes, QDF_MAC_ADDR_SIZE); 4190 } 4191 } 4192 } 4193 } 4194 4195 bool 4196 sap_search_mac_list(struct qdf_mac_addr *macList, 4197 uint16_t num_mac, uint8_t *peerMac, 4198 uint16_t *index) 4199 { 4200 int32_t nRes = -1, nStart = 0, nEnd, nMiddle; 4201 4202 nEnd = num_mac - 1; 4203 4204 if ((!macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) { 4205 sap_err("either buffer is NULL or size = %d is more", num_mac); 4206 return false; 4207 } 4208 4209 while (nStart <= nEnd) { 4210 nMiddle = (nStart + nEnd) / 2; 4211 nRes = 4212 qdf_mem_cmp(&macList[nMiddle], peerMac, 4213 QDF_MAC_ADDR_SIZE); 4214 4215 if (0 == nRes) { 4216 sap_debug("search SUCC"); 4217 /* "index equals NULL" means the caller does not need the */ 4218 /* index value of the peerMac being searched */ 4219 if (index) { 4220 *index = (uint16_t)nMiddle; 4221 sap_debug("index %d", *index); 4222 } 4223 return true; 4224 } 4225 if (nRes < 0) 4226 nStart = nMiddle + 1; 4227 else 4228 nEnd = nMiddle - 1; 4229 } 4230 4231 sap_debug("search not succ"); 4232 return false; 4233 } 4234 4235 void sap_add_mac_to_acl(struct qdf_mac_addr *macList, 4236 uint16_t *size, uint8_t *peerMac) 4237 { 4238 int32_t nRes = -1; 4239 int i; 4240 4241 sap_debug("add acl entered"); 4242 4243 if (!macList || *size > MAX_ACL_MAC_ADDRESS) { 4244 sap_debug("either buffer is NULL or size = %d is incorrect", 4245 *size); 4246 return; 4247 } 4248 4249 for (i = ((*size) - 1); i >= 0; i--) { 4250 nRes = 4251 qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE); 4252 if (nRes > 0) { 4253 /* Move alphabetically greater mac addresses one index down to allow for insertion 4254 of new mac in sorted order */ 4255 qdf_mem_copy((macList + i + 1)->bytes, 4256 (macList + i)->bytes, QDF_MAC_ADDR_SIZE); 4257 } else { 4258 break; 4259 } 4260 } 4261 /* This should also take care of if the element is the first to be added in the list */ 4262 qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE); 4263 /* increment the list size */ 4264 (*size)++; 4265 } 4266 4267 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList, 4268 uint16_t *size, uint16_t index) 4269 { 4270 int i; 4271 4272 sap_debug("remove acl entered"); 4273 /* 4274 * Return if the list passed is empty. Ideally this should never happen 4275 * since this funcn is always called after sap_search_mac_list to get 4276 * the index of the mac addr to be removed and this will only get 4277 * called if the search is successful. Still no harm in having the check 4278 */ 4279 if ((!macList) || (*size == 0) || 4280 (*size > MAX_ACL_MAC_ADDRESS)) { 4281 sap_err("either buffer is NULL or size %d is incorrect", 4282 *size); 4283 return; 4284 } 4285 for (i = index; i < ((*size) - 1); i++) { 4286 /* Move mac addresses starting from "index" passed one index up to delete the void 4287 created by deletion of a mac address in ACL */ 4288 qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes, 4289 QDF_MAC_ADDR_SIZE); 4290 } 4291 /* The last space should be made empty since all mac addresses moved one step up */ 4292 qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE); 4293 /* reduce the list size by 1 */ 4294 (*size)--; 4295 } 4296 4297 void sap_print_acl(struct qdf_mac_addr *macList, uint16_t size) 4298 { 4299 uint16_t i; 4300 uint8_t *macArray; 4301 4302 sap_debug("print acl entered"); 4303 4304 if ((!macList) || (size == 0) || (size > MAX_ACL_MAC_ADDRESS)) { 4305 sap_err("Either buffer is NULL or size %d is incorrect", size); 4306 return; 4307 } 4308 4309 for (i = 0; i < size; i++) { 4310 macArray = (macList + i)->bytes; 4311 sap_debug("** ACL entry %i - " QDF_MAC_ADDR_FMT, i, 4312 QDF_MAC_ADDR_REF(macArray)); 4313 } 4314 return; 4315 } 4316 4317 QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sap_ctx, 4318 uint8_t *peerMac) 4319 { 4320 if (eSAP_ALLOW_ALL == sap_ctx->eSapMacAddrAclMode) 4321 return QDF_STATUS_SUCCESS; 4322 4323 if (sap_search_mac_list 4324 (sap_ctx->acceptMacList, sap_ctx->nAcceptMac, peerMac, NULL)) 4325 return QDF_STATUS_SUCCESS; 4326 4327 if (sap_search_mac_list 4328 (sap_ctx->denyMacList, sap_ctx->nDenyMac, peerMac, NULL)) { 4329 sap_err("Peer " QDF_MAC_ADDR_FMT " in deny list", 4330 QDF_MAC_ADDR_REF(peerMac)); 4331 return QDF_STATUS_E_FAILURE; 4332 } 4333 /* A new station CAN associate, unless in deny list. Less stringent mode */ 4334 if (eSAP_ACCEPT_UNLESS_DENIED == sap_ctx->eSapMacAddrAclMode) 4335 return QDF_STATUS_SUCCESS; 4336 4337 /* A new station CANNOT associate, unless in accept list. More stringent mode */ 4338 if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) { 4339 sap_debug("Peer " QDF_MAC_ADDR_FMT 4340 " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", 4341 QDF_MAC_ADDR_REF(peerMac)); 4342 return QDF_STATUS_E_FAILURE; 4343 } 4344 4345 /* The new STA is neither in accept list nor in deny list. In this case, deny the association 4346 * but send a wifi event notification indicating the mac address being denied 4347 */ 4348 if (eSAP_SUPPORT_ACCEPT_AND_DENY == sap_ctx->eSapMacAddrAclMode) { 4349 sap_signal_hdd_event(sap_ctx, NULL, eSAP_UNKNOWN_STA_JOIN, 4350 (void *) peerMac); 4351 sap_debug("Peer " QDF_MAC_ADDR_FMT 4352 " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", 4353 QDF_MAC_ADDR_REF(peerMac)); 4354 return QDF_STATUS_E_FAILURE; 4355 } 4356 return QDF_STATUS_SUCCESS; 4357 } 4358 4359 void sap_dump_acs_channel(struct sap_acs_cfg *acs_cfg) 4360 { 4361 uint32_t buf_len = 0, len = 0, i; 4362 uint8_t *chan_buff = NULL; 4363 4364 /* 4365 * Buffer of (num channel * 5) + 1 to consider the 4 char freq 4366 * and 1 space after it for each channel and 1 to end the string 4367 * with NULL. 4368 */ 4369 buf_len = (acs_cfg->ch_list_count * 5) + 1; 4370 chan_buff = qdf_mem_malloc(buf_len); 4371 if (!chan_buff) 4372 return; 4373 4374 for (i = 0; i < acs_cfg->ch_list_count; i++) 4375 len += qdf_scnprintf(chan_buff + len, buf_len - len, 4376 " %d", acs_cfg->freq_list[i]); 4377 4378 sap_nofl_debug("ACS freq list[%d]:%s", 4379 acs_cfg->ch_list_count, chan_buff); 4380 qdf_mem_free(chan_buff); 4381 } 4382 4383 #ifdef SOFTAP_CHANNEL_RANGE 4384 /** 4385 * sap_get_freq_list() - get the list of channel frequency 4386 * @sap_ctx: sap context 4387 * @freq_list: pointer to channel list array 4388 * @num_ch: pointer to number of channels. 4389 * 4390 * This function populates the list of channel frequency for scanning. 4391 * 4392 * Return: QDF_STATUS 4393 */ 4394 static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, 4395 uint32_t **freq_list, 4396 uint8_t *num_ch) 4397 { 4398 uint8_t loop_count; 4399 uint32_t *list; 4400 uint8_t ch_count; 4401 uint8_t dfs_master_enable; 4402 uint32_t start_ch_freq, band_start_ch; 4403 uint32_t end_ch_freq, band_end_ch; 4404 uint32_t en_lte_coex; 4405 struct mac_context *mac_ctx; 4406 uint16_t ch_width; 4407 uint8_t normalize_factor = 100; 4408 uint32_t chan_freq; 4409 struct acs_weight *weight_list; 4410 struct acs_weight_range *range_list; 4411 bool freq_present_in_list = false; 4412 uint8_t i; 4413 bool srd_chan_enabled; 4414 enum QDF_OPMODE vdev_opmode; 4415 4416 mac_ctx = sap_get_mac_context(); 4417 if (!mac_ctx) { 4418 sap_err("Invalid MAC context"); 4419 *num_ch = 0; 4420 *freq_list = NULL; 4421 return QDF_STATUS_E_FAULT; 4422 } 4423 4424 weight_list = mac_ctx->mlme_cfg->acs.normalize_weight_chan; 4425 range_list = mac_ctx->mlme_cfg->acs.normalize_weight_range; 4426 4427 dfs_master_enable = mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable; 4428 if (sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) 4429 dfs_master_enable = false; 4430 4431 start_ch_freq = sap_ctx->acs_cfg->start_ch_freq; 4432 end_ch_freq = sap_ctx->acs_cfg->end_ch_freq; 4433 ch_width = sap_ctx->acs_cfg->ch_width; 4434 4435 sap_debug("startChannel %d, EndChannel %d, ch_width %d, HW:%d", 4436 start_ch_freq, end_ch_freq, ch_width, 4437 sap_ctx->acs_cfg->hw_mode); 4438 4439 wlansap_extend_to_acs_range(MAC_HANDLE(mac_ctx), 4440 &start_ch_freq, &end_ch_freq, 4441 &band_start_ch, &band_end_ch); 4442 4443 sap_debug("expanded startChannel %d,EndChannel %d band_start_ch %d, band_end_ch %d", 4444 start_ch_freq, end_ch_freq, band_start_ch, band_end_ch); 4445 4446 en_lte_coex = mac_ctx->mlme_cfg->sap_cfg.enable_lte_coex; 4447 4448 /* Check if LTE coex is enabled and 2.4GHz is selected */ 4449 if (en_lte_coex && (band_start_ch == CHAN_ENUM_2412) && 4450 (band_end_ch == CHAN_ENUM_2484)) { 4451 /* Set 2.4GHz upper limit to channel 9 for LTE COEX */ 4452 band_end_ch = CHAN_ENUM_2452; 4453 } 4454 4455 /* Allocate the max number of channel supported */ 4456 list = qdf_mem_malloc((NUM_CHANNELS) * sizeof(uint32_t)); 4457 if (!list) { 4458 *num_ch = 0; 4459 *freq_list = NULL; 4460 return QDF_STATUS_E_NOMEM; 4461 } 4462 4463 /* Search for the Active channels in the given range */ 4464 ch_count = 0; 4465 for (loop_count = band_start_ch; loop_count <= band_end_ch; 4466 loop_count++) { 4467 chan_freq = WLAN_REG_CH_TO_FREQ(loop_count); 4468 4469 /* go to next channel if rf_channel is out of range */ 4470 if (start_ch_freq > WLAN_REG_CH_TO_FREQ(loop_count) || 4471 end_ch_freq < WLAN_REG_CH_TO_FREQ(loop_count)) 4472 continue; 4473 /* 4474 * go to next channel if none of these condition pass 4475 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE 4476 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE 4477 */ 4478 if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) && 4479 wlan_reg_get_channel_state_from_secondary_list_for_freq( 4480 mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count))) 4481 || 4482 ((false == mac_ctx->scan.fEnableDFSChnlScan) && 4483 (CHANNEL_STATE_ENABLE == 4484 wlan_reg_get_channel_state_from_secondary_list_for_freq( 4485 mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count))) 4486 ))) 4487 continue; 4488 4489 /* check if the channel is in NOL denylist */ 4490 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(WLAN_REG_CH_TO_FREQ( 4491 loop_count))) { 4492 if (sap_dfs_is_channel_in_nol_list( 4493 sap_ctx, 4494 chan_freq, 4495 PHY_SINGLE_CHANNEL_CENTERED)) { 4496 sap_debug("Ch freq %d in NOL list", chan_freq); 4497 continue; 4498 } 4499 } 4500 /* Skip DSRC channels */ 4501 if (wlan_reg_is_dsrc_freq(WLAN_REG_CH_TO_FREQ(loop_count))) 4502 continue; 4503 4504 /* 4505 * Skip the channels which are not in ACS config from user 4506 * space 4507 */ 4508 if (!wlansap_is_channel_present_in_acs_list( 4509 chan_freq, 4510 sap_ctx->acs_cfg->freq_list, 4511 sap_ctx->acs_cfg->ch_list_count)) 4512 continue; 4513 /* Dont scan DFS channels in case of MCC disallowed 4514 * As it can result in SAP starting on DFS channel 4515 * resulting MCC on DFS channel 4516 */ 4517 if (wlan_reg_is_dfs_in_secondary_list_for_freq( 4518 mac_ctx->pdev, 4519 WLAN_REG_CH_TO_FREQ(loop_count))) { 4520 if (!dfs_master_enable) 4521 continue; 4522 if (wlansap_dcs_is_wlan_interference_mitigation_enabled( 4523 sap_ctx)) 4524 sap_debug("dfs chan_freq %d added when dcs enabled", 4525 WLAN_REG_CH_TO_FREQ(loop_count)); 4526 else if (policy_mgr_disallow_mcc( 4527 mac_ctx->psoc, 4528 WLAN_REG_CH_TO_FREQ(loop_count))) 4529 continue; 4530 normalize_factor = 4531 MLME_GET_DFS_CHAN_WEIGHT( 4532 mac_ctx->mlme_cfg->acs.np_chan_weightage); 4533 freq_present_in_list = true; 4534 } 4535 4536 vdev_opmode = wlan_vdev_mlme_get_opmode(sap_ctx->vdev); 4537 wlan_mlme_get_srd_master_mode_for_vdev(mac_ctx->psoc, 4538 vdev_opmode, 4539 &srd_chan_enabled); 4540 4541 if (!srd_chan_enabled && 4542 wlan_reg_is_etsi_srd_chan_for_freq( 4543 mac_ctx->pdev, 4544 WLAN_REG_CH_TO_FREQ(loop_count))) { 4545 sap_debug("vdev opmode %d not allowed on SRD freq %d", 4546 vdev_opmode, WLAN_REG_CH_TO_FREQ(loop_count)); 4547 continue; 4548 } 4549 4550 /* Check if the freq is present in range list */ 4551 for (i = 0; i < mac_ctx->mlme_cfg->acs.num_weight_range; i++) { 4552 if (chan_freq >= range_list[i].start_freq && 4553 chan_freq <= range_list[i].end_freq) { 4554 normalize_factor = 4555 range_list[i].normalize_weight; 4556 sap_debug("Range list, freq %d normalize weight factor %d", 4557 chan_freq, normalize_factor); 4558 freq_present_in_list = true; 4559 } 4560 } 4561 4562 for (i = 0; 4563 i < mac_ctx->mlme_cfg->acs.normalize_weight_num_chan; 4564 i++) { 4565 if (chan_freq == weight_list[i].chan_freq) { 4566 normalize_factor = 4567 weight_list[i].normalize_weight; 4568 sap_debug("freq %d normalize weight factor %d", 4569 chan_freq, normalize_factor); 4570 freq_present_in_list = true; 4571 } 4572 } 4573 4574 /* This would mean that the user does not want this freq */ 4575 if (freq_present_in_list && !normalize_factor) { 4576 sap_debug("chan_freq %d ecluded normalize weight 0", 4577 chan_freq); 4578 freq_present_in_list = false; 4579 continue; 4580 } 4581 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4582 if (sap_ctx->acs_cfg->skip_scan_status == 4583 eSAP_DO_PAR_ACS_SCAN) { 4584 uint32_t ch_freq; 4585 4586 ch_freq = WLAN_REG_CH_TO_FREQ(loop_count); 4587 if ((ch_freq >= 4588 sap_ctx->acs_cfg->skip_scan_range1_stch && 4589 ch_freq <= 4590 sap_ctx->acs_cfg->skip_scan_range1_endch) || 4591 (ch_freq >= 4592 sap_ctx->acs_cfg->skip_scan_range2_stch && 4593 ch_freq <= 4594 sap_ctx->acs_cfg->skip_scan_range2_endch)) { 4595 list[ch_count] = 4596 WLAN_REG_CH_TO_FREQ(loop_count); 4597 ch_count++; 4598 sap_debug("%d %d added to ACS ch range", 4599 ch_count, ch_freq); 4600 } else { 4601 sap_debug("%d %d skipped from ACS ch range", 4602 ch_count, ch_freq); 4603 } 4604 } else { 4605 list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count); 4606 ch_count++; 4607 sap_debug("%d added to ACS ch range", ch_count); 4608 } 4609 #else 4610 list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count); 4611 ch_count++; 4612 #endif 4613 } 4614 if (!ch_count) { 4615 sap_info("No active channels present for the current region"); 4616 /* 4617 * LTE COEX: channel range outside the restricted 2.4GHz 4618 * band limits 4619 */ 4620 if (en_lte_coex && 4621 start_ch_freq > WLAN_REG_CH_TO_FREQ(band_end_ch)) 4622 sap_info("SAP can't be started as due to LTE COEX"); 4623 } 4624 4625 /* return the channel list and number of channels to scan */ 4626 *num_ch = ch_count; 4627 if (ch_count != 0) { 4628 *freq_list = list; 4629 } else { 4630 *freq_list = NULL; 4631 qdf_mem_free(list); 4632 return QDF_STATUS_SUCCESS; 4633 } 4634 4635 for (loop_count = 0; loop_count < ch_count; loop_count++) { 4636 sap_ctx->acs_cfg->freq_list[loop_count] = list[loop_count]; 4637 } 4638 sap_ctx->acs_cfg->ch_list_count = ch_count; 4639 sap_dump_acs_channel(sap_ctx->acs_cfg); 4640 4641 return QDF_STATUS_SUCCESS; 4642 } 4643 #endif 4644 4645 #ifdef DFS_COMPONENT_ENABLE 4646 qdf_freq_t sap_indicate_radar(struct sap_context *sap_ctx) 4647 { 4648 qdf_freq_t chan_freq = 0; 4649 struct mac_context *mac; 4650 4651 if (!sap_ctx) { 4652 sap_err("null sap_ctx"); 4653 return 0; 4654 } 4655 4656 mac = sap_get_mac_context(); 4657 if (!mac) { 4658 sap_err("Invalid MAC context"); 4659 return 0; 4660 } 4661 4662 /* 4663 * SAP needs to generate Channel Switch IE 4664 * if the radar is found in the STARTED state 4665 */ 4666 if (sap_ctx->fsm_state == SAP_STARTED) 4667 mac->sap.SapDfsInfo.csaIERequired = true; 4668 4669 if (mac->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) { 4670 mac->sap.SapDfsInfo.new_chanWidth = 4671 sap_ctx->ch_params.ch_width; 4672 sap_debug("DFS channel switch disabled, CSA to same ch %d wd %d", 4673 sap_ctx->chan_freq, sap_ctx->ch_params.ch_width); 4674 return sap_ctx->chan_freq; 4675 } 4676 4677 /* set the Radar Found flag in SapDfsInfo */ 4678 sap_ctx->sap_radar_found_status = true; 4679 4680 chan_freq = wlan_pre_cac_get_freq_before_pre_cac(sap_ctx->vdev); 4681 if (chan_freq) { 4682 sap_info("sapdfs: set chan freq before pre cac %d as target chan", 4683 chan_freq); 4684 return chan_freq; 4685 } 4686 4687 if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS == 4688 sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ, 4689 (void *) eSAP_STATUS_SUCCESS))) 4690 return 0; 4691 4692 if (!sap_is_chan_change_needed(sap_ctx)) 4693 return sap_ctx->chan_freq; 4694 4695 chan_freq = sap_random_channel_sel(sap_ctx); 4696 if (!chan_freq) 4697 sap_signal_hdd_event(sap_ctx, NULL, 4698 eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS); 4699 4700 sap_warn("sapdfs: New selected target freq is [%d]", chan_freq); 4701 4702 return chan_freq; 4703 } 4704 #endif 4705 4706 /* 4707 * CAC timer callback function. 4708 * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm(). 4709 */ 4710 void sap_dfs_cac_timer_callback(void *data) 4711 { 4712 struct sap_context *sap_ctx; 4713 struct sap_sm_event sap_event; 4714 mac_handle_t mac_handle = data; 4715 struct mac_context *mac; 4716 4717 if (!mac_handle) { 4718 sap_err("Invalid mac_handle"); 4719 return; 4720 } 4721 mac = MAC_CONTEXT(mac_handle); 4722 sap_ctx = sap_find_cac_wait_session(mac_handle); 4723 if (!sap_ctx) { 4724 sap_err("no SAP contexts in wait state"); 4725 return; 4726 } 4727 4728 if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) { 4729 sap_err("vdev mismatch sap_ctx->vdev_id %d mac->sap.SapDfsInfo.vdev_id %d", 4730 sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id); 4731 return; 4732 } 4733 4734 /* 4735 * SAP may not be in CAC wait state, when the timer runs out. 4736 * if following flag is set, then timer is in initialized state, 4737 * destroy timer here. 4738 */ 4739 if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) { 4740 if (!sap_ctx->dfs_cac_offload) 4741 qdf_mc_timer_destroy( 4742 &mac->sap.SapDfsInfo.sap_dfs_cac_timer); 4743 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 4744 mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 4745 } 4746 4747 /* 4748 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm 4749 */ 4750 sap_debug("sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_chan_freq = %d on sapctx[%pK]", 4751 sap_ctx->chan_freq, sap_ctx); 4752 4753 sap_event.event = eSAP_DFS_CHANNEL_CAC_END; 4754 sap_event.params = 0; 4755 sap_event.u1 = 0; 4756 sap_event.u2 = 0; 4757 4758 sap_fsm(sap_ctx, &sap_event); 4759 } 4760 4761 /* 4762 * Function to stop the DFS CAC Timer 4763 */ 4764 static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx) 4765 { 4766 struct mac_context *mac; 4767 4768 if (!sap_ctx) 4769 return 0; 4770 4771 mac = sap_get_mac_context(); 4772 if (!mac) { 4773 sap_err("Invalid MAC context"); 4774 return 0; 4775 } 4776 4777 if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) { 4778 sap_err("Invalid vdev Id sap_ctx_vdev_id %d mac_ctx vdev id %d", 4779 sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id); 4780 return 0; 4781 } 4782 4783 if (sap_ctx->dfs_cac_offload) { 4784 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 4785 mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 4786 return 0; 4787 } 4788 4789 if (QDF_TIMER_STATE_RUNNING != 4790 qdf_mc_timer_get_current_state(&mac->sap.SapDfsInfo. 4791 sap_dfs_cac_timer)) { 4792 return 0; 4793 } 4794 4795 qdf_mc_timer_stop(&mac->sap.SapDfsInfo.sap_dfs_cac_timer); 4796 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 4797 mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 4798 qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer); 4799 4800 return 0; 4801 } 4802 4803 /* 4804 * Function to start the DFS CAC Timer 4805 * when SAP is started on a DFS channel 4806 */ 4807 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx) 4808 { 4809 QDF_STATUS status; 4810 uint32_t cac_dur; 4811 struct mac_context *mac; 4812 enum dfs_reg dfs_region; 4813 4814 if (!sap_ctx) { 4815 sap_err("null sap_ctx"); 4816 return 0; 4817 } 4818 4819 mac = sap_get_mac_context(); 4820 if (!mac) { 4821 sap_err("Invalid MAC context"); 4822 return 0; 4823 } 4824 /* start time only when is_dfs_cac_timer_running is not running */ 4825 if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) { 4826 sap_err("Invalid state is_dfs_cac_timer_running"); 4827 return 0; 4828 } 4829 4830 if (sap_ctx->dfs_cac_offload) { 4831 sap_debug("cac timer offloaded to firmware"); 4832 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 4833 mac->sap.SapDfsInfo.vdev_id = sap_ctx->vdev_id; 4834 return 1; 4835 } 4836 4837 sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region, 4838 sap_ctx->chan_freq, &sap_ctx->ch_params); 4839 if (0 == cac_dur) 4840 return 0; 4841 4842 #ifdef QCA_WIFI_EMULATION 4843 cac_dur = cac_dur / 100; 4844 #endif 4845 sap_debug("sapdfs: SAP_DFS_CHANNEL_CAC_START on CH freq %d, CAC_DUR-%d sec", 4846 sap_ctx->chan_freq, cac_dur / 1000); 4847 4848 qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, 4849 QDF_TIMER_TYPE_SW, 4850 sap_dfs_cac_timer_callback, MAC_HANDLE(mac)); 4851 4852 /* Start the CAC timer */ 4853 status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, 4854 cac_dur); 4855 if (QDF_IS_STATUS_ERROR(status)) { 4856 sap_err("failed to start cac timer"); 4857 goto destroy_timer; 4858 } 4859 4860 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 4861 mac->sap.SapDfsInfo.vdev_id = sap_ctx->vdev_id; 4862 4863 return 0; 4864 4865 destroy_timer: 4866 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 4867 mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID; 4868 qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer); 4869 4870 return 1; 4871 } 4872 4873 /* 4874 * This function initializes the NOL list 4875 * parameters required to track the radar 4876 * found DFS channels in the current Reg. Domain . 4877 */ 4878 QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sap_ctx) 4879 { 4880 struct mac_context *mac; 4881 4882 if (!sap_ctx) { 4883 sap_err("Invalid SAP context"); 4884 return QDF_STATUS_E_FAULT; 4885 } 4886 4887 mac = sap_get_mac_context(); 4888 if (!mac) { 4889 sap_err("Invalid MAC context"); 4890 return QDF_STATUS_E_FAULT; 4891 } 4892 4893 utils_dfs_init_nol(mac->pdev); 4894 4895 return QDF_STATUS_SUCCESS; 4896 } 4897 4898 /** 4899 * sap_is_active() - Check SAP active or not by sap_context object 4900 * @sap_ctx: Pointer to the SAP context 4901 * 4902 * Return: true if SAP is active 4903 */ 4904 static bool sap_is_active(struct sap_context *sap_ctx) 4905 { 4906 return sap_ctx->fsm_state != SAP_INIT; 4907 } 4908 4909 /* 4910 * This function will calculate how many interfaces 4911 * have sap persona and returns total number of sap persona. 4912 */ 4913 uint8_t sap_get_total_number_sap_intf(mac_handle_t mac_handle) 4914 { 4915 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4916 uint8_t intf = 0; 4917 uint8_t intf_count = 0; 4918 struct sap_context *sap_context; 4919 4920 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 4921 if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona) 4922 || 4923 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona)) 4924 && mac->sap.sapCtxList[intf].sap_context) { 4925 sap_context = 4926 mac->sap.sapCtxList[intf].sap_context; 4927 if (!sap_is_active(sap_context)) 4928 continue; 4929 intf_count++; 4930 } 4931 } 4932 return intf_count; 4933 } 4934 4935 /** 4936 * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready 4937 * for channel change 4938 * @mac_handle: Opaque handle to the global MAC context 4939 * @sap_ctx: sap context for which this function has been called 4940 * 4941 * This function will find the concurrent sap context apart from 4942 * passed sap context and return its channel change ready status 4943 * 4944 * 4945 * Return: true if other SAP personas are ready to channel switch else false 4946 */ 4947 bool is_concurrent_sap_ready_for_channel_change(mac_handle_t mac_handle, 4948 struct sap_context *sap_ctx) 4949 { 4950 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4951 struct sap_context *sap_context; 4952 uint8_t intf = 0; 4953 4954 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 4955 if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona) 4956 || 4957 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona)) 4958 && mac->sap.sapCtxList[intf].sap_context) { 4959 sap_context = 4960 mac->sap.sapCtxList[intf].sap_context; 4961 if (!sap_is_active(sap_context)) 4962 continue; 4963 if (sap_context == sap_ctx) { 4964 sap_err("sapCtx matched [%pK]", sap_ctx); 4965 continue; 4966 } else { 4967 sap_err("concurrent sapCtx[%pK] didn't matche with [%pK]", 4968 sap_context, sap_ctx); 4969 return sap_context->is_sap_ready_for_chnl_chng; 4970 } 4971 } 4972 } 4973 return false; 4974 } 4975 4976 /** 4977 * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS 4978 * @mac_handle: Opaque handle to the global MAC context 4979 * @given_sapctx: current SAP persona's channel 4980 * 4981 * If provided SAP's channel is DFS then Loop through each SAP or GO persona and 4982 * check if other beaconing entity's channel is same DFS channel. If they are 4983 * same then concurrent sap is doing SCC DFS. 4984 * 4985 * Return: true if two or more beaconing entities doing SCC DFS else false 4986 */ 4987 bool sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle, 4988 struct sap_context *given_sapctx) 4989 { 4990 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4991 struct sap_context *sap_ctx; 4992 uint8_t intf = 0, scc_dfs_counter = 0; 4993 qdf_freq_t ch_freq; 4994 4995 ch_freq = given_sapctx->chan_freq; 4996 /* 4997 * current SAP persona's channel itself is not DFS, so no need to check 4998 * what other persona's channel is 4999 */ 5000 if (!wlan_reg_is_dfs_for_freq(mac->pdev, 5001 ch_freq)) { 5002 sap_debug("skip this loop as provided channel is non-dfs"); 5003 return false; 5004 } 5005 5006 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 5007 if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) && 5008 (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona)) 5009 continue; 5010 if (!mac->sap.sapCtxList[intf].sap_context) 5011 continue; 5012 sap_ctx = mac->sap.sapCtxList[intf].sap_context; 5013 if (!sap_is_active(sap_ctx)) 5014 continue; 5015 /* if same SAP contexts then skip to next context */ 5016 if (sap_ctx == given_sapctx) 5017 continue; 5018 if (given_sapctx->chan_freq == sap_ctx->chan_freq) 5019 scc_dfs_counter++; 5020 } 5021 5022 /* Found atleast two of the beaconing entities doing SCC DFS */ 5023 if (scc_dfs_counter) 5024 return true; 5025 5026 return false; 5027 } 5028 5029 /** 5030 * sap_build_start_bss_config() - Fill the start bss request for SAP 5031 * @sap_bss_cfg: start bss config 5032 * @config: sap config 5033 * 5034 * This function fills the start bss request for SAP 5035 * 5036 * Return: None 5037 */ 5038 void 5039 sap_build_start_bss_config(struct start_bss_config *sap_bss_cfg, 5040 struct sap_config *config) 5041 { 5042 qdf_mem_zero(&sap_bss_cfg->ssId.ssId, sizeof(sap_bss_cfg->ssId.ssId)); 5043 sap_bss_cfg->ssId.length = config->SSIDinfo.ssid.length; 5044 qdf_mem_copy(&sap_bss_cfg->ssId.ssId, config->SSIDinfo.ssid.ssId, 5045 config->SSIDinfo.ssid.length); 5046 5047 if (config->authType == eSAP_SHARED_KEY) 5048 sap_bss_cfg->authType = eSIR_SHARED_KEY; 5049 else if (config->authType == eSAP_OPEN_SYSTEM) 5050 sap_bss_cfg->authType = eSIR_OPEN_SYSTEM; 5051 else 5052 sap_bss_cfg->authType = eSIR_AUTO_SWITCH; 5053 5054 sap_bss_cfg->beaconInterval = (uint16_t)config->beacon_int; 5055 sap_bss_cfg->privacy = config->privacy; 5056 sap_bss_cfg->ssidHidden = config->SSIDinfo.ssidHidden; 5057 sap_bss_cfg->dtimPeriod = config->dtim_period; 5058 sap_bss_cfg->wps_state = config->wps_state; 5059 sap_bss_cfg->beacon_tx_rate = config->beacon_tx_rate; 5060 5061 /* RSNIE */ 5062 sap_bss_cfg->rsnIE.length = config->RSNWPAReqIELength; 5063 if (config->RSNWPAReqIELength) 5064 qdf_mem_copy(sap_bss_cfg->rsnIE.rsnIEdata, 5065 config->RSNWPAReqIE, config->RSNWPAReqIELength); 5066 5067 /* Probe response IE */ 5068 if (config->probeRespIEsBufferLen > 0 && 5069 config->pProbeRespIEsBuffer) { 5070 sap_bss_cfg->add_ie_params.probeRespDataLen = 5071 config->probeRespIEsBufferLen; 5072 sap_bss_cfg->add_ie_params.probeRespData_buff = 5073 config->pProbeRespIEsBuffer; 5074 } else { 5075 sap_bss_cfg->add_ie_params.probeRespDataLen = 0; 5076 sap_bss_cfg->add_ie_params.probeRespData_buff = NULL; 5077 } 5078 5079 /*assoc resp IE */ 5080 if (config->assocRespIEsLen > 0 && config->pAssocRespIEsBuffer) { 5081 sap_bss_cfg->add_ie_params.assocRespDataLen = 5082 config->assocRespIEsLen; 5083 sap_bss_cfg->add_ie_params.assocRespData_buff = 5084 config->pAssocRespIEsBuffer; 5085 } else { 5086 sap_bss_cfg->add_ie_params.assocRespDataLen = 0; 5087 sap_bss_cfg->add_ie_params.assocRespData_buff = NULL; 5088 } 5089 5090 if (config->probeRespBcnIEsLen > 0 && 5091 config->pProbeRespBcnIEsBuffer) { 5092 sap_bss_cfg->add_ie_params.probeRespBCNDataLen = 5093 config->probeRespBcnIEsLen; 5094 sap_bss_cfg->add_ie_params.probeRespBCNData_buff = 5095 config->pProbeRespBcnIEsBuffer; 5096 } else { 5097 sap_bss_cfg->add_ie_params.probeRespBCNDataLen = 0; 5098 sap_bss_cfg->add_ie_params.probeRespBCNData_buff = NULL; 5099 } 5100 5101 if (config->supported_rates.numRates) { 5102 qdf_mem_copy(sap_bss_cfg->operationalRateSet.rate, 5103 config->supported_rates.rate, 5104 config->supported_rates.numRates); 5105 sap_bss_cfg->operationalRateSet.numRates = 5106 config->supported_rates.numRates; 5107 } 5108 5109 if (config->extended_rates.numRates) { 5110 qdf_mem_copy(sap_bss_cfg->extendedRateSet.rate, 5111 config->extended_rates.rate, 5112 config->extended_rates.numRates); 5113 sap_bss_cfg->extendedRateSet.numRates = 5114 config->extended_rates.numRates; 5115 } 5116 5117 return; 5118 } 5119