cfg80211: Share Channel DFS state across wiphys of same DFS domain

Sharing DFS channel state across multiple wiphys (radios) could
be useful with multiple radios on the system. When one radio
completes CAC and markes the channel available another radio
can use this information and start beaconing without really doing
CAC.

Whenever there is a state change in dfs channel associated to
a particular wiphy the the same state change is propagated to
other wiphys having the same DFS reg domain configuration.
Also when a new wiphy is created the dfs channel state of
other existing wiphys of same DFS domain is copied.

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index cd29366..01ce4a6 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -810,6 +810,10 @@
 				nl80211_radar_notify(rdev, &chandef,
 						     radar_event, NULL,
 						     GFP_ATOMIC);
+
+				regulatory_propagate_dfs_state(wiphy, &chandef,
+							       c->dfs_state,
+							       radar_event);
 				continue;
 			}
 
@@ -846,6 +850,9 @@
 	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);
 
@@ -872,6 +879,9 @@
 			  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: