aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Kconfig11
-rw-r--r--net/wireless/core.c14
-rw-r--r--net/wireless/core.h4
-rw-r--r--net/wireless/mlme.c15
-rw-r--r--net/wireless/nl80211.c358
-rw-r--r--net/wireless/nl80211.h4
-rw-r--r--net/wireless/reg.c61
-rw-r--r--net/wireless/scan.c13
-rw-r--r--net/wireless/sme.c8
-rw-r--r--net/wireless/sysfs.c6
-rw-r--r--net/wireless/util.c38
11 files changed, 471 insertions, 61 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 1f1ef70f34f..8e2a668c923 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -159,3 +159,14 @@ config LIB80211_DEBUG
159 from lib80211. 159 from lib80211.
160 160
161 If unsure, say N. 161 If unsure, say N.
162
163config CFG80211_ALLOW_RECONNECT
164 bool "Allow reconnect while already connected"
165 depends on CFG80211
166 default n
167 help
168 cfg80211 stack doesn't allow to connect if you are already
169 connected. This option allows to make a connection in this case.
170
171 Select this option ONLY for wlan drivers that are specifically
172 built for such purposes.
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 880dbe2e6f9..c14865172da 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -488,6 +488,10 @@ int wiphy_register(struct wiphy *wiphy)
488 int i; 488 int i;
489 u16 ifmodes = wiphy->interface_modes; 489 u16 ifmodes = wiphy->interface_modes;
490 490
491 if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
492 !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
493 return -EINVAL;
494
491 if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) 495 if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
492 return -EINVAL; 496 return -EINVAL;
493 497
@@ -612,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy)
612 if (res) 616 if (res)
613 goto out_rm_dev; 617 goto out_rm_dev;
614 618
619 rtnl_lock();
620 rdev->wiphy.registered = true;
621 rtnl_unlock();
615 return 0; 622 return 0;
616 623
617out_rm_dev: 624out_rm_dev:
@@ -643,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy)
643{ 650{
644 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 651 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
645 652
653 rtnl_lock();
654 rdev->wiphy.registered = false;
655 rtnl_unlock();
656
646 rfkill_unregister(rdev->rfkill); 657 rfkill_unregister(rdev->rfkill);
647 658
648 /* protect the device list */ 659 /* protect the device list */
@@ -918,7 +929,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
918 * Configure power management to the driver here so that its 929 * Configure power management to the driver here so that its
919 * correctly set also after interface type changes etc. 930 * correctly set also after interface type changes etc.
920 */ 931 */
921 if (wdev->iftype == NL80211_IFTYPE_STATION && 932 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
933 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
922 rdev->ops->set_power_mgmt) 934 rdev->ops->set_power_mgmt)
923 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, 935 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
924 wdev->ps, 936 wdev->ps,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a570ff9214e..8672e028022 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -447,6 +447,10 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
447 447
448u16 cfg80211_calculate_bitrate(struct rate_info *rate); 448u16 cfg80211_calculate_bitrate(struct rate_info *rate);
449 449
450int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
451 const u8 *rates, unsigned int n_rates,
452 u32 *mask);
453
450int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, 454int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
451 u32 beacon_int); 455 u32 beacon_int);
452 456
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 493b939970c..832f6574e4e 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -170,7 +170,9 @@ void __cfg80211_send_deauth(struct net_device *dev,
170 break; 170 break;
171 } 171 }
172 if (wdev->authtry_bsses[i] && 172 if (wdev->authtry_bsses[i] &&
173 memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { 173 memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
174 ETH_ALEN) == 0 &&
175 memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) {
174 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 176 cfg80211_unhold_bss(wdev->authtry_bsses[i]);
175 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 177 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
176 wdev->authtry_bsses[i] = NULL; 178 wdev->authtry_bsses[i] = NULL;
@@ -1082,3 +1084,14 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev,
1082 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); 1084 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
1083} 1085}
1084EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); 1086EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
1087
1088void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
1089 const u8 *replay_ctr, gfp_t gfp)
1090{
1091 struct wireless_dev *wdev = dev->ieee80211_ptr;
1092 struct wiphy *wiphy = wdev->wiphy;
1093 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1094
1095 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
1096}
1097EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cea338150d0..fb18bb4dea7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -83,8 +83,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
83 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 83 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
84 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, 84 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
85 85
86 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, 86 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
87 [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, 87 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
88 88
89 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, 89 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
90 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, 90 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
@@ -126,8 +126,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, 127 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
128 128
129 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 129 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
130 .len = NL80211_HT_CAPABILITY_LEN },
131 130
132 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, 131 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
133 [NL80211_ATTR_IE] = { .type = NLA_BINARY, 132 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
@@ -176,6 +175,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
176 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, 175 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
177 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, 176 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, 177 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
178 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
179 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
179}; 180};
180 181
181/* policy for the key attributes */ 182/* policy for the key attributes */
@@ -204,6 +205,18 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
204 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, 205 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
205 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, 206 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
206 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, 207 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
208 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
209 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
210 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
211 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
212};
213
214/* policy for GTK rekey offload attributes */
215static const struct nla_policy
216nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
217 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
218 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
219 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
207}; 220};
208 221
209/* ifidx get helper */ 222/* ifidx get helper */
@@ -683,8 +696,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
683 dev->wiphy.coverage_class); 696 dev->wiphy.coverage_class);
684 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 697 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
685 dev->wiphy.max_scan_ssids); 698 dev->wiphy.max_scan_ssids);
699 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
700 dev->wiphy.max_sched_scan_ssids);
686 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 701 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
687 dev->wiphy.max_scan_ie_len); 702 dev->wiphy.max_scan_ie_len);
703 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
704 dev->wiphy.max_sched_scan_ie_len);
688 705
689 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 706 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
690 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 707 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
@@ -920,6 +937,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
920 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); 937 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
921 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) 938 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
922 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); 939 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
940 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
941 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
942 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
943 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
944 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
945 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
946 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
947 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
948 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
949 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
923 if (dev->wiphy.wowlan.n_patterns) { 950 if (dev->wiphy.wowlan.n_patterns) {
924 struct nl80211_wowlan_pattern_support pat = { 951 struct nl80211_wowlan_pattern_support pat = {
925 .max_patterns = dev->wiphy.wowlan.n_patterns, 952 .max_patterns = dev->wiphy.wowlan.n_patterns,
@@ -2209,6 +2236,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2209 } 2236 }
2210 nla_nest_end(msg, sinfoattr); 2237 nla_nest_end(msg, sinfoattr);
2211 2238
2239 if (sinfo->assoc_req_ies)
2240 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
2241 sinfo->assoc_req_ies);
2242
2212 return genlmsg_end(msg, hdr); 2243 return genlmsg_end(msg, hdr);
2213 2244
2214 nla_put_failure: 2245 nla_put_failure:
@@ -2236,6 +2267,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
2236 } 2267 }
2237 2268
2238 while (1) { 2269 while (1) {
2270 memset(&sinfo, 0, sizeof(sinfo));
2239 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 2271 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
2240 mac_addr, &sinfo); 2272 mac_addr, &sinfo);
2241 if (err == -ENOENT) 2273 if (err == -ENOENT)
@@ -3297,7 +3329,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3297 struct nlattr *attr; 3329 struct nlattr *attr;
3298 struct wiphy *wiphy; 3330 struct wiphy *wiphy;
3299 int err, tmp, n_ssids = 0, n_channels, i; 3331 int err, tmp, n_ssids = 0, n_channels, i;
3300 enum ieee80211_band band;
3301 size_t ie_len; 3332 size_t ie_len;
3302 3333
3303 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3334 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
@@ -3317,6 +3348,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3317 if (!n_channels) 3348 if (!n_channels)
3318 return -EINVAL; 3349 return -EINVAL;
3319 } else { 3350 } else {
3351 enum ieee80211_band band;
3320 n_channels = 0; 3352 n_channels = 0;
3321 3353
3322 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 3354 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
@@ -3377,6 +3409,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3377 i++; 3409 i++;
3378 } 3410 }
3379 } else { 3411 } else {
3412 enum ieee80211_band band;
3413
3380 /* all channels */ 3414 /* all channels */
3381 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 3415 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
3382 int j; 3416 int j;
@@ -3423,6 +3457,30 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3423 request->ie_len); 3457 request->ie_len);
3424 } 3458 }
3425 3459
3460 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3461 if (wiphy->bands[i])
3462 request->rates[i] =
3463 (1 << wiphy->bands[i]->n_bitrates) - 1;
3464
3465 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
3466 nla_for_each_nested(attr,
3467 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
3468 tmp) {
3469 enum ieee80211_band band = nla_type(attr);
3470
3471 if (band < 0 || band >= IEEE80211_NUM_BANDS) {
3472 err = -EINVAL;
3473 goto out_free;
3474 }
3475 err = ieee80211_get_ratemask(wiphy->bands[band],
3476 nla_data(attr),
3477 nla_len(attr),
3478 &request->rates[band]);
3479 if (err)
3480 goto out_free;
3481 }
3482 }
3483
3426 request->dev = dev; 3484 request->dev = dev;
3427 request->wiphy = &rdev->wiphy; 3485 request->wiphy = &rdev->wiphy;
3428 3486
@@ -3488,7 +3546,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3488 tmp) 3546 tmp)
3489 n_ssids++; 3547 n_ssids++;
3490 3548
3491 if (n_ssids > wiphy->max_scan_ssids) 3549 if (n_ssids > wiphy->max_sched_scan_ssids)
3492 return -EINVAL; 3550 return -EINVAL;
3493 3551
3494 if (info->attrs[NL80211_ATTR_IE]) 3552 if (info->attrs[NL80211_ATTR_IE])
@@ -3496,7 +3554,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3496 else 3554 else
3497 ie_len = 0; 3555 ie_len = 0;
3498 3556
3499 if (ie_len > wiphy->max_scan_ie_len) 3557 if (ie_len > wiphy->max_sched_scan_ie_len)
3500 return -EINVAL; 3558 return -EINVAL;
3501 3559
3502 mutex_lock(&rdev->sched_scan_mtx); 3560 mutex_lock(&rdev->sched_scan_mtx);
@@ -3632,7 +3690,8 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
3632 return err; 3690 return err;
3633} 3691}
3634 3692
3635static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, 3693static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
3694 u32 seq, int flags,
3636 struct cfg80211_registered_device *rdev, 3695 struct cfg80211_registered_device *rdev,
3637 struct wireless_dev *wdev, 3696 struct wireless_dev *wdev,
3638 struct cfg80211_internal_bss *intbss) 3697 struct cfg80211_internal_bss *intbss)
@@ -3644,11 +3703,13 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
3644 3703
3645 ASSERT_WDEV_LOCK(wdev); 3704 ASSERT_WDEV_LOCK(wdev);
3646 3705
3647 hdr = nl80211hdr_put(msg, pid, seq, flags, 3706 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags,
3648 NL80211_CMD_NEW_SCAN_RESULTS); 3707 NL80211_CMD_NEW_SCAN_RESULTS);
3649 if (!hdr) 3708 if (!hdr)
3650 return -1; 3709 return -1;
3651 3710
3711 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
3712
3652 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation); 3713 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation);
3653 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex); 3714 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
3654 3715
@@ -3737,11 +3798,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3737 spin_lock_bh(&rdev->bss_lock); 3798 spin_lock_bh(&rdev->bss_lock);
3738 cfg80211_bss_expire(rdev); 3799 cfg80211_bss_expire(rdev);
3739 3800
3801 cb->seq = rdev->bss_generation;
3802
3740 list_for_each_entry(scan, &rdev->bss_list, list) { 3803 list_for_each_entry(scan, &rdev->bss_list, list) {
3741 if (++idx <= start) 3804 if (++idx <= start)
3742 continue; 3805 continue;
3743 if (nl80211_send_bss(skb, 3806 if (nl80211_send_bss(skb, cb,
3744 NETLINK_CB(cb->skb).pid,
3745 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3807 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3746 rdev, wdev, scan) < 0) { 3808 rdev, wdev, scan) < 0) {
3747 idx--; 3809 idx--;
@@ -3765,10 +3827,6 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3765 void *hdr; 3827 void *hdr;
3766 struct nlattr *infoattr; 3828 struct nlattr *infoattr;
3767 3829
3768 /* Survey without a channel doesn't make sense */
3769 if (!survey->channel)
3770 return -EINVAL;
3771
3772 hdr = nl80211hdr_put(msg, pid, seq, flags, 3830 hdr = nl80211hdr_put(msg, pid, seq, flags,
3773 NL80211_CMD_NEW_SURVEY_RESULTS); 3831 NL80211_CMD_NEW_SURVEY_RESULTS);
3774 if (!hdr) 3832 if (!hdr)
@@ -3831,6 +3889,8 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3831 } 3889 }
3832 3890
3833 while (1) { 3891 while (1) {
3892 struct ieee80211_channel *chan;
3893
3834 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx, 3894 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
3835 &survey); 3895 &survey);
3836 if (res == -ENOENT) 3896 if (res == -ENOENT)
@@ -3838,6 +3898,19 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3838 if (res) 3898 if (res)
3839 goto out_err; 3899 goto out_err;
3840 3900
3901 /* Survey without a channel doesn't make sense */
3902 if (!survey.channel) {
3903 res = -EINVAL;
3904 goto out;
3905 }
3906
3907 chan = ieee80211_get_channel(&dev->wiphy,
3908 survey.channel->center_freq);
3909 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
3910 survey_idx++;
3911 continue;
3912 }
3913
3841 if (nl80211_send_survey(skb, 3914 if (nl80211_send_survey(skb,
3842 NETLINK_CB(cb->skb).pid, 3915 NETLINK_CB(cb->skb).pid,
3843 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3916 cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -4044,9 +4117,12 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4044 if (len % sizeof(u32)) 4117 if (len % sizeof(u32))
4045 return -EINVAL; 4118 return -EINVAL;
4046 4119
4120 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
4121 return -EINVAL;
4122
4047 memcpy(settings->akm_suites, data, len); 4123 memcpy(settings->akm_suites, data, len);
4048 4124
4049 for (i = 0; i < settings->n_ciphers_pairwise; i++) 4125 for (i = 0; i < settings->n_akm_suites; i++)
4050 if (!nl80211_valid_akm_suite(settings->akm_suites[i])) 4126 if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
4051 return -EINVAL; 4127 return -EINVAL;
4052 } 4128 }
@@ -4294,25 +4370,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4294 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 4370 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
4295 struct ieee80211_supported_band *sband = 4371 struct ieee80211_supported_band *sband =
4296 wiphy->bands[ibss.channel->band]; 4372 wiphy->bands[ibss.channel->band];
4297 int i, j; 4373 int err;
4298
4299 if (n_rates == 0)
4300 return -EINVAL;
4301 4374
4302 for (i = 0; i < n_rates; i++) { 4375 err = ieee80211_get_ratemask(sband, rates, n_rates,
4303 int rate = (rates[i] & 0x7f) * 5; 4376 &ibss.basic_rates);
4304 bool found = false; 4377 if (err)
4305 4378 return err;
4306 for (j = 0; j < sband->n_bitrates; j++) {
4307 if (sband->bitrates[j].bitrate == rate) {
4308 found = true;
4309 ibss.basic_rates |= BIT(j);
4310 break;
4311 }
4312 }
4313 if (!found)
4314 return -EINVAL;
4315 }
4316 } 4379 }
4317 4380
4318 if (info->attrs[NL80211_ATTR_MCAST_RATE] && 4381 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
@@ -4372,6 +4435,93 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4372 return err; 4435 return err;
4373} 4436}
4374 4437
4438static int nl80211_testmode_dump(struct sk_buff *skb,
4439 struct netlink_callback *cb)
4440{
4441 struct cfg80211_registered_device *dev;
4442 int err;
4443 long phy_idx;
4444 void *data = NULL;
4445 int data_len = 0;
4446
4447 if (cb->args[0]) {
4448 /*
4449 * 0 is a valid index, but not valid for args[0],
4450 * so we need to offset by 1.
4451 */
4452 phy_idx = cb->args[0] - 1;
4453 } else {
4454 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
4455 nl80211_fam.attrbuf, nl80211_fam.maxattr,
4456 nl80211_policy);
4457 if (err)
4458 return err;
4459 if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY])
4460 return -EINVAL;
4461 phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
4462 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
4463 cb->args[1] =
4464 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
4465 }
4466
4467 if (cb->args[1]) {
4468 data = nla_data((void *)cb->args[1]);
4469 data_len = nla_len((void *)cb->args[1]);
4470 }
4471
4472 mutex_lock(&cfg80211_mutex);
4473 dev = cfg80211_rdev_by_wiphy_idx(phy_idx);
4474 if (!dev) {
4475 mutex_unlock(&cfg80211_mutex);
4476 return -ENOENT;
4477 }
4478 cfg80211_lock_rdev(dev);
4479 mutex_unlock(&cfg80211_mutex);
4480
4481 if (!dev->ops->testmode_dump) {
4482 err = -EOPNOTSUPP;
4483 goto out_err;
4484 }
4485
4486 while (1) {
4487 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid,
4488 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4489 NL80211_CMD_TESTMODE);
4490 struct nlattr *tmdata;
4491
4492 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) {
4493 genlmsg_cancel(skb, hdr);
4494 break;
4495 }
4496
4497 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
4498 if (!tmdata) {
4499 genlmsg_cancel(skb, hdr);
4500 break;
4501 }
4502 err = dev->ops->testmode_dump(&dev->wiphy, skb, cb,
4503 data, data_len);
4504 nla_nest_end(skb, tmdata);
4505
4506 if (err == -ENOBUFS || err == -ENOENT) {
4507 genlmsg_cancel(skb, hdr);
4508 break;
4509 } else if (err) {
4510 genlmsg_cancel(skb, hdr);
4511 goto out_err;
4512 }
4513
4514 genlmsg_end(skb, hdr);
4515 }
4516
4517 err = skb->len;
4518 /* see above */
4519 cb->args[0] = phy_idx + 1;
4520 out_err:
4521 cfg80211_unlock_rdev(dev);
4522 return err;
4523}
4524
4375static struct sk_buff * 4525static struct sk_buff *
4376__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, 4526__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
4377 int approxlen, u32 pid, u32 seq, gfp_t gfp) 4527 int approxlen, u32 pid, u32 seq, gfp_t gfp)
@@ -5161,6 +5311,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
5161 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); 5311 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
5162 if (rdev->wowlan->magic_pkt) 5312 if (rdev->wowlan->magic_pkt)
5163 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); 5313 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
5314 if (rdev->wowlan->gtk_rekey_failure)
5315 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
5316 if (rdev->wowlan->eap_identity_req)
5317 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
5318 if (rdev->wowlan->four_way_handshake)
5319 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
5320 if (rdev->wowlan->rfkill_release)
5321 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
5164 if (rdev->wowlan->n_patterns) { 5322 if (rdev->wowlan->n_patterns) {
5165 struct nlattr *nl_pats, *nl_pat; 5323 struct nlattr *nl_pats, *nl_pat;
5166 int i, pat_len; 5324 int i, pat_len;
@@ -5237,6 +5395,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5237 new_triggers.magic_pkt = true; 5395 new_triggers.magic_pkt = true;
5238 } 5396 }
5239 5397
5398 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
5399 return -EINVAL;
5400
5401 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
5402 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
5403 return -EINVAL;
5404 new_triggers.gtk_rekey_failure = true;
5405 }
5406
5407 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
5408 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
5409 return -EINVAL;
5410 new_triggers.eap_identity_req = true;
5411 }
5412
5413 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
5414 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
5415 return -EINVAL;
5416 new_triggers.four_way_handshake = true;
5417 }
5418
5419 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
5420 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
5421 return -EINVAL;
5422 new_triggers.rfkill_release = true;
5423 }
5424
5240 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { 5425 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
5241 struct nlattr *pat; 5426 struct nlattr *pat;
5242 int n_patterns = 0; 5427 int n_patterns = 0;
@@ -5318,6 +5503,57 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5318 return err; 5503 return err;
5319} 5504}
5320 5505
5506static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
5507{
5508 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5509 struct net_device *dev = info->user_ptr[1];
5510 struct wireless_dev *wdev = dev->ieee80211_ptr;
5511 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
5512 struct cfg80211_gtk_rekey_data rekey_data;
5513 int err;
5514
5515 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
5516 return -EINVAL;
5517
5518 err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
5519 nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
5520 nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
5521 nl80211_rekey_policy);
5522 if (err)
5523 return err;
5524
5525 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
5526 return -ERANGE;
5527 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
5528 return -ERANGE;
5529 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
5530 return -ERANGE;
5531
5532 memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]),
5533 NL80211_KEK_LEN);
5534 memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]),
5535 NL80211_KCK_LEN);
5536 memcpy(rekey_data.replay_ctr,
5537 nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]),
5538 NL80211_REPLAY_CTR_LEN);
5539
5540 wdev_lock(wdev);
5541 if (!wdev->current_bss) {
5542 err = -ENOTCONN;
5543 goto out;
5544 }
5545
5546 if (!rdev->ops->set_rekey_data) {
5547 err = -EOPNOTSUPP;
5548 goto out;
5549 }
5550
5551 err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data);
5552 out:
5553 wdev_unlock(wdev);
5554 return err;
5555}
5556
5321#define NL80211_FLAG_NEED_WIPHY 0x01 5557#define NL80211_FLAG_NEED_WIPHY 0x01
5322#define NL80211_FLAG_NEED_NETDEV 0x02 5558#define NL80211_FLAG_NEED_NETDEV 0x02
5323#define NL80211_FLAG_NEED_RTNL 0x04 5559#define NL80211_FLAG_NEED_RTNL 0x04
@@ -5669,6 +5905,7 @@ static struct genl_ops nl80211_ops[] = {
5669 { 5905 {
5670 .cmd = NL80211_CMD_TESTMODE, 5906 .cmd = NL80211_CMD_TESTMODE,
5671 .doit = nl80211_testmode_do, 5907 .doit = nl80211_testmode_do,
5908 .dumpit = nl80211_testmode_dump,
5672 .policy = nl80211_policy, 5909 .policy = nl80211_policy,
5673 .flags = GENL_ADMIN_PERM, 5910 .flags = GENL_ADMIN_PERM,
5674 .internal_flags = NL80211_FLAG_NEED_WIPHY | 5911 .internal_flags = NL80211_FLAG_NEED_WIPHY |
@@ -5848,6 +6085,14 @@ static struct genl_ops nl80211_ops[] = {
5848 .internal_flags = NL80211_FLAG_NEED_WIPHY | 6085 .internal_flags = NL80211_FLAG_NEED_WIPHY |
5849 NL80211_FLAG_NEED_RTNL, 6086 NL80211_FLAG_NEED_RTNL,
5850 }, 6087 },
6088 {
6089 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
6090 .doit = nl80211_set_rekey_data,
6091 .policy = nl80211_policy,
6092 .flags = GENL_ADMIN_PERM,
6093 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6094 NL80211_FLAG_NEED_RTNL,
6095 },
5851}; 6096};
5852 6097
5853static struct genl_multicast_group nl80211_mlme_mcgrp = { 6098static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -6792,6 +7037,51 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
6792 nlmsg_free(msg); 7037 nlmsg_free(msg);
6793} 7038}
6794 7039
7040void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
7041 struct net_device *netdev, const u8 *bssid,
7042 const u8 *replay_ctr, gfp_t gfp)
7043{
7044 struct sk_buff *msg;
7045 struct nlattr *rekey_attr;
7046 void *hdr;
7047
7048 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7049 if (!msg)
7050 return;
7051
7052 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
7053 if (!hdr) {
7054 nlmsg_free(msg);
7055 return;
7056 }
7057
7058 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
7059 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
7060 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
7061
7062 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
7063 if (!rekey_attr)
7064 goto nla_put_failure;
7065
7066 NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR,
7067 NL80211_REPLAY_CTR_LEN, replay_ctr);
7068
7069 nla_nest_end(msg, rekey_attr);
7070
7071 if (genlmsg_end(msg, hdr) < 0) {
7072 nlmsg_free(msg);
7073 return;
7074 }
7075
7076 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7077 nl80211_mlme_mcgrp.id, gfp);
7078 return;
7079
7080 nla_put_failure:
7081 genlmsg_cancel(msg, hdr);
7082 nlmsg_free(msg);
7083}
7084
6795void 7085void
6796nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 7086nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
6797 struct net_device *netdev, const u8 *peer, 7087 struct net_device *netdev, const u8 *peer,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 2f1bfb87a65..5d69c56400a 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -109,4 +109,8 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
109 struct net_device *netdev, const u8 *peer, 109 struct net_device *netdev, const u8 *peer,
110 u32 num_packets, gfp_t gfp); 110 u32 num_packets, gfp_t gfp);
111 111
112void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
113 struct net_device *netdev, const u8 *bssid,
114 const u8 *replay_ctr, gfp_t gfp);
115
112#endif /* __NET_WIRELESS_NL80211_H */ 116#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 1ad0f39fe09..ca754451e76 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -57,8 +57,17 @@
57#define REG_DBG_PRINT(args...) 57#define REG_DBG_PRINT(args...)
58#endif 58#endif
59 59
60static struct regulatory_request core_request_world = {
61 .initiator = NL80211_REGDOM_SET_BY_CORE,
62 .alpha2[0] = '0',
63 .alpha2[1] = '0',
64 .intersect = false,
65 .processed = true,
66 .country_ie_env = ENVIRON_ANY,
67};
68
60/* Receipt of information from last regulatory request */ 69/* Receipt of information from last regulatory request */
61static struct regulatory_request *last_request; 70static struct regulatory_request *last_request = &core_request_world;
62 71
63/* To trigger userspace events */ 72/* To trigger userspace events */
64static struct platform_device *reg_pdev; 73static struct platform_device *reg_pdev;
@@ -150,7 +159,7 @@ static char user_alpha2[2];
150module_param(ieee80211_regdom, charp, 0444); 159module_param(ieee80211_regdom, charp, 0444);
151MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 160MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
152 161
153static void reset_regdomains(void) 162static void reset_regdomains(bool full_reset)
154{ 163{
155 /* avoid freeing static information or freeing something twice */ 164 /* avoid freeing static information or freeing something twice */
156 if (cfg80211_regdomain == cfg80211_world_regdom) 165 if (cfg80211_regdomain == cfg80211_world_regdom)
@@ -165,6 +174,13 @@ static void reset_regdomains(void)
165 174
166 cfg80211_world_regdom = &world_regdom; 175 cfg80211_world_regdom = &world_regdom;
167 cfg80211_regdomain = NULL; 176 cfg80211_regdomain = NULL;
177
178 if (!full_reset)
179 return;
180
181 if (last_request != &core_request_world)
182 kfree(last_request);
183 last_request = &core_request_world;
168} 184}
169 185
170/* 186/*
@@ -175,7 +191,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
175{ 191{
176 BUG_ON(!last_request); 192 BUG_ON(!last_request);
177 193
178 reset_regdomains(); 194 reset_regdomains(false);
179 195
180 cfg80211_world_regdom = rd; 196 cfg80211_world_regdom = rd;
181 cfg80211_regdomain = rd; 197 cfg80211_regdomain = rd;
@@ -852,6 +868,7 @@ static void handle_channel(struct wiphy *wiphy,
852 return; 868 return;
853 } 869 }
854 870
871 chan->beacon_found = false;
855 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); 872 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
856 chan->max_antenna_gain = min(chan->orig_mag, 873 chan->max_antenna_gain = min(chan->orig_mag,
857 (int) MBI_TO_DBI(power_rule->max_antenna_gain)); 874 (int) MBI_TO_DBI(power_rule->max_antenna_gain));
@@ -903,7 +920,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
903 initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 920 initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
904 !is_world_regdom(last_request->alpha2)) { 921 !is_world_regdom(last_request->alpha2)) {
905 REG_DBG_PRINT("Ignoring regulatory request %s " 922 REG_DBG_PRINT("Ignoring regulatory request %s "
906 "since the driver requires its own regulaotry " 923 "since the driver requires its own regulatory "
907 "domain to be set first", 924 "domain to be set first",
908 reg_initiator_name(initiator)); 925 reg_initiator_name(initiator));
909 return true; 926 return true;
@@ -1125,12 +1142,13 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
1125 enum ieee80211_band band; 1142 enum ieee80211_band band;
1126 1143
1127 if (ignore_reg_update(wiphy, initiator)) 1144 if (ignore_reg_update(wiphy, initiator))
1128 goto out; 1145 return;
1146
1129 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1147 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1130 if (wiphy->bands[band]) 1148 if (wiphy->bands[band])
1131 handle_band(wiphy, band, initiator); 1149 handle_band(wiphy, band, initiator);
1132 } 1150 }
1133out: 1151
1134 reg_process_beacons(wiphy); 1152 reg_process_beacons(wiphy);
1135 reg_process_ht_flags(wiphy); 1153 reg_process_ht_flags(wiphy);
1136 if (wiphy->reg_notifier) 1154 if (wiphy->reg_notifier)
@@ -1394,7 +1412,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
1394 } 1412 }
1395 1413
1396new_request: 1414new_request:
1397 kfree(last_request); 1415 if (last_request != &core_request_world)
1416 kfree(last_request);
1398 1417
1399 last_request = pending_request; 1418 last_request = pending_request;
1400 last_request->intersect = intersect; 1419 last_request->intersect = intersect;
@@ -1564,9 +1583,6 @@ static int regulatory_hint_core(const char *alpha2)
1564{ 1583{
1565 struct regulatory_request *request; 1584 struct regulatory_request *request;
1566 1585
1567 kfree(last_request);
1568 last_request = NULL;
1569
1570 request = kzalloc(sizeof(struct regulatory_request), 1586 request = kzalloc(sizeof(struct regulatory_request),
1571 GFP_KERNEL); 1587 GFP_KERNEL);
1572 if (!request) 1588 if (!request)
@@ -1757,6 +1773,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1757static void restore_regulatory_settings(bool reset_user) 1773static void restore_regulatory_settings(bool reset_user)
1758{ 1774{
1759 char alpha2[2]; 1775 char alpha2[2];
1776 char world_alpha2[2];
1760 struct reg_beacon *reg_beacon, *btmp; 1777 struct reg_beacon *reg_beacon, *btmp;
1761 struct regulatory_request *reg_request, *tmp; 1778 struct regulatory_request *reg_request, *tmp;
1762 LIST_HEAD(tmp_reg_req_list); 1779 LIST_HEAD(tmp_reg_req_list);
@@ -1764,7 +1781,7 @@ static void restore_regulatory_settings(bool reset_user)
1764 mutex_lock(&cfg80211_mutex); 1781 mutex_lock(&cfg80211_mutex);
1765 mutex_lock(&reg_mutex); 1782 mutex_lock(&reg_mutex);
1766 1783
1767 reset_regdomains(); 1784 reset_regdomains(true);
1768 restore_alpha2(alpha2, reset_user); 1785 restore_alpha2(alpha2, reset_user);
1769 1786
1770 /* 1787 /*
@@ -1807,11 +1824,13 @@ static void restore_regulatory_settings(bool reset_user)
1807 1824
1808 /* First restore to the basic regulatory settings */ 1825 /* First restore to the basic regulatory settings */
1809 cfg80211_regdomain = cfg80211_world_regdom; 1826 cfg80211_regdomain = cfg80211_world_regdom;
1827 world_alpha2[0] = cfg80211_regdomain->alpha2[0];
1828 world_alpha2[1] = cfg80211_regdomain->alpha2[1];
1810 1829
1811 mutex_unlock(&reg_mutex); 1830 mutex_unlock(&reg_mutex);
1812 mutex_unlock(&cfg80211_mutex); 1831 mutex_unlock(&cfg80211_mutex);
1813 1832
1814 regulatory_hint_core(cfg80211_regdomain->alpha2); 1833 regulatory_hint_core(world_alpha2);
1815 1834
1816 /* 1835 /*
1817 * This restores the ieee80211_regdom module parameter 1836 * This restores the ieee80211_regdom module parameter
@@ -2024,12 +2043,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2024 } 2043 }
2025 2044
2026 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 2045 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2046 if (!request_wiphy &&
2047 (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
2048 last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
2049 schedule_delayed_work(&reg_timeout, 0);
2050 return -ENODEV;
2051 }
2027 2052
2028 if (!last_request->intersect) { 2053 if (!last_request->intersect) {
2029 int r; 2054 int r;
2030 2055
2031 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { 2056 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
2032 reset_regdomains(); 2057 reset_regdomains(false);
2033 cfg80211_regdomain = rd; 2058 cfg80211_regdomain = rd;
2034 return 0; 2059 return 0;
2035 } 2060 }
@@ -2050,7 +2075,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2050 if (r) 2075 if (r)
2051 return r; 2076 return r;
2052 2077
2053 reset_regdomains(); 2078 reset_regdomains(false);
2054 cfg80211_regdomain = rd; 2079 cfg80211_regdomain = rd;
2055 return 0; 2080 return 0;
2056 } 2081 }
@@ -2075,7 +2100,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2075 2100
2076 rd = NULL; 2101 rd = NULL;
2077 2102
2078 reset_regdomains(); 2103 reset_regdomains(false);
2079 cfg80211_regdomain = intersected_rd; 2104 cfg80211_regdomain = intersected_rd;
2080 2105
2081 return 0; 2106 return 0;
@@ -2095,7 +2120,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2095 kfree(rd); 2120 kfree(rd);
2096 rd = NULL; 2121 rd = NULL;
2097 2122
2098 reset_regdomains(); 2123 reset_regdomains(false);
2099 cfg80211_regdomain = intersected_rd; 2124 cfg80211_regdomain = intersected_rd;
2100 2125
2101 return 0; 2126 return 0;
@@ -2248,9 +2273,9 @@ void /* __init_or_exit */ regulatory_exit(void)
2248 mutex_lock(&cfg80211_mutex); 2273 mutex_lock(&cfg80211_mutex);
2249 mutex_lock(&reg_mutex); 2274 mutex_lock(&reg_mutex);
2250 2275
2251 reset_regdomains(); 2276 reset_regdomains(true);
2252 2277
2253 kfree(last_request); 2278 dev_set_uevent_suppress(&reg_pdev->dev, true);
2254 2279
2255 platform_device_unregister(reg_pdev); 2280 platform_device_unregister(reg_pdev);
2256 2281
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index ae0c2256ba3..1c100d331e1 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -17,7 +17,7 @@
17#include "nl80211.h" 17#include "nl80211.h"
18#include "wext-compat.h" 18#include "wext-compat.h"
19 19
20#define IEEE80211_SCAN_RESULT_EXPIRE (15 * HZ) 20#define IEEE80211_SCAN_RESULT_EXPIRE (3 * HZ)
21 21
22void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) 22void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
23{ 23{
@@ -132,18 +132,17 @@ EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
132int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 132int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
133 bool driver_initiated) 133 bool driver_initiated)
134{ 134{
135 int err;
136 struct net_device *dev; 135 struct net_device *dev;
137 136
138 lockdep_assert_held(&rdev->sched_scan_mtx); 137 lockdep_assert_held(&rdev->sched_scan_mtx);
139 138
140 if (!rdev->sched_scan_req) 139 if (!rdev->sched_scan_req)
141 return 0; 140 return -ENOENT;
142 141
143 dev = rdev->sched_scan_req->dev; 142 dev = rdev->sched_scan_req->dev;
144 143
145 if (!driver_initiated) { 144 if (!driver_initiated) {
146 err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev); 145 int err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
147 if (err) 146 if (err)
148 return err; 147 return err;
149 } 148 }
@@ -153,7 +152,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
153 kfree(rdev->sched_scan_req); 152 kfree(rdev->sched_scan_req);
154 rdev->sched_scan_req = NULL; 153 rdev->sched_scan_req = NULL;
155 154
156 return err; 155 return 0;
157} 156}
158 157
159static void bss_release(struct kref *ref) 158static void bss_release(struct kref *ref)
@@ -863,6 +862,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
863 creq->n_ssids = 0; 862 creq->n_ssids = 0;
864 } 863 }
865 864
865 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
866 if (wiphy->bands[i])
867 creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
868
866 rdev->scan_req = creq; 869 rdev->scan_req = creq;
867 err = rdev->ops->scan(wiphy, dev, creq); 870 err = rdev->ops->scan(wiphy, dev, creq);
868 if (err) { 871 if (err) {
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index b7b6ff8be55..c0fe1a8a6ee 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -118,6 +118,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
118 i++, j++) 118 i++, j++)
119 request->channels[i] = 119 request->channels[i] =
120 &wdev->wiphy->bands[band]->channels[j]; 120 &wdev->wiphy->bands[band]->channels[j];
121 request->rates[band] =
122 (1 << wdev->wiphy->bands[band]->n_bitrates) - 1;
121 } 123 }
122 } 124 }
123 request->n_channels = n_channels; 125 request->n_channels = n_channels;
@@ -659,8 +661,10 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
659 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 661 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
660 return; 662 return;
661 663
664#ifndef CONFIG_CFG80211_ALLOW_RECONNECT
662 if (wdev->sme_state != CFG80211_SME_CONNECTED) 665 if (wdev->sme_state != CFG80211_SME_CONNECTED)
663 return; 666 return;
667#endif
664 668
665 if (wdev->current_bss) { 669 if (wdev->current_bss) {
666 cfg80211_unhold_bss(wdev->current_bss); 670 cfg80211_unhold_bss(wdev->current_bss);
@@ -758,10 +762,14 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
758 762
759 ASSERT_WDEV_LOCK(wdev); 763 ASSERT_WDEV_LOCK(wdev);
760 764
765#ifndef CONFIG_CFG80211_ALLOW_RECONNECT
761 if (wdev->sme_state != CFG80211_SME_IDLE) 766 if (wdev->sme_state != CFG80211_SME_IDLE)
762 return -EALREADY; 767 return -EALREADY;
763 768
764 if (WARN_ON(wdev->connect_keys)) { 769 if (WARN_ON(wdev->connect_keys)) {
770#else
771 if (wdev->connect_keys) {
772#endif
765 kfree(wdev->connect_keys); 773 kfree(wdev->connect_keys);
766 wdev->connect_keys = NULL; 774 wdev->connect_keys = NULL;
767 } 775 }
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index c6e4ca6a7d2..ff574597a85 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
93 93
94 if (rdev->ops->suspend) { 94 if (rdev->ops->suspend) {
95 rtnl_lock(); 95 rtnl_lock();
96 ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); 96 if (rdev->wiphy.registered)
97 ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
97 rtnl_unlock(); 98 rtnl_unlock();
98 } 99 }
99 100
@@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev)
112 113
113 if (rdev->ops->resume) { 114 if (rdev->ops->resume) {
114 rtnl_lock(); 115 rtnl_lock();
115 ret = rdev->ops->resume(&rdev->wiphy); 116 if (rdev->wiphy.registered)
117 ret = rdev->ops->resume(&rdev->wiphy);
116 rtnl_unlock(); 118 rtnl_unlock();
117 } 119 }
118 120
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4d7b83fbc32..be75a3a0424 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1006,3 +1006,41 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
1006 1006
1007 return -EBUSY; 1007 return -EBUSY;
1008} 1008}
1009
1010int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
1011 const u8 *rates, unsigned int n_rates,
1012 u32 *mask)
1013{
1014 int i, j;
1015
1016 if (!sband)
1017 return -EINVAL;
1018
1019 if (n_rates == 0 || n_rates > NL80211_MAX_SUPP_RATES)
1020 return -EINVAL;
1021
1022 *mask = 0;
1023
1024 for (i = 0; i < n_rates; i++) {
1025 int rate = (rates[i] & 0x7f) * 5;
1026 bool found = false;
1027
1028 for (j = 0; j < sband->n_bitrates; j++) {
1029 if (sband->bitrates[j].bitrate == rate) {
1030 found = true;
1031 *mask |= BIT(j);
1032 break;
1033 }
1034 }
1035 if (!found)
1036 return -EINVAL;
1037 }
1038
1039 /*
1040 * mask must have at least one bit set here since we
1041 * didn't accept a 0-length rates array nor allowed
1042 * entries in the array that didn't exist
1043 */
1044
1045 return 0;
1046}