1 /* 2 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * \file lim_send_management_frames.c 22 * 23 * \brief Code for preparing and sending 802.11 Management frames 24 * 25 * 26 */ 27 28 #include "sir_api.h" 29 #include "ani_global.h" 30 #include "sir_mac_prot_def.h" 31 #include "utils_api.h" 32 #include "lim_types.h" 33 #include "lim_utils.h" 34 #include "lim_security_utils.h" 35 #include "lim_prop_exts_utils.h" 36 #include "dot11f.h" 37 #include "sch_api.h" 38 #include "lim_send_messages.h" 39 #include "lim_assoc_utils.h" 40 #include "lim_ft.h" 41 #include "wni_cfg.h" 42 43 #include "lim_ft_defs.h" 44 #include "lim_session.h" 45 #include "qdf_types.h" 46 #include "qdf_trace.h" 47 #include "cds_utils.h" 48 #include "sme_trace.h" 49 #include "rrm_api.h" 50 #include "qdf_crypto.h" 51 #include "parser_api.h" 52 53 #include "wma_types.h" 54 #include <cdp_txrx_cmn.h> 55 #include <cdp_txrx_peer_ops.h> 56 #include "lim_process_fils.h" 57 #include "wlan_utility.h" 58 #include <wlan_mlme_api.h> 59 #include <wlan_mlme_main.h> 60 #include "wlan_crypto_global_api.h" 61 #include "wlan_connectivity_logging.h" 62 #include "lim_mlo.h" 63 #include "wlan_mlo_mgr_sta.h" 64 #include "wlan_t2lm_api.h" 65 66 /** 67 * 68 * \brief This function is called to add the sequence number to the 69 * management frames 70 * 71 * \param mac Pointer to Global MAC structure 72 * 73 * \param pMacHdr Pointer to MAC management header 74 * 75 * The pMacHdr argument points to the MAC management header. The 76 * sequence number stored in the mac structure will be incremented 77 * and updated to the MAC management header. The start sequence 78 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is 79 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence 80 * number will roll over. 81 * 82 */ 83 static void lim_add_mgmt_seq_num(struct mac_context *mac, tpSirMacMgmtHdr pMacHdr) 84 { 85 if (mac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) { 86 mac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1; 87 } 88 89 mac->mgmtSeqNum++; 90 91 pMacHdr->seqControl.seqNumLo = (mac->mgmtSeqNum & LOW_SEQ_NUM_MASK); 92 pMacHdr->seqControl.seqNumHi = 93 ((mac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET); 94 } 95 96 /** 97 * lim_populate_mac_header() - Fill in 802.11 header of frame 98 * 99 * @mac_ctx: Pointer to Global MAC structure 100 * @buf: Pointer to the frame buffer that needs to be populate 101 * @type: 802.11 Type of the frame 102 * @sub_type: 802.11 Subtype of the frame 103 * @peer_addr: dst address 104 * @self_mac_addr: local mac address 105 * 106 * This function is called by various LIM modules to prepare the 107 * 802.11 frame MAC header 108 * 109 * The buf argument points to the beginning of the frame buffer to 110 * which - a) The 802.11 MAC header is set b) Following this MAC header 111 * will be the MGMT frame payload The payload itself is populated by the 112 * caller API 113 * 114 * Return: None 115 */ 116 117 void lim_populate_mac_header(struct mac_context *mac_ctx, uint8_t *buf, 118 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr, 119 tSirMacAddr self_mac_addr) 120 { 121 tpSirMacMgmtHdr mac_hdr; 122 123 /* Prepare MAC management header */ 124 mac_hdr = (tpSirMacMgmtHdr) (buf); 125 126 /* Prepare FC */ 127 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; 128 mac_hdr->fc.type = type; 129 mac_hdr->fc.subType = sub_type; 130 131 /* Prepare Address 1 */ 132 qdf_mem_copy((uint8_t *) mac_hdr->da, 133 (uint8_t *) peer_addr, sizeof(tSirMacAddr)); 134 135 /* Prepare Address 2 */ 136 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr); 137 138 /* Prepare Address 3 */ 139 qdf_mem_copy((uint8_t *) mac_hdr->bssId, 140 (uint8_t *) peer_addr, sizeof(tSirMacAddr)); 141 142 /* Prepare sequence number */ 143 lim_add_mgmt_seq_num(mac_ctx, mac_hdr); 144 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d", 145 mac_hdr->seqControl.seqNumLo, 146 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum); 147 } 148 149 /** 150 * lim_send_probe_req_mgmt_frame() - send probe request management frame 151 * @mac_ctx: Pointer to Global MAC structure 152 * @ssid: SSID to be sent in Probe Request frame 153 * @bssid: BSSID to be sent in Probe Request frame 154 * @chan_freq: Channel frequency on which the Probe Request is going out 155 * @self_macaddr: self MAC address 156 * @dot11mode: self dotllmode 157 * @additional_ielen: if non-zero, include additional_ie in the Probe Request 158 * frame 159 * @additional_ie: if additional_ielen is non zero, include this field in the 160 * Probe Request frame 161 * 162 * This function is called by various LIM modules to send Probe Request frame 163 * during active scan/learn phase. 164 * Probe request is sent out in the following scenarios: 165 * --heartbeat failure: session needed 166 * --join req: session needed 167 * --foreground scan: no session 168 * --background scan: no session 169 * --sch_beacon_processing: to get EDCA parameters: session needed 170 * 171 * Return: QDF_STATUS (QDF_STATUS_SUCCESS on success and error codes otherwise) 172 */ 173 QDF_STATUS 174 lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, 175 tSirMacSSid *ssid, 176 tSirMacAddr bssid, 177 qdf_freq_t chan_freq, 178 tSirMacAddr self_macaddr, 179 uint32_t dot11mode, 180 uint16_t *additional_ielen, 181 uint8_t *additional_ie) 182 { 183 tDot11fProbeRequest *pr; 184 uint32_t status, bytes, payload; 185 uint8_t *frame; 186 void *packet; 187 QDF_STATUS qdf_status; 188 struct pe_session *pesession; 189 uint8_t sessionid; 190 const uint8_t *p2pie = NULL; 191 uint8_t txflag = 0; 192 uint8_t vdev_id = 0; 193 bool is_vht_enabled = false; 194 uint8_t txPower; 195 uint16_t addn_ielen = 0; 196 bool extracted_ext_cap_flag = false; 197 tDot11fIEExtCap extracted_ext_cap; 198 QDF_STATUS sir_status; 199 const uint8_t *qcn_ie = NULL; 200 uint8_t channel; 201 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 202 bool is_band_2g; 203 uint16_t ie_buf_size; 204 uint16_t mlo_ie_len = 0; 205 206 if (additional_ielen) 207 addn_ielen = *additional_ielen; 208 209 channel = wlan_reg_freq_to_chan(mac_ctx->pdev, chan_freq); 210 /* 211 * The probe req should not send 11ac capabilities if band is 212 * 2.4GHz, unless gEnableVhtFor24GHzBand is enabled in INI. So 213 * if gEnableVhtFor24GHzBand is false and dot11mode is 11ac 214 * set it to 11n. 215 */ 216 if (wlan_reg_is_24ghz_ch_freq(chan_freq) && 217 !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && 218 (MLME_DOT11_MODE_11AC == dot11mode || 219 MLME_DOT11_MODE_11AC_ONLY == dot11mode)) 220 dot11mode = MLME_DOT11_MODE_11N; 221 /* 222 * session context may or may not be present, when probe request needs 223 * to be sent out. Following cases exist: 224 * --heartbeat failure: session needed 225 * --join req: session needed 226 * --foreground scan: no session 227 * --background scan: no session 228 * --sch_beacon_processing: to get EDCA parameters: session needed 229 * If session context does not exist, some IEs will be populated from 230 * CFGs, e.g. Supported and Extended rate set IEs 231 */ 232 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid); 233 234 if (pesession) 235 vdev_id = pesession->vdev_id; 236 237 pr = qdf_mem_malloc(sizeof(*pr)); 238 if (!pr) { 239 pe_err("memory alloc failed for probe request"); 240 return QDF_STATUS_E_NOMEM; 241 } 242 243 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */ 244 /* and then hand it off to 'dot11f_pack_probe_request' (for */ 245 /* serialization). */ 246 247 /* & delegating to assorted helpers: */ 248 populate_dot11f_ssid(mac_ctx, ssid, &pr->SSID); 249 250 if (addn_ielen && additional_ie) 251 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen); 252 253 /* 254 * Don't include 11b rate if it is a P2P search or probe request is 255 * sent by P2P Client 256 */ 257 if ((MLME_DOT11_MODE_11B != dot11mode) && (p2pie) && 258 ((pesession) && (QDF_P2P_CLIENT_MODE == pesession->opmode))) { 259 /* 260 * In the below API pass channel number > 14, do that it fills 261 * only 11a rates in supported rates 262 */ 263 populate_dot11f_supp_rates(mac_ctx, 15, &pr->SuppRates, 264 pesession); 265 } else { 266 populate_dot11f_supp_rates(mac_ctx, channel, 267 &pr->SuppRates, pesession); 268 269 if (MLME_DOT11_MODE_11B != dot11mode) { 270 populate_dot11f_ext_supp_rates1(mac_ctx, channel, 271 &pr->ExtSuppRates); 272 } 273 } 274 275 /* 276 * Table 7-14 in IEEE Std. 802.11k-2008 says 277 * DS params "can" be present in RRM is disabled and "is" present if 278 * RRM is enabled. It should be ok even if we add it into probe req when 279 * RRM is not enabled. 280 */ 281 populate_dot11f_ds_params(mac_ctx, &pr->DSParams, 282 chan_freq); 283 /* Call RRM module to get the tx power for management used. */ 284 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession); 285 populate_dot11f_wfatpc(mac_ctx, &pr->WFATPC, txPower, 0); 286 287 if (pesession) { 288 /* Include HT Capability IE */ 289 if (pesession->htCapability && 290 !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) 291 populate_dot11f_ht_caps(mac_ctx, pesession, 292 &pr->HTCaps); 293 } else { /* !pesession */ 294 if (IS_DOT11_MODE_HT(dot11mode) && 295 !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) 296 populate_dot11f_ht_caps(mac_ctx, NULL, &pr->HTCaps); 297 } 298 299 /* 300 * Set channelbonding information as "disabled" when tuned to a 301 * 2.4 GHz channel 302 */ 303 if (wlan_reg_is_24ghz_ch_freq(chan_freq)) { 304 if (mac_ctx->roam.configParam.channelBondingMode24GHz 305 == PHY_SINGLE_CHANNEL_CENTERED) { 306 pr->HTCaps.supportedChannelWidthSet = 307 eHT_CHANNEL_WIDTH_20MHZ; 308 pr->HTCaps.shortGI40MHz = 0; 309 } else { 310 pr->HTCaps.supportedChannelWidthSet = 311 eHT_CHANNEL_WIDTH_40MHZ; 312 } 313 } 314 if (pesession) { 315 /* Include VHT Capability IE */ 316 if (pesession->vhtCapability && 317 !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { 318 populate_dot11f_vht_caps(mac_ctx, pesession, 319 &pr->VHTCaps); 320 is_vht_enabled = true; 321 } 322 } else { 323 if (IS_DOT11_MODE_VHT(dot11mode) && 324 !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { 325 populate_dot11f_vht_caps(mac_ctx, pesession, 326 &pr->VHTCaps); 327 is_vht_enabled = true; 328 } 329 } 330 if (pesession) 331 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr->ExtCap, 332 pesession); 333 334 if (IS_DOT11_MODE_HE(dot11mode) && pesession) 335 lim_update_session_he_capable(mac_ctx, pesession); 336 337 populate_dot11f_he_caps(mac_ctx, pesession, &pr->he_cap); 338 populate_dot11f_he_6ghz_cap(mac_ctx, pesession, 339 &pr->he_6ghz_band_cap); 340 341 if (IS_DOT11_MODE_EHT(dot11mode) && pesession && 342 pesession->lim_join_req) { 343 lim_update_session_eht_capable(mac_ctx, pesession); 344 mlo_ie_len = lim_send_probe_req_frame_mlo(mac_ctx, pesession); 345 } 346 347 populate_dot11f_eht_caps(mac_ctx, pesession, &pr->eht_cap); 348 349 if (addn_ielen && additional_ie) { 350 qdf_mem_zero((uint8_t *)&extracted_ext_cap, 351 sizeof(tDot11fIEExtCap)); 352 sir_status = lim_strip_extcap_update_struct(mac_ctx, 353 additional_ie, 354 &addn_ielen, 355 &extracted_ext_cap); 356 if (QDF_STATUS_SUCCESS != sir_status) { 357 pe_debug("Unable to Stripoff ExtCap IE from Probe Req"); 358 } else { 359 struct s_ext_cap *p_ext_cap = 360 (struct s_ext_cap *) 361 extracted_ext_cap.bytes; 362 if (p_ext_cap->interworking_service) 363 p_ext_cap->qos_map = 1; 364 extracted_ext_cap.num_bytes = 365 lim_compute_ext_cap_ie_length 366 (&extracted_ext_cap); 367 extracted_ext_cap_flag = 368 (extracted_ext_cap.num_bytes > 0); 369 if (additional_ielen) 370 *additional_ielen = addn_ielen; 371 } 372 qcn_ie = wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_QCN_OUI_TYPE, 373 SIR_MAC_QCN_OUI_TYPE_SIZE, 374 additional_ie, addn_ielen); 375 } 376 377 /* Add qcn_ie only if qcn ie is not present in additional_ie */ 378 if (pesession) { 379 if (!qcn_ie) 380 populate_dot11f_qcn_ie(mac_ctx, pesession, 381 &pr->qcn_ie, 382 QCN_IE_ATTR_ID_ALL); 383 else 384 populate_dot11f_qcn_ie(mac_ctx, pesession, 385 &pr->qcn_ie, 386 QCN_IE_ATTR_ID_VHT_MCS11); 387 } 388 389 /* 390 * Extcap IE now support variable length, merge Extcap IE from addn_ie 391 * may change the frame size. Therefore, MUST merge ExtCap IE before 392 * dot11f get packed payload size. 393 */ 394 if (extracted_ext_cap_flag) 395 lim_merge_extcap_struct(&pr->ExtCap, &extracted_ext_cap, true); 396 397 398 /* That's it-- now we pack it. First, how much space are we going to */ 399 status = dot11f_get_packed_probe_request_size(mac_ctx, pr, &payload); 400 if (DOT11F_FAILED(status)) { 401 pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)", 402 status); 403 /* We'll fall back on the worst case scenario: */ 404 payload = sizeof(tDot11fProbeRequest); 405 } else if (DOT11F_WARNED(status)) { 406 pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)", 407 status); 408 } 409 410 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen + mlo_ie_len; 411 412 /* Ok-- try to allocate some memory: */ 413 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame, 414 (void **)&packet); 415 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 416 pe_err("Failed to allocate %d bytes for a Probe Request", bytes); 417 qdf_mem_free(pr); 418 return QDF_STATUS_E_NOMEM; 419 } 420 /* Paranoia: */ 421 qdf_mem_zero(frame, bytes); 422 423 /* Next, we fill out the buffer descriptor: */ 424 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 425 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr); 426 427 /* That done, pack the Probe Request: */ 428 status = dot11f_pack_probe_request(mac_ctx, pr, frame + 429 sizeof(tSirMacMgmtHdr), 430 payload, &payload); 431 if (DOT11F_FAILED(status)) { 432 pe_err("Failed to pack a Probe Request (0x%08x)", status); 433 cds_packet_free((void *)packet); 434 return QDF_STATUS_E_FAILURE; /* allocated! */ 435 } else if (DOT11F_WARNED(status)) { 436 pe_warn("There were warnings while packing a Probe Request (0x%08x)", status); 437 } 438 439 /* Strip EHT capabilities IE */ 440 if (lim_is_session_eht_capable(pesession)) { 441 ie_buf_size = payload; 442 443 eht_cap_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 444 if (!eht_cap_ie) { 445 pe_err("malloc failed for eht_cap_ie"); 446 goto skip_eht_ie_update; 447 } 448 449 qdf_status = lim_strip_eht_cap_ie(mac_ctx, frame + 450 sizeof(tSirMacMgmtHdr), 451 &ie_buf_size, eht_cap_ie); 452 if (QDF_IS_STATUS_ERROR(qdf_status)) { 453 pe_err("Failed to strip EHT cap IE"); 454 qdf_mem_free(eht_cap_ie); 455 goto skip_eht_ie_update; 456 } 457 458 is_band_2g = 459 WLAN_REG_IS_24GHZ_CH_FREQ(pesession->curr_op_freq); 460 461 lim_ieee80211_pack_ehtcap(eht_cap_ie, pr->eht_cap, pr->he_cap, 462 is_band_2g); 463 eht_cap_ie_len = eht_cap_ie[1] + 2; 464 465 /* Copy the EHT IE to the end of the frame */ 466 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + 467 ie_buf_size, 468 eht_cap_ie, eht_cap_ie_len); 469 qdf_mem_free(eht_cap_ie); 470 payload = ie_buf_size + eht_cap_ie_len; 471 } 472 skip_eht_ie_update: 473 qdf_mem_free(pr); 474 475 /* Append any AddIE if present. */ 476 if (addn_ielen) { 477 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 478 additional_ie, addn_ielen); 479 payload += addn_ielen; 480 } 481 482 if (mlo_ie_len) { 483 qdf_status = lim_fill_complete_mlo_ie(pesession, mlo_ie_len, 484 frame + sizeof(tSirMacMgmtHdr) + payload); 485 if (QDF_IS_STATUS_ERROR(qdf_status)) { 486 pe_debug("assemble ml ie error, status %d", qdf_status); 487 mlo_ie_len = 0; 488 } 489 490 payload += mlo_ie_len; 491 } 492 493 pe_nofl_debug("Probe req TX: vdev %d seq num %d to " QDF_MAC_ADDR_FMT " len %d", 494 vdev_id, mac_ctx->mgmtSeqNum, 495 QDF_MAC_ADDR_REF(bssid), 496 (int)sizeof(tSirMacMgmtHdr) + payload); 497 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, frame, 498 sizeof(tSirMacMgmtHdr) + payload); 499 500 /* If this probe request is sent during P2P Search State, then we need 501 * to send it at OFDM rate. 502 */ 503 if ((REG_BAND_5G == lim_get_rf_band(chan_freq)) || 504 /* 505 * For unicast probe req mgmt from Join function we don't set 506 * above variables. So we need to add one more check whether it 507 * is opmode is P2P_CLIENT or not 508 */ 509 ((pesession) && (QDF_P2P_CLIENT_MODE == pesession->opmode))) 510 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 511 512 qdf_status = 513 wma_tx_frame(mac_ctx, packet, 514 (uint16_t) sizeof(tSirMacMgmtHdr) + payload, 515 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 516 lim_tx_complete, frame, txflag, vdev_id, 517 0, RATEID_DEFAULT, 0); 518 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 519 pe_err("could not send Probe Request frame!"); 520 /* Pkt will be freed up by the callback */ 521 return QDF_STATUS_E_FAILURE; 522 } 523 524 return QDF_STATUS_SUCCESS; 525 } /* End lim_send_probe_req_mgmt_frame. */ 526 527 static QDF_STATUS lim_get_addn_ie_for_probe_resp(struct mac_context *mac, 528 uint8_t *addIE, uint16_t *addnIELen, 529 uint8_t probeReqP2pIe) 530 { 531 /* If Probe request doesn't have P2P IE, then take out P2P IE 532 from additional IE */ 533 if (!probeReqP2pIe) { 534 uint8_t *tempbuf = NULL; 535 uint16_t tempLen = 0; 536 int left = *addnIELen; 537 uint8_t *ptr = addIE; 538 uint8_t elem_id, elem_len; 539 540 if (!addIE) { 541 pe_err("NULL addIE pointer"); 542 return QDF_STATUS_E_FAILURE; 543 } 544 545 tempbuf = qdf_mem_malloc(left); 546 if (!tempbuf) 547 return QDF_STATUS_E_NOMEM; 548 549 while (left >= 2) { 550 elem_id = ptr[0]; 551 elem_len = ptr[1]; 552 left -= 2; 553 if (elem_len > left) { 554 pe_err("Invalid IEs eid: %d elem_len: %d left: %d", 555 elem_id, elem_len, left); 556 qdf_mem_free(tempbuf); 557 return QDF_STATUS_E_FAILURE; 558 } 559 if (!((WLAN_ELEMID_VENDOR == elem_id) && 560 (memcmp 561 (&ptr[2], SIR_MAC_P2P_OUI, 562 SIR_MAC_P2P_OUI_SIZE) == 0))) { 563 qdf_mem_copy(tempbuf + tempLen, &ptr[0], 564 elem_len + 2); 565 tempLen += (elem_len + 2); 566 } 567 left -= elem_len; 568 ptr += (elem_len + 2); 569 } 570 qdf_mem_copy(addIE, tempbuf, tempLen); 571 *addnIELen = tempLen; 572 qdf_mem_free(tempbuf); 573 } 574 return QDF_STATUS_SUCCESS; 575 } 576 577 /** 578 * lim_add_additional_ie() - Add additional IE to management frame 579 * @frame: pointer to frame 580 * @frame_offset: current offset of frame 581 * @add_ie: pointer to additional ie 582 * @add_ie_len: length of additional ie 583 * @p2p_ie: pointer to p2p ie 584 * @noa_ie: pointer to noa ie, this is separate p2p ie 585 * @noa_ie_len: length of noa ie 586 * @noa_stream: pointer to noa stream, this is noa attribute only 587 * @noa_stream_len: length of noa stream 588 * 589 * This function adds additional IE to management frame. 590 * 591 * Return: None 592 */ 593 static void lim_add_additional_ie(uint8_t *frame, uint32_t frame_offset, 594 uint8_t *add_ie, uint32_t add_ie_len, 595 uint8_t *p2p_ie, uint8_t *noa_ie, 596 uint32_t noa_ie_len, uint8_t *noa_stream, 597 uint32_t noa_stream_len) { 598 uint16_t p2p_ie_offset; 599 600 if (!add_ie_len || !add_ie) { 601 pe_debug("no valid additional ie"); 602 return; 603 } 604 605 if (!noa_stream_len) { 606 qdf_mem_copy(frame + frame_offset, &add_ie[0], add_ie_len); 607 return; 608 } 609 610 if (noa_ie_len > (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) { 611 pe_err("Not able to insert NoA, len=%d", noa_ie_len); 612 return; 613 } else if (noa_ie_len > 0) { 614 pe_debug("new p2p ie for noa attr"); 615 qdf_mem_copy(frame + frame_offset, &add_ie[0], add_ie_len); 616 frame_offset += add_ie_len; 617 qdf_mem_copy(frame + frame_offset, &noa_ie[0], noa_ie_len); 618 } else { 619 if (!p2p_ie || (p2p_ie < add_ie) || 620 (p2p_ie > (add_ie + add_ie_len))) { 621 pe_err("invalid p2p ie"); 622 return; 623 } 624 p2p_ie_offset = p2p_ie - add_ie + p2p_ie[1] + 2; 625 if (p2p_ie_offset > add_ie_len) { 626 pe_err("Invalid p2p ie"); 627 return; 628 } 629 pe_debug("insert noa attr to existed p2p ie"); 630 p2p_ie[1] = p2p_ie[1] + noa_stream_len; 631 qdf_mem_copy(frame + frame_offset, &add_ie[0], p2p_ie_offset); 632 frame_offset += p2p_ie_offset; 633 qdf_mem_copy(frame + frame_offset, &noa_stream[0], 634 noa_stream_len); 635 if (p2p_ie_offset < add_ie_len) { 636 frame_offset += noa_stream_len; 637 qdf_mem_copy(frame + frame_offset, 638 &add_ie[p2p_ie_offset], 639 add_ie_len - p2p_ie_offset); 640 } 641 } 642 } 643 644 void 645 lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, 646 tSirMacAddr peer_macaddr, 647 tpAniSSID ssid, 648 struct pe_session *pe_session, 649 uint8_t preq_p2pie) 650 { 651 tDot11fProbeResponse *frm; 652 QDF_STATUS sir_status; 653 uint32_t cfg, payload, bytes = 0, status; 654 tpSirMacMgmtHdr mac_hdr; 655 uint8_t *frame; 656 void *packet = NULL; 657 QDF_STATUS qdf_status; 658 uint32_t addn_ie_present = false; 659 660 uint16_t addn_ie_len = 0; 661 bool wps_ap = 0; 662 uint8_t tx_flag = 0; 663 uint8_t *add_ie = NULL; 664 uint8_t *p2p_ie = NULL; 665 uint8_t noalen = 0; 666 uint8_t total_noalen = 0; 667 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; 668 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; 669 uint8_t vdev_id = 0; 670 bool is_vht_enabled = false; 671 tDot11fIEExtCap extracted_ext_cap = {0}; 672 bool extracted_ext_cap_flag = false; 673 uint16_t mlo_ie_len = 0; 674 675 /* We don't answer requests in this case*/ 676 if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG) 677 return; 678 679 if (!pe_session) 680 return; 681 682 /* 683 * In case when cac timer is running for this SAP session then 684 * avoid sending probe rsp out. It is violation of dfs specification. 685 */ 686 if (((pe_session->opmode == QDF_SAP_MODE) || 687 (pe_session->opmode == QDF_P2P_GO_MODE)) && 688 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) { 689 pe_info("CAC timer is running, probe response dropped"); 690 return; 691 } 692 if (wlan_vdev_is_up(pe_session->vdev) != QDF_STATUS_SUCCESS) 693 return; 694 695 vdev_id = pe_session->vdev_id; 696 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse)); 697 if (!frm) 698 return; 699 /* 700 * Fill out 'frm', after which we'll just hand the struct off to 701 * 'dot11f_pack_probe_response'. 702 */ 703 qdf_mem_zero((uint8_t *) frm, sizeof(tDot11fProbeResponse)); 704 705 /* 706 * Timestamp to be updated by TFP, below. 707 * 708 * Beacon Interval: 709 */ 710 if (LIM_IS_AP_ROLE(pe_session)) { 711 frm->BeaconInterval.interval = 712 mac_ctx->sch.beacon_interval; 713 } else { 714 cfg = mac_ctx->mlme_cfg->sap_cfg.beacon_interval; 715 frm->BeaconInterval.interval = (uint16_t) cfg; 716 } 717 718 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session); 719 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID); 720 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL, 721 &frm->SuppRates, pe_session); 722 populate_dot11f_tpc_report(mac_ctx, &frm->TPCReport, pe_session); 723 724 populate_dot11f_ds_params( 725 mac_ctx, &frm->DSParams, 726 pe_session->curr_op_freq); 727 728 if (LIM_IS_AP_ROLE(pe_session)) { 729 if (pe_session->wps_state != SAP_WPS_DISABLED) 730 populate_dot11f_probe_res_wpsi_es(mac_ctx, 731 &frm->WscProbeRes, 732 pe_session); 733 } else { 734 wps_ap = mac_ctx->mlme_cfg->wps_params.enable_wps & 735 WNI_CFG_WPS_ENABLE_AP; 736 if (wps_ap) 737 populate_dot11f_wsc_in_probe_res(mac_ctx, 738 &frm->WscProbeRes); 739 740 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState == 741 eLIM_WSC_ENROLL_BEGIN) { 742 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx, 743 &frm->WscProbeRes); 744 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState = 745 eLIM_WSC_ENROLL_IN_PROGRESS; 746 } 747 748 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState == 749 eLIM_WSC_ENROLL_END) { 750 de_populate_dot11f_wsc_registrar_info_in_probe_res( 751 mac_ctx, &frm->WscProbeRes); 752 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState = 753 eLIM_WSC_ENROLL_NOOP; 754 } 755 } 756 757 populate_dot11f_country(mac_ctx, &frm->Country, pe_session); 758 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session); 759 760 if (pe_session->dot11mode != MLME_DOT11_MODE_11B) 761 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session); 762 763 populate_dot11f_ext_supp_rates(mac_ctx, 764 POPULATE_DOT11F_RATES_OPERATIONAL, 765 &frm->ExtSuppRates, pe_session); 766 767 /* Populate HT IEs, when operating in 11n */ 768 if (pe_session->htCapability) { 769 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps); 770 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session); 771 } 772 if (pe_session->vhtCapability) { 773 pe_debug("Populate VHT IE in Probe Response"); 774 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps); 775 populate_dot11f_vht_operation(mac_ctx, pe_session, 776 &frm->VHTOperation); 777 populate_dot11f_tx_power_env(mac_ctx, 778 &frm->transmit_power_env[0], 779 pe_session->ch_width, 780 pe_session->curr_op_freq, 781 &frm->num_transmit_power_env, false); 782 /* 783 * we do not support multi users yet. 784 * populate_dot11f_vht_ext_bss_load( mac_ctx, 785 * &frm.VHTExtBssLoad ); 786 */ 787 is_vht_enabled = true; 788 } 789 790 if (wlan_reg_is_6ghz_chan_freq(pe_session->curr_op_freq)) { 791 populate_dot11f_tx_power_env(mac_ctx, 792 &frm->transmit_power_env[0], 793 pe_session->ch_width, 794 pe_session->curr_op_freq, 795 &frm->num_transmit_power_env, 796 false); 797 } 798 799 if (lim_is_session_he_capable(pe_session)) { 800 pe_debug("Populate HE IEs"); 801 populate_dot11f_he_caps(mac_ctx, pe_session, 802 &frm->he_cap); 803 populate_dot11f_he_operation(mac_ctx, pe_session, 804 &frm->he_op); 805 populate_dot11f_sr_info(mac_ctx, pe_session, 806 &frm->spatial_reuse); 807 populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, 808 &frm->he_6ghz_band_cap); 809 } 810 811 if (wlan_vdev_mlme_is_mlo_ap(pe_session->vdev)) { 812 mlo_ie_len = lim_send_bcn_frame_mlo(mac_ctx, pe_session); 813 populate_dot11f_mlo_rnr(mac_ctx, pe_session, 814 &frm->reduced_neighbor_report); 815 } 816 if (lim_is_session_eht_capable(pe_session)) { 817 pe_debug("Populate EHT IEs"); 818 populate_dot11f_eht_caps(mac_ctx, pe_session, &frm->eht_cap); 819 populate_dot11f_eht_operation(mac_ctx, pe_session, 820 &frm->eht_op); 821 } 822 823 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap, 824 pe_session); 825 826 if (pe_session->pLimStartBssReq) { 827 populate_dot11f_wpa(mac_ctx, 828 &(pe_session->pLimStartBssReq->rsnIE), 829 &frm->WPA); 830 populate_dot11f_rsn_opaque(mac_ctx, 831 &(pe_session->pLimStartBssReq->rsnIE), 832 &frm->RSNOpaque); 833 } 834 835 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams, 836 &frm->WMMCaps, pe_session); 837 838 #if defined(FEATURE_WLAN_WAPI) 839 if (pe_session->pLimStartBssReq) 840 populate_dot11f_wapi(mac_ctx, 841 &(pe_session->pLimStartBssReq->rsnIE), 842 &frm->WAPI); 843 #endif /* defined(FEATURE_WLAN_WAPI) */ 844 845 /* 846 * Only use CFG for non-listen mode. This CFG is not working for 847 * concurrency. In listening mode, probe rsp IEs is passed in 848 * the message from SME to PE. 849 */ 850 addn_ie_present = 851 (pe_session->add_ie_params.probeRespDataLen != 0); 852 853 if (addn_ie_present) { 854 855 add_ie = qdf_mem_malloc( 856 pe_session->add_ie_params.probeRespDataLen); 857 if (!add_ie) 858 goto err_ret; 859 860 qdf_mem_copy(add_ie, 861 pe_session->add_ie_params.probeRespData_buff, 862 pe_session->add_ie_params.probeRespDataLen); 863 addn_ie_len = pe_session->add_ie_params.probeRespDataLen; 864 865 if (QDF_STATUS_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx, 866 add_ie, &addn_ie_len, preq_p2pie)) { 867 pe_err("Unable to get addn_ie"); 868 goto err_ret; 869 } 870 871 sir_status = lim_strip_extcap_update_struct(mac_ctx, 872 add_ie, &addn_ie_len, 873 &extracted_ext_cap); 874 if (QDF_STATUS_SUCCESS != sir_status) { 875 pe_debug("Unable to strip off ExtCap IE"); 876 } else { 877 extracted_ext_cap_flag = true; 878 } 879 880 bytes = bytes + addn_ie_len; 881 882 if (preq_p2pie) 883 p2p_ie = (uint8_t *)limGetP2pIEPtr(mac_ctx, &add_ie[0], 884 addn_ie_len); 885 886 if (p2p_ie) { 887 /* get NoA attribute stream P2P IE */ 888 noalen = lim_get_noa_attr_stream(mac_ctx, 889 noa_stream, pe_session); 890 if (noalen) { 891 if ((p2p_ie[1] + noalen) > 892 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) { 893 total_noalen = lim_build_p2p_ie( 894 mac_ctx, 895 &noa_ie[0], 896 &noa_stream[0], 897 noalen); 898 bytes = bytes + total_noalen; 899 } else { 900 bytes = bytes + noalen; 901 } 902 } 903 } 904 } 905 906 /* 907 * Extcap IE now support variable length, merge Extcap IE from addn_ie 908 * may change the frame size. Therefore, MUST merge ExtCap IE before 909 * dot11f get packed payload size. 910 */ 911 if (extracted_ext_cap_flag) 912 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap, 913 true); 914 populate_dot11f_bcn_prot_extcaps(mac_ctx, pe_session, &frm->ExtCap); 915 916 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload); 917 if (DOT11F_FAILED(status)) { 918 pe_err("Probe Response size error (0x%08x)", 919 status); 920 /* We'll fall back on the worst case scenario: */ 921 payload = sizeof(tDot11fProbeResponse); 922 } else if (DOT11F_WARNED(status)) { 923 pe_warn("Probe Response size warning (0x%08x)", 924 status); 925 } 926 927 bytes += payload + sizeof(tSirMacMgmtHdr) + mlo_ie_len; 928 929 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame, 930 (void **)&packet); 931 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 932 pe_err("Probe Response allocation failed"); 933 goto err_ret; 934 } 935 /* Paranoia: */ 936 qdf_mem_zero(frame, bytes); 937 938 /* Next, we fill out the buffer descriptor: */ 939 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 940 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr, 941 pe_session->self_mac_addr); 942 943 mac_hdr = (tpSirMacMgmtHdr) frame; 944 945 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId); 946 947 /* That done, pack the Probe Response: */ 948 status = 949 dot11f_pack_probe_response(mac_ctx, frm, 950 frame + sizeof(tSirMacMgmtHdr), 951 payload, &payload); 952 if (DOT11F_FAILED(status)) { 953 pe_err("Probe Response pack failure (0x%08x)", 954 status); 955 goto err_ret; 956 } else if (DOT11F_WARNED(status)) { 957 pe_warn("Probe Response pack warning (0x%08x)", status); 958 } 959 960 if (mlo_ie_len) { 961 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 962 frame + sizeof(tSirMacMgmtHdr) + payload); 963 if (QDF_IS_STATUS_ERROR(qdf_status)) { 964 pe_debug("assemble ml ie error"); 965 mlo_ie_len = 0; 966 } 967 payload += mlo_ie_len; 968 } 969 970 pe_debug("Sending Probe Response frame to: "QDF_MAC_ADDR_FMT, 971 QDF_MAC_ADDR_REF(peer_macaddr)); 972 973 lim_add_additional_ie(frame, sizeof(tSirMacMgmtHdr) + payload, add_ie, 974 addn_ie_len, p2p_ie, noa_ie, total_noalen, 975 noa_stream, noalen); 976 977 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 978 pe_session->opmode == QDF_P2P_CLIENT_MODE || 979 pe_session->opmode == QDF_P2P_GO_MODE) 980 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 981 982 /* Queue Probe Response frame in high priority WQ */ 983 qdf_status = wma_tx_frame(mac_ctx, packet, 984 (uint16_t)bytes, 985 TXRX_FRM_802_11_MGMT, 986 ANI_TXDIR_TODS, 987 7, lim_tx_complete, frame, tx_flag, 988 vdev_id, 0, RATEID_DEFAULT, 0); 989 990 /* Pkt will be freed up by the callback */ 991 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 992 pe_err("Could not send Probe Response"); 993 994 if (add_ie) 995 qdf_mem_free(add_ie); 996 997 qdf_mem_free(frm); 998 return; 999 1000 err_ret: 1001 if (add_ie) 1002 qdf_mem_free(add_ie); 1003 if (frm) 1004 qdf_mem_free(frm); 1005 if (packet) 1006 cds_packet_free((void *)packet); 1007 return; 1008 1009 } /* End lim_send_probe_rsp_mgmt_frame. */ 1010 1011 void 1012 lim_send_addts_req_action_frame(struct mac_context *mac, 1013 tSirMacAddr peerMacAddr, 1014 tSirAddtsReqInfo *pAddTS, struct pe_session *pe_session) 1015 { 1016 uint16_t i; 1017 uint8_t *pFrame; 1018 tDot11fAddTSRequest AddTSReq; 1019 tDot11fWMMAddTSRequest WMMAddTSReq; 1020 uint32_t nPayload, nBytes, nStatus; 1021 tpSirMacMgmtHdr pMacHdr; 1022 void *pPacket; 1023 #ifdef FEATURE_WLAN_ESE 1024 uint32_t phyMode; 1025 #endif 1026 QDF_STATUS qdf_status; 1027 uint8_t txFlag = 0; 1028 uint8_t smeSessionId = 0; 1029 1030 if (!pe_session) { 1031 return; 1032 } 1033 1034 smeSessionId = pe_session->smeSessionId; 1035 1036 if (!pAddTS->wmeTspecPresent) { 1037 qdf_mem_zero((uint8_t *) &AddTSReq, sizeof(AddTSReq)); 1038 1039 AddTSReq.Action.action = QOS_ADD_TS_REQ; 1040 AddTSReq.DialogToken.token = pAddTS->dialogToken; 1041 AddTSReq.Category.category = ACTION_CATEGORY_QOS; 1042 if (pAddTS->lleTspecPresent) { 1043 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC); 1044 } else { 1045 populate_dot11f_wmmtspec(&pAddTS->tspec, 1046 &AddTSReq.WMMTSPEC); 1047 } 1048 1049 if (pAddTS->lleTspecPresent) { 1050 AddTSReq.num_WMMTCLAS = 0; 1051 AddTSReq.num_TCLAS = pAddTS->numTclas; 1052 for (i = 0; i < pAddTS->numTclas; ++i) { 1053 populate_dot11f_tclas(mac, &pAddTS->tclasInfo[i], 1054 &AddTSReq.TCLAS[i]); 1055 } 1056 } else { 1057 AddTSReq.num_TCLAS = 0; 1058 AddTSReq.num_WMMTCLAS = pAddTS->numTclas; 1059 for (i = 0; i < pAddTS->numTclas; ++i) { 1060 populate_dot11f_wmmtclas(mac, 1061 &pAddTS->tclasInfo[i], 1062 &AddTSReq.WMMTCLAS[i]); 1063 } 1064 } 1065 1066 if (pAddTS->tclasProcPresent) { 1067 if (pAddTS->lleTspecPresent) { 1068 AddTSReq.TCLASSPROC.processing = 1069 pAddTS->tclasProc; 1070 AddTSReq.TCLASSPROC.present = 1; 1071 } else { 1072 AddTSReq.WMMTCLASPROC.version = 1; 1073 AddTSReq.WMMTCLASPROC.processing = 1074 pAddTS->tclasProc; 1075 AddTSReq.WMMTCLASPROC.present = 1; 1076 } 1077 } 1078 1079 nStatus = 1080 dot11f_get_packed_add_ts_request_size(mac, &AddTSReq, &nPayload); 1081 if (DOT11F_FAILED(nStatus)) { 1082 pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)", 1083 nStatus); 1084 /* We'll fall back on the worst case scenario: */ 1085 nPayload = sizeof(tDot11fAddTSRequest); 1086 } else if (DOT11F_WARNED(nStatus)) { 1087 pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)", 1088 nStatus); 1089 } 1090 } else { 1091 qdf_mem_zero((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq)); 1092 1093 WMMAddTSReq.Action.action = QOS_ADD_TS_REQ; 1094 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken; 1095 WMMAddTSReq.Category.category = ACTION_CATEGORY_WMM; 1096 1097 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */ 1098 WMMAddTSReq.StatusCode.statusCode = 0; 1099 1100 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC); 1101 #ifdef FEATURE_WLAN_ESE 1102 lim_get_phy_mode(mac, &phyMode, pe_session); 1103 1104 if (phyMode == WNI_CFG_PHY_MODE_11G 1105 || phyMode == WNI_CFG_PHY_MODE_11A) { 1106 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS; 1107 } else { 1108 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS; 1109 } 1110 populate_dot11_tsrsie(mac, &pAddTS->tsrsIE, 1111 &WMMAddTSReq.ESETrafStrmRateSet, 1112 sizeof(uint8_t)); 1113 #endif 1114 /* fillWmeTspecIE */ 1115 1116 nStatus = 1117 dot11f_get_packed_wmm_add_ts_request_size(mac, &WMMAddTSReq, 1118 &nPayload); 1119 if (DOT11F_FAILED(nStatus)) { 1120 pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)", 1121 nStatus); 1122 /* We'll fall back on the worst case scenario: */ 1123 nPayload = sizeof(tDot11fAddTSRequest); 1124 } else if (DOT11F_WARNED(nStatus)) { 1125 pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)", 1126 nStatus); 1127 } 1128 } 1129 1130 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 1131 1132 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 1133 (void **)&pPacket); 1134 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1135 pe_err("Failed to allocate %d bytes for an Add TS Request", 1136 nBytes); 1137 return; 1138 } 1139 /* Paranoia: */ 1140 qdf_mem_zero(pFrame, nBytes); 1141 1142 /* Next, we fill out the buffer descriptor: */ 1143 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 1144 SIR_MAC_MGMT_ACTION, peerMacAddr, pe_session->self_mac_addr); 1145 pMacHdr = (tpSirMacMgmtHdr) pFrame; 1146 1147 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 1148 1149 lim_set_protected_bit(mac, pe_session, peerMacAddr, pMacHdr); 1150 1151 /* That done, pack the struct: */ 1152 if (!pAddTS->wmeTspecPresent) { 1153 nStatus = dot11f_pack_add_ts_request(mac, &AddTSReq, 1154 pFrame + 1155 sizeof(tSirMacMgmtHdr), 1156 nPayload, &nPayload); 1157 if (DOT11F_FAILED(nStatus)) { 1158 pe_err("Failed to pack an Add TS Request " 1159 "(0x%08x)", nStatus); 1160 cds_packet_free((void *)pPacket); 1161 return; /* allocated! */ 1162 } else if (DOT11F_WARNED(nStatus)) { 1163 pe_warn("There were warnings while packing an Add TS Request (0x%08x)", 1164 nStatus); 1165 } 1166 } else { 1167 nStatus = dot11f_pack_wmm_add_ts_request(mac, &WMMAddTSReq, 1168 pFrame + 1169 sizeof(tSirMacMgmtHdr), 1170 nPayload, &nPayload); 1171 if (DOT11F_FAILED(nStatus)) { 1172 pe_err("Failed to pack a WMM Add TS Request (0x%08x)", 1173 nStatus); 1174 cds_packet_free((void *)pPacket); 1175 return; /* allocated! */ 1176 } else if (DOT11F_WARNED(nStatus)) { 1177 pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)", 1178 nStatus); 1179 } 1180 } 1181 1182 pe_debug("Sending an Add TS Request frame to "QDF_MAC_ADDR_FMT, 1183 QDF_MAC_ADDR_REF(peerMacAddr)); 1184 1185 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 1186 pe_session->opmode == QDF_P2P_CLIENT_MODE || 1187 pe_session->opmode == QDF_P2P_GO_MODE) 1188 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 1189 1190 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 1191 pe_session->peSessionId, pMacHdr->fc.subType)); 1192 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 1193 pe_session, QDF_STATUS_SUCCESS, 1194 QDF_STATUS_SUCCESS); 1195 1196 /* Queue Addts Response frame in high priority WQ */ 1197 qdf_status = wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 1198 TXRX_FRM_802_11_MGMT, 1199 ANI_TXDIR_TODS, 1200 7, lim_tx_complete, pFrame, txFlag, 1201 smeSessionId, 0, RATEID_DEFAULT, 0); 1202 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 1203 pe_session->peSessionId, qdf_status)); 1204 1205 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1206 pe_err("Could not send an Add TS Request (%X", 1207 qdf_status); 1208 } /* End lim_send_addts_req_action_frame. */ 1209 1210 #ifdef WLAN_FEATURE_MSCS 1211 /** 1212 * lim_mscs_req_tx_complete_cnf()- Confirmation for mscs req sent over the air 1213 * @context: pointer to global mac 1214 * @buf: buffer 1215 * @tx_complete : Sent status 1216 * @params; tx completion params 1217 * 1218 * Return: This returns QDF_STATUS 1219 */ 1220 1221 static QDF_STATUS lim_mscs_req_tx_complete_cnf(void *context, qdf_nbuf_t buf, 1222 uint32_t tx_complete, 1223 void *params) 1224 { 1225 uint16_t mscs_ack_status; 1226 uint16_t reason_code; 1227 1228 pe_debug("mscs req TX: %s (%d)", 1229 (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? 1230 "success" : "fail", tx_complete); 1231 1232 if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { 1233 mscs_ack_status = ACKED; 1234 reason_code = QDF_STATUS_SUCCESS; 1235 } else { 1236 mscs_ack_status = NOT_ACKED; 1237 reason_code = QDF_STATUS_E_FAILURE; 1238 } 1239 if (buf) 1240 qdf_nbuf_free(buf); 1241 1242 return QDF_STATUS_SUCCESS; 1243 } 1244 1245 void lim_send_mscs_req_action_frame(struct mac_context *mac, 1246 struct qdf_mac_addr peer_mac, 1247 struct mscs_req_info *mscs_req, 1248 struct pe_session *pe_session) 1249 { 1250 uint8_t *frame; 1251 tDot11fmscs_request_action_frame mscs_req_frame; 1252 uint32_t payload, bytes; 1253 tpSirMacMgmtHdr peer_mac_hdr; 1254 void *packet; 1255 QDF_STATUS qdf_status; 1256 tpSirMacMgmtHdr mac_hdr; 1257 1258 qdf_mem_zero(&mscs_req_frame, sizeof(mscs_req_frame)); 1259 1260 mscs_req_frame.Action.action = MCSC_REQ; 1261 mscs_req_frame.DialogToken.token = mscs_req->dialog_token; 1262 mscs_req_frame.Category.category = ACTION_CATEGORY_RVS; 1263 populate_dot11f_mscs_dec_element(mscs_req, &mscs_req_frame); 1264 bytes = dot11f_get_packed_mscs_request_action_frameSize(mac, 1265 &mscs_req_frame, &payload); 1266 if (DOT11F_FAILED(bytes)) { 1267 pe_err("Failed to calculate the packed size for an MSCS Request (0x%08x)", 1268 bytes); 1269 /* We'll fall back on the worst case scenario: */ 1270 payload = sizeof(tDot11fmscs_request_action_frame); 1271 } else if (DOT11F_WARNED(bytes)) { 1272 pe_warn("There were warnings while calculating the packed size for MSCS Request (0x%08x)", 1273 bytes); 1274 } 1275 1276 bytes = payload + sizeof(struct qdf_mac_addr); 1277 1278 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame, 1279 (void **)&packet); 1280 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1281 pe_err("Failed to allocate %d bytes for an mscs request", 1282 bytes); 1283 return; 1284 } 1285 /* Paranoia: */ 1286 qdf_mem_zero(frame, bytes); 1287 1288 lim_populate_mac_header(mac, frame, SIR_MAC_MGMT_FRAME, 1289 SIR_MAC_MGMT_ACTION, 1290 peer_mac.bytes, pe_session->self_mac_addr); 1291 peer_mac_hdr = (tpSirMacMgmtHdr) frame; 1292 1293 qdf_mem_copy(peer_mac.bytes, pe_session->bssId, QDF_MAC_ADDR_SIZE); 1294 1295 lim_set_protected_bit(mac, pe_session, peer_mac.bytes, peer_mac_hdr); 1296 1297 bytes = dot11f_pack_mscs_request_action_frame(mac, &mscs_req_frame, 1298 frame + 1299 sizeof(tSirMacMgmtHdr), 1300 payload, &payload); 1301 if (DOT11F_FAILED(bytes)) { 1302 pe_err("Failed to pack an mscs Request " "(0x%08x)", bytes); 1303 cds_packet_free((void *)packet); 1304 return; /* allocated! */ 1305 } else if (DOT11F_WARNED(bytes)) { 1306 pe_warn("There were warnings while packing an mscs Request (0x%08x)", 1307 bytes); 1308 } 1309 1310 mac_hdr = (tpSirMacMgmtHdr) frame; 1311 1312 pe_debug("mscs req TX: vdev id: %d to "QDF_MAC_ADDR_FMT" seq num[%d], frame subtype:%d ", 1313 mscs_req->vdev_id, QDF_MAC_ADDR_REF(peer_mac.bytes), 1314 mac->mgmtSeqNum, mac_hdr->fc.subType); 1315 1316 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, 1317 frame, 1318 (uint16_t)(sizeof(tSirMacMgmtHdr) + payload)); 1319 qdf_status = 1320 wma_tx_frameWithTxComplete(mac, packet, 1321 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload), 1322 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 1323 lim_tx_complete, frame, lim_mscs_req_tx_complete_cnf, 1324 HAL_USE_PEER_STA_REQUESTED_MASK, 1325 pe_session->vdev_id, false, 0, RATEID_DEFAULT, 0, 0); 1326 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 1327 mlme_set_is_mscs_req_sent(pe_session->vdev, true); 1328 } else { 1329 pe_err("Could not send an mscs Request (%X)", qdf_status); 1330 } 1331 1332 /* Pkt will be freed up by the callback */ 1333 } /* End lim_send_mscs_req_action_frame */ 1334 #endif 1335 1336 /** 1337 * lim_assoc_rsp_tx_complete() - Confirmation for assoc rsp OTA 1338 * @context: pointer to global mac 1339 * @buf: buffer which is nothing but entire assoc rsp frame 1340 * @tx_complete : Sent status 1341 * @params; tx completion params 1342 * 1343 * Return: This returns QDF_STATUS 1344 */ 1345 static QDF_STATUS lim_assoc_rsp_tx_complete( 1346 void *context, 1347 qdf_nbuf_t buf, 1348 uint32_t tx_complete, 1349 void *params) 1350 { 1351 struct mac_context *mac_ctx = (struct mac_context *)context; 1352 tSirMacMgmtHdr *mac_hdr; 1353 struct pe_session *session_entry; 1354 uint8_t session_id; 1355 tpLimMlmAssocInd lim_assoc_ind; 1356 tpDphHashNode sta_ds; 1357 uint16_t aid; 1358 uint8_t *data; 1359 struct assoc_ind *sme_assoc_ind; 1360 struct scheduler_msg msg; 1361 tpSirAssocReq assoc_req; 1362 1363 if (!buf) { 1364 pe_err("Assoc rsp frame buffer is NULL"); 1365 goto null_buf; 1366 } 1367 1368 data = qdf_nbuf_data(buf); 1369 1370 if (!data) { 1371 pe_err("Assoc rsp frame is NULL"); 1372 goto end; 1373 } 1374 1375 mac_hdr = (tSirMacMgmtHdr *)data; 1376 1377 session_entry = pe_find_session_by_bssid( 1378 mac_ctx, mac_hdr->sa, 1379 &session_id); 1380 if (!session_entry) { 1381 pe_err("session entry is NULL"); 1382 goto end; 1383 } 1384 1385 sta_ds = dph_lookup_hash_entry(mac_ctx, 1386 (uint8_t *)mac_hdr->da, &aid, 1387 &session_entry->dph.dphHashTable); 1388 if (!sta_ds) { 1389 pe_err("sta_ds is NULL"); 1390 goto end; 1391 } 1392 1393 /* Get a copy of the already parsed Assoc Request */ 1394 assoc_req = 1395 (tpSirAssocReq)session_entry->parsedAssocReq[sta_ds->assocId]; 1396 1397 if (!assoc_req) { 1398 pe_err("assoc req for assoc_id:%d is NULL", sta_ds->assocId); 1399 goto end; 1400 } 1401 1402 if (tx_complete != WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { 1403 lim_send_disassoc_mgmt_frame(mac_ctx, 1404 REASON_DISASSOC_DUE_TO_INACTIVITY, 1405 sta_ds->staAddr, 1406 session_entry, false); 1407 lim_trigger_sta_deletion(mac_ctx, sta_ds, session_entry); 1408 goto free_buffers; 1409 } 1410 1411 if (lim_is_mlo_conn(session_entry, sta_ds) && 1412 QDF_IS_STATUS_ERROR(lim_mlo_assoc_ind_upper_layer( 1413 mac_ctx, session_entry, 1414 &assoc_req->mlo_info))) { 1415 pe_err("partner link indicate upper layer error"); 1416 goto free_assoc_req; 1417 } 1418 lim_assoc_ind = qdf_mem_malloc(sizeof(tLimMlmAssocInd)); 1419 if (!lim_assoc_ind) 1420 goto free_assoc_req; 1421 1422 if (!lim_fill_lim_assoc_ind_params(lim_assoc_ind, mac_ctx, 1423 sta_ds, session_entry)) { 1424 pe_err("lim assoc ind fill error"); 1425 goto lim_assoc_ind; 1426 } 1427 1428 sme_assoc_ind = qdf_mem_malloc(sizeof(struct assoc_ind)); 1429 if (!sme_assoc_ind) 1430 goto lim_assoc_ind; 1431 1432 sme_assoc_ind->messageType = eWNI_SME_ASSOC_IND_UPPER_LAYER; 1433 lim_fill_sme_assoc_ind_params( 1434 mac_ctx, lim_assoc_ind, 1435 sme_assoc_ind, 1436 session_entry, true); 1437 1438 qdf_mem_zero(&msg, sizeof(struct scheduler_msg)); 1439 msg.type = eWNI_SME_ASSOC_IND_UPPER_LAYER; 1440 msg.bodyptr = sme_assoc_ind; 1441 msg.bodyval = 0; 1442 sme_assoc_ind->reassocReq = sta_ds->mlmStaContext.subType; 1443 sme_assoc_ind->timingMeasCap = sta_ds->timingMeasCap; 1444 MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId, msg.type)); 1445 lim_sys_process_mmh_msg_api(mac_ctx, &msg); 1446 1447 qdf_mem_free(lim_assoc_ind); 1448 1449 free_buffers: 1450 lim_free_assoc_req_frm_buf(assoc_req); 1451 qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]); 1452 session_entry->parsedAssocReq[sta_ds->assocId] = NULL; 1453 qdf_nbuf_free(buf); 1454 1455 return QDF_STATUS_SUCCESS; 1456 1457 lim_assoc_ind: 1458 qdf_mem_free(lim_assoc_ind); 1459 free_assoc_req: 1460 lim_free_assoc_req_frm_buf(assoc_req); 1461 qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]); 1462 session_entry->parsedAssocReq[sta_ds->assocId] = NULL; 1463 end: 1464 qdf_nbuf_free(buf); 1465 null_buf: 1466 return QDF_STATUS_E_FAILURE; 1467 } 1468 1469 #ifdef WLAN_FEATURE_11BE 1470 QDF_STATUS lim_strip_eht_cap_ie(struct mac_context *mac_ctx, 1471 uint8_t *frame_ies, 1472 uint16_t *ie_buf_size, 1473 uint8_t *eht_cap_ie) 1474 { 1475 return lim_strip_ie(mac_ctx, frame_ies, ie_buf_size, 1476 WLAN_ELEMID_EXTN_ELEM, ONE_BYTE, 1477 EHT_CAP_OUI_TYPE, EHT_CAP_OUI_SIZE, 1478 eht_cap_ie, WLAN_MAX_IE_LEN); 1479 } 1480 1481 QDF_STATUS lim_strip_eht_op_ie(struct mac_context *mac_ctx, 1482 uint8_t *frame_ies, 1483 uint16_t *ie_buf_size, 1484 uint8_t *eht_op_ie) 1485 { 1486 return lim_strip_ie(mac_ctx, frame_ies, ie_buf_size, 1487 WLAN_ELEMID_EXTN_ELEM, ONE_BYTE, 1488 EHT_OP_OUI_TYPE, EHT_OP_OUI_SIZE, 1489 eht_op_ie, WLAN_MAX_IE_LEN); 1490 } 1491 #endif 1492 1493 void 1494 lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx, 1495 uint16_t status_code, uint16_t aid, 1496 tSirMacAddr peer_addr, 1497 uint8_t subtype, tpDphHashNode sta, 1498 struct pe_session *pe_session, 1499 bool tx_complete) 1500 { 1501 static tDot11fAssocResponse frm; 1502 uint8_t *frame; 1503 tpSirMacMgmtHdr mac_hdr; 1504 QDF_STATUS sir_status; 1505 uint8_t lle_mode = 0, addts; 1506 tHalBitVal qos_mode, wme_mode; 1507 uint32_t payload, bytes = 0, status; 1508 void *packet; 1509 QDF_STATUS qdf_status; 1510 tUpdateBeaconParams beacon_params; 1511 uint8_t tx_flag = 0; 1512 uint32_t addn_ie_len = 0; 1513 uint8_t *add_ie; 1514 tpSirAssocReq assoc_req = NULL; 1515 uint8_t sme_session = 0; 1516 bool is_vht = false; 1517 uint16_t stripoff_len = 0; 1518 tDot11fIEExtCap extracted_ext_cap; 1519 bool extracted_flag = false; 1520 uint8_t retry_int; 1521 uint16_t max_retries; 1522 uint8_t *eht_op_ie = NULL, eht_op_ie_len = 0; 1523 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 1524 bool is_band_2g; 1525 uint16_t ie_buf_size; 1526 uint16_t mlo_ie_len = 0; 1527 struct element_info ie; 1528 1529 if (!pe_session) { 1530 pe_err("pe_session is NULL"); 1531 return; 1532 } 1533 if (sta && lim_is_mlo_conn(pe_session, sta) && 1534 !lim_is_mlo_recv_assoc(sta)) { 1535 pe_err("Do not send assoc rsp in mlo partner peer " 1536 QDF_MAC_ADDR_FMT, 1537 QDF_MAC_ADDR_REF(sta->staAddr)); 1538 return; 1539 } 1540 1541 sme_session = pe_session->smeSessionId; 1542 1543 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 1544 1545 limGetQosMode(pe_session, &qos_mode); 1546 limGetWmeMode(pe_session, &wme_mode); 1547 1548 /* 1549 * An Add TS IE is added only if the AP supports it and 1550 * the requesting STA sent a traffic spec. 1551 */ 1552 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0; 1553 1554 frm.Status.status = status_code; 1555 1556 frm.AID.associd = aid | LIM_AID_MASK; 1557 1558 if (!sta) { 1559 populate_dot11f_supp_rates(mac_ctx, 1560 POPULATE_DOT11F_RATES_OPERATIONAL, 1561 &frm.SuppRates, pe_session); 1562 populate_dot11f_ext_supp_rates(mac_ctx, 1563 POPULATE_DOT11F_RATES_OPERATIONAL, 1564 &frm.ExtSuppRates, pe_session); 1565 } else { 1566 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates, 1567 &frm.ExtSuppRates, 1568 sta->supportedRates.llbRates, 1569 sta->supportedRates.llaRates); 1570 } 1571 1572 if (LIM_IS_AP_ROLE(pe_session) && sta && 1573 QDF_STATUS_SUCCESS == status_code) { 1574 assoc_req = (tpSirAssocReq) 1575 pe_session->parsedAssocReq[sta->assocId]; 1576 /* 1577 * populate P2P IE in AssocRsp when assoc_req from the peer 1578 * includes P2P IE 1579 */ 1580 if (assoc_req && assoc_req->addIEPresent) 1581 populate_dot11_assoc_res_p2p_ie(mac_ctx, 1582 &frm.P2PAssocRes, 1583 assoc_req); 1584 } 1585 1586 if (sta) { 1587 if (eHAL_SET == qos_mode) { 1588 if (sta->lleEnabled) { 1589 lle_mode = 1; 1590 populate_dot11f_edca_param_set(mac_ctx, 1591 &frm.EDCAParamSet, pe_session); 1592 } 1593 } 1594 1595 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) { 1596 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams, 1597 pe_session); 1598 1599 if (sta->wsmEnabled) 1600 populate_dot11f_wmm_caps(&frm.WMMCaps); 1601 } 1602 1603 if (sta->mlmStaContext.htCapability && 1604 pe_session->htCapability) { 1605 populate_dot11f_ht_caps(mac_ctx, pe_session, 1606 &frm.HTCaps); 1607 /* 1608 * Check the STA capability and 1609 * update the HTCaps accordingly 1610 */ 1611 frm.HTCaps.supportedChannelWidthSet = ( 1612 sta->htSupportedChannelWidthSet < 1613 pe_session->htSupportedChannelWidthSet) ? 1614 sta->htSupportedChannelWidthSet : 1615 pe_session->htSupportedChannelWidthSet; 1616 if (!frm.HTCaps.supportedChannelWidthSet) 1617 frm.HTCaps.shortGI40MHz = 0; 1618 1619 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo, 1620 pe_session); 1621 } 1622 1623 if (sta->mlmStaContext.vhtCapability && 1624 pe_session->vhtCapability) { 1625 populate_dot11f_vht_caps(mac_ctx, pe_session, 1626 &frm.VHTCaps); 1627 populate_dot11f_vht_operation(mac_ctx, pe_session, 1628 &frm.VHTOperation); 1629 is_vht = true; 1630 } else if (sta->mlmStaContext.force_1x1 && 1631 frm.HTCaps.present) { 1632 /* 1633 * WAR: In P2P GO mode, if the P2P client device 1634 * is only HT capable and not VHT capable, but the P2P 1635 * GO device is VHT capable and advertises 2x2 NSS with 1636 * HT capability client device, which results in IOT 1637 * issues. 1638 * When GO is operating in DBS mode, GO beacons 1639 * advertise 2x2 capability but include OMN IE to 1640 * indicate current operating mode of 1x1. But here 1641 * peer device is only HT capable and will not 1642 * understand OMN IE. 1643 */ 1644 frm.HTInfo.basicMCSSet[1] = 0; 1645 frm.HTCaps.supportedMCSSet[1] = 0; 1646 } 1647 1648 if (pe_session->vhtCapability && 1649 pe_session->vendor_vht_sap && 1650 (assoc_req) && 1651 assoc_req->vendor_vht_ie.VHTCaps.present) { 1652 frm.vendor_vht_ie.present = 1; 1653 frm.vendor_vht_ie.sub_type = 1654 pe_session->vendor_specific_vht_ie_sub_type; 1655 frm.vendor_vht_ie.VHTCaps.present = 1; 1656 populate_dot11f_vht_caps(mac_ctx, pe_session, 1657 &frm.vendor_vht_ie.VHTCaps); 1658 populate_dot11f_vht_operation(mac_ctx, pe_session, 1659 &frm.vendor_vht_ie.VHTOperation); 1660 is_vht = true; 1661 } 1662 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap, 1663 pe_session); 1664 1665 populate_dot11f_qcn_ie(mac_ctx, pe_session, &frm.qcn_ie, 1666 QCN_IE_ATTR_ID_ALL); 1667 1668 if (lim_is_sta_he_capable(sta) && 1669 lim_is_session_he_capable(pe_session)) { 1670 populate_dot11f_he_caps(mac_ctx, pe_session, 1671 &frm.he_cap); 1672 populate_dot11f_sr_info(mac_ctx, pe_session, 1673 &frm.spatial_reuse); 1674 populate_dot11f_he_operation(mac_ctx, pe_session, 1675 &frm.he_op); 1676 populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, 1677 &frm.he_6ghz_band_cap); 1678 } 1679 1680 if (lim_is_sta_eht_capable(sta) && 1681 lim_is_session_eht_capable(pe_session)) { 1682 populate_dot11f_eht_caps(mac_ctx, pe_session, 1683 &frm.eht_cap); 1684 populate_dot11f_eht_operation(mac_ctx, pe_session, 1685 &frm.eht_op); 1686 } 1687 1688 if (status_code == STATUS_ASSOC_REJECTED_TEMPORARILY) { 1689 max_retries = 1690 mac_ctx->mlme_cfg->gen.pmf_sa_query_max_retries; 1691 retry_int = 1692 mac_ctx->mlme_cfg->gen.pmf_sa_query_retry_interval; 1693 populate_dot11f_timeout_interval(mac_ctx, 1694 &frm.TimeoutInterval, 1695 SIR_MAC_TI_TYPE_ASSOC_COMEBACK, 1696 (max_retries - 1697 sta->pmfSaQueryRetryCount) 1698 * retry_int); 1699 } 1700 1701 if (LIM_IS_AP_ROLE(pe_session) && sta->non_ecsa_capable) 1702 pe_session->lim_non_ecsa_cap_num++; 1703 } 1704 1705 qdf_mem_zero((uint8_t *) &beacon_params, sizeof(beacon_params)); 1706 1707 if (LIM_IS_AP_ROLE(pe_session) && 1708 (pe_session->gLimProtectionControl != 1709 MLME_FORCE_POLICY_PROTECTION_DISABLE)) 1710 lim_decide_ap_protection(mac_ctx, peer_addr, &beacon_params, 1711 pe_session); 1712 1713 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params, 1714 pe_session); 1715 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params, 1716 pe_session); 1717 1718 /* 1719 * Populate Do11capabilities after updating session with 1720 * Assos req details 1721 */ 1722 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session); 1723 1724 beacon_params.bss_idx = pe_session->vdev_id; 1725 1726 /* Send message to HAL about beacon parameter change. */ 1727 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) 1728 && beacon_params.paramChangeBitmap) { 1729 sch_set_fixed_beacon_fields(mac_ctx, pe_session); 1730 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session); 1731 } 1732 1733 lim_obss_send_detection_cfg(mac_ctx, pe_session, false); 1734 1735 add_ie = qdf_mem_malloc(WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN); 1736 if (!add_ie) { 1737 pe_err("memory alloc failed for add_ie"); 1738 return; 1739 } 1740 1741 if (assoc_req) { 1742 addn_ie_len = pe_session->add_ie_params.assocRespDataLen; 1743 1744 /* Nonzero length indicates Assoc rsp IE available */ 1745 if (addn_ie_len > 0 && 1746 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN && 1747 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) { 1748 qdf_mem_copy(add_ie, 1749 pe_session->add_ie_params.assocRespData_buff, 1750 pe_session->add_ie_params.assocRespDataLen); 1751 1752 qdf_mem_zero((uint8_t *) &extracted_ext_cap, 1753 sizeof(extracted_ext_cap)); 1754 1755 stripoff_len = addn_ie_len; 1756 sir_status = 1757 lim_strip_extcap_update_struct 1758 (mac_ctx, &add_ie[0], &stripoff_len, 1759 &extracted_ext_cap); 1760 if (QDF_STATUS_SUCCESS != sir_status) { 1761 pe_debug("strip off extcap IE failed"); 1762 } else { 1763 addn_ie_len = stripoff_len; 1764 extracted_flag = true; 1765 } 1766 bytes = bytes + addn_ie_len; 1767 } 1768 } 1769 1770 /* 1771 * Extcap IE now support variable length, merge Extcap IE from addn_ie 1772 * may change the frame size. Therefore, MUST merge ExtCap IE before 1773 * dot11f get packed payload size. 1774 */ 1775 if (extracted_flag) 1776 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap, 1777 true); 1778 populate_dot11f_bcn_prot_extcaps(mac_ctx, pe_session, &(frm.ExtCap)); 1779 if (sta && lim_is_sta_eht_capable(sta) && 1780 lim_is_mlo_conn(pe_session, sta) && 1781 lim_is_session_eht_capable(pe_session) && 1782 wlan_vdev_mlme_is_mlo_ap(pe_session->vdev) && 1783 (status_code != STATUS_ASSOC_REJECTED_TEMPORARILY)) { 1784 pe_debug("Populate mlo IEs"); 1785 mlo_ie_len = lim_send_assoc_rsp_mgmt_frame_mlo(mac_ctx, 1786 pe_session, 1787 sta, &frm); 1788 } 1789 1790 /* Allocate a buffer for this frame: */ 1791 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload); 1792 if (DOT11F_FAILED(status)) { 1793 pe_err("get Association Response size failure (0x%08x)", 1794 status); 1795 goto error; 1796 } else if (DOT11F_WARNED(status)) { 1797 pe_warn("get Association Response size warning (0x%08x)", 1798 status); 1799 } 1800 1801 bytes += sizeof(tSirMacMgmtHdr) + payload + mlo_ie_len; 1802 1803 if (sta) { 1804 bytes += sta->mlmStaContext.owe_ie_len; 1805 bytes += sta->mlmStaContext.ft_ie_len; 1806 } 1807 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame, 1808 (void **)&packet); 1809 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1810 pe_err("cds_packet_alloc failed"); 1811 goto error; 1812 } 1813 /* Paranoia: */ 1814 qdf_mem_zero(frame, bytes); 1815 1816 /* Next, we fill out the buffer descriptor: */ 1817 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 1818 (LIM_ASSOC == subtype) ? 1819 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP, 1820 peer_addr, 1821 pe_session->self_mac_addr); 1822 mac_hdr = (tpSirMacMgmtHdr) frame; 1823 1824 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId); 1825 1826 status = dot11f_pack_assoc_response(mac_ctx, &frm, 1827 frame + sizeof(tSirMacMgmtHdr), 1828 payload, &payload); 1829 if (DOT11F_FAILED(status)) { 1830 pe_err("Association Response pack failure(0x%08x)", 1831 status); 1832 cds_packet_free((void *)packet); 1833 goto error; 1834 } else if (DOT11F_WARNED(status)) { 1835 pe_warn("Association Response pack warning (0x%08x)", 1836 status); 1837 } 1838 1839 /* Strip EHT operation and EHT capabilities IEs */ 1840 if (lim_is_session_eht_capable(pe_session)) { 1841 ie_buf_size = payload - WLAN_ASSOC_RSP_IES_OFFSET; 1842 eht_op_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 1843 if (!eht_op_ie) { 1844 pe_err("malloc failed for eht_op_ie"); 1845 cds_packet_free((void *)packet); 1846 goto error; 1847 } 1848 1849 qdf_status = lim_strip_eht_op_ie(mac_ctx, frame + 1850 sizeof(tSirMacMgmtHdr) + 1851 WLAN_ASSOC_RSP_IES_OFFSET, 1852 &ie_buf_size, eht_op_ie); 1853 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1854 pe_err("Failed to strip EHT op IE"); 1855 qdf_mem_free(eht_cap_ie); 1856 cds_packet_free((void *)packet); 1857 cds_packet_free((void *)packet); 1858 } 1859 1860 lim_ieee80211_pack_ehtop(eht_op_ie, frm.eht_op, 1861 frm.VHTOperation, 1862 frm.he_op, 1863 frm.HTInfo); 1864 eht_op_ie_len = eht_op_ie[1] + 2; 1865 1866 /* Copy the EHT operation IE to the end of the frame */ 1867 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + 1868 WLAN_ASSOC_RSP_IES_OFFSET + ie_buf_size, 1869 eht_op_ie, eht_op_ie_len); 1870 qdf_mem_free(eht_op_ie); 1871 bytes = bytes - payload; 1872 payload = ie_buf_size + WLAN_ASSOC_RSP_IES_OFFSET + 1873 eht_op_ie_len; 1874 bytes = bytes + payload; 1875 1876 ie_buf_size = payload - WLAN_ASSOC_RSP_IES_OFFSET; 1877 eht_cap_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 1878 if (!eht_cap_ie) { 1879 pe_err("malloc failed for eht_cap_ie"); 1880 cds_packet_free((void *)packet); 1881 goto error; 1882 } 1883 1884 qdf_status = lim_strip_eht_cap_ie(mac_ctx, frame + 1885 sizeof(tSirMacMgmtHdr) + 1886 WLAN_ASSOC_RSP_IES_OFFSET, 1887 &ie_buf_size, eht_cap_ie); 1888 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1889 pe_err("Failed to strip EHT cap IE"); 1890 qdf_mem_free(eht_cap_ie); 1891 cds_packet_free((void *)packet); 1892 goto error; 1893 } 1894 1895 is_band_2g = 1896 WLAN_REG_IS_24GHZ_CH_FREQ(pe_session->curr_op_freq); 1897 lim_ieee80211_pack_ehtcap(eht_cap_ie, frm.eht_cap, frm.he_cap, 1898 is_band_2g); 1899 1900 eht_cap_ie_len = eht_cap_ie[1] + 2; 1901 1902 /* Copy the EHT capability IE to the end of the frame */ 1903 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + 1904 WLAN_ASSOC_RSP_IES_OFFSET + ie_buf_size, 1905 eht_cap_ie, eht_cap_ie_len); 1906 qdf_mem_free(eht_cap_ie); 1907 bytes = bytes - payload; 1908 payload = ie_buf_size + WLAN_ASSOC_RSP_IES_OFFSET + 1909 eht_cap_ie_len; 1910 bytes = bytes + payload; 1911 } 1912 1913 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN) { 1914 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 1915 &add_ie[0], addn_ie_len); 1916 payload += addn_ie_len; 1917 } 1918 1919 if (sta && sta->mlmStaContext.owe_ie_len) { 1920 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 1921 sta->mlmStaContext.owe_ie, 1922 sta->mlmStaContext.owe_ie_len); 1923 payload += sta->mlmStaContext.owe_ie_len; 1924 } 1925 1926 if (sta && sta->mlmStaContext.ft_ie_len) { 1927 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 1928 sta->mlmStaContext.ft_ie, 1929 sta->mlmStaContext.ft_ie_len); 1930 payload += sta->mlmStaContext.ft_ie_len; 1931 } 1932 1933 if (sta && mlo_ie_len) { 1934 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 1935 frame + sizeof(tSirMacMgmtHdr) + payload); 1936 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1937 pe_debug("assemble ml ie error"); 1938 mlo_ie_len = 0; 1939 } 1940 payload += mlo_ie_len; 1941 } 1942 1943 pe_nofl_debug("Assoc rsp TX: vdev %d subtype %d to "QDF_MAC_ADDR_FMT" seq num %d status %d aid %d addn_ie_len %d ht %d vht %d vendor vht %d he %d eht %d", 1944 pe_session->vdev_id, subtype, 1945 QDF_MAC_ADDR_REF(mac_hdr->da), 1946 mac_ctx->mgmtSeqNum, status_code, aid, addn_ie_len, 1947 frm.HTCaps.present, frm.VHTCaps.present, 1948 frm.vendor_vht_ie.present, frm.he_cap.present, 1949 frm.eht_cap.present); 1950 1951 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 1952 pe_session->opmode == QDF_P2P_CLIENT_MODE || 1953 pe_session->opmode == QDF_P2P_GO_MODE) 1954 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 1955 1956 ie.ptr = frame + sizeof(tSirMacMgmtHdr) + WLAN_ASSOC_RSP_IES_OFFSET; 1957 ie.len = payload - WLAN_ASSOC_RSP_IES_OFFSET; 1958 1959 mlme_set_peer_assoc_rsp_ie(mac_ctx->psoc, peer_addr, &ie); 1960 1961 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 1962 pe_session->peSessionId, mac_hdr->fc.subType)); 1963 lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr, 1964 pe_session, QDF_STATUS_SUCCESS, status_code); 1965 /* Queue Association Response frame in high priority WQ */ 1966 if (tx_complete) 1967 qdf_status = wma_tx_frameWithTxComplete( 1968 mac_ctx, packet, (uint16_t)bytes, 1969 TXRX_FRM_802_11_MGMT, 1970 ANI_TXDIR_TODS, 1971 7, lim_tx_complete, frame, 1972 lim_assoc_rsp_tx_complete, tx_flag, 1973 sme_session, false, 0, RATEID_DEFAULT, 0, 0); 1974 else 1975 qdf_status = wma_tx_frame( 1976 mac_ctx, packet, (uint16_t)bytes, 1977 TXRX_FRM_802_11_MGMT, 1978 ANI_TXDIR_TODS, 1979 7, lim_tx_complete, frame, tx_flag, 1980 sme_session, 0, RATEID_DEFAULT, 0); 1981 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 1982 pe_session->peSessionId, qdf_status)); 1983 1984 /* Pkt will be freed up by the callback */ 1985 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 1986 pe_err("Could not Send Re/AssocRsp, retCode=%X", 1987 qdf_status); 1988 1989 /* 1990 * update the ANI peer station count. 1991 * FIXME_PROTECTION : take care of different type of station 1992 * counter inside this function. 1993 */ 1994 lim_util_count_sta_add(mac_ctx, sta, pe_session); 1995 1996 error: 1997 qdf_mem_free(add_ie); 1998 } 1999 2000 void 2001 lim_send_delts_req_action_frame(struct mac_context *mac, 2002 tSirMacAddr peer, 2003 uint8_t wmmTspecPresent, 2004 struct mac_ts_info *pTsinfo, 2005 struct mac_tspec_ie *pTspecIe, 2006 struct pe_session *pe_session) 2007 { 2008 uint8_t *pFrame; 2009 tpSirMacMgmtHdr pMacHdr; 2010 tDot11fDelTS DelTS; 2011 tDot11fWMMDelTS WMMDelTS; 2012 uint32_t nBytes, nPayload, nStatus; 2013 void *pPacket; 2014 QDF_STATUS qdf_status; 2015 uint8_t txFlag = 0; 2016 uint8_t smeSessionId = 0; 2017 2018 if (!pe_session) 2019 return; 2020 2021 smeSessionId = pe_session->smeSessionId; 2022 2023 if (!wmmTspecPresent) { 2024 qdf_mem_zero((uint8_t *) &DelTS, sizeof(DelTS)); 2025 2026 DelTS.Category.category = ACTION_CATEGORY_QOS; 2027 DelTS.Action.action = QOS_DEL_TS_REQ; 2028 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo); 2029 2030 nStatus = dot11f_get_packed_del_ts_size(mac, &DelTS, &nPayload); 2031 if (DOT11F_FAILED(nStatus)) { 2032 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", 2033 nStatus); 2034 /* We'll fall back on the worst case scenario: */ 2035 nPayload = sizeof(tDot11fDelTS); 2036 } else if (DOT11F_WARNED(nStatus)) { 2037 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)", 2038 nStatus); 2039 } 2040 } else { 2041 qdf_mem_zero((uint8_t *) &WMMDelTS, sizeof(WMMDelTS)); 2042 2043 WMMDelTS.Category.category = ACTION_CATEGORY_WMM; 2044 WMMDelTS.Action.action = QOS_DEL_TS_REQ; 2045 WMMDelTS.DialogToken.token = 0; 2046 WMMDelTS.StatusCode.statusCode = 0; 2047 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC); 2048 nStatus = 2049 dot11f_get_packed_wmm_del_ts_size(mac, &WMMDelTS, &nPayload); 2050 if (DOT11F_FAILED(nStatus)) { 2051 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", 2052 nStatus); 2053 /* We'll fall back on the worst case scenario: */ 2054 nPayload = sizeof(tDot11fDelTS); 2055 } else if (DOT11F_WARNED(nStatus)) { 2056 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)", 2057 nStatus); 2058 } 2059 } 2060 2061 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 2062 2063 qdf_status = 2064 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 2065 (void **)&pPacket); 2066 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2067 pe_err("Failed to allocate %d bytes for an Add TS Response", 2068 nBytes); 2069 return; 2070 } 2071 /* Paranoia: */ 2072 qdf_mem_zero(pFrame, nBytes); 2073 2074 /* Next, we fill out the buffer descriptor: */ 2075 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 2076 SIR_MAC_MGMT_ACTION, peer, pe_session->self_mac_addr); 2077 pMacHdr = (tpSirMacMgmtHdr) pFrame; 2078 2079 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 2080 2081 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 2082 2083 /* That done, pack the struct: */ 2084 if (!wmmTspecPresent) { 2085 nStatus = dot11f_pack_del_ts(mac, &DelTS, 2086 pFrame + sizeof(tSirMacMgmtHdr), 2087 nPayload, &nPayload); 2088 if (DOT11F_FAILED(nStatus)) { 2089 pe_err("Failed to pack a Del TS frame (0x%08x)", 2090 nStatus); 2091 cds_packet_free((void *)pPacket); 2092 return; /* allocated! */ 2093 } else if (DOT11F_WARNED(nStatus)) { 2094 pe_warn("There were warnings while packing a Del TS frame (0x%08x)", 2095 nStatus); 2096 } 2097 } else { 2098 nStatus = dot11f_pack_wmm_del_ts(mac, &WMMDelTS, 2099 pFrame + sizeof(tSirMacMgmtHdr), 2100 nPayload, &nPayload); 2101 if (DOT11F_FAILED(nStatus)) { 2102 pe_err("Failed to pack a WMM Del TS frame (0x%08x)", 2103 nStatus); 2104 cds_packet_free((void *)pPacket); 2105 return; /* allocated! */ 2106 } else if (DOT11F_WARNED(nStatus)) { 2107 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)", 2108 nStatus); 2109 } 2110 } 2111 2112 pe_debug("Sending DELTS REQ (size %d) to "QDF_MAC_ADDR_FMT, nBytes, 2113 QDF_MAC_ADDR_REF(pMacHdr->da)); 2114 2115 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 2116 pe_session->opmode == QDF_P2P_CLIENT_MODE || 2117 pe_session->opmode == QDF_P2P_GO_MODE) 2118 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 2119 2120 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 2121 pe_session->peSessionId, pMacHdr->fc.subType)); 2122 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 2123 pe_session, QDF_STATUS_SUCCESS, 2124 QDF_STATUS_SUCCESS); 2125 qdf_status = wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 2126 TXRX_FRM_802_11_MGMT, 2127 ANI_TXDIR_TODS, 2128 7, lim_tx_complete, pFrame, txFlag, 2129 smeSessionId, 0, RATEID_DEFAULT, 0); 2130 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 2131 pe_session->peSessionId, qdf_status)); 2132 /* Pkt will be freed up by the callback */ 2133 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 2134 pe_err("Failed to send Del TS (%X)!", qdf_status); 2135 2136 } /* End lim_send_delts_req_action_frame. */ 2137 2138 #define SAE_AUTH_SEQ_NUM_OFFSET 2 2139 #define SAE_AUTH_STATUS_CODE_OFFSET 4 2140 #define SAE_AUTH_MESSAGE_TYPE_OFFSET 6 2141 #define SAE_FRAME_LENGTH \ 2142 (sizeof(struct wlan_frame_hdr) + SAE_AUTH_MESSAGE_TYPE_OFFSET) 2143 2144 /** 2145 * wlan_send_tx_complete_event() - Fill mgmt params 2146 * 2147 * @context: Pointer to mac context 2148 * @buf: skb buffer 2149 * @params: Pointer to wmi_mgmt_params 2150 * @tx_complete: Sent status 2151 * @tag: wlan main tag 2152 * 2153 * Function is used to send connectivity log event for mgmt ack status 2154 * 2155 * Return None 2156 */ 2157 2158 static void wlan_send_tx_complete_event(struct mac_context *mac, qdf_nbuf_t buf, 2159 struct wmi_mgmt_params *params, 2160 uint8_t tx_complete, 2161 enum wlan_main_tag tag) 2162 { 2163 struct pe_session *pe_session = NULL; 2164 struct wlan_frame_hdr *mac_hdr; 2165 enum qdf_dp_tx_rx_status qdf_tx_complete; 2166 uint8_t *frm_body; 2167 uint16_t reason_code = 0; 2168 2169 pe_session = pe_find_session_by_vdev_id(mac, params->vdev_id); 2170 if (pe_session && pe_session->opmode == QDF_STA_MODE) { 2171 if (qdf_nbuf_len(buf) < sizeof(struct wlan_frame_hdr) + 2) 2172 return; 2173 2174 mac_hdr = (struct wlan_frame_hdr *)qdf_nbuf_data(buf); 2175 frm_body = (uint8_t *)mac_hdr + sizeof(struct wlan_frame_hdr); 2176 2177 if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) 2178 qdf_tx_complete = QDF_TX_RX_STATUS_OK; 2179 else if (tx_complete == WMI_MGMT_TX_COMP_TYPE_DISCARD) 2180 qdf_tx_complete = QDF_TX_RX_STATUS_FW_DISCARD; 2181 else 2182 qdf_tx_complete = QDF_TX_RX_STATUS_NO_ACK; 2183 2184 if (tag == WLAN_AUTH_REQ) { 2185 uint16_t algo = 0, type = 0, seq = 0, status = 0; 2186 2187 if (qdf_nbuf_len(buf) < SAE_FRAME_LENGTH) 2188 return; 2189 2190 algo = *(uint16_t *)frm_body; 2191 seq = *(uint16_t *)(frm_body + SAE_AUTH_SEQ_NUM_OFFSET); 2192 status = 2193 *(uint16_t *)(frm_body + SAE_AUTH_STATUS_CODE_OFFSET); 2194 2195 if (algo == eSIR_AUTH_TYPE_SAE) 2196 type = seq; 2197 2198 wlan_connectivity_mgmt_event( 2199 mac->psoc, 2200 mac_hdr, params->vdev_id, status, 2201 qdf_tx_complete, mac->lim.bss_rssi, 2202 algo, type, seq, 0, WLAN_AUTH_REQ); 2203 return; 2204 } 2205 2206 if (tag == WLAN_DEAUTH_TX || tag == WLAN_DISASSOC_TX) 2207 reason_code = pe_session->deauth_disassoc_rc; 2208 2209 wlan_connectivity_mgmt_event( 2210 mac->psoc, 2211 mac_hdr, params->vdev_id, reason_code, 2212 qdf_tx_complete, mac->lim.bss_rssi, 2213 0, 0, 0, 0, tag); 2214 } 2215 } 2216 2217 /** 2218 * lim_assoc_tx_complete_cnf()- Confirmation for assoc sent over the air 2219 * @context: pointer to global mac 2220 * @buf: buffer 2221 * @tx_complete : Sent status 2222 * @params; tx completion params 2223 * 2224 * Return: This returns QDF_STATUS 2225 */ 2226 2227 static QDF_STATUS lim_assoc_tx_complete_cnf(void *context, 2228 qdf_nbuf_t buf, 2229 uint32_t tx_complete, 2230 void *params) 2231 { 2232 uint16_t assoc_ack_status; 2233 uint16_t reason_code; 2234 struct mac_context *mac_ctx = (struct mac_context *)context; 2235 2236 pe_nofl_rl_info("Assoc req TX: %s (%d)", 2237 (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? 2238 "success" : "fail", tx_complete); 2239 2240 if (params) 2241 wlan_send_tx_complete_event(context, buf, params, tx_complete, 2242 WLAN_ASSOC_REQ); 2243 2244 if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { 2245 assoc_ack_status = ACKED; 2246 reason_code = QDF_STATUS_SUCCESS; 2247 mac_ctx->assoc_ack_status = LIM_ACK_RCD_SUCCESS; 2248 } else if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK) { 2249 assoc_ack_status = NOT_ACKED; 2250 reason_code = QDF_STATUS_E_FAILURE; 2251 mac_ctx->assoc_ack_status = LIM_ACK_RCD_FAILURE; 2252 } else { 2253 assoc_ack_status = SENT_FAIL; 2254 reason_code = QDF_STATUS_E_FAILURE; 2255 mac_ctx->assoc_ack_status = LIM_TX_FAILED; 2256 } 2257 2258 if (buf) 2259 qdf_nbuf_free(buf); 2260 2261 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT, 2262 NULL, assoc_ack_status, reason_code); 2263 return QDF_STATUS_SUCCESS; 2264 } 2265 2266 #ifdef WLAN_ADAPTIVE_11R 2267 /** 2268 * lim_fill_adaptive_11r_ie() - Populate the Vendor specific adaptive 11r 2269 * IE to association request frame 2270 * @pe_session: pointer to PE session 2271 * @ie_buf: buffer to which Adaptive 11r IE will be copied 2272 * @ie_len: length of the Adaptive 11r Vendor specific IE 2273 * 2274 * Return QDF_STATUS 2275 */ 2276 static QDF_STATUS lim_fill_adaptive_11r_ie(struct pe_session *pe_session, 2277 uint8_t **ie_buf, uint8_t *ie_len) 2278 { 2279 uint8_t *buf = NULL, *adaptive_11r_ie = NULL; 2280 2281 if (!pe_session->is_adaptive_11r_connection) 2282 return QDF_STATUS_SUCCESS; 2283 2284 /* 2285 * Vendor specific Adaptive 11r IE to be advertised in Assoc 2286 * req: 2287 * Type 0xDD 2288 * Length 0x0B 2289 * OUI 0x00 0x00 0x0F 2290 * Type 0x22 2291 * subtype 0x00 2292 * Version 0x01 2293 * Length 0x04 2294 * Data 0x00 00 00 01(0th bit is 1 means adaptive 11r is 2295 * supported) 2296 */ 2297 adaptive_11r_ie = qdf_mem_malloc(ADAPTIVE_11R_STA_IE_LEN + 2); 2298 if (!adaptive_11r_ie) 2299 return QDF_STATUS_E_FAILURE; 2300 2301 /* Fill the Vendor IE Type (0xDD) */ 2302 buf = adaptive_11r_ie; 2303 *buf = WLAN_ELEMID_VENDOR; 2304 buf++; 2305 2306 /* Fill the Vendor IE length (0x0B) */ 2307 *buf = ADAPTIVE_11R_STA_IE_LEN; 2308 buf++; 2309 2310 /* 2311 * Fill the Adaptive 11r Vendor specific OUI(0x00 0x00 0x0F 0x22) 2312 */ 2313 qdf_mem_copy(buf, ADAPTIVE_11R_STA_OUI, ADAPTIVE_11R_OUI_LEN); 2314 buf += ADAPTIVE_11R_OUI_LEN; 2315 2316 /* Fill Adaptive 11r Vendor specific Subtype (0x00) */ 2317 *buf = ADAPTIVE_11R_OUI_SUBTYPE; 2318 buf++; 2319 2320 /* Fill Adaptive 11r Version (0x01) */ 2321 *buf = ADAPTIVE_11R_OUI_VERSION; 2322 buf++; 2323 2324 /* Fill Adaptive 11r IE Data length (0x04) */ 2325 *buf = ADAPTIVE_11R_DATA_LEN; 2326 buf++; 2327 2328 /* Fill Adaptive 11r IE Data (0x00 0x00 0x00 0x01) */ 2329 qdf_mem_copy(buf, ADAPTIVE_11R_OUI_DATA, ADAPTIVE_11R_DATA_LEN); 2330 2331 *ie_len = ADAPTIVE_11R_STA_IE_LEN + 2; 2332 *ie_buf = adaptive_11r_ie; 2333 2334 return QDF_STATUS_SUCCESS; 2335 } 2336 2337 #else 2338 static inline 2339 QDF_STATUS lim_fill_adaptive_11r_ie(struct pe_session *pe_session, 2340 uint8_t **ie_buf, uint8_t *ie_len) 2341 { 2342 return QDF_STATUS_SUCCESS; 2343 } 2344 #endif 2345 2346 /** 2347 * lim_send_assoc_req_mgmt_frame() - Send association request 2348 * @mac_ctx: Handle to MAC context 2349 * @mlm_assoc_req: Association request information 2350 * @pe_session: PE session information 2351 * 2352 * Builds and transmits association request frame to AP. 2353 * 2354 * Return: Void 2355 */ 2356 void 2357 lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, 2358 tLimMlmAssocReq *mlm_assoc_req, 2359 struct pe_session *pe_session) 2360 { 2361 int ret; 2362 tDot11fAssocRequest *frm; 2363 uint16_t caps; 2364 uint8_t *frame, *rsnx_ie = NULL; 2365 QDF_STATUS sir_status; 2366 tLimMlmAssocCnf assoc_cnf; 2367 uint32_t bytes = 0, payload, status; 2368 uint8_t qos_enabled, wme_enabled, wsm_enabled; 2369 void *packet; 2370 QDF_STATUS qdf_status; 2371 uint16_t add_ie_len, current_len = 0, vendor_ie_len = 0; 2372 uint8_t *add_ie = NULL, *mscs_ext_ie = NULL; 2373 const uint8_t *wps_ie = NULL; 2374 uint8_t power_caps = false; 2375 uint8_t tx_flag = 0; 2376 uint8_t vdev_id = 0; 2377 bool vht_enabled = false; 2378 tDot11fIEExtCap extr_ext_cap; 2379 bool extr_ext_flag = true, is_open_auth = false; 2380 tpSirMacMgmtHdr mac_hdr; 2381 uint32_t ie_offset = 0; 2382 uint8_t *p_ext_cap = NULL; 2383 tDot11fIEExtCap bcn_ext_cap; 2384 uint8_t *bcn_ie = NULL; 2385 uint32_t bcn_ie_len = 0; 2386 uint32_t aes_block_size_len = 0; 2387 enum rateid min_rid = RATEID_DEFAULT; 2388 uint8_t *mbo_ie = NULL, *adaptive_11r_ie = NULL, *vendor_ies = NULL; 2389 uint8_t mbo_ie_len = 0, adaptive_11r_ie_len = 0, rsnx_ie_len = 0; 2390 uint8_t mscs_ext_ie_len = 0; 2391 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 2392 bool bss_mfp_capable, frag_ie_present = false; 2393 int8_t peer_rssi = 0; 2394 bool is_band_2g; 2395 uint16_t ie_buf_size; 2396 uint16_t mlo_ie_len, fils_hlp_ie_len = 0; 2397 uint8_t *fils_hlp_ie = NULL; 2398 2399 if (!pe_session) { 2400 pe_err("pe_session is NULL"); 2401 qdf_mem_free(mlm_assoc_req); 2402 return; 2403 } 2404 2405 vdev_id = pe_session->vdev_id; 2406 2407 /* check this early to avoid unnecessary operation */ 2408 if (!pe_session->lim_join_req) { 2409 pe_err("pe_session->lim_join_req is NULL"); 2410 qdf_mem_free(mlm_assoc_req); 2411 return; 2412 } 2413 add_ie_len = pe_session->lim_join_req->addIEAssoc.length; 2414 if (add_ie_len) { 2415 add_ie = qdf_mem_malloc(add_ie_len); 2416 if (!add_ie) { 2417 qdf_mem_free(mlm_assoc_req); 2418 return; 2419 } 2420 /* 2421 * copy the additional ie to local, as this func modify 2422 * the IE, these IE will be required in assoc/re-assoc 2423 * retry. So do not modify the original IE. 2424 */ 2425 qdf_mem_copy(add_ie, pe_session->lim_join_req->addIEAssoc.addIEdata, 2426 add_ie_len); 2427 2428 } 2429 2430 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest)); 2431 if (!frm) { 2432 qdf_mem_free(mlm_assoc_req); 2433 qdf_mem_free(add_ie); 2434 return; 2435 } 2436 qdf_mem_zero((uint8_t *) frm, sizeof(tDot11fAssocRequest)); 2437 2438 if (add_ie_len && pe_session->is_ext_caps_present) { 2439 qdf_mem_zero((uint8_t *) &extr_ext_cap, 2440 sizeof(tDot11fIEExtCap)); 2441 sir_status = lim_strip_extcap_update_struct(mac_ctx, 2442 add_ie, &add_ie_len, &extr_ext_cap); 2443 if (QDF_STATUS_SUCCESS != sir_status) { 2444 extr_ext_flag = false; 2445 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req"); 2446 } else { 2447 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) 2448 extr_ext_cap.bytes; 2449 2450 if (p_ext_cap->interworking_service) 2451 p_ext_cap->qos_map = 1; 2452 extr_ext_cap.num_bytes = 2453 lim_compute_ext_cap_ie_length(&extr_ext_cap); 2454 extr_ext_flag = (extr_ext_cap.num_bytes > 0); 2455 } 2456 } else { 2457 extr_ext_flag = false; 2458 } 2459 2460 caps = mlm_assoc_req->capabilityInfo; 2461 #if defined(FEATURE_WLAN_WAPI) 2462 /* 2463 * According to WAPI standard: 2464 * 7.3.1.4 Capability Information field 2465 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 2466 * in transmitted Association or Reassociation management frames. 2467 * APs ignore the Privacy subfield within received Association and 2468 * Reassociation management frames. 2469 */ 2470 if (pe_session->encryptType == eSIR_ED_WPI) 2471 ((tSirMacCapabilityInfo *) &caps)->privacy = 0; 2472 #endif 2473 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities); 2474 2475 frm->ListenInterval.interval = mlm_assoc_req->listenInterval; 2476 2477 populate_dot11f_ssid2(pe_session, &frm->SSID); 2478 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL, 2479 &frm->SuppRates, pe_session); 2480 2481 qos_enabled = (pe_session->limQosEnabled) && 2482 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps); 2483 2484 wme_enabled = (pe_session->limWmeEnabled) && 2485 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps); 2486 2487 /* We prefer .11e asociations: */ 2488 if (qos_enabled) 2489 wme_enabled = false; 2490 2491 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled && 2492 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps); 2493 2494 if (pe_session->lim11hEnable && 2495 pe_session->spectrumMgtEnabled == true) { 2496 power_caps = true; 2497 2498 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps, 2499 LIM_ASSOC, pe_session); 2500 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels, 2501 LIM_ASSOC, pe_session); 2502 2503 } 2504 if (mac_ctx->rrm.rrmPEContext.rrmEnable && 2505 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) { 2506 if (power_caps == false) { 2507 power_caps = true; 2508 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps, 2509 LIM_ASSOC, pe_session); 2510 } 2511 } 2512 if (qos_enabled) 2513 populate_dot11f_qos_caps_station(mac_ctx, pe_session, 2514 &frm->QOSCapsStation); 2515 2516 populate_dot11f_ext_supp_rates(mac_ctx, 2517 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates, 2518 pe_session); 2519 2520 if (mac_ctx->rrm.rrmPEContext.rrmEnable && 2521 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) 2522 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap, 2523 pe_session); 2524 2525 /* 2526 * The join request *should* contain zero or one of the WPA and RSN 2527 * IEs. The payload send along with the request is a 2528 * 'struct join_req'; the IE portion is held inside a 'tSirRSNie': 2529 * typedef struct sSirRSNie 2530 * { 2531 * uint16_t length; 2532 * uint8_t rsnIEdata[WLAN_MAX_IE_LEN+2]; 2533 * } tSirRSNie, *tpSirRSNie; 2534 * So, we should be able to make the following two calls harmlessly, 2535 * since they do nothing if they don't find the given IE in the 2536 * bytestream with which they're provided. 2537 * The net effect of this will be to faithfully transmit whatever 2538 * security IE is in the join request. 2539 * However, if we're associating for the purpose of WPS 2540 * enrollment, and we've been configured to indicate that by 2541 * eliding the WPA or RSN IE, we just skip this: 2542 */ 2543 if (add_ie_len && add_ie) 2544 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len); 2545 2546 if (!wps_ie) { 2547 populate_dot11f_rsn_opaque(mac_ctx, 2548 &pe_session->lim_join_req->rsnIE, 2549 &frm->RSNOpaque); 2550 populate_dot11f_wpa_opaque(mac_ctx, 2551 &pe_session->lim_join_req->rsnIE, 2552 &frm->WPAOpaque); 2553 #if defined(FEATURE_WLAN_WAPI) 2554 populate_dot11f_wapi_opaque(mac_ctx, 2555 &(pe_session->lim_join_req->rsnIE), 2556 &frm->WAPIOpaque); 2557 #endif /* defined(FEATURE_WLAN_WAPI) */ 2558 } 2559 /* include WME EDCA IE as well */ 2560 if (wme_enabled) { 2561 populate_dot11f_wmm_info_station_per_session(mac_ctx, 2562 pe_session, &frm->WMMInfoStation); 2563 2564 if (wsm_enabled) 2565 populate_dot11f_wmm_caps(&frm->WMMCaps); 2566 } 2567 2568 /* 2569 * Populate HT IEs, when operating in 11n and 2570 * when AP is also operating in 11n mode 2571 */ 2572 if (pe_session->htCapability && 2573 mac_ctx->lim.htCapabilityPresentInBeacon) 2574 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps); 2575 else if (pe_session->he_with_wep_tkip) 2576 populate_dot11f_ht_caps(mac_ctx, NULL, &frm->HTCaps); 2577 2578 if (pe_session->vhtCapability && 2579 pe_session->vhtCapabilityPresentInBeacon) { 2580 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps); 2581 vht_enabled = true; 2582 if (pe_session->gLimOperatingMode.present && 2583 pe_session->ap_ch_width == CH_WIDTH_20MHZ && 2584 frm->VHTCaps.present && 2585 !IS_DOT11_MODE_HE(pe_session->dot11mode)) { 2586 populate_dot11f_operating_mode(mac_ctx, 2587 &frm->OperatingMode, pe_session); 2588 } 2589 } else if (pe_session->he_with_wep_tkip) { 2590 populate_dot11f_vht_caps(mac_ctx, NULL, &frm->VHTCaps); 2591 } 2592 2593 if (!vht_enabled && pe_session->is_vendor_specific_vhtcaps) { 2594 frm->vendor_vht_ie.present = 1; 2595 frm->vendor_vht_ie.sub_type = 2596 pe_session->vendor_specific_vht_ie_sub_type; 2597 frm->vendor_vht_ie.VHTCaps.present = 1; 2598 if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.vendor_vhtie && 2599 pe_session->vht_config.su_beam_formee) { 2600 pe_debug("Disable SU beamformee for vendor IE"); 2601 pe_session->vht_config.su_beam_formee = 0; 2602 } 2603 populate_dot11f_vht_caps(mac_ctx, pe_session, 2604 &frm->vendor_vht_ie.VHTCaps); 2605 vht_enabled = true; 2606 } 2607 if (pe_session->is_ext_caps_present) 2608 populate_dot11f_ext_cap(mac_ctx, vht_enabled, 2609 &frm->ExtCap, pe_session); 2610 2611 populate_dot11f_qcn_ie(mac_ctx, pe_session, 2612 &frm->qcn_ie, QCN_IE_ATTR_ID_ALL); 2613 2614 populate_dot11f_bss_max_idle(mac_ctx, pe_session, 2615 &frm->bss_max_idle_period); 2616 2617 if (IS_DOT11_MODE_HE(pe_session->dot11mode)) 2618 lim_update_session_he_capable(mac_ctx, pe_session); 2619 2620 if (lim_is_session_he_capable(pe_session)) { 2621 populate_dot11f_he_caps(mac_ctx, pe_session, 2622 &frm->he_cap); 2623 populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, 2624 &frm->he_6ghz_band_cap); 2625 } else if (pe_session->he_with_wep_tkip) { 2626 populate_dot11f_he_caps(mac_ctx, NULL, &frm->he_cap); 2627 populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, 2628 &frm->he_6ghz_band_cap); 2629 } 2630 2631 if (add_ie_len && lim_is_session_eht_capable(pe_session)) { 2632 populate_dot11f_eht_caps(mac_ctx, pe_session, &frm->eht_cap); 2633 lim_strip_mlo_ie(mac_ctx, add_ie, &add_ie_len); 2634 } 2635 2636 mlo_ie_len = lim_fill_assoc_req_mlo_ie(mac_ctx, pe_session, frm); 2637 2638 /** 2639 * In case of ML connection, if ML IE length is 0 then return failure. 2640 */ 2641 if (mlo_is_mld_sta(pe_session->vdev) && !mlo_ie_len) { 2642 pe_err("Failed to add ML IE for vdev:%d", pe_session->vdev_id); 2643 goto end; 2644 } 2645 2646 if (pe_session->is11Rconnection) { 2647 struct bss_description *bssdescr; 2648 2649 bssdescr = &pe_session->lim_join_req->bssDescription; 2650 pe_debug("mdie = %02x %02x %02x", 2651 (unsigned int) bssdescr->mdie[0], 2652 (unsigned int) bssdescr->mdie[1], 2653 (unsigned int) bssdescr->mdie[2]); 2654 populate_mdie(mac_ctx, &frm->MobilityDomain, 2655 pe_session->lim_join_req->bssDescription.mdie); 2656 2657 /* 2658 * IEEE80211-ai [13.2.4 FT initial mobility domain association 2659 * over FILS in an RSN] 2660 * Populate FT IE in association request. This FT IE should be 2661 * same as the FT IE received in auth response frame during the 2662 * FT-FILS authentication. 2663 */ 2664 if (lim_is_fils_connection(pe_session)) 2665 populate_fils_ft_info(mac_ctx, &frm->FTInfo, 2666 pe_session); 2667 } 2668 2669 #ifdef FEATURE_WLAN_ESE 2670 /* 2671 * ESE Version IE will be included in association request 2672 * when ESE is enabled on DUT through ini and it is also 2673 * advertised by the peer AP to which we are trying to 2674 * associate to. 2675 */ 2676 if (pe_session->is_ese_version_ie_present && 2677 mac_ctx->mlme_cfg->lfr.ese_enabled) 2678 populate_dot11f_ese_version(&frm->ESEVersion); 2679 /* For ESE Associations fill the ESE IEs */ 2680 if (wlan_cm_get_ese_assoc(mac_ctx->pdev, pe_session->vdev_id)) { 2681 #ifndef FEATURE_DISABLE_RM 2682 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap); 2683 #endif 2684 } 2685 #endif 2686 2687 /* 2688 * Extcap IE now support variable length, merge Extcap IE from addn_ie 2689 * may change the frame size. Therefore, MUST merge ExtCap IE before 2690 * dot11f get packed payload size. 2691 */ 2692 if (extr_ext_flag) 2693 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true); 2694 2695 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */ 2696 if (frm->ExtCap.present && pe_session->is_ext_caps_present) { 2697 ie_offset = DOT11F_FF_TIMESTAMP_LEN + 2698 DOT11F_FF_BEACONINTERVAL_LEN + 2699 DOT11F_FF_CAPABILITIES_LEN; 2700 2701 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap)); 2702 if (pe_session->beacon && (pe_session->bcnLen > 2703 (ie_offset + sizeof(struct wlan_frame_hdr)))) { 2704 bcn_ie = pe_session->beacon + ie_offset + 2705 sizeof(struct wlan_frame_hdr); 2706 bcn_ie_len = pe_session->bcnLen - ie_offset - 2707 sizeof(struct wlan_frame_hdr); 2708 p_ext_cap = (uint8_t *)wlan_get_ie_ptr_from_eid( 2709 DOT11F_EID_EXTCAP, 2710 bcn_ie, bcn_ie_len); 2711 lim_update_extcap_struct(mac_ctx, p_ext_cap, 2712 &bcn_ext_cap); 2713 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap, 2714 false); 2715 } 2716 2717 populate_dot11f_btm_extended_caps(mac_ctx, pe_session, 2718 &frm->ExtCap); 2719 /* 2720 * TWT extended capabilities should be populated after the 2721 * intersection of beacon caps and self caps is done because 2722 * the bits for TWT are unique to STA and AP and cannot be 2723 * intersected. 2724 */ 2725 populate_dot11f_twt_extended_caps(mac_ctx, pe_session, 2726 &frm->ExtCap); 2727 } else { 2728 wlan_cm_set_assoc_btm_cap(pe_session->vdev, false); 2729 } 2730 2731 if (QDF_STATUS_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx, 2732 add_ie, &add_ie_len, &frm->SuppOperatingClasses)) 2733 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req"); 2734 2735 if (lim_is_fils_connection(pe_session)) { 2736 populate_dot11f_fils_params(mac_ctx, frm, pe_session); 2737 aes_block_size_len = AES_BLOCK_SIZE; 2738 if (add_ie_len && wlan_get_ie_ptr_from_eid(WLAN_ELEMID_FRAGMENT, 2739 add_ie, add_ie_len)) 2740 frag_ie_present = true; 2741 } 2742 2743 /* Strip and append HLP container IE only if it is fragmented */ 2744 if (frag_ie_present && add_ie_len && 2745 wlan_get_ext_ie_ptr_from_ext_id(SIR_FILS_HLP_OUI_TYPE, 2746 SIR_FILS_HLP_OUI_LEN, add_ie, 2747 add_ie_len)) { 2748 fils_hlp_ie = qdf_mem_malloc(SIR_FILS_HLP_IE_LEN); 2749 if (!fils_hlp_ie) 2750 goto end; 2751 2752 qdf_status = 2753 lim_strip_ie(mac_ctx, add_ie, &add_ie_len, 2754 WLAN_ELEMID_EXTN_ELEM, ONE_BYTE, 2755 SIR_FILS_HLP_OUI_TYPE, 2756 SIR_FILS_HLP_OUI_LEN, fils_hlp_ie, 2757 SIR_FILS_HLP_IE_LEN - 2); 2758 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2759 pe_err("Failed to strip FILS HLP container IE"); 2760 goto end; 2761 } 2762 fils_hlp_ie_len = fils_hlp_ie[1] + 2; 2763 2764 current_len = add_ie_len; 2765 qdf_status = 2766 lim_strip_ie(mac_ctx, add_ie, &add_ie_len, 2767 WLAN_ELEMID_FRAGMENT, ONE_BYTE, 2768 NULL, 0, &fils_hlp_ie[fils_hlp_ie_len], 2769 SIR_FILS_HLP_IE_LEN - fils_hlp_ie_len - 2); 2770 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2771 pe_err("Failed to strip fragment IE of HLP container IE"); 2772 goto end; 2773 } 2774 fils_hlp_ie_len += current_len - add_ie_len; 2775 } 2776 2777 /* RSNX IE for SAE PWE derivation based on H2E */ 2778 if (add_ie_len && 2779 wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSNXE, add_ie, add_ie_len)) { 2780 rsnx_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 2781 if (!rsnx_ie) 2782 goto end; 2783 2784 qdf_status = lim_strip_ie(mac_ctx, add_ie, &add_ie_len, 2785 WLAN_ELEMID_RSNXE, ONE_BYTE, 2786 NULL, 0, rsnx_ie, WLAN_MAX_IE_LEN); 2787 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2788 pe_err("Failed to strip Vendor IEs"); 2789 goto end; 2790 } 2791 rsnx_ie_len = rsnx_ie[1] + 2; 2792 } 2793 /* MSCS ext ie */ 2794 if (add_ie_len && 2795 wlan_get_ext_ie_ptr_from_ext_id(MSCS_OUI_TYPE, MSCS_OUI_SIZE, 2796 add_ie, add_ie_len)) { 2797 mscs_ext_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 2798 if (!mscs_ext_ie) 2799 goto end; 2800 2801 qdf_status = lim_strip_ie(mac_ctx, add_ie, &add_ie_len, 2802 WLAN_ELEMID_EXTN_ELEM, ONE_BYTE, 2803 MSCS_OUI_TYPE, MSCS_OUI_SIZE, 2804 mscs_ext_ie, WLAN_MAX_IE_LEN); 2805 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2806 pe_err("Failed to strip MSCS ext IE"); 2807 goto end; 2808 } 2809 mscs_ext_ie_len = mscs_ext_ie[1] + 2; 2810 } 2811 2812 /* 2813 * MBO IE needs to be appendded at the end of the assoc request 2814 * frame and is not parsed and unpacked by the frame parser 2815 * as the supplicant can send multiple TLVs with same Attribute 2816 * in the MBO IE and the frame parser does not support multiple 2817 * TLVs with same attribute in a single IE. 2818 * Strip off the MBO IE from add_ie and append it at the end. 2819 */ 2820 if (add_ie_len && 2821 wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_MBO_OUI, 2822 SIR_MAC_MBO_OUI_SIZE, add_ie, 2823 add_ie_len)) { 2824 mbo_ie = qdf_mem_malloc(DOT11F_IE_MBO_IE_MAX_LEN + 2); 2825 if (!mbo_ie) 2826 goto end; 2827 2828 qdf_status = lim_strip_ie(mac_ctx, add_ie, &add_ie_len, 2829 WLAN_ELEMID_VENDOR, ONE_BYTE, 2830 SIR_MAC_MBO_OUI, 2831 SIR_MAC_MBO_OUI_SIZE, 2832 mbo_ie, DOT11F_IE_MBO_IE_MAX_LEN); 2833 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2834 pe_err("Failed to strip MBO IE"); 2835 goto end; 2836 } 2837 2838 /* Include the EID and length fields */ 2839 mbo_ie_len = mbo_ie[1] + 2; 2840 2841 if (pe_session->connected_akm == ANI_AKM_TYPE_NONE) 2842 is_open_auth = true; 2843 2844 if (!is_open_auth) { 2845 bss_mfp_capable = 2846 lim_get_vdev_rmf_capable(mac_ctx, pe_session); 2847 if (!bss_mfp_capable) { 2848 pe_debug("Peer doesn't support PMF, Don't add MBO IE"); 2849 qdf_mem_free(mbo_ie); 2850 mbo_ie = NULL; 2851 mbo_ie_len = 0; 2852 } 2853 } 2854 } 2855 2856 /* 2857 * Strip rest of the vendor IEs and append to the assoc request frame. 2858 * Append the IEs just before MBO IEs as MBO IEs have to be at the 2859 * end of the frame. 2860 */ 2861 if (add_ie_len && 2862 wlan_get_ie_ptr_from_eid(WLAN_ELEMID_VENDOR, add_ie, add_ie_len)) { 2863 vendor_ies = qdf_mem_malloc(MAX_VENDOR_IES_LEN + 2); 2864 if (vendor_ies) { 2865 current_len = add_ie_len; 2866 qdf_status = lim_strip_ie(mac_ctx, add_ie, &add_ie_len, 2867 WLAN_ELEMID_VENDOR, ONE_BYTE, 2868 NULL, 2869 0, 2870 vendor_ies, 2871 MAX_VENDOR_IES_LEN); 2872 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2873 pe_err("Failed to strip Vendor IEs"); 2874 goto end; 2875 } 2876 2877 vendor_ie_len = current_len - add_ie_len; 2878 } 2879 } 2880 2881 qdf_status = lim_fill_adaptive_11r_ie(pe_session, &adaptive_11r_ie, 2882 &adaptive_11r_ie_len); 2883 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2884 pe_err("Failed to fill adaptive 11r IE"); 2885 goto end; 2886 } 2887 2888 /* 2889 * Do unpack to populate the add_ie buffer to frm structure 2890 * before packing the frm structure. In this way, the IE ordering 2891 * which the latest 802.11 spec mandates is maintained. 2892 */ 2893 if (add_ie_len) { 2894 ret = dot11f_unpack_assoc_request(mac_ctx, add_ie, 2895 add_ie_len, frm, true); 2896 if (DOT11F_FAILED(ret)) { 2897 pe_err("unpack failed, ret: 0x%x", ret); 2898 goto end; 2899 } 2900 } 2901 2902 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload); 2903 if (DOT11F_FAILED(status)) { 2904 pe_err("Association Request packet size failure(0x%08x)", 2905 status); 2906 /* We'll fall back on the worst case scenario: */ 2907 payload = sizeof(tDot11fAssocRequest); 2908 } else if (DOT11F_WARNED(status)) { 2909 pe_warn("Association request packet size warning (0x%08x)", 2910 status); 2911 } 2912 2913 bytes = payload + sizeof(tSirMacMgmtHdr) + aes_block_size_len + 2914 rsnx_ie_len + mbo_ie_len + adaptive_11r_ie_len + 2915 mscs_ext_ie_len + vendor_ie_len + mlo_ie_len + fils_hlp_ie_len; 2916 2917 2918 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame, 2919 (void **)&packet); 2920 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2921 pe_err("Failed to allocate %d bytes", bytes); 2922 2923 pe_session->limMlmState = pe_session->limPrevMlmState; 2924 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE, 2925 pe_session->peSessionId, 2926 pe_session->limMlmState)); 2927 2928 /* Update PE session id */ 2929 assoc_cnf.sessionId = pe_session->peSessionId; 2930 2931 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 2932 2933 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 2934 (uint32_t *) &assoc_cnf); 2935 2936 goto end; 2937 } 2938 /* Paranoia: */ 2939 qdf_mem_zero(frame, bytes); 2940 2941 /* Next, we fill out the buffer descriptor: */ 2942 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 2943 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId, 2944 pe_session->self_mac_addr); 2945 /* That done, pack the Assoc Request: */ 2946 status = dot11f_pack_assoc_request(mac_ctx, frm, 2947 frame + sizeof(tSirMacMgmtHdr), payload, &payload); 2948 if (DOT11F_FAILED(status)) { 2949 pe_err("Assoc request pack failure (0x%08x)", status); 2950 cds_packet_free((void *)packet); 2951 goto end; 2952 } else if (DOT11F_WARNED(status)) { 2953 pe_warn("Assoc request pack warning (0x%08x)", status); 2954 } 2955 2956 if (fils_hlp_ie && fils_hlp_ie_len) { 2957 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 2958 fils_hlp_ie, fils_hlp_ie_len); 2959 payload = payload + fils_hlp_ie_len; 2960 } 2961 2962 /* Strip EHT capabilities IE */ 2963 if (lim_is_session_eht_capable(pe_session)) { 2964 ie_buf_size = payload - WLAN_ASSOC_REQ_IES_OFFSET; 2965 2966 eht_cap_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 2967 if (!eht_cap_ie) { 2968 pe_err("malloc failed for eht_cap_ie"); 2969 cds_packet_free((void *)packet); 2970 goto end; 2971 } 2972 2973 qdf_status = lim_strip_eht_cap_ie(mac_ctx, frame + 2974 sizeof(tSirMacMgmtHdr) + 2975 WLAN_ASSOC_REQ_IES_OFFSET, 2976 &ie_buf_size, eht_cap_ie); 2977 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2978 pe_err("Failed to strip EHT cap IE"); 2979 qdf_mem_free(eht_cap_ie); 2980 cds_packet_free((void *)packet); 2981 goto end; 2982 } 2983 2984 is_band_2g = 2985 WLAN_REG_IS_24GHZ_CH_FREQ(pe_session->curr_op_freq); 2986 2987 lim_ieee80211_pack_ehtcap(eht_cap_ie, frm->eht_cap, frm->he_cap, 2988 is_band_2g); 2989 eht_cap_ie_len = eht_cap_ie[1] + 2; 2990 2991 /* Copy the EHT IE to the end of the frame */ 2992 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + 2993 WLAN_ASSOC_REQ_IES_OFFSET + ie_buf_size, 2994 eht_cap_ie, eht_cap_ie_len); 2995 qdf_mem_free(eht_cap_ie); 2996 payload = ie_buf_size + WLAN_ASSOC_REQ_IES_OFFSET + 2997 eht_cap_ie_len; 2998 } 2999 3000 if (rsnx_ie && rsnx_ie_len) { 3001 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 3002 rsnx_ie, rsnx_ie_len); 3003 payload = payload + rsnx_ie_len; 3004 } 3005 3006 if (mscs_ext_ie && mscs_ext_ie_len) { 3007 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 3008 mscs_ext_ie, mscs_ext_ie_len); 3009 payload = payload + mscs_ext_ie_len; 3010 } 3011 3012 /* Copy the vendor IEs to the end of the frame */ 3013 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 3014 vendor_ies, vendor_ie_len); 3015 payload = payload + vendor_ie_len; 3016 3017 /* Copy the MBO IE to the end of the frame */ 3018 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 3019 mbo_ie, mbo_ie_len); 3020 payload = payload + mbo_ie_len; 3021 3022 /* 3023 * Copy the Vendor specific Adaptive 11r IE to end of the 3024 * assoc request frame 3025 */ 3026 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, 3027 adaptive_11r_ie, adaptive_11r_ie_len); 3028 payload = payload + adaptive_11r_ie_len; 3029 3030 if (mlo_ie_len) { 3031 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 3032 frame + sizeof(tSirMacMgmtHdr) + payload); 3033 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3034 pe_debug("assemble ml ie error"); 3035 mlo_ie_len = 0; 3036 } 3037 payload = payload + mlo_ie_len; 3038 } 3039 3040 if (pe_session->assoc_req) { 3041 qdf_mem_free(pe_session->assoc_req); 3042 pe_session->assoc_req = NULL; 3043 pe_session->assocReqLen = 0; 3044 } 3045 3046 if (lim_is_fils_connection(pe_session)) { 3047 qdf_status = aead_encrypt_assoc_req(mac_ctx, pe_session, 3048 frame, &payload); 3049 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3050 cds_packet_free((void *)packet); 3051 goto end; 3052 } 3053 } 3054 3055 pe_session->assoc_req = qdf_mem_malloc(payload); 3056 if (pe_session->assoc_req) { 3057 /* 3058 * Store the Assoc request. This is sent to csr/hdd in 3059 * join cnf response. 3060 */ 3061 qdf_mem_copy(pe_session->assoc_req, 3062 frame + sizeof(tSirMacMgmtHdr), payload); 3063 pe_session->assocReqLen = payload; 3064 } 3065 3066 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 3067 pe_session->opmode == QDF_P2P_CLIENT_MODE || 3068 pe_session->opmode == QDF_P2P_GO_MODE) 3069 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 3070 3071 if (pe_session->opmode == QDF_P2P_CLIENT_MODE || 3072 pe_session->opmode == QDF_STA_MODE) 3073 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK; 3074 3075 mac_hdr = (tpSirMacMgmtHdr) frame; 3076 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 3077 pe_session->peSessionId, mac_hdr->fc.subType)); 3078 3079 pe_debug("extr_ext_flag %d mbo ie len %d is open auth %d stripped vendor len %d he with tkip %d ht %d vht %d opmode %d vendor vht %d he %d eht %d", 3080 extr_ext_flag, mbo_ie_len, is_open_auth, current_len, 3081 pe_session->he_with_wep_tkip, 3082 frm->HTCaps.present, frm->VHTCaps.present, 3083 frm->OperatingMode.present, frm->vendor_vht_ie.present, 3084 frm->he_cap.present, frm->eht_cap.present); 3085 pe_nofl_info("Assoc req TX: vdev %d to "QDF_MAC_ADDR_FMT" seq num %d", 3086 pe_session->vdev_id, QDF_MAC_ADDR_REF(pe_session->bssId), 3087 mac_ctx->mgmtSeqNum); 3088 3089 min_rid = lim_get_min_session_txrate(pe_session, NULL); 3090 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT, 3091 pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 3092 lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr, 3093 pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 3094 peer_rssi = mac_ctx->lim.bss_rssi; 3095 3096 qdf_status = 3097 wma_tx_frameWithTxComplete(mac_ctx, packet, 3098 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload), 3099 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 3100 lim_tx_complete, frame, lim_assoc_tx_complete_cnf, 3101 tx_flag, vdev_id, false, 0, 3102 min_rid, peer_rssi, 0); 3103 MTRACE(qdf_trace 3104 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 3105 pe_session->peSessionId, qdf_status)); 3106 3107 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3108 pe_err("Failed to send Association Request (%X)!", 3109 qdf_status); 3110 mac_ctx->assoc_ack_status = LIM_TX_FAILED; 3111 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT, 3112 pe_session, SENT_FAIL, QDF_STATUS_E_FAILURE); 3113 /* Pkt will be freed up by the callback */ 3114 } 3115 3116 end: 3117 qdf_mem_free(fils_hlp_ie); 3118 qdf_mem_free(rsnx_ie); 3119 qdf_mem_free(vendor_ies); 3120 qdf_mem_free(mbo_ie); 3121 qdf_mem_free(mscs_ext_ie); 3122 3123 /* Free up buffer allocated for mlm_assoc_req */ 3124 qdf_mem_free(adaptive_11r_ie); 3125 qdf_mem_free(mlm_assoc_req); 3126 qdf_mem_free(add_ie); 3127 mlm_assoc_req = NULL; 3128 qdf_mem_free(frm); 3129 return; 3130 } 3131 3132 /** 3133 * lim_get_addba_rsp_ptr() - Search the pointer to addba response 3134 * @ie: the pointer to entire frame 3135 * @ie_len: length of ie 3136 * 3137 * Host reserved 8 bytes for CCMP header trailer and initialize them 3138 * as 0 when rmf enabled & key installed and tx addba rsp frame. So, 3139 * search the pointer to addba response and then unpack the frame. 3140 * 3141 * Return: the pointer to addba response 3142 */ 3143 static uint8_t * 3144 lim_get_addba_rsp_ptr(uint8_t *ie, uint32_t ie_len) 3145 { 3146 uint32_t left = ie_len; 3147 uint8_t *ptr = ie; 3148 uint8_t category, action; 3149 uint32_t addba_rsp_len = sizeof(tDot11faddba_rsp); 3150 3151 while (left >= addba_rsp_len) { 3152 category = ptr[0]; 3153 action = ptr[1]; 3154 3155 if (category == ACTION_CATEGORY_BACK && 3156 action == ADDBA_RESPONSE) 3157 return ptr; 3158 3159 left--; 3160 ptr++; 3161 } 3162 3163 return NULL; 3164 } 3165 3166 /** 3167 * lim_addba_rsp_tx_complete_cnf() - Confirmation for add BA response OTA 3168 * @context: pointer to global mac 3169 * @buf: buffer which is nothing but entire ADD BA frame 3170 * @tx_complete : Sent status 3171 * @params; tx completion params 3172 * 3173 * Return: This returns QDF_STATUS 3174 */ 3175 static QDF_STATUS lim_addba_rsp_tx_complete_cnf(void *context, 3176 qdf_nbuf_t buf, 3177 uint32_t tx_complete, 3178 void *params) 3179 { 3180 struct mac_context *mac_ctx = (struct mac_context *)context; 3181 tSirMacMgmtHdr *mac_hdr; 3182 tDot11faddba_rsp rsp = {0}; 3183 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 3184 uint32_t rsp_len; 3185 QDF_STATUS status; 3186 uint8_t *data; 3187 uint8_t *addba_rsp_ptr; 3188 uint32_t data_len; 3189 struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)params; 3190 3191 if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) 3192 pe_debug("Add ba response successfully sent"); 3193 else 3194 pe_debug("Fail to send add ba response"); 3195 3196 if (!buf) { 3197 pe_err("Addba response frame buffer is NULL"); 3198 return QDF_STATUS_E_FAILURE; 3199 } 3200 3201 data = qdf_nbuf_data(buf); 3202 3203 if (!data) { 3204 pe_err("Addba response frame is NULL"); 3205 return QDF_STATUS_E_FAILURE; 3206 } 3207 3208 data_len = (uint32_t)qdf_nbuf_get_data_len(buf); 3209 if (data_len < (sizeof(*mac_hdr) + sizeof(rsp))) { 3210 pe_err("Invalid data len %d", data_len); 3211 return QDF_STATUS_E_FAILURE; 3212 } 3213 3214 addba_rsp_ptr = lim_get_addba_rsp_ptr( 3215 data + sizeof(*mac_hdr), 3216 data_len - sizeof(*mac_hdr)); 3217 if (!addba_rsp_ptr) { 3218 pe_debug("null addba_rsp_ptr"); 3219 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, 3220 (void *)data, data_len); 3221 addba_rsp_ptr = (uint8_t *)data + sizeof(*mac_hdr); 3222 } 3223 mac_hdr = (tSirMacMgmtHdr *)data; 3224 rsp_len = sizeof(rsp); 3225 status = dot11f_unpack_addba_rsp(mac_ctx, addba_rsp_ptr, 3226 rsp_len, &rsp, false); 3227 3228 if (DOT11F_FAILED(status)) { 3229 pe_err("Failed to unpack and parse (0x%08x, %d bytes)", 3230 status, rsp_len); 3231 goto error; 3232 } 3233 3234 cdp_addba_resp_tx_completion(soc, mac_hdr->da, mgmt_params->vdev_id, 3235 rsp.addba_param_set.tid, tx_complete); 3236 error: 3237 if (buf) 3238 qdf_nbuf_free(buf); 3239 3240 return QDF_STATUS_SUCCESS; 3241 } 3242 3243 #define SAE_AUTH_ALGO_LEN 2 3244 #define SAE_AUTH_ALGO_OFFSET 0 3245 static bool lim_is_ack_for_sae_auth(qdf_nbuf_t buf) 3246 { 3247 tpSirMacMgmtHdr mac_hdr; 3248 uint16_t *sae_auth, min_len; 3249 3250 if (!buf) { 3251 pe_debug("buf is NULL"); 3252 return false; 3253 } 3254 3255 min_len = sizeof(tSirMacMgmtHdr) + SAE_AUTH_ALGO_LEN; 3256 if (qdf_nbuf_len(buf) < min_len) { 3257 pe_debug("buf_len %d less than min_len %d", 3258 (uint32_t)qdf_nbuf_len(buf), min_len); 3259 return false; 3260 } 3261 3262 mac_hdr = (tpSirMacMgmtHdr)(qdf_nbuf_data(buf)); 3263 if (mac_hdr->fc.subType == SIR_MAC_MGMT_AUTH) { 3264 sae_auth = (uint16_t *)((uint8_t *)mac_hdr + 3265 sizeof(tSirMacMgmtHdr)); 3266 if (sae_auth[SAE_AUTH_ALGO_OFFSET] == 3267 eSIR_AUTH_TYPE_SAE) 3268 return true; 3269 } 3270 3271 return false; 3272 } 3273 3274 /** 3275 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air 3276 * @context: pointer to global mac 3277 * @buf: buffer 3278 * @tx_complete : Sent status 3279 * @params: tx completion params 3280 * 3281 * Return: This returns QDF_STATUS 3282 */ 3283 static QDF_STATUS lim_auth_tx_complete_cnf(void *context, 3284 qdf_nbuf_t buf, 3285 uint32_t tx_complete, 3286 void *params) 3287 { 3288 struct mac_context *mac_ctx = (struct mac_context *)context; 3289 uint16_t auth_ack_status; 3290 uint16_t reason_code; 3291 bool sae_auth_acked; 3292 3293 if (params) 3294 wlan_send_tx_complete_event(context, buf, params, tx_complete, 3295 WLAN_AUTH_REQ); 3296 3297 pe_nofl_rl_info("Auth TX: %s (%d)", 3298 (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? 3299 "success" : "fail", tx_complete); 3300 if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { 3301 mac_ctx->auth_ack_status = LIM_ACK_RCD_SUCCESS; 3302 auth_ack_status = ACKED; 3303 reason_code = QDF_STATUS_SUCCESS; 3304 sae_auth_acked = lim_is_ack_for_sae_auth(buf); 3305 /* 3306 * 'Change' timer for future activations only if ack 3307 * received is not for WPA SAE auth frames. 3308 */ 3309 if (!sae_auth_acked) 3310 lim_deactivate_and_change_timer(mac_ctx, 3311 eLIM_AUTH_RETRY_TIMER); 3312 } else if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK) { 3313 mac_ctx->auth_ack_status = LIM_ACK_RCD_FAILURE; 3314 auth_ack_status = NOT_ACKED; 3315 reason_code = QDF_STATUS_E_FAILURE; 3316 } else { 3317 mac_ctx->auth_ack_status = LIM_TX_FAILED; 3318 auth_ack_status = SENT_FAIL; 3319 reason_code = QDF_STATUS_E_FAILURE; 3320 } 3321 3322 if (buf) 3323 qdf_nbuf_free(buf); 3324 3325 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT, 3326 NULL, auth_ack_status, reason_code); 3327 3328 return QDF_STATUS_SUCCESS; 3329 } 3330 3331 #ifdef WLAN_FEATURE_11BE_MLO 3332 static uint32_t lim_calculate_auth_mlo_ie_len(struct mac_context *mac_ctx, 3333 struct pe_session *session, 3334 tSirMacAddr peer_addr) 3335 { 3336 struct wlan_mlo_ie *mlo_ie; 3337 uint32_t mlo_ie_len = 0; 3338 struct tLimPreAuthNode *auth_node; 3339 3340 mlo_ie = &session->mlo_ie; 3341 if (wlan_vdev_mlme_is_mlo_vdev(session->vdev)) { 3342 qdf_mem_zero(mlo_ie, sizeof(*mlo_ie)); 3343 3344 pe_debug("Auth TX sys role: %d", GET_LIM_SYSTEM_ROLE(session)); 3345 if (LIM_IS_STA_ROLE(session)) { 3346 populate_dot11f_auth_mlo_ie(mac_ctx, session, mlo_ie); 3347 mlo_ie_len = lim_caculate_mlo_ie_length(mlo_ie); 3348 } else if (LIM_IS_AP_ROLE(session)) { 3349 auth_node = lim_search_pre_auth_list(mac_ctx, peer_addr); 3350 if (!auth_node) { 3351 pe_err("no pre-auth ctx with peer addr"); 3352 return 0; 3353 } 3354 3355 /* 3356 * Populate MLO IE in Auth response frame if 3357 * is_mlo_ie_present flag is set. It is set when peer 3358 * is MLO AP 3359 */ 3360 if (auth_node && auth_node->is_mlo_ie_present) { 3361 populate_dot11f_auth_mlo_ie(mac_ctx, session, 3362 mlo_ie); 3363 mlo_ie_len = lim_caculate_mlo_ie_length(mlo_ie); 3364 } 3365 } 3366 } 3367 3368 return mlo_ie_len; 3369 } 3370 3371 #else 3372 static inline 3373 uint32_t lim_calculate_auth_mlo_ie_len(struct mac_context *mac_ctx, 3374 struct pe_session *session, 3375 tSirMacAddr peer_addr) 3376 { 3377 return 0; 3378 } 3379 #endif 3380 3381 /** 3382 * lim_send_auth_mgmt_frame() - Send an Authentication frame 3383 * 3384 * @mac_ctx: Pointer to Global MAC structure 3385 * @auth_frame: Pointer to Authentication frame structure 3386 * @peer_addr: MAC address of destination peer 3387 * @wep_bit: wep bit in frame control for Authentication frame3 3388 * @session: PE session information 3389 * 3390 * This function is called by lim_process_mlm_messages(). Authentication frame 3391 * is formatted and sent when this function is called. 3392 * 3393 * Return: void 3394 */ 3395 void 3396 lim_send_auth_mgmt_frame(struct mac_context *mac_ctx, 3397 tpSirMacAuthFrameBody auth_frame, 3398 tSirMacAddr peer_addr, 3399 uint8_t wep_challenge_len, 3400 struct pe_session *session) 3401 { 3402 uint8_t *frame, *body; 3403 uint32_t frame_len = 0, body_len = 0; 3404 tpSirMacMgmtHdr mac_hdr; 3405 void *packet; 3406 QDF_STATUS qdf_status, status; 3407 uint8_t tx_flag = 0; 3408 uint8_t vdev_id = 0; 3409 uint16_t ft_ies_length = 0; 3410 bool challenge_req = false; 3411 enum rateid min_rid = RATEID_DEFAULT; 3412 uint16_t ch_freq_tx_frame = 0; 3413 int8_t peer_rssi = 0; 3414 uint8_t *mlo_ie_buf; 3415 uint32_t mlo_ie_len = 0; 3416 3417 if (!session) { 3418 pe_err("Error: psession Entry is NULL"); 3419 return; 3420 } 3421 3422 vdev_id = session->vdev_id; 3423 3424 if (wep_challenge_len) { 3425 /* 3426 * Auth frame3 to be sent with encrypted framebody 3427 * 3428 * Allocate buffer for Authenticaton frame of size 3429 * equal to management frame header length plus 2 bytes 3430 * each for auth algorithm number, transaction number, 3431 * status code, 128 bytes for challenge text and 3432 * 4 bytes each for IV & ICV. 3433 */ 3434 body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN; 3435 frame_len = sizeof(tSirMacMgmtHdr) + body_len; 3436 3437 goto alloc_packet; 3438 } 3439 3440 switch (auth_frame->authTransactionSeqNumber) { 3441 case SIR_MAC_AUTH_FRAME_1: 3442 /* 3443 * Allocate buffer for Authenticaton frame of size 3444 * equal to management frame header length plus 2 bytes 3445 * each for auth algorithm number, transaction number 3446 * and status code. 3447 */ 3448 3449 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN; 3450 frame_len = sizeof(tSirMacMgmtHdr) + body_len; 3451 3452 status = lim_create_fils_auth_data(mac_ctx, auth_frame, 3453 session, &frame_len); 3454 if (QDF_IS_STATUS_ERROR(status)) 3455 return; 3456 3457 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) { 3458 if (session->ftPEContext.pFTPreAuthReq && 3459 0 != session->ftPEContext.pFTPreAuthReq-> 3460 ft_ies_length) { 3461 ft_ies_length = session->ftPEContext. 3462 pFTPreAuthReq->ft_ies_length; 3463 frame_len += ft_ies_length; 3464 pe_debug("Auth frame, FTIES length added=%d", 3465 ft_ies_length); 3466 } else { 3467 pe_debug("Auth frame, Does not contain FTIES!"); 3468 frame_len += (2 + SIR_MDIE_SIZE); 3469 } 3470 } 3471 3472 /* include MDIE in FILS authentication frame */ 3473 if (session->lim_join_req && 3474 session->is11Rconnection && 3475 auth_frame->authAlgoNumber == SIR_FILS_SK_WITHOUT_PFS && 3476 session->lim_join_req->bssDescription.mdiePresent) 3477 frame_len += (2 + SIR_MDIE_SIZE); 3478 break; 3479 3480 case SIR_MAC_AUTH_FRAME_2: 3481 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) || 3482 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) && 3483 (auth_frame->authStatusCode != STATUS_SUCCESS))) { 3484 /* 3485 * Allocate buffer for Authenticaton frame of size 3486 * equal to management frame header length plus 3487 * 2 bytes each for auth algorithm number, 3488 * transaction number and status code. 3489 */ 3490 3491 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN; 3492 frame_len = sizeof(tSirMacMgmtHdr) + body_len; 3493 } else { 3494 /* 3495 * Shared Key algorithm with challenge text 3496 * to be sent. 3497 * 3498 * Allocate buffer for Authenticaton frame of size 3499 * equal to management frame header length plus 3500 * 2 bytes each for auth algorithm number, 3501 * transaction number, status code and 128 bytes 3502 * for challenge text. 3503 */ 3504 3505 challenge_req = true; 3506 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN + 3507 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + 3508 SIR_MAC_CHALLENGE_ID_LEN; 3509 frame_len = sizeof(tSirMacMgmtHdr) + body_len; 3510 } 3511 break; 3512 3513 case SIR_MAC_AUTH_FRAME_3: 3514 /* 3515 * Auth frame3 to be sent without encrypted framebody 3516 * 3517 * Allocate buffer for Authenticaton frame of size equal 3518 * to management frame header length plus 2 bytes each 3519 * for auth algorithm number, transaction number and 3520 * status code. 3521 */ 3522 3523 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN; 3524 frame_len = sizeof(tSirMacMgmtHdr) + body_len; 3525 break; 3526 3527 case SIR_MAC_AUTH_FRAME_4: 3528 /* 3529 * Allocate buffer for Authenticaton frame of size equal 3530 * to management frame header length plus 2 bytes each 3531 * for auth algorithm number, transaction number and 3532 * status code. 3533 */ 3534 3535 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN; 3536 frame_len = sizeof(tSirMacMgmtHdr) + body_len; 3537 3538 break; 3539 default: 3540 pe_err("Invalid auth transaction seq num"); 3541 return; 3542 } /* switch (auth_frame->authTransactionSeqNumber) */ 3543 3544 mlo_ie_len = lim_calculate_auth_mlo_ie_len(mac_ctx, session, peer_addr); 3545 3546 if (mlo_ie_len) { 3547 mlo_ie_buf = qdf_mem_malloc(mlo_ie_len); 3548 if (mlo_ie_buf) { 3549 qdf_status = lim_fill_complete_mlo_ie(session, 3550 mlo_ie_len, 3551 mlo_ie_buf); 3552 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3553 mlo_ie_len = 0; 3554 qdf_mem_free(mlo_ie_buf); 3555 } 3556 3557 frame_len += mlo_ie_len; 3558 } 3559 } 3560 alloc_packet: 3561 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame, 3562 (void **)&packet); 3563 3564 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3565 pe_err("call to bufAlloc failed for AUTH frame"); 3566 return; 3567 } 3568 3569 qdf_mem_zero(frame, frame_len); 3570 3571 /* Prepare BD */ 3572 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 3573 SIR_MAC_MGMT_AUTH, peer_addr, session->self_mac_addr); 3574 mac_hdr = (tpSirMacMgmtHdr) frame; 3575 if (wep_challenge_len) 3576 mac_hdr->fc.wep = LIM_WEP_IN_FC; 3577 else 3578 mac_hdr->fc.wep = LIM_NO_WEP_IN_FC; 3579 3580 /* Prepare BSSId */ 3581 if (LIM_IS_AP_ROLE(session)) 3582 qdf_mem_copy((uint8_t *) mac_hdr->bssId, 3583 (uint8_t *) session->bssId, 3584 sizeof(tSirMacAddr)); 3585 3586 /* Prepare Authentication frame body */ 3587 body = frame + sizeof(tSirMacMgmtHdr); 3588 3589 if (wep_challenge_len) { 3590 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len); 3591 } else { 3592 *((uint16_t *) (body)) = 3593 sir_swap_u16if_needed(auth_frame->authAlgoNumber); 3594 body += sizeof(uint16_t); 3595 body_len -= sizeof(uint16_t); 3596 3597 *((uint16_t *) (body)) = 3598 sir_swap_u16if_needed( 3599 auth_frame->authTransactionSeqNumber); 3600 body += sizeof(uint16_t); 3601 body_len -= sizeof(uint16_t); 3602 3603 *((uint16_t *) (body)) = 3604 sir_swap_u16if_needed(auth_frame->authStatusCode); 3605 body += sizeof(uint16_t); 3606 body_len -= sizeof(uint16_t); 3607 3608 if (challenge_req) { 3609 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) { 3610 /* copy challenge IE id, len, challenge text */ 3611 *body = auth_frame->type; 3612 body++; 3613 body_len -= sizeof(uint8_t); 3614 *body = auth_frame->length; 3615 body++; 3616 body_len -= sizeof(uint8_t); 3617 qdf_mem_copy(body, auth_frame->challengeText, 3618 body_len); 3619 pe_err("Incomplete challenge info: length: %d, expected: %d", 3620 body_len, 3621 SIR_MAC_AUTH_CHALLENGE_BODY_LEN); 3622 body += body_len; 3623 body_len = 0; 3624 } else { 3625 /* copy challenge IE id, len, challenge text */ 3626 *body = auth_frame->type; 3627 body++; 3628 *body = auth_frame->length; 3629 body++; 3630 qdf_mem_copy(body, auth_frame->challengeText, 3631 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH); 3632 body += SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH; 3633 body_len -= SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + 3634 SIR_MAC_CHALLENGE_ID_LEN; 3635 } 3636 } 3637 3638 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) && 3639 (auth_frame->authTransactionSeqNumber == 3640 SIR_MAC_AUTH_FRAME_1) && 3641 (session->ftPEContext.pFTPreAuthReq)) { 3642 3643 if (ft_ies_length > 0) { 3644 qdf_mem_copy(body, 3645 session->ftPEContext. 3646 pFTPreAuthReq->ft_ies, 3647 ft_ies_length); 3648 pe_debug("Auth1 Frame FTIE is: "); 3649 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, 3650 QDF_TRACE_LEVEL_DEBUG, 3651 (uint8_t *) body, 3652 ft_ies_length); 3653 } else if (session->ftPEContext. 3654 pFTPreAuthReq->pbssDescription) { 3655 /* MDID attr is 54 */ 3656 *body = WLAN_ELEMID_MOBILITY_DOMAIN; 3657 body++; 3658 *body = SIR_MDIE_SIZE; 3659 body++; 3660 qdf_mem_copy(body, 3661 &session->ftPEContext.pFTPreAuthReq-> 3662 pbssDescription->mdie[0], 3663 SIR_MDIE_SIZE); 3664 } 3665 } else if ((auth_frame->authAlgoNumber == 3666 SIR_FILS_SK_WITHOUT_PFS) && 3667 (auth_frame->authTransactionSeqNumber == 3668 SIR_MAC_AUTH_FRAME_1)) { 3669 pe_debug("FILS: appending fils Auth data"); 3670 lim_add_fils_data_to_auth_frame(session, body); 3671 } 3672 } 3673 3674 if (mlo_ie_len && mlo_ie_buf) { 3675 qdf_mem_copy(body, mlo_ie_buf, mlo_ie_len); 3676 qdf_mem_free(mlo_ie_buf); 3677 } 3678 3679 pe_nofl_info("Auth TX: vdev %d seq %d seq num %d status %d WEP %d to " QDF_MAC_ADDR_FMT, 3680 vdev_id, auth_frame->authTransactionSeqNumber, 3681 mac_ctx->mgmtSeqNum, auth_frame->authStatusCode, 3682 mac_hdr->fc.wep, QDF_MAC_ADDR_REF(mac_hdr->da)); 3683 3684 if ((session->ftPEContext.pFTPreAuthReq) && 3685 (!wlan_reg_is_24ghz_ch_freq( 3686 session->ftPEContext.pFTPreAuthReq->pre_auth_channel_freq))) 3687 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 3688 else if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 3689 session->opmode == QDF_P2P_CLIENT_MODE || 3690 session->opmode == QDF_P2P_GO_MODE) 3691 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 3692 3693 if (session->opmode == QDF_P2P_CLIENT_MODE || 3694 session->opmode == QDF_STA_MODE) 3695 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK; 3696 3697 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 3698 session->peSessionId, mac_hdr->fc.subType)); 3699 3700 if (mac_ctx->auth_ack_status != LIM_ACK_RCD_FAILURE && 3701 mac_ctx->auth_ack_status != LIM_TX_FAILED) 3702 mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; 3703 min_rid = lim_get_min_session_txrate(session, NULL); 3704 peer_rssi = mac_ctx->lim.bss_rssi; 3705 lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr, 3706 session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 3707 3708 if (session->ftPEContext.pFTPreAuthReq) 3709 ch_freq_tx_frame = session->ftPEContext. 3710 pFTPreAuthReq->pre_auth_channel_freq; 3711 3712 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet, 3713 (uint16_t)frame_len, 3714 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 3715 7, lim_tx_complete, frame, 3716 lim_auth_tx_complete_cnf, 3717 tx_flag, vdev_id, false, 3718 ch_freq_tx_frame, min_rid, peer_rssi, 0); 3719 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 3720 session->peSessionId, qdf_status)); 3721 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3722 pe_err("*** Could not send Auth frame, retCode=%X ***", 3723 qdf_status); 3724 mac_ctx->auth_ack_status = LIM_TX_FAILED; 3725 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT, 3726 session, SENT_FAIL, QDF_STATUS_E_FAILURE); 3727 /* Pkt will be freed up by the callback */ 3728 } 3729 return; 3730 } 3731 3732 static 3733 void lim_delete_deauth_all_pending_sta(struct mac_context *mac_ctx, 3734 struct pe_session *session) 3735 { 3736 int i = 0; 3737 tpDphHashNode sta_ds = NULL; 3738 3739 if (!session) 3740 return; 3741 3742 for (i = 0; i < session->dph.dphHashTable.size; i++) { 3743 sta_ds = dph_get_hash_entry(mac_ctx, i, 3744 &session->dph.dphHashTable); 3745 /* 3746 * In case of multiple STA kickout on SAP interface, 3747 * DeauthAckTimer would be started only for the first 3748 * deauth queued. So, the ack timeout would not be 3749 * fired for other deauth frames. Therefore as part of 3750 * of this timer expiry(of first queued deauth), trigger 3751 * sta deletion for all the peers with deauth in progress. 3752 * 3753 * Do not trigger deletion if sta_deletion is already in 3754 * progress. 3755 */ 3756 3757 if (!sta_ds || !sta_ds->valid || 3758 sta_ds->sta_deletion_in_progress || 3759 !sta_ds->is_disassoc_deauth_in_progress) 3760 continue; 3761 3762 sta_ds->is_disassoc_deauth_in_progress = 0; 3763 lim_trigger_sta_deletion(mac_ctx, sta_ds, session); 3764 } 3765 } 3766 3767 QDF_STATUS lim_send_deauth_cnf(struct mac_context *mac_ctx, uint8_t vdev_id) 3768 { 3769 uint16_t aid; 3770 tpDphHashNode sta_ds; 3771 tLimMlmDeauthReq *deauth_req; 3772 tLimMlmDeauthCnf deauth_cnf; 3773 struct pe_session *session_entry; 3774 QDF_STATUS qdf_status; 3775 uint32_t i; 3776 3777 deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; 3778 if (deauth_req) { 3779 if (tx_timer_running( 3780 &mac_ctx->lim.lim_timers.gLimDeauthAckTimer)) 3781 lim_deactivate_and_change_timer(mac_ctx, 3782 eLIM_DEAUTH_ACK_TIMER); 3783 3784 session_entry = pe_find_session_by_session_id(mac_ctx, 3785 deauth_req->sessionId); 3786 if (!session_entry) { 3787 pe_err("session does not exist for given sessionId"); 3788 deauth_cnf.resultCode = 3789 eSIR_SME_INVALID_PARAMETERS; 3790 goto end; 3791 } 3792 if (qdf_is_macaddr_broadcast(&deauth_req->peer_macaddr) && 3793 mac_ctx->mlme_cfg->sap_cfg.is_sap_bcast_deauth_enabled) { 3794 if (wlan_vdev_mlme_is_mlo_ap(session_entry->vdev)) { 3795 for (i = 1; 3796 i < session_entry->dph.dphHashTable.size; 3797 i++) { 3798 sta_ds = dph_get_hash_entry( 3799 mac_ctx, i, 3800 &session_entry->dph.dphHashTable); 3801 if (!sta_ds) 3802 continue; 3803 if (lim_is_mlo_conn(session_entry, 3804 sta_ds)) 3805 lim_mlo_notify_peer_disconn( 3806 session_entry, 3807 sta_ds); 3808 } 3809 } 3810 qdf_status = lim_del_sta_all(mac_ctx, session_entry); 3811 qdf_mem_free(deauth_req); 3812 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = 3813 NULL; 3814 return qdf_status; 3815 } 3816 3817 sta_ds = 3818 dph_lookup_hash_entry(mac_ctx, 3819 deauth_req->peer_macaddr.bytes, 3820 &aid, 3821 &session_entry-> 3822 dph.dphHashTable); 3823 if (!sta_ds) { 3824 deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 3825 goto end; 3826 } 3827 3828 lim_mlo_notify_peer_disconn(session_entry, sta_ds); 3829 3830 /* / Receive path cleanup with dummy packet */ 3831 lim_ft_cleanup_pre_auth_info(mac_ctx, session_entry); 3832 lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry, true); 3833 if ((session_entry->limSystemRole == eLIM_STA_ROLE) && 3834 ( 3835 #ifdef FEATURE_WLAN_ESE 3836 (wlan_cm_get_ese_assoc(mac_ctx->pdev, 3837 session_entry->vdev_id)) || 3838 #endif 3839 (cm_is_fast_roam_enabled(mac_ctx->psoc)) || 3840 (session_entry->is11Rconnection))) { 3841 pe_debug("FT Preauth (%pK,%d) Deauth rc %d src = %d", 3842 session_entry, 3843 session_entry->peSessionId, 3844 deauth_req->reasonCode, 3845 deauth_req->deauthTrigger); 3846 lim_ft_cleanup(mac_ctx, session_entry); 3847 } else { 3848 #ifdef FEATURE_WLAN_ESE 3849 pe_debug("No FT Preauth Session Cleanup in role %d" 3850 " isESE %d" 3851 " isLFR %d" 3852 " is11r %d, Deauth reason %d Trigger = %d", 3853 session_entry->limSystemRole, 3854 mac_ctx->mlme_cfg->lfr.ese_enabled, 3855 cm_is_fast_roam_enabled(mac_ctx->psoc), 3856 session_entry->is11Rconnection, 3857 deauth_req->reasonCode, 3858 deauth_req->deauthTrigger); 3859 #else 3860 pe_debug("No FT Preauth Session Cleanup in role %d" 3861 " isLFR %d" 3862 " is11r %d, Deauth reason %d Trigger = %d", 3863 session_entry->limSystemRole, 3864 cm_is_fast_roam_enabled(mac_ctx->psoc), 3865 session_entry->is11Rconnection, 3866 deauth_req->reasonCode, 3867 deauth_req->deauthTrigger); 3868 #endif 3869 } 3870 /* Free up buffer allocated for mlmDeauthReq */ 3871 qdf_mem_free(deauth_req); 3872 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL; 3873 } else { 3874 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 3875 if (!session_entry || (session_entry->opmode != QDF_SAP_MODE && 3876 session_entry->opmode !=QDF_P2P_GO_MODE)) 3877 return QDF_STATUS_SUCCESS; 3878 /* 3879 * If deauth request is not present, then the deauth could 3880 * be from the SB STA kickout queued in SAP context. 3881 * Cleanup all the STA which has is_disassoc_deauth_in_progress 3882 */ 3883 lim_delete_deauth_all_pending_sta(mac_ctx, session_entry); 3884 } 3885 return QDF_STATUS_SUCCESS; 3886 end: 3887 qdf_copy_macaddr(&deauth_cnf.peer_macaddr, 3888 &deauth_req->peer_macaddr); 3889 deauth_cnf.deauthTrigger = deauth_req->deauthTrigger; 3890 deauth_cnf.aid = deauth_req->aid; 3891 deauth_cnf.sessionId = deauth_req->sessionId; 3892 3893 /* Free up buffer allocated */ 3894 /* for mlmDeauthReq */ 3895 qdf_mem_free(deauth_req); 3896 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL; 3897 3898 lim_post_sme_message(mac_ctx, 3899 LIM_MLM_DEAUTH_CNF, (uint32_t *) &deauth_cnf); 3900 return QDF_STATUS_SUCCESS; 3901 } 3902 3903 /** 3904 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME 3905 * 3906 * @mac_ctx: Handle to MAC context 3907 * 3908 * Sends disassoc confirmation to SME. Removes disassoc request stored 3909 * in lim. 3910 * 3911 * Return: QDF_STATUS_SUCCESS 3912 */ 3913 3914 QDF_STATUS lim_send_disassoc_cnf(struct mac_context *mac_ctx) 3915 { 3916 uint16_t aid; 3917 tpDphHashNode sta_ds; 3918 tLimMlmDisassocCnf disassoc_cnf; 3919 struct pe_session *pe_session; 3920 tLimMlmDisassocReq *disassoc_req; 3921 3922 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; 3923 if (disassoc_req) { 3924 if (tx_timer_running( 3925 &mac_ctx->lim.lim_timers.gLimDisassocAckTimer)) 3926 lim_deactivate_and_change_timer(mac_ctx, 3927 eLIM_DISASSOC_ACK_TIMER); 3928 3929 pe_session = pe_find_session_by_session_id( 3930 mac_ctx, disassoc_req->sessionId); 3931 if (!pe_session) { 3932 pe_err("No session for given sessionId"); 3933 disassoc_cnf.resultCode = 3934 eSIR_SME_INVALID_PARAMETERS; 3935 goto end; 3936 } 3937 3938 sta_ds = dph_lookup_hash_entry(mac_ctx, 3939 disassoc_req->peer_macaddr.bytes, &aid, 3940 &pe_session->dph.dphHashTable); 3941 if (!sta_ds) { 3942 pe_err("StaDs Null"); 3943 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 3944 goto end; 3945 } 3946 3947 lim_mlo_notify_peer_disconn(pe_session, sta_ds); 3948 3949 /* Receive path cleanup with dummy packet */ 3950 if (QDF_STATUS_SUCCESS != 3951 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session, true)) { 3952 disassoc_cnf.resultCode = 3953 eSIR_SME_RESOURCES_UNAVAILABLE; 3954 pe_err("cleanup_rx_path error"); 3955 goto end; 3956 } 3957 if (LIM_IS_STA_ROLE(pe_session) && 3958 (disassoc_req->reasonCode != 3959 REASON_AUTHORIZED_ACCESS_LIMIT_REACHED)) { 3960 pe_debug("FT Preauth Session (%pK %d) Clean up", 3961 pe_session, pe_session->peSessionId); 3962 3963 /* Delete FT session if there exists one */ 3964 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session); 3965 } 3966 /* Free up buffer allocated for mlmDisassocReq */ 3967 qdf_mem_free(disassoc_req); 3968 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; 3969 return QDF_STATUS_SUCCESS; 3970 } else { 3971 return QDF_STATUS_SUCCESS; 3972 } 3973 end: 3974 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr, 3975 (uint8_t *) disassoc_req->peer_macaddr.bytes, 3976 QDF_MAC_ADDR_SIZE); 3977 disassoc_cnf.aid = disassoc_req->aid; 3978 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger; 3979 3980 /* Update PE session ID */ 3981 disassoc_cnf.sessionId = disassoc_req->sessionId; 3982 3983 if (disassoc_req) { 3984 /* / Free up buffer allocated for mlmDisassocReq */ 3985 qdf_mem_free(disassoc_req); 3986 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; 3987 } 3988 3989 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF, 3990 (uint32_t *) &disassoc_cnf); 3991 return QDF_STATUS_SUCCESS; 3992 } 3993 3994 QDF_STATUS lim_disassoc_tx_complete_cnf(void *context, 3995 uint32_t tx_success, 3996 void *params) 3997 { 3998 struct mac_context *max_ctx = (struct mac_context *)context; 3999 4000 pe_debug("tx_success: %d", tx_success); 4001 4002 return lim_send_disassoc_cnf(max_ctx); 4003 } 4004 4005 static QDF_STATUS lim_disassoc_tx_complete_cnf_handler(void *context, 4006 qdf_nbuf_t buf, 4007 uint32_t tx_success, 4008 void *params) 4009 { 4010 struct mac_context *max_ctx = (struct mac_context *)context; 4011 QDF_STATUS status_code; 4012 struct scheduler_msg msg = {0}; 4013 4014 if (params) 4015 wlan_send_tx_complete_event(context, buf, params, tx_success, 4016 WLAN_DISASSOC_TX); 4017 4018 pe_debug("tx_success: %d", tx_success); 4019 4020 if (buf) 4021 qdf_nbuf_free(buf); 4022 msg.type = (uint16_t) WMA_DISASSOC_TX_COMP; 4023 msg.bodyptr = params; 4024 msg.bodyval = tx_success; 4025 4026 status_code = lim_post_msg_high_priority(max_ctx, &msg); 4027 if (status_code != QDF_STATUS_SUCCESS) 4028 pe_err("posting message: %X to LIM failed, reason: %d", 4029 msg.type, status_code); 4030 return status_code; 4031 } 4032 4033 QDF_STATUS lim_deauth_tx_complete_cnf(void *context, 4034 uint32_t tx_success, 4035 void *params) 4036 { 4037 struct mac_context *mac_ctx = (struct mac_context *)context; 4038 struct wmi_mgmt_params *mgmt_params = 4039 (struct wmi_mgmt_params *)params; 4040 uint8_t vdev_id = WLAN_INVALID_VDEV_ID; 4041 4042 pe_debug("tx_success: %d", tx_success); 4043 if (mgmt_params) 4044 vdev_id = mgmt_params->vdev_id; 4045 4046 return lim_send_deauth_cnf(mac_ctx, vdev_id); 4047 } 4048 4049 static QDF_STATUS lim_ap_delete_sta_upon_deauth_tx(struct mac_context *mac_ctx, 4050 struct pe_session *session, 4051 tSirMacAddr peer) 4052 { 4053 tpDphHashNode stads; 4054 uint16_t aid; 4055 4056 if (!session || (session->opmode != QDF_SAP_MODE && 4057 session->opmode != QDF_P2P_GO_MODE)) 4058 return QDF_STATUS_E_FAILURE; 4059 4060 stads = dph_lookup_hash_entry(mac_ctx, peer, &aid, 4061 &session->dph.dphHashTable); 4062 4063 if (!stads || !stads->ocv_enabled || 4064 stads->last_ocv_done_freq == session->curr_op_freq) 4065 return QDF_STATUS_E_FAILURE; 4066 4067 /* 4068 * Proceed with sta deletion only if 4069 * is_disassoc_deauth_in_progress is set. If unset, 4070 * sta deletion will be handled by the deauth ack 4071 * timeout handler. 4072 */ 4073 if (!stads->is_disassoc_deauth_in_progress || 4074 stads->sta_deletion_in_progress) 4075 return QDF_STATUS_SUCCESS; 4076 4077 lim_trigger_sta_deletion(mac_ctx, stads, session); 4078 return QDF_STATUS_SUCCESS; 4079 } 4080 4081 static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context, 4082 qdf_nbuf_t buf, 4083 uint32_t tx_success, 4084 void *params) 4085 { 4086 struct mac_context *mac_ctx = (struct mac_context *)context; 4087 QDF_STATUS status_code = QDF_STATUS_E_FAILURE; 4088 struct scheduler_msg msg = {0}; 4089 tLimMlmDeauthReq *deauth_req; 4090 struct pe_session *session = NULL; 4091 tSirMacMgmtHdr *mac_hdr; 4092 uint8_t vdev_id = WLAN_INVALID_VDEV_ID; 4093 struct wmi_mgmt_params *mgmt_params = 4094 (struct wmi_mgmt_params *)params; 4095 4096 if (params) 4097 wlan_send_tx_complete_event(context, buf, params, tx_success, 4098 WLAN_DEAUTH_TX); 4099 4100 deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; 4101 4102 pe_debug("tx_complete = %s tx_success = %d", 4103 (tx_success == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? 4104 "success" : "fail", tx_success); 4105 4106 if (buf && (qdf_nbuf_len(buf) > sizeof(struct wlan_frame_hdr) + 2)) 4107 mac_hdr = (tSirMacMgmtHdr *)qdf_nbuf_data(buf); 4108 4109 if (!deauth_req && mac_hdr) { 4110 if (mgmt_params) 4111 vdev_id = mgmt_params->vdev_id; 4112 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 4113 status_code = lim_ap_delete_sta_upon_deauth_tx(mac_ctx, session, 4114 (uint8_t *)mac_hdr->da); 4115 } 4116 4117 if (buf) 4118 qdf_nbuf_free(buf); 4119 4120 /* Cleanup has been handled for SAP/GO context, return */ 4121 if (QDF_IS_STATUS_SUCCESS(status_code)) 4122 return QDF_STATUS_SUCCESS; 4123 4124 if (deauth_req) 4125 session = pe_find_session_by_session_id(mac_ctx, 4126 deauth_req->sessionId); 4127 if (tx_success != WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK && session && 4128 session->deauth_retry.retry_cnt) { 4129 if (tx_timer_running( 4130 &mac_ctx->lim.lim_timers.gLimDeauthAckTimer)) 4131 lim_deactivate_and_change_timer(mac_ctx, 4132 eLIM_DEAUTH_ACK_TIMER); 4133 lim_send_deauth_mgmt_frame(mac_ctx, 4134 session->deauth_retry.reason_code, 4135 session->deauth_retry.peer_macaddr.bytes, 4136 session, true); 4137 session->deauth_retry.retry_cnt--; 4138 return QDF_STATUS_SUCCESS; 4139 } 4140 msg.type = (uint16_t) WMA_DEAUTH_TX_COMP; 4141 msg.bodyptr = params; 4142 msg.bodyval = tx_success; 4143 4144 status_code = lim_post_msg_high_priority(mac_ctx, &msg); 4145 if (status_code != QDF_STATUS_SUCCESS) 4146 pe_err("posting message: %X to LIM failed, reason: %d", 4147 msg.type, status_code); 4148 return status_code; 4149 } 4150 4151 /** 4152 * lim_append_ies_to_frame() - Append IEs to the frame 4153 * 4154 * @frame: Pointer to the frame buffer that needs to be populated 4155 * @frame_len: Pointer for current frame length 4156 * @ie: pointer for disconnect IEs 4157 * 4158 * This function is called by lim_send_disassoc_mgmt_frame and 4159 * lim_send_deauth_mgmt_frame APIs as part of disconnection. 4160 * Append IEs and update frame length. 4161 * 4162 * Return: None 4163 */ 4164 static void 4165 lim_append_ies_to_frame(uint8_t *frame, uint32_t *frame_len, 4166 struct element_info *ie) 4167 { 4168 if (!ie || !ie->len || !ie->ptr) 4169 return; 4170 qdf_mem_copy(frame, ie->ptr, ie->len); 4171 *frame_len += ie->len; 4172 pe_debug("Appended IEs len: %u", ie->len); 4173 } 4174 4175 /** 4176 * \brief This function is called to send Disassociate frame. 4177 * 4178 * 4179 * \param mac Pointer to Global MAC structure 4180 * 4181 * \param nReason Indicates the reason that need to be sent in 4182 * Disassociation frame 4183 * 4184 * \param peerMacAddr MAC address of the STA to which Disassociation frame is 4185 * sent 4186 * 4187 * 4188 */ 4189 4190 void 4191 lim_send_disassoc_mgmt_frame(struct mac_context *mac, 4192 uint16_t nReason, 4193 tSirMacAddr peer, 4194 struct pe_session *pe_session, bool waitForAck) 4195 { 4196 tDot11fDisassociation frm; 4197 uint8_t *pFrame; 4198 tpSirMacMgmtHdr pMacHdr; 4199 uint32_t nBytes, nPayload, nStatus; 4200 void *pPacket; 4201 QDF_STATUS qdf_status; 4202 uint8_t txFlag = 0; 4203 uint32_t val = 0; 4204 uint8_t smeSessionId = 0; 4205 struct element_info *discon_ie; 4206 4207 if (!pe_session) { 4208 return; 4209 } 4210 4211 /* 4212 * In case when cac timer is running for this SAP session then 4213 * avoid sending disassoc out. It is violation of dfs specification. 4214 */ 4215 if (((pe_session->opmode == QDF_SAP_MODE) || 4216 (pe_session->opmode == QDF_P2P_GO_MODE)) && 4217 (true == mac->sap.SapDfsInfo.is_dfs_cac_timer_running)) { 4218 pe_info("CAC timer is running, drop disassoc from going out"); 4219 if (waitForAck) 4220 lim_send_disassoc_cnf(mac); 4221 return; 4222 } else if (lim_is_ml_peer_state_disconn(mac, pe_session, peer)) { 4223 /** 4224 * Check if disassoc is already sent on link vdev and ML peer 4225 * state is moved to ML_PEER_DISCONN_INITIATED. In which case, 4226 * do not send disassoc on assoc vdev, issue disassoc only if 4227 * this check fails. 4228 */ 4229 pe_debug("disassoc tx not required for vdev id %d", 4230 pe_session->vdev_id); 4231 lim_send_disassoc_cnf(mac); 4232 return; 4233 } 4234 smeSessionId = pe_session->smeSessionId; 4235 4236 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 4237 4238 frm.Reason.code = nReason; 4239 4240 nStatus = dot11f_get_packed_disassociation_size(mac, &frm, &nPayload); 4241 if (DOT11F_FAILED(nStatus)) { 4242 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)", 4243 nStatus); 4244 /* We'll fall back on the worst case scenario: */ 4245 nPayload = sizeof(tDot11fDisassociation); 4246 } else if (DOT11F_WARNED(nStatus)) { 4247 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)", 4248 nStatus); 4249 } 4250 4251 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 4252 4253 discon_ie = mlme_get_self_disconnect_ies(pe_session->vdev); 4254 if (discon_ie && discon_ie->len) 4255 nBytes += discon_ie->len; 4256 4257 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 4258 (void **)&pPacket); 4259 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4260 pe_err("Failed to allocate %d bytes for a Disassociation", 4261 nBytes); 4262 if (waitForAck) 4263 lim_send_disassoc_cnf(mac); 4264 return; 4265 } 4266 /* Paranoia: */ 4267 qdf_mem_zero(pFrame, nBytes); 4268 4269 /* Next, we fill out the buffer descriptor: */ 4270 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 4271 SIR_MAC_MGMT_DISASSOC, peer, pe_session->self_mac_addr); 4272 pMacHdr = (tpSirMacMgmtHdr) pFrame; 4273 4274 /* Prepare the BSSID */ 4275 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 4276 4277 if (mac->is_usr_cfg_pmf_wep != PMF_WEP_DISABLE) 4278 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 4279 else 4280 pe_debug("Skip WEP bit setting per usr cfg"); 4281 4282 if (mac->is_usr_cfg_pmf_wep == PMF_INCORRECT_KEY) 4283 txFlag |= HAL_USE_INCORRECT_KEY_PMF; 4284 4285 nStatus = dot11f_pack_disassociation(mac, &frm, pFrame + 4286 sizeof(tSirMacMgmtHdr), 4287 nPayload, &nPayload); 4288 if (DOT11F_FAILED(nStatus)) { 4289 pe_err("Failed to pack a Disassociation (0x%08x)", 4290 nStatus); 4291 cds_packet_free((void *)pPacket); 4292 if (waitForAck) 4293 lim_send_disassoc_cnf(mac); 4294 return; 4295 } else if (DOT11F_WARNED(nStatus)) { 4296 pe_warn("There were warnings while packing a Disassociation (0x%08x)", 4297 nStatus); 4298 } 4299 4300 /* Copy disconnect IEs to the end of the frame */ 4301 lim_append_ies_to_frame(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, 4302 &nPayload, discon_ie); 4303 mlme_free_self_disconnect_ies(pe_session->vdev); 4304 4305 pe_nofl_info("Disassoc TX: vdev %d seq %d reason %u and waitForAck %d to " QDF_MAC_ADDR_FMT " From " QDF_MAC_ADDR_FMT, 4306 pe_session->vdev_id, mac->mgmtSeqNum, nReason, waitForAck, 4307 QDF_MAC_ADDR_REF(pMacHdr->da), 4308 QDF_MAC_ADDR_REF(pe_session->self_mac_addr)); 4309 4310 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 4311 pe_session->opmode == QDF_P2P_CLIENT_MODE || 4312 pe_session->opmode == QDF_P2P_GO_MODE) 4313 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 4314 4315 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; 4316 4317 pe_session->deauth_disassoc_rc = nReason; 4318 if (waitForAck) { 4319 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4320 pe_session->peSessionId, 4321 pMacHdr->fc.subType)); 4322 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 4323 pe_session, QDF_STATUS_SUCCESS, 4324 QDF_STATUS_SUCCESS); 4325 4326 /* Queue Disassociation frame in high priority WQ */ 4327 /* get the duration from the request */ 4328 qdf_status = 4329 wma_tx_frameWithTxComplete(mac, pPacket, (uint16_t) nBytes, 4330 TXRX_FRM_802_11_MGMT, 4331 ANI_TXDIR_TODS, 7, lim_tx_complete, 4332 pFrame, lim_disassoc_tx_complete_cnf_handler, 4333 txFlag, smeSessionId, false, 0, 4334 RATEID_DEFAULT, 0, 0); 4335 MTRACE(qdf_trace 4336 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 4337 pe_session->peSessionId, qdf_status)); 4338 4339 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4340 pe_err("Failed to send disassoc frame"); 4341 lim_send_disassoc_cnf(mac); 4342 return; 4343 } 4344 4345 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); 4346 4347 if (tx_timer_change 4348 (&mac->lim.lim_timers.gLimDisassocAckTimer, val, 0) 4349 != TX_SUCCESS) { 4350 pe_err("Unable to change Disassoc ack Timer val"); 4351 return; 4352 } else if (TX_SUCCESS != 4353 tx_timer_activate(&mac->lim.lim_timers. 4354 gLimDisassocAckTimer)) { 4355 pe_err("Unable to activate Disassoc ack Timer"); 4356 lim_deactivate_and_change_timer(mac, 4357 eLIM_DISASSOC_ACK_TIMER); 4358 return; 4359 } 4360 } else { 4361 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4362 pe_session->peSessionId, 4363 pMacHdr->fc.subType)); 4364 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 4365 pe_session, 4366 QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 4367 wlan_connectivity_mgmt_event(mac->psoc, 4368 (struct wlan_frame_hdr *)pMacHdr, 4369 pe_session->vdev_id, nReason, 4370 QDF_TX_RX_STATUS_OK, 4371 mac->lim.bss_rssi, 0, 0, 0, 0, 4372 WLAN_DISASSOC_TX); 4373 4374 /* Queue Disassociation frame in high priority WQ */ 4375 qdf_status = wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 4376 TXRX_FRM_802_11_MGMT, 4377 ANI_TXDIR_TODS, 4378 7, 4379 lim_tx_complete, pFrame, txFlag, 4380 smeSessionId, 0, RATEID_DEFAULT, 0); 4381 MTRACE(qdf_trace 4382 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 4383 pe_session->peSessionId, qdf_status)); 4384 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4385 pe_err("Failed to send Disassociation (%X)!", 4386 qdf_status); 4387 /* Pkt will be freed up by the callback */ 4388 } 4389 } 4390 } /* End lim_send_disassoc_mgmt_frame. */ 4391 4392 /** 4393 * \brief This function is called to send a Deauthenticate frame 4394 * 4395 * 4396 * \param mac Pointer to global MAC structure 4397 * 4398 * \param nReason Indicates the reason that need to be sent in the 4399 * Deauthenticate frame 4400 * 4401 * \param peer address of the STA to which the frame is to be sent 4402 * 4403 * 4404 */ 4405 4406 void 4407 lim_send_deauth_mgmt_frame(struct mac_context *mac, 4408 uint16_t nReason, 4409 tSirMacAddr peer, 4410 struct pe_session *pe_session, bool waitForAck) 4411 { 4412 tDot11fDeAuth frm; 4413 uint8_t *pFrame; 4414 tpSirMacMgmtHdr pMacHdr; 4415 uint32_t nBytes, nPayload, nStatus; 4416 void *pPacket; 4417 QDF_STATUS qdf_status; 4418 uint8_t txFlag = 0; 4419 uint32_t val = 0; 4420 #ifdef FEATURE_WLAN_TDLS 4421 uint16_t aid; 4422 tpDphHashNode sta; 4423 #endif 4424 uint8_t smeSessionId = 0; 4425 struct element_info *discon_ie; 4426 bool drop_deauth = false; 4427 4428 if (!pe_session) { 4429 return; 4430 } 4431 4432 /* 4433 * Avoid sending deauth frame out when 4434 * 1. CAC timer is running for this SAP session, 4435 * It is avoid violation of dfs specification. 4436 * 2. Silent deauth is requested for a particular peer 4437 */ 4438 if ((pe_session->opmode == QDF_SAP_MODE) || 4439 (pe_session->opmode == QDF_P2P_GO_MODE)) { 4440 if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) { 4441 pe_info("CAC timer is running, drop the deauth from going out"); 4442 drop_deauth = true; 4443 } 4444 if (nReason == REASON_HOST_TRIGGERED_SILENT_DEAUTH) { 4445 pe_info("Silent deauth, remove the peer"); 4446 drop_deauth = true; 4447 } 4448 if (drop_deauth) { 4449 if (waitForAck) 4450 lim_send_deauth_cnf(mac, pe_session->vdev_id); 4451 return; 4452 } 4453 } else if (lim_is_ml_peer_state_disconn(mac, pe_session, peer)) { 4454 /** 4455 * Check if deauth is already sent on link vdev and ML peer 4456 * state is moved to ML_PEER_DISCONN_INITIATED. In which case, 4457 * do not send deauth on assoc vdev as well. Issue deauth only 4458 * if this check fails. 4459 */ 4460 pe_debug("Deauth tx not required for vdev id %d", 4461 pe_session->vdev_id); 4462 lim_send_deauth_cnf(mac, pe_session->vdev_id); 4463 return; 4464 } 4465 smeSessionId = pe_session->smeSessionId; 4466 4467 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 4468 4469 frm.Reason.code = nReason; 4470 4471 nStatus = dot11f_get_packed_de_auth_size(mac, &frm, &nPayload); 4472 if (DOT11F_FAILED(nStatus)) { 4473 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)", 4474 nStatus); 4475 /* We'll fall back on the worst case scenario: */ 4476 nPayload = sizeof(tDot11fDeAuth); 4477 } else if (DOT11F_WARNED(nStatus)) { 4478 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)", 4479 nStatus); 4480 } 4481 4482 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 4483 discon_ie = mlme_get_self_disconnect_ies(pe_session->vdev); 4484 if (discon_ie && discon_ie->len) 4485 nBytes += discon_ie->len; 4486 4487 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 4488 (void **)&pPacket); 4489 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4490 pe_err("Failed to allocate %d bytes for a De-Authentication", 4491 nBytes); 4492 if (waitForAck) 4493 lim_send_deauth_cnf(mac, pe_session->vdev_id); 4494 return; 4495 } 4496 /* Paranoia: */ 4497 qdf_mem_zero(pFrame, nBytes); 4498 4499 /* Next, we fill out the buffer descriptor: */ 4500 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 4501 SIR_MAC_MGMT_DEAUTH, peer, pe_session->self_mac_addr); 4502 pMacHdr = (tpSirMacMgmtHdr) pFrame; 4503 4504 /* Prepare the BSSID */ 4505 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 4506 4507 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 4508 4509 nStatus = dot11f_pack_de_auth(mac, &frm, pFrame + 4510 sizeof(tSirMacMgmtHdr), nPayload, &nPayload); 4511 if (DOT11F_FAILED(nStatus)) { 4512 pe_err("Failed to pack a DeAuthentication (0x%08x)", 4513 nStatus); 4514 cds_packet_free((void *)pPacket); 4515 if (waitForAck) 4516 lim_send_deauth_cnf(mac, pe_session->vdev_id); 4517 return; 4518 } else if (DOT11F_WARNED(nStatus)) { 4519 pe_warn("There were warnings while packing a De-Authentication (0x%08x)", 4520 nStatus); 4521 } 4522 4523 /* Copy disconnect IEs to the end of the frame */ 4524 lim_append_ies_to_frame(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, 4525 &nPayload, discon_ie); 4526 mlme_free_self_disconnect_ies(pe_session->vdev); 4527 4528 pe_nofl_rl_info("Deauth TX: vdev %d seq_num %d reason %u waitForAck %d to " QDF_MAC_ADDR_FMT " from " QDF_MAC_ADDR_FMT, 4529 pe_session->vdev_id, mac->mgmtSeqNum, nReason, waitForAck, 4530 QDF_MAC_ADDR_REF(pMacHdr->da), 4531 QDF_MAC_ADDR_REF(pe_session->self_mac_addr)); 4532 4533 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 4534 pe_session->opmode == QDF_P2P_CLIENT_MODE || 4535 pe_session->opmode == QDF_P2P_GO_MODE) 4536 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 4537 4538 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; 4539 #ifdef FEATURE_WLAN_TDLS 4540 sta = 4541 dph_lookup_hash_entry(mac, peer, &aid, 4542 &pe_session->dph.dphHashTable); 4543 #endif 4544 4545 pe_session->deauth_disassoc_rc = nReason; 4546 if (waitForAck) { 4547 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4548 pe_session->peSessionId, 4549 pMacHdr->fc.subType)); 4550 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 4551 pe_session, 4552 QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 4553 if (pe_session->opmode == QDF_STA_MODE && 4554 mac->mlme_cfg->sta.deauth_retry_cnt && 4555 !pe_session->deauth_retry.retry_cnt) { 4556 pe_session->deauth_retry.retry_cnt = 4557 mac->mlme_cfg->sta.deauth_retry_cnt; 4558 pe_session->deauth_retry.reason_code = nReason; 4559 qdf_mem_copy(pe_session->deauth_retry.peer_macaddr.bytes, 4560 peer, QDF_MAC_ADDR_SIZE); 4561 } 4562 4563 /* Queue Disassociation frame in high priority WQ */ 4564 qdf_status = 4565 wma_tx_frameWithTxComplete(mac, pPacket, (uint16_t) nBytes, 4566 TXRX_FRM_802_11_MGMT, 4567 ANI_TXDIR_TODS, 7, lim_tx_complete, 4568 pFrame, lim_deauth_tx_complete_cnf_handler, 4569 txFlag, smeSessionId, false, 0, 4570 RATEID_DEFAULT, 0, 0); 4571 MTRACE(qdf_trace 4572 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 4573 pe_session->peSessionId, qdf_status)); 4574 /* Pkt will be freed up by the callback lim_tx_complete */ 4575 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4576 pe_err("Failed to send De-Authentication (%X)!", 4577 qdf_status); 4578 4579 /* Call lim_process_deauth_ack_timeout which will send 4580 * DeauthCnf for this frame 4581 */ 4582 lim_process_deauth_ack_timeout(mac, 4583 pe_session->peSessionId); 4584 return; 4585 } 4586 4587 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); 4588 if (tx_timer_change_context( 4589 &mac->lim.lim_timers.gLimDeauthAckTimer, 4590 pe_session->vdev_id) != TX_SUCCESS) { 4591 pe_err("Unable to update the vdev id in the Deauth ack timer"); 4592 return; 4593 } else if (tx_timer_change 4594 (&mac->lim.lim_timers.gLimDeauthAckTimer, val, 0) 4595 != TX_SUCCESS) { 4596 pe_err("Unable to change Deauth ack Timer val"); 4597 return; 4598 } else if (TX_SUCCESS != 4599 tx_timer_activate(&mac->lim.lim_timers. 4600 gLimDeauthAckTimer)) { 4601 pe_err("Unable to activate Deauth ack Timer"); 4602 lim_deactivate_and_change_timer(mac, 4603 eLIM_DEAUTH_ACK_TIMER); 4604 return; 4605 } 4606 } else { 4607 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4608 pe_session->peSessionId, 4609 pMacHdr->fc.subType)); 4610 #ifdef FEATURE_WLAN_TDLS 4611 if ((sta) 4612 && (STA_ENTRY_TDLS_PEER == sta->staType)) { 4613 /* Queue Disassociation frame in high priority WQ */ 4614 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 4615 pe_session, 4616 QDF_STATUS_SUCCESS, 4617 QDF_STATUS_SUCCESS); 4618 qdf_status = 4619 wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 4620 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS, 4621 7, lim_tx_complete, pFrame, txFlag, 4622 smeSessionId, 0, RATEID_DEFAULT, 0); 4623 } else { 4624 #endif 4625 lim_diag_mgmt_tx_event_report(mac, pMacHdr, 4626 pe_session, 4627 QDF_STATUS_SUCCESS, 4628 QDF_STATUS_SUCCESS); 4629 4630 wlan_connectivity_mgmt_event(mac->psoc, 4631 (struct wlan_frame_hdr *)pMacHdr, 4632 pe_session->vdev_id, nReason, 4633 QDF_TX_RX_STATUS_OK, 4634 mac->lim.bss_rssi, 0, 0, 0, 0, 4635 WLAN_DEAUTH_TX); 4636 4637 /* Queue Disassociation frame in high priority WQ */ 4638 qdf_status = 4639 wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 4640 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 4641 7, lim_tx_complete, pFrame, txFlag, 4642 smeSessionId, 0, RATEID_DEFAULT, 0); 4643 #ifdef FEATURE_WLAN_TDLS 4644 } 4645 #endif 4646 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 4647 pe_session->peSessionId, qdf_status)); 4648 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4649 pe_err("Failed to send De-Authentication (%X)!", 4650 qdf_status); 4651 /* Pkt will be freed up by the callback */ 4652 } 4653 } 4654 4655 } /* End lim_send_deauth_mgmt_frame. */ 4656 4657 #ifdef ANI_SUPPORT_11H 4658 /** 4659 * \brief Send a Measurement Report Action frame 4660 * 4661 * 4662 * \param mac Pointer to the global MAC structure 4663 * 4664 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame 4665 * 4666 * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else 4667 * 4668 * 4669 */ 4670 4671 QDF_STATUS 4672 lim_send_meas_report_frame(struct mac_context *mac, 4673 tpSirMacMeasReqActionFrame pMeasReqFrame, 4674 tSirMacAddr peer, struct pe_session *pe_session) 4675 { 4676 tDot11fMeasurementReport frm; 4677 uint8_t *pFrame; 4678 QDF_STATUS nSirStatus; 4679 tpSirMacMgmtHdr pMacHdr; 4680 uint32_t nBytes, nPayload, nStatus; 4681 void *pPacket; 4682 QDF_STATUS qdf_status; 4683 4684 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 4685 4686 frm.Category.category = ACTION_CATEGORY_SPECTRUM_MGMT; 4687 frm.Action.action = ACTION_SPCT_MSR_RPRT; 4688 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken; 4689 4690 switch (pMeasReqFrame->measReqIE.measType) { 4691 case SIR_MAC_BASIC_MEASUREMENT_TYPE: 4692 nSirStatus = 4693 populate_dot11f_measurement_report0(mac, pMeasReqFrame, 4694 &frm.MeasurementReport); 4695 break; 4696 case SIR_MAC_CCA_MEASUREMENT_TYPE: 4697 nSirStatus = 4698 populate_dot11f_measurement_report1(mac, pMeasReqFrame, 4699 &frm.MeasurementReport); 4700 break; 4701 case SIR_MAC_RPI_MEASUREMENT_TYPE: 4702 nSirStatus = 4703 populate_dot11f_measurement_report2(mac, pMeasReqFrame, 4704 &frm.MeasurementReport); 4705 break; 4706 default: 4707 pe_err("Unknown measurement type %d in limSendMeasReportFrame", 4708 pMeasReqFrame->measReqIE.measType); 4709 return QDF_STATUS_E_FAILURE; 4710 } 4711 4712 if (QDF_STATUS_SUCCESS != nSirStatus) 4713 return QDF_STATUS_E_FAILURE; 4714 4715 nStatus = dot11f_get_packed_measurement_report_size(mac, &frm, &nPayload); 4716 if (DOT11F_FAILED(nStatus)) { 4717 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)", 4718 nStatus); 4719 /* We'll fall back on the worst case scenario: */ 4720 nPayload = sizeof(tDot11fMeasurementReport); 4721 } else if (DOT11F_WARNED(nStatus)) { 4722 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)", 4723 nStatus); 4724 } 4725 4726 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 4727 4728 qdf_status = 4729 cds_packet_alloc(mac->hdd_handle, TXRX_FRM_802_11_MGMT, 4730 (uint16_t) nBytes, (void **)&pFrame, 4731 (void **)&pPacket); 4732 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4733 pe_err("Failed to allocate %d bytes for a De-Authentication", 4734 nBytes); 4735 return QDF_STATUS_E_FAILURE; 4736 } 4737 /* Paranoia: */ 4738 qdf_mem_zero(pFrame, nBytes); 4739 4740 /* Next, we fill out the buffer descriptor: */ 4741 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 4742 SIR_MAC_MGMT_ACTION, peer); 4743 pMacHdr = (tpSirMacMgmtHdr) pFrame; 4744 4745 qdf_mem_copy(pMacHdr->bssId, pe_session->bssId, sizeof(tSirMacAddr)); 4746 4747 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 4748 4749 nStatus = dot11f_pack_measurement_report(mac, &frm, pFrame + 4750 sizeof(tSirMacMgmtHdr), 4751 nPayload, &nPayload); 4752 if (DOT11F_FAILED(nStatus)) { 4753 pe_err("Failed to pack a Measurement Report (0x%08x)", 4754 nStatus); 4755 cds_packet_free(mac->hdd_handle, TXRX_FRM_802_11_MGMT, 4756 (void *)pFrame, (void *)pPacket); 4757 return QDF_STATUS_E_FAILURE; /* allocated! */ 4758 } else if (DOT11F_WARNED(nStatus)) { 4759 pe_warn("There were warnings while packing a Measurement Report (0x%08x)", 4760 nStatus); 4761 } 4762 4763 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4764 ((pe_session) ? pe_session-> 4765 peSessionId : NO_SESSION), pMacHdr->fc.subType)); 4766 qdf_status = 4767 wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 4768 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 4769 lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT, 0); 4770 MTRACE(qdf_trace 4771 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 4772 ((pe_session) ? pe_session->peSessionId : NO_SESSION), 4773 qdf_status)); 4774 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4775 pe_err("Failed to send a Measurement Report (%X)!", 4776 qdf_status); 4777 /* Pkt will be freed up by the callback */ 4778 return QDF_STATUS_E_FAILURE; /* just allocated... */ 4779 } 4780 4781 return QDF_STATUS_SUCCESS; 4782 4783 } /* End lim_send_meas_report_frame. */ 4784 4785 /** 4786 * \brief Send a TPC Report Action frame 4787 * 4788 * 4789 * \param mac Pointer to the global MAC datastructure 4790 * 4791 * \param pTpcReqFrame Pointer to the received TPC Request 4792 * 4793 * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else 4794 * 4795 * 4796 */ 4797 4798 QDF_STATUS 4799 lim_send_tpc_report_frame(struct mac_context *mac, 4800 tpSirMacTpcReqActionFrame pTpcReqFrame, 4801 tSirMacAddr peer, struct pe_session *pe_session) 4802 { 4803 tDot11fTPCReport frm; 4804 uint8_t *pFrame; 4805 tpSirMacMgmtHdr pMacHdr; 4806 uint32_t nBytes, nPayload, nStatus; 4807 void *pPacket; 4808 QDF_STATUS qdf_status; 4809 struct vdev_mlme_obj *mlme_obj; 4810 4811 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 4812 4813 frm.Category.category = ACTION_CATEGORY_SPECTRUM_MGMT; 4814 frm.Action.action = ACTION_SPCT_TPC_RPRT; 4815 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken; 4816 4817 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); 4818 if (mlme_obj) 4819 frm.TPCReport.tx_power = mlme_obj->mgmt.generic.tx_pwrlimit; 4820 4821 frm.TPCReport.link_margin = 0; 4822 frm.TPCReport.present = 1; 4823 4824 nStatus = dot11f_get_packed_tpc_report_size(mac, &frm, &nPayload); 4825 if (DOT11F_FAILED(nStatus)) { 4826 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus); 4827 /* We'll fall back on the worst case scenario: */ 4828 nPayload = sizeof(tDot11fTPCReport); 4829 } else if (DOT11F_WARNED(nStatus)) { 4830 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)", 4831 nStatus); 4832 } 4833 4834 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 4835 4836 qdf_status = 4837 cds_packet_alloc(mac->hdd_handle, TXRX_FRM_802_11_MGMT, 4838 (uint16_t) nBytes, (void **)&pFrame, 4839 (void **)&pPacket); 4840 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4841 pe_err("Failed to allocate %d bytes for a TPC" 4842 " Report", nBytes); 4843 return QDF_STATUS_E_FAILURE; 4844 } 4845 /* Paranoia: */ 4846 qdf_mem_zero(pFrame, nBytes); 4847 4848 /* Next, we fill out the buffer descriptor: */ 4849 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 4850 SIR_MAC_MGMT_ACTION, peer); 4851 4852 pMacHdr = (tpSirMacMgmtHdr) pFrame; 4853 4854 qdf_mem_copy(pMacHdr->bssId, pe_session->bssId, sizeof(tSirMacAddr)); 4855 4856 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 4857 4858 nStatus = dot11f_pack_tpc_report(mac, &frm, pFrame + 4859 sizeof(tSirMacMgmtHdr), 4860 nPayload, &nPayload); 4861 if (DOT11F_FAILED(nStatus)) { 4862 pe_err("Failed to pack a TPC Report (0x%08x)", 4863 nStatus); 4864 cds_packet_free(mac->hdd_handle, TXRX_FRM_802_11_MGMT, 4865 (void *)pFrame, (void *)pPacket); 4866 return QDF_STATUS_E_FAILURE; /* allocated! */ 4867 } else if (DOT11F_WARNED(nStatus)) { 4868 pe_warn("There were warnings while packing a TPC Report (0x%08x)", 4869 nStatus); 4870 4871 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4872 ((pe_session) ? pe_session-> 4873 peSessionId : NO_SESSION), pMacHdr->fc.subType)); 4874 qdf_status = 4875 wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 4876 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 4877 lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT, 0); 4878 MTRACE(qdf_trace 4879 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 4880 ((pe_session) ? pe_session->peSessionId : NO_SESSION), 4881 qdf_status)); 4882 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4883 pe_err("Failed to send a TPC Report (%X)!", 4884 qdf_status); 4885 /* Pkt will be freed up by the callback */ 4886 return QDF_STATUS_E_FAILURE; /* just allocated... */ 4887 } 4888 4889 return QDF_STATUS_SUCCESS; 4890 4891 } /* End lim_send_tpc_report_frame. */ 4892 #endif /* ANI_SUPPORT_11H */ 4893 4894 /** 4895 * \brief Send a Channel Switch Announcement 4896 * 4897 * 4898 * \param mac Pointer to the global MAC datastructure 4899 * 4900 * \param peer MAC address to which this frame will be sent 4901 * 4902 * \param nMode 4903 * 4904 * \param nNewChannel 4905 * 4906 * \param nCount 4907 * 4908 * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else 4909 * 4910 * 4911 */ 4912 4913 QDF_STATUS 4914 lim_send_channel_switch_mgmt_frame(struct mac_context *mac, 4915 tSirMacAddr peer, 4916 uint8_t nMode, 4917 uint8_t nNewChannel, 4918 uint8_t nCount, struct pe_session *pe_session) 4919 { 4920 tDot11fChannelSwitch frm; 4921 uint8_t *pFrame; 4922 tpSirMacMgmtHdr pMacHdr; 4923 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */ 4924 void *pPacket; 4925 QDF_STATUS qdf_status; 4926 uint8_t txFlag = 0; 4927 4928 uint8_t smeSessionId = 0; 4929 4930 if (!pe_session) { 4931 pe_err("Session entry is NULL!!!"); 4932 return QDF_STATUS_E_FAILURE; 4933 } 4934 smeSessionId = pe_session->smeSessionId; 4935 4936 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 4937 4938 frm.Category.category = ACTION_CATEGORY_SPECTRUM_MGMT; 4939 frm.Action.action = ACTION_SPCT_CHL_SWITCH; 4940 frm.ChanSwitchAnn.switchMode = nMode; 4941 frm.ChanSwitchAnn.newChannel = nNewChannel; 4942 frm.ChanSwitchAnn.switchCount = nCount; 4943 frm.ChanSwitchAnn.present = 1; 4944 4945 nStatus = dot11f_get_packed_channel_switch_size(mac, &frm, &nPayload); 4946 if (DOT11F_FAILED(nStatus)) { 4947 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)", 4948 nStatus); 4949 /* We'll fall back on the worst case scenario: */ 4950 nPayload = sizeof(tDot11fChannelSwitch); 4951 } else if (DOT11F_WARNED(nStatus)) { 4952 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)", 4953 nStatus); 4954 } 4955 4956 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 4957 4958 qdf_status = 4959 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 4960 (void **)&pPacket); 4961 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4962 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes); 4963 return QDF_STATUS_E_FAILURE; 4964 } 4965 /* Paranoia: */ 4966 qdf_mem_zero(pFrame, nBytes); 4967 4968 /* Next, we fill out the buffer descriptor: */ 4969 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 4970 SIR_MAC_MGMT_ACTION, peer, 4971 pe_session->self_mac_addr); 4972 pMacHdr = (tpSirMacMgmtHdr) pFrame; 4973 qdf_mem_copy((uint8_t *) pMacHdr->bssId, 4974 (uint8_t *) pe_session->bssId, sizeof(tSirMacAddr)); 4975 4976 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 4977 4978 nStatus = dot11f_pack_channel_switch(mac, &frm, pFrame + 4979 sizeof(tSirMacMgmtHdr), 4980 nPayload, &nPayload); 4981 if (DOT11F_FAILED(nStatus)) { 4982 pe_err("Failed to pack a Channel Switch (0x%08x)", 4983 nStatus); 4984 cds_packet_free((void *)pPacket); 4985 return QDF_STATUS_E_FAILURE; /* allocated! */ 4986 } else if (DOT11F_WARNED(nStatus)) { 4987 pe_warn("There were warnings while packing a Channel Switch (0x%08x)", 4988 nStatus); 4989 } 4990 4991 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 4992 pe_session->opmode == QDF_P2P_CLIENT_MODE || 4993 pe_session->opmode == QDF_P2P_GO_MODE) 4994 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 4995 4996 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 4997 pe_session->peSessionId, pMacHdr->fc.subType)); 4998 qdf_status = wma_tx_frame(mac, pPacket, (uint16_t) nBytes, 4999 TXRX_FRM_802_11_MGMT, 5000 ANI_TXDIR_TODS, 5001 7, lim_tx_complete, pFrame, txFlag, 5002 smeSessionId, 0, RATEID_DEFAULT, 0); 5003 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 5004 pe_session->peSessionId, qdf_status)); 5005 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5006 pe_err("Failed to send a Channel Switch (%X)!", 5007 qdf_status); 5008 /* Pkt will be freed up by the callback */ 5009 return QDF_STATUS_E_FAILURE; 5010 } 5011 5012 return QDF_STATUS_SUCCESS; 5013 5014 } /* End lim_send_channel_switch_mgmt_frame. */ 5015 5016 /** 5017 * lim_send_extended_chan_switch_action_frame()- function to send ECSA 5018 * action frame over the air . 5019 * @mac_ctx: pointer to global mac structure 5020 * @peer: Destination mac. 5021 * @mode: channel switch mode 5022 * @new_op_class: new op class 5023 * @new_channel: new channel to switch 5024 * @count: channel switch count 5025 * 5026 * This function is called to send ECSA frame. 5027 * 5028 * Return: success if frame is sent else return failure 5029 */ 5030 5031 QDF_STATUS 5032 lim_send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, 5033 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class, 5034 uint8_t new_channel, uint8_t count, struct pe_session *session_entry) 5035 { 5036 tDot11fext_channel_switch_action_frame frm; 5037 uint8_t *frame; 5038 tpSirMacMgmtHdr mac_hdr; 5039 uint32_t num_bytes, n_payload, status; 5040 void *packet; 5041 QDF_STATUS qdf_status; 5042 uint8_t txFlag = 0; 5043 uint8_t vdev_id = 0; 5044 uint8_t ch_spacing; 5045 tLimWiderBWChannelSwitchInfo *wide_bw_ie; 5046 uint8_t reg_cc[REG_ALPHA2_LEN + 1]; 5047 5048 if (!session_entry) { 5049 pe_err("Session entry is NULL!!!"); 5050 return QDF_STATUS_E_FAILURE; 5051 } 5052 5053 vdev_id = session_entry->smeSessionId; 5054 5055 qdf_mem_zero(&frm, sizeof(frm)); 5056 5057 frm.Category.category = ACTION_CATEGORY_PUBLIC; 5058 frm.Action.action = PUB_ACTION_EXT_CHANNEL_SWITCH_ID; 5059 5060 frm.ext_chan_switch_ann_action.switch_mode = mode; 5061 frm.ext_chan_switch_ann_action.op_class = new_op_class; 5062 frm.ext_chan_switch_ann_action.new_channel = new_channel; 5063 frm.ext_chan_switch_ann_action.switch_count = count; 5064 5065 wlan_reg_read_current_country(mac_ctx->psoc, reg_cc); 5066 ch_spacing = wlan_reg_dmn_get_chanwidth_from_opclass( 5067 reg_cc, new_channel, new_op_class); 5068 5069 if ((ch_spacing == 80) || (ch_spacing == 160)) { 5070 wide_bw_ie = &session_entry->gLimWiderBWChannelSwitch; 5071 frm.WiderBWChanSwitchAnn.newChanWidth = 5072 wide_bw_ie->newChanWidth; 5073 frm.WiderBWChanSwitchAnn.newCenterChanFreq0 = 5074 wide_bw_ie->newCenterChanFreq0; 5075 frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 5076 wide_bw_ie->newCenterChanFreq1; 5077 frm.WiderBWChanSwitchAnn.present = 1; 5078 pe_debug("wrapper: width:%d f0:%d f1:%d", 5079 frm.WiderBWChanSwitchAnn.newChanWidth, 5080 frm.WiderBWChanSwitchAnn.newCenterChanFreq0, 5081 frm.WiderBWChanSwitchAnn.newCenterChanFreq1); 5082 } 5083 5084 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx, 5085 &frm, &n_payload); 5086 if (DOT11F_FAILED(status)) { 5087 pe_err("Failed to get packed size for Channel Switch 0x%08x", 5088 status); 5089 /* We'll fall back on the worst case scenario*/ 5090 n_payload = sizeof(tDot11fext_channel_switch_action_frame); 5091 } else if (DOT11F_WARNED(status)) { 5092 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)", 5093 status); 5094 } 5095 5096 num_bytes = n_payload + sizeof(tSirMacMgmtHdr); 5097 5098 qdf_status = cds_packet_alloc((uint16_t)num_bytes, 5099 (void **) &frame, (void **) &packet); 5100 5101 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5102 pe_err("Failed to allocate %d bytes for a Ext Channel Switch", 5103 num_bytes); 5104 return QDF_STATUS_E_FAILURE; 5105 } 5106 5107 /* Paranoia*/ 5108 qdf_mem_zero(frame, num_bytes); 5109 5110 /* Next, we fill out the buffer descriptor */ 5111 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 5112 SIR_MAC_MGMT_ACTION, peer, session_entry->self_mac_addr); 5113 mac_hdr = (tpSirMacMgmtHdr) frame; 5114 qdf_mem_copy((uint8_t *) mac_hdr->bssId, 5115 (uint8_t *) session_entry->bssId, 5116 sizeof(tSirMacAddr)); 5117 5118 lim_set_protected_bit(mac_ctx, session_entry, peer, mac_hdr); 5119 5120 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm, 5121 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload); 5122 if (DOT11F_FAILED(status)) { 5123 pe_err("Failed to pack a Channel Switch 0x%08x", status); 5124 cds_packet_free((void *)packet); 5125 return QDF_STATUS_E_FAILURE; 5126 } else if (DOT11F_WARNED(status)) { 5127 pe_warn("There were warnings while packing a Channel Switch 0x%08x", 5128 status); 5129 } 5130 5131 if (!wlan_reg_is_24ghz_ch_freq(session_entry->curr_op_freq) || 5132 session_entry->opmode == QDF_P2P_CLIENT_MODE || 5133 session_entry->opmode == QDF_P2P_GO_MODE) 5134 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 5135 5136 pe_debug("ECSA frame to :"QDF_MAC_ADDR_FMT" count %d mode %d chan %d op class %d", 5137 QDF_MAC_ADDR_REF(mac_hdr->da), 5138 frm.ext_chan_switch_ann_action.switch_count, 5139 frm.ext_chan_switch_ann_action.switch_mode, 5140 frm.ext_chan_switch_ann_action.new_channel, 5141 frm.ext_chan_switch_ann_action.op_class); 5142 5143 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 5144 session_entry->peSessionId, mac_hdr->fc.subType)); 5145 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes, 5146 TXRX_FRM_802_11_MGMT, 5147 ANI_TXDIR_TODS, 5148 7, 5149 lim_tx_complete, frame, 5150 txFlag, vdev_id, 0, 5151 RATEID_DEFAULT, 0); 5152 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 5153 session_entry->peSessionId, qdf_status)); 5154 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5155 pe_err("Failed to send a Ext Channel Switch %X!", 5156 qdf_status); 5157 /* Pkt will be freed up by the callback */ 5158 return QDF_STATUS_E_FAILURE; 5159 } 5160 return QDF_STATUS_SUCCESS; 5161 } /* End lim_send_extended_chan_switch_action_frame */ 5162 5163 5164 /** 5165 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm 5166 * sent over the air 5167 * 5168 * @context: pointer to global mac 5169 * @buf: buffer 5170 * @tx_complete : Sent status 5171 * @params: tx completion params 5172 * 5173 * Return: This returns QDF_STATUS 5174 */ 5175 5176 static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf( 5177 void *context, 5178 qdf_nbuf_t buf, 5179 uint32_t tx_complete, 5180 void *params) 5181 { 5182 pe_debug("tx_complete: %d", tx_complete); 5183 if (buf) 5184 qdf_nbuf_free(buf); 5185 return QDF_STATUS_SUCCESS; 5186 } 5187 5188 /** 5189 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send 5190 * p2p oper chan change confirm action frame 5191 * @mac_ctx: pointer to global mac structure 5192 * @peer: Destination mac. 5193 * @session_entry: session entry 5194 * 5195 * This function is called to send p2p oper chan change confirm action frame. 5196 * 5197 * Return: success if frame is sent else return failure 5198 */ 5199 5200 QDF_STATUS 5201 lim_p2p_oper_chan_change_confirm_action_frame(struct mac_context *mac_ctx, 5202 tSirMacAddr peer, struct pe_session *session_entry) 5203 { 5204 tDot11fp2p_oper_chan_change_confirm frm; 5205 uint8_t *frame; 5206 tpSirMacMgmtHdr mac_hdr; 5207 uint32_t num_bytes, n_payload, status; 5208 void *packet; 5209 QDF_STATUS qdf_status; 5210 uint8_t tx_flag = 0; 5211 uint8_t vdev_id = 0; 5212 5213 if (!session_entry) { 5214 pe_err("Session entry is NULL!!!"); 5215 return QDF_STATUS_E_FAILURE; 5216 } 5217 5218 vdev_id = session_entry->smeSessionId; 5219 5220 qdf_mem_zero(&frm, sizeof(frm)); 5221 5222 frm.Category.category = ACTION_CATEGORY_VENDOR_SPECIFIC; 5223 5224 qdf_mem_copy(frm.p2p_action_oui.oui_data, 5225 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE); 5226 frm.p2p_action_subtype.subtype = 0x04; 5227 frm.DialogToken.token = 0x0; 5228 5229 if (session_entry->htCapability) { 5230 pe_debug("Populate HT Caps in Assoc Request"); 5231 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps); 5232 } 5233 5234 if (session_entry->vhtCapability) { 5235 pe_debug("Populate VHT Caps in Assoc Request"); 5236 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps); 5237 populate_dot11f_operating_mode(mac_ctx, 5238 &frm.OperatingMode, session_entry); 5239 } 5240 5241 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx, 5242 &frm, &n_payload); 5243 if (DOT11F_FAILED(status)) { 5244 pe_err("Failed to get packed size 0x%08x", status); 5245 /* We'll fall back on the worst case scenario*/ 5246 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm); 5247 } else if (DOT11F_WARNED(status)) { 5248 pe_warn("There were warnings while calculating the packed size (0x%08x)", 5249 status); 5250 } 5251 5252 num_bytes = n_payload + sizeof(tSirMacMgmtHdr); 5253 5254 qdf_status = cds_packet_alloc((uint16_t)num_bytes, 5255 (void **) &frame, (void **) &packet); 5256 5257 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5258 pe_err("Failed to allocate %d bytes", num_bytes); 5259 return QDF_STATUS_E_FAILURE; 5260 } 5261 5262 qdf_mem_zero(frame, num_bytes); 5263 5264 /* Next, fill out the buffer descriptor */ 5265 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME, 5266 SIR_MAC_MGMT_ACTION, peer, session_entry->self_mac_addr); 5267 mac_hdr = (tpSirMacMgmtHdr) frame; 5268 qdf_mem_copy((uint8_t *) mac_hdr->bssId, 5269 (uint8_t *) session_entry->bssId, 5270 sizeof(tSirMacAddr)); 5271 5272 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm, 5273 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload); 5274 if (DOT11F_FAILED(status)) { 5275 pe_err("Failed to pack 0x%08x", status); 5276 cds_packet_free((void *)packet); 5277 return QDF_STATUS_E_FAILURE; 5278 } else if (DOT11F_WARNED(status)) { 5279 pe_warn("There were warnings while packing 0x%08x", 5280 status); 5281 } 5282 5283 if (!wlan_reg_is_24ghz_ch_freq(session_entry->curr_op_freq) || 5284 session_entry->opmode == QDF_P2P_CLIENT_MODE || 5285 session_entry->opmode == QDF_P2P_GO_MODE) { 5286 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 5287 } 5288 pe_debug("Send frame on channel freq %d to mac " 5289 QDF_MAC_ADDR_FMT, session_entry->curr_op_freq, 5290 QDF_MAC_ADDR_REF(peer)); 5291 5292 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 5293 session_entry->peSessionId, mac_hdr->fc.subType)); 5294 5295 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet, 5296 (uint16_t)num_bytes, 5297 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 5298 7, lim_tx_complete, frame, 5299 lim_oper_chan_change_confirm_tx_complete_cnf, 5300 tx_flag, vdev_id, false, 0, RATEID_DEFAULT, 0, 0); 5301 5302 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 5303 session_entry->peSessionId, qdf_status)); 5304 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5305 pe_err("Failed to send status %X!", qdf_status); 5306 /* Pkt will be freed up by the callback */ 5307 return QDF_STATUS_E_FAILURE; 5308 } 5309 return QDF_STATUS_SUCCESS; 5310 } 5311 5312 5313 /** 5314 * \brief Send a Neighbor Report Request Action frame 5315 * 5316 * 5317 * \param mac Pointer to the global MAC structure 5318 * 5319 * \param pNeighborReq Address of a tSirMacNeighborReportReq 5320 * 5321 * \param peer mac address of peer station. 5322 * 5323 * \param pe_session address of session entry. 5324 * 5325 * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else 5326 * 5327 * 5328 */ 5329 5330 QDF_STATUS 5331 lim_send_neighbor_report_request_frame(struct mac_context *mac, 5332 tpSirMacNeighborReportReq pNeighborReq, 5333 tSirMacAddr peer, struct pe_session *pe_session) 5334 { 5335 QDF_STATUS status_code = QDF_STATUS_SUCCESS; 5336 tDot11fNeighborReportRequest frm; 5337 uint8_t *pFrame; 5338 tpSirMacMgmtHdr pMacHdr; 5339 uint32_t nBytes, nPayload, nStatus; 5340 void *pPacket; 5341 QDF_STATUS qdf_status; 5342 uint8_t txFlag = 0; 5343 uint8_t smeSessionId = 0; 5344 5345 if (!pe_session) { 5346 pe_err("(!psession) in Request to send Neighbor Report request action frame"); 5347 return QDF_STATUS_E_FAILURE; 5348 } 5349 smeSessionId = pe_session->smeSessionId; 5350 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 5351 5352 frm.Category.category = ACTION_CATEGORY_RRM; 5353 frm.Action.action = RRM_NEIGHBOR_REQ; 5354 frm.DialogToken.token = pNeighborReq->dialogToken; 5355 5356 if (pNeighborReq->ssid_present) { 5357 populate_dot11f_ssid(mac, &pNeighborReq->ssid, &frm.SSID); 5358 } 5359 5360 nStatus = 5361 dot11f_get_packed_neighbor_report_request_size(mac, &frm, &nPayload); 5362 if (DOT11F_FAILED(nStatus)) { 5363 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)", 5364 nStatus); 5365 /* We'll fall back on the worst case scenario: */ 5366 nPayload = sizeof(tDot11fNeighborReportRequest); 5367 } else if (DOT11F_WARNED(nStatus)) { 5368 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)", 5369 nStatus); 5370 } 5371 5372 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 5373 5374 qdf_status = 5375 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 5376 (void **)&pPacket); 5377 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5378 pe_err("Failed to allocate %d bytes for a Neighbor " 5379 "Report Request", nBytes); 5380 return QDF_STATUS_E_FAILURE; 5381 } 5382 /* Paranoia: */ 5383 qdf_mem_zero(pFrame, nBytes); 5384 5385 /* Copy necessary info to BD */ 5386 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 5387 SIR_MAC_MGMT_ACTION, peer, pe_session->self_mac_addr); 5388 5389 /* Update A3 with the BSSID */ 5390 pMacHdr = (tpSirMacMgmtHdr) pFrame; 5391 5392 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 5393 5394 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 5395 5396 /* Now, we're ready to "pack" the frames */ 5397 nStatus = dot11f_pack_neighbor_report_request(mac, 5398 &frm, 5399 pFrame + 5400 sizeof(tSirMacMgmtHdr), 5401 nPayload, &nPayload); 5402 5403 if (DOT11F_FAILED(nStatus)) { 5404 pe_err("Failed to pack an Neighbor Report Request (0x%08x)", 5405 nStatus); 5406 5407 /* FIXME - Need to convert to QDF_STATUS */ 5408 status_code = QDF_STATUS_E_FAILURE; 5409 goto returnAfterError; 5410 } else if (DOT11F_WARNED(nStatus)) { 5411 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)", 5412 nStatus); 5413 } 5414 5415 pe_debug("Sending a Neighbor Report Request to "QDF_MAC_ADDR_FMT, 5416 QDF_MAC_ADDR_REF(peer)); 5417 5418 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 5419 pe_session->opmode == QDF_P2P_CLIENT_MODE || 5420 pe_session->opmode == QDF_P2P_GO_MODE) 5421 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 5422 5423 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 5424 pe_session->peSessionId, pMacHdr->fc.subType)); 5425 qdf_status = wma_tx_frame(mac, 5426 pPacket, 5427 (uint16_t) nBytes, 5428 TXRX_FRM_802_11_MGMT, 5429 ANI_TXDIR_TODS, 5430 7, lim_tx_complete, pFrame, txFlag, 5431 smeSessionId, 0, RATEID_DEFAULT, 0); 5432 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 5433 pe_session->peSessionId, qdf_status)); 5434 if (QDF_STATUS_SUCCESS != qdf_status) { 5435 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 5436 status_code = QDF_STATUS_E_FAILURE; 5437 /* Pkt will be freed up by the callback */ 5438 return status_code; 5439 } else 5440 return QDF_STATUS_SUCCESS; 5441 5442 returnAfterError: 5443 cds_packet_free((void *)pPacket); 5444 5445 return status_code; 5446 } /* End lim_send_neighbor_report_request_frame. */ 5447 5448 QDF_STATUS 5449 lim_send_link_report_action_frame(struct mac_context *mac, 5450 tpSirMacLinkReport pLinkReport, 5451 tSirMacAddr peer, struct pe_session *pe_session) 5452 { 5453 QDF_STATUS status_code = QDF_STATUS_SUCCESS; 5454 tDot11fLinkMeasurementReport frm; 5455 uint8_t *pFrame; 5456 tpSirMacMgmtHdr pMacHdr; 5457 uint32_t nBytes, nPayload, nStatus; 5458 void *pPacket; 5459 QDF_STATUS qdf_status; 5460 uint8_t txFlag = 0; 5461 uint8_t vdev_id = 0; 5462 5463 if (!pe_session) { 5464 pe_err("RRM: Send link report: NULL PE session"); 5465 return QDF_STATUS_E_FAILURE; 5466 } 5467 5468 vdev_id = pe_session->vdev_id; 5469 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 5470 5471 frm.Category.category = ACTION_CATEGORY_RRM; 5472 frm.Action.action = RRM_LINK_MEASUREMENT_RPT; 5473 frm.DialogToken.token = pLinkReport->dialogToken; 5474 5475 /* IEEE Std. 802.11 7.3.2.18. for the report element. */ 5476 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */ 5477 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */ 5478 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */ 5479 /* such case this way than changing the frame parser. */ 5480 frm.TPCEleID.TPCId = WLAN_ELEMID_TPCREP; 5481 frm.TPCEleLen.TPCLen = 2; 5482 frm.TxPower.txPower = pLinkReport->txPower; 5483 frm.LinkMargin.linkMargin = 0; 5484 5485 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna; 5486 frm.TxAntennaId.antennaId = pLinkReport->txAntenna; 5487 frm.RCPI.rcpi = pLinkReport->rcpi; 5488 frm.RSNI.rsni = pLinkReport->rsni; 5489 5490 nStatus = 5491 dot11f_get_packed_link_measurement_report_size(mac, &frm, &nPayload); 5492 if (DOT11F_FAILED(nStatus)) { 5493 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus); 5494 /* We'll fall back on the worst case scenario: */ 5495 nPayload = sizeof(tDot11fLinkMeasurementReport); 5496 } else if (DOT11F_WARNED(nStatus)) { 5497 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)", 5498 nStatus); 5499 } 5500 5501 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 5502 5503 qdf_status = 5504 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 5505 (void **)&pPacket); 5506 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5507 pe_err("Failed to allocate %d bytes for a Link " 5508 "Report", nBytes); 5509 return QDF_STATUS_E_FAILURE; 5510 } 5511 /* Paranoia: */ 5512 qdf_mem_zero(pFrame, nBytes); 5513 5514 /* Copy necessary info to BD */ 5515 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 5516 SIR_MAC_MGMT_ACTION, peer, pe_session->self_mac_addr); 5517 5518 /* Update A3 with the BSSID */ 5519 pMacHdr = (tpSirMacMgmtHdr) pFrame; 5520 5521 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 5522 5523 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 5524 5525 /* Now, we're ready to "pack" the frames */ 5526 nStatus = dot11f_pack_link_measurement_report(mac, 5527 &frm, 5528 pFrame + 5529 sizeof(tSirMacMgmtHdr), 5530 nPayload, &nPayload); 5531 5532 if (DOT11F_FAILED(nStatus)) { 5533 pe_err("Failed to pack an Link Report (0x%08x)", nStatus); 5534 5535 /* FIXME - Need to convert to QDF_STATUS */ 5536 status_code = QDF_STATUS_E_FAILURE; 5537 goto returnAfterError; 5538 } else if (DOT11F_WARNED(nStatus)) { 5539 pe_warn("There were warnings while packing Link Report (0x%08x)", 5540 nStatus); 5541 } 5542 5543 pe_warn("RRM: Sending Link Report to "QDF_MAC_ADDR_FMT" on vdev[%d]", 5544 QDF_MAC_ADDR_REF(peer), vdev_id); 5545 5546 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 5547 pe_session->opmode == QDF_P2P_CLIENT_MODE || 5548 pe_session->opmode == QDF_P2P_GO_MODE) 5549 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 5550 5551 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 5552 pe_session->peSessionId, pMacHdr->fc.subType)); 5553 qdf_status = wma_tx_frame(mac, 5554 pPacket, 5555 (uint16_t) nBytes, 5556 TXRX_FRM_802_11_MGMT, 5557 ANI_TXDIR_TODS, 5558 7, lim_tx_complete, pFrame, txFlag, 5559 vdev_id, 0, RATEID_DEFAULT, 0); 5560 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 5561 pe_session->peSessionId, qdf_status)); 5562 if (QDF_STATUS_SUCCESS != qdf_status) { 5563 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 5564 status_code = QDF_STATUS_E_FAILURE; 5565 /* Pkt will be freed up by the callback */ 5566 return status_code; 5567 } else 5568 return QDF_STATUS_SUCCESS; 5569 5570 returnAfterError: 5571 cds_packet_free((void *)pPacket); 5572 5573 return status_code; 5574 } /* End lim_send_link_report_action_frame. */ 5575 5576 #ifdef CONNECTIVITY_DIAG_EVENT 5577 /** 5578 * lim_beacon_report_response_event() - Send Beacon Report Response log 5579 * event 5580 * @token: Dialog token 5581 * @num_rpt: Number of Report element 5582 * @vdev_id: vdev Id 5583 */ 5584 static void 5585 lim_beacon_report_response_event(uint8_t token, uint8_t num_rpt, 5586 uint8_t vdev_id) 5587 { 5588 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_bcn_rpt); 5589 5590 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 5591 5592 wlan_diag_event.diag_cmn.vdev_id = vdev_id; 5593 wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us(); 5594 wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get()); 5595 5596 wlan_diag_event.version = DIAG_BCN_RPT_VERSION; 5597 wlan_diag_event.subtype = WLAN_CONN_DIAG_BCN_RPT_RESP_EVENT; 5598 wlan_diag_event.meas_token = token; 5599 wlan_diag_event.num_rpt = num_rpt; 5600 5601 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BCN_RPT); 5602 } 5603 #else 5604 static void 5605 lim_beacon_report_response_event(uint8_t token, uint8_t num_rpt, 5606 uint8_t vdev_id) 5607 { 5608 } 5609 #endif 5610 5611 QDF_STATUS 5612 lim_send_radio_measure_report_action_frame(struct mac_context *mac, 5613 uint8_t dialog_token, 5614 uint8_t num_report, 5615 bool is_last_frame, 5616 tpSirMacRadioMeasureReport pRRMReport, 5617 tSirMacAddr peer, 5618 struct pe_session *pe_session) 5619 { 5620 QDF_STATUS status_code = QDF_STATUS_SUCCESS; 5621 uint8_t *pFrame; 5622 tpSirMacMgmtHdr pMacHdr; 5623 uint32_t nBytes, nPayload, nStatus; 5624 void *pPacket; 5625 QDF_STATUS qdf_status; 5626 uint8_t i; 5627 uint8_t txFlag = 0; 5628 uint8_t smeSessionId = 0; 5629 bool is_last_report = false; 5630 5631 /* Malloc size of (tDot11fIEMeasurementReport) * (num_report - 1) 5632 * as memory for one Dot11fIEMeasurementReport is already calculated. 5633 */ 5634 tDot11fRadioMeasurementReport *frm = 5635 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport) + 5636 (sizeof(tDot11fIEMeasurementReport) * (num_report - 1))); 5637 if (!frm) 5638 return QDF_STATUS_E_NOMEM; 5639 5640 if (!pe_session) { 5641 pe_err("session not found"); 5642 qdf_mem_free(frm); 5643 return QDF_STATUS_E_FAILURE; 5644 } 5645 5646 smeSessionId = pe_session->smeSessionId; 5647 5648 frm->Category.category = ACTION_CATEGORY_RRM; 5649 frm->Action.action = RRM_RADIO_MEASURE_RPT; 5650 frm->DialogToken.token = dialog_token; 5651 5652 frm->num_MeasurementReport = num_report; 5653 5654 for (i = 0; i < frm->num_MeasurementReport; i++) { 5655 frm->MeasurementReport[i].type = pRRMReport[i].type; 5656 frm->MeasurementReport[i].token = pRRMReport[i].token; 5657 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */ 5658 switch (pRRMReport[i].type) { 5659 case SIR_MAC_RRM_BEACON_TYPE: 5660 /* 5661 * Last beacon report indication needs to be set to 1 5662 * only for the last report in the last frame 5663 */ 5664 if (is_last_frame && 5665 (i == (frm->num_MeasurementReport - 1))) 5666 is_last_report = true; 5667 5668 populate_dot11f_beacon_report(mac, 5669 &frm->MeasurementReport[i], 5670 &pRRMReport[i].report. 5671 beaconReport, 5672 is_last_report); 5673 frm->MeasurementReport[i].incapable = 5674 pRRMReport[i].incapable; 5675 frm->MeasurementReport[i].refused = 5676 pRRMReport[i].refused; 5677 frm->MeasurementReport[i].present = 1; 5678 break; 5679 default: 5680 frm->MeasurementReport[i].incapable = 5681 pRRMReport[i].incapable; 5682 frm->MeasurementReport[i].refused = 5683 pRRMReport[i].refused; 5684 frm->MeasurementReport[i].present = 1; 5685 break; 5686 } 5687 } 5688 5689 5690 nStatus = 5691 dot11f_get_packed_radio_measurement_report_size(mac, frm, &nPayload); 5692 if (DOT11F_FAILED(nStatus)) { 5693 pe_nofl_err("TX: [802.11 RRM] Failed to get packed size for RM Report (0x%08x)", 5694 nStatus); 5695 /* We'll fall back on the worst case scenario: */ 5696 nPayload = sizeof(tDot11fLinkMeasurementReport); 5697 qdf_mem_free(frm); 5698 return QDF_STATUS_E_FAILURE; 5699 } else if (DOT11F_WARNED(nStatus)) { 5700 pe_warn("Warnings while calculating the size for Radio Measure Report (0x%08x)", 5701 nStatus); 5702 } 5703 5704 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 5705 5706 qdf_status = 5707 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 5708 (void **)&pPacket); 5709 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5710 pe_nofl_err("TX: [802.11 RRM] Allocation of %d bytes failed for RM" 5711 "Report", nBytes); 5712 qdf_mem_free(frm); 5713 return QDF_STATUS_E_FAILURE; 5714 } 5715 /* Paranoia: */ 5716 qdf_mem_zero(pFrame, nBytes); 5717 5718 /* Copy necessary info to BD */ 5719 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 5720 SIR_MAC_MGMT_ACTION, peer, pe_session->self_mac_addr); 5721 5722 /* Update A3 with the BSSID */ 5723 pMacHdr = (tpSirMacMgmtHdr) pFrame; 5724 5725 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 5726 5727 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 5728 5729 /* Now, we're ready to "pack" the frames */ 5730 nStatus = dot11f_pack_radio_measurement_report(mac, 5731 frm, 5732 pFrame + 5733 sizeof(tSirMacMgmtHdr), 5734 nPayload, &nPayload); 5735 5736 if (DOT11F_FAILED(nStatus)) { 5737 pe_nofl_err("Failed to pack an Radio Measure Report (0x%08x)", 5738 nStatus); 5739 5740 /* FIXME - Need to convert to QDF_STATUS */ 5741 status_code = QDF_STATUS_E_FAILURE; 5742 goto returnAfterError; 5743 } else if (DOT11F_WARNED(nStatus)) { 5744 pe_warn("Warnings while packing Radio Measure Report (0x%08x)", 5745 nStatus); 5746 } 5747 5748 if (frm->MeasurementReport[0].type == SIR_MAC_RRM_BEACON_TYPE) { 5749 lim_beacon_report_response_event(frm->MeasurementReport[0].token, 5750 num_report, 5751 wlan_vdev_get_id(pe_session->vdev)); 5752 } 5753 5754 pe_nofl_info("TX: %s seq_no:%d dialog_token:%d no. of APs:%d is_last_rpt:%d num_report: %d peer:"QDF_MAC_ADDR_FMT, 5755 frm->MeasurementReport[0].type == SIR_MAC_RRM_BEACON_TYPE ? 5756 "[802.11 BCN_RPT]" : "[802.11 RRM]", 5757 (pMacHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET | 5758 pMacHdr->seqControl.seqNumLo), 5759 dialog_token, frm->num_MeasurementReport, 5760 is_last_report, num_report, 5761 QDF_MAC_ADDR_REF(peer)); 5762 5763 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 5764 pe_session->opmode == QDF_P2P_CLIENT_MODE || 5765 pe_session->opmode == QDF_P2P_GO_MODE) 5766 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 5767 5768 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 5769 pe_session->peSessionId, pMacHdr->fc.subType)); 5770 qdf_status = wma_tx_frame(mac, pPacket, (uint16_t)nBytes, 5771 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 5772 7, lim_tx_complete, pFrame, txFlag, 5773 smeSessionId, 0, RATEID_DEFAULT, 0); 5774 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 5775 pe_session->peSessionId, qdf_status)); 5776 if (QDF_STATUS_SUCCESS != qdf_status) { 5777 pe_nofl_err("TX: [802.11 RRM] Send FAILED! err_status [%d]", 5778 qdf_status); 5779 status_code = QDF_STATUS_E_FAILURE; 5780 /* Pkt will be freed up by the callback */ 5781 } 5782 5783 qdf_mem_free(frm); 5784 return status_code; 5785 5786 returnAfterError: 5787 qdf_mem_free(frm); 5788 cds_packet_free((void *)pPacket); 5789 return status_code; 5790 } 5791 5792 bool 5793 lim_is_self_and_peer_ocv_capable(struct mac_context *mac, 5794 uint8_t *peer, 5795 struct pe_session *pe_session) 5796 { 5797 uint16_t self_rsn_cap, aid; 5798 tpDphHashNode sta_ds; 5799 5800 self_rsn_cap = wlan_crypto_get_param(pe_session->vdev, 5801 WLAN_CRYPTO_PARAM_RSN_CAP); 5802 if (!(self_rsn_cap & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED)) 5803 return false; 5804 5805 sta_ds = dph_lookup_hash_entry(mac, peer, &aid, 5806 &pe_session->dph.dphHashTable); 5807 5808 if (sta_ds && sta_ds->ocv_enabled) 5809 return true; 5810 5811 return false; 5812 } 5813 5814 void 5815 lim_fill_oci_params(struct mac_context *mac, struct pe_session *session, 5816 tDot11fIEoci *oci, uint8_t *peer, uint16_t *tx_chan_width) 5817 { 5818 tpDphHashNode sta_ds; 5819 uint16_t aid; 5820 uint8_t ch_offset; 5821 uint8_t prim_ch_num = wlan_reg_freq_to_chan(mac->pdev, 5822 session->curr_op_freq); 5823 if (session->ch_width == CH_WIDTH_80MHZ) { 5824 ch_offset = BW80; 5825 } else { 5826 switch (session->htSecondaryChannelOffset) { 5827 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 5828 ch_offset = BW40_HIGH_PRIMARY; 5829 break; 5830 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 5831 ch_offset = BW40_LOW_PRIMARY; 5832 break; 5833 default: 5834 ch_offset = BW20; 5835 break; 5836 } 5837 } 5838 oci->op_class = lim_op_class_from_bandwidth(mac, 5839 session->curr_op_freq, 5840 session->ch_width, 5841 ch_offset); 5842 oci->prim_ch_num = prim_ch_num; 5843 oci->freq_seg_1_ch_num = session->ch_center_freq_seg1; 5844 oci->present = 1; 5845 if (tx_chan_width) 5846 *tx_chan_width = ch_width_in_mhz(session->ch_width); 5847 if (LIM_IS_STA_ROLE(session)) 5848 return; 5849 5850 if (!peer || !tx_chan_width) 5851 return; 5852 5853 sta_ds = dph_lookup_hash_entry(mac, peer, &aid, 5854 &session->dph.dphHashTable); 5855 if (!sta_ds) { 5856 pe_nofl_debug("no find sta ds "QDF_MAC_ADDR_FMT, 5857 QDF_MAC_ADDR_REF(peer)); 5858 return; 5859 } 5860 if (WLAN_REG_IS_24GHZ_CH_FREQ(session->curr_op_freq)) { 5861 if (*tx_chan_width > 20 && 5862 !sta_ds->htSupportedChannelWidthSet) { 5863 *tx_chan_width = 20; 5864 pe_nofl_debug("peer no support ht40 in 2g, %d :"QDF_MAC_ADDR_FMT, 5865 sta_ds->ch_width, 5866 QDF_MAC_ADDR_REF(peer)); 5867 } 5868 } 5869 } 5870 5871 /** 5872 * \brief Send SA query request action frame to peer 5873 * 5874 * \sa lim_send_sa_query_request_frame 5875 * 5876 * 5877 * \param mac The global struct mac_context *object 5878 * 5879 * \param transId Transaction identifier 5880 * 5881 * \param peer The Mac address of the station to which this action frame is addressed 5882 * 5883 * \param pe_session The PE session entry 5884 * 5885 * \return QDF_STATUS_SUCCESS if setup completes successfully 5886 * QDF_STATUS_E_FAILURE is some problem is encountered 5887 */ 5888 5889 QDF_STATUS lim_send_sa_query_request_frame(struct mac_context *mac, uint8_t *transId, 5890 tSirMacAddr peer, 5891 struct pe_session *pe_session) 5892 { 5893 5894 tDot11fSaQueryReq frm; /* SA query request action frame */ 5895 uint8_t *pFrame; 5896 QDF_STATUS nSirStatus; 5897 tpSirMacMgmtHdr pMacHdr; 5898 uint32_t nBytes, nPayload, nStatus; 5899 void *pPacket; 5900 QDF_STATUS qdf_status; 5901 uint8_t txFlag = 0; 5902 uint8_t smeSessionId = 0; 5903 5904 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 5905 frm.Category.category = ACTION_CATEGORY_SA_QUERY; 5906 /* 11w action field is : 5907 action: 0 --> SA Query Request action frame 5908 action: 1 --> SA Query Response action frame */ 5909 frm.Action.action = SA_QUERY_REQUEST; 5910 /* 11w SA Query Request transId */ 5911 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2); 5912 5913 if (lim_is_self_and_peer_ocv_capable(mac, peer, pe_session)) 5914 lim_fill_oci_params(mac, pe_session, &frm.oci, NULL, NULL); 5915 5916 nStatus = dot11f_get_packed_sa_query_req_size(mac, &frm, &nPayload); 5917 if (DOT11F_FAILED(nStatus)) { 5918 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)", 5919 nStatus); 5920 /* We'll fall back on the worst case scenario: */ 5921 nPayload = sizeof(tDot11fSaQueryReq); 5922 } else if (DOT11F_WARNED(nStatus)) { 5923 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)", 5924 nStatus); 5925 } 5926 5927 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 5928 qdf_status = 5929 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket); 5930 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5931 pe_err("Failed to allocate %d bytes for a SA Query Request " 5932 "action frame", nBytes); 5933 return QDF_STATUS_E_FAILURE; 5934 } 5935 /* Paranoia: */ 5936 qdf_mem_zero(pFrame, nBytes); 5937 5938 /* Copy necessary info to BD */ 5939 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 5940 SIR_MAC_MGMT_ACTION, peer, pe_session->self_mac_addr); 5941 5942 /* Update A3 with the BSSID */ 5943 pMacHdr = (tpSirMacMgmtHdr) pFrame; 5944 5945 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 5946 5947 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */ 5948 /* in the FC */ 5949 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 5950 5951 /* Pack 11w SA Query Request frame */ 5952 nStatus = dot11f_pack_sa_query_req(mac, 5953 &frm, 5954 pFrame + sizeof(tSirMacMgmtHdr), 5955 nPayload, &nPayload); 5956 5957 if (DOT11F_FAILED(nStatus)) { 5958 pe_err("Failed to pack an SA Query Request (0x%08x)", 5959 nStatus); 5960 /* FIXME - Need to convert to QDF_STATUS */ 5961 nSirStatus = QDF_STATUS_E_FAILURE; 5962 goto returnAfterError; 5963 } else if (DOT11F_WARNED(nStatus)) { 5964 pe_warn("There were warnings while packing SA Query Request (0x%08x)", 5965 nStatus); 5966 } 5967 5968 pe_debug("Sending an SA Query Request from "QDF_MAC_ADDR_FMT" to "QDF_MAC_ADDR_FMT, 5969 QDF_MAC_ADDR_REF(pe_session->self_mac_addr), 5970 QDF_MAC_ADDR_REF(peer)); 5971 5972 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 5973 pe_session->opmode == QDF_P2P_CLIENT_MODE || 5974 pe_session->opmode == QDF_P2P_GO_MODE) 5975 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 5976 5977 smeSessionId = pe_session->smeSessionId; 5978 5979 qdf_status = wma_tx_frame(mac, 5980 pPacket, 5981 (uint16_t) nBytes, 5982 TXRX_FRM_802_11_MGMT, 5983 ANI_TXDIR_TODS, 5984 7, lim_tx_complete, pFrame, txFlag, 5985 smeSessionId, 0, RATEID_DEFAULT, 0); 5986 if (QDF_STATUS_SUCCESS != qdf_status) { 5987 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 5988 nSirStatus = QDF_STATUS_E_FAILURE; 5989 /* Pkt will be freed up by the callback */ 5990 return nSirStatus; 5991 } else { 5992 return QDF_STATUS_SUCCESS; 5993 } 5994 5995 returnAfterError: 5996 cds_packet_free((void *)pPacket); 5997 return nSirStatus; 5998 } /* End lim_send_sa_query_request_frame */ 5999 6000 /** 6001 * \brief Send SA query response action frame to peer 6002 * 6003 * \sa lim_send_sa_query_response_frame 6004 * 6005 * 6006 * \param mac The global struct mac_context *object 6007 * 6008 * \param transId Transaction identifier received in SA query request action frame 6009 * 6010 * \param peer The Mac address of the AP to which this action frame is addressed 6011 * 6012 * \param pe_session The PE session entry 6013 * 6014 * \return QDF_STATUS_SUCCESS if setup completes successfully 6015 * QDF_STATUS_E_FAILURE is some problem is encountered 6016 */ 6017 6018 QDF_STATUS lim_send_sa_query_response_frame(struct mac_context *mac, 6019 uint8_t *transId, tSirMacAddr peer, 6020 struct pe_session *pe_session) 6021 { 6022 6023 tDot11fSaQueryRsp frm; /* SA query response action frame */ 6024 uint8_t *pFrame; 6025 QDF_STATUS nSirStatus; 6026 tpSirMacMgmtHdr pMacHdr; 6027 uint32_t nBytes, nPayload, nStatus; 6028 void *pPacket; 6029 QDF_STATUS qdf_status; 6030 uint8_t txFlag = 0; 6031 uint8_t smeSessionId = 0; 6032 6033 smeSessionId = pe_session->smeSessionId; 6034 6035 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 6036 frm.Category.category = ACTION_CATEGORY_SA_QUERY; 6037 /*11w action field is : 6038 action: 0 --> SA query request action frame 6039 action: 1 --> SA query response action frame */ 6040 frm.Action.action = SA_QUERY_RESPONSE; 6041 /*11w SA query response transId is same as 6042 SA query request transId */ 6043 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2); 6044 if (lim_is_self_and_peer_ocv_capable(mac, peer, pe_session)) 6045 lim_fill_oci_params(mac, pe_session, &frm.oci, NULL, NULL); 6046 6047 nStatus = dot11f_get_packed_sa_query_rsp_size(mac, &frm, &nPayload); 6048 if (DOT11F_FAILED(nStatus)) { 6049 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)", 6050 nStatus); 6051 /* We'll fall back on the worst case scenario: */ 6052 nPayload = sizeof(tDot11fSaQueryRsp); 6053 } else if (DOT11F_WARNED(nStatus)) { 6054 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)", 6055 nStatus); 6056 } 6057 nBytes = nPayload + sizeof(tSirMacMgmtHdr); 6058 qdf_status = 6059 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket); 6060 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 6061 pe_err("Failed to allocate %d bytes for a SA query response" 6062 " action frame", nBytes); 6063 return QDF_STATUS_E_FAILURE; 6064 } 6065 /* Paranoia: */ 6066 qdf_mem_zero(pFrame, nBytes); 6067 6068 /* Copy necessary info to BD */ 6069 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 6070 SIR_MAC_MGMT_ACTION, peer, pe_session->self_mac_addr); 6071 6072 /* Update A3 with the BSSID */ 6073 pMacHdr = (tpSirMacMgmtHdr) pFrame; 6074 6075 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 6076 6077 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */ 6078 /* in the FC */ 6079 lim_set_protected_bit(mac, pe_session, peer, pMacHdr); 6080 6081 /* Pack 11w SA query response frame */ 6082 nStatus = dot11f_pack_sa_query_rsp(mac, 6083 &frm, 6084 pFrame + sizeof(tSirMacMgmtHdr), 6085 nPayload, &nPayload); 6086 6087 if (DOT11F_FAILED(nStatus)) { 6088 pe_err("Failed to pack an SA Query Response (0x%08x)", 6089 nStatus); 6090 /* FIXME - Need to convert to QDF_STATUS */ 6091 nSirStatus = QDF_STATUS_E_FAILURE; 6092 goto returnAfterError; 6093 } else if (DOT11F_WARNED(nStatus)) { 6094 pe_warn("There were warnings while packing SA Query Response (0x%08x)", 6095 nStatus); 6096 } 6097 6098 pe_debug("Sending SA Query Response to "QDF_MAC_ADDR_FMT" op_class %d prim_ch_num %d freq_seg_1_ch_num %d oci_present %d", 6099 QDF_MAC_ADDR_REF(peer), frm.oci.op_class, 6100 frm.oci.prim_ch_num, frm.oci.freq_seg_1_ch_num, 6101 frm.oci.present); 6102 6103 if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || 6104 pe_session->opmode == QDF_P2P_CLIENT_MODE || 6105 pe_session->opmode == QDF_P2P_GO_MODE) 6106 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 6107 6108 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 6109 pe_session->peSessionId, pMacHdr->fc.subType)); 6110 qdf_status = wma_tx_frame(mac, 6111 pPacket, 6112 (uint16_t) nBytes, 6113 TXRX_FRM_802_11_MGMT, 6114 ANI_TXDIR_TODS, 6115 7, lim_tx_complete, pFrame, txFlag, 6116 smeSessionId, 0, RATEID_DEFAULT, 0); 6117 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 6118 pe_session->peSessionId, qdf_status)); 6119 if (QDF_STATUS_SUCCESS != qdf_status) { 6120 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 6121 nSirStatus = QDF_STATUS_E_FAILURE; 6122 /* Pkt will be freed up by the callback */ 6123 return nSirStatus; 6124 } else { 6125 return QDF_STATUS_SUCCESS; 6126 } 6127 6128 returnAfterError: 6129 cds_packet_free((void *)pPacket); 6130 return nSirStatus; 6131 } /* End lim_send_sa_query_response_frame */ 6132 6133 #if defined(CONFIG_LITHIUM) || defined(CONFIG_BERYLLIUM) 6134 #ifdef WLAN_FEATURE_11AX 6135 #define IS_PE_SESSION_HE_MODE(_session) ((_session)->he_capable) 6136 #else 6137 #define IS_PE_SESSION_HE_MODE(_session) false 6138 #endif /* WLAN_FEATURE_11AX */ 6139 #else 6140 #define IS_PE_SESSION_HE_MODE(_session) false 6141 #endif 6142 6143 #ifdef FEATURE_WLAN_TDLS 6144 static bool lim_tdls_peer_support_he(tpDphHashNode sta_ds) 6145 { 6146 bool peer_he_cap = false; 6147 6148 if (sta_ds) { 6149 peer_he_cap = lim_is_sta_he_capable(sta_ds); 6150 if (sta_ds->staType == STA_ENTRY_TDLS_PEER && peer_he_cap) 6151 return true; 6152 else 6153 return false; 6154 } else { 6155 return false; 6156 } 6157 } 6158 #else 6159 static inline 6160 bool lim_tdls_peer_support_he(tpDphHashNode sta_ds) 6161 { 6162 return false; 6163 } 6164 #endif 6165 6166 #ifdef WLAN_FEATURE_11BE_MLO 6167 static 6168 void lim_prepare_tdls_with_mlo(struct pe_session *session, 6169 tSirMacAddr peer_mac, tSirMacAddr self_mac, 6170 uint16_t *action) 6171 { 6172 uint8_t *mld_addr; 6173 6174 if (!sir_compare_mac_addr(session->bssId, peer_mac) && 6175 wlan_mlo_get_tdls_link_vdev(session->vdev)) { 6176 mld_addr = wlan_vdev_mlme_get_mldaddr(session->vdev); 6177 sir_copy_mac_addr(self_mac, mld_addr); 6178 *action = ACTION_CATEGORY_BACK << 8 | ADDBA_RESPONSE; 6179 } else { 6180 sir_copy_mac_addr(self_mac, session->self_mac_addr); 6181 *action = 0; 6182 } 6183 } 6184 #else 6185 static 6186 void lim_prepare_tdls_with_mlo(struct pe_session *session, 6187 tSirMacAddr peer_mac, tSirMacAddr self_mac, 6188 uint16_t *action) 6189 { 6190 sir_copy_mac_addr(self_mac, session->self_mac_addr); 6191 *action = 0; 6192 } 6193 #endif 6194 6195 QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, 6196 tSirMacAddr peer_mac, uint16_t tid, 6197 struct pe_session *session, uint8_t addba_extn_present, 6198 uint8_t amsdu_support, uint8_t is_wep, uint16_t calc_buff_size) 6199 { 6200 6201 tDot11faddba_rsp frm; 6202 uint8_t *frame_ptr; 6203 tpSirMacMgmtHdr mgmt_hdr; 6204 uint32_t num_bytes, payload_size, status; 6205 void *pkt_ptr = NULL; 6206 QDF_STATUS qdf_status; 6207 uint8_t tx_flag = 0; 6208 uint8_t vdev_id = 0; 6209 uint16_t buff_size, status_code, batimeout; 6210 uint16_t frm_buff_size = 0; 6211 uint8_t dialog_token; 6212 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 6213 uint8_t he_frag = 0; 6214 tpDphHashNode sta_ds = NULL; 6215 uint16_t aid; 6216 bool he_cap = false; 6217 bool eht_cap = false; 6218 struct wlan_mlme_qos *qos_aggr; 6219 tSirMacAddr self_mac; 6220 uint16_t action; 6221 6222 vdev_id = session->vdev_id; 6223 6224 cdp_addba_responsesetup(soc, peer_mac, vdev_id, tid, 6225 &dialog_token, &status_code, &buff_size, 6226 &batimeout); 6227 6228 qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params; 6229 qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); 6230 frm.Category.category = ACTION_CATEGORY_BACK; 6231 frm.Action.action = ADDBA_RESPONSE; 6232 6233 frm.DialogToken.token = dialog_token; 6234 frm.Status.status = status_code; 6235 6236 sta_ds = dph_lookup_hash_entry(mac_ctx, peer_mac, &aid, 6237 &session->dph.dphHashTable); 6238 6239 if (sta_ds && lim_is_session_he_capable(session)) 6240 he_cap = lim_is_sta_he_capable(sta_ds); 6241 6242 if (sta_ds && lim_is_session_eht_capable(session)) 6243 eht_cap = lim_is_sta_eht_capable(sta_ds); 6244 6245 if ((LIM_IS_STA_ROLE(session) && qos_aggr->rx_aggregation_size == 1 && 6246 !mac_ctx->usr_cfg_ba_buff_size) || mac_ctx->reject_addba_req) { 6247 frm.Status.status = STATUS_REQUEST_DECLINED; 6248 pe_err("refused addba req for rx_aggregation_size: %d mac_ctx->reject_addba_req: %d", 6249 qos_aggr->rx_aggregation_size, mac_ctx->reject_addba_req); 6250 } else if (LIM_IS_STA_ROLE(session) && !mac_ctx->usr_cfg_ba_buff_size) { 6251 frm_buff_size = 6252 QDF_MIN(qos_aggr->rx_aggregation_size, calc_buff_size); 6253 pe_debug("rx_aggregation_size %d, calc_buff_size %d", 6254 qos_aggr->rx_aggregation_size, calc_buff_size); 6255 6256 if (eht_cap) { 6257 if (frm_buff_size > MAX_EHT_BA_BUFF_SIZE) 6258 frm_buff_size = MAX_EHT_BA_BUFF_SIZE; 6259 } else { 6260 if (frm_buff_size > MAX_BA_BUFF_SIZE) 6261 frm_buff_size = MAX_BA_BUFF_SIZE; 6262 } 6263 } else { 6264 if (sta_ds && sta_ds->staType == STA_ENTRY_NDI_PEER) 6265 frm_buff_size = calc_buff_size; 6266 else if (eht_cap) 6267 frm_buff_size = MAX_EHT_BA_BUFF_SIZE; 6268 else if (he_cap) 6269 frm_buff_size = MAX_BA_BUFF_SIZE; 6270 else 6271 frm_buff_size = SIR_MAC_BA_DEFAULT_BUFF_SIZE; 6272 6273 if (mac_ctx->usr_cfg_ba_buff_size) 6274 frm_buff_size = mac_ctx->usr_cfg_ba_buff_size; 6275 6276 if (eht_cap) { 6277 if (frm_buff_size > MAX_EHT_BA_BUFF_SIZE) 6278 frm_buff_size = MAX_EHT_BA_BUFF_SIZE; 6279 } else { 6280 if (frm_buff_size > MAX_BA_BUFF_SIZE) 6281 frm_buff_size = MAX_BA_BUFF_SIZE; 6282 } 6283 6284 if (frm_buff_size > SIR_MAC_BA_DEFAULT_BUFF_SIZE) { 6285 if (session->active_ba_64_session) { 6286 frm_buff_size = SIR_MAC_BA_DEFAULT_BUFF_SIZE; 6287 } 6288 } else if (!session->active_ba_64_session) { 6289 session->active_ba_64_session = true; 6290 } 6291 if (buff_size && frm_buff_size > buff_size) { 6292 pe_debug("buff size: %d larger than peer's capability: %d", 6293 frm_buff_size, buff_size); 6294 frm_buff_size = buff_size; 6295 } 6296 } 6297 6298 /* In case where AP advertizes BA window size which is different 6299 * than our max supported BA window size. 6300 */ 6301 cdp_tid_update_ba_win_size(soc, peer_mac, vdev_id, tid, frm_buff_size); 6302 6303 frm.addba_param_set.tid = tid; 6304 frm.addba_param_set.buff_size = frm_buff_size % MAX_EHT_BA_BUFF_SIZE; 6305 6306 /* Enable RX AMSDU only in HE mode if supported */ 6307 if (mac_ctx->is_usr_cfg_amsdu_enabled && 6308 ((IS_PE_SESSION_HE_MODE(session) && 6309 WLAN_REG_IS_24GHZ_CH_FREQ(session->curr_op_freq)) || 6310 !WLAN_REG_IS_24GHZ_CH_FREQ(session->curr_op_freq) || 6311 lim_tdls_peer_support_he(sta_ds))) 6312 frm.addba_param_set.amsdu_supp = amsdu_support; 6313 else 6314 frm.addba_param_set.amsdu_supp = 0; 6315 6316 frm.addba_param_set.policy = SIR_MAC_BA_POLICY_IMMEDIATE; 6317 frm.ba_timeout.timeout = batimeout; 6318 if (addba_extn_present) { 6319 frm.addba_extn_element.present = 1; 6320 frm.addba_extn_element.no_fragmentation = 1; 6321 frm.addba_extn_element.extd_buff_size = 6322 frm_buff_size / MAX_EHT_BA_BUFF_SIZE; 6323 if (lim_is_session_he_capable(session)) { 6324 he_frag = lim_get_session_he_frag_cap(session); 6325 if (he_frag != 0) { 6326 frm.addba_extn_element.no_fragmentation = 0; 6327 frm.addba_extn_element.he_frag_operation = 6328 he_frag; 6329 } 6330 } 6331 } 6332 6333 /* 6334 * for TDLS MLO case, it needs to use MLD mac address for TA and 6335 * set action code to send out from specific vdev in fw. 6336 */ 6337 lim_prepare_tdls_with_mlo(session, peer_mac, self_mac, &action); 6338 pe_debug("Sending a ADDBA Response from "QDF_MAC_ADDR_FMT" to "QDF_MAC_ADDR_FMT, 6339 QDF_MAC_ADDR_REF(self_mac), 6340 QDF_MAC_ADDR_REF(peer_mac)); 6341 pe_debug("tid %d dialog_token %d status %d buff_size %d amsdu_supp %d", 6342 tid, frm.DialogToken.token, frm.Status.status, 6343 frm.addba_param_set.buff_size, 6344 frm.addba_param_set.amsdu_supp); 6345 pe_debug("addba_extn %d he_capable %d no_frag %d he_frag %d, exted buff size %d", 6346 addba_extn_present, 6347 lim_is_session_he_capable(session), 6348 frm.addba_extn_element.no_fragmentation, 6349 frm.addba_extn_element.he_frag_operation, 6350 frm.addba_extn_element.extd_buff_size); 6351 6352 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size); 6353 if (DOT11F_FAILED(status)) { 6354 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).", 6355 status); 6356 /* We'll fall back on the worst case scenario: */ 6357 payload_size = sizeof(tDot11faddba_rsp); 6358 } else if (DOT11F_WARNED(status)) { 6359 pe_warn("There were warnings while calculating the packed size for a ADDBA Response (0x%08x).", status); 6360 } 6361 6362 num_bytes = payload_size + sizeof(*mgmt_hdr); 6363 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 6364 (void **)&pkt_ptr); 6365 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || (!pkt_ptr)) { 6366 pe_err("Failed to allocate %d bytes for a ADDBA response action frame", 6367 num_bytes); 6368 return QDF_STATUS_E_FAILURE; 6369 } 6370 qdf_mem_zero(frame_ptr, num_bytes); 6371 6372 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 6373 SIR_MAC_MGMT_ACTION, peer_mac, self_mac); 6374 6375 /* Update A3 with the BSSID */ 6376 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr; 6377 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 6378 6379 /* ADDBA Response is a robust mgmt action frame, 6380 * set the "protect" (aka WEP) bit in the FC 6381 */ 6382 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr); 6383 6384 if (is_wep && sta_ds && sta_ds->staType == STA_ENTRY_NDI_PEER) { 6385 mgmt_hdr->fc.wep = 1; 6386 tx_flag |= HAL_USE_PMF; 6387 } 6388 6389 status = dot11f_pack_addba_rsp(mac_ctx, &frm, 6390 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size, 6391 &payload_size); 6392 6393 if (DOT11F_FAILED(status)) { 6394 pe_err("Failed to pack a ADDBA Response (0x%08x)", 6395 status); 6396 qdf_status = QDF_STATUS_E_FAILURE; 6397 goto error_addba_rsp; 6398 } else if (DOT11F_WARNED(status)) { 6399 pe_warn("There were warnings while packing ADDBA Response (0x%08x)", 6400 status); 6401 } 6402 6403 6404 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 6405 session->opmode == QDF_P2P_CLIENT_MODE || 6406 session->opmode == QDF_P2P_GO_MODE) 6407 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 6408 6409 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 6410 session->peSessionId, mgmt_hdr->fc.subType)); 6411 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, pkt_ptr, 6412 (uint16_t)num_bytes, 6413 TXRX_FRM_802_11_MGMT, 6414 ANI_TXDIR_TODS, 7, 6415 NULL, frame_ptr, 6416 lim_addba_rsp_tx_complete_cnf, 6417 tx_flag, vdev_id, 6418 false, 0, RATEID_DEFAULT, 0, 6419 action); 6420 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 6421 session->peSessionId, qdf_status)); 6422 if (QDF_STATUS_SUCCESS != qdf_status) { 6423 pe_err("wma_tx_frame FAILED! Status [%d]", 6424 qdf_status); 6425 return QDF_STATUS_E_FAILURE; 6426 } else { 6427 return QDF_STATUS_SUCCESS; 6428 } 6429 6430 error_addba_rsp: 6431 cds_packet_free((void *)pkt_ptr); 6432 return qdf_status; 6433 } 6434 6435 #ifdef WLAN_FEATURE_11BE_MLO 6436 QDF_STATUS 6437 lim_send_epcs_update_edca_params(struct wlan_objmgr_vdev *vdev, 6438 tSirMacEdcaParamRecord *edca, bool mu_edca) 6439 { 6440 struct mac_context *mac_ctx; 6441 6442 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 6443 if (!mac_ctx) 6444 return QDF_STATUS_E_INVAL; 6445 6446 return lim_send_edca_params(mac_ctx, edca, 6447 wlan_vdev_get_id(vdev), mu_edca); 6448 } 6449 6450 QDF_STATUS 6451 lim_send_epcs_restore_edca_params(struct wlan_objmgr_vdev *vdev) 6452 { 6453 struct mac_context *mac_ctx; 6454 struct pe_session *session; 6455 6456 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 6457 if (!mac_ctx) 6458 return QDF_STATUS_E_INVAL; 6459 6460 session = pe_find_session_by_vdev_id(mac_ctx, wlan_vdev_get_id(vdev)); 6461 if (!session) 6462 return QDF_STATUS_E_INVAL; 6463 6464 lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive, 6465 session->vdev_id, false); 6466 6467 if (mac_ctx->usr_cfg_mu_edca_params) 6468 lim_send_edca_params(mac_ctx, mac_ctx->usr_mu_edca_params, 6469 session->vdev_id, true); 6470 else if (session->mu_edca_present) 6471 lim_send_edca_params(mac_ctx, session->ap_mu_edca_params, 6472 session->vdev_id, true); 6473 6474 return QDF_STATUS_SUCCESS; 6475 } 6476 6477 QDF_STATUS 6478 lim_send_epcs_action_rsp_frame(struct wlan_objmgr_vdev *vdev, 6479 uint8_t *peer_mac, 6480 struct wlan_action_frame_args *args) 6481 { 6482 struct mac_context *mac_ctx; 6483 struct pe_session *session; 6484 tDot11fepcs_neg_rsp frm; 6485 uint8_t *frame_ptr; 6486 tpSirMacMgmtHdr mgmt_hdr; 6487 uint32_t num_bytes, payload_size, status; 6488 void *pkt_ptr = NULL; 6489 uint8_t vdev_id = 0; 6490 uint8_t tx_flag = 0; 6491 QDF_STATUS qdf_status; 6492 6493 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 6494 if (!mac_ctx) 6495 return QDF_STATUS_E_INVAL; 6496 6497 session = pe_find_session_by_vdev_id(mac_ctx, wlan_vdev_get_id(vdev)); 6498 if (!session) 6499 return QDF_STATUS_E_INVAL; 6500 6501 frm.Category.category = args->category; 6502 frm.Action.action = args->action; 6503 frm.DialogToken.token = args->arg1; 6504 frm.Status.status = args->arg2; 6505 6506 pe_debug("Sending a EPCS negotiation Response from " QDF_MAC_ADDR_FMT " to " QDF_MAC_ADDR_FMT, 6507 QDF_MAC_ADDR_REF(session->self_mac_addr), 6508 QDF_MAC_ADDR_REF(peer_mac)); 6509 pe_debug("Dialog token %d status %d", frm.DialogToken.token, 6510 frm.Status.status); 6511 6512 status = dot11f_get_packed_epcs_neg_rspSize(mac_ctx, &frm, 6513 &payload_size); 6514 if (DOT11F_FAILED(status)) { 6515 pe_err("Failed to calculate packed size for a EPCS negotiation Response (0x%08x).", 6516 status); 6517 /* We'll fall back on the worst case scenario: */ 6518 payload_size = sizeof(tDot11fepcs_neg_rsp); 6519 } else if (DOT11F_WARNED(status)) { 6520 pe_warn("There were warnings while calculating packed size for a EPCS negotiation Response (0x%08x).", 6521 status); 6522 } 6523 6524 num_bytes = payload_size + sizeof(*mgmt_hdr); 6525 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 6526 (void **)&pkt_ptr); 6527 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || !pkt_ptr) { 6528 pe_err("Failed to allocate %d bytes for a EPCS rsp action frm", 6529 num_bytes); 6530 return QDF_STATUS_E_FAILURE; 6531 } 6532 6533 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 6534 SIR_MAC_MGMT_ACTION, peer_mac, 6535 session->self_mac_addr); 6536 6537 /* Update A3 with the BSSID */ 6538 mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr; 6539 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 6540 6541 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr); 6542 6543 status = dot11f_pack_epcs_neg_rsp(mac_ctx, &frm, 6544 frame_ptr + sizeof(tSirMacMgmtHdr), 6545 payload_size, &payload_size); 6546 6547 if (DOT11F_FAILED(status)) { 6548 pe_err("Failed to pack a EPCS negotiation response (0x%08x)", 6549 status); 6550 qdf_status = QDF_STATUS_E_FAILURE; 6551 goto error_epcs_rsp; 6552 } else if (DOT11F_WARNED(status)) { 6553 pe_warn("There were warnings while packing EPCS rsp (0x%08x)", 6554 status); 6555 } 6556 6557 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 6558 session->opmode == QDF_P2P_CLIENT_MODE || 6559 session->opmode == QDF_P2P_GO_MODE) 6560 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 6561 6562 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 6563 session->peSessionId, mgmt_hdr->fc.subType)); 6564 6565 vdev_id = session->vdev_id; 6566 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t)num_bytes, 6567 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 6568 lim_tx_complete, frame_ptr, tx_flag, 6569 vdev_id, 0, RATEID_DEFAULT, 0); 6570 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 6571 session->peSessionId, qdf_status)); 6572 if (QDF_STATUS_SUCCESS != qdf_status) { 6573 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 6574 return QDF_STATUS_E_FAILURE; 6575 } else { 6576 return QDF_STATUS_SUCCESS; 6577 } 6578 6579 error_epcs_rsp: 6580 cds_packet_free((void *)pkt_ptr); 6581 return qdf_status; 6582 } 6583 6584 QDF_STATUS 6585 lim_send_epcs_action_req_frame(struct wlan_objmgr_vdev *vdev, 6586 uint8_t *peer_mac, 6587 struct wlan_action_frame_args *args) 6588 { 6589 tDot11fepcs_neg_req frm; 6590 struct mac_context *mac_ctx; 6591 struct pe_session *session; 6592 uint8_t *frame_ptr; 6593 tpSirMacMgmtHdr mgmt_hdr; 6594 uint32_t num_bytes, payload_size, status; 6595 void *pkt_ptr = NULL; 6596 QDF_STATUS qdf_status; 6597 uint8_t vdev_id = 0; 6598 uint8_t tx_flag = 0; 6599 6600 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 6601 if (!mac_ctx) 6602 return QDF_STATUS_E_INVAL; 6603 6604 if (!vdev) 6605 return QDF_STATUS_E_NULL_VALUE; 6606 6607 vdev_id = wlan_vdev_get_id(vdev); 6608 6609 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 6610 if (!session) { 6611 pe_debug("session not found for given vdev_id %d ", vdev_id); 6612 return QDF_STATUS_E_INVAL; 6613 } 6614 6615 frm.Category.category = args->category; 6616 frm.Action.action = args->action; 6617 frm.DialogToken.token = args->arg1; 6618 6619 pe_debug("Sending a EPCS negotiation Request from " QDF_MAC_ADDR_FMT " to " QDF_MAC_ADDR_FMT, 6620 QDF_MAC_ADDR_REF(session->self_mac_addr), 6621 QDF_MAC_ADDR_REF(peer_mac)); 6622 pe_debug("Dialog token %d", frm.DialogToken.token); 6623 6624 status = dot11f_get_packed_epcs_neg_reqSize(mac_ctx, &frm, 6625 &payload_size); 6626 if (DOT11F_FAILED(status)) { 6627 pe_err("Failed to calculate packed size for a EPCS negotiation Request (0x%08x).", 6628 status); 6629 /* We'll fall back on the worst case scenario: */ 6630 payload_size = sizeof(tDot11fepcs_neg_req); 6631 } else if (DOT11F_WARNED(status)) { 6632 pe_warn("There were warnings while calculating packed size for a EPCS negotiation Request (0x%08x).", 6633 status); 6634 } 6635 6636 num_bytes = payload_size + sizeof(*mgmt_hdr); 6637 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 6638 (void **)&pkt_ptr); 6639 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || (!pkt_ptr)) { 6640 pe_err("Failed to allocate %d bytes for a EPCS req action frm", 6641 num_bytes); 6642 return QDF_STATUS_E_FAILURE; 6643 } 6644 6645 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 6646 SIR_MAC_MGMT_ACTION, peer_mac, 6647 session->self_mac_addr); 6648 6649 /* Update A3 with the BSSID */ 6650 mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr; 6651 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 6652 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr); 6653 6654 status = dot11f_pack_epcs_neg_req(mac_ctx, &frm, 6655 frame_ptr + sizeof(tSirMacMgmtHdr), 6656 payload_size, &payload_size); 6657 6658 if (DOT11F_FAILED(status)) { 6659 pe_err("Failed to pack a EPCS negotiation request (0x%08x)", 6660 status); 6661 qdf_status = QDF_STATUS_E_FAILURE; 6662 goto error_epcs_req; 6663 } else if (DOT11F_WARNED(status)) { 6664 pe_warn("There were warnings while packing EPCS req (0x%08x)", 6665 status); 6666 } 6667 6668 pe_debug("Dump EPCS TX req action frame"); 6669 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, frame_ptr, 6670 num_bytes); 6671 6672 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 6673 session->opmode == QDF_P2P_CLIENT_MODE || 6674 session->opmode == QDF_P2P_GO_MODE) 6675 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 6676 6677 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 6678 session->peSessionId, mgmt_hdr->fc.subType)); 6679 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t)num_bytes, 6680 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 6681 lim_tx_complete, frame_ptr, tx_flag, 6682 vdev_id, 0, RATEID_DEFAULT, 0); 6683 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 6684 session->peSessionId, qdf_status)); 6685 if (qdf_status != QDF_STATUS_SUCCESS) { 6686 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 6687 return QDF_STATUS_E_FAILURE; 6688 } else { 6689 return QDF_STATUS_SUCCESS; 6690 } 6691 6692 error_epcs_req: 6693 cds_packet_free((void *)pkt_ptr); 6694 return qdf_status; 6695 } 6696 6697 QDF_STATUS 6698 lim_send_epcs_action_teardown_frame(struct wlan_objmgr_vdev *vdev, 6699 uint8_t *peer_mac, 6700 struct wlan_action_frame_args *args) 6701 { 6702 tDot11fepcs_teardown frm; 6703 struct mac_context *mac_ctx; 6704 struct pe_session *session; 6705 uint8_t *frame_ptr; 6706 tpSirMacMgmtHdr mgmt_hdr; 6707 uint32_t num_bytes, payload_size, status; 6708 void *pkt_ptr = NULL; 6709 QDF_STATUS qdf_status; 6710 uint8_t vdev_id = 0; 6711 uint8_t tx_flag = 0; 6712 6713 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 6714 if (!mac_ctx) 6715 return QDF_STATUS_E_INVAL; 6716 6717 if (!vdev) 6718 return QDF_STATUS_E_NULL_VALUE; 6719 6720 vdev_id = wlan_vdev_get_id(vdev); 6721 6722 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 6723 if (!session) { 6724 pe_err("session not found for given vdev_id %d", vdev_id); 6725 return QDF_STATUS_E_INVAL; 6726 } 6727 6728 frm.Category.category = args->category; 6729 frm.Action.action = args->action; 6730 6731 pe_debug("Sending a EPCS tear down from " QDF_MAC_ADDR_FMT " to " QDF_MAC_ADDR_FMT, 6732 QDF_MAC_ADDR_REF(session->self_mac_addr), 6733 QDF_MAC_ADDR_REF(peer_mac)); 6734 6735 status = dot11f_get_packed_epcs_teardownSize(mac_ctx, &frm, 6736 &payload_size); 6737 if (DOT11F_FAILED(status)) { 6738 pe_err("Failed to calculate packed size for a EPCS tear down (0x%08x).", 6739 status); 6740 /* We'll fall back on the worst case scenario: */ 6741 payload_size = sizeof(tDot11fepcs_teardown); 6742 } else if (DOT11F_WARNED(status)) { 6743 pe_warn("There were warnings while calculating packed size for a EPCS tear down (0x%08x).", 6744 status); 6745 } 6746 6747 num_bytes = payload_size + sizeof(*mgmt_hdr); 6748 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 6749 (void **)&pkt_ptr); 6750 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || (!pkt_ptr)) { 6751 pe_err("Failed to allocate %d bytes for a EPCS req action frm", 6752 num_bytes); 6753 return QDF_STATUS_E_FAILURE; 6754 } 6755 qdf_mem_zero(frame_ptr, num_bytes); 6756 6757 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 6758 SIR_MAC_MGMT_ACTION, peer_mac, 6759 session->self_mac_addr); 6760 6761 /* Update A3 with the BSSID */ 6762 mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr; 6763 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 6764 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr); 6765 6766 status = dot11f_pack_epcs_teardown(mac_ctx, &frm, 6767 frame_ptr + sizeof(tSirMacMgmtHdr), 6768 payload_size, &payload_size); 6769 if (DOT11F_FAILED(status)) { 6770 pe_err("Failed to pack a EPCS tear down (0x%08x)", 6771 status); 6772 qdf_status = QDF_STATUS_E_FAILURE; 6773 goto error_epcs_td; 6774 } else if (DOT11F_WARNED(status)) { 6775 pe_warn("There were warnings while packing EPCS tear down(0x%08x)", 6776 status); 6777 } 6778 6779 pe_debug("Dump EPCS TX tear down action frame"); 6780 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, frame_ptr, 6781 num_bytes); 6782 6783 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 6784 session->opmode == QDF_P2P_CLIENT_MODE || 6785 session->opmode == QDF_P2P_GO_MODE) 6786 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 6787 6788 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 6789 session->peSessionId, mgmt_hdr->fc.subType)); 6790 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t)num_bytes, 6791 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 6792 lim_tx_complete, frame_ptr, tx_flag, 6793 vdev_id, 0, RATEID_DEFAULT, 0); 6794 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 6795 session->peSessionId, qdf_status)); 6796 if (qdf_status != QDF_STATUS_SUCCESS) { 6797 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 6798 return QDF_STATUS_E_FAILURE; 6799 } else { 6800 return QDF_STATUS_SUCCESS; 6801 } 6802 6803 error_epcs_td: 6804 cds_packet_free((void *)pkt_ptr); 6805 return qdf_status; 6806 } 6807 6808 QDF_STATUS 6809 lim_send_t2lm_action_rsp_frame(struct mac_context *mac_ctx, 6810 tSirMacAddr peer_mac, 6811 struct pe_session *session, uint8_t token, 6812 enum wlan_t2lm_resp_frm_type status_code) 6813 { 6814 tDot11ft2lm_neg_rsp frm; 6815 uint8_t session_id = 0; 6816 uint8_t *frame_ptr; 6817 tpSirMacMgmtHdr mgmt_hdr; 6818 uint32_t num_bytes, payload_size, status; 6819 void *pkt_ptr = NULL; 6820 QDF_STATUS qdf_status; 6821 uint8_t vdev_id = 0; 6822 uint8_t tx_flag = 0; 6823 6824 session_id = session->smeSessionId; 6825 6826 vdev_id = session->vdev_id; 6827 6828 qdf_mem_zero((uint8_t *)&frm, sizeof(frm)); 6829 frm.Category.category = ACTION_CATEGORY_PROTECTED_EHT; 6830 frm.Action.action = EHT_T2LM_RESPONSE; 6831 6832 frm.DialogToken.token = token; 6833 frm.Status.status = status_code; 6834 6835 pe_debug("Sending a T2LM negotiation Response from " QDF_MAC_ADDR_FMT " to " QDF_MAC_ADDR_FMT, 6836 QDF_MAC_ADDR_REF(session->self_mac_addr), 6837 QDF_MAC_ADDR_REF(peer_mac)); 6838 pe_debug("Dialog token %d status %d", frm.DialogToken.token, 6839 frm.Status.status); 6840 6841 status = dot11f_get_packed_t2lm_neg_rspSize(mac_ctx, &frm, 6842 &payload_size); 6843 if (DOT11F_FAILED(status)) { 6844 pe_err("Failed to calculate packed size for a T2LM negotiation Response (0x%08x).", 6845 status); 6846 /* We'll fall back on the worst case scenario: */ 6847 payload_size = sizeof(tDot11ft2lm_neg_rsp); 6848 } else if (DOT11F_WARNED(status)) { 6849 pe_warn("There were warnings while calculating packed size for a T2LM negotiation Response (0x%08x).", 6850 status); 6851 } 6852 6853 num_bytes = payload_size + sizeof(*mgmt_hdr); 6854 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 6855 (void **)&pkt_ptr); 6856 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || (!pkt_ptr)) { 6857 pe_err("Failed to allocate %d bytes for a T2LM rsp action frm", 6858 num_bytes); 6859 return QDF_STATUS_E_FAILURE; 6860 } 6861 qdf_mem_zero(frame_ptr, num_bytes); 6862 6863 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 6864 SIR_MAC_MGMT_ACTION, peer_mac, 6865 session->self_mac_addr); 6866 6867 /* Update A3 with the BSSID */ 6868 mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr; 6869 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 6870 6871 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr); 6872 6873 status = dot11f_pack_t2lm_neg_rsp(mac_ctx, &frm, 6874 frame_ptr + sizeof(tSirMacMgmtHdr), 6875 payload_size, &payload_size); 6876 6877 if (DOT11F_FAILED(status)) { 6878 pe_err("Failed to pack a T2LM negotiation response (0x%08x)", 6879 status); 6880 qdf_status = QDF_STATUS_E_FAILURE; 6881 goto error_t2lm_rsp; 6882 } else if (DOT11F_WARNED(status)) { 6883 pe_warn("There were warnings while packing T2LM rsp (0x%08x)", 6884 status); 6885 } 6886 6887 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 6888 session->opmode == QDF_P2P_CLIENT_MODE || 6889 session->opmode == QDF_P2P_GO_MODE) 6890 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 6891 6892 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 6893 session->peSessionId, mgmt_hdr->fc.subType)); 6894 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t)num_bytes, 6895 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 6896 lim_tx_complete, frame_ptr, tx_flag, 6897 vdev_id, 0, RATEID_DEFAULT, 0); 6898 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 6899 session->peSessionId, qdf_status)); 6900 if (QDF_STATUS_SUCCESS != qdf_status) { 6901 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 6902 return QDF_STATUS_E_FAILURE; 6903 } else { 6904 return QDF_STATUS_SUCCESS; 6905 } 6906 6907 error_t2lm_rsp: 6908 cds_packet_free((void *)pkt_ptr); 6909 return qdf_status; 6910 } 6911 6912 QDF_STATUS 6913 lim_send_t2lm_action_req_frame(struct wlan_objmgr_vdev *vdev, 6914 uint8_t *peer_mac, 6915 struct wlan_action_frame_args *args, 6916 struct wlan_t2lm_onging_negotiation_info *t2lm_neg, 6917 uint8_t token) 6918 { 6919 tDot11ft2lm_neg_req frm; 6920 struct mac_context *mac_ctx; 6921 struct pe_session *session; 6922 uint8_t session_id = 0; 6923 uint8_t *frame_ptr; 6924 tpSirMacMgmtHdr mgmt_hdr; 6925 uint32_t num_bytes, payload_size, status; 6926 void *pkt_ptr = NULL; 6927 QDF_STATUS qdf_status; 6928 uint8_t vdev_id = 0; 6929 uint8_t tx_flag = 0; 6930 struct wlan_ie_tid_to_link_mapping *t2lm_ie; 6931 struct wlan_ie_tid_to_link_mapping *ie_buf; 6932 uint8_t *t2lm_frame; 6933 6934 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 6935 if (!mac_ctx) 6936 return QDF_STATUS_E_INVAL; 6937 6938 if (!vdev) 6939 return QDF_STATUS_E_NULL_VALUE; 6940 6941 vdev_id = wlan_vdev_get_id(vdev); 6942 6943 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 6944 if (!session) { 6945 pe_err("session not found for given vdev_id %d", vdev_id); 6946 return QDF_STATUS_E_INVAL; 6947 } 6948 session_id = session->smeSessionId; 6949 6950 qdf_mem_zero((uint8_t *)&frm, sizeof(frm)); 6951 6952 ie_buf = qdf_mem_malloc(sizeof(uint8_t) * T2LM_IE_ACTION_FRAME_MAX_LEN); 6953 6954 if (!ie_buf) { 6955 pe_err("Malloc failed"); 6956 return QDF_STATUS_E_NULL_VALUE; 6957 } 6958 6959 t2lm_ie = (struct wlan_ie_tid_to_link_mapping *)&frm.t2lm_ie[0].data; 6960 t2lm_frame = wlan_mlo_add_t2lm_ie((uint8_t *)ie_buf, 6961 t2lm_neg, 6962 vdev); 6963 if (!t2lm_frame) { 6964 pe_debug("Failed to populate T2LM IE"); 6965 qdf_mem_free(ie_buf); 6966 return QDF_STATUS_E_FAILURE; 6967 } 6968 6969 frm.t2lm_ie[0].num_data = ie_buf->elem_len - 1; 6970 6971 pe_debug("Dump T2LM IE buff len %d", ie_buf->elem_len); 6972 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, ie_buf, 6973 ie_buf->elem_len + sizeof(struct ie_header)); 6974 6975 qdf_mem_copy(&frm.t2lm_ie[0].data, ie_buf->data, 6976 frm.t2lm_ie[0].num_data); 6977 6978 qdf_mem_free(ie_buf); 6979 6980 frm.Category.category = args->category; 6981 frm.Action.action = args->action; 6982 frm.DialogToken.token = args->arg1; 6983 frm.num_t2lm_ie = 1; 6984 frm.t2lm_ie[0].present = 1; 6985 6986 pe_debug("Sending a T2LM negotiation Request from " QDF_MAC_ADDR_FMT " to " QDF_MAC_ADDR_FMT, 6987 QDF_MAC_ADDR_REF(session->self_mac_addr), 6988 QDF_MAC_ADDR_REF(peer_mac)); 6989 pe_debug("Dialog token %d", frm.DialogToken.token); 6990 6991 status = dot11f_get_packed_t2lm_neg_reqSize(mac_ctx, &frm, 6992 &payload_size); 6993 if (DOT11F_FAILED(status)) { 6994 pe_err("Failed to calculate packed size for a T2LM negotiation Request (0x%08x).", 6995 status); 6996 /* We'll fall back on the worst case scenario: */ 6997 payload_size = sizeof(tDot11ft2lm_neg_req); 6998 } else if (DOT11F_WARNED(status)) { 6999 pe_warn("There were warnings while calculating packed size for a T2LM negotiation Request (0x%08x).", 7000 status); 7001 } 7002 7003 num_bytes = payload_size + sizeof(*mgmt_hdr); 7004 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 7005 (void **)&pkt_ptr); 7006 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || (!pkt_ptr)) { 7007 pe_err("Failed to allocate %d bytes for a T2LM req action frm", 7008 num_bytes); 7009 return QDF_STATUS_E_FAILURE; 7010 } 7011 qdf_mem_zero(frame_ptr, num_bytes); 7012 7013 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 7014 SIR_MAC_MGMT_ACTION, peer_mac, 7015 session->self_mac_addr); 7016 7017 /* Update A3 with the BSSID */ 7018 mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr; 7019 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 7020 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr); 7021 7022 status = dot11f_pack_t2lm_neg_req(mac_ctx, &frm, 7023 frame_ptr + sizeof(tSirMacMgmtHdr), 7024 payload_size, &payload_size); 7025 7026 if (DOT11F_FAILED(status)) { 7027 pe_err("Failed to pack a T2LM negotiation request (0x%08x)", 7028 status); 7029 qdf_status = QDF_STATUS_E_FAILURE; 7030 goto error_t2lm_req; 7031 } else if (DOT11F_WARNED(status)) { 7032 pe_warn("There were warnings while packing T2LM req (0x%08x)", 7033 status); 7034 } 7035 7036 pe_debug("Dump T2LM TX req action frame"); 7037 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, frame_ptr, 7038 num_bytes); 7039 7040 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || 7041 session->opmode == QDF_P2P_CLIENT_MODE || 7042 session->opmode == QDF_P2P_GO_MODE) 7043 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 7044 7045 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 7046 session->peSessionId, mgmt_hdr->fc.subType)); 7047 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t)num_bytes, 7048 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, 7049 lim_tx_complete, frame_ptr, tx_flag, 7050 vdev_id, 0, RATEID_DEFAULT, 0); 7051 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 7052 session->peSessionId, qdf_status)); 7053 if (qdf_status != QDF_STATUS_SUCCESS) { 7054 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status); 7055 return QDF_STATUS_E_FAILURE; 7056 } else { 7057 return QDF_STATUS_SUCCESS; 7058 } 7059 7060 error_t2lm_req: 7061 cds_packet_free((void *)pkt_ptr); 7062 return qdf_status; 7063 } 7064 #endif 7065 7066 /** 7067 * lim_delba_tx_complete_cnf() - Confirmation for Delba OTA 7068 * @context: pointer to global mac 7069 * @buf: netbuf of Del BA frame 7070 * @tx_complete : Sent status 7071 * @params; tx completion params 7072 * 7073 * Return: This returns QDF_STATUS 7074 */ 7075 static QDF_STATUS lim_delba_tx_complete_cnf(void *context, 7076 qdf_nbuf_t buf, 7077 uint32_t tx_complete, 7078 void *params) 7079 { 7080 struct mac_context *mac_ctx = (struct mac_context *)context; 7081 tSirMacMgmtHdr *mac_hdr; 7082 struct sDot11fdelba_req frm; 7083 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 7084 uint32_t frame_len; 7085 QDF_STATUS status; 7086 uint8_t *data; 7087 struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)params; 7088 7089 if (!mgmt_params || !mac_ctx || !buf || !soc) { 7090 pe_err("delba tx cnf invalid parameters"); 7091 goto error; 7092 } 7093 data = qdf_nbuf_data(buf); 7094 if (!data) { 7095 pe_err("Delba frame is NULL"); 7096 goto error; 7097 } 7098 7099 mac_hdr = (tSirMacMgmtHdr *)data; 7100 qdf_mem_zero((void *)&frm, sizeof(struct sDot11fdelba_req)); 7101 frame_len = sizeof(frm); 7102 status = dot11f_unpack_delba_req(mac_ctx, (uint8_t *)data + 7103 sizeof(*mac_hdr), frame_len, 7104 &frm, false); 7105 if (DOT11F_FAILED(status)) { 7106 pe_err("Failed to unpack and parse delba (0x%08x, %d bytes)", 7107 status, frame_len); 7108 goto error; 7109 } 7110 pe_debug("delba ota done vdev %d "QDF_MAC_ADDR_FMT" tid %d desc_id %d status %d", 7111 mgmt_params->vdev_id, 7112 QDF_MAC_ADDR_REF(mac_hdr->da), frm.delba_param_set.tid, 7113 mgmt_params->desc_id, tx_complete); 7114 cdp_delba_tx_completion(soc, mac_hdr->da, mgmt_params->vdev_id, 7115 frm.delba_param_set.tid, tx_complete); 7116 7117 error: 7118 if (buf) 7119 qdf_nbuf_free(buf); 7120 7121 return QDF_STATUS_SUCCESS; 7122 } 7123 7124 QDF_STATUS lim_send_delba_action_frame(struct mac_context *mac_ctx, 7125 uint8_t vdev_id, uint8_t *peer_macaddr, 7126 uint8_t tid, uint8_t reason_code) 7127 { 7128 struct pe_session *session; 7129 struct sDot11fdelba_req frm; 7130 QDF_STATUS qdf_status; 7131 tpSirMacMgmtHdr mgmt_hdr; 7132 uint32_t num_bytes, payload_size = 0; 7133 uint32_t status; 7134 void *pkt_ptr = NULL; 7135 uint8_t *frame_ptr; 7136 uint8_t tx_flag = 0; 7137 7138 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 7139 if (!session) { 7140 pe_debug("delba invalid vdev id %d ", vdev_id); 7141 return QDF_STATUS_E_INVAL; 7142 } 7143 pe_debug("send delba vdev %d "QDF_MAC_ADDR_FMT" tid %d reason %d", vdev_id, 7144 QDF_MAC_ADDR_REF(peer_macaddr), tid, reason_code); 7145 qdf_mem_zero((uint8_t *)&frm, sizeof(frm)); 7146 frm.Category.category = ACTION_CATEGORY_BACK; 7147 frm.Action.action = DELBA; 7148 frm.delba_param_set.initiator = 0; 7149 frm.delba_param_set.tid = tid; 7150 frm.Reason.code = reason_code; 7151 7152 status = dot11f_get_packed_delba_req_size(mac_ctx, &frm, &payload_size); 7153 if (DOT11F_FAILED(status)) { 7154 pe_err("Failed to calculate the packed size for a DELBA(0x%08x).", 7155 status); 7156 /* We'll fall back on the worst case scenario: */ 7157 payload_size = sizeof(struct sDot11fdelba_req); 7158 } else if (DOT11F_WARNED(status)) { 7159 pe_warn("Warnings in calculating the packed size for a DELBA (0x%08x).", 7160 status); 7161 } 7162 num_bytes = payload_size + sizeof(*mgmt_hdr); 7163 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr, 7164 (void **)&pkt_ptr); 7165 if (!QDF_IS_STATUS_SUCCESS(qdf_status) || !pkt_ptr) { 7166 pe_err("Failed to allocate %d bytes for a DELBA", 7167 num_bytes); 7168 return QDF_STATUS_E_FAILURE; 7169 } 7170 qdf_mem_zero(frame_ptr, num_bytes); 7171 7172 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME, 7173 SIR_MAC_MGMT_ACTION, peer_macaddr, 7174 session->self_mac_addr); 7175 7176 /* Update A3 with the BSSID */ 7177 mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr; 7178 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId); 7179 7180 /* DEL is a robust mgmt action frame, 7181 * set the "protect" (aka WEP) bit in the FC 7182 */ 7183 lim_set_protected_bit(mac_ctx, session, peer_macaddr, mgmt_hdr); 7184 7185 status = dot11f_pack_delba_req(mac_ctx, &frm, 7186 frame_ptr + sizeof(tSirMacMgmtHdr), 7187 payload_size, &payload_size); 7188 if (DOT11F_FAILED(status)) { 7189 pe_err("Failed to pack a DELBA (0x%08x)", 7190 status); 7191 qdf_status = QDF_STATUS_E_FAILURE; 7192 goto error_delba; 7193 } else if (DOT11F_WARNED(status)) { 7194 pe_warn("There were warnings while packing DELBA (0x%08x)", 7195 status); 7196 } 7197 if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq) || 7198 wlan_reg_is_6ghz_chan_freq(session->curr_op_freq) || 7199 session->opmode == QDF_P2P_CLIENT_MODE || 7200 session->opmode == QDF_P2P_GO_MODE) 7201 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; 7202 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, 7203 session->peSessionId, mgmt_hdr->fc.subType)); 7204 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, pkt_ptr, 7205 (uint16_t)num_bytes, 7206 TXRX_FRM_802_11_MGMT, 7207 ANI_TXDIR_TODS, 7, 7208 NULL, frame_ptr, 7209 lim_delba_tx_complete_cnf, 7210 tx_flag, vdev_id, 7211 false, 0, RATEID_DEFAULT, 0, 0); 7212 if (qdf_status != QDF_STATUS_SUCCESS) { 7213 pe_err("delba wma_tx_frame FAILED! Status [%d]", qdf_status); 7214 return qdf_status; 7215 } else { 7216 return QDF_STATUS_SUCCESS; 7217 } 7218 7219 error_delba: 7220 if (pkt_ptr) 7221 cds_packet_free((void *)pkt_ptr); 7222 7223 return qdf_status; 7224 } 7225 7226 #define MAC_AUTH_FRAME_STATUS_CODE_OFFSET 4 7227 7228 /** 7229 * lim_tx_mgmt_frame() - Transmits Auth mgmt frame 7230 * @mac_ctx Pointer to Global MAC structure 7231 * @vdev_id: vdev id 7232 * @msg_len: Received message length 7233 * @packet: Packet to be transmitted 7234 * @frame: Received frame 7235 * 7236 * Return: None 7237 */ 7238 static void lim_tx_mgmt_frame(struct mac_context *mac_ctx, uint8_t vdev_id, 7239 uint32_t msg_len, void *packet, uint8_t *frame) 7240 { 7241 tpSirMacFrameCtl fc = (tpSirMacFrameCtl)frame; 7242 QDF_STATUS qdf_status; 7243 struct pe_session *session = NULL; 7244 uint16_t auth_ack_status; 7245 enum rateid min_rid = RATEID_DEFAULT; 7246 enum QDF_OPMODE opmode; 7247 uint16_t session_id; 7248 qdf_freq_t channel_freq = 0; 7249 qdf_freq_t *pre_auth_freq = NULL; 7250 7251 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id); 7252 if (opmode != QDF_NAN_DISC_MODE) { 7253 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 7254 if (!session) { 7255 cds_packet_free((void *)packet); 7256 pe_err("session not found for given vdev_id %d", 7257 vdev_id); 7258 return; 7259 } 7260 session_id = session->peSessionId; 7261 } else { 7262 session_id = vdev_id; 7263 } 7264 7265 qdf_mtrace(QDF_MODULE_ID_PE, QDF_MODULE_ID_WMA, TRACE_CODE_TX_MGMT, 7266 session_id, 0); 7267 7268 if (opmode != QDF_NAN_DISC_MODE) { 7269 if (fc->subType == SIR_MAC_MGMT_AUTH) { 7270 tpSirFTPreAuthReq pre_auth_req; 7271 uint16_t auth_algo = *(uint16_t *)(frame + 7272 sizeof(tSirMacMgmtHdr)); 7273 7274 if (auth_algo == eSIR_AUTH_TYPE_SAE) { 7275 if (session->ftPEContext.pFTPreAuthReq) { 7276 pre_auth_req = 7277 session->ftPEContext.pFTPreAuthReq; 7278 channel_freq = 7279 pre_auth_req->pre_auth_channel_freq; 7280 } 7281 pre_auth_freq = &channel_freq; 7282 } 7283 pe_debug("TX SAE pre-auth frame on freq %d", 7284 channel_freq); 7285 } 7286 min_rid = lim_get_min_session_txrate(session, pre_auth_freq); 7287 } 7288 7289 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet, 7290 (uint16_t)msg_len, 7291 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7292 7, lim_tx_complete, frame, 7293 lim_auth_tx_complete_cnf, 7294 0, vdev_id, false, channel_freq, 7295 min_rid, 0, 0); 7296 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, 7297 session_id, qdf_status)); 7298 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 7299 pe_err("*** Could not send Auth frame (subType: %d), retCode=%X ***", 7300 fc->subType, qdf_status); 7301 mac_ctx->auth_ack_status = LIM_TX_FAILED; 7302 auth_ack_status = SENT_FAIL; 7303 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT, 7304 session, auth_ack_status, QDF_STATUS_E_FAILURE); 7305 /* Pkt will be freed up by the callback */ 7306 } 7307 } 7308 7309 static void 7310 lim_handle_sae_auth_retry(struct mac_context *mac_ctx, uint8_t vdev_id, 7311 uint8_t *frame, uint32_t frame_len) 7312 { 7313 struct pe_session *session; 7314 struct sae_auth_retry *sae_retry; 7315 uint8_t retry_count = 0; 7316 uint32_t val = 0; 7317 7318 session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 7319 if (!session) { 7320 pe_err("session not found for given vdev_id %d", 7321 vdev_id); 7322 return; 7323 } 7324 if ((session->opmode != QDF_STA_MODE) && 7325 (session->opmode != QDF_P2P_CLIENT_MODE)) 7326 return; 7327 7328 if (session->limMlmState == eLIM_MLM_WT_SAE_AUTH_STATE) 7329 wlan_mlme_get_sae_auth_retry_count(mac_ctx->psoc, &retry_count); 7330 else 7331 wlan_mlme_get_sae_roam_auth_retry_count(mac_ctx->psoc, 7332 &retry_count); 7333 if (!retry_count) { 7334 pe_debug("vdev %d: SAE Auth retry disabled", vdev_id); 7335 return; 7336 } 7337 7338 sae_retry = mlme_get_sae_auth_retry(session->vdev); 7339 if (!sae_retry) { 7340 pe_err("sae retry pointer is NULL for vdev_id %d", 7341 vdev_id); 7342 return; 7343 } 7344 7345 if (sae_retry->sae_auth.ptr) 7346 lim_sae_auth_cleanup_retry(mac_ctx, vdev_id); 7347 7348 sae_retry->sae_auth.ptr = qdf_mem_malloc(frame_len); 7349 if (!sae_retry->sae_auth.ptr) 7350 return; 7351 7352 pe_debug("SAE auth frame queued vdev_id %d seq_num %d", 7353 vdev_id, mac_ctx->mgmtSeqNum + 1); 7354 qdf_mem_copy(sae_retry->sae_auth.ptr, frame, frame_len); 7355 mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer.sessionId = 7356 session->peSessionId; 7357 sae_retry->sae_auth.len = frame_len; 7358 sae_retry->sae_auth_max_retry = retry_count; 7359 7360 val = mac_ctx->mlme_cfg->timeouts.sae_auth_failure_timeout; 7361 7362 tx_timer_change( 7363 &mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer, 7364 SYS_MS_TO_TICKS(val), 0); 7365 /* Activate Auth Retry timer */ 7366 if (tx_timer_activate( 7367 &mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) != 7368 TX_SUCCESS) { 7369 pe_err("failed to start periodic auth retry timer"); 7370 lim_sae_auth_cleanup_retry(mac_ctx, vdev_id); 7371 } 7372 } 7373 7374 #ifdef WLAN_FEATURE_11BE_MLO 7375 static QDF_STATUS lim_update_mld_to_link_address(struct mac_context *mac_ctx, 7376 struct wlan_objmgr_vdev *vdev, 7377 tpSirMacMgmtHdr mac_hdr) 7378 { 7379 struct qdf_mac_addr *self_link_addr; 7380 struct tLimPreAuthNode *pre_auth_node; 7381 struct qdf_mac_addr peer_link_addr; 7382 struct qdf_mac_addr *peer_roaming_link_addr; 7383 enum QDF_OPMODE opmode; 7384 QDF_STATUS status; 7385 7386 if (!wlan_cm_is_sae_auth_addr_conversion_required(vdev)) 7387 return QDF_STATUS_SUCCESS; 7388 7389 opmode = wlan_vdev_mlme_get_opmode(vdev); 7390 self_link_addr = (struct qdf_mac_addr *) 7391 wlan_vdev_mlme_get_linkaddr(vdev); 7392 7393 switch (opmode) { 7394 case QDF_SAP_MODE: 7395 pre_auth_node = 7396 lim_search_pre_auth_list_by_mld_addr(mac_ctx, 7397 mac_hdr->da); 7398 if (!pre_auth_node) { 7399 /** 7400 * Using MLD address, if pre_auth_node is not present then 7401 * check for peer mac address due to legacy connection. 7402 */ 7403 pre_auth_node = lim_search_pre_auth_list(mac_ctx, 7404 mac_hdr->da); 7405 if (!pre_auth_node) { 7406 pe_err("pre_auth not found by MLD: "QDF_MAC_ADDR_FMT, 7407 QDF_MAC_ADDR_REF(mac_hdr->da)); 7408 return QDF_STATUS_E_INVAL; 7409 } else { 7410 return QDF_STATUS_SUCCESS; 7411 } 7412 } 7413 7414 qdf_mem_copy(mac_hdr->da, pre_auth_node->peerMacAddr, 7415 QDF_MAC_ADDR_SIZE); 7416 qdf_mem_copy(mac_hdr->bssId, self_link_addr->bytes, 7417 QDF_MAC_ADDR_SIZE); 7418 break; 7419 case QDF_STA_MODE: 7420 if (!wlan_cm_is_vdev_roaming(vdev)) { 7421 status = wlan_vdev_get_bss_peer_mac(vdev, 7422 &peer_link_addr); 7423 if (QDF_IS_STATUS_ERROR(status)) 7424 return status; 7425 } else { 7426 peer_roaming_link_addr = 7427 wlan_cm_roaming_get_peer_link_addr(vdev); 7428 if (!peer_roaming_link_addr) 7429 return QDF_STATUS_E_FAILURE; 7430 peer_link_addr = *peer_roaming_link_addr; 7431 } 7432 7433 qdf_mem_copy(mac_hdr->da, peer_link_addr.bytes, 7434 QDF_MAC_ADDR_SIZE); 7435 qdf_mem_copy(mac_hdr->bssId, peer_link_addr.bytes, 7436 QDF_MAC_ADDR_SIZE); 7437 break; 7438 default: 7439 return QDF_STATUS_SUCCESS; 7440 } 7441 7442 qdf_mem_copy(mac_hdr->sa, self_link_addr->bytes, QDF_MAC_ADDR_SIZE); 7443 7444 return QDF_STATUS_SUCCESS; 7445 } 7446 #else 7447 static QDF_STATUS lim_update_mld_to_link_address(struct mac_context *mac_ctx, 7448 struct wlan_objmgr_vdev *vdev, 7449 tpSirMacMgmtHdr mac_hdr) 7450 { 7451 return QDF_STATUS_SUCCESS; 7452 } 7453 #endif 7454 7455 void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf, 7456 uint16_t buf_len) 7457 { 7458 QDF_STATUS qdf_status; 7459 uint8_t *frame; 7460 void *packet; 7461 tpSirMacFrameCtl fc = (tpSirMacFrameCtl)buf; 7462 tpSirMacMgmtHdr mac_hdr = (tpSirMacMgmtHdr)buf; 7463 struct wlan_objmgr_vdev *vdev; 7464 QDF_STATUS status; 7465 7466 pe_debug("sending fc->type: %d fc->subType: %d", fc->type, fc->subType); 7467 7468 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 7469 WLAN_LEGACY_MAC_ID); 7470 if (!vdev) 7471 return; 7472 7473 /* Case: 7474 * 1. In case of SAP, userspace will send MLD addresses in 2nd and 4th 7475 * SAE auth frames. Driver needs to convert it into link address. 7476 * 2. In case of STA, userspace will send MLD addresses in 1st and 3rd 7477 * SAE auth frames. Driver needs to convert it into link address. 7478 */ 7479 status = lim_update_mld_to_link_address(mac_ctx, vdev, mac_hdr); 7480 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7481 7482 if (QDF_IS_STATUS_ERROR(status)) { 7483 pe_err("SAE address conversion failure with status:%d", status); 7484 return; 7485 } 7486 7487 lim_add_mgmt_seq_num(mac_ctx, mac_hdr); 7488 qdf_status = cds_packet_alloc(buf_len, (void **)&frame, 7489 (void **)&packet); 7490 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 7491 pe_err("call to bufAlloc failed for AUTH frame"); 7492 return; 7493 } 7494 7495 qdf_mem_copy(frame, buf, buf_len); 7496 lim_tx_mgmt_frame(mac_ctx, vdev_id, buf_len, packet, frame); 7497 } 7498 7499 void lim_send_mgmt_frame_tx(struct mac_context *mac_ctx, 7500 struct scheduler_msg *msg) 7501 { 7502 struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr; 7503 uint32_t msg_len; 7504 tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data; 7505 uint8_t vdev_id; 7506 uint16_t auth_algo; 7507 7508 msg_len = mb_msg->msg_len - sizeof(*mb_msg); 7509 vdev_id = mb_msg->vdev_id; 7510 7511 if (fc->subType == SIR_MAC_MGMT_AUTH) { 7512 auth_algo = *(uint16_t *)(mb_msg->data + 7513 sizeof(tSirMacMgmtHdr)); 7514 if (auth_algo == eSIR_AUTH_TYPE_SAE) 7515 lim_handle_sae_auth_retry(mac_ctx, vdev_id, 7516 mb_msg->data, msg_len); 7517 if (auth_algo == eSIR_FT_AUTH) { 7518 struct tLimPreAuthNode *sta_pre_auth_ctx; 7519 7520 sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx, 7521 ((tpSirMacMgmtHdr)(mb_msg->data))->da); 7522 pe_debug("FT Auth TX to " QDF_MAC_ADDR_FMT, 7523 QDF_MAC_ADDR_REF(((tpSirMacMgmtHdr)(mb_msg->data))->da)); 7524 if (sta_pre_auth_ctx) { 7525 pe_debug("STA is AUTHENTICATED_STATE"); 7526 sta_pre_auth_ctx->mlmState = 7527 eLIM_MLM_AUTHENTICATED_STATE; 7528 } 7529 } 7530 } 7531 mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; 7532 lim_send_frame(mac_ctx, vdev_id, mb_msg->data, msg_len); 7533 } 7534