diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 1 | ||||
-rw-r--r-- | net/mac80211/work.c | 24 |
3 files changed, 26 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2f0642d9e15..e65ee7f6244 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -330,6 +330,7 @@ struct ieee80211_work { u8 key_len, key_idx; bool privacy; bool synced; + struct cfg80211_bss *bss; } probe_auth; struct { struct cfg80211_bss *bss; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 295be92f7c7..f24430b66ee 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2502,6 +2502,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, wk->probe_auth.algorithm = auth_alg; wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY; + wk->probe_auth.bss = req->bss; /* if we already have a probe, don't probe again */ if (req->bss->proberesp_ies) diff --git a/net/mac80211/work.c b/net/mac80211/work.c index c6dd01a0529..290ddbb4d1d 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -454,6 +454,30 @@ ieee80211_authenticate(struct ieee80211_work *wk) struct ieee80211_sub_if_data *sdata = wk->sdata; struct ieee80211_local *local = sdata->local; + /* HACK!!! cw1200 device requires SSID to be available at AUTH stage. + * cfg80211 beacon cache is designed to handle multi-SSID BSSes, so + * bss struct returned by cfg80211_get_bss() has random SSID if BSS + * just changed SSID before authentication (typical for p2p). + * This is a firmware design fault, however as a workaround cfg80211 + * beacon cache is purged to make sure target BSS is searchable + * in rb-tree at the AUTH stage. + */ + struct cfg80211_bss *bss; + while (true) { + bss = cfg80211_get_bss(local->hw.wiphy, + wk->probe_auth.bss->channel, + wk->probe_auth.bss->bssid, + NULL, 0, 0, 0); + if (WARN_ON(!bss)) + break; + if (bss == wk->probe_auth.bss) { + cfg80211_put_bss(bss); + break; + } + cfg80211_unlink_bss(local->hw.wiphy, bss); + } + /* End of the hack */ + if (!wk->probe_auth.synced) { int ret = drv_tx_sync(local, sdata, wk->filter_ta, IEEE80211_TX_SYNC_AUTH); |