1 /* 2 * Copyright (c) 2012-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 * lim_process_tdls.c 22 * OVERVIEW: 23 * 24 * DEPENDENCIES: 25 * 26 * Are listed for each API below. 27 * ===========================================================================*/ 28 29 /*=========================================================================== 30 31 * EDIT HISTORY FOR FILE 32 33 * This section contains comments describing changes made to the module. 34 * Notice that changes are listed in reverse chronological order. 35 36 * $Header$$DateTime$$Author$ 37 38 * when who what, where, why 39 * ---------- --- ------------------------------------------------------ 40 * 05/05/2010 Ashwani Initial Creation, added TDLS action frame 41 * functionality,TDLS message exchange with SME..etc.. 42 43 ===========================================================================*/ 44 45 /** 46 * \file lim_process_tdls.c 47 * 48 * \brief Code for preparing,processing and sending 802.11z action frames 49 * 50 */ 51 52 #ifdef FEATURE_WLAN_TDLS 53 54 #include "sir_api.h" 55 #include "ani_global.h" 56 #include "sir_mac_prot_def.h" 57 #include "utils_api.h" 58 #include "lim_types.h" 59 #include "lim_utils.h" 60 #include "lim_security_utils.h" 61 #include "dot11f.h" 62 #include "sch_api.h" 63 #include "lim_send_messages.h" 64 #include "utils_parser.h" 65 #include "lim_assoc_utils.h" 66 #include "lim_prop_exts_utils.h" 67 #include "dph_hash_table.h" 68 #include "wma_types.h" 69 #include "cds_regdomain.h" 70 #include "cds_utils.h" 71 #include "wlan_mlo_mgr_sta.h" 72 #include "wlan_reg_services_api.h" 73 #include "wlan_tdls_tgt_api.h" 74 #include "wlan_mlme_public_struct.h" 75 #include "wlan_mlme_api.h" 76 #include "wlan_tdls_public_structs.h" 77 #include "wlan_cfg80211_tdls.h" 78 #include "wlan_tdls_api.h" 79 #include "lim_mlo.h" 80 81 /* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630 82 There was IOT issue with cisco 1252 open mode, where it pads 83 discovery req/teardown frame with some junk value up to min size. 84 To avoid this issue, we pad QCOM_VENDOR_IE. 85 If there is other IOT issue because of this bandage, define NO_PAD... 86 */ 87 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 88 #define MIN_IEEE_8023_SIZE 46 89 #define MIN_VENDOR_SPECIFIC_IE_SIZE 5 90 #endif 91 92 /* 93 * TDLS data frames will go out/come in as non-qos data. 94 * so, eth_890d_header will be aligned access.. 95 */ 96 static const uint8_t eth_890d_header[] = { 97 0xaa, 0xaa, 0x03, 0x00, 98 0x00, 0x00, 0x89, 0x0d, 99 }; 100 101 #define ETH_ADDR_LEN 6 /* bytes */ 102 103 struct tdls_ethernet_hdr { 104 uint8_t dest_addr[ETH_ADDR_LEN]; 105 uint8_t src_addr[ETH_ADDR_LEN]; 106 } qdf_packed; 107 108 #define eth_890d_hdr_len 2 /* bytes */ 109 110 static const uint8_t eth_890d_tdls_discvory_frm_hdr[] = { 111 0x89, 0x0d, 0x02, 0x0c, 0x0a, 112 }; 113 114 #define TDLS_ETHR_HDR_LEN (sizeof(struct tdls_ethernet_hdr)) 115 116 /* 117 * type of links used in TDLS 118 */ 119 enum tdlsLinks { 120 TDLS_LINK_AP, 121 TDLS_LINK_DIRECT 122 } e_tdls_link; 123 124 enum tdlsReqType { 125 TDLS_INITIATOR, 126 TDLS_RESPONDER 127 } e_tdls_req_type; 128 129 typedef enum tdlsLinkSetupStatus { 130 TDLS_SETUP_STATUS_SUCCESS = 0, 131 TDLS_SETUP_STATUS_FAILURE = 37 132 } etdlsLinkSetupStatus; 133 134 /* These maps to Kernel TDLS peer capability 135 * flags and should get changed as and when necessary 136 */ 137 enum tdls_peer_capability { 138 TDLS_PEER_HT_CAP = 0, 139 TDLS_PEER_VHT_CAP = 1, 140 TDLS_PEER_WMM_CAP = 2, 141 TDLS_PEER_HE_CAP = 3 142 } e_tdls_peer_capability; 143 144 #define LINK_IDEN_ADDR_OFFSET(x) (&(x)->LinkIdentifier) 145 146 /* TODO, Move this parameters to configuration */ 147 #define PEER_PSM_SUPPORT (0) 148 #define TDLS_SUPPORT (1) 149 #define TDLS_PROHIBITED (0) 150 #define TDLS_CH_SWITCH_PROHIBITED (1) 151 /** @brief Set bit manipulation macro */ 152 #define SET_BIT(value, mask) ((value) |= (1 << (mask))) 153 /** @brief Clear bit manipulation macro */ 154 #define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask))) 155 /** @brief Check bit manipulation macro */ 156 #define CHECK_BIT(value, mask) ((value) & (1 << (mask))) 157 158 #define SET_PEER_AID_BITMAP(peer_bitmap, aid) \ 159 do { \ 160 if ((aid) < (sizeof(uint32_t) << 3)) \ 161 SET_BIT(peer_bitmap[0], (aid)); \ 162 else if ((aid) < (sizeof(uint32_t) << 4)) \ 163 SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\ 164 } while (0); 165 166 #define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \ 167 do { \ 168 if ((aid) < (sizeof(uint32_t) << 3)) \ 169 CLEAR_BIT(peer_bitmap[0], (aid)); \ 170 else if ((aid) < (sizeof(uint32_t) << 4)) \ 171 CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\ 172 } while (0); 173 174 #define IS_QOS_ENABLED(pe_session) ((((pe_session)->limQosEnabled) && \ 175 SIR_MAC_GET_QOS((pe_session)->limCurrentBssCaps)) || \ 176 (((pe_session)->limWmeEnabled) && \ 177 LIM_BSS_CAPS_GET(WME, (pe_session)->limCurrentBssQosCaps))) 178 179 #define TID_AC_VI 4 180 #define TID_AC_BK 1 181 182 static const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode) 183 { 184 switch (tdlsActionCode) { 185 CASE_RETURN_STRING(TDLS_SETUP_REQUEST); 186 CASE_RETURN_STRING(TDLS_SETUP_RESPONSE); 187 CASE_RETURN_STRING(TDLS_SETUP_CONFIRM); 188 CASE_RETURN_STRING(TDLS_TEARDOWN); 189 CASE_RETURN_STRING(TDLS_PEER_TRAFFIC_INDICATION); 190 CASE_RETURN_STRING(TDLS_CHANNEL_SWITCH_REQUEST); 191 CASE_RETURN_STRING(TDLS_CHANNEL_SWITCH_RESPONSE); 192 CASE_RETURN_STRING(TDLS_PEER_TRAFFIC_RESPONSE); 193 CASE_RETURN_STRING(TDLS_DISCOVERY_REQUEST); 194 CASE_RETURN_STRING(TDLS_DISCOVERY_RESPONSE); 195 } 196 return (const uint8_t *)"UNKNOWN"; 197 } 198 199 /* 200 * initialize TDLS setup list and related data structures. 201 */ 202 void lim_init_tdls_data(struct mac_context *mac, struct pe_session *pe_session) 203 { 204 lim_init_peer_idxpool(mac, pe_session); 205 206 return; 207 } 208 209 static bool 210 is_duplicate_chan(uint8_t *arr, uint8_t index, uint8_t ch_id) 211 { 212 int i; 213 214 for (i = 0; i < index; i++) { 215 if (arr[i] == ch_id) 216 return true; 217 } 218 return false; 219 } 220 221 static void populate_dot11f_tdls_offchannel_params( 222 struct mac_context *mac, 223 struct pe_session *pe_session, 224 tDot11fIESuppChannels *suppChannels, 225 tDot11fIESuppOperatingClasses *suppOperClasses) 226 { 227 uint32_t numChans = CFG_VALID_CHANNEL_LIST_LEN; 228 uint8_t validChan[CFG_VALID_CHANNEL_LIST_LEN]; 229 uint8_t i, count_opclss = 1; 230 uint8_t valid_count = 0; 231 uint8_t chanOffset; 232 uint8_t op_class; 233 uint8_t numClasses; 234 uint8_t classes[REG_MAX_SUPP_OPER_CLASSES]; 235 uint32_t band; 236 uint8_t nss_2g; 237 uint8_t nss_5g; 238 qdf_freq_t ch_freq; 239 bool is_vlp_country; 240 uint8_t ap_cc[REG_ALPHA2_LEN + 1]; 241 uint8_t reg_cc[REG_ALPHA2_LEN + 1]; 242 243 numChans = mac->mlme_cfg->reg.valid_channel_list_num; 244 245 if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq)) 246 band = BAND_2G; 247 else 248 band = BAND_5G; 249 250 nss_5g = QDF_MIN(mac->vdev_type_nss_5g.tdls, 251 mac->user_configured_nss); 252 nss_2g = QDF_MIN(mac->vdev_type_nss_2g.tdls, 253 mac->user_configured_nss); 254 255 wlan_cm_get_country_code(mac->pdev, pe_session->vdev_id, ap_cc); 256 wlan_reg_read_current_country(mac->psoc, reg_cc); 257 is_vlp_country = wlan_reg_ctry_support_vlp(ap_cc) && 258 wlan_reg_ctry_support_vlp(reg_cc); 259 260 /* validating the channel list for DFS and 2G channels */ 261 for (i = 0; i < numChans; i++) { 262 ch_freq = mac->mlme_cfg->reg.valid_channel_freq_list[i]; 263 264 validChan[i] = wlan_reg_freq_to_chan(mac->pdev, 265 mac->mlme_cfg->reg.valid_channel_freq_list[i]); 266 267 if (is_duplicate_chan(validChan, i, validChan[i])) 268 continue; 269 270 if ((band == BAND_5G) && 271 (NSS_2x2_MODE == nss_5g) && 272 (NSS_1x1_MODE == nss_2g) && 273 (wlan_reg_is_dfs_for_freq(mac->pdev, ch_freq))) { 274 pe_debug("skipping channel: %d, nss_5g: %d, nss_2g: %d", 275 validChan[i], nss_5g, nss_2g); 276 continue; 277 } else { 278 if (wlan_reg_is_dsrc_freq(ch_freq)) { 279 pe_debug("skipping freq: %d from the valid freq list", 280 ch_freq); 281 continue; 282 } 283 } 284 285 if (wlan_reg_is_6ghz_chan_freq(ch_freq) && 286 !(is_vlp_country && 287 wlan_reg_is_6ghz_psc_chan_freq(ch_freq))) { 288 pe_debug("skipping is_vlp_country %d or non-psc channel %d", 289 is_vlp_country, ch_freq); 290 continue; 291 } 292 293 if (valid_count >= ARRAY_SIZE(suppChannels->bands)) 294 break; 295 296 suppChannels->bands[valid_count][0] = validChan[i]; 297 suppChannels->bands[valid_count][1] = 1; 298 valid_count++; 299 } 300 301 suppChannels->num_bands = valid_count; 302 suppChannels->present = 1; 303 304 /* find channel offset and get op class for current operating channel */ 305 switch (pe_session->htSecondaryChannelOffset) { 306 case PHY_SINGLE_CHANNEL_CENTERED: 307 chanOffset = BW20; 308 break; 309 310 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 311 chanOffset = BW40_LOW_PRIMARY; 312 break; 313 314 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 315 chanOffset = BW40_HIGH_PRIMARY; 316 break; 317 318 default: 319 chanOffset = BWALL; 320 break; 321 } 322 323 op_class = wlan_reg_dmn_get_opclass_from_channel( 324 reg_cc, 325 wlan_reg_freq_to_chan(mac->pdev, pe_session->curr_op_freq), 326 chanOffset); 327 328 suppOperClasses->present = 1; 329 suppOperClasses->classes[0] = op_class; 330 331 wlan_reg_dmn_get_curr_opclasses(&numClasses, &classes[0]); 332 333 for (i = 0; i < numClasses; i++) { 334 if (wlan_reg_is_6ghz_op_class(mac->pdev, classes[i]) && 335 !is_vlp_country) 336 continue; 337 338 suppOperClasses->classes[count_opclss] = classes[i]; 339 count_opclss++; 340 } 341 342 pe_debug("countryCodeCurrent: %s, curr_op_freq: %d, htSecondaryChannelOffset: %d, chanOffset: %d op class: %d num_supportd_chan %d total opclasses %d num_supportd_opclass %d", 343 reg_cc, 344 pe_session->curr_op_freq, 345 pe_session->htSecondaryChannelOffset, 346 chanOffset, op_class, valid_count, numClasses, 347 count_opclss); 348 349 /* add one for present operating class, added in the beginning */ 350 suppOperClasses->num_classes = count_opclss; 351 352 return; 353 } 354 355 #ifdef WLAN_FEATURE_11BE_MLO 356 /** 357 * lim_tdls_copy_self_mac() - copy mac address 358 * @session: pe session 359 * @init_sta_addr: the pointer to save the address 360 * 361 * For MLD device, it needs to copy mld mac address. 362 * 363 * Return: void 364 */ 365 static void lim_tdls_copy_self_mac(struct pe_session *session, 366 uint8_t *init_sta_addr) 367 { 368 struct wlan_mlo_dev_context *mlo_dev_ctx; 369 370 if (wlan_vdev_mlme_is_mlo_vdev(session->vdev)) { 371 mlo_dev_ctx = session->vdev->mlo_dev_ctx; 372 if (!mlo_dev_ctx) { 373 pe_debug("mlo_dev_ctx is NULL"); 374 return; 375 } 376 377 qdf_mem_copy((uint8_t *)init_sta_addr, 378 mlo_dev_ctx->mld_addr.bytes, QDF_MAC_ADDR_SIZE); 379 } else { 380 qdf_mem_copy((uint8_t *)init_sta_addr, 381 session->self_mac_addr, QDF_MAC_ADDR_SIZE); 382 } 383 } 384 #else 385 static void lim_tdls_copy_self_mac(struct pe_session *session, 386 uint8_t *init_sta_addr) 387 { 388 qdf_mem_copy((uint8_t *)init_sta_addr, 389 session->self_mac_addr, QDF_MAC_ADDR_SIZE); 390 } 391 #endif 392 393 /* 394 * FUNCTION: Populate Link Identifier element IE 395 * 396 */ 397 398 static void populate_dot11f_link_iden(struct mac_context *mac, 399 struct pe_session *pe_session, 400 tDot11fIELinkIdentifier *linkIden, 401 struct qdf_mac_addr peer_mac, 402 uint8_t reqType) 403 { 404 uint8_t *initaddr = NULL; 405 uint8_t *respaddr = NULL; 406 407 (reqType == TDLS_INITIATOR) ? ((initaddr = linkIden->InitStaAddr), 408 (respaddr = linkIden->RespStaAddr)) 409 : ((respaddr = linkIden->InitStaAddr), 410 (initaddr = linkIden->RespStaAddr)); 411 qdf_mem_copy((uint8_t *)linkIden->bssid, 412 (uint8_t *)pe_session->bssId, QDF_MAC_ADDR_SIZE); 413 414 lim_tdls_copy_self_mac(pe_session, initaddr); 415 416 qdf_mem_copy((uint8_t *)respaddr, (uint8_t *)peer_mac.bytes, 417 QDF_MAC_ADDR_SIZE); 418 419 linkIden->present = 1; 420 return; 421 422 } 423 424 static void populate_dot11f_tdls_ext_capability(struct mac_context *mac, 425 struct pe_session *pe_session, 426 tDot11fIEExtCap *extCapability) 427 { 428 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes; 429 430 p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT; 431 p_ext_cap->tdls_peer_uapsd_buffer_sta = mac->lim.gLimTDLSBufStaEnabled; 432 433 /* 434 * Set TDLS channel switching bits only if offchannel is enabled 435 * and TDLS Channel Switching is not prohibited by AP in ExtCap 436 * IE in assoc/re-assoc response. 437 */ 438 if ((1 == mac->lim.gLimTDLSOffChannelEnabled) && 439 (!mlme_get_tdls_chan_switch_prohibited(pe_session->vdev))) { 440 p_ext_cap->tdls_channel_switching = 1; 441 p_ext_cap->tdls_chan_swit_prohibited = 0; 442 } else { 443 p_ext_cap->tdls_channel_switching = 0; 444 p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED; 445 } 446 p_ext_cap->tdls_support = TDLS_SUPPORT; 447 p_ext_cap->tdls_prohibited = TDLS_PROHIBITED; 448 /* 449 * For supporting wider bandwidth set tdls_wider_bw set as 1 450 */ 451 if (wlan_cfg80211_tdls_is_fw_wideband_capable(pe_session->vdev) && 452 (mac->lim.gLimTDLSOffChannelEnabled || 453 !wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq))) 454 p_ext_cap->tdls_wider_bw = 1; 455 456 extCapability->present = 1; 457 extCapability->num_bytes = lim_compute_ext_cap_ie_length(extCapability); 458 459 return; 460 } 461 462 /* 463 * prepare TDLS frame header, it includes 464 * | | | | 465 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD 466 * | | | | 467 */ 468 static uint32_t lim_prepare_tdls_frame_header(struct mac_context *mac, uint8_t *pFrame, 469 tDot11fIELinkIdentifier *link_iden, 470 uint8_t tdlsLinkType, uint8_t reqType, 471 uint8_t tid, 472 struct pe_session *pe_session) 473 { 474 tpSirMacDataHdr3a pMacHdr; 475 uint32_t header_offset = 0; 476 uint8_t *addr1 = NULL; 477 uint8_t *addr3 = NULL; 478 uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP) 479 ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS; 480 uint8_t *peerMac = (reqType == TDLS_INITIATOR) 481 ? link_iden->RespStaAddr : link_iden->InitStaAddr; 482 uint8_t *staMac = (reqType == TDLS_INITIATOR) 483 ? link_iden->InitStaAddr : link_iden->RespStaAddr; 484 tpDphHashNode sta_ds; 485 uint16_t aid = 0; 486 uint8_t qos_mode = 0; 487 488 pMacHdr = (tpSirMacDataHdr3a) (pFrame); 489 490 /* 491 * if TDLS frame goes through the AP link, it follows normal address 492 * pattern, if TDLS frame goes through the direct link, then 493 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID 494 */ 495 (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)), 496 (addr3 = (peerMac))) 497 : ((addr1 = (peerMac)), (addr3 = (link_iden->bssid))); 498 /* 499 * prepare 802.11 header 500 */ 501 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; 502 pMacHdr->fc.type = SIR_MAC_DATA_FRAME; 503 504 sta_ds = dph_lookup_hash_entry(mac, peerMac, &aid, 505 &pe_session->dph.dphHashTable); 506 if (sta_ds) 507 qos_mode = sta_ds->qosMode; 508 509 pMacHdr->fc.subType = 510 ((IS_QOS_ENABLED(pe_session) && 511 (tdlsLinkType == TDLS_LINK_AP)) || 512 ((tdlsLinkType == TDLS_LINK_DIRECT) && qos_mode)) 513 ? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA; 514 515 /* 516 * TL is not setting up below fields, so we are doing it here 517 */ 518 pMacHdr->fc.toDS = toDs; 519 pMacHdr->fc.powerMgmt = 0; 520 pMacHdr->fc.wep = (pe_session->encryptType == eSIR_ED_NONE) ? 0 : 1; 521 522 qdf_mem_copy((uint8_t *) pMacHdr->addr1, 523 (uint8_t *) addr1, sizeof(tSirMacAddr)); 524 qdf_mem_copy((uint8_t *) pMacHdr->addr2, 525 (uint8_t *) staMac, sizeof(tSirMacAddr)); 526 527 qdf_mem_copy((uint8_t *) pMacHdr->addr3, 528 (uint8_t *) (addr3), sizeof(tSirMacAddr)); 529 530 pe_debug("Preparing TDLS frame header to %s A1:" 531 QDF_MAC_ADDR_FMT", A2:"QDF_MAC_ADDR_FMT", A3:" 532 QDF_MAC_ADDR_FMT, 533 (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT", 534 QDF_MAC_ADDR_REF(pMacHdr->addr1), 535 QDF_MAC_ADDR_REF(pMacHdr->addr2), 536 QDF_MAC_ADDR_REF(pMacHdr->addr3)); 537 538 if (pMacHdr->fc.subType == SIR_MAC_DATA_QOS_DATA) { 539 pMacHdr->qosControl.tid = tid; 540 header_offset += sizeof(tSirMacDataHdr3a); 541 } else 542 header_offset += sizeof(tSirMacMgmtHdr); 543 544 /* 545 * Now form RFC1042 header 546 */ 547 qdf_mem_copy((uint8_t *) (pFrame + header_offset), 548 (uint8_t *) eth_890d_header, sizeof(eth_890d_header)); 549 550 header_offset += sizeof(eth_890d_header); 551 552 /* add payload type as TDLS */ 553 *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS; 554 header_offset += PAYLOAD_TYPE_TDLS_SIZE; 555 556 return header_offset; 557 } 558 559 /** 560 * lim_mgmt_tdls_tx_complete - callback to indicate Tx completion 561 * @context: pointer to mac structure 562 * @buf: buffer 563 * @tx_complete: indicates tx success/failure 564 * @params: tx completion params 565 * 566 * Function will be invoked on receiving tx completion indication 567 * 568 * Return: success: eHAL_STATUS_SUCCESS failure: eHAL_STATUS_FAILURE 569 */ 570 static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf, 571 uint32_t tx_complete, void *params) 572 { 573 struct mac_context *mac_ctx = (struct mac_context *)context; 574 struct tdls_ethernet_hdr *ethernet_hdr; 575 tpSirMacActionFrameHdr action_hdr; 576 bool is_tdls_discvory_frm = false; 577 578 579 if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) { 580 if (buf && 581 (qdf_nbuf_len(buf) >= (TDLS_ETHR_HDR_LEN + 582 eth_890d_hdr_len + 583 PAYLOAD_TYPE_TDLS_SIZE + 584 sizeof(*action_hdr)))) { 585 ethernet_hdr = 586 (struct tdls_ethernet_hdr *)qdf_nbuf_data(buf); 587 is_tdls_discvory_frm = 588 !qdf_mem_cmp(((uint8_t *)qdf_nbuf_data(buf) + 589 TDLS_ETHR_HDR_LEN), 590 eth_890d_tdls_discvory_frm_hdr, 591 sizeof(eth_890d_tdls_discvory_frm_hdr)); 592 593 if (is_tdls_discvory_frm && 594 tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) 595 wlan_tdls_increment_discovery_attempts( 596 mac_ctx->psoc, 597 mac_ctx->lim.tdls_frm_session_id, 598 ethernet_hdr->dest_addr); 599 } 600 601 lim_send_sme_mgmt_tx_completion(mac_ctx, 602 mac_ctx->lim.tdls_frm_session_id, 603 tx_complete); 604 mac_ctx->lim.tdls_frm_session_id = NO_SESSION; 605 } 606 607 pe_debug("tdls_frm_session_id: %x tx_complete: %x is_discovery:%d", 608 mac_ctx->lim.tdls_frm_session_id, tx_complete, 609 is_tdls_discvory_frm); 610 611 if (buf) 612 qdf_nbuf_free(buf); 613 614 return QDF_STATUS_SUCCESS; 615 } 616 617 #ifdef WLAN_FEATURE_11BE_MLO 618 /** 619 * lim_get_assoc_link_vdev_id() - get vdev id 620 * @session: pe session 621 * 622 * Since fw only uses assoc link vdev to transmit data packets, 623 * it needs to fetch the right vdev id when transfer tdls management 624 * frame for partner link. 625 * 626 * Return: vdev id 627 */ 628 static uint8_t lim_get_assoc_link_vdev_id(struct pe_session *session) 629 { 630 struct wlan_objmgr_vdev *assoc_vdev; 631 632 if (wlan_vdev_mlme_is_mlo_vdev(session->vdev)) { 633 assoc_vdev = wlan_mlo_get_assoc_link_vdev(session->vdev); 634 if (assoc_vdev) 635 return wlan_vdev_get_id(assoc_vdev); 636 } 637 638 return session->smeSessionId; 639 } 640 #else 641 static uint8_t lim_get_assoc_link_vdev_id(struct pe_session *session) 642 { 643 return session->smeSessionId; 644 } 645 #endif 646 647 /* 648 * This function can be used for bacst or unicast discovery request 649 * We are not differentiating it here, it will all depend on peer MAC address, 650 */ 651 static QDF_STATUS lim_send_tdls_dis_req_frame(struct mac_context *mac, 652 struct qdf_mac_addr peer_mac, 653 uint8_t dialog, 654 struct pe_session *pe_session, 655 enum wifi_traffic_ac ac) 656 { 657 tDot11fTDLSDisReq *tdls_dis_req; 658 uint32_t status = 0; 659 uint32_t nPayload = 0; 660 uint32_t size = 0; 661 uint32_t nBytes = 0; 662 uint32_t header_offset = 0; 663 uint8_t *pFrame; 664 void *pPacket; 665 uint8_t vdev_id; 666 QDF_STATUS qdf_status; 667 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 668 uint32_t padLen = 0; 669 #endif 670 uint8_t smeSessionId = 0; 671 uint16_t mlo_ie_len = 0; 672 673 if (!pe_session) { 674 pe_err("pe_session is NULL"); 675 return QDF_STATUS_E_FAILURE; 676 } 677 678 tdls_dis_req = qdf_mem_malloc(sizeof(*tdls_dis_req)); 679 if (!tdls_dis_req) { 680 pe_err("memory allocation failed for DisReq"); 681 return QDF_STATUS_E_NOMEM; 682 } 683 684 smeSessionId = pe_session->smeSessionId; 685 /* 686 * The scheme here is to fill out a 'tDot11fProbeRequest' structure 687 * and then hand it off to 'dot11f_pack_probe_request' (for 688 * serialization). 689 */ 690 691 /* 692 * setup Fixed fields, 693 */ 694 tdls_dis_req->Category.category = ACTION_CATEGORY_TDLS; 695 tdls_dis_req->Action.action = TDLS_DISCOVERY_REQUEST; 696 tdls_dis_req->DialogToken.token = dialog; 697 698 size = sizeof(tSirMacAddr); 699 700 populate_dot11f_link_iden(mac, pe_session, 701 &tdls_dis_req->LinkIdentifier, 702 peer_mac, TDLS_INITIATOR); 703 704 if (wlan_vdev_mlme_is_mlo_vdev(pe_session->vdev)) 705 mlo_ie_len = lim_send_tdls_mgmt_frame_mlo(mac, pe_session); 706 707 /* 708 * now we pack it. First, how much space are we going to need? 709 */ 710 status = dot11f_get_packed_tdls_dis_req_size(mac, tdls_dis_req, 711 &nPayload); 712 if (DOT11F_FAILED(status)) { 713 pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)", 714 status); 715 /* We'll fall back on the worst case scenario: */ 716 nPayload = sizeof(tDot11fTDLSDisReq); 717 } else if (DOT11F_WARNED(status)) { 718 pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)", 719 status); 720 } 721 722 /* 723 * This frame is going out from PE as data frames with special ethertype 724 * 89-0d. 725 * 8 bytes of RFC 1042 header 726 */ 727 728 nBytes = nPayload + ((IS_QOS_ENABLED(pe_session)) 729 ? sizeof(tSirMacDataHdr3a) : 730 sizeof(tSirMacMgmtHdr)) 731 + sizeof(eth_890d_header) 732 + PAYLOAD_TYPE_TDLS_SIZE 733 + mlo_ie_len; 734 735 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 736 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) 737 Hence AP itself padding some bytes, which caused teardown packet is dropped at 738 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 739 */ 740 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) { 741 padLen = 742 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE); 743 744 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ 745 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) 746 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; 747 748 nBytes += padLen; 749 } 750 #endif 751 752 /* Ok-- try to allocate memory from MGMT PKT pool */ 753 754 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 755 (void **)&pPacket); 756 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 757 pe_err("Failed to allocate: %d bytes for a TDLS Discovery Request", 758 nBytes); 759 qdf_mem_free(tdls_dis_req); 760 return QDF_STATUS_E_NOMEM; 761 } 762 763 /* zero out the memory */ 764 qdf_mem_zero(pFrame, nBytes); 765 766 /* 767 * IE formation, memory allocation is completed, Now form TDLS discovery 768 * request frame 769 */ 770 771 /* fill out the buffer descriptor */ 772 773 header_offset = lim_prepare_tdls_frame_header(mac, pFrame, 774 &tdls_dis_req->LinkIdentifier, TDLS_LINK_AP, 775 TDLS_INITIATOR, 776 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK, 777 pe_session); 778 779 status = dot11f_pack_tdls_dis_req(mac, tdls_dis_req, pFrame 780 + header_offset, nPayload, &nPayload); 781 782 if (DOT11F_FAILED(status)) { 783 pe_err("Failed to pack a TDLS discovery req (0x%08x)", 784 status); 785 cds_packet_free((void *)pPacket); 786 qdf_mem_free(tdls_dis_req); 787 return QDF_STATUS_E_FAILURE; 788 } else if (DOT11F_WARNED(status)) { 789 pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)", 790 status); 791 } 792 793 if (mlo_ie_len) { 794 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 795 pFrame + header_offset + 796 nPayload); 797 if (QDF_IS_STATUS_ERROR(qdf_status)) { 798 pe_debug("assemble ml ie error"); 799 mlo_ie_len = 0; 800 } 801 802 nPayload += mlo_ie_len; 803 } 804 805 lim_cp_stats_cstats_log_disc_req_evt(tdls_dis_req, pe_session); 806 807 qdf_mem_free(tdls_dis_req); 808 809 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 810 if (padLen != 0) { 811 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ 812 uint8_t *padVendorSpecific = pFrame + header_offset + nPayload; 813 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ 814 padVendorSpecific[0] = 221; 815 padVendorSpecific[1] = padLen - 2; 816 padVendorSpecific[2] = 0x00; 817 padVendorSpecific[3] = 0xA0; 818 padVendorSpecific[4] = 0xC6; 819 820 pe_debug("Padding Vendor Specific Ie Len: %d", padLen); 821 822 /* padding zero if more than 5 bytes are required */ 823 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) 824 qdf_mem_zero(pFrame + header_offset + nPayload + 825 MIN_VENDOR_SPECIFIC_IE_SIZE, 826 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE); 827 } 828 #endif 829 830 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, 831 TDLS_DISCOVERY_REQUEST, 832 lim_trace_tdls_action_string(TDLS_DISCOVERY_REQUEST), 833 QDF_MAC_ADDR_REF(peer_mac.bytes)); 834 835 mac->lim.tdls_frm_session_id = pe_session->smeSessionId; 836 vdev_id = lim_get_assoc_link_vdev_id(pe_session); 837 838 lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, 839 pe_session, QDF_STATUS_SUCCESS, 840 QDF_STATUS_SUCCESS); 841 qdf_status = wma_tx_frameWithTxComplete(mac, pPacket, 842 (uint16_t) nBytes, 843 TXRX_FRM_802_11_DATA, 844 ANI_TXDIR_TODS, 845 TID_AC_VI, 846 lim_tx_complete, pFrame, 847 lim_mgmt_tdls_tx_complete, 848 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME | 849 HAL_USE_PEER_STA_REQUESTED_MASK, 850 vdev_id, false, 0, 851 RATEID_DEFAULT, 0, 0); 852 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 853 mac->lim.tdls_frm_session_id = NO_SESSION; 854 pe_err("could not send TDLS Discovery Request frame"); 855 return QDF_STATUS_E_FAILURE; 856 } 857 858 return QDF_STATUS_SUCCESS; 859 860 } 861 862 /* 863 * This static function is consistent with any kind of TDLS management 864 * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame, 865 * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame 866 */ 867 static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac, 868 uint32_t selfDot11Mode, 869 tDot11fIEHTCaps *htCap, 870 tDot11fIEVHTCaps *vhtCap, 871 struct pe_session *pe_session) 872 { 873 uint8_t nss; 874 qdf_size_t val_len; 875 struct mlme_vht_capabilities_info *vht_cap_info; 876 bool is_wideband; 877 878 is_wideband = 879 wlan_cfg80211_tdls_is_fw_wideband_capable(pe_session->vdev); 880 881 vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info; 882 883 if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq)) 884 nss = mac->vdev_type_nss_2g.tdls; 885 else 886 nss = mac->vdev_type_nss_5g.tdls; 887 888 nss = QDF_MIN(nss, mac->user_configured_nss); 889 if (IS_DOT11_MODE_HT(selfDot11Mode) && 890 !lim_is_he_6ghz_band(pe_session)) { 891 /* Include HT Capability IE */ 892 populate_dot11f_ht_caps(mac, pe_session, htCap); 893 val_len = SIZE_OF_SUPPORTED_MCS_SET; 894 wlan_mlme_get_cfg_str(&htCap->supportedMCSSet[0], 895 &mac->mlme_cfg->rates.supported_mcs_set, 896 &val_len); 897 if (WLAN_REG_IS_5GHZ_CH_FREQ(pe_session->curr_op_freq) && 898 !wlan_reg_is_dfs_for_freq(mac->pdev, 899 pe_session->curr_op_freq) && 900 is_wideband) 901 htCap->supportedChannelWidthSet = 1; 902 else 903 if (pe_session->ch_width == CH_WIDTH_20MHZ) 904 htCap->supportedChannelWidthSet = 0; 905 906 if (NSS_1x1_MODE == nss) 907 htCap->supportedMCSSet[1] = 0; 908 /* 909 * Advertise ht capability and max supported channel bandwidth 910 * when populating HT IE in TDLS Setup Request/Setup Response/ 911 * Setup Confirmation frames. 912 * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz 913 * off-channel direct link may be started if both TDLS peer STAs 914 * indicated 40 MHz support in the Supported Channel Width Set 915 * field of the HT Capabilities element (which is included in 916 * the TDLS Setup Request frame and the TDLS Setup Response 917 * frame). Switching to a 40 MHz off-channel direct link is 918 * achieved by including the following information in the TDLS 919 * Channel Switch Request 920 * 11.21.1 General: The channel width of the TDLS direct link on 921 * the base channel shall not exceed the channel width of the 922 * BSS to which the TDLS peer STAs are associated. 923 * Select supportedChannelWidthSet based on channel bonding 924 * settings for each band 925 */ 926 } else { 927 htCap->present = 0; 928 } 929 pe_debug("HT present: %hu, Chan Width: %hu", 930 htCap->present, htCap->supportedChannelWidthSet); 931 932 if ((WLAN_REG_IS_24GHZ_CH_FREQ(pe_session->curr_op_freq) && 933 vht_cap_info->b24ghz_band) || 934 WLAN_REG_IS_5GHZ_CH_FREQ(pe_session->curr_op_freq)) { 935 if (IS_DOT11_MODE_VHT(selfDot11Mode) && 936 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 937 /* 938 * Include VHT Capability IE 939 * 940 * VHT supportedChannelWidthSet should be set such as 941 * 1. Set to 0 if AP does not support either 942 * 160 or 80+80 MHz. With 0, it means 20/40/80 Mhz. 943 * Since for TDLS wideband we need to restrict the BW 944 * to 80 MHz for AP supporting BW less than 80 Mhz. 945 * So, set it to 0 for such cases so that TDLS STA 946 * can connect with 80 MHz width. 947 * 2. Set to 1 if AP supports 160 MHz, thus TDLS STA can 948 * connect with 160 MHz BW 949 * 3. Set to 2 if AP supports 160 MHz and 950 * 80+80 MHz. Not possible in case of 5 GHz 951 * 952 * The value 3 is reserved 953 */ 954 populate_dot11f_vht_caps(mac, pe_session, vhtCap); 955 vhtCap->suBeamformeeCap = 0; 956 vhtCap->suBeamFormerCap = 0; 957 vhtCap->muBeamformeeCap = 0; 958 vhtCap->muBeamformerCap = 0; 959 960 vhtCap->rxMCSMap = vht_cap_info->rx_mcs_map; 961 962 vhtCap->rxHighSupDataRate = 963 vht_cap_info->rx_supp_data_rate; 964 vhtCap->txMCSMap = vht_cap_info->tx_mcs_map; 965 vhtCap->txSupDataRate = vht_cap_info->tx_supp_data_rate; 966 if (nss == NSS_1x1_MODE) { 967 vhtCap->txMCSMap |= DISABLE_NSS2_MCS; 968 vhtCap->rxMCSMap |= DISABLE_NSS2_MCS; 969 vhtCap->txSupDataRate = 970 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 971 vhtCap->rxHighSupDataRate = 972 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 973 } 974 } else { 975 vhtCap->present = 0; 976 } 977 } else { 978 /* Vht Disable from ini in 2.4 GHz */ 979 vhtCap->present = 0; 980 } 981 pe_debug("VHT present: %hu, Chan Width: %u", 982 vhtCap->present, vhtCap->supportedChannelWidthSet); 983 } 984 985 #ifdef WLAN_FEATURE_11AX 986 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) 987 static void 988 lim_tdls_populate_dot11f_6hgz_he_caps(struct mac_context *mac, 989 struct tdls_add_sta_req *add_sta_req, 990 tDot11fIEhe_6ghz_band_cap *pDot11f) 991 { 992 union { 993 struct hecap_6ghz he_6ghz_cap; 994 struct he_6ghz_capability_info dot11f; 995 } peer_cfg; 996 997 if (!add_sta_req->he_6ghz_cap.a_mpdu_params && 998 !add_sta_req->he_6ghz_cap.info) { 999 tdls_debug("6Ghz HE capabilities not present"); 1000 return; 1001 } 1002 1003 qdf_mem_copy(&peer_cfg.he_6ghz_cap, 1004 &add_sta_req->he_6ghz_cap, 1005 sizeof(add_sta_req->he_6ghz_cap)); 1006 1007 pDot11f->present = 1; 1008 pDot11f->min_mpdu_start_spacing = 1009 peer_cfg.dot11f.min_mpdu_start_spacing; 1010 pDot11f->max_ampdu_len_exp = peer_cfg.dot11f.max_ampdu_len_exp; 1011 pDot11f->max_mpdu_len = peer_cfg.dot11f.max_mpdu_len; 1012 pDot11f->sm_pow_save = peer_cfg.dot11f.sm_pow_save; 1013 pDot11f->rd_responder = peer_cfg.dot11f.rd_responder; 1014 pDot11f->rx_ant_pattern_consistency = 1015 peer_cfg.dot11f.rx_ant_pattern_consistency; 1016 pDot11f->tx_ant_pattern_consistency = 1017 peer_cfg.dot11f.tx_ant_pattern_consistency; 1018 1019 lim_log_he_6g_cap(mac, pDot11f); 1020 } 1021 1022 static void lim_populate_tdls_setup_6g_cap(struct mac_context *mac, 1023 tDot11fIEhe_6ghz_band_cap *hecap_6g, 1024 struct pe_session *session) 1025 { 1026 if (hecap_6g) 1027 populate_dot11f_he_6ghz_cap(mac, session, hecap_6g); 1028 } 1029 1030 #else 1031 static void 1032 lim_tdls_populate_dot11f_6hgz_he_caps(struct mac_context *mac, 1033 struct tdls_add_sta_req *add_sta_req, 1034 tDot11fIEhe_6ghz_band_cap *pDot11f) 1035 { 1036 } 1037 1038 static void lim_populate_tdls_setup_6g_cap(struct mac_context *mac, 1039 tDot11fIEhe_6ghz_band_cap *hecap_6g, 1040 struct pe_session *session) 1041 { 1042 } 1043 #endif 1044 1045 static void lim_fill_session_he_width(struct pe_session *session, 1046 tDot11fIEhe_cap *heCap) 1047 { 1048 /* 1049 * For TDLS, the bw is filled using mlme_cfg so max supported bw 1050 * will be set, so here reset he bw as per session bw. 1051 */ 1052 if (session->ch_width == CH_WIDTH_20MHZ) { 1053 goto bw_20; 1054 } else if (session->ch_width == CH_WIDTH_40MHZ) { 1055 heCap->chan_width_0 = 1; 1056 goto bw_40; 1057 } else if (session->ch_width == CH_WIDTH_80MHZ) { 1058 heCap->chan_width_1 = 1; 1059 goto bw_80; 1060 } else if (session->ch_width == CH_WIDTH_160MHZ) { 1061 heCap->chan_width_2 = 1; 1062 goto bw_160; 1063 } else if (session->ch_width == CH_WIDTH_80P80MHZ) { 1064 heCap->chan_width_3 = 1; 1065 return; 1066 } 1067 1068 bw_20: 1069 heCap->chan_width_0 = 0; 1070 bw_40: 1071 heCap->chan_width_1 = 0; 1072 bw_80: 1073 heCap->chan_width_2 = 0; 1074 bw_160: 1075 heCap->chan_width_3 = 0; 1076 } 1077 1078 static void lim_tdls_set_he_chan_width(struct mac_context *mac, 1079 tDot11fIEhe_cap *heCap, 1080 struct pe_session *session, 1081 bool wideband_sta) 1082 { 1083 if (!wideband_sta || 1084 wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) { 1085 lim_fill_session_he_width(session, heCap); 1086 return; 1087 } 1088 1089 if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq)) { 1090 if (wlan_reg_is_dfs_for_freq(mac->pdev, 1091 session->curr_op_freq)) { 1092 lim_fill_session_he_width(session, heCap); 1093 return; 1094 } 1095 /* 1096 * Right now, no support for ch_width 160 Mhz or 80P80 Mhz in 5 Ghz 1097 * Also, restricting bw to 80 Mhz in case ap on 5 ghz is operating in 1098 * less than 80 Mhz bw. 1099 */ 1100 if (session->ch_width <= CH_WIDTH_80MHZ) 1101 heCap->chan_width_2 = 0; 1102 heCap->chan_width_3 = 0; 1103 heCap->chan_width_4 = 0; 1104 heCap->chan_width_5 = 0; 1105 heCap->chan_width_6 = 0; 1106 } 1107 } 1108 1109 static void lim_tdls_populate_ppe_caps(struct mac_context *mac, 1110 struct pe_session *session, 1111 tDot11fIEhe_cap *he_cap) 1112 { 1113 uint8_t *ppet; 1114 1115 /* 1116 * No Need to populate if ppet is not present 1117 */ 1118 if (!he_cap->ppet_present) 1119 return; 1120 1121 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) 1122 ppet = mac->mlme_cfg->he_caps.he_ppet_5g; 1123 else 1124 ppet = mac->mlme_cfg->he_caps.he_ppet_2g; 1125 1126 he_cap->ppet.ppe_threshold.num_ppe_th = lim_truncate_ppet(ppet, 1127 MLME_HE_PPET_LEN); 1128 1129 /* 1130 * If num_ppe_th calculated above is zero and ppet_present is set then 1131 * atleast one byte should be sent with zero data otherwise framework 1132 * will fail add_sta on the peer end. 1133 */ 1134 if (he_cap->ppet.ppe_threshold.num_ppe_th) 1135 qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th, ppet, 1136 MLME_HE_PPET_LEN); 1137 else 1138 he_cap->ppet.ppe_threshold.num_ppe_th = 1; 1139 } 1140 1141 static void populate_dot11f_set_tdls_he_cap(struct mac_context *mac, 1142 uint32_t selfDot11Mode, 1143 tDot11fIEhe_cap *heCap, 1144 tDot11fIEhe_6ghz_band_cap *hecap_6g, 1145 struct pe_session *session) 1146 { 1147 if (IS_DOT11_MODE_HE(selfDot11Mode)) { 1148 populate_dot11f_he_caps(mac, NULL, heCap); 1149 lim_tdls_set_he_chan_width(mac, heCap, session, 1150 wlan_cfg80211_tdls_is_fw_wideband_capable(session->vdev)); 1151 lim_tdls_populate_ppe_caps(mac, session, heCap); 1152 lim_log_he_cap(mac, heCap); 1153 lim_populate_tdls_setup_6g_cap(mac, hecap_6g, session); 1154 } else { 1155 pe_debug("Not populating he cap as SelfDot11Mode not HE %d", 1156 selfDot11Mode); 1157 } 1158 } 1159 1160 static void lim_tdls_fill_dis_rsp_he_cap(struct mac_context *mac, 1161 uint32_t selfDot11Mode, 1162 tDot11fTDLSDisRsp *tdls_dis_rsp, 1163 struct pe_session *pe_session) 1164 { 1165 populate_dot11f_set_tdls_he_cap(mac, selfDot11Mode, 1166 &tdls_dis_rsp->he_cap, 1167 NULL, 1168 pe_session); 1169 } 1170 1171 static void lim_tdls_fill_setup_req_he_cap(struct mac_context *mac, 1172 uint32_t selfDot11Mode, 1173 tDot11fTDLSSetupReq *tdls_setup_req, 1174 struct pe_session *pe_session) 1175 { 1176 populate_dot11f_set_tdls_he_cap(mac, selfDot11Mode, 1177 &tdls_setup_req->he_cap, 1178 &tdls_setup_req->he_6ghz_band_cap, 1179 pe_session); 1180 } 1181 1182 static void lim_tdls_fill_setup_rsp_he_cap(struct mac_context *mac, 1183 uint32_t selfDot11Mode, 1184 tDot11fTDLSSetupRsp *tdls_setup_rsp, 1185 struct pe_session *pe_session) 1186 { 1187 populate_dot11f_set_tdls_he_cap(mac, selfDot11Mode, 1188 &tdls_setup_rsp->he_cap, 1189 &tdls_setup_rsp->he_6ghz_band_cap, 1190 pe_session); 1191 } 1192 1193 static void lim_tdls_populate_he_operations(struct mac_context *mac, 1194 struct pe_session *pe_session, 1195 tDot11fIEhe_op *he_op) 1196 { 1197 struct wlan_mlme_he_caps *he_cap_info; 1198 uint16_t mcs_set = 0; 1199 1200 he_cap_info = &mac->mlme_cfg->he_caps; 1201 he_op->co_located_bss = 0; 1202 he_op->bss_color = pe_session->he_bss_color_change.new_color; 1203 if (!he_op->bss_color) 1204 he_op->bss_col_disabled = 1; 1205 1206 mcs_set = (uint16_t)he_cap_info->he_ops_basic_mcs_nss; 1207 if (pe_session->nss == NSS_1x1_MODE) 1208 mcs_set |= 0xFFFC; 1209 else 1210 mcs_set |= 0xFFF0; 1211 1212 *((uint16_t *)he_op->basic_mcs_nss) = mcs_set; 1213 populate_dot11f_he_operation(mac, 1214 pe_session, 1215 he_op); 1216 } 1217 1218 static void lim_tdls_fill_setup_cnf_he_op(struct mac_context *mac, 1219 uint32_t peer_capability, 1220 tDot11fTDLSSetupCnf *tdls_setup_cnf, 1221 struct pe_session *pe_session) 1222 { 1223 if (CHECK_BIT(peer_capability, TDLS_PEER_HE_CAP)) 1224 lim_tdls_populate_he_operations(mac, 1225 pe_session, 1226 &tdls_setup_cnf->he_op); 1227 } 1228 1229 static void lim_tdls_fill_he_wideband_offchannel_mcs(struct mac_context *mac_ctx, 1230 tpDphHashNode stads, 1231 uint8_t nss, 1232 struct pe_session *session) 1233 { 1234 struct supported_rates *rates = &stads->supportedRates; 1235 tDot11fIEhe_cap *peer_he_caps = &stads->he_config; 1236 struct tdls_vdev_priv_obj *tdls_obj = NULL; 1237 struct tdls_peer *tdls_peer_candidate = NULL; 1238 struct tdls_peer *curr_peer_candidate = NULL; 1239 qdf_list_t *head; 1240 qdf_list_node_t *p_node; 1241 int i = 0; 1242 uint16_t rx_he_mcs_map_160 = 0xfffa; 1243 uint16_t tx_he_mcs_map_160 = 0xfffa; 1244 QDF_STATUS status; 1245 1246 tdls_obj = wlan_vdev_get_tdls_vdev_obj(session->vdev); 1247 if (!tdls_obj) { 1248 pe_debug("failed to ger tdls priv object"); 1249 return; 1250 } 1251 1252 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 1253 head = &tdls_obj->peer_list[i]; 1254 status = qdf_list_peek_front(head, &p_node); 1255 while (QDF_IS_STATUS_SUCCESS(status)) { 1256 curr_peer_candidate = qdf_container_of(p_node, 1257 struct tdls_peer, 1258 node); 1259 if (!qdf_mem_cmp(&curr_peer_candidate->peer_mac.bytes, 1260 &stads->staAddr, QDF_MAC_ADDR_SIZE)) { 1261 tdls_peer_candidate = curr_peer_candidate; 1262 break; 1263 } 1264 status = qdf_list_peek_next(head, p_node, &p_node); 1265 } 1266 } 1267 1268 if (!tdls_peer_candidate) { 1269 pe_debug("failed to ger tdls peer object"); 1270 return; 1271 } 1272 1273 if (stads->ch_width == CH_WIDTH_160MHZ) { 1274 lim_populate_he_mcs_per_bw( 1275 mac_ctx, &rates->rx_he_mcs_map_160, 1276 &rates->tx_he_mcs_map_160, 1277 *((uint16_t *)peer_he_caps->rx_he_mcs_map_160), 1278 *((uint16_t *)peer_he_caps->tx_he_mcs_map_160), 1279 nss, 1280 *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 1281 rx_he_mcs_map_160), 1282 *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 1283 tx_he_mcs_map_160)); 1284 } else if (tdls_peer_candidate->pref_off_chan_width & 1285 (1 << BW_160_OFFSET_BIT)) { 1286 lim_populate_he_mcs_per_bw( 1287 mac_ctx, &rates->rx_he_mcs_map_160, 1288 &rates->tx_he_mcs_map_160, 1289 rx_he_mcs_map_160, 1290 tx_he_mcs_map_160, 1291 nss, 1292 *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 1293 rx_he_mcs_map_160), 1294 *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 1295 tx_he_mcs_map_160)); 1296 } else { 1297 rates->tx_he_mcs_map_160 = HE_MCS_ALL_DISABLED; 1298 rates->rx_he_mcs_map_160 = HE_MCS_ALL_DISABLED; 1299 } 1300 if (stads->ch_width == CH_WIDTH_80P80MHZ) { 1301 lim_populate_he_mcs_per_bw( 1302 mac_ctx, &rates->rx_he_mcs_map_80_80, 1303 &rates->tx_he_mcs_map_80_80, 1304 *((uint16_t *)peer_he_caps->rx_he_mcs_map_80_80), 1305 *((uint16_t *)peer_he_caps->tx_he_mcs_map_80_80), nss, 1306 *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 1307 rx_he_mcs_map_80_80), 1308 *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 1309 tx_he_mcs_map_80_80)); 1310 } else { 1311 rates->tx_he_mcs_map_80_80 = HE_MCS_ALL_DISABLED; 1312 rates->rx_he_mcs_map_80_80 = HE_MCS_ALL_DISABLED; 1313 } 1314 } 1315 1316 static void lim_tdls_populate_he_matching_rate_set(struct mac_context *mac_ctx, 1317 tpDphHashNode stads, 1318 uint8_t nss, 1319 struct pe_session *session) 1320 { 1321 lim_populate_he_mcs_set(mac_ctx, &stads->supportedRates, 1322 &stads->he_config, session, nss); 1323 1324 lim_tdls_fill_he_wideband_offchannel_mcs(mac_ctx, stads, nss, session); 1325 } 1326 1327 static QDF_STATUS 1328 lim_tdls_populate_dot11f_he_caps(struct mac_context *mac, 1329 struct tdls_add_sta_req *add_sta_req, 1330 tDot11fIEhe_cap *pDot11f) 1331 { 1332 uint32_t chan_width; 1333 union { 1334 struct hecap nCfgValue; 1335 struct he_capability_info he_cap; 1336 } uHECapInfo; 1337 1338 if (add_sta_req->he_cap_len < MIN_TDLS_HE_CAP_LEN) { 1339 pe_debug("He_capability invalid"); 1340 return QDF_STATUS_E_INVAL; 1341 } 1342 1343 qdf_mem_copy(&uHECapInfo.nCfgValue, &add_sta_req->he_cap, 1344 sizeof(uHECapInfo.nCfgValue)); 1345 1346 pDot11f->present = 1; 1347 pDot11f->htc_he = uHECapInfo.he_cap.htc_he; 1348 pDot11f->twt_request = uHECapInfo.he_cap.twt_request; 1349 pDot11f->twt_responder = uHECapInfo.he_cap.twt_responder; 1350 pDot11f->fragmentation = uHECapInfo.he_cap.fragmentation; 1351 pDot11f->max_num_frag_msdu_amsdu_exp = 1352 uHECapInfo.he_cap.max_num_frag_msdu_amsdu_exp; 1353 pDot11f->min_frag_size = uHECapInfo.he_cap.min_frag_size; 1354 pDot11f->trigger_frm_mac_pad = uHECapInfo.he_cap.trigger_frm_mac_pad; 1355 pDot11f->multi_tid_aggr_rx_supp = 1356 uHECapInfo.he_cap.multi_tid_aggr_rx_supp; 1357 pDot11f->he_link_adaptation = uHECapInfo.he_cap.he_link_adaptation; 1358 pDot11f->all_ack = uHECapInfo.he_cap.all_ack; 1359 pDot11f->trigd_rsp_sched = uHECapInfo.he_cap.trigd_rsp_sched; 1360 pDot11f->a_bsr = uHECapInfo.he_cap.a_bsr; 1361 pDot11f->broadcast_twt = uHECapInfo.he_cap.broadcast_twt; 1362 pDot11f->ba_32bit_bitmap = uHECapInfo.he_cap.ba_32bit_bitmap; 1363 pDot11f->mu_cascade = uHECapInfo.he_cap.mu_cascade; 1364 pDot11f->ack_enabled_multitid = uHECapInfo.he_cap.ack_enabled_multitid; 1365 pDot11f->omi_a_ctrl = uHECapInfo.he_cap.omi_a_ctrl; 1366 pDot11f->ofdma_ra = uHECapInfo.he_cap.ofdma_ra; 1367 pDot11f->max_ampdu_len_exp_ext = 1368 uHECapInfo.he_cap.max_ampdu_len_exp_ext; 1369 pDot11f->amsdu_frag = uHECapInfo.he_cap.amsdu_frag; 1370 pDot11f->flex_twt_sched = uHECapInfo.he_cap.flex_twt_sched; 1371 pDot11f->rx_ctrl_frame = uHECapInfo.he_cap.rx_ctrl_frame; 1372 1373 pDot11f->bsrp_ampdu_aggr = uHECapInfo.he_cap.bsrp_ampdu_aggr; 1374 pDot11f->qtp = uHECapInfo.he_cap.qtp; 1375 pDot11f->a_bqr = uHECapInfo.he_cap.a_bqr; 1376 pDot11f->spatial_reuse_param_rspder = 1377 uHECapInfo.he_cap.spatial_reuse_param_rspder; 1378 pDot11f->ops_supp = uHECapInfo.he_cap.ops_supp; 1379 pDot11f->ndp_feedback_supp = uHECapInfo.he_cap.ndp_feedback_supp; 1380 pDot11f->amsdu_in_ampdu = uHECapInfo.he_cap.amsdu_in_ampdu; 1381 1382 chan_width = uHECapInfo.he_cap.chan_width; 1383 pDot11f->chan_width_0 = HE_CH_WIDTH_GET_BIT(chan_width, 0); 1384 pDot11f->chan_width_1 = HE_CH_WIDTH_GET_BIT(chan_width, 1); 1385 pDot11f->chan_width_2 = HE_CH_WIDTH_GET_BIT(chan_width, 2); 1386 pDot11f->chan_width_3 = HE_CH_WIDTH_GET_BIT(chan_width, 3); 1387 pDot11f->chan_width_4 = HE_CH_WIDTH_GET_BIT(chan_width, 4); 1388 pDot11f->chan_width_5 = HE_CH_WIDTH_GET_BIT(chan_width, 5); 1389 pDot11f->chan_width_6 = HE_CH_WIDTH_GET_BIT(chan_width, 6); 1390 1391 pDot11f->rx_pream_puncturing = uHECapInfo.he_cap.rx_pream_puncturing; 1392 pDot11f->device_class = uHECapInfo.he_cap.device_class; 1393 pDot11f->ldpc_coding = uHECapInfo.he_cap.ldpc_coding; 1394 pDot11f->he_1x_ltf_800_gi_ppdu = 1395 uHECapInfo.he_cap.he_1x_ltf_800_gi_ppdu; 1396 pDot11f->midamble_tx_rx_max_nsts = 1397 uHECapInfo.he_cap.midamble_tx_rx_max_nsts; 1398 pDot11f->he_4x_ltf_3200_gi_ndp = 1399 uHECapInfo.he_cap.he_4x_ltf_3200_gi_ndp; 1400 pDot11f->tb_ppdu_tx_stbc_lt_80mhz = 1401 uHECapInfo.he_cap.tb_ppdu_tx_stbc_lt_80mhz; 1402 pDot11f->rx_stbc_lt_80mhz = uHECapInfo.he_cap.rx_stbc_lt_80mhz; 1403 pDot11f->tb_ppdu_tx_stbc_gt_80mhz = 1404 uHECapInfo.he_cap.tb_ppdu_tx_stbc_gt_80mhz; 1405 pDot11f->rx_stbc_gt_80mhz = uHECapInfo.he_cap.rx_stbc_gt_80mhz; 1406 pDot11f->doppler = uHECapInfo.he_cap.doppler; 1407 pDot11f->ul_mu = uHECapInfo.he_cap.ul_mu; 1408 pDot11f->dcm_enc_tx = uHECapInfo.he_cap.dcm_enc_tx; 1409 pDot11f->dcm_enc_rx = uHECapInfo.he_cap.dcm_enc_rx; 1410 pDot11f->ul_he_mu = uHECapInfo.he_cap.ul_he_mu; 1411 pDot11f->su_beamformer = uHECapInfo.he_cap.su_beamformer; 1412 1413 pDot11f->su_beamformee = uHECapInfo.he_cap.su_beamformee; 1414 pDot11f->mu_beamformer = uHECapInfo.he_cap.mu_beamformer; 1415 pDot11f->bfee_sts_lt_80 = uHECapInfo.he_cap.bfee_sts_lt_80; 1416 pDot11f->bfee_sts_gt_80 = uHECapInfo.he_cap.bfee_sts_gt_80; 1417 pDot11f->num_sounding_lt_80 = uHECapInfo.he_cap.num_sounding_lt_80; 1418 pDot11f->num_sounding_gt_80 = uHECapInfo.he_cap.num_sounding_gt_80; 1419 pDot11f->su_feedback_tone16 = uHECapInfo.he_cap.su_feedback_tone16; 1420 pDot11f->mu_feedback_tone16 = uHECapInfo.he_cap.mu_feedback_tone16; 1421 pDot11f->codebook_su = uHECapInfo.he_cap.codebook_su; 1422 pDot11f->codebook_mu = uHECapInfo.he_cap.codebook_mu; 1423 pDot11f->beamforming_feedback = uHECapInfo.he_cap.beamforming_feedback; 1424 pDot11f->he_er_su_ppdu = uHECapInfo.he_cap.he_er_su_ppdu; 1425 pDot11f->dl_mu_mimo_part_bw = uHECapInfo.he_cap.dl_mu_mimo_part_bw; 1426 pDot11f->ppet_present = uHECapInfo.he_cap.ppet_present; 1427 pDot11f->srp = uHECapInfo.he_cap.srp; 1428 pDot11f->power_boost = uHECapInfo.he_cap.power_boost; 1429 1430 pDot11f->he_ltf_800_gi_4x = uHECapInfo.he_cap.he_ltf_800_gi_4x; 1431 pDot11f->max_nc = uHECapInfo.he_cap.max_nc; 1432 pDot11f->er_he_ltf_800_gi_4x = uHECapInfo.he_cap.er_he_ltf_800_gi_4x; 1433 pDot11f->he_ppdu_20_in_40Mhz_2G = 1434 uHECapInfo.he_cap.he_ppdu_20_in_40Mhz_2G; 1435 pDot11f->he_ppdu_20_in_160_80p80Mhz = 1436 uHECapInfo.he_cap.he_ppdu_20_in_160_80p80Mhz; 1437 pDot11f->he_ppdu_80_in_160_80p80Mhz = 1438 uHECapInfo.he_cap.he_ppdu_80_in_160_80p80Mhz; 1439 pDot11f->er_1x_he_ltf_gi = 1440 uHECapInfo.he_cap.er_1x_he_ltf_gi; 1441 pDot11f->midamble_tx_rx_1x_he_ltf = 1442 uHECapInfo.he_cap.midamble_tx_rx_1x_he_ltf; 1443 pDot11f->reserved2 = uHECapInfo.he_cap.reserved2; 1444 1445 pDot11f->rx_he_mcs_map_lt_80 = uHECapInfo.he_cap.rx_he_mcs_map_lt_80; 1446 pDot11f->tx_he_mcs_map_lt_80 = uHECapInfo.he_cap.tx_he_mcs_map_lt_80; 1447 if (pDot11f->chan_width_2) { 1448 *((uint16_t *)pDot11f->rx_he_mcs_map_160) = 1449 uHECapInfo.he_cap.rx_he_mcs_map_160; 1450 *((uint16_t *)pDot11f->tx_he_mcs_map_160) = 1451 uHECapInfo.he_cap.tx_he_mcs_map_160; 1452 } 1453 if (pDot11f->chan_width_3) { 1454 *((uint16_t *)pDot11f->rx_he_mcs_map_80_80) = 1455 uHECapInfo.he_cap.rx_he_mcs_map_80_80; 1456 *((uint16_t *)pDot11f->tx_he_mcs_map_80_80) = 1457 uHECapInfo.he_cap.tx_he_mcs_map_80_80; 1458 } 1459 1460 return QDF_STATUS_SUCCESS; 1461 } 1462 1463 static void lim_tdls_check_and_force_he_ldpc_cap(struct pe_session *pe_session, 1464 tDphHashNode *sta) 1465 { 1466 if (pe_session && sta->he_config.present) 1467 lim_check_and_force_he_ldpc_cap(pe_session, &sta->he_config); 1468 } 1469 1470 static enum phy_ch_width lim_tdls_get_he_ch_width(struct pe_session *pe_session, 1471 tDot11fIEhe_cap *he_cap) 1472 { 1473 enum phy_ch_width ch_width = CH_WIDTH_20MHZ; 1474 1475 if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) && 1476 he_cap->chan_width_0) 1477 return CH_WIDTH_40MHZ; 1478 1479 if (he_cap->chan_width_3) 1480 ch_width = CH_WIDTH_80P80MHZ; 1481 else if (he_cap->chan_width_2) 1482 ch_width = CH_WIDTH_160MHZ; 1483 else if (he_cap->chan_width_1) 1484 ch_width = CH_WIDTH_80MHZ; 1485 1486 return ch_width; 1487 } 1488 1489 static void lim_tdls_update_node_he_caps(struct mac_context *mac, 1490 struct tdls_add_sta_req *add_sta_req, 1491 tDphHashNode *sta, 1492 struct pe_session *pe_session, 1493 bool wide_band_peer) 1494 { 1495 QDF_STATUS status = QDF_STATUS_SUCCESS; 1496 1497 pe_debug("Populating HE IEs"); 1498 status = lim_tdls_populate_dot11f_he_caps(mac, add_sta_req, 1499 &sta->he_config); 1500 1501 if (status != QDF_STATUS_SUCCESS) 1502 return; 1503 1504 if (!sta->he_config.present) 1505 return; 1506 1507 sta->mlmStaContext.he_capable = 1; 1508 lim_tdls_set_he_chan_width(mac, &sta->he_config, pe_session, 1509 wide_band_peer); 1510 lim_log_he_cap(mac, &sta->he_config); 1511 if (lim_is_he_6ghz_band(pe_session)) { 1512 lim_tdls_populate_dot11f_6hgz_he_caps(mac, add_sta_req, 1513 &sta->he_6g_band_cap); 1514 /* 1515 * In 6Ghz, vht and ht ie may not present, peer channel width 1516 * is populated while extracting HT and VHT cap itself. So, 1517 * incase of 6ghz fill the chan_width. 1518 */ 1519 lim_update_stads_he_6ghz_op(pe_session, sta); 1520 } 1521 sta->ch_width = lim_tdls_get_he_ch_width(pe_session, 1522 &sta->he_config); 1523 pe_debug("sta->ch_width %d", sta->ch_width); 1524 } 1525 1526 #else 1527 static void lim_tdls_fill_dis_rsp_he_cap(struct mac_context *mac, 1528 uint32_t selfDot11Mode, 1529 tDot11fTDLSDisRsp *tdls_dis_rsp, 1530 struct pe_session *pe_session) 1531 { 1532 } 1533 1534 static void lim_tdls_fill_setup_req_he_cap(struct mac_context *mac, 1535 uint32_t selfDot11Mode, 1536 tDot11fTDLSSetupReq *tdls_setup_req, 1537 struct pe_session *pe_session) 1538 { 1539 } 1540 1541 static void lim_tdls_fill_setup_rsp_he_cap(struct mac_context *mac, 1542 uint32_t selfDot11Mode, 1543 tDot11fTDLSSetupRsp *tdls_setup_rsp, 1544 struct pe_session *pe_session) 1545 { 1546 } 1547 1548 static void lim_tdls_fill_setup_cnf_he_op(struct mac_context *mac, 1549 uint32_t peer_capability, 1550 tDot11fTDLSSetupCnf *tdls_setup_cnf, 1551 struct pe_session *pe_session) 1552 { 1553 } 1554 1555 static void lim_tdls_populate_he_matching_rate_set(struct mac_context *mac_ctx, 1556 tpDphHashNode stads, 1557 uint8_t nss, 1558 struct pe_session *session) 1559 { 1560 } 1561 1562 static void lim_tdls_update_node_he_caps(struct mac_context *mac, 1563 struct tdls_add_sta_req *add_sta_req, 1564 tDphHashNode *sta, 1565 struct pe_session *pe_session, 1566 bool wide_band_peer) 1567 { 1568 } 1569 1570 static void lim_tdls_check_and_force_he_ldpc_cap(struct pe_session *pe_session, 1571 tDphHashNode *sta) 1572 { 1573 } 1574 1575 #endif 1576 1577 #ifdef WLAN_FEATURE_11BE 1578 static uint8_t * 1579 lim_ieee80211_pack_ehtcap_tdls(struct mac_context *mac, 1580 struct pe_session *pe_session, uint8_t *len) 1581 { 1582 tDot11fIEhe_cap he_cap; 1583 uint8_t *eht_cap_ie; 1584 bool is_band_2g; 1585 uint32_t self_mode; 1586 1587 if (!pe_session || !len) 1588 return NULL; 1589 1590 eht_cap_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); 1591 if (!eht_cap_ie) { 1592 pe_err("malloc failed for eht_cap_ie"); 1593 *len = 0; 1594 return NULL; 1595 } 1596 1597 is_band_2g = WLAN_REG_IS_24GHZ_CH_FREQ(pe_session->curr_op_freq); 1598 self_mode = mac->mlme_cfg->dot11_mode.dot11_mode; 1599 populate_dot11f_set_tdls_he_cap(mac, self_mode, &he_cap, 1600 NULL, pe_session); 1601 1602 lim_ieee80211_pack_ehtcap(eht_cap_ie, pe_session->eht_config, 1603 he_cap, is_band_2g); 1604 1605 *len = eht_cap_ie[1] + 2; 1606 return eht_cap_ie; 1607 } 1608 #else 1609 static uint8_t * 1610 lim_ieee80211_pack_ehtcap_tdls(struct mac_context *mac, 1611 struct pe_session *pe_session, uint8_t *len) 1612 { 1613 if (!mac || !pe_session || !len) 1614 return NULL; 1615 1616 *len = 0; 1617 return NULL; 1618 } 1619 #endif 1620 1621 /* 1622 * Send TDLS discovery response frame on direct link. 1623 */ 1624 static QDF_STATUS lim_send_tdls_dis_rsp_frame(struct mac_context *mac, 1625 struct qdf_mac_addr peer_mac, 1626 uint8_t dialog, 1627 struct pe_session *pe_session, 1628 uint8_t *addIe, 1629 uint16_t addIeLen) 1630 { 1631 tDot11fTDLSDisRsp *tdls_dis_rsp; 1632 uint16_t caps = 0; 1633 uint32_t status = 0; 1634 uint32_t nPayload = 0; 1635 uint32_t nBytes = 0; 1636 uint8_t *pFrame; 1637 void *pPacket; 1638 QDF_STATUS qdf_status; 1639 uint32_t selfDot11Mode; 1640 uint8_t selfaddr[QDF_MAC_ADDR_SIZE]; 1641 /* Placeholder to support different channel bonding mode of TDLS than AP. */ 1642 /* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */ 1643 /* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */ 1644 /* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */ 1645 /* uint32_t tdlsChannelBondingMode; */ 1646 uint8_t smeSessionId = 0; 1647 uint16_t mlo_ie_len = 0; 1648 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 1649 uint16_t action; 1650 1651 if (!pe_session) { 1652 pe_err("pe_session is NULL"); 1653 return QDF_STATUS_E_FAILURE; 1654 } 1655 1656 tdls_dis_rsp = qdf_mem_malloc(sizeof(*tdls_dis_rsp)); 1657 if (!tdls_dis_rsp) { 1658 pe_err("memory allocation failed for DisRsp"); 1659 return QDF_STATUS_E_NOMEM; 1660 } 1661 1662 smeSessionId = pe_session->smeSessionId; 1663 1664 /* 1665 * The scheme here is to fill out a 'tDot11fProbeRequest' structure 1666 * and then hand it off to 'dot11f_pack_probe_request' (for 1667 * serialization). 1668 */ 1669 1670 /* 1671 * setup Fixed fields, 1672 */ 1673 tdls_dis_rsp->Category.category = ACTION_CATEGORY_PUBLIC; 1674 tdls_dis_rsp->Action.action = TDLS_DISCOVERY_RESPONSE; 1675 tdls_dis_rsp->DialogToken.token = dialog; 1676 1677 populate_dot11f_link_iden(mac, pe_session, 1678 LINK_IDEN_ADDR_OFFSET(tdls_dis_rsp), 1679 peer_mac, TDLS_RESPONDER); 1680 1681 if (lim_get_capability_info(mac, &caps, pe_session) != 1682 QDF_STATUS_SUCCESS) { 1683 /* 1684 * Could not get Capabilities value 1685 * from CFG. Log error. 1686 */ 1687 pe_err("could not retrieve Capabilities value"); 1688 } 1689 swap_bit_field16(caps, (uint16_t *)&tdls_dis_rsp->Capabilities); 1690 1691 /* populate supported rate and ext supported rate IE */ 1692 if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac, 1693 &tdls_dis_rsp->SuppRates, 1694 &tdls_dis_rsp->ExtSuppRates, 1695 wlan_reg_freq_to_chan( 1696 mac->pdev, pe_session->curr_op_freq))) 1697 pe_err("could not populate supported data rates"); 1698 1699 /* populate extended capability IE */ 1700 populate_dot11f_tdls_ext_capability(mac, 1701 pe_session, 1702 &tdls_dis_rsp->ExtCap); 1703 1704 selfDot11Mode = mac->mlme_cfg->dot11_mode.dot11_mode; 1705 1706 /* Populate HT/VHT Capabilities */ 1707 populate_dot11f_tdls_ht_vht_cap(mac, selfDot11Mode, 1708 &tdls_dis_rsp->HTCaps, 1709 &tdls_dis_rsp->VHTCaps, 1710 pe_session); 1711 1712 lim_tdls_fill_dis_rsp_he_cap(mac, selfDot11Mode, tdls_dis_rsp, 1713 pe_session); 1714 1715 if (wlan_vdev_mlme_is_mlo_vdev(pe_session->vdev)) 1716 mlo_ie_len = lim_send_tdls_mgmt_frame_mlo(mac, pe_session); 1717 1718 if (lim_is_session_eht_capable(pe_session)) { 1719 eht_cap_ie = lim_ieee80211_pack_ehtcap_tdls(mac, pe_session, 1720 &eht_cap_ie_len); 1721 if (!eht_cap_ie) { 1722 pe_err("malloc failed for eht_cap_ie"); 1723 qdf_mem_free(tdls_dis_rsp); 1724 return QDF_STATUS_E_FAILURE; 1725 } 1726 } 1727 1728 /* Populate TDLS offchannel param only if offchannel is enabled 1729 * and TDLS Channel Switching is not prohibited by AP in ExtCap 1730 * IE in assoc/re-assoc response. 1731 */ 1732 if ((1 == mac->lim.gLimTDLSOffChannelEnabled) && 1733 (!mlme_get_tdls_chan_switch_prohibited(pe_session->vdev))) { 1734 populate_dot11f_tdls_offchannel_params(mac, pe_session, 1735 &tdls_dis_rsp->SuppChannels, 1736 &tdls_dis_rsp->SuppOperatingClasses); 1737 if (mac->mlme_cfg->gen.band_capability != BIT(REG_BAND_2G)) { 1738 tdls_dis_rsp->ht2040_bss_coexistence.present = 1; 1739 tdls_dis_rsp->ht2040_bss_coexistence.info_request = 1; 1740 } 1741 } else { 1742 pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d", 1743 mac->lim.gLimTDLSOffChannelEnabled, 1744 mlme_get_tdls_chan_switch_prohibited(pe_session->vdev)); 1745 } 1746 /* 1747 * now we pack it. First, how much space are we going to need? 1748 */ 1749 status = dot11f_get_packed_tdls_dis_rsp_size(mac, tdls_dis_rsp, 1750 &nPayload); 1751 if (DOT11F_FAILED(status)) { 1752 pe_err("Failed to calculate the packed size for a Discovery Response (0x%08x)", 1753 status); 1754 /* We'll fall back on the worst case scenario: */ 1755 nPayload = sizeof(tDot11fProbeRequest); 1756 } else if (DOT11F_WARNED(status)) { 1757 pe_warn("There were warnings while calculating the packed size for a Discovery Response (0x%08x)", 1758 status); 1759 } 1760 1761 /* 1762 * This frame is going out from PE as data frames with special ethertype 1763 * 89-0d. 1764 * 8 bytes of RFC 1042 header 1765 */ 1766 1767 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen + 1768 eht_cap_ie_len + mlo_ie_len; 1769 1770 /* Ok-- try to allocate memory from MGMT PKT pool */ 1771 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 1772 (void **)&pPacket); 1773 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1774 pe_err("Failed to allocate %d bytes for a TDLS Discovery Request", 1775 nBytes); 1776 qdf_mem_free(eht_cap_ie); 1777 qdf_mem_free(tdls_dis_rsp); 1778 return QDF_STATUS_E_NOMEM; 1779 } 1780 1781 /* zero out the memory */ 1782 qdf_mem_zero(pFrame, nBytes); 1783 1784 /* 1785 * IE formation, memory allocation is completed, Now form TDLS discovery 1786 * response frame 1787 */ 1788 1789 /* Make public Action Frame */ 1790 lim_tdls_copy_self_mac(pe_session, selfaddr); 1791 lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME, 1792 SIR_MAC_MGMT_ACTION, peer_mac.bytes, 1793 selfaddr); 1794 1795 { 1796 tpSirMacMgmtHdr pMacHdr; 1797 1798 pMacHdr = (tpSirMacMgmtHdr) pFrame; 1799 pMacHdr->fc.toDS = ANI_TXDIR_IBSS; 1800 pMacHdr->fc.powerMgmt = 0; 1801 sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId); 1802 } 1803 1804 status = dot11f_pack_tdls_dis_rsp(mac, tdls_dis_rsp, pFrame + 1805 sizeof(tSirMacMgmtHdr), 1806 nPayload, &nPayload); 1807 if (DOT11F_FAILED(status)) { 1808 pe_err("Failed to pack a TDLS discovery response (0x%08x)", 1809 status); 1810 cds_packet_free((void *)pPacket); 1811 qdf_mem_free(eht_cap_ie); 1812 qdf_mem_free(tdls_dis_rsp); 1813 return QDF_STATUS_E_FAILURE; 1814 } else if (DOT11F_WARNED(status)) { 1815 pe_warn("There were warnings while packing TDLS Discovery Response (0x%08x)", 1816 status); 1817 } 1818 1819 if (eht_cap_ie_len) { 1820 /* Copy the EHT IE to the end of the frame */ 1821 qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, 1822 eht_cap_ie, eht_cap_ie_len); 1823 qdf_mem_free(eht_cap_ie); 1824 1825 nPayload += eht_cap_ie_len; 1826 } 1827 1828 if (mlo_ie_len) { 1829 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 1830 pFrame + 1831 sizeof(tSirMacMgmtHdr) + 1832 nPayload); 1833 1834 if (QDF_IS_STATUS_ERROR(qdf_status)) { 1835 pe_debug("assemble ml ie error"); 1836 mlo_ie_len = 0; 1837 } 1838 1839 nPayload += mlo_ie_len; 1840 } 1841 1842 lim_cp_stats_cstats_log_disc_resp_evt(tdls_dis_rsp, pe_session); 1843 1844 qdf_mem_free(tdls_dis_rsp); 1845 1846 if (0 != addIeLen) { 1847 pe_debug("Copy Additional Ie Len: %d", addIeLen); 1848 qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe, 1849 addIeLen); 1850 } 1851 pe_debug("[TDLS] action: %d (%s) -DIRECT-> OTA peer="QDF_MAC_ADDR_FMT, 1852 TDLS_DISCOVERY_RESPONSE, 1853 lim_trace_tdls_action_string(TDLS_DISCOVERY_RESPONSE), 1854 QDF_MAC_ADDR_REF(peer_mac.bytes)); 1855 1856 mac->lim.tdls_frm_session_id = pe_session->smeSessionId; 1857 lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, 1858 pe_session, QDF_STATUS_SUCCESS, 1859 QDF_STATUS_SUCCESS); 1860 /* 1861 * Transmit Discovery response and watch if this is delivered to 1862 * peer STA. 1863 */ 1864 /* In CLD 2.0, pass Discovery Response as mgmt frame so that 1865 * wma does not do header conversion to 802.3 before calling tx/rx 1866 * routine and subsequenly target also sends frame as is OTA 1867 */ 1868 action = ACTION_CATEGORY_PUBLIC << 8 | TDLS_DISCOVERY_RESPONSE; 1869 qdf_status = wma_tx_frameWithTxComplete(mac, pPacket, (uint16_t) nBytes, 1870 TXRX_FRM_802_11_MGMT, 1871 ANI_TXDIR_IBSS, 1872 0, 1873 lim_tx_complete, pFrame, 1874 lim_mgmt_tdls_tx_complete, 1875 HAL_USE_SELF_STA_REQUESTED_MASK, 1876 smeSessionId, false, 0, 1877 RATEID_DEFAULT, 0, 1878 action); 1879 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 1880 mac->lim.tdls_frm_session_id = NO_SESSION; 1881 pe_err("could not send TDLS Discovery Response frame!"); 1882 return QDF_STATUS_E_FAILURE; 1883 } 1884 1885 return QDF_STATUS_SUCCESS; 1886 } 1887 1888 /* 1889 * This static function is currently used by lim_send_tdls_link_setup_req_frame and 1890 * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable. 1891 */ 1892 static void populate_dotf_tdls_vht_aid(struct mac_context *mac, uint32_t selfDot11Mode, 1893 struct qdf_mac_addr peerMac, 1894 tDot11fIEAID *Aid, 1895 struct pe_session *pe_session) 1896 { 1897 if (((wlan_reg_freq_to_chan(mac->pdev, pe_session->curr_op_freq) <= 1898 SIR_11B_CHANNEL_END) && 1899 mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) || 1900 (wlan_reg_freq_to_chan(mac->pdev, pe_session->curr_op_freq) >= 1901 SIR_11B_CHANNEL_END)) { 1902 if (IS_DOT11_MODE_VHT(selfDot11Mode) && 1903 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 1904 1905 uint16_t aid; 1906 tpDphHashNode sta; 1907 1908 sta = 1909 dph_lookup_hash_entry(mac, peerMac.bytes, &aid, 1910 &pe_session->dph. 1911 dphHashTable); 1912 if (sta) { 1913 Aid->present = 1; 1914 Aid->assocId = aid | LIM_AID_MASK; /* set bit 14 and 15 1's */ 1915 } else { 1916 Aid->present = 0; 1917 pe_err("sta is NULL for " 1918 QDF_MAC_ADDR_FMT, 1919 QDF_MAC_ADDR_REF(peerMac.bytes)); 1920 } 1921 } 1922 } else { 1923 Aid->present = 0; 1924 pe_warn("Vht not enable from ini for 2.4GHz"); 1925 } 1926 } 1927 1928 #ifdef CONFIG_HL_SUPPORT 1929 1930 /** 1931 * wma_tx_frame_with_tx_complete_send() - Send tx frames on Direct link or AP link 1932 * depend on reason code 1933 * @mac: pointer to MAC Sirius parameter structure 1934 * @pPacket: pointer to mgmt packet 1935 * @nBytes: number of bytes to send 1936 * @tid:tid value for AC 1937 * @pFrame: pointer to tdls frame 1938 * @smeSessionId:session id 1939 * @flag: tdls flag 1940 * 1941 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code. 1942 * 1943 * Return: None 1944 */ 1945 static inline QDF_STATUS 1946 wma_tx_frame_with_tx_complete_send(struct mac_context *mac, void *pPacket, 1947 uint16_t nBytes, 1948 uint8_t tid, 1949 uint8_t *pFrame, 1950 uint8_t smeSessionId, bool flag) 1951 { 1952 return wma_tx_frameWithTxComplete(mac, pPacket, 1953 (uint16_t) nBytes, 1954 TXRX_FRM_802_11_DATA, 1955 ANI_TXDIR_TODS, 1956 tid, 1957 lim_tx_complete, pFrame, 1958 lim_mgmt_tdls_tx_complete, 1959 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 1960 | HAL_USE_PEER_STA_REQUESTED_MASK, 1961 smeSessionId, flag, 0, 1962 RATEID_DEFAULT, 0, 0); 1963 } 1964 #else 1965 1966 static inline QDF_STATUS 1967 wma_tx_frame_with_tx_complete_send(struct mac_context *mac, void *pPacket, 1968 uint16_t nBytes, 1969 uint8_t tid, 1970 uint8_t *pFrame, 1971 uint8_t smeSessionId, bool flag) 1972 { 1973 return wma_tx_frameWithTxComplete(mac, pPacket, 1974 (uint16_t) nBytes, 1975 TXRX_FRM_802_11_DATA, 1976 ANI_TXDIR_TODS, 1977 tid, 1978 lim_tx_complete, pFrame, 1979 lim_mgmt_tdls_tx_complete, 1980 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 1981 | HAL_USE_PEER_STA_REQUESTED_MASK, 1982 smeSessionId, false, 0, 1983 RATEID_DEFAULT, 0, 0); 1984 } 1985 #endif 1986 1987 static 1988 bool lim_is_wide_band_set(uint8_t *ext_capability) 1989 { 1990 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)ext_capability; 1991 1992 if (!p_ext_cap) 1993 return false; 1994 1995 pe_debug("p_ext_cap->tdls_wider_bw %d", p_ext_cap->tdls_wider_bw); 1996 return p_ext_cap->tdls_wider_bw; 1997 } 1998 1999 /* 2000 * TDLS setup Request frame on AP link 2001 */ 2002 static 2003 QDF_STATUS lim_send_tdls_link_setup_req_frame(struct mac_context *mac, 2004 struct qdf_mac_addr peer_mac, 2005 uint8_t dialog, 2006 struct pe_session *pe_session, 2007 uint8_t *addIe, 2008 uint16_t addIeLen, 2009 enum wifi_traffic_ac ac) 2010 { 2011 tDot11fTDLSSetupReq *tdls_setup_req; 2012 uint16_t caps = 0; 2013 uint32_t status = 0; 2014 uint32_t payload = 0; 2015 uint32_t nbytes = 0; 2016 uint32_t header_offset = 0; 2017 uint8_t vdev_id; 2018 uint8_t *frame; 2019 void *packet; 2020 QDF_STATUS qdf_status; 2021 uint32_t selfDot11Mode; 2022 uint8_t smeSessionId = 0; 2023 uint8_t sp_length = 0; 2024 uint16_t mlo_ie_len = 0; 2025 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 2026 2027 /* Placeholder to support different channel bonding mode of TDLS than AP. */ 2028 /* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */ 2029 /* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */ 2030 /* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */ 2031 /* uint32_t tdlsChannelBondingMode; */ 2032 2033 if (!pe_session) { 2034 pe_err("pe_session is NULL"); 2035 return QDF_STATUS_E_FAILURE; 2036 } 2037 2038 tdls_setup_req = qdf_mem_malloc(sizeof(*tdls_setup_req)); 2039 if (!tdls_setup_req) { 2040 pe_err("memory allocation failed for SetupReq"); 2041 return QDF_STATUS_E_NOMEM; 2042 } 2043 2044 /* 2045 * The scheme here is to fill out a 'tDot11fProbeRequest' structure 2046 * and then hand it off to 'dot11f_pack_probe_request' (for 2047 * serialization). 2048 */ 2049 smeSessionId = pe_session->smeSessionId; 2050 2051 tdls_setup_req->Category.category = ACTION_CATEGORY_TDLS; 2052 tdls_setup_req->Action.action = TDLS_SETUP_REQUEST; 2053 tdls_setup_req->DialogToken.token = dialog; 2054 2055 populate_dot11f_link_iden(mac, pe_session, 2056 &tdls_setup_req->LinkIdentifier, peer_mac, 2057 TDLS_INITIATOR); 2058 2059 if (lim_get_capability_info(mac, &caps, pe_session) != 2060 QDF_STATUS_SUCCESS) { 2061 /* 2062 * Could not get Capabilities value 2063 * from CFG. Log error. 2064 */ 2065 pe_err("could not retrieve Capabilities value"); 2066 } 2067 swap_bit_field16(caps, (uint16_t *)&tdls_setup_req->Capabilities); 2068 2069 /* populate supported rate and ext supported rate IE */ 2070 if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac, 2071 &tdls_setup_req->SuppRates, 2072 &tdls_setup_req->ExtSuppRates, 2073 wlan_reg_freq_to_chan( 2074 mac->pdev, pe_session->curr_op_freq))) 2075 pe_err("could not populate supported data rates"); 2076 2077 /* Populate extended capability IE */ 2078 populate_dot11f_tdls_ext_capability(mac, 2079 pe_session, 2080 &tdls_setup_req->ExtCap); 2081 2082 if (1 == mac->lim.gLimTDLSWmmMode) { 2083 2084 pe_debug("populate WMM IE in Setup Request Frame"); 2085 sp_length = mac->mlme_cfg->wmm_params.max_sp_length; 2086 /* include WMM IE */ 2087 tdls_setup_req->WMMInfoStation.version = SIR_MAC_OUI_VERSION_1; 2088 tdls_setup_req->WMMInfoStation.acvo_uapsd = 2089 (mac->lim.gLimTDLSUapsdMask & 0x01); 2090 tdls_setup_req->WMMInfoStation.acvi_uapsd = 2091 ((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1); 2092 tdls_setup_req->WMMInfoStation.acbk_uapsd = 2093 ((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2); 2094 tdls_setup_req->WMMInfoStation.acbe_uapsd = 2095 ((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3); 2096 tdls_setup_req->WMMInfoStation.max_sp_length = sp_length; 2097 tdls_setup_req->WMMInfoStation.present = 1; 2098 } else { 2099 /* 2100 * TODO: we need to see if we have to support conditions where 2101 * we have EDCA parameter info element is needed a) if we need 2102 * different QOS parameters for off channel operations or QOS 2103 * is not supported on AP link and we wanted to QOS on direct 2104 * link. 2105 */ 2106 2107 /* Populate QOS info, needed for Peer U-APSD session */ 2108 2109 /* 2110 * TODO: Now hardcoded, since populate_dot11f_qos_caps_station() 2111 * depends on AP's capability, and TDLS doesn't want to depend 2112 * on AP's capability 2113 */ 2114 2115 pe_debug("populate QOS IE in Setup Request Frame"); 2116 tdls_setup_req->QOSCapsStation.present = 1; 2117 tdls_setup_req->QOSCapsStation.max_sp_length = 0; 2118 tdls_setup_req->QOSCapsStation.qack = 0; 2119 tdls_setup_req->QOSCapsStation.acbe_uapsd = 2120 ((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3); 2121 tdls_setup_req->QOSCapsStation.acbk_uapsd = 2122 ((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2); 2123 tdls_setup_req->QOSCapsStation.acvi_uapsd = 2124 ((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1); 2125 tdls_setup_req->QOSCapsStation.acvo_uapsd = 2126 (mac->lim.gLimTDLSUapsdMask & 0x01); 2127 } 2128 2129 /* 2130 * we will always try to init TDLS link with 11n capabilities 2131 * let TDLS setup response to come, and we will set our caps based 2132 * of peer caps 2133 */ 2134 2135 selfDot11Mode = mac->mlme_cfg->dot11_mode.dot11_mode; 2136 2137 /* Populate HT/VHT Capabilities */ 2138 2139 populate_dot11f_tdls_ht_vht_cap(mac, selfDot11Mode, 2140 &tdls_setup_req->HTCaps, 2141 &tdls_setup_req->VHTCaps, 2142 pe_session); 2143 lim_tdls_fill_setup_req_he_cap(mac, selfDot11Mode, tdls_setup_req, 2144 pe_session); 2145 /* Populate AID */ 2146 populate_dotf_tdls_vht_aid(mac, selfDot11Mode, peer_mac, 2147 &tdls_setup_req->AID, pe_session); 2148 2149 if (wlan_vdev_mlme_is_mlo_vdev(pe_session->vdev)) 2150 mlo_ie_len = lim_send_tdls_mgmt_frame_mlo(mac, pe_session); 2151 2152 if (lim_is_session_eht_capable(pe_session)) { 2153 eht_cap_ie = lim_ieee80211_pack_ehtcap_tdls(mac, pe_session, 2154 &eht_cap_ie_len); 2155 if (!eht_cap_ie) { 2156 pe_err("malloc failed for eht_cap_ie"); 2157 qdf_mem_free(tdls_setup_req); 2158 return QDF_STATUS_E_FAILURE; 2159 } 2160 } 2161 2162 /* Populate TDLS offchannel param only if offchannel is enabled 2163 * and TDLS Channel Switching is not prohibited by AP in ExtCap 2164 * IE in assoc/re-assoc response. 2165 */ 2166 if ((1 == mac->lim.gLimTDLSOffChannelEnabled) && 2167 (!mlme_get_tdls_chan_switch_prohibited(pe_session->vdev))) { 2168 populate_dot11f_tdls_offchannel_params(mac, pe_session, 2169 &tdls_setup_req->SuppChannels, 2170 &tdls_setup_req->SuppOperatingClasses); 2171 if (mac->mlme_cfg->gen.band_capability != BIT(REG_BAND_2G)) { 2172 tdls_setup_req->ht2040_bss_coexistence.present = 1; 2173 tdls_setup_req->ht2040_bss_coexistence.info_request = 1; 2174 } 2175 } else { 2176 pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d", 2177 mac->lim.gLimTDLSOffChannelEnabled, 2178 mlme_get_tdls_chan_switch_prohibited(pe_session->vdev)); 2179 } 2180 /* 2181 * now we pack it. First, how much space are we going to need? 2182 */ 2183 status = dot11f_get_packed_tdls_setup_req_size(mac, tdls_setup_req, 2184 &payload); 2185 if (DOT11F_FAILED(status)) { 2186 pe_err("Failed to calculate the packed size for a Setup Request (0x%08x)", 2187 status); 2188 /* We'll fall back on the worst case scenario: */ 2189 payload = sizeof(tDot11fProbeRequest); 2190 } else if (DOT11F_WARNED(status)) { 2191 pe_warn("There were warnings while calculating the packed size for a Setup Request (0x%08x)", 2192 status); 2193 } 2194 2195 /* 2196 * This frame is going out from PE as data frames with special ethertype 2197 * 89-0d. 2198 * 8 bytes of RFC 1042 header 2199 */ 2200 2201 nbytes = payload + ((IS_QOS_ENABLED(pe_session)) 2202 ? sizeof(tSirMacDataHdr3a) : 2203 sizeof(tSirMacMgmtHdr)) 2204 + sizeof(eth_890d_header) 2205 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen + eht_cap_ie_len 2206 + mlo_ie_len; 2207 2208 /* Ok-- try to allocate memory from MGMT PKT pool */ 2209 qdf_status = cds_packet_alloc((uint16_t)nbytes, (void **)&frame, 2210 (void **)&packet); 2211 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2212 pe_err("Failed to allocate %d bytes for a TDLS Setup Request", 2213 nbytes); 2214 qdf_mem_free(eht_cap_ie); 2215 qdf_mem_free(tdls_setup_req); 2216 return QDF_STATUS_E_NOMEM; 2217 } 2218 2219 /* zero out the memory */ 2220 qdf_mem_zero(frame, nbytes); 2221 2222 /* 2223 * IE formation, memory allocation is completed, Now form TDLS discovery 2224 * request frame 2225 */ 2226 2227 /* fill out the buffer descriptor */ 2228 2229 header_offset = lim_prepare_tdls_frame_header(mac, frame, 2230 &tdls_setup_req->LinkIdentifier, 2231 TDLS_LINK_AP, TDLS_INITIATOR, 2232 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK, 2233 pe_session); 2234 2235 pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x", 2236 tdls_setup_req->VHTCaps.supportedChannelWidthSet, 2237 tdls_setup_req->VHTCaps.rxMCSMap, 2238 tdls_setup_req->VHTCaps.txMCSMap, 2239 tdls_setup_req->VHTCaps.txSupDataRate); 2240 2241 status = dot11f_pack_tdls_setup_req(mac, tdls_setup_req, 2242 frame + header_offset, 2243 payload, &payload); 2244 2245 if (DOT11F_FAILED(status)) { 2246 pe_err("Failed to pack a TDLS Setup request (0x%08x)", 2247 status); 2248 cds_packet_free((void *)packet); 2249 qdf_mem_free(eht_cap_ie); 2250 qdf_mem_free(tdls_setup_req); 2251 return QDF_STATUS_E_FAILURE; 2252 } else if (DOT11F_WARNED(status)) { 2253 pe_warn("There were warnings while packing TDLS Setup Request (0x%08x)", 2254 status); 2255 } 2256 2257 lim_cp_stats_cstats_log_setup_req_evt(tdls_setup_req, pe_session); 2258 2259 qdf_mem_free(tdls_setup_req); 2260 2261 /* Copy the additional IE. */ 2262 /* TODO : addIe is added at the end of the frame. This means it doesn't */ 2263 /* follow the order. This should be ok, but we should consider changing this */ 2264 /* if there is any IOT issue. */ 2265 if (addIeLen != 0) { 2266 pe_debug("Copy Additional Ie Len = %d", addIeLen); 2267 qdf_mem_copy(frame + header_offset + payload, addIe, 2268 addIeLen); 2269 payload += addIeLen; 2270 } 2271 2272 if (eht_cap_ie_len) { 2273 /* Copy the EHT IE to the end of the frame */ 2274 qdf_mem_copy(frame + header_offset + payload, 2275 eht_cap_ie, eht_cap_ie_len); 2276 qdf_mem_free(eht_cap_ie); 2277 2278 payload += eht_cap_ie_len; 2279 } 2280 2281 if (mlo_ie_len) { 2282 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 2283 frame + header_offset + 2284 payload); 2285 2286 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2287 pe_debug("assemble ml ie error"); 2288 mlo_ie_len = 0; 2289 } 2290 2291 payload += mlo_ie_len; 2292 } 2293 2294 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, 2295 TDLS_SETUP_REQUEST, 2296 lim_trace_tdls_action_string(TDLS_SETUP_REQUEST), 2297 QDF_MAC_ADDR_REF(peer_mac.bytes)); 2298 2299 mac->lim.tdls_frm_session_id = pe_session->smeSessionId; 2300 2301 vdev_id = lim_get_assoc_link_vdev_id(pe_session); 2302 2303 lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) frame, 2304 pe_session, QDF_STATUS_SUCCESS, 2305 QDF_STATUS_SUCCESS); 2306 2307 qdf_status = wma_tx_frame_with_tx_complete_send(mac, packet, 2308 (uint16_t)nbytes, 2309 TID_AC_VI, 2310 frame, 2311 vdev_id, true); 2312 2313 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2314 mac->lim.tdls_frm_session_id = NO_SESSION; 2315 pe_err("could not send TDLS Setup Request frame!"); 2316 return QDF_STATUS_E_FAILURE; 2317 } 2318 2319 return QDF_STATUS_SUCCESS; 2320 2321 } 2322 2323 /* 2324 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code. 2325 */ 2326 static 2327 QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac, 2328 struct qdf_mac_addr peer_mac, 2329 uint16_t reason, 2330 uint8_t responder, 2331 struct pe_session *pe_session, 2332 uint8_t *addIe, uint16_t addIeLen, 2333 enum wifi_traffic_ac ac) 2334 { 2335 tDot11fTDLSTeardown *teardown; 2336 uint32_t status = 0; 2337 uint32_t payload = 0; 2338 uint32_t nbytes = 0; 2339 uint32_t header_offset = 0; 2340 uint8_t *frame; 2341 void *packet; 2342 uint8_t vdev_id; 2343 QDF_STATUS qdf_status; 2344 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 2345 uint32_t padlen = 0; 2346 #endif 2347 uint8_t smeSessionId = 0; 2348 tpDphHashNode sta_ds; 2349 uint16_t aid = 0; 2350 uint8_t qos_mode = 0; 2351 uint8_t tdls_link_type; 2352 2353 if (!pe_session) { 2354 pe_err("pe_session is NULL"); 2355 return QDF_STATUS_E_FAILURE; 2356 } 2357 2358 teardown = qdf_mem_malloc(sizeof(*teardown)); 2359 if (!teardown) { 2360 pe_err("memory allocation failed for teardown"); 2361 return QDF_STATUS_E_NOMEM; 2362 } 2363 2364 smeSessionId = pe_session->smeSessionId; 2365 /* 2366 * The scheme here is to fill out a 'tDot11fProbeRequest' structure 2367 * and then hand it off to 'dot11f_pack_probe_request' (for 2368 * serialization). 2369 */ 2370 teardown->Category.category = ACTION_CATEGORY_TDLS; 2371 teardown->Action.action = TDLS_TEARDOWN; 2372 teardown->Reason.code = reason; 2373 2374 populate_dot11f_link_iden(mac, pe_session, 2375 LINK_IDEN_ADDR_OFFSET(teardown), 2376 peer_mac, 2377 (responder == 2378 true) ? TDLS_RESPONDER : TDLS_INITIATOR); 2379 2380 /* 2381 * now we pack it. First, how much space are we going to need? 2382 */ 2383 status = dot11f_get_packed_tdls_teardown_size(mac, teardown, &payload); 2384 if (DOT11F_FAILED(status)) { 2385 pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)", 2386 status); 2387 /* We'll fall back on the worst case scenario: */ 2388 payload = sizeof(tDot11fProbeRequest); 2389 } else if (DOT11F_WARNED(status)) { 2390 pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)", 2391 status); 2392 } 2393 2394 /* 2395 * This frame is going out from PE as data frames with special ethertype 2396 * 89-0d. 2397 * 8 bytes of RFC 1042 header 2398 */ 2399 sta_ds = dph_lookup_hash_entry(mac, pe_session->bssId, &aid, 2400 &pe_session->dph.dphHashTable); 2401 if (sta_ds) 2402 qos_mode = sta_ds->qosMode; 2403 2404 if (reason == REASON_TDLS_PEER_UNREACHABLE) 2405 tdls_link_type = TDLS_LINK_AP; 2406 else 2407 tdls_link_type = TDLS_LINK_DIRECT; 2408 2409 nbytes = payload + sizeof(eth_890d_header) + PAYLOAD_TYPE_TDLS_SIZE; 2410 nbytes += addIeLen; 2411 2412 if ((IS_QOS_ENABLED(pe_session) && tdls_link_type == TDLS_LINK_AP) || 2413 (tdls_link_type == TDLS_LINK_DIRECT && qos_mode)) 2414 nbytes += sizeof(tSirMacDataHdr3a); 2415 else 2416 nbytes += sizeof(tSirMacMgmtHdr); 2417 2418 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 2419 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) 2420 Hence AP itself padding some bytes, which caused teardown packet is dropped at 2421 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 2422 */ 2423 if (payload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) { 2424 padlen = 2425 MIN_IEEE_8023_SIZE - (payload + PAYLOAD_TYPE_TDLS_SIZE); 2426 2427 /* 2428 * if padlen is less than minimum vendorSpecific (5), 2429 * pad up to 5 2430 */ 2431 if (padlen < MIN_VENDOR_SPECIFIC_IE_SIZE) 2432 padlen = MIN_VENDOR_SPECIFIC_IE_SIZE; 2433 2434 nbytes += padlen; 2435 } 2436 #endif 2437 2438 /* Ok-- try to allocate memory from MGMT PKT pool */ 2439 qdf_status = cds_packet_alloc((uint16_t)nbytes, (void **)&frame, 2440 (void **)&packet); 2441 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2442 pe_err("Failed to allocate %d bytes for a TDLS Teardown Frame.", 2443 nbytes); 2444 qdf_mem_free(teardown); 2445 return QDF_STATUS_E_NOMEM; 2446 } 2447 2448 /* zero out the memory */ 2449 qdf_mem_zero(frame, nbytes); 2450 2451 /* 2452 * IE formation, memory allocation is completed, Now form TDLS discovery 2453 * request frame 2454 */ 2455 2456 /* fill out the buffer descriptor */ 2457 pe_debug("Reason of TDLS Teardown: %d", reason); 2458 header_offset = lim_prepare_tdls_frame_header(mac, frame, 2459 LINK_IDEN_ADDR_OFFSET(teardown), 2460 (reason == REASON_TDLS_PEER_UNREACHABLE) ? 2461 TDLS_LINK_AP : TDLS_LINK_DIRECT, 2462 (responder == true) ? TDLS_RESPONDER : TDLS_INITIATOR, 2463 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK, 2464 pe_session); 2465 2466 status = dot11f_pack_tdls_teardown(mac, teardown, frame 2467 + header_offset, payload, &payload); 2468 2469 if (DOT11F_FAILED(status)) { 2470 pe_err("Failed to pack a TDLS Teardown frame (0x%08x)", 2471 status); 2472 cds_packet_free((void *)packet); 2473 qdf_mem_free(teardown); 2474 return QDF_STATUS_E_FAILURE; 2475 } else if (DOT11F_WARNED(status)) { 2476 pe_warn("There were warnings while packing TDLS Teardown frame (0x%08x)", 2477 status); 2478 } 2479 2480 lim_cp_stats_cstats_log_tear_down_evt(teardown, pe_session); 2481 2482 qdf_mem_free(teardown); 2483 2484 if (addIeLen != 0) { 2485 pe_debug("Copy Additional Ie Len = %d", addIeLen); 2486 qdf_mem_copy(frame + header_offset + payload, addIe, 2487 addIeLen); 2488 } 2489 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 2490 if (padlen != 0) { 2491 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ 2492 uint8_t *padVendorSpecific = 2493 frame + header_offset + payload + addIeLen; 2494 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ 2495 padVendorSpecific[0] = 221; 2496 padVendorSpecific[1] = padlen - 2; 2497 padVendorSpecific[2] = 0x00; 2498 padVendorSpecific[3] = 0xA0; 2499 padVendorSpecific[4] = 0xC6; 2500 2501 pe_debug("Padding Vendor Specific Ie Len = %d", padlen); 2502 2503 /* padding zero if more than 5 bytes are required */ 2504 if (padlen > MIN_VENDOR_SPECIFIC_IE_SIZE) 2505 qdf_mem_zero(frame + header_offset + payload + 2506 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, 2507 padlen - MIN_VENDOR_SPECIFIC_IE_SIZE); 2508 } 2509 #endif 2510 pe_debug("[TDLS] vdev:%d action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_FMT, 2511 pe_session->vdev_id, TDLS_TEARDOWN, 2512 lim_trace_tdls_action_string(TDLS_TEARDOWN), 2513 ((reason == REASON_TDLS_PEER_UNREACHABLE) ? "AP" : "DIRECT"), 2514 QDF_MAC_ADDR_REF(peer_mac.bytes)); 2515 2516 mac->lim.tdls_frm_session_id = pe_session->smeSessionId; 2517 2518 vdev_id = lim_get_assoc_link_vdev_id(pe_session); 2519 2520 lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr)frame, 2521 pe_session, QDF_STATUS_SUCCESS, 2522 QDF_STATUS_SUCCESS); 2523 2524 qdf_status = wma_tx_frame_with_tx_complete_send(mac, packet, 2525 (uint16_t)nbytes, 2526 TID_AC_VI, frame, vdev_id, 2527 (reason == REASON_TDLS_PEER_UNREACHABLE) 2528 ? true : false); 2529 2530 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2531 mac->lim.tdls_frm_session_id = NO_SESSION; 2532 pe_err("could not send TDLS Teardown frame"); 2533 return QDF_STATUS_E_FAILURE; 2534 2535 } 2536 2537 return QDF_STATUS_SUCCESS; 2538 } 2539 2540 /* 2541 * Send Setup RSP frame on AP link. 2542 */ 2543 static QDF_STATUS 2544 lim_send_tdls_setup_rsp_frame(struct mac_context *mac, 2545 struct qdf_mac_addr peer_mac, 2546 uint8_t dialog, 2547 struct pe_session *pe_session, 2548 etdlsLinkSetupStatus setupStatus, 2549 uint8_t *addIe, uint16_t addIeLen, 2550 enum wifi_traffic_ac ac) 2551 { 2552 tDot11fTDLSSetupRsp *setup_rsp; 2553 uint32_t status = 0; 2554 uint16_t caps = 0; 2555 uint32_t nPayload = 0; 2556 uint32_t header_offset = 0; 2557 uint32_t nBytes = 0; 2558 uint8_t *pFrame; 2559 void *pPacket; 2560 QDF_STATUS qdf_status; 2561 uint32_t selfDot11Mode; 2562 uint8_t max_sp_length = 0; 2563 uint8_t vdev_id; 2564 /* Placeholder to support different channel bonding mode of TDLS than AP. */ 2565 /* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */ 2566 /* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */ 2567 /* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */ 2568 /* uint32_t tdlsChannelBondingMode; */ 2569 uint8_t smeSessionId = 0; 2570 uint16_t mlo_ie_len = 0; 2571 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 2572 2573 if (!pe_session) { 2574 pe_err("pe_session is NULL"); 2575 return QDF_STATUS_E_FAILURE; 2576 } 2577 2578 setup_rsp = qdf_mem_malloc(sizeof(*setup_rsp)); 2579 if (!setup_rsp) { 2580 pe_err("memory allocation failed for SetupRsp"); 2581 return QDF_STATUS_E_NOMEM; 2582 } 2583 2584 smeSessionId = pe_session->smeSessionId; 2585 2586 /* 2587 * The scheme here is to fill out a 'tDot11fProbeRequest' structure 2588 * and then hand it off to 'dot11f_pack_probe_request' (for 2589 * serialization). 2590 */ 2591 2592 /* 2593 * setup Fixed fields, 2594 */ 2595 setup_rsp->Category.category = ACTION_CATEGORY_TDLS; 2596 setup_rsp->Action.action = TDLS_SETUP_RESPONSE; 2597 setup_rsp->DialogToken.token = dialog; 2598 2599 populate_dot11f_link_iden(mac, pe_session, 2600 LINK_IDEN_ADDR_OFFSET(setup_rsp), peer_mac, 2601 TDLS_RESPONDER); 2602 2603 if (lim_get_capability_info(mac, &caps, pe_session) != 2604 QDF_STATUS_SUCCESS) { 2605 /* 2606 * Could not get Capabilities value 2607 * from CFG. Log error. 2608 */ 2609 pe_err("could not retrieve Capabilities value"); 2610 } 2611 swap_bit_field16(caps, (uint16_t *)&setup_rsp->Capabilities); 2612 2613 if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac, 2614 &setup_rsp->SuppRates, 2615 &setup_rsp->ExtSuppRates, 2616 wlan_reg_freq_to_chan( 2617 mac->pdev, pe_session->curr_op_freq))) 2618 pe_err("could not populate supported data rates"); 2619 2620 /* Populate extended capability IE */ 2621 populate_dot11f_tdls_ext_capability(mac, 2622 pe_session, 2623 &setup_rsp->ExtCap); 2624 2625 if (1 == mac->lim.gLimTDLSWmmMode) { 2626 2627 pe_debug("populate WMM IE in Setup Response frame"); 2628 max_sp_length = mac->mlme_cfg->wmm_params.max_sp_length; 2629 /* include WMM IE */ 2630 setup_rsp->WMMInfoStation.version = SIR_MAC_OUI_VERSION_1; 2631 setup_rsp->WMMInfoStation.acvo_uapsd = 2632 (mac->lim.gLimTDLSUapsdMask & 0x01); 2633 setup_rsp->WMMInfoStation.acvi_uapsd = 2634 ((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1); 2635 setup_rsp->WMMInfoStation.acbk_uapsd = 2636 ((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2); 2637 setup_rsp->WMMInfoStation.acbe_uapsd = 2638 ((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3); 2639 setup_rsp->WMMInfoStation.max_sp_length = max_sp_length; 2640 setup_rsp->WMMInfoStation.present = 1; 2641 } else { 2642 /* 2643 * TODO: we need to see if we have to support conditions where 2644 * we have EDCA parameter info element is needed a) if we need 2645 * different QOS parameters for off channel operations or QOS 2646 * is not supported on AP link and we wanted to QOS on direct 2647 * link. 2648 */ 2649 /* Populate QOS info, needed for Peer U-APSD session */ 2650 /* 2651 * TODO: Now hardcoded, because 2652 * populate_dot11f_qos_caps_station() depends on AP's 2653 * capability, and TDLS doesn't want to depend on AP's 2654 * capability 2655 */ 2656 pe_debug("populate QOS IE in Setup Response frame"); 2657 setup_rsp->QOSCapsStation.present = 1; 2658 setup_rsp->QOSCapsStation.max_sp_length = 0; 2659 setup_rsp->QOSCapsStation.qack = 0; 2660 setup_rsp->QOSCapsStation.acbe_uapsd = 2661 ((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3); 2662 setup_rsp->QOSCapsStation.acbk_uapsd = 2663 ((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2); 2664 setup_rsp->QOSCapsStation.acvi_uapsd = 2665 ((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1); 2666 setup_rsp->QOSCapsStation.acvo_uapsd = 2667 (mac->lim.gLimTDLSUapsdMask & 0x01); 2668 } 2669 2670 selfDot11Mode = mac->mlme_cfg->dot11_mode.dot11_mode; 2671 2672 /* Populate HT/VHT Capabilities */ 2673 populate_dot11f_tdls_ht_vht_cap(mac, selfDot11Mode, &setup_rsp->HTCaps, 2674 &setup_rsp->VHTCaps, pe_session); 2675 2676 lim_tdls_fill_setup_rsp_he_cap(mac, selfDot11Mode, setup_rsp, 2677 pe_session); 2678 /* Populate AID */ 2679 populate_dotf_tdls_vht_aid(mac, selfDot11Mode, peer_mac, 2680 &setup_rsp->AID, pe_session); 2681 2682 if (wlan_vdev_mlme_is_mlo_vdev(pe_session->vdev)) 2683 mlo_ie_len = lim_send_tdls_mgmt_frame_mlo(mac, pe_session); 2684 2685 if (lim_is_session_eht_capable(pe_session)) { 2686 eht_cap_ie = lim_ieee80211_pack_ehtcap_tdls(mac, pe_session, 2687 &eht_cap_ie_len); 2688 if (!eht_cap_ie) { 2689 pe_err("malloc failed for eht_cap_ie"); 2690 qdf_mem_free(setup_rsp); 2691 return QDF_STATUS_E_FAILURE; 2692 } 2693 } 2694 2695 /* Populate TDLS offchannel param only if offchannel is enabled 2696 * and TDLS Channel Switching is not prohibited by AP in ExtCap 2697 * IE in assoc/re-assoc response. 2698 */ 2699 if ((1 == mac->lim.gLimTDLSOffChannelEnabled) && 2700 (!mlme_get_tdls_chan_switch_prohibited(pe_session->vdev))) { 2701 populate_dot11f_tdls_offchannel_params(mac, pe_session, 2702 &setup_rsp->SuppChannels, 2703 &setup_rsp-> 2704 SuppOperatingClasses); 2705 if (mac->mlme_cfg->gen.band_capability != BIT(REG_BAND_2G)) { 2706 setup_rsp->ht2040_bss_coexistence.present = 1; 2707 setup_rsp->ht2040_bss_coexistence.info_request = 1; 2708 } 2709 } else { 2710 pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d", 2711 mac->lim.gLimTDLSOffChannelEnabled, 2712 mlme_get_tdls_chan_switch_prohibited(pe_session->vdev)); 2713 } 2714 setup_rsp->Status.status = setupStatus; 2715 /* 2716 * now we pack it. First, how much space are we going to need? 2717 */ 2718 status = dot11f_get_packed_tdls_setup_rsp_size(mac, setup_rsp, 2719 &nPayload); 2720 if (DOT11F_FAILED(status)) { 2721 pe_err("Failed to calculate the packed size for a Setup Response (0x%08x)", 2722 status); 2723 /* We'll fall back on the worst case scenario: */ 2724 nPayload = sizeof(tDot11fProbeRequest); 2725 } else if (DOT11F_WARNED(status)) { 2726 pe_warn("There were warnings while calculating the packed size for Setup Response (0x%08x)", 2727 status); 2728 } 2729 2730 /* 2731 * This frame is going out from PE as data frames with special ethertype 2732 * 89-0d. 2733 * 8 bytes of RFC 1042 header 2734 */ 2735 2736 nBytes = nPayload + ((IS_QOS_ENABLED(pe_session)) 2737 ? sizeof(tSirMacDataHdr3a) : 2738 sizeof(tSirMacMgmtHdr)) 2739 + sizeof(eth_890d_header) 2740 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen + eht_cap_ie_len 2741 + mlo_ie_len; 2742 2743 /* Ok-- try to allocate memory from MGMT PKT pool */ 2744 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 2745 (void **)&pPacket); 2746 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2747 pe_err("Failed to allocate %d bytes for a TDLS Setup Response", 2748 nBytes); 2749 qdf_mem_free(eht_cap_ie); 2750 qdf_mem_free(setup_rsp); 2751 return QDF_STATUS_E_NOMEM; 2752 } 2753 2754 /* zero out the memory */ 2755 qdf_mem_zero(pFrame, nBytes); 2756 2757 /* 2758 * IE formation, memory allocation is completed, Now form TDLS discovery 2759 * request frame 2760 */ 2761 2762 /* fill out the buffer descriptor */ 2763 2764 header_offset = lim_prepare_tdls_frame_header(mac, pFrame, 2765 LINK_IDEN_ADDR_OFFSET(setup_rsp), TDLS_LINK_AP, 2766 TDLS_RESPONDER, 2767 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK, 2768 pe_session); 2769 2770 pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x", 2771 setup_rsp->VHTCaps.supportedChannelWidthSet, 2772 setup_rsp->VHTCaps.rxMCSMap, setup_rsp->VHTCaps.txMCSMap, 2773 setup_rsp->VHTCaps.txSupDataRate); 2774 status = dot11f_pack_tdls_setup_rsp(mac, setup_rsp, 2775 pFrame + header_offset, 2776 nPayload, &nPayload); 2777 2778 if (DOT11F_FAILED(status)) { 2779 pe_err("Failed to pack a TDLS Setup Response (0x%08x)", 2780 status); 2781 cds_packet_free((void *)pPacket); 2782 qdf_mem_free(eht_cap_ie); 2783 qdf_mem_free(setup_rsp); 2784 return QDF_STATUS_E_FAILURE; 2785 } else if (DOT11F_WARNED(status)) { 2786 pe_warn("There were warnings while packing TDLS Setup Response (0x%08x)", 2787 status); 2788 } 2789 2790 lim_cp_stats_cstats_log_setup_resp_evt(setup_rsp, pe_session); 2791 2792 qdf_mem_free(setup_rsp); 2793 2794 /* Copy the additional IE. */ 2795 /* TODO : addIe is added at the end of the frame. This means it doesn't */ 2796 /* follow the order. This should be ok, but we should consider changing this */ 2797 /* if there is any IOT issue. */ 2798 if (addIeLen != 0) { 2799 qdf_mem_copy(pFrame + header_offset + nPayload, addIe, 2800 addIeLen); 2801 nPayload += addIeLen; 2802 } 2803 2804 if (eht_cap_ie_len) { 2805 /* Copy the EHT IE to the end of the frame */ 2806 qdf_mem_copy(pFrame + header_offset + nPayload, 2807 eht_cap_ie, eht_cap_ie_len); 2808 qdf_mem_free(eht_cap_ie); 2809 2810 nPayload += eht_cap_ie_len; 2811 } 2812 2813 if (mlo_ie_len) { 2814 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 2815 pFrame + header_offset + 2816 nPayload); 2817 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2818 pe_debug("assemble ml ie error"); 2819 mlo_ie_len = 0; 2820 } 2821 2822 nPayload += mlo_ie_len; 2823 } 2824 2825 pe_debug("[TDLS] vdev:%d action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, 2826 pe_session->vdev_id, TDLS_SETUP_RESPONSE, 2827 lim_trace_tdls_action_string(TDLS_SETUP_RESPONSE), 2828 QDF_MAC_ADDR_REF(peer_mac.bytes)); 2829 2830 mac->lim.tdls_frm_session_id = pe_session->smeSessionId; 2831 vdev_id = lim_get_assoc_link_vdev_id(pe_session); 2832 lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, 2833 pe_session, QDF_STATUS_SUCCESS, 2834 QDF_STATUS_SUCCESS); 2835 2836 qdf_status = wma_tx_frame_with_tx_complete_send(mac, pPacket, 2837 (uint16_t) nBytes, 2838 TID_AC_VI, 2839 pFrame, 2840 vdev_id, true); 2841 2842 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2843 mac->lim.tdls_frm_session_id = NO_SESSION; 2844 pe_err("could not send TDLS Dis Request frame!"); 2845 return QDF_STATUS_E_FAILURE; 2846 } 2847 2848 return QDF_STATUS_SUCCESS; 2849 } 2850 2851 /* 2852 * Send TDLS setup CNF frame on AP link 2853 */ 2854 static 2855 QDF_STATUS lim_send_tdls_link_setup_cnf_frame(struct mac_context *mac, 2856 struct qdf_mac_addr peer_mac, 2857 uint8_t dialog, 2858 uint32_t peerCapability, 2859 struct pe_session *pe_session, 2860 uint8_t *addIe, 2861 uint16_t addIeLen, 2862 enum wifi_traffic_ac ac) 2863 { 2864 tDot11fTDLSSetupCnf *setup_cnf; 2865 uint32_t status = 0; 2866 uint32_t nPayload = 0; 2867 uint32_t nBytes = 0; 2868 uint32_t header_offset = 0; 2869 uint8_t *pFrame; 2870 void *pPacket; 2871 QDF_STATUS qdf_status; 2872 uint8_t vdev_id; 2873 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 2874 uint32_t padLen = 0; 2875 #endif 2876 uint8_t smeSessionId = 0; 2877 uint16_t mlo_ie_len = 0; 2878 uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0; 2879 2880 if (!pe_session) { 2881 pe_err("pe_session is NULL"); 2882 return QDF_STATUS_E_FAILURE; 2883 } 2884 2885 setup_cnf = qdf_mem_malloc(sizeof(*setup_cnf)); 2886 if (!setup_cnf) { 2887 pe_err("memory allocation failed for SetupCnf"); 2888 return QDF_STATUS_E_NOMEM; 2889 } 2890 2891 /* 2892 * The scheme here is to fill out a 'tDot11fProbeRequest' structure 2893 * and then hand it off to 'dot11f_pack_probe_request' (for 2894 * serialization). We start by zero-initializing the structure: 2895 */ 2896 smeSessionId = pe_session->smeSessionId; 2897 2898 /* 2899 * setup Fixed fields, 2900 */ 2901 setup_cnf->Category.category = ACTION_CATEGORY_TDLS; 2902 setup_cnf->Action.action = TDLS_SETUP_CONFIRM; 2903 setup_cnf->DialogToken.token = dialog; 2904 2905 populate_dot11f_link_iden(mac, pe_session, 2906 LINK_IDEN_ADDR_OFFSET(setup_cnf), peer_mac, 2907 TDLS_INITIATOR); 2908 /* 2909 * TODO: we need to see if we have to support conditions where we have 2910 * EDCA parameter info element is needed a) if we need different QOS 2911 * parameters for off channel operations or QOS is not supported on 2912 * AP link and we wanted to QOS on direct link. 2913 */ 2914 2915 /* Check self and peer WMM capable */ 2916 if ((1 == mac->lim.gLimTDLSWmmMode) && 2917 (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) { 2918 pe_debug("populate WMM praram in Setup Confirm"); 2919 populate_dot11f_wmm_params(mac, &setup_cnf->WMMParams, 2920 pe_session); 2921 } 2922 2923 /* Check peer is VHT capable */ 2924 if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) { 2925 populate_dot11f_vht_operation(mac, 2926 pe_session, 2927 &setup_cnf->VHTOperation); 2928 populate_dot11f_ht_info(mac, &setup_cnf->HTInfo, pe_session); 2929 } else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) { /* Check peer is HT capable */ 2930 populate_dot11f_ht_info(mac, &setup_cnf->HTInfo, pe_session); 2931 } 2932 2933 lim_tdls_fill_setup_cnf_he_op(mac, peerCapability, setup_cnf, 2934 pe_session); 2935 2936 if (wlan_vdev_mlme_is_mlo_vdev(pe_session->vdev)) 2937 mlo_ie_len = lim_send_tdls_mgmt_frame_mlo(mac, pe_session); 2938 2939 if (lim_is_session_eht_capable(pe_session)) { 2940 eht_cap_ie = lim_ieee80211_pack_ehtcap_tdls(mac, pe_session, 2941 &eht_cap_ie_len); 2942 if (!eht_cap_ie) { 2943 pe_err("malloc failed for eht_cap_ie"); 2944 qdf_mem_free(setup_cnf); 2945 return QDF_STATUS_E_FAILURE; 2946 } 2947 } 2948 /* 2949 * now we pack it. First, how much space are we going to need? 2950 */ 2951 status = dot11f_get_packed_tdls_setup_cnf_size(mac, setup_cnf, 2952 &nPayload); 2953 if (DOT11F_FAILED(status)) { 2954 pe_err("Failed to calculate the packed size for a Setup Confirm (0x%08x)", 2955 status); 2956 /* We'll fall back on the worst case scenario: */ 2957 nPayload = sizeof(tDot11fProbeRequest); 2958 } else if (DOT11F_WARNED(status)) { 2959 pe_warn("There were warnings while calculating the packed size for Setup Confirm (0x%08x)", 2960 status); 2961 } 2962 2963 /* 2964 * This frame is going out from PE as data frames with special ethertype 2965 * 89-0d. 2966 * 8 bytes of RFC 1042 header 2967 */ 2968 2969 nBytes = nPayload + ((IS_QOS_ENABLED(pe_session)) 2970 ? sizeof(tSirMacDataHdr3a) : 2971 sizeof(tSirMacMgmtHdr)) 2972 + sizeof(eth_890d_header) 2973 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen + eht_cap_ie_len 2974 + mlo_ie_len; 2975 2976 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 2977 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) 2978 Hence AP itself padding some bytes, which caused teardown packet is dropped at 2979 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 2980 */ 2981 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) { 2982 padLen = 2983 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE); 2984 2985 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ 2986 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) 2987 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; 2988 2989 nBytes += padLen; 2990 } 2991 #endif 2992 2993 /* Ok-- try to allocate memory from MGMT PKT pool */ 2994 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, 2995 (void **)&pPacket); 2996 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 2997 pe_err("Failed to allocate %d bytes for a TDLS Setup Confirm", 2998 nBytes); 2999 qdf_mem_free(eht_cap_ie); 3000 qdf_mem_free(setup_cnf); 3001 return QDF_STATUS_E_NOMEM; 3002 } 3003 3004 /* zero out the memory */ 3005 qdf_mem_zero(pFrame, nBytes); 3006 3007 /* 3008 * IE formation, memory allocation is completed, Now form TDLS discovery 3009 * request frame 3010 */ 3011 3012 /* fill out the buffer descriptor */ 3013 3014 header_offset = lim_prepare_tdls_frame_header(mac, pFrame, 3015 LINK_IDEN_ADDR_OFFSET(setup_cnf), 3016 TDLS_LINK_AP, 3017 TDLS_INITIATOR, 3018 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK, 3019 pe_session); 3020 3021 status = dot11f_pack_tdls_setup_cnf(mac, setup_cnf, pFrame 3022 + header_offset, nPayload, &nPayload); 3023 3024 if (DOT11F_FAILED(status)) { 3025 pe_err("Failed to pack a TDLS discovery req (0x%08x)", status); 3026 cds_packet_free((void *)pPacket); 3027 qdf_mem_free(eht_cap_ie); 3028 qdf_mem_free(setup_cnf); 3029 return QDF_STATUS_E_FAILURE; 3030 } else if (DOT11F_WARNED(status)) { 3031 pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)", 3032 status); 3033 } 3034 3035 lim_cp_stats_cstats_log_setup_confirm_evt(setup_cnf, pe_session); 3036 3037 qdf_mem_free(setup_cnf); 3038 3039 /* Copy the additional IE. */ 3040 /* TODO : addIe is added at the end of the frame. This means it doesn't */ 3041 /* follow the order. This should be ok, but we should consider changing this */ 3042 /* if there is any IOT issue. */ 3043 if (addIeLen != 0) { 3044 qdf_mem_copy(pFrame + header_offset + nPayload, addIe, 3045 addIeLen); 3046 nPayload += addIeLen; 3047 } 3048 3049 if (eht_cap_ie_len) { 3050 /* Copy the EHT IE to the end of the frame */ 3051 qdf_mem_copy(pFrame + header_offset + nPayload, 3052 eht_cap_ie, eht_cap_ie_len); 3053 qdf_mem_free(eht_cap_ie); 3054 3055 nPayload += eht_cap_ie_len; 3056 } 3057 3058 if (mlo_ie_len) { 3059 qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len, 3060 pFrame + header_offset + 3061 nPayload); 3062 3063 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3064 pe_debug("assemble ml ie error"); 3065 mlo_ie_len = 0; 3066 } 3067 3068 nPayload += mlo_ie_len; 3069 } 3070 #ifndef NO_PAD_TDLS_MIN_8023_SIZE 3071 if (padLen != 0) { 3072 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ 3073 uint8_t *padVendorSpecific = 3074 pFrame + header_offset + nPayload + addIeLen; 3075 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ 3076 padVendorSpecific[0] = 221; 3077 padVendorSpecific[1] = padLen - 2; 3078 padVendorSpecific[2] = 0x00; 3079 padVendorSpecific[3] = 0xA0; 3080 padVendorSpecific[4] = 0xC6; 3081 3082 pe_debug("Padding Vendor Specific Ie Len: %d", padLen); 3083 3084 /* padding zero if more than 5 bytes are required */ 3085 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) 3086 qdf_mem_zero(pFrame + header_offset + nPayload + 3087 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, 3088 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE); 3089 } 3090 #endif 3091 3092 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, 3093 TDLS_SETUP_CONFIRM, 3094 lim_trace_tdls_action_string(TDLS_SETUP_CONFIRM), 3095 QDF_MAC_ADDR_REF(peer_mac.bytes)); 3096 3097 mac->lim.tdls_frm_session_id = pe_session->smeSessionId; 3098 vdev_id = lim_get_assoc_link_vdev_id(pe_session); 3099 lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, 3100 pe_session, QDF_STATUS_SUCCESS, 3101 QDF_STATUS_SUCCESS); 3102 3103 qdf_status = wma_tx_frame_with_tx_complete_send(mac, pPacket, 3104 (uint16_t) nBytes, 3105 TID_AC_VI, 3106 pFrame, 3107 vdev_id, true); 3108 3109 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3110 mac->lim.tdls_frm_session_id = NO_SESSION; 3111 pe_err("could not send TDLS Setup Confirm frame"); 3112 return QDF_STATUS_E_FAILURE; 3113 3114 } 3115 3116 return QDF_STATUS_SUCCESS; 3117 } 3118 3119 /* This Function is similar to populate_dot11f_ht_caps, except that 3120 * the HT Capabilities are considered from the AddStaReq rather from 3121 * the cfg.dat as in populate_dot11f_ht_caps 3122 */ 3123 static QDF_STATUS 3124 lim_tdls_populate_dot11f_ht_caps(struct mac_context *mac, 3125 struct pe_session *pe_session, 3126 struct tdls_add_sta_req *add_sta_req, 3127 tDot11fIEHTCaps *pDot11f) 3128 { 3129 uint32_t nCfgValue; 3130 uint8_t nCfgValue8; 3131 tSirMacHTParametersInfo *pHTParametersInfo; 3132 union { 3133 uint16_t nCfgValue16; 3134 struct mlme_ht_capabilities_info ht_cap_info; 3135 tSirMacExtendedHTCapabilityInfo extHtCapInfo; 3136 } uHTCapabilityInfo; 3137 3138 tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo; 3139 tSirMacASCapabilityInfo *pASCapabilityInfo; 3140 3141 nCfgValue = add_sta_req->ht_cap.hc_cap; 3142 3143 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; 3144 3145 pDot11f->advCodingCap = uHTCapabilityInfo.ht_cap_info.adv_coding_cap; 3146 pDot11f->mimoPowerSave = uHTCapabilityInfo.ht_cap_info.mimo_power_save; 3147 pDot11f->greenField = uHTCapabilityInfo.ht_cap_info.green_field; 3148 pDot11f->shortGI20MHz = uHTCapabilityInfo.ht_cap_info.short_gi_20_mhz; 3149 pDot11f->shortGI40MHz = uHTCapabilityInfo.ht_cap_info.short_gi_40_mhz; 3150 pDot11f->txSTBC = uHTCapabilityInfo.ht_cap_info.tx_stbc; 3151 pDot11f->rxSTBC = uHTCapabilityInfo.ht_cap_info.rx_stbc; 3152 pDot11f->delayedBA = uHTCapabilityInfo.ht_cap_info.delayed_ba; 3153 pDot11f->maximalAMSDUsize = 3154 uHTCapabilityInfo.ht_cap_info.maximal_amsdu_size; 3155 pDot11f->dsssCckMode40MHz = 3156 uHTCapabilityInfo.ht_cap_info.dsss_cck_mode_40_mhz; 3157 pDot11f->psmp = uHTCapabilityInfo.ht_cap_info.psmp; 3158 pDot11f->stbcControlFrame = 3159 uHTCapabilityInfo.ht_cap_info.stbc_control_frame; 3160 pDot11f->lsigTXOPProtection = 3161 uHTCapabilityInfo.ht_cap_info.l_sig_tx_op_protection; 3162 3163 /* 3164 * All sessionized entries will need the check below 3165 * Only in case of NO session 3166 */ 3167 if (!pe_session) { 3168 pDot11f->supportedChannelWidthSet = 3169 uHTCapabilityInfo.ht_cap_info. 3170 supported_channel_width_set; 3171 } else { 3172 pDot11f->supportedChannelWidthSet = 3173 pe_session->htSupportedChannelWidthSet; 3174 } 3175 3176 /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is 3177 eHT_CHANNEL_WIDTH_20MHZ */ 3178 if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) { 3179 pDot11f->shortGI40MHz = 0; 3180 } 3181 3182 pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d", 3183 pDot11f->supportedChannelWidthSet, 3184 pDot11f->mimoPowerSave, 3185 pDot11f->greenField, 3186 pDot11f->shortGI20MHz, 3187 pDot11f->shortGI40MHz, 3188 pDot11f->dsssCckMode40MHz); 3189 3190 nCfgValue = add_sta_req->ht_cap.ampdu_param; 3191 3192 nCfgValue8 = (uint8_t) nCfgValue; 3193 pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8; 3194 3195 pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor; 3196 pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; 3197 pDot11f->reserved1 = pHTParametersInfo->reserved; 3198 3199 pe_debug("AMPDU Param: %x", nCfgValue); 3200 qdf_mem_copy(pDot11f->supportedMCSSet, add_sta_req->ht_cap.mcsset, 3201 SIZE_OF_SUPPORTED_MCS_SET); 3202 3203 nCfgValue = add_sta_req->ht_cap.extcap; 3204 3205 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; 3206 3207 pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco; 3208 pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime; 3209 pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback; 3210 3211 nCfgValue = add_sta_req->ht_cap.txbf_cap; 3212 3213 pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue; 3214 pDot11f->txBF = pTxBFCapabilityInfo->txBF; 3215 pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding; 3216 pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding; 3217 pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF; 3218 pDot11f->txZLF = pTxBFCapabilityInfo->txZLF; 3219 pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF; 3220 pDot11f->calibration = pTxBFCapabilityInfo->calibration; 3221 pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF; 3222 pDot11f->explicitUncompressedSteeringMatrix = 3223 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix; 3224 pDot11f->explicitBFCSIFeedback = 3225 pTxBFCapabilityInfo->explicitBFCSIFeedback; 3226 pDot11f->explicitUncompressedSteeringMatrixFeedback = 3227 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback; 3228 pDot11f->explicitCompressedSteeringMatrixFeedback = 3229 pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback; 3230 pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae; 3231 pDot11f->uncompressedSteeringMatrixBFAntennae = 3232 pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae; 3233 pDot11f->compressedSteeringMatrixBFAntennae = 3234 pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae; 3235 3236 nCfgValue = add_sta_req->ht_cap.antenna; 3237 3238 nCfgValue8 = (uint8_t) nCfgValue; 3239 3240 pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8; 3241 pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection; 3242 pDot11f->explicitCSIFeedbackTx = 3243 pASCapabilityInfo->explicitCSIFeedbackTx; 3244 pDot11f->antennaIndicesFeedbackTx = 3245 pASCapabilityInfo->antennaIndicesFeedbackTx; 3246 pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback; 3247 pDot11f->antennaIndicesFeedback = 3248 pASCapabilityInfo->antennaIndicesFeedback; 3249 pDot11f->rxAS = pASCapabilityInfo->rxAS; 3250 pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs; 3251 3252 pDot11f->present = add_sta_req->htcap_present; 3253 3254 return QDF_STATUS_SUCCESS; 3255 3256 } 3257 3258 static QDF_STATUS 3259 lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, 3260 struct tdls_add_sta_req *add_sta_req, 3261 tDot11fIEVHTCaps *pDot11f) 3262 { 3263 uint32_t nCfgValue = 0; 3264 union { 3265 uint32_t nCfgValue32; 3266 tSirMacVHTCapabilityInfo vhtCapInfo; 3267 } uVHTCapabilityInfo; 3268 union { 3269 uint16_t nCfgValue16; 3270 tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo; 3271 tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo; 3272 } uVHTSupDataRateInfo; 3273 3274 pDot11f->present = add_sta_req->vhtcap_present; 3275 3276 nCfgValue = add_sta_req->vht_cap.vht_capinfo; 3277 uVHTCapabilityInfo.nCfgValue32 = nCfgValue; 3278 3279 pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen; 3280 pDot11f->supportedChannelWidthSet = 3281 uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet; 3282 pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap; 3283 pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz; 3284 pDot11f->shortGI160and80plus80MHz = 3285 uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz; 3286 pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC; 3287 pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC; 3288 pDot11f->suBeamFormerCap = 0; 3289 pDot11f->suBeamformeeCap = 0; 3290 pDot11f->csnofBeamformerAntSup = 3291 uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup; 3292 pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim; 3293 pDot11f->muBeamformerCap = 0; 3294 pDot11f->muBeamformeeCap = 0; 3295 pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS; 3296 pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap; 3297 pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp; 3298 pDot11f->vhtLinkAdaptCap = 3299 uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap; 3300 pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern; 3301 pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern; 3302 pDot11f->extended_nss_bw_supp = 3303 uVHTCapabilityInfo.vhtCapInfo.extended_nss_bw_supp; 3304 3305 pDot11f->rxMCSMap = add_sta_req->vht_cap.supp_mcs.rx_mcs_map; 3306 3307 nCfgValue = add_sta_req->vht_cap.supp_mcs.rx_highest; 3308 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; 3309 pDot11f->rxHighSupDataRate = 3310 uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate; 3311 pDot11f->max_nsts_total = 3312 uVHTSupDataRateInfo.vhtRxsupDataRateInfo.max_nsts_total; 3313 3314 pDot11f->txMCSMap = add_sta_req->vht_cap.supp_mcs.tx_mcs_map; 3315 3316 nCfgValue = add_sta_req->vht_cap.supp_mcs.tx_highest; 3317 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; 3318 pDot11f->txSupDataRate = 3319 uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate; 3320 3321 pDot11f->vht_extended_nss_bw_cap = 3322 uVHTSupDataRateInfo.vhtTxSupDataRateInfo.vht_extended_nss_bw_cap; 3323 3324 lim_log_vht_cap(mac, pDot11f); 3325 3326 return QDF_STATUS_SUCCESS; 3327 } 3328 3329 #ifdef WLAN_FEATURE_11BE 3330 static void 3331 lim_tdls_populate_eht_mcs(struct mac_context *mac_ctx, tpDphHashNode stads, 3332 struct pe_session *session_entry) 3333 { 3334 lim_populate_eht_mcs_set(mac_ctx, &stads->supportedRates, 3335 &stads->eht_config, session_entry, 3336 session_entry->nss); 3337 } 3338 #else 3339 static void 3340 lim_tdls_populate_eht_mcs(struct mac_context *mac_ctx, tpDphHashNode stads, 3341 struct pe_session *session_entry) 3342 { 3343 } 3344 #endif 3345 3346 /** 3347 * lim_tdls_populate_matching_rate_set() - populate matching rate set 3348 * 3349 * @mac_ctx - global MAC context 3350 * @stads - station hash entry 3351 * @supp_rate_set - pointer to supported rate set 3352 * @supp_rates_len - length of the supported rates 3353 * @supp_mcs_set - pointer to supported MSC set 3354 * @session_entry - pointer to PE session entry 3355 * @vht_caps - pointer to VHT capability 3356 * 3357 * 3358 * This function gets set of available rates from the config and compare them 3359 * against the set of received supported rates. After the comparison station 3360 * entry's rates is populated with 11A rates and 11B rates. 3361 * 3362 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure. 3363 */ 3364 static QDF_STATUS 3365 lim_tdls_populate_matching_rate_set(struct mac_context *mac_ctx, 3366 tpDphHashNode stads, 3367 uint8_t *supp_rate_set, 3368 uint8_t supp_rates_len, 3369 uint8_t *supp_mcs_set, 3370 struct pe_session *session_entry, 3371 tDot11fIEVHTCaps *vht_caps) 3372 { 3373 tSirMacRateSet temp_rate_set; 3374 uint32_t i, j, is_a_rate; 3375 uint32_t phymode; 3376 uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; 3377 struct supported_rates *rates; 3378 uint8_t a_rateindex = 0; 3379 uint8_t b_rateindex = 0; 3380 uint8_t nss; 3381 qdf_size_t val_len; 3382 3383 is_a_rate = 0; 3384 3385 lim_get_phy_mode(mac_ctx, &phymode, NULL); 3386 3387 /** 3388 * Copy received rates in temp_rate_set, the parser has ensured 3389 * unicity of the rates so there cannot be more than 12 . 3390 */ 3391 if (supp_rates_len > SIR_MAC_MAX_NUMBER_OF_RATES) { 3392 pe_warn("Supported rates length: %d more than the Max limit, reset to Max", 3393 supp_rates_len); 3394 supp_rates_len = SIR_MAC_MAX_NUMBER_OF_RATES; 3395 } 3396 3397 for (i = 0; i < supp_rates_len; i++) 3398 temp_rate_set.rate[i] = supp_rate_set[i]; 3399 3400 temp_rate_set.numRates = supp_rates_len; 3401 3402 rates = &stads->supportedRates; 3403 qdf_mem_zero(rates, sizeof(*rates)); 3404 3405 for (j = 0; j < temp_rate_set.numRates; j++) { 3406 if ((b_rateindex > SIR_NUM_11B_RATES) || 3407 (a_rateindex > SIR_NUM_11A_RATES)) { 3408 pe_warn("Invalid number of rates (11b->%d, 11a->%d)", 3409 b_rateindex, a_rateindex); 3410 return QDF_STATUS_E_FAILURE; 3411 } 3412 if (sirIsArate(temp_rate_set.rate[j] & 0x7f)) { 3413 is_a_rate = 1; 3414 if (a_rateindex < SIR_NUM_11A_RATES) 3415 rates->llaRates[a_rateindex++] = 3416 temp_rate_set.rate[j]; 3417 } else { 3418 if (b_rateindex < SIR_NUM_11B_RATES) 3419 rates->llbRates[b_rateindex++] = 3420 temp_rate_set.rate[j]; 3421 } 3422 } 3423 3424 if (wlan_reg_is_5ghz_ch_freq(session_entry->curr_op_freq)) 3425 nss = mac_ctx->vdev_type_nss_5g.tdls; 3426 else 3427 nss = mac_ctx->vdev_type_nss_2g.tdls; 3428 3429 nss = QDF_MIN(nss, mac_ctx->user_configured_nss); 3430 3431 /* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */ 3432 #ifdef FEATURE_WLAN_TDLS 3433 if (stads->mlmStaContext.htCapability) 3434 #else 3435 if (IS_DOT11_MODE_HT(session_entry->dot11mode) && 3436 (stads->mlmStaContext.htCapability)) 3437 #endif 3438 { 3439 val_len = SIZE_OF_SUPPORTED_MCS_SET; 3440 if (wlan_mlme_get_cfg_str( 3441 mcsSet, 3442 &mac_ctx->mlme_cfg->rates.supported_mcs_set, 3443 &val_len) != QDF_STATUS_SUCCESS) { 3444 /* Could not get rateset from CFG. Log error. */ 3445 pe_err("could not retrieve supportedMCSSet"); 3446 return QDF_STATUS_E_FAILURE; 3447 } 3448 3449 if (NSS_1x1_MODE == nss) 3450 mcsSet[1] = 0; 3451 for (i = 0; i < val_len; i++) 3452 stads->supportedRates.supportedMCSSet[i] = 3453 mcsSet[i] & supp_mcs_set[i]; 3454 3455 pe_debug("MCS Rate Set Bitmap from CFG and DPH"); 3456 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) { 3457 pe_debug("%x %x", mcsSet[i], 3458 stads->supportedRates.supportedMCSSet[i]); 3459 } 3460 } 3461 lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps, 3462 session_entry, nss, NULL); 3463 3464 lim_tdls_populate_eht_mcs(mac_ctx, stads, session_entry); 3465 3466 lim_tdls_populate_he_matching_rate_set(mac_ctx, stads, nss, 3467 session_entry); 3468 /** 3469 * Set the erpEnabled bit if the phy is in G mode and at least 3470 * one A rate is supported 3471 */ 3472 if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate) 3473 stads->erpEnabled = eHAL_SET; 3474 3475 return QDF_STATUS_SUCCESS; 3476 } 3477 3478 static void lim_tdls_fill_session_vht_width(struct pe_session *pe_session, 3479 tDphHashNode *sta) 3480 { 3481 if (pe_session->ch_width) 3482 sta->vhtSupportedChannelWidthSet = 3483 pe_session->ch_width - 1; 3484 else 3485 sta->vhtSupportedChannelWidthSet = 3486 pe_session->ch_width; 3487 } 3488 3489 static inline enum phy_ch_width 3490 lim_reg_bw_to_ht_ch_width(uint16_t reg_max_bw) 3491 { 3492 return reg_max_bw > 20 ? CH_WIDTH_40MHZ : CH_WIDTH_20MHZ; 3493 } 3494 3495 #ifdef WLAN_FEATURE_11BE 3496 static void 3497 lim_tdls_populate_dot11f_eht_caps(struct pe_session *pe_session, 3498 tDphHashNode *sta, 3499 struct tdls_add_sta_req *add_sta_req) 3500 { 3501 if (add_sta_req->ehtcap_present) { 3502 pe_debug("copy eht config from pe_session"); 3503 qdf_mem_copy(&sta->eht_config, &pe_session->eht_config, 3504 sizeof(sta->eht_config)); 3505 qdf_mem_copy(&sta->eht_op, &pe_session->eht_op, 3506 sizeof(sta->eht_op)); 3507 } 3508 } 3509 #else 3510 static inline void 3511 lim_tdls_populate_dot11f_eht_caps(struct pe_session *pe_session, 3512 tDphHashNode *sta, 3513 struct tdls_add_sta_req *add_sta_req) 3514 { 3515 } 3516 #endif 3517 3518 /* 3519 * update HASH node entry info 3520 */ 3521 static void lim_tdls_update_hash_node_info(struct mac_context *mac, 3522 tDphHashNode *sta, 3523 struct tdls_add_sta_req *add_sta_req, 3524 struct pe_session *pe_session) 3525 { 3526 tDot11fIEHTCaps htCap = {0,}; 3527 tDot11fIEHTCaps *htCaps; 3528 tDot11fIEVHTCaps *pVhtCaps = NULL; 3529 tDot11fIEVHTCaps *pVhtCaps_txbf = NULL; 3530 tDot11fIEVHTCaps vhtCap; 3531 uint8_t cbMode, selfDot11Mode; 3532 bool wide_band_peer = false; 3533 uint16_t reg_max_bw = 0; 3534 uint16_t reg_ch_width = 0; 3535 3536 if (add_sta_req->tdls_oper == TDLS_OPER_ADD) { 3537 populate_dot11f_ht_caps(mac, pe_session, &htCap); 3538 } else if (add_sta_req->tdls_oper == TDLS_OPER_UPDATE) { 3539 lim_tdls_populate_dot11f_ht_caps(mac, NULL, 3540 add_sta_req, &htCap); 3541 sta->rmfEnabled = add_sta_req->is_pmf; 3542 } 3543 3544 lim_tdls_populate_dot11f_eht_caps(pe_session, sta, add_sta_req); 3545 3546 reg_max_bw = wlan_reg_get_max_chwidth(mac->pdev, 3547 pe_session->curr_op_freq); 3548 3549 wide_band_peer = lim_is_wide_band_set(add_sta_req->extn_capability) && 3550 wlan_cfg80211_tdls_is_fw_wideband_capable(pe_session->vdev); 3551 selfDot11Mode = mac->mlme_cfg->dot11_mode.dot11_mode; 3552 htCaps = &htCap; 3553 if (htCaps->present && IS_DOT11_MODE_HT(selfDot11Mode)) { 3554 sta->mlmStaContext.htCapability = 1; 3555 sta->htGreenfield = htCaps->greenField; 3556 /* 3557 * sta->htSupportedChannelWidthSet should have the base 3558 * channel capability. The htSupportedChannelWidthSet of the 3559 * TDLS link on base channel should be less than or equal to 3560 * channel width of STA-AP link. So take this setting from the 3561 * pe_session. 3562 */ 3563 /* 3564 * Since, now wideband is supported, bw should be restricted 3565 * only in case of dfs channel 3566 */ 3567 pe_debug("peer htSupportedChannelWidthSet: 0x%x " 3568 "pe session htSupportedChannelWidthSet: 0x%x", 3569 htCaps->supportedChannelWidthSet, 3570 pe_session->htSupportedChannelWidthSet); 3571 3572 if (!wide_band_peer || 3573 wlan_reg_is_dfs_for_freq(mac->pdev, 3574 pe_session->curr_op_freq) || 3575 wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq)) { 3576 sta->htSupportedChannelWidthSet = 3577 (htCaps->supportedChannelWidthSet < 3578 pe_session->htSupportedChannelWidthSet) ? 3579 htCaps->supportedChannelWidthSet : 3580 pe_session->htSupportedChannelWidthSet; 3581 } else { 3582 reg_ch_width = lim_reg_bw_to_ht_ch_width(reg_max_bw); 3583 3584 pe_debug("regulatory max bw %d MHz ch_width 0x%x", 3585 reg_max_bw, 3586 reg_ch_width); 3587 3588 sta->htSupportedChannelWidthSet = 3589 (htCaps->supportedChannelWidthSet < 3590 reg_ch_width) ? 3591 htCaps->supportedChannelWidthSet : 3592 reg_ch_width; 3593 } 3594 3595 pe_debug("sta->htSupportedChannelWidthSet: 0x%x", 3596 sta->htSupportedChannelWidthSet); 3597 3598 sta->ch_width = sta->htSupportedChannelWidthSet; 3599 sta->htMIMOPSState = htCaps->mimoPowerSave; 3600 sta->htMaxAmsduLength = htCaps->maximalAMSDUsize; 3601 sta->htAMpduDensity = htCaps->mpduDensity; 3602 sta->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz; 3603 sta->htShortGI20Mhz = htCaps->shortGI20MHz; 3604 sta->htShortGI40Mhz = htCaps->shortGI40MHz; 3605 sta->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor; 3606 lim_fill_rx_highest_supported_rate(mac, 3607 &sta->supportedRates. 3608 rxHighestDataRate, 3609 htCaps->supportedMCSSet); 3610 sta->ht_caps = add_sta_req->ht_cap.hc_cap; 3611 } else { 3612 sta->mlmStaContext.htCapability = 0; 3613 } 3614 lim_tdls_populate_dot11f_vht_caps(mac, add_sta_req, &vhtCap); 3615 pVhtCaps = &vhtCap; 3616 if (pVhtCaps->present && IS_DOT11_MODE_VHT(selfDot11Mode)) { 3617 sta->mlmStaContext.vhtCapability = 1; 3618 3619 /* 3620 * 11.21.1 General: The channel width of the TDLS direct 3621 * link on the base channel shall not exceed the channel 3622 * width of the BSS to which the TDLS peer STAs are 3623 * associated, if the base channel is dfs channel and peer is 3624 * not wide band supported 3625 */ 3626 if (!wide_band_peer || 3627 wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq)) { 3628 lim_tdls_fill_session_vht_width(pe_session, sta); 3629 } else { 3630 if (pVhtCaps->supportedChannelWidthSet >= 3631 VHT_CAP_NO_160M_SUPP) 3632 sta->vhtSupportedChannelWidthSet = 3633 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; 3634 3635 if (wlan_reg_is_dfs_for_freq(mac->pdev, 3636 pe_session->curr_op_freq)) { 3637 lim_tdls_fill_session_vht_width(pe_session, 3638 sta); 3639 } 3640 } 3641 3642 if (sta->htSupportedChannelWidthSet) { 3643 if (sta->vhtSupportedChannelWidthSet > 3644 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 3645 sta->ch_width = CH_WIDTH_160MHZ; 3646 else 3647 sta->ch_width = 3648 sta->vhtSupportedChannelWidthSet + 1; 3649 } else { 3650 sta->ch_width = CH_WIDTH_20MHZ; 3651 } 3652 3653 pe_debug("vhtSupportedChannelWidthSet: %hu htSupportedChannelWidthSet: %hu sta_ch_width %d", 3654 sta->vhtSupportedChannelWidthSet, 3655 sta->htSupportedChannelWidthSet, 3656 sta->ch_width); 3657 3658 sta->vhtLdpcCapable = pVhtCaps->ldpcCodingCap; 3659 sta->vhtBeamFormerCapable = 0; 3660 pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&add_sta_req->vht_cap); 3661 pVhtCaps_txbf->suBeamformeeCap = 0; 3662 pVhtCaps_txbf->suBeamFormerCap = 0; 3663 pVhtCaps_txbf->muBeamformerCap = 0; 3664 pVhtCaps_txbf->muBeamformeeCap = 0; 3665 sta->vht_caps = add_sta_req->vht_cap.vht_capinfo; 3666 } else { 3667 sta->mlmStaContext.vhtCapability = 0; 3668 sta->vhtSupportedChannelWidthSet = 3669 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; 3670 } 3671 3672 if (IS_DOT11_MODE_HE(selfDot11Mode)) 3673 lim_tdls_update_node_he_caps(mac, add_sta_req, sta, pe_session, 3674 wide_band_peer); 3675 else 3676 pe_debug("Not populating he cap as SelfDot11Mode not HE %d", 3677 selfDot11Mode); 3678 /* 3679 * Calculate the Secondary Coannel Offset if our 3680 * own channel bonding state is enabled 3681 */ 3682 if (pe_session->htSupportedChannelWidthSet) { 3683 cbMode = lim_select_cb_mode(sta, pe_session, 3684 wlan_reg_freq_to_chan( 3685 mac->pdev, pe_session->curr_op_freq), 3686 sta->vhtSupportedChannelWidthSet); 3687 3688 if (sta->mlmStaContext.vhtCapability) 3689 sta->htSecondaryChannelOffset = 3690 lim_get_htcb_state(cbMode); 3691 else 3692 sta->htSecondaryChannelOffset = cbMode; 3693 } 3694 /* Lets enable QOS parameter */ 3695 sta->qosMode = (add_sta_req->capability & CAPABILITIES_QOS_OFFSET) 3696 || add_sta_req->htcap_present; 3697 sta->wmeEnabled = 1; 3698 sta->lleEnabled = 0; 3699 /* TDLS Dummy AddSTA does not have qosInfo , is it OK ?? 3700 */ 3701 sta->qos.capability.qosInfo = 3702 (*(tSirMacQosInfoStation *) &add_sta_req->uapsd_queues); 3703 3704 /* populate matching rate set */ 3705 3706 /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ?? 3707 */ 3708 3709 lim_tdls_populate_matching_rate_set(mac, sta, 3710 add_sta_req->supported_rates, 3711 add_sta_req->supported_rates_length, 3712 add_sta_req->ht_cap.mcsset, 3713 pe_session, pVhtCaps); 3714 3715 lim_tdls_check_and_force_he_ldpc_cap(pe_session, sta); 3716 3717 /* TDLS Dummy AddSTA does not have right capability , is it OK ?? 3718 */ 3719 sta->mlmStaContext.capabilityInfo = 3720 (*(tSirMacCapabilityInfo *) &add_sta_req->capability); 3721 3722 return; 3723 } 3724 3725 /* 3726 * Add STA for TDLS setup procedure 3727 */ 3728 static QDF_STATUS lim_tdls_setup_add_sta(struct mac_context *mac, 3729 struct tdls_add_sta_req *pAddStaReq, 3730 struct pe_session *pe_session) 3731 { 3732 tpDphHashNode sta = NULL; 3733 QDF_STATUS status = QDF_STATUS_SUCCESS; 3734 uint16_t aid = 0; 3735 3736 sta = dph_lookup_hash_entry(mac, pAddStaReq->peermac.bytes, &aid, 3737 &pe_session->dph.dphHashTable); 3738 if (!sta && pAddStaReq->tdls_oper == TDLS_OPER_UPDATE) { 3739 pe_err("TDLS update peer is given without peer creation"); 3740 return QDF_STATUS_E_FAILURE; 3741 } 3742 if (sta && pAddStaReq->tdls_oper == TDLS_OPER_ADD) { 3743 pe_err("TDLS entry for peer: "QDF_MAC_ADDR_FMT " already exist, cannot add new entry", 3744 QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); 3745 return QDF_STATUS_E_FAILURE; 3746 } 3747 3748 if (sta && sta->staType != STA_ENTRY_TDLS_PEER) { 3749 pe_err("Non TDLS entry for peer: "QDF_MAC_ADDR_FMT " already exist", 3750 QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); 3751 return QDF_STATUS_E_FAILURE; 3752 } 3753 3754 if (!sta) { 3755 aid = lim_assign_peer_idx(mac, pe_session); 3756 3757 if (!aid) { 3758 pe_err("No more free AID for peer: "QDF_MAC_ADDR_FMT, 3759 QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); 3760 return QDF_STATUS_E_FAILURE; 3761 } 3762 3763 /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */ 3764 SET_PEER_AID_BITMAP(pe_session->peerAIDBitmap, aid); 3765 3766 pe_debug("Aid: %d, for peer: " QDF_MAC_ADDR_FMT, 3767 aid, QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); 3768 sta = 3769 dph_get_hash_entry(mac, aid, 3770 &pe_session->dph.dphHashTable); 3771 3772 if (sta) { 3773 (void)lim_del_sta(mac, sta, false /*asynchronous */, 3774 pe_session); 3775 lim_delete_dph_hash_entry(mac, sta->staAddr, aid, 3776 pe_session); 3777 } 3778 3779 sta = dph_add_hash_entry(mac, pAddStaReq->peermac.bytes, 3780 aid, &pe_session->dph.dphHashTable); 3781 3782 if (!sta) { 3783 pe_err("add hash entry failed"); 3784 QDF_ASSERT(0); 3785 return QDF_STATUS_E_FAILURE; 3786 } 3787 } 3788 3789 lim_tdls_update_hash_node_info(mac, sta, pAddStaReq, pe_session); 3790 3791 sta->staType = STA_ENTRY_TDLS_PEER; 3792 3793 status = 3794 lim_add_sta(mac, sta, 3795 (pAddStaReq->tdls_oper == 3796 TDLS_OPER_UPDATE) ? true : false, pe_session); 3797 3798 if (QDF_STATUS_SUCCESS != status) { 3799 /* should not fail */ 3800 QDF_ASSERT(0); 3801 } 3802 return status; 3803 } 3804 3805 /* 3806 * Del STA, after Link is teardown or discovery response sent on direct link 3807 */ 3808 static QDF_STATUS lim_tdls_del_sta(struct mac_context *mac, 3809 struct qdf_mac_addr peerMac, 3810 struct pe_session *pe_session, 3811 bool resp_reqd) 3812 { 3813 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3814 uint16_t peerIdx = 0; 3815 tpDphHashNode sta; 3816 3817 sta = dph_lookup_hash_entry(mac, peerMac.bytes, &peerIdx, 3818 &pe_session->dph.dphHashTable); 3819 3820 if (sta && sta->staType == STA_ENTRY_TDLS_PEER) 3821 status = lim_del_sta(mac, sta, resp_reqd, pe_session); 3822 else 3823 pe_debug("TDLS peer "QDF_MAC_ADDR_FMT" not found", 3824 QDF_MAC_ADDR_REF(peerMac.bytes)); 3825 3826 return status; 3827 } 3828 3829 /* 3830 * Once Link is setup with PEER, send Add STA ind to SME 3831 */ 3832 static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(struct mac_context *mac, 3833 uint8_t sessionId, 3834 tSirMacAddr peerMac, 3835 uint8_t updateSta, 3836 tDphHashNode *sta, uint8_t status) 3837 { 3838 struct scheduler_msg msg = { 0 }; 3839 struct tdls_add_sta_rsp *add_sta_rsp; 3840 QDF_STATUS ret; 3841 3842 msg.type = eWNI_SME_TDLS_ADD_STA_RSP; 3843 3844 add_sta_rsp = qdf_mem_malloc(sizeof(*add_sta_rsp)); 3845 if (!add_sta_rsp) 3846 return QDF_STATUS_E_NOMEM; 3847 3848 add_sta_rsp->session_id = sessionId; 3849 add_sta_rsp->status_code = status; 3850 3851 if (peerMac) { 3852 qdf_mem_copy(add_sta_rsp->peermac.bytes, 3853 (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE); 3854 } 3855 if (updateSta) 3856 add_sta_rsp->tdls_oper = TDLS_OPER_UPDATE; 3857 else 3858 add_sta_rsp->tdls_oper = TDLS_OPER_ADD; 3859 3860 add_sta_rsp->psoc = mac->psoc; 3861 msg.bodyptr = add_sta_rsp; 3862 msg.callback = tgt_tdls_add_peer_rsp; 3863 3864 ret = scheduler_post_message(QDF_MODULE_ID_PE, 3865 QDF_MODULE_ID_TDLS, 3866 QDF_MODULE_ID_TARGET_IF, &msg); 3867 if (QDF_IS_STATUS_ERROR(ret)) { 3868 pe_err("post msg fail, %d", ret); 3869 qdf_mem_free(add_sta_rsp); 3870 } 3871 3872 return ret; 3873 } 3874 3875 /* 3876 * STA RSP received from HAL 3877 */ 3878 QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg, 3879 struct pe_session *pe_session) 3880 { 3881 tAddStaParams *pAddStaParams = (tAddStaParams *) msg; 3882 uint8_t status = QDF_STATUS_SUCCESS; 3883 tDphHashNode *sta = NULL; 3884 uint16_t aid = 0; 3885 3886 SET_LIM_PROCESS_DEFD_MESGS(mac, true); 3887 pe_debug("staMac: "QDF_MAC_ADDR_FMT, 3888 QDF_MAC_ADDR_REF(pAddStaParams->staMac)); 3889 3890 if (pAddStaParams->status != QDF_STATUS_SUCCESS) { 3891 QDF_ASSERT(0); 3892 pe_err("Add sta failed "); 3893 status = QDF_STATUS_E_FAILURE; 3894 goto add_sta_error; 3895 } 3896 3897 sta = dph_lookup_hash_entry(mac, pAddStaParams->staMac, &aid, 3898 &pe_session->dph.dphHashTable); 3899 if (!sta) { 3900 pe_err("sta is NULL "); 3901 status = QDF_STATUS_E_FAILURE; 3902 goto add_sta_error; 3903 } 3904 3905 sta->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; 3906 sta->valid = 1; 3907 add_sta_error: 3908 status = lim_send_sme_tdls_add_sta_rsp(mac, pe_session->smeSessionId, 3909 pAddStaParams->staMac, 3910 pAddStaParams->updateSta, sta, 3911 status); 3912 qdf_mem_free(pAddStaParams); 3913 return status; 3914 } 3915 3916 /** 3917 * lim_send_tdls_comp_mgmt_rsp() - Send Response to upper layers 3918 * @mac_ctx: Pointer to Global MAC structure 3919 * @msg_type: Indicates message type 3920 * @result_code: Indicates the result of previously issued 3921 * eWNI_SME_msg_type_REQ message 3922 * @vdev_id: vdev id 3923 * 3924 * This function is called by lim_process_sme_req_messages() to send 3925 * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP 3926 * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC 3927 * Software. 3928 * 3929 * Return: None 3930 */ 3931 3932 static void 3933 lim_send_tdls_comp_mgmt_rsp(struct mac_context *mac_ctx, uint16_t msg_type, 3934 tSirResultCodes result_code, uint8_t vdev_id) 3935 { 3936 struct scheduler_msg msg = {0}; 3937 struct tdls_send_mgmt_rsp *sme_rsp; 3938 QDF_STATUS status; 3939 3940 pe_debug("vdev:%d Sending message %s with reasonCode %s", vdev_id, 3941 lim_msg_str(msg_type), lim_result_code_str(result_code)); 3942 3943 sme_rsp = qdf_mem_malloc(sizeof(*sme_rsp)); 3944 if (!sme_rsp) 3945 return; 3946 3947 sme_rsp->status_code = (enum legacy_result_code)result_code; 3948 sme_rsp->vdev_id = vdev_id; 3949 sme_rsp->psoc = mac_ctx->psoc; 3950 3951 msg.type = msg_type; 3952 msg.bodyptr = sme_rsp; 3953 msg.callback = tgt_tdls_send_mgmt_rsp; 3954 status = scheduler_post_message(QDF_MODULE_ID_PE, 3955 QDF_MODULE_ID_TDLS, 3956 QDF_MODULE_ID_TARGET_IF, &msg); 3957 if (QDF_IS_STATUS_ERROR(status)) { 3958 pe_err("post msg fail, %d", status); 3959 qdf_mem_free(sme_rsp); 3960 } 3961 } 3962 3963 QDF_STATUS lim_process_sme_tdls_mgmt_send_req(struct mac_context *mac_ctx, 3964 void *msg) 3965 { 3966 struct tdls_send_mgmt_request *send_req = msg; 3967 struct pe_session *session_entry; 3968 uint8_t session_id; 3969 uint16_t ie_len; 3970 tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS; 3971 3972 pe_debug("Send Mgmt Received"); 3973 session_entry = pe_find_session_by_bssid(mac_ctx, 3974 send_req->bssid.bytes, 3975 &session_id); 3976 if (!session_entry) { 3977 pe_err("PE Session does not exist for given sme session_id %d", 3978 send_req->session_id); 3979 goto lim_tdls_send_mgmt_error; 3980 } 3981 3982 /* check if we are in proper state to work as TDLS client */ 3983 if (!LIM_IS_STA_ROLE(session_entry)) { 3984 pe_err("send mgmt received in wrong system Role: %d", 3985 GET_LIM_SYSTEM_ROLE(session_entry)); 3986 goto lim_tdls_send_mgmt_error; 3987 } 3988 3989 if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry)) { 3990 pe_err("roaming in progress, reject mgmt! for session %d", 3991 send_req->session_id); 3992 result_code = eSIR_SME_REFUSED; 3993 goto lim_tdls_send_mgmt_error; 3994 } 3995 3996 /* 3997 * if we are still good, go ahead and check if we are in proper state to 3998 * do TDLS discovery req/rsp/....frames. 3999 */ 4000 if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && 4001 (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) { 4002 pe_err("send mgmt received in invalid LIMsme state: %d", 4003 session_entry->limSmeState); 4004 goto lim_tdls_send_mgmt_error; 4005 } 4006 4007 cds_tdls_tx_rx_mgmt_event(ACTION_CATEGORY_TDLS, 4008 SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION, 4009 send_req->req_type, send_req->peer_mac.bytes); 4010 4011 ie_len = send_req->length - sizeof(*send_req); 4012 4013 switch (send_req->req_type) { 4014 case TDLS_DISCOVERY_REQUEST: 4015 pe_debug("Transmit Discovery Request Frame"); 4016 /* format TDLS discovery request frame and transmit it */ 4017 lim_send_tdls_dis_req_frame(mac_ctx, send_req->peer_mac, 4018 send_req->dialog, session_entry, 4019 send_req->ac); 4020 result_code = eSIR_SME_SUCCESS; 4021 break; 4022 case TDLS_DISCOVERY_RESPONSE: 4023 pe_debug("Transmit Discovery Response Frame"); 4024 /* Send a response mgmt action frame */ 4025 lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peer_mac, 4026 send_req->dialog, session_entry, 4027 send_req->add_ie, ie_len); 4028 result_code = eSIR_SME_SUCCESS; 4029 break; 4030 case TDLS_SETUP_REQUEST: 4031 pe_debug("Transmit Setup Request Frame"); 4032 lim_send_tdls_link_setup_req_frame(mac_ctx, 4033 send_req->peer_mac, 4034 send_req->dialog, 4035 session_entry, 4036 send_req->add_ie, ie_len, 4037 send_req->ac); 4038 result_code = eSIR_SME_SUCCESS; 4039 break; 4040 case TDLS_SETUP_RESPONSE: 4041 pe_debug("Transmit Setup Response Frame"); 4042 lim_send_tdls_setup_rsp_frame(mac_ctx, 4043 send_req->peer_mac, 4044 send_req->dialog, session_entry, 4045 send_req->status_code, 4046 send_req->add_ie, ie_len, 4047 send_req->ac); 4048 result_code = eSIR_SME_SUCCESS; 4049 break; 4050 case TDLS_SETUP_CONFIRM: 4051 pe_debug("Transmit Setup Confirm Frame"); 4052 lim_send_tdls_link_setup_cnf_frame(mac_ctx, 4053 send_req->peer_mac, 4054 send_req->dialog, 4055 send_req->peer_capability, 4056 session_entry, 4057 send_req->add_ie, ie_len, 4058 send_req->ac); 4059 result_code = eSIR_SME_SUCCESS; 4060 break; 4061 case TDLS_TEARDOWN: 4062 pe_debug("Transmit Teardown Frame"); 4063 lim_send_tdls_teardown_frame(mac_ctx, 4064 send_req->peer_mac, 4065 send_req->status_code, 4066 send_req->responder, 4067 session_entry, 4068 send_req->add_ie, ie_len, 4069 send_req->ac); 4070 result_code = eSIR_SME_SUCCESS; 4071 break; 4072 case TDLS_PEER_TRAFFIC_INDICATION: 4073 break; 4074 case TDLS_CHANNEL_SWITCH_REQUEST: 4075 break; 4076 case TDLS_CHANNEL_SWITCH_RESPONSE: 4077 break; 4078 case TDLS_PEER_TRAFFIC_RESPONSE: 4079 break; 4080 default: 4081 break; 4082 } 4083 4084 lim_tdls_send_mgmt_error: 4085 lim_send_tdls_comp_mgmt_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP, 4086 result_code, send_req->session_id); 4087 4088 return QDF_STATUS_SUCCESS; 4089 } 4090 4091 /* 4092 * Once link is teardown, send Del Peer Ind to SME 4093 */ 4094 static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(struct mac_context *mac, 4095 uint8_t sessionId, 4096 struct qdf_mac_addr peerMac, 4097 tDphHashNode *sta, uint8_t status) 4098 { 4099 struct scheduler_msg msg = { 0 }; 4100 struct tdls_del_sta_rsp *del_sta_rsp; 4101 QDF_STATUS ret; 4102 4103 msg.type = eWNI_SME_TDLS_DEL_STA_RSP; 4104 4105 del_sta_rsp = qdf_mem_malloc(sizeof(*del_sta_rsp)); 4106 if (!del_sta_rsp) 4107 return QDF_STATUS_E_NOMEM; 4108 4109 del_sta_rsp->session_id = sessionId; 4110 del_sta_rsp->status_code = status; 4111 4112 qdf_copy_macaddr(&del_sta_rsp->peermac, &peerMac); 4113 4114 del_sta_rsp->psoc = mac->psoc; 4115 msg.bodyptr = del_sta_rsp; 4116 msg.callback = tgt_tdls_del_peer_rsp; 4117 ret = scheduler_post_message(QDF_MODULE_ID_PE, 4118 QDF_MODULE_ID_TDLS, 4119 QDF_MODULE_ID_TARGET_IF, &msg); 4120 if (QDF_IS_STATUS_ERROR(ret)) { 4121 pe_err("post msg fail, %d", ret); 4122 qdf_mem_free(del_sta_rsp); 4123 } 4124 4125 return ret; 4126 } 4127 4128 QDF_STATUS lim_process_sme_tdls_add_sta_req(struct mac_context *mac, 4129 void *msg) 4130 { 4131 struct tdls_add_sta_req *add_sta_req = msg; 4132 struct pe_session *pe_session; 4133 uint8_t session_id; 4134 4135 pe_debug("TDLS Add STA Request Received"); 4136 pe_session = 4137 pe_find_session_by_bssid(mac, add_sta_req->bssid.bytes, 4138 &session_id); 4139 if (!pe_session) { 4140 pe_err("PE Session does not exist for given sme sessionId: %d", 4141 add_sta_req->session_id); 4142 goto lim_tdls_add_sta_error; 4143 } 4144 4145 /* check if we are in proper state to work as TDLS client */ 4146 if (!LIM_IS_STA_ROLE(pe_session)) { 4147 pe_err("send mgmt received in wrong system Role: %d", 4148 GET_LIM_SYSTEM_ROLE(pe_session)); 4149 goto lim_tdls_add_sta_error; 4150 } 4151 4152 if (lim_is_roam_synch_in_progress(mac->psoc, pe_session)) { 4153 pe_err("roaming in progress, reject add sta! for session %d", 4154 add_sta_req->session_id); 4155 goto lim_tdls_add_sta_error; 4156 } 4157 4158 /* 4159 * if we are still good, go ahead and check if we are in proper state to 4160 * do TDLS discovery req/rsp/....frames. 4161 */ 4162 if ((pe_session->limSmeState != eLIM_SME_ASSOCIATED_STATE) && 4163 (pe_session->limSmeState != eLIM_SME_LINK_EST_STATE)) { 4164 pe_err("send mgmt received in invalid LIMsme state: %d", 4165 pe_session->limSmeState); 4166 goto lim_tdls_add_sta_error; 4167 } 4168 4169 4170 /* To start with, send add STA request to HAL */ 4171 if (QDF_STATUS_E_FAILURE == lim_tdls_setup_add_sta(mac, add_sta_req, pe_session)) { 4172 pe_err("Add TDLS Station request failed"); 4173 goto lim_tdls_add_sta_error; 4174 } 4175 return QDF_STATUS_SUCCESS; 4176 lim_tdls_add_sta_error: 4177 lim_send_sme_tdls_add_sta_rsp(mac, 4178 add_sta_req->session_id, 4179 add_sta_req->peermac.bytes, 4180 (add_sta_req->tdls_oper == TDLS_OPER_UPDATE), 4181 NULL, QDF_STATUS_E_FAILURE); 4182 4183 return QDF_STATUS_SUCCESS; 4184 } 4185 4186 QDF_STATUS lim_process_sme_tdls_del_sta_req(struct mac_context *mac, 4187 void *msg) 4188 { 4189 struct tdls_del_sta_req *del_sta_req = msg; 4190 struct pe_session *pe_session; 4191 uint8_t session_id; 4192 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4193 tSirMacAddr peer; 4194 4195 pe_debug("TDLS Delete STA Request Received"); 4196 pe_session = 4197 pe_find_session_by_bssid(mac, del_sta_req->bssid.bytes, 4198 &session_id); 4199 if (!pe_session) { 4200 pe_err("PE Session does not exist for given vdev id: %d", 4201 del_sta_req->session_id); 4202 lim_send_sme_tdls_del_sta_rsp(mac, del_sta_req->session_id, 4203 del_sta_req->peermac, NULL, 4204 QDF_STATUS_E_FAILURE); 4205 return QDF_STATUS_E_FAILURE; 4206 } 4207 4208 /* check if we are in proper state to work as TDLS client */ 4209 if (!LIM_IS_STA_ROLE(pe_session)) { 4210 pe_err("Del sta received in wrong system Role %d", 4211 GET_LIM_SYSTEM_ROLE(pe_session)); 4212 goto lim_tdls_del_sta_error; 4213 } 4214 4215 if (lim_is_roam_synch_in_progress(mac->psoc, pe_session)) { 4216 pe_err("roaming in progress, reject del sta! for session %d", 4217 del_sta_req->session_id); 4218 lim_send_sme_tdls_del_sta_rsp(mac, del_sta_req->session_id, 4219 del_sta_req->peermac, NULL, 4220 QDF_STATUS_E_FAILURE); 4221 return QDF_STATUS_E_FAILURE; 4222 } 4223 4224 /* 4225 * if we are still good, go ahead and check if we are in proper state to 4226 * do TDLS discovery req/rsp/....frames. 4227 */ 4228 if ((pe_session->limSmeState != eLIM_SME_ASSOCIATED_STATE) && 4229 (pe_session->limSmeState != eLIM_SME_LINK_EST_STATE)) { 4230 4231 pe_err("Del Sta received in invalid LIMsme state: %d", 4232 pe_session->limSmeState); 4233 goto lim_tdls_del_sta_error; 4234 } 4235 4236 qdf_mem_copy(peer, del_sta_req->peermac.bytes, sizeof(tSirMacAddr)); 4237 lim_send_deauth_mgmt_frame(mac, REASON_DEAUTH_NETWORK_LEAVING, 4238 peer, pe_session, false); 4239 status = lim_tdls_del_sta(mac, del_sta_req->peermac, 4240 pe_session, true); 4241 if (status == QDF_STATUS_SUCCESS) 4242 return status; 4243 4244 lim_tdls_del_sta_error: 4245 lim_send_sme_tdls_del_sta_rsp(mac, pe_session->smeSessionId, 4246 del_sta_req->peermac, NULL, QDF_STATUS_E_FAILURE); 4247 4248 return status; 4249 } 4250 4251 /** 4252 * lim_check_aid_and_delete_peer() - Function to check aid and delete peer 4253 * @p_mac: pointer to mac context 4254 * @session_entry: pointer to PE session 4255 * 4256 * This function verifies aid and delete's peer with that aid from hash table 4257 * 4258 * Return: None 4259 */ 4260 static void lim_check_aid_and_delete_peer(struct mac_context *p_mac, 4261 struct pe_session *session_entry) 4262 { 4263 tpDphHashNode stads = NULL; 4264 int i, aid; 4265 size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap); 4266 struct qdf_mac_addr mac_addr; 4267 QDF_STATUS status; 4268 /* 4269 * Check all the set bit in peerAIDBitmap and delete the peer 4270 * (with that aid) entry from the hash table and add the aid 4271 * in free pool 4272 */ 4273 for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) { 4274 for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) { 4275 if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid)) 4276 continue; 4277 stads = dph_get_hash_entry(p_mac, 4278 (aid + i * (sizeof(uint32_t) << 3)), 4279 &session_entry->dph.dphHashTable); 4280 4281 if (!stads) 4282 goto skip; 4283 4284 pe_debug("Deleting "QDF_MAC_ADDR_FMT, 4285 QDF_MAC_ADDR_REF(stads->staAddr)); 4286 4287 if (!lim_is_roam_synch_in_progress(p_mac->psoc, 4288 session_entry)) { 4289 lim_send_deauth_mgmt_frame(p_mac, 4290 REASON_DEAUTH_NETWORK_LEAVING, 4291 stads->staAddr, session_entry, false); 4292 } 4293 /* Delete TDLS peer */ 4294 qdf_mem_copy(mac_addr.bytes, stads->staAddr, 4295 QDF_MAC_ADDR_SIZE); 4296 4297 status = lim_tdls_del_sta(p_mac, mac_addr, 4298 session_entry, false); 4299 4300 dph_delete_hash_entry(p_mac, 4301 stads->staAddr, stads->assocId, 4302 &session_entry->dph.dphHashTable); 4303 skip: 4304 lim_release_peer_idx(p_mac, 4305 (aid + i * (sizeof(uint32_t) << 3)), 4306 session_entry); 4307 CLEAR_BIT(session_entry->peerAIDBitmap[i], aid); 4308 } 4309 } 4310 } 4311 4312 void lim_update_tdls_set_state_for_fw(struct pe_session *session_entry, 4313 bool value) 4314 { 4315 session_entry->tdls_send_set_state_disable = value; 4316 } 4317 4318 void lim_update_tdls_2g_bw(struct pe_session *session) 4319 { 4320 struct wlan_objmgr_psoc *psoc = NULL; 4321 4322 /* 4323 * For 2.4 GHz band, if AP switches its BW from 40 MHz to 20 Mhz, it 4324 * changes its beacon respectivily with ch_width 20 Mhz without STA 4325 * disconnection. 4326 * This will result in TDLS remaining on 40 MHz and not following APs BW 4327 * on 2.4 GHz. 4328 * Better Teardown the link here and with traffic going on between peers 4329 * the tdls connection will again be restablished with the new BW 4330 */ 4331 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) 4332 return; 4333 4334 psoc = wlan_vdev_get_psoc(session->vdev); 4335 if (!psoc) 4336 return; 4337 4338 wlan_tdls_teardown_links(psoc); 4339 } 4340 4341 /** 4342 * lim_delete_tdls_peers() - delete tdls peers 4343 * 4344 * @mac_ctx - global MAC context 4345 * @session_entry - PE session entry 4346 * 4347 * Delete all the TDLS peer connected before leaving the BSS 4348 * 4349 * Return: QDF_STATUS_SUCCESS on success, error code otherwise 4350 */ 4351 QDF_STATUS lim_delete_tdls_peers(struct mac_context *mac_ctx, 4352 struct pe_session *session_entry) 4353 { 4354 4355 if (!session_entry) { 4356 pe_err("NULL session_entry"); 4357 return QDF_STATUS_E_FAILURE; 4358 } 4359 4360 lim_check_aid_and_delete_peer(mac_ctx, session_entry); 4361 4362 tgt_tdls_delete_all_peers_indication(mac_ctx->psoc, 4363 session_entry->smeSessionId); 4364 4365 if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry)) 4366 return QDF_STATUS_SUCCESS; 4367 4368 /* In case of CSA, Only peers in lim and TDLS component 4369 * needs to be removed and set state disable command 4370 * should not be sent to fw as there is no way to enable 4371 * TDLS in FW after vdev restart. 4372 */ 4373 if (session_entry->tdls_send_set_state_disable) { 4374 tgt_tdls_peers_deleted_notification(mac_ctx->psoc, 4375 session_entry-> 4376 smeSessionId); 4377 } 4378 4379 /* reset the set_state_disable flag */ 4380 session_entry->tdls_send_set_state_disable = true; 4381 return QDF_STATUS_SUCCESS; 4382 } 4383 4384 /** 4385 * lim_process_sme_del_all_tdls_peers(): process delete tdls peers 4386 * @p_mac: pointer to mac context 4387 * @msg_buf: message buffer 4388 * 4389 * This function processes request to delete tdls peers 4390 * 4391 * Return: Success: QDF_STATUS_SUCCESS Failure: Error value 4392 */ 4393 QDF_STATUS lim_process_sme_del_all_tdls_peers(struct mac_context *p_mac, 4394 uint32_t *msg_buf) 4395 { 4396 struct tdls_del_all_tdls_peers *msg; 4397 struct pe_session *session_entry; 4398 uint8_t session_id; 4399 4400 msg = (struct tdls_del_all_tdls_peers *)msg_buf; 4401 if (!msg) { 4402 pe_err("NULL msg"); 4403 return QDF_STATUS_E_FAILURE; 4404 } 4405 4406 session_entry = pe_find_session_by_bssid(p_mac, 4407 msg->bssid.bytes, &session_id); 4408 if (!session_entry) { 4409 pe_debug("NULL pe_session"); 4410 return QDF_STATUS_E_FAILURE; 4411 } 4412 4413 lim_check_aid_and_delete_peer(p_mac, session_entry); 4414 4415 tgt_tdls_peers_deleted_notification(p_mac->psoc, 4416 session_entry->smeSessionId); 4417 4418 return QDF_STATUS_SUCCESS; 4419 } 4420 4421 /** 4422 * lim_process_tdls_del_sta_rsp() - Handle WDA_DELETE_STA_RSP for TDLS 4423 * @mac_ctx: Global MAC context 4424 * @lim_msg: LIM message 4425 * @pe_session: PE session 4426 * 4427 * Return: None 4428 */ 4429 void lim_process_tdls_del_sta_rsp(struct mac_context *mac_ctx, 4430 struct scheduler_msg *lim_msg, 4431 struct pe_session *session_entry) 4432 { 4433 tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr; 4434 tpDphHashNode sta_ds; 4435 uint16_t peer_idx = 0; 4436 struct qdf_mac_addr peer_mac; 4437 4438 if (!del_sta_params) { 4439 pe_err("del_sta_params is NULL"); 4440 return; 4441 } 4442 4443 qdf_mem_copy(peer_mac.bytes, 4444 del_sta_params->staMac, QDF_MAC_ADDR_SIZE); 4445 4446 sta_ds = dph_lookup_hash_entry(mac_ctx, del_sta_params->staMac, 4447 &peer_idx, &session_entry->dph.dphHashTable); 4448 if (!sta_ds) { 4449 pe_err("DPH Entry for STA: %X is missing release the serialization command", 4450 DPH_STA_HASH_INDEX_PEER); 4451 lim_send_sme_tdls_del_sta_rsp(mac_ctx, 4452 session_entry->smeSessionId, 4453 peer_mac, NULL, 4454 QDF_STATUS_SUCCESS); 4455 goto skip_event; 4456 } 4457 4458 if (QDF_STATUS_SUCCESS != del_sta_params->status) { 4459 pe_err("DEL STA failed!"); 4460 lim_send_sme_tdls_del_sta_rsp(mac_ctx, 4461 session_entry->smeSessionId, 4462 peer_mac, NULL, QDF_STATUS_E_FAILURE); 4463 goto skip_event; 4464 } 4465 4466 pe_debug("DEL STA success"); 4467 4468 /* now send indication to SME-->HDD->TL to remove STA from TL */ 4469 4470 lim_send_sme_tdls_del_sta_rsp(mac_ctx, session_entry->smeSessionId, 4471 peer_mac, sta_ds, 4472 QDF_STATUS_SUCCESS); 4473 lim_release_peer_idx(mac_ctx, sta_ds->assocId, session_entry); 4474 4475 /* Clear the aid in peerAIDBitmap as this aid is now in freepool */ 4476 CLEAR_PEER_AID_BITMAP(session_entry->peerAIDBitmap, 4477 sta_ds->assocId); 4478 lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, sta_ds->assocId, 4479 session_entry); 4480 4481 skip_event: 4482 qdf_mem_free(del_sta_params); 4483 lim_msg->bodyptr = NULL; 4484 } 4485 4486 4487 #endif 4488