diff options
author | David S. Miller <davem@davemloft.net> | 2016-05-12 11:46:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-12 11:46:58 -0400 |
commit | 7fd38193d0473acc6e8f108107d0466f07768853 (patch) | |
tree | 076f5d81a643c818dcf6561dad0f3d75d1049dc5 /net | |
parent | 488992916c50890fbe5e7057e29681a4c4fdf1f8 (diff) | |
parent | 46fa38e84b656f80edf83d21144221b0cad18d61 (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.c | 5 | ||||
-rw-r--r-- | net/mac80211/rx.c | 70 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 16 | ||||
-rw-r--r-- | net/wireless/chan.c | 2 | ||||
-rw-r--r-- | net/wireless/core.c | 17 | ||||
-rw-r--r-- | net/wireless/core.h | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 53 | ||||
-rw-r--r-- | net/wireless/reg.c | 2 | ||||
-rw-r--r-- | net/wireless/scan.c | 8 | ||||
-rw-r--r-- | net/wireless/sme.c | 32 | ||||
-rw-r--r-- | net/wireless/sysfs.c | 2 | ||||
-rw-r--r-- | net/wireless/util.c | 6 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 35 |
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 | } |
1320 | EXPORT_SYMBOL(ieee80211_sta_ps_transition); | 1320 | EXPORT_SYMBOL(ieee80211_sta_ps_transition); |
1321 | 1321 | ||
1322 | void 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 | } | ||
1334 | EXPORT_SYMBOL(ieee80211_sta_pspoll); | ||
1335 | |||
1336 | void 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 | } | ||
1360 | EXPORT_SYMBOL(ieee80211_sta_uapsd_trigger); | ||
1361 | |||
1322 | static ieee80211_rx_result debug_noinline | 1362 | static ieee80211_rx_result debug_noinline |
1323 | ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) | 1363 | ieee80211_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 | } |
365 | EXPORT_SYMBOL(cfg80211_find_ie); | 365 | EXPORT_SYMBOL(cfg80211_find_ie); |
366 | 366 | ||
367 | const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, | 367 | const 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; |
391 | cont: | 395 | cont: |
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 | ||
756 | void 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, | 757 | void 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 | } |
790 | EXPORT_SYMBOL(cfg80211_connect_result); | 806 | EXPORT_SYMBOL(cfg80211_connect_bss); |
791 | 807 | ||
792 | /* Consumes bss object one way or another */ | 808 | /* Consumes bss object one way or another */ |
793 | void __cfg80211_roamed(struct wireless_dev *wdev, | 809 | void __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 | } |
66 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwname); | 31 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwname); |