1 /* 2 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /*=========================================================================== 20 21 s a p F s m . C 22 23 OVERVIEW: 24 25 This software unit holds the implementation of the WLAN SAP Finite 26 State Machine modules 27 28 DEPENDENCIES: 29 30 Are listed for each API below. 31 ===========================================================================*/ 32 33 /*---------------------------------------------------------------------------- 34 * Include Files 35 * -------------------------------------------------------------------------*/ 36 #include "sap_internal.h" 37 #include <wlan_dfs_tgt_api.h> 38 #include <wlan_dfs_utils_api.h> 39 #include <wlan_dfs_public_struct.h> 40 #include <wlan_reg_services_api.h> 41 /* Pick up the SME API definitions */ 42 #include "sme_api.h" 43 /* Pick up the PMC API definitions */ 44 #include "cds_utils.h" 45 #include "cds_ieee80211_common_i.h" 46 #include "cds_reg_service.h" 47 #include "qdf_util.h" 48 #include "wlan_policy_mgr_api.h" 49 #include "cfg_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_ucfg_api.h> 57 #include "wlan_reg_services_api.h" 58 59 /*---------------------------------------------------------------------------- 60 * Preprocessor Definitions and Constants 61 * -------------------------------------------------------------------------*/ 62 63 /*---------------------------------------------------------------------------- 64 * Type Declarations 65 * -------------------------------------------------------------------------*/ 66 67 /*---------------------------------------------------------------------------- 68 * Global Data Definitions 69 * -------------------------------------------------------------------------*/ 70 71 /*---------------------------------------------------------------------------- 72 * External declarations for global context 73 * -------------------------------------------------------------------------*/ 74 #ifdef FEATURE_WLAN_CH_AVOID 75 extern sapSafeChannelType safe_channels[]; 76 #endif /* FEATURE_WLAN_CH_AVOID */ 77 78 /*---------------------------------------------------------------------------- 79 * Static Variable Definitions 80 * -------------------------------------------------------------------------*/ 81 82 /*---------------------------------------------------------------------------- 83 * Static Function Declarations and Definitions 84 * -------------------------------------------------------------------------*/ 85 #ifdef SOFTAP_CHANNEL_RANGE 86 static QDF_STATUS sap_get_channel_list(struct sap_context *sapContext, 87 uint8_t **channelList, 88 uint8_t *numberOfChannels); 89 #endif 90 91 /*========================================================================== 92 FUNCTION sapStopDfsCacTimer 93 94 DESCRIPTION 95 Function to sttop the DFS CAC timer when SAP is stopped 96 DEPENDENCIES 97 NA. 98 99 PARAMETERS 100 101 IN 102 sapContext: SAP Context 103 RETURN VALUE 104 DFS Timer start status 105 SIDE EFFECTS 106 ============================================================================*/ 107 108 static int sap_stop_dfs_cac_timer(struct sap_context *sapContext); 109 110 /*========================================================================== 111 FUNCTION sapStartDfsCacTimer 112 113 DESCRIPTION 114 Function to start the DFS CAC timer when SAP is started on DFS Channel 115 DEPENDENCIES 116 NA. 117 118 PARAMETERS 119 120 IN 121 sapContext: SAP Context 122 RETURN VALUE 123 DFS Timer start status 124 SIDE EFFECTS 125 ============================================================================*/ 126 127 static int sap_start_dfs_cac_timer(struct sap_context *sapContext); 128 129 /** sap_hdd_event_to_string() - convert hdd event to string 130 * @event: eSapHddEvent event type 131 * 132 * This function converts eSapHddEvent into string 133 * 134 * Return: string for the @event. 135 */ 136 static uint8_t *sap_hdd_event_to_string(eSapHddEvent event) 137 { 138 switch (event) { 139 CASE_RETURN_STRING(eSAP_START_BSS_EVENT); 140 CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT); 141 CASE_RETURN_STRING(eSAP_STA_ASSOC_IND); 142 CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT); 143 CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT); 144 CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT); 145 CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT); 146 CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT); 147 CASE_RETURN_STRING(eSAP_ASSOC_STA_CALLBACK_EVENT); 148 CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT); 149 CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT); 150 CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT); 151 CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN); 152 CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED); 153 CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT); 154 CASE_RETURN_STRING(eSAP_DFS_CAC_START); 155 CASE_RETURN_STRING(eSAP_DFS_CAC_INTERRUPTED); 156 CASE_RETURN_STRING(eSAP_DFS_CAC_END); 157 CASE_RETURN_STRING(eSAP_DFS_PRE_CAC_END); 158 CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT); 159 CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC); 160 CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL); 161 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 162 CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT); 163 #endif 164 CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED); 165 CASE_RETURN_STRING(eSAP_ECSA_CHANGE_CHAN_IND); 166 default: 167 return "eSAP_HDD_EVENT_UNKNOWN"; 168 } 169 } 170 171 /*---------------------------------------------------------------------------- 172 * Externalized Function Definitions 173 * -------------------------------------------------------------------------*/ 174 175 /*---------------------------------------------------------------------------- 176 * Function Declarations and Documentation 177 * -------------------------------------------------------------------------*/ 178 179 /*========================================================================== 180 FUNCTION sap_event_init 181 182 DESCRIPTION 183 Function for initializing sWLAN_SAPEvent structure 184 185 DEPENDENCIES 186 NA. 187 188 PARAMETERS 189 190 IN 191 sapEvent : State machine event 192 193 RETURN VALUE 194 195 None 196 197 SIDE EFFECTS 198 ============================================================================*/ 199 static inline void sap_event_init(ptWLAN_SAPEvent sapEvent) 200 { 201 sapEvent->event = eSAP_MAC_SCAN_COMPLETE; 202 sapEvent->params = 0; 203 sapEvent->u1 = 0; 204 sapEvent->u2 = 0; 205 } 206 207 #ifdef DFS_COMPONENT_ENABLE 208 /** 209 * sap_random_channel_sel() - This function randomly pick up an available 210 * channel 211 * @sap_ctx: sap context. 212 * 213 * This function first eliminates invalid channel, then selects random channel 214 * using following algorithm: 215 * 216 * Return: channel number picked 217 **/ 218 static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) 219 { 220 uint8_t ch; 221 uint8_t ch_wd; 222 struct wlan_objmgr_pdev *pdev = NULL; 223 tHalHandle hal; 224 struct ch_params *ch_params; 225 uint32_t hw_mode; 226 tpAniSirGlobal mac_ctx; 227 struct dfs_acs_info acs_info = {0}; 228 229 hal = CDS_GET_HAL_CB(); 230 if (!hal) { 231 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 232 FL("null hal")); 233 return 0; 234 } 235 236 mac_ctx = PMAC_STRUCT(hal); 237 if (!mac_ctx) { 238 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 239 FL("null mac_ctx")); 240 return 0; 241 } 242 243 pdev = mac_ctx->pdev; 244 if (!pdev) { 245 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 246 FL("null pdev")); 247 return 0; 248 } 249 250 ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params; 251 if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) { 252 ch_wd = sap_ctx->ch_width_orig; 253 mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd; 254 } else { 255 ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; 256 } 257 258 ch_params->ch_width = ch_wd; 259 if (sap_ctx->acs_cfg) { 260 acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode; 261 acs_info.start_ch = sap_ctx->acs_cfg->start_ch; 262 acs_info.end_ch = sap_ctx->acs_cfg->end_ch; 263 } else { 264 acs_info.acs_mode = false; 265 } 266 if (QDF_IS_STATUS_ERROR(utils_dfs_get_random_channel( 267 pdev, 0, ch_params, &hw_mode, &ch, &acs_info))) { 268 /* No available channel found */ 269 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 270 FL("No available channel found!!!")); 271 sap_signal_hdd_event(sap_ctx, NULL, 272 eSAP_DFS_NO_AVAILABLE_CHANNEL, 273 (void *)eSAP_STATUS_SUCCESS); 274 return 0; 275 } 276 mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width; 277 sap_ctx->ch_params.ch_width = ch_params->ch_width; 278 sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset; 279 sap_ctx->ch_params.center_freq_seg0 = ch_params->center_freq_seg0; 280 sap_ctx->ch_params.center_freq_seg1 = ch_params->center_freq_seg1; 281 return ch; 282 } 283 #else 284 static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) 285 { 286 return 0; 287 } 288 #endif 289 290 /** 291 * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding. 292 * @sap_ctx: sap context 293 * 294 * Check if the current SAP operating channel is bonded to weather radar 295 * channel in ETSI domain. 296 * 297 * Return: True if bonded to weather channel in ETSI 298 */ 299 static bool 300 sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx) 301 { 302 if (IS_CH_BONDING_WITH_WEATHER_CH(sap_ctx->channel) && 303 (sap_ctx->ch_params.ch_width != CH_WIDTH_20MHZ)) 304 return true; 305 306 return false; 307 } 308 309 /* 310 * sap_get_bonding_channels() - get bonding channels from primary channel. 311 * @sapContext: Handle to SAP context. 312 * @channel: Channel to get bonded channels. 313 * @channels: Bonded channel list 314 * @size: Max bonded channels 315 * @chanBondState: The channel bonding mode of the passed channel. 316 * 317 * Return: Number of sub channels 318 */ 319 static uint8_t sap_get_bonding_channels(struct sap_context *sapContext, 320 uint8_t channel, 321 uint8_t *channels, uint8_t size, 322 ePhyChanBondState chanBondState) 323 { 324 tHalHandle hHal = CDS_GET_HAL_CB(); 325 tpAniSirGlobal pMac; 326 uint8_t numChannel; 327 328 if (channels == NULL) 329 return 0; 330 331 if (size < MAX_BONDED_CHANNELS) 332 return 0; 333 334 if (NULL != hHal) 335 pMac = PMAC_STRUCT(hHal); 336 else 337 return 0; 338 339 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 340 FL("cbmode: %d, channel: %d"), chanBondState, channel); 341 342 switch (chanBondState) { 343 case PHY_SINGLE_CHANNEL_CENTERED: 344 numChannel = 1; 345 channels[0] = channel; 346 break; 347 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 348 numChannel = 2; 349 channels[0] = channel - 4; 350 channels[1] = channel; 351 break; 352 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 353 numChannel = 2; 354 channels[0] = channel; 355 channels[1] = channel + 4; 356 break; 357 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: 358 numChannel = 4; 359 channels[0] = channel; 360 channels[1] = channel + 4; 361 channels[2] = channel + 8; 362 channels[3] = channel + 12; 363 break; 364 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: 365 numChannel = 4; 366 channels[0] = channel - 4; 367 channels[1] = channel; 368 channels[2] = channel + 4; 369 channels[3] = channel + 8; 370 break; 371 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: 372 numChannel = 4; 373 channels[0] = channel - 8; 374 channels[1] = channel - 4; 375 channels[2] = channel; 376 channels[3] = channel + 4; 377 break; 378 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: 379 numChannel = 4; 380 channels[0] = channel - 12; 381 channels[1] = channel - 8; 382 channels[2] = channel - 4; 383 channels[3] = channel; 384 break; 385 default: 386 numChannel = 1; 387 channels[0] = channel; 388 break; 389 } 390 391 return numChannel; 392 } 393 394 /** 395 * sap_ch_params_to_bonding_channels() - get bonding channels from channel param 396 * @ch_params: channel params ( bw, pri and sec channel info) 397 * @channels: bonded channel list 398 * 399 * Return: Number of sub channels 400 */ 401 static uint8_t sap_ch_params_to_bonding_channels( 402 struct ch_params *ch_params, 403 uint8_t *channels) 404 { 405 uint8_t center_chan = ch_params->center_freq_seg0; 406 uint8_t nchannels = 0; 407 408 switch (ch_params->ch_width) { 409 case CH_WIDTH_160MHZ: 410 nchannels = 8; 411 center_chan = ch_params->center_freq_seg1; 412 channels[0] = center_chan - 14; 413 channels[1] = center_chan - 10; 414 channels[2] = center_chan - 6; 415 channels[3] = center_chan - 2; 416 channels[4] = center_chan + 2; 417 channels[5] = center_chan + 6; 418 channels[6] = center_chan + 10; 419 channels[7] = center_chan + 14; 420 break; 421 case CH_WIDTH_80P80MHZ: 422 nchannels = 8; 423 channels[0] = center_chan - 6; 424 channels[1] = center_chan - 2; 425 channels[2] = center_chan + 2; 426 channels[3] = center_chan + 6; 427 428 center_chan = ch_params->center_freq_seg1; 429 channels[4] = center_chan - 6; 430 channels[5] = center_chan - 2; 431 channels[6] = center_chan + 2; 432 channels[7] = center_chan + 6; 433 break; 434 case CH_WIDTH_80MHZ: 435 nchannels = 4; 436 channels[0] = center_chan - 6; 437 channels[1] = center_chan - 2; 438 channels[2] = center_chan + 2; 439 channels[3] = center_chan + 6; 440 break; 441 case CH_WIDTH_40MHZ: 442 nchannels = 2; 443 channels[0] = center_chan - 2; 444 channels[1] = center_chan + 2; 445 break; 446 default: 447 nchannels = 1; 448 channels[0] = center_chan; 449 break; 450 } 451 452 return nchannels; 453 } 454 455 /** 456 * sap_get_cac_dur_dfs_region() - get cac duration and dfs region. 457 * @sap_ctxt: sap context 458 * @cac_duration_ms: pointer to cac duration 459 * @dfs_region: pointer to dfs region 460 * 461 * Get cac duration and dfs region. 462 * 463 * Return: None 464 */ 465 static void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx, 466 uint32_t *cac_duration_ms, 467 uint32_t *dfs_region) 468 { 469 int i; 470 uint8_t channels[MAX_BONDED_CHANNELS]; 471 uint8_t num_channels; 472 struct ch_params *ch_params = &sap_ctx->ch_params; 473 tHalHandle hal = NULL; 474 tpAniSirGlobal mac = NULL; 475 476 if (!sap_ctx) { 477 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 478 "%s: null sap_ctx", __func__); 479 return; 480 } 481 482 hal = CDS_GET_HAL_CB(); 483 if (!hal) { 484 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 485 "%s: null hal", __func__); 486 return; 487 } 488 489 mac = PMAC_STRUCT(hal); 490 wlan_reg_get_dfs_region(mac->pdev, dfs_region); 491 if (mac->sap.SapDfsInfo.ignore_cac) { 492 *cac_duration_ms = 0; 493 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 494 "%s: ignore_cac is set", __func__); 495 return; 496 } 497 *cac_duration_ms = DEFAULT_CAC_TIMEOUT; 498 499 if (*dfs_region != DFS_ETSI_REG) { 500 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 501 FL("sapdfs: default cac duration")); 502 return; 503 } 504 505 if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx)) { 506 *cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT; 507 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 508 FL("sapdfs: bonding_etsi_weather_channel")); 509 return; 510 } 511 512 qdf_mem_zero(channels, sizeof(channels)); 513 num_channels = sap_ch_params_to_bonding_channels(ch_params, channels); 514 for (i = 0; i < num_channels; i++) { 515 if (IS_ETSI_WEATHER_CH(channels[i])) { 516 *cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT; 517 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 518 FL("sapdfs: ch=%d is etsi weather channel"), 519 channels[i]); 520 return; 521 } 522 } 523 524 } 525 526 void sap_dfs_set_current_channel(void *ctx) 527 { 528 struct sap_context *sap_ctx = ctx; 529 uint32_t ic_flags = 0; 530 uint16_t ic_flagext = 0; 531 uint8_t ic_ieee = sap_ctx->channel; 532 uint16_t ic_freq = utils_dfs_chan_to_freq(sap_ctx->channel); 533 uint8_t vht_seg0 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; 534 uint8_t vht_seg1 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; 535 struct wlan_objmgr_pdev *pdev; 536 tpAniSirGlobal mac_ctx; 537 tHalHandle hal; 538 uint32_t use_nol = 0; 539 int error; 540 541 hal = CDS_GET_HAL_CB(); 542 if (!hal) { 543 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 544 FL("null hal")); 545 return; 546 } 547 548 mac_ctx = PMAC_STRUCT(hal); 549 pdev = mac_ctx->pdev; 550 if (!pdev) { 551 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 552 FL("null pdev")); 553 return; 554 } 555 556 switch (sap_ctx->csr_roamProfile.ch_params.ch_width) { 557 case CH_WIDTH_20MHZ: 558 ic_flags |= IEEE80211_CHAN_VHT20; 559 break; 560 case CH_WIDTH_40MHZ: 561 ic_flags |= IEEE80211_CHAN_VHT40PLUS; 562 break; 563 case CH_WIDTH_80MHZ: 564 ic_flags |= IEEE80211_CHAN_VHT80; 565 break; 566 case CH_WIDTH_80P80MHZ: 567 ic_flags |= IEEE80211_CHAN_VHT80_80; 568 break; 569 case CH_WIDTH_160MHZ: 570 ic_flags |= IEEE80211_CHAN_VHT160; 571 break; 572 default: 573 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 574 FL("Invalid channel width=%d"), 575 sap_ctx->csr_roamProfile.ch_params.ch_width); 576 return; 577 } 578 579 if (WLAN_REG_IS_24GHZ_CH(sap_ctx->channel)) 580 ic_flags |= IEEE80211_CHAN_2GHZ; 581 else 582 ic_flags |= IEEE80211_CHAN_5GHZ; 583 584 if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel)) 585 ic_flagext |= IEEE80211_CHAN_DFS; 586 587 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 588 FL("freq=%d, channel=%d, seg0=%d, seg1=%d, flags=0x%x, ext flags=0x%x"), 589 ic_freq, ic_ieee, vht_seg0, vht_seg1, ic_flags, ic_flagext); 590 591 tgt_dfs_set_current_channel(pdev, ic_freq, ic_flags, 592 ic_flagext, ic_ieee, vht_seg0, vht_seg1); 593 594 if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel)) { 595 if (policy_mgr_concurrent_beaconing_sessions_running( 596 mac_ctx->psoc)) { 597 uint16_t con_ch; 598 599 con_ch = sme_get_concurrent_operation_channel(hal); 600 if (!con_ch || !wlan_reg_is_dfs_ch(pdev, con_ch)) 601 tgt_dfs_get_radars(pdev); 602 } else { 603 tgt_dfs_get_radars(pdev); 604 } 605 tgt_dfs_set_phyerr_filter_offload(pdev); 606 if (sap_ctx->csr_roamProfile.disableDFSChSwitch) 607 tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol, 608 sizeof(uint32_t), NULL, NULL, &error); 609 } 610 } 611 612 /* 613 * FUNCTION sap_dfs_is_w53_invalid 614 * 615 * DESCRIPTION Checks if the passed channel is W53 and returns if 616 * SAP W53 opearation is allowed. 617 * 618 * DEPENDENCIES PARAMETERS 619 * IN hHAL : HAL pointer 620 * channelID: Channel Number to be verified 621 * 622 * RETURN VALUE : bool 623 * true: If W53 operation is disabled 624 * false: If W53 operation is enabled 625 * 626 * SIDE EFFECTS 627 */ 628 bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID) 629 { 630 tpAniSirGlobal pMac; 631 632 pMac = PMAC_STRUCT(hHal); 633 if (NULL == pMac) { 634 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 635 FL("invalid pMac")); 636 return false; 637 } 638 639 /* 640 * Check for JAPAN W53 Channel operation capability 641 */ 642 if (true == pMac->sap.SapDfsInfo.is_dfs_w53_disabled && 643 true == IS_CHAN_JAPAN_W53(channelID)) { 644 return true; 645 } 646 647 return false; 648 } 649 650 /* 651 * FUNCTION sap_dfs_is_channel_in_preferred_location 652 * 653 * DESCRIPTION Checks if the passed channel is in accordance with preferred 654 * Channel location settings. 655 * 656 * DEPENDENCIES PARAMETERS 657 * IN hHAL : HAL pointer 658 * channelID: Channel Number to be verified 659 * 660 * RETURN VALUE :bool 661 * true:If Channel location is same as the preferred location 662 * false:If Channel location is not same as the preferred location 663 * 664 * SIDE EFFECTS 665 */ 666 bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal, uint8_t channelID) 667 { 668 tpAniSirGlobal pMac; 669 670 pMac = PMAC_STRUCT(hHal); 671 if (NULL == pMac) { 672 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 673 FL("invalid pMac")); 674 return true; 675 } 676 if ((SAP_CHAN_PREFERRED_INDOOR == 677 pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) && 678 (true == IS_CHAN_JAPAN_OUTDOOR(channelID))) { 679 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 680 FL 681 ("CHAN=%d is Outdoor so invalid,preferred Indoor only"), 682 channelID); 683 return false; 684 } else if ((SAP_CHAN_PREFERRED_OUTDOOR == 685 pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) 686 && (true == IS_CHAN_JAPAN_INDOOR(channelID))) { 687 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 688 FL 689 ("CHAN=%d is Indoor so invalid,preferred Outdoor only"), 690 channelID); 691 return false; 692 } 693 694 return true; 695 } 696 697 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 698 /** 699 * sap_check_in_avoid_ch_list() - checks if given channel present is channel 700 * avoidance list 701 * 702 * @sap_ctx: sap context. 703 * @channel: channel to be checked in sap_ctx's avoid ch list 704 * 705 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on 706 * which MDM device's AP with MCC was detected. This function checks if given 707 * channel is present in that list. 708 * 709 * Return: true, if channel was present, false othersie. 710 */ 711 bool sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel) 712 { 713 uint8_t i = 0; 714 struct sap_avoid_channels_info *ie_info = 715 &sap_ctx->sap_detected_avoid_ch_ie; 716 for (i = 0; i < sizeof(ie_info->channels); i++) 717 if (ie_info->channels[i] == channel) 718 return true; 719 return false; 720 } 721 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 722 723 /** 724 * sap_dfs_is_channel_in_nol_list() - given bonded channel is available 725 * @sap_context: Handle to SAP context. 726 * @channel_number: Channel on which availability should be checked. 727 * @chan_bondState: The channel bonding mode of the passed channel. 728 * 729 * This function Checks if a given bonded channel is available or 730 * usable for DFS operation. 731 * 732 * Return: false if channel is available, true if channel is in NOL. 733 */ 734 bool 735 sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context, 736 uint8_t channel_number, 737 ePhyChanBondState chan_bondState) 738 { 739 int i; 740 tHalHandle h_hal = CDS_GET_HAL_CB(); 741 tpAniSirGlobal mac_ctx; 742 uint8_t channels[MAX_BONDED_CHANNELS]; 743 uint8_t num_channels; 744 struct wlan_objmgr_pdev *pdev = NULL; 745 enum channel_state ch_state; 746 747 if (!h_hal) { 748 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 749 FL("invalid h_hal")); 750 return false; 751 } else { 752 mac_ctx = PMAC_STRUCT(h_hal); 753 } 754 755 /* get the bonded channels */ 756 if (channel_number == sap_context->channel && chan_bondState >= 757 PHY_CHANNEL_BONDING_STATE_MAX) 758 num_channels = sap_ch_params_to_bonding_channels( 759 &sap_context->ch_params, channels); 760 else 761 num_channels = sap_get_bonding_channels(sap_context, 762 channel_number, channels, 763 MAX_BONDED_CHANNELS, chan_bondState); 764 765 pdev = mac_ctx->pdev; 766 if (!pdev) { 767 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 768 FL("null pdev")); 769 return false; 770 } 771 772 /* check for NOL, first on will break the loop */ 773 for (i = 0; i < num_channels; i++) { 774 ch_state = wlan_reg_get_channel_state(pdev, channels[i]); 775 if (CHANNEL_STATE_ENABLE != ch_state && 776 CHANNEL_STATE_DFS != ch_state) { 777 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 778 FL("Invalid ch num=%d, ch state=%d"), 779 channels[i], ch_state); 780 return true; 781 } 782 } /* loop for bonded channels */ 783 784 return false; 785 } 786 787 uint8_t sap_select_default_oper_chan(struct sap_acs_cfg *acs_cfg) 788 { 789 uint8_t channel; 790 791 if (NULL == acs_cfg) { 792 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 793 "ACS config invalid!"); 794 QDF_BUG(0); 795 return 0; 796 } 797 798 if (acs_cfg->hw_mode == eCSR_DOT11_MODE_11a) { 799 channel = SAP_DEFAULT_5GHZ_CHANNEL; 800 } else if ((acs_cfg->hw_mode == eCSR_DOT11_MODE_11n) || 801 (acs_cfg->hw_mode == eCSR_DOT11_MODE_11n_ONLY) || 802 (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ac) || 803 (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ac_ONLY) || 804 (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ax) || 805 (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ax_ONLY)) { 806 if (WLAN_REG_IS_5GHZ_CH(acs_cfg->start_ch)) 807 channel = SAP_DEFAULT_5GHZ_CHANNEL; 808 else 809 channel = SAP_DEFAULT_24GHZ_CHANNEL; 810 } else { 811 channel = SAP_DEFAULT_24GHZ_CHANNEL; 812 } 813 814 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 815 FL("channel selected to start bss %d"), channel); 816 return channel; 817 } 818 819 /** 820 * sap_goto_channel_sel - Function for initiating scan request for SME 821 * @sap_context: Sap Context value. 822 * @sap_event: State machine event 823 * @sap_do_acs_pre_start_bss: true, if ACS scan is issued pre start BSS 824 * false, if ACS scan is issued post start BSS. 825 * @check_for_connection_update: true, check and wait for connection update 826 * false, do not perform connection update 827 * 828 * Initiates sme scan for ACS to pick a channel. 829 * 830 * Return: The QDF_STATUS code associated with performing the operation. 831 */ 832 QDF_STATUS sap_goto_channel_sel(struct sap_context *sap_context, 833 ptWLAN_SAPEvent sap_event, 834 bool sap_do_acs_pre_start_bss, 835 bool check_for_connection_update) 836 { 837 838 /* Initiate a SCAN request */ 839 QDF_STATUS qdf_ret_status; 840 /* To be initialised if scan is required */ 841 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 842 tpAniSirGlobal mac_ctx; 843 struct scan_start_request *req; 844 struct wlan_objmgr_vdev *vdev; 845 uint8_t i; 846 uint8_t pdev_id; 847 848 #ifdef SOFTAP_CHANNEL_RANGE 849 uint8_t *channel_list = NULL; 850 uint8_t num_of_channels = 0; 851 #endif 852 tHalHandle h_hal; 853 uint8_t con_ch; 854 uint8_t vdev_id; 855 uint32_t scan_id; 856 857 h_hal = cds_get_context(QDF_MODULE_ID_SME); 858 if (NULL == h_hal) { 859 /* we have a serious problem */ 860 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 861 FL("invalid h_hal")); 862 return QDF_STATUS_E_FAULT; 863 } 864 865 mac_ctx = PMAC_STRUCT(h_hal); 866 if (NULL == mac_ctx) { 867 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 868 FL("Invalid MAC context")); 869 return QDF_STATUS_E_FAILURE; 870 } 871 if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || 872 ((sap_context->cc_switch_mode == 873 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && 874 (policy_mgr_mode_specific_connection_count(mac_ctx->psoc, 875 PM_SAP_MODE, NULL) || 876 policy_mgr_mode_specific_connection_count(mac_ctx->psoc, 877 PM_P2P_GO_MODE, NULL)))) { 878 con_ch = 879 sme_get_concurrent_operation_channel(h_hal); 880 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 881 if (con_ch && sap_context->channel == AUTO_CHANNEL_SELECT) { 882 sap_context->dfs_ch_disable = true; 883 } else if (con_ch && sap_context->channel != con_ch && 884 wlan_reg_is_dfs_ch(mac_ctx->pdev, 885 sap_context->channel)) { 886 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 887 FL("MCC DFS not supported in AP_AP Mode")); 888 return QDF_STATUS_E_ABORTED; 889 } 890 #endif 891 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 892 if (sap_context->cc_switch_mode != 893 QDF_MCC_TO_SCC_SWITCH_DISABLE && 894 sap_context->channel) { 895 /* 896 * For ACS request ,the sapContext->channel is 0, 897 * we skip below overlap checking. When the ACS 898 * finish and SAPBSS start, the sapContext->channel 899 * will not be 0. Then the overlap checking will be 900 * reactivated.If we use sapContext->channel = 0 901 * to perform the overlap checking, an invalid overlap 902 * channel con_ch could becreated. That may cause 903 * SAP start failed. 904 */ 905 con_ch = sme_check_concurrent_channel_overlap(h_hal, 906 sap_context->channel, 907 sap_context->csr_roamProfile.phyMode, 908 sap_context->cc_switch_mode); 909 if (con_ch && !(wlan_reg_is_dfs_ch(mac_ctx->pdev, 910 con_ch) && 911 sap_context->cc_switch_mode == 912 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)) { 913 QDF_TRACE(QDF_MODULE_ID_SAP, 914 QDF_TRACE_LEVEL_ERROR, 915 "%s: Override ch %d to %d due to CC Intf", 916 __func__, sap_context->channel, con_ch); 917 sap_context->channel = con_ch; 918 wlan_reg_set_channel_params(mac_ctx->pdev, 919 sap_context->channel, 0, 920 &sap_context->ch_params); 921 } 922 } 923 #endif 924 } 925 926 if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) == 927 (QDF_STA_MASK | QDF_SAP_MASK)) || 928 ((sap_context->cc_switch_mode == 929 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && 930 (policy_mgr_get_concurrency_mode(mac_ctx->psoc) == 931 (QDF_STA_MASK | QDF_P2P_GO_MASK)))) { 932 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE 933 if (sap_context->channel == AUTO_CHANNEL_SELECT) 934 sap_context->dfs_ch_disable = true; 935 else if (wlan_reg_is_dfs_ch(mac_ctx->pdev, 936 sap_context->channel)) { 937 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 938 FL("DFS not supported in STA_AP Mode")); 939 return QDF_STATUS_E_ABORTED; 940 } 941 #endif 942 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 943 if (sap_context->cc_switch_mode != 944 QDF_MCC_TO_SCC_SWITCH_DISABLE && 945 sap_context->channel) { 946 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 947 FL("check for overlap: chan:%d mode:%d"), 948 sap_context->channel, 949 sap_context->csr_roamProfile.phyMode); 950 con_ch = sme_check_concurrent_channel_overlap(h_hal, 951 sap_context->channel, 952 sap_context->csr_roamProfile.phyMode, 953 sap_context->cc_switch_mode); 954 if (sap_context->cc_switch_mode != 955 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) { 956 if (QDF_IS_STATUS_ERROR( 957 policy_mgr_valid_sap_conc_channel_check( 958 mac_ctx->psoc, &con_ch, 959 sap_context->channel))) { 960 QDF_TRACE(QDF_MODULE_ID_SAP, 961 QDF_TRACE_LEVEL_WARN, 962 FL("SAP can't start (no MCC)")); 963 return QDF_STATUS_E_ABORTED; 964 } 965 } 966 if (con_ch && !wlan_reg_is_dfs_ch(mac_ctx->pdev, 967 con_ch)) { 968 QDF_TRACE(QDF_MODULE_ID_SAP, 969 QDF_TRACE_LEVEL_ERROR, 970 "%s: Override ch %d to %d due to CC Intf", 971 __func__, sap_context->channel, con_ch); 972 sap_context->channel = con_ch; 973 wlan_reg_set_channel_params(mac_ctx->pdev, 974 sap_context->channel, 0, 975 &sap_context->ch_params); 976 } 977 } 978 #endif 979 } 980 981 if (sap_context->channel == AUTO_CHANNEL_SELECT) { 982 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 983 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 984 FL("%s skip_acs_status = %d "), __func__, 985 sap_context->acs_cfg->skip_scan_status); 986 if (sap_context->acs_cfg->skip_scan_status != 987 eSAP_SKIP_ACS_SCAN) { 988 #endif 989 990 req = qdf_mem_malloc(sizeof(*req)); 991 if (!req) { 992 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 993 FL("Failed to allocate memory")); 994 return QDF_STATUS_E_NOMEM; 995 } 996 997 pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev); 998 vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(mac_ctx->psoc, 999 pdev_id, 1000 sap_context->self_mac_addr, 1001 WLAN_LEGACY_SME_ID); 1002 if (!vdev) { 1003 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1004 FL("Invalid vdev objmgr")); 1005 return QDF_STATUS_E_INVAL; 1006 } 1007 1008 ucfg_scan_init_default_params(vdev, req); 1009 req->scan_req.dwell_time_active = 0; 1010 scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc); 1011 req->scan_req.scan_id = scan_id; 1012 vdev_id = wlan_vdev_get_id(vdev); 1013 req->scan_req.vdev_id = vdev_id; 1014 req->scan_req.scan_req_id = sap_context->req_id; 1015 sap_get_channel_list(sap_context, &channel_list, 1016 &num_of_channels); 1017 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1018 if (num_of_channels != 0) { 1019 #endif 1020 1021 req->scan_req.chan_list.num_chan = num_of_channels; 1022 for (i = 0; i < num_of_channels; i++) 1023 req->scan_req.chan_list.chan[i].freq = 1024 wlan_chan_to_freq(channel_list[i]); 1025 if (sap_context->channelList) { 1026 qdf_mem_free(sap_context->channelList); 1027 sap_context->channelList = NULL; 1028 sap_context->num_of_channel = 0; 1029 } 1030 sap_context->channelList = channel_list; 1031 sap_context->num_of_channel = num_of_channels; 1032 /* Set requestType to Full scan */ 1033 1034 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1035 FL("calling ucfg_scan_start")); 1036 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1037 if (sap_context->acs_cfg->skip_scan_status == 1038 eSAP_DO_NEW_ACS_SCAN) 1039 #endif 1040 sme_scan_flush_result(h_hal); 1041 sap_context->sap_acs_pre_start_bss = sap_do_acs_pre_start_bss; 1042 qdf_ret_status = ucfg_scan_start(req); 1043 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1044 1045 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 1046 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1047 FL("scan request fail %d!!!"), 1048 qdf_ret_status); 1049 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1050 FL("SAP Configuring default channel, Ch=%d"), 1051 sap_context->channel); 1052 sap_context->channel = sap_select_default_oper_chan( 1053 sap_context->acs_cfg); 1054 1055 #ifdef SOFTAP_CHANNEL_RANGE 1056 if (sap_context->channelList != NULL) { 1057 sap_context->channel = 1058 sap_context->channelList[0]; 1059 qdf_mem_free(sap_context-> 1060 channelList); 1061 sap_context->channelList = NULL; 1062 sap_context->num_of_channel = 0; 1063 } 1064 #endif 1065 if (true == sap_do_acs_pre_start_bss) { 1066 /* 1067 * In case of ACS req before start Bss, 1068 * return failure so that the calling 1069 * function can use the default channel. 1070 */ 1071 return QDF_STATUS_E_FAILURE; 1072 } else { 1073 /* Fill in the event structure */ 1074 sap_event_init(sap_event); 1075 /* Handle event */ 1076 qdf_status = sap_fsm(sap_context, sap_event); 1077 } 1078 } else { 1079 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1080 FL("return sme_ScanReq, scanID=%d, Ch=%d"), 1081 scan_id, 1082 sap_context->channel); 1083 host_log_acs_scan_start(scan_id, vdev_id); 1084 } 1085 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1086 } 1087 } else { 1088 sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN; 1089 } 1090 1091 if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) { 1092 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1093 FL("## %s SKIPPED ACS SCAN"), __func__); 1094 1095 if (true == sap_do_acs_pre_start_bss) 1096 wlansap_pre_start_bss_acs_scan_callback(h_hal, 1097 sap_context, sap_context->sessionId, 0, 1098 eCSR_SCAN_SUCCESS); 1099 else 1100 wlansap_scan_callback(h_hal, sap_context, 1101 sap_context->sessionId, 0, eCSR_SCAN_SUCCESS); 1102 } 1103 #endif 1104 } else { 1105 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1106 FL("for configured channel, Ch= %d"), 1107 sap_context->channel); 1108 1109 if (check_for_connection_update) { 1110 /* This wait happens in the hostapd context. The event 1111 * is set in the MC thread context. 1112 */ 1113 qdf_status = 1114 policy_mgr_update_and_wait_for_connection_update( 1115 mac_ctx->psoc, 1116 sap_context->sessionId, 1117 sap_context->channel, 1118 POLICY_MGR_UPDATE_REASON_START_AP); 1119 if (QDF_IS_STATUS_ERROR(qdf_status)) 1120 return qdf_status; 1121 } 1122 1123 if (sap_do_acs_pre_start_bss == true) { 1124 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1125 FL("ACS end due to Ch override. Sel Ch = %d"), 1126 sap_context->channel); 1127 sap_context->acs_cfg->pri_ch = sap_context->channel; 1128 sap_context->acs_cfg->ch_width = 1129 sap_context->ch_width_orig; 1130 sap_config_acs_result(h_hal, sap_context, 0); 1131 return QDF_STATUS_E_CANCELED; 1132 } else { 1133 /* 1134 * Fill in the event structure 1135 * Eventhough scan was not done, 1136 * means a user set channel was chosen 1137 */ 1138 sap_event_init(sap_event); 1139 /* Handle event */ 1140 qdf_status = sap_fsm(sap_context, sap_event); 1141 } 1142 } 1143 1144 /* 1145 * If scan failed, get default channel and advance state 1146 * machine as success with default channel 1147 * 1148 * Have to wait for the call back to be called to get the 1149 * channel cannot advance state machine here as said above 1150 */ 1151 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1152 FL("before exiting sap_goto_channel_sel channel=%d"), 1153 sap_context->channel); 1154 1155 return QDF_STATUS_SUCCESS; 1156 } 1157 1158 /** 1159 * sap_find_valid_concurrent_session() - to find valid concurrent session 1160 * @hal: pointer to hal abstration layer 1161 * 1162 * This API will check if any valid concurrent SAP session is present 1163 * 1164 * Return: pointer to sap context of valid concurrent session 1165 */ 1166 static struct sap_context *sap_find_valid_concurrent_session(tHalHandle hal) 1167 { 1168 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 1169 uint8_t intf = 0; 1170 struct sap_context *sap_ctx; 1171 1172 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1173 if (((QDF_SAP_MODE == 1174 mac_ctx->sap.sapCtxList[intf].sapPersona) || 1175 (QDF_P2P_GO_MODE == 1176 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 1177 mac_ctx->sap.sapCtxList[intf].sap_context != NULL) { 1178 sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context; 1179 if (sap_ctx->sapsMachine != eSAP_DISCONNECTED) 1180 return sap_ctx; 1181 } 1182 } 1183 1184 return NULL; 1185 } 1186 1187 static QDF_STATUS sap_clear_global_dfs_param(tHalHandle hal) 1188 { 1189 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 1190 1191 if (NULL != sap_find_valid_concurrent_session(hal)) { 1192 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1193 "conc session exists, no need to clear dfs struct"); 1194 return QDF_STATUS_SUCCESS; 1195 } 1196 /* 1197 * CAC timer will be initiated and started only when SAP starts 1198 * on DFS channel and it will be stopped and destroyed 1199 * immediately once the radar detected or timedout. So 1200 * as per design CAC timer should be destroyed after stop 1201 */ 1202 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) { 1203 qdf_mc_timer_stop(&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer); 1204 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 1205 qdf_mc_timer_destroy( 1206 &mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer); 1207 } 1208 mac_ctx->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; 1209 sap_cac_reset_notify(hal); 1210 qdf_mem_zero(&mac_ctx->sap, sizeof(mac_ctx->sap)); 1211 1212 return QDF_STATUS_SUCCESS; 1213 } 1214 1215 QDF_STATUS sap_set_session_param(tHalHandle hal, struct sap_context *sapctx, 1216 uint32_t session_id) 1217 { 1218 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 1219 int i; 1220 1221 sapctx->sessionId = session_id; 1222 sapctx->is_pre_cac_on = false; 1223 sapctx->pre_cac_complete = false; 1224 sapctx->chan_before_pre_cac = 0; 1225 1226 /* When SSR, SAP will restart, clear the old context,sessionId */ 1227 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 1228 if (mac_ctx->sap.sapCtxList[i].sap_context == sapctx) 1229 mac_ctx->sap.sapCtxList[i].sap_context = NULL; 1230 } 1231 mac_ctx->sap.sapCtxList[sapctx->sessionId].sessionID = 1232 sapctx->sessionId; 1233 mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx; 1234 mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = 1235 sapctx->csr_roamProfile.csrPersona; 1236 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1237 "%s: Initializing sapContext = %pK with session = %d", __func__, 1238 sapctx, session_id); 1239 1240 return QDF_STATUS_SUCCESS; 1241 } 1242 1243 QDF_STATUS sap_clear_session_param(tHalHandle hal, struct sap_context *sapctx, 1244 uint32_t session_id) 1245 { 1246 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 1247 1248 if (sapctx->sessionId >= SAP_MAX_NUM_SESSION) 1249 return QDF_STATUS_E_FAILURE; 1250 1251 mac_ctx->sap.sapCtxList[sapctx->sessionId].sessionID = 1252 CSR_SESSION_ID_INVALID; 1253 mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL; 1254 mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = 1255 QDF_MAX_NO_OF_MODE; 1256 sap_clear_global_dfs_param(hal); 1257 sap_free_roam_profile(&sapctx->csr_roamProfile); 1258 qdf_mem_zero(sapctx, sizeof(*sapctx)); 1259 sapctx->sessionId = CSR_SESSION_ID_INVALID; 1260 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1261 "%s: Initializing State: %d, sapContext value = %pK", __func__, 1262 sapctx->sapsMachine, sapctx); 1263 1264 return QDF_STATUS_SUCCESS; 1265 } 1266 1267 /*========================================================================== 1268 FUNCTION sapGotoStarting 1269 1270 DESCRIPTION 1271 Function for initiating start bss request for SME 1272 1273 DEPENDENCIES 1274 NA. 1275 1276 PARAMETERS 1277 1278 IN 1279 sapContext : Sap Context value 1280 sapEvent : State machine event 1281 bssType : Type of bss to start, INRA AP 1282 status : Return the SAP status here 1283 1284 RETURN VALUE 1285 The QDF_STATUS code associated with performing the operation 1286 1287 QDF_STATUS_SUCCESS: Success 1288 1289 SIDE EFFECTS 1290 ============================================================================*/ 1291 static QDF_STATUS sap_goto_starting(struct sap_context *sapContext, 1292 ptWLAN_SAPEvent sapEvent, 1293 eCsrRoamBssType bssType) 1294 { 1295 /* tHalHandle */ 1296 tHalHandle hHal = CDS_GET_HAL_CB(); 1297 QDF_STATUS qdf_ret_status; 1298 1299 /*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/ 1300 char key_material[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 1301 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, }; 1302 sapContext->key_type = 0x05; 1303 sapContext->key_length = 32; 1304 /* Need a key size define */ 1305 qdf_mem_copy(sapContext->key_material, key_material, 1306 sizeof(key_material)); 1307 1308 if (NULL == hHal) { 1309 /* we have a serious problem */ 1310 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 1311 "In %s, invalid hHal", __func__); 1312 return QDF_STATUS_E_FAULT; 1313 } 1314 1315 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, "%s: session: %d", 1316 __func__, sapContext->sessionId); 1317 1318 qdf_ret_status = sme_roam_connect(hHal, sapContext->sessionId, 1319 &sapContext->csr_roamProfile, 1320 &sapContext->csr_roamId); 1321 if (QDF_STATUS_SUCCESS != qdf_ret_status) 1322 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1323 "%s: Failed to issue sme_roam_connect", __func__); 1324 1325 return qdf_ret_status; 1326 } /* sapGotoStarting */ 1327 1328 /*========================================================================== 1329 FUNCTION sapGotoDisconnecting 1330 1331 DESCRIPTION 1332 Processing of SAP FSM Disconnecting state 1333 1334 DEPENDENCIES 1335 NA. 1336 1337 PARAMETERS 1338 1339 IN 1340 sapContext : Sap Context value 1341 status : Return the SAP status here 1342 1343 RETURN VALUE 1344 The QDF_STATUS code associated with performing the operation 1345 1346 QDF_STATUS_SUCCESS: Success 1347 1348 SIDE EFFECTS 1349 ============================================================================*/ 1350 static QDF_STATUS sap_goto_disconnecting(struct sap_context *sapContext) 1351 { 1352 QDF_STATUS qdf_ret_status; 1353 tHalHandle hHal; 1354 1355 hHal = CDS_GET_HAL_CB(); 1356 if (NULL == hHal) { 1357 /* we have a serious problem */ 1358 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1359 "In %s, invalid hHal", __func__); 1360 return QDF_STATUS_E_FAULT; 1361 } 1362 1363 sap_free_roam_profile(&sapContext->csr_roamProfile); 1364 qdf_ret_status = sme_roam_stop_bss(hHal, sapContext->sessionId); 1365 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 1366 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1367 "Error: In %s calling sme_roam_stop_bss status = %d", 1368 __func__, qdf_ret_status); 1369 return QDF_STATUS_E_FAILURE; 1370 } 1371 1372 return QDF_STATUS_SUCCESS; 1373 } 1374 1375 /*========================================================================== 1376 FUNCTION sapGotoDisconnected 1377 1378 DESCRIPTION 1379 Function for setting the SAP FSM to Disconnection state 1380 1381 DEPENDENCIES 1382 NA. 1383 1384 PARAMETERS 1385 1386 IN 1387 sapContext : Sap Context value 1388 sapEvent : State machine event 1389 status : Return the SAP status here 1390 1391 RETURN VALUE 1392 The QDF_STATUS code associated with performing the operation 1393 1394 QDF_STATUS_SUCCESS: Success 1395 1396 SIDE EFFECTS 1397 ============================================================================*/ 1398 static QDF_STATUS sap_goto_disconnected(struct sap_context *sapContext) 1399 { 1400 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1401 tWLAN_SAPEvent sapEvent; 1402 /* Processing has to be coded */ 1403 /* Clean up stations from TL etc as AP BSS is shut down then set event */ 1404 sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS; /* hardcoded */ 1405 sapEvent.params = 0; 1406 sapEvent.u1 = 0; 1407 sapEvent.u2 = 0; 1408 /* Handle event */ 1409 qdf_status = sap_fsm(sapContext, &sapEvent); 1410 1411 return qdf_status; 1412 } 1413 1414 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 1415 /** 1416 * sap_handle_acs_scan_event() - handle acs scan event for SAP 1417 * @sap_context: ptSapContext 1418 * @sap_event: tSap_Event 1419 * @status: status of acs scan 1420 * 1421 * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event. 1422 * 1423 * Return: void 1424 */ 1425 static void sap_handle_acs_scan_event(struct sap_context *sap_context, 1426 tSap_Event *sap_event, eSapStatus status) 1427 { 1428 sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT; 1429 sap_event->sapevt.sap_acs_scan_comp.status = status; 1430 sap_event->sapevt.sap_acs_scan_comp.num_of_channels = 1431 sap_context->num_of_channel; 1432 sap_event->sapevt.sap_acs_scan_comp.channellist = 1433 sap_context->channelList; 1434 } 1435 #else 1436 static void sap_handle_acs_scan_event(struct sap_context *sap_context, 1437 tSap_Event *sap_event, eSapStatus status) 1438 { 1439 } 1440 #endif 1441 1442 /** 1443 * sap_signal_hdd_event() - send event notification 1444 * @sap_ctx: Sap Context 1445 * @csr_roaminfo: Pointer to CSR roam information 1446 * @sap_hddevent: SAP HDD event 1447 * @context: to pass the element for future support 1448 * 1449 * Function for HDD to send the event notification using callback 1450 * 1451 * Return: QDF_STATUS 1452 */ 1453 QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, 1454 struct csr_roam_info *csr_roaminfo, eSapHddEvent sap_hddevent, 1455 void *context) 1456 { 1457 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1458 tSap_Event sap_ap_event = {0}; 1459 tHalHandle hal = CDS_GET_HAL_CB(); 1460 tpAniSirGlobal mac_ctx; 1461 tSirSmeChanInfo *chaninfo; 1462 tSap_StationAssocIndication *assoc_ind; 1463 tSap_StartBssCompleteEvent *bss_complete; 1464 struct sap_ch_selected_s *acs_selected; 1465 tSap_StationAssocReassocCompleteEvent *reassoc_complete; 1466 tSap_StationDisassocCompleteEvent *disassoc_comp; 1467 tSap_StationSetKeyCompleteEvent *key_complete; 1468 tSap_StationMICFailureEvent *mic_failure; 1469 1470 /* Format the Start BSS Complete event to return... */ 1471 if (NULL == sap_ctx->pfnSapEventCallback) { 1472 return QDF_STATUS_E_FAILURE; 1473 } 1474 if (NULL == hal) { 1475 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1476 FL("Invalid hal")); 1477 return QDF_STATUS_E_FAILURE; 1478 } 1479 mac_ctx = PMAC_STRUCT(hal); 1480 if (NULL == mac_ctx) { 1481 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1482 FL("Invalid MAC context")); 1483 return QDF_STATUS_E_FAILURE; 1484 } 1485 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1486 FL("SAP event callback event = %s"), 1487 sap_hdd_event_to_string(sap_hddevent)); 1488 1489 switch (sap_hddevent) { 1490 case eSAP_STA_ASSOC_IND: 1491 if (!csr_roaminfo) { 1492 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1493 FL("Invalid CSR Roam Info")); 1494 return QDF_STATUS_E_INVAL; 1495 } 1496 /* TODO - Indicate the assoc request indication to OS */ 1497 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND; 1498 assoc_ind = &sap_ap_event.sapevt.sapAssocIndication; 1499 1500 qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac); 1501 assoc_ind->staId = csr_roaminfo->staId; 1502 assoc_ind->status = 0; 1503 /* Required for indicating the frames to upper layer */ 1504 assoc_ind->beaconLength = csr_roaminfo->beaconLength; 1505 assoc_ind->beaconPtr = csr_roaminfo->beaconPtr; 1506 assoc_ind->assocReqLength = csr_roaminfo->assocReqLength; 1507 assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr; 1508 assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta; 1509 assoc_ind->ecsa_capable = csr_roaminfo->ecsa_capable; 1510 if (csr_roaminfo->u.pConnectedProfile != NULL) { 1511 assoc_ind->negotiatedAuthType = 1512 csr_roaminfo->u.pConnectedProfile->AuthType; 1513 assoc_ind->negotiatedUCEncryptionType = 1514 csr_roaminfo->u.pConnectedProfile->EncryptionType; 1515 assoc_ind->negotiatedMCEncryptionType = 1516 csr_roaminfo->u.pConnectedProfile->mcEncryptionType; 1517 assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired; 1518 } 1519 break; 1520 case eSAP_START_BSS_EVENT: 1521 sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT; 1522 bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent; 1523 1524 bss_complete->status = (eSapStatus) context; 1525 bss_complete->staId = sap_ctx->sap_sta_id; 1526 1527 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1528 FL("(eSAP_START_BSS_EVENT): staId = %d"), 1529 bss_complete->staId); 1530 1531 bss_complete->operatingChannel = (uint8_t) sap_ctx->channel; 1532 bss_complete->ch_width = sap_ctx->ch_params.ch_width; 1533 bss_complete->sessionId = sap_ctx->sessionId; 1534 break; 1535 case eSAP_DFS_CAC_START: 1536 case eSAP_DFS_CAC_INTERRUPTED: 1537 case eSAP_DFS_CAC_END: 1538 case eSAP_DFS_PRE_CAC_END: 1539 case eSAP_DFS_RADAR_DETECT: 1540 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC: 1541 case eSAP_DFS_NO_AVAILABLE_CHANNEL: 1542 sap_ap_event.sapHddEventCode = sap_hddevent; 1543 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 1544 (eSapStatus) context; 1545 break; 1546 case eSAP_ACS_SCAN_SUCCESS_EVENT: 1547 sap_handle_acs_scan_event(sap_ctx, &sap_ap_event, 1548 (eSapStatus)context); 1549 break; 1550 case eSAP_ACS_CHANNEL_SELECTED: 1551 sap_ap_event.sapHddEventCode = sap_hddevent; 1552 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 1553 if (eSAP_STATUS_SUCCESS == (eSapStatus)context) { 1554 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 1555 acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; 1556 acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; 1557 acs_selected->vht_seg0_center_ch = 1558 sap_ctx->acs_cfg->vht_seg0_center_ch; 1559 acs_selected->vht_seg1_center_ch = 1560 sap_ctx->acs_cfg->vht_seg1_center_ch; 1561 } else if (eSAP_STATUS_FAILURE == (eSapStatus)context) { 1562 acs_selected->pri_ch = 0; 1563 } 1564 break; 1565 1566 case eSAP_STOP_BSS_EVENT: 1567 sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT; 1568 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 1569 (eSapStatus) context; 1570 break; 1571 1572 case eSAP_STA_ASSOC_EVENT: 1573 case eSAP_STA_REASSOC_EVENT: 1574 1575 if (!csr_roaminfo) { 1576 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1577 FL("Invalid CSR Roam Info")); 1578 return QDF_STATUS_E_INVAL; 1579 } 1580 if (eSAP_DISCONNECTING == sap_ctx->sapsMachine) { 1581 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1582 "SAP is disconnecting, not able to handle any incoming (re)assoc req"); 1583 return QDF_STATUS_E_ABORTED; 1584 } 1585 1586 reassoc_complete = 1587 &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent; 1588 1589 if (csr_roaminfo->fReassocReq) 1590 sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT; 1591 else 1592 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT; 1593 1594 qdf_copy_macaddr(&reassoc_complete->staMac, 1595 &csr_roaminfo->peerMac); 1596 reassoc_complete->staId = csr_roaminfo->staId; 1597 reassoc_complete->statusCode = csr_roaminfo->statusCode; 1598 reassoc_complete->iesLen = csr_roaminfo->rsnIELen; 1599 qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE, 1600 csr_roaminfo->rsnIELen); 1601 1602 #ifdef FEATURE_WLAN_WAPI 1603 if (csr_roaminfo->wapiIELen) { 1604 uint8_t len = reassoc_complete->iesLen; 1605 1606 reassoc_complete->iesLen += csr_roaminfo->wapiIELen; 1607 qdf_mem_copy(&reassoc_complete->ies[len], 1608 csr_roaminfo->pwapiIE, 1609 csr_roaminfo->wapiIELen); 1610 } 1611 #endif 1612 if (csr_roaminfo->addIELen) { 1613 uint8_t len = reassoc_complete->iesLen; 1614 1615 reassoc_complete->iesLen += csr_roaminfo->addIELen; 1616 qdf_mem_copy(&reassoc_complete->ies[len], 1617 csr_roaminfo->paddIE, 1618 csr_roaminfo->addIELen); 1619 if (wlan_get_vendor_ie_ptr_from_oui( 1620 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, 1621 csr_roaminfo->paddIE, csr_roaminfo->addIELen)) { 1622 reassoc_complete->staType = eSTA_TYPE_P2P_CLI; 1623 } else { 1624 reassoc_complete->staType = eSTA_TYPE_INFRA; 1625 } 1626 } 1627 1628 /* also fill up the channel info from the csr_roamInfo */ 1629 chaninfo = &reassoc_complete->chan_info; 1630 1631 chaninfo->chan_id = csr_roaminfo->chan_info.chan_id; 1632 chaninfo->mhz = csr_roaminfo->chan_info.mhz; 1633 chaninfo->info = csr_roaminfo->chan_info.info; 1634 chaninfo->band_center_freq1 = 1635 csr_roaminfo->chan_info.band_center_freq1; 1636 chaninfo->band_center_freq2 = 1637 csr_roaminfo->chan_info.band_center_freq2; 1638 chaninfo->reg_info_1 = 1639 csr_roaminfo->chan_info.reg_info_1; 1640 chaninfo->reg_info_2 = 1641 csr_roaminfo->chan_info.reg_info_2; 1642 chaninfo->nss = csr_roaminfo->chan_info.nss; 1643 chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags; 1644 1645 reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta; 1646 reassoc_complete->status = (eSapStatus) context; 1647 reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap; 1648 reassoc_complete->ampdu = csr_roaminfo->ampdu; 1649 reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable; 1650 reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc; 1651 reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc; 1652 reassoc_complete->ch_width = csr_roaminfo->ch_width; 1653 reassoc_complete->mode = csr_roaminfo->mode; 1654 reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx; 1655 reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx; 1656 reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx; 1657 reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map; 1658 reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map; 1659 reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable; 1660 if (csr_roaminfo->ht_caps.present) 1661 reassoc_complete->ht_caps = csr_roaminfo->ht_caps; 1662 if (csr_roaminfo->vht_caps.present) 1663 reassoc_complete->vht_caps = csr_roaminfo->vht_caps; 1664 1665 break; 1666 1667 case eSAP_STA_DISASSOC_EVENT: 1668 if (!csr_roaminfo) { 1669 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1670 FL("Invalid CSR Roam Info")); 1671 return QDF_STATUS_E_INVAL; 1672 } 1673 sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; 1674 disassoc_comp = 1675 &sap_ap_event.sapevt.sapStationDisassocCompleteEvent; 1676 1677 qdf_copy_macaddr(&disassoc_comp->staMac, 1678 &csr_roaminfo->peerMac); 1679 disassoc_comp->staId = csr_roaminfo->staId; 1680 if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED) 1681 disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC; 1682 else 1683 disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC; 1684 1685 disassoc_comp->statusCode = csr_roaminfo->statusCode; 1686 disassoc_comp->status = (eSapStatus) context; 1687 disassoc_comp->rssi = csr_roaminfo->rssi; 1688 disassoc_comp->rx_rate = csr_roaminfo->rx_rate; 1689 disassoc_comp->tx_rate = csr_roaminfo->tx_rate; 1690 disassoc_comp->reason_code = csr_roaminfo->disassoc_reason; 1691 break; 1692 1693 case eSAP_STA_SET_KEY_EVENT: 1694 1695 if (!csr_roaminfo) { 1696 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1697 FL("Invalid CSR Roam Info")); 1698 return QDF_STATUS_E_INVAL; 1699 } 1700 sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT; 1701 key_complete = 1702 &sap_ap_event.sapevt.sapStationSetKeyCompleteEvent; 1703 key_complete->status = (eSapStatus) context; 1704 qdf_copy_macaddr(&key_complete->peerMacAddr, 1705 &csr_roaminfo->peerMac); 1706 break; 1707 1708 case eSAP_STA_MIC_FAILURE_EVENT: 1709 1710 if (!csr_roaminfo) { 1711 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1712 FL("Invalid CSR Roam Info")); 1713 return QDF_STATUS_E_INVAL; 1714 } 1715 sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; 1716 mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent; 1717 1718 qdf_mem_copy(&mic_failure->srcMacAddr, 1719 csr_roaminfo->u.pMICFailureInfo->srcMacAddr, 1720 sizeof(tSirMacAddr)); 1721 qdf_mem_copy(&mic_failure->staMac.bytes, 1722 csr_roaminfo->u.pMICFailureInfo->taMacAddr, 1723 sizeof(tSirMacAddr)); 1724 qdf_mem_copy(&mic_failure->dstMacAddr.bytes, 1725 csr_roaminfo->u.pMICFailureInfo->dstMacAddr, 1726 sizeof(tSirMacAddr)); 1727 mic_failure->multicast = 1728 csr_roaminfo->u.pMICFailureInfo->multicast; 1729 mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1; 1730 mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId; 1731 qdf_mem_copy(mic_failure->TSC, 1732 csr_roaminfo->u.pMICFailureInfo->TSC, 1733 SIR_CIPHER_SEQ_CTR_SIZE); 1734 break; 1735 1736 case eSAP_ASSOC_STA_CALLBACK_EVENT: 1737 break; 1738 1739 case eSAP_WPS_PBC_PROBE_REQ_EVENT: 1740 1741 if (!csr_roaminfo) { 1742 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1743 FL("Invalid CSR Roam Info")); 1744 return QDF_STATUS_E_INVAL; 1745 } 1746 sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; 1747 1748 qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent. 1749 WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq, 1750 sizeof(tSirWPSPBCProbeReq)); 1751 break; 1752 1753 case eSAP_DISCONNECT_ALL_P2P_CLIENT: 1754 sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; 1755 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 1756 (eSapStatus) context; 1757 break; 1758 1759 case eSAP_MAC_TRIG_STOP_BSS_EVENT: 1760 sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; 1761 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 1762 (eSapStatus) context; 1763 break; 1764 1765 case eSAP_UNKNOWN_STA_JOIN: 1766 sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; 1767 qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin. 1768 macaddr.bytes, (void *) context, 1769 QDF_MAC_ADDR_SIZE); 1770 break; 1771 1772 case eSAP_MAX_ASSOC_EXCEEDED: 1773 1774 if (!csr_roaminfo) { 1775 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1776 FL("Invalid CSR Roam Info")); 1777 return QDF_STATUS_E_INVAL; 1778 } 1779 sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; 1780 qdf_copy_macaddr(&sap_ap_event.sapevt. 1781 sapMaxAssocExceeded.macaddr, 1782 &csr_roaminfo->peerMac); 1783 break; 1784 1785 case eSAP_CHANNEL_CHANGE_EVENT: 1786 /* 1787 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS 1788 * follows pri AP 1789 */ 1790 sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; 1791 sap_ctx->acs_cfg->ch_width = 1792 sap_ctx->csr_roamProfile.ch_params.ch_width; 1793 sap_config_acs_result(hal, sap_ctx, sap_ctx->secondary_ch); 1794 1795 sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; 1796 1797 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 1798 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 1799 acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; 1800 acs_selected->ch_width = 1801 sap_ctx->csr_roamProfile.ch_params.ch_width; 1802 acs_selected->vht_seg0_center_ch = 1803 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; 1804 acs_selected->vht_seg1_center_ch = 1805 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; 1806 break; 1807 1808 case eSAP_ECSA_CHANGE_CHAN_IND: 1809 1810 if (!csr_roaminfo) { 1811 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1812 FL("Invalid CSR Roam Info")); 1813 return QDF_STATUS_E_INVAL; 1814 } 1815 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1816 "In %s, SAP event callback event = %s", 1817 __func__, "eSAP_ECSA_CHANGE_CHAN_IND"); 1818 sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND; 1819 sap_ap_event.sapevt.sap_chan_cng_ind.new_chan = 1820 csr_roaminfo->target_channel; 1821 break; 1822 case eSAP_DFS_NEXT_CHANNEL_REQ: 1823 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1824 "In %s, SAP event callback event = %s", 1825 __func__, "eSAP_DFS_NEXT_CHANNEL_REQ"); 1826 sap_ap_event.sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ; 1827 break; 1828 case eSAP_STOP_BSS_DUE_TO_NO_CHNL: 1829 sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL; 1830 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1831 FL("stopping session_id:%d, bssid:%pM, channel:%d"), 1832 sap_ctx->sessionId, sap_ctx->self_mac_addr, 1833 sap_ctx->channel); 1834 break; 1835 default: 1836 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1837 FL("SAP Unknown callback event = %d"), 1838 sap_hddevent); 1839 break; 1840 } 1841 qdf_status = (*sap_ctx->pfnSapEventCallback) 1842 (&sap_ap_event, sap_ctx->pUsrContext); 1843 1844 return qdf_status; 1845 1846 } 1847 1848 /** 1849 * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state 1850 * @handle: Global MAC handle 1851 * 1852 * Finds and gets the context of a SAP session in CAC wait state. 1853 * 1854 * Return: Valid SAP context on success, else NULL 1855 */ 1856 static struct sap_context *sap_find_cac_wait_session(tHalHandle handle) 1857 { 1858 tpAniSirGlobal mac = PMAC_STRUCT(handle); 1859 uint8_t i = 0; 1860 struct sap_context *sapContext; 1861 1862 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1863 "%s", __func__); 1864 1865 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 1866 sapContext = mac->sap.sapCtxList[i].sap_context; 1867 if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona) 1868 || 1869 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) && 1870 (sapContext) && 1871 (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) { 1872 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1873 "%s: found SAP in cac wait state", __func__); 1874 return sapContext; 1875 } 1876 if (sapContext) { 1877 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1878 "sapdfs: mode:%d intf:%d state:%d", 1879 mac->sap.sapCtxList[i].sapPersona, i, 1880 sapContext->sapsMachine); 1881 } 1882 } 1883 1884 return NULL; 1885 } 1886 1887 /*========================================================================== 1888 FUNCTION sap_cac_reset_notify 1889 1890 DESCRIPTION Function will be called up on stop bss indication to clean up 1891 DFS global structure. 1892 1893 DEPENDENCIES PARAMETERS 1894 IN hHAL : HAL pointer 1895 1896 RETURN VALUE : void. 1897 1898 SIDE EFFECTS 1899 ============================================================================*/ 1900 void sap_cac_reset_notify(tHalHandle hHal) 1901 { 1902 uint8_t intf = 0; 1903 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1904 1905 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1906 struct sap_context *sap_context = 1907 pMac->sap.sapCtxList[intf].sap_context; 1908 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 1909 || 1910 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 1911 && pMac->sap.sapCtxList[intf].sap_context != NULL) { 1912 sap_context->isCacStartNotified = false; 1913 sap_context->isCacEndNotified = false; 1914 } 1915 } 1916 } 1917 1918 /*========================================================================== 1919 FUNCTION sap_cac_start_notify 1920 1921 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event 1922 to HDD 1923 1924 DEPENDENCIES PARAMETERS 1925 IN hHAL : HAL pointer 1926 1927 RETURN VALUE : QDF_STATUS. 1928 1929 SIDE EFFECTS 1930 ============================================================================*/ 1931 static QDF_STATUS sap_cac_start_notify(tHalHandle hHal) 1932 { 1933 uint8_t intf = 0; 1934 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1935 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1936 1937 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1938 struct sap_context *sap_context = 1939 pMac->sap.sapCtxList[intf].sap_context; 1940 struct csr_roam_profile *profile; 1941 1942 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 1943 || 1944 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 1945 && pMac->sap.sapCtxList[intf].sap_context != NULL && 1946 (false == sap_context->isCacStartNotified)) { 1947 /* Don't start CAC for non-dfs channel, its violation */ 1948 profile = &sap_context->csr_roamProfile; 1949 if (!wlan_reg_is_dfs_ch(pMac->pdev, 1950 profile->operationChannel)) 1951 continue; 1952 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1953 "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]", 1954 sap_context); 1955 1956 qdf_status = sap_signal_hdd_event(sap_context, NULL, 1957 eSAP_DFS_CAC_START, 1958 (void *) 1959 eSAP_STATUS_SUCCESS); 1960 if (QDF_STATUS_SUCCESS != qdf_status) { 1961 QDF_TRACE(QDF_MODULE_ID_SAP, 1962 QDF_TRACE_LEVEL_ERROR, 1963 "In %s, failed setting isCacStartNotified on interface[%d]", 1964 __func__, intf); 1965 return qdf_status; 1966 } 1967 sap_context->isCacStartNotified = true; 1968 } 1969 } 1970 return qdf_status; 1971 } 1972 1973 /** 1974 * wlansap_update_pre_cac_end() - Update pre cac end to upper layer 1975 * @sap_context: SAP context 1976 * @mac: Global MAC structure 1977 * @intf: Interface number 1978 * 1979 * Notifies pre cac end to upper layer 1980 * 1981 * Return: QDF_STATUS 1982 */ 1983 static QDF_STATUS wlansap_update_pre_cac_end(struct sap_context *sap_context, 1984 tpAniSirGlobal mac, uint8_t intf) 1985 { 1986 QDF_STATUS qdf_status; 1987 1988 sap_context->isCacEndNotified = true; 1989 mac->sap.SapDfsInfo.sap_radar_found_status = false; 1990 sap_context->sapsMachine = eSAP_STARTED; 1991 1992 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1993 "In %s, pre cac end notify on %d: from state %s => %s", 1994 __func__, intf, "eSAP_DFS_CAC_WAIT", 1995 "eSAP_STARTED"); 1996 1997 qdf_status = sap_signal_hdd_event(sap_context, 1998 NULL, eSAP_DFS_PRE_CAC_END, 1999 (void *)eSAP_STATUS_SUCCESS); 2000 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2001 QDF_TRACE(QDF_MODULE_ID_SAP, 2002 QDF_TRACE_LEVEL_ERROR, 2003 "In %s, pre cac notify failed on intf %d", 2004 __func__, intf); 2005 return qdf_status; 2006 } 2007 2008 return QDF_STATUS_SUCCESS; 2009 } 2010 2011 /*========================================================================== 2012 FUNCTION sap_cac_end_notify 2013 2014 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event 2015 to HDD 2016 2017 DEPENDENCIES PARAMETERS 2018 IN hHAL : HAL pointer 2019 2020 RETURN VALUE : QDF_STATUS. 2021 2022 SIDE EFFECTS 2023 ============================================================================*/ 2024 static QDF_STATUS sap_cac_end_notify(tHalHandle hHal, 2025 struct csr_roam_info *roamInfo) 2026 { 2027 uint8_t intf; 2028 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2029 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2030 2031 /* 2032 * eSAP_DFS_CHANNEL_CAC_END: 2033 * CAC Period elapsed and there was no radar 2034 * found so, SAP can continue beaconing. 2035 * sap_radar_found_status is set to 0 2036 */ 2037 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2038 struct sap_context *sap_context = 2039 pMac->sap.sapCtxList[intf].sap_context; 2040 struct csr_roam_profile *profile; 2041 2042 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 2043 || 2044 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 2045 && pMac->sap.sapCtxList[intf].sap_context != NULL && 2046 (false == sap_context->isCacEndNotified) && 2047 (sap_context->sapsMachine == eSAP_DFS_CAC_WAIT)) { 2048 sap_context = pMac->sap.sapCtxList[intf].sap_context; 2049 /* Don't check CAC for non-dfs channel */ 2050 profile = &sap_context->csr_roamProfile; 2051 if (!wlan_reg_is_dfs_ch(pMac->pdev, 2052 profile->operationChannel)) 2053 continue; 2054 2055 /* If this is an end notification of a pre cac, the 2056 * SAP must not start beaconing and must delete the 2057 * temporary interface created for pre cac and switch 2058 * the original SAP to the pre CAC channel. 2059 */ 2060 if (sap_context->is_pre_cac_on) { 2061 qdf_status = wlansap_update_pre_cac_end( 2062 sap_context, pMac, intf); 2063 if (QDF_IS_STATUS_ERROR(qdf_status)) 2064 return qdf_status; 2065 /* pre CAC is not allowed with any concurrency. 2066 * So, we can break from here. 2067 */ 2068 break; 2069 } 2070 2071 qdf_status = sap_signal_hdd_event(sap_context, NULL, 2072 eSAP_DFS_CAC_END, 2073 (void *) 2074 eSAP_STATUS_SUCCESS); 2075 if (QDF_STATUS_SUCCESS != qdf_status) { 2076 QDF_TRACE(QDF_MODULE_ID_SAP, 2077 QDF_TRACE_LEVEL_ERROR, 2078 "In %s, failed setting isCacEndNotified on interface[%d]", 2079 __func__, intf); 2080 return qdf_status; 2081 } 2082 sap_context->isCacEndNotified = true; 2083 pMac->sap.SapDfsInfo.sap_radar_found_status = false; 2084 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2085 "sapdfs: Start beacon request on sapctx[%pK]", 2086 sap_context); 2087 2088 /* Start beaconing on the new channel */ 2089 wlansap_start_beacon_req(sap_context); 2090 2091 /* Transition from eSAP_STARTING to eSAP_STARTED 2092 * (both without substates) 2093 */ 2094 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2095 "sapdfs: channel[%d] from state %s => %s", 2096 sap_context->channel, "eSAP_STARTING", 2097 "eSAP_STARTED"); 2098 2099 sap_context->sapsMachine = eSAP_STARTED; 2100 2101 /*Action code for transition */ 2102 qdf_status = sap_signal_hdd_event(sap_context, roamInfo, 2103 eSAP_START_BSS_EVENT, 2104 (void *) 2105 eSAP_STATUS_SUCCESS); 2106 if (QDF_STATUS_SUCCESS != qdf_status) { 2107 QDF_TRACE(QDF_MODULE_ID_SAP, 2108 QDF_TRACE_LEVEL_ERROR, 2109 "In %s, failed setting isCacEndNotified on interface[%d]", 2110 __func__, intf); 2111 return qdf_status; 2112 } 2113 2114 /* Transition from eSAP_STARTING to eSAP_STARTED 2115 * (both without substates) 2116 */ 2117 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2118 "In %s, from state %s => %s", 2119 __func__, "eSAP_DFS_CAC_WAIT", 2120 "eSAP_STARTED"); 2121 } 2122 } 2123 /* 2124 * All APs are done with CAC timer, all APs should start beaconing. 2125 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets 2126 * say AP1 goes down and comes back on same DFS channel. In this case 2127 * AP1 shouldn't start CAC timer and start beacon immediately beacause 2128 * AP2 is already beaconing on this channel. This case will be handled 2129 * by checking against eSAP_DFS_SKIP_CAC while starting the timer. 2130 */ 2131 pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC; 2132 return qdf_status; 2133 } 2134 2135 /** 2136 * sap_fsm_state_disconnected() - utility function called from sap fsm 2137 * @sap_ctx: SAP context 2138 * @sap_event: SAP event buffer 2139 * @mac_ctx: global MAC context 2140 * @hal: HAL handle 2141 * 2142 * This function is called for state transition from "eSAP_DISCONNECTED" 2143 * 2144 * Return: QDF_STATUS 2145 */ 2146 static QDF_STATUS sap_fsm_state_disconnected(struct sap_context *sap_ctx, 2147 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2148 tHalHandle hal) 2149 { 2150 uint32_t msg = sap_event->event; 2151 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2152 2153 if (msg == eSAP_HDD_START_INFRA_BSS) { 2154 /* 2155 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT 2156 * (both without substates) 2157 */ 2158 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2159 FL("new from state %s => %s: session:%d"), 2160 "eSAP_DISCONNECTED", "eSAP_CH_SELECT", 2161 sap_ctx->sessionId); 2162 2163 /* init dfs channel nol */ 2164 sap_init_dfs_channel_nol_list(sap_ctx); 2165 2166 /* Set SAP device role */ 2167 sap_ctx->sapsMachine = eSAP_CH_SELECT; 2168 2169 /* 2170 * Perform sme_ScanRequest. This scan request is post start bss 2171 * request so, set the third to false. 2172 */ 2173 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 2174 true); 2175 } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { 2176 /* 2177 * No need of state check here, caller is expected to perform 2178 * the checks before sending the event 2179 */ 2180 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 2181 2182 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2183 FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT")); 2184 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) { 2185 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2186 FL("sapdfs: starting dfs cac timer on sapctx[%pK]"), 2187 sap_ctx); 2188 sap_start_dfs_cac_timer(sap_ctx); 2189 } 2190 2191 qdf_status = sap_cac_start_notify(hal); 2192 } else if (msg == eSAP_CHANNEL_SELECTION_RETRY) { 2193 /* Set SAP device role */ 2194 sap_ctx->sapsMachine = eSAP_CH_SELECT; 2195 2196 /* 2197 * Perform sme_ScanRequest. This scan request is post start bss 2198 * request so, set the third to false. 2199 */ 2200 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 2201 false); 2202 } else { 2203 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2204 FL("in state %s, event msg %d"), 2205 "eSAP_DISCONNECTED", msg); 2206 } 2207 2208 return qdf_status; 2209 } 2210 2211 /** 2212 * sap_fsm_state_ch_select() - utility function called from sap fsm 2213 * @sap_ctx: SAP context 2214 * @sap_event: SAP event buffer 2215 * @mac_ctx: global MAC context 2216 * @hal: HAL handle 2217 * 2218 * This function is called for state transition from "eSAP_CH_SELECT" 2219 * 2220 * Return: QDF_STATUS 2221 */ 2222 static QDF_STATUS sap_fsm_state_ch_select(struct sap_context *sap_ctx, 2223 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2224 tHalHandle hal) 2225 { 2226 uint32_t msg = sap_event->event; 2227 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2228 bool b_leak_chan = false; 2229 uint8_t temp_chan; 2230 2231 if (msg == eSAP_MAC_SCAN_COMPLETE) { 2232 temp_chan = sap_ctx->channel; 2233 utils_dfs_mark_leaking_ch(mac_ctx->pdev, 2234 sap_ctx->ch_params.ch_width, 2235 1, &temp_chan); 2236 2237 /* 2238 * if selelcted channel has leakage to channels 2239 * in NOL, the temp_chan will be reset 2240 */ 2241 b_leak_chan = (temp_chan != sap_ctx->channel); 2242 /* 2243 * check if channel is in DFS_NOL or if the channel 2244 * has leakage to the channels in NOL 2245 */ 2246 if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel, 2247 PHY_CHANNEL_BONDING_STATE_MAX) || b_leak_chan) { 2248 uint8_t ch; 2249 2250 /* find a new available channel */ 2251 ch = sap_random_channel_sel(sap_ctx); 2252 if (ch == 0) { 2253 /* No available channel found */ 2254 QDF_TRACE(QDF_MODULE_ID_SAP, 2255 QDF_TRACE_LEVEL_ERROR, 2256 FL("No available channel found!!!")); 2257 sap_signal_hdd_event(sap_ctx, NULL, 2258 eSAP_DFS_NO_AVAILABLE_CHANNEL, 2259 (void *)eSAP_STATUS_SUCCESS); 2260 return QDF_STATUS_E_FAULT; 2261 } 2262 2263 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2264 FL("channel %d is in NOL, StartBss on new channel %d"), 2265 sap_ctx->channel, ch); 2266 2267 sap_ctx->channel = ch; 2268 wlan_reg_set_channel_params(mac_ctx->pdev, 2269 sap_ctx->channel, 2270 sap_ctx->secondary_ch, 2271 &sap_ctx->ch_params); 2272 } 2273 if (sap_ctx->channel > 14 && 2274 (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g || 2275 sap_ctx->csr_roamProfile.phyMode == 2276 eCSR_DOT11_MODE_11g_ONLY)) 2277 sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a; 2278 2279 /* 2280 * when AP2 is started while AP1 is performing ACS, we may not 2281 * have the AP1 channel yet.So here after the completion of AP2 2282 * ACS check if AP1 ACS resulting channel is DFS and if yes 2283 * override AP2 ACS scan result with AP1 DFS channel 2284 */ 2285 if (policy_mgr_concurrent_beaconing_sessions_running( 2286 mac_ctx->psoc)) { 2287 uint16_t con_ch; 2288 2289 con_ch = sme_get_concurrent_operation_channel(hal); 2290 if (con_ch && wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch)) 2291 sap_ctx->channel = con_ch; 2292 } 2293 2294 /* 2295 * Transition from eSAP_CH_SELECT to eSAP_STARTING 2296 * (both without substates) 2297 */ 2298 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2299 FL("from state %s => %s"), 2300 "eSAP_CH_SELECT", "eSAP_STARTING"); 2301 /* Channel selected. Now can sap_goto_starting */ 2302 sap_ctx->sapsMachine = eSAP_STARTING; 2303 /* Specify the channel */ 2304 sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels = 2305 1; 2306 sap_ctx->csr_roamProfile.ChannelInfo.ChannelList = 2307 &sap_ctx->csr_roamProfile.operationChannel; 2308 sap_ctx->csr_roamProfile.operationChannel = 2309 (uint8_t) sap_ctx->channel; 2310 sap_ctx->csr_roamProfile.ch_params.ch_width = 2311 sap_ctx->ch_params.ch_width; 2312 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 = 2313 sap_ctx->ch_params.center_freq_seg0; 2314 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 = 2315 sap_ctx->ch_params.center_freq_seg1; 2316 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset = 2317 sap_ctx->ch_params.sec_ch_offset; 2318 sap_get_cac_dur_dfs_region(sap_ctx, 2319 &sap_ctx->csr_roamProfile.cac_duration_ms, 2320 &sap_ctx->csr_roamProfile.dfs_regdomain); 2321 sap_ctx->csr_roamProfile.beacon_tx_rate = 2322 sap_ctx->beacon_tx_rate; 2323 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2324 FL("notify hostapd about channel selection: %d"), 2325 sap_ctx->channel); 2326 sap_signal_hdd_event(sap_ctx, NULL, 2327 eSAP_CHANNEL_CHANGE_EVENT, 2328 (void *) eSAP_STATUS_SUCCESS); 2329 sap_dfs_set_current_channel(sap_ctx); 2330 qdf_status = sap_goto_starting(sap_ctx, sap_event, 2331 eCSR_BSS_TYPE_INFRA_AP); 2332 } else if (msg == eSAP_CHANNEL_SELECTION_FAILED) { 2333 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2334 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2335 FL("Cannot start BSS, ACS Fail")); 2336 sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT, 2337 (void *)eSAP_STATUS_FAILURE); 2338 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 2339 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2340 sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT, 2341 (void *)eSAP_STATUS_FAILURE); 2342 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2343 "%s: BSS stopped when Ch select in Progress", __func__); 2344 } else { 2345 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2346 FL("in state %s, invalid event msg %d"), 2347 "eSAP_CH_SELECT", msg); 2348 } 2349 2350 return qdf_status; 2351 } 2352 2353 /** 2354 * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm 2355 * @sap_ctx: SAP context 2356 * @sap_event: SAP event buffer 2357 * @mac_ctx: global MAC context 2358 * @hal: HAL handle 2359 * 2360 * This function is called for state transition from "eSAP_DFS_CAC_WAIT" 2361 * 2362 * Return: QDF_STATUS 2363 */ 2364 static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx, 2365 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2366 tHalHandle hal) 2367 { 2368 uint32_t msg = sap_event->event; 2369 struct csr_roam_info *roam_info = 2370 (struct csr_roam_info *) (sap_event->params); 2371 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2372 2373 if (msg == eSAP_DFS_CHANNEL_CAC_START) { 2374 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2375 FL("from state %s => %s"), 2376 "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT"); 2377 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) 2378 sap_start_dfs_cac_timer(sap_ctx); 2379 qdf_status = sap_cac_start_notify(hal); 2380 } else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) { 2381 uint8_t intf; 2382 /* 2383 * Radar found while performing channel availability 2384 * check, need to switch the channel again 2385 */ 2386 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2387 "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n"); 2388 if (mac_ctx->sap.SapDfsInfo.target_channel) { 2389 wlan_reg_set_channel_params(mac_ctx->pdev, 2390 mac_ctx->sap.SapDfsInfo.target_channel, 0, 2391 &sap_ctx->ch_params); 2392 } else { 2393 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2394 FL("Invalid target channel %d"), 2395 mac_ctx->sap.SapDfsInfo.target_channel); 2396 return qdf_status; 2397 } 2398 2399 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2400 struct sap_context *t_sap_ctx; 2401 struct csr_roam_profile *profile; 2402 2403 t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context; 2404 if (((QDF_SAP_MODE == 2405 mac_ctx->sap.sapCtxList[intf].sapPersona) || 2406 (QDF_P2P_GO_MODE == 2407 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 2408 t_sap_ctx != NULL && 2409 t_sap_ctx->sapsMachine != eSAP_DISCONNECTED) { 2410 profile = &t_sap_ctx->csr_roamProfile; 2411 if (!wlan_reg_is_passive_or_disable_ch( 2412 mac_ctx->pdev, 2413 profile->operationChannel)) 2414 continue; 2415 /* SAP to be moved to DISCONNECTING state */ 2416 t_sap_ctx->sapsMachine = eSAP_DISCONNECTING; 2417 /* 2418 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: 2419 * A Radar is found on current DFS Channel 2420 * while in CAC WAIT period So, do a channel 2421 * switch to randomly selected target channel. 2422 * Send the Channel change message to SME/PE. 2423 * sap_radar_found_status is set to 1 2424 */ 2425 wlansap_channel_change_request( 2426 t_sap_ctx, 2427 mac_ctx->sap.SapDfsInfo.target_channel); 2428 } 2429 } 2430 } else if (msg == eSAP_DFS_CHANNEL_CAC_END) { 2431 qdf_status = sap_cac_end_notify(hal, roam_info); 2432 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 2433 /* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */ 2434 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2435 FL("from state %s => %s"), 2436 "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING"); 2437 2438 /* 2439 * Stop the CAC timer only in following conditions 2440 * single AP: if there is a single AP then stop the timer 2441 * mulitple APs: incase of multiple APs, make sure that 2442 * all APs are down. 2443 */ 2444 if (NULL == sap_find_valid_concurrent_session(hal)) { 2445 QDF_TRACE(QDF_MODULE_ID_SAP, 2446 QDF_TRACE_LEVEL_INFO_MED, 2447 FL("sapdfs: no sessions are valid, stopping timer")); 2448 sap_stop_dfs_cac_timer(sap_ctx); 2449 } 2450 2451 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 2452 qdf_status = sap_goto_disconnecting(sap_ctx); 2453 } else { 2454 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2455 FL("in state %s, invalid event msg %d"), 2456 "eSAP_DFS_CAC_WAIT", msg); 2457 } 2458 2459 return qdf_status; 2460 } 2461 2462 /** 2463 * sap_fsm_state_starting() - utility function called from sap fsm 2464 * @sap_ctx: SAP context 2465 * @sap_event: SAP event buffer 2466 * @mac_ctx: global MAC context 2467 * @hal: HAL handle 2468 * 2469 * This function is called for state transition from "eSAP_STARTING" 2470 * 2471 * Return: QDF_STATUS 2472 */ 2473 static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, 2474 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2475 tHalHandle hal) 2476 { 2477 uint32_t msg = sap_event->event; 2478 struct csr_roam_info *roam_info = 2479 (struct csr_roam_info *) (sap_event->params); 2480 tSapDfsInfo *sap_dfs_info; 2481 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2482 uint8_t is_dfs = false; 2483 2484 if (msg == eSAP_MAC_START_BSS_SUCCESS) { 2485 /* 2486 * Transition from eSAP_STARTING to eSAP_STARTED 2487 * (both without substates) 2488 */ 2489 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2490 FL("from state channel = %d %s => %s ch_width %d"), 2491 sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED", 2492 sap_ctx->ch_params.ch_width); 2493 sap_ctx->sapsMachine = eSAP_STARTED; 2494 2495 /* Action code for transition */ 2496 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 2497 eSAP_START_BSS_EVENT, 2498 (void *) eSAP_STATUS_SUCCESS); 2499 2500 /* 2501 * The upper layers have been informed that AP is up and 2502 * running, however, the AP is still not beaconing, until 2503 * CAC is done if the operating channel is DFS 2504 */ 2505 if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { 2506 is_dfs = true; 2507 } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { 2508 if (wlan_reg_get_channel_state(mac_ctx->pdev, 2509 sap_ctx->channel) == 2510 CHANNEL_STATE_DFS || 2511 wlan_reg_get_channel_state(mac_ctx->pdev, 2512 sap_ctx->ch_params.center_freq_seg1 - 2513 SIR_80MHZ_START_CENTER_CH_DIFF) == 2514 CHANNEL_STATE_DFS) 2515 is_dfs = true; 2516 } else { 2517 if (wlan_reg_get_channel_state(mac_ctx->pdev, 2518 sap_ctx->channel) == 2519 CHANNEL_STATE_DFS) 2520 is_dfs = true; 2521 } 2522 2523 if (is_dfs) { 2524 sap_dfs_info = &mac_ctx->sap.SapDfsInfo; 2525 if ((false == sap_dfs_info->ignore_cac) && 2526 (eSAP_DFS_DO_NOT_SKIP_CAC == 2527 sap_dfs_info->cac_state) && 2528 !sap_ctx->pre_cac_complete) { 2529 /* Move the device in CAC_WAIT_STATE */ 2530 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 2531 2532 /* 2533 * Need to stop the OS transmit queues, 2534 * so that no traffic can flow down the stack 2535 */ 2536 2537 /* Start CAC wait timer */ 2538 if (sap_dfs_info->is_dfs_cac_timer_running != 2539 true) 2540 sap_start_dfs_cac_timer(sap_ctx); 2541 qdf_status = sap_cac_start_notify(hal); 2542 2543 } else { 2544 wlansap_start_beacon_req(sap_ctx); 2545 } 2546 } 2547 } else if (msg == eSAP_MAC_START_FAILS || 2548 msg == eSAP_HDD_STOP_INFRA_BSS) { 2549 /* 2550 * Transition from eSAP_STARTING to eSAP_DISCONNECTED 2551 * (both without substates) 2552 */ 2553 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2554 FL("from state %s => %s"), 2555 "eSAP_STARTING", "eSAP_DISCONNECTED"); 2556 2557 /* Advance outer statevar */ 2558 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2559 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 2560 eSAP_START_BSS_EVENT, 2561 (void *) eSAP_STATUS_FAILURE); 2562 qdf_status = sap_goto_disconnected(sap_ctx); 2563 /* Close the SME session */ 2564 } else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) { 2565 /* The operating channel has changed, update hostapd */ 2566 sap_ctx->channel = 2567 (uint8_t) mac_ctx->sap.SapDfsInfo.target_channel; 2568 2569 sap_ctx->sapsMachine = eSAP_STARTED; 2570 2571 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2572 FL("from state %s => %s"), 2573 "eSAP_STARTING", "eSAP_STARTED"); 2574 2575 /* Indicate change in the state to upper layers */ 2576 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 2577 eSAP_START_BSS_EVENT, 2578 (void *)eSAP_STATUS_SUCCESS); 2579 } else { 2580 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2581 FL("in state %s, invalid event msg %d"), 2582 "eSAP_STARTING", msg); 2583 } 2584 2585 return qdf_status; 2586 } 2587 2588 /** 2589 * sap_fsm_state_started() - utility function called from sap fsm 2590 * @sap_ctx: SAP context 2591 * @sap_event: SAP event buffer 2592 * @mac_ctx: global MAC context 2593 * 2594 * This function is called for state transition from "eSAP_STARTED" 2595 * 2596 * Return: QDF_STATUS 2597 */ 2598 static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, 2599 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx) 2600 { 2601 uint32_t msg = sap_event->event; 2602 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2603 2604 if (msg == eSAP_HDD_STOP_INFRA_BSS) { 2605 /* 2606 * Transition from eSAP_STARTED to eSAP_DISCONNECTING 2607 * (both without substates) 2608 */ 2609 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2610 FL("from state %s => %s"), 2611 "eSAP_STARTED", "eSAP_DISCONNECTING"); 2612 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 2613 qdf_status = sap_goto_disconnecting(sap_ctx); 2614 } else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) { 2615 uint8_t intf; 2616 if (!mac_ctx->sap.SapDfsInfo.target_channel) { 2617 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2618 FL("Invalid target channel %d"), 2619 mac_ctx->sap.SapDfsInfo.target_channel); 2620 return qdf_status; 2621 } 2622 2623 /* 2624 * Radar is seen on the current operating channel 2625 * send CSA IE for all associated stations 2626 * Request for CSA IE transmission 2627 */ 2628 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2629 struct sap_context *temp_sap_ctx; 2630 struct csr_roam_profile *profile; 2631 2632 if (((QDF_SAP_MODE == 2633 mac_ctx->sap.sapCtxList[intf].sapPersona) || 2634 (QDF_P2P_GO_MODE == 2635 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 2636 mac_ctx->sap.sapCtxList[intf].sap_context != NULL) { 2637 temp_sap_ctx = 2638 mac_ctx->sap.sapCtxList[intf].sap_context; 2639 /* 2640 * Radar won't come on non-dfs channel, so 2641 * no need to move them 2642 */ 2643 profile = &temp_sap_ctx->csr_roamProfile; 2644 if (!wlan_reg_is_passive_or_disable_ch( 2645 mac_ctx->pdev, 2646 profile->operationChannel)) 2647 continue; 2648 QDF_TRACE(QDF_MODULE_ID_SAP, 2649 QDF_TRACE_LEVEL_INFO_MED, 2650 FL("sapdfs: Sending CSAIE for sapctx[%pK]"), 2651 temp_sap_ctx); 2652 2653 qdf_status = 2654 wlansap_dfs_send_csa_ie_request(temp_sap_ctx); 2655 } 2656 } 2657 } else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) { 2658 enum QDF_OPMODE persona; 2659 2660 if (!sap_ctx) { 2661 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2662 FL("Invalid sap_ctx")); 2663 return qdf_status; 2664 } 2665 2666 persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId]. 2667 sapPersona; 2668 2669 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2670 FL("app trigger chan switch: mode:%d vdev:%d"), 2671 persona, sap_ctx->sessionId); 2672 2673 if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona)) 2674 qdf_status = wlansap_dfs_send_csa_ie_request(sap_ctx); 2675 } else { 2676 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2677 FL("in state %s, invalid event msg %d"), 2678 "eSAP_STARTED", msg); 2679 } 2680 2681 return qdf_status; 2682 } 2683 2684 /** 2685 * sap_fsm_state_disconnecting() - utility function called from sap fsm 2686 * @sap_ctx: SAP context 2687 * @sap_event: SAP event buffer 2688 * @mac_ctx: global MAC context 2689 * 2690 * This function is called for state transition from "eSAP_DISCONNECTING" 2691 * 2692 * Return: QDF_STATUS 2693 */ 2694 static QDF_STATUS sap_fsm_state_disconnecting(struct sap_context *sap_ctx, 2695 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2696 tHalHandle hal) 2697 { 2698 uint32_t msg = sap_event->event; 2699 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2700 2701 if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) { 2702 /* 2703 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED 2704 * (both without substates) 2705 */ 2706 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2707 FL("from state %s => %s"), 2708 "eSAP_DISCONNECTING", "eSAP_DISCONNECTED"); 2709 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2710 2711 /* Close the SME session */ 2712 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 2713 eSAP_STOP_BSS_EVENT, 2714 (void *)eSAP_STATUS_SUCCESS); 2715 } else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) { 2716 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2717 FL("sapdfs: Send channel change request on sapctx[%pK]"), 2718 sap_ctx); 2719 2720 sap_get_cac_dur_dfs_region(sap_ctx, 2721 &sap_ctx->csr_roamProfile.cac_duration_ms, 2722 &sap_ctx->csr_roamProfile.dfs_regdomain); 2723 /* 2724 * Most likely, radar has been detected and SAP wants to 2725 * change the channel 2726 */ 2727 qdf_status = wlansap_channel_change_request(sap_ctx, 2728 mac_ctx->sap.SapDfsInfo.target_channel); 2729 2730 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2731 FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ")); 2732 } else if (msg == eWNI_SME_CHANNEL_CHANGE_RSP) { 2733 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2734 FL("in state %s, event msg %d result %d"), 2735 "eSAP_DISCONNECTING ", msg, sap_event->u2); 2736 if (sap_event->u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE) 2737 qdf_status = sap_goto_disconnecting(sap_ctx); 2738 } else if ((msg == eSAP_HDD_STOP_INFRA_BSS) && 2739 (sap_ctx->is_chan_change_inprogress)) { 2740 /* stop bss is received while processing channel change */ 2741 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2742 FL("in state %s, event msg %d result %d"), 2743 "eSAP_DISCONNECTING ", msg, sap_event->u2); 2744 qdf_status = sap_goto_disconnecting(sap_ctx); 2745 } else { 2746 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2747 FL("in state %s, invalid event msg %d"), 2748 "eSAP_DISCONNECTING", msg); 2749 } 2750 2751 return qdf_status; 2752 } 2753 2754 /** 2755 * sap_fsm() - SAP statem machine entry function 2756 * @sap_ctx: SAP context 2757 * @sap_event: SAP event 2758 * 2759 * SAP statem machine entry function 2760 * 2761 * Return: QDF_STATUS 2762 */ 2763 QDF_STATUS sap_fsm(struct sap_context *sap_ctx, ptWLAN_SAPEvent sap_event) 2764 { 2765 /* 2766 * Retrieve the phy link state machine structure 2767 * from the sap_ctx value 2768 * state var that keeps track of state machine 2769 */ 2770 eSapFsmStates_t state_var = sap_ctx->sapsMachine; 2771 uint32_t msg = sap_event->event; /* State machine input event message */ 2772 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2773 tHalHandle hal = CDS_GET_HAL_CB(); 2774 tpAniSirGlobal mac_ctx; 2775 2776 if (NULL == hal) { 2777 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2778 FL("Invalid hal")); 2779 return QDF_STATUS_E_FAILURE; 2780 } 2781 2782 mac_ctx = PMAC_STRUCT(hal); 2783 if (NULL == mac_ctx) { 2784 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2785 FL("Invalid MAC context")); 2786 return QDF_STATUS_E_FAILURE; 2787 } 2788 2789 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 2790 FL("sap_ctx=%pK, state_var=%d, msg=0x%x"), 2791 sap_ctx, state_var, msg); 2792 2793 switch (state_var) { 2794 case eSAP_DISCONNECTED: 2795 qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event, 2796 mac_ctx, hal); 2797 break; 2798 2799 case eSAP_CH_SELECT: 2800 qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event, 2801 mac_ctx, hal); 2802 break; 2803 2804 case eSAP_DFS_CAC_WAIT: 2805 qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event, 2806 mac_ctx, hal); 2807 break; 2808 2809 case eSAP_STARTING: 2810 qdf_status = sap_fsm_state_starting(sap_ctx, sap_event, 2811 mac_ctx, hal); 2812 break; 2813 2814 case eSAP_STARTED: 2815 qdf_status = sap_fsm_state_started(sap_ctx, sap_event, 2816 mac_ctx); 2817 break; 2818 2819 case eSAP_DISCONNECTING: 2820 qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event, 2821 mac_ctx, hal); 2822 break; 2823 } 2824 return qdf_status; 2825 } 2826 2827 eSapStatus 2828 sapconvert_to_csr_profile(tsap_config_t *pconfig_params, eCsrRoamBssType bssType, 2829 struct csr_roam_profile *profile) 2830 { 2831 /* Create Roam profile for SoftAP to connect */ 2832 profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; 2833 profile->SSIDs.numOfSSIDs = 1; 2834 profile->csrPersona = pconfig_params->persona; 2835 profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch; 2836 2837 qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, 2838 sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); 2839 2840 /* Flag to not broadcast the SSID information */ 2841 profile->SSIDs.SSIDList[0].ssidHidden = 2842 pconfig_params->SSIDinfo.ssidHidden; 2843 2844 profile->SSIDs.SSIDList[0].SSID.length = 2845 pconfig_params->SSIDinfo.ssid.length; 2846 qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, 2847 pconfig_params->SSIDinfo.ssid.ssId, 2848 sizeof(pconfig_params->SSIDinfo.ssid.ssId)); 2849 2850 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 2851 2852 if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 2853 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 2854 } else if (pconfig_params->authType == eSAP_SHARED_KEY) { 2855 profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; 2856 } else { 2857 profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; 2858 } 2859 2860 profile->AuthType.numEntries = 1; 2861 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; 2862 2863 /* Always set the Encryption Type */ 2864 profile->EncryptionType.numEntries = 1; 2865 profile->EncryptionType.encryptionType[0] = 2866 pconfig_params->RSNEncryptType; 2867 2868 profile->mcEncryptionType.numEntries = 1; 2869 profile->mcEncryptionType.encryptionType[0] = 2870 pconfig_params->mcRSNEncryptType; 2871 2872 if (pconfig_params->privacy & eSAP_SHARED_KEY) { 2873 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; 2874 } 2875 2876 profile->privacy = pconfig_params->privacy; 2877 profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq; 2878 2879 if (pconfig_params->authType == eSAP_SHARED_KEY) { 2880 profile->csr80211AuthType = eSIR_SHARED_KEY; 2881 } else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 2882 profile->csr80211AuthType = eSIR_OPEN_SYSTEM; 2883 } else { 2884 profile->csr80211AuthType = eSIR_AUTO_SWITCH; 2885 } 2886 2887 /* Initialize we are not going to use it */ 2888 profile->pWPAReqIE = NULL; 2889 profile->nWPAReqIELength = 0; 2890 2891 if (profile->pRSNReqIE) { 2892 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 2893 FL("pRSNReqIE already allocated.")); 2894 qdf_mem_free(profile->pRSNReqIE); 2895 profile->pRSNReqIE = NULL; 2896 } 2897 2898 /* set the RSN/WPA IE */ 2899 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 2900 if (pconfig_params->RSNWPAReqIELength) { 2901 profile->pRSNReqIE = 2902 qdf_mem_malloc(pconfig_params->RSNWPAReqIELength); 2903 if (NULL == profile->pRSNReqIE) { 2904 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2905 " %s Fail to alloc memory", __func__); 2906 return eSAP_STATUS_FAILURE; 2907 } 2908 qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE, 2909 pconfig_params->RSNWPAReqIELength); 2910 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 2911 } 2912 2913 /* set the phyMode to accept anything */ 2914 /* Best means everything because it covers all the things we support */ 2915 /* eCSR_DOT11_MODE_BEST */ 2916 profile->phyMode = pconfig_params->SapHw_mode; 2917 2918 /* Configure beaconInterval */ 2919 profile->beaconInterval = (uint16_t) pconfig_params->beacon_int; 2920 2921 /* set DTIM period */ 2922 profile->dtimPeriod = pconfig_params->dtim_period; 2923 2924 /* set Uapsd enable bit */ 2925 profile->ApUapsdEnable = pconfig_params->UapsdEnable; 2926 2927 /* Enable protection parameters */ 2928 profile->protEnabled = pconfig_params->protEnabled; 2929 profile->obssProtEnabled = pconfig_params->obssProtEnabled; 2930 profile->cfg_protection = pconfig_params->ht_capab; 2931 2932 /* country code */ 2933 if (pconfig_params->countryCode[0]) 2934 qdf_mem_copy(profile->countryCode, pconfig_params->countryCode, 2935 WNI_CFG_COUNTRY_CODE_LEN); 2936 profile->ieee80211d = pconfig_params->ieee80211d; 2937 /* wps config info */ 2938 profile->wps_state = pconfig_params->wps_state; 2939 2940 #ifdef WLAN_FEATURE_11W 2941 /* MFP capable/required */ 2942 profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0; 2943 profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; 2944 #endif 2945 2946 if (pconfig_params->probeRespIEsBufferLen > 0 && 2947 pconfig_params->pProbeRespIEsBuffer != NULL) { 2948 profile->addIeParams.probeRespDataLen = 2949 pconfig_params->probeRespIEsBufferLen; 2950 profile->addIeParams.probeRespData_buff = 2951 pconfig_params->pProbeRespIEsBuffer; 2952 } else { 2953 profile->addIeParams.probeRespDataLen = 0; 2954 profile->addIeParams.probeRespData_buff = NULL; 2955 } 2956 /*assoc resp IE */ 2957 if (pconfig_params->assocRespIEsLen > 0 && 2958 pconfig_params->pAssocRespIEsBuffer != NULL) { 2959 profile->addIeParams.assocRespDataLen = 2960 pconfig_params->assocRespIEsLen; 2961 profile->addIeParams.assocRespData_buff = 2962 pconfig_params->pAssocRespIEsBuffer; 2963 } else { 2964 profile->addIeParams.assocRespDataLen = 0; 2965 profile->addIeParams.assocRespData_buff = NULL; 2966 } 2967 2968 if (pconfig_params->probeRespBcnIEsLen > 0 && 2969 pconfig_params->pProbeRespBcnIEsBuffer != NULL) { 2970 profile->addIeParams.probeRespBCNDataLen = 2971 pconfig_params->probeRespBcnIEsLen; 2972 profile->addIeParams.probeRespBCNData_buff = 2973 pconfig_params->pProbeRespBcnIEsBuffer; 2974 } else { 2975 profile->addIeParams.probeRespBCNDataLen = 0; 2976 profile->addIeParams.probeRespBCNData_buff = NULL; 2977 } 2978 profile->sap_dot11mc = pconfig_params->sap_dot11mc; 2979 2980 if (pconfig_params->supported_rates.numRates) { 2981 qdf_mem_copy(profile->supported_rates.rate, 2982 pconfig_params->supported_rates.rate, 2983 pconfig_params->supported_rates.numRates); 2984 profile->supported_rates.numRates = 2985 pconfig_params->supported_rates.numRates; 2986 } 2987 2988 if (pconfig_params->extended_rates.numRates) { 2989 qdf_mem_copy(profile->extended_rates.rate, 2990 pconfig_params->extended_rates.rate, 2991 pconfig_params->extended_rates.numRates); 2992 profile->extended_rates.numRates = 2993 pconfig_params->extended_rates.numRates; 2994 } 2995 2996 profile->chan_switch_hostapd_rate_enabled = 2997 pconfig_params->chan_switch_hostapd_rate_enabled; 2998 2999 return eSAP_STATUS_SUCCESS; /* Success. */ 3000 } 3001 3002 void sap_free_roam_profile(struct csr_roam_profile *profile) 3003 { 3004 if (profile->pRSNReqIE) { 3005 qdf_mem_free(profile->pRSNReqIE); 3006 profile->pRSNReqIE = NULL; 3007 } 3008 } 3009 3010 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size) 3011 { 3012 uint8_t outer, inner; 3013 struct qdf_mac_addr temp; 3014 int32_t nRes = -1; 3015 3016 if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) { 3017 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3018 FL("either buffer is NULL or size = %d is more"), size); 3019 return; 3020 } 3021 3022 for (outer = 0; outer < size; outer++) { 3023 for (inner = 0; inner < size - 1; inner++) { 3024 nRes = 3025 qdf_mem_cmp((macList + inner)->bytes, 3026 (macList + inner + 1)->bytes, 3027 QDF_MAC_ADDR_SIZE); 3028 if (nRes > 0) { 3029 qdf_mem_copy(temp.bytes, 3030 (macList + inner + 1)->bytes, 3031 QDF_MAC_ADDR_SIZE); 3032 qdf_mem_copy((macList + inner + 1)->bytes, 3033 (macList + inner)->bytes, 3034 QDF_MAC_ADDR_SIZE); 3035 qdf_mem_copy((macList + inner)->bytes, 3036 temp.bytes, QDF_MAC_ADDR_SIZE); 3037 } 3038 } 3039 } 3040 } 3041 3042 bool 3043 sap_search_mac_list(struct qdf_mac_addr *macList, 3044 uint8_t num_mac, uint8_t *peerMac, 3045 uint8_t *index) 3046 { 3047 int32_t nRes = -1; 3048 int8_t nStart = 0, nEnd, nMiddle; 3049 3050 nEnd = num_mac - 1; 3051 3052 if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) { 3053 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3054 FL("either buffer is NULL or size = %d is more."), num_mac); 3055 return false; 3056 } 3057 3058 while (nStart <= nEnd) { 3059 nMiddle = (nStart + nEnd) / 2; 3060 nRes = 3061 qdf_mem_cmp(&macList[nMiddle], peerMac, 3062 QDF_MAC_ADDR_SIZE); 3063 3064 if (0 == nRes) { 3065 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3066 "search SUCC"); 3067 /* "index equals NULL" means the caller does not need the */ 3068 /* index value of the peerMac being searched */ 3069 if (index != NULL) { 3070 *index = (uint8_t) nMiddle; 3071 QDF_TRACE(QDF_MODULE_ID_SAP, 3072 QDF_TRACE_LEVEL_INFO_HIGH, "index %d", 3073 *index); 3074 } 3075 return true; 3076 } 3077 if (nRes < 0) 3078 nStart = nMiddle + 1; 3079 else 3080 nEnd = nMiddle - 1; 3081 } 3082 3083 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3084 "search not succ"); 3085 return false; 3086 } 3087 3088 void sap_add_mac_to_acl(struct qdf_mac_addr *macList, 3089 uint8_t *size, uint8_t *peerMac) 3090 { 3091 int32_t nRes = -1; 3092 int i; 3093 3094 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3095 "add acl entered"); 3096 3097 if (NULL == macList || *size > MAX_ACL_MAC_ADDRESS) { 3098 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3099 FL("either buffer is NULL or size = %d is incorrect."), 3100 *size); 3101 return; 3102 } 3103 3104 for (i = ((*size) - 1); i >= 0; i--) { 3105 nRes = 3106 qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE); 3107 if (nRes > 0) { 3108 /* Move alphabetically greater mac addresses one index down to allow for insertion 3109 of new mac in sorted order */ 3110 qdf_mem_copy((macList + i + 1)->bytes, 3111 (macList + i)->bytes, QDF_MAC_ADDR_SIZE); 3112 } else { 3113 break; 3114 } 3115 } 3116 /* This should also take care of if the element is the first to be added in the list */ 3117 qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE); 3118 /* increment the list size */ 3119 (*size)++; 3120 } 3121 3122 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList, 3123 uint8_t *size, uint8_t index) 3124 { 3125 int i; 3126 3127 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3128 "remove acl entered"); 3129 /* 3130 * Return if the list passed is empty. Ideally this should never happen 3131 * since this funcn is always called after sap_search_mac_list to get 3132 * the index of the mac addr to be removed and this will only get 3133 * called if the search is successful. Still no harm in having the check 3134 */ 3135 if ((macList == NULL) || (*size == 0) || 3136 (*size > MAX_ACL_MAC_ADDRESS)) { 3137 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3138 FL("either buffer is NULL or size %d is incorrect."), 3139 *size); 3140 return; 3141 } 3142 for (i = index; i < ((*size) - 1); i++) { 3143 /* Move mac addresses starting from "index" passed one index up to delete the void 3144 created by deletion of a mac address in ACL */ 3145 qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes, 3146 QDF_MAC_ADDR_SIZE); 3147 } 3148 /* The last space should be made empty since all mac addesses moved one step up */ 3149 qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE); 3150 /* reduce the list size by 1 */ 3151 (*size)--; 3152 } 3153 3154 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size) 3155 { 3156 int i; 3157 uint8_t *macArray; 3158 3159 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3160 "print acl entered"); 3161 3162 if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) { 3163 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3164 "In %s, either buffer is NULL or size %d is incorrect.", 3165 __func__, size); 3166 return; 3167 } 3168 3169 for (i = 0; i < size; i++) { 3170 macArray = (macList + i)->bytes; 3171 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3172 "** ACL entry %i - " MAC_ADDRESS_STR, i, 3173 MAC_ADDR_ARRAY(macArray)); 3174 } 3175 return; 3176 } 3177 3178 QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sapContext, 3179 uint8_t *peerMac) 3180 { 3181 if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode) 3182 return QDF_STATUS_SUCCESS; 3183 3184 if (sap_search_mac_list 3185 (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL)) 3186 return QDF_STATUS_SUCCESS; 3187 3188 if (sap_search_mac_list 3189 (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) { 3190 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3191 "In %s, Peer " MAC_ADDRESS_STR " in deny list", 3192 __func__, MAC_ADDR_ARRAY(peerMac)); 3193 return QDF_STATUS_E_FAILURE; 3194 } 3195 /* A new station CAN associate, unless in deny list. Less stringent mode */ 3196 if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode) 3197 return QDF_STATUS_SUCCESS; 3198 3199 /* A new station CANNOT associate, unless in accept list. More stringent mode */ 3200 if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) { 3201 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3202 "In %s, Peer " MAC_ADDRESS_STR 3203 " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", 3204 __func__, MAC_ADDR_ARRAY(peerMac)); 3205 return QDF_STATUS_E_FAILURE; 3206 } 3207 3208 /* The new STA is neither in accept list nor in deny list. In this case, deny the association 3209 * but send a wifi event notification indicating the mac address being denied 3210 */ 3211 if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) { 3212 sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, 3213 (void *) peerMac); 3214 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3215 "In %s, Peer " MAC_ADDRESS_STR 3216 " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", 3217 __func__, MAC_ADDR_ARRAY(peerMac)); 3218 return QDF_STATUS_E_FAILURE; 3219 } 3220 return QDF_STATUS_SUCCESS; 3221 } 3222 3223 #ifdef SOFTAP_CHANNEL_RANGE 3224 /** 3225 * sap_get_channel_list() - get the list of channels 3226 * @sap_ctx: sap context 3227 * @ch_list: pointer to channel list array 3228 * @num_ch: pointer to number of channels. 3229 * 3230 * This function populates the list of channels for scanning. 3231 * 3232 * Return: QDF_STATUS 3233 */ 3234 static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx, 3235 uint8_t **ch_list, 3236 uint8_t *num_ch) 3237 { 3238 uint8_t loop_count; 3239 uint8_t *list; 3240 uint8_t ch_count; 3241 uint8_t start_ch_num, band_start_ch; 3242 uint8_t end_ch_num, band_end_ch; 3243 uint32_t en_lte_coex; 3244 tHalHandle hal = CDS_GET_HAL_CB(); 3245 #ifdef FEATURE_WLAN_CH_AVOID 3246 uint8_t i; 3247 #endif 3248 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 3249 tSapChSelSpectInfo spect_info_obj = { NULL, 0 }; 3250 uint16_t ch_width; 3251 3252 if (NULL == hal) { 3253 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3254 FL("Invalid HAL pointer from p_cds_gctx")); 3255 *num_ch = 0; 3256 *ch_list = NULL; 3257 return QDF_STATUS_E_FAULT; 3258 } 3259 3260 start_ch_num = sap_ctx->acs_cfg->start_ch; 3261 end_ch_num = sap_ctx->acs_cfg->end_ch; 3262 ch_width = sap_ctx->acs_cfg->ch_width; 3263 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3264 FL("startChannel %d, EndChannel %d, ch_width %d, HW:%d"), 3265 start_ch_num, end_ch_num, ch_width, 3266 sap_ctx->acs_cfg->hw_mode); 3267 3268 wlansap_extend_to_acs_range(hal, &start_ch_num, &end_ch_num, 3269 &band_start_ch, &band_end_ch); 3270 3271 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3272 FL("expanded startChannel %d,EndChannel %d"), 3273 start_ch_num, end_ch_num); 3274 3275 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3276 FL("band_start_ch %d, band_end_ch %d"), 3277 band_start_ch, band_end_ch); 3278 3279 sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex); 3280 3281 /* Check if LTE coex is enabled and 2.4GHz is selected */ 3282 if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) && 3283 (band_end_ch == CHAN_ENUM_14)) { 3284 /* Set 2.4GHz upper limit to channel 9 for LTE COEX */ 3285 band_end_ch = CHAN_ENUM_9; 3286 } 3287 3288 /* Allocate the max number of channel supported */ 3289 list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS + 3290 NUM_24GHZ_CHANNELS); 3291 if (NULL == list) { 3292 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3293 FL("Unable to allocate channel list")); 3294 *num_ch = 0; 3295 *ch_list = NULL; 3296 return QDF_STATUS_E_NOMEM; 3297 } 3298 3299 /* Search for the Active channels in the given range */ 3300 ch_count = 0; 3301 for (loop_count = band_start_ch; loop_count <= band_end_ch; 3302 loop_count++) { 3303 /* go to next channel if rf_channel is out of range */ 3304 if ((start_ch_num > WLAN_REG_CH_NUM(loop_count)) || 3305 (end_ch_num < WLAN_REG_CH_NUM(loop_count))) 3306 continue; 3307 /* 3308 * go to next channel if none of these condition pass 3309 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE 3310 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE 3311 */ 3312 if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) && 3313 wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)) || 3314 ((false == mac_ctx->scan.fEnableDFSChnlScan) && 3315 (CHANNEL_STATE_ENABLE == 3316 wlan_reg_get_channel_state(mac_ctx->pdev, loop_count))))) 3317 continue; 3318 3319 /* 3320 * Skip the channels which are not in ACS config from user 3321 * space 3322 */ 3323 if (SAP_CHANNEL_NOT_SELECTED == 3324 sap_channel_in_acs_channel_list( 3325 WLAN_REG_CH_NUM(loop_count), 3326 sap_ctx, &spect_info_obj)) 3327 continue; 3328 /* Dont scan DFS channels in case of MCC disallowed 3329 * As it can result in SAP starting on DFS channel 3330 * resulting MCC on DFS channel 3331 */ 3332 if (wlan_reg_is_dfs_ch(mac_ctx->pdev, 3333 WLAN_REG_CH_NUM(loop_count)) && 3334 policy_mgr_disallow_mcc(mac_ctx->psoc, 3335 WLAN_REG_CH_NUM(loop_count))) 3336 continue; 3337 3338 /* 3339 * If we have any 5Ghz channel in the channel list 3340 * and bw is 40/80/160 Mhz then we don't want SAP to 3341 * come up in 2.4Ghz as for 40Mhz, 2.4Ghz channel is 3342 * not preferred and 80/160Mhz is not allowed for 2.4Ghz 3343 * band. So, don't even scan on 2.4Ghz channels if bw is 3344 * 40/80/160Mhz and channel list has any 5Ghz channel. 3345 */ 3346 if (end_ch_num >= WLAN_REG_CH_NUM(CHAN_ENUM_36) && 3347 ((ch_width == CH_WIDTH_40MHZ) || 3348 (ch_width == CH_WIDTH_80MHZ) || 3349 (ch_width == CH_WIDTH_80P80MHZ) || 3350 (ch_width == CH_WIDTH_160MHZ))) { 3351 if (WLAN_REG_CH_NUM(loop_count) >= 3352 WLAN_REG_CH_NUM(CHAN_ENUM_1) && 3353 WLAN_REG_CH_NUM(loop_count) <= 3354 WLAN_REG_CH_NUM(CHAN_ENUM_14)) 3355 continue; 3356 } 3357 3358 #ifdef FEATURE_WLAN_CH_AVOID 3359 for (i = 0; i < NUM_CHANNELS; i++) { 3360 if (safe_channels[i].channelNumber == 3361 WLAN_REG_CH_NUM(loop_count)) { 3362 /* Check if channel is safe */ 3363 if (true == safe_channels[i].isSafe) { 3364 #endif 3365 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 3366 uint8_t ch; 3367 3368 ch = WLAN_REG_CH_NUM(loop_count); 3369 if ((sap_ctx->acs_cfg->skip_scan_status == 3370 eSAP_DO_PAR_ACS_SCAN)) { 3371 if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch && 3372 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) || 3373 (ch >= sap_ctx->acs_cfg->skip_scan_range2_stch && 3374 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) { 3375 list[ch_count] = 3376 WLAN_REG_CH_NUM(loop_count); 3377 ch_count++; 3378 QDF_TRACE(QDF_MODULE_ID_SAP, 3379 QDF_TRACE_LEVEL_INFO, 3380 FL("%d %d added to ACS ch range"), 3381 ch_count, ch); 3382 } else { 3383 QDF_TRACE(QDF_MODULE_ID_SAP, 3384 QDF_TRACE_LEVEL_INFO_HIGH, 3385 FL("%d %d skipped from ACS ch range"), 3386 ch_count, ch); 3387 } 3388 } else { 3389 list[ch_count] = 3390 WLAN_REG_CH_NUM(loop_count); 3391 ch_count++; 3392 QDF_TRACE(QDF_MODULE_ID_SAP, 3393 QDF_TRACE_LEVEL_INFO, 3394 FL("%d %d added to ACS ch range"), 3395 ch_count, ch); 3396 } 3397 #else 3398 list[ch_count] = WLAN_REG_CH_NUM(loop_count); 3399 ch_count++; 3400 #endif 3401 #ifdef FEATURE_WLAN_CH_AVOID 3402 } 3403 break; 3404 } 3405 } 3406 #endif 3407 } 3408 if (0 == ch_count) { 3409 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3410 FL("No active channels present for the current region")); 3411 /* 3412 * LTE COEX: channel range outside the restricted 2.4GHz 3413 * band limits 3414 */ 3415 if (en_lte_coex && (start_ch_num > band_end_ch)) 3416 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 3417 FL("SAP can't be started as due to LTE COEX")); 3418 } 3419 3420 /* return the channel list and number of channels to scan */ 3421 *num_ch = ch_count; 3422 if (ch_count != 0) { 3423 *ch_list = list; 3424 } else { 3425 *ch_list = NULL; 3426 qdf_mem_free(list); 3427 } 3428 3429 for (loop_count = 0; loop_count < ch_count; loop_count++) { 3430 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 3431 FL("channel number: %d"), list[loop_count]); 3432 } 3433 return QDF_STATUS_SUCCESS; 3434 } 3435 #endif 3436 3437 #ifdef DFS_COMPONENT_ENABLE 3438 uint8_t sap_indicate_radar(struct sap_context *sap_ctx) 3439 { 3440 uint8_t target_channel = 0; 3441 tHalHandle hal; 3442 tpAniSirGlobal mac; 3443 3444 if (!sap_ctx) { 3445 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3446 FL("null sap_ctx")); 3447 return 0; 3448 } 3449 3450 hal = CDS_GET_HAL_CB(); 3451 if (!hal) { 3452 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3453 FL("null hal")); 3454 return 0; 3455 } 3456 3457 mac = PMAC_STRUCT(hal); 3458 3459 /* 3460 * SAP needs to generate Channel Switch IE 3461 * if the radar is found in the STARTED state 3462 */ 3463 if (eSAP_STARTED == sap_ctx->sapsMachine) 3464 mac->sap.SapDfsInfo.csaIERequired = true; 3465 3466 if (sap_ctx->csr_roamProfile.disableDFSChSwitch) 3467 return sap_ctx->channel; 3468 3469 /* set the Radar Found flag in SapDfsInfo */ 3470 mac->sap.SapDfsInfo.sap_radar_found_status = true; 3471 3472 if (sap_ctx->chan_before_pre_cac) { 3473 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3474 FL("sapdfs: set chan before pre cac %d as target chan"), 3475 sap_ctx->chan_before_pre_cac); 3476 return sap_ctx->chan_before_pre_cac; 3477 } 3478 3479 if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS == 3480 sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ, 3481 (void *) eSAP_STATUS_SUCCESS))) 3482 return 0; 3483 3484 target_channel = sap_random_channel_sel(sap_ctx); 3485 if (!target_channel) 3486 sap_signal_hdd_event(sap_ctx, NULL, 3487 eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS); 3488 3489 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 3490 FL("sapdfs: New selected target channel is [%d]"), 3491 target_channel); 3492 3493 return target_channel; 3494 } 3495 #endif 3496 3497 /* 3498 * CAC timer callback function. 3499 * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm(). 3500 */ 3501 void sap_dfs_cac_timer_callback(void *data) 3502 { 3503 struct sap_context *sapContext; 3504 tWLAN_SAPEvent sapEvent; 3505 tHalHandle hHal = (tHalHandle) data; 3506 tpAniSirGlobal pMac; 3507 3508 if (NULL == hHal) { 3509 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3510 "In %s invalid hHal", __func__); 3511 return; 3512 } 3513 pMac = PMAC_STRUCT(hHal); 3514 sapContext = sap_find_cac_wait_session(hHal); 3515 if (NULL == sapContext) { 3516 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3517 "%s: no SAP contexts in wait state", __func__); 3518 return; 3519 } 3520 3521 /* 3522 * SAP may not be in CAC wait state, when the timer runs out. 3523 * if following flag is set, then timer is in initialized state, 3524 * destroy timer here. 3525 */ 3526 if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) { 3527 if (!sapContext->dfs_cac_offload) 3528 qdf_mc_timer_destroy( 3529 &pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3530 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 3531 } 3532 3533 /* 3534 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm 3535 */ 3536 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3537 "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]", 3538 sapContext->channel, sapContext); 3539 3540 sapEvent.event = eSAP_DFS_CHANNEL_CAC_END; 3541 sapEvent.params = 0; 3542 sapEvent.u1 = 0; 3543 sapEvent.u2 = 0; 3544 3545 sap_fsm(sapContext, &sapEvent); 3546 } 3547 3548 /* 3549 * Function to stop the DFS CAC Timer 3550 */ 3551 static int sap_stop_dfs_cac_timer(struct sap_context *sapContext) 3552 { 3553 tHalHandle hHal; 3554 tpAniSirGlobal pMac; 3555 3556 if (sapContext == NULL) 3557 return 0; 3558 3559 hHal = CDS_GET_HAL_CB(); 3560 if (NULL == hHal) { 3561 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3562 "In %s invalid hHal", __func__); 3563 return 0; 3564 } 3565 pMac = PMAC_STRUCT(hHal); 3566 3567 if (sapContext->dfs_cac_offload) { 3568 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3569 return 0; 3570 } 3571 3572 if (QDF_TIMER_STATE_RUNNING != 3573 qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo. 3574 sap_dfs_cac_timer)) { 3575 return 0; 3576 } 3577 3578 qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3579 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3580 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3581 3582 return 0; 3583 } 3584 3585 3586 /* 3587 * Function to start the DFS CAC Timer 3588 * when SAP is started on a DFS channel 3589 */ 3590 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx) 3591 { 3592 QDF_STATUS status; 3593 uint32_t cac_dur; 3594 tHalHandle hal = NULL; 3595 tpAniSirGlobal mac = NULL; 3596 enum dfs_reg dfs_region; 3597 3598 if (!sap_ctx) { 3599 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3600 "%s: null sap_ctx", __func__); 3601 return 0; 3602 } 3603 3604 hal = CDS_GET_HAL_CB(); 3605 if (!hal) { 3606 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3607 "%s: null hal", __func__); 3608 return 0; 3609 } 3610 3611 mac = PMAC_STRUCT(hal); 3612 if (sap_ctx->dfs_cac_offload) { 3613 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 3614 "%s: cac timer offloaded to firmware", __func__); 3615 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 3616 return 1; 3617 } 3618 3619 sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region); 3620 if (0 == cac_dur) 3621 return 0; 3622 3623 #ifdef QCA_WIFI_NAPIER_EMULATION 3624 cac_dur = cac_dur / 100; 3625 #endif 3626 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3627 "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH-%d, CAC_DUR-%d sec", 3628 sap_ctx->channel, cac_dur / 1000); 3629 3630 qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, 3631 QDF_TIMER_TYPE_SW, 3632 sap_dfs_cac_timer_callback, (void *)hal); 3633 3634 /* Start the CAC timer */ 3635 status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, 3636 cac_dur); 3637 if (status == QDF_STATUS_SUCCESS) { 3638 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 3639 return 1; 3640 } else { 3641 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 3642 qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer); 3643 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3644 "%s: failed to start cac timer", __func__); 3645 return 0; 3646 } 3647 } 3648 3649 /* 3650 * This function initializes the NOL list 3651 * parameters required to track the radar 3652 * found DFS channels in the current Reg. Domain . 3653 */ 3654 QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sapContext) 3655 { 3656 tHalHandle hHal; 3657 tpAniSirGlobal pMac; 3658 3659 if (NULL == sapContext) { 3660 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3661 "Invalid sapContext pointer on sap_init_dfs_channel_nol_list"); 3662 return QDF_STATUS_E_FAULT; 3663 } 3664 hHal = CDS_GET_HAL_CB(); 3665 3666 if (NULL == hHal) { 3667 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3668 "In %s invalid hHal", __func__); 3669 return QDF_STATUS_E_FAULT; 3670 } 3671 pMac = PMAC_STRUCT(hHal); 3672 3673 utils_dfs_init_nol(pMac->pdev); 3674 3675 return QDF_STATUS_SUCCESS; 3676 } 3677 3678 /* 3679 * This function will calculate how many interfaces 3680 * have sap persona and returns total number of sap persona. 3681 */ 3682 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal) 3683 { 3684 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3685 uint8_t intf = 0; 3686 uint8_t intf_count = 0; 3687 3688 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3689 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3690 || 3691 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3692 && pMac->sap.sapCtxList[intf].sap_context != NULL) { 3693 intf_count++; 3694 } 3695 } 3696 return intf_count; 3697 } 3698 3699 /** 3700 * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready 3701 * for channel change 3702 * @hHal: HAL pointer 3703 * @sapContext: sap context for which this function has been called 3704 * 3705 * This function will find the concurrent sap context apart from 3706 * passed sap context and return its channel change ready status 3707 * 3708 * 3709 * Return: true if other SAP personas are ready to channel switch else false 3710 */ 3711 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal, 3712 struct sap_context *sapContext) 3713 { 3714 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3715 struct sap_context *sap_context; 3716 uint8_t intf = 0; 3717 3718 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3719 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3720 || 3721 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3722 && pMac->sap.sapCtxList[intf].sap_context != NULL) { 3723 sap_context = 3724 pMac->sap.sapCtxList[intf].sap_context; 3725 if (sap_context == sapContext) { 3726 QDF_TRACE(QDF_MODULE_ID_SAP, 3727 QDF_TRACE_LEVEL_ERROR, 3728 FL("sapCtx matched [%pK]"), 3729 sapContext); 3730 continue; 3731 } else { 3732 QDF_TRACE(QDF_MODULE_ID_SAP, 3733 QDF_TRACE_LEVEL_ERROR, 3734 FL 3735 ("concurrent sapCtx[%pK] didn't matche with [%pK]"), 3736 sap_context, sapContext); 3737 return sap_context->is_sap_ready_for_chnl_chng; 3738 } 3739 } 3740 } 3741 return false; 3742 } 3743 3744 /** 3745 * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS 3746 * @hal: pointer to hal 3747 * @sap_context: current SAP persona's channel 3748 * 3749 * If provided SAP's channel is DFS then Loop through each SAP or GO persona and 3750 * check if other beaconing entity's channel is same DFS channel. If they are 3751 * same then concurrent sap is doing SCC DFS. 3752 * 3753 * Return: true if two or more beaconing entitity doing SCC DFS else false 3754 */ 3755 bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal, 3756 struct sap_context *given_sapctx) 3757 { 3758 tpAniSirGlobal mac = PMAC_STRUCT(hal); 3759 struct sap_context *sap_ctx; 3760 uint8_t intf = 0, scc_dfs_counter = 0; 3761 3762 /* 3763 * current SAP persona's channel itself is not DFS, so no need to check 3764 * what other persona's channel is 3765 */ 3766 if (!wlan_reg_is_dfs_ch(mac->pdev, 3767 given_sapctx->csr_roamProfile.operationChannel)) { 3768 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 3769 FL("skip this loop as provided channel is non-dfs")); 3770 return false; 3771 } 3772 3773 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3774 if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) && 3775 (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona)) 3776 continue; 3777 if (!mac->sap.sapCtxList[intf].sap_context) 3778 continue; 3779 sap_ctx = mac->sap.sapCtxList[intf].sap_context; 3780 /* if same SAP contexts then skip to next context */ 3781 if (sap_ctx == given_sapctx) 3782 continue; 3783 if (given_sapctx->csr_roamProfile.operationChannel == 3784 sap_ctx->csr_roamProfile.operationChannel) 3785 scc_dfs_counter++; 3786 } 3787 3788 /* Found atleast two of the beaconing entities doing SCC DFS */ 3789 if (scc_dfs_counter) 3790 return true; 3791 3792 return false; 3793 } 3794