qcacld-3.0: Check LDPC based on peer capabilities
Set LDPC if AP sets it in either assoc response or beacon
along with one of the following conditions:
1) nss should be greater than 4
2) channel width should be more than 20 Mhz
3) MCS 10 and 11 bit must be set
Change-Id: If23b119b3bf2d07282e9fc9a3bfbb6baa0887737
CRs-Fixed: 2708333
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h
index 793d0d0..aa2e901 100644
--- a/core/mac/src/pe/lim/lim_assoc_utils.h
+++ b/core/mac/src/pe/lim/lim_assoc_utils.h
@@ -179,7 +179,8 @@
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 0a955f9..7b1c5b7 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 @@
*/
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;
@@ -185,7 +185,8 @@
}
if (IS_DOT11_MODE_HE(session_entry->dot11mode))
- lim_update_stads_he_caps(sta_ds, assoc_rsp, session_entry);
+ lim_update_stads_he_caps(sta_ds, assoc_rsp,
+ session_entry, beacon);
if (lim_is_sta_he_capable(sta_ds))
he_cap = &assoc_rsp->he_cap;
@@ -927,7 +928,7 @@
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 */
@@ -1015,17 +1016,18 @@
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;
if (session_entry->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 b54a706..c9fac73 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 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 @@
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 @@
}
}
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 e57a2fa..f5a20f0 100644
--- a/core/mac/src/pe/lim/lim_reassoc_utils.c
+++ b/core/mac/src/pe/lim/lim_reassoc_utils.c
@@ -163,14 +163,15 @@
*/
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,
@@ -282,9 +283,6 @@
*/
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.
@@ -294,6 +292,9 @@
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 95297ab..e667aa8 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -6809,8 +6809,70 @@
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(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
- struct pe_session *session_entry)
+ struct pe_session *session_entry,
+ tSchBeaconStruct *beacon)
{
tDot11fIEhe_cap *he_cap;
@@ -6820,8 +6882,13 @@
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));
-
}
void lim_update_stads_he_6ghz_op(struct pe_session *session,
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index faad0c0..34afd0d 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -1203,11 +1203,13 @@
* @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(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
@@ -1435,7 +1437,7 @@
}
static inline void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
- struct pe_session *session_entry)
+ struct pe_session *session_entry, tSchBeaconStruct *beacon)
{
return;
}