Browse Source

qcacld-3.0: Add Q-Q feature 4K QAM (MCS12/MCS13) support

Add host driver support for MCS 12/13, a Q-Q PHY feature.
The following changes are being introduced as a part of this
 - Advertisement of the MCS 12/13 using the QCN IE
 - Interaction between the Host and the FW regarding the target and
   peer capabilities for the new features introduced.
 - The new data structures and variables to populate and use the feature
   capability
 - Routines to add and parse the IE.

Change-Id: I2b91a271d30b1230ef7bb14ee08d0b9da2706db4
CRs-Fixed: 2610277
Sourav Mohapatra 5 years ago
parent
commit
698d9392c3

+ 2 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -1080,6 +1080,8 @@ static void mlme_init_he_cap_in_cfg(struct wlan_objmgr_psoc *psoc,
 			cfg_get(psoc, CFG_HE_STA_OBSSPD);
 	qdf_mem_zero(he_caps->he_ppet_2g, MLME_HE_PPET_LEN);
 	qdf_mem_zero(he_caps->he_ppet_5g, MLME_HE_PPET_LEN);
+	mlme_cfg->he_caps.he_mcs_12_13_supp_2g = 0;
+	mlme_cfg->he_caps.he_mcs_12_13_supp_5g = 0;
 }
 #else
 static void mlme_init_he_cap_in_cfg(struct wlan_objmgr_psoc *psoc,

+ 2 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -929,6 +929,8 @@ struct wlan_mlme_he_caps {
 	uint8_t enable_ul_mimo;
 	uint8_t enable_ul_ofdm;
 	uint32_t he_sta_obsspd;
+	uint16_t he_mcs_12_13_supp_2g;
+	uint16_t he_mcs_12_13_supp_5g;
 };
 #endif
 

+ 5 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -831,6 +831,11 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc,
 		     HE_MAX_PPET_SIZE);
 
 	mlme_obj->cfg.he_caps.he_cap_orig = mlme_obj->cfg.he_caps.dot11_he_cap;
+	mlme_obj->cfg.he_caps.he_mcs_12_13_supp_2g =
+				wma_cfg->he_mcs_12_13_supp_2g;
+	mlme_obj->cfg.he_caps.he_mcs_12_13_supp_5g =
+				wma_cfg->he_mcs_12_13_supp_5g;
+
 	return status;
 }
 #endif

+ 8 - 1
core/mac/src/cfg/cfgUtil/dot11f.frms

@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2006-2007, 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2006-2007, 2014-2018, 2020 The Linux Foundation.
+ * All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -2617,6 +2618,7 @@ IE TimeAdvertisement (EID_TIME_ADVERTISEMENT)   // 8.4.2.63
 
 const QTI_VERSION_ATTR_ID = 1;
 const QTI_VHT_MCS_10_11_ATTR_ID = 2;
+const QTI_HE_MCS_11_12_ATTR_ID = 9;
 
 IE qcn_ie (EID_VENDOR_SPECIFIC) OUI ( 0x8C, 0xFD, 0xF0, 0x01 )
 {
@@ -2630,6 +2632,11 @@ IE qcn_ie (EID_VENDOR_SPECIFIC) OUI ( 0x8C, 0xFD, 0xF0, 0x01 )
    {
       vht_mcs_10_11_supp, 1;
    }
+
+   OPTIE IE he_mcs13_attr (QTI_HE_MCS_11_12_ATTR_ID)
+   {
+      he_mcs_12_13_supp, 2;
+   }
 }
 
 IE esp_information (EID_EXTN_ID_ELEMENT) OUI ( 0x0B )

+ 42 - 2
core/mac/src/include/dot11f.h

@@ -26,7 +26,7 @@
  *
  *
  * This file was automatically generated by 'framesc'
- * Wed Feb 12 21:00:55 2020 from the following file(s):
+ * Mon Mar 16 12:19:32 2020 from the following file(s):
  *
  * dot11f.frms
  *
@@ -2730,6 +2730,45 @@ uint32_t dot11f_get_packed_ie_R1KH_ID(
 }; /* End extern "C". */
 #endif /* C++ */
 
+/* EID 9 (0x09) */
+typedef struct sDot11fIEhe_mcs13_attr {
+	uint8_t             present;
+	uint16_t            he_mcs_12_13_supp;
+} tDot11fIEhe_mcs13_attr;
+
+#define DOT11F_EID_HE_MCS13_ATTR (9)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HE_MCS13_ATTR_MIN_LEN (2)
+
+#define DOT11F_IE_HE_MCS13_ATTR_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_he_mcs13_attr(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEhe_mcs13_attr*,
+	bool);
+
+uint32_t dot11f_pack_ie_he_mcs13_attr(
+	tpAniSirGlobal,
+	tDot11fIEhe_mcs13_attr *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_he_mcs13_attr(
+	tpAniSirGlobal,
+	tDot11fIEhe_mcs13_attr *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
 /* EID 1 (0x01) */
 typedef struct sDot11fIEversion_attr {
 	uint8_t             present;
@@ -9376,6 +9415,7 @@ typedef struct sDot11fIEqcn_ie {
 	uint8_t                        present;
 	tDot11fIEversion_attr          version_attr;
 	tDot11fIEvht_mcs11_attr        vht_mcs11_attr;
+	tDot11fIEhe_mcs13_attr         he_mcs13_attr;
 } tDot11fIEqcn_ie;
 
 #define DOT11F_EID_QCN_IE (221)
@@ -9383,7 +9423,7 @@ typedef struct sDot11fIEqcn_ie {
 /* N.B. These #defines do *not* include the EID & length */
 #define DOT11F_IE_QCN_IE_MIN_LEN (4)
 
-#define DOT11F_IE_QCN_IE_MAX_LEN (11)
+#define DOT11F_IE_QCN_IE_MAX_LEN (15)
 
 #ifdef __cplusplus
 extern "C" {

+ 1 - 0
core/mac/src/include/dph_global.h

@@ -181,6 +181,7 @@ typedef struct sDphHashNode {
 
 #ifdef WLAN_FEATURE_11AX
 	tDot11fIEhe_cap he_config;
+	uint16_t he_mcs_12_13_map;
 #endif
 	/* Peer operation class, extracted from ASSOC request frame*/
 	tDot11fIESuppOperatingClasses supp_operating_classes;

+ 1 - 0
core/mac/src/include/parser_api.h

@@ -1068,6 +1068,7 @@ populate_dot11f_ext_cap(struct mac_context *mac, bool isVHTEnabled,
 			tDot11fIEExtCap *pDot11f, struct pe_session *pe_session);
 
 void populate_dot11f_qcn_ie(struct mac_context *mac,
+			    struct pe_session *pe_session,
 			    tDot11fIEqcn_ie *qcn_ie,
 			    uint8_t attr_id);
 

+ 15 - 0
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -2015,9 +2015,21 @@ static void lim_update_he_stbc_capable(tpAddStaParams add_sta_params)
 		add_sta_params->stbc_capable =
 			add_sta_params->he_config.rx_stbc_lt_80mhz;
 }
+
+static void lim_update_he_mcs_12_13(tpAddStaParams add_sta_params,
+				    tpDphHashNode sta_ds)
+{
+	if (sta_ds->he_mcs_12_13_map)
+		add_sta_params->he_mcs_12_13_map = sta_ds->he_mcs_12_13_map;
+}
+
 #else
 static void lim_update_he_stbc_capable(tpAddStaParams add_sta_params)
 {}
+
+static void lim_update_he_mcs_12_13(tpAddStaParams add_sta_params,
+				    tpDphHashNode sta_ds)
+{}
 #endif
 
 /**
@@ -2443,6 +2455,7 @@ lim_add_sta(struct mac_context *mac_ctx,
 	}
 
 	lim_update_he_stbc_capable(add_sta_params);
+	lim_update_he_mcs_12_13(add_sta_params, sta_ds);
 
 	msg_q.type = WMA_ADD_STA_REQ;
 	msg_q.reserved = 0;
@@ -3539,6 +3552,8 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp
 						 NULL,
 						 pAssocRsp);
 			lim_update_he_stbc_capable(&pAddBssParams->staContext);
+			lim_update_he_mcs_12_13(&pAddBssParams->staContext,
+						sta);
 		}
 
 		/*

+ 1 - 1
core/mac/src/pe/lim/lim_process_assoc_req_frame.c

@@ -1701,7 +1701,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 				assoc_req->qcn_ie.vht_mcs11_attr.
 				vht_mcs_10_11_supp;
 	}
-	lim_intersect_sta_he_caps(assoc_req, session, sta_ds);
+	lim_intersect_sta_he_caps(mac_ctx, assoc_req, session, sta_ds);
 
 	if (lim_populate_matching_rate_set(mac_ctx, sta_ds,
 			&(assoc_req->supportedRates),

+ 2 - 1
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -186,7 +186,8 @@ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx,
 	}
 
 	if (IS_DOT11_MODE_HE(session_entry->dot11mode))
-		lim_update_stads_he_caps(sta_ds, assoc_rsp, session_entry);
+		lim_update_stads_he_caps(mac_ctx, sta_ds, assoc_rsp,
+					 session_entry);
 
 	if (lim_is_sta_he_capable(sta_ds))
 		he_cap = &assoc_rsp->he_cap;

+ 7 - 5
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -352,10 +352,11 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx,
 	}
 	/* Add qcn_ie only if qcn ie is not present in additional_ie */
 	if (!qcn_ie)
-		populate_dot11f_qcn_ie(mac_ctx, &pr.qcn_ie, QCN_IE_ATTR_ID_ALL);
+		populate_dot11f_qcn_ie(mac_ctx, pesession,
+				       &pr.qcn_ie, QCN_IE_ATTR_ID_ALL);
 	else
-		populate_dot11f_qcn_ie(mac_ctx, &pr.qcn_ie,
-				       QCN_IE_ATTR_ID_VHT_MCS11);
+		populate_dot11f_qcn_ie(mac_ctx, pesession,
+				       &pr.qcn_ie, QCN_IE_ATTR_ID_VHT_MCS11);
 
 	/*
 	 * Extcap IE now support variable length, merge Extcap IE from addn_ie
@@ -1374,7 +1375,7 @@ lim_send_assoc_rsp_mgmt_frame(
 			populate_dot11f_vht_operation(mac_ctx, pe_session,
 					&frm.vendor_vht_ie.VHTOperation);
 			is_vht = true;
-			populate_dot11f_qcn_ie(mac_ctx, &frm.qcn_ie,
+			populate_dot11f_qcn_ie(mac_ctx, pe_session, &frm.qcn_ie,
 					       QCN_IE_ATTR_ID_ALL);
 		}
 		populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
@@ -2088,7 +2089,8 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
 		populate_dot11f_ext_cap(mac_ctx, vht_enabled,
 				&frm->ExtCap, pe_session);
 
-	populate_dot11f_qcn_ie(mac_ctx, &frm->qcn_ie, QCN_IE_ATTR_ID_ALL);
+	populate_dot11f_qcn_ie(mac_ctx, pe_session,
+			       &frm->qcn_ie, QCN_IE_ATTR_ID_ALL);
 
 	if (lim_is_session_he_capable(pe_session)) {
 		pe_debug("Populate HE IEs");

+ 56 - 5
core/mac/src/pe/lim/lim_utils.c

@@ -6601,6 +6601,9 @@ void lim_add_he_cap(struct mac_context *mac_ctx, struct pe_session *pe_session,
 	qdf_mem_copy(&add_sta_params->he_config, &assoc_req->he_cap,
 		     sizeof(add_sta_params->he_config));
 
+	add_sta_params->he_mcs_12_13_map =
+		assoc_req->qcn_ie.he_mcs13_attr.he_mcs_12_13_supp;
+
 	if (lim_is_he_6ghz_band(pe_session))
 		lim_update_he_6ghz_band_caps(mac_ctx,
 					     &assoc_req->he_6ghz_band_cap,
@@ -6686,15 +6689,40 @@ static void lim_intersect_he_caps(tDot11fIEhe_cap *rcvd_he,
 					peer_he->twt_responder : 0;
 }
 
-void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, struct pe_session *session,
-		tpDphHashNode sta_ds)
+void lim_intersect_sta_he_caps(struct mac_context *mac_ctx,
+			       tpSirAssocReq assoc_req,
+			       struct pe_session *session,
+			       tpDphHashNode sta_ds)
 {
 	tDot11fIEhe_cap *rcvd_he = &assoc_req->he_cap;
 	tDot11fIEhe_cap *session_he = &session->he_config;
 	tDot11fIEhe_cap *peer_he = &sta_ds->he_config;
 
-	if (sta_ds->mlmStaContext.he_capable)
-		lim_intersect_he_caps(rcvd_he, session_he, peer_he);
+	if (!sta_ds->mlmStaContext.he_capable)
+		return;
+
+	/* If HE is not supported, do not fill sta_ds and return */
+	if (!IS_DOT11_MODE_HE(session->dot11mode))
+		return;
+
+	lim_intersect_he_caps(rcvd_he, session_he, peer_he);
+
+	/* If MCS 12/13 is supported from assoc QCN IE */
+	if (assoc_req->qcn_ie.present &&
+	    assoc_req->qcn_ie.he_mcs13_attr.present) {
+		sta_ds->he_mcs_12_13_map =
+		      assoc_req->qcn_ie.he_mcs13_attr.he_mcs_12_13_supp;
+	} else {
+		return;
+	}
+
+	/* Take intersection of FW capability for HE MCS 12/13 */
+	if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq))
+		sta_ds->he_mcs_12_13_map &=
+			mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_2g;
+	else
+		sta_ds->he_mcs_12_13_map &=
+			mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_5g;
 }
 
 void lim_intersect_ap_he_caps(struct pe_session *session, struct bss_params *add_bss,
@@ -6756,7 +6784,8 @@ void lim_update_he_6gop_assoc_resp(struct bss_params *pAddBssParams,
 	pAddBssParams->staContext.ch_width = pAddBssParams->ch_width;
 }
 
-void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+void lim_update_stads_he_caps(struct mac_context *mac_ctx,
+			      tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
 			      struct pe_session *session_entry)
 {
 	tDot11fIEhe_cap *he_cap;
@@ -6769,6 +6798,26 @@ void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
 
 	qdf_mem_copy(&sta_ds->he_config, he_cap, sizeof(*he_cap));
 
+	/* If HE is not supported, do not fill sta_ds and return */
+	if (!IS_DOT11_MODE_HE(session_entry->dot11mode))
+		return;
+
+	/* If MCS 12/13 is supported by the assoc resp QCN IE */
+	if (assoc_rsp->qcn_ie.present &&
+	    assoc_rsp->qcn_ie.he_mcs13_attr.present) {
+		sta_ds->he_mcs_12_13_map =
+			assoc_rsp->qcn_ie.he_mcs13_attr.he_mcs_12_13_supp;
+	} else {
+		return;
+	}
+
+	/* Take intersection of the FW capability for HE MCS 12/13 */
+	if (wlan_reg_is_24ghz_ch_freq(session_entry->curr_op_freq))
+		sta_ds->he_mcs_12_13_map &=
+			mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_2g;
+	else
+		sta_ds->he_mcs_12_13_map &=
+			mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_5g;
 }
 
 void lim_update_stads_he_6ghz_op(struct pe_session *session,
@@ -7096,6 +7145,7 @@ void lim_update_sta_he_capable(struct mac_context *mac,
 	else
 		add_sta_params->he_capable = session_entry->he_capable;
 
+	add_sta_params->he_mcs_12_13_map = sta_ds->he_mcs_12_13_map;
 	pe_debug("he_capable: %d", add_sta_params->he_capable);
 }
 
@@ -7430,6 +7480,7 @@ QDF_STATUS lim_populate_he_mcs_set(struct mac_context *mac_ctx,
 		peer_he_caps->tx_he_mcs_map_lt_80, nss,
 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80,
 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80);
+
 	if (session_entry->ch_width == CH_WIDTH_160MHZ) {
 		lim_populate_he_mcs_per_bw(
 			mac_ctx, &rates->rx_he_mcs_map_160,

+ 16 - 7
core/mac/src/pe/lim/lim_utils.h

@@ -1059,14 +1059,17 @@ void lim_intersect_ap_he_caps(struct pe_session *session, struct bss_params *add
 
 /**
  * lim_intersect_sta_he_caps() - Intersect STA capability with SAP capability
+ * @mac_ctx: pointer to the MAC context
  * @assoc_req: pointer to assoc request
  * @session: pointer to PE session
  * @sta_ds: pointer to STA dph hash table entry
  *
  * Return: None
  */
-void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, struct pe_session *session,
-		tpDphHashNode sta_ds);
+void lim_intersect_sta_he_caps(struct mac_context *mac_ctx,
+			       tpSirAssocReq assoc_req,
+			       struct pe_session *session,
+			       tpDphHashNode sta_ds);
 
 /**
  * lim_add_he_cap() - Copy HE capability into Add sta params
@@ -1193,13 +1196,15 @@ void lim_log_he_cap(struct mac_context *mac, tDot11fIEhe_cap *he_cap);
 
 /**
  * lim_update_stads_he_caps() - Copy HE capability into STA DPH hash table entry
+ * @mac_ctx: pointer to mac context
  * @sta_ds: pointer to sta dph hash table entry
  * @assoc_rsp: pointer to assoc response
  * @session_entry: pointer to PE session
  *
  * Return: None
  */
-void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+void lim_update_stads_he_caps(struct mac_context *mac_ctx,
+			      tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
 			      struct pe_session *session_entry);
 
 /**
@@ -1420,13 +1425,17 @@ static inline void lim_intersect_ap_he_caps(struct pe_session *session,
 	return;
 }
 
-static inline void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req,
-		struct pe_session *session, tpDphHashNode sta_ds)
+static inline void lim_intersect_sta_he_caps(struct mac_context *mac_ctx,
+					     tpSirAssocReq assoc_req,
+					     struct pe_session *session,
+					     tpDphHashNode sta_ds)
 {
 }
 
-static inline void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
-		struct pe_session *session_entry)
+static inline void lim_update_stads_he_caps(struct mac_context *mac_ctx,
+					    tpDphHashNode sta_ds,
+					    tpSirAssocRsp assoc_rsp,
+					    struct pe_session *session_entry)
 {
 	return;
 }

+ 1 - 1
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -467,7 +467,7 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 						 &bcn_2->vht_transmit_power_env,
 						 session->ch_width,
 						 session->curr_op_freq);
-		populate_dot11f_qcn_ie(mac_ctx, &bcn_2->qcn_ie,
+		populate_dot11f_qcn_ie(mac_ctx, session, &bcn_2->qcn_ie,
 				       QCN_IE_ATTR_ID_ALL);
 	}
 

File diff suppressed because it is too large
+ 133 - 109
core/mac/src/sys/legacy/src/utils/src/dot11f.c


+ 33 - 2
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -1225,7 +1225,36 @@ populate_dot11f_ext_cap(struct mac_context *mac,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef WLAN_FEATURE_11AX
+static void populate_dot11f_qcn_ie_he_params(struct mac_context *mac,
+					     struct pe_session *pe_session,
+					     tDot11fIEqcn_ie *qcn_ie,
+					     uint8_t attr_id)
+{
+	uint16_t mcs_12_13_supp;
+
+	if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq))
+		mcs_12_13_supp = mac->mlme_cfg->he_caps.he_mcs_12_13_supp_2g;
+	else
+		mcs_12_13_supp = mac->mlme_cfg->he_caps.he_mcs_12_13_supp_5g;
+
+	if (!mcs_12_13_supp)
+		return;
+
+	qcn_ie->present = 1;
+	qcn_ie->he_mcs13_attr.present = 1;
+	qcn_ie->he_mcs13_attr.he_mcs_12_13_supp = mcs_12_13_supp;
+}
+#else /* WLAN_FEATURE_11AX */
+static void populate_dot11f_qcn_ie_he_params(struct mac_context *mac,
+					     struct pe_session *pe_session,
+					     tDot11fIEqcn_ie *qcn_ie,
+					     uint8_t attr_id)
+{}
+#endif /* WLAN_FEATURE_11AX */
+
 void populate_dot11f_qcn_ie(struct mac_context *mac,
+			    struct pe_session *pe_session,
 			    tDot11fIEqcn_ie *qcn_ie,
 			    uint8_t attr_id)
 {
@@ -1243,6 +1272,8 @@ void populate_dot11f_qcn_ie(struct mac_context *mac,
 		qcn_ie->vht_mcs11_attr.present = 1;
 		qcn_ie->vht_mcs11_attr.vht_mcs_10_11_supp = 1;
 	}
+
+	populate_dot11f_qcn_ie_he_params(mac, pe_session, qcn_ie, attr_id);
 }
 
 QDF_STATUS
@@ -6228,8 +6259,8 @@ populate_dot11f_he_bss_color_change(struct mac_context *mac_ctx,
 
 	return QDF_STATUS_SUCCESS;
 }
-#endif
-#endif
+#endif /* WLAN_FEATURE_11AX_BSS_COLOR */
+#endif /* WLAN_FEATURE_11AX */
 
 #ifdef WLAN_SUPPORT_TWT
 QDF_STATUS populate_dot11f_twt_extended_caps(struct mac_context *mac_ctx,

+ 7 - 0
core/wma/inc/wma_he.h

@@ -23,6 +23,13 @@
 #include "sir_api.h"
 #include "target_if.h"
 
+/* Number of bits to shift on HE MCS 12 13 MAP to get the desired map */
+#define WMA_MCS_12_13_MAP_L80 16
+#define WMA_MCS_12_13_MAP_G80 8
+
+/* Mask to fill tx and rx mcs rate maps to be sent to the FW */
+#define WMA_MCS_12_13_PEER_RATE_MAP 0x00ff0000
+
 #ifdef WLAN_FEATURE_11AX
 /**
  * wma_print_he_cap() - Print HE capabilities

+ 1 - 0
core/wma/inc/wma_if.h

@@ -244,6 +244,7 @@ typedef struct {
 	tDot11fIEhe_cap he_config;
 	tDot11fIEhe_op he_op;
 	tDot11fIEhe_6ghz_band_cap he_6ghz_band_caps;
+	uint16_t he_mcs_12_13_map;
 #endif
 	uint8_t stbc_capable;
 #ifdef WLAN_SUPPORT_TWT

+ 2 - 0
core/wma/inc/wma_tgt_cfg.h

@@ -206,6 +206,8 @@ struct wma_tgt_cfg {
 	uint8_t ppet_5g[HE_MAX_PPET_SIZE];
 	tDot11fIEhe_cap he_cap_2g;
 	tDot11fIEhe_cap he_cap_5g;
+	uint16_t he_mcs_12_13_supp_2g;
+	uint16_t he_mcs_12_13_supp_5g;
 #endif
 	bool dfs_cac_offload;
 	bool tx_bfee_8ss_enabled;

+ 43 - 7
core/wma/src/wma_he.c

@@ -162,6 +162,7 @@ static void wma_convert_he_ppet(uint8_t *he_ppet,
  * @supp_mcs: Max MCS supported (Tx/Rx)
  * @tx_chain_mask: Tx chain mask
  * @rx_chain_mask: Rx chain mask
+ * @mcs_12_13_support: Store the supported MCS 12/13 capability
  *
  * This function converts various HE capability received as part of extended
  * service ready event into dot11f structure. GET macros are defined at WMI
@@ -171,7 +172,8 @@ static void wma_convert_he_ppet(uint8_t *he_ppet,
  */
 static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t *mac_cap,
 			       uint32_t *phy_cap, uint32_t supp_mcs,
-			       uint32_t tx_chain_mask, uint32_t rx_chain_mask)
+			       uint32_t tx_chain_mask, uint32_t rx_chain_mask,
+			       uint16_t *mcs_12_13_supp)
 {
 	uint8_t nss, chan_width;
 	uint16_t rx_mcs_le_80, tx_mcs_le_80, rx_mcs_160, tx_mcs_160;
@@ -227,6 +229,7 @@ static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t *mac_cap,
 		WMI_HECAP_MAC_PUNCSOUNDING_GET(mac_cap[1]);
 	he_cap->ht_vht_trg_frm_rx_supp =
 		WMI_HECAP_MAC_HTVHTTRIGRX_GET(mac_cap[1]);
+	*mcs_12_13_supp = WMI_GET_BITS(mac_cap[1], 16, 16);
 	/* HE PHY capabilities */
 	chan_width = WMI_HECAP_PHY_CBW_GET(phy_cap);
 	he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(chan_width, 0);
@@ -932,7 +935,8 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl,
 					mac_cap->he_cap_phy_info_2G,
 					mac_cap->he_supp_mcs_2G,
 					mac_cap->tx_chain_mask_2G,
-					mac_cap->rx_chain_mask_2G);
+					mac_cap->rx_chain_mask_2G,
+					&tgt_cfg->he_mcs_12_13_supp_2g);
 			WMA_LOGD(FL("2g phy: nss: %d, ru_idx_msk: %d"),
 					mac_cap->he_ppet2G.numss_m1,
 					mac_cap->he_ppet2G.ru_bit_mask);
@@ -958,7 +962,8 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl,
 					mac_cap->he_cap_phy_info_5G,
 					mac_cap->he_supp_mcs_5G,
 					mac_cap->tx_chain_mask_5G,
-					mac_cap->rx_chain_mask_5G);
+					mac_cap->rx_chain_mask_5G,
+					&tgt_cfg->he_mcs_12_13_supp_5g);
 			WMA_LOGD(FL("5g phy: nss: %d, ru_idx_msk: %d"),
 					mac_cap->he_ppet5G.numss_m1,
 					mac_cap->he_ppet5G.ru_bit_mask);
@@ -1251,19 +1256,50 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
 		params->supportedRates.rx_he_mcs_map_lt_80;
 	peer->peer_he_tx_mcs_set[0] =
 		params->supportedRates.tx_he_mcs_map_lt_80;
+	if (params->he_mcs_12_13_map) {
+		peer->peer_he_tx_mcs_set[0] |=
+			(params->he_mcs_12_13_map <<
+			 WMA_MCS_12_13_MAP_L80) & WMA_MCS_12_13_PEER_RATE_MAP;
+		peer->peer_he_rx_mcs_set[0] |=
+			(params->he_mcs_12_13_map <<
+			 WMA_MCS_12_13_MAP_L80) & WMA_MCS_12_13_PEER_RATE_MAP;
+	}
 
 	if (params->ch_width > CH_WIDTH_80MHZ) {
 		peer->peer_he_mcs_count = WMI_HOST_MAX_HE_RATE_SET;
-		peer->peer_he_rx_mcs_set[1] =
+		peer->peer_he_rx_mcs_set[1] |=
 			params->supportedRates.rx_he_mcs_map_160;
-		peer->peer_he_tx_mcs_set[1] =
+		peer->peer_he_tx_mcs_set[1] |=
 			params->supportedRates.tx_he_mcs_map_160;
-		peer->peer_he_rx_mcs_set[2] =
+		peer->peer_he_rx_mcs_set[2] |=
 			params->supportedRates.rx_he_mcs_map_80_80;
-		peer->peer_he_tx_mcs_set[2] =
+		peer->peer_he_tx_mcs_set[2] |=
 			params->supportedRates.tx_he_mcs_map_80_80;
+
+		if (params->he_mcs_12_13_map) {
+			peer->peer_he_tx_mcs_set[1] |=
+				(params->he_mcs_12_13_map <<
+				 WMA_MCS_12_13_MAP_G80) &
+				 WMA_MCS_12_13_PEER_RATE_MAP;
+			peer->peer_he_tx_mcs_set[2] |=
+				(params->he_mcs_12_13_map <<
+				 WMA_MCS_12_13_MAP_G80) &
+				 WMA_MCS_12_13_PEER_RATE_MAP;
+			peer->peer_he_rx_mcs_set[1] |=
+				(params->he_mcs_12_13_map <<
+				 WMA_MCS_12_13_MAP_G80) &
+				 WMA_MCS_12_13_PEER_RATE_MAP;
+			peer->peer_he_rx_mcs_set[2] |=
+				(params->he_mcs_12_13_map <<
+				 WMA_MCS_12_13_MAP_G80) &
+				 WMA_MCS_12_13_PEER_RATE_MAP;
+		}
 	}
 
+	wma_debug("Sending TX/RX MCS set to FW: <=80: %x, 80+80: %x, 160: %x",
+		  peer->peer_he_rx_mcs_set[0], peer->peer_he_rx_mcs_set[1],
+		  peer->peer_he_rx_mcs_set[2]);
+
 #define HE2x2MCSMASK 0xc
 
 	peer->peer_nss = ((params->supportedRates.rx_he_mcs_map_lt_80 &

Some files were not shown because too many files changed in this diff