diff options
author | Dedy Lansky <dlansky@codeaurora.org> | 2015-02-08 08:52:03 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-03-03 09:56:01 -0500 |
commit | 6eb18137643fee5f182d85c818062b4feddfb76b (patch) | |
tree | 6c9712c947498fd2291a53acfe2be48711a881ac /net/wireless | |
parent | 76a70e9c4b45fc1dbcbff6f7ae88ac7e1ddfb677 (diff) |
cfg80211: add bss_type and privacy arguments in cfg80211_get_bss()
802.11ad adds new a network type (PBSS) and changes the capability
field interpretation for the DMG (60G) band.
The same 2 bits that were interpreted as "ESS" and "IBSS" before are
re-used as a 2-bit field with 3 valid values (and 1 reserved). Valid
values are: "IBSS", "PBSS" (new) and "AP".
In order to get the BSS struct for the new PBSS networks, change the
cfg80211_get_bss() function to take a new enum ieee80211_bss_type
argument with the valid network types, as "capa_mask" and "capa_val"
no longer work correctly (the search must be band-aware now.)
The remaining bits in "capa_mask" and "capa_val" are used only for
privacy matching so replace those two with a privacy enum as well.
Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
[rewrite commit log, tiny fixes]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/ibss.c | 2 | ||||
-rw-r--r-- | net/wireless/mlme.c | 6 | ||||
-rw-r--r-- | net/wireless/scan.c | 86 | ||||
-rw-r--r-- | net/wireless/sme.c | 16 | ||||
-rw-r--r-- | net/wireless/trace.h | 24 |
5 files changed, 102 insertions, 32 deletions
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index e24fc585c883..1a65662a5d73 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -30,7 +30,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, | |||
30 | return; | 30 | return; |
31 | 31 | ||
32 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, | 32 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, |
33 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); | 33 | IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY); |
34 | 34 | ||
35 | if (WARN_ON(!bss)) | 35 | if (WARN_ON(!bss)) |
36 | return; | 36 | return; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 2c52b59e43f3..7aae329e2b4e 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -229,7 +229,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
229 | return -EALREADY; | 229 | return -EALREADY; |
230 | 230 | ||
231 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 231 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
232 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 232 | IEEE80211_BSS_TYPE_ESS, |
233 | IEEE80211_PRIVACY_ANY); | ||
233 | if (!req.bss) | 234 | if (!req.bss) |
234 | return -ENOENT; | 235 | return -ENOENT; |
235 | 236 | ||
@@ -296,7 +297,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
296 | rdev->wiphy.vht_capa_mod_mask); | 297 | rdev->wiphy.vht_capa_mod_mask); |
297 | 298 | ||
298 | req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 299 | req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
299 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 300 | IEEE80211_BSS_TYPE_ESS, |
301 | IEEE80211_PRIVACY_ANY); | ||
300 | if (!req->bss) | 302 | if (!req->bss) |
301 | return -ENOENT; | 303 | return -ENOENT; |
302 | 304 | ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index ceb8f0040dae..3a50aa2553bf 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -531,24 +531,78 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
534 | static bool cfg80211_bss_type_match(u16 capability, | ||
535 | enum ieee80211_band band, | ||
536 | enum ieee80211_bss_type bss_type) | ||
537 | { | ||
538 | bool ret = true; | ||
539 | u16 mask, val; | ||
540 | |||
541 | if (bss_type == IEEE80211_BSS_TYPE_ANY) | ||
542 | return ret; | ||
543 | |||
544 | if (band == IEEE80211_BAND_60GHZ) { | ||
545 | mask = WLAN_CAPABILITY_DMG_TYPE_MASK; | ||
546 | switch (bss_type) { | ||
547 | case IEEE80211_BSS_TYPE_ESS: | ||
548 | val = WLAN_CAPABILITY_DMG_TYPE_AP; | ||
549 | break; | ||
550 | case IEEE80211_BSS_TYPE_PBSS: | ||
551 | val = WLAN_CAPABILITY_DMG_TYPE_PBSS; | ||
552 | break; | ||
553 | case IEEE80211_BSS_TYPE_IBSS: | ||
554 | val = WLAN_CAPABILITY_DMG_TYPE_IBSS; | ||
555 | break; | ||
556 | default: | ||
557 | return false; | ||
558 | } | ||
559 | } else { | ||
560 | mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS; | ||
561 | switch (bss_type) { | ||
562 | case IEEE80211_BSS_TYPE_ESS: | ||
563 | val = WLAN_CAPABILITY_ESS; | ||
564 | break; | ||
565 | case IEEE80211_BSS_TYPE_IBSS: | ||
566 | val = WLAN_CAPABILITY_IBSS; | ||
567 | break; | ||
568 | case IEEE80211_BSS_TYPE_MBSS: | ||
569 | val = 0; | ||
570 | break; | ||
571 | default: | ||
572 | return false; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | ret = ((capability & mask) == val); | ||
577 | return ret; | ||
578 | } | ||
579 | |||
534 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | 580 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
535 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 581 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
536 | struct ieee80211_channel *channel, | 582 | struct ieee80211_channel *channel, |
537 | const u8 *bssid, | 583 | const u8 *bssid, |
538 | const u8 *ssid, size_t ssid_len, | 584 | const u8 *ssid, size_t ssid_len, |
539 | u16 capa_mask, u16 capa_val) | 585 | enum ieee80211_bss_type bss_type, |
586 | enum ieee80211_privacy privacy) | ||
540 | { | 587 | { |
541 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | 588 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
542 | struct cfg80211_internal_bss *bss, *res = NULL; | 589 | struct cfg80211_internal_bss *bss, *res = NULL; |
543 | unsigned long now = jiffies; | 590 | unsigned long now = jiffies; |
591 | int bss_privacy; | ||
544 | 592 | ||
545 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, | 593 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type, |
546 | capa_val); | 594 | privacy); |
547 | 595 | ||
548 | spin_lock_bh(&rdev->bss_lock); | 596 | spin_lock_bh(&rdev->bss_lock); |
549 | 597 | ||
550 | list_for_each_entry(bss, &rdev->bss_list, list) { | 598 | list_for_each_entry(bss, &rdev->bss_list, list) { |
551 | if ((bss->pub.capability & capa_mask) != capa_val) | 599 | if (!cfg80211_bss_type_match(bss->pub.capability, |
600 | bss->pub.channel->band, bss_type)) | ||
601 | continue; | ||
602 | |||
603 | bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY); | ||
604 | if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) || | ||
605 | (privacy == IEEE80211_PRIVACY_OFF && bss_privacy)) | ||
552 | continue; | 606 | continue; |
553 | if (channel && bss->pub.channel != channel) | 607 | if (channel && bss->pub.channel != channel) |
554 | continue; | 608 | continue; |
@@ -896,6 +950,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
896 | struct cfg80211_bss_ies *ies; | 950 | struct cfg80211_bss_ies *ies; |
897 | struct ieee80211_channel *channel; | 951 | struct ieee80211_channel *channel; |
898 | struct cfg80211_internal_bss tmp = {}, *res; | 952 | struct cfg80211_internal_bss tmp = {}, *res; |
953 | int bss_type; | ||
899 | bool signal_valid; | 954 | bool signal_valid; |
900 | 955 | ||
901 | if (WARN_ON(!wiphy)) | 956 | if (WARN_ON(!wiphy)) |
@@ -950,8 +1005,15 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
950 | if (!res) | 1005 | if (!res) |
951 | return NULL; | 1006 | return NULL; |
952 | 1007 | ||
953 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | 1008 | if (channel->band == IEEE80211_BAND_60GHZ) { |
954 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 1009 | bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK; |
1010 | if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP || | ||
1011 | bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS) | ||
1012 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1013 | } else { | ||
1014 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | ||
1015 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1016 | } | ||
955 | 1017 | ||
956 | trace_cfg80211_return_bss(&res->pub); | 1018 | trace_cfg80211_return_bss(&res->pub); |
957 | /* cfg80211_bss_update gives us a referenced result */ | 1019 | /* cfg80211_bss_update gives us a referenced result */ |
@@ -973,6 +1035,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
973 | bool signal_valid; | 1035 | bool signal_valid; |
974 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 1036 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
975 | u.probe_resp.variable); | 1037 | u.probe_resp.variable); |
1038 | int bss_type; | ||
976 | 1039 | ||
977 | BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != | 1040 | BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != |
978 | offsetof(struct ieee80211_mgmt, u.beacon.variable)); | 1041 | offsetof(struct ieee80211_mgmt, u.beacon.variable)); |
@@ -1025,8 +1088,15 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
1025 | if (!res) | 1088 | if (!res) |
1026 | return NULL; | 1089 | return NULL; |
1027 | 1090 | ||
1028 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | 1091 | if (channel->band == IEEE80211_BAND_60GHZ) { |
1029 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 1092 | bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK; |
1093 | if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP || | ||
1094 | bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS) | ||
1095 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1096 | } else { | ||
1097 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | ||
1098 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1099 | } | ||
1030 | 1100 | ||
1031 | trace_cfg80211_return_bss(&res->pub); | 1101 | trace_cfg80211_return_bss(&res->pub); |
1032 | /* cfg80211_bss_update gives us a referenced result */ | 1102 | /* cfg80211_bss_update gives us a referenced result */ |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 0ab3711c79a0..ea1da6621ff0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -257,19 +257,15 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) | |||
257 | { | 257 | { |
258 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 258 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
259 | struct cfg80211_bss *bss; | 259 | struct cfg80211_bss *bss; |
260 | u16 capa = WLAN_CAPABILITY_ESS; | ||
261 | 260 | ||
262 | ASSERT_WDEV_LOCK(wdev); | 261 | ASSERT_WDEV_LOCK(wdev); |
263 | 262 | ||
264 | if (wdev->conn->params.privacy) | ||
265 | capa |= WLAN_CAPABILITY_PRIVACY; | ||
266 | |||
267 | bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, | 263 | bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, |
268 | wdev->conn->params.bssid, | 264 | wdev->conn->params.bssid, |
269 | wdev->conn->params.ssid, | 265 | wdev->conn->params.ssid, |
270 | wdev->conn->params.ssid_len, | 266 | wdev->conn->params.ssid_len, |
271 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, | 267 | IEEE80211_BSS_TYPE_ESS, |
272 | capa); | 268 | IEEE80211_PRIVACY(wdev->conn->params.privacy)); |
273 | if (!bss) | 269 | if (!bss) |
274 | return NULL; | 270 | return NULL; |
275 | 271 | ||
@@ -637,8 +633,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
637 | WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect); | 633 | WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect); |
638 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 634 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, |
639 | wdev->ssid, wdev->ssid_len, | 635 | wdev->ssid, wdev->ssid_len, |
640 | WLAN_CAPABILITY_ESS, | 636 | IEEE80211_BSS_TYPE_ESS, |
641 | WLAN_CAPABILITY_ESS); | 637 | IEEE80211_PRIVACY_ANY); |
642 | if (bss) | 638 | if (bss) |
643 | cfg80211_hold_bss(bss_from_pub(bss)); | 639 | cfg80211_hold_bss(bss_from_pub(bss)); |
644 | } | 640 | } |
@@ -795,8 +791,8 @@ void cfg80211_roamed(struct net_device *dev, | |||
795 | struct cfg80211_bss *bss; | 791 | struct cfg80211_bss *bss; |
796 | 792 | ||
797 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, | 793 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, |
798 | wdev->ssid_len, WLAN_CAPABILITY_ESS, | 794 | wdev->ssid_len, |
799 | WLAN_CAPABILITY_ESS); | 795 | IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY); |
800 | if (WARN_ON(!bss)) | 796 | if (WARN_ON(!bss)) |
801 | return; | 797 | return; |
802 | 798 | ||
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b17b3692f8c2..b19773c9c81b 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -2636,28 +2636,30 @@ DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_stopped, | |||
2636 | TRACE_EVENT(cfg80211_get_bss, | 2636 | TRACE_EVENT(cfg80211_get_bss, |
2637 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, | 2637 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, |
2638 | const u8 *bssid, const u8 *ssid, size_t ssid_len, | 2638 | const u8 *bssid, const u8 *ssid, size_t ssid_len, |
2639 | u16 capa_mask, u16 capa_val), | 2639 | enum ieee80211_bss_type bss_type, |
2640 | TP_ARGS(wiphy, channel, bssid, ssid, ssid_len, capa_mask, capa_val), | 2640 | enum ieee80211_privacy privacy), |
2641 | TP_ARGS(wiphy, channel, bssid, ssid, ssid_len, bss_type, privacy), | ||
2641 | TP_STRUCT__entry( | 2642 | TP_STRUCT__entry( |
2642 | WIPHY_ENTRY | 2643 | WIPHY_ENTRY |
2643 | CHAN_ENTRY | 2644 | CHAN_ENTRY |
2644 | MAC_ENTRY(bssid) | 2645 | MAC_ENTRY(bssid) |
2645 | __dynamic_array(u8, ssid, ssid_len) | 2646 | __dynamic_array(u8, ssid, ssid_len) |
2646 | __field(u16, capa_mask) | 2647 | __field(enum ieee80211_bss_type, bss_type) |
2647 | __field(u16, capa_val) | 2648 | __field(enum ieee80211_privacy, privacy) |
2648 | ), | 2649 | ), |
2649 | TP_fast_assign( | 2650 | TP_fast_assign( |
2650 | WIPHY_ASSIGN; | 2651 | WIPHY_ASSIGN; |
2651 | CHAN_ASSIGN(channel); | 2652 | CHAN_ASSIGN(channel); |
2652 | MAC_ASSIGN(bssid, bssid); | 2653 | MAC_ASSIGN(bssid, bssid); |
2653 | memcpy(__get_dynamic_array(ssid), ssid, ssid_len); | 2654 | memcpy(__get_dynamic_array(ssid), ssid, ssid_len); |
2654 | __entry->capa_mask = capa_mask; | 2655 | __entry->bss_type = bss_type; |
2655 | __entry->capa_val = capa_val; | 2656 | __entry->privacy = privacy; |
2656 | ), | 2657 | ), |
2657 | TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT ", buf: %#.2x, " | 2658 | TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT |
2658 | "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG, | 2659 | ", buf: %#.2x, bss_type: %d, privacy: %d", |
2659 | MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0], | 2660 | WIPHY_PR_ARG, CHAN_PR_ARG, MAC_PR_ARG(bssid), |
2660 | __entry->capa_mask, __entry->capa_val) | 2661 | ((u8 *)__get_dynamic_array(ssid))[0], __entry->bss_type, |
2662 | __entry->privacy) | ||
2661 | ); | 2663 | ); |
2662 | 2664 | ||
2663 | TRACE_EVENT(cfg80211_inform_bss_width_frame, | 2665 | TRACE_EVENT(cfg80211_inform_bss_width_frame, |