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