aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
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
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')
-rw-r--r--net/wireless/ibss.c2
-rw-r--r--net/wireless/mlme.c6
-rw-r--r--net/wireless/scan.c86
-rw-r--r--net/wireless/sme.c16
-rw-r--r--net/wireless/trace.h24
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
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 */
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,
2636TRACE_EVENT(cfg80211_get_bss, 2636TRACE_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
2663TRACE_EVENT(cfg80211_inform_bss_width_frame, 2665TRACE_EVENT(cfg80211_inform_bss_width_frame,