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 * This file lim_send_sme_rspMessages.cc contains the functions 30 * for sending SME response/notification messages to applications 31 * above MAC software. 32 * Author: Chandra Modumudi 33 * Date: 02/13/02 34 * History:- 35 * Date Modified by Modification Information 36 * -------------------------------------------------------------------- 37 */ 38 39 #include "qdf_types.h" 40 #include "wni_api.h" 41 #include "sir_common.h" 42 #include "ani_global.h" 43 44 #include "wni_cfg.h" 45 #include "sys_def.h" 46 #include "cfg_api.h" 47 48 #include "sch_api.h" 49 #include "utils_api.h" 50 #include "lim_utils.h" 51 #include "lim_security_utils.h" 52 #include "lim_ser_des_utils.h" 53 #include "lim_send_sme_rsp_messages.h" 54 #include "lim_ibss_peer_mgmt.h" 55 #include "lim_session_utils.h" 56 #include "lim_types.h" 57 #include "sir_api.h" 58 #include "cds_regdomain.h" 59 #include "lim_send_messages.h" 60 #include "nan_datapath.h" 61 #include "lim_assoc_utils.h" 62 63 static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx, 64 tpPESession session_entry, tSirResultCodes result_code, 65 tpSirSmeJoinRsp sme_join_rsp); 66 67 /** 68 * lim_send_sme_rsp() - Send Response to upper layers 69 * @mac_ctx: Pointer to Global MAC structure 70 * @msg_type: Indicates message type 71 * @result_code: Indicates the result of previously issued 72 * eWNI_SME_msg_type_REQ message 73 * 74 * This function is called by lim_process_sme_req_messages() to send 75 * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP 76 * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC 77 * Software. 78 * 79 * Return: None 80 */ 81 82 void 83 lim_send_sme_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type, 84 tSirResultCodes result_code, uint8_t sme_session_id, 85 uint16_t sme_transaction_id) 86 { 87 tSirMsgQ msg; 88 tSirSmeRsp *sme_rsp; 89 90 lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"), 91 lim_msg_str(msg_type), lim_result_code_str(result_code)); 92 93 sme_rsp = qdf_mem_malloc(sizeof(tSirSmeRsp)); 94 if (NULL == sme_rsp) { 95 /* Buffer not available. Log error */ 96 QDF_TRACE(QDF_MODULE_ID_PE, LOGP, 97 FL("call to AllocateMemory failed for eWNI_SME_*_RSP")); 98 return; 99 } 100 101 sme_rsp->messageType = msg_type; 102 sme_rsp->length = sizeof(tSirSmeRsp); 103 sme_rsp->statusCode = result_code; 104 105 sme_rsp->sessionId = sme_session_id; 106 sme_rsp->transactionId = sme_transaction_id; 107 108 msg.type = msg_type; 109 msg.bodyptr = sme_rsp; 110 msg.bodyval = 0; 111 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, 112 sme_session_id, msg.type)); 113 114 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 115 switch (msg_type) { 116 case eWNI_SME_STOP_BSS_RSP: 117 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT, 118 NULL, (uint16_t) result_code, 0); 119 break; 120 } 121 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 122 lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT); 123 } 124 125 126 127 /** 128 * lim_send_sme_roc_rsp() - Send Response to SME 129 * @mac_ctx: Pointer to Global MAC structure 130 * @status: Resume link status 131 * @result_code: Result of the ROC request 132 * @sme_session_id: SME sesson Id 133 * @scan_id: Scan Identifier 134 * 135 * This function is called to send ROC rsp 136 * message to SME. 137 * 138 * Return: None 139 */ 140 void 141 lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type, 142 tSirResultCodes result_code, uint8_t sme_session_id, 143 uint32_t scan_id) 144 { 145 tSirMsgQ msg; 146 struct sir_roc_rsp *sme_rsp; 147 148 lim_log(mac_ctx, LOG1, 149 FL("Sending message %s with reasonCode %s scanId %d"), 150 lim_msg_str(msg_type), lim_result_code_str(result_code), 151 scan_id); 152 153 sme_rsp = qdf_mem_malloc(sizeof(struct sir_roc_rsp)); 154 if (NULL == sme_rsp) { 155 QDF_TRACE(QDF_MODULE_ID_PE, LOGP, 156 FL("call to AllocateMemory failed for eWNI_SME_*_RSP")); 157 return; 158 } 159 160 sme_rsp->message_type = msg_type; 161 sme_rsp->length = sizeof(struct sir_roc_rsp); 162 sme_rsp->status = result_code; 163 164 sme_rsp->session_id = sme_session_id; 165 sme_rsp->scan_id = scan_id; 166 167 msg.type = msg_type; 168 msg.bodyptr = sme_rsp; 169 msg.bodyval = 0; 170 MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type)); 171 lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT); 172 } 173 174 175 /** 176 * lim_get_max_rate_flags() - Get rate flags 177 * @mac_ctx: Pointer to global MAC structure 178 * @sta_ds: Pointer to station ds structure 179 * 180 * This function is called to get the rate flags for a connection 181 * from the station ds structure depending on the ht and the vht 182 * channel width supported. 183 * 184 * Return: Returns the populated rate_flags 185 */ 186 uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds) 187 { 188 uint32_t rate_flags = 0; 189 190 if (sta_ds == NULL) { 191 lim_log(mac_ctx, LOGE, FL("sta_ds is NULL")); 192 return rate_flags; 193 } 194 195 if (!sta_ds->mlmStaContext.htCapability && 196 !sta_ds->mlmStaContext.vhtCapability) { 197 rate_flags |= eHAL_TX_RATE_LEGACY; 198 } else { 199 if (sta_ds->mlmStaContext.vhtCapability) { 200 if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ == 201 sta_ds->vhtSupportedChannelWidthSet) { 202 rate_flags |= eHAL_TX_RATE_VHT80; 203 } else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ == 204 sta_ds->vhtSupportedChannelWidthSet) { 205 if (sta_ds->htSupportedChannelWidthSet) 206 rate_flags |= eHAL_TX_RATE_VHT40; 207 else 208 rate_flags |= eHAL_TX_RATE_VHT20; 209 } 210 } else if (sta_ds->mlmStaContext.htCapability) { 211 if (sta_ds->htSupportedChannelWidthSet) 212 rate_flags |= eHAL_TX_RATE_HT40; 213 else 214 rate_flags |= eHAL_TX_RATE_HT20; 215 } 216 } 217 218 if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz) 219 rate_flags |= eHAL_TX_RATE_SGI; 220 221 return rate_flags; 222 } 223 224 /** 225 * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME 226 * @mac_ctx Pointer to Global MAC structure 227 * @status Resume link status 228 * @ctx context passed while calling resmune link. 229 * (join response to be sent) 230 * 231 * This function is called to send Join/Reassoc rsp 232 * message to SME after the resume link. 233 * 234 * Return: None 235 */ 236 static void lim_send_sme_join_reassoc_rsp_after_resume(tpAniSirGlobal mac_ctx, 237 QDF_STATUS status, uint32_t *ctx) 238 { 239 tSirMsgQ msg; 240 tpSirSmeJoinRsp sme_join_rsp = (tpSirSmeJoinRsp) ctx; 241 242 msg.type = sme_join_rsp->messageType; 243 msg.bodyptr = sme_join_rsp; 244 msg.bodyval = 0; 245 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, NO_SESSION, msg.type)); 246 lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT); 247 } 248 249 /** 250 * lim_handle_join_rsp_status() - Handle the response. 251 * @mac_ctx: Pointer to Global MAC structure 252 * @session_entry: PE Session Info 253 * @result_code: Indicates the result of previously issued 254 * eWNI_SME_msgType_REQ message 255 * @sme_join_rsp The received response. 256 * 257 * This function will handle both the success and failure status 258 * of the received response. 259 * 260 * Return: None 261 */ 262 static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx, 263 tpPESession session_entry, tSirResultCodes result_code, 264 tpSirSmeJoinRsp sme_join_rsp) 265 { 266 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 267 tSirSmeHTProfile *ht_profile; 268 #endif 269 if (result_code == eSIR_SME_SUCCESS) { 270 if (session_entry->beacon != NULL) { 271 sme_join_rsp->beaconLength = session_entry->bcnLen; 272 qdf_mem_copy(sme_join_rsp->frames, 273 session_entry->beacon, 274 sme_join_rsp->beaconLength); 275 qdf_mem_free(session_entry->beacon); 276 session_entry->beacon = NULL; 277 session_entry->bcnLen = 0; 278 lim_log(mac_ctx, LOG1, FL("Beacon=%d"), 279 sme_join_rsp->beaconLength); 280 } 281 if (session_entry->assocReq != NULL) { 282 sme_join_rsp->assocReqLength = 283 session_entry->assocReqLen; 284 qdf_mem_copy(sme_join_rsp->frames + 285 sme_join_rsp->beaconLength, 286 session_entry->assocReq, 287 sme_join_rsp->assocReqLength); 288 qdf_mem_free(session_entry->assocReq); 289 session_entry->assocReq = NULL; 290 session_entry->assocReqLen = 0; 291 lim_log(mac_ctx, 292 LOG1, FL("AssocReq=%d"), 293 sme_join_rsp->assocReqLength); 294 } 295 if (session_entry->assocRsp != NULL) { 296 sme_join_rsp->assocRspLength = 297 session_entry->assocRspLen; 298 qdf_mem_copy(sme_join_rsp->frames + 299 sme_join_rsp->beaconLength + 300 sme_join_rsp->assocReqLength, 301 session_entry->assocRsp, 302 sme_join_rsp->assocRspLength); 303 qdf_mem_free(session_entry->assocRsp); 304 session_entry->assocRsp = NULL; 305 session_entry->assocRspLen = 0; 306 } 307 if (session_entry->ricData != NULL) { 308 sme_join_rsp->parsedRicRspLen = 309 session_entry->RICDataLen; 310 qdf_mem_copy(sme_join_rsp->frames + 311 sme_join_rsp->beaconLength + 312 sme_join_rsp->assocReqLength + 313 sme_join_rsp->assocRspLength, 314 session_entry->ricData, 315 sme_join_rsp->parsedRicRspLen); 316 qdf_mem_free(session_entry->ricData); 317 session_entry->ricData = NULL; 318 session_entry->RICDataLen = 0; 319 lim_log(mac_ctx, LOG1, FL("RicLength=%d"), 320 sme_join_rsp->parsedRicRspLen); 321 } 322 #ifdef FEATURE_WLAN_ESE 323 if (session_entry->tspecIes != NULL) { 324 sme_join_rsp->tspecIeLen = 325 session_entry->tspecLen; 326 qdf_mem_copy(sme_join_rsp->frames + 327 sme_join_rsp->beaconLength + 328 sme_join_rsp->assocReqLength + 329 sme_join_rsp->assocRspLength + 330 sme_join_rsp->parsedRicRspLen, 331 session_entry->tspecIes, 332 sme_join_rsp->tspecIeLen); 333 qdf_mem_free(session_entry->tspecIes); 334 session_entry->tspecIes = NULL; 335 session_entry->tspecLen = 0; 336 lim_log(mac_ctx, LOG1, FL("ESE-TspecLen=%d"), 337 sme_join_rsp->tspecIeLen); 338 } 339 #endif 340 sme_join_rsp->aid = session_entry->limAID; 341 lim_log(mac_ctx, LOG1, FL("AssocRsp=%d"), 342 sme_join_rsp->assocRspLength); 343 sme_join_rsp->vht_channel_width = 344 session_entry->ch_width; 345 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 346 if (session_entry->cc_switch_mode != 347 QDF_MCC_TO_SCC_SWITCH_DISABLE) { 348 ht_profile = &sme_join_rsp->HTProfile; 349 ht_profile->htSupportedChannelWidthSet = 350 session_entry->htSupportedChannelWidthSet; 351 ht_profile->htRecommendedTxWidthSet = 352 session_entry->htRecommendedTxWidthSet; 353 ht_profile->htSecondaryChannelOffset = 354 session_entry->htSecondaryChannelOffset; 355 ht_profile->dot11mode = session_entry->dot11mode; 356 ht_profile->htCapability = session_entry->htCapability; 357 ht_profile->vhtCapability = 358 session_entry->vhtCapability; 359 ht_profile->apCenterChan = session_entry->ch_center_freq_seg0; 360 ht_profile->apChanWidth = session_entry->ch_width; 361 } 362 #endif 363 } else { 364 if (session_entry->beacon != NULL) { 365 qdf_mem_free(session_entry->beacon); 366 session_entry->beacon = NULL; 367 session_entry->bcnLen = 0; 368 } 369 if (session_entry->assocReq != NULL) { 370 qdf_mem_free(session_entry->assocReq); 371 session_entry->assocReq = NULL; 372 session_entry->assocReqLen = 0; 373 } 374 if (session_entry->assocRsp != NULL) { 375 qdf_mem_free(session_entry->assocRsp); 376 session_entry->assocRsp = NULL; 377 session_entry->assocRspLen = 0; 378 } 379 if (session_entry->ricData != NULL) { 380 qdf_mem_free(session_entry->ricData); 381 session_entry->ricData = NULL; 382 session_entry->RICDataLen = 0; 383 } 384 #ifdef FEATURE_WLAN_ESE 385 if (session_entry->tspecIes != NULL) { 386 qdf_mem_free(session_entry->tspecIes); 387 session_entry->tspecIes = NULL; 388 session_entry->tspecLen = 0; 389 } 390 #endif 391 } 392 } 393 394 /** 395 * lim_add_bss_info() - copy data from session entry to join rsp 396 * @sta_ds: Station dph entry 397 * @sme_join_rsp: Join response buffer to be filled up 398 * 399 * Return: None 400 */ 401 static void lim_add_bss_info(tpDphHashNode sta_ds, tpSirSmeJoinRsp sme_join_rsp) 402 { 403 struct parsed_ies *parsed_ies = &sta_ds->parsed_ies; 404 405 if (parsed_ies->hs20vendor_ie.present) 406 sme_join_rsp->hs20vendor_ie = parsed_ies->hs20vendor_ie; 407 if (parsed_ies->vht_caps.present) 408 sme_join_rsp->vht_caps = parsed_ies->vht_caps; 409 if (parsed_ies->ht_caps.present) 410 sme_join_rsp->ht_caps = parsed_ies->ht_caps; 411 if (parsed_ies->ht_operation.present) 412 sme_join_rsp->ht_operation = parsed_ies->ht_operation; 413 if (parsed_ies->vht_operation.present) 414 sme_join_rsp->vht_operation = parsed_ies->vht_operation; 415 } 416 417 /** 418 * lim_send_sme_join_reassoc_rsp() - Send Response to Upper Layers 419 * @mac_ctx: Pointer to Global MAC structure 420 * @msg_type: Indicates message type 421 * @result_code: Indicates the result of previously issued 422 * eWNI_SME_msgType_REQ message 423 * @prot_status_code: Protocol Status Code 424 * @session_entry: PE Session Info 425 * @sme_session_id: SME Session ID 426 * @sme_transaction_id: SME Transaction ID 427 * 428 * This function is called by lim_process_sme_req_messages() to send 429 * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications 430 * above MAC Software. 431 * 432 * Return: None 433 */ 434 435 void 436 lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type, 437 tSirResultCodes result_code, uint16_t prot_status_code, 438 tpPESession session_entry, uint8_t sme_session_id, 439 uint16_t sme_transaction_id) 440 { 441 tpSirSmeJoinRsp sme_join_rsp; 442 uint32_t rsp_len; 443 tpDphHashNode sta_ds = NULL; 444 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 445 if (msg_type == eWNI_SME_REASSOC_RSP) 446 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT, 447 session_entry, (uint16_t) result_code, 0); 448 else 449 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_RSP_EVENT, 450 session_entry, (uint16_t) result_code, 0); 451 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 452 453 lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"), 454 lim_msg_str(msg_type), lim_result_code_str(result_code)); 455 456 if (session_entry == NULL) { 457 rsp_len = sizeof(tSirSmeJoinRsp); 458 sme_join_rsp = qdf_mem_malloc(rsp_len); 459 if (NULL == sme_join_rsp) { 460 lim_log(mac_ctx, LOGP, 461 FL("Mem Alloc fail - JOIN/REASSOC_RSP")); 462 return; 463 } 464 465 qdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0); 466 sme_join_rsp->beaconLength = 0; 467 sme_join_rsp->assocReqLength = 0; 468 sme_join_rsp->assocRspLength = 0; 469 } else { 470 rsp_len = session_entry->assocReqLen + 471 session_entry->assocRspLen + session_entry->bcnLen + 472 session_entry->RICDataLen + 473 #ifdef FEATURE_WLAN_ESE 474 session_entry->tspecLen + 475 #endif 476 sizeof(tSirSmeJoinRsp) - sizeof(uint8_t); 477 sme_join_rsp = qdf_mem_malloc(rsp_len); 478 if (NULL == sme_join_rsp) { 479 lim_log(mac_ctx, LOGP, 480 FL("MemAlloc fail - JOIN/REASSOC_RSP")); 481 return; 482 } 483 qdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0); 484 if (result_code == eSIR_SME_SUCCESS) { 485 sta_ds = dph_get_hash_entry(mac_ctx, 486 DPH_STA_HASH_INDEX_PEER, 487 &session_entry->dph.dphHashTable); 488 if (sta_ds == NULL) { 489 lim_log(mac_ctx, LOGE, 490 FL("Get Self Sta Entry fail")); 491 } else { 492 /* Pass the peer's staId */ 493 sme_join_rsp->staId = sta_ds->staIndex; 494 sme_join_rsp->ucastSig = 495 sta_ds->ucUcastSig; 496 sme_join_rsp->bcastSig = 497 sta_ds->ucBcastSig; 498 sme_join_rsp->timingMeasCap = 499 sta_ds->timingMeasCap; 500 #ifdef FEATURE_WLAN_TDLS 501 sme_join_rsp->tdls_prohibited = 502 session_entry->tdls_prohibited; 503 sme_join_rsp->tdls_chan_swit_prohibited = 504 session_entry->tdls_chan_swit_prohibited; 505 #endif 506 sme_join_rsp->nss = sta_ds->nss; 507 sme_join_rsp->max_rate_flags = 508 lim_get_max_rate_flags(mac_ctx, sta_ds); 509 lim_add_bss_info(sta_ds, sme_join_rsp); 510 } 511 } 512 sme_join_rsp->beaconLength = 0; 513 sme_join_rsp->assocReqLength = 0; 514 sme_join_rsp->assocRspLength = 0; 515 sme_join_rsp->parsedRicRspLen = 0; 516 #ifdef FEATURE_WLAN_ESE 517 sme_join_rsp->tspecIeLen = 0; 518 #endif 519 lim_handle_join_rsp_status(mac_ctx, session_entry, result_code, 520 sme_join_rsp); 521 522 /* Send supported NSS 1x1 to SME */ 523 sme_join_rsp->supported_nss_1x1 = 524 session_entry->supported_nss_1x1; 525 lim_log(mac_ctx, LOG1, 526 FL("SME Join Rsp is supported NSS 1X1: %d"), 527 sme_join_rsp->supported_nss_1x1); 528 } 529 530 sme_join_rsp->messageType = msg_type; 531 sme_join_rsp->length = (uint16_t) rsp_len; 532 sme_join_rsp->statusCode = result_code; 533 sme_join_rsp->protStatusCode = prot_status_code; 534 535 sme_join_rsp->sessionId = sme_session_id; 536 sme_join_rsp->transactionId = sme_transaction_id; 537 538 lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, QDF_STATUS_SUCCESS, 539 (uint32_t *)sme_join_rsp); 540 } 541 542 /** 543 * lim_send_sme_start_bss_rsp() 544 * 545 ***FUNCTION: 546 * This function is called to send eWNI_SME_START_BSS_RSP 547 * message to applications above MAC Software. 548 * 549 ***PARAMS: 550 * 551 ***LOGIC: 552 * 553 ***ASSUMPTIONS: 554 * NA 555 * 556 ***NOTE: 557 * NA 558 * 559 * @param pMac Pointer to Global MAC structure 560 * @param msgType Indicates message type 561 * @param resultCode Indicates the result of previously issued 562 * eWNI_SME_msgType_REQ message 563 * 564 * @return None 565 */ 566 567 void 568 lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac, 569 uint16_t msgType, tSirResultCodes resultCode, 570 tpPESession psessionEntry, uint8_t smesessionId, 571 uint16_t smetransactionId) 572 { 573 574 uint16_t size = 0; 575 tSirMsgQ mmhMsg; 576 tSirSmeStartBssRsp *pSirSmeRsp; 577 uint16_t ieLen; 578 uint16_t ieOffset, curLen; 579 580 PELOG1(lim_log(pMac, LOG1, FL("Sending message %s with reasonCode %s"), 581 lim_msg_str(msgType), lim_result_code_str(resultCode)); 582 ) 583 584 size = sizeof(tSirSmeStartBssRsp); 585 586 if (psessionEntry == NULL) { 587 pSirSmeRsp = qdf_mem_malloc(size); 588 if (NULL == pSirSmeRsp) { 589 /* / Buffer not available. Log error */ 590 lim_log(pMac, LOGP, 591 FL 592 ("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP")); 593 return; 594 } 595 qdf_mem_set((uint8_t *) pSirSmeRsp, size, 0); 596 597 } else { 598 /* subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID */ 599 ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET; 600 ieLen = psessionEntry->schBeaconOffsetBegin 601 + psessionEntry->schBeaconOffsetEnd - ieOffset; 602 /* calculate the memory size to allocate */ 603 size += ieLen; 604 605 pSirSmeRsp = qdf_mem_malloc(size); 606 if (NULL == pSirSmeRsp) { 607 /* / Buffer not available. Log error */ 608 lim_log(pMac, LOGP, 609 FL 610 ("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP")); 611 612 return; 613 } 614 qdf_mem_set((uint8_t *) pSirSmeRsp, size, 0); 615 size = sizeof(tSirSmeStartBssRsp); 616 if (resultCode == eSIR_SME_SUCCESS) { 617 618 sir_copy_mac_addr(pSirSmeRsp->bssDescription.bssId, 619 psessionEntry->bssId); 620 621 /* Read beacon interval from session */ 622 pSirSmeRsp->bssDescription.beaconInterval = 623 (uint16_t) psessionEntry->beaconParams. 624 beaconInterval; 625 pSirSmeRsp->bssType = psessionEntry->bssType; 626 627 if (cfg_get_capability_info 628 (pMac, &pSirSmeRsp->bssDescription.capabilityInfo, 629 psessionEntry) 630 != eSIR_SUCCESS) 631 lim_log(pMac, LOGP, 632 FL 633 ("could not retrieve Capabilities value")); 634 635 lim_get_phy_mode(pMac, 636 (uint32_t *) &pSirSmeRsp->bssDescription. 637 nwType, psessionEntry); 638 639 pSirSmeRsp->bssDescription.channelId = 640 psessionEntry->currentOperChannel; 641 642 if (!LIM_IS_NDI_ROLE(psessionEntry)) { 643 curLen = psessionEntry->schBeaconOffsetBegin - ieOffset; 644 qdf_mem_copy((uint8_t *) &pSirSmeRsp->bssDescription. 645 ieFields, 646 psessionEntry->pSchBeaconFrameBegin + 647 ieOffset, (uint32_t) curLen); 648 649 qdf_mem_copy(((uint8_t *) &pSirSmeRsp->bssDescription. 650 ieFields) + curLen, 651 psessionEntry->pSchBeaconFrameEnd, 652 (uint32_t) psessionEntry-> 653 schBeaconOffsetEnd); 654 655 /* subtracting size of length indicator itself and size of pointer to ieFields */ 656 pSirSmeRsp->bssDescription.length = 657 sizeof(tSirBssDescription) - sizeof(uint16_t) - 658 sizeof(uint32_t) + ieLen; 659 /* This is the size of the message, subtracting the size of the pointer to ieFields */ 660 size += ieLen - sizeof(uint32_t); 661 } 662 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 663 if (psessionEntry->cc_switch_mode 664 != QDF_MCC_TO_SCC_SWITCH_DISABLE) { 665 pSirSmeRsp->HTProfile. 666 htSupportedChannelWidthSet = 667 psessionEntry->htSupportedChannelWidthSet; 668 pSirSmeRsp->HTProfile.htRecommendedTxWidthSet = 669 psessionEntry->htRecommendedTxWidthSet; 670 pSirSmeRsp->HTProfile.htSecondaryChannelOffset = 671 psessionEntry->htSecondaryChannelOffset; 672 pSirSmeRsp->HTProfile.dot11mode = 673 psessionEntry->dot11mode; 674 pSirSmeRsp->HTProfile.htCapability = 675 psessionEntry->htCapability; 676 pSirSmeRsp->HTProfile.vhtCapability = 677 psessionEntry->vhtCapability; 678 pSirSmeRsp->HTProfile.apCenterChan = 679 psessionEntry->ch_center_freq_seg0; 680 pSirSmeRsp->HTProfile.apChanWidth = 681 psessionEntry->ch_width; 682 } 683 #endif 684 } 685 } 686 pSirSmeRsp->messageType = msgType; 687 pSirSmeRsp->length = size; 688 689 /* Update SME session Id and transaction Id */ 690 pSirSmeRsp->sessionId = smesessionId; 691 pSirSmeRsp->transactionId = smetransactionId; 692 pSirSmeRsp->statusCode = resultCode; 693 if (psessionEntry != NULL) 694 pSirSmeRsp->staId = psessionEntry->staId; /* else it will be always zero smeRsp StaID = 0 */ 695 696 mmhMsg.type = msgType; 697 mmhMsg.bodyptr = pSirSmeRsp; 698 mmhMsg.bodyval = 0; 699 if (psessionEntry == NULL) { 700 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 701 NO_SESSION, mmhMsg.type)); 702 } else { 703 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 704 psessionEntry->peSessionId, mmhMsg.type)); 705 } 706 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 707 lim_diag_event_report(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT, 708 psessionEntry, (uint16_t) resultCode, 0); 709 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 710 711 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 712 } /*** end lim_send_sme_start_bss_rsp() ***/ 713 714 /** 715 * lim_send_sme_scan_rsp() - Send scan response to SME 716 * @pMac: Pointer to Global MAC structure 717 * @length: Indicates length of message 718 * @resultCode: Indicates the result of previously issued 719 * eWNI_SME_SCAN_REQ message 720 * @scan_id: scan identifier 721 * 722 * This function is called by lim_process_sme_req_messages() to send 723 * eWNI_SME_SCAN_RSP message to applications above MAC 724 * 725 * return: None 726 */ 727 728 void 729 lim_send_sme_scan_rsp(tpAniSirGlobal pMac, tSirResultCodes resultCode, 730 uint8_t smesessionId, uint16_t smetranscationId, 731 uint32_t scan_id) 732 { 733 lim_post_sme_scan_rsp_message(pMac, resultCode, smesessionId, 734 smetranscationId, scan_id); 735 } 736 737 /** 738 * lim_post_sme_scan_rsp_message() 739 * 740 ***FUNCTION: 741 * This function is called by lim_send_sme_scan_rsp() to send 742 * eWNI_SME_SCAN_RSP message with failed result code 743 * 744 ***NOTE: 745 * NA 746 * 747 * @param pMac Pointer to Global MAC structure 748 * @param length Indicates length of message 749 * @param resultCode failed result code 750 * 751 * @return None 752 */ 753 754 void 755 lim_post_sme_scan_rsp_message(tpAniSirGlobal pMac, 756 tSirResultCodes resultCode, uint8_t smesessionId, 757 uint16_t smetransactionId, 758 uint32_t scan_id) 759 { 760 tpSirSmeScanRsp pSirSmeScanRsp; 761 tSirMsgQ mmhMsg; 762 763 lim_log(pMac, LOG1, FL("send SME_SCAN_RSP (reasonCode %s)."), 764 lim_result_code_str(resultCode)); 765 766 pSirSmeScanRsp = qdf_mem_malloc(sizeof(tSirSmeScanRsp)); 767 if (NULL == pSirSmeScanRsp) { 768 lim_log(pMac, LOGP, 769 FL("AllocateMemory failed for eWNI_SME_SCAN_RSP")); 770 return; 771 } 772 qdf_mem_set((void *)pSirSmeScanRsp, sizeof(tSirSmeScanRsp), 0); 773 774 pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; 775 pSirSmeScanRsp->statusCode = resultCode; 776 777 /*Update SME session Id and transaction Id */ 778 pSirSmeScanRsp->sessionId = smesessionId; 779 pSirSmeScanRsp->transcationId = smetransactionId; 780 pSirSmeScanRsp->scan_id = scan_id; 781 782 mmhMsg.type = eWNI_SME_SCAN_RSP; 783 mmhMsg.bodyptr = pSirSmeScanRsp; 784 mmhMsg.bodyval = 0; 785 786 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); 787 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 788 lim_diag_event_report(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL, 789 (uint16_t) resultCode, 0); 790 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 791 792 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 793 return; 794 795 } /*** lim_post_sme_scan_rsp_message ***/ 796 797 void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal pMac, 798 QDF_STATUS status, uint32_t *pCtx) 799 { 800 tSirMsgQ mmhMsg; 801 tSirMsgQ *pMsg = (tSirMsgQ *) pCtx; 802 803 mmhMsg.type = pMsg->type; 804 mmhMsg.bodyptr = pMsg; 805 mmhMsg.bodyval = 0; 806 807 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); 808 809 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 810 } 811 812 /** 813 * lim_send_sme_disassoc_ntf() 814 * 815 ***FUNCTION: 816 * This function is called by limProcessSmeMessages() to send 817 * eWNI_SME_DISASSOC_RSP/IND message to host 818 * 819 ***PARAMS: 820 * 821 ***LOGIC: 822 * 823 ***ASSUMPTIONS: 824 * NA 825 * 826 ***NOTE: 827 * This function is used for sending eWNI_SME_DISASSOC_CNF, 828 * or eWNI_SME_DISASSOC_IND to host depending on 829 * disassociation trigger. 830 * 831 * @param peerMacAddr Indicates the peer MAC addr to which 832 * disassociate was initiated 833 * @param reasonCode Indicates the reason for Disassociation 834 * @param disassocTrigger Indicates the trigger for Disassociation 835 * @param aid Indicates the STAID. This parameter is 836 * present only on AP. 837 * 838 * @return None 839 */ 840 void 841 lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac, 842 tSirMacAddr peerMacAddr, 843 tSirResultCodes reasonCode, 844 uint16_t disassocTrigger, 845 uint16_t aid, 846 uint8_t smesessionId, 847 uint16_t smetransactionId, tpPESession psessionEntry) 848 { 849 850 uint8_t *pBuf; 851 tSirSmeDisassocRsp *pSirSmeDisassocRsp; 852 tSirSmeDisassocInd *pSirSmeDisassocInd; 853 uint32_t *pMsg = NULL; 854 bool failure = false; 855 tpPESession session = NULL; 856 uint16_t i, assoc_id; 857 tpDphHashNode sta_ds = NULL; 858 859 lim_log(pMac, LOG1, FL("Disassoc Ntf with trigger : %d reasonCode: %d"), 860 disassocTrigger, reasonCode); 861 862 switch (disassocTrigger) { 863 case eLIM_DUPLICATE_ENTRY: 864 /* 865 * Duplicate entry is removed at LIM. 866 * Initiate new entry for other session 867 */ 868 lim_log(pMac, LOG1, 869 FL("Rcvd eLIM_DUPLICATE_ENTRY for " MAC_ADDRESS_STR), 870 MAC_ADDR_ARRAY(peerMacAddr)); 871 872 for (i = 0; i < pMac->lim.maxBssId; i++) { 873 if ((&pMac->lim.gpSession[i] != NULL) && 874 (pMac->lim.gpSession[i].valid) && 875 (pMac->lim.gpSession[i].pePersona == 876 QDF_SAP_MODE)) { 877 /* Find the sta ds entry in another session */ 878 session = &pMac->lim.gpSession[i]; 879 sta_ds = dph_lookup_hash_entry(pMac, 880 peerMacAddr, &assoc_id, 881 &session->dph.dphHashTable); 882 } 883 } 884 if (sta_ds 885 #ifdef WLAN_FEATURE_11W 886 && (!sta_ds->rmfEnabled) 887 #endif 888 ) { 889 if (lim_add_sta(pMac, sta_ds, false, session) != 890 eSIR_SUCCESS) 891 lim_log(pMac, LOGE, 892 FL("could not Add STA with assocId=%d"), 893 sta_ds->assocId); 894 } 895 failure = true; 896 break; 897 898 case eLIM_PEER_ENTITY_DISASSOC: 899 if (reasonCode != eSIR_SME_STA_NOT_ASSOCIATED) { 900 failure = true; 901 goto error; 902 } 903 904 case eLIM_HOST_DISASSOC: 905 /** 906 * Disassociation response due to 907 * host triggered disassociation 908 */ 909 910 pSirSmeDisassocRsp = qdf_mem_malloc(sizeof(tSirSmeDisassocRsp)); 911 if (NULL == pSirSmeDisassocRsp) { 912 /* Log error */ 913 lim_log(pMac, LOGP, FL("Memory allocation failed")); 914 failure = true; 915 goto error; 916 } 917 lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with " 918 "retCode: %d for " MAC_ADDRESS_STR), 919 reasonCode, MAC_ADDR_ARRAY(peerMacAddr)); 920 pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP; 921 pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp); 922 /* sessionId */ 923 pBuf = (uint8_t *) &pSirSmeDisassocRsp->sessionId; 924 *pBuf = smesessionId; 925 pBuf++; 926 927 /* transactionId */ 928 lim_copy_u16(pBuf, smetransactionId); 929 pBuf += sizeof(uint16_t); 930 931 /* statusCode */ 932 lim_copy_u32(pBuf, reasonCode); 933 pBuf += sizeof(tSirResultCodes); 934 935 /* peerMacAddr */ 936 qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr)); 937 pBuf += sizeof(tSirMacAddr); 938 939 /* Clear Station Stats */ 940 /* for sta, it is always 1, IBSS is handled at halInitSta */ 941 942 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 943 944 lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT, 945 psessionEntry, (uint16_t) reasonCode, 0); 946 #endif 947 pMsg = (uint32_t *) pSirSmeDisassocRsp; 948 break; 949 950 default: 951 /** 952 * Disassociation indication due to Disassociation 953 * frame reception from peer entity or due to 954 * loss of link with peer entity. 955 */ 956 pSirSmeDisassocInd = qdf_mem_malloc(sizeof(tSirSmeDisassocInd)); 957 if (NULL == pSirSmeDisassocInd) { 958 /* Log error */ 959 lim_log(pMac, LOGP, FL("Memory allocation failed")); 960 failure = true; 961 goto error; 962 } 963 lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_IND with " 964 "retCode: %d for " MAC_ADDRESS_STR), 965 reasonCode, MAC_ADDR_ARRAY(peerMacAddr)); 966 pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; 967 pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd); 968 969 /* Update SME session Id and Transaction Id */ 970 pSirSmeDisassocInd->sessionId = smesessionId; 971 pSirSmeDisassocInd->transactionId = smetransactionId; 972 pSirSmeDisassocInd->reasonCode = reasonCode; 973 pBuf = (uint8_t *) &pSirSmeDisassocInd->statusCode; 974 975 lim_copy_u32(pBuf, reasonCode); 976 pBuf += sizeof(tSirResultCodes); 977 978 qdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); 979 pBuf += sizeof(tSirMacAddr); 980 981 qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr)); 982 983 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 984 lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, 985 psessionEntry, (uint16_t) reasonCode, 0); 986 #endif 987 pMsg = (uint32_t *) pSirSmeDisassocInd; 988 989 break; 990 } 991 992 error: 993 /* Delete the PE session Created */ 994 if ((psessionEntry != NULL) && LIM_IS_STA_ROLE(psessionEntry)) 995 pe_delete_session(pMac, psessionEntry); 996 997 if (false == failure) 998 lim_send_sme_disassoc_deauth_ntf(pMac, QDF_STATUS_SUCCESS, 999 (uint32_t *) pMsg); 1000 } /*** end lim_send_sme_disassoc_ntf() ***/ 1001 1002 /** ----------------------------------------------------------------- 1003 \brief lim_send_sme_disassoc_ind() - sends SME_DISASSOC_IND 1004 1005 After receiving disassociation frame from peer entity, this 1006 function sends a eWNI_SME_DISASSOC_IND to SME with a specific 1007 reason code. 1008 1009 \param pMac - global mac structure 1010 \param pStaDs - station dph hash node 1011 \return none 1012 \sa 1013 ----------------------------------------------------------------- */ 1014 void 1015 lim_send_sme_disassoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs, 1016 tpPESession psessionEntry) 1017 { 1018 tSirMsgQ mmhMsg; 1019 tSirSmeDisassocInd *pSirSmeDisassocInd; 1020 1021 pSirSmeDisassocInd = qdf_mem_malloc(sizeof(tSirSmeDisassocInd)); 1022 if (NULL == pSirSmeDisassocInd) { 1023 lim_log(pMac, LOGP, 1024 FL("AllocateMemory failed for eWNI_SME_DISASSOC_IND")); 1025 return; 1026 } 1027 1028 pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; 1029 pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd); 1030 1031 pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId; 1032 pSirSmeDisassocInd->transactionId = psessionEntry->transactionId; 1033 pSirSmeDisassocInd->statusCode = eSIR_SME_DEAUTH_STATUS; 1034 pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason; 1035 1036 qdf_mem_copy(pSirSmeDisassocInd->bssid.bytes, psessionEntry->bssId, 1037 QDF_MAC_ADDR_SIZE); 1038 1039 qdf_mem_copy(pSirSmeDisassocInd->peer_macaddr.bytes, pStaDs->staAddr, 1040 QDF_MAC_ADDR_SIZE); 1041 1042 pSirSmeDisassocInd->staId = pStaDs->staIndex; 1043 1044 mmhMsg.type = eWNI_SME_DISASSOC_IND; 1045 mmhMsg.bodyptr = pSirSmeDisassocInd; 1046 mmhMsg.bodyval = 0; 1047 1048 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1049 psessionEntry->peSessionId, mmhMsg.type)); 1050 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1051 lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry, 1052 0, (uint16_t) pStaDs->mlmStaContext.disassocReason); 1053 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1054 1055 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1056 1057 } /*** end lim_send_sme_disassoc_ind() ***/ 1058 1059 /** ----------------------------------------------------------------- 1060 \brief lim_send_sme_deauth_ind() - sends SME_DEAUTH_IND 1061 1062 After receiving deauthentication frame from peer entity, this 1063 function sends a eWNI_SME_DEAUTH_IND to SME with a specific 1064 reason code. 1065 1066 \param pMac - global mac structure 1067 \param pStaDs - station dph hash node 1068 \return none 1069 \sa 1070 ----------------------------------------------------------------- */ 1071 void 1072 lim_send_sme_deauth_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs, 1073 tpPESession psessionEntry) 1074 { 1075 tSirMsgQ mmhMsg; 1076 tSirSmeDeauthInd *pSirSmeDeauthInd; 1077 1078 pSirSmeDeauthInd = qdf_mem_malloc(sizeof(tSirSmeDeauthInd)); 1079 if (NULL == pSirSmeDeauthInd) { 1080 lim_log(pMac, LOGP, 1081 FL("AllocateMemory failed for eWNI_SME_DEAUTH_IND ")); 1082 return; 1083 } 1084 1085 pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; 1086 pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd); 1087 1088 pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId; 1089 pSirSmeDeauthInd->transactionId = psessionEntry->transactionId; 1090 if (eSIR_INFRA_AP_MODE == psessionEntry->bssType) { 1091 pSirSmeDeauthInd->statusCode = 1092 (tSirResultCodes) pStaDs->mlmStaContext.cleanupTrigger; 1093 } else { 1094 /* Need to indicatet he reascon code over the air */ 1095 pSirSmeDeauthInd->statusCode = 1096 (tSirResultCodes) pStaDs->mlmStaContext.disassocReason; 1097 } 1098 /* BSSID */ 1099 qdf_mem_copy(pSirSmeDeauthInd->bssid.bytes, psessionEntry->bssId, 1100 QDF_MAC_ADDR_SIZE); 1101 /* peerMacAddr */ 1102 qdf_mem_copy(pSirSmeDeauthInd->peer_macaddr.bytes, pStaDs->staAddr, 1103 QDF_MAC_ADDR_SIZE); 1104 pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason; 1105 1106 pSirSmeDeauthInd->staId = pStaDs->staIndex; 1107 if (eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON == 1108 pStaDs->mlmStaContext.disassocReason) 1109 pSirSmeDeauthInd->rssi = pStaDs->del_sta_ctx_rssi; 1110 1111 mmhMsg.type = eWNI_SME_DEAUTH_IND; 1112 mmhMsg.bodyptr = pSirSmeDeauthInd; 1113 mmhMsg.bodyval = 0; 1114 1115 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type)); 1116 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1117 lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry, 1118 0, pStaDs->mlmStaContext.cleanupTrigger); 1119 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1120 1121 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1122 return; 1123 } /*** end lim_send_sme_deauth_ind() ***/ 1124 1125 #ifdef FEATURE_WLAN_TDLS 1126 /** 1127 * lim_send_sme_tdls_del_sta_ind() 1128 * 1129 ***FUNCTION: 1130 * This function is called to send the TDLS STA context deletion to SME. 1131 * 1132 ***LOGIC: 1133 * 1134 ***ASSUMPTIONS: 1135 * 1136 ***NOTE: 1137 * NA 1138 * 1139 * @param pMac - Pointer to global MAC structure 1140 * @param pStaDs - Pointer to internal STA Datastructure 1141 * @param psessionEntry - Pointer to the session entry 1142 * @param reasonCode - Reason for TDLS sta deletion 1143 * @return None 1144 */ 1145 void 1146 lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs, 1147 tpPESession psessionEntry, uint16_t reasonCode) 1148 { 1149 tSirMsgQ mmhMsg; 1150 tSirTdlsDelStaInd *pSirTdlsDelStaInd; 1151 1152 pSirTdlsDelStaInd = qdf_mem_malloc(sizeof(tSirTdlsDelStaInd)); 1153 if (NULL == pSirTdlsDelStaInd) { 1154 lim_log(pMac, LOGP, 1155 FL 1156 ("AllocateMemory failed for eWNI_SME_TDLS_DEL_STA_IND ")); 1157 return; 1158 } 1159 /* messageType */ 1160 pSirTdlsDelStaInd->messageType = eWNI_SME_TDLS_DEL_STA_IND; 1161 pSirTdlsDelStaInd->length = sizeof(tSirTdlsDelStaInd); 1162 1163 /* sessionId */ 1164 pSirTdlsDelStaInd->sessionId = psessionEntry->smeSessionId; 1165 1166 /* peerMacAddr */ 1167 qdf_mem_copy(pSirTdlsDelStaInd->peermac.bytes, pStaDs->staAddr, 1168 QDF_MAC_ADDR_SIZE); 1169 1170 /* staId */ 1171 lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->staId), 1172 (uint16_t) pStaDs->staIndex); 1173 1174 /* reasonCode */ 1175 lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->reasonCode), reasonCode); 1176 1177 mmhMsg.type = eWNI_SME_TDLS_DEL_STA_IND; 1178 mmhMsg.bodyptr = pSirTdlsDelStaInd; 1179 mmhMsg.bodyval = 0; 1180 1181 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1182 return; 1183 } /*** end lim_send_sme_tdls_del_sta_ind() ***/ 1184 1185 /** 1186 * lim_send_sme_tdls_delete_all_peer_ind() 1187 * 1188 ***FUNCTION: 1189 * This function is called to send the eWNI_SME_TDLS_DEL_ALL_PEER_IND 1190 * message to SME. 1191 * 1192 ***LOGIC: 1193 * 1194 ***ASSUMPTIONS: 1195 * 1196 ***NOTE: 1197 * NA 1198 * 1199 * @param pMac - Pointer to global MAC structure 1200 * @param psessionEntry - Pointer to the session entry 1201 * @return None 1202 */ 1203 void 1204 lim_send_sme_tdls_delete_all_peer_ind(tpAniSirGlobal pMac, tpPESession psessionEntry) 1205 { 1206 tSirMsgQ mmhMsg; 1207 tSirTdlsDelAllPeerInd *pSirTdlsDelAllPeerInd; 1208 1209 pSirTdlsDelAllPeerInd = qdf_mem_malloc(sizeof(tSirTdlsDelAllPeerInd)); 1210 if (NULL == pSirTdlsDelAllPeerInd) { 1211 lim_log(pMac, LOGP, 1212 FL 1213 ("AllocateMemory failed for eWNI_SME_TDLS_DEL_ALL_PEER_IND")); 1214 return; 1215 } 1216 /* messageType */ 1217 pSirTdlsDelAllPeerInd->messageType = eWNI_SME_TDLS_DEL_ALL_PEER_IND; 1218 pSirTdlsDelAllPeerInd->length = sizeof(tSirTdlsDelAllPeerInd); 1219 1220 /* sessionId */ 1221 pSirTdlsDelAllPeerInd->sessionId = psessionEntry->smeSessionId; 1222 1223 mmhMsg.type = eWNI_SME_TDLS_DEL_ALL_PEER_IND; 1224 mmhMsg.bodyptr = pSirTdlsDelAllPeerInd; 1225 mmhMsg.bodyval = 0; 1226 1227 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1228 return; 1229 } /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/ 1230 1231 /** 1232 * lim_send_sme_mgmt_tx_completion() 1233 * 1234 ***FUNCTION: 1235 * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND 1236 * message to SME. 1237 * 1238 ***LOGIC: 1239 * 1240 ***ASSUMPTIONS: 1241 * 1242 ***NOTE: 1243 * NA 1244 * 1245 * @param pMac - Pointer to global MAC structure 1246 * @param psessionEntry - Pointer to the session entry 1247 * @param txCompleteStatus - TX Complete Status of Mgmt Frames 1248 * @return None 1249 */ 1250 void 1251 lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac, 1252 tpPESession psessionEntry, uint32_t txCompleteStatus) 1253 { 1254 tSirMsgQ mmhMsg; 1255 tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd; 1256 1257 pSirMgmtTxCompletionInd = 1258 qdf_mem_malloc(sizeof(tSirMgmtTxCompletionInd)); 1259 if (NULL == pSirMgmtTxCompletionInd) { 1260 lim_log(pMac, LOGP, 1261 FL 1262 ("AllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND")); 1263 return; 1264 } 1265 /* messageType */ 1266 pSirMgmtTxCompletionInd->messageType = 1267 eWNI_SME_MGMT_FRM_TX_COMPLETION_IND; 1268 pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd); 1269 1270 /* sessionId */ 1271 pSirMgmtTxCompletionInd->sessionId = psessionEntry->smeSessionId; 1272 1273 pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus; 1274 1275 mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND; 1276 mmhMsg.bodyptr = pSirMgmtTxCompletionInd; 1277 mmhMsg.bodyval = 0; 1278 1279 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1280 return; 1281 } /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/ 1282 1283 void lim_send_sme_tdls_event_notify(tpAniSirGlobal pMac, uint16_t msgType, 1284 void *events) 1285 { 1286 tSirMsgQ mmhMsg; 1287 1288 switch (msgType) { 1289 case SIR_HAL_TDLS_SHOULD_DISCOVER: 1290 mmhMsg.type = eWNI_SME_TDLS_SHOULD_DISCOVER; 1291 break; 1292 case SIR_HAL_TDLS_SHOULD_TEARDOWN: 1293 mmhMsg.type = eWNI_SME_TDLS_SHOULD_TEARDOWN; 1294 break; 1295 case SIR_HAL_TDLS_PEER_DISCONNECTED: 1296 mmhMsg.type = eWNI_SME_TDLS_PEER_DISCONNECTED; 1297 break; 1298 case SIR_HAL_TDLS_CONNECTION_TRACKER_NOTIFICATION: 1299 mmhMsg.type = eWNI_SME_TDLS_CONNECTION_TRACKER_NOTIFICATION; 1300 break; 1301 } 1302 1303 mmhMsg.bodyptr = events; 1304 mmhMsg.bodyval = 0; 1305 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1306 return; 1307 } 1308 #endif /* FEATURE_WLAN_TDLS */ 1309 1310 /** 1311 * lim_send_sme_deauth_ntf() 1312 * 1313 ***FUNCTION: 1314 * This function is called by limProcessSmeMessages() to send 1315 * eWNI_SME_DISASSOC_RSP/IND message to host 1316 * 1317 ***PARAMS: 1318 * 1319 ***LOGIC: 1320 * 1321 ***ASSUMPTIONS: 1322 * NA 1323 * 1324 ***NOTE: 1325 * This function is used for sending eWNI_SME_DEAUTH_CNF or 1326 * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger. 1327 * 1328 * @param peerMacAddr Indicates the peer MAC addr to which 1329 * deauthentication was initiated 1330 * @param reasonCode Indicates the reason for Deauthetication 1331 * @param deauthTrigger Indicates the trigger for Deauthetication 1332 * @param aid Indicates the STAID. This parameter is present 1333 * only on AP. 1334 * 1335 * @return None 1336 */ 1337 void 1338 lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, 1339 tSirResultCodes reasonCode, uint16_t deauthTrigger, 1340 uint16_t aid, uint8_t smesessionId, 1341 uint16_t smetransactionId) 1342 { 1343 uint8_t *pBuf; 1344 tSirSmeDeauthRsp *pSirSmeDeauthRsp; 1345 tSirSmeDeauthInd *pSirSmeDeauthInd; 1346 tpPESession psessionEntry; 1347 uint8_t sessionId; 1348 uint32_t *pMsg; 1349 1350 psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId); 1351 switch (deauthTrigger) { 1352 case eLIM_PEER_ENTITY_DEAUTH: 1353 return; 1354 1355 case eLIM_HOST_DEAUTH: 1356 /** 1357 * Deauthentication response to host triggered 1358 * deauthentication. 1359 */ 1360 pSirSmeDeauthRsp = qdf_mem_malloc(sizeof(tSirSmeDeauthRsp)); 1361 if (NULL == pSirSmeDeauthRsp) { 1362 /* Log error */ 1363 lim_log(pMac, LOGP, 1364 FL 1365 ("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP")); 1366 1367 return; 1368 } 1369 lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with " 1370 "retCode: %d for" MAC_ADDRESS_STR), 1371 reasonCode, MAC_ADDR_ARRAY(peerMacAddr)); 1372 pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP; 1373 pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp); 1374 pSirSmeDeauthRsp->statusCode = reasonCode; 1375 pSirSmeDeauthRsp->sessionId = smesessionId; 1376 pSirSmeDeauthRsp->transactionId = smetransactionId; 1377 1378 pBuf = (uint8_t *) pSirSmeDeauthRsp->peer_macaddr.bytes; 1379 qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr)); 1380 1381 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1382 lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT, 1383 psessionEntry, 0, (uint16_t) reasonCode); 1384 #endif 1385 pMsg = (uint32_t *) pSirSmeDeauthRsp; 1386 1387 break; 1388 1389 default: 1390 /** 1391 * Deauthentication indication due to Deauthentication 1392 * frame reception from peer entity or due to 1393 * loss of link with peer entity. 1394 */ 1395 pSirSmeDeauthInd = qdf_mem_malloc(sizeof(tSirSmeDeauthInd)); 1396 if (NULL == pSirSmeDeauthInd) { 1397 /* Log error */ 1398 lim_log(pMac, LOGP, 1399 FL 1400 ("call to AllocateMemory failed for eWNI_SME_DEAUTH_Ind")); 1401 1402 return; 1403 } 1404 lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_IND with " 1405 "retCode: %d for " MAC_ADDRESS_STR), 1406 reasonCode, MAC_ADDR_ARRAY(peerMacAddr)); 1407 pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; 1408 pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd); 1409 pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; 1410 1411 /* sessionId */ 1412 pBuf = (uint8_t *) &pSirSmeDeauthInd->sessionId; 1413 *pBuf++ = smesessionId; 1414 1415 /* transaction ID */ 1416 lim_copy_u16(pBuf, smetransactionId); 1417 pBuf += sizeof(uint16_t); 1418 1419 /* status code */ 1420 lim_copy_u32(pBuf, reasonCode); 1421 pBuf += sizeof(tSirResultCodes); 1422 1423 /* bssId */ 1424 qdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); 1425 pBuf += sizeof(tSirMacAddr); 1426 1427 /* peerMacAddr */ 1428 qdf_mem_copy(pSirSmeDeauthInd->peer_macaddr.bytes, peerMacAddr, 1429 QDF_MAC_ADDR_SIZE); 1430 1431 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1432 lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, 1433 psessionEntry, 0, (uint16_t) reasonCode); 1434 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1435 pMsg = (uint32_t *) pSirSmeDeauthInd; 1436 1437 break; 1438 } 1439 1440 /*Delete the PE session created */ 1441 if (psessionEntry != NULL) { 1442 pe_delete_session(pMac, psessionEntry); 1443 } 1444 1445 lim_send_sme_disassoc_deauth_ntf(pMac, QDF_STATUS_SUCCESS, 1446 (uint32_t *) pMsg); 1447 1448 } /*** end lim_send_sme_deauth_ntf() ***/ 1449 1450 /** 1451 * lim_send_sme_wm_status_change_ntf() - Send Notification 1452 * @mac_ctx: Global MAC Context 1453 * @status_change_code: Indicates the change in the wireless medium. 1454 * @status_change_info: Indicates the information associated with 1455 * change in the wireless medium. 1456 * @info_len: Indicates the length of status change information 1457 * being sent. 1458 * @session_id SessionID 1459 * 1460 * This function is called by limProcessSmeMessages() to send 1461 * eWNI_SME_WM_STATUS_CHANGE_NTF message to host. 1462 * 1463 * Return: None 1464 */ 1465 void 1466 lim_send_sme_wm_status_change_ntf(tpAniSirGlobal mac_ctx, 1467 tSirSmeStatusChangeCode status_change_code, 1468 uint32_t *status_change_info, uint16_t info_len, uint8_t session_id) 1469 { 1470 tSirMsgQ msg; 1471 tSirSmeWmStatusChangeNtf *wm_status_change_ntf; 1472 1473 wm_status_change_ntf = qdf_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf)); 1474 if (NULL == wm_status_change_ntf) { 1475 lim_log(mac_ctx, LOGE, 1476 FL("Mem Alloc failed - eWNI_SME_WM_STATUS_CHANGE_NTF")); 1477 return; 1478 } 1479 1480 msg.type = eWNI_SME_WM_STATUS_CHANGE_NTF; 1481 msg.bodyval = 0; 1482 msg.bodyptr = wm_status_change_ntf; 1483 1484 switch (status_change_code) { 1485 case eSIR_SME_RADAR_DETECTED: 1486 break; 1487 default: 1488 wm_status_change_ntf->messageType = 1489 eWNI_SME_WM_STATUS_CHANGE_NTF; 1490 wm_status_change_ntf->statusChangeCode = status_change_code; 1491 wm_status_change_ntf->length = sizeof(tSirSmeWmStatusChangeNtf); 1492 wm_status_change_ntf->sessionId = session_id; 1493 if (sizeof(wm_status_change_ntf->statusChangeInfo) >= 1494 info_len) { 1495 qdf_mem_copy( 1496 (uint8_t *) &wm_status_change_ntf->statusChangeInfo, 1497 (uint8_t *) status_change_info, info_len); 1498 } 1499 lim_log(mac_ctx, LOGE, 1500 FL("**---** StatusChg: code 0x%x, length %d **---**"), 1501 status_change_code, info_len); 1502 break; 1503 } 1504 1505 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, session_id, msg.type)); 1506 if (eSIR_SUCCESS != lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT)) { 1507 qdf_mem_free(wm_status_change_ntf); 1508 lim_log(mac_ctx, LOGP, 1509 FL("lim_sys_process_mmh_msg_api failed")); 1510 } 1511 1512 } /*** end lim_send_sme_wm_status_change_ntf() ***/ 1513 1514 /** 1515 * lim_send_sme_set_context_rsp() 1516 * 1517 ***FUNCTION: 1518 * This function is called by limProcessSmeMessages() to send 1519 * eWNI_SME_SETCONTEXT_RSP message to host 1520 * 1521 ***PARAMS: 1522 * 1523 ***LOGIC: 1524 * 1525 ***ASSUMPTIONS: 1526 * NA 1527 * 1528 ***NOTE: 1529 * 1530 * @param pMac Pointer to Global MAC structure 1531 * @param peerMacAddr Indicates the peer MAC addr to which 1532 * setContext was performed 1533 * @param aid Indicates the aid corresponding to the peer MAC 1534 * address 1535 * @param resultCode Indicates the result of previously issued 1536 * eWNI_SME_SETCONTEXT_RSP message 1537 * 1538 * @return None 1539 */ 1540 void 1541 lim_send_sme_set_context_rsp(tpAniSirGlobal pMac, 1542 struct qdf_mac_addr peer_macaddr, uint16_t aid, 1543 tSirResultCodes resultCode, 1544 tpPESession psessionEntry, uint8_t smesessionId, 1545 uint16_t smetransactionId) 1546 { 1547 tSirMsgQ mmhMsg; 1548 tSirSmeSetContextRsp *pSirSmeSetContextRsp; 1549 1550 pSirSmeSetContextRsp = qdf_mem_malloc(sizeof(tSirSmeSetContextRsp)); 1551 if (NULL == pSirSmeSetContextRsp) { 1552 /* Log error */ 1553 lim_log(pMac, LOGP, 1554 FL 1555 ("call to AllocateMemory failed for SmeSetContextRsp")); 1556 1557 return; 1558 } 1559 1560 pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP; 1561 pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp); 1562 pSirSmeSetContextRsp->statusCode = resultCode; 1563 1564 qdf_copy_macaddr(&pSirSmeSetContextRsp->peer_macaddr, &peer_macaddr); 1565 1566 /* Update SME session and transaction Id */ 1567 pSirSmeSetContextRsp->sessionId = smesessionId; 1568 pSirSmeSetContextRsp->transactionId = smetransactionId; 1569 1570 mmhMsg.type = eWNI_SME_SETCONTEXT_RSP; 1571 mmhMsg.bodyptr = pSirSmeSetContextRsp; 1572 mmhMsg.bodyval = 0; 1573 if (NULL == psessionEntry) { 1574 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1575 NO_SESSION, mmhMsg.type)); 1576 } else { 1577 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1578 psessionEntry->peSessionId, mmhMsg.type)); 1579 } 1580 1581 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1582 lim_diag_event_report(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT, 1583 psessionEntry, (uint16_t) resultCode, 0); 1584 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1585 1586 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1587 } /*** end lim_send_sme_set_context_rsp() ***/ 1588 1589 /** 1590 * lim_send_sme_neighbor_bss_ind() 1591 * 1592 ***FUNCTION: 1593 * This function is called by lim_lookup_nadd_hash_entry() to send 1594 * eWNI_SME_NEIGHBOR_BSS_IND message to host 1595 * 1596 ***PARAMS: 1597 * 1598 ***LOGIC: 1599 * 1600 ***ASSUMPTIONS: 1601 * NA 1602 * 1603 ***NOTE: 1604 * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to 1605 * host upon detecting new BSS during background scanning if CFG 1606 * option is enabled for sending such indication 1607 * 1608 * @param pMac - Pointer to Global MAC structure 1609 * @return None 1610 */ 1611 1612 void 1613 lim_send_sme_neighbor_bss_ind(tpAniSirGlobal pMac, tLimScanResultNode *pBssDescr) 1614 { 1615 tSirMsgQ msgQ; 1616 uint32_t val; 1617 tSirSmeNeighborBssInd *pNewBssInd; 1618 1619 if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) || 1620 ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) && 1621 pMac->lim.gLimRspReqd)) { 1622 /* LIM is not in background scan state OR */ 1623 /* current scan is initiated by HDD. */ 1624 /* No need to send new BSS indication to HDD */ 1625 return; 1626 } 1627 1628 if (wlan_cfg_get_int(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) != 1629 eSIR_SUCCESS) { 1630 lim_log(pMac, LOGP, 1631 FL("could not get NEIGHBOR_BSS_IND from CFG")); 1632 1633 return; 1634 } 1635 1636 if (val == 0) 1637 return; 1638 1639 /** 1640 * Need to indicate new BSSs found during 1641 * background scanning to host. 1642 * Allocate buffer for sending indication. 1643 * Length of buffer is length of BSS description 1644 * and length of header itself 1645 */ 1646 val = pBssDescr->bssDescription.length + sizeof(uint16_t) + 1647 sizeof(uint32_t) + sizeof(uint8_t); 1648 pNewBssInd = qdf_mem_malloc(val); 1649 if (NULL == pNewBssInd) { 1650 /* Log error */ 1651 lim_log(pMac, LOGP, 1652 FL 1653 ("call to AllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND")); 1654 1655 return; 1656 } 1657 1658 pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND; 1659 pNewBssInd->length = (uint16_t) val; 1660 pNewBssInd->sessionId = 0; 1661 1662 qdf_mem_copy((uint8_t *) pNewBssInd->bssDescription, 1663 (uint8_t *) &pBssDescr->bssDescription, 1664 pBssDescr->bssDescription.length + sizeof(uint16_t)); 1665 1666 msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND; 1667 msgQ.bodyptr = pNewBssInd; 1668 msgQ.bodyval = 0; 1669 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, msgQ.type)); 1670 lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT); 1671 } /*** end lim_send_sme_neighbor_bss_ind() ***/ 1672 1673 /** ----------------------------------------------------------------- 1674 \brief lim_send_sme_addts_rsp() - sends SME ADDTS RSP 1675 \ This function sends a eWNI_SME_ADDTS_RSP to SME. 1676 \ SME only looks at rc and tspec field. 1677 \param pMac - global mac structure 1678 \param rspReqd - is SmeAddTsRsp required 1679 \param status - status code of SME_ADD_TS_RSP 1680 \return tspec 1681 \sa 1682 ----------------------------------------------------------------- */ 1683 void 1684 lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status, 1685 tpPESession psessionEntry, tSirMacTspecIE tspec, 1686 uint8_t smesessionId, uint16_t smetransactionId) 1687 { 1688 tpSirAddtsRsp rsp; 1689 tSirMsgQ mmhMsg; 1690 1691 if (!rspReqd) 1692 return; 1693 1694 rsp = qdf_mem_malloc(sizeof(tSirAddtsRsp)); 1695 if (NULL == rsp) { 1696 lim_log(pMac, LOGP, FL("AllocateMemory failed for ADDTS_RSP")); 1697 return; 1698 } 1699 1700 qdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0); 1701 rsp->messageType = eWNI_SME_ADDTS_RSP; 1702 rsp->rc = status; 1703 rsp->rsp.status = (enum eSirMacStatusCodes)status; 1704 rsp->rsp.tspec = tspec; 1705 /* Update SME session Id and transcation Id */ 1706 rsp->sessionId = smesessionId; 1707 rsp->transactionId = smetransactionId; 1708 1709 mmhMsg.type = eWNI_SME_ADDTS_RSP; 1710 mmhMsg.bodyptr = rsp; 1711 mmhMsg.bodyval = 0; 1712 if (NULL == psessionEntry) { 1713 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1714 NO_SESSION, mmhMsg.type)); 1715 } else { 1716 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1717 psessionEntry->peSessionId, mmhMsg.type)); 1718 } 1719 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1720 lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0, 1721 0); 1722 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1723 1724 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1725 return; 1726 } 1727 1728 void 1729 lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, uint32_t status, 1730 tpPESession psessionEntry, uint8_t smesessionId, 1731 uint16_t smetransactionId) 1732 { 1733 tpSirDeltsRsp rsp; 1734 tSirMsgQ mmhMsg; 1735 1736 lim_log(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d", 1737 delts->aid, 1738 delts->req.tsinfo.traffic.tsid, 1739 delts->req.tsinfo.traffic.userPrio, status); 1740 if (!delts->rspReqd) 1741 return; 1742 1743 rsp = qdf_mem_malloc(sizeof(tSirDeltsRsp)); 1744 if (NULL == rsp) { 1745 /* Log error */ 1746 lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_RSP")); 1747 return; 1748 } 1749 qdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0); 1750 1751 if (psessionEntry != NULL) { 1752 1753 rsp->aid = delts->aid; 1754 qdf_copy_macaddr(&rsp->macaddr, &delts->macaddr); 1755 qdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) &delts->req, 1756 sizeof(tSirDeltsReqInfo)); 1757 } 1758 1759 rsp->messageType = eWNI_SME_DELTS_RSP; 1760 rsp->rc = status; 1761 1762 /* Update SME session Id and transcation Id */ 1763 rsp->sessionId = smesessionId; 1764 rsp->transactionId = smetransactionId; 1765 1766 mmhMsg.type = eWNI_SME_DELTS_RSP; 1767 mmhMsg.bodyptr = rsp; 1768 mmhMsg.bodyval = 0; 1769 if (NULL == psessionEntry) { 1770 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1771 NO_SESSION, mmhMsg.type)); 1772 } else { 1773 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 1774 psessionEntry->peSessionId, mmhMsg.type)); 1775 } 1776 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1777 lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry, 1778 (uint16_t) status, 0); 1779 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1780 1781 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1782 } 1783 1784 void 1785 lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, uint16_t aid, 1786 tpPESession psessionEntry) 1787 { 1788 tpSirDeltsRsp rsp; 1789 tSirMsgQ mmhMsg; 1790 1791 lim_log(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)", 1792 aid, delts->tsinfo.traffic.tsid, delts->tsinfo.traffic.userPrio); 1793 1794 rsp = qdf_mem_malloc(sizeof(tSirDeltsRsp)); 1795 if (NULL == rsp) { 1796 /* Log error */ 1797 lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_IND")); 1798 return; 1799 } 1800 qdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0); 1801 1802 rsp->messageType = eWNI_SME_DELTS_IND; 1803 rsp->rc = eSIR_SUCCESS; 1804 rsp->aid = aid; 1805 qdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) delts, sizeof(*delts)); 1806 1807 /* Update SME session Id and SME transaction Id */ 1808 1809 rsp->sessionId = psessionEntry->smeSessionId; 1810 rsp->transactionId = psessionEntry->transactionId; 1811 1812 mmhMsg.type = eWNI_SME_DELTS_IND; 1813 mmhMsg.bodyptr = rsp; 1814 mmhMsg.bodyval = 0; 1815 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type)); 1816 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 1817 lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0, 1818 0); 1819 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 1820 1821 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1822 } 1823 1824 /** 1825 * lim_send_sme_pe_statistics_rsp() 1826 * 1827 ***FUNCTION: 1828 * This function is called to send 802.11 statistics response to HDD. 1829 * This function posts the result back to HDD. This is a response to 1830 * HDD's request for statistics. 1831 * 1832 ***PARAMS: 1833 * 1834 ***LOGIC: 1835 * 1836 ***ASSUMPTIONS: 1837 * NA 1838 * 1839 ***NOTE: 1840 * NA 1841 * 1842 * @param pMac Pointer to Global MAC structure 1843 * @param p80211Stats Statistics sent in response 1844 * @param resultCode TODO: 1845 * 1846 * 1847 * @return none 1848 */ 1849 1850 void 1851 lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgType, void *stats) 1852 { 1853 tSirMsgQ mmhMsg; 1854 uint8_t sessionId; 1855 tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats; 1856 tpPESession pPeSessionEntry; 1857 1858 /* Get the Session Id based on Sta Id */ 1859 pPeSessionEntry = 1860 pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId); 1861 1862 /* Fill the Session Id */ 1863 if (NULL != pPeSessionEntry) { 1864 /* Fill the Session Id */ 1865 pPeStats->sessionId = pPeSessionEntry->smeSessionId; 1866 } 1867 1868 pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP; 1869 1870 /* msgType should be WMA_GET_STATISTICS_RSP */ 1871 mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP; 1872 1873 mmhMsg.bodyptr = stats; 1874 mmhMsg.bodyval = 0; 1875 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); 1876 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1877 1878 return; 1879 1880 } /*** end lim_send_sme_pe_statistics_rsp() ***/ 1881 1882 #ifdef FEATURE_WLAN_ESE 1883 /** 1884 * lim_send_sme_pe_ese_tsm_rsp() - send tsm response 1885 * @pMac: Pointer to global pMac structure 1886 * @pStats: Pointer to TSM Stats 1887 * 1888 * This function is called to send tsm stats response to HDD. 1889 * This function posts the result back to HDD. This is a response to 1890 * HDD's request to get tsm stats. 1891 * 1892 * Return: None 1893 */ 1894 void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac, 1895 tAniGetTsmStatsRsp *pStats) 1896 { 1897 tSirMsgQ mmhMsg; 1898 uint8_t sessionId; 1899 tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats; 1900 tpPESession pPeSessionEntry = NULL; 1901 1902 /* Get the Session Id based on Sta Id */ 1903 pPeSessionEntry = 1904 pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId); 1905 1906 /* Fill the Session Id */ 1907 if (NULL != pPeSessionEntry) { 1908 /* Fill the Session Id */ 1909 pPeStats->sessionId = pPeSessionEntry->smeSessionId; 1910 } else { 1911 PELOGE(lim_log 1912 (pMac, LOGE, FL("Session not found for the Sta id(%d)"), 1913 pPeStats->staId);) 1914 return; 1915 } 1916 1917 pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP; 1918 pPeStats->tsmMetrics.RoamingCount 1919 = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount; 1920 pPeStats->tsmMetrics.RoamingDly 1921 = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly; 1922 1923 mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP; 1924 mmhMsg.bodyptr = pStats; 1925 mmhMsg.bodyval = 0; 1926 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); 1927 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1928 1929 return; 1930 } /*** end lim_send_sme_pe_ese_tsm_rsp() ***/ 1931 1932 #endif /* FEATURE_WLAN_ESE */ 1933 1934 void 1935 lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac, 1936 tSirMacAddr peerMacAddr, 1937 uint16_t staIndex, 1938 uint8_t ucastIdx, 1939 uint8_t bcastIdx, 1940 uint8_t *beacon, 1941 uint16_t beaconLen, uint16_t msgType, uint8_t sessionId) 1942 { 1943 tSirMsgQ mmhMsg; 1944 tSmeIbssPeerInd *pNewPeerInd; 1945 1946 pNewPeerInd = qdf_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen); 1947 if (NULL == pNewPeerInd) { 1948 PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));) 1949 return; 1950 } 1951 1952 qdf_mem_set((void *)pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen), 1953 0); 1954 1955 qdf_mem_copy((uint8_t *) pNewPeerInd->peer_addr.bytes, 1956 peerMacAddr, QDF_MAC_ADDR_SIZE); 1957 pNewPeerInd->staId = staIndex; 1958 pNewPeerInd->ucastSig = ucastIdx; 1959 pNewPeerInd->bcastSig = bcastIdx; 1960 pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen; 1961 pNewPeerInd->mesgType = msgType; 1962 pNewPeerInd->sessionId = sessionId; 1963 1964 if (beacon != NULL) { 1965 qdf_mem_copy((void *)((uint8_t *) pNewPeerInd + 1966 sizeof(tSmeIbssPeerInd)), (void *)beacon, 1967 beaconLen); 1968 } 1969 1970 mmhMsg.type = msgType; 1971 mmhMsg.bodyptr = pNewPeerInd; 1972 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); 1973 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 1974 1975 } 1976 1977 /** 1978 * lim_handle_csa_offload_msg() - Handle CSA offload message 1979 * @mac_ctx: pointer to global adapter context 1980 * @msg: Message pointer. 1981 * 1982 * Return: None 1983 */ 1984 void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) 1985 { 1986 tpPESession session_entry; 1987 tSirMsgQ mmh_msg; 1988 struct csa_offload_params *csa_params = 1989 (struct csa_offload_params *) (msg->bodyptr); 1990 tpSmeCsaOffloadInd csa_offload_ind; 1991 tpDphHashNode sta_ds = NULL; 1992 uint8_t session_id; 1993 uint16_t aid = 0; 1994 uint16_t chan_space = 0; 1995 struct ch_params_s ch_params; 1996 1997 tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL; 1998 tLimChannelSwitchInfo *lim_ch_switch = NULL; 1999 2000 lim_log(mac_ctx, LOG1, FL("handle csa offload msg")); 2001 2002 if (!csa_params) { 2003 lim_log(mac_ctx, LOGE, FL("limMsgQ body ptr is NULL")); 2004 return; 2005 } 2006 2007 session_entry = 2008 pe_find_session_by_bssid(mac_ctx, 2009 csa_params->bssId, &session_id); 2010 if (!session_entry) { 2011 lim_log(mac_ctx, LOGE, 2012 FL("Session does not exists for %pM"), 2013 csa_params->bssId); 2014 goto err; 2015 } 2016 2017 sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid, 2018 &session_entry->dph.dphHashTable); 2019 2020 if (!sta_ds) { 2021 lim_log(mac_ctx, LOGE, 2022 FL("sta_ds does not exist")); 2023 goto err; 2024 } 2025 2026 if (LIM_IS_STA_ROLE(session_entry)) { 2027 /* 2028 * on receiving channel switch announcement from AP, delete all 2029 * TDLS peers before leaving BSS and proceed for channel switch 2030 */ 2031 lim_delete_tdls_peers(mac_ctx, session_entry); 2032 2033 lim_ch_switch = &session_entry->gLimChannelSwitch; 2034 session_entry->gLimChannelSwitch.switchMode = 2035 csa_params->switch_mode; 2036 /* timer already started by firmware, switch immediately */ 2037 session_entry->gLimChannelSwitch.switchCount = 0; 2038 session_entry->gLimChannelSwitch.primaryChannel = 2039 csa_params->channel; 2040 session_entry->gLimChannelSwitch.state = 2041 eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; 2042 session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ; 2043 lim_ch_switch->sec_ch_offset = 2044 session_entry->htSecondaryChannelOffset; 2045 session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 0; 2046 session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 0; 2047 chnl_switch_info = 2048 &session_entry->gLimWiderBWChannelSwitch; 2049 2050 lim_log(mac_ctx, LOG1, 2051 FL("vht:%d ht:%d flag:%x chan:%d seg1:%d seg2:%d width:%d country:%s class:%d"), 2052 session_entry->vhtCapability, 2053 session_entry->htSupportedChannelWidthSet, 2054 csa_params->ies_present_flag, 2055 csa_params->channel, csa_params->new_ch_freq_seg1, 2056 csa_params->new_ch_freq_seg2, 2057 csa_params->new_ch_width, 2058 mac_ctx->scan.countryCodeCurrent, 2059 csa_params->new_op_class); 2060 2061 if (session_entry->vhtCapability && 2062 session_entry->htSupportedChannelWidthSet) { 2063 if (csa_params->ies_present_flag & lim_wbw_ie_present) { 2064 chnl_switch_info->newChanWidth = 2065 csa_params->new_ch_width; 2066 chnl_switch_info->newCenterChanFreq0 = 2067 csa_params->new_ch_freq_seg1; 2068 chnl_switch_info->newCenterChanFreq1 = 2069 csa_params->new_ch_freq_seg2; 2070 session_entry->gLimChannelSwitch.state = 2071 eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; 2072 session_entry->gLimChannelSwitch.ch_width = 2073 csa_params->new_ch_width + 1; 2074 } else if (csa_params->ies_present_flag 2075 & lim_xcsa_ie_present) { 2076 chan_space = 2077 cds_reg_dmn_get_chanwidth_from_opclass( 2078 mac_ctx->scan.countryCodeCurrent, 2079 csa_params->channel, 2080 csa_params->new_op_class); 2081 session_entry->gLimChannelSwitch.state = 2082 eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; 2083 2084 if (chan_space == 80) { 2085 chnl_switch_info->newChanWidth = 2086 CH_WIDTH_80MHZ; 2087 } else if (chan_space == 40) { 2088 chnl_switch_info->newChanWidth = 2089 CH_WIDTH_40MHZ; 2090 } else { 2091 chnl_switch_info->newChanWidth = 2092 CH_WIDTH_20MHZ; 2093 lim_ch_switch->state = 2094 eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; 2095 } 2096 2097 ch_params.ch_width = 2098 chnl_switch_info->newChanWidth; 2099 cds_set_channel_params(csa_params->channel, 2100 0, &ch_params); 2101 chnl_switch_info->newCenterChanFreq0 = 2102 ch_params.center_freq_seg0; 2103 /* 2104 * This is not applicable for 20/40/80 MHz. 2105 * Only used when we support 80+80 MHz operation. 2106 * In case of 80+80 MHz, this parameter indicates 2107 * center channel frequency index of 80 MHz 2108 * channel offrequency segment 1. 2109 */ 2110 chnl_switch_info->newCenterChanFreq1 = 2111 ch_params.center_freq_seg1; 2112 lim_ch_switch->sec_ch_offset = 2113 ch_params.sec_ch_offset; 2114 2115 } 2116 session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 2117 chnl_switch_info->newCenterChanFreq0; 2118 session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 2119 chnl_switch_info->newCenterChanFreq1; 2120 session_entry->gLimChannelSwitch.ch_width = 2121 chnl_switch_info->newChanWidth; 2122 2123 } else if (session_entry->htSupportedChannelWidthSet) { 2124 if (csa_params->ies_present_flag 2125 & lim_xcsa_ie_present) { 2126 chan_space = 2127 cds_reg_dmn_get_chanwidth_from_opclass( 2128 mac_ctx->scan.countryCodeCurrent, 2129 csa_params->channel, 2130 csa_params->new_op_class); 2131 lim_ch_switch->state = 2132 eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; 2133 if (chan_space == 40) { 2134 lim_ch_switch->ch_width = 2135 CH_WIDTH_40MHZ; 2136 chnl_switch_info->newChanWidth = 2137 CH_WIDTH_40MHZ; 2138 ch_params.ch_width = 2139 chnl_switch_info->newChanWidth; 2140 cds_set_channel_params( 2141 csa_params->channel, 2142 0, &ch_params); 2143 lim_ch_switch->ch_center_freq_seg0 = 2144 ch_params.center_freq_seg0; 2145 lim_ch_switch->sec_ch_offset = 2146 ch_params.sec_ch_offset; 2147 } else { 2148 lim_ch_switch->ch_width = 2149 CH_WIDTH_20MHZ; 2150 chnl_switch_info->newChanWidth = 2151 CH_WIDTH_40MHZ; 2152 lim_ch_switch->state = 2153 eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; 2154 lim_ch_switch->sec_ch_offset = 2155 PHY_SINGLE_CHANNEL_CENTERED; 2156 } 2157 } else { 2158 lim_ch_switch->ch_width = 2159 CH_WIDTH_40MHZ; 2160 lim_ch_switch->state = 2161 eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; 2162 ch_params.ch_width = CH_WIDTH_40MHZ; 2163 cds_set_channel_params(csa_params->channel, 2164 0, &ch_params); 2165 lim_ch_switch->ch_center_freq_seg0 = 2166 ch_params.center_freq_seg0; 2167 lim_ch_switch->sec_ch_offset = 2168 ch_params.sec_ch_offset; 2169 } 2170 2171 } 2172 lim_log(mac_ctx, LOG1, FL("new ch width = %d space:%d"), 2173 session_entry->gLimChannelSwitch.ch_width, chan_space); 2174 2175 lim_prepare_for11h_channel_switch(mac_ctx, session_entry); 2176 csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd)); 2177 if (NULL == csa_offload_ind) { 2178 lim_log(mac_ctx, LOGE, 2179 FL("memalloc fail eWNI_SME_CSA_OFFLOAD_EVENT")); 2180 goto err; 2181 } 2182 2183 qdf_mem_set(csa_offload_ind, sizeof(tSmeCsaOffloadInd), 0); 2184 csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT; 2185 csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd); 2186 qdf_mem_copy(csa_offload_ind->bssid.bytes, session_entry->bssId, 2187 QDF_MAC_ADDR_SIZE); 2188 mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT; 2189 mmh_msg.bodyptr = csa_offload_ind; 2190 mmh_msg.bodyval = 0; 2191 lim_log(mac_ctx, LOG1, 2192 FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME.")); 2193 MTRACE(mac_trace_msg_tx 2194 (mac_ctx, session_entry->peSessionId, mmh_msg.type)); 2195 #ifdef FEATURE_WLAN_DIAG_SUPPORT 2196 lim_diag_event_report(mac_ctx, 2197 WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT, session_entry, 2198 eSIR_SUCCESS, eSIR_SUCCESS); 2199 #endif 2200 lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT); 2201 } 2202 2203 err: 2204 qdf_mem_free(csa_params); 2205 } 2206 2207 /*-------------------------------------------------------------------------- 2208 \brief pe_delete_session() - Handle the Delete BSS Response from HAL. 2209 2210 \param pMac - pointer to global adapter context 2211 \param sessionId - Message pointer. 2212 2213 \sa 2214 --------------------------------------------------------------------------*/ 2215 2216 void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ) 2217 { 2218 tpPESession psessionEntry; 2219 tpDeleteBssParams pDelBss = (tpDeleteBssParams) (MsgQ->bodyptr); 2220 2221 psessionEntry = 2222 pe_find_session_by_session_id(pMac, pDelBss->sessionId); 2223 if (psessionEntry == NULL) { 2224 lim_log(pMac, LOGE, 2225 FL("Session Does not exist for given sessionID %d"), 2226 pDelBss->sessionId); 2227 qdf_mem_free(MsgQ->bodyptr); 2228 return; 2229 } 2230 if (LIM_IS_IBSS_ROLE(psessionEntry)) 2231 lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry); 2232 else if (LIM_IS_UNKNOWN_ROLE(psessionEntry)) 2233 lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry); 2234 else if (LIM_IS_NDI_ROLE(psessionEntry)) 2235 lim_ndi_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry); 2236 else 2237 lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry); 2238 2239 } 2240 2241 /** ----------------------------------------------------------------- 2242 \brief lim_send_sme_aggr_qos_rsp() - sends SME FT AGGR QOS RSP 2243 \ This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME. 2244 \ SME only looks at rc and tspec field. 2245 \param pMac - global mac structure 2246 \param rspReqd - is SmeAddTsRsp required 2247 \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP 2248 \return tspec 2249 \sa 2250 ----------------------------------------------------------------- */ 2251 void 2252 lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp, 2253 uint8_t smesessionId) 2254 { 2255 tSirMsgQ mmhMsg; 2256 2257 mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP; 2258 mmhMsg.bodyptr = aggrQosRsp; 2259 mmhMsg.bodyval = 0; 2260 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 2261 smesessionId, mmhMsg.type)); 2262 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 2263 2264 return; 2265 } 2266 2267 void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, 2268 uint8_t smesessionId) 2269 { 2270 tSirMsgQ mmhMsg; 2271 tSmeMaxAssocInd *pSmeMaxAssocInd; 2272 2273 pSmeMaxAssocInd = qdf_mem_malloc(sizeof(tSmeMaxAssocInd)); 2274 if (NULL == pSmeMaxAssocInd) { 2275 PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));) 2276 return; 2277 } 2278 qdf_mem_set((void *)pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd), 0); 2279 qdf_mem_copy((uint8_t *) pSmeMaxAssocInd->peer_mac.bytes, 2280 (uint8_t *) peerMacAddr, QDF_MAC_ADDR_SIZE); 2281 pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED; 2282 pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd); 2283 pSmeMaxAssocInd->sessionId = smesessionId; 2284 mmhMsg.type = pSmeMaxAssocInd->mesgType; 2285 mmhMsg.bodyptr = pSmeMaxAssocInd; 2286 PELOG1(lim_log(pMac, LOG1, FL("msgType %s peerMacAddr " MAC_ADDRESS_STR 2287 " sme session id %d"), 2288 "eWNI_SME_MAX_ASSOC_EXCEEDED", 2289 MAC_ADDR_ARRAY(peerMacAddr)); 2290 ) 2291 MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, 2292 smesessionId, mmhMsg.type)); 2293 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 2294 2295 return; 2296 } 2297 2298 /** ----------------------------------------------------------------- 2299 \brief lim_send_sme_dfs_event_notify() - sends 2300 eWNI_SME_DFS_RADAR_FOUND 2301 After receiving WMI_PHYERR_EVENTID indication frame from FW, this 2302 function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify 2303 that a RADAR is found on current operating channel and SAP- 2304 has to move to a new channel. 2305 \param pMac - global mac structure 2306 \param msgType - message type received from lower layer 2307 \param event - event data received from lower layer 2308 \return none 2309 \sa 2310 ----------------------------------------------------------------- */ 2311 void 2312 lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType, void *event) 2313 { 2314 tSirMsgQ mmhMsg; 2315 mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND; 2316 mmhMsg.bodyptr = event; 2317 mmhMsg.bodyval = 0; 2318 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 2319 return; 2320 } 2321 2322 /*-------------------------------------------------------------------------- 2323 \brief lim_send_dfs_chan_sw_ie_update() 2324 This timer handler updates the channel switch IE in beacon template 2325 2326 \param pMac - pointer to global adapter context 2327 \return - channel to scan from valid session else zero. 2328 \sa 2329 --------------------------------------------------------------------------*/ 2330 static void 2331 lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal pMac, tpPESession psessionEntry) 2332 { 2333 2334 /* Update the beacon template and send to FW */ 2335 if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) { 2336 PELOGE(lim_log(pMac, LOGE, FL("Unable to set CSA IE in beacon"));) 2337 return; 2338 } 2339 2340 /* Send update beacon template message */ 2341 lim_send_beacon_ind(pMac, psessionEntry); 2342 PELOG1(lim_log(pMac, LOG1, 2343 FL(" Updated CSA IE, IE COUNT = %d"), 2344 psessionEntry->gLimChannelSwitch.switchCount); 2345 ) 2346 2347 return; 2348 } 2349 2350 /** ----------------------------------------------------------------- 2351 \brief lim_send_sme_ap_channel_switch_resp() - sends 2352 eWNI_SME_CHANNEL_CHANGE_RSP 2353 After receiving WMA_SWITCH_CHANNEL_RSP indication this 2354 function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify 2355 that the Channel change has been done to the specified target 2356 channel in the Channel change request 2357 \param pMac - global mac structure 2358 \param psessionEntry - session info 2359 \param pChnlParams - Channel switch params 2360 --------------------------------------------------------------------*/ 2361 void 2362 lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac, 2363 tpPESession psessionEntry, 2364 tpSwitchChannelParams pChnlParams) 2365 { 2366 tSirMsgQ mmhMsg; 2367 tpSwitchChannelParams pSmeSwithChnlParams; 2368 uint8_t channelId; 2369 bool is_ch_dfs = false; 2370 enum phy_ch_width ch_width; 2371 uint8_t ch_center_freq_seg1; 2372 2373 pSmeSwithChnlParams = (tSwitchChannelParams *) 2374 qdf_mem_malloc(sizeof(tSwitchChannelParams)); 2375 if (NULL == pSmeSwithChnlParams) { 2376 lim_log(pMac, LOGP, 2377 FL("AllocateMemory failed for pSmeSwithChnlParams\n")); 2378 return; 2379 } 2380 2381 qdf_mem_set((void *)pSmeSwithChnlParams, 2382 sizeof(tSwitchChannelParams), 0); 2383 2384 qdf_mem_copy(pSmeSwithChnlParams, pChnlParams, 2385 sizeof(tSwitchChannelParams)); 2386 2387 channelId = pSmeSwithChnlParams->channelNumber; 2388 ch_width = pSmeSwithChnlParams->ch_width; 2389 ch_center_freq_seg1 = pSmeSwithChnlParams->ch_center_freq_seg1; 2390 2391 /* 2392 * Pass the sme sessionID to SME instead 2393 * PE session ID. 2394 */ 2395 pSmeSwithChnlParams->peSessionId = psessionEntry->smeSessionId; 2396 2397 mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP; 2398 mmhMsg.bodyptr = (void *)pSmeSwithChnlParams; 2399 mmhMsg.bodyval = 0; 2400 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 2401 2402 /* 2403 * We should start beacon transmission only if the new 2404 * channel after channel change is Non-DFS. For a DFS 2405 * channel, PE will receive an explicit request from 2406 * upper layers to start the beacon transmission . 2407 */ 2408 2409 if (ch_width == CH_WIDTH_160MHZ) { 2410 is_ch_dfs = true; 2411 } else if (ch_width == CH_WIDTH_80P80MHZ) { 2412 if (cds_get_channel_state(channelId) == CHANNEL_STATE_DFS || 2413 cds_get_channel_state(ch_center_freq_seg1 - 2414 SIR_80MHZ_START_CENTER_CH_DIFF) == 2415 CHANNEL_STATE_DFS) 2416 is_ch_dfs = true; 2417 } else { 2418 if (cds_get_channel_state(channelId) == CHANNEL_STATE_DFS) 2419 is_ch_dfs = true; 2420 } 2421 2422 if (!is_ch_dfs) { 2423 if (channelId == psessionEntry->currentOperChannel) { 2424 lim_apply_configuration(pMac, psessionEntry); 2425 lim_send_beacon_ind(pMac, psessionEntry); 2426 } else { 2427 PELOG1(lim_log(pMac, LOG1, 2428 FL 2429 ("Failed to Transmit Beacons on channel = %d" 2430 "after AP channel change response"), 2431 psessionEntry->bcnLen); 2432 ) 2433 } 2434 } 2435 return; 2436 } 2437 2438 /** ----------------------------------------------------------------- 2439 \brief lim_process_beacon_tx_success_ind() - This function is used 2440 explicitely to handle successful beacon transmission indication 2441 from the FW. This is a generic event generated by the FW afer the 2442 first beacon is sent out after the beacon template update by the 2443 host 2444 \param pMac - global mac structure 2445 \param psessionEntry - session info 2446 \return none 2447 \sa 2448 ----------------------------------------------------------------- */ 2449 void 2450 lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType, void *event) 2451 { 2452 /* Currently, this event is used only for DFS channel switch announcement 2453 * IE update in the template. If required to be used for other IE updates 2454 * add appropriate code by introducing a state variable 2455 */ 2456 tpPESession psessionEntry; 2457 tSirMsgQ mmhMsg; 2458 tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse; 2459 struct sir_beacon_tx_complete_rsp *beacon_tx_comp_rsp_ptr; 2460 uint8_t length = sizeof(tSirSmeCSAIeTxCompleteRsp); 2461 tpSirFirstBeaconTxCompleteInd pBcnTxInd = 2462 (tSirFirstBeaconTxCompleteInd *) event; 2463 2464 psessionEntry = pe_find_session_by_bss_idx(pMac, pBcnTxInd->bssIdx); 2465 if (psessionEntry == NULL) { 2466 lim_log(pMac, LOGE, 2467 FL("Session Does not exist for given sessionID")); 2468 return; 2469 } 2470 2471 lim_log(pMac, LOG1, FL("role:%d swIe:%d opIe:%d"), 2472 GET_LIM_SYSTEM_ROLE(psessionEntry), 2473 psessionEntry->dfsIncludeChanSwIe, 2474 psessionEntry->gLimOperatingMode.present); 2475 2476 if (LIM_IS_AP_ROLE(psessionEntry) && 2477 true == psessionEntry->dfsIncludeChanSwIe) { 2478 /* Send only 5 beacons with CSA IE Set in when a radar is detected */ 2479 if (psessionEntry->gLimChannelSwitch.switchCount > 0) { 2480 /* 2481 * Send the next beacon with updated CSA IE count 2482 */ 2483 lim_send_dfs_chan_sw_ie_update(pMac, psessionEntry); 2484 /* Decrement the IE count */ 2485 psessionEntry->gLimChannelSwitch.switchCount--; 2486 } else { 2487 /* Done with CSA IE update, send response back to SME */ 2488 psessionEntry->gLimChannelSwitch.switchCount = 0; 2489 if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == false) 2490 psessionEntry->gLimChannelSwitch.switchMode = 0; 2491 psessionEntry->dfsIncludeChanSwIe = false; 2492 psessionEntry->dfsIncludeChanWrapperIe = false; 2493 2494 pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *) 2495 qdf_mem_malloc(length); 2496 2497 if (NULL == pChanSwTxResponse) { 2498 lim_log(pMac, LOGP, 2499 FL 2500 ("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp")); 2501 return; 2502 } 2503 2504 qdf_mem_set((void *)pChanSwTxResponse, length, 0); 2505 pChanSwTxResponse->sessionId = 2506 psessionEntry->smeSessionId; 2507 pChanSwTxResponse->chanSwIeTxStatus = 2508 QDF_STATUS_SUCCESS; 2509 2510 mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND; 2511 mmhMsg.bodyptr = pChanSwTxResponse; 2512 mmhMsg.bodyval = 0; 2513 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 2514 } 2515 } 2516 2517 if (LIM_IS_AP_ROLE(psessionEntry) && 2518 psessionEntry->gLimOperatingMode.present) { 2519 /* Done with nss update, send response back to SME */ 2520 psessionEntry->gLimOperatingMode.present = 0; 2521 beacon_tx_comp_rsp_ptr = (struct sir_beacon_tx_complete_rsp *) 2522 qdf_mem_malloc(sizeof(*beacon_tx_comp_rsp_ptr)); 2523 if (NULL == beacon_tx_comp_rsp_ptr) { 2524 lim_log(pMac, LOGP, 2525 FL 2526 ("AllocateMemory failed for beacon_tx_comp_rsp_ptr")); 2527 return; 2528 } 2529 qdf_mem_set((void *)beacon_tx_comp_rsp_ptr, 2530 sizeof(*beacon_tx_comp_rsp_ptr), 0); 2531 beacon_tx_comp_rsp_ptr->session_id = 2532 psessionEntry->smeSessionId; 2533 beacon_tx_comp_rsp_ptr->tx_status = QDF_STATUS_SUCCESS; 2534 mmhMsg.type = eWNI_SME_NSS_UPDATE_RSP; 2535 mmhMsg.bodyptr = beacon_tx_comp_rsp_ptr; 2536 mmhMsg.bodyval = 0; 2537 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); 2538 } 2539 return; 2540 } 2541