diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 44a3fc2ce38d..20aa390cf338 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -177,6 +177,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
177 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, | 177 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, |
178 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, | 178 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, |
179 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, | 179 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, |
180 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, | ||
180 | }; | 181 | }; |
181 | 182 | ||
182 | /* policy for the key attributes */ | 183 | /* policy for the key attributes */ |
@@ -3324,7 +3325,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3324 | struct nlattr *attr; | 3325 | struct nlattr *attr; |
3325 | struct wiphy *wiphy; | 3326 | struct wiphy *wiphy; |
3326 | int err, tmp, n_ssids = 0, n_channels, i; | 3327 | int err, tmp, n_ssids = 0, n_channels, i; |
3327 | enum ieee80211_band band; | ||
3328 | size_t ie_len; | 3328 | size_t ie_len; |
3329 | 3329 | ||
3330 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3330 | 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) | |||
3344 | if (!n_channels) | 3344 | if (!n_channels) |
3345 | return -EINVAL; | 3345 | return -EINVAL; |
3346 | } else { | 3346 | } else { |
3347 | enum ieee80211_band band; | ||
3347 | n_channels = 0; | 3348 | n_channels = 0; |
3348 | 3349 | ||
3349 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | 3350 | 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) | |||
3404 | i++; | 3405 | i++; |
3405 | } | 3406 | } |
3406 | } else { | 3407 | } else { |
3408 | enum ieee80211_band band; | ||
3409 | |||
3407 | /* all channels */ | 3410 | /* all channels */ |
3408 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 3411 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
3409 | int j; | 3412 | int j; |
@@ -3450,6 +3453,28 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3450 | request->ie_len); | 3453 | request->ie_len); |
3451 | } | 3454 | } |
3452 | 3455 | ||
3456 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | ||
3457 | request->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; | ||
3458 | |||
3459 | if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) { | ||
3460 | nla_for_each_nested(attr, | ||
3461 | info->attrs[NL80211_ATTR_SCAN_SUPP_RATES], | ||
3462 | tmp) { | ||
3463 | enum ieee80211_band band = nla_type(attr); | ||
3464 | |||
3465 | if (band < 0 || band > IEEE80211_NUM_BANDS) { | ||
3466 | err = -EINVAL; | ||
3467 | goto out_free; | ||
3468 | } | ||
3469 | err = ieee80211_get_ratemask(wiphy->bands[band], | ||
3470 | nla_data(attr), | ||
3471 | nla_len(attr), | ||
3472 | &request->rates[band]); | ||
3473 | if (err) | ||
3474 | goto out_free; | ||
3475 | } | ||
3476 | } | ||
3477 | |||
3453 | request->dev = dev; | 3478 | request->dev = dev; |
3454 | request->wiphy = &rdev->wiphy; | 3479 | request->wiphy = &rdev->wiphy; |
3455 | 3480 | ||
@@ -4336,25 +4361,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
4336 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 4361 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
4337 | struct ieee80211_supported_band *sband = | 4362 | struct ieee80211_supported_band *sband = |
4338 | wiphy->bands[ibss.channel->band]; | 4363 | wiphy->bands[ibss.channel->band]; |
4339 | int i, j; | 4364 | int err; |
4340 | |||
4341 | if (n_rates == 0) | ||
4342 | return -EINVAL; | ||
4343 | |||
4344 | for (i = 0; i < n_rates; i++) { | ||
4345 | int rate = (rates[i] & 0x7f) * 5; | ||
4346 | bool found = false; | ||
4347 | 4365 | ||
4348 | for (j = 0; j < sband->n_bitrates; j++) { | 4366 | err = ieee80211_get_ratemask(sband, rates, n_rates, |
4349 | if (sband->bitrates[j].bitrate == rate) { | 4367 | &ibss.basic_rates); |
4350 | found = true; | 4368 | if (err) |
4351 | ibss.basic_rates |= BIT(j); | 4369 | return err; |
4352 | break; | ||
4353 | } | ||
4354 | } | ||
4355 | if (!found) | ||
4356 | return -EINVAL; | ||
4357 | } | ||
4358 | } | 4370 | } |
4359 | 4371 | ||
4360 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && | 4372 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && |