Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-2.6-block.git] / net / wireless / nl80211.c
index 711cb7ad6ae011132b868d928ebe23037040db82..056a7307862b78f5f0b2013b41c2686b5de18064 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright 2015      Intel Deutschland GmbH
+ * Copyright 2015-2016 Intel Deutschland GmbH
  */
 
 #include <linux/if.h>
@@ -401,6 +401,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
        [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
        [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
+       [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -3461,6 +3462,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
                        return PTR_ERR(params.acl);
        }
 
+       params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
+       if (params.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ])
+               return -EOPNOTSUPP;
+
        wdev_lock(wdev);
        err = rdev_start_ap(rdev, dev, &params);
        if (!err) {
@@ -7281,9 +7286,11 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
-               if (!(rdev->wiphy.features &
-                     NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) ||
-                   !(rdev->wiphy.features & NL80211_FEATURE_QUIET))
+               if (!((rdev->wiphy.features &
+                       NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
+                      (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
+                   !wiphy_ext_feature_isset(&rdev->wiphy,
+                                            NL80211_EXT_FEATURE_RRM))
                        return -EINVAL;
                req.flags |= ASSOC_REQ_USE_RRM;
        }
@@ -7971,15 +7978,23 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
-               if (!(rdev->wiphy.features &
-                     NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) ||
-                   !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) {
+               if (!((rdev->wiphy.features &
+                       NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
+                      (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
+                   !wiphy_ext_feature_isset(&rdev->wiphy,
+                                            NL80211_EXT_FEATURE_RRM)) {
                        kzfree(connkeys);
                        return -EINVAL;
                }
                connect.flags |= ASSOC_REQ_USE_RRM;
        }
 
+       connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
+       if (connect.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ]) {
+               kzfree(connkeys);
+               return -EOPNOTSUPP;
+       }
+
        wdev_lock(dev->ieee80211_ptr);
        err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
        wdev_unlock(dev->ieee80211_ptr);
@@ -13201,7 +13216,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
        struct wireless_dev *wdev;
        struct cfg80211_beacon_registration *reg, *tmp;
 
-       if (state != NETLINK_URELEASE)
+       if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
                return NOTIFY_DONE;
 
        rcu_read_lock();