diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d9e6b9fbd95b..ae02d96eb8ec 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7416,6 +7416,17 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
                                       struct cfg80211_chan_def *chandef,
                                       u8 count);

+/*
+ * cfg80211_ch_switch - trigger channel switch from driver
+ * same as is can be triggered from hostapd_cli chan_switch
+ * @dev: the device which switched channels
+ * @chandef: the new channel definition
+ * @csa_count: the number of TBTTs until the channel switch happens
+ */
+bool cfg80211_ch_switch(struct net_device *dev,
+                              struct cfg80211_chan_def *chandef,
+                              u8 csa_count);
+
 /**
  * ieee80211_operating_class_to_band - convert operating class to band
  *
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 19dc0ee807f6..c9ed073e5ab3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -16854,6 +16854,89 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
 }
 EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);

+static void nl80211_ch_switch(struct cfg80211_registered_device *rdev,
+                             struct net_device *netdev,
+                             struct cfg80211_chan_def *chandef,
+                             u8 csa_count,
+                             gfp_t gfp)
+{
+       struct sk_buff *msg;
+       void *hdr;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CHANNEL_SWITCH);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
+                       chandef->chan->center_freq))
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
+               goto nla_put_failure;
+
+       if (chandef->width == NL80211_CHAN_WIDTH_40) {
+               enum nl80211_channel_type chan_type = NL80211_CHAN_HT40MINUS;
+
+               if (chandef->center_freq1 > chandef->chan->center_freq)
+                       chan_type = NL80211_CHAN_HT40PLUS;
+
+               if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+                               chan_type))
+                       goto nla_put_failure;
+       }
+
+       if (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, csa_count))
+               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);
+}
+
+bool cfg80211_ch_switch(struct net_device *dev,
+                       struct cfg80211_chan_def *chandef,
+                       u8 csa_count)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
+                   wdev->iftype != NL80211_IFTYPE_P2P_GO &&
+                   wdev->iftype != NL80211_IFTYPE_ADHOC &&
+                   wdev->iftype != NL80211_IFTYPE_MESH_POINT))
+               return false;
+
+       if (WARN_ON(!chandef || !chandef->chan))
+               return false;
+
+       nl80211_ch_switch(rdev, dev, chandef, csa_count, GFP_ATOMIC);
+
+       return true;
+}
+EXPORT_SYMBOL(cfg80211_ch_switch);
+
 void
 nl80211_radar_notify(struct cfg80211_registered_device *rdev,
                     const struct cfg80211_chan_def *chandef,
