Loading include/uapi/linux/nl80211.h +5 −0 Original line number Diff line number Diff line Loading @@ -4904,12 +4904,17 @@ enum nl80211_smps_mode { * change to the channel status. * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is * over, channel becomes usable. * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this * non-operating channel is expired and no longer valid. New CAC must * be done on this channel before starting the operation. This is not * applicable for ETSI dfs domain where pre-CAC is valid for ever. */ enum nl80211_radar_event { NL80211_RADAR_DETECTED, NL80211_RADAR_CAC_FINISHED, NL80211_RADAR_CAC_ABORTED, NL80211_RADAR_NOP_FINISHED, NL80211_RADAR_PRE_CAC_EXPIRED, }; /** Loading net/wireless/ap.c +5 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, rdev_set_qos_map(rdev, dev, NULL); if (notify) nl80211_send_ap_stopped(wdev); /* Should we apply the grace period during beaconing interface * shutdown also? */ cfg80211_sched_dfs_chan_update(rdev); } return err; Loading net/wireless/chan.c +99 −0 Original line number Diff line number Diff line Loading @@ -456,6 +456,105 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, return (r1 + r2 > 0); } /* * Checks if center frequency of chan falls with in the bandwidth * range of chandef. */ bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, struct ieee80211_channel *chan) { int width; u32 cf_offset, freq; if (chandef->chan->center_freq == chan->center_freq) return true; width = cfg80211_chandef_get_width(chandef); if (width <= 20) return false; cf_offset = width / 2 - 10; for (freq = chandef->center_freq1 - width / 2 + 10; freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) { if (chan->center_freq == freq) return true; } if (!chandef->center_freq2) return false; for (freq = chandef->center_freq2 - width / 2 + 10; freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) { if (chan->center_freq == freq) return true; } return false; } bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev) { bool active = false; ASSERT_WDEV_LOCK(wdev); if (!wdev->chandef.chan) return false; switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: active = wdev->beacon_interval != 0; break; case NL80211_IFTYPE_ADHOC: active = wdev->ssid_len != 0; break; case NL80211_IFTYPE_MESH_POINT: active = wdev->mesh_id_len != 0; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_P2P_DEVICE: break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: WARN_ON(1); } return active; } bool cfg80211_any_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)) { wdev_unlock(wdev); continue; } if (cfg80211_is_sub_chan(&wdev->chandef, chan)) { wdev_unlock(wdev); return true; } wdev_unlock(wdev); } return false; } static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy, u32 center_freq, Loading net/wireless/core.h +10 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,16 @@ unsigned int cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef); void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, struct ieee80211_channel *chan); bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev); bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, struct ieee80211_channel *chan); static inline unsigned int elapsed_jiffies_msecs(unsigned long start) { unsigned long end = jiffies; Loading net/wireless/ibss.c +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) if (!nowext) wdev->wext.ibss.ssid_len = 0; #endif cfg80211_sched_dfs_chan_update(rdev); } void cfg80211_clear_ibss(struct net_device *dev, bool nowext) Loading Loading
include/uapi/linux/nl80211.h +5 −0 Original line number Diff line number Diff line Loading @@ -4904,12 +4904,17 @@ enum nl80211_smps_mode { * change to the channel status. * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is * over, channel becomes usable. * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this * non-operating channel is expired and no longer valid. New CAC must * be done on this channel before starting the operation. This is not * applicable for ETSI dfs domain where pre-CAC is valid for ever. */ enum nl80211_radar_event { NL80211_RADAR_DETECTED, NL80211_RADAR_CAC_FINISHED, NL80211_RADAR_CAC_ABORTED, NL80211_RADAR_NOP_FINISHED, NL80211_RADAR_PRE_CAC_EXPIRED, }; /** Loading
net/wireless/ap.c +5 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, rdev_set_qos_map(rdev, dev, NULL); if (notify) nl80211_send_ap_stopped(wdev); /* Should we apply the grace period during beaconing interface * shutdown also? */ cfg80211_sched_dfs_chan_update(rdev); } return err; Loading
net/wireless/chan.c +99 −0 Original line number Diff line number Diff line Loading @@ -456,6 +456,105 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, return (r1 + r2 > 0); } /* * Checks if center frequency of chan falls with in the bandwidth * range of chandef. */ bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, struct ieee80211_channel *chan) { int width; u32 cf_offset, freq; if (chandef->chan->center_freq == chan->center_freq) return true; width = cfg80211_chandef_get_width(chandef); if (width <= 20) return false; cf_offset = width / 2 - 10; for (freq = chandef->center_freq1 - width / 2 + 10; freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) { if (chan->center_freq == freq) return true; } if (!chandef->center_freq2) return false; for (freq = chandef->center_freq2 - width / 2 + 10; freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) { if (chan->center_freq == freq) return true; } return false; } bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev) { bool active = false; ASSERT_WDEV_LOCK(wdev); if (!wdev->chandef.chan) return false; switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: active = wdev->beacon_interval != 0; break; case NL80211_IFTYPE_ADHOC: active = wdev->ssid_len != 0; break; case NL80211_IFTYPE_MESH_POINT: active = wdev->mesh_id_len != 0; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_P2P_DEVICE: break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: WARN_ON(1); } return active; } bool cfg80211_any_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)) { wdev_unlock(wdev); continue; } if (cfg80211_is_sub_chan(&wdev->chandef, chan)) { wdev_unlock(wdev); return true; } wdev_unlock(wdev); } return false; } static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy, u32 center_freq, Loading
net/wireless/core.h +10 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,16 @@ unsigned int cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef); void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, struct ieee80211_channel *chan); bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev); bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, struct ieee80211_channel *chan); static inline unsigned int elapsed_jiffies_msecs(unsigned long start) { unsigned long end = jiffies; Loading
net/wireless/ibss.c +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) if (!nowext) wdev->wext.ibss.ssid_len = 0; #endif cfg80211_sched_dfs_chan_update(rdev); } void cfg80211_clear_ibss(struct net_device *dev, bool nowext) Loading