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->sessionId = sap_ctx->sessionId; 1533 break; 1534 case eSAP_DFS_CAC_START: 1535 case eSAP_DFS_CAC_INTERRUPTED: 1536 case eSAP_DFS_CAC_END: 1537 case eSAP_DFS_PRE_CAC_END: 1538 case eSAP_DFS_RADAR_DETECT: 1539 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC: 1540 case eSAP_DFS_NO_AVAILABLE_CHANNEL: 1541 sap_ap_event.sapHddEventCode = sap_hddevent; 1542 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 1543 (eSapStatus) context; 1544 break; 1545 case eSAP_ACS_SCAN_SUCCESS_EVENT: 1546 sap_handle_acs_scan_event(sap_ctx, &sap_ap_event, 1547 (eSapStatus)context); 1548 break; 1549 case eSAP_ACS_CHANNEL_SELECTED: 1550 sap_ap_event.sapHddEventCode = sap_hddevent; 1551 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 1552 if (eSAP_STATUS_SUCCESS == (eSapStatus)context) { 1553 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 1554 acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; 1555 acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; 1556 acs_selected->vht_seg0_center_ch = 1557 sap_ctx->acs_cfg->vht_seg0_center_ch; 1558 acs_selected->vht_seg1_center_ch = 1559 sap_ctx->acs_cfg->vht_seg1_center_ch; 1560 } else if (eSAP_STATUS_FAILURE == (eSapStatus)context) { 1561 acs_selected->pri_ch = 0; 1562 } 1563 break; 1564 1565 case eSAP_STOP_BSS_EVENT: 1566 sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT; 1567 sap_ap_event.sapevt.sapStopBssCompleteEvent.status = 1568 (eSapStatus) context; 1569 break; 1570 1571 case eSAP_STA_ASSOC_EVENT: 1572 case eSAP_STA_REASSOC_EVENT: 1573 1574 if (!csr_roaminfo) { 1575 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1576 FL("Invalid CSR Roam Info")); 1577 return QDF_STATUS_E_INVAL; 1578 } 1579 if (eSAP_DISCONNECTING == sap_ctx->sapsMachine) { 1580 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1581 "SAP is disconnecting, not able to handle any incoming (re)assoc req"); 1582 return QDF_STATUS_E_ABORTED; 1583 } 1584 1585 reassoc_complete = 1586 &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent; 1587 1588 if (csr_roaminfo->fReassocReq) 1589 sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT; 1590 else 1591 sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT; 1592 1593 qdf_copy_macaddr(&reassoc_complete->staMac, 1594 &csr_roaminfo->peerMac); 1595 reassoc_complete->staId = csr_roaminfo->staId; 1596 reassoc_complete->statusCode = csr_roaminfo->statusCode; 1597 reassoc_complete->iesLen = csr_roaminfo->rsnIELen; 1598 qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE, 1599 csr_roaminfo->rsnIELen); 1600 1601 #ifdef FEATURE_WLAN_WAPI 1602 if (csr_roaminfo->wapiIELen) { 1603 uint8_t len = reassoc_complete->iesLen; 1604 1605 reassoc_complete->iesLen += csr_roaminfo->wapiIELen; 1606 qdf_mem_copy(&reassoc_complete->ies[len], 1607 csr_roaminfo->pwapiIE, 1608 csr_roaminfo->wapiIELen); 1609 } 1610 #endif 1611 if (csr_roaminfo->addIELen) { 1612 uint8_t len = reassoc_complete->iesLen; 1613 1614 reassoc_complete->iesLen += csr_roaminfo->addIELen; 1615 qdf_mem_copy(&reassoc_complete->ies[len], 1616 csr_roaminfo->paddIE, 1617 csr_roaminfo->addIELen); 1618 if (wlan_get_vendor_ie_ptr_from_oui( 1619 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, 1620 csr_roaminfo->paddIE, csr_roaminfo->addIELen)) { 1621 reassoc_complete->staType = eSTA_TYPE_P2P_CLI; 1622 } else { 1623 reassoc_complete->staType = eSTA_TYPE_INFRA; 1624 } 1625 } 1626 1627 /* also fill up the channel info from the csr_roamInfo */ 1628 chaninfo = &reassoc_complete->chan_info; 1629 1630 chaninfo->chan_id = csr_roaminfo->chan_info.chan_id; 1631 chaninfo->mhz = csr_roaminfo->chan_info.mhz; 1632 chaninfo->info = csr_roaminfo->chan_info.info; 1633 chaninfo->band_center_freq1 = 1634 csr_roaminfo->chan_info.band_center_freq1; 1635 chaninfo->band_center_freq2 = 1636 csr_roaminfo->chan_info.band_center_freq2; 1637 chaninfo->reg_info_1 = 1638 csr_roaminfo->chan_info.reg_info_1; 1639 chaninfo->reg_info_2 = 1640 csr_roaminfo->chan_info.reg_info_2; 1641 chaninfo->nss = csr_roaminfo->chan_info.nss; 1642 chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags; 1643 1644 reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta; 1645 reassoc_complete->status = (eSapStatus) context; 1646 reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap; 1647 reassoc_complete->ampdu = csr_roaminfo->ampdu; 1648 reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable; 1649 reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc; 1650 reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc; 1651 reassoc_complete->ch_width = csr_roaminfo->ch_width; 1652 reassoc_complete->mode = csr_roaminfo->mode; 1653 reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx; 1654 reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx; 1655 reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx; 1656 reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map; 1657 reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map; 1658 reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable; 1659 if (csr_roaminfo->ht_caps.present) 1660 reassoc_complete->ht_caps = csr_roaminfo->ht_caps; 1661 if (csr_roaminfo->vht_caps.present) 1662 reassoc_complete->vht_caps = csr_roaminfo->vht_caps; 1663 1664 break; 1665 1666 case eSAP_STA_DISASSOC_EVENT: 1667 if (!csr_roaminfo) { 1668 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1669 FL("Invalid CSR Roam Info")); 1670 return QDF_STATUS_E_INVAL; 1671 } 1672 sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; 1673 disassoc_comp = 1674 &sap_ap_event.sapevt.sapStationDisassocCompleteEvent; 1675 1676 qdf_copy_macaddr(&disassoc_comp->staMac, 1677 &csr_roaminfo->peerMac); 1678 disassoc_comp->staId = csr_roaminfo->staId; 1679 if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED) 1680 disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC; 1681 else 1682 disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC; 1683 1684 disassoc_comp->statusCode = csr_roaminfo->statusCode; 1685 disassoc_comp->status = (eSapStatus) context; 1686 disassoc_comp->rssi = csr_roaminfo->rssi; 1687 disassoc_comp->rx_rate = csr_roaminfo->rx_rate; 1688 disassoc_comp->tx_rate = csr_roaminfo->tx_rate; 1689 disassoc_comp->reason_code = csr_roaminfo->disassoc_reason; 1690 break; 1691 1692 case eSAP_STA_SET_KEY_EVENT: 1693 1694 if (!csr_roaminfo) { 1695 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1696 FL("Invalid CSR Roam Info")); 1697 return QDF_STATUS_E_INVAL; 1698 } 1699 sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT; 1700 key_complete = 1701 &sap_ap_event.sapevt.sapStationSetKeyCompleteEvent; 1702 key_complete->status = (eSapStatus) context; 1703 qdf_copy_macaddr(&key_complete->peerMacAddr, 1704 &csr_roaminfo->peerMac); 1705 break; 1706 1707 case eSAP_STA_MIC_FAILURE_EVENT: 1708 1709 if (!csr_roaminfo) { 1710 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1711 FL("Invalid CSR Roam Info")); 1712 return QDF_STATUS_E_INVAL; 1713 } 1714 sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; 1715 mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent; 1716 1717 qdf_mem_copy(&mic_failure->srcMacAddr, 1718 csr_roaminfo->u.pMICFailureInfo->srcMacAddr, 1719 sizeof(tSirMacAddr)); 1720 qdf_mem_copy(&mic_failure->staMac.bytes, 1721 csr_roaminfo->u.pMICFailureInfo->taMacAddr, 1722 sizeof(tSirMacAddr)); 1723 qdf_mem_copy(&mic_failure->dstMacAddr.bytes, 1724 csr_roaminfo->u.pMICFailureInfo->dstMacAddr, 1725 sizeof(tSirMacAddr)); 1726 mic_failure->multicast = 1727 csr_roaminfo->u.pMICFailureInfo->multicast; 1728 mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1; 1729 mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId; 1730 qdf_mem_copy(mic_failure->TSC, 1731 csr_roaminfo->u.pMICFailureInfo->TSC, 1732 SIR_CIPHER_SEQ_CTR_SIZE); 1733 break; 1734 1735 case eSAP_ASSOC_STA_CALLBACK_EVENT: 1736 break; 1737 1738 case eSAP_WPS_PBC_PROBE_REQ_EVENT: 1739 1740 if (!csr_roaminfo) { 1741 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1742 FL("Invalid CSR Roam Info")); 1743 return QDF_STATUS_E_INVAL; 1744 } 1745 sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; 1746 1747 qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent. 1748 WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq, 1749 sizeof(tSirWPSPBCProbeReq)); 1750 break; 1751 1752 case eSAP_DISCONNECT_ALL_P2P_CLIENT: 1753 sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; 1754 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 1755 (eSapStatus) context; 1756 break; 1757 1758 case eSAP_MAC_TRIG_STOP_BSS_EVENT: 1759 sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; 1760 sap_ap_event.sapevt.sapActionCnf.actionSendSuccess = 1761 (eSapStatus) context; 1762 break; 1763 1764 case eSAP_UNKNOWN_STA_JOIN: 1765 sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; 1766 qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin. 1767 macaddr.bytes, (void *) context, 1768 QDF_MAC_ADDR_SIZE); 1769 break; 1770 1771 case eSAP_MAX_ASSOC_EXCEEDED: 1772 1773 if (!csr_roaminfo) { 1774 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1775 FL("Invalid CSR Roam Info")); 1776 return QDF_STATUS_E_INVAL; 1777 } 1778 sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; 1779 qdf_copy_macaddr(&sap_ap_event.sapevt. 1780 sapMaxAssocExceeded.macaddr, 1781 &csr_roaminfo->peerMac); 1782 break; 1783 1784 case eSAP_CHANNEL_CHANGE_EVENT: 1785 /* 1786 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS 1787 * follows pri AP 1788 */ 1789 sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; 1790 sap_ctx->acs_cfg->ch_width = 1791 sap_ctx->csr_roamProfile.ch_params.ch_width; 1792 sap_config_acs_result(hal, sap_ctx, sap_ctx->secondary_ch); 1793 1794 sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; 1795 1796 acs_selected = &sap_ap_event.sapevt.sap_ch_selected; 1797 acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; 1798 acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; 1799 acs_selected->ch_width = 1800 sap_ctx->csr_roamProfile.ch_params.ch_width; 1801 acs_selected->vht_seg0_center_ch = 1802 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; 1803 acs_selected->vht_seg1_center_ch = 1804 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; 1805 break; 1806 1807 case eSAP_ECSA_CHANGE_CHAN_IND: 1808 1809 if (!csr_roaminfo) { 1810 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1811 FL("Invalid CSR Roam Info")); 1812 return QDF_STATUS_E_INVAL; 1813 } 1814 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1815 "In %s, SAP event callback event = %s", 1816 __func__, "eSAP_ECSA_CHANGE_CHAN_IND"); 1817 sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND; 1818 sap_ap_event.sapevt.sap_chan_cng_ind.new_chan = 1819 csr_roaminfo->target_channel; 1820 break; 1821 case eSAP_DFS_NEXT_CHANNEL_REQ: 1822 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1823 "In %s, SAP event callback event = %s", 1824 __func__, "eSAP_DFS_NEXT_CHANNEL_REQ"); 1825 sap_ap_event.sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ; 1826 break; 1827 case eSAP_STOP_BSS_DUE_TO_NO_CHNL: 1828 sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL; 1829 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 1830 FL("stopping session_id:%d, bssid:%pM, channel:%d"), 1831 sap_ctx->sessionId, sap_ctx->self_mac_addr, 1832 sap_ctx->channel); 1833 break; 1834 default: 1835 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1836 FL("SAP Unknown callback event = %d"), 1837 sap_hddevent); 1838 break; 1839 } 1840 qdf_status = (*sap_ctx->pfnSapEventCallback) 1841 (&sap_ap_event, sap_ctx->pUsrContext); 1842 1843 return qdf_status; 1844 1845 } 1846 1847 /** 1848 * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state 1849 * @handle: Global MAC handle 1850 * 1851 * Finds and gets the context of a SAP session in CAC wait state. 1852 * 1853 * Return: Valid SAP context on success, else NULL 1854 */ 1855 static struct sap_context *sap_find_cac_wait_session(tHalHandle handle) 1856 { 1857 tpAniSirGlobal mac = PMAC_STRUCT(handle); 1858 uint8_t i = 0; 1859 struct sap_context *sapContext; 1860 1861 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1862 "%s", __func__); 1863 1864 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 1865 sapContext = mac->sap.sapCtxList[i].sap_context; 1866 if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona) 1867 || 1868 (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) && 1869 (sapContext) && 1870 (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) { 1871 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1872 "%s: found SAP in cac wait state", __func__); 1873 return sapContext; 1874 } 1875 if (sapContext) { 1876 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1877 "sapdfs: mode:%d intf:%d state:%d", 1878 mac->sap.sapCtxList[i].sapPersona, i, 1879 sapContext->sapsMachine); 1880 } 1881 } 1882 1883 return NULL; 1884 } 1885 1886 /*========================================================================== 1887 FUNCTION sap_cac_reset_notify 1888 1889 DESCRIPTION Function will be called up on stop bss indication to clean up 1890 DFS global structure. 1891 1892 DEPENDENCIES PARAMETERS 1893 IN hHAL : HAL pointer 1894 1895 RETURN VALUE : void. 1896 1897 SIDE EFFECTS 1898 ============================================================================*/ 1899 void sap_cac_reset_notify(tHalHandle hHal) 1900 { 1901 uint8_t intf = 0; 1902 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1903 1904 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1905 struct sap_context *sap_context = 1906 pMac->sap.sapCtxList[intf].sap_context; 1907 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 1908 || 1909 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 1910 && pMac->sap.sapCtxList[intf].sap_context != NULL) { 1911 sap_context->isCacStartNotified = false; 1912 sap_context->isCacEndNotified = false; 1913 } 1914 } 1915 } 1916 1917 /*========================================================================== 1918 FUNCTION sap_cac_start_notify 1919 1920 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event 1921 to HDD 1922 1923 DEPENDENCIES PARAMETERS 1924 IN hHAL : HAL pointer 1925 1926 RETURN VALUE : QDF_STATUS. 1927 1928 SIDE EFFECTS 1929 ============================================================================*/ 1930 static QDF_STATUS sap_cac_start_notify(tHalHandle hHal) 1931 { 1932 uint8_t intf = 0; 1933 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1934 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1935 1936 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 1937 struct sap_context *sap_context = 1938 pMac->sap.sapCtxList[intf].sap_context; 1939 struct csr_roam_profile *profile; 1940 1941 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 1942 || 1943 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 1944 && pMac->sap.sapCtxList[intf].sap_context != NULL && 1945 (false == sap_context->isCacStartNotified)) { 1946 /* Don't start CAC for non-dfs channel, its violation */ 1947 profile = &sap_context->csr_roamProfile; 1948 if (!wlan_reg_is_dfs_ch(pMac->pdev, 1949 profile->operationChannel)) 1950 continue; 1951 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 1952 "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]", 1953 sap_context); 1954 1955 qdf_status = sap_signal_hdd_event(sap_context, NULL, 1956 eSAP_DFS_CAC_START, 1957 (void *) 1958 eSAP_STATUS_SUCCESS); 1959 if (QDF_STATUS_SUCCESS != qdf_status) { 1960 QDF_TRACE(QDF_MODULE_ID_SAP, 1961 QDF_TRACE_LEVEL_ERROR, 1962 "In %s, failed setting isCacStartNotified on interface[%d]", 1963 __func__, intf); 1964 return qdf_status; 1965 } 1966 sap_context->isCacStartNotified = true; 1967 } 1968 } 1969 return qdf_status; 1970 } 1971 1972 /** 1973 * wlansap_update_pre_cac_end() - Update pre cac end to upper layer 1974 * @sap_context: SAP context 1975 * @mac: Global MAC structure 1976 * @intf: Interface number 1977 * 1978 * Notifies pre cac end to upper layer 1979 * 1980 * Return: QDF_STATUS 1981 */ 1982 static QDF_STATUS wlansap_update_pre_cac_end(struct sap_context *sap_context, 1983 tpAniSirGlobal mac, uint8_t intf) 1984 { 1985 QDF_STATUS qdf_status; 1986 1987 sap_context->isCacEndNotified = true; 1988 mac->sap.SapDfsInfo.sap_radar_found_status = false; 1989 sap_context->sapsMachine = eSAP_STARTED; 1990 1991 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1992 "In %s, pre cac end notify on %d: from state %s => %s", 1993 __func__, intf, "eSAP_DFS_CAC_WAIT", 1994 "eSAP_STARTED"); 1995 1996 qdf_status = sap_signal_hdd_event(sap_context, 1997 NULL, eSAP_DFS_PRE_CAC_END, 1998 (void *)eSAP_STATUS_SUCCESS); 1999 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2000 QDF_TRACE(QDF_MODULE_ID_SAP, 2001 QDF_TRACE_LEVEL_ERROR, 2002 "In %s, pre cac notify failed on intf %d", 2003 __func__, intf); 2004 return qdf_status; 2005 } 2006 2007 return QDF_STATUS_SUCCESS; 2008 } 2009 2010 /*========================================================================== 2011 FUNCTION sap_cac_end_notify 2012 2013 DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event 2014 to HDD 2015 2016 DEPENDENCIES PARAMETERS 2017 IN hHAL : HAL pointer 2018 2019 RETURN VALUE : QDF_STATUS. 2020 2021 SIDE EFFECTS 2022 ============================================================================*/ 2023 static QDF_STATUS sap_cac_end_notify(tHalHandle hHal, 2024 struct csr_roam_info *roamInfo) 2025 { 2026 uint8_t intf; 2027 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2028 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2029 2030 /* 2031 * eSAP_DFS_CHANNEL_CAC_END: 2032 * CAC Period elapsed and there was no radar 2033 * found so, SAP can continue beaconing. 2034 * sap_radar_found_status is set to 0 2035 */ 2036 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2037 struct sap_context *sap_context = 2038 pMac->sap.sapCtxList[intf].sap_context; 2039 struct csr_roam_profile *profile; 2040 2041 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 2042 || 2043 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 2044 && pMac->sap.sapCtxList[intf].sap_context != NULL && 2045 (false == sap_context->isCacEndNotified) && 2046 (sap_context->sapsMachine == eSAP_DFS_CAC_WAIT)) { 2047 sap_context = pMac->sap.sapCtxList[intf].sap_context; 2048 /* Don't check CAC for non-dfs channel */ 2049 profile = &sap_context->csr_roamProfile; 2050 if (!wlan_reg_is_dfs_ch(pMac->pdev, 2051 profile->operationChannel)) 2052 continue; 2053 2054 /* If this is an end notification of a pre cac, the 2055 * SAP must not start beaconing and must delete the 2056 * temporary interface created for pre cac and switch 2057 * the original SAP to the pre CAC channel. 2058 */ 2059 if (sap_context->is_pre_cac_on) { 2060 qdf_status = wlansap_update_pre_cac_end( 2061 sap_context, pMac, intf); 2062 if (QDF_IS_STATUS_ERROR(qdf_status)) 2063 return qdf_status; 2064 /* pre CAC is not allowed with any concurrency. 2065 * So, we can break from here. 2066 */ 2067 break; 2068 } 2069 2070 qdf_status = sap_signal_hdd_event(sap_context, NULL, 2071 eSAP_DFS_CAC_END, 2072 (void *) 2073 eSAP_STATUS_SUCCESS); 2074 if (QDF_STATUS_SUCCESS != qdf_status) { 2075 QDF_TRACE(QDF_MODULE_ID_SAP, 2076 QDF_TRACE_LEVEL_ERROR, 2077 "In %s, failed setting isCacEndNotified on interface[%d]", 2078 __func__, intf); 2079 return qdf_status; 2080 } 2081 sap_context->isCacEndNotified = true; 2082 pMac->sap.SapDfsInfo.sap_radar_found_status = false; 2083 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2084 "sapdfs: Start beacon request on sapctx[%pK]", 2085 sap_context); 2086 2087 /* Start beaconing on the new channel */ 2088 wlansap_start_beacon_req(sap_context); 2089 2090 /* Transition from eSAP_STARTING to eSAP_STARTED 2091 * (both without substates) 2092 */ 2093 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2094 "sapdfs: channel[%d] from state %s => %s", 2095 sap_context->channel, "eSAP_STARTING", 2096 "eSAP_STARTED"); 2097 2098 sap_context->sapsMachine = eSAP_STARTED; 2099 2100 /*Action code for transition */ 2101 qdf_status = sap_signal_hdd_event(sap_context, roamInfo, 2102 eSAP_START_BSS_EVENT, 2103 (void *) 2104 eSAP_STATUS_SUCCESS); 2105 if (QDF_STATUS_SUCCESS != qdf_status) { 2106 QDF_TRACE(QDF_MODULE_ID_SAP, 2107 QDF_TRACE_LEVEL_ERROR, 2108 "In %s, failed setting isCacEndNotified on interface[%d]", 2109 __func__, intf); 2110 return qdf_status; 2111 } 2112 2113 /* Transition from eSAP_STARTING to eSAP_STARTED 2114 * (both without substates) 2115 */ 2116 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2117 "In %s, from state %s => %s", 2118 __func__, "eSAP_DFS_CAC_WAIT", 2119 "eSAP_STARTED"); 2120 } 2121 } 2122 /* 2123 * All APs are done with CAC timer, all APs should start beaconing. 2124 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets 2125 * say AP1 goes down and comes back on same DFS channel. In this case 2126 * AP1 shouldn't start CAC timer and start beacon immediately beacause 2127 * AP2 is already beaconing on this channel. This case will be handled 2128 * by checking against eSAP_DFS_SKIP_CAC while starting the timer. 2129 */ 2130 pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC; 2131 return qdf_status; 2132 } 2133 2134 /** 2135 * sap_fsm_state_disconnected() - utility function called from sap fsm 2136 * @sap_ctx: SAP context 2137 * @sap_event: SAP event buffer 2138 * @mac_ctx: global MAC context 2139 * @hal: HAL handle 2140 * 2141 * This function is called for state transition from "eSAP_DISCONNECTED" 2142 * 2143 * Return: QDF_STATUS 2144 */ 2145 static QDF_STATUS sap_fsm_state_disconnected(struct sap_context *sap_ctx, 2146 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2147 tHalHandle hal) 2148 { 2149 uint32_t msg = sap_event->event; 2150 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2151 2152 if (msg == eSAP_HDD_START_INFRA_BSS) { 2153 /* 2154 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT 2155 * (both without substates) 2156 */ 2157 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2158 FL("new from state %s => %s: session:%d"), 2159 "eSAP_DISCONNECTED", "eSAP_CH_SELECT", 2160 sap_ctx->sessionId); 2161 2162 /* init dfs channel nol */ 2163 sap_init_dfs_channel_nol_list(sap_ctx); 2164 2165 /* Set SAP device role */ 2166 sap_ctx->sapsMachine = eSAP_CH_SELECT; 2167 2168 /* 2169 * Perform sme_ScanRequest. This scan request is post start bss 2170 * request so, set the third to false. 2171 */ 2172 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 2173 true); 2174 } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { 2175 /* 2176 * No need of state check here, caller is expected to perform 2177 * the checks before sending the event 2178 */ 2179 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 2180 2181 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2182 FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT")); 2183 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) { 2184 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2185 FL("sapdfs: starting dfs cac timer on sapctx[%pK]"), 2186 sap_ctx); 2187 sap_start_dfs_cac_timer(sap_ctx); 2188 } 2189 2190 qdf_status = sap_cac_start_notify(hal); 2191 } else if (msg == eSAP_CHANNEL_SELECTION_RETRY) { 2192 /* Set SAP device role */ 2193 sap_ctx->sapsMachine = eSAP_CH_SELECT; 2194 2195 /* 2196 * Perform sme_ScanRequest. This scan request is post start bss 2197 * request so, set the third to false. 2198 */ 2199 qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false, 2200 false); 2201 } else { 2202 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2203 FL("in state %s, event msg %d"), 2204 "eSAP_DISCONNECTED", msg); 2205 } 2206 2207 return qdf_status; 2208 } 2209 2210 /** 2211 * sap_fsm_state_ch_select() - utility function called from sap fsm 2212 * @sap_ctx: SAP context 2213 * @sap_event: SAP event buffer 2214 * @mac_ctx: global MAC context 2215 * @hal: HAL handle 2216 * 2217 * This function is called for state transition from "eSAP_CH_SELECT" 2218 * 2219 * Return: QDF_STATUS 2220 */ 2221 static QDF_STATUS sap_fsm_state_ch_select(struct sap_context *sap_ctx, 2222 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2223 tHalHandle hal) 2224 { 2225 uint32_t msg = sap_event->event; 2226 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2227 bool b_leak_chan = false; 2228 uint8_t temp_chan; 2229 2230 if (msg == eSAP_MAC_SCAN_COMPLETE) { 2231 temp_chan = sap_ctx->channel; 2232 utils_dfs_mark_leaking_ch(mac_ctx->pdev, 2233 sap_ctx->ch_params.ch_width, 2234 1, &temp_chan); 2235 2236 /* 2237 * if selelcted channel has leakage to channels 2238 * in NOL, the temp_chan will be reset 2239 */ 2240 b_leak_chan = (temp_chan != sap_ctx->channel); 2241 /* 2242 * check if channel is in DFS_NOL or if the channel 2243 * has leakage to the channels in NOL 2244 */ 2245 if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel, 2246 PHY_CHANNEL_BONDING_STATE_MAX) || b_leak_chan) { 2247 uint8_t ch; 2248 2249 /* find a new available channel */ 2250 ch = sap_random_channel_sel(sap_ctx); 2251 if (ch == 0) { 2252 /* No available channel found */ 2253 QDF_TRACE(QDF_MODULE_ID_SAP, 2254 QDF_TRACE_LEVEL_ERROR, 2255 FL("No available channel found!!!")); 2256 sap_signal_hdd_event(sap_ctx, NULL, 2257 eSAP_DFS_NO_AVAILABLE_CHANNEL, 2258 (void *)eSAP_STATUS_SUCCESS); 2259 return QDF_STATUS_E_FAULT; 2260 } 2261 2262 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2263 FL("channel %d is in NOL, StartBss on new channel %d"), 2264 sap_ctx->channel, ch); 2265 2266 sap_ctx->channel = ch; 2267 wlan_reg_set_channel_params(mac_ctx->pdev, 2268 sap_ctx->channel, 2269 sap_ctx->secondary_ch, 2270 &sap_ctx->ch_params); 2271 } 2272 if (sap_ctx->channel > 14 && 2273 (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g || 2274 sap_ctx->csr_roamProfile.phyMode == 2275 eCSR_DOT11_MODE_11g_ONLY)) 2276 sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a; 2277 2278 /* 2279 * when AP2 is started while AP1 is performing ACS, we may not 2280 * have the AP1 channel yet.So here after the completion of AP2 2281 * ACS check if AP1 ACS resulting channel is DFS and if yes 2282 * override AP2 ACS scan result with AP1 DFS channel 2283 */ 2284 if (policy_mgr_concurrent_beaconing_sessions_running( 2285 mac_ctx->psoc)) { 2286 uint16_t con_ch; 2287 2288 con_ch = sme_get_concurrent_operation_channel(hal); 2289 if (con_ch && wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch)) 2290 sap_ctx->channel = con_ch; 2291 } 2292 2293 /* 2294 * Transition from eSAP_CH_SELECT to eSAP_STARTING 2295 * (both without substates) 2296 */ 2297 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2298 FL("from state %s => %s"), 2299 "eSAP_CH_SELECT", "eSAP_STARTING"); 2300 /* Channel selected. Now can sap_goto_starting */ 2301 sap_ctx->sapsMachine = eSAP_STARTING; 2302 /* Specify the channel */ 2303 sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels = 2304 1; 2305 sap_ctx->csr_roamProfile.ChannelInfo.ChannelList = 2306 &sap_ctx->csr_roamProfile.operationChannel; 2307 sap_ctx->csr_roamProfile.operationChannel = 2308 (uint8_t) sap_ctx->channel; 2309 sap_ctx->csr_roamProfile.ch_params.ch_width = 2310 sap_ctx->ch_params.ch_width; 2311 sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 = 2312 sap_ctx->ch_params.center_freq_seg0; 2313 sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 = 2314 sap_ctx->ch_params.center_freq_seg1; 2315 sap_ctx->csr_roamProfile.ch_params.sec_ch_offset = 2316 sap_ctx->ch_params.sec_ch_offset; 2317 sap_get_cac_dur_dfs_region(sap_ctx, 2318 &sap_ctx->csr_roamProfile.cac_duration_ms, 2319 &sap_ctx->csr_roamProfile.dfs_regdomain); 2320 sap_ctx->csr_roamProfile.beacon_tx_rate = 2321 sap_ctx->beacon_tx_rate; 2322 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2323 FL("notify hostapd about channel selection: %d"), 2324 sap_ctx->channel); 2325 sap_signal_hdd_event(sap_ctx, NULL, 2326 eSAP_CHANNEL_CHANGE_EVENT, 2327 (void *) eSAP_STATUS_SUCCESS); 2328 sap_dfs_set_current_channel(sap_ctx); 2329 qdf_status = sap_goto_starting(sap_ctx, sap_event, 2330 eCSR_BSS_TYPE_INFRA_AP); 2331 } else if (msg == eSAP_CHANNEL_SELECTION_FAILED) { 2332 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2333 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2334 FL("Cannot start BSS, ACS Fail")); 2335 sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT, 2336 (void *)eSAP_STATUS_FAILURE); 2337 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 2338 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2339 sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT, 2340 (void *)eSAP_STATUS_FAILURE); 2341 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2342 "%s: BSS stopped when Ch select in Progress", __func__); 2343 } else { 2344 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2345 FL("in state %s, invalid event msg %d"), 2346 "eSAP_CH_SELECT", msg); 2347 } 2348 2349 return qdf_status; 2350 } 2351 2352 /** 2353 * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm 2354 * @sap_ctx: SAP context 2355 * @sap_event: SAP event buffer 2356 * @mac_ctx: global MAC context 2357 * @hal: HAL handle 2358 * 2359 * This function is called for state transition from "eSAP_DFS_CAC_WAIT" 2360 * 2361 * Return: QDF_STATUS 2362 */ 2363 static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx, 2364 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2365 tHalHandle hal) 2366 { 2367 uint32_t msg = sap_event->event; 2368 struct csr_roam_info *roam_info = 2369 (struct csr_roam_info *) (sap_event->params); 2370 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2371 2372 if (msg == eSAP_DFS_CHANNEL_CAC_START) { 2373 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2374 FL("from state %s => %s"), 2375 "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT"); 2376 if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) 2377 sap_start_dfs_cac_timer(sap_ctx); 2378 qdf_status = sap_cac_start_notify(hal); 2379 } else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) { 2380 uint8_t intf; 2381 /* 2382 * Radar found while performing channel availability 2383 * check, need to switch the channel again 2384 */ 2385 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2386 "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n"); 2387 if (mac_ctx->sap.SapDfsInfo.target_channel) { 2388 wlan_reg_set_channel_params(mac_ctx->pdev, 2389 mac_ctx->sap.SapDfsInfo.target_channel, 0, 2390 &sap_ctx->ch_params); 2391 } else { 2392 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2393 FL("Invalid target channel %d"), 2394 mac_ctx->sap.SapDfsInfo.target_channel); 2395 return qdf_status; 2396 } 2397 2398 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2399 struct sap_context *t_sap_ctx; 2400 struct csr_roam_profile *profile; 2401 2402 t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context; 2403 if (((QDF_SAP_MODE == 2404 mac_ctx->sap.sapCtxList[intf].sapPersona) || 2405 (QDF_P2P_GO_MODE == 2406 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 2407 t_sap_ctx != NULL && 2408 t_sap_ctx->sapsMachine != eSAP_DISCONNECTED) { 2409 profile = &t_sap_ctx->csr_roamProfile; 2410 if (!wlan_reg_is_passive_or_disable_ch( 2411 mac_ctx->pdev, 2412 profile->operationChannel)) 2413 continue; 2414 /* SAP to be moved to DISCONNECTING state */ 2415 t_sap_ctx->sapsMachine = eSAP_DISCONNECTING; 2416 /* 2417 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: 2418 * A Radar is found on current DFS Channel 2419 * while in CAC WAIT period So, do a channel 2420 * switch to randomly selected target channel. 2421 * Send the Channel change message to SME/PE. 2422 * sap_radar_found_status is set to 1 2423 */ 2424 wlansap_channel_change_request( 2425 t_sap_ctx, 2426 mac_ctx->sap.SapDfsInfo.target_channel); 2427 } 2428 } 2429 } else if (msg == eSAP_DFS_CHANNEL_CAC_END) { 2430 qdf_status = sap_cac_end_notify(hal, roam_info); 2431 } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { 2432 /* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */ 2433 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2434 FL("from state %s => %s"), 2435 "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING"); 2436 2437 /* 2438 * Stop the CAC timer only in following conditions 2439 * single AP: if there is a single AP then stop the timer 2440 * mulitple APs: incase of multiple APs, make sure that 2441 * all APs are down. 2442 */ 2443 if (NULL == sap_find_valid_concurrent_session(hal)) { 2444 QDF_TRACE(QDF_MODULE_ID_SAP, 2445 QDF_TRACE_LEVEL_INFO_MED, 2446 FL("sapdfs: no sessions are valid, stopping timer")); 2447 sap_stop_dfs_cac_timer(sap_ctx); 2448 } 2449 2450 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 2451 qdf_status = sap_goto_disconnecting(sap_ctx); 2452 } else { 2453 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2454 FL("in state %s, invalid event msg %d"), 2455 "eSAP_DFS_CAC_WAIT", msg); 2456 } 2457 2458 return qdf_status; 2459 } 2460 2461 /** 2462 * sap_fsm_state_starting() - utility function called from sap fsm 2463 * @sap_ctx: SAP context 2464 * @sap_event: SAP event buffer 2465 * @mac_ctx: global MAC context 2466 * @hal: HAL handle 2467 * 2468 * This function is called for state transition from "eSAP_STARTING" 2469 * 2470 * Return: QDF_STATUS 2471 */ 2472 static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, 2473 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2474 tHalHandle hal) 2475 { 2476 uint32_t msg = sap_event->event; 2477 struct csr_roam_info *roam_info = 2478 (struct csr_roam_info *) (sap_event->params); 2479 tSapDfsInfo *sap_dfs_info; 2480 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2481 uint8_t is_dfs = false; 2482 2483 if (msg == eSAP_MAC_START_BSS_SUCCESS) { 2484 /* 2485 * Transition from eSAP_STARTING to eSAP_STARTED 2486 * (both without substates) 2487 */ 2488 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2489 FL("from state channel = %d %s => %s ch_width %d"), 2490 sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED", 2491 sap_ctx->ch_params.ch_width); 2492 sap_ctx->sapsMachine = eSAP_STARTED; 2493 2494 /* Action code for transition */ 2495 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 2496 eSAP_START_BSS_EVENT, 2497 (void *) eSAP_STATUS_SUCCESS); 2498 2499 /* 2500 * The upper layers have been informed that AP is up and 2501 * running, however, the AP is still not beaconing, until 2502 * CAC is done if the operating channel is DFS 2503 */ 2504 if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { 2505 is_dfs = true; 2506 } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { 2507 if (wlan_reg_get_channel_state(mac_ctx->pdev, 2508 sap_ctx->channel) == 2509 CHANNEL_STATE_DFS || 2510 wlan_reg_get_channel_state(mac_ctx->pdev, 2511 sap_ctx->ch_params.center_freq_seg1 - 2512 SIR_80MHZ_START_CENTER_CH_DIFF) == 2513 CHANNEL_STATE_DFS) 2514 is_dfs = true; 2515 } else { 2516 if (wlan_reg_get_channel_state(mac_ctx->pdev, 2517 sap_ctx->channel) == 2518 CHANNEL_STATE_DFS) 2519 is_dfs = true; 2520 } 2521 2522 if (is_dfs) { 2523 sap_dfs_info = &mac_ctx->sap.SapDfsInfo; 2524 if ((false == sap_dfs_info->ignore_cac) && 2525 (eSAP_DFS_DO_NOT_SKIP_CAC == 2526 sap_dfs_info->cac_state) && 2527 !sap_ctx->pre_cac_complete) { 2528 /* Move the device in CAC_WAIT_STATE */ 2529 sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT; 2530 2531 /* 2532 * Need to stop the OS transmit queues, 2533 * so that no traffic can flow down the stack 2534 */ 2535 2536 /* Start CAC wait timer */ 2537 if (sap_dfs_info->is_dfs_cac_timer_running != 2538 true) 2539 sap_start_dfs_cac_timer(sap_ctx); 2540 qdf_status = sap_cac_start_notify(hal); 2541 2542 } else { 2543 wlansap_start_beacon_req(sap_ctx); 2544 } 2545 } 2546 } else if (msg == eSAP_MAC_START_FAILS || 2547 msg == eSAP_HDD_STOP_INFRA_BSS) { 2548 /* 2549 * Transition from eSAP_STARTING to eSAP_DISCONNECTED 2550 * (both without substates) 2551 */ 2552 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2553 FL("from state %s => %s"), 2554 "eSAP_STARTING", "eSAP_DISCONNECTED"); 2555 2556 /* Advance outer statevar */ 2557 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2558 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 2559 eSAP_START_BSS_EVENT, 2560 (void *) eSAP_STATUS_FAILURE); 2561 qdf_status = sap_goto_disconnected(sap_ctx); 2562 /* Close the SME session */ 2563 } else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) { 2564 /* The operating channel has changed, update hostapd */ 2565 sap_ctx->channel = 2566 (uint8_t) mac_ctx->sap.SapDfsInfo.target_channel; 2567 2568 sap_ctx->sapsMachine = eSAP_STARTED; 2569 2570 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2571 FL("from state %s => %s"), 2572 "eSAP_STARTING", "eSAP_STARTED"); 2573 2574 /* Indicate change in the state to upper layers */ 2575 qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, 2576 eSAP_START_BSS_EVENT, 2577 (void *)eSAP_STATUS_SUCCESS); 2578 } else { 2579 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2580 FL("in state %s, invalid event msg %d"), 2581 "eSAP_STARTING", msg); 2582 } 2583 2584 return qdf_status; 2585 } 2586 2587 /** 2588 * sap_fsm_state_started() - utility function called from sap fsm 2589 * @sap_ctx: SAP context 2590 * @sap_event: SAP event buffer 2591 * @mac_ctx: global MAC context 2592 * 2593 * This function is called for state transition from "eSAP_STARTED" 2594 * 2595 * Return: QDF_STATUS 2596 */ 2597 static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, 2598 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx) 2599 { 2600 uint32_t msg = sap_event->event; 2601 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2602 2603 if (msg == eSAP_HDD_STOP_INFRA_BSS) { 2604 /* 2605 * Transition from eSAP_STARTED to eSAP_DISCONNECTING 2606 * (both without substates) 2607 */ 2608 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2609 FL("from state %s => %s"), 2610 "eSAP_STARTED", "eSAP_DISCONNECTING"); 2611 sap_ctx->sapsMachine = eSAP_DISCONNECTING; 2612 qdf_status = sap_goto_disconnecting(sap_ctx); 2613 } else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) { 2614 uint8_t intf; 2615 if (!mac_ctx->sap.SapDfsInfo.target_channel) { 2616 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2617 FL("Invalid target channel %d"), 2618 mac_ctx->sap.SapDfsInfo.target_channel); 2619 return qdf_status; 2620 } 2621 2622 /* 2623 * Radar is seen on the current operating channel 2624 * send CSA IE for all associated stations 2625 * Request for CSA IE transmission 2626 */ 2627 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 2628 struct sap_context *temp_sap_ctx; 2629 struct csr_roam_profile *profile; 2630 2631 if (((QDF_SAP_MODE == 2632 mac_ctx->sap.sapCtxList[intf].sapPersona) || 2633 (QDF_P2P_GO_MODE == 2634 mac_ctx->sap.sapCtxList[intf].sapPersona)) && 2635 mac_ctx->sap.sapCtxList[intf].sap_context != NULL) { 2636 temp_sap_ctx = 2637 mac_ctx->sap.sapCtxList[intf].sap_context; 2638 /* 2639 * Radar won't come on non-dfs channel, so 2640 * no need to move them 2641 */ 2642 profile = &temp_sap_ctx->csr_roamProfile; 2643 if (!wlan_reg_is_passive_or_disable_ch( 2644 mac_ctx->pdev, 2645 profile->operationChannel)) 2646 continue; 2647 QDF_TRACE(QDF_MODULE_ID_SAP, 2648 QDF_TRACE_LEVEL_INFO_MED, 2649 FL("sapdfs: Sending CSAIE for sapctx[%pK]"), 2650 temp_sap_ctx); 2651 2652 qdf_status = 2653 wlansap_dfs_send_csa_ie_request(temp_sap_ctx); 2654 } 2655 } 2656 } else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) { 2657 enum QDF_OPMODE persona; 2658 2659 if (!sap_ctx) { 2660 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2661 FL("Invalid sap_ctx")); 2662 return qdf_status; 2663 } 2664 2665 persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId]. 2666 sapPersona; 2667 2668 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2669 FL("app trigger chan switch: mode:%d vdev:%d"), 2670 persona, sap_ctx->sessionId); 2671 2672 if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona)) 2673 qdf_status = wlansap_dfs_send_csa_ie_request(sap_ctx); 2674 } else { 2675 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2676 FL("in state %s, invalid event msg %d"), 2677 "eSAP_STARTED", msg); 2678 } 2679 2680 return qdf_status; 2681 } 2682 2683 /** 2684 * sap_fsm_state_disconnecting() - utility function called from sap fsm 2685 * @sap_ctx: SAP context 2686 * @sap_event: SAP event buffer 2687 * @mac_ctx: global MAC context 2688 * 2689 * This function is called for state transition from "eSAP_DISCONNECTING" 2690 * 2691 * Return: QDF_STATUS 2692 */ 2693 static QDF_STATUS sap_fsm_state_disconnecting(struct sap_context *sap_ctx, 2694 ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx, 2695 tHalHandle hal) 2696 { 2697 uint32_t msg = sap_event->event; 2698 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2699 2700 if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) { 2701 /* 2702 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED 2703 * (both without substates) 2704 */ 2705 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2706 FL("from state %s => %s"), 2707 "eSAP_DISCONNECTING", "eSAP_DISCONNECTED"); 2708 sap_ctx->sapsMachine = eSAP_DISCONNECTED; 2709 2710 /* Close the SME session */ 2711 qdf_status = sap_signal_hdd_event(sap_ctx, NULL, 2712 eSAP_STOP_BSS_EVENT, 2713 (void *)eSAP_STATUS_SUCCESS); 2714 } else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) { 2715 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 2716 FL("sapdfs: Send channel change request on sapctx[%pK]"), 2717 sap_ctx); 2718 2719 sap_get_cac_dur_dfs_region(sap_ctx, 2720 &sap_ctx->csr_roamProfile.cac_duration_ms, 2721 &sap_ctx->csr_roamProfile.dfs_regdomain); 2722 /* 2723 * Most likely, radar has been detected and SAP wants to 2724 * change the channel 2725 */ 2726 qdf_status = wlansap_channel_change_request(sap_ctx, 2727 mac_ctx->sap.SapDfsInfo.target_channel); 2728 2729 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2730 FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ")); 2731 } else if (msg == eWNI_SME_CHANNEL_CHANGE_RSP) { 2732 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2733 FL("in state %s, event msg %d result %d"), 2734 "eSAP_DISCONNECTING ", msg, sap_event->u2); 2735 if (sap_event->u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE) 2736 qdf_status = sap_goto_disconnecting(sap_ctx); 2737 } else if ((msg == eSAP_HDD_STOP_INFRA_BSS) && 2738 (sap_ctx->is_chan_change_inprogress)) { 2739 /* stop bss is received while processing channel change */ 2740 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2741 FL("in state %s, event msg %d result %d"), 2742 "eSAP_DISCONNECTING ", msg, sap_event->u2); 2743 qdf_status = sap_goto_disconnecting(sap_ctx); 2744 } else { 2745 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2746 FL("in state %s, invalid event msg %d"), 2747 "eSAP_DISCONNECTING", msg); 2748 } 2749 2750 return qdf_status; 2751 } 2752 2753 /** 2754 * sap_fsm() - SAP statem machine entry function 2755 * @sap_ctx: SAP context 2756 * @sap_event: SAP event 2757 * 2758 * SAP statem machine entry function 2759 * 2760 * Return: QDF_STATUS 2761 */ 2762 QDF_STATUS sap_fsm(struct sap_context *sap_ctx, ptWLAN_SAPEvent sap_event) 2763 { 2764 /* 2765 * Retrieve the phy link state machine structure 2766 * from the sap_ctx value 2767 * state var that keeps track of state machine 2768 */ 2769 eSapFsmStates_t state_var = sap_ctx->sapsMachine; 2770 uint32_t msg = sap_event->event; /* State machine input event message */ 2771 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2772 tHalHandle hal = CDS_GET_HAL_CB(); 2773 tpAniSirGlobal mac_ctx; 2774 2775 if (NULL == hal) { 2776 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2777 FL("Invalid hal")); 2778 return QDF_STATUS_E_FAILURE; 2779 } 2780 2781 mac_ctx = PMAC_STRUCT(hal); 2782 if (NULL == mac_ctx) { 2783 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2784 FL("Invalid MAC context")); 2785 return QDF_STATUS_E_FAILURE; 2786 } 2787 2788 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 2789 FL("sap_ctx=%pK, state_var=%d, msg=0x%x"), 2790 sap_ctx, state_var, msg); 2791 2792 switch (state_var) { 2793 case eSAP_DISCONNECTED: 2794 qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event, 2795 mac_ctx, hal); 2796 break; 2797 2798 case eSAP_CH_SELECT: 2799 qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event, 2800 mac_ctx, hal); 2801 break; 2802 2803 case eSAP_DFS_CAC_WAIT: 2804 qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event, 2805 mac_ctx, hal); 2806 break; 2807 2808 case eSAP_STARTING: 2809 qdf_status = sap_fsm_state_starting(sap_ctx, sap_event, 2810 mac_ctx, hal); 2811 break; 2812 2813 case eSAP_STARTED: 2814 qdf_status = sap_fsm_state_started(sap_ctx, sap_event, 2815 mac_ctx); 2816 break; 2817 2818 case eSAP_DISCONNECTING: 2819 qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event, 2820 mac_ctx, hal); 2821 break; 2822 } 2823 return qdf_status; 2824 } 2825 2826 eSapStatus 2827 sapconvert_to_csr_profile(tsap_config_t *pconfig_params, eCsrRoamBssType bssType, 2828 struct csr_roam_profile *profile) 2829 { 2830 /* Create Roam profile for SoftAP to connect */ 2831 profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; 2832 profile->SSIDs.numOfSSIDs = 1; 2833 profile->csrPersona = pconfig_params->persona; 2834 profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch; 2835 2836 qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, 2837 sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); 2838 2839 /* Flag to not broadcast the SSID information */ 2840 profile->SSIDs.SSIDList[0].ssidHidden = 2841 pconfig_params->SSIDinfo.ssidHidden; 2842 2843 profile->SSIDs.SSIDList[0].SSID.length = 2844 pconfig_params->SSIDinfo.ssid.length; 2845 qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, 2846 pconfig_params->SSIDinfo.ssid.ssId, 2847 sizeof(pconfig_params->SSIDinfo.ssid.ssId)); 2848 2849 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 2850 2851 if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 2852 profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; 2853 } else if (pconfig_params->authType == eSAP_SHARED_KEY) { 2854 profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; 2855 } else { 2856 profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; 2857 } 2858 2859 profile->AuthType.numEntries = 1; 2860 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; 2861 2862 /* Always set the Encryption Type */ 2863 profile->EncryptionType.numEntries = 1; 2864 profile->EncryptionType.encryptionType[0] = 2865 pconfig_params->RSNEncryptType; 2866 2867 profile->mcEncryptionType.numEntries = 1; 2868 profile->mcEncryptionType.encryptionType[0] = 2869 pconfig_params->mcRSNEncryptType; 2870 2871 if (pconfig_params->privacy & eSAP_SHARED_KEY) { 2872 profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; 2873 } 2874 2875 profile->privacy = pconfig_params->privacy; 2876 profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq; 2877 2878 if (pconfig_params->authType == eSAP_SHARED_KEY) { 2879 profile->csr80211AuthType = eSIR_SHARED_KEY; 2880 } else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) { 2881 profile->csr80211AuthType = eSIR_OPEN_SYSTEM; 2882 } else { 2883 profile->csr80211AuthType = eSIR_AUTO_SWITCH; 2884 } 2885 2886 /* Initialize we are not going to use it */ 2887 profile->pWPAReqIE = NULL; 2888 profile->nWPAReqIELength = 0; 2889 2890 if (profile->pRSNReqIE) { 2891 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 2892 FL("pRSNReqIE already allocated.")); 2893 qdf_mem_free(profile->pRSNReqIE); 2894 profile->pRSNReqIE = NULL; 2895 } 2896 2897 /* set the RSN/WPA IE */ 2898 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 2899 if (pconfig_params->RSNWPAReqIELength) { 2900 profile->pRSNReqIE = 2901 qdf_mem_malloc(pconfig_params->RSNWPAReqIELength); 2902 if (NULL == profile->pRSNReqIE) { 2903 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2904 " %s Fail to alloc memory", __func__); 2905 return eSAP_STATUS_FAILURE; 2906 } 2907 qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE, 2908 pconfig_params->RSNWPAReqIELength); 2909 profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; 2910 } 2911 2912 /* set the phyMode to accept anything */ 2913 /* Best means everything because it covers all the things we support */ 2914 /* eCSR_DOT11_MODE_BEST */ 2915 profile->phyMode = pconfig_params->SapHw_mode; 2916 2917 /* Configure beaconInterval */ 2918 profile->beaconInterval = (uint16_t) pconfig_params->beacon_int; 2919 2920 /* set DTIM period */ 2921 profile->dtimPeriod = pconfig_params->dtim_period; 2922 2923 /* set Uapsd enable bit */ 2924 profile->ApUapsdEnable = pconfig_params->UapsdEnable; 2925 2926 /* Enable protection parameters */ 2927 profile->protEnabled = pconfig_params->protEnabled; 2928 profile->obssProtEnabled = pconfig_params->obssProtEnabled; 2929 profile->cfg_protection = pconfig_params->ht_capab; 2930 2931 /* country code */ 2932 if (pconfig_params->countryCode[0]) 2933 qdf_mem_copy(profile->countryCode, pconfig_params->countryCode, 2934 WNI_CFG_COUNTRY_CODE_LEN); 2935 profile->ieee80211d = pconfig_params->ieee80211d; 2936 /* wps config info */ 2937 profile->wps_state = pconfig_params->wps_state; 2938 2939 #ifdef WLAN_FEATURE_11W 2940 /* MFP capable/required */ 2941 profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0; 2942 profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; 2943 #endif 2944 2945 if (pconfig_params->probeRespIEsBufferLen > 0 && 2946 pconfig_params->pProbeRespIEsBuffer != NULL) { 2947 profile->addIeParams.probeRespDataLen = 2948 pconfig_params->probeRespIEsBufferLen; 2949 profile->addIeParams.probeRespData_buff = 2950 pconfig_params->pProbeRespIEsBuffer; 2951 } else { 2952 profile->addIeParams.probeRespDataLen = 0; 2953 profile->addIeParams.probeRespData_buff = NULL; 2954 } 2955 /*assoc resp IE */ 2956 if (pconfig_params->assocRespIEsLen > 0 && 2957 pconfig_params->pAssocRespIEsBuffer != NULL) { 2958 profile->addIeParams.assocRespDataLen = 2959 pconfig_params->assocRespIEsLen; 2960 profile->addIeParams.assocRespData_buff = 2961 pconfig_params->pAssocRespIEsBuffer; 2962 } else { 2963 profile->addIeParams.assocRespDataLen = 0; 2964 profile->addIeParams.assocRespData_buff = NULL; 2965 } 2966 2967 if (pconfig_params->probeRespBcnIEsLen > 0 && 2968 pconfig_params->pProbeRespBcnIEsBuffer != NULL) { 2969 profile->addIeParams.probeRespBCNDataLen = 2970 pconfig_params->probeRespBcnIEsLen; 2971 profile->addIeParams.probeRespBCNData_buff = 2972 pconfig_params->pProbeRespBcnIEsBuffer; 2973 } else { 2974 profile->addIeParams.probeRespBCNDataLen = 0; 2975 profile->addIeParams.probeRespBCNData_buff = NULL; 2976 } 2977 profile->sap_dot11mc = pconfig_params->sap_dot11mc; 2978 2979 if (pconfig_params->supported_rates.numRates) { 2980 qdf_mem_copy(profile->supported_rates.rate, 2981 pconfig_params->supported_rates.rate, 2982 pconfig_params->supported_rates.numRates); 2983 profile->supported_rates.numRates = 2984 pconfig_params->supported_rates.numRates; 2985 } 2986 2987 if (pconfig_params->extended_rates.numRates) { 2988 qdf_mem_copy(profile->extended_rates.rate, 2989 pconfig_params->extended_rates.rate, 2990 pconfig_params->extended_rates.numRates); 2991 profile->extended_rates.numRates = 2992 pconfig_params->extended_rates.numRates; 2993 } 2994 2995 profile->chan_switch_hostapd_rate_enabled = 2996 pconfig_params->chan_switch_hostapd_rate_enabled; 2997 2998 return eSAP_STATUS_SUCCESS; /* Success. */ 2999 } 3000 3001 void sap_free_roam_profile(struct csr_roam_profile *profile) 3002 { 3003 if (profile->pRSNReqIE) { 3004 qdf_mem_free(profile->pRSNReqIE); 3005 profile->pRSNReqIE = NULL; 3006 } 3007 } 3008 3009 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size) 3010 { 3011 uint8_t outer, inner; 3012 struct qdf_mac_addr temp; 3013 int32_t nRes = -1; 3014 3015 if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) { 3016 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3017 FL("either buffer is NULL or size = %d is more"), size); 3018 return; 3019 } 3020 3021 for (outer = 0; outer < size; outer++) { 3022 for (inner = 0; inner < size - 1; inner++) { 3023 nRes = 3024 qdf_mem_cmp((macList + inner)->bytes, 3025 (macList + inner + 1)->bytes, 3026 QDF_MAC_ADDR_SIZE); 3027 if (nRes > 0) { 3028 qdf_mem_copy(temp.bytes, 3029 (macList + inner + 1)->bytes, 3030 QDF_MAC_ADDR_SIZE); 3031 qdf_mem_copy((macList + inner + 1)->bytes, 3032 (macList + inner)->bytes, 3033 QDF_MAC_ADDR_SIZE); 3034 qdf_mem_copy((macList + inner)->bytes, 3035 temp.bytes, QDF_MAC_ADDR_SIZE); 3036 } 3037 } 3038 } 3039 } 3040 3041 bool 3042 sap_search_mac_list(struct qdf_mac_addr *macList, 3043 uint8_t num_mac, uint8_t *peerMac, 3044 uint8_t *index) 3045 { 3046 int32_t nRes = -1; 3047 int8_t nStart = 0, nEnd, nMiddle; 3048 3049 nEnd = num_mac - 1; 3050 3051 if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) { 3052 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3053 FL("either buffer is NULL or size = %d is more."), num_mac); 3054 return false; 3055 } 3056 3057 while (nStart <= nEnd) { 3058 nMiddle = (nStart + nEnd) / 2; 3059 nRes = 3060 qdf_mem_cmp(&macList[nMiddle], peerMac, 3061 QDF_MAC_ADDR_SIZE); 3062 3063 if (0 == nRes) { 3064 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3065 "search SUCC"); 3066 /* "index equals NULL" means the caller does not need the */ 3067 /* index value of the peerMac being searched */ 3068 if (index != NULL) { 3069 *index = (uint8_t) nMiddle; 3070 QDF_TRACE(QDF_MODULE_ID_SAP, 3071 QDF_TRACE_LEVEL_INFO_HIGH, "index %d", 3072 *index); 3073 } 3074 return true; 3075 } 3076 if (nRes < 0) 3077 nStart = nMiddle + 1; 3078 else 3079 nEnd = nMiddle - 1; 3080 } 3081 3082 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3083 "search not succ"); 3084 return false; 3085 } 3086 3087 void sap_add_mac_to_acl(struct qdf_mac_addr *macList, 3088 uint8_t *size, uint8_t *peerMac) 3089 { 3090 int32_t nRes = -1; 3091 int i; 3092 3093 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3094 "add acl entered"); 3095 3096 if (NULL == macList || *size > MAX_ACL_MAC_ADDRESS) { 3097 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3098 FL("either buffer is NULL or size = %d is incorrect."), 3099 *size); 3100 return; 3101 } 3102 3103 for (i = ((*size) - 1); i >= 0; i--) { 3104 nRes = 3105 qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE); 3106 if (nRes > 0) { 3107 /* Move alphabetically greater mac addresses one index down to allow for insertion 3108 of new mac in sorted order */ 3109 qdf_mem_copy((macList + i + 1)->bytes, 3110 (macList + i)->bytes, QDF_MAC_ADDR_SIZE); 3111 } else { 3112 break; 3113 } 3114 } 3115 /* This should also take care of if the element is the first to be added in the list */ 3116 qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE); 3117 /* increment the list size */ 3118 (*size)++; 3119 } 3120 3121 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList, 3122 uint8_t *size, uint8_t index) 3123 { 3124 int i; 3125 3126 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3127 "remove acl entered"); 3128 /* 3129 * Return if the list passed is empty. Ideally this should never happen 3130 * since this funcn is always called after sap_search_mac_list to get 3131 * the index of the mac addr to be removed and this will only get 3132 * called if the search is successful. Still no harm in having the check 3133 */ 3134 if ((macList == NULL) || (*size == 0) || 3135 (*size > MAX_ACL_MAC_ADDRESS)) { 3136 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3137 FL("either buffer is NULL or size %d is incorrect."), 3138 *size); 3139 return; 3140 } 3141 for (i = index; i < ((*size) - 1); i++) { 3142 /* Move mac addresses starting from "index" passed one index up to delete the void 3143 created by deletion of a mac address in ACL */ 3144 qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes, 3145 QDF_MAC_ADDR_SIZE); 3146 } 3147 /* The last space should be made empty since all mac addesses moved one step up */ 3148 qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE); 3149 /* reduce the list size by 1 */ 3150 (*size)--; 3151 } 3152 3153 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size) 3154 { 3155 int i; 3156 uint8_t *macArray; 3157 3158 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3159 "print acl entered"); 3160 3161 if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) { 3162 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3163 "In %s, either buffer is NULL or size %d is incorrect.", 3164 __func__, size); 3165 return; 3166 } 3167 3168 for (i = 0; i < size; i++) { 3169 macArray = (macList + i)->bytes; 3170 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3171 "** ACL entry %i - " MAC_ADDRESS_STR, i, 3172 MAC_ADDR_ARRAY(macArray)); 3173 } 3174 return; 3175 } 3176 3177 QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sapContext, 3178 uint8_t *peerMac) 3179 { 3180 if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode) 3181 return QDF_STATUS_SUCCESS; 3182 3183 if (sap_search_mac_list 3184 (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL)) 3185 return QDF_STATUS_SUCCESS; 3186 3187 if (sap_search_mac_list 3188 (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) { 3189 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3190 "In %s, Peer " MAC_ADDRESS_STR " in deny list", 3191 __func__, MAC_ADDR_ARRAY(peerMac)); 3192 return QDF_STATUS_E_FAILURE; 3193 } 3194 /* A new station CAN associate, unless in deny list. Less stringent mode */ 3195 if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode) 3196 return QDF_STATUS_SUCCESS; 3197 3198 /* A new station CANNOT associate, unless in accept list. More stringent mode */ 3199 if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) { 3200 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3201 "In %s, Peer " MAC_ADDRESS_STR 3202 " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", 3203 __func__, MAC_ADDR_ARRAY(peerMac)); 3204 return QDF_STATUS_E_FAILURE; 3205 } 3206 3207 /* The new STA is neither in accept list nor in deny list. In this case, deny the association 3208 * but send a wifi event notification indicating the mac address being denied 3209 */ 3210 if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) { 3211 sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, 3212 (void *) peerMac); 3213 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3214 "In %s, Peer " MAC_ADDRESS_STR 3215 " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", 3216 __func__, MAC_ADDR_ARRAY(peerMac)); 3217 return QDF_STATUS_E_FAILURE; 3218 } 3219 return QDF_STATUS_SUCCESS; 3220 } 3221 3222 #ifdef SOFTAP_CHANNEL_RANGE 3223 /** 3224 * sap_get_channel_list() - get the list of channels 3225 * @sap_ctx: sap context 3226 * @ch_list: pointer to channel list array 3227 * @num_ch: pointer to number of channels. 3228 * 3229 * This function populates the list of channels for scanning. 3230 * 3231 * Return: QDF_STATUS 3232 */ 3233 static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx, 3234 uint8_t **ch_list, 3235 uint8_t *num_ch) 3236 { 3237 uint8_t loop_count; 3238 uint8_t *list; 3239 uint8_t ch_count; 3240 uint8_t start_ch_num, band_start_ch; 3241 uint8_t end_ch_num, band_end_ch; 3242 uint32_t en_lte_coex; 3243 tHalHandle hal = CDS_GET_HAL_CB(); 3244 #ifdef FEATURE_WLAN_CH_AVOID 3245 uint8_t i; 3246 #endif 3247 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 3248 tSapChSelSpectInfo spect_info_obj = { NULL, 0 }; 3249 uint16_t ch_width; 3250 3251 if (NULL == hal) { 3252 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3253 FL("Invalid HAL pointer from p_cds_gctx")); 3254 *num_ch = 0; 3255 *ch_list = NULL; 3256 return QDF_STATUS_E_FAULT; 3257 } 3258 3259 start_ch_num = sap_ctx->acs_cfg->start_ch; 3260 end_ch_num = sap_ctx->acs_cfg->end_ch; 3261 ch_width = sap_ctx->acs_cfg->ch_width; 3262 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3263 FL("startChannel %d, EndChannel %d, ch_width %d, HW:%d"), 3264 start_ch_num, end_ch_num, ch_width, 3265 sap_ctx->acs_cfg->hw_mode); 3266 3267 wlansap_extend_to_acs_range(hal, &start_ch_num, &end_ch_num, 3268 &band_start_ch, &band_end_ch); 3269 3270 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3271 FL("expanded startChannel %d,EndChannel %d"), 3272 start_ch_num, end_ch_num); 3273 3274 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3275 FL("band_start_ch %d, band_end_ch %d"), 3276 band_start_ch, band_end_ch); 3277 3278 sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex); 3279 3280 /* Check if LTE coex is enabled and 2.4GHz is selected */ 3281 if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) && 3282 (band_end_ch == CHAN_ENUM_14)) { 3283 /* Set 2.4GHz upper limit to channel 9 for LTE COEX */ 3284 band_end_ch = CHAN_ENUM_9; 3285 } 3286 3287 /* Allocate the max number of channel supported */ 3288 list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS + 3289 NUM_24GHZ_CHANNELS); 3290 if (NULL == list) { 3291 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3292 FL("Unable to allocate channel list")); 3293 *num_ch = 0; 3294 *ch_list = NULL; 3295 return QDF_STATUS_E_NOMEM; 3296 } 3297 3298 /* Search for the Active channels in the given range */ 3299 ch_count = 0; 3300 for (loop_count = band_start_ch; loop_count <= band_end_ch; 3301 loop_count++) { 3302 /* go to next channel if rf_channel is out of range */ 3303 if ((start_ch_num > WLAN_REG_CH_NUM(loop_count)) || 3304 (end_ch_num < WLAN_REG_CH_NUM(loop_count))) 3305 continue; 3306 /* 3307 * go to next channel if none of these condition pass 3308 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE 3309 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE 3310 */ 3311 if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) && 3312 wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)) || 3313 ((false == mac_ctx->scan.fEnableDFSChnlScan) && 3314 (CHANNEL_STATE_ENABLE == 3315 wlan_reg_get_channel_state(mac_ctx->pdev, loop_count))))) 3316 continue; 3317 3318 /* 3319 * Skip the channels which are not in ACS config from user 3320 * space 3321 */ 3322 if (SAP_CHANNEL_NOT_SELECTED == 3323 sap_channel_in_acs_channel_list( 3324 WLAN_REG_CH_NUM(loop_count), 3325 sap_ctx, &spect_info_obj)) 3326 continue; 3327 /* Dont scan DFS channels in case of MCC disallowed 3328 * As it can result in SAP starting on DFS channel 3329 * resulting MCC on DFS channel 3330 */ 3331 if (wlan_reg_is_dfs_ch(mac_ctx->pdev, 3332 WLAN_REG_CH_NUM(loop_count)) && 3333 policy_mgr_disallow_mcc(mac_ctx->psoc, 3334 WLAN_REG_CH_NUM(loop_count))) 3335 continue; 3336 3337 /* 3338 * If we have any 5Ghz channel in the channel list 3339 * and bw is 40/80/160 Mhz then we don't want SAP to 3340 * come up in 2.4Ghz as for 40Mhz, 2.4Ghz channel is 3341 * not preferred and 80/160Mhz is not allowed for 2.4Ghz 3342 * band. So, don't even scan on 2.4Ghz channels if bw is 3343 * 40/80/160Mhz and channel list has any 5Ghz channel. 3344 */ 3345 if (end_ch_num >= WLAN_REG_CH_NUM(CHAN_ENUM_36) && 3346 ((ch_width == CH_WIDTH_40MHZ) || 3347 (ch_width == CH_WIDTH_80MHZ) || 3348 (ch_width == CH_WIDTH_80P80MHZ) || 3349 (ch_width == CH_WIDTH_160MHZ))) { 3350 if (WLAN_REG_CH_NUM(loop_count) >= 3351 WLAN_REG_CH_NUM(CHAN_ENUM_1) && 3352 WLAN_REG_CH_NUM(loop_count) <= 3353 WLAN_REG_CH_NUM(CHAN_ENUM_14)) 3354 continue; 3355 } 3356 3357 #ifdef FEATURE_WLAN_CH_AVOID 3358 for (i = 0; i < NUM_CHANNELS; i++) { 3359 if (safe_channels[i].channelNumber == 3360 WLAN_REG_CH_NUM(loop_count)) { 3361 /* Check if channel is safe */ 3362 if (true == safe_channels[i].isSafe) { 3363 #endif 3364 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 3365 uint8_t ch; 3366 3367 ch = WLAN_REG_CH_NUM(loop_count); 3368 if ((sap_ctx->acs_cfg->skip_scan_status == 3369 eSAP_DO_PAR_ACS_SCAN)) { 3370 if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch && 3371 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) || 3372 (ch >= sap_ctx->acs_cfg->skip_scan_range2_stch && 3373 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) { 3374 list[ch_count] = 3375 WLAN_REG_CH_NUM(loop_count); 3376 ch_count++; 3377 QDF_TRACE(QDF_MODULE_ID_SAP, 3378 QDF_TRACE_LEVEL_INFO, 3379 FL("%d %d added to ACS ch range"), 3380 ch_count, ch); 3381 } else { 3382 QDF_TRACE(QDF_MODULE_ID_SAP, 3383 QDF_TRACE_LEVEL_INFO_HIGH, 3384 FL("%d %d skipped from ACS ch range"), 3385 ch_count, ch); 3386 } 3387 } else { 3388 list[ch_count] = 3389 WLAN_REG_CH_NUM(loop_count); 3390 ch_count++; 3391 QDF_TRACE(QDF_MODULE_ID_SAP, 3392 QDF_TRACE_LEVEL_INFO, 3393 FL("%d %d added to ACS ch range"), 3394 ch_count, ch); 3395 } 3396 #else 3397 list[ch_count] = WLAN_REG_CH_NUM(loop_count); 3398 ch_count++; 3399 #endif 3400 #ifdef FEATURE_WLAN_CH_AVOID 3401 } 3402 break; 3403 } 3404 } 3405 #endif 3406 } 3407 if (0 == ch_count) { 3408 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3409 FL("No active channels present for the current region")); 3410 /* 3411 * LTE COEX: channel range outside the restricted 2.4GHz 3412 * band limits 3413 */ 3414 if (en_lte_coex && (start_ch_num > band_end_ch)) 3415 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 3416 FL("SAP can't be started as due to LTE COEX")); 3417 } 3418 3419 /* return the channel list and number of channels to scan */ 3420 *num_ch = ch_count; 3421 if (ch_count != 0) { 3422 *ch_list = list; 3423 } else { 3424 *ch_list = NULL; 3425 qdf_mem_free(list); 3426 } 3427 3428 for (loop_count = 0; loop_count < ch_count; loop_count++) { 3429 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 3430 FL("channel number: %d"), list[loop_count]); 3431 } 3432 return QDF_STATUS_SUCCESS; 3433 } 3434 #endif 3435 3436 #ifdef DFS_COMPONENT_ENABLE 3437 uint8_t sap_indicate_radar(struct sap_context *sap_ctx) 3438 { 3439 uint8_t target_channel = 0; 3440 tHalHandle hal; 3441 tpAniSirGlobal mac; 3442 3443 if (!sap_ctx) { 3444 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3445 FL("null sap_ctx")); 3446 return 0; 3447 } 3448 3449 hal = CDS_GET_HAL_CB(); 3450 if (!hal) { 3451 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3452 FL("null hal")); 3453 return 0; 3454 } 3455 3456 mac = PMAC_STRUCT(hal); 3457 3458 /* 3459 * SAP needs to generate Channel Switch IE 3460 * if the radar is found in the STARTED state 3461 */ 3462 if (eSAP_STARTED == sap_ctx->sapsMachine) 3463 mac->sap.SapDfsInfo.csaIERequired = true; 3464 3465 if (sap_ctx->csr_roamProfile.disableDFSChSwitch) 3466 return sap_ctx->channel; 3467 3468 /* set the Radar Found flag in SapDfsInfo */ 3469 mac->sap.SapDfsInfo.sap_radar_found_status = true; 3470 3471 if (sap_ctx->chan_before_pre_cac) { 3472 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3473 FL("sapdfs: set chan before pre cac %d as target chan"), 3474 sap_ctx->chan_before_pre_cac); 3475 return sap_ctx->chan_before_pre_cac; 3476 } 3477 3478 if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS == 3479 sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ, 3480 (void *) eSAP_STATUS_SUCCESS))) 3481 return 0; 3482 3483 target_channel = sap_random_channel_sel(sap_ctx); 3484 if (!target_channel) 3485 sap_signal_hdd_event(sap_ctx, NULL, 3486 eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS); 3487 3488 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, 3489 FL("sapdfs: New selected target channel is [%d]"), 3490 target_channel); 3491 3492 return target_channel; 3493 } 3494 #endif 3495 3496 /* 3497 * CAC timer callback function. 3498 * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm(). 3499 */ 3500 void sap_dfs_cac_timer_callback(void *data) 3501 { 3502 struct sap_context *sapContext; 3503 tWLAN_SAPEvent sapEvent; 3504 tHalHandle hHal = (tHalHandle) data; 3505 tpAniSirGlobal pMac; 3506 3507 if (NULL == hHal) { 3508 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3509 "In %s invalid hHal", __func__); 3510 return; 3511 } 3512 pMac = PMAC_STRUCT(hHal); 3513 sapContext = sap_find_cac_wait_session(hHal); 3514 if (NULL == sapContext) { 3515 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3516 "%s: no SAP contexts in wait state", __func__); 3517 return; 3518 } 3519 3520 /* 3521 * SAP may not be in CAC wait state, when the timer runs out. 3522 * if following flag is set, then timer is in initialized state, 3523 * destroy timer here. 3524 */ 3525 if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) { 3526 if (!sapContext->dfs_cac_offload) 3527 qdf_mc_timer_destroy( 3528 &pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3529 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 3530 } 3531 3532 /* 3533 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm 3534 */ 3535 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3536 "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]", 3537 sapContext->channel, sapContext); 3538 3539 sapEvent.event = eSAP_DFS_CHANNEL_CAC_END; 3540 sapEvent.params = 0; 3541 sapEvent.u1 = 0; 3542 sapEvent.u2 = 0; 3543 3544 sap_fsm(sapContext, &sapEvent); 3545 } 3546 3547 /* 3548 * Function to stop the DFS CAC Timer 3549 */ 3550 static int sap_stop_dfs_cac_timer(struct sap_context *sapContext) 3551 { 3552 tHalHandle hHal; 3553 tpAniSirGlobal pMac; 3554 3555 if (sapContext == NULL) 3556 return 0; 3557 3558 hHal = CDS_GET_HAL_CB(); 3559 if (NULL == hHal) { 3560 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3561 "In %s invalid hHal", __func__); 3562 return 0; 3563 } 3564 pMac = PMAC_STRUCT(hHal); 3565 3566 if (sapContext->dfs_cac_offload) { 3567 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3568 return 0; 3569 } 3570 3571 if (QDF_TIMER_STATE_RUNNING != 3572 qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo. 3573 sap_dfs_cac_timer)) { 3574 return 0; 3575 } 3576 3577 qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3578 pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; 3579 qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); 3580 3581 return 0; 3582 } 3583 3584 3585 /* 3586 * Function to start the DFS CAC Timer 3587 * when SAP is started on a DFS channel 3588 */ 3589 static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx) 3590 { 3591 QDF_STATUS status; 3592 uint32_t cac_dur; 3593 tHalHandle hal = NULL; 3594 tpAniSirGlobal mac = NULL; 3595 enum dfs_reg dfs_region; 3596 3597 if (!sap_ctx) { 3598 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3599 "%s: null sap_ctx", __func__); 3600 return 0; 3601 } 3602 3603 hal = CDS_GET_HAL_CB(); 3604 if (!hal) { 3605 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3606 "%s: null hal", __func__); 3607 return 0; 3608 } 3609 3610 mac = PMAC_STRUCT(hal); 3611 if (sap_ctx->dfs_cac_offload) { 3612 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 3613 "%s: cac timer offloaded to firmware", __func__); 3614 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 3615 return 1; 3616 } 3617 3618 sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region); 3619 if (0 == cac_dur) 3620 return 0; 3621 3622 #ifdef QCA_WIFI_NAPIER_EMULATION 3623 cac_dur = cac_dur / 100; 3624 #endif 3625 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, 3626 "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH-%d, CAC_DUR-%d sec", 3627 sap_ctx->channel, cac_dur / 1000); 3628 3629 qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, 3630 QDF_TIMER_TYPE_SW, 3631 sap_dfs_cac_timer_callback, (void *)hal); 3632 3633 /* Start the CAC timer */ 3634 status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, 3635 cac_dur); 3636 if (status == QDF_STATUS_SUCCESS) { 3637 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true; 3638 return 1; 3639 } else { 3640 mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false; 3641 qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer); 3642 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3643 "%s: failed to start cac timer", __func__); 3644 return 0; 3645 } 3646 } 3647 3648 /* 3649 * This function initializes the NOL list 3650 * parameters required to track the radar 3651 * found DFS channels in the current Reg. Domain . 3652 */ 3653 QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sapContext) 3654 { 3655 tHalHandle hHal; 3656 tpAniSirGlobal pMac; 3657 3658 if (NULL == sapContext) { 3659 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3660 "Invalid sapContext pointer on sap_init_dfs_channel_nol_list"); 3661 return QDF_STATUS_E_FAULT; 3662 } 3663 hHal = CDS_GET_HAL_CB(); 3664 3665 if (NULL == hHal) { 3666 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3667 "In %s invalid hHal", __func__); 3668 return QDF_STATUS_E_FAULT; 3669 } 3670 pMac = PMAC_STRUCT(hHal); 3671 3672 utils_dfs_init_nol(pMac->pdev); 3673 3674 return QDF_STATUS_SUCCESS; 3675 } 3676 3677 /* 3678 * This function will calculate how many interfaces 3679 * have sap persona and returns total number of sap persona. 3680 */ 3681 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal) 3682 { 3683 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3684 uint8_t intf = 0; 3685 uint8_t intf_count = 0; 3686 3687 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3688 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3689 || 3690 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3691 && pMac->sap.sapCtxList[intf].sap_context != NULL) { 3692 intf_count++; 3693 } 3694 } 3695 return intf_count; 3696 } 3697 3698 /** 3699 * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready 3700 * for channel change 3701 * @hHal: HAL pointer 3702 * @sapContext: sap context for which this function has been called 3703 * 3704 * This function will find the concurrent sap context apart from 3705 * passed sap context and return its channel change ready status 3706 * 3707 * 3708 * Return: true if other SAP personas are ready to channel switch else false 3709 */ 3710 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal, 3711 struct sap_context *sapContext) 3712 { 3713 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3714 struct sap_context *sap_context; 3715 uint8_t intf = 0; 3716 3717 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3718 if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona) 3719 || 3720 (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) 3721 && pMac->sap.sapCtxList[intf].sap_context != NULL) { 3722 sap_context = 3723 pMac->sap.sapCtxList[intf].sap_context; 3724 if (sap_context == sapContext) { 3725 QDF_TRACE(QDF_MODULE_ID_SAP, 3726 QDF_TRACE_LEVEL_ERROR, 3727 FL("sapCtx matched [%pK]"), 3728 sapContext); 3729 continue; 3730 } else { 3731 QDF_TRACE(QDF_MODULE_ID_SAP, 3732 QDF_TRACE_LEVEL_ERROR, 3733 FL 3734 ("concurrent sapCtx[%pK] didn't matche with [%pK]"), 3735 sap_context, sapContext); 3736 return sap_context->is_sap_ready_for_chnl_chng; 3737 } 3738 } 3739 } 3740 return false; 3741 } 3742 3743 /** 3744 * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS 3745 * @hal: pointer to hal 3746 * @sap_context: current SAP persona's channel 3747 * 3748 * If provided SAP's channel is DFS then Loop through each SAP or GO persona and 3749 * check if other beaconing entity's channel is same DFS channel. If they are 3750 * same then concurrent sap is doing SCC DFS. 3751 * 3752 * Return: true if two or more beaconing entitity doing SCC DFS else false 3753 */ 3754 bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal, 3755 struct sap_context *given_sapctx) 3756 { 3757 tpAniSirGlobal mac = PMAC_STRUCT(hal); 3758 struct sap_context *sap_ctx; 3759 uint8_t intf = 0, scc_dfs_counter = 0; 3760 3761 /* 3762 * current SAP persona's channel itself is not DFS, so no need to check 3763 * what other persona's channel is 3764 */ 3765 if (!wlan_reg_is_dfs_ch(mac->pdev, 3766 given_sapctx->csr_roamProfile.operationChannel)) { 3767 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 3768 FL("skip this loop as provided channel is non-dfs")); 3769 return false; 3770 } 3771 3772 for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { 3773 if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) && 3774 (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona)) 3775 continue; 3776 if (!mac->sap.sapCtxList[intf].sap_context) 3777 continue; 3778 sap_ctx = mac->sap.sapCtxList[intf].sap_context; 3779 /* if same SAP contexts then skip to next context */ 3780 if (sap_ctx == given_sapctx) 3781 continue; 3782 if (given_sapctx->csr_roamProfile.operationChannel == 3783 sap_ctx->csr_roamProfile.operationChannel) 3784 scc_dfs_counter++; 3785 } 3786 3787 /* Found atleast two of the beaconing entities doing SCC DFS */ 3788 if (scc_dfs_counter) 3789 return true; 3790 3791 return false; 3792 } 3793