diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c01e0c115fb4..a823b34120aa 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5778,7 +5778,8 @@ static inline void wiphy_unlock(struct wiphy *wiphy)
  * @unprot_beacon_reported: (private) timestamp of last
  *	unprotected beacon report
  * @links: array of %IEEE80211_MLD_MAX_NUM_LINKS elements containing @addr
- *	@ap and @client for each link
+ *	@ap and @client for each link. If link is 6 GHz link then uses
+ *	@reg_6ghz_pwr_configured as well.
  * @valid_links: bitmap describing what elements of @links are valid
  */
 struct wireless_dev {
@@ -5887,11 +5888,14 @@ struct wireless_dev {
 			struct {
 				unsigned int beacon_interval;
 				struct cfg80211_chan_def chandef;
+				enum ieee80211_ap_reg_power power_mode_6ghz;
 			} ap;
 			struct {
 				struct cfg80211_internal_bss *current_bss;
+				enum ieee80211_client_reg_power power_mode_6ghz;
 			} client;
 		};
+		bool reg_6ghz_pwr_configured;
 	} links[IEEE80211_MLD_MAX_NUM_LINKS];
 	u16 valid_links;
 };
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1be5f79c73ae..0f37376912c6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1299,6 +1299,8 @@
  * @NL80211_CMD_MODIFY_LINK_STA: Modify a link of an MLD station
  * @NL80211_CMD_REMOVE_LINK_STA: Remove a link of an MLD station
  *
+ * @NL80211_CMD_SET_6GHZ_POWER_MODE: Set 6 GHz power mode for the interface
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1550,6 +1552,8 @@ enum nl80211_commands {
 	NL80211_CMD_MODIFY_LINK_STA,
 	NL80211_CMD_REMOVE_LINK_STA,
 
+	NL80211_CMD_SET_6GHZ_POWER_MODE,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -2774,6 +2778,10 @@ enum nl80211_commands {
  *	bit corresponds to the lowest 20 MHz channel. Each bit set to 1
  *	indicates that the sub-channel is punctured. Higher 16 bits are
  *	reserved.
+ * @NL80211_ATTR_6GHZ_REG_POWER_MODE: Regulatory power mode for 6 GHz operation.
+ *	This can be used for both AP and clients. Values are defined in
+ *	&enum ieee80211_ap_reg_power and &enum ieee80211_client_reg_power.
+ *	Therefore, iftype should be taken into consideration. u8 value.
  *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -3306,6 +3314,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_PUNCT_BITMAP,
 
+	NL80211_ATTR_6GHZ_REG_POWER_MODE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index 0962770303b2..b8e2d9466434 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -30,6 +30,8 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
 	if (!wdev->links[link_id].ap.beacon_interval)
 		return -ENOENT;
 
+	wdev->links[link_id].reg_6ghz_pwr_configured = false;
+
 	err = rdev_stop_ap(rdev, dev, link_id);
 	if (!err) {
 		wdev->conn_owner_nlportid = 0;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ca40fab0d3ad..9dd3876f6440 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -806,6 +806,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
 	[NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff),
+	[NL80211_ATTR_6GHZ_REG_POWER_MODE] = { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -16180,6 +16181,61 @@ nl80211_remove_link_station(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
+static bool nl80211_6ghz_power_mode_is_valid(enum nl80211_iftype iftype,
+					     u8 power_mode)
+{
+	/* For APs, referenced from enum ieee80211_ap_reg_power, and
+	 * For clients, referenced from enum ieee80211_client_reg_power
+	 */
+	switch (iftype) {
+	case NL80211_IFTYPE_AP:
+		return ((power_mode >= IEEE80211_REG_LPI_AP) &&
+			(power_mode <= IEEE80211_REG_AP_POWER_MAX));
+	case NL80211_IFTYPE_STATION:
+		return ((power_mode >= IEEE80211_REG_DEFAULT_CLIENT) &&
+			(power_mode <= IEEE80211_REG_CLIENT_POWER_MAX));
+	default:
+		return false;
+	}
+}
+
+static int nl80211_set_6ghz_power_mode(struct sk_buff *skb,
+				       struct genl_info *info)
+{
+	struct net_device *netdev = info->user_ptr[1];
+	struct wireless_dev *wdev = netdev->ieee80211_ptr;
+	enum nl80211_iftype iftype = wdev->iftype;
+	unsigned int link_id = nl80211_link_id(info->attrs);
+	u8 power_mode;
+
+	if (iftype != NL80211_IFTYPE_AP &&
+	    iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	if (!info->attrs[NL80211_ATTR_6GHZ_REG_POWER_MODE])
+		return -EINVAL;
+
+	power_mode = nla_get_u8(info->attrs[NL80211_ATTR_6GHZ_REG_POWER_MODE]);
+	if (!nl80211_6ghz_power_mode_is_valid(iftype, power_mode))
+		return -EINVAL;
+
+	wdev_lock(wdev);
+	if (wdev->links[link_id].reg_6ghz_pwr_configured) {
+		wdev_unlock(wdev);
+		return -EALREADY;
+	}
+
+	if (iftype == NL80211_IFTYPE_AP)
+		wdev->links[link_id].ap.power_mode_6ghz = power_mode;
+	else
+		wdev->links[link_id].client.power_mode_6ghz = power_mode;
+
+	wdev->links[link_id].reg_6ghz_pwr_configured = true;
+
+	wdev_unlock(wdev);
+	return 0;
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -17354,6 +17410,14 @@ static const struct genl_small_ops nl80211_small_ops[] = {
 		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
 					 NL80211_FLAG_MLO_VALID_LINK_ID),
 	},
+	{
+		.cmd = NL80211_CMD_SET_6GHZ_POWER_MODE,
+		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+		.doit = nl80211_set_6ghz_power_mode,
+		.flags = GENL_UNS_ADMIN_PERM,
+		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
+					 NL80211_FLAG_MLO_VALID_LINK_ID),
+	},
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
@@ -17370,7 +17434,7 @@ static struct genl_family nl80211_fam __ro_after_init = {
 	.n_ops = ARRAY_SIZE(nl80211_ops),
 	.small_ops = nl80211_small_ops,
 	.n_small_ops = ARRAY_SIZE(nl80211_small_ops),
-	.resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1,
+	.resv_start_op = NL80211_CMD_SET_6GHZ_POWER_MODE + 1,
 	.mcgrps = nl80211_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
 	.parallel_ops = true,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 28ce13840a88..5ccc371fdfaf 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1558,6 +1558,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 	if (!wdev->connected)
 		wdev->u.client.ssid_len = 0;
 
+	wdev->links[0].reg_6ghz_pwr_configured = false;
+
 	return err;
 }
 
