|
@@ -177,6 +177,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|
[NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
|
|
[NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
|
|
[NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
|
|
[NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
|
|
[NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
|
|
[NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
|
|
|
|
+ [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
|
|
};
|
|
};
|
|
|
|
|
|
/* policy for the key attributes */
|
|
/* policy for the key attributes */
|
|
@@ -3324,7 +3325,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
struct nlattr *attr;
|
|
struct nlattr *attr;
|
|
struct wiphy *wiphy;
|
|
struct wiphy *wiphy;
|
|
int err, tmp, n_ssids = 0, n_channels, i;
|
|
int err, tmp, n_ssids = 0, n_channels, i;
|
|
- enum ieee80211_band band;
|
|
|
|
size_t ie_len;
|
|
size_t ie_len;
|
|
|
|
|
|
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
|
|
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
|
|
@@ -3344,6 +3344,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
if (!n_channels)
|
|
if (!n_channels)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
} else {
|
|
} else {
|
|
|
|
+ enum ieee80211_band band;
|
|
n_channels = 0;
|
|
n_channels = 0;
|
|
|
|
|
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++)
|
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++)
|
|
@@ -3404,6 +3405,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
i++;
|
|
i++;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
|
|
+ enum ieee80211_band band;
|
|
|
|
+
|
|
/* all channels */
|
|
/* all channels */
|
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
|
int j;
|
|
int j;
|
|
@@ -3450,6 +3453,28 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
request->ie_len);
|
|
request->ie_len);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++)
|
|
|
|
+ request->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
|
|
|
|
+
|
|
|
|
+ if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
|
|
|
|
+ nla_for_each_nested(attr,
|
|
|
|
+ info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
|
|
|
|
+ tmp) {
|
|
|
|
+ enum ieee80211_band band = nla_type(attr);
|
|
|
|
+
|
|
|
|
+ if (band < 0 || band > IEEE80211_NUM_BANDS) {
|
|
|
|
+ err = -EINVAL;
|
|
|
|
+ goto out_free;
|
|
|
|
+ }
|
|
|
|
+ err = ieee80211_get_ratemask(wiphy->bands[band],
|
|
|
|
+ nla_data(attr),
|
|
|
|
+ nla_len(attr),
|
|
|
|
+ &request->rates[band]);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out_free;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
request->dev = dev;
|
|
request->dev = dev;
|
|
request->wiphy = &rdev->wiphy;
|
|
request->wiphy = &rdev->wiphy;
|
|
|
|
|
|
@@ -4336,25 +4361,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
|
|
nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
|
|
nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
|
|
struct ieee80211_supported_band *sband =
|
|
struct ieee80211_supported_band *sband =
|
|
wiphy->bands[ibss.channel->band];
|
|
wiphy->bands[ibss.channel->band];
|
|
- int i, j;
|
|
|
|
-
|
|
|
|
- if (n_rates == 0)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < n_rates; i++) {
|
|
|
|
- int rate = (rates[i] & 0x7f) * 5;
|
|
|
|
- bool found = false;
|
|
|
|
|
|
+ int err;
|
|
|
|
|
|
- for (j = 0; j < sband->n_bitrates; j++) {
|
|
|
|
- if (sband->bitrates[j].bitrate == rate) {
|
|
|
|
- found = true;
|
|
|
|
- ibss.basic_rates |= BIT(j);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (!found)
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
|
|
+ err = ieee80211_get_ratemask(sband, rates, n_rates,
|
|
|
|
+ &ibss.basic_rates);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
|
|
if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
|