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