thp: fix interrupt unsafe locking in split_huge_page()
[cascardo/linux.git] / net / wireless / nl80211.c
index 75b0d23..d4786f2 100644 (file)
@@ -4256,8 +4256,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
         * station. Include these parameters here and will check them in
         * cfg80211_check_station_change().
         */
-       if (info->attrs[NL80211_ATTR_PEER_AID])
-               params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
+       if (info->attrs[NL80211_ATTR_STA_AID])
+               params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
 
        if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
                params.listen_interval =
@@ -4359,6 +4359,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
        struct net_device *dev = info->user_ptr[1];
        struct station_parameters params;
        u8 *mac_addr = NULL;
+       u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
+                        BIT(NL80211_STA_FLAG_ASSOCIATED);
 
        memset(&params, 0, sizeof(params));
 
@@ -4470,10 +4472,23 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
                /* allow authenticated/associated only if driver handles it */
                if (!(rdev->wiphy.features &
                                NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
-                   params.sta_flags_mask &
-                               (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
-                                BIT(NL80211_STA_FLAG_ASSOCIATED)))
-                       return -EINVAL;
+                   params.sta_flags_mask & auth_assoc)
+                       return -EINVAL;
+
+               /* Older userspace, or userspace wanting to be compatible with
+                * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
+                * and assoc flags in the mask, but assumes the station will be
+                * added as associated anyway since this was the required driver
+                * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
+                * introduced.
+                * In order to not bother drivers with this quirk in the API
+                * set the flags in both the mask and set for new stations in
+                * this case.
+                */
+               if (!(params.sta_flags_mask & auth_assoc)) {
+                       params.sta_flags_mask |= auth_assoc;
+                       params.sta_flags_set |= auth_assoc;
+               }
 
                /* must be last in here for error handling */
                params.vlan = get_vlan(info, rdev);
@@ -5997,6 +6012,24 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
+static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct wireless_dev *wdev = info->user_ptr[1];
+
+       if (!rdev->ops->abort_scan)
+               return -EOPNOTSUPP;
+
+       if (rdev->scan_msg)
+               return 0;
+
+       if (!rdev->scan_req)
+               return -ENOENT;
+
+       rdev_abort_scan(rdev, wdev);
+       return 0;
+}
+
 static int
 nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
                               struct cfg80211_sched_scan_request *request,
@@ -6507,8 +6540,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
        if (WARN_ON(!cac_time_ms))
                cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
 
-       err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef,
-                                              cac_time_ms);
+       err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
        if (!err) {
                wdev->chandef = chandef;
                wdev->cac_started = true;
@@ -7571,7 +7603,7 @@ static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
        if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
                return -EINVAL;
 
-       err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate);
+       err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
 
        return err;
 }
@@ -9719,7 +9751,7 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
 
        if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
                cfg80211_rdev_free_coalesce(rdev);
-               rdev->ops->set_coalesce(&rdev->wiphy, NULL);
+               rdev_set_coalesce(rdev, NULL);
                return 0;
        }
 
@@ -9747,7 +9779,7 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
                i++;
        }
 
-       err = rdev->ops->set_coalesce(&rdev->wiphy, &new_coalesce);
+       err = rdev_set_coalesce(rdev, &new_coalesce);
        if (err)
                goto error;
 
@@ -10948,6 +10980,14 @@ static const struct genl_ops nl80211_ops[] = {
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
+       {
+               .cmd = NL80211_CMD_ABORT_SCAN,
+               .doit = nl80211_abort_scan,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
        {
                .cmd = NL80211_CMD_GET_SCAN,
                .policy = nl80211_policy,