aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c3
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c9
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c2
-rw-r--r--drivers/net/wireless/cw1200/sta.c4
-rw-r--r--drivers/net/wireless/libertas/cfg.c6
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c8
-rw-r--r--include/net/cfg80211.h39
-rw-r--r--net/mac80211/ibss.c43
-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
13 files changed, 168 insertions, 80 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index d6d2f0f00caa..d372ebfd933d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1386,7 +1386,8 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
1386 lockdep_assert_held(&ar->conf_mutex); 1386 lockdep_assert_held(&ar->conf_mutex);
1387 1387
1388 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, 1388 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan,
1389 info->bssid, NULL, 0, 0, 0); 1389 info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY,
1390 IEEE80211_PRIVACY_ANY);
1390 if (bss) { 1391 if (bss) {
1391 const struct cfg80211_bss_ies *ies; 1392 const struct cfg80211_bss_ies *ies;
1392 1393
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 85da63a67faf..ff7ba5c195c6 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -686,20 +686,21 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
686{ 686{
687 struct ath6kl *ar = vif->ar; 687 struct ath6kl *ar = vif->ar;
688 struct cfg80211_bss *bss; 688 struct cfg80211_bss *bss;
689 u16 cap_mask, cap_val; 689 u16 cap_val;
690 enum ieee80211_bss_type bss_type;
690 u8 *ie; 691 u8 *ie;
691 692
692 if (nw_type & ADHOC_NETWORK) { 693 if (nw_type & ADHOC_NETWORK) {
693 cap_mask = WLAN_CAPABILITY_IBSS;
694 cap_val = WLAN_CAPABILITY_IBSS; 694 cap_val = WLAN_CAPABILITY_IBSS;
695 bss_type = IEEE80211_BSS_TYPE_IBSS;
695 } else { 696 } else {
696 cap_mask = WLAN_CAPABILITY_ESS;
697 cap_val = WLAN_CAPABILITY_ESS; 697 cap_val = WLAN_CAPABILITY_ESS;
698 bss_type = IEEE80211_BSS_TYPE_ESS;
698 } 699 }
699 700
700 bss = cfg80211_get_bss(ar->wiphy, chan, bssid, 701 bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
701 vif->ssid, vif->ssid_len, 702 vif->ssid, vif->ssid_len,
702 cap_mask, cap_val); 703 bss_type, IEEE80211_PRIVACY_ANY);
703 if (bss == NULL) { 704 if (bss == NULL) {
704 /* 705 /*
705 * Since cfg80211 may not yet know about the BSS, 706 * Since cfg80211 may not yet know about the BSS,
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 2d5ea21be47e..adfd815e3f7d 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -395,7 +395,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
395 395
396 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, 396 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
397 sme->ssid, sme->ssid_len, 397 sme->ssid, sme->ssid_len,
398 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 398 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
399 if (!bss) { 399 if (!bss) {
400 wil_err(wil, "Unable to find BSS\n"); 400 wil_err(wil, "Unable to find BSS\n");
401 return -ENOENT; 401 return -ENOENT;
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 4a47c7f8a246..1b58b2e2a538 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -1240,8 +1240,8 @@ static void cw1200_do_join(struct cw1200_common *priv)
1240 1240
1241 bssid = priv->vif->bss_conf.bssid; 1241 bssid = priv->vif->bss_conf.bssid;
1242 1242
1243 bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel, 1243 bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel, bssid, NULL, 0,
1244 bssid, NULL, 0, 0, 0); 1244 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
1245 1245
1246 if (!bss && !conf->ibss_joined) { 1246 if (!bss && !conf->ibss_joined) {
1247 wsm_unlock_tx(priv); 1247 wsm_unlock_tx(priv);
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index a92985a6ea21..1a4d558022d8 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1356,8 +1356,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1356 1356
1357 /* Find the BSS we want using available scan results */ 1357 /* Find the BSS we want using available scan results */
1358 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, 1358 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
1359 sme->ssid, sme->ssid_len, 1359 sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS,
1360 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 1360 IEEE80211_PRIVACY_ANY);
1361 if (!bss) { 1361 if (!bss) {
1362 wiphy_err(wiphy, "assoc: bss %pM not in scan results\n", 1362 wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
1363 sme->bssid); 1363 sme->bssid);
@@ -2000,7 +2000,7 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2000 * bss list is populated already */ 2000 * bss list is populated already */
2001 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid, 2001 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
2002 params->ssid, params->ssid_len, 2002 params->ssid, params->ssid_len,
2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 2003 IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY);
2004 2004
2005 if (bss) { 2005 if (bss) {
2006 ret = lbs_ibss_join_existing(priv, params, bss); 2006 ret = lbs_ibss_join_existing(priv, params, bss);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 41c8e25df954..a47eb55bb6da 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1954,13 +1954,13 @@ done:
1954 if (mode == NL80211_IFTYPE_ADHOC) 1954 if (mode == NL80211_IFTYPE_ADHOC)
1955 bss = cfg80211_get_bss(priv->wdev.wiphy, channel, 1955 bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
1956 bssid, ssid, ssid_len, 1956 bssid, ssid, ssid_len,
1957 WLAN_CAPABILITY_IBSS, 1957 IEEE80211_BSS_TYPE_IBSS,
1958 WLAN_CAPABILITY_IBSS); 1958 IEEE80211_PRIVACY_ANY);
1959 else 1959 else
1960 bss = cfg80211_get_bss(priv->wdev.wiphy, channel, 1960 bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
1961 bssid, ssid, ssid_len, 1961 bssid, ssid, ssid_len,
1962 WLAN_CAPABILITY_ESS, 1962 IEEE80211_BSS_TYPE_ESS,
1963 WLAN_CAPABILITY_ESS); 1963 IEEE80211_PRIVACY_ANY);
1964 1964
1965 if (!bss) { 1965 if (!bss) {
1966 if (is_scanning_required) { 1966 if (is_scanning_required) {
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 64e09e1e8099..28fff56f5606 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -215,6 +215,39 @@ enum ieee80211_rate_flags {
215}; 215};
216 216
217/** 217/**
218 * enum ieee80211_bss_type - BSS type filter
219 *
220 * @IEEE80211_BSS_TYPE_ESS: Infrastructure BSS
221 * @IEEE80211_BSS_TYPE_PBSS: Personal BSS
222 * @IEEE80211_BSS_TYPE_IBSS: Independent BSS
223 * @IEEE80211_BSS_TYPE_MBSS: Mesh BSS
224 * @IEEE80211_BSS_TYPE_ANY: Wildcard value for matching any BSS type
225 */
226enum ieee80211_bss_type {
227 IEEE80211_BSS_TYPE_ESS,
228 IEEE80211_BSS_TYPE_PBSS,
229 IEEE80211_BSS_TYPE_IBSS,
230 IEEE80211_BSS_TYPE_MBSS,
231 IEEE80211_BSS_TYPE_ANY
232};
233
234/**
235 * enum ieee80211_privacy - BSS privacy filter
236 *
237 * @IEEE80211_PRIVACY_ON: privacy bit set
238 * @IEEE80211_PRIVACY_OFF: privacy bit clear
239 * @IEEE80211_PRIVACY_ANY: Wildcard value for matching any privacy setting
240 */
241enum ieee80211_privacy {
242 IEEE80211_PRIVACY_ON,
243 IEEE80211_PRIVACY_OFF,
244 IEEE80211_PRIVACY_ANY
245};
246
247#define IEEE80211_PRIVACY(x) \
248 ((x) ? IEEE80211_PRIVACY_ON : IEEE80211_PRIVACY_OFF)
249
250/**
218 * struct ieee80211_rate - bitrate definition 251 * struct ieee80211_rate - bitrate definition
219 * 252 *
220 * This structure describes a bitrate that an 802.11 PHY can 253 * This structure describes a bitrate that an 802.11 PHY can
@@ -4012,14 +4045,16 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
4012 struct ieee80211_channel *channel, 4045 struct ieee80211_channel *channel,
4013 const u8 *bssid, 4046 const u8 *bssid,
4014 const u8 *ssid, size_t ssid_len, 4047 const u8 *ssid, size_t ssid_len,
4015 u16 capa_mask, u16 capa_val); 4048 enum ieee80211_bss_type bss_type,
4049 enum ieee80211_privacy);
4016static inline struct cfg80211_bss * 4050static inline struct cfg80211_bss *
4017cfg80211_get_ibss(struct wiphy *wiphy, 4051cfg80211_get_ibss(struct wiphy *wiphy,
4018 struct ieee80211_channel *channel, 4052 struct ieee80211_channel *channel,
4019 const u8 *ssid, size_t ssid_len) 4053 const u8 *ssid, size_t ssid_len)
4020{ 4054{
4021 return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len, 4055 return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len,
4022 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 4056 IEEE80211_BSS_TYPE_IBSS,
4057 IEEE80211_PRIVACY_ANY);
4023} 4058}
4024 4059
4025/** 4060/**
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b606b53a49a7..ee93d7d9aa4b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -470,22 +470,19 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
470 struct beacon_data *presp, *old_presp; 470 struct beacon_data *presp, *old_presp;
471 struct cfg80211_bss *cbss; 471 struct cfg80211_bss *cbss;
472 const struct cfg80211_bss_ies *ies; 472 const struct cfg80211_bss_ies *ies;
473 u16 capability; 473 u16 capability = 0;
474 u64 tsf; 474 u64 tsf;
475 int ret = 0; 475 int ret = 0;
476 476
477 sdata_assert_lock(sdata); 477 sdata_assert_lock(sdata);
478 478
479 capability = WLAN_CAPABILITY_IBSS;
480
481 if (ifibss->privacy) 479 if (ifibss->privacy)
482 capability |= WLAN_CAPABILITY_PRIVACY; 480 capability = WLAN_CAPABILITY_PRIVACY;
483 481
484 cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan, 482 cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan,
485 ifibss->bssid, ifibss->ssid, 483 ifibss->bssid, ifibss->ssid,
486 ifibss->ssid_len, WLAN_CAPABILITY_IBSS | 484 ifibss->ssid_len, IEEE80211_BSS_TYPE_IBSS,
487 WLAN_CAPABILITY_PRIVACY, 485 IEEE80211_PRIVACY(ifibss->privacy));
488 capability);
489 486
490 if (WARN_ON(!cbss)) { 487 if (WARN_ON(!cbss)) {
491 ret = -EINVAL; 488 ret = -EINVAL;
@@ -525,23 +522,17 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
525 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 522 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
526 struct cfg80211_bss *cbss; 523 struct cfg80211_bss *cbss;
527 int err, changed = 0; 524 int err, changed = 0;
528 u16 capability;
529 525
530 sdata_assert_lock(sdata); 526 sdata_assert_lock(sdata);
531 527
532 /* update cfg80211 bss information with the new channel */ 528 /* update cfg80211 bss information with the new channel */
533 if (!is_zero_ether_addr(ifibss->bssid)) { 529 if (!is_zero_ether_addr(ifibss->bssid)) {
534 capability = WLAN_CAPABILITY_IBSS;
535
536 if (ifibss->privacy)
537 capability |= WLAN_CAPABILITY_PRIVACY;
538
539 cbss = cfg80211_get_bss(sdata->local->hw.wiphy, 530 cbss = cfg80211_get_bss(sdata->local->hw.wiphy,
540 ifibss->chandef.chan, 531 ifibss->chandef.chan,
541 ifibss->bssid, ifibss->ssid, 532 ifibss->bssid, ifibss->ssid,
542 ifibss->ssid_len, WLAN_CAPABILITY_IBSS | 533 ifibss->ssid_len,
543 WLAN_CAPABILITY_PRIVACY, 534 IEEE80211_BSS_TYPE_IBSS,
544 capability); 535 IEEE80211_PRIVACY(ifibss->privacy));
545 /* XXX: should not really modify cfg80211 data */ 536 /* XXX: should not really modify cfg80211 data */
546 if (cbss) { 537 if (cbss) {
547 cbss->channel = sdata->csa_chandef.chan; 538 cbss->channel = sdata->csa_chandef.chan;
@@ -682,19 +673,13 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
682 struct cfg80211_bss *cbss; 673 struct cfg80211_bss *cbss;
683 struct beacon_data *presp; 674 struct beacon_data *presp;
684 struct sta_info *sta; 675 struct sta_info *sta;
685 u16 capability;
686 676
687 if (!is_zero_ether_addr(ifibss->bssid)) { 677 if (!is_zero_ether_addr(ifibss->bssid)) {
688 capability = WLAN_CAPABILITY_IBSS;
689
690 if (ifibss->privacy)
691 capability |= WLAN_CAPABILITY_PRIVACY;
692
693 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan, 678 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
694 ifibss->bssid, ifibss->ssid, 679 ifibss->bssid, ifibss->ssid,
695 ifibss->ssid_len, WLAN_CAPABILITY_IBSS | 680 ifibss->ssid_len,
696 WLAN_CAPABILITY_PRIVACY, 681 IEEE80211_BSS_TYPE_IBSS,
697 capability); 682 IEEE80211_PRIVACY(ifibss->privacy));
698 683
699 if (cbss) { 684 if (cbss) {
700 cfg80211_unlink_bss(local->hw.wiphy, cbss); 685 cfg80211_unlink_bss(local->hw.wiphy, cbss);
@@ -1325,7 +1310,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
1325 const u8 *bssid = NULL; 1310 const u8 *bssid = NULL;
1326 enum nl80211_bss_scan_width scan_width; 1311 enum nl80211_bss_scan_width scan_width;
1327 int active_ibss; 1312 int active_ibss;
1328 u16 capability;
1329 1313
1330 sdata_assert_lock(sdata); 1314 sdata_assert_lock(sdata);
1331 1315
@@ -1335,9 +1319,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
1335 if (active_ibss) 1319 if (active_ibss)
1336 return; 1320 return;
1337 1321
1338 capability = WLAN_CAPABILITY_IBSS;
1339 if (ifibss->privacy)
1340 capability |= WLAN_CAPABILITY_PRIVACY;
1341 if (ifibss->fixed_bssid) 1322 if (ifibss->fixed_bssid)
1342 bssid = ifibss->bssid; 1323 bssid = ifibss->bssid;
1343 if (ifibss->fixed_channel) 1324 if (ifibss->fixed_channel)
@@ -1346,8 +1327,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
1346 bssid = ifibss->bssid; 1327 bssid = ifibss->bssid;
1347 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, 1328 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
1348 ifibss->ssid, ifibss->ssid_len, 1329 ifibss->ssid, ifibss->ssid_len,
1349 WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_PRIVACY, 1330 IEEE80211_BSS_TYPE_IBSS,
1350 capability); 1331 IEEE80211_PRIVACY(ifibss->privacy));
1351 1332
1352 if (cbss) { 1333 if (cbss) {
1353 struct ieee80211_bss *bss; 1334 struct ieee80211_bss *bss;
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,