aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/chan.c
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-01-29 08:22:27 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-02-04 15:58:17 -0500
commit9e0e29615a2077be852b1245b57c5b00fa609522 (patch)
tree73d899373e01efe1fd72a895d8e2fe2f6bc8fcb2 /net/wireless/chan.c
parentfe94f3a4ffaa20c7470038c69ffc8e545ef5f90a (diff)
cfg80211: consider existing DFS interfaces
It was possible to break interface combinations in the following way: combo 1: iftype = AP, num_ifaces = 2, num_chans = 2, combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20 With the above interface combinations it was possible to: step 1. start AP on DFS channel by matching combo 2 step 2. start AP on non-DFS channel by matching combo 1 This was possible beacuse (step 2) did not consider if other interfaces require radar detection. The patch changes how cfg80211 tracks channels - instead of channel itself now a complete chandef is stored. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/chan.c')
-rw-r--r--net/wireless/chan.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 78559b5bbd1f..f8ab7df1ab0d 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
642void 642void
643cfg80211_get_chan_state(struct wireless_dev *wdev, 643cfg80211_get_chan_state(struct wireless_dev *wdev,
644 struct ieee80211_channel **chan, 644 struct ieee80211_channel **chan,
645 enum cfg80211_chan_mode *chanmode) 645 enum cfg80211_chan_mode *chanmode,
646 u8 *radar_detect)
646{ 647{
647 *chan = NULL; 648 *chan = NULL;
648 *chanmode = CHAN_MODE_UNDEFINED; 649 *chanmode = CHAN_MODE_UNDEFINED;
@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
660 !wdev->ibss_dfs_possible) 661 !wdev->ibss_dfs_possible)
661 ? CHAN_MODE_SHARED 662 ? CHAN_MODE_SHARED
662 : CHAN_MODE_EXCLUSIVE; 663 : CHAN_MODE_EXCLUSIVE;
664
665 /* consider worst-case - IBSS can try to return to the
666 * original user-specified channel as creator */
667 if (wdev->ibss_dfs_possible)
668 *radar_detect |= BIT(wdev->chandef.width);
663 return; 669 return;
664 } 670 }
665 break; 671 break;
@@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
674 case NL80211_IFTYPE_AP: 680 case NL80211_IFTYPE_AP:
675 case NL80211_IFTYPE_P2P_GO: 681 case NL80211_IFTYPE_P2P_GO:
676 if (wdev->cac_started) { 682 if (wdev->cac_started) {
677 *chan = wdev->channel; 683 *chan = wdev->chandef.chan;
678 *chanmode = CHAN_MODE_SHARED; 684 *chanmode = CHAN_MODE_SHARED;
685 *radar_detect |= BIT(wdev->chandef.width);
679 } else if (wdev->beacon_interval) { 686 } else if (wdev->beacon_interval) {
680 *chan = wdev->channel; 687 *chan = wdev->chandef.chan;
681 *chanmode = CHAN_MODE_SHARED; 688 *chanmode = CHAN_MODE_SHARED;
689
690 if (cfg80211_chandef_dfs_required(wdev->wiphy,
691 &wdev->chandef))
692 *radar_detect |= BIT(wdev->chandef.width);
682 } 693 }
683 return; 694 return;
684 case NL80211_IFTYPE_MESH_POINT: 695 case NL80211_IFTYPE_MESH_POINT:
685 if (wdev->mesh_id_len) { 696 if (wdev->mesh_id_len) {
686 *chan = wdev->channel; 697 *chan = wdev->chandef.chan;
687 *chanmode = CHAN_MODE_SHARED; 698 *chanmode = CHAN_MODE_SHARED;
699
700 if (cfg80211_chandef_dfs_required(wdev->wiphy,
701 &wdev->chandef))
702 *radar_detect |= BIT(wdev->chandef.width);
688 } 703 }
689 return; 704 return;
690 case NL80211_IFTYPE_MONITOR: 705 case NL80211_IFTYPE_MONITOR: