summaryrefslogtreecommitdiffstats
path: root/net/wireless/chan.c
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2014-02-23 02:13:01 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-04-09 04:55:34 -0400
commit174e0cd28af0fe3c6c634c3e4d9e042c683bd7f7 (patch)
tree047a3e0b02e6e5bb41324cd4571ef6251cd5fa79 /net/wireless/chan.c
parent94fc661f68c881eaa3a5904c12a2269372aa94d9 (diff)
cfg80211: Enable GO operation on additional channels
Allow GO operation on a channel marked with IEEE80211_CHAN_GO_CONCURRENT iff there is an active station interface that is associated to an AP operating on the same channel in the 2 GHz band or the same UNII band (in the 5 GHz band). This relaxation is not allowed if the channel is marked with IEEE80211_CHAN_RADAR. Note that this is a permissive approach to the FCC definitions, that require a clear assessment that the device operating the AP is an authorized master, i.e., with radar detection and DFS capabilities. It is assumed that such restrictions are enforced by user space. Furthermore, it is assumed, that if the conditions that allowed for the operation of the GO on such a channel change, i.e., the station interface disconnected from the AP, it is the responsibility of user space to evacuate the GO from the channel. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/chan.c')
-rw-r--r--net/wireless/chan.c76
1 files changed, 73 insertions, 3 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 9c9501a35fb5..50202af7fba3 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -661,15 +661,85 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
661} 661}
662EXPORT_SYMBOL(cfg80211_chandef_usable); 662EXPORT_SYMBOL(cfg80211_chandef_usable);
663 663
664/*
665 * For GO only, check if the channel can be used under permissive conditions
666 * mandated by the some regulatory bodies, i.e., the channel is marked with
667 * IEEE80211_CHAN_GO_CONCURRENT and there is an additional station interface
668 * associated to an AP on the same channel or on the same UNII band
669 * (assuming that the AP is an authorized master).
670 */
671static bool cfg80211_go_permissive_chan(struct cfg80211_registered_device *rdev,
672 struct ieee80211_channel *chan)
673{
674 struct wireless_dev *wdev_iter;
675 struct wiphy *wiphy = wiphy_idx_to_wiphy(rdev->wiphy_idx);
676
677 ASSERT_RTNL();
678
679 if (!config_enabled(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
680 !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR) ||
681 !(chan->flags & IEEE80211_CHAN_GO_CONCURRENT))
682 return false;
683
684 /*
685 * Generally, it is possible to rely on another device/driver to allow
686 * the GO concurrent relaxation, however, since the device can further
687 * enforce the relaxation (by doing a similar verifications as this),
688 * and thus fail the GO instantiation, consider only the interfaces of
689 * the current registered device.
690 */
691 list_for_each_entry(wdev_iter, &rdev->wdev_list, list) {
692 struct ieee80211_channel *other_chan = NULL;
693 int r1, r2;
694
695 if (wdev_iter->iftype != NL80211_IFTYPE_STATION ||
696 !netif_running(wdev_iter->netdev))
697 continue;
698
699 wdev_lock(wdev_iter);
700 if (wdev_iter->current_bss)
701 other_chan = wdev_iter->current_bss->pub.channel;
702 wdev_unlock(wdev_iter);
703
704 if (!other_chan)
705 continue;
706
707 if (chan == other_chan)
708 return true;
709
710 if (chan->band != IEEE80211_BAND_5GHZ)
711 continue;
712
713 r1 = cfg80211_get_unii(chan->center_freq);
714 r2 = cfg80211_get_unii(other_chan->center_freq);
715
716 if (r1 != -EINVAL && r1 == r2)
717 return true;
718 }
719
720 return false;
721}
722
664bool cfg80211_reg_can_beacon(struct wiphy *wiphy, 723bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
665 struct cfg80211_chan_def *chandef) 724 struct cfg80211_chan_def *chandef,
725 enum nl80211_iftype iftype)
666{ 726{
727 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
667 bool res; 728 bool res;
668 u32 prohibited_flags = IEEE80211_CHAN_DISABLED | 729 u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
669 IEEE80211_CHAN_NO_IR |
670 IEEE80211_CHAN_RADAR; 730 IEEE80211_CHAN_RADAR;
671 731
672 trace_cfg80211_reg_can_beacon(wiphy, chandef); 732 trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype);
733
734 /*
735 * Under certain conditions suggested by the some regulatory bodies
736 * a GO can operate on channels marked with IEEE80211_NO_IR
737 * so set this flag only if such relaxations are not enabled and
738 * the conditions are not met.
739 */
740 if (iftype != NL80211_IFTYPE_P2P_GO ||
741 !cfg80211_go_permissive_chan(rdev, chandef->chan))
742 prohibited_flags |= IEEE80211_CHAN_NO_IR;
673 743
674 if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 && 744 if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 &&
675 cfg80211_chandef_dfs_available(wiphy, chandef)) { 745 cfg80211_chandef_dfs_available(wiphy, chandef)) {