瀏覽代碼

qcacld-3.0: [11AX] Add support to update HE MCS

Add support to update HE MCS. lim_populate_he_mcs_set() is added to
take care of populating the rates and MCS values.

Change-Id: I12c0ab95cc566c906f1707010dfb2ef3ec4fa681
CRs-Fixed: 1073481
Krishna Kumaar Natarajan 8 年之前
父節點
當前提交
d1cd56e731

+ 38 - 22
core/mac/inc/sir_api.h

@@ -337,37 +337,42 @@ struct rrm_config_param {
 const char *lim_bss_type_to_string(const uint16_t bss_type);
 const char *lim_scan_type_to_string(const uint8_t scan_type);
 
+/**
+ * struct sSirSupportedRates - stores rates/MCS supported
+ * @llbRates: 11b rates in unit of 500kbps
+ * @llaRates: 11a rates in unit of 500kbps
+ * @supportedMCSSet: supported basic MCS, 0-76 bits used, remaining reserved
+ *                    bits 0-15 and 32 should be set.
+ * @rxHighestDataRate: RX Highest Supported Data Rate defines the highest data
+ *                      rate that the STA is able to receive, in unites of 1Mbps
+ *                      This value is derived from "Supported MCS Set field"
+ *                      inside the HT capability element.
+ * @vhtRxMCSMap: Indicates the Maximum MCS(VHT) that can be received for each
+ *                number of spacial streams
+ * @vhtRxHighestDataRate: Indicate the highest VHT data rate that the STA is
+ *                         able to receive
+ * @vhtTxMCSMap: Indicates the Maximum MCS(VHT) that can be transmitted for
+ *                each number of spacial streams
+ * @vhtTxHighestDataRate: Indicate the highest VHT data rate that the STA is
+ *                         able to transmit
+ * @he_rx_mcs: Indicates the Maximum MCS(HE) that can be received for each
+ *              number of spacial streams
+ * @he_tx_mcs: Indicates the Maximum MCS(HE) that can be transmitted for each
+ *              number of spacial streams
+ */
 typedef struct sSirSupportedRates {
-	/*
-	 * 11b, 11a and aniLegacyRates are IE rates which gives rate in unit
-	 * of 500Kbps
-	 */
 	uint16_t llbRates[SIR_NUM_11B_RATES];
 	uint16_t llaRates[SIR_NUM_11A_RATES];
-	/*
-	 * 0-76 bits used, remaining reserved
-	 * bits 0-15 and 32 should be set.
-	 */
 	uint8_t supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET];
-
-	/*
-	 * RX Highest Supported Data Rate defines the highest data
-	 * rate that the STA is able to receive, in unites of 1Mbps.
-	 * This value is derived from "Supported MCS Set field" inside
-	 * the HT capability element.
-	 */
 	uint16_t rxHighestDataRate;
-
-	/*Indicates the Maximum MCS that can be received for each number
-	   of spacial streams */
 	uint16_t vhtRxMCSMap;
-	/*Indicate the highest VHT data rate that the STA is able to receive */
 	uint16_t vhtRxHighestDataRate;
-	/*Indicates the Maximum MCS that can be transmitted for each number
-	   of spacial streams */
 	uint16_t vhtTxMCSMap;
-	/*Indicate the highest VHT data rate that the STA is able to transmit */
 	uint16_t vhtTxHighestDataRate;
+#ifdef WLAN_FEATURE_11AX
+	uint16_t he_rx_mcs;
+	uint16_t he_tx_mcs;
+#endif
 } tSirSupportedRates, *tpSirSupportedRates;
 
 typedef enum eSirRFBand {
@@ -6864,6 +6869,17 @@ struct wow_enable_params {
 
 #define HE_MAX_PHY_CAP_SIZE 3
 
+/*
+ * Three bits are used for each MCS
+ * For SS - 1; bits 0-2
+ * For SS - 2; bits 3-5
+ * MCS values are interpreted as in IEEE 11ax-D1.0 spec
+ */
+#define HE_MCS_1x1 0xFFF8
+#define HE_MCS_2x2 0xFFC7
+
+#define HEMCSSIZE 3
+
 /**
  * struct he_capability - to store 11ax HE capabilities
  * @phy_cap: HE PHY capabilities

+ 17 - 8
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -1536,7 +1536,8 @@ tSirRetStatus
 lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
 		tpSirSupportedRates rates, uint8_t *supported_mcs_set,
 		uint8_t basic_only, tpPESession session_entry,
-		tDot11fIEVHTCaps *vht_caps)
+		struct sDot11fIEVHTCaps *vht_caps,
+		struct sDot11fIEvendor_he_cap *he_caps)
 {
 	tSirMacRateSet temp_rate_set;
 	tSirMacRateSet temp_rate_set2;
@@ -1674,16 +1675,17 @@ lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
 	}
 	lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps,
 			session_entry, session_entry->nss);
+	lim_populate_he_mcs_set(mac_ctx, rates, he_caps,
+			session_entry, session_entry->nss);
 
 	return eSIR_SUCCESS;
 }
 
 tSirRetStatus
 lim_populate_peer_rate_set(tpAniSirGlobal pMac,
-			   tpSirSupportedRates pRates,
-			   uint8_t *pSupportedMCSSet,
-			   uint8_t basicOnly,
-			   tpPESession psessionEntry, tDot11fIEVHTCaps *pVHTCaps)
+		tpSirSupportedRates pRates, uint8_t *pSupportedMCSSet,
+		uint8_t basicOnly, tpPESession psessionEntry,
+		tDot11fIEVHTCaps *pVHTCaps, tDot11fIEvendor_he_cap *he_caps)
 {
 	tSirMacRateSet tempRateSet;
 	tSirMacRateSet tempRateSet2;
@@ -1820,6 +1822,9 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac,
 	}
 	lim_populate_vht_mcs_set(pMac, pRates, pVHTCaps,
 			psessionEntry, psessionEntry->nss);
+	lim_populate_he_mcs_set(pMac, pRates, he_caps,
+			psessionEntry, psessionEntry->nss);
+
 	return eSIR_SUCCESS;
 } /*** lim_populate_peer_rate_set() ***/
 
@@ -1859,7 +1864,8 @@ tSirRetStatus lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx,
 					     tSirMacRateSet *ext_rate_set,
 					     uint8_t *supported_mcs_set,
 					     tpPESession session_entry,
-					     tDot11fIEVHTCaps *vht_caps)
+					     tDot11fIEVHTCaps *vht_caps,
+					     tDot11fIEvendor_he_cap *he_caps)
 {
 	tSirMacRateSet temp_rate_set;
 	tSirMacRateSet temp_rate_set2;
@@ -2048,6 +2054,8 @@ tSirRetStatus lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx,
 	}
 	lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps,
 				 session_entry, session_entry->nss);
+	lim_populate_he_mcs_set(mac_ctx, &sta_ds->supportedRates, he_caps,
+				session_entry, session_entry->nss);
 	/*
 	 * Set the erpEnabled bit if the phy is in G mode and at least
 	 * one A rate is supported
@@ -2737,7 +2745,7 @@ lim_add_sta_self(tpAniSirGlobal pMac, uint16_t staIdx, uint8_t updateSta,
 	}
 
 	lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
-				  psessionEntry, NULL);
+				  psessionEntry, NULL, NULL);
 	if (IS_DOT11_MODE_HT(selfStaDot11Mode)) {
 		pAddStaParams->htCapable = true;
 #ifdef DISABLE_GF_FOR_INTEROP
@@ -4488,7 +4496,8 @@ tSirRetStatus lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t update
 			supportedRates,
 			pBeaconStruct->HTCaps.supportedMCSSet,
 			false, psessionEntry,
-			&pBeaconStruct->VHTCaps);
+			&pBeaconStruct->VHTCaps,
+			&pBeaconStruct->vendor_he_cap);
 
 	pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
 

+ 7 - 7
core/mac/src/pe/lim/lim_assoc_utils.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -67,14 +67,16 @@ tSirRetStatus lim_populate_peer_rate_set(tpAniSirGlobal pMac,
 					 uint8_t *pSupportedMCSSet,
 					 uint8_t basicOnly,
 					 tpPESession psessionEntry,
-					 tDot11fIEVHTCaps * pVHTCaps);
+					 tDot11fIEVHTCaps *pVHTCaps,
+					 tDot11fIEvendor_he_cap *he_caps);
 
 tSirRetStatus lim_populate_own_rate_set(tpAniSirGlobal pMac,
 					tpSirSupportedRates pRates,
 					uint8_t *pSupportedMCSSet,
 					uint8_t basicOnly,
 					tpPESession psessionEntry,
-					tDot11fIEVHTCaps * pVHTCaps);
+					tDot11fIEVHTCaps *pVHTCaps,
+					tDot11fIEvendor_he_cap *he_caps);
 
 tSirRetStatus
 lim_populate_matching_rate_set(tpAniSirGlobal pMac,
@@ -83,10 +85,8 @@ lim_populate_matching_rate_set(tpAniSirGlobal pMac,
 			       tSirMacRateSet *pExtRateSet,
 			       uint8_t *pSupportedMCSSet,
 			       tpPESession psessionEntry,
-			       tDot11fIEVHTCaps * pVHTCaps);
-
-#define MCSMAPMASK1x1 0x3
-#define MCSMAPMASK2x2 0xC
+			       tDot11fIEVHTCaps *pVHTCaps,
+			       tDot11fIEvendor_he_cap *he_caps);
 
 tSirRetStatus lim_add_sta(tpAniSirGlobal, tpDphHashNode, uint8_t, tpPESession);
 tSirRetStatus lim_del_bss(tpAniSirGlobal, tpDphHashNode, uint16_t, tpPESession);

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

@@ -440,7 +440,8 @@ void lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac,
 					   supportedRates,
 					   pBeaconStruct->HTCaps.supportedMCSSet,
 					   false, pftSessionEntry,
-					   &pBeaconStruct->VHTCaps);
+					   &pBeaconStruct->VHTCaps,
+					   &pBeaconStruct->vendor_he_cap);
 	}
 
 	pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower;

+ 2 - 2
core/mac/src/pe/lim/lim_ibss_peer_mgmt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -329,7 +329,7 @@ ibss_sta_rates_update(tpAniSirGlobal pMac,
 	lim_populate_matching_rate_set(pMac, pStaDs, &pPeer->supportedRates,
 				       &pPeer->extendedRates,
 				       pPeer->supportedMCSSet, psessionEntry,
-				       &pPeer->VHTCaps);
+				       &pPeer->VHTCaps, NULL);
 	pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo;
 } /*** end ibss_sta_info_update() ***/
 

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

@@ -1425,7 +1425,9 @@ static bool lim_update_sta_ds(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
 			&(assoc_req->supportedRates),
 			&(assoc_req->extendedRates),
 			assoc_req->HTCaps.supportedMCSSet,
-			session, vht_caps) != eSIR_SUCCESS) {
+			session, vht_caps,
+			&assoc_req->he_cap) != eSIR_SUCCESS)
+	{
 		/* Could not update hash table entry at DPH with rateset */
 		lim_log(mac_ctx, LOGE,
 			FL("Couldn't update hash entry for aid=%d, MacAddr: "

+ 9 - 4
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -154,6 +154,7 @@ void lim_update_assoc_sta_datas(tpAniSirGlobal mac_ctx,
 	uint32_t phy_mode;
 	bool qos_mode;
 	tDot11fIEVHTCaps *vht_caps = NULL;
+	tDot11fIEvendor_he_cap *he_cap = NULL;
 
 	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
 	sta_ds->staType = STA_ENTRY_SELF;
@@ -196,10 +197,17 @@ void lim_update_assoc_sta_datas(tpAniSirGlobal mac_ctx,
 			}
 		}
 	}
+
+	if (IS_DOT11_MODE_HE(session_entry->dot11mode))
+		lim_update_stads_he_caps(sta_ds, assoc_rsp, session_entry);
+
+	if (lim_is_sta_he_capable(sta_ds))
+		he_cap = &assoc_rsp->vendor_he_cap;
+
 	if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates,
 				assoc_rsp->HTCaps.supportedMCSSet,
 				false, session_entry,
-				vht_caps) != eSIR_SUCCESS) {
+				vht_caps, he_cap) != eSIR_SUCCESS) {
 		lim_log(mac_ctx, LOGP,
 			FL("could not get rateset and extended rate set"));
 		return;
@@ -208,9 +216,6 @@ void lim_update_assoc_sta_datas(tpAniSirGlobal mac_ctx,
 		((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
 		 == MCSMAPMASK2x2) ? 1 : 2;
 
-	if (IS_DOT11_MODE_HE(session_entry->dot11mode))
-		lim_update_stads_he_caps(sta_ds, assoc_rsp, session_entry);
-
 	/* If one of the rates is 11g rates, set the ERP mode. */
 	if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
 		sirIsArate(sta_ds->supportedRates.llaRates[0] & 0x7f))

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

@@ -496,7 +496,7 @@ void lim_process_sta_mlm_add_bss_rsp_ft(tpAniSirGlobal pMac,
 	pAddStaParams->shortPreambleSupported =
 		(uint8_t) psessionEntry->beaconParams.fShortPreamble;
 	lim_populate_peer_rate_set(pMac, &pAddStaParams->supportedRates, NULL,
-				   false, psessionEntry, NULL);
+				   false, psessionEntry, NULL, NULL);
 
 	if (psessionEntry->htCapability) {
 		pAddStaParams->htCapable = psessionEntry->htCapability;

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

@@ -455,7 +455,7 @@ static void mlm_add_sta(tpAniSirGlobal mac_ctx, tpAddStaParams sta_param,
 	sta_param->send_smps_action = session_entry->send_smps_action;
 
 	lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
-				  false, session_entry, NULL);
+				  false, session_entry, NULL, NULL);
 
 	lim_log(mac_ctx, LOGE, FL(
 		"GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d,"

+ 100 - 0
core/mac/src/pe/lim/lim_utils.c

@@ -7896,6 +7896,106 @@ QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx, tpPESession session,
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+/**
+ * MCS-NSS Map will be as follows - Each MCS is 3 bits
+ *  - 0 indicates support for HE-MCS 0-7 for n spatial streams
+ *  - 1 indicates support for HE-MCS 0-8 for n spatial streams
+ *  - 2 indicates support for HE-MCS 0-9 for n spatial streams
+ *  - 3 indicates support for HE-MCS 0-10 for n spatial streams
+ *  - 4 indicates support for HE-MCS 0-11 for n spatial streams
+ *  - 5-6 reserved
+ *  - 7 indicates that n spatial streams is not supported
+ * +-----+-----+-----+-----+-----+-----+-----+-----+-----+-
+ * |  SS |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * | MCS |   7 |  7  |  7  |  7  |  7  |  7  |  4  |  4  |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ */
+QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
+				   tpSirSupportedRates rates,
+				   tDot11fIEvendor_he_cap *peer_he_caps,
+				   tpPESession session_entry, uint8_t nss)
+{
+	uint32_t val;
+	uint32_t self_sta_dot11mode = 0;
+	uint8_t self_mcs, peer_mcs, negotiated_mcs;
+	uint32_t mcsmap = 0xFFFFFFFF;
+	bool support_2x2 = false;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
+
+	if (!IS_DOT11_MODE_HE(self_sta_dot11mode))
+		return QDF_STATUS_SUCCESS;
+
+	if (wlan_cfg_get_int(mac_ctx, WNI_CFG_HE_MCS, &val) != eSIR_SUCCESS) {
+		lim_log(mac_ctx, LOGE, FL("could not retrieve HE_MCS"));
+		goto error;
+	}
+
+	self_mcs = (uint16_t) val;
+	if (NSS_1x1_MODE == nss) {
+		/* Add MCS for SS-1 */
+		mcsmap = self_mcs;
+		mcsmap |= HE_MCS_1x1;
+	} else if (NSS_2x2_MODE == nss) {
+		/* Add MCS for SS-1 */
+		mcsmap = self_mcs;
+		/* Add MCS for SS-2 */
+		mcsmap |= (self_mcs << HEMCSSIZE);
+		mcsmap |= HE_MCS_2x2;
+
+	}
+	rates->he_rx_mcs = rates->he_tx_mcs = mcsmap;
+
+	if ((peer_he_caps == NULL) || (!peer_he_caps->present)) {
+		lim_log(mac_ctx, LOG1,
+			FL("self rate: nss %d he_rx_mcs - %x he_tx_mcs - %x"),
+			nss, rates->he_rx_mcs, rates->he_tx_mcs);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	lim_log(mac_ctx, LOG1, FL("peer rates: rx_mcs - %x tx_mcs - %x"),
+		peer_he_caps->mcs_supported, peer_he_caps->mcs_supported);
+
+	if (session_entry && session_entry->nss == NSS_2x2_MODE) {
+		if (mac_ctx->lteCoexAntShare &&
+			IS_24G_CH(session_entry->currentOperChannel)) {
+			if (IS_2X2_CHAIN(session_entry->chainMask))
+				support_2x2 = true;
+			else
+				lim_log(mac_ctx, LOGE, FL("2x2 not enabled %d"),
+					session_entry->chainMask);
+		} else {
+			support_2x2 = true;
+		}
+	}
+
+	peer_mcs = peer_he_caps->mcs_supported;
+	negotiated_mcs = QDF_MIN(peer_mcs, self_mcs);
+
+	if (support_2x2) {
+		/* Add MCS for SS-1 */
+		mcsmap = negotiated_mcs;
+		/* Add MCS for SS-2 */
+		mcsmap |= (negotiated_mcs << HEMCSSIZE);
+		mcsmap |= HE_MCS_2x2;
+	} else {
+		/* Add MCS for SS-1 */
+		mcsmap = negotiated_mcs;
+		mcsmap |= HE_MCS_1x1;
+	}
+	rates->he_rx_mcs = rates->he_tx_mcs = mcsmap;
+
+	lim_log(mac_ctx, LOG1,
+		FL("enable2x2 - %d nss %d he_rx_mcs - %x he_tx_mcs - %x"),
+		mac_ctx->roam.configParam.enable2x2, nss,
+		rates->he_rx_mcs, rates->he_tx_mcs);
+
+	return QDF_STATUS_SUCCESS;
+error:
+	return QDF_STATUS_E_FAILURE;
+}
 #endif
 
 void lim_decrement_pending_mgmt_count(tpAniSirGlobal mac_ctx)

+ 29 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -680,7 +680,11 @@ tSirRetStatus lim_strip_ie(tpAniSirGlobal mac_ctx,
 		uint8_t *oui, uint8_t out_len, uint8_t *extracted_ie,
 		uint32_t eid_max_len);
 
+#define MCSMAPMASK1x1 0x3
+#define MCSMAPMASK2x2 0xC
+
 #ifdef WLAN_FEATURE_11AX
+
 /**
  * lim_intersect_ap_he_caps() - Intersect AP capability with self STA capability
  * @session: pointer to PE session
@@ -891,6 +895,22 @@ void lim_set_he_caps(tpAniSirGlobal mac, tpPESession session,
  */
 QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx, tpPESession session,
 			       uint8_t vdev_id);
+
+/**
+ * lim_populate_he_mcs_set - function to populate HE mcs rate set
+ * @mac_ctx: pointer to global mac structure
+ * @rates: pointer to supported rate set
+ * @peer_vht_caps: pointer to peer HE capabilities
+ * @session_entry: pe session entry
+ *
+ * Populates HE mcs rate set based on peer and self capabilities
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
+		tpSirSupportedRates rates, tDot11fIEvendor_he_cap *peer_he_caps,
+		tpPESession session_entry, uint8_t nss);
+
 #else
 static inline void lim_add_he_cap(tpAddStaParams add_sta_params,
 				  tpSirAssocReq assoc_req)
@@ -940,6 +960,7 @@ static inline void lim_copy_bss_he_cap(tpPESession session,
 				tpSirSmeStartBssReq sme_start_bss_req)
 {
 }
+
 static inline void lim_copy_join_req_he_cap(tpPESession session,
 			tpSirSmeJoinReq sme_join_req)
 {
@@ -1003,6 +1024,14 @@ static inline QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+static inline QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
+				tpSirSupportedRates rates,
+				tDot11fIEvendor_he_cap *peer_he_caps,
+				tpPESession session_entry, uint8_t nss)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 #endif
 
 /**

+ 30 - 5
core/wma/src/wma_he.c

@@ -274,6 +274,7 @@ static void wma_convert_he_cap(tDot11fIEvendor_he_cap *he_cap, uint32_t mac_cap,
 
 	he_cap->nss_supported = nss - 1;
 	he_cap->mcs_supported = mcs;
+
 	/* For Draft 1.0, following fields will be zero */
 	he_cap->tx_bw_bitmap = 0;
 	he_cap->rx_bw_bitmap = 0;
@@ -627,7 +628,7 @@ void wma_update_target_ext_he_cap(tp_wma_handle wma_handle,
 				  struct wma_tgt_cfg *tgt_cfg)
 {
 	tDot11fIEvendor_he_cap *he_cap = &tgt_cfg->he_cap;
-	int i, j = 0, max_mac;
+	int i, j = 0, k, max_mac;
 	uint32_t he_mac;
 	uint32_t he_phy[WMI_MAX_HECAP_PHY_SIZE];
 	uint8_t *he_ppet;
@@ -635,7 +636,7 @@ void wma_update_target_ext_he_cap(tp_wma_handle wma_handle,
 	WMI_MAC_PHY_CAPABILITIES *mac_cap;
 	tDot11fIEvendor_he_cap he_cap_mac0 = {0}, he_cap_mac1 = {0};
 	tDot11fIEvendor_he_cap tmp_he_cap = {0};
-	uint8_t mcs, nss;
+	uint8_t mcs, nss, mcs_temp;
 
 	if (!wma_handle ||
 		(0 == wma_handle->phy_caps.num_hw_modes.num_hw_modes)) {
@@ -662,11 +663,18 @@ void wma_update_target_ext_he_cap(tp_wma_handle wma_handle,
 			qdf_mem_copy(he_phy, mac_cap->he_cap_phy_info_2G,
 				     WMI_MAX_HECAP_PHY_SIZE * 4);
 			he_ppet = (uint8_t *)&mac_cap->he_ppet2G;
-			mcs = mac_cap->he_supp_mcs_2G;
 			nss = (mac_cap->tx_chain_mask_2G >
 				mac_cap->rx_chain_mask_2G) ?
 					mac_cap->tx_chain_mask_2G :
 					mac_cap->rx_chain_mask_2G;
+			mcs = 0;
+			for (k = 1; k < nss; k++) {
+				mcs_temp = WMI_HE_MAX_MCS_4_SS_MASK(
+						mac_cap->he_supp_mcs_2G, k);
+				if (mcs_temp > mcs)
+					mcs = mcs_temp;
+			}
+
 			wma_convert_he_cap(&he_cap_mac0, he_mac, he_phy,
 					   he_ppet, mcs, nss);
 			if (he_cap_mac0.present)
@@ -677,11 +685,17 @@ void wma_update_target_ext_he_cap(tp_wma_handle wma_handle,
 			qdf_mem_copy(he_phy, mac_cap->he_cap_phy_info_5G,
 				     WMI_MAX_HECAP_PHY_SIZE * 4);
 			he_ppet = (uint8_t *)&mac_cap->he_ppet5G;
-			mcs = mac_cap->he_supp_mcs_5G;
 			nss = (mac_cap->tx_chain_mask_5G >
 				mac_cap->rx_chain_mask_5G) ?
 					mac_cap->tx_chain_mask_5G :
 					mac_cap->rx_chain_mask_5G;
+			mcs = 0;
+			for (k = 1; k < nss; k++) {
+				mcs_temp = WMI_HE_MAX_MCS_4_SS_MASK(
+						mac_cap->he_supp_mcs_5G, k);
+				if (mcs_temp > mcs)
+					mcs = mcs_temp;
+			}
 			wma_convert_he_cap(&he_cap_mac1, he_mac, he_phy,
 					   he_ppet, mcs, nss);
 			if (he_cap_mac1.present)
@@ -830,7 +844,7 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
 	tDot11fIEvendor_he_op *he_op = &params->he_op;
 	uint32_t *phy_cap = peer->peer_he_cap_phyinfo;
 	uint32_t mac_cap = 0, he_ops = 0;
-	uint8_t temp;
+	uint8_t temp, i;
 
 	if (params->he_capable)
 		peer->peer_flags |= WMI_PEER_HE;
@@ -912,6 +926,17 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
 	WMI_HECAP_PHY_PWRBOOSTAR_SET(phy_cap, he_cap->power_boost);
 	WMI_HECAP_PHY_4XLTFAND800NSECSGI_SET(phy_cap, he_cap->he_ltf_gi_4x);
 
+	/* until further update in standard */
+	peer->peer_he_mcs_count = WMI_HOST_MAX_HE_RATE_SET;
+	for (i = 0; i < peer->peer_he_mcs_count; i++) {
+		peer->peer_he_rx_mcs_set[i] = params->supportedRates.he_rx_mcs;
+		peer->peer_he_tx_mcs_set[i] = params->supportedRates.he_tx_mcs;
+
+		WMA_LOGD(FL("[HE - MCS Map: %d] rx_mcs: %x, tx_mcs: %x"), i,
+			 peer->peer_he_rx_mcs_set[i],
+			 peer->peer_he_tx_mcs_set[i]);
+	}
+
 	WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color);
 	WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe);
 	WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required);

+ 4 - 0
core/wma/src/wma_mgmt.c

@@ -1231,6 +1231,10 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
 		}
 	}
 
+	WMA_LOGD(FL("rx_max_rate: %d, rx_mcs: %x, tx_max_rate: %d, tx_mcs: %x"),
+		 cmd->rx_max_rate, cmd->rx_mcs_set, cmd->tx_max_rate,
+		 cmd->tx_mcs_set);
+
 	/*
 	 * Limit nss to max number of rf chain supported by target
 	 * Otherwise Fw will crash