aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c54
1 files changed, 13 insertions, 41 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0cd548267d4a..2ff7376f35a3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -701,15 +701,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
701 701
702 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 702 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
703 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 703 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
704 struct ieee80211_channel *chan;
705 struct ieee80211_sta_ht_cap *ht_cap;
706 u32 freq; 704 u32 freq;
707 705
708 if (!rdev->ops->set_channel) {
709 result = -EOPNOTSUPP;
710 goto bad_res;
711 }
712
713 result = -EINVAL; 706 result = -EINVAL;
714 707
715 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 708 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
@@ -723,42 +716,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
723 } 716 }
724 717
725 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 718 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
726 chan = ieee80211_get_channel(&rdev->wiphy, freq);
727
728 /* Primary channel not allowed */
729 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
730 goto bad_res;
731
732 if (channel_type == NL80211_CHAN_HT40MINUS &&
733 (chan->flags & IEEE80211_CHAN_NO_HT40MINUS))
734 goto bad_res;
735 else if (channel_type == NL80211_CHAN_HT40PLUS &&
736 (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
737 goto bad_res;
738
739 /*
740 * At this point we know if that if HT40 was requested
741 * we are allowed to use it and the extension channel
742 * exists.
743 */
744 719
745 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap; 720 mutex_lock(&rdev->devlist_mtx);
746 721 result = rdev_set_freq(rdev, freq, channel_type);
747 /* no HT capabilities or intolerant */ 722 mutex_unlock(&rdev->devlist_mtx);
748 if (channel_type != NL80211_CHAN_NO_HT) {
749 if (!ht_cap->ht_supported)
750 goto bad_res;
751 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
752 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
753 goto bad_res;
754 }
755
756 result = rdev->ops->set_channel(&rdev->wiphy, chan,
757 channel_type);
758 if (result) 723 if (result)
759 goto bad_res; 724 goto bad_res;
760
761 rdev->channel = chan;
762 } 725 }
763 726
764 changed = 0; 727 changed = 0;
@@ -3453,7 +3416,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3453 struct cfg80211_registered_device *rdev; 3416 struct cfg80211_registered_device *rdev;
3454 struct net_device *dev; 3417 struct net_device *dev;
3455 struct cfg80211_crypto_settings crypto; 3418 struct cfg80211_crypto_settings crypto;
3456 struct ieee80211_channel *chan; 3419 struct ieee80211_channel *chan, *fixedchan;
3457 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; 3420 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
3458 int err, ssid_len, ie_len = 0; 3421 int err, ssid_len, ie_len = 0;
3459 bool use_mfp = false; 3422 bool use_mfp = false;
@@ -3496,6 +3459,15 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3496 goto out; 3459 goto out;
3497 } 3460 }
3498 3461
3462 mutex_lock(&rdev->devlist_mtx);
3463 fixedchan = rdev_fixed_channel(rdev, NULL);
3464 if (fixedchan && chan != fixedchan) {
3465 err = -EBUSY;
3466 mutex_unlock(&rdev->devlist_mtx);
3467 goto out;
3468 }
3469 mutex_unlock(&rdev->devlist_mtx);
3470
3499 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 3471 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3500 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 3472 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3501 3473