diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 54 |
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 | ||