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/scan.c | |
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/scan.c')
-rw-r--r-- | net/wireless/scan.c | 86 |
1 files changed, 78 insertions, 8 deletions
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 */ |