diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h index f73313a351..f663ace513 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.h +++ b/core/mac/src/pe/lim/lim_assoc_utils.h @@ -199,7 +199,8 @@ void lim_update_re_assoc_globals(struct mac_context *mac, void lim_update_assoc_sta_datas(struct mac_context *mac, tpDphHashNode sta, tpSirAssocRsp pAssocRsp, - struct pe_session *pe_session); + struct pe_session *pe_session, + tSchBeaconStruct *beacon); /** * lim_sta_add_bss_update_ht_parameter() - function to update ht related diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 01bb5d6116..8378c2f739 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -129,7 +129,7 @@ static void lim_update_stads_htcap(struct mac_context *mac_ctx, */ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry) + struct pe_session *session_entry, tSchBeaconStruct *beacon) { uint32_t phy_mode; bool qos_mode; @@ -186,7 +186,7 @@ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, if (IS_DOT11_MODE_HE(session_entry->dot11mode)) lim_update_stads_he_caps(mac_ctx, sta_ds, assoc_rsp, - session_entry); + session_entry, beacon); if (lim_is_sta_he_capable(sta_ds)) he_cap = &assoc_rsp->he_cap; @@ -928,7 +928,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, lim_is_roam_synch_in_progress(session_entry)) { pe_debug("Sending self sta"); lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, - session_entry); + session_entry, NULL); lim_update_stads_ext_cap(mac_ctx, session_entry, assoc_rsp, sta_ds); /* Store assigned AID for TIM processing */ @@ -1016,16 +1016,17 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, session_entry->smeSessionId, session_entry->nss); - lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, session_entry); /* * Extract the AP capabilities from the beacon that * was received earlier - */ + */ ie_len = lim_get_ielen_from_bss_description( &session_entry->lim_join_req->bssDescription); lim_extract_ap_capabilities(mac_ctx, (uint8_t *)session_entry->lim_join_req->bssDescription.ieFields, ie_len, beacon); + lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, + session_entry, beacon); if (lim_is_session_he_capable(session_entry)) { session_entry->mu_edca_present = assoc_rsp->mu_edca_present; diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c index 9fe39bf01f..e9eb163bbc 100644 --- a/core/mac/src/pe/lim/lim_prop_exts_utils.c +++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c @@ -160,47 +160,6 @@ static void lim_extract_he_op(struct pe_session *session, } } -static bool lim_check_he_80_mcs11_supp(struct pe_session *session, - tSirProbeRespBeacon *beacon_struct) { - uint16_t rx_mcs_map; - uint16_t tx_mcs_map; - rx_mcs_map = beacon_struct->he_cap.rx_he_mcs_map_lt_80; - tx_mcs_map = beacon_struct->he_cap.tx_he_mcs_map_lt_80; - if ((session->nss == NSS_1x1_MODE) && - ((HE_GET_MCS_4_NSS(rx_mcs_map, 1) == HE_MCS_0_11) || - (HE_GET_MCS_4_NSS(tx_mcs_map, 1) == HE_MCS_0_11))) - return true; - - if ((session->nss == NSS_2x2_MODE) && - ((HE_GET_MCS_4_NSS(rx_mcs_map, 2) == HE_MCS_0_11) || - (HE_GET_MCS_4_NSS(tx_mcs_map, 2) == HE_MCS_0_11))) - return true; - - return false; -} - -static void lim_check_he_ldpc_cap(struct pe_session *session, - tSirProbeRespBeacon *beacon_struct) -{ - if (session->he_capable && beacon_struct->he_cap.present) { - if (beacon_struct->he_cap.ldpc_coding) - return; - else if ((session->ch_width == CH_WIDTH_20MHZ) && - !lim_check_he_80_mcs11_supp(session, - beacon_struct)) - return; - session->he_capable = false; - pe_err("LDPC check failed for HE operation"); - if (session->vhtCapability) { - session->dot11mode = MLME_DOT11_MODE_11AC; - pe_debug("Update dot11mode to 11ac"); - } else { - session->dot11mode = MLME_DOT11_MODE_11N; - pe_debug("Update dot11mode to 11N"); - } - } -} - static void lim_check_is_he_mcs_valid(struct pe_session *session, tSirProbeRespBeacon *beacon_struct) { @@ -300,9 +259,6 @@ void lim_update_he_bw_cap_mcs(struct pe_session *session, static inline void lim_extract_he_op(struct pe_session *session, tSirProbeRespBeacon *beacon_struct) {} -static void lim_check_he_ldpc_cap(struct pe_session *session, - tSirProbeRespBeacon *beacon_struct) -{} static void lim_check_is_he_mcs_valid(struct pe_session *session, tSirProbeRespBeacon *beacon_struct) { @@ -565,7 +521,6 @@ void lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, } } lim_check_is_he_mcs_valid(session, beacon_struct); - lim_check_he_ldpc_cap(session, beacon_struct); lim_extract_he_op(session, beacon_struct); lim_update_he_bw_cap_mcs(session, beacon_struct); /* Extract the UAPSD flag from WMM Parameter element */ diff --git a/core/mac/src/pe/lim/lim_reassoc_utils.c b/core/mac/src/pe/lim/lim_reassoc_utils.c index 1be2732e7e..9809474c32 100644 --- a/core/mac/src/pe/lim/lim_reassoc_utils.c +++ b/core/mac/src/pe/lim/lim_reassoc_utils.c @@ -162,14 +162,16 @@ void lim_handle_del_bss_in_re_assoc_context(struct mac_context *mac, */ assocRsp = (tpSirAssocRsp) pe_session->limAssocResponseData; - lim_update_assoc_sta_datas(mac, sta, assocRsp, - pe_session); - lim_update_re_assoc_globals(mac, assocRsp, pe_session); + bss_desc = &pe_session->pLimReAssocReq->bssDescription; lim_extract_ap_capabilities(mac, - (uint8_t *) bss_desc->ieFields, + (uint8_t *)bss_desc->ieFields, lim_get_ielen_from_bss_description(bss_desc), beacon_struct); + + lim_update_assoc_sta_datas(mac, sta, assocRsp, + pe_session, beacon_struct); + lim_update_re_assoc_globals(mac, assocRsp, pe_session); if (mac->lim.gLimProtectionControl != MLME_FORCE_POLICY_PROTECTION_DISABLE) lim_decide_sta_protection_on_assoc(mac, @@ -281,18 +283,14 @@ void lim_handle_add_bss_in_re_assoc_context(struct mac_context *mac, */ assocRsp = (tpSirAssocRsp) pe_session->limAssocResponseData; - lim_update_assoc_sta_datas(mac, sta, assocRsp, - pe_session); - lim_update_re_assoc_globals(mac, assocRsp, pe_session); lim_extract_ap_capabilities(mac, - (uint8_t *) pe_session-> - pLimReAssocReq->bssDescription. - ieFields, - lim_get_ielen_from_bss_description - (&pe_session-> - pLimReAssocReq-> - bssDescription), - pBeaconStruct); + (uint8_t *)pe_session->pLimReAssocReq->bssDescription.ieFields, + lim_get_ielen_from_bss_description + (&pe_session->pLimReAssocReq->bssDescription), + pBeaconStruct); + lim_update_assoc_sta_datas(mac, sta, assocRsp, + pe_session, pBeaconStruct); + lim_update_re_assoc_globals(mac, assocRsp, pe_session); if (mac->lim.gLimProtectionControl != MLME_FORCE_POLICY_PROTECTION_DISABLE) lim_decide_sta_protection_on_assoc(mac, diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index fb85e1bfe8..636492addf 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -6658,9 +6658,69 @@ void lim_update_he_6gop_assoc_resp(struct bss_params *pAddBssParams, pAddBssParams->staContext.ch_width = pAddBssParams->ch_width; } +static bool lim_check_is_bss_greater_than_4_nss_supp(struct pe_session *session, + tDot11fIEhe_cap *he_cap) +{ + uint8_t i; + uint16_t mcs_map; +#define NSS_4 4 +#define NSS_8 8 + + if (!session->he_capable || !he_cap->present) + return false; + mcs_map = he_cap->rx_he_mcs_map_lt_80; + for (i = NSS_4; i < NSS_8; i++) { + if (((mcs_map >> (i * 2)) & 0x3) != 0x3) + return true; + } + + return false; +} + +static bool lim_check_he_80_mcs11_supp(struct pe_session *session, + tDot11fIEhe_cap *he_cap) +{ + uint16_t rx_mcs_map; + uint16_t tx_mcs_map; + rx_mcs_map = he_cap->rx_he_mcs_map_lt_80; + tx_mcs_map = he_cap->tx_he_mcs_map_lt_80; + if ((session->nss == NSS_1x1_MODE) && + ((HE_GET_MCS_4_NSS(rx_mcs_map, 1) == HE_MCS_0_11) || + (HE_GET_MCS_4_NSS(tx_mcs_map, 1) == HE_MCS_0_11))) + return true; + + if ((session->nss == NSS_2x2_MODE) && + ((HE_GET_MCS_4_NSS(rx_mcs_map, 2) == HE_MCS_0_11) || + (HE_GET_MCS_4_NSS(tx_mcs_map, 2) == HE_MCS_0_11))) + return true; + + return false; +} + +/** + * lim_check_he_ldpc_cap() - set he ladpc coding to one if + * channel width is > 20 or mcs 10/11 bit are supported or + * nss is greater than 4. + * @beacon_struct: beacon structure + * @session: A pointer to session entry. + * + * Return: None + */ + +static void lim_check_and_force_he_ldpc_cap(struct pe_session *session, + tDot11fIEhe_cap *he_cap) +{ + if (!he_cap->ldpc_coding && + (session->ch_width > CH_WIDTH_20MHZ || + lim_check_he_80_mcs11_supp(session, he_cap) || + lim_check_is_bss_greater_than_4_nss_supp(session, he_cap))) + he_cap->ldpc_coding = 1; +} + void lim_update_stads_he_caps(struct mac_context *mac_ctx, tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry) + struct pe_session *session_entry, + tSchBeaconStruct *beacon) { tDot11fIEhe_cap *he_cap; @@ -6670,6 +6730,13 @@ void lim_update_stads_he_caps(struct mac_context *mac_ctx, if (!he_cap->present) return; + /* setting lpdc_coding if any of assoc_rsp or beacon has ladpc_coding + * enabled + */ + if (beacon) + he_cap->ldpc_coding |= beacon->he_cap.ldpc_coding; + lim_check_and_force_he_ldpc_cap(session_entry, he_cap); + qdf_mem_copy(&sta_ds->he_config, he_cap, sizeof(*he_cap)); /* If HE is not supported, do not fill sta_ds and return */ diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 96401d1f12..6e3e8aa352 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -1188,12 +1188,14 @@ void lim_log_he_cap(struct mac_context *mac, tDot11fIEhe_cap *he_cap); * @sta_ds: pointer to sta dph hash table entry * @assoc_rsp: pointer to assoc response * @session_entry: pointer to PE session + * @beacon: pointer to beacon * * Return: None */ void lim_update_stads_he_caps(struct mac_context *mac_ctx, tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry); + struct pe_session *session_entry, + tSchBeaconStruct *beacon); /** * lim_update_usr_he_cap() - Update HE capability based on userspace @@ -1425,7 +1427,8 @@ static inline void lim_intersect_sta_he_caps(struct mac_context *mac_ctx, static inline void lim_update_stads_he_caps(struct mac_context *mac_ctx, tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry) + struct pe_session *session_entry, + tSchBeaconStruct *beacon) { return; }