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