diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 4826420ba6..ddff4abfc1 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -19730,6 +19730,15 @@ static int wlan_hdd_cfg80211_set_ie(struct hdd_adapter *adapter, eLen + 2); if (status) return status; + } else if (genie[0] == + SIR_MSCS_ELEMENT_EXT_EID) { + hdd_debug("MSCS EXT IE(len %d)", + eLen + 2); + status = wlan_hdd_add_assoc_ie( + adapter, genie - 2, + eLen + 2); + if (status) + return status; } else { hdd_err("UNKNOWN EID: %X", genie[0]); } diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 52413bb66e..f2a10866ef 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5274,6 +5274,9 @@ struct wow_enable_params { #define SET_AUTO_RATE_HE_LTF_VAL(set_val, bit_mask) \ (set_val = (set_val & HE_SGI_MASK) | bit_mask) +#define MSCS_OUI_TYPE "\x58" +#define MSCS_OUI_SIZE 1 + #ifdef WLAN_FEATURE_11AX #define HE_CAP_OUI_TYPE "\x23" #define HE_CAP_OUI_SIZE 1 diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index a7623d4188..78c13525d1 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -218,6 +218,8 @@ /* OWE DH Parameter element https://tools.ietf.org/html/rfc8110 */ #define SIR_DH_PARAMETER_ELEMENT_EXT_EID 32 +#define SIR_MSCS_ELEMENT_EXT_EID 88 + /* OUI and type definition for WPA IE in network byte order */ #define SIR_MAC_WPA_OUI 0x01F25000 #define SIR_MAC_WSC_OUI "\x00\x50\xf2\x04" diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index e946fce9b6..ab8897f759 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -1873,7 +1873,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, void *packet; QDF_STATUS qdf_status; uint16_t add_ie_len, current_len = 0, vendor_ie_len = 0; - uint8_t *add_ie = NULL; + uint8_t *add_ie = NULL, *mscs_ext_ie = NULL; const uint8_t *wps_ie = NULL; uint8_t power_caps = false; uint8_t tx_flag = 0; @@ -1891,6 +1891,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, enum rateid min_rid = RATEID_DEFAULT; uint8_t *mbo_ie = NULL, *adaptive_11r_ie = NULL, *vendor_ies = NULL; uint8_t mbo_ie_len = 0, adaptive_11r_ie_len = 0, rsnx_ie_len = 0; + uint8_t mscs_ext_ie_len = 0; bool bss_mfp_capable; if (!pe_session) { @@ -2228,6 +2229,23 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, } rsnx_ie_len = rsnx_ie[1] + 2; } + /* MSCS ext ie */ + if (wlan_get_ext_ie_ptr_from_ext_id(MSCS_OUI_TYPE, MSCS_OUI_SIZE, + add_ie, add_ie_len)) { + mscs_ext_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2); + if (!mscs_ext_ie) + goto end; + + qdf_status = lim_strip_ie(mac_ctx, add_ie, &add_ie_len, + WLAN_ELEMID_EXTN_ELEM, ONE_BYTE, + MSCS_OUI_TYPE, MSCS_OUI_SIZE, + mscs_ext_ie, WLAN_MAX_IE_LEN); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + pe_err("Failed to strip MSCS ext IE"); + goto end; + } + mscs_ext_ie_len = mscs_ext_ie[1] + 2; + } /* * MBO IE needs to be appendded at the end of the assoc request @@ -2333,7 +2351,8 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, } bytes = payload + sizeof(tSirMacMgmtHdr) + aes_block_size_len + - rsnx_ie_len + mbo_ie_len + adaptive_11r_ie_len + vendor_ie_len; + rsnx_ie_len + mbo_ie_len + adaptive_11r_ie_len + + mscs_ext_ie_len + vendor_ie_len; qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame, (void **)&packet); @@ -2379,6 +2398,12 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, payload = payload + rsnx_ie_len; } + if (mscs_ext_ie && mscs_ext_ie_len) { + qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, + mscs_ext_ie, mscs_ext_ie_len); + payload = payload + mscs_ext_ie_len; + } + /* Copy the vendor IEs to the end of the frame */ qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload, vendor_ies, vendor_ie_len); @@ -2468,6 +2493,7 @@ end: qdf_mem_free(rsnx_ie); qdf_mem_free(vendor_ies); qdf_mem_free(mbo_ie); + qdf_mem_free(mscs_ext_ie); /* Free up buffer allocated for mlm_assoc_req */ qdf_mem_free(adaptive_11r_ie);