aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>2014-02-21 13:46:13 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-02-25 11:32:54 -0500
commit31559f35c5724976fd975e5d7e90cdb693b8dd27 (patch)
tree92f0a7e9a2474e730a2461c1e284cb16f77d1b4b
parent089027e57cfa79337feffdd7252c8ba0be352afa (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>
-rw-r--r--include/net/cfg80211.h5
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/wireless/chan.c56
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/mlme.c2
-rw-r--r--net/wireless/nl80211.c9
6 files changed, 76 insertions, 7 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bfa9a0c7b2d7..ff3af16eba21 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2505,7 +2505,8 @@ struct cfg80211_ops {
2505 2505
2506 int (*start_radar_detection)(struct wiphy *wiphy, 2506 int (*start_radar_detection)(struct wiphy *wiphy,
2507 struct net_device *dev, 2507 struct net_device *dev,
2508 struct cfg80211_chan_def *chandef); 2508 struct cfg80211_chan_def *chandef,
2509 u32 cac_time_ms);
2509 int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev, 2510 int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
2510 struct cfg80211_update_ft_ies_params *ftie); 2511 struct cfg80211_update_ft_ies_params *ftie);
2511 int (*crit_proto_start)(struct wiphy *wiphy, 2512 int (*crit_proto_start)(struct wiphy *wiphy,
@@ -3182,6 +3183,7 @@ struct cfg80211_cached_keys;
3182 * @p2p_started: true if this is a P2P Device that has been started 3183 * @p2p_started: true if this is a P2P Device that has been started
3183 * @cac_started: true if DFS channel availability check has been started 3184 * @cac_started: true if DFS channel availability check has been started
3184 * @cac_start_time: timestamp (jiffies) when the dfs state was entered. 3185 * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
3186 * @cac_time_ms: CAC time in ms
3185 * @ps: powersave mode is enabled 3187 * @ps: powersave mode is enabled
3186 * @ps_timeout: dynamic powersave timeout 3188 * @ps_timeout: dynamic powersave timeout
3187 * @ap_unexpected_nlportid: (private) netlink port ID of application 3189 * @ap_unexpected_nlportid: (private) netlink port ID of application
@@ -3237,6 +3239,7 @@ struct wireless_dev {
3237 3239
3238 bool cac_started; 3240 bool cac_started;
3239 unsigned long cac_start_time; 3241 unsigned long cac_start_time;
3242 unsigned int cac_time_ms;
3240 3243
3241#ifdef CONFIG_CFG80211_WEXT 3244#ifdef CONFIG_CFG80211_WEXT
3242 /* wext data */ 3245 /* wext data */
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
2915static int ieee80211_start_radar_detection(struct wiphy *wiphy, 2915static 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
493static 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
522unsigned int
523cfg80211_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
494static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 550static 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
403void cfg80211_dfs_channels_update_work(struct work_struct *work); 403void cfg80211_dfs_channels_update_work(struct work_struct *work);
404 404
405unsigned int
406cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
407 const struct cfg80211_chan_def *chandef);
405 408
406static inline int 409static inline int
407cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, 410cfg80211_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}