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