aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h46
-rw-r--r--include/uapi/linux/nl80211.h61
-rw-r--r--net/wireless/chan.c129
-rw-r--r--net/wireless/core.c3
-rw-r--r--net/wireless/core.h28
-rw-r--r--net/wireless/mlme.c120
-rw-r--r--net/wireless/nl80211.c135
-rw-r--r--net/wireless/nl80211.h7
-rw-r--r--net/wireless/reg.c3
-rw-r--r--net/wireless/scan.c10
-rw-r--r--net/wireless/trace.h45
11 files changed, 570 insertions, 17 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7e6569e1f16f..ee11a3db730b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -114,6 +114,9 @@ enum ieee80211_channel_flags {
114#define IEEE80211_CHAN_NO_HT40 \ 114#define IEEE80211_CHAN_NO_HT40 \
115 (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) 115 (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
116 116
117#define IEEE80211_DFS_MIN_CAC_TIME_MS 60000
118#define IEEE80211_DFS_MIN_NOP_TIME_MS (30 * 60 * 1000)
119
117/** 120/**
118 * struct ieee80211_channel - channel definition 121 * struct ieee80211_channel - channel definition
119 * 122 *
@@ -134,6 +137,9 @@ enum ieee80211_channel_flags {
134 * to enable this, this is useful only on 5 GHz band. 137 * to enable this, this is useful only on 5 GHz band.
135 * @orig_mag: internal use 138 * @orig_mag: internal use
136 * @orig_mpwr: internal use 139 * @orig_mpwr: internal use
140 * @dfs_state: current state of this channel. Only relevant if radar is required
141 * on this channel.
142 * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
137 */ 143 */
138struct ieee80211_channel { 144struct ieee80211_channel {
139 enum ieee80211_band band; 145 enum ieee80211_band band;
@@ -146,6 +152,8 @@ struct ieee80211_channel {
146 bool beacon_found; 152 bool beacon_found;
147 u32 orig_flags; 153 u32 orig_flags;
148 int orig_mag, orig_mpwr; 154 int orig_mag, orig_mpwr;
155 enum nl80211_dfs_state dfs_state;
156 unsigned long dfs_state_entered;
149}; 157};
150 158
151/** 159/**
@@ -569,6 +577,7 @@ struct cfg80211_acl_data {
569 * @p2p_opp_ps: P2P opportunistic PS 577 * @p2p_opp_ps: P2P opportunistic PS
570 * @acl: ACL configuration used by the drivers which has support for 578 * @acl: ACL configuration used by the drivers which has support for
571 * MAC address based access control 579 * MAC address based access control
580 * @radar_required: set if radar detection is required
572 */ 581 */
573struct cfg80211_ap_settings { 582struct cfg80211_ap_settings {
574 struct cfg80211_chan_def chandef; 583 struct cfg80211_chan_def chandef;
@@ -586,6 +595,7 @@ struct cfg80211_ap_settings {
586 u8 p2p_ctwindow; 595 u8 p2p_ctwindow;
587 bool p2p_opp_ps; 596 bool p2p_opp_ps;
588 const struct cfg80211_acl_data *acl; 597 const struct cfg80211_acl_data *acl;
598 bool radar_required;
589}; 599};
590 600
591/** 601/**
@@ -1909,6 +1919,8 @@ struct cfg80211_gtk_rekey_data {
1909 * this new list replaces the existing one. Driver has to clear its ACL 1919 * this new list replaces the existing one. Driver has to clear its ACL
1910 * when number of MAC addresses entries is passed as 0. Drivers which 1920 * when number of MAC addresses entries is passed as 0. Drivers which
1911 * advertise the support for MAC based ACL have to implement this callback. 1921 * advertise the support for MAC based ACL have to implement this callback.
1922 *
1923 * @start_radar_detection: Start radar detection in the driver.
1912 */ 1924 */
1913struct cfg80211_ops { 1925struct cfg80211_ops {
1914 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); 1926 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2132,6 +2144,10 @@ struct cfg80211_ops {
2132 2144
2133 int (*set_mac_acl)(struct wiphy *wiphy, struct net_device *dev, 2145 int (*set_mac_acl)(struct wiphy *wiphy, struct net_device *dev,
2134 const struct cfg80211_acl_data *params); 2146 const struct cfg80211_acl_data *params);
2147
2148 int (*start_radar_detection)(struct wiphy *wiphy,
2149 struct net_device *dev,
2150 struct cfg80211_chan_def *chandef);
2135}; 2151};
2136 2152
2137/* 2153/*
@@ -2715,6 +2731,8 @@ struct cfg80211_cached_keys;
2715 * beacons, 0 when not valid 2731 * beacons, 0 when not valid
2716 * @address: The address for this device, valid only if @netdev is %NULL 2732 * @address: The address for this device, valid only if @netdev is %NULL
2717 * @p2p_started: true if this is a P2P Device that has been started 2733 * @p2p_started: true if this is a P2P Device that has been started
2734 * @cac_started: true if DFS channel availability check has been started
2735 * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
2718 */ 2736 */
2719struct wireless_dev { 2737struct wireless_dev {
2720 struct wiphy *wiphy; 2738 struct wiphy *wiphy;
@@ -2766,6 +2784,9 @@ struct wireless_dev {
2766 2784
2767 u32 ap_unexpected_nlportid; 2785 u32 ap_unexpected_nlportid;
2768 2786
2787 bool cac_started;
2788 unsigned long cac_start_time;
2789
2769#ifdef CONFIG_CFG80211_WEXT 2790#ifdef CONFIG_CFG80211_WEXT
2770 /* wext data */ 2791 /* wext data */
2771 struct { 2792 struct {
@@ -3755,6 +3776,31 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
3755 gfp_t gfp); 3776 gfp_t gfp);
3756 3777
3757/** 3778/**
3779 * cfg80211_radar_event - radar detection event
3780 * @wiphy: the wiphy
3781 * @chandef: chandef for the current channel
3782 * @gfp: context flags
3783 *
3784 * This function is called when a radar is detected on the current chanenl.
3785 */
3786void cfg80211_radar_event(struct wiphy *wiphy,
3787 struct cfg80211_chan_def *chandef, gfp_t gfp);
3788
3789/**
3790 * cfg80211_cac_event - Channel availability check (CAC) event
3791 * @netdev: network device
3792 * @event: type of event
3793 * @gfp: context flags
3794 *
3795 * This function is called when a Channel availability check (CAC) is finished
3796 * or aborted. This must be called to notify the completion of a CAC process,
3797 * also by full-MAC drivers.
3798 */
3799void cfg80211_cac_event(struct net_device *netdev,
3800 enum nl80211_radar_event event, gfp_t gfp);
3801
3802
3803/**
3758 * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer 3804 * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer
3759 * @dev: network device 3805 * @dev: network device
3760 * @peer: peer's MAC address 3806 * @peer: peer's MAC address
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5309b34930ea..90b7af86f392 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -603,6 +603,14 @@
603 * command is used in AP/P2P GO mode. Driver has to make sure to clear its 603 * command is used in AP/P2P GO mode. Driver has to make sure to clear its
604 * ACL list during %NL80211_CMD_STOP_AP. 604 * ACL list during %NL80211_CMD_STOP_AP.
605 * 605 *
606 * @NL80211_CMD_RADAR_DETECT: Start a Channel availability check (CAC). Once
607 * a radar is detected or the channel availability scan (CAC) has finished
608 * or was aborted, or a radar was detected, usermode will be notified with
609 * this event. This command is also used to notify userspace about radars
610 * while operating on this channel.
611 * %NL80211_ATTR_RADAR_EVENT is used to inform about the type of the
612 * event.
613 *
606 * @NL80211_CMD_MAX: highest used command number 614 * @NL80211_CMD_MAX: highest used command number
607 * @__NL80211_CMD_AFTER_LAST: internal use 615 * @__NL80211_CMD_AFTER_LAST: internal use
608 */ 616 */
@@ -755,6 +763,8 @@ enum nl80211_commands {
755 763
756 NL80211_CMD_SET_MAC_ACL, 764 NL80211_CMD_SET_MAC_ACL,
757 765
766 NL80211_CMD_RADAR_DETECT,
767
758 /* add new commands above here */ 768 /* add new commands above here */
759 769
760 /* used to define NL80211_CMD_MAX below */ 770 /* used to define NL80211_CMD_MAX below */
@@ -1342,6 +1352,9 @@ enum nl80211_commands {
1342 * number of MAC addresses that a device can support for MAC 1352 * number of MAC addresses that a device can support for MAC
1343 * ACL. 1353 * ACL.
1344 * 1354 *
1355 * @NL80211_ATTR_RADAR_EVENT: Type of radar event for notification to userspace,
1356 * contains a value of enum nl80211_radar_event (u32).
1357 *
1345 * @NL80211_ATTR_MAX: highest attribute number currently defined 1358 * @NL80211_ATTR_MAX: highest attribute number currently defined
1346 * @__NL80211_ATTR_AFTER_LAST: internal use 1359 * @__NL80211_ATTR_AFTER_LAST: internal use
1347 */ 1360 */
@@ -1620,6 +1633,8 @@ enum nl80211_attrs {
1620 1633
1621 NL80211_ATTR_MAC_ACL_MAX, 1634 NL80211_ATTR_MAC_ACL_MAX,
1622 1635
1636 NL80211_ATTR_RADAR_EVENT,
1637
1623 /* add attributes here, update the policy in nl80211.c */ 1638 /* add attributes here, update the policy in nl80211.c */
1624 1639
1625 __NL80211_ATTR_AFTER_LAST, 1640 __NL80211_ATTR_AFTER_LAST,
@@ -2022,6 +2037,10 @@ enum nl80211_band_attr {
2022 * on this channel in current regulatory domain. 2037 * on this channel in current regulatory domain.
2023 * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm 2038 * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
2024 * (100 * dBm). 2039 * (100 * dBm).
2040 * @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS
2041 * (enum nl80211_dfs_state)
2042 * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in miliseconds for how long
2043 * this channel is in this DFS state.
2025 * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number 2044 * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
2026 * currently defined 2045 * currently defined
2027 * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use 2046 * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
@@ -2034,6 +2053,8 @@ enum nl80211_frequency_attr {
2034 NL80211_FREQUENCY_ATTR_NO_IBSS, 2053 NL80211_FREQUENCY_ATTR_NO_IBSS,
2035 NL80211_FREQUENCY_ATTR_RADAR, 2054 NL80211_FREQUENCY_ATTR_RADAR,
2036 NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2055 NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
2056 NL80211_FREQUENCY_ATTR_DFS_STATE,
2057 NL80211_FREQUENCY_ATTR_DFS_TIME,
2037 2058
2038 /* keep last */ 2059 /* keep last */
2039 __NL80211_FREQUENCY_ATTR_AFTER_LAST, 2060 __NL80211_FREQUENCY_ATTR_AFTER_LAST,
@@ -3489,4 +3510,44 @@ enum nl80211_acl_policy {
3489 NL80211_ACL_POLICY_DENY_UNLESS_LISTED, 3510 NL80211_ACL_POLICY_DENY_UNLESS_LISTED,
3490}; 3511};
3491 3512
3513/**
3514 * enum nl80211_radar_event - type of radar event for DFS operation
3515 *
3516 * Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace
3517 * about detected radars or success of the channel available check (CAC)
3518 *
3519 * @NL80211_RADAR_DETECTED: A radar pattern has been detected. The channel is
3520 * now unusable.
3521 * @NL80211_RADAR_CAC_FINISHED: Channel Availability Check has been finished,
3522 * the channel is now available.
3523 * @NL80211_RADAR_CAC_ABORTED: Channel Availability Check has been aborted, no
3524 * change to the channel status.
3525 * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
3526 * over, channel becomes usable.
3527 */
3528enum nl80211_radar_event {
3529 NL80211_RADAR_DETECTED,
3530 NL80211_RADAR_CAC_FINISHED,
3531 NL80211_RADAR_CAC_ABORTED,
3532 NL80211_RADAR_NOP_FINISHED,
3533};
3534
3535/**
3536 * enum nl80211_dfs_state - DFS states for channels
3537 *
3538 * Channel states used by the DFS code.
3539 *
3540 * @IEEE80211_DFS_USABLE: The channel can be used, but channel availability
3541 * check (CAC) must be performed before using it for AP or IBSS.
3542 * @IEEE80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it
3543 * is therefore marked as not available.
3544 * @IEEE80211_DFS_AVAILABLE: The channel has been CAC checked and is available.
3545 */
3546
3547enum nl80211_dfs_state {
3548 NL80211_DFS_USABLE,
3549 NL80211_DFS_UNAVAILABLE,
3550 NL80211_DFS_AVAILABLE,
3551};
3552
3492#endif /* __LINUX_NL80211_H */ 3553#endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 396373f3ec26..810c23cfb894 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -147,6 +147,32 @@ static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
147 } 147 }
148} 148}
149 149
150static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
151{
152 int width;
153
154 switch (c->width) {
155 case NL80211_CHAN_WIDTH_20:
156 case NL80211_CHAN_WIDTH_20_NOHT:
157 width = 20;
158 break;
159 case NL80211_CHAN_WIDTH_40:
160 width = 40;
161 break;
162 case NL80211_CHAN_WIDTH_80P80:
163 case NL80211_CHAN_WIDTH_80:
164 width = 80;
165 break;
166 case NL80211_CHAN_WIDTH_160:
167 width = 160;
168 break;
169 default:
170 WARN_ON_ONCE(1);
171 return -1;
172 }
173 return width;
174}
175
150const struct cfg80211_chan_def * 176const struct cfg80211_chan_def *
151cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1, 177cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
152 const struct cfg80211_chan_def *c2) 178 const struct cfg80211_chan_def *c2)
@@ -192,6 +218,93 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
192} 218}
193EXPORT_SYMBOL(cfg80211_chandef_compatible); 219EXPORT_SYMBOL(cfg80211_chandef_compatible);
194 220
221static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
222 u32 bandwidth,
223 enum nl80211_dfs_state dfs_state)
224{
225 struct ieee80211_channel *c;
226 u32 freq;
227
228 for (freq = center_freq - bandwidth/2 + 10;
229 freq <= center_freq + bandwidth/2 - 10;
230 freq += 20) {
231 c = ieee80211_get_channel(wiphy, freq);
232 if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
233 continue;
234
235 c->dfs_state = dfs_state;
236 c->dfs_state_entered = jiffies;
237 }
238}
239
240void cfg80211_set_dfs_state(struct wiphy *wiphy,
241 const struct cfg80211_chan_def *chandef,
242 enum nl80211_dfs_state dfs_state)
243{
244 int width;
245
246 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
247 return;
248
249 width = cfg80211_chandef_get_width(chandef);
250 if (width < 0)
251 return;
252
253 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
254 width, dfs_state);
255
256 if (!chandef->center_freq2)
257 return;
258 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
259 width, dfs_state);
260}
261
262static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
263 u32 center_freq,
264 u32 bandwidth)
265{
266 struct ieee80211_channel *c;
267 u32 freq;
268
269 for (freq = center_freq - bandwidth/2 + 10;
270 freq <= center_freq + bandwidth/2 - 10;
271 freq += 20) {
272 c = ieee80211_get_channel(wiphy, freq);
273 if (!c)
274 return -EINVAL;
275
276 if (c->flags & IEEE80211_CHAN_RADAR)
277 return 1;
278 }
279 return 0;
280}
281
282
283int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
284 const struct cfg80211_chan_def *chandef)
285{
286 int width;
287 int r;
288
289 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
290 return -EINVAL;
291
292 width = cfg80211_chandef_get_width(chandef);
293 if (width < 0)
294 return -EINVAL;
295
296 r = cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq1,
297 width);
298 if (r)
299 return r;
300
301 if (!chandef->center_freq2)
302 return 0;
303
304 return cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq2,
305 width);
306}
307
195static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 308static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
196 u32 center_freq, u32 bandwidth, 309 u32 center_freq, u32 bandwidth,
197 u32 prohibited_flags) 310 u32 prohibited_flags)
@@ -203,7 +316,16 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
203 freq <= center_freq + bandwidth/2 - 10; 316 freq <= center_freq + bandwidth/2 - 10;
204 freq += 20) { 317 freq += 20) {
205 c = ieee80211_get_channel(wiphy, freq); 318 c = ieee80211_get_channel(wiphy, freq);
206 if (!c || c->flags & prohibited_flags) 319 if (!c)
320 return false;
321
322 /* check for radar flags */
323 if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) &&
324 (c->dfs_state != NL80211_DFS_AVAILABLE))
325 return false;
326
327 /* check for the other flags */
328 if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR)
207 return false; 329 return false;
208 } 330 }
209 331
@@ -344,7 +466,10 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
344 break; 466 break;
345 case NL80211_IFTYPE_AP: 467 case NL80211_IFTYPE_AP:
346 case NL80211_IFTYPE_P2P_GO: 468 case NL80211_IFTYPE_P2P_GO:
347 if (wdev->beacon_interval) { 469 if (wdev->cac_started) {
470 *chan = wdev->channel;
471 *chanmode = CHAN_MODE_SHARED;
472 } else if (wdev->beacon_interval) {
348 *chan = wdev->channel; 473 *chan = wdev->channel;
349 *chanmode = CHAN_MODE_SHARED; 474 *chanmode = CHAN_MODE_SHARED;
350 } 475 }
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f0a1bbe95cff..922002105062 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -324,6 +324,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
324 INIT_LIST_HEAD(&rdev->bss_list); 324 INIT_LIST_HEAD(&rdev->bss_list);
325 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 325 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
326 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results); 326 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
327 INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk,
328 cfg80211_dfs_channels_update_work);
327#ifdef CONFIG_CFG80211_WEXT 329#ifdef CONFIG_CFG80211_WEXT
328 rdev->wiphy.wext = &cfg80211_wext_handler; 330 rdev->wiphy.wext = &cfg80211_wext_handler;
329#endif 331#endif
@@ -695,6 +697,7 @@ void wiphy_unregister(struct wiphy *wiphy)
695 flush_work(&rdev->scan_done_wk); 697 flush_work(&rdev->scan_done_wk);
696 cancel_work_sync(&rdev->conn_work); 698 cancel_work_sync(&rdev->conn_work);
697 flush_work(&rdev->event_work); 699 flush_work(&rdev->event_work);
700 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
698 701
699 if (rdev->wowlan && rdev->ops->set_wakeup) 702 if (rdev->wowlan && rdev->ops->set_wakeup)
700 rdev_set_wakeup(rdev, false); 703 rdev_set_wakeup(rdev, false);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 949c9573d8d7..3aec0e429d8a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -86,6 +86,8 @@ struct cfg80211_registered_device {
86 86
87 struct cfg80211_wowlan *wowlan; 87 struct cfg80211_wowlan *wowlan;
88 88
89 struct delayed_work dfs_update_channels_wk;
90
89 /* must be last because of the way we do wiphy_priv(), 91 /* must be last because of the way we do wiphy_priv(),
90 * and it should at least be aligned to NETDEV_ALIGN */ 92 * and it should at least be aligned to NETDEV_ALIGN */
91 struct wiphy wiphy __aligned(NETDEV_ALIGN); 93 struct wiphy wiphy __aligned(NETDEV_ALIGN);
@@ -431,6 +433,22 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
431 enum cfg80211_chan_mode chanmode, 433 enum cfg80211_chan_mode chanmode,
432 u8 radar_detect); 434 u8 radar_detect);
433 435
436/**
437 * cfg80211_chandef_dfs_required - checks if radar detection is required
438 * @wiphy: the wiphy to validate against
439 * @chandef: the channel definition to check
440 * Return: 1 if radar detection is required, 0 if it is not, < 0 on error
441 */
442int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
443 const struct cfg80211_chan_def *c);
444
445void cfg80211_set_dfs_state(struct wiphy *wiphy,
446 const struct cfg80211_chan_def *chandef,
447 enum nl80211_dfs_state dfs_state);
448
449void cfg80211_dfs_channels_update_work(struct work_struct *work);
450
451
434static inline int 452static inline int
435cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, 453cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
436 struct wireless_dev *wdev, 454 struct wireless_dev *wdev,
@@ -457,6 +475,16 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev,
457 chan, chanmode, 0); 475 chan, chanmode, 0);
458} 476}
459 477
478static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
479{
480 unsigned long end = jiffies;
481
482 if (end >= start)
483 return jiffies_to_msecs(end - start);
484
485 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
486}
487
460void 488void
461cfg80211_get_chan_state(struct wireless_dev *wdev, 489cfg80211_get_chan_state(struct wireless_dev *wdev,
462 struct ieee80211_channel **chan, 490 struct ieee80211_channel **chan,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 8e6920728c43..caddca35d686 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -987,3 +987,123 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
987 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); 987 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
988} 988}
989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); 989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
990
991void cfg80211_dfs_channels_update_work(struct work_struct *work)
992{
993 struct delayed_work *delayed_work;
994 struct cfg80211_registered_device *rdev;
995 struct cfg80211_chan_def chandef;
996 struct ieee80211_supported_band *sband;
997 struct ieee80211_channel *c;
998 struct wiphy *wiphy;
999 bool check_again = false;
1000 unsigned long timeout, next_time = 0;
1001 int bandid, i;
1002
1003 delayed_work = container_of(work, struct delayed_work, work);
1004 rdev = container_of(delayed_work, struct cfg80211_registered_device,
1005 dfs_update_channels_wk);
1006 wiphy = &rdev->wiphy;
1007
1008 mutex_lock(&cfg80211_mutex);
1009 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
1010 sband = wiphy->bands[bandid];
1011 if (!sband)
1012 continue;
1013
1014 for (i = 0; i < sband->n_channels; i++) {
1015 c = &sband->channels[i];
1016
1017 if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
1018 continue;
1019
1020 timeout = c->dfs_state_entered +
1021 IEEE80211_DFS_MIN_NOP_TIME_MS;
1022
1023 if (time_after_eq(jiffies, timeout)) {
1024 c->dfs_state = NL80211_DFS_USABLE;
1025 cfg80211_chandef_create(&chandef, c,
1026 NL80211_CHAN_NO_HT);
1027
1028 nl80211_radar_notify(rdev, &chandef,
1029 NL80211_RADAR_NOP_FINISHED,
1030 NULL, GFP_ATOMIC);
1031 continue;
1032 }
1033
1034 if (!check_again)
1035 next_time = timeout - jiffies;
1036 else
1037 next_time = min(next_time, timeout - jiffies);
1038 check_again = true;
1039 }
1040 }
1041 mutex_unlock(&cfg80211_mutex);
1042
1043 /* reschedule if there are other channels waiting to be cleared again */
1044 if (check_again)
1045 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
1046 next_time);
1047}
1048
1049
1050void cfg80211_radar_event(struct wiphy *wiphy,
1051 struct cfg80211_chan_def *chandef,
1052 gfp_t gfp)
1053{
1054 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1055 unsigned long timeout;
1056
1057 trace_cfg80211_radar_event(wiphy, chandef);
1058
1059 /* only set the chandef supplied channel to unavailable, in
1060 * case the radar is detected on only one of multiple channels
1061 * spanned by the chandef.
1062 */
1063 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
1064
1065 timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
1066 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
1067 timeout);
1068
1069 nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
1070}
1071EXPORT_SYMBOL(cfg80211_radar_event);
1072
1073void cfg80211_cac_event(struct net_device *netdev,
1074 enum nl80211_radar_event event, gfp_t gfp)
1075{
1076 struct wireless_dev *wdev = netdev->ieee80211_ptr;
1077 struct wiphy *wiphy = wdev->wiphy;
1078 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1079 struct cfg80211_chan_def chandef;
1080 unsigned long timeout;
1081
1082 trace_cfg80211_cac_event(netdev, event);
1083
1084 if (WARN_ON(!wdev->cac_started))
1085 return;
1086
1087 if (WARN_ON(!wdev->channel))
1088 return;
1089
1090 cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT);
1091
1092 switch (event) {
1093 case NL80211_RADAR_CAC_FINISHED:
1094 timeout = wdev->cac_start_time +
1095 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
1096 WARN_ON(!time_after_eq(jiffies, timeout));
1097 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE);
1098 break;
1099 case NL80211_RADAR_CAC_ABORTED:
1100 break;
1101 default:
1102 WARN_ON(1);
1103 return;
1104 }
1105 wdev->cac_started = false;
1106
1107 nl80211_radar_notify(rdev, &chandef, event, netdev, gfp);
1108}
1109EXPORT_SYMBOL(cfg80211_cac_event);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d29a461b4981..c1e18ccf4049 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -552,9 +552,16 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
552 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && 552 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
553 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) 553 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
554 goto nla_put_failure; 554 goto nla_put_failure;
555 if ((chan->flags & IEEE80211_CHAN_RADAR) && 555 if (chan->flags & IEEE80211_CHAN_RADAR) {
556 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) 556 u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
557 goto nla_put_failure; 557 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
558 goto nla_put_failure;
559 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
560 chan->dfs_state))
561 goto nla_put_failure;
562 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time))
563 goto nla_put_failure;
564 }
558 565
559 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 566 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
560 DBM_TO_MBM(chan->max_power))) 567 DBM_TO_MBM(chan->max_power)))
@@ -2775,6 +2782,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2775 struct wireless_dev *wdev = dev->ieee80211_ptr; 2782 struct wireless_dev *wdev = dev->ieee80211_ptr;
2776 struct cfg80211_ap_settings params; 2783 struct cfg80211_ap_settings params;
2777 int err; 2784 int err;
2785 u8 radar_detect_width = 0;
2778 2786
2779 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2787 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2780 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2788 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
@@ -2893,9 +2901,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2893 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef)) 2901 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
2894 return -EINVAL; 2902 return -EINVAL;
2895 2903
2904 err = cfg80211_chandef_dfs_required(wdev->wiphy, &params.chandef);
2905 if (err < 0)
2906 return err;
2907 if (err) {
2908 radar_detect_width = BIT(params.chandef.width);
2909 params.radar_required = true;
2910 }
2911
2896 mutex_lock(&rdev->devlist_mtx); 2912 mutex_lock(&rdev->devlist_mtx);
2897 err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan, 2913 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
2898 CHAN_MODE_SHARED); 2914 params.chandef.chan,
2915 CHAN_MODE_SHARED,
2916 radar_detect_width);
2899 mutex_unlock(&rdev->devlist_mtx); 2917 mutex_unlock(&rdev->devlist_mtx);
2900 2918
2901 if (err) 2919 if (err)
@@ -5055,6 +5073,54 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
5055 return err; 5073 return err;
5056} 5074}
5057 5075
5076static int nl80211_start_radar_detection(struct sk_buff *skb,
5077 struct genl_info *info)
5078{
5079 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5080 struct net_device *dev = info->user_ptr[1];
5081 struct wireless_dev *wdev = dev->ieee80211_ptr;
5082 struct cfg80211_chan_def chandef;
5083 int err;
5084
5085 err = nl80211_parse_chandef(rdev, info, &chandef);
5086 if (err)
5087 return err;
5088
5089 if (wdev->cac_started)
5090 return -EBUSY;
5091
5092 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef);
5093 if (err < 0)
5094 return err;
5095
5096 if (err == 0)
5097 return -EINVAL;
5098
5099 if (chandef.chan->dfs_state != NL80211_DFS_USABLE)
5100 return -EINVAL;
5101
5102 if (!rdev->ops->start_radar_detection)
5103 return -EOPNOTSUPP;
5104
5105 mutex_lock(&rdev->devlist_mtx);
5106 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5107 chandef.chan, CHAN_MODE_SHARED,
5108 BIT(chandef.width));
5109 if (err)
5110 goto err_locked;
5111
5112 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5113 if (!err) {
5114 wdev->channel = chandef.chan;
5115 wdev->cac_started = true;
5116 wdev->cac_start_time = jiffies;
5117 }
5118err_locked:
5119 mutex_unlock(&rdev->devlist_mtx);
5120
5121 return err;
5122}
5123
5058static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, 5124static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5059 u32 seq, int flags, 5125 u32 seq, int flags,
5060 struct cfg80211_registered_device *rdev, 5126 struct cfg80211_registered_device *rdev,
@@ -8305,6 +8371,14 @@ static struct genl_ops nl80211_ops[] = {
8305 .internal_flags = NL80211_FLAG_NEED_NETDEV | 8371 .internal_flags = NL80211_FLAG_NEED_NETDEV |
8306 NL80211_FLAG_NEED_RTNL, 8372 NL80211_FLAG_NEED_RTNL,
8307 }, 8373 },
8374 {
8375 .cmd = NL80211_CMD_RADAR_DETECT,
8376 .doit = nl80211_start_radar_detection,
8377 .policy = nl80211_policy,
8378 .flags = GENL_ADMIN_PERM,
8379 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
8380 NL80211_FLAG_NEED_RTNL,
8381 },
8308}; 8382};
8309 8383
8310static struct genl_multicast_group nl80211_mlme_mcgrp = { 8384static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -9502,6 +9576,57 @@ nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev,
9502} 9576}
9503 9577
9504void 9578void
9579nl80211_radar_notify(struct cfg80211_registered_device *rdev,
9580 struct cfg80211_chan_def *chandef,
9581 enum nl80211_radar_event event,
9582 struct net_device *netdev, gfp_t gfp)
9583{
9584 struct sk_buff *msg;
9585 void *hdr;
9586
9587 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9588 if (!msg)
9589 return;
9590
9591 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
9592 if (!hdr) {
9593 nlmsg_free(msg);
9594 return;
9595 }
9596
9597 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
9598 goto nla_put_failure;
9599
9600 /* NOP and radar events don't need a netdev parameter */
9601 if (netdev) {
9602 struct wireless_dev *wdev = netdev->ieee80211_ptr;
9603
9604 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
9605 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
9606 goto nla_put_failure;
9607 }
9608
9609 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
9610 goto nla_put_failure;
9611
9612 if (nl80211_send_chandef(msg, chandef))
9613 goto nla_put_failure;
9614
9615 if (genlmsg_end(msg, hdr) < 0) {
9616 nlmsg_free(msg);
9617 return;
9618 }
9619
9620 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
9621 nl80211_mlme_mcgrp.id, gfp);
9622 return;
9623
9624 nla_put_failure:
9625 genlmsg_cancel(msg, hdr);
9626 nlmsg_free(msg);
9627}
9628
9629void
9505nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 9630nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
9506 struct net_device *netdev, const u8 *peer, 9631 struct net_device *netdev, const u8 *peer,
9507 u32 num_packets, gfp_t gfp) 9632 u32 num_packets, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 2acba8477e9d..b061da4919e1 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -108,6 +108,13 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
108 struct net_device *netdev, 108 struct net_device *netdev,
109 enum nl80211_cqm_rssi_threshold_event rssi_event, 109 enum nl80211_cqm_rssi_threshold_event rssi_event,
110 gfp_t gfp); 110 gfp_t gfp);
111
112void
113nl80211_radar_notify(struct cfg80211_registered_device *rdev,
114 struct cfg80211_chan_def *chandef,
115 enum nl80211_radar_event event,
116 struct net_device *netdev, gfp_t gfp);
117
111void 118void
112nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 119nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
113 struct net_device *netdev, const u8 *peer, 120 struct net_device *netdev, const u8 *peer,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 08d3da2c70ab..e97d5b071ab6 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -884,6 +884,9 @@ static void handle_channel(struct wiphy *wiphy,
884 return; 884 return;
885 } 885 }
886 886
887 chan->dfs_state = NL80211_DFS_USABLE;
888 chan->dfs_state_entered = jiffies;
889
887 chan->beacon_found = false; 890 chan->beacon_found = false;
888 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); 891 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
889 chan->max_antenna_gain = 892 chan->max_antenna_gain =
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index d0fc6da2d097..f0d9b5154bab 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1210,16 +1210,6 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
1210 } 1210 }
1211} 1211}
1212 1212
1213static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
1214{
1215 unsigned long end = jiffies;
1216
1217 if (end >= start)
1218 return jiffies_to_msecs(end - start);
1219
1220 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
1221}
1222
1223static char * 1213static char *
1224ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, 1214ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1225 struct cfg80211_internal_bss *bss, char *current_ev, 1215 struct cfg80211_internal_bss *bss, char *current_ev,
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index c9cafb0ea95f..b7a531380e19 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2051,6 +2051,21 @@ TRACE_EVENT(cfg80211_reg_can_beacon,
2051 WIPHY_PR_ARG, CHAN_DEF_PR_ARG) 2051 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2052); 2052);
2053 2053
2054TRACE_EVENT(cfg80211_chandef_dfs_required,
2055 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
2056 TP_ARGS(wiphy, chandef),
2057 TP_STRUCT__entry(
2058 WIPHY_ENTRY
2059 CHAN_DEF_ENTRY
2060 ),
2061 TP_fast_assign(
2062 WIPHY_ASSIGN;
2063 CHAN_DEF_ASSIGN(chandef);
2064 ),
2065 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
2066 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2067);
2068
2054TRACE_EVENT(cfg80211_ch_switch_notify, 2069TRACE_EVENT(cfg80211_ch_switch_notify,
2055 TP_PROTO(struct net_device *netdev, 2070 TP_PROTO(struct net_device *netdev,
2056 struct cfg80211_chan_def *chandef), 2071 struct cfg80211_chan_def *chandef),
@@ -2067,6 +2082,36 @@ TRACE_EVENT(cfg80211_ch_switch_notify,
2067 NETDEV_PR_ARG, CHAN_DEF_PR_ARG) 2082 NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
2068); 2083);
2069 2084
2085TRACE_EVENT(cfg80211_radar_event,
2086 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
2087 TP_ARGS(wiphy, chandef),
2088 TP_STRUCT__entry(
2089 WIPHY_ENTRY
2090 CHAN_DEF_ENTRY
2091 ),
2092 TP_fast_assign(
2093 WIPHY_ASSIGN;
2094 CHAN_DEF_ASSIGN(chandef);
2095 ),
2096 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
2097 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2098);
2099
2100TRACE_EVENT(cfg80211_cac_event,
2101 TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt),
2102 TP_ARGS(netdev, evt),
2103 TP_STRUCT__entry(
2104 NETDEV_ENTRY
2105 __field(enum nl80211_radar_event, evt)
2106 ),
2107 TP_fast_assign(
2108 NETDEV_ASSIGN;
2109 __entry->evt = evt;
2110 ),
2111 TP_printk(NETDEV_PR_FMT ", event: %d",
2112 NETDEV_PR_ARG, __entry->evt)
2113);
2114
2070DECLARE_EVENT_CLASS(cfg80211_rx_evt, 2115DECLARE_EVENT_CLASS(cfg80211_rx_evt,
2071 TP_PROTO(struct net_device *netdev, const u8 *addr), 2116 TP_PROTO(struct net_device *netdev, const u8 *addr),
2072 TP_ARGS(netdev, addr), 2117 TP_ARGS(netdev, addr),