diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e56af095828e..fe4f416b85e1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -9070,4 +9070,16 @@ static inline int cfg80211_color_change_notify(struct net_device *dev)
 bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
 					      const struct cfg80211_chan_def *chandef);
 
+/**
+ * cfg80211_update_muedca_params_event - Notify userspace about updated
+ *	MU-EDCA parameters
+ *
+ * @wiphy: the wiphy
+ * @params: Updated MU-EDCA parameters
+ * @gfp: allocation flags
+ */
+void cfg80211_update_muedca_params_event(struct wiphy *wiphy,
+					 const struct ieee80211_mu_edca_param_set *params,
+					 gfp_t gfp);
+
 #endif /* __NET_CFG80211_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e68169130e7e..51c8a94bc411 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1309,6 +1309,11 @@
  *	The number of peers that HW timestamping can be enabled for concurrently
  *	is indicated by %NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS.
  *
+ * @NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS: Updated MU-EDCA parameters from
+ *	driver. This event is used to update dynamic MU-EDCA parameters in
+ *	management frames, coming from driver and now need to be reflected in
+ *	management frames.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1562,6 +1567,8 @@ enum nl80211_commands {
 
 	NL80211_CMD_SET_HW_TIMESTAMP,
 
+	NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -2807,6 +2814,9 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_DYN_MUEDCA_ENABLE: Flag attribute to indicate user space has
  *  enabled Driver control of dynamically updating MU-EDCA parameters.
+ * @NL80211_ATTR_HE_MUEDCA_PARAMS: MU-EDCA AC parameters for the
+ *	%NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS command in format described in
+ *	P802.11ax_D4.0 section 9.4.2.245
  *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -3345,6 +3355,7 @@ enum nl80211_attrs {
 	NL80211_ATTR_EMA_RNR_ELEMS,
 
 	NL80211_ATTR_DYN_MUEDCA_ENABLE,
+	NL80211_ATTR_HE_MUEDCA_PARAMS,
 
 	/* add attributes here, update the policy in nl80211.c */
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e9e939706630..af36440f2a51 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -816,6 +816,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
 	[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
 	[NL80211_ATTR_DYN_MUEDCA_ENABLE] = { .type = NLA_FLAG },
+	[NL80211_ATTR_HE_MUEDCA_PARAMS] =
+	       NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_mu_edca_param_set)),
 };
 
 /* policy for the key attributes */
@@ -20017,6 +20019,44 @@ void cfg80211_update_owe_info_event(struct net_device *netdev,
 }
 EXPORT_SYMBOL(cfg80211_update_owe_info_event);
 
+void
+cfg80211_update_muedca_params_event(struct wiphy *wiphy,
+				    const struct ieee80211_mu_edca_param_set *params,
+				    gfp_t gfp)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+
+	trace_cfg80211_update_muedca_params_event(wiphy, params);
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS);
+	if (!hdr)
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+		goto nla_put_failure;
+
+	if (nla_put(msg, NL80211_ATTR_HE_MUEDCA_PARAMS,
+		    sizeof(*params), params))
+		goto nla_put_failure;
+
+	genlmsg_end(msg, hdr);
+
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+				NL80211_MCGRP_MLME, gfp);
+	return;
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_update_muedca_params_event);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 716a1fa70069..3ac552be0129 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3785,6 +3785,46 @@ TRACE_EVENT(cfg80211_update_owe_info_event,
 		  __entry->assoc_link_id, __entry->peer_mld_addr)
 );
 
+TRACE_EVENT(cfg80211_update_muedca_params_event,
+	TP_PROTO(struct wiphy *wiphy,
+		 const struct ieee80211_mu_edca_param_set *params),
+	TP_ARGS(wiphy, params),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		__field(u8, mu_qos_info)
+		__field(u8, be_aifsn)
+		__field(u8, be_ecw_min_max)
+		__field(u8, be_mu_edca_timer)
+		__field(u8, bk_aifsn)
+		__field(u8, bk_ecw_min_max)
+		__field(u8, bk_mu_edca_timer)
+		__field(u8, vi_aifsn)
+		__field(u8, vi_ecw_min_max)
+		__field(u8, vi_mu_edca_timer)
+		__field(u8, vo_aifsn)
+		__field(u8, vo_ecw_min_max)
+		__field(u8, vo_mu_edca_timer)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		__entry->mu_qos_info = params->mu_qos_info;
+		__entry->be_aifsn = params->ac_be.aifsn;
+		__entry->be_ecw_min_max = params->ac_be.ecw_min_max;
+		__entry->be_mu_edca_timer = params->ac_be.mu_edca_timer;
+		__entry->bk_aifsn = params->ac_bk.aifsn;
+		__entry->bk_ecw_min_max = params->ac_bk.ecw_min_max;
+		__entry->bk_mu_edca_timer = params->ac_bk.mu_edca_timer;
+		__entry->vi_aifsn = params->ac_vi.aifsn;
+		__entry->vi_ecw_min_max = params->ac_vi.ecw_min_max;
+		__entry->vi_mu_edca_timer = params->ac_vi.mu_edca_timer;
+		__entry->vo_aifsn = params->ac_vo.aifsn;
+		__entry->vo_ecw_min_max = params->ac_vo.ecw_min_max;
+		__entry->vo_mu_edca_timer = params->ac_vo.mu_edca_timer;
+	),
+	TP_printk(WIPHY_PR_FMT ", MU QOS info: %u", WIPHY_PR_ARG,
+		  __entry->mu_qos_info)
+);
+
 TRACE_EVENT(cfg80211_bss_color_notify,
 	TP_PROTO(struct net_device *netdev,
 		 enum nl80211_commands cmd,
