return active;
 }
 
-bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
-                                 struct ieee80211_channel *chan)
+static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
+                                       struct ieee80211_channel *chan)
 {
        struct wireless_dev *wdev;
 
-       ASSERT_RTNL();
-
-       if (!(chan->flags & IEEE80211_CHAN_RADAR))
-               return false;
-
        list_for_each_entry(wdev, &wiphy->wdev_list, list) {
                wdev_lock(wdev);
                if (!cfg80211_beaconing_iface_active(wdev)) {
        return false;
 }
 
+bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+                                 struct ieee80211_channel *chan)
+{
+       struct cfg80211_registered_device *rdev;
+
+       ASSERT_RTNL();
+
+       if (!(chan->flags & IEEE80211_CHAN_RADAR))
+               return false;
+
+       list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+               if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
+                       continue;
+
+               if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan))
+                       return true;
+       }
+
+       return false;
+}
+
 static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
                                             u32 center_freq,
                                             u32 bandwidth)
 
        rtnl_unlock();
 }
 
+static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
+{
+       struct cfg80211_registered_device *rdev;
+
+       rdev = container_of(work, struct cfg80211_registered_device,
+                           propagate_radar_detect_wk);
+
+       rtnl_lock();
+
+       regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->radar_chandef,
+                                      NL80211_DFS_UNAVAILABLE,
+                                      NL80211_RADAR_DETECTED);
+
+       rtnl_unlock();
+}
+
+static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
+{
+       struct cfg80211_registered_device *rdev;
+
+       rdev = container_of(work, struct cfg80211_registered_device,
+                           propagate_cac_done_wk);
+
+       rtnl_lock();
+
+       regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->cac_done_chandef,
+                                      NL80211_DFS_AVAILABLE,
+                                      NL80211_RADAR_CAC_FINISHED);
+
+       rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
        spin_lock_init(&rdev->destroy_list_lock);
        INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
        INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+       INIT_WORK(&rdev->propagate_radar_detect_wk,
+                 cfg80211_propagate_radar_detect_wk);
+       INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
 
 #ifdef CONFIG_CFG80211_DEFAULT_PS
        rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
        flush_work(&rdev->destroy_work);
        flush_work(&rdev->sched_scan_stop_wk);
        flush_work(&rdev->mlme_unreg_wk);
+       flush_work(&rdev->propagate_radar_detect_wk);
+       flush_work(&rdev->propagate_cac_done_wk);
 
 #ifdef CONFIG_PM
        if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
 
 
        struct work_struct sched_scan_stop_wk;
 
+       struct cfg80211_chan_def radar_chandef;
+       struct work_struct propagate_radar_detect_wk;
+
+       struct cfg80211_chan_def cac_done_chandef;
+       struct work_struct propagate_cac_done_wk;
+
        /* must be last because of the way we do wiphy_priv(),
         * and it should at least be aligned to NETDEV_ALIGN */
        struct wiphy wiphy __aligned(NETDEV_ALIGN);
 
                                nl80211_radar_notify(rdev, &chandef,
                                                     radar_event, NULL,
                                                     GFP_ATOMIC);
+
+                               regulatory_propagate_dfs_state(wiphy, &chandef,
+                                                              c->dfs_state,
+                                                              radar_event);
                                continue;
                        }
 
        cfg80211_sched_dfs_chan_update(rdev);
 
        nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
+
+       memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
+       queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
 }
 EXPORT_SYMBOL(cfg80211_radar_event);
 
                          msecs_to_jiffies(wdev->cac_time_ms);
                WARN_ON(!time_after_eq(jiffies, timeout));
                cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+               memcpy(&rdev->cac_done_chandef, chandef,
+                      sizeof(struct cfg80211_chan_def));
+               queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
                cfg80211_sched_dfs_chan_update(rdev);
                break;
        case NL80211_RADAR_CAC_ABORTED:
 
        return REG_REQ_IGNORE;
 }
 
+bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2)
+{
+       const struct ieee80211_regdomain *wiphy1_regd = NULL;
+       const struct ieee80211_regdomain *wiphy2_regd = NULL;
+       const struct ieee80211_regdomain *cfg80211_regd = NULL;
+       bool dfs_domain_same;
+
+       rcu_read_lock();
+
+       cfg80211_regd = rcu_dereference(cfg80211_regdomain);
+       wiphy1_regd = rcu_dereference(wiphy1->regd);
+       if (!wiphy1_regd)
+               wiphy1_regd = cfg80211_regd;
+
+       wiphy2_regd = rcu_dereference(wiphy2->regd);
+       if (!wiphy2_regd)
+               wiphy2_regd = cfg80211_regd;
+
+       dfs_domain_same = wiphy1_regd->dfs_region == wiphy2_regd->dfs_region;
+
+       rcu_read_unlock();
+
+       return dfs_domain_same;
+}
+
+static void reg_copy_dfs_chan_state(struct ieee80211_channel *dst_chan,
+                                   struct ieee80211_channel *src_chan)
+{
+       if (!(dst_chan->flags & IEEE80211_CHAN_RADAR) ||
+           !(src_chan->flags & IEEE80211_CHAN_RADAR))
+               return;
+
+       if (dst_chan->flags & IEEE80211_CHAN_DISABLED ||
+           src_chan->flags & IEEE80211_CHAN_DISABLED)
+               return;
+
+       if (src_chan->center_freq == dst_chan->center_freq &&
+           dst_chan->dfs_state == NL80211_DFS_USABLE) {
+               dst_chan->dfs_state = src_chan->dfs_state;
+               dst_chan->dfs_state_entered = src_chan->dfs_state_entered;
+       }
+}
+
+static void wiphy_share_dfs_chan_state(struct wiphy *dst_wiphy,
+                                      struct wiphy *src_wiphy)
+{
+       struct ieee80211_supported_band *src_sband, *dst_sband;
+       struct ieee80211_channel *src_chan, *dst_chan;
+       int i, j, band;
+
+       if (!reg_dfs_domain_same(dst_wiphy, src_wiphy))
+               return;
+
+       for (band = 0; band < NUM_NL80211_BANDS; band++) {
+               dst_sband = dst_wiphy->bands[band];
+               src_sband = src_wiphy->bands[band];
+               if (!dst_sband || !src_sband)
+                       continue;
+
+               for (i = 0; i < dst_sband->n_channels; i++) {
+                       dst_chan = &dst_sband->channels[i];
+                       for (j = 0; j < src_sband->n_channels; j++) {
+                               src_chan = &src_sband->channels[j];
+                               reg_copy_dfs_chan_state(dst_chan, src_chan);
+                       }
+               }
+       }
+}
+
+static void wiphy_all_share_dfs_chan_state(struct wiphy *wiphy)
+{
+       struct cfg80211_registered_device *rdev;
+
+       ASSERT_RTNL();
+
+       list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+               if (wiphy == &rdev->wiphy)
+                       continue;
+               wiphy_share_dfs_chan_state(wiphy, &rdev->wiphy);
+       }
+}
+
 /* This processes *all* regulatory hints */
 static void reg_process_hint(struct regulatory_request *reg_request)
 {
        if (treatment == REG_REQ_ALREADY_SET && wiphy &&
            wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
                wiphy_update_regulatory(wiphy, reg_request->initiator);
+               wiphy_all_share_dfs_chan_state(wiphy);
                reg_check_channels();
        }
 
 
        lr = get_last_request();
        wiphy_update_regulatory(wiphy, lr->initiator);
+       wiphy_all_share_dfs_chan_state(wiphy);
 }
 
 void wiphy_regulatory_deregister(struct wiphy *wiphy)
        return pre_cac_allowed;
 }
 
+void regulatory_propagate_dfs_state(struct wiphy *wiphy,
+                                   struct cfg80211_chan_def *chandef,
+                                   enum nl80211_dfs_state dfs_state,
+                                   enum nl80211_radar_event event)
+{
+       struct cfg80211_registered_device *rdev;
+
+       ASSERT_RTNL();
+
+       if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+               return;
+
+       if (WARN_ON(!(chandef->chan->flags & IEEE80211_CHAN_RADAR)))
+               return;
+
+       list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+               if (wiphy == &rdev->wiphy)
+                       continue;
+
+               if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
+                       continue;
+
+               if (!ieee80211_get_channel(&rdev->wiphy,
+                                          chandef->chan->center_freq))
+                       continue;
+
+               cfg80211_set_dfs_state(&rdev->wiphy, chandef, dfs_state);
+
+               if (event == NL80211_RADAR_DETECTED ||
+                   event == NL80211_RADAR_CAC_FINISHED)
+                       cfg80211_sched_dfs_chan_update(rdev);
+
+               nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL);
+       }
+}
+
 int __init regulatory_init(void)
 {
        int err = 0;
 
  * Pre-CAC is allowed only in ETSI domain.
  */
 bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
+
+/**
+ * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys
+ * @wiphy - wiphy on which radar is detected and the event will be propagated
+ *     to other available wiphys having the same DFS domain
+ * @chandef - Channel definition of radar detected channel
+ * @dfs_state - DFS channel state to be set
+ * @event - Type of radar event which triggered this DFS state change
+ *
+ * This function should be called with rtnl lock held.
+ */
+void regulatory_propagate_dfs_state(struct wiphy *wiphy,
+                                   struct cfg80211_chan_def *chandef,
+                                   enum nl80211_dfs_state dfs_state,
+                                   enum nl80211_radar_event event);
+
+/**
+ * reg_dfs_domain_same - Checks if both wiphy have same DFS domain configured
+ * @wiphy1 - wiphy it's dfs_region to be checked against that of wiphy2
+ * @wiphy2 - wiphy it's dfs_region to be checked against that of wiphy1
+ */
+bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2);
 #endif  /* __NET_WIRELESS_REG_H */