aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-05-12 11:46:58 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-12 11:46:58 -0400
commit7fd38193d0473acc6e8f108107d0466f07768853 (patch)
tree076f5d81a643c818dcf6561dad0f3d75d1049dc5 /net
parent488992916c50890fbe5e7057e29681a4c4fdf1f8 (diff)
parent46fa38e84b656f80edf83d21144221b0cad18d61 (diff)
Merge tag 'mac80211-next-for-davem-2016-05-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== Some more work for 4.7, notably: * completion and fixups of nla_put_64_64bit() work * remove a/b/g/n from wext nickname to avoid confusion with 11ac (which wouldn't even fit fully there due to string length restrictions) along with some other minor changes/cleanups. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c5
-rw-r--r--net/mac80211/rx.c70
-rw-r--r--net/mac80211/wpa.c16
-rw-r--r--net/wireless/chan.c2
-rw-r--r--net/wireless/core.c17
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/nl80211.c53
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/scan.c8
-rw-r--r--net/wireless/sme.c32
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c6
-rw-r--r--net/wireless/wext-compat.c35
13 files changed, 141 insertions, 113 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 885f4ca0888d..8d426f637f58 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2399,6 +2399,11 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2399 return; 2399 return;
2400 } 2400 }
2401 2401
2402 /* AP is probably out of range (or not reachable for another reason) so
2403 * remove the bss struct for that AP.
2404 */
2405 cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
2406
2402 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 2407 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
2403 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 2408 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2404 true, frame_buf); 2409 true, frame_buf);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c5678703921e..5e65e838992a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1319,13 +1319,52 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *pubsta, bool start)
1319} 1319}
1320EXPORT_SYMBOL(ieee80211_sta_ps_transition); 1320EXPORT_SYMBOL(ieee80211_sta_ps_transition);
1321 1321
1322void ieee80211_sta_pspoll(struct ieee80211_sta *pubsta)
1323{
1324 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1325
1326 if (test_sta_flag(sta, WLAN_STA_SP))
1327 return;
1328
1329 if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
1330 ieee80211_sta_ps_deliver_poll_response(sta);
1331 else
1332 set_sta_flag(sta, WLAN_STA_PSPOLL);
1333}
1334EXPORT_SYMBOL(ieee80211_sta_pspoll);
1335
1336void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)
1337{
1338 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1339 u8 ac = ieee802_1d_to_ac[tid & 7];
1340
1341 /*
1342 * If this AC is not trigger-enabled do nothing.
1343 *
1344 * NB: This could/should check a separate bitmap of trigger-
1345 * enabled queues, but for now we only implement uAPSD w/o
1346 * TSPEC changes to the ACs, so they're always the same.
1347 */
1348 if (!(sta->sta.uapsd_queues & BIT(ac)))
1349 return;
1350
1351 /* if we are in a service period, do nothing */
1352 if (test_sta_flag(sta, WLAN_STA_SP))
1353 return;
1354
1355 if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
1356 ieee80211_sta_ps_deliver_uapsd(sta);
1357 else
1358 set_sta_flag(sta, WLAN_STA_UAPSD);
1359}
1360EXPORT_SYMBOL(ieee80211_sta_uapsd_trigger);
1361
1322static ieee80211_rx_result debug_noinline 1362static ieee80211_rx_result debug_noinline
1323ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) 1363ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
1324{ 1364{
1325 struct ieee80211_sub_if_data *sdata = rx->sdata; 1365 struct ieee80211_sub_if_data *sdata = rx->sdata;
1326 struct ieee80211_hdr *hdr = (void *)rx->skb->data; 1366 struct ieee80211_hdr *hdr = (void *)rx->skb->data;
1327 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); 1367 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1328 int tid, ac;
1329 1368
1330 if (!rx->sta) 1369 if (!rx->sta)
1331 return RX_CONTINUE; 1370 return RX_CONTINUE;
@@ -1351,12 +1390,7 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
1351 return RX_CONTINUE; 1390 return RX_CONTINUE;
1352 1391
1353 if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) { 1392 if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) {
1354 if (!test_sta_flag(rx->sta, WLAN_STA_SP)) { 1393 ieee80211_sta_pspoll(&rx->sta->sta);
1355 if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER))
1356 ieee80211_sta_ps_deliver_poll_response(rx->sta);
1357 else
1358 set_sta_flag(rx->sta, WLAN_STA_PSPOLL);
1359 }
1360 1394
1361 /* Free PS Poll skb here instead of returning RX_DROP that would 1395 /* Free PS Poll skb here instead of returning RX_DROP that would
1362 * count as an dropped frame. */ 1396 * count as an dropped frame. */
@@ -1368,27 +1402,11 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
1368 ieee80211_has_pm(hdr->frame_control) && 1402 ieee80211_has_pm(hdr->frame_control) &&
1369 (ieee80211_is_data_qos(hdr->frame_control) || 1403 (ieee80211_is_data_qos(hdr->frame_control) ||
1370 ieee80211_is_qos_nullfunc(hdr->frame_control))) { 1404 ieee80211_is_qos_nullfunc(hdr->frame_control))) {
1371 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 1405 u8 tid;
1372 ac = ieee802_1d_to_ac[tid & 7];
1373 1406
1374 /* 1407 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
1375 * If this AC is not trigger-enabled do nothing.
1376 *
1377 * NB: This could/should check a separate bitmap of trigger-
1378 * enabled queues, but for now we only implement uAPSD w/o
1379 * TSPEC changes to the ACs, so they're always the same.
1380 */
1381 if (!(rx->sta->sta.uapsd_queues & BIT(ac)))
1382 return RX_CONTINUE;
1383
1384 /* if we are in a service period, do nothing */
1385 if (test_sta_flag(rx->sta, WLAN_STA_SP))
1386 return RX_CONTINUE;
1387 1408
1388 if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER)) 1409 ieee80211_sta_uapsd_trigger(&rx->sta->sta, tid);
1389 ieee80211_sta_ps_deliver_uapsd(rx->sta);
1390 else
1391 set_sta_flag(rx->sta, WLAN_STA_UAPSD);
1392 } 1410 }
1393 1411
1394 return RX_CONTINUE; 1412 return RX_CONTINUE;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 7e4f2652bca7..b48c1e13e281 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -519,12 +519,16 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
519 return RX_DROP_UNUSABLE; 519 return RX_DROP_UNUSABLE;
520 520
521 if (!(status->flag & RX_FLAG_PN_VALIDATED)) { 521 if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
522 int res;
523
522 ccmp_hdr2pn(pn, skb->data + hdrlen); 524 ccmp_hdr2pn(pn, skb->data + hdrlen);
523 525
524 queue = rx->security_idx; 526 queue = rx->security_idx;
525 527
526 if (memcmp(pn, key->u.ccmp.rx_pn[queue], 528 res = memcmp(pn, key->u.ccmp.rx_pn[queue],
527 IEEE80211_CCMP_PN_LEN) <= 0) { 529 IEEE80211_CCMP_PN_LEN);
530 if (res < 0 ||
531 (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
528 key->u.ccmp.replays++; 532 key->u.ccmp.replays++;
529 return RX_DROP_UNUSABLE; 533 return RX_DROP_UNUSABLE;
530 } 534 }
@@ -745,12 +749,16 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
745 return RX_DROP_UNUSABLE; 749 return RX_DROP_UNUSABLE;
746 750
747 if (!(status->flag & RX_FLAG_PN_VALIDATED)) { 751 if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
752 int res;
753
748 gcmp_hdr2pn(pn, skb->data + hdrlen); 754 gcmp_hdr2pn(pn, skb->data + hdrlen);
749 755
750 queue = rx->security_idx; 756 queue = rx->security_idx;
751 757
752 if (memcmp(pn, key->u.gcmp.rx_pn[queue], 758 res = memcmp(pn, key->u.gcmp.rx_pn[queue],
753 IEEE80211_GCMP_PN_LEN) <= 0) { 759 IEEE80211_GCMP_PN_LEN);
760 if (res < 0 ||
761 (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
754 key->u.gcmp.replays++; 762 key->u.gcmp.replays++;
755 return RX_DROP_UNUSABLE; 763 return RX_DROP_UNUSABLE;
756 } 764 }
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index a6631fb319c1..da49c0b1fd32 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -739,7 +739,7 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
739 * and thus fail the GO instantiation, consider only the interfaces of 739 * and thus fail the GO instantiation, consider only the interfaces of
740 * the current registered device. 740 * the current registered device.
741 */ 741 */
742 list_for_each_entry(wdev, &rdev->wdev_list, list) { 742 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
743 struct ieee80211_channel *other_chan = NULL; 743 struct ieee80211_channel *other_chan = NULL;
744 int r1, r2; 744 int r1, r2;
745 745
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7f7b9409bf4c..d25c82bc1bbe 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2014 Intel Mobile Communications GmbH 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
6 * Copyright 2015 Intel Deutschland GmbH
6 */ 7 */
7 8
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -157,7 +158,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
157 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) 158 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
158 return -EOPNOTSUPP; 159 return -EOPNOTSUPP;
159 160
160 list_for_each_entry(wdev, &rdev->wdev_list, list) { 161 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
161 if (!wdev->netdev) 162 if (!wdev->netdev)
162 continue; 163 continue;
163 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; 164 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
@@ -171,7 +172,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
171 /* failed -- clean up to old netns */ 172 /* failed -- clean up to old netns */
172 net = wiphy_net(&rdev->wiphy); 173 net = wiphy_net(&rdev->wiphy);
173 174
174 list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list, 175 list_for_each_entry_continue_reverse(wdev,
176 &rdev->wiphy.wdev_list,
175 list) { 177 list) {
176 if (!wdev->netdev) 178 if (!wdev->netdev)
177 continue; 179 continue;
@@ -230,7 +232,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
230 232
231 ASSERT_RTNL(); 233 ASSERT_RTNL();
232 234
233 list_for_each_entry(wdev, &rdev->wdev_list, list) { 235 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
234 if (wdev->netdev) { 236 if (wdev->netdev) {
235 dev_close(wdev->netdev); 237 dev_close(wdev->netdev);
236 continue; 238 continue;
@@ -298,7 +300,8 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
298 kfree(item); 300 kfree(item);
299 spin_unlock_irq(&rdev->destroy_list_lock); 301 spin_unlock_irq(&rdev->destroy_list_lock);
300 302
301 list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) { 303 list_for_each_entry_safe(wdev, tmp,
304 &rdev->wiphy.wdev_list, list) {
302 if (nlportid == wdev->owner_nlportid) 305 if (nlportid == wdev->owner_nlportid)
303 rdev_del_virtual_intf(rdev, wdev); 306 rdev_del_virtual_intf(rdev, wdev);
304 } 307 }
@@ -410,7 +413,7 @@ use_default_name:
410 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 413 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
411 } 414 }
412 415
413 INIT_LIST_HEAD(&rdev->wdev_list); 416 INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
414 INIT_LIST_HEAD(&rdev->beacon_registrations); 417 INIT_LIST_HEAD(&rdev->beacon_registrations);
415 spin_lock_init(&rdev->beacon_registrations_lock); 418 spin_lock_init(&rdev->beacon_registrations_lock);
416 spin_lock_init(&rdev->bss_lock); 419 spin_lock_init(&rdev->bss_lock);
@@ -799,7 +802,7 @@ void wiphy_unregister(struct wiphy *wiphy)
799 nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); 802 nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
800 rdev->wiphy.registered = false; 803 rdev->wiphy.registered = false;
801 804
802 WARN_ON(!list_empty(&rdev->wdev_list)); 805 WARN_ON(!list_empty(&rdev->wiphy.wdev_list));
803 806
804 /* 807 /*
805 * First remove the hardware from everywhere, this makes 808 * First remove the hardware from everywhere, this makes
@@ -1021,7 +1024,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1021 spin_lock_init(&wdev->mgmt_registrations_lock); 1024 spin_lock_init(&wdev->mgmt_registrations_lock);
1022 1025
1023 wdev->identifier = ++rdev->wdev_id; 1026 wdev->identifier = ++rdev->wdev_id;
1024 list_add_rcu(&wdev->list, &rdev->wdev_list); 1027 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
1025 rdev->devlist_generation++; 1028 rdev->devlist_generation++;
1026 /* can only change netns with wiphy */ 1029 /* can only change netns with wiphy */
1027 dev->features |= NETIF_F_NETNS_LOCAL; 1030 dev->features |= NETIF_F_NETNS_LOCAL;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 022ccad06cbe..025b7a5d508b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -50,10 +50,9 @@ struct cfg80211_registered_device {
50 /* wiphy index, internal only */ 50 /* wiphy index, internal only */
51 int wiphy_idx; 51 int wiphy_idx;
52 52
53 /* associated wireless interfaces, protected by rtnl or RCU */ 53 /* protected by RTNL */
54 struct list_head wdev_list;
55 int devlist_generation, wdev_id; 54 int devlist_generation, wdev_id;
56 int opencount; /* also protected by devlist_mtx */ 55 int opencount;
57 wait_queue_head_t dev_wait; 56 wait_queue_head_t dev_wait;
58 57
59 struct list_head beacon_registrations; 58 struct list_head beacon_registrations;
@@ -214,6 +213,7 @@ struct cfg80211_event {
214 const u8 *resp_ie; 213 const u8 *resp_ie;
215 size_t req_ie_len; 214 size_t req_ie_len;
216 size_t resp_ie_len; 215 size_t resp_ie_len;
216 struct cfg80211_bss *bss;
217 u16 status; 217 u16 status;
218 } cr; 218 } cr;
219 struct { 219 struct {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index afeb1ef1b199..d7599014055d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -103,7 +103,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
103 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) 103 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
104 continue; 104 continue;
105 105
106 list_for_each_entry(wdev, &rdev->wdev_list, list) { 106 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
107 if (have_ifidx && wdev->netdev && 107 if (have_ifidx && wdev->netdev &&
108 wdev->netdev->ifindex == ifidx) { 108 wdev->netdev->ifindex == ifidx) {
109 result = wdev; 109 result = wdev;
@@ -149,7 +149,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
149 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); 149 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
150 if (tmp) { 150 if (tmp) {
151 /* make sure wdev exists */ 151 /* make sure wdev exists */
152 list_for_each_entry(wdev, &tmp->wdev_list, list) { 152 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
153 if (wdev->identifier != (u32)wdev_id) 153 if (wdev->identifier != (u32)wdev_id)
154 continue; 154 continue;
155 found = true; 155 found = true;
@@ -535,7 +535,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
535 *rdev = wiphy_to_rdev(wiphy); 535 *rdev = wiphy_to_rdev(wiphy);
536 *wdev = NULL; 536 *wdev = NULL;
537 537
538 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 538 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
539 if (tmp->identifier == cb->args[1]) { 539 if (tmp->identifier == cb->args[1]) {
540 *wdev = tmp; 540 *wdev = tmp;
541 break; 541 break;
@@ -2490,7 +2490,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2490 } 2490 }
2491 if_idx = 0; 2491 if_idx = 0;
2492 2492
2493 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2493 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
2494 if (if_idx < if_start) { 2494 if (if_idx < if_start) {
2495 if_idx++; 2495 if_idx++;
2496 continue; 2496 continue;
@@ -2762,7 +2762,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2762 spin_lock_init(&wdev->mgmt_registrations_lock); 2762 spin_lock_init(&wdev->mgmt_registrations_lock);
2763 2763
2764 wdev->identifier = ++rdev->wdev_id; 2764 wdev->identifier = ++rdev->wdev_id;
2765 list_add_rcu(&wdev->list, &rdev->wdev_list); 2765 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
2766 rdev->devlist_generation++; 2766 rdev->devlist_generation++;
2767 break; 2767 break;
2768 default: 2768 default:
@@ -3298,7 +3298,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3298 struct wireless_dev *wdev; 3298 struct wireless_dev *wdev;
3299 bool ret = false; 3299 bool ret = false;
3300 3300
3301 list_for_each_entry(wdev, &rdev->wdev_list, list) { 3301 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
3302 if (wdev->iftype != NL80211_IFTYPE_AP && 3302 if (wdev->iftype != NL80211_IFTYPE_AP &&
3303 wdev->iftype != NL80211_IFTYPE_P2P_GO) 3303 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3304 continue; 3304 continue;
@@ -3755,11 +3755,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
3755 goto nla_put_failure; 3755 goto nla_put_failure;
3756 3756
3757#define PUT_SINFO(attr, memb, type) do { \ 3757#define PUT_SINFO(attr, memb, type) do { \
3758 if (sinfo->filled & BIT(NL80211_STA_INFO_ ## attr) && \ 3758 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
3759 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
3759 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \ 3760 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
3760 sinfo->memb)) \ 3761 sinfo->memb)) \
3761 goto nla_put_failure; \ 3762 goto nla_put_failure; \
3762 } while (0) 3763 } while (0)
3764#define PUT_SINFO_U64(attr, memb) do { \
3765 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
3766 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
3767 sinfo->memb, NL80211_STA_INFO_PAD)) \
3768 goto nla_put_failure; \
3769 } while (0)
3763 3770
3764 PUT_SINFO(CONNECTED_TIME, connected_time, u32); 3771 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
3765 PUT_SINFO(INACTIVE_TIME, inactive_time, u32); 3772 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
@@ -3776,11 +3783,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
3776 (u32)sinfo->tx_bytes)) 3783 (u32)sinfo->tx_bytes))
3777 goto nla_put_failure; 3784 goto nla_put_failure;
3778 3785
3779 PUT_SINFO(RX_BYTES64, rx_bytes, u64); 3786 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
3780 PUT_SINFO(TX_BYTES64, tx_bytes, u64); 3787 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
3781 PUT_SINFO(LLID, llid, u16); 3788 PUT_SINFO(LLID, llid, u16);
3782 PUT_SINFO(PLID, plid, u16); 3789 PUT_SINFO(PLID, plid, u16);
3783 PUT_SINFO(PLINK_STATE, plink_state, u8); 3790 PUT_SINFO(PLINK_STATE, plink_state, u8);
3791 PUT_SINFO_U64(RX_DURATION, rx_duration);
3784 3792
3785 switch (rdev->wiphy.signal_type) { 3793 switch (rdev->wiphy.signal_type) {
3786 case CFG80211_SIGNAL_TYPE_MBM: 3794 case CFG80211_SIGNAL_TYPE_MBM:
@@ -3848,12 +3856,13 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
3848 &sinfo->sta_flags)) 3856 &sinfo->sta_flags))
3849 goto nla_put_failure; 3857 goto nla_put_failure;
3850 3858
3851 PUT_SINFO(T_OFFSET, t_offset, u64); 3859 PUT_SINFO_U64(T_OFFSET, t_offset);
3852 PUT_SINFO(RX_DROP_MISC, rx_dropped_misc, u64); 3860 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
3853 PUT_SINFO(BEACON_RX, rx_beacon, u64); 3861 PUT_SINFO_U64(BEACON_RX, rx_beacon);
3854 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); 3862 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
3855 3863
3856#undef PUT_SINFO 3864#undef PUT_SINFO
3865#undef PUT_SINFO_U64
3857 3866
3858 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) { 3867 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
3859 struct nlattr *tidsattr; 3868 struct nlattr *tidsattr;
@@ -3876,19 +3885,19 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
3876 if (!tidattr) 3885 if (!tidattr)
3877 goto nla_put_failure; 3886 goto nla_put_failure;
3878 3887
3879#define PUT_TIDVAL(attr, memb, type) do { \ 3888#define PUT_TIDVAL_U64(attr, memb) do { \
3880 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \ 3889 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
3881 nla_put_ ## type(msg, NL80211_TID_STATS_ ## attr, \ 3890 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
3882 tidstats->memb)) \ 3891 tidstats->memb, NL80211_TID_STATS_PAD)) \
3883 goto nla_put_failure; \ 3892 goto nla_put_failure; \
3884 } while (0) 3893 } while (0)
3885 3894
3886 PUT_TIDVAL(RX_MSDU, rx_msdu, u64); 3895 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
3887 PUT_TIDVAL(TX_MSDU, tx_msdu, u64); 3896 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
3888 PUT_TIDVAL(TX_MSDU_RETRIES, tx_msdu_retries, u64); 3897 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
3889 PUT_TIDVAL(TX_MSDU_FAILED, tx_msdu_failed, u64); 3898 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
3890 3899
3891#undef PUT_TIDVAL 3900#undef PUT_TIDVAL_U64
3892 nla_nest_end(msg, tidattr); 3901 nla_nest_end(msg, tidattr);
3893 } 3902 }
3894 3903
@@ -10383,7 +10392,7 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
10383 *wdev = NULL; 10392 *wdev = NULL;
10384 10393
10385 if (cb->args[1]) { 10394 if (cb->args[1]) {
10386 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 10395 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
10387 if (tmp->identifier == cb->args[1] - 1) { 10396 if (tmp->identifier == cb->args[1] - 1) {
10388 *wdev = tmp; 10397 *wdev = tmp;
10389 break; 10398 break;
@@ -13404,7 +13413,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
13404 sched_scan_req->owner_nlportid == notify->portid) 13413 sched_scan_req->owner_nlportid == notify->portid)
13405 schedule_scan_stop = true; 13414 schedule_scan_stop = true;
13406 13415
13407 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { 13416 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
13408 cfg80211_mlme_unregister_socket(wdev, notify->portid); 13417 cfg80211_mlme_unregister_socket(wdev, notify->portid);
13409 13418
13410 if (wdev->owner_nlportid == notify->portid) 13419 if (wdev->owner_nlportid == notify->portid)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e271dea6bc02..5dbac3749738 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1639,7 +1639,7 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy)
1639 1639
1640 ASSERT_RTNL(); 1640 ASSERT_RTNL();
1641 1641
1642 list_for_each_entry(wdev, &rdev->wdev_list, list) 1642 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
1643 if (!reg_wdev_chan_valid(wiphy, wdev)) 1643 if (!reg_wdev_chan_valid(wiphy, wdev))
1644 cfg80211_leave(rdev, wdev); 1644 cfg80211_leave(rdev, wdev);
1645} 1645}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index abdf651a70d9..ef2955c89a00 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -364,13 +364,16 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
364} 364}
365EXPORT_SYMBOL(cfg80211_find_ie); 365EXPORT_SYMBOL(cfg80211_find_ie);
366 366
367const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, 367const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
368 const u8 *ies, int len) 368 const u8 *ies, int len)
369{ 369{
370 struct ieee80211_vendor_ie *ie; 370 struct ieee80211_vendor_ie *ie;
371 const u8 *pos = ies, *end = ies + len; 371 const u8 *pos = ies, *end = ies + len;
372 int ie_oui; 372 int ie_oui;
373 373
374 if (WARN_ON(oui_type > 0xff))
375 return NULL;
376
374 while (pos < end) { 377 while (pos < end) {
375 pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, 378 pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos,
376 end - pos); 379 end - pos);
@@ -386,7 +389,8 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
386 goto cont; 389 goto cont;
387 390
388 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; 391 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
389 if (ie_oui == oui && ie->oui_type == oui_type) 392 if (ie_oui == oui &&
393 (oui_type < 0 || ie->oui_type == oui_type))
390 return pos; 394 return pos;
391cont: 395cont:
392 pos += 2 + ie->len; 396 pos += 2 + ie->len;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index e22e5b83cfa9..584fdc347221 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -223,7 +223,7 @@ void cfg80211_conn_work(struct work_struct *work)
223 223
224 rtnl_lock(); 224 rtnl_lock();
225 225
226 list_for_each_entry(wdev, &rdev->wdev_list, list) { 226 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
227 if (!wdev->netdev) 227 if (!wdev->netdev)
228 continue; 228 continue;
229 229
@@ -617,7 +617,7 @@ static bool cfg80211_is_all_idle(void)
617 * count as new regulatory hints. 617 * count as new regulatory hints.
618 */ 618 */
619 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 619 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
620 list_for_each_entry(wdev, &rdev->wdev_list, list) { 620 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
621 wdev_lock(wdev); 621 wdev_lock(wdev);
622 if (wdev->conn || wdev->current_bss) 622 if (wdev->conn || wdev->current_bss)
623 is_all_idle = false; 623 is_all_idle = false;
@@ -753,19 +753,32 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
753 kfree(country_ie); 753 kfree(country_ie);
754} 754}
755 755
756void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 756/* Consumes bss object one way or another */
757 const u8 *req_ie, size_t req_ie_len, 757void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
758 const u8 *resp_ie, size_t resp_ie_len, 758 struct cfg80211_bss *bss, const u8 *req_ie,
759 u16 status, gfp_t gfp) 759 size_t req_ie_len, const u8 *resp_ie,
760 size_t resp_ie_len, u16 status, gfp_t gfp)
760{ 761{
761 struct wireless_dev *wdev = dev->ieee80211_ptr; 762 struct wireless_dev *wdev = dev->ieee80211_ptr;
762 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 763 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
763 struct cfg80211_event *ev; 764 struct cfg80211_event *ev;
764 unsigned long flags; 765 unsigned long flags;
765 766
767 if (bss) {
768 /* Make sure the bss entry provided by the driver is valid. */
769 struct cfg80211_internal_bss *ibss = bss_from_pub(bss);
770
771 if (WARN_ON(list_empty(&ibss->list))) {
772 cfg80211_put_bss(wdev->wiphy, bss);
773 return;
774 }
775 }
776
766 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 777 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
767 if (!ev) 778 if (!ev) {
779 cfg80211_put_bss(wdev->wiphy, bss);
768 return; 780 return;
781 }
769 782
770 ev->type = EVENT_CONNECT_RESULT; 783 ev->type = EVENT_CONNECT_RESULT;
771 if (bssid) 784 if (bssid)
@@ -780,6 +793,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
780 ev->cr.resp_ie_len = resp_ie_len; 793 ev->cr.resp_ie_len = resp_ie_len;
781 memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len); 794 memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
782 } 795 }
796 if (bss)
797 cfg80211_hold_bss(bss_from_pub(bss));
798 ev->cr.bss = bss;
783 ev->cr.status = status; 799 ev->cr.status = status;
784 800
785 spin_lock_irqsave(&wdev->event_lock, flags); 801 spin_lock_irqsave(&wdev->event_lock, flags);
@@ -787,7 +803,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
787 spin_unlock_irqrestore(&wdev->event_lock, flags); 803 spin_unlock_irqrestore(&wdev->event_lock, flags);
788 queue_work(cfg80211_wq, &rdev->event_work); 804 queue_work(cfg80211_wq, &rdev->event_work);
789} 805}
790EXPORT_SYMBOL(cfg80211_connect_result); 806EXPORT_SYMBOL(cfg80211_connect_bss);
791 807
792/* Consumes bss object one way or another */ 808/* Consumes bss object one way or another */
793void __cfg80211_roamed(struct wireless_dev *wdev, 809void __cfg80211_roamed(struct wireless_dev *wdev,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 9cee0220665d..e46469bc130f 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -91,7 +91,7 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
91{ 91{
92 struct wireless_dev *wdev; 92 struct wireless_dev *wdev;
93 93
94 list_for_each_entry(wdev, &rdev->wdev_list, list) 94 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
95 cfg80211_leave(rdev, wdev); 95 cfg80211_leave(rdev, wdev);
96} 96}
97 97
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f36039888eb5..219bd197039e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -950,7 +950,7 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
950 ev->cr.resp_ie, ev->cr.resp_ie_len, 950 ev->cr.resp_ie, ev->cr.resp_ie_len,
951 ev->cr.status, 951 ev->cr.status,
952 ev->cr.status == WLAN_STATUS_SUCCESS, 952 ev->cr.status == WLAN_STATUS_SUCCESS,
953 NULL); 953 ev->cr.bss);
954 break; 954 break;
955 case EVENT_ROAMED: 955 case EVENT_ROAMED:
956 __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie, 956 __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
@@ -986,7 +986,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
986 986
987 ASSERT_RTNL(); 987 ASSERT_RTNL();
988 988
989 list_for_each_entry(wdev, &rdev->wdev_list, list) 989 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
990 cfg80211_process_wdev_events(wdev); 990 cfg80211_process_wdev_events(wdev);
991} 991}
992 992
@@ -1560,7 +1560,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1560 if (!beacon_int) 1560 if (!beacon_int)
1561 return -EINVAL; 1561 return -EINVAL;
1562 1562
1563 list_for_each_entry(wdev, &rdev->wdev_list, list) { 1563 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
1564 if (!wdev->beacon_interval) 1564 if (!wdev->beacon_interval)
1565 continue; 1565 continue;
1566 if (wdev->beacon_interval != beacon_int) { 1566 if (wdev->beacon_interval != beacon_int) {
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 4c89f0ca61ba..9f27221c8913 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -25,42 +25,7 @@ int cfg80211_wext_giwname(struct net_device *dev,
25 struct iw_request_info *info, 25 struct iw_request_info *info,
26 char *name, char *extra) 26 char *name, char *extra)
27{ 27{
28 struct wireless_dev *wdev = dev->ieee80211_ptr;
29 struct ieee80211_supported_band *sband;
30 bool is_ht = false, is_a = false, is_b = false, is_g = false;
31
32 if (!wdev)
33 return -EOPNOTSUPP;
34
35 sband = wdev->wiphy->bands[NL80211_BAND_5GHZ];
36 if (sband) {
37 is_a = true;
38 is_ht |= sband->ht_cap.ht_supported;
39 }
40
41 sband = wdev->wiphy->bands[NL80211_BAND_2GHZ];
42 if (sband) {
43 int i;
44 /* Check for mandatory rates */
45 for (i = 0; i < sband->n_bitrates; i++) {
46 if (sband->bitrates[i].bitrate == 10)
47 is_b = true;
48 if (sband->bitrates[i].bitrate == 60)
49 is_g = true;
50 }
51 is_ht |= sband->ht_cap.ht_supported;
52 }
53
54 strcpy(name, "IEEE 802.11"); 28 strcpy(name, "IEEE 802.11");
55 if (is_a)
56 strcat(name, "a");
57 if (is_b)
58 strcat(name, "b");
59 if (is_g)
60 strcat(name, "g");
61 if (is_ht)
62 strcat(name, "n");
63
64 return 0; 29 return 0;
65} 30}
66EXPORT_WEXT_HANDLER(cfg80211_wext_giwname); 31EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);