cfg80211: fix TDLS setup with VHT peers
[pandora-kernel.git] / net / wireless / nl80211.c
index ba4f172..13997c9 100644 (file)
@@ -337,6 +337,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
        [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
        [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
+       [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
        [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
        [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
                                      .len = IEEE80211_MAX_DATA_LEN },
@@ -3814,7 +3815,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
 {
        if (params->listen_interval != -1)
                return -EINVAL;
-       if (params->aid)
+       if (params->aid &&
+           !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
                return -EINVAL;
 
        /* When you run into this, adjust the code below for the new flag */
@@ -6012,17 +6014,6 @@ skip_beacons:
                params.radar_required = true;
        }
 
-       /* TODO: I left this here for now.  With channel switch, the
-        * verification is a bit more complicated, because we only do
-        * it later when the channel switch really happens.
-        */
-       err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
-                                          params.chandef.chan,
-                                          CHAN_MODE_SHARED,
-                                          radar_detect_width);
-       if (err)
-               return err;
-
        if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
                params.block_tx = true;
 
@@ -7365,6 +7356,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
        u32 peer_capability = 0;
        u16 status_code;
        u8 *peer;
+       bool initiator;
 
        if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
            !rdev->ops->tdls_mgmt)
@@ -7381,12 +7373,14 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
        action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
        status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
        dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
+       initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
        if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
                peer_capability =
                        nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
 
        return rdev_tdls_mgmt(rdev, dev, peer, action_code,
                              dialog_token, status_code, peer_capability,
+                             initiator,
                              nla_data(info->attrs[NL80211_ATTR_IE]),
                              nla_len(info->attrs[NL80211_ATTR_IE]));
 }