1 /* 2 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 /** 29 * =========================================================================== 30 * sapModule.C 31 * OVERVIEW: 32 * This software unit holds the implementation of the WLAN SAP modules 33 * functions providing EXTERNAL APIs. It is also where the global SAP module 34 * context gets initialised 35 * DEPENDENCIES: 36 * Are listed for each API below. 37 * =========================================================================== 38 */ 39 40 /* $Header$ */ 41 42 /*---------------------------------------------------------------------------- 43 * Include Files 44 * -------------------------------------------------------------------------*/ 45 #include "qdf_trace.h" 46 #include "qdf_util.h" 47 #include "qdf_atomic.h" 48 /* Pick up the sme callback registration API */ 49 #include "sme_api.h" 50 51 /* SAP API header file */ 52 53 #include "sap_internal.h" 54 #include "sme_inside.h" 55 #include "cds_ieee80211_common_i.h" 56 #include "cds_regdomain.h" 57 #include "cds_concurrency.h" 58 59 /*---------------------------------------------------------------------------- 60 * Preprocessor Definitions and Constants 61 * -------------------------------------------------------------------------*/ 62 #define SAP_DEBUG 63 64 /*---------------------------------------------------------------------------- 65 * Type Declarations 66 * -------------------------------------------------------------------------*/ 67 68 /*---------------------------------------------------------------------------- 69 * Global Data Definitions 70 * -------------------------------------------------------------------------*/ 71 72 /*---------------------------------------------------------------------------- 73 * External declarations for global context 74 * -------------------------------------------------------------------------*/ 75 /* No! Get this from CDS. */ 76 /* The main per-Physical Link (per WLAN association) context. */ 77 static ptSapContext gp_sap_ctx[SAP_MAX_NUM_SESSION]; 78 static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION]; 79 80 /*---------------------------------------------------------------------------- 81 * Static Variable Definitions 82 * -------------------------------------------------------------------------*/ 83 static qdf_mutex_t sap_context_lock; 84 85 /*---------------------------------------------------------------------------- 86 * Static Function Declarations and Definitions 87 * -------------------------------------------------------------------------*/ 88 89 /*---------------------------------------------------------------------------- 90 * Externalized Function Definitions 91 * -------------------------------------------------------------------------*/ 92 93 /*---------------------------------------------------------------------------- 94 * Function Declarations and Documentation 95 * -------------------------------------------------------------------------*/ 96 97 /** 98 * wlansap_global_init() - Initialize SAP globals 99 * 100 * Initializes the SAP global data structures 101 * 102 * Return: QDF_STATUS 103 */ 104 QDF_STATUS wlansap_global_init(void) 105 { 106 uint32_t i; 107 108 if (QDF_IS_STATUS_ERROR(qdf_mutex_create(&sap_context_lock))) { 109 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 110 "failed to init sap_context_lock"); 111 return QDF_STATUS_E_FAULT; 112 } 113 114 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 115 gp_sap_ctx[i] = NULL; 116 qdf_atomic_init(&sap_ctx_ref_count[i]); 117 } 118 119 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 120 "%s: sap global context initialized", __func__); 121 122 return QDF_STATUS_SUCCESS; 123 } 124 125 /** 126 * wlansap_global_deinit() - De-initialize SAP globals 127 * 128 * De-initializes the SAP global data structures 129 * 130 * Return: QDF_STATUS 131 */ 132 QDF_STATUS wlansap_global_deinit(void) 133 { 134 uint32_t i; 135 136 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 137 if (gp_sap_ctx[i]) { 138 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 139 "we could be leaking context:%d", i); 140 } 141 gp_sap_ctx[i] = NULL; 142 qdf_atomic_init(&sap_ctx_ref_count[i]); 143 } 144 145 if (QDF_IS_STATUS_ERROR(qdf_mutex_destroy(&sap_context_lock))) { 146 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 147 "failed to destroy sap_context_lock"); 148 return QDF_STATUS_E_FAULT; 149 } 150 151 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 152 "%s: sap global context deinitialized", __func__); 153 154 return QDF_STATUS_SUCCESS; 155 } 156 157 /** 158 * wlansap_save_context() - Save the context in global SAP context 159 * @ctx: SAP context to be stored 160 * 161 * Stores the given SAP context in the global SAP context array 162 * 163 * Return: QDF_STATUS 164 */ 165 static QDF_STATUS wlansap_save_context(ptSapContext ctx) 166 { 167 uint32_t i; 168 169 qdf_mutex_acquire(&sap_context_lock); 170 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 171 if (gp_sap_ctx[i] == NULL) { 172 gp_sap_ctx[i] = ctx; 173 qdf_atomic_inc(&sap_ctx_ref_count[i]); 174 qdf_mutex_release(&sap_context_lock); 175 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 176 "%s: sap context saved at index:%d", 177 __func__, i); 178 return QDF_STATUS_SUCCESS; 179 } 180 } 181 qdf_mutex_release(&sap_context_lock); 182 183 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 184 "%s: failed to save sap context", __func__); 185 186 return QDF_STATUS_E_FAILURE; 187 } 188 189 /** 190 * wlansap_context_get() - Verify SAP context and increment ref count 191 * @ctx: Context to be checked 192 * 193 * Verifies the SAP context and increments the reference count maintained for 194 * the corresponding SAP context. 195 * 196 * Return: QDF_STATUS 197 */ 198 QDF_STATUS wlansap_context_get(ptSapContext ctx) 199 { 200 uint32_t i; 201 202 qdf_mutex_acquire(&sap_context_lock); 203 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 204 if (ctx && (gp_sap_ctx[i] == ctx)) { 205 qdf_atomic_inc(&sap_ctx_ref_count[i]); 206 qdf_mutex_release(&sap_context_lock); 207 return QDF_STATUS_SUCCESS; 208 } 209 } 210 qdf_mutex_release(&sap_context_lock); 211 212 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 213 "%s: sap session is not valid", __func__); 214 return QDF_STATUS_E_FAILURE; 215 } 216 217 /** 218 * wlansap_context_put() - Check the reference count and free SAP context 219 * @ctx: SAP context to be checked and freed 220 * 221 * Checks the reference count and frees the SAP context 222 * 223 * Return: None 224 */ 225 void wlansap_context_put(ptSapContext ctx) 226 { 227 uint32_t i; 228 229 if (!ctx) 230 return; 231 232 qdf_mutex_acquire(&sap_context_lock); 233 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 234 if (gp_sap_ctx[i] == ctx) { 235 if (qdf_atomic_dec_and_test(&sap_ctx_ref_count[i])) { 236 qdf_mem_free(ctx); 237 gp_sap_ctx[i] = NULL; 238 QDF_TRACE(QDF_MODULE_ID_SAP, 239 QDF_TRACE_LEVEL_INFO, 240 "%s: sap session freed: %d", 241 __func__, i); 242 } 243 qdf_mutex_release(&sap_context_lock); 244 return; 245 } 246 } 247 qdf_mutex_release(&sap_context_lock); 248 } 249 250 /** 251 * wlansap_open() - WLAN SAP open function call 252 * @p_cds_gctx: Pointer to the global cds context; a handle to SAP's 253 * 254 * Called at driver initialization (cds_open). SAP will initialize 255 * all its internal resources and will wait for the call to start to 256 * register with the other modules. 257 * 258 * Return: Pointer to the SAP context 259 */ 260 void *wlansap_open(void *p_cds_gctx) 261 { 262 ptSapContext pSapCtx = NULL; 263 QDF_STATUS status; 264 265 /* dynamically allocate the sapContext */ 266 pSapCtx = (ptSapContext) qdf_mem_malloc(sizeof(tSapContext)); 267 268 if (NULL == pSapCtx) { 269 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 270 "%s: Invalid SAP pointer from p_cds_gctx", __func__); 271 return NULL; 272 } 273 274 /* Clean up SAP control block, initialize all values */ 275 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "wlansap_open"); 276 277 wlansap_clean_cb(pSapCtx, 0); /*do not empty */ 278 279 /* Setup the "link back" to the CDS context */ 280 pSapCtx->p_cds_gctx = p_cds_gctx; 281 282 /* Save the SAP context pointer */ 283 status = wlansap_save_context(pSapCtx); 284 if (QDF_IS_STATUS_ERROR(status)) { 285 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 286 "%s: failed to save SAP context", __func__); 287 qdf_mem_free(pSapCtx); 288 return NULL; 289 } 290 291 return pSapCtx; 292 } /* wlansap_open */ 293 294 /** 295 * wlansap_start() - wlan start SAP. 296 * @pCtx: Pointer to the global cds context; a handle to SAP's 297 * control block can be extracted from its context 298 * When MBSSID feature is enabled, SAP context is directly 299 * passed to SAP APIs 300 * @mode: Device mode 301 * @addr: MAC address of the SAP 302 * @session_id: Pointer to the session id 303 * 304 * Called as part of the overall start procedure (cds_enable). SAP will 305 * use this call to register with TL as the SAP entity for SAP RSN frames. 306 * 307 * Return: The result code associated with performing the operation 308 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 309 * access would cause a page fault. 310 * QDF_STATUS_SUCCESS: Success 311 */ 312 QDF_STATUS wlansap_start(void *pCtx, enum tQDF_ADAPTER_MODE mode, 313 uint8_t *addr, uint32_t *session_id) 314 { 315 ptSapContext pSapCtx = NULL; 316 QDF_STATUS qdf_ret_status; 317 tHalHandle hal; 318 319 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 320 321 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 322 "wlansap_start invoked successfully"); 323 /*------------------------------------------------------------------------ 324 Sanity check 325 Extract SAP control block 326 ------------------------------------------------------------------------*/ 327 pSapCtx = CDS_GET_SAP_CB(pCtx); 328 329 if (NULL == pSapCtx) { 330 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 331 "%s: Invalid SAP pointer from pCtx", __func__); 332 return QDF_STATUS_E_FAULT; 333 } 334 335 /*------------------------------------------------------------------------ 336 For now, presume security is not enabled. 337 -----------------------------------------------------------------------*/ 338 pSapCtx->ucSecEnabled = WLANSAP_SECURITY_ENABLED_STATE; 339 340 /*------------------------------------------------------------------------ 341 Now configure the roaming profile links. To SSID and bssid. 342 ------------------------------------------------------------------------*/ 343 /* We have room for two SSIDs. */ 344 pSapCtx->csr_roamProfile.SSIDs.numOfSSIDs = 1; /* This is true for now. */ 345 pSapCtx->csr_roamProfile.SSIDs.SSIDList = pSapCtx->SSIDList; /* Array of two */ 346 pSapCtx->csr_roamProfile.SSIDs.SSIDList[0].SSID.length = 0; 347 pSapCtx->csr_roamProfile.SSIDs.SSIDList[0].handoffPermitted = false; 348 pSapCtx->csr_roamProfile.SSIDs.SSIDList[0].ssidHidden = 349 pSapCtx->SSIDList[0].ssidHidden; 350 351 pSapCtx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1; /* This is true for now. */ 352 pSapCtx->csr_roamProfile.BSSIDs.bssid = &pSapCtx->bssid; 353 pSapCtx->csr_roamProfile.csrPersona = mode; 354 qdf_mem_copy(pSapCtx->self_mac_addr, addr, QDF_MAC_ADDR_SIZE); 355 qdf_event_create(&pSapCtx->sap_session_opened_evt); 356 357 /* Now configure the auth type in the roaming profile. To open. */ 358 pSapCtx->csr_roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; /* open is the default */ 359 360 if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(&pSapCtx->SapGlobalLock))) { 361 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 362 "wlansap_start failed init lock"); 363 return QDF_STATUS_E_FAULT; 364 } 365 366 hal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 367 if (!hal) { 368 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 369 "%s: Invalid HAL pointer", __func__); 370 return QDF_STATUS_E_INVAL; 371 } 372 373 qdf_ret_status = sap_open_session(hal, pSapCtx, session_id); 374 375 if (QDF_STATUS_SUCCESS != qdf_ret_status) { 376 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 377 "Error: In %s calling sap_open_session status = %d", 378 __func__, qdf_ret_status); 379 return QDF_STATUS_E_FAILURE; 380 } 381 382 return QDF_STATUS_SUCCESS; 383 } 384 385 /** 386 * wlansap_stop() - stop SAP module. 387 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 388 * can be extracted from its context. When MBSSID feature is enabled, 389 * SAP context is directly passed to SAP APIs 390 * 391 * Called by cds_disable to stop operation in SAP, before close. SAP will 392 * suspend all BT-AMP Protocol Adaption Layer operation and will wait for the 393 * close request to clean up its resources. 394 * 395 * Return: The result code associated with performing the operation 396 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 397 * access would cause a page fault. 398 * QDF_STATUS_SUCCESS: Success 399 */ 400 QDF_STATUS wlansap_stop(void *pCtx) 401 { 402 ptSapContext pSapCtx = NULL; 403 404 /* Sanity check - Extract SAP control block */ 405 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 406 "wlansap_stop invoked successfully "); 407 408 pSapCtx = CDS_GET_SAP_CB(pCtx); 409 if (NULL == pSapCtx) { 410 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 411 "%s: Invalid SAP pointer from pCtx", __func__); 412 return QDF_STATUS_E_FAULT; 413 } 414 415 sap_free_roam_profile(&pSapCtx->csr_roamProfile); 416 417 if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(&pSapCtx->SapGlobalLock))) { 418 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 419 "wlansap_stop failed destroy lock"); 420 return QDF_STATUS_E_FAULT; 421 } 422 423 return QDF_STATUS_SUCCESS; 424 } 425 426 /** 427 * wlansap_close - close SAP module. 428 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 429 * can be extracted from its context. When MBSSID feature is enabled, 430 * SAP context is directly passed to SAP APIs. 431 * 432 * Called by cds_close during general driver close procedure. SAP will clean up 433 * all the internal resources. 434 * 435 * Return: The result code associated with performing the operation 436 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 437 * access would cause a page fault 438 * QDF_STATUS_SUCCESS: Success 439 */ 440 QDF_STATUS wlansap_close(void *pCtx) 441 { 442 ptSapContext pSapCtx = NULL; 443 444 /* Sanity check - Extract SAP control block */ 445 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 446 "wlansap_close invoked"); 447 448 pSapCtx = CDS_GET_SAP_CB(pCtx); 449 if (NULL == pSapCtx) { 450 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 451 "%s: Invalid SAP pointer from pCtx", __func__); 452 return QDF_STATUS_E_FAULT; 453 } 454 455 /* Cleanup SAP control block */ 456 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 457 "wlansap_close"); 458 459 /* empty queues/lists/pkts if any */ 460 wlansap_clean_cb(pSapCtx, true); 461 462 wlansap_context_put(pSapCtx); 463 464 return QDF_STATUS_SUCCESS; 465 } /* wlansap_close */ 466 467 /*---------------------------------------------------------------------------- 468 * Utility Function implementations 469 * -------------------------------------------------------------------------*/ 470 471 /** 472 * wlansap_clean_cb() - clean SAP callback function. 473 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 474 * can be extracted from its context. When MBSSID feature is enabled, 475 * SAP context is directly passed to SAP APIs. 476 * 477 * Clear out all fields in the SAP context. 478 * 479 * Return: The result code associated with performing the operation 480 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 481 * access would cause a page fault 482 * QDF_STATUS_SUCCESS: Success 483 */ 484 QDF_STATUS wlansap_clean_cb(ptSapContext pSapCtx, uint32_t freeFlag /* 0 / *do not empty* /); */ 485 ) { 486 tHalHandle hal; 487 488 /*------------------------------------------------------------------------ 489 Sanity check SAP control block 490 ------------------------------------------------------------------------*/ 491 492 if (NULL == pSapCtx) { 493 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 494 "%s: Invalid SAP pointer", __func__); 495 return QDF_STATUS_E_FAULT; 496 } 497 498 /*------------------------------------------------------------------------ 499 Clean up SAP control block, initialize all values 500 ------------------------------------------------------------------------*/ 501 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 502 "wlansap_clean_cb"); 503 504 hal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 505 if (eSAP_TRUE == pSapCtx->isSapSessionOpen && hal) { 506 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 507 "close existing SAP session"); 508 sap_close_session(hal, pSapCtx, NULL, false); 509 } 510 511 qdf_mem_zero(pSapCtx, sizeof(tSapContext)); 512 513 pSapCtx->p_cds_gctx = NULL; 514 515 pSapCtx->sapsMachine = eSAP_DISCONNECTED; 516 517 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 518 "%s: Initializing State: %d, sapContext value = %p", __func__, 519 pSapCtx->sapsMachine, pSapCtx); 520 pSapCtx->sessionId = 0; 521 pSapCtx->channel = 0; 522 523 return QDF_STATUS_SUCCESS; 524 } /* wlansap_clean_cb */ 525 526 /*========================================================================== 527 FUNCTION wlansap_pmc_full_pwr_req_cb 528 529 DESCRIPTION 530 Callback provide to PMC in the pmc_request_full_power API. 531 532 DEPENDENCIES 533 534 PARAMETERS 535 536 IN 537 callbackContext: The user passed in a context to identify 538 status : The qdf_ret_status 539 540 RETURN VALUE 541 None 542 543 SIDE EFFECTS 544 ============================================================================*/ 545 void 546 wlansap_pmc_full_pwr_req_cb(void *callbackContext, QDF_STATUS status) 547 { 548 if (QDF_IS_STATUS_SUCCESS(status)) { 549 /* If success what else to be handled??? */ 550 } else { 551 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, 552 "wlansap_pmc_full_pwr_req_cb: PMC failed to put the chip in Full power"); 553 554 } 555 556 } /* wlansap_pmc_full_pwr_req_cb */ 557 558 /** 559 * wlansap_get_state() - get SAP state 560 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 561 * can be extracted from its context. When MBSSID feature is enabled, 562 * SAP context is directly passed to SAP APIs. 563 * 564 * This api returns the current SAP state to the caller. 565 * 566 * Return: uint8_t - the SAP FSM state. 567 */ 568 uint8_t wlansap_get_state(void *pCtx) 569 { 570 ptSapContext pSapCtx = NULL; 571 572 pSapCtx = CDS_GET_SAP_CB(pCtx); 573 574 if (NULL == pSapCtx) { 575 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 576 "%s: Invalid SAP pointer from pCtx", __func__); 577 return QDF_STATUS_E_FAULT; 578 } 579 return pSapCtx->sapsMachine; 580 } 581 582 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 583 /*========================================================================== 584 FUNCTION wlansap_check_cc_intf 585 586 DESCRIPTION Restart SAP if Concurrent Channel interfering 587 588 DEPENDENCIES NA. 589 590 PARAMETERS 591 IN 592 Ctx: Pointer to cds Context or Sap Context based on MBSSID 593 594 RETURN VALUE NONE 595 596 SIDE EFFECTS 597 ============================================================================*/ 598 uint16_t wlansap_check_cc_intf(void *Ctx) 599 { 600 tHalHandle hHal; 601 uint16_t intf_ch; 602 ptSapContext pSapCtx = CDS_GET_SAP_CB(Ctx); 603 604 hHal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 605 if (NULL == hHal) { 606 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 607 "%s: Invalid MAC context from p_cds_gctx", __func__); 608 return 0; 609 } 610 intf_ch = sme_check_concurrent_channel_overlap(hHal, 0, 0, 611 pSapCtx->cc_switch_mode); 612 return intf_ch; 613 } 614 #endif 615 616 /** 617 * wlansap_set_scan_acs_channel_params() - Config scan and channel parameters. 618 * pconfig: Pointer to the SAP config 619 * psap_ctx: Pointer to the SAP Context. 620 * pusr_context: Parameter that will be passed 621 * back in all the SAP callback events. 622 * 623 * This api function is used to copy Scan and Channel parameters from sap 624 * config to sap context. 625 * 626 * Return: The result code associated with 627 * performing the operation 628 */ 629 QDF_STATUS 630 wlansap_set_scan_acs_channel_params(tsap_Config_t *pconfig, 631 ptSapContext psap_ctx, 632 void *pusr_context) 633 { 634 tHalHandle h_hal = NULL; 635 636 if (NULL == pconfig) { 637 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 638 "%s: Invalid pconfig passed ", __func__); 639 return QDF_STATUS_E_FAULT; 640 } 641 642 if (NULL == psap_ctx) { 643 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 644 "%s: Invalid pconfig passed ", __func__); 645 return QDF_STATUS_E_FAULT; 646 } 647 648 /* Channel selection is auto or configured */ 649 psap_ctx->channel = pconfig->channel; 650 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 651 psap_ctx->cc_switch_mode = pconfig->cc_switch_mode; 652 #endif 653 psap_ctx->pUsrContext = pusr_context; 654 psap_ctx->enableOverLapCh = pconfig->enOverLapCh; 655 psap_ctx->acs_cfg = &pconfig->acs_cfg; 656 psap_ctx->ch_width_orig = pconfig->acs_cfg.ch_width; 657 psap_ctx->secondary_ch = pconfig->sec_ch; 658 659 /* 660 * Set the BSSID to your "self MAC Addr" read 661 * the mac address from Configuation ITEM received 662 * from HDD 663 */ 664 psap_ctx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1; 665 666 /* Save a copy to SAP context */ 667 qdf_mem_copy(psap_ctx->csr_roamProfile.BSSIDs.bssid, 668 pconfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE); 669 qdf_mem_copy(psap_ctx->self_mac_addr, 670 pconfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE); 671 672 h_hal = (tHalHandle)CDS_GET_HAL_CB(psap_ctx->p_cds_gctx); 673 if (NULL == h_hal) { 674 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 675 "%s: Invalid MAC context from pvosGCtx", __func__); 676 } else { 677 /* 678 * If concurrent session is running that is already associated 679 * then we just follow that sessions country info (whether 680 * present or not doesn't maater as we have to follow whatever 681 * STA session does) 682 */ 683 if ((0 == sme_get_concurrent_operation_channel(h_hal)) && 684 pconfig->ieee80211d) { 685 /* Setting the region/country information */ 686 sme_set_reg_info(h_hal, pconfig->countryCode); 687 sme_apply_channel_power_info_to_fw(h_hal); 688 } 689 } 690 691 return QDF_STATUS_SUCCESS; 692 } 693 /** 694 * wlan_sap_get_vht_ch_width() - Returns SAP VHT channel width. 695 * @ctx: Pointer to cds Context or Sap Context based on MBSSID 696 * 697 * This function provides the SAP current VHT channel with. 698 * 699 * Return: VHT channel width 700 */ 701 uint32_t wlan_sap_get_vht_ch_width(void *ctx) 702 { 703 ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx); 704 705 if (!sap_ctx) { 706 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 707 FL("Invalid SAP pointer from ctx")); 708 return 0; 709 } 710 711 return sap_ctx->ch_params.ch_width; 712 } 713 714 /** 715 * wlan_sap_set_vht_ch_width() - Sets SAP VHT channel width. 716 * @ctx: Pointer to cds Context or Sap Context based on MBSSID 717 * @vht_channel_width: SAP VHT channel width value. 718 * 719 * This function sets the SAP current VHT channel with. 720 * 721 * Return: None 722 */ 723 void wlan_sap_set_vht_ch_width(void *ctx, uint32_t vht_channel_width) 724 { 725 ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx); 726 727 if (!sap_ctx) { 728 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 729 FL("Invalid SAP pointer from ctx")); 730 return; 731 } 732 733 sap_ctx->ch_params.ch_width = vht_channel_width; 734 } 735 736 /** 737 * wlan_sap_validate_channel_switch() - validate target channel switch w.r.t 738 * concurreny rules set to avoid channel interference. 739 * @hal - Hal context 740 * @sap_ch - channel to switch 741 * @sap_context - sap session context 742 * 743 * Return: true if there is no channel interference else return false 744 */ 745 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 746 static bool wlan_sap_validate_channel_switch(tHalHandle hal, uint16_t sap_ch, 747 ptSapContext sap_context) 748 { 749 return sme_validate_sap_channel_switch( 750 hal, 751 sap_ch, 752 sap_context->csr_roamProfile.phyMode, 753 sap_context->cc_switch_mode, 754 sap_context->sessionId); 755 } 756 #else 757 static inline bool wlan_sap_validate_channel_switch(tHalHandle hal, 758 uint16_t sap_ch, ptSapContext sap_context) 759 { 760 return true; 761 } 762 #endif 763 /** 764 * wlansap_start_bss() - start BSS 765 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 766 * can be extracted from its context. When MBSSID feature is enabled, 767 * SAP context is directly passed to SAP APIs. 768 * @pQctCommitConfig: Pointer to configuration structure passed down from 769 * HDD(HostApd for Android) 770 * @hdd_SapEventCallback: Callback function in HDD called by SAP to inform HDD 771 * about SAP results 772 * @pUsrContext: Parameter that will be passed back in all the SAP callback 773 * events. 774 * 775 * This api function provides SAP FSM event eWLAN_SAP_PHYSICAL_LINK_CREATE for 776 * starting AP BSS 777 * 778 * Return: The result code associated with performing the operation 779 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 780 * access would cause a page fault 781 * QDF_STATUS_SUCCESS: Success 782 */ 783 QDF_STATUS wlansap_start_bss(void *pCtx, /* pwextCtx */ 784 tpWLAN_SAPEventCB pSapEventCallback, 785 tsap_Config_t *pConfig, void *pUsrContext) { 786 tWLAN_SAPEvent sapEvent; /* State machine event */ 787 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 788 ptSapContext pSapCtx = NULL; 789 tHalHandle hHal; 790 tpAniSirGlobal pmac = NULL; 791 792 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 793 794 /*------------------------------------------------------------------------ 795 Sanity check 796 Extract SAP control block 797 ------------------------------------------------------------------------*/ 798 pSapCtx = CDS_GET_SAP_CB(pCtx); 799 800 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 801 "wlansap_start_bss: sapContext=%p", pSapCtx); 802 803 if (NULL == pSapCtx) { 804 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 805 "%s: Invalid SAP pointer from pCtx", 806 __func__); 807 return QDF_STATUS_E_FAULT; 808 } 809 pSapCtx->sapsMachine = eSAP_DISCONNECTED; 810 811 /* Channel selection is auto or configured */ 812 pSapCtx->channel = pConfig->channel; 813 pSapCtx->ch_params.ch_width = pConfig->ch_params.ch_width; 814 pSapCtx->ch_params.center_freq_seg0 = 815 pConfig->ch_params.center_freq_seg0; 816 pSapCtx->ch_params.center_freq_seg1 = 817 pConfig->ch_params.center_freq_seg1; 818 pSapCtx->ch_params.sec_ch_offset = 819 pConfig->ch_params.sec_ch_offset; 820 pSapCtx->ch_width_orig = pConfig->ch_width_orig; 821 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 822 pSapCtx->cc_switch_mode = pConfig->cc_switch_mode; 823 #endif 824 pSapCtx->pUsrContext = pUsrContext; 825 pSapCtx->enableOverLapCh = pConfig->enOverLapCh; 826 pSapCtx->acs_cfg = &pConfig->acs_cfg; 827 /* Set the BSSID to your "self MAC Addr" read the mac address 828 from Configuation ITEM received from HDD */ 829 pSapCtx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1; 830 qdf_mem_copy(pSapCtx->csr_roamProfile.BSSIDs.bssid, 831 pSapCtx->self_mac_addr, sizeof(struct qdf_mac_addr)); 832 833 /* Save a copy to SAP context */ 834 qdf_mem_copy(pSapCtx->csr_roamProfile.BSSIDs.bssid, 835 pConfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE); 836 qdf_mem_copy(pSapCtx->self_mac_addr, 837 pConfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE); 838 839 /* copy the configuration items to csrProfile */ 840 sapconvert_to_csr_profile(pConfig, eCSR_BSS_TYPE_INFRA_AP, 841 &pSapCtx->csr_roamProfile); 842 hHal = (tHalHandle) CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 843 if (NULL == hHal) { 844 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 845 "%s: Invalid MAC context from p_cds_gctx", 846 __func__); 847 return QDF_STATUS_E_FAULT; 848 } else { 849 /* If concurrent session is running that is already associated 850 * then we just follow that sessions country info (whether 851 * present or not doesn't maater as we have to follow whatever 852 * STA session does) */ 853 if ((0 == sme_get_concurrent_operation_channel(hHal)) && 854 pConfig->ieee80211d) { 855 /* Setting the region/country information */ 856 sme_set_reg_info(hHal, pConfig->countryCode); 857 sme_apply_channel_power_info_to_fw(hHal); 858 } 859 } 860 861 pmac = PMAC_STRUCT(hHal); 862 if (NULL == pmac) { 863 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 864 "%s: Invalid MAC context from p_cds_gctx", 865 __func__); 866 return QDF_STATUS_E_FAULT; 867 } 868 /* 869 * Copy the DFS Test Mode setting to pmac for 870 * access in lower layers 871 */ 872 pmac->sap.SapDfsInfo.disable_dfs_ch_switch = 873 pConfig->disableDFSChSwitch; 874 875 /* Copy MAC filtering settings to sap context */ 876 pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl; 877 qdf_mem_copy(pSapCtx->acceptMacList, pConfig->accept_mac, 878 sizeof(pConfig->accept_mac)); 879 pSapCtx->nAcceptMac = pConfig->num_accept_mac; 880 sap_sort_mac_list(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); 881 qdf_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac, 882 sizeof(pConfig->deny_mac)); 883 pSapCtx->nDenyMac = pConfig->num_deny_mac; 884 sap_sort_mac_list(pSapCtx->denyMacList, pSapCtx->nDenyMac); 885 /* Fill in the event structure for FSM */ 886 sapEvent.event = eSAP_HDD_START_INFRA_BSS; 887 sapEvent.params = 0; /* pSapPhysLinkCreate */ 888 889 /* Store the HDD callback in SAP context */ 890 pSapCtx->pfnSapEventCallback = pSapEventCallback; 891 892 /* Handle event */ 893 qdf_status = sap_fsm(pSapCtx, &sapEvent); 894 895 return qdf_status; 896 } /* wlansap_start_bss */ 897 898 /** 899 * wlansap_set_mac_acl() - set MAC list entry in ACL. 900 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 901 * can be extracted from its context. When MBSSID feature is enabled, 902 * SAP context is directly passed to SAP APIs. 903 * @pConfig: Pointer to SAP config. 904 * 905 * This api function provides SAP to set mac list entry in accept list as well 906 * as deny list 907 * 908 * Return: The result code associated with performing the operation 909 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 910 * access would cause a page fault 911 * QDF_STATUS_SUCCESS: Success 912 */ 913 QDF_STATUS wlansap_set_mac_acl(void *pCtx, /* pwextCtx */ 914 tsap_Config_t *pConfig) { 915 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 916 ptSapContext pSapCtx = NULL; 917 918 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 919 "wlansap_set_mac_acl"); 920 921 pSapCtx = CDS_GET_SAP_CB(pCtx); 922 if (NULL == pSapCtx) { 923 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 924 "%s: Invalid SAP pointer from pCtx", 925 __func__); 926 return QDF_STATUS_E_FAULT; 927 } 928 /* Copy MAC filtering settings to sap context */ 929 pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl; 930 931 if (eSAP_DENY_UNLESS_ACCEPTED == pSapCtx->eSapMacAddrAclMode) { 932 qdf_mem_copy(pSapCtx->acceptMacList, 933 pConfig->accept_mac, 934 sizeof(pConfig->accept_mac)); 935 pSapCtx->nAcceptMac = pConfig->num_accept_mac; 936 sap_sort_mac_list(pSapCtx->acceptMacList, 937 pSapCtx->nAcceptMac); 938 } else if (eSAP_ACCEPT_UNLESS_DENIED == 939 pSapCtx->eSapMacAddrAclMode) { 940 qdf_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac, 941 sizeof(pConfig->deny_mac)); 942 pSapCtx->nDenyMac = pConfig->num_deny_mac; 943 sap_sort_mac_list(pSapCtx->denyMacList, pSapCtx->nDenyMac); 944 } 945 946 return qdf_status; 947 } /* wlansap_set_mac_acl */ 948 949 /** 950 * wlansap_stop_bss() - stop BSS. 951 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 952 * can be extracted from its context. When MBSSID feature is enabled, 953 * SAP context is directly passed to SAP APIs. 954 * 955 * This api function provides SAP FSM event eSAP_HDD_STOP_INFRA_BSS for 956 * stopping AP BSS 957 * 958 * Return: The result code associated with performing the operation 959 * QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL; 960 * access would cause a page fault 961 * QDF_STATUS_SUCCESS: Success 962 */ 963 QDF_STATUS wlansap_stop_bss(void *pCtx) 964 { 965 tWLAN_SAPEvent sapEvent; /* State machine event */ 966 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 967 ptSapContext pSapCtx = NULL; 968 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 969 970 /*------------------------------------------------------------------------ 971 Sanity check 972 Extract SAP control block 973 ------------------------------------------------------------------------*/ 974 if (NULL == pCtx) { 975 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 976 "%s: Invalid Global CDS handle", __func__); 977 return QDF_STATUS_E_FAULT; 978 } 979 980 pSapCtx = CDS_GET_SAP_CB(pCtx); 981 982 if (NULL == pSapCtx) { 983 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 984 "%s: Invalid SAP pointer from pCtx", __func__); 985 return QDF_STATUS_E_FAULT; 986 } 987 988 /* Fill in the event structure for FSM */ 989 sapEvent.event = eSAP_HDD_STOP_INFRA_BSS; 990 sapEvent.params = 0; 991 992 /* Handle event */ 993 qdf_status = sap_fsm(pSapCtx, &sapEvent); 994 995 return qdf_status; 996 } 997 998 /** 999 * wlansap_get_assoc_stations() - get list of associated stations. 1000 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1001 * can be extracted from its context. When MBSSID feature is enabled, 1002 * SAP context is directly passed to SAP APIs. 1003 * @modId: Module from whom list of associtated stations is supposed to be 1004 * probed. If an invalid module is passed then by default 1005 * QDF_MODULE_ID_PE will be probed 1006 * @pAssocStas: Pointer to list of associated stations that are known to the 1007 * module specified in mod parameter 1008 * 1009 * This api function is used to probe the list of associated stations from 1010 * various modules of CORE stack 1011 * NOTE: The memory for this list will be allocated by the caller of this API 1012 * 1013 * Return: The result code associated with performing the operation 1014 * QDF_STATUS_SUCCESS: Success 1015 */ 1016 QDF_STATUS 1017 wlansap_get_assoc_stations 1018 (void *pCtx, QDF_MODULE_ID modId, tpSap_AssocMacAddr pAssocStas) { 1019 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1020 1021 /*------------------------------------------------------------------------ 1022 Sanity check 1023 Extract SAP control block 1024 ------------------------------------------------------------------------*/ 1025 if (NULL == pSapCtx) { 1026 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1027 "%s: Invalid SAP pointer from pCtx", __func__); 1028 return QDF_STATUS_E_FAULT; 1029 } 1030 1031 sme_roam_get_associated_stas(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx), 1032 pSapCtx->sessionId, modId, 1033 pSapCtx->pUsrContext, 1034 (void **) pSapCtx->pfnSapEventCallback, 1035 (uint8_t *) pAssocStas); 1036 1037 return QDF_STATUS_SUCCESS; 1038 } 1039 1040 /** 1041 * wlansap_remove_wps_session_overlap() - remove overlapping wps session. 1042 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1043 * can be extracted from its context. When MBSSID feature is enabled, 1044 * SAP context is directly passed to SAP APIs. 1045 * @pRemoveMac: pointer to struct qdf_mac_addr for session MAC address 1046 * 1047 * This api function provides for Ap App/HDD to remove an entry from session 1048 * overlap info. 1049 * 1050 * Return: The QDF_STATUS code associated with performing the operation 1051 * QDF_STATUS_SUCCESS: Success 1052 * QDF_STATUS_E_FAULT: Session is not dectected. 1053 * The parameter is function not valid. 1054 */ 1055 QDF_STATUS 1056 wlansap_remove_wps_session_overlap(void *pCtx, 1057 struct qdf_mac_addr pRemoveMac) 1058 { 1059 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1060 1061 /*------------------------------------------------------------------------ 1062 Sanity check 1063 Extract SAP control block 1064 ------------------------------------------------------------------------*/ 1065 if (NULL == pSapCtx) { 1066 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1067 "%s: Invalid SAP pointer from pCtx", __func__); 1068 return QDF_STATUS_E_FAULT; 1069 } 1070 1071 sme_roam_get_wps_session_overlap(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx), 1072 pSapCtx->sessionId, pSapCtx->pUsrContext, 1073 (void **) pSapCtx->pfnSapEventCallback, 1074 pRemoveMac); 1075 1076 return QDF_STATUS_SUCCESS; 1077 } 1078 1079 /** 1080 * wlansap_get_wps_session_overlap() - get overlapping wps session. 1081 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1082 * can be extracted from its context. When MBSSID feature is enabled, 1083 * SAP context is directly passed to SAP APIs. 1084 * 1085 * This api function provides for Ap App/HDD to get WPS session overlap info. 1086 * 1087 * Return: The QDF_STATUS code associated with performing the operation 1088 * QDF_STATUS_SUCCESS: Success 1089 */ 1090 QDF_STATUS wlansap_get_wps_session_overlap(void *pCtx) 1091 { 1092 struct qdf_mac_addr pRemoveMac = QDF_MAC_ADDR_ZERO_INITIALIZER; 1093 1094 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1095 1096 /*------------------------------------------------------------------------ 1097 Sanity check 1098 Extract SAP control block 1099 ------------------------------------------------------------------------*/ 1100 if (NULL == pSapCtx) { 1101 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1102 "%s: Invalid SAP pointer from pCtx", __func__); 1103 return QDF_STATUS_E_FAULT; 1104 } 1105 1106 sme_roam_get_wps_session_overlap(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx), 1107 pSapCtx->sessionId, pSapCtx->pUsrContext, 1108 (void **) pSapCtx->pfnSapEventCallback, 1109 pRemoveMac); 1110 1111 return QDF_STATUS_SUCCESS; 1112 } 1113 1114 /* This routine will set the mode of operation for ACL dynamically*/ 1115 QDF_STATUS wlansap_set_mode(void *pCtx, uint32_t mode) 1116 { 1117 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1118 1119 if (NULL == pSapCtx) { 1120 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1121 "%s: Invalid SAP pointer from pCtx", __func__); 1122 return QDF_STATUS_E_FAULT; 1123 } 1124 1125 pSapCtx->eSapMacAddrAclMode = (eSapMacAddrACL) mode; 1126 return QDF_STATUS_SUCCESS; 1127 } 1128 1129 /* Get ACL Mode */ 1130 QDF_STATUS wlansap_get_acl_mode(void *pCtx, eSapMacAddrACL *mode) 1131 { 1132 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1133 1134 if (NULL == pSapCtx) { 1135 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1136 "%s: Invalid SAP pointer from pCtx", __func__); 1137 return QDF_STATUS_E_FAULT; 1138 } 1139 1140 *mode = pSapCtx->eSapMacAddrAclMode; 1141 return QDF_STATUS_SUCCESS; 1142 } 1143 1144 /* API to get ACL Accept List */ 1145 QDF_STATUS 1146 wlansap_get_acl_accept_list(void *pCtx, struct qdf_mac_addr *pAcceptList, 1147 uint8_t *nAcceptList) 1148 { 1149 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1150 if (NULL == pSapCtx) { 1151 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1152 "%s: Invalid SAP pointer from p_cds_gctx", __func__); 1153 return QDF_STATUS_E_FAULT; 1154 } 1155 1156 memcpy((void *)pAcceptList, (void *)pSapCtx->acceptMacList, 1157 (pSapCtx->nAcceptMac * QDF_MAC_ADDR_SIZE)); 1158 *nAcceptList = pSapCtx->nAcceptMac; 1159 return QDF_STATUS_SUCCESS; 1160 } 1161 1162 /* API to get Deny List */ 1163 QDF_STATUS 1164 wlansap_get_acl_deny_list(void *pCtx, struct qdf_mac_addr *pDenyList, 1165 uint8_t *nDenyList) 1166 { 1167 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1168 if (NULL == pSapCtx) { 1169 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1170 "%s: Invalid SAP pointer from p_cds_gctx", __func__); 1171 return QDF_STATUS_E_FAULT; 1172 } 1173 1174 memcpy((void *)pDenyList, (void *)pSapCtx->denyMacList, 1175 (pSapCtx->nDenyMac * QDF_MAC_ADDR_SIZE)); 1176 *nDenyList = pSapCtx->nDenyMac; 1177 return QDF_STATUS_SUCCESS; 1178 } 1179 1180 /* This routine will clear all the entries in accept list as well as deny list */ 1181 1182 QDF_STATUS wlansap_clear_acl(void *pCtx) 1183 { 1184 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1185 uint8_t i; 1186 1187 if (NULL == pSapCtx) { 1188 return QDF_STATUS_E_RESOURCES; 1189 } 1190 1191 if (pSapCtx->denyMacList != NULL) { 1192 for (i = 0; i < (pSapCtx->nDenyMac - 1); i++) { 1193 qdf_mem_zero((pSapCtx->denyMacList + i)->bytes, 1194 QDF_MAC_ADDR_SIZE); 1195 1196 } 1197 } 1198 sap_print_acl(pSapCtx->denyMacList, pSapCtx->nDenyMac); 1199 pSapCtx->nDenyMac = 0; 1200 1201 if (pSapCtx->acceptMacList != NULL) { 1202 for (i = 0; i < (pSapCtx->nAcceptMac - 1); i++) { 1203 qdf_mem_zero((pSapCtx->acceptMacList + i)->bytes, 1204 QDF_MAC_ADDR_SIZE); 1205 1206 } 1207 } 1208 sap_print_acl(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); 1209 pSapCtx->nAcceptMac = 0; 1210 1211 return QDF_STATUS_SUCCESS; 1212 } 1213 1214 /* 1215 * wlansap_modify_acl() -Update ACL entries 1216 * 1217 * @ctx: Global context 1218 * @peer_sta_mac: peer sta mac to be updated. 1219 * @list_type: white/Black list type. 1220 * @cmd: command to be executed on ACL. 1221 * 1222 * This function is called when a peer needs to be added or deleted from the 1223 * white/black ACL 1224 * 1225 * Return: Status 1226 */ 1227 1228 QDF_STATUS 1229 wlansap_modify_acl 1230 (void *ctx, 1231 uint8_t *peer_sta_mac, eSapACLType list_type, eSapACLCmdType cmd) { 1232 eSapBool sta_white_list = eSAP_FALSE, sta_black_list = eSAP_FALSE; 1233 uint8_t staWLIndex, staBLIndex; 1234 ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx); 1235 1236 if (NULL == sap_ctx) { 1237 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1238 "%s: Invalid SAP Context", __func__); 1239 return QDF_STATUS_E_FAULT; 1240 } 1241 1242 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1243 "Modify ACL entered\n" "Before modification of ACL\n" 1244 "size of accept and deny lists %d %d", sap_ctx->nAcceptMac, 1245 sap_ctx->nDenyMac); 1246 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1247 "*** WHITE LIST ***"); 1248 sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac); 1249 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1250 "*** BLACK LIST ***"); 1251 sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac); 1252 1253 /* the expectation is a mac addr will not be in both the lists at the same time. 1254 It is the responsiblity of userspace to ensure this */ 1255 sta_white_list = 1256 sap_search_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac, 1257 peer_sta_mac, &staWLIndex); 1258 sta_black_list = 1259 sap_search_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac, 1260 peer_sta_mac, &staBLIndex); 1261 1262 if (sta_white_list && sta_black_list) { 1263 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1264 "Peer mac " MAC_ADDRESS_STR 1265 " found in white and black lists." 1266 "Initial lists passed incorrect. Cannot execute this command.", 1267 MAC_ADDR_ARRAY(peer_sta_mac)); 1268 return QDF_STATUS_E_FAILURE; 1269 1270 } 1271 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1272 "cmd %d", cmd); 1273 1274 switch (list_type) { 1275 case eSAP_WHITE_LIST: 1276 if (cmd == ADD_STA_TO_ACL) { 1277 /* error check */ 1278 /* if list is already at max, return failure */ 1279 if (sap_ctx->nAcceptMac == MAX_ACL_MAC_ADDRESS) { 1280 QDF_TRACE(QDF_MODULE_ID_SAP, 1281 QDF_TRACE_LEVEL_ERROR, 1282 "White list is already maxed out. Cannot accept " 1283 MAC_ADDRESS_STR, 1284 MAC_ADDR_ARRAY(peer_sta_mac)); 1285 return QDF_STATUS_E_FAILURE; 1286 } 1287 if (sta_white_list) { 1288 /* Do nothing if already present in white list. Just print a warning */ 1289 QDF_TRACE(QDF_MODULE_ID_SAP, 1290 QDF_TRACE_LEVEL_WARN, 1291 "MAC address already present in white list " 1292 MAC_ADDRESS_STR, 1293 MAC_ADDR_ARRAY(peer_sta_mac)); 1294 return QDF_STATUS_SUCCESS; 1295 } 1296 if (sta_black_list) { 1297 /* remove it from black list before adding to the white list */ 1298 QDF_TRACE(QDF_MODULE_ID_SAP, 1299 QDF_TRACE_LEVEL_WARN, 1300 "STA present in black list so first remove from it"); 1301 sap_remove_mac_from_acl(sap_ctx-> 1302 denyMacList, 1303 &sap_ctx->nDenyMac, 1304 staBLIndex); 1305 } 1306 QDF_TRACE(QDF_MODULE_ID_SAP, 1307 QDF_TRACE_LEVEL_INFO, 1308 "... Now add to the white list"); 1309 sap_add_mac_to_acl(sap_ctx->acceptMacList, 1310 &sap_ctx->nAcceptMac, 1311 peer_sta_mac); 1312 QDF_TRACE(QDF_MODULE_ID_SAP, 1313 QDF_TRACE_LEVEL_INFO_LOW, 1314 "size of accept and deny lists %d %d", 1315 sap_ctx->nAcceptMac, 1316 sap_ctx->nDenyMac); 1317 } else if (cmd == DELETE_STA_FROM_ACL) { 1318 if (sta_white_list) { 1319 1320 struct tagCsrDelStaParams delStaParams; 1321 1322 QDF_TRACE(QDF_MODULE_ID_SAP, 1323 QDF_TRACE_LEVEL_INFO, 1324 "Delete from white list"); 1325 sap_remove_mac_from_acl(sap_ctx->acceptMacList, 1326 &sap_ctx->nAcceptMac, 1327 staWLIndex); 1328 /* If a client is deleted from white list and it is connected, send deauth */ 1329 wlansap_populate_del_sta_params(peer_sta_mac, 1330 eCsrForcedDeauthSta, 1331 (SIR_MAC_MGMT_DEAUTH >> 4), 1332 &delStaParams); 1333 wlansap_deauth_sta(ctx, &delStaParams); 1334 QDF_TRACE(QDF_MODULE_ID_SAP, 1335 QDF_TRACE_LEVEL_INFO_LOW, 1336 "size of accept and deny lists %d %d", 1337 sap_ctx->nAcceptMac, 1338 sap_ctx->nDenyMac); 1339 } else { 1340 QDF_TRACE(QDF_MODULE_ID_SAP, 1341 QDF_TRACE_LEVEL_WARN, 1342 "MAC address to be deleted is not present in the white list " 1343 MAC_ADDRESS_STR, 1344 MAC_ADDR_ARRAY(peer_sta_mac)); 1345 return QDF_STATUS_E_FAILURE; 1346 } 1347 } else { 1348 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1349 "Invalid cmd type passed"); 1350 return QDF_STATUS_E_FAILURE; 1351 } 1352 break; 1353 1354 case eSAP_BLACK_LIST: 1355 1356 if (cmd == ADD_STA_TO_ACL) { 1357 struct tagCsrDelStaParams delStaParams; 1358 /* error check */ 1359 /* if list is already at max, return failure */ 1360 if (sap_ctx->nDenyMac == MAX_ACL_MAC_ADDRESS) { 1361 QDF_TRACE(QDF_MODULE_ID_SAP, 1362 QDF_TRACE_LEVEL_ERROR, 1363 "Black list is already maxed out. Cannot accept " 1364 MAC_ADDRESS_STR, 1365 MAC_ADDR_ARRAY(peer_sta_mac)); 1366 return QDF_STATUS_E_FAILURE; 1367 } 1368 if (sta_black_list) { 1369 /* Do nothing if already present in white list */ 1370 QDF_TRACE(QDF_MODULE_ID_SAP, 1371 QDF_TRACE_LEVEL_WARN, 1372 "MAC address already present in black list " 1373 MAC_ADDRESS_STR, 1374 MAC_ADDR_ARRAY(peer_sta_mac)); 1375 return QDF_STATUS_SUCCESS; 1376 } 1377 if (sta_white_list) { 1378 /* remove it from white list before adding to the black list */ 1379 QDF_TRACE(QDF_MODULE_ID_SAP, 1380 QDF_TRACE_LEVEL_WARN, 1381 "Present in white list so first remove from it"); 1382 sap_remove_mac_from_acl(sap_ctx-> 1383 acceptMacList, 1384 &sap_ctx-> 1385 nAcceptMac, 1386 staWLIndex); 1387 } 1388 /* If we are adding a client to the black list; if its connected, send deauth */ 1389 wlansap_populate_del_sta_params(peer_sta_mac, 1390 eCsrForcedDeauthSta, 1391 (SIR_MAC_MGMT_DEAUTH >> 4), 1392 &delStaParams); 1393 wlansap_deauth_sta(ctx, &delStaParams); 1394 QDF_TRACE(QDF_MODULE_ID_SAP, 1395 QDF_TRACE_LEVEL_INFO, 1396 "... Now add to black list"); 1397 sap_add_mac_to_acl(sap_ctx->denyMacList, 1398 &sap_ctx->nDenyMac, peer_sta_mac); 1399 QDF_TRACE(QDF_MODULE_ID_SAP, 1400 QDF_TRACE_LEVEL_INFO_LOW, 1401 "size of accept and deny lists %d %d", 1402 sap_ctx->nAcceptMac, 1403 sap_ctx->nDenyMac); 1404 } else if (cmd == DELETE_STA_FROM_ACL) { 1405 if (sta_black_list) { 1406 QDF_TRACE(QDF_MODULE_ID_SAP, 1407 QDF_TRACE_LEVEL_INFO, 1408 "Delete from black list"); 1409 sap_remove_mac_from_acl(sap_ctx->denyMacList, 1410 &sap_ctx->nDenyMac, 1411 staBLIndex); 1412 QDF_TRACE(QDF_MODULE_ID_SAP, 1413 QDF_TRACE_LEVEL_INFO_LOW, 1414 "no accept and deny mac %d %d", 1415 sap_ctx->nAcceptMac, 1416 sap_ctx->nDenyMac); 1417 } else { 1418 QDF_TRACE(QDF_MODULE_ID_SAP, 1419 QDF_TRACE_LEVEL_WARN, 1420 "MAC address to be deleted is not present in the black list " 1421 MAC_ADDRESS_STR, 1422 MAC_ADDR_ARRAY(peer_sta_mac)); 1423 return QDF_STATUS_E_FAILURE; 1424 } 1425 } else { 1426 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1427 "Invalid cmd type passed"); 1428 return QDF_STATUS_E_FAILURE; 1429 } 1430 break; 1431 1432 default: 1433 { 1434 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1435 "Invalid list type passed %d", list_type); 1436 return QDF_STATUS_E_FAILURE; 1437 } 1438 } 1439 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, 1440 "After modification of ACL"); 1441 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1442 "*** WHITE LIST ***"); 1443 sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac); 1444 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1445 "*** BLACK LIST ***"); 1446 sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac); 1447 return QDF_STATUS_SUCCESS; 1448 } 1449 1450 /** 1451 * wlansap_disassoc_sta() - initiate disassociation of station. 1452 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1453 * can be extracted from its context. When MBSSID feature is enabled, 1454 * SAP context is directly passed to SAP APIs. 1455 * @pPeerStaMac: Mac address of the station to disassociate 1456 * 1457 * This api function provides for Ap App/HDD initiated disassociation of station 1458 * 1459 * Return: The QDF_STATUS code associated with performing the operation 1460 * QDF_STATUS_SUCCESS: Success 1461 */ 1462 QDF_STATUS wlansap_disassoc_sta(void *pCtx, const uint8_t *pPeerStaMac) 1463 { 1464 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1465 1466 /*------------------------------------------------------------------------ 1467 Sanity check 1468 Extract SAP control block 1469 ------------------------------------------------------------------------*/ 1470 if (NULL == pSapCtx) { 1471 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1472 "%s: Invalid SAP pointer from pCtx", __func__); 1473 return QDF_STATUS_E_FAULT; 1474 } 1475 1476 sme_roam_disconnect_sta(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx), 1477 pSapCtx->sessionId, pPeerStaMac); 1478 1479 return QDF_STATUS_SUCCESS; 1480 } 1481 1482 /** 1483 * wlansap_deauth_sta() - Ap App/HDD initiated deauthentication of station 1484 * @pCtx : Pointer to the global cds context; a handle to SAP's 1485 * control block can be extracted from its context 1486 * When MBSSID feature is enabled, SAP context is directly 1487 * passed to SAP APIs 1488 * @pDelStaParams : Pointer to parameters of the station to deauthenticate 1489 * 1490 * This api function provides for Ap App/HDD initiated deauthentication of 1491 * station 1492 * 1493 * Return: The QDF_STATUS code associated with performing the operation 1494 */ 1495 QDF_STATUS wlansap_deauth_sta(void *pCtx, 1496 struct tagCsrDelStaParams *pDelStaParams) 1497 { 1498 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 1499 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 1500 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1501 1502 /*------------------------------------------------------------------------ 1503 Sanity check 1504 Extract SAP control block 1505 ------------------------------------------------------------------------*/ 1506 if (NULL == pSapCtx) { 1507 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1508 "%s: Invalid SAP pointer from pCtx", __func__); 1509 return qdf_status; 1510 } 1511 1512 qdf_ret_status = 1513 sme_roam_deauth_sta(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx), 1514 pSapCtx->sessionId, pDelStaParams); 1515 1516 if (qdf_ret_status == QDF_STATUS_SUCCESS) { 1517 qdf_status = QDF_STATUS_SUCCESS; 1518 } 1519 return qdf_status; 1520 } 1521 1522 /** 1523 * wlansap_update_bw80_cbmode() - fucntion to update channel bonding mode for 1524 * VHT80 channel. 1525 * @channel: target channel 1526 * @sme_config: sme configuration context 1527 * 1528 * Return: none 1529 */ 1530 static inline void wlansap_update_bw80_cbmode(uint32_t channel, 1531 tSmeConfigParams *sme_config) 1532 { 1533 if (channel == 36 || channel == 52 || channel == 100 || 1534 channel == 116 || channel == 149 || channel == 132) { 1535 sme_config->csrConfig.channelBondingMode5GHz = 1536 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; 1537 } else if (channel == 40 || channel == 56 || channel == 104 || 1538 channel == 120 || channel == 153 || channel == 136) { 1539 sme_config->csrConfig.channelBondingMode5GHz = 1540 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; 1541 } else if (channel == 44 || channel == 60 || channel == 108 || 1542 channel == 124 || channel == 157 || channel == 140) { 1543 sme_config->csrConfig.channelBondingMode5GHz = 1544 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; 1545 } else if (channel == 48 || channel == 64 || channel == 112 || 1546 channel == 128 || channel == 144 || channel == 161) { 1547 sme_config->csrConfig.channelBondingMode5GHz = 1548 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; 1549 } 1550 } 1551 1552 /** 1553 * wlansap_update_csa_channel_params() - fucntion to populate channel width and 1554 * bonding modes. 1555 * @sap_context: sap adapter context 1556 * @channel: target channel 1557 * 1558 * Return: The QDF_STATUS code associated with performing the operation 1559 */ 1560 static QDF_STATUS wlansap_update_csa_channel_params(ptSapContext sap_context, 1561 uint32_t channel) 1562 { 1563 void *hal; 1564 tpAniSirGlobal mac_ctx; 1565 uint8_t bw; 1566 1567 hal = CDS_GET_HAL_CB(sap_context->p_cds_gctx); 1568 if (!hal) { 1569 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1570 "%s: Invalid hal pointer from p_cds_gctx", __func__); 1571 return QDF_STATUS_E_FAULT; 1572 } 1573 1574 mac_ctx = PMAC_STRUCT(hal); 1575 1576 if (channel <= CHAN_ENUM_14) { 1577 /* 1578 * currently OBSS scan is done in hostapd, so to avoid 1579 * SAP coming up in HT40 on channel switch we are 1580 * disabling channel bonding in 2.4Ghz. 1581 */ 1582 mac_ctx->sap.SapDfsInfo.new_chanWidth = 0; 1583 1584 } else { 1585 1586 if (sap_context->ch_width_orig >= CH_WIDTH_80MHZ) 1587 bw = BW80; 1588 else if (sap_context->ch_width_orig == CH_WIDTH_40MHZ) 1589 bw = BW40_HIGH_PRIMARY; 1590 else 1591 bw = BW20; 1592 1593 for (; bw >= BW20; bw--) { 1594 uint16_t op_class; 1595 1596 op_class = cds_reg_dmn_get_opclass_from_channel( 1597 mac_ctx->scan.countryCodeCurrent, 1598 channel, bw); 1599 if (!op_class) 1600 continue; 1601 1602 if (bw == BW80) { 1603 mac_ctx->sap.SapDfsInfo.new_chanWidth = 1604 CH_WIDTH_80MHZ; 1605 } else if (bw == BW40_HIGH_PRIMARY) { 1606 mac_ctx->sap.SapDfsInfo.new_chanWidth = 1607 CH_WIDTH_40MHZ; 1608 } else if (bw == BW40_LOW_PRIMARY) { 1609 mac_ctx->sap.SapDfsInfo.new_chanWidth = 1610 CH_WIDTH_40MHZ; 1611 } else { 1612 mac_ctx->sap.SapDfsInfo.new_chanWidth = 1613 CH_WIDTH_20MHZ; 1614 } 1615 break; 1616 } 1617 1618 } 1619 1620 return QDF_STATUS_SUCCESS; 1621 } 1622 1623 /** 1624 * wlansap_set_channel_change_with_csa() - Set channel change with CSA 1625 * @p_cds_gctx: Pointer to cds global context structure 1626 * @targetChannel: Target channel 1627 * @target_bw: Target bandwidth 1628 * 1629 * This api function does a channel change to the target channel specified. 1630 * CSA IE is included in the beacons before doing a channel change. 1631 * 1632 * Return: QDF_STATUS 1633 */ 1634 QDF_STATUS 1635 wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel, 1636 enum phy_ch_width target_bw) 1637 { 1638 1639 ptSapContext sapContext = NULL; 1640 tWLAN_SAPEvent sapEvent; 1641 tpAniSirGlobal pMac = NULL; 1642 void *hHal = NULL; 1643 bool valid; 1644 QDF_STATUS status; 1645 1646 sapContext = CDS_GET_SAP_CB(p_cds_gctx); 1647 if (NULL == sapContext) { 1648 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1649 "%s: Invalid SAP pointer from p_cds_gctx", __func__); 1650 1651 return QDF_STATUS_E_FAULT; 1652 } 1653 1654 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 1655 if (NULL == hHal) { 1656 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1657 "%s: Invalid HAL pointer from p_cds_gctx", __func__); 1658 return QDF_STATUS_E_FAULT; 1659 } 1660 pMac = PMAC_STRUCT(hHal); 1661 1662 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1663 "%s: sap chan:%d target:%d conc:%d", 1664 __func__, sapContext->channel, targetChannel, 1665 cds_concurrent_open_sessions_running()); 1666 1667 /* 1668 * Now, validate if the passed channel is valid in the 1669 * current regulatory domain. 1670 */ 1671 if (sapContext->channel != targetChannel && 1672 ((cds_get_channel_state(targetChannel) == 1673 CHANNEL_STATE_ENABLE) || 1674 (cds_get_channel_state(targetChannel) == 1675 CHANNEL_STATE_DFS && 1676 !cds_concurrent_open_sessions_running()))) { 1677 /* 1678 * validate target channel switch w.r.t various concurrency 1679 * rules set. 1680 */ 1681 valid = wlan_sap_validate_channel_switch(hHal, targetChannel, 1682 sapContext); 1683 if (!valid) { 1684 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1685 FL("Channel switch to %u is not allowed due to concurrent channel interference"), 1686 targetChannel); 1687 return QDF_STATUS_E_FAULT; 1688 } 1689 /* 1690 * Post a CSA IE request to SAP state machine with 1691 * target channel information and also CSA IE required 1692 * flag set in sapContext only, if SAP is in eSAP_STARTED 1693 * state. 1694 */ 1695 if (eSAP_STARTED == sapContext->sapsMachine) { 1696 status = wlansap_update_csa_channel_params(sapContext, 1697 targetChannel); 1698 if (status != QDF_STATUS_SUCCESS) 1699 return status; 1700 1701 /* 1702 * Copy the requested target channel 1703 * to sap context. 1704 */ 1705 pMac->sap.SapDfsInfo.target_channel = targetChannel; 1706 pMac->sap.SapDfsInfo.new_ch_params.ch_width = 1707 pMac->sap.SapDfsInfo.new_chanWidth; 1708 1709 /* By this time, the best bandwidth is calculated for 1710 * the given target channel. Now, if there was a 1711 * request from user to move to a selected bandwidth, 1712 * we can see if it can be honored. 1713 * 1714 * Ex1: BW80 was selected for the target channel and 1715 * user wants BW40, it can be allowed 1716 * Ex2: BW40 was selected for the target channel and 1717 * user wants BW80, it cannot be allowed for the given 1718 * target channel. 1719 * 1720 * So, the MIN of the selected channel bandwidth and 1721 * user input is used for the bandwidth 1722 */ 1723 if (target_bw != CH_WIDTH_MAX) { 1724 QDF_TRACE(QDF_MODULE_ID_SAP, 1725 QDF_TRACE_LEVEL_INFO, 1726 "%s: target bw:%d new width:%d", 1727 __func__, target_bw, 1728 pMac->sap.SapDfsInfo. 1729 new_ch_params.ch_width); 1730 pMac->sap.SapDfsInfo.new_ch_params.ch_width = 1731 pMac->sap.SapDfsInfo.new_chanWidth = 1732 QDF_MIN(pMac->sap.SapDfsInfo. 1733 new_ch_params.ch_width, 1734 target_bw); 1735 } 1736 cds_set_channel_params(targetChannel, 1737 0, &pMac->sap.SapDfsInfo.new_ch_params); 1738 /* 1739 * Set the CSA IE required flag. 1740 */ 1741 pMac->sap.SapDfsInfo.csaIERequired = true; 1742 1743 /* 1744 * Set the radar found status to allow the channel 1745 * change to happen same as in the case of a radar 1746 * detection. Since, this will allow SAP to be in 1747 * correct state and also resume the netif queues 1748 * that were suspended in HDD before the channel 1749 * request was issued. 1750 */ 1751 pMac->sap.SapDfsInfo.sap_radar_found_status = true; 1752 pMac->sap.SapDfsInfo.cac_state = 1753 eSAP_DFS_DO_NOT_SKIP_CAC; 1754 sap_cac_reset_notify(hHal); 1755 1756 /* 1757 * Post the eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START 1758 * to SAP state machine to process the channel 1759 * request with CSA IE set in the beacons. 1760 */ 1761 sapEvent.event = 1762 eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START; 1763 sapEvent.params = 0; 1764 sapEvent.u1 = 0; 1765 sapEvent.u2 = 0; 1766 1767 sap_fsm(sapContext, &sapEvent); 1768 1769 } else { 1770 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1771 "%s: Failed to request Channel Change, since" 1772 "SAP is not in eSAP_STARTED state", __func__); 1773 return QDF_STATUS_E_FAULT; 1774 } 1775 1776 } else { 1777 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1778 "%s: Channel = %d is not valid in the current" 1779 "regulatory domain", __func__, targetChannel); 1780 1781 return QDF_STATUS_E_FAULT; 1782 } 1783 1784 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 1785 "%s: Posted eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START successfully to sap_fsm for Channel = %d", 1786 __func__, targetChannel); 1787 1788 return QDF_STATUS_SUCCESS; 1789 } 1790 1791 /** 1792 * wlansap_set_counter_measure() - set counter measure. 1793 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1794 * can be extracted from its context. When MBSSID feature is enabled, 1795 * SAP context is directly passed to SAP APIs. 1796 * @bEnable: If true than all stations will be disassociated and no more 1797 * will be allowed to associate. If false than CORE will come out 1798 * of this state. 1799 * 1800 * This api function is used to disassociate all the stations and prevent 1801 * association for any other station.Whenever Authenticator receives 2 mic 1802 * failures within 60 seconds, Authenticator will enable counter measure at 1803 * SAP Layer. Authenticator will start the 60 seconds timer. Core stack will 1804 * not allow any STA to associate till HDD disables counter meassure. Core 1805 * stack shall kick out all the STA which are currently associated and DIASSOC 1806 * Event will be propogated to HDD for each STA to clean up the HDD STA table. 1807 * Once the 60 seconds timer expires, Authenticator will disable the counter 1808 * meassure at core stack. Now core stack can allow STAs to associate. 1809 * 1810 * Return: The QDF_STATUS code associated with performing the operation 1811 * QDF_STATUS_SUCCESS: Success 1812 */ 1813 QDF_STATUS wlansap_set_counter_measure(void *pCtx, bool bEnable) 1814 { 1815 ptSapContext pSapCtx = CDS_GET_SAP_CB(pCtx); 1816 1817 /*------------------------------------------------------------------------ 1818 Sanity check 1819 Extract SAP control block 1820 ------------------------------------------------------------------------*/ 1821 if (NULL == pSapCtx) { 1822 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1823 "%s: Invalid SAP pointer from pCtx", __func__); 1824 return QDF_STATUS_E_FAULT; 1825 } 1826 1827 sme_roam_tkip_counter_measures(CDS_GET_HAL_CB(pSapCtx->p_cds_gctx), 1828 pSapCtx->sessionId, bEnable); 1829 1830 return QDF_STATUS_SUCCESS; 1831 } 1832 1833 /** 1834 * wlansap_set_key_sta() - set keys for a stations. 1835 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1836 * can be extracted from its context. When MBSSID feature is enabled, 1837 * SAP context is directly passed to SAP APIs. 1838 * @pSetKeyInfo : tCsrRoamSetKey structure for the station 1839 * 1840 * This api function provides for Ap App/HDD to set key for a station. 1841 * 1842 * Return: The QDF_STATUS code associated with performing the operation 1843 * QDF_STATUS_SUCCESS: Success 1844 */ 1845 QDF_STATUS wlansap_set_key_sta(void *pCtx, tCsrRoamSetKey *pSetKeyInfo) 1846 { 1847 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1848 ptSapContext pSapCtx = NULL; 1849 void *hHal = NULL; 1850 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 1851 uint32_t roamId = 0xFF; 1852 1853 pSapCtx = CDS_GET_SAP_CB(pCtx); 1854 if (NULL == pSapCtx) { 1855 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1856 "%s: Invalid SAP pointer from pCtx", 1857 __func__); 1858 return QDF_STATUS_E_FAULT; 1859 } 1860 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 1861 if (NULL == hHal) { 1862 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1863 "%s: Invalid HAL pointer from p_cds_gctx", 1864 __func__); 1865 return QDF_STATUS_E_FAULT; 1866 } 1867 qdf_ret_status = 1868 sme_roam_set_key(hHal, pSapCtx->sessionId, pSetKeyInfo, 1869 &roamId); 1870 1871 if (qdf_ret_status == QDF_STATUS_SUCCESS) 1872 qdf_status = QDF_STATUS_SUCCESS; 1873 else 1874 qdf_status = QDF_STATUS_E_FAULT; 1875 1876 return qdf_status; 1877 } 1878 1879 /** 1880 * wlan_sap_getstation_ie_information() - RSNIE Population 1881 * 1882 * @ctx: Global context 1883 * @len: Length of @buf 1884 * @buf: RSNIE IE data 1885 * 1886 * Populate RSN IE from CSR to HDD context 1887 * 1888 * Return: QDF_STATUS enumeration 1889 */ 1890 1891 QDF_STATUS 1892 wlan_sap_getstation_ie_information 1893 (void *ctx, uint32_t *len, uint8_t *buf) { 1894 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 1895 ptSapContext sap_ctx = NULL; 1896 uint32_t ie_len = 0; 1897 1898 sap_ctx = CDS_GET_SAP_CB(ctx); 1899 if (NULL == sap_ctx) { 1900 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1901 FL("Invalid SAP pointer from pCtx")); 1902 return QDF_STATUS_E_FAULT; 1903 } 1904 1905 if (len) { 1906 ie_len = *len; 1907 *len = sap_ctx->nStaWPARSnReqIeLength; 1908 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1909 FL("WPAIE len : %x"), *len); 1910 if ((buf) && (ie_len >= sap_ctx->nStaWPARSnReqIeLength)) { 1911 qdf_mem_copy(buf, 1912 sap_ctx->pStaWpaRsnReqIE, 1913 sap_ctx->nStaWPARSnReqIeLength); 1914 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1915 FL("WPAIE: %02x:%02x:%02x:%02x:%02x:%02x"), 1916 buf[0], buf[1], buf[2], buf[3], buf[4], 1917 buf[5]); 1918 qdf_status = QDF_STATUS_SUCCESS; 1919 } 1920 } 1921 return qdf_status; 1922 } 1923 1924 /** 1925 * wlansap_set_wps_ie() - set WPI IE 1926 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1927 * can be extracted from its context. When MBSSID feature is enabled, 1928 * SAP context is directly passed to SAP APIs. 1929 * @pWPSIE: tSap_WPSIE structure that include WPS IEs 1930 * 1931 * This api function provides API for App/HDD to set WPS IE. 1932 * 1933 * Return: The QDF_STATUS code associated with performing the operation 1934 * QDF_STATUS_SUCCESS: Success and error code otherwise. 1935 */ 1936 QDF_STATUS wlansap_set_wps_ie(void *pCtx, tSap_WPSIE *pSap_WPSIe) 1937 { 1938 ptSapContext pSapCtx = NULL; 1939 void *hHal = NULL; 1940 1941 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 1942 "%s, %d", __func__, __LINE__); 1943 1944 pSapCtx = CDS_GET_SAP_CB(pCtx); 1945 if (NULL == pSapCtx) { 1946 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1947 "%s: Invalid SAP pointer from pCtx", 1948 __func__); 1949 return QDF_STATUS_E_FAULT; 1950 } 1951 1952 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 1953 if (NULL == hHal) { 1954 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 1955 "%s: Invalid HAL pointer from p_cds_gctx", 1956 __func__); 1957 return QDF_STATUS_E_FAULT; 1958 } 1959 1960 if (sap_acquire_global_lock(pSapCtx) == QDF_STATUS_SUCCESS) { 1961 if (pSap_WPSIe->sapWPSIECode == eSAP_WPS_BEACON_IE) { 1962 qdf_mem_copy(&pSapCtx->APWPSIEs.SirWPSBeaconIE, 1963 &pSap_WPSIe->sapwpsie. 1964 sapWPSBeaconIE, 1965 sizeof(tSap_WPSBeaconIE)); 1966 } else if (pSap_WPSIe->sapWPSIECode == 1967 eSAP_WPS_PROBE_RSP_IE) { 1968 qdf_mem_copy(&pSapCtx->APWPSIEs. 1969 SirWPSProbeRspIE, 1970 &pSap_WPSIe->sapwpsie. 1971 sapWPSProbeRspIE, 1972 sizeof(tSap_WPSProbeRspIE)); 1973 } else { 1974 sap_release_global_lock(pSapCtx); 1975 return QDF_STATUS_E_FAULT; 1976 } 1977 sap_release_global_lock(pSapCtx); 1978 return QDF_STATUS_SUCCESS; 1979 } else 1980 return QDF_STATUS_E_FAULT; 1981 } 1982 1983 /** 1984 * wlansap_update_wps_ie() - update WPI IE 1985 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 1986 * can be extracted from its context. When MBSSID feature is enabled, 1987 * SAP context is directly passed to SAP APIs. 1988 * 1989 * This api function provides API for App/HDD to update WPS IE. 1990 * 1991 * Return: The QDF_STATUS code associated with performing the operation 1992 * QDF_STATUS_SUCCESS: Success and error code otherwise. 1993 */ 1994 QDF_STATUS wlansap_update_wps_ie(void *pCtx) 1995 { 1996 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 1997 ptSapContext pSapCtx = NULL; 1998 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 1999 void *hHal = NULL; 2000 2001 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2002 "%s, %d", __func__, __LINE__); 2003 2004 pSapCtx = CDS_GET_SAP_CB(pCtx); 2005 if (NULL == pSapCtx) { 2006 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2007 "%s: Invalid SAP pointer from pCtx", 2008 __func__); 2009 return QDF_STATUS_E_FAULT; 2010 } 2011 2012 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2013 if (NULL == hHal) { 2014 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2015 "%s: Invalid HAL pointer from p_cds_gctx", 2016 __func__); 2017 return QDF_STATUS_E_FAULT; 2018 } 2019 2020 qdf_ret_status = 2021 sme_roam_update_apwpsie(hHal, pSapCtx->sessionId, 2022 &pSapCtx->APWPSIEs); 2023 2024 if (qdf_ret_status == QDF_STATUS_SUCCESS) 2025 qdf_status = QDF_STATUS_SUCCESS; 2026 else 2027 qdf_status = QDF_STATUS_E_FAULT; 2028 2029 return qdf_status; 2030 } 2031 2032 /** 2033 * wlansap_get_wps_state() - get WPS session state 2034 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2035 * can be extracted from its context. When MBSSID feature is enabled, 2036 * SAP context is directly passed to SAP APIs. 2037 * @pbWPSState: Pointer to variable to indicate if device is in 2038 * WPS Registration state 2039 * 2040 * This api function provides for Ap App/HDD to check if WPS session in process. 2041 * 2042 * Return: The QDF_STATUS code associated with performing the operation 2043 * QDF_STATUS_SUCCESS: Success 2044 */ 2045 QDF_STATUS wlansap_get_wps_state(void *pCtx, bool *bWPSState) 2046 { 2047 ptSapContext pSapCtx = NULL; 2048 void *hHal = NULL; 2049 2050 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2051 "%s, %d", __func__, __LINE__); 2052 2053 pSapCtx = CDS_GET_SAP_CB(pCtx); 2054 if (NULL == pSapCtx) { 2055 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2056 "%s: Invalid SAP pointer from pCtx", 2057 __func__); 2058 return QDF_STATUS_E_FAULT; 2059 } 2060 2061 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2062 if (NULL == hHal) { 2063 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2064 "%s: Invalid HAL pointer from p_cds_gctx", 2065 __func__); 2066 return QDF_STATUS_E_FAULT; 2067 } 2068 2069 if (sap_acquire_global_lock(pSapCtx) == QDF_STATUS_SUCCESS) { 2070 if (pSapCtx->APWPSIEs.SirWPSProbeRspIE. 2071 FieldPresent & 2072 SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) 2073 *bWPSState = true; 2074 else 2075 *bWPSState = false; 2076 2077 sap_release_global_lock(pSapCtx); 2078 2079 return QDF_STATUS_SUCCESS; 2080 } else 2081 return QDF_STATUS_E_FAULT; 2082 2083 } 2084 2085 QDF_STATUS sap_acquire_global_lock(ptSapContext pSapCtx) 2086 { 2087 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 2088 2089 if (QDF_IS_STATUS_SUCCESS(qdf_mutex_acquire(&pSapCtx->SapGlobalLock))) { 2090 qdf_status = QDF_STATUS_SUCCESS; 2091 } 2092 2093 return qdf_status; 2094 } 2095 2096 QDF_STATUS sap_release_global_lock(ptSapContext pSapCtx) 2097 { 2098 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 2099 2100 if (QDF_IS_STATUS_SUCCESS(qdf_mutex_release(&pSapCtx->SapGlobalLock))) { 2101 qdf_status = QDF_STATUS_SUCCESS; 2102 } 2103 2104 return qdf_status; 2105 } 2106 2107 /** 2108 * wlansap_set_wparsn_ies() - set WPA RSN IEs 2109 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2110 * can be extracted from its context. When MBSSID feature is enabled, 2111 * SAP context is directly passed to SAP APIs. 2112 * @pWPARSNIEs : buffer to the WPA/RSN IEs 2113 * @WPARSNIEsLen: length of WPA/RSN IEs 2114 * 2115 * This api function provides for Ap App/HDD to set AP WPA and RSN IE in its 2116 * beacon and probe response. 2117 * 2118 * Return: The QDF_STATUS code associated with performing the operation 2119 * QDF_STATUS_SUCCESS: Success and error code otherwise 2120 */ 2121 QDF_STATUS wlansap_set_wparsn_ies 2122 (void *pCtx, uint8_t *pWPARSNIEs, uint32_t WPARSNIEsLen) { 2123 ptSapContext pSapCtx = NULL; 2124 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2125 void *hHal = NULL; 2126 2127 pSapCtx = CDS_GET_SAP_CB(pCtx); 2128 if (NULL == pSapCtx) { 2129 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2130 "%s: Invalid SAP pointer from pCtx", 2131 __func__); 2132 return QDF_STATUS_E_FAULT; 2133 } 2134 2135 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2136 if (NULL == hHal) { 2137 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2138 "%s: Invalid HAL pointer from p_cds_gctx", 2139 __func__); 2140 return QDF_STATUS_E_FAULT; 2141 } 2142 2143 pSapCtx->APWPARSNIEs.length = (uint16_t) WPARSNIEsLen; 2144 qdf_mem_copy(pSapCtx->APWPARSNIEs.rsnIEdata, pWPARSNIEs, 2145 WPARSNIEsLen); 2146 2147 qdf_ret_status = 2148 sme_roam_update_apwparsni_es(hHal, pSapCtx->sessionId, 2149 &pSapCtx->APWPARSNIEs); 2150 2151 if (qdf_ret_status == QDF_STATUS_SUCCESS) 2152 return QDF_STATUS_SUCCESS; 2153 else 2154 return QDF_STATUS_E_FAULT; 2155 2156 return QDF_STATUS_E_FAULT; 2157 } 2158 2159 /** 2160 * wlansap_send_action() - send action frame 2161 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2162 * can be extracted from its context. When MBSSID feature is enabled, 2163 * SAP context is directly passed to SAP APIs. 2164 * @pBuf: Pointer of the action frame to be transmitted 2165 * @len: Length of the action frame 2166 * 2167 * This api function provides to send action frame sent by upper layer. 2168 * 2169 * Return: The QDF_STATUS code associated with performing the operation 2170 * QDF_STATUS_SUCCESS: Success and error code otherwise 2171 */ 2172 QDF_STATUS wlansap_send_action(void *pCtx, const uint8_t *pBuf, 2173 uint32_t len, uint16_t wait, uint16_t channel_freq) 2174 { 2175 ptSapContext pSapCtx = NULL; 2176 void *hHal = NULL; 2177 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2178 2179 pSapCtx = CDS_GET_SAP_CB(pCtx); 2180 if (NULL == pSapCtx) { 2181 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2182 "%s: Invalid SAP pointer from pCtx", 2183 __func__); 2184 return QDF_STATUS_E_FAULT; 2185 } 2186 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2187 if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) { 2188 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2189 "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", 2190 __func__, hHal, pSapCtx->isSapSessionOpen); 2191 return QDF_STATUS_E_FAULT; 2192 } 2193 2194 qdf_ret_status = 2195 sme_send_action(hHal, pSapCtx->sessionId, pBuf, len, 0, 2196 0, channel_freq); 2197 2198 if (QDF_STATUS_SUCCESS == qdf_ret_status) { 2199 return QDF_STATUS_SUCCESS; 2200 } 2201 2202 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2203 "Failed to Send Action Frame"); 2204 2205 return QDF_STATUS_E_FAULT; 2206 } 2207 2208 /** 2209 * wlansap_remain_on_channel() - set remain on channel 2210 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2211 * can be extracted from its context. When MBSSID feature is enabled, 2212 * SAP context is directly passed to SAP APIs. 2213 * @channel: Channel on which driver has to listen 2214 * @duration: Duration for which driver has to listen on specified channel 2215 * @callback: Callback function to be called once Listen is done. 2216 * @pContext: Context needs to be called in callback function. 2217 * @scan_id: scan identifier 2218 * 2219 * This api function provides to set Remain On channel on specified channel 2220 * for specified duration. 2221 * 2222 * Return: The QDF_STATUS code associated with performing the operation 2223 * QDF_STATUS_SUCCESS: Success and error code otherwise 2224 */ 2225 QDF_STATUS wlansap_remain_on_channel(void *pCtx, 2226 uint8_t channel, uint32_t duration, remainOnChanCallback callback, 2227 void *pContext, uint32_t *scan_id) 2228 { 2229 ptSapContext pSapCtx = NULL; 2230 void *hHal = NULL; 2231 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2232 2233 pSapCtx = CDS_GET_SAP_CB(pCtx); 2234 if (NULL == pSapCtx) { 2235 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2236 "%s: Invalid SAP pointer from pCtx", 2237 __func__); 2238 return QDF_STATUS_E_FAULT; 2239 } 2240 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2241 if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) { 2242 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2243 "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", 2244 __func__, hHal, pSapCtx->isSapSessionOpen); 2245 return QDF_STATUS_E_FAULT; 2246 } 2247 2248 qdf_ret_status = sme_remain_on_channel(hHal, pSapCtx->sessionId, 2249 channel, duration, callback, pContext, 2250 true, scan_id); 2251 2252 if (QDF_STATUS_SUCCESS == qdf_ret_status) { 2253 return QDF_STATUS_SUCCESS; 2254 } 2255 2256 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2257 "Failed to Set Remain on Channel"); 2258 2259 return QDF_STATUS_E_FAULT; 2260 } 2261 2262 /** 2263 * wlansap_cancel_remain_on_channel() - cancel remain on channel 2264 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2265 * can be extracted from its context. When MBSSID feature is enabled, 2266 * SAP context is directly passed to SAP APIs. 2267 * 2268 * This api cancel previous remain on channel request. 2269 * 2270 * Return: The QDF_STATUS code associated with performing the operation 2271 * QDF_STATUS_SUCCESS: Success and error code otherwie 2272 */ 2273 QDF_STATUS wlansap_cancel_remain_on_channel(void *pCtx, 2274 uint32_t scan_id) 2275 { 2276 ptSapContext pSapCtx = NULL; 2277 void *hHal = NULL; 2278 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2279 2280 pSapCtx = CDS_GET_SAP_CB(pCtx); 2281 if (NULL == pSapCtx) { 2282 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2283 "%s: Invalid SAP pointer from pCtx", 2284 __func__); 2285 return QDF_STATUS_E_FAULT; 2286 } 2287 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2288 if ((NULL == hHal) || 2289 (eSAP_TRUE != pSapCtx->isSapSessionOpen)) { 2290 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2291 "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", 2292 __func__, hHal, pSapCtx->isSapSessionOpen); 2293 return QDF_STATUS_E_FAULT; 2294 } 2295 2296 qdf_ret_status = 2297 sme_cancel_remain_on_channel(hHal, pSapCtx->sessionId, 2298 scan_id); 2299 2300 if (QDF_STATUS_SUCCESS == qdf_ret_status) { 2301 return QDF_STATUS_SUCCESS; 2302 } 2303 2304 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2305 "Failed to Cancel Remain on Channel"); 2306 2307 return QDF_STATUS_E_FAULT; 2308 } 2309 2310 /** 2311 * wlan_sap_set_pre_cac_status() - Set the pre cac status 2312 * @ctx: SAP context 2313 * @status: Status of pre cac 2314 * @handle: Global MAC handle 2315 * 2316 * Sets the pre cac status in the MAC context and updates the state 2317 * 2318 * Return: QDF_STATUS 2319 */ 2320 QDF_STATUS wlan_sap_set_pre_cac_status(void *ctx, bool status, 2321 tHalHandle handle) 2322 { 2323 ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx); 2324 tpAniSirGlobal mac_ctx = PMAC_STRUCT(handle); 2325 2326 if (!mac_ctx) { 2327 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2328 "%s: Invalid mac pointer", __func__); 2329 return QDF_STATUS_E_FAULT; 2330 } 2331 2332 if (!sap_ctx) { 2333 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2334 "%s: Invalid SAP pointer", __func__); 2335 return QDF_STATUS_E_FAULT; 2336 } 2337 2338 sap_ctx->is_pre_cac_on = status; 2339 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 2340 "%s: is_pre_cac_on:%d", __func__, sap_ctx->is_pre_cac_on); 2341 2342 return QDF_STATUS_SUCCESS; 2343 } 2344 2345 /** 2346 * wlan_sap_set_chan_before_pre_cac() - Save the channel before pre cac 2347 * @ctx: SAP context 2348 * @chan_before_pre_cac: Channel before pre cac 2349 * 2350 * Saves the channel that was in use before pre cac operation 2351 * 2352 * Return: QDF_STATUS 2353 */ 2354 QDF_STATUS wlan_sap_set_chan_before_pre_cac(void *ctx, 2355 uint8_t chan_before_pre_cac) 2356 { 2357 ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx); 2358 2359 if (!sap_ctx) { 2360 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2361 "%s: Invalid SAP pointer", __func__); 2362 return QDF_STATUS_E_FAULT; 2363 } 2364 2365 sap_ctx->chan_before_pre_cac = chan_before_pre_cac; 2366 return QDF_STATUS_SUCCESS; 2367 } 2368 2369 /** 2370 * wlan_sap_set_pre_cac_complete_status() - Sets pre cac complete status 2371 * @ctx: SAP context 2372 * @status: Status of pre cac complete 2373 * 2374 * Sets the status of pre cac i.e., whether pre cac is complete or not 2375 * 2376 * Return: QDF_STATUS 2377 */ 2378 QDF_STATUS wlan_sap_set_pre_cac_complete_status(void *ctx, bool status) 2379 { 2380 ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx); 2381 2382 if (!sap_ctx) { 2383 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2384 "%s: Invalid SAP pointer", __func__); 2385 return QDF_STATUS_E_FAULT; 2386 } 2387 2388 sap_ctx->pre_cac_complete = status; 2389 2390 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, 2391 "%s: pre cac complete status:%d session:%d", 2392 __func__, status, sap_ctx->sessionId); 2393 2394 return QDF_STATUS_SUCCESS; 2395 } 2396 2397 /** 2398 * wlan_sap_is_pre_cac_active() - Checks if pre cac in in progress 2399 * @handle: Global MAC handle 2400 * 2401 * Checks if pre cac is in progress in any of the SAP contexts 2402 * 2403 * Return: True is pre cac is active, false otherwise 2404 */ 2405 bool wlan_sap_is_pre_cac_active(tHalHandle handle) 2406 { 2407 tpAniSirGlobal mac = NULL; 2408 int i; 2409 2410 mac = PMAC_STRUCT(handle); 2411 if (!mac) { 2412 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2413 "%s: Invalid mac context", __func__); 2414 return false; 2415 } 2416 2417 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 2418 ptSapContext context = 2419 (ptSapContext) mac->sap.sapCtxList[i].pSapContext; 2420 if (context && context->is_pre_cac_on) 2421 return true; 2422 } 2423 return false; 2424 } 2425 2426 /** 2427 * wlan_sap_get_pre_cac_vdev_id() - Get vdev id of the pre cac interface 2428 * @handle: Global handle 2429 * @vdev_id: vdev id 2430 * 2431 * Fetches the vdev id of the pre cac interface 2432 * 2433 * Return: QDF_STATUS 2434 */ 2435 QDF_STATUS wlan_sap_get_pre_cac_vdev_id(tHalHandle handle, uint8_t *vdev_id) 2436 { 2437 tpAniSirGlobal mac = NULL; 2438 uint8_t i; 2439 2440 mac = PMAC_STRUCT(handle); 2441 if (!mac) { 2442 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 2443 "%s: Invalid mac context", __func__); 2444 return QDF_STATUS_E_FAULT; 2445 } 2446 2447 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 2448 ptSapContext context = 2449 (ptSapContext) mac->sap.sapCtxList[i].pSapContext; 2450 if (context && context->is_pre_cac_on) { 2451 *vdev_id = i; 2452 return QDF_STATUS_SUCCESS; 2453 } 2454 } 2455 return QDF_STATUS_E_FAILURE; 2456 } 2457 2458 /** 2459 * wlansap_register_mgmt_frame() - register management frame 2460 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2461 * can be extracted from its context. When MBSSID feature is enabled, 2462 * SAP context is directly passed to SAP APIs. 2463 * @frameType: frameType that needs to be registered with PE. 2464 * @matchData: Data pointer which should be matched after frame type is matched. 2465 * @matchLen: Length of the matchData 2466 * 2467 * HDD use this API to register specified type of frame with CORE stack. 2468 * On receiving such kind of frame CORE stack should pass this frame to HDD 2469 * 2470 * Return: The QDF_STATUS code associated with performing the operation 2471 * QDF_STATUS_SUCCESS: Success and error code otherwise 2472 */ 2473 QDF_STATUS wlansap_register_mgmt_frame 2474 (void *pCtx, 2475 uint16_t frameType, uint8_t *matchData, uint16_t matchLen) { 2476 ptSapContext pSapCtx = NULL; 2477 void *hHal = NULL; 2478 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2479 2480 pSapCtx = CDS_GET_SAP_CB(pCtx); 2481 if (NULL == pSapCtx) { 2482 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2483 "%s: Invalid SAP pointer from pCtx", 2484 __func__); 2485 return QDF_STATUS_E_FAULT; 2486 } 2487 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2488 if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) { 2489 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2490 "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", 2491 __func__, hHal, pSapCtx->isSapSessionOpen); 2492 return QDF_STATUS_E_FAULT; 2493 } 2494 2495 qdf_ret_status = sme_register_mgmt_frame(hHal, pSapCtx->sessionId, 2496 frameType, matchData, 2497 matchLen); 2498 2499 if (QDF_STATUS_SUCCESS == qdf_ret_status) { 2500 return QDF_STATUS_SUCCESS; 2501 } 2502 2503 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2504 "Failed to Register MGMT frame"); 2505 2506 return QDF_STATUS_E_FAULT; 2507 } 2508 2509 /** 2510 * wlansap_de_register_mgmt_frame() - de register management frame 2511 * @pCtx: Pointer to the global cds context; a handle to SAP's control block 2512 * can be extracted from its context. When MBSSID feature is enabled, 2513 * SAP context is directly passed to SAP APIs. 2514 * @frameType: frameType that needs to be De-registered with PE. 2515 * @matchData: Data pointer which should be matched after frame type is matched. 2516 * @matchLen: Length of the matchData 2517 * 2518 * This API is used to deregister previously registered frame. 2519 * 2520 * Return: The QDF_STATUS code associated with performing the operation 2521 * QDF_STATUS_SUCCESS: Success and error code otherwise 2522 */ 2523 QDF_STATUS wlansap_de_register_mgmt_frame 2524 (void *pCtx, 2525 uint16_t frameType, uint8_t *matchData, uint16_t matchLen) { 2526 ptSapContext pSapCtx = NULL; 2527 void *hHal = NULL; 2528 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2529 2530 pSapCtx = CDS_GET_SAP_CB(pCtx); 2531 if (NULL == pSapCtx) { 2532 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2533 "%s: Invalid SAP pointer from pCtx", 2534 __func__); 2535 return QDF_STATUS_E_FAULT; 2536 } 2537 hHal = CDS_GET_HAL_CB(pSapCtx->p_cds_gctx); 2538 if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) { 2539 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2540 "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", 2541 __func__, hHal, pSapCtx->isSapSessionOpen); 2542 return QDF_STATUS_E_FAULT; 2543 } 2544 2545 qdf_ret_status = 2546 sme_deregister_mgmt_frame(hHal, pSapCtx->sessionId, frameType, 2547 matchData, matchLen); 2548 2549 if (QDF_STATUS_SUCCESS == qdf_ret_status) { 2550 return QDF_STATUS_SUCCESS; 2551 } 2552 2553 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2554 "Failed to Deregister MGMT frame"); 2555 2556 return QDF_STATUS_E_FAULT; 2557 } 2558 2559 /*========================================================================== 2560 FUNCTION wlansap_channel_change_request 2561 2562 DESCRIPTION 2563 This API is used to send an Indication to SME/PE to change the 2564 current operating channel to a different target channel. 2565 2566 The Channel change will be issued by SAP under the following 2567 scenarios. 2568 1. A radar indication is received during SAP CAC WAIT STATE and 2569 channel change is required. 2570 2. A radar indication is received during SAP STARTED STATE and 2571 channel change is required. 2572 DEPENDENCIES 2573 NA. 2574 2575 PARAMETERS 2576 IN 2577 pSapCtx: Pointer to cds global context structure 2578 2579 RETURN VALUE 2580 The QDF_STATUS code associated with performing the operation 2581 2582 QDF_STATUS_SUCCESS: Success 2583 2584 SIDE EFFECTS 2585 ============================================================================*/ 2586 QDF_STATUS 2587 wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel) 2588 { 2589 ptSapContext sapContext = NULL; 2590 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2591 void *hHal = NULL; 2592 tpAniSirGlobal mac_ctx = NULL; 2593 eCsrPhyMode phy_mode; 2594 struct ch_params_s *ch_params; 2595 sapContext = (ptSapContext) pSapCtx; 2596 2597 if (NULL == sapContext) { 2598 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2599 "%s: Invalid SAP pointer", __func__); 2600 return QDF_STATUS_E_FAULT; 2601 } 2602 2603 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2604 if (NULL == hHal) { 2605 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2606 "%s: Invalid HAL pointer from p_cds_gctx", __func__); 2607 return QDF_STATUS_E_FAULT; 2608 } 2609 mac_ctx = PMAC_STRUCT(hHal); 2610 phy_mode = sapContext->csr_roamProfile.phyMode; 2611 sapContext->csr_roamProfile.ChannelInfo.ChannelList[0] = target_channel; 2612 /* 2613 * We are getting channel bonding mode from sapDfsInfor structure 2614 * because we've implemented channel width fallback mechanism for DFS 2615 * which will result in channel width changing dynamically. 2616 */ 2617 ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params; 2618 cds_set_channel_params(target_channel, 0, ch_params); 2619 sapContext->ch_params.ch_width = ch_params->ch_width; 2620 /* Update the channel as this will be used to 2621 * send event to supplicant 2622 */ 2623 sapContext->channel = target_channel; 2624 sapContext->csr_roamProfile.ch_params.ch_width = ch_params->ch_width; 2625 sapContext->csr_roamProfile.ch_params.sec_ch_offset = 2626 ch_params->sec_ch_offset; 2627 sapContext->csr_roamProfile.ch_params.center_freq_seg0 = 2628 ch_params->center_freq_seg0; 2629 sapContext->csr_roamProfile.ch_params.center_freq_seg1 = 2630 ch_params->center_freq_seg1; 2631 2632 qdf_ret_status = sme_roam_channel_change_req(hHal, sapContext->bssid, 2633 ch_params, &sapContext->csr_roamProfile); 2634 2635 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2636 "%s: chan:%d width:%d offset:%d seg0:%d seg1:%d", 2637 __func__, sapContext->channel, ch_params->ch_width, 2638 ch_params->sec_ch_offset, ch_params->center_freq_seg0, 2639 ch_params->center_freq_seg1); 2640 2641 if (qdf_ret_status == QDF_STATUS_SUCCESS) { 2642 sap_signal_hdd_event(sapContext, NULL, 2643 eSAP_CHANNEL_CHANGE_EVENT, 2644 (void *) eSAP_STATUS_SUCCESS); 2645 2646 return QDF_STATUS_SUCCESS; 2647 } 2648 return QDF_STATUS_E_FAULT; 2649 } 2650 2651 /*========================================================================== 2652 2653 FUNCTION wlansap_start_beacon_req 2654 DESCRIPTION 2655 This API is used to send an Indication to SME/PE to start 2656 beaconing on the current operating channel. 2657 2658 Brief:When SAP is started on DFS channel and when ADD BSS RESP is received 2659 LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When 2660 CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon 2661 request to LIM. 2662 2663 DEPENDENCIES 2664 NA. 2665 2666 PARAMETERS 2667 2668 IN 2669 pSapCtx: Pointer to cds global context structure 2670 2671 RETURN VALUE 2672 The QDF_STATUS code associated with performing the operation 2673 2674 QDF_STATUS_SUCCESS: Success 2675 2676 SIDE EFFECTS 2677 ============================================================================*/ 2678 QDF_STATUS wlansap_start_beacon_req(void *pSapCtx) 2679 { 2680 ptSapContext sapContext = NULL; 2681 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2682 void *hHal = NULL; 2683 uint8_t dfsCacWaitStatus = 0; 2684 tpAniSirGlobal pMac = NULL; 2685 sapContext = (ptSapContext) pSapCtx; 2686 2687 if (NULL == sapContext) { 2688 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2689 "%s: Invalid SAP pointer", __func__); 2690 return QDF_STATUS_E_FAULT; 2691 } 2692 2693 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2694 if (NULL == hHal) { 2695 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2696 "%s: Invalid HAL pointer from p_cds_gctx", __func__); 2697 return QDF_STATUS_E_FAULT; 2698 } 2699 pMac = PMAC_STRUCT(hHal); 2700 2701 /* No Radar was found during CAC WAIT, So start Beaconing */ 2702 if (pMac->sap.SapDfsInfo.sap_radar_found_status == false) { 2703 /* CAC Wait done without any Radar Detection */ 2704 dfsCacWaitStatus = true; 2705 sapContext->pre_cac_complete = false; 2706 qdf_ret_status = sme_roam_start_beacon_req(hHal, 2707 sapContext->bssid, 2708 dfsCacWaitStatus); 2709 if (qdf_ret_status == QDF_STATUS_SUCCESS) { 2710 return QDF_STATUS_SUCCESS; 2711 } 2712 return QDF_STATUS_E_FAULT; 2713 } 2714 2715 return QDF_STATUS_E_FAULT; 2716 } 2717 2718 /*========================================================================== 2719 FUNCTION wlansap_dfs_send_csa_ie_request 2720 2721 DESCRIPTION 2722 This API is used to send channel switch announcement request to PE 2723 DEPENDENCIES 2724 NA. 2725 2726 PARAMETERS 2727 IN 2728 pSapCtx: Pointer to cds global context structure 2729 2730 RETURN VALUE 2731 The QDF_STATUS code associated with performing the operation 2732 2733 QDF_STATUS_SUCCESS: Success 2734 2735 SIDE EFFECTS 2736 ============================================================================*/ 2737 QDF_STATUS wlansap_dfs_send_csa_ie_request(void *pSapCtx) 2738 { 2739 ptSapContext sapContext = NULL; 2740 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; 2741 void *hHal = NULL; 2742 tpAniSirGlobal pMac = NULL; 2743 sapContext = (ptSapContext) pSapCtx; 2744 2745 if (NULL == sapContext) { 2746 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2747 "%s: Invalid SAP pointer", __func__); 2748 return QDF_STATUS_E_FAULT; 2749 } 2750 2751 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 2752 if (NULL == hHal) { 2753 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2754 "%s: Invalid HAL pointer from p_cds_gctx", __func__); 2755 return QDF_STATUS_E_FAULT; 2756 } 2757 pMac = PMAC_STRUCT(hHal); 2758 2759 pMac->sap.SapDfsInfo.new_ch_params.ch_width = 2760 pMac->sap.SapDfsInfo.new_chanWidth; 2761 cds_set_channel_params(pMac->sap.SapDfsInfo.target_channel, 2762 0, &pMac->sap.SapDfsInfo.new_ch_params); 2763 2764 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 2765 "%s: chan:%d req:%d width:%d off:%d", 2766 __func__, pMac->sap.SapDfsInfo.target_channel, 2767 pMac->sap.SapDfsInfo.csaIERequired, 2768 pMac->sap.SapDfsInfo.new_ch_params.ch_width, 2769 pMac->sap.SapDfsInfo.new_ch_params.sec_ch_offset); 2770 2771 qdf_ret_status = sme_roam_csa_ie_request(hHal, 2772 sapContext->bssid, 2773 pMac->sap.SapDfsInfo.target_channel, 2774 pMac->sap.SapDfsInfo.csaIERequired, 2775 &pMac->sap.SapDfsInfo.new_ch_params); 2776 2777 if (qdf_ret_status == QDF_STATUS_SUCCESS) { 2778 return QDF_STATUS_SUCCESS; 2779 } 2780 2781 return QDF_STATUS_E_FAULT; 2782 } 2783 2784 /*========================================================================== 2785 FUNCTION wlansap_get_dfs_ignore_cac 2786 2787 DESCRIPTION 2788 This API is used to get the value of ignore_cac value 2789 2790 DEPENDENCIES 2791 NA. 2792 2793 PARAMETERS 2794 IN 2795 hHal : HAL pointer 2796 pIgnore_cac : pointer to ignore_cac variable 2797 2798 RETURN VALUE 2799 The QDF_STATUS code associated with performing the operation 2800 2801 QDF_STATUS_SUCCESS: Success 2802 2803 SIDE EFFECTS 2804 ============================================================================*/ 2805 QDF_STATUS wlansap_get_dfs_ignore_cac(tHalHandle hHal, uint8_t *pIgnore_cac) 2806 { 2807 tpAniSirGlobal pMac = NULL; 2808 2809 if (NULL != hHal) { 2810 pMac = PMAC_STRUCT(hHal); 2811 } else { 2812 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2813 "%s: Invalid hHal pointer", __func__); 2814 return QDF_STATUS_E_FAULT; 2815 } 2816 2817 *pIgnore_cac = pMac->sap.SapDfsInfo.ignore_cac; 2818 return QDF_STATUS_SUCCESS; 2819 } 2820 2821 /*========================================================================== 2822 FUNCTION wlansap_set_dfs_ignore_cac 2823 2824 DESCRIPTION 2825 This API is used to Set the value of ignore_cac value 2826 2827 DEPENDENCIES 2828 NA. 2829 2830 PARAMETERS 2831 IN 2832 hHal : HAL pointer 2833 ignore_cac : value to set for ignore_cac variable in DFS global structure. 2834 2835 RETURN VALUE 2836 The QDF_STATUS code associated with performing the operation 2837 2838 QDF_STATUS_SUCCESS: Success 2839 2840 SIDE EFFECTS 2841 ============================================================================*/ 2842 QDF_STATUS wlansap_set_dfs_ignore_cac(tHalHandle hHal, uint8_t ignore_cac) 2843 { 2844 tpAniSirGlobal pMac = NULL; 2845 2846 if (NULL != hHal) { 2847 pMac = PMAC_STRUCT(hHal); 2848 } else { 2849 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2850 "%s: Invalid hHal pointer", __func__); 2851 return QDF_STATUS_E_FAULT; 2852 } 2853 2854 pMac->sap.SapDfsInfo.ignore_cac = (ignore_cac >= true) ? 2855 true : false; 2856 return QDF_STATUS_SUCCESS; 2857 } 2858 2859 /** 2860 * wlansap_set_dfs_restrict_japan_w53() - enable/disable dfS for japan 2861 * @hHal : HAL pointer 2862 * @disable_Dfs_JapanW3 :Indicates if Japan W53 is disabled when set to 1 2863 * Indicates if Japan W53 is enabled when set to 0 2864 * 2865 * This API is used to enable or disable Japan W53 Band 2866 * Return: The QDF_STATUS code associated with performing the operation 2867 * QDF_STATUS_SUCCESS: Success 2868 */ 2869 QDF_STATUS 2870 wlansap_set_dfs_restrict_japan_w53(tHalHandle hHal, uint8_t disable_Dfs_W53) 2871 { 2872 tpAniSirGlobal pMac = NULL; 2873 QDF_STATUS status; 2874 uint8_t dfs_region; 2875 2876 if (NULL != hHal) { 2877 pMac = PMAC_STRUCT(hHal); 2878 } else { 2879 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2880 "%s: Invalid hHal pointer", __func__); 2881 return QDF_STATUS_E_FAULT; 2882 } 2883 2884 cds_get_dfs_region(&dfs_region); 2885 2886 /* 2887 * Set the JAPAN W53 restriction only if the current 2888 * regulatory domain is JAPAN. 2889 */ 2890 if (DFS_MKK_REGION == dfs_region) { 2891 pMac->sap.SapDfsInfo.is_dfs_w53_disabled = disable_Dfs_W53; 2892 QDF_TRACE(QDF_MODULE_ID_SAP, 2893 QDF_TRACE_LEVEL_INFO_LOW, 2894 FL("sapdfs: SET DFS JAPAN W53 DISABLED = %d"), 2895 pMac->sap.SapDfsInfo.is_dfs_w53_disabled); 2896 2897 status = QDF_STATUS_SUCCESS; 2898 } else { 2899 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2900 FL 2901 ("Regdomain not japan, set disable JP W53 not valid")); 2902 2903 status = QDF_STATUS_E_FAULT; 2904 } 2905 2906 return status; 2907 } 2908 2909 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 2910 /** 2911 * wlan_sap_set_channel_avoidance() - sets sap mcc channel avoidance ini param 2912 * @hal: hal handle 2913 * @sap_channel_avoidance: ini parameter value 2914 * 2915 * sets sap mcc channel avoidance ini param, to be called in sap_start 2916 * 2917 * Return: success of failure of operation 2918 */ 2919 QDF_STATUS 2920 wlan_sap_set_channel_avoidance(tHalHandle hal, bool sap_channel_avoidance) 2921 { 2922 tpAniSirGlobal mac_ctx = NULL; 2923 if (NULL != hal) 2924 mac_ctx = PMAC_STRUCT(hal); 2925 if (mac_ctx == NULL || hal == NULL) { 2926 QDF_TRACE(QDF_MODULE_ID_SAP, 2927 QDF_TRACE_LEVEL_ERROR, 2928 FL("hal or mac_ctx pointer NULL")); 2929 return QDF_STATUS_E_FAULT; 2930 } 2931 mac_ctx->sap.sap_channel_avoidance = sap_channel_avoidance; 2932 return QDF_STATUS_SUCCESS; 2933 } 2934 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 2935 2936 /** 2937 * wlansap_set_dfs_preferred_channel_location() - set dfs preferred channel 2938 * @hHal : HAL pointer 2939 * @dfs_Preferred_Channels_location : 2940 * 0 - Indicates No preferred channel location restrictions 2941 * 1 - Indicates SAP Indoor Channels operation only. 2942 * 2 - Indicates SAP Outdoor Channels operation only. 2943 * 2944 * This API is used to set sap preferred channels location 2945 * to resetrict the DFS random channel selection algorithm 2946 * either Indoor/Outdoor channels only. 2947 * 2948 * Return: The QDF_STATUS code associated with performing the operation 2949 * QDF_STATUS_SUCCESS: Success and error code otherwise. 2950 */ 2951 QDF_STATUS 2952 wlansap_set_dfs_preferred_channel_location(tHalHandle hHal, 2953 uint8_t 2954 dfs_Preferred_Channels_location) 2955 { 2956 tpAniSirGlobal pMac = NULL; 2957 QDF_STATUS status; 2958 uint8_t dfs_region; 2959 2960 if (NULL != hHal) { 2961 pMac = PMAC_STRUCT(hHal); 2962 } else { 2963 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2964 "%s: Invalid hHal pointer", __func__); 2965 return QDF_STATUS_E_FAULT; 2966 } 2967 2968 cds_get_dfs_region(&dfs_region); 2969 2970 /* 2971 * The Indoor/Outdoor only random channel selection 2972 * restriction is currently enforeced only for 2973 * JAPAN regulatory domain. 2974 */ 2975 if (DFS_MKK_REGION == dfs_region) { 2976 pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location = 2977 dfs_Preferred_Channels_location; 2978 QDF_TRACE(QDF_MODULE_ID_SAP, 2979 QDF_TRACE_LEVEL_INFO_LOW, 2980 FL 2981 ("sapdfs:Set Preferred Operating Channel location=%d"), 2982 pMac->sap.SapDfsInfo. 2983 sap_operating_chan_preferred_location); 2984 2985 status = QDF_STATUS_SUCCESS; 2986 } else { 2987 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 2988 FL 2989 ("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location")); 2990 2991 status = QDF_STATUS_E_FAULT; 2992 } 2993 2994 return status; 2995 } 2996 2997 /*========================================================================== 2998 FUNCTION wlansap_set_dfs_target_chnl 2999 3000 DESCRIPTION 3001 This API is used to set next target chnl as provided channel. 3002 you can provide any valid channel to this API. 3003 3004 DEPENDENCIES 3005 NA. 3006 3007 PARAMETERS 3008 IN 3009 hHal : HAL pointer 3010 target_channel : target channel to be set 3011 3012 RETURN VALUE 3013 The QDF_STATUS code associated with performing the operation 3014 3015 QDF_STATUS_SUCCESS: Success 3016 3017 SIDE EFFECTS 3018 ============================================================================*/ 3019 QDF_STATUS wlansap_set_dfs_target_chnl(tHalHandle hHal, uint8_t target_channel) 3020 { 3021 tpAniSirGlobal pMac = NULL; 3022 3023 if (NULL != hHal) { 3024 pMac = PMAC_STRUCT(hHal); 3025 } else { 3026 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3027 "%s: Invalid hHal pointer", __func__); 3028 return QDF_STATUS_E_FAULT; 3029 } 3030 if (target_channel > 0) { 3031 pMac->sap.SapDfsInfo.user_provided_target_channel = 3032 target_channel; 3033 } else { 3034 pMac->sap.SapDfsInfo.user_provided_target_channel = 0; 3035 } 3036 3037 return QDF_STATUS_SUCCESS; 3038 } 3039 3040 QDF_STATUS 3041 wlansap_update_sap_config_add_ie(tsap_Config_t *pConfig, 3042 const uint8_t *pAdditionIEBuffer, 3043 uint16_t additionIELength, 3044 eUpdateIEsType updateType) 3045 { 3046 QDF_STATUS status = QDF_STATUS_SUCCESS; 3047 uint8_t bufferValid = false; 3048 uint16_t bufferLength = 0; 3049 uint8_t *pBuffer = NULL; 3050 3051 if (NULL == pConfig) { 3052 return QDF_STATUS_E_FAULT; 3053 } 3054 3055 if ((pAdditionIEBuffer != NULL) && (additionIELength != 0)) { 3056 /* initialize the buffer pointer so that pe can copy */ 3057 if (additionIELength > 0) { 3058 bufferLength = additionIELength; 3059 pBuffer = qdf_mem_malloc(bufferLength); 3060 if (NULL == pBuffer) { 3061 QDF_TRACE(QDF_MODULE_ID_SME, 3062 QDF_TRACE_LEVEL_ERROR, 3063 FL("Could not allocate the buffer ")); 3064 return QDF_STATUS_E_NOMEM; 3065 } 3066 qdf_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength); 3067 bufferValid = true; 3068 } 3069 } 3070 3071 switch (updateType) { 3072 case eUPDATE_IE_PROBE_BCN: 3073 if (bufferValid) { 3074 pConfig->probeRespBcnIEsLen = bufferLength; 3075 pConfig->pProbeRespBcnIEsBuffer = pBuffer; 3076 } else { 3077 qdf_mem_free(pConfig->pProbeRespBcnIEsBuffer); 3078 pConfig->probeRespBcnIEsLen = 0; 3079 pConfig->pProbeRespBcnIEsBuffer = NULL; 3080 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 3081 FL 3082 ("No Probe Resp beacone IE received in set beacon")); 3083 } 3084 break; 3085 case eUPDATE_IE_PROBE_RESP: 3086 if (bufferValid) { 3087 pConfig->probeRespIEsBufferLen = bufferLength; 3088 pConfig->pProbeRespIEsBuffer = pBuffer; 3089 } else { 3090 qdf_mem_free(pConfig->pProbeRespIEsBuffer); 3091 pConfig->probeRespIEsBufferLen = 0; 3092 pConfig->pProbeRespIEsBuffer = NULL; 3093 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 3094 FL 3095 ("No Probe Response IE received in set beacon")); 3096 } 3097 break; 3098 case eUPDATE_IE_ASSOC_RESP: 3099 if (bufferValid) { 3100 pConfig->assocRespIEsLen = bufferLength; 3101 pConfig->pAssocRespIEsBuffer = pBuffer; 3102 } else { 3103 qdf_mem_free(pConfig->pAssocRespIEsBuffer); 3104 pConfig->assocRespIEsLen = 0; 3105 pConfig->pAssocRespIEsBuffer = NULL; 3106 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 3107 FL 3108 ("No Assoc Response IE received in set beacon")); 3109 } 3110 break; 3111 default: 3112 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 3113 FL("No matching buffer type %d"), updateType); 3114 if (pBuffer != NULL) 3115 qdf_mem_free(pBuffer); 3116 break; 3117 } 3118 3119 return status; 3120 } 3121 3122 QDF_STATUS 3123 wlansap_reset_sap_config_add_ie(tsap_Config_t *pConfig, eUpdateIEsType updateType) 3124 { 3125 if (NULL == pConfig) { 3126 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3127 "%s: Invalid Config pointer", __func__); 3128 return QDF_STATUS_E_FAULT; 3129 } 3130 3131 switch (updateType) { 3132 case eUPDATE_IE_ALL: /*only used to reset */ 3133 case eUPDATE_IE_PROBE_RESP: 3134 qdf_mem_free(pConfig->pProbeRespIEsBuffer); 3135 pConfig->probeRespIEsBufferLen = 0; 3136 pConfig->pProbeRespIEsBuffer = NULL; 3137 if (eUPDATE_IE_ALL != updateType) 3138 break; 3139 3140 case eUPDATE_IE_ASSOC_RESP: 3141 qdf_mem_free(pConfig->pAssocRespIEsBuffer); 3142 pConfig->assocRespIEsLen = 0; 3143 pConfig->pAssocRespIEsBuffer = NULL; 3144 if (eUPDATE_IE_ALL != updateType) 3145 break; 3146 3147 case eUPDATE_IE_PROBE_BCN: 3148 qdf_mem_free(pConfig->pProbeRespBcnIEsBuffer); 3149 pConfig->probeRespBcnIEsLen = 0; 3150 pConfig->pProbeRespBcnIEsBuffer = NULL; 3151 if (eUPDATE_IE_ALL != updateType) 3152 break; 3153 3154 default: 3155 if (eUPDATE_IE_ALL != updateType) 3156 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3157 FL("Invalid buffer type %d"), updateType); 3158 break; 3159 } 3160 return QDF_STATUS_SUCCESS; 3161 } 3162 3163 /*========================================================================== 3164 FUNCTION wlansap_extend_to_acs_range 3165 3166 DESCRIPTION Function extends give channel range to consider ACS chan bonding 3167 3168 DEPENDENCIES PARAMETERS 3169 3170 IN /OUT 3171 *startChannelNum : ACS extend start ch 3172 *endChannelNum : ACS extended End ch 3173 *bandStartChannel: Band start ch 3174 *bandEndChannel : Band end ch 3175 3176 RETURN VALUE NONE 3177 3178 SIDE EFFECTS 3179 ============================================================================*/ 3180 void wlansap_extend_to_acs_range(uint8_t *startChannelNum, 3181 uint8_t *endChannelNum, 3182 uint8_t *bandStartChannel, 3183 uint8_t *bandEndChannel) 3184 { 3185 #define ACS_WLAN_20M_CH_INC 4 3186 #define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC 3187 #define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3) 3188 3189 uint8_t tmp_startChannelNum = 0, tmp_endChannelNum = 0; 3190 3191 if (*startChannelNum <= 14 && *endChannelNum <= 14) { 3192 *bandStartChannel = CHAN_ENUM_1; 3193 *bandEndChannel = CHAN_ENUM_14; 3194 tmp_startChannelNum = *startChannelNum > 5 ? 3195 (*startChannelNum - ACS_2G_EXTEND) : 1; 3196 tmp_endChannelNum = (*endChannelNum + ACS_2G_EXTEND) <= 14 ? 3197 (*endChannelNum + ACS_2G_EXTEND) : 14; 3198 } else if (*startChannelNum >= 36 && *endChannelNum >= 36) { 3199 *bandStartChannel = CHAN_ENUM_36; 3200 *bandEndChannel = CHAN_ENUM_165; 3201 tmp_startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 36 ? 3202 (*startChannelNum - ACS_5G_EXTEND) : 36; 3203 tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 165 ? 3204 (*endChannelNum + ACS_5G_EXTEND) : 165; 3205 } else { 3206 *bandStartChannel = CHAN_ENUM_1; 3207 *bandEndChannel = CHAN_ENUM_165; 3208 tmp_startChannelNum = *startChannelNum > 5 ? 3209 (*startChannelNum - ACS_2G_EXTEND) : 1; 3210 tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 165 ? 3211 (*endChannelNum + ACS_5G_EXTEND) : 165; 3212 } 3213 3214 /* Note if the ACS range include only DFS channels, do not cross range 3215 * Active scanning in adjacent non DFS channels results in transmission 3216 * spikes in DFS specturm channels which is due to emission spill. 3217 * Remove the active channels from extend ACS range for DFS only range 3218 */ 3219 if (CDS_IS_DFS_CH(*startChannelNum)) { 3220 while (!CDS_IS_DFS_CH(tmp_startChannelNum) && 3221 tmp_startChannelNum < *startChannelNum) 3222 tmp_startChannelNum += ACS_WLAN_20M_CH_INC; 3223 3224 *startChannelNum = tmp_startChannelNum; 3225 } 3226 if (CDS_IS_DFS_CH(*endChannelNum)) { 3227 while (!CDS_IS_DFS_CH(tmp_endChannelNum) && 3228 tmp_endChannelNum > *endChannelNum) 3229 tmp_endChannelNum -= ACS_WLAN_20M_CH_INC; 3230 3231 *endChannelNum = tmp_endChannelNum; 3232 } 3233 } 3234 3235 /** 3236 * wlansap_get_dfs_nol() - Get the DFS NOL 3237 * @pSapCtx: SAP context 3238 * @nol: Pointer to the NOL 3239 * @nol_len: Length of the NOL 3240 * 3241 * Provides the DFS NOL 3242 * 3243 * Return: QDF_STATUS 3244 */ 3245 QDF_STATUS wlansap_get_dfs_nol(void *pSapCtx, uint8_t *nol, uint32_t *nol_len) 3246 { 3247 int i = 0, j = 0; 3248 ptSapContext sapContext = (ptSapContext) pSapCtx; 3249 void *hHal = NULL; 3250 tpAniSirGlobal pMac = NULL; 3251 uint64_t current_time, found_time, elapsed_time; 3252 unsigned long left_time; 3253 tSapDfsNolInfo *dfs_nol = NULL; 3254 bool bAvailable = false; 3255 *nol_len = 0; 3256 3257 if (NULL == sapContext) { 3258 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3259 "%s: Invalid SAP pointer from p_cds_gctx", __func__); 3260 return QDF_STATUS_E_FAULT; 3261 } 3262 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 3263 if (NULL == hHal) { 3264 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3265 "%s: Invalid HAL pointer from p_cds_gctx", __func__); 3266 return QDF_STATUS_E_FAULT; 3267 } 3268 pMac = PMAC_STRUCT(hHal); 3269 3270 if (!pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) { 3271 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3272 "%s: DFS NOL is empty", __func__); 3273 return QDF_STATUS_SUCCESS; 3274 } 3275 3276 dfs_nol = pMac->sap.SapDfsInfo.sapDfsChannelNolList; 3277 3278 if (!dfs_nol) { 3279 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3280 "%s: DFS NOL context is null", __func__); 3281 return QDF_STATUS_E_FAULT; 3282 } 3283 3284 for (i = 0; i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; 3285 i++) { 3286 if (!dfs_nol[i].dfs_channel_number) 3287 continue; 3288 3289 current_time = cds_get_monotonic_boottime(); 3290 found_time = dfs_nol[i].radar_found_timestamp; 3291 3292 elapsed_time = current_time - found_time; 3293 3294 /* check if channel is available 3295 * if either channel is usable or available, or timer expired 30mins 3296 */ 3297 bAvailable = 3298 ((dfs_nol[i].radar_status_flag == 3299 eSAP_DFS_CHANNEL_AVAILABLE) 3300 || (dfs_nol[i].radar_status_flag == 3301 eSAP_DFS_CHANNEL_USABLE) 3302 || (elapsed_time >= SAP_DFS_NON_OCCUPANCY_PERIOD)); 3303 3304 if (bAvailable) { 3305 dfs_nol[i].radar_status_flag = 3306 eSAP_DFS_CHANNEL_AVAILABLE; 3307 dfs_nol[i].radar_found_timestamp = 0; 3308 3309 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3310 "%s: Channel[%d] is AVAILABLE", 3311 __func__, dfs_nol[i].dfs_channel_number); 3312 } else { 3313 3314 /* the time left in min */ 3315 left_time = SAP_DFS_NON_OCCUPANCY_PERIOD - elapsed_time; 3316 left_time = left_time / (60 * 1000 * 1000); 3317 3318 nol[j++] = dfs_nol[i].dfs_channel_number; 3319 (*nol_len)++; 3320 3321 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3322 "%s: Channel[%d] is UNAVAILABLE [%lu min left]", 3323 __func__, 3324 dfs_nol[i].dfs_channel_number, left_time); 3325 } 3326 } 3327 3328 return QDF_STATUS_SUCCESS; 3329 } 3330 3331 /*========================================================================== 3332 FUNCTION wlansap_set_dfs_nol 3333 3334 DESCRIPTION 3335 This API is used to set the dfs nol 3336 DEPENDENCIES 3337 NA. 3338 3339 PARAMETERS 3340 IN 3341 sapContext: Pointer to cds global context structure 3342 conf: set type 3343 3344 RETURN VALUE 3345 The QDF_STATUS code associated with performing the operation 3346 3347 QDF_STATUS_SUCCESS: Success 3348 3349 SIDE EFFECTS 3350 ============================================================================*/ 3351 QDF_STATUS wlansap_set_dfs_nol(void *pSapCtx, eSapDfsNolType conf) 3352 { 3353 int i = 0; 3354 ptSapContext sapContext = (ptSapContext) pSapCtx; 3355 void *hHal = NULL; 3356 tpAniSirGlobal pMac = NULL; 3357 3358 if (NULL == sapContext) { 3359 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3360 "%s: Invalid SAP pointer from p_cds_gctx", __func__); 3361 return QDF_STATUS_E_FAULT; 3362 } 3363 hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); 3364 if (NULL == hHal) { 3365 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3366 "%s: Invalid HAL pointer from p_cds_gctx", __func__); 3367 return QDF_STATUS_E_FAULT; 3368 } 3369 pMac = PMAC_STRUCT(hHal); 3370 3371 if (!pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) { 3372 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3373 "%s: DFS NOL is empty", __func__); 3374 return QDF_STATUS_SUCCESS; 3375 } 3376 3377 if (conf == eSAP_DFS_NOL_CLEAR) { 3378 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3379 "%s: clear the DFS NOL", __func__); 3380 3381 for (i = 0; 3382 i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; 3383 i++) { 3384 if (!pMac->sap.SapDfsInfo. 3385 sapDfsChannelNolList[i].dfs_channel_number) 3386 continue; 3387 3388 pMac->sap.SapDfsInfo. 3389 sapDfsChannelNolList[i].radar_status_flag = 3390 eSAP_DFS_CHANNEL_AVAILABLE; 3391 pMac->sap.SapDfsInfo. 3392 sapDfsChannelNolList[i].radar_found_timestamp = 0; 3393 } 3394 } else if (conf == eSAP_DFS_NOL_RANDOMIZE) { 3395 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3396 "%s: Randomize the DFS NOL", __func__); 3397 3398 /* random 1/0 to decide to put the channel into NOL */ 3399 for (i = 0; 3400 i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; 3401 i++) { 3402 uint32_t random_bytes = 0; 3403 get_random_bytes(&random_bytes, 1); 3404 3405 if (!pMac->sap.SapDfsInfo. 3406 sapDfsChannelNolList[i].dfs_channel_number) 3407 continue; 3408 3409 if ((random_bytes + jiffies) % 2) { 3410 /* mark the channel unavailable */ 3411 pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] 3412 .radar_status_flag = 3413 eSAP_DFS_CHANNEL_UNAVAILABLE; 3414 3415 /* mark the timestamp */ 3416 pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] 3417 .radar_found_timestamp = 3418 cds_get_monotonic_boottime(); 3419 } else { 3420 /* mark the channel available */ 3421 pMac->sap.SapDfsInfo. 3422 sapDfsChannelNolList[i].radar_status_flag = 3423 eSAP_DFS_CHANNEL_AVAILABLE; 3424 3425 /* clear the timestamp */ 3426 pMac->sap.SapDfsInfo. 3427 sapDfsChannelNolList 3428 [i].radar_found_timestamp = 0; 3429 } 3430 3431 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3432 "%s: Set channel[%d] %s", 3433 __func__, 3434 pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] 3435 .dfs_channel_number, 3436 (pMac->sap.SapDfsInfo. 3437 sapDfsChannelNolList[i].radar_status_flag > 3438 eSAP_DFS_CHANNEL_AVAILABLE) ? "UNAVAILABLE" : 3439 "AVAILABLE"); 3440 } 3441 } else { 3442 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3443 "%s: unsupport type %d", __func__, conf); 3444 } 3445 3446 /* set DFS-NOL back to keep it update-to-date in CNSS */ 3447 sap_signal_hdd_event(sapContext, NULL, eSAP_DFS_NOL_SET, 3448 (void *) eSAP_STATUS_SUCCESS); 3449 3450 return QDF_STATUS_SUCCESS; 3451 } 3452 3453 /** 3454 * wlansap_populate_del_sta_params() - populate delete station parameter 3455 * @mac: Pointer to peer mac address. 3456 * @reason_code: Reason code for the disassoc/deauth. 3457 * @subtype: Subtype points to either disassoc/deauth frame. 3458 * @pDelStaParams: Address where parameters to be populated. 3459 * 3460 * This API is used to populate delete station parameter structure 3461 * 3462 * Return: none 3463 */ 3464 3465 void wlansap_populate_del_sta_params(const uint8_t *mac, 3466 uint16_t reason_code, 3467 uint8_t subtype, 3468 struct tagCsrDelStaParams *pDelStaParams) 3469 { 3470 if (NULL == mac) 3471 qdf_set_macaddr_broadcast(&pDelStaParams->peerMacAddr); 3472 else 3473 qdf_mem_copy(pDelStaParams->peerMacAddr.bytes, mac, 3474 QDF_MAC_ADDR_SIZE); 3475 3476 if (reason_code == 0) 3477 pDelStaParams->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON; 3478 else 3479 pDelStaParams->reason_code = reason_code; 3480 3481 if (subtype == (SIR_MAC_MGMT_DEAUTH >> 4) || 3482 subtype == (SIR_MAC_MGMT_DISASSOC >> 4)) 3483 pDelStaParams->subtype = subtype; 3484 else 3485 pDelStaParams->subtype = (SIR_MAC_MGMT_DEAUTH >> 4); 3486 3487 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, 3488 FL( 3489 "Delete STA with RC:%hu subtype:%hhu MAC::" 3490 MAC_ADDRESS_STR), 3491 pDelStaParams->reason_code, pDelStaParams->subtype, 3492 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr.bytes)); 3493 } 3494 3495 /** 3496 * wlansap_acs_chselect() - Initiates acs channel selection 3497 * @pvos_gctx: Pointer to vos global context structure 3498 * @pacs_event_callback: Callback function in hdd called by sap 3499 * to inform hdd about channel section result 3500 * @pconfig: Pointer to configuration structure 3501 * passed down from hdd 3502 * @pusr_context: Parameter that will be passed back in all 3503 * the sap callback events. 3504 * 3505 * This function serves as an api for hdd to initiate acs scan pre 3506 * start bss. 3507 * 3508 * Return: The QDF_STATUS code associated with performing the operation. 3509 */ 3510 QDF_STATUS 3511 wlansap_acs_chselect(void *pvos_gctx, 3512 tpWLAN_SAPEventCB pacs_event_callback, 3513 tsap_Config_t *pconfig, 3514 void *pusr_context) 3515 { 3516 ptSapContext sap_context = NULL; 3517 tHalHandle h_hal = NULL; 3518 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 3519 tpAniSirGlobal pmac = NULL; 3520 3521 sap_context = CDS_GET_SAP_CB(pvos_gctx); 3522 if (NULL == sap_context) { 3523 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3524 "%s: Invalid SAP pointer from pvos_gctx", __func__); 3525 3526 return QDF_STATUS_E_FAULT; 3527 } 3528 3529 h_hal = (tHalHandle)CDS_GET_HAL_CB(sap_context->p_cds_gctx); 3530 if (NULL == h_hal) { 3531 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3532 "%s: Invalid MAC context from pvosGCtx", __func__); 3533 return QDF_STATUS_E_FAULT; 3534 } 3535 3536 pmac = PMAC_STRUCT(h_hal); 3537 sap_context->acs_cfg = &pconfig->acs_cfg; 3538 sap_context->ch_width_orig = pconfig->acs_cfg.ch_width; 3539 sap_context->csr_roamProfile.phyMode = pconfig->acs_cfg.hw_mode; 3540 3541 /* 3542 * Now, configure the scan and ACS channel params 3543 * to issue a scan request. 3544 */ 3545 wlansap_set_scan_acs_channel_params(pconfig, sap_context, 3546 pusr_context); 3547 3548 /* 3549 * Copy the HDD callback function to report the 3550 * ACS result after scan in SAP context callback function. 3551 */ 3552 sap_context->pfnSapEventCallback = pacs_event_callback; 3553 /* 3554 * init dfs channel nol 3555 */ 3556 sap_init_dfs_channel_nol_list(sap_context); 3557 3558 /* 3559 * Issue the scan request. This scan request is 3560 * issued before the start BSS is done so 3561 * 3562 * 1. No need to pass the second parameter 3563 * as the SAP state machine is not started yet 3564 * and there is no need for any event posting. 3565 * 3566 * 2. Set third parameter to TRUE to indicate the 3567 * channel selection function to register a 3568 * different scan callback fucntion to process 3569 * the results pre start BSS. 3570 */ 3571 qdf_status = sap_goto_channel_sel(sap_context, NULL, true, false); 3572 3573 if (QDF_STATUS_E_ABORTED == qdf_status) { 3574 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3575 "In %s,DFS not supported in the current operating mode", 3576 __func__); 3577 return QDF_STATUS_E_FAILURE; 3578 } else if (QDF_STATUS_E_CANCELED == qdf_status) { 3579 /* 3580 * ERROR is returned when either the SME scan request 3581 * failed or ACS is overridden due to other constrainst 3582 * So send selected channel to HDD 3583 */ 3584 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3585 FL("Scan Req Failed/ACS Overridden")); 3586 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, 3587 FL("Selected channel = %d"), 3588 sap_context->channel); 3589 3590 return sap_signal_hdd_event(sap_context, NULL, 3591 eSAP_ACS_CHANNEL_SELECTED, 3592 (void *) eSAP_STATUS_SUCCESS); 3593 } else if (QDF_STATUS_SUCCESS == qdf_status) { 3594 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, 3595 FL("Successfully Issued a Pre Start Bss Scan Request")); 3596 } 3597 return qdf_status; 3598 } 3599 3600 /** 3601 * wlan_sap_enable_phy_error_logs() - Enable DFS phy error logs 3602 * @hal: global hal handle 3603 * @enable_log: value to set 3604 * 3605 * Since the frequency of DFS phy error is very high, enabling logs for them 3606 * all the times can cause crash and will also create lot of useless logs 3607 * causing difficulties in debugging other issue. This function will be called 3608 * from iwpriv cmd to eanble such logs temporarily. 3609 * 3610 * Return: void 3611 */ 3612 void wlan_sap_enable_phy_error_logs(tHalHandle hal, bool enable_log) 3613 { 3614 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 3615 mac_ctx->sap.enable_dfs_phy_error_logs = enable_log; 3616 } 3617