diff options
author | Janusz Dziedzic <janusz.dziedzic@tieto.com> | 2014-02-21 13:46:13 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-02-25 11:32:54 -0500 |
commit | 31559f35c5724976fd975e5d7e90cdb693b8dd27 (patch) | |
tree | 92f0a7e9a2474e730a2461c1e284cb16f77d1b4b /net | |
parent | 089027e57cfa79337feffdd7252c8ba0be352afa (diff) |
cfg80211: DFS get CAC time from regulatory database
Send Channel Availability Check time as a parameter
of start_radar_detection() callback.
Get CAC time from regulatory database.
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 8 | ||||
-rw-r--r-- | net/wireless/chan.c | 56 | ||||
-rw-r--r-- | net/wireless/core.h | 3 | ||||
-rw-r--r-- | net/wireless/mlme.c | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 9 |
5 files changed, 72 insertions, 6 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1acb29109b45..80534f524fd6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2914,11 +2914,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, | |||
2914 | 2914 | ||
2915 | static int ieee80211_start_radar_detection(struct wiphy *wiphy, | 2915 | static int ieee80211_start_radar_detection(struct wiphy *wiphy, |
2916 | struct net_device *dev, | 2916 | struct net_device *dev, |
2917 | struct cfg80211_chan_def *chandef) | 2917 | struct cfg80211_chan_def *chandef, |
2918 | u32 cac_time_ms) | ||
2918 | { | 2919 | { |
2919 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2920 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2920 | struct ieee80211_local *local = sdata->local; | 2921 | struct ieee80211_local *local = sdata->local; |
2921 | unsigned long timeout; | ||
2922 | int err; | 2922 | int err; |
2923 | 2923 | ||
2924 | mutex_lock(&local->mtx); | 2924 | mutex_lock(&local->mtx); |
@@ -2937,9 +2937,9 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy, | |||
2937 | if (err) | 2937 | if (err) |
2938 | goto out_unlock; | 2938 | goto out_unlock; |
2939 | 2939 | ||
2940 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); | ||
2941 | ieee80211_queue_delayed_work(&sdata->local->hw, | 2940 | ieee80211_queue_delayed_work(&sdata->local->hw, |
2942 | &sdata->dfs_cac_timer_work, timeout); | 2941 | &sdata->dfs_cac_timer_work, |
2942 | msecs_to_jiffies(cac_time_ms)); | ||
2943 | 2943 | ||
2944 | out_unlock: | 2944 | out_unlock: |
2945 | mutex_unlock(&local->mtx); | 2945 | mutex_unlock(&local->mtx); |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 5946450c5406..8659d5cee2a6 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -490,6 +490,62 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy, | |||
490 | return r; | 490 | return r; |
491 | } | 491 | } |
492 | 492 | ||
493 | static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy, | ||
494 | u32 center_freq, | ||
495 | u32 bandwidth) | ||
496 | { | ||
497 | struct ieee80211_channel *c; | ||
498 | u32 start_freq, end_freq, freq; | ||
499 | unsigned int dfs_cac_ms = 0; | ||
500 | |||
501 | start_freq = cfg80211_get_start_freq(center_freq, bandwidth); | ||
502 | end_freq = cfg80211_get_end_freq(center_freq, bandwidth); | ||
503 | |||
504 | for (freq = start_freq; freq <= end_freq; freq += 20) { | ||
505 | c = ieee80211_get_channel(wiphy, freq); | ||
506 | if (!c) | ||
507 | return 0; | ||
508 | |||
509 | if (c->flags & IEEE80211_CHAN_DISABLED) | ||
510 | return 0; | ||
511 | |||
512 | if (!(c->flags & IEEE80211_CHAN_RADAR)) | ||
513 | continue; | ||
514 | |||
515 | if (c->dfs_cac_ms > dfs_cac_ms) | ||
516 | dfs_cac_ms = c->dfs_cac_ms; | ||
517 | } | ||
518 | |||
519 | return dfs_cac_ms; | ||
520 | } | ||
521 | |||
522 | unsigned int | ||
523 | cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, | ||
524 | const struct cfg80211_chan_def *chandef) | ||
525 | { | ||
526 | int width; | ||
527 | unsigned int t1 = 0, t2 = 0; | ||
528 | |||
529 | if (WARN_ON(!cfg80211_chandef_valid(chandef))) | ||
530 | return 0; | ||
531 | |||
532 | width = cfg80211_chandef_get_width(chandef); | ||
533 | if (width < 0) | ||
534 | return 0; | ||
535 | |||
536 | t1 = cfg80211_get_chans_dfs_cac_time(wiphy, | ||
537 | chandef->center_freq1, | ||
538 | width); | ||
539 | |||
540 | if (!chandef->center_freq2) | ||
541 | return t1; | ||
542 | |||
543 | t2 = cfg80211_get_chans_dfs_cac_time(wiphy, | ||
544 | chandef->center_freq2, | ||
545 | width); | ||
546 | |||
547 | return max(t1, t2); | ||
548 | } | ||
493 | 549 | ||
494 | static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, | 550 | static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, |
495 | u32 center_freq, u32 bandwidth, | 551 | u32 center_freq, u32 bandwidth, |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 40683004d523..64fde38c1a7e 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -402,6 +402,9 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy, | |||
402 | 402 | ||
403 | void cfg80211_dfs_channels_update_work(struct work_struct *work); | 403 | void cfg80211_dfs_channels_update_work(struct work_struct *work); |
404 | 404 | ||
405 | unsigned int | ||
406 | cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, | ||
407 | const struct cfg80211_chan_def *chandef); | ||
405 | 408 | ||
406 | static inline int | 409 | static inline int |
407 | cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | 410 | cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index d47c9d127b1e..c52ff59a3e96 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -778,7 +778,7 @@ void cfg80211_cac_event(struct net_device *netdev, | |||
778 | switch (event) { | 778 | switch (event) { |
779 | case NL80211_RADAR_CAC_FINISHED: | 779 | case NL80211_RADAR_CAC_FINISHED: |
780 | timeout = wdev->cac_start_time + | 780 | timeout = wdev->cac_start_time + |
781 | msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); | 781 | msecs_to_jiffies(wdev->cac_time_ms); |
782 | WARN_ON(!time_after_eq(jiffies, timeout)); | 782 | WARN_ON(!time_after_eq(jiffies, timeout)); |
783 | cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); | 783 | cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); |
784 | break; | 784 | break; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9f7ebf94a050..8fa02a3fa7f7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -5779,6 +5779,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, | |||
5779 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 5779 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
5780 | struct cfg80211_chan_def chandef; | 5780 | struct cfg80211_chan_def chandef; |
5781 | enum nl80211_dfs_regions dfs_region; | 5781 | enum nl80211_dfs_regions dfs_region; |
5782 | unsigned int cac_time_ms; | ||
5782 | int err; | 5783 | int err; |
5783 | 5784 | ||
5784 | dfs_region = reg_get_dfs_region(wdev->wiphy); | 5785 | dfs_region = reg_get_dfs_region(wdev->wiphy); |
@@ -5814,11 +5815,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, | |||
5814 | if (err) | 5815 | if (err) |
5815 | return err; | 5816 | return err; |
5816 | 5817 | ||
5817 | err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); | 5818 | cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); |
5819 | if (WARN_ON(!cac_time_ms)) | ||
5820 | cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; | ||
5821 | |||
5822 | err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef, | ||
5823 | cac_time_ms); | ||
5818 | if (!err) { | 5824 | if (!err) { |
5819 | wdev->chandef = chandef; | 5825 | wdev->chandef = chandef; |
5820 | wdev->cac_started = true; | 5826 | wdev->cac_started = true; |
5821 | wdev->cac_start_time = jiffies; | 5827 | wdev->cac_start_time = jiffies; |
5828 | wdev->cac_time_ms = cac_time_ms; | ||
5822 | } | 5829 | } |
5823 | return err; | 5830 | return err; |
5824 | } | 5831 | } |