@@ -2067,6 +2067,88 @@ reg_process_hint_country_ie(struct wiphy *wiphy,
20672067 return REG_REQ_IGNORE ;
20682068}
20692069
2070+ bool reg_dfs_domain_same (struct wiphy * wiphy1 , struct wiphy * wiphy2 )
2071+ {
2072+ const struct ieee80211_regdomain * wiphy1_regd = NULL ;
2073+ const struct ieee80211_regdomain * wiphy2_regd = NULL ;
2074+ const struct ieee80211_regdomain * cfg80211_regd = NULL ;
2075+ bool dfs_domain_same ;
2076+
2077+ rcu_read_lock ();
2078+
2079+ cfg80211_regd = rcu_dereference (cfg80211_regdomain );
2080+ wiphy1_regd = rcu_dereference (wiphy1 -> regd );
2081+ if (!wiphy1_regd )
2082+ wiphy1_regd = cfg80211_regd ;
2083+
2084+ wiphy2_regd = rcu_dereference (wiphy2 -> regd );
2085+ if (!wiphy2_regd )
2086+ wiphy2_regd = cfg80211_regd ;
2087+
2088+ dfs_domain_same = wiphy1_regd -> dfs_region == wiphy2_regd -> dfs_region ;
2089+
2090+ rcu_read_unlock ();
2091+
2092+ return dfs_domain_same ;
2093+ }
2094+
2095+ static void reg_copy_dfs_chan_state (struct ieee80211_channel * dst_chan ,
2096+ struct ieee80211_channel * src_chan )
2097+ {
2098+ if (!(dst_chan -> flags & IEEE80211_CHAN_RADAR ) ||
2099+ !(src_chan -> flags & IEEE80211_CHAN_RADAR ))
2100+ return ;
2101+
2102+ if (dst_chan -> flags & IEEE80211_CHAN_DISABLED ||
2103+ src_chan -> flags & IEEE80211_CHAN_DISABLED )
2104+ return ;
2105+
2106+ if (src_chan -> center_freq == dst_chan -> center_freq &&
2107+ dst_chan -> dfs_state == NL80211_DFS_USABLE ) {
2108+ dst_chan -> dfs_state = src_chan -> dfs_state ;
2109+ dst_chan -> dfs_state_entered = src_chan -> dfs_state_entered ;
2110+ }
2111+ }
2112+
2113+ static void wiphy_share_dfs_chan_state (struct wiphy * dst_wiphy ,
2114+ struct wiphy * src_wiphy )
2115+ {
2116+ struct ieee80211_supported_band * src_sband , * dst_sband ;
2117+ struct ieee80211_channel * src_chan , * dst_chan ;
2118+ int i , j , band ;
2119+
2120+ if (!reg_dfs_domain_same (dst_wiphy , src_wiphy ))
2121+ return ;
2122+
2123+ for (band = 0 ; band < NUM_NL80211_BANDS ; band ++ ) {
2124+ dst_sband = dst_wiphy -> bands [band ];
2125+ src_sband = src_wiphy -> bands [band ];
2126+ if (!dst_sband || !src_sband )
2127+ continue ;
2128+
2129+ for (i = 0 ; i < dst_sband -> n_channels ; i ++ ) {
2130+ dst_chan = & dst_sband -> channels [i ];
2131+ for (j = 0 ; j < src_sband -> n_channels ; j ++ ) {
2132+ src_chan = & src_sband -> channels [j ];
2133+ reg_copy_dfs_chan_state (dst_chan , src_chan );
2134+ }
2135+ }
2136+ }
2137+ }
2138+
2139+ static void wiphy_all_share_dfs_chan_state (struct wiphy * wiphy )
2140+ {
2141+ struct cfg80211_registered_device * rdev ;
2142+
2143+ ASSERT_RTNL ();
2144+
2145+ list_for_each_entry (rdev , & cfg80211_rdev_list , list ) {
2146+ if (wiphy == & rdev -> wiphy )
2147+ continue ;
2148+ wiphy_share_dfs_chan_state (wiphy , & rdev -> wiphy );
2149+ }
2150+ }
2151+
20702152/* This processes *all* regulatory hints */
20712153static void reg_process_hint (struct regulatory_request * reg_request )
20722154{
@@ -2110,6 +2192,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
21102192 if (treatment == REG_REQ_ALREADY_SET && wiphy &&
21112193 wiphy -> regulatory_flags & REGULATORY_STRICT_REG ) {
21122194 wiphy_update_regulatory (wiphy , reg_request -> initiator );
2195+ wiphy_all_share_dfs_chan_state (wiphy );
21132196 reg_check_channels ();
21142197 }
21152198
@@ -3061,6 +3144,7 @@ void wiphy_regulatory_register(struct wiphy *wiphy)
30613144
30623145 lr = get_last_request ();
30633146 wiphy_update_regulatory (wiphy , lr -> initiator );
3147+ wiphy_all_share_dfs_chan_state (wiphy );
30643148}
30653149
30663150void wiphy_regulatory_deregister (struct wiphy * wiphy )
@@ -3148,6 +3232,42 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
31483232 return pre_cac_allowed ;
31493233}
31503234
3235+ void regulatory_propagate_dfs_state (struct wiphy * wiphy ,
3236+ struct cfg80211_chan_def * chandef ,
3237+ enum nl80211_dfs_state dfs_state ,
3238+ enum nl80211_radar_event event )
3239+ {
3240+ struct cfg80211_registered_device * rdev ;
3241+
3242+ ASSERT_RTNL ();
3243+
3244+ if (WARN_ON (!cfg80211_chandef_valid (chandef )))
3245+ return ;
3246+
3247+ if (WARN_ON (!(chandef -> chan -> flags & IEEE80211_CHAN_RADAR )))
3248+ return ;
3249+
3250+ list_for_each_entry (rdev , & cfg80211_rdev_list , list ) {
3251+ if (wiphy == & rdev -> wiphy )
3252+ continue ;
3253+
3254+ if (!reg_dfs_domain_same (wiphy , & rdev -> wiphy ))
3255+ continue ;
3256+
3257+ if (!ieee80211_get_channel (& rdev -> wiphy ,
3258+ chandef -> chan -> center_freq ))
3259+ continue ;
3260+
3261+ cfg80211_set_dfs_state (& rdev -> wiphy , chandef , dfs_state );
3262+
3263+ if (event == NL80211_RADAR_DETECTED ||
3264+ event == NL80211_RADAR_CAC_FINISHED )
3265+ cfg80211_sched_dfs_chan_update (rdev );
3266+
3267+ nl80211_radar_notify (rdev , chandef , event , NULL , GFP_KERNEL );
3268+ }
3269+ }
3270+
31513271int __init regulatory_init (void )
31523272{
31533273 int err = 0 ;
0 commit comments