aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
authorDedy Lansky <dlansky@codeaurora.org>2015-02-08 08:52:03 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-03-03 09:56:01 -0500
commit6eb18137643fee5f182d85c818062b4feddfb76b (patch)
tree6c9712c947498fd2291a53acfe2be48711a881ac /net/wireless/scan.c
parent76a70e9c4b45fc1dbcbff6f7ae88ac7e1ddfb677 (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.c86
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
534static 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. */
535struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, 581struct 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 */