qcacld-3.0: Add support to process MU EDCA param set

Add support to process MU EDCA param set in assoc response
frames and send the params to FW.

Change-Id: Ia492d1212b3c357647a89e4f98d3cfdc7ff7bbac
CRs-Fixed: 2220227
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 4ce9b45..c5eaa6a 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -1166,7 +1166,10 @@
 typedef struct sSirMacEdcaParamRecord {
 	tSirMacAciAifsn aci;
 	tSirMacCW cw;
-	uint16_t txoplimit;
+	union {
+		uint16_t txoplimit;
+		uint16_t mu_edca_timer;
+	};
 	uint8_t no_ack;
 } qdf_packed tSirMacEdcaParamRecord;
 
diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms
index b17f8b1..a5bc974 100644
--- a/core/mac/src/cfg/cfgUtil/dot11f.frms
+++ b/core/mac/src/cfg/cfgUtil/dot11f.frms
@@ -2959,7 +2959,7 @@
     };
 }
 
-IE mu_edca_param_set (EID_VENDOR_SPECIFIC) OUI (0x00, 0x13, 0x74, 0x04)
+IE mu_edca_param_set (EID_EXTN_ID_ELEMENT) OUI (0x26)
 {
     qos, 1;
     {
diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h
index 60f3e19..151190d 100644
--- a/core/mac/src/include/dot11f.h
+++ b/core/mac/src/include/dot11f.h
@@ -35,7 +35,7 @@
  *
  *
  * This file was automatically generated by 'framesc'
- * Fri Feb 16 12:30:33 2018 from the following file(s):
+ * Wed Feb 21 17:16:54 2018 from the following file(s):
  *
  * dot11f.frms
  *
@@ -9046,7 +9046,7 @@
 }; /* End extern "C". */
 #endif /* C++ */
 
-/* EID 221 (0xdd) {OUI 0x00, 0x13, 0x74, 0x04} */
+/* EID 255 (0xff) Extended EID 38 (0x26) */
 typedef struct sDot11fIEmu_edca_param_set {
 	uint8_t             present;
 	uint8_t             qos;
@@ -9080,12 +9080,12 @@
 	uint8_t             acvo_muedca_timer;
 } tDot11fIEmu_edca_param_set;
 
-#define DOT11F_EID_MU_EDCA_PARAM_SET (221)
+#define DOT11F_EID_MU_EDCA_PARAM_SET (255)
 
 /* N.B. These #defines do *not* include the EID & length */
-#define DOT11F_IE_MU_EDCA_PARAM_SET_MIN_LEN (17)
+#define DOT11F_IE_MU_EDCA_PARAM_SET_MIN_LEN (13)
 
-#define DOT11F_IE_MU_EDCA_PARAM_SET_MAX_LEN (17)
+#define DOT11F_IE_MU_EDCA_PARAM_SET_MAX_LEN (13)
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h
index 3e1d71b..95a9028 100644
--- a/core/mac/src/include/parser_api.h
+++ b/core/mac/src/include/parser_api.h
@@ -422,6 +422,8 @@
 	tSirQCNIE QCN_IE;
 	tDot11fIEhe_cap he_cap;
 	tDot11fIEhe_op he_op;
+	bool mu_edca_present;
+	tSirMacEdcaParamSetIE mu_edca;
 #ifdef WLAN_FEATURE_FILS_SK
 	tDot11fIEfils_session fils_session;
 	tDot11fIEfils_key_confirmation fils_key_auth;
diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c
index e367fe9..bae3e44 100644
--- a/core/mac/src/pe/lim/lim_ft.c
+++ b/core/mac/src/pe/lim/lim_ft.c
@@ -1050,7 +1050,7 @@
 
 				lim_send_edca_params(pMac,
 					     psessionEntry->gLimEdcaParamsActive,
-					     pSta->bssId);
+					     pSta->bssId, false);
 
 			if (eSIR_SUCCESS !=
 			    lim_tspec_add(pMac, pSta->staAddr, pSta->assocId,
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index 3a1a691..6c50058 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -854,7 +854,7 @@
 				   &session->dph.dphHashTable);
 	if (sta_ds_ptr != NULL)
 		lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
-				     sta_ds_ptr->bssId);
+				     sta_ds_ptr->bssId, false);
 	else
 		pe_err("Self entry missing in Hash Table");
 	sir_copy_mac_addr(peer_macaddr, session->bssId);
@@ -1060,7 +1060,7 @@
 				   &session->dph.dphHashTable);
 	if (sta_ds_ptr != NULL)
 		lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
-				     sta_ds_ptr->bssId);
+				     sta_ds_ptr->bssId, false);
 	else
 		pe_err("Self entry missing in Hash Table");
 
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 3492047..15fe3b8 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -517,6 +517,7 @@
 	uint8_t sme_sessionid = 0;
 	struct csr_roam_session *roam_session;
 #endif
+	tSirMacEdcaParamRecord mu_edca_set[MAX_NUM_AC];
 
 	/* Initialize status code to success. */
 	if (lim_is_roam_synch_in_progress(session_entry))
@@ -923,7 +924,7 @@
 			if (!lim_is_roam_synch_in_progress(session_entry)) {
 				lim_send_edca_params(mac_ctx,
 					session_entry->gLimEdcaParamsActive,
-					sta_ds->bssId);
+					sta_ds->bssId, false);
 				lim_add_ft_sta_self(mac_ctx,
 					(assoc_rsp->aid & 0x3FFF),
 					session_entry);
@@ -1003,6 +1004,18 @@
 		ie_len,
 		beacon);
 
+	if (lim_is_session_he_capable(session_entry) &&
+			assoc_rsp->mu_edca_present) {
+		pe_debug("Send MU EDCA params to FW");
+		mu_edca_set[EDCA_AC_BE] = assoc_rsp->mu_edca.acbe;
+		mu_edca_set[EDCA_AC_BK] = assoc_rsp->mu_edca.acbk;
+		mu_edca_set[EDCA_AC_VI] = assoc_rsp->mu_edca.acvi;
+		mu_edca_set[EDCA_AC_VO] = assoc_rsp->mu_edca.acvo;
+		lim_send_edca_params(mac_ctx, mu_edca_set,
+				sta_ds->bssId, true);
+
+	}
+
 	if (beacon->VHTCaps.present)
 		sta_ds->parsed_ies.vht_caps = beacon->VHTCaps;
 	if (beacon->HTCaps.present)
diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
index 72dab9b..5f4e9fd 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -2519,7 +2519,7 @@
 				session_entry->gLimEdcaParams, session_entry);
 			lim_send_edca_params(mac_ctx,
 				session_entry->gLimEdcaParamsActive,
-				sta_ds->bssId);
+				sta_ds->bssId, false);
 			rrm_cache_mgmt_tx_power(mac_ctx,
 				add_bss_params->txMgmtPower, session_entry);
 			if (lim_add_sta_self(mac_ctx, sta_idx, update_sta,
diff --git a/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
index 83f9a64..f0eaf5c 100644
--- a/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
+++ b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -281,10 +281,9 @@
 						session_entry->
 						gLimEdcaParams,
 						session_entry);
-					lim_send_edca_params(mac_ctx,
-					session_entry->
-					gLimEdcaParamsActive,
-					sta_ds->bssId);
+				lim_send_edca_params(mac_ctx,
+					session_entry->gLimEdcaParamsActive,
+					sta_ds->bssId, false);
 			} else {
 				pe_err("SelfEntry missing in Hash");
 			}
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 36de901..8ccba3c 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -3416,7 +3416,7 @@
 				   &psessionEntry->dph.dphHashTable);
 	if (pStaDs != NULL) {
 		lim_send_edca_params(pMac, psessionEntry->gLimEdcaParamsActive,
-				     pStaDs->bssId);
+				     pStaDs->bssId, false);
 		status = eSIR_SUCCESS;
 	} else {
 		pe_err("Self entry missing in Hash Table");
@@ -3575,7 +3575,7 @@
 	if (sta_ds_ptr)
 		lim_send_edca_params(mac_ctx,
 				     pe_session->gLimEdcaParamsActive,
-				     sta_ds_ptr->bssId);
+				     sta_ds_ptr->bssId, false);
 	else
 		pe_err("Self entry missing in Hash Table");
 }
diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c
index cc73e62..1bf3b08 100644
--- a/core/mac/src/pe/lim/lim_send_messages.c
+++ b/core/mac/src/pe/lim/lim_send_messages.c
@@ -293,12 +293,11 @@
  */
 tSirRetStatus lim_send_edca_params(tpAniSirGlobal pMac,
 				   tSirMacEdcaParamRecord *pUpdatedEdcaParams,
-				   uint16_t bssIdx)
+				   uint16_t bssIdx, bool mu_edca)
 {
 	tEdcaParams *pEdcaParams = NULL;
 	tSirRetStatus retCode = eSIR_SUCCESS;
 	struct scheduler_msg msgQ = {0};
-	uint8_t i;
 
 	pEdcaParams = qdf_mem_malloc(sizeof(tEdcaParams));
 	if (NULL == pEdcaParams) {
@@ -311,19 +310,12 @@
 	pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK];
 	pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI];
 	pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO];
+	pEdcaParams->mu_edca_params = mu_edca;
 	msgQ.type = WMA_UPDATE_EDCA_PROFILE_IND;
 	msgQ.reserved = 0;
 	msgQ.bodyptr = pEdcaParams;
 	msgQ.bodyval = 0;
-	pe_debug("Sending WMA_UPDATE_EDCA_PROFILE_IND, EDCA Parameters:");
-	for (i = 0; i < MAX_NUM_AC; i++) {
-		pe_debug("AC[%d]:  AIFSN %d, ACM %d, CWmin %d, CWmax %d, TxOp %d ",
-		       i, pUpdatedEdcaParams[i].aci.aifsn,
-		       pUpdatedEdcaParams[i].aci.acm,
-		       pUpdatedEdcaParams[i].cw.min,
-		       pUpdatedEdcaParams[i].cw.max,
-		       pUpdatedEdcaParams[i].txoplimit);
-	}
+	pe_debug("Sending WMA_UPDATE_EDCA_PROFILE_IND");
 	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
 	retCode = wma_post_ctrl_msg(pMac, &msgQ);
 	if (eSIR_SUCCESS != retCode) {
diff --git a/core/mac/src/pe/lim/lim_send_messages.h b/core/mac/src/pe/lim/lim_send_messages.h
index 58c1550..0d8ce98 100644
--- a/core/mac/src/pe/lim/lim_send_messages.h
+++ b/core/mac/src/pe/lim/lim_send_messages.h
@@ -76,7 +76,7 @@
 
 tSirRetStatus lim_send_edca_params(tpAniSirGlobal pMac,
 				   tSirMacEdcaParamRecord *pUpdatedEdcaParams,
-				   uint16_t bssIdx);
+				   uint16_t bssIdx, bool mu_edca);
 tSirRetStatus lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
 				 tSirMacAddr bssId, tSirMacAddr selfMac,
 				 tpSetLinkStateCallback callback,
diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c
index 0210d35..b04a752 100644
--- a/core/mac/src/pe/sch/sch_beacon_process.c
+++ b/core/mac/src/pe/sch/sch_beacon_process.c
@@ -447,7 +447,7 @@
 					session->gLimEdcaParams, session);
 				lim_send_edca_params(mac_ctx,
 					session->gLimEdcaParamsActive,
-					pStaDs->bssId);
+					pStaDs->bssId, false);
 			} else {
 				pe_err("Self Entry missing in Hash Table");
 			}
diff --git a/core/mac/src/pe/sch/sch_message.c b/core/mac/src/pe/sch/sch_message.c
index 8d5578d..48e48cd 100644
--- a/core/mac/src/pe/sch/sch_message.c
+++ b/core/mac/src/pe/sch/sch_message.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -436,7 +436,7 @@
 
 	/* For AP, the bssID is stored in LIM Global context. */
 	lim_send_edca_params(pMac, psessionEntry->gLimEdcaParams,
-			     psessionEntry->bssIdx);
+			     psessionEntry->bssIdx, false);
 }
 
 /** ----------------------------------------------------------
diff --git a/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h b/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
index 3b63a0d..c7749e5 100644
--- a/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
+++ b/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -75,6 +75,9 @@
 void convert_erp_info(tpAniSirGlobal, tSirMacErpInfo *, tDot11fIEERPInfo *);
 void convert_edca_param(tpAniSirGlobal, tSirMacEdcaParamSetIE *,
 			tDot11fIEEDCAParamSet *);
+void convert_mu_edca_param(tpAniSirGlobal mac_ctx,
+			tSirMacEdcaParamSetIE *mu_edca,
+			tDot11fIEmu_edca_param_set *ie);
 void convert_tspec(tpAniSirGlobal, tSirMacTspecIE *, tDot11fIETSPEC *);
 tSirRetStatus convert_tclas(tpAniSirGlobal, tSirTclasInfo *, tDot11fIETCLAS *);
 void convert_wmmtspec(tpAniSirGlobal, tSirMacTspecIE *, tDot11fIEWMMTSPEC *);
diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
index 7091f91..519758f 100644
--- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c
+++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
@@ -33,7 +33,7 @@
  *
  *
  * This file was automatically generated by 'framesc'
- * Fri Feb 16 12:30:33 2018 from the following file(s):
+ * Wed Feb 21 17:16:54 2018 from the following file(s):
  *
  * dot11f.frms
  *
@@ -7526,8 +7526,8 @@
 	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
 	{ offsetof(tDot11fAssocResponse, mu_edca_param_set),
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
-	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
-	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
 	{ offsetof(tDot11fAssocResponse, MBO_IE), offsetof(tDot11fIEMBO_IE,
 	present), 0, "MBO_IE", 0, 6, 295, SigIeMBO_IE, {80, 111, 154, 22, 0},
 	4, DOT11F_EID_MBO_IE, 0, 0, },
@@ -7819,8 +7819,8 @@
 	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
 	{ offsetof(tDot11fBeacon, mu_edca_param_set),
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
-	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
-	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
 	{ offsetof(tDot11fBeacon, esp_information),
 	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
 	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
@@ -8045,8 +8045,8 @@
 	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
 	{ offsetof(tDot11fBeacon2, mu_edca_param_set),
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
-	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
-	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
 	{ offsetof(tDot11fBeacon2, esp_information),
 	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
 	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
@@ -8271,8 +8271,8 @@
 	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
 	{ offsetof(tDot11fBeaconIEs, mu_edca_param_set),
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
-	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
-	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
 	{ offsetof(tDot11fBeaconIEs, esp_information),
 	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
 	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
@@ -8916,8 +8916,8 @@
 	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
 	{ offsetof(tDot11fProbeResponse, mu_edca_param_set),
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
-	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
-	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
 	{ offsetof(tDot11fProbeResponse, esp_information),
 	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
 	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
@@ -9315,8 +9315,8 @@
 	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
 	{ offsetof(tDot11fReAssocResponse, mu_edca_param_set),
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
-	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
-	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
 	{ offsetof(tDot11fReAssocResponse, MBO_IE), offsetof(tDot11fIEMBO_IE,
 	present), 0, "MBO_IE", 0, 6, 295, SigIeMBO_IE, {80, 111, 154, 22, 0},
 	4, DOT11F_EID_MBO_IE, 0, 0, },
@@ -23864,17 +23864,11 @@
 	while (pSrc->present) {
 		if (nNeeded > nBuf)
 			return DOT11F_BUFFER_OVERFLOW;
-		*pBuf = 221;
+		*pBuf = 255;
 		++pBuf; ++(*pnConsumed);
 		pIeLen = pBuf;
 		++pBuf; ++(*pnConsumed);
-		*pBuf = 0x0;
-		++pBuf; ++(*pnConsumed);
-		*pBuf = 0x13;
-		++pBuf; ++(*pnConsumed);
-		*pBuf = 0x74;
-		++pBuf; ++(*pnConsumed);
-		*pBuf = 0x4;
+		*pBuf = 38;
 		++pBuf; ++(*pnConsumed);
 		*pBuf = pSrc->qos;
 		*pnConsumed += 1;
diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
index 0f3c1af..4df9dc5 100644
--- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c
+++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
@@ -3054,7 +3054,6 @@
 		pAssocRsp->edcaPresent = 1;
 		convert_edca_param(pMac, &pAssocRsp->edca, &ar->EDCAParamSet);
 	}
-
 	if (ar->WMMParams.present) {
 		pAssocRsp->wmeEdcaPresent = 1;
 		convert_wmm_params(pMac, &pAssocRsp->edca, &ar->WMMParams);
@@ -3199,6 +3198,13 @@
 				pAssocRsp->he_op.bss_col_disabled);
 	}
 
+	if (ar->mu_edca_param_set.present) {
+		pe_debug("11AX: HE MU EDCA param IE present");
+		pAssocRsp->mu_edca_present = true;
+		convert_mu_edca_param(pMac, &pAssocRsp->mu_edca,
+				&ar->mu_edca_param_set);
+	}
+
 	if (ar->MBO_IE.present && ar->MBO_IE.rssi_assoc_rej.present) {
 		qdf_mem_copy(&pAssocRsp->rssi_assoc_rej,
 				&ar->MBO_IE.rssi_assoc_rej,
diff --git a/core/mac/src/sys/legacy/src/utils/src/utils_parser.c b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
index f8aa565..31c1601 100644
--- a/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
+++ b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -374,6 +374,42 @@
 
 }
 
+void convert_mu_edca_param(tpAniSirGlobal mac_ctx,
+			tSirMacEdcaParamSetIE *mu_edca,
+			tDot11fIEmu_edca_param_set *ie)
+{
+	qdf_mem_copy((uint8_t *) &mu_edca->qosInfo, (uint8_t *) &ie->qos, 1);
+
+	mu_edca->acbe.aci.aifsn = ie->acbe_aifsn;
+	mu_edca->acbe.aci.acm = ie->acbe_acm;
+	mu_edca->acbe.aci.aci = ie->acbe_aci;
+	mu_edca->acbe.cw.min = ie->acbe_acwmin;
+	mu_edca->acbe.cw.max = ie->acbe_acwmax;
+	mu_edca->acbe.mu_edca_timer = ie->acbe_muedca_timer;
+
+	mu_edca->acbk.aci.aifsn = ie->acbk_aifsn;
+	mu_edca->acbk.aci.acm = ie->acbk_acm;
+	mu_edca->acbk.aci.aci = ie->acbk_aci;
+	mu_edca->acbk.cw.min = ie->acbk_acwmin;
+	mu_edca->acbk.cw.max = ie->acbk_acwmax;
+	mu_edca->acbk.mu_edca_timer = ie->acbk_muedca_timer;
+
+	mu_edca->acvi.aci.aifsn = ie->acvi_aifsn;
+	mu_edca->acvi.aci.acm = ie->acvi_acm;
+	mu_edca->acvi.aci.aci = ie->acvi_aci;
+	mu_edca->acvi.cw.min = ie->acvi_acwmin;
+	mu_edca->acvi.cw.max = ie->acvi_acwmax;
+	mu_edca->acvi.mu_edca_timer = ie->acvi_muedca_timer;
+
+	mu_edca->acvo.aci.aifsn = ie->acvo_aifsn;
+	mu_edca->acvo.aci.acm = ie->acvo_acm;
+	mu_edca->acvo.aci.aci = ie->acvo_aci;
+	mu_edca->acvo.cw.min = ie->acvo_acwmin;
+	mu_edca->acvo.cw.max = ie->acvo_acwmax;
+	mu_edca->acvo.mu_edca_timer = ie->acvo_muedca_timer;
+
+}
+
 void convert_tspec(tpAniSirGlobal pMac,
 		   tSirMacTspecIE *pOld, tDot11fIETSPEC *pNew)
 {
diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h
index 35cc5db..88f799b 100644
--- a/core/wma/inc/wma_if.h
+++ b/core/wma/inc/wma_if.h
@@ -1028,6 +1028,7 @@
  * @acbk: Background access catagory
  * @acvi: video access catagory
  * @acvo: voice access catagory
+ * @mu_edca_params: flag to indicate MU EDCA
  */
 typedef struct {
 	uint16_t bssIdx;
@@ -1035,6 +1036,7 @@
 	tSirMacEdcaParamRecord acbk;
 	tSirMacEdcaParamRecord acvi;
 	tSirMacEdcaParamRecord acvo;
+	bool mu_edca_params;
 } tEdcaParams, *tpEdcaParams;
 
 /**
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index 29f2f46..9203572 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -663,7 +663,8 @@
 				     uint8_t max_sp);
 
 void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param,
-					  struct wmi_host_wme_vparams *wmm_param, int ac);
+				   struct wmi_host_wme_vparams *wmm_param,
+				   int ac, bool mu_edca_param);
 
 void wma_set_tx_power(WMA_HANDLE handle,
 			     tMaxTxPowerParams *tx_pwr_params);
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index 1a82590..6323f6b 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -2332,7 +2332,8 @@
 			goto fail;
 		}
 
-		wma_update_edca_params_for_ac(edca_record, &wmm_param[ac], ac);
+		wma_update_edca_params_for_ac(edca_record, &wmm_param[ac], ac,
+				edca_params->mu_edca_params);
 
 		ol_tx_wmm_param.ac[ac].aifs = wmm_param[ac].aifs;
 		ol_tx_wmm_param.ac[ac].cwmin = wmm_param[ac].cwmin;
@@ -2340,7 +2341,9 @@
 	}
 
 	status = wmi_unified_process_update_edca_param(wma_handle->wmi_handle,
-						vdev_id, wmm_param);
+						vdev_id,
+						edca_params->mu_edca_params,
+						wmm_param);
 	if (status == QDF_STATUS_E_NOMEM)
 		return status;
 	else if (status == QDF_STATUS_E_FAILURE)
diff --git a/core/wma/src/wma_power.c b/core/wma/src/wma_power.c
index 0e811e9..5b83d46 100644
--- a/core/wma/src/wma_power.c
+++ b/core/wma/src/wma_power.c
@@ -319,20 +319,32 @@
  */
 void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param,
 				   struct wmi_host_wme_vparams *wmm_param,
-				   int ac)
+				   int ac, bool mu_edca_param)
 {
 #define WMA_WMM_EXPO_TO_VAL(val)        ((1 << (val)) - 1)
-	wmm_param->cwmin = WMA_WMM_EXPO_TO_VAL(edca_param->cw.min);
-	wmm_param->cwmax = WMA_WMM_EXPO_TO_VAL(edca_param->cw.max);
+	if (mu_edca_param) {
+		wmm_param->cwmin = edca_param->cw.min;
+		wmm_param->cwmax = edca_param->cw.max;
+	} else {
+		wmm_param->cwmin = WMA_WMM_EXPO_TO_VAL(edca_param->cw.min);
+		wmm_param->cwmax = WMA_WMM_EXPO_TO_VAL(edca_param->cw.max);
+	}
 	wmm_param->aifs = edca_param->aci.aifsn;
-	wmm_param->txoplimit = edca_param->txoplimit;
+	if (mu_edca_param)
+		wmm_param->mu_edca_timer = edca_param->mu_edca_timer;
+	else
+		wmm_param->txoplimit = edca_param->txoplimit;
 	wmm_param->acm = edca_param->aci.acm;
 
 	wmm_param->noackpolicy = edca_param->no_ack;
 
-	WMA_LOGD("WMM PARAMS AC[%d]: AIFS %d Min %d Max %d TXOP %d ACM %d NOACK %d",
-		ac, wmm_param->aifs, wmm_param->cwmin, wmm_param->cwmax,
-		wmm_param->txoplimit, wmm_param->acm, wmm_param->noackpolicy);
+	WMA_LOGD("WMM PARAMS AC[%d]: AIFS %d Min %d Max %d %s %d ACM %d NOACK %d",
+			ac, wmm_param->aifs, wmm_param->cwmin,
+			wmm_param->cwmax,
+			mu_edca_param ? "MU_EDCA TIMER" : "TXOP",
+			mu_edca_param ? wmm_param->mu_edca_timer :
+				wmm_param->txoplimit,
+			wmm_param->acm, wmm_param->noackpolicy);
 }
 
 /**