diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-09-16 12:04:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-09-16 16:21:00 -0400 |
commit | bbac31f4c0339f6c51afbd0edfb4959df9b53fa9 (patch) | |
tree | 50764245ec0b1a3ca2e25f43bdbe5d674ec0258e /net | |
parent | 8c6c03fe230c448e5795464a9d73efb796acf3d6 (diff) |
cfg80211: fix SME connect
There's a check saying
/* we're good if we have both BSSID and channel */
if (wdev->conn->params.bssid && wdev->conn->params.channel) {
but that isn't true -- we need the BSS struct. This leads
to errors such as
Trying to associate with 00:1b:53:11:dc:40 (SSID='TEST' freq=2412 MHz)
ioctl[SIOCSIWFREQ]: No such file or directory
ioctl[SIOCSIWESSID]: No such file or directory
Association request to the driver failed
Associated with 00:1b:53:11:dc:40
in wpa_supplicant, as reported by Holger.
Instead, we really need to have the BSS struct, and if we
don't, then we need to initiate a scan for it. But we may
already have the BSS struct here, so hang on to it if we
do and scan if we don't.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Tested-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/sme.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 68307883ec87..7fae7eee65de 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -188,7 +188,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
188 | rtnl_unlock(); | 188 | rtnl_unlock(); |
189 | } | 189 | } |
190 | 190 | ||
191 | static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) | 191 | static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) |
192 | { | 192 | { |
193 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 193 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
194 | struct cfg80211_bss *bss; | 194 | struct cfg80211_bss *bss; |
@@ -205,7 +205,7 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) | |||
205 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, | 205 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, |
206 | capa); | 206 | capa); |
207 | if (!bss) | 207 | if (!bss) |
208 | return false; | 208 | return NULL; |
209 | 209 | ||
210 | memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN); | 210 | memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN); |
211 | wdev->conn->params.bssid = wdev->conn->bssid; | 211 | wdev->conn->params.bssid = wdev->conn->bssid; |
@@ -213,14 +213,14 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) | |||
213 | wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; | 213 | wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; |
214 | schedule_work(&rdev->conn_work); | 214 | schedule_work(&rdev->conn_work); |
215 | 215 | ||
216 | cfg80211_put_bss(bss); | 216 | return bss; |
217 | return true; | ||
218 | } | 217 | } |
219 | 218 | ||
220 | static void __cfg80211_sme_scan_done(struct net_device *dev) | 219 | static void __cfg80211_sme_scan_done(struct net_device *dev) |
221 | { | 220 | { |
222 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 221 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
223 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 222 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
223 | struct cfg80211_bss *bss; | ||
224 | 224 | ||
225 | ASSERT_WDEV_LOCK(wdev); | 225 | ASSERT_WDEV_LOCK(wdev); |
226 | 226 | ||
@@ -234,7 +234,10 @@ static void __cfg80211_sme_scan_done(struct net_device *dev) | |||
234 | wdev->conn->state != CFG80211_CONN_SCAN_AGAIN) | 234 | wdev->conn->state != CFG80211_CONN_SCAN_AGAIN) |
235 | return; | 235 | return; |
236 | 236 | ||
237 | if (!cfg80211_get_conn_bss(wdev)) { | 237 | bss = cfg80211_get_conn_bss(wdev); |
238 | if (bss) { | ||
239 | cfg80211_put_bss(bss); | ||
240 | } else { | ||
238 | /* not found */ | 241 | /* not found */ |
239 | if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) | 242 | if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) |
240 | schedule_work(&rdev->conn_work); | 243 | schedule_work(&rdev->conn_work); |
@@ -670,6 +673,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
670 | { | 673 | { |
671 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 674 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
672 | struct ieee80211_channel *chan; | 675 | struct ieee80211_channel *chan; |
676 | struct cfg80211_bss *bss = NULL; | ||
673 | int err; | 677 | int err; |
674 | 678 | ||
675 | ASSERT_WDEV_LOCK(wdev); | 679 | ASSERT_WDEV_LOCK(wdev); |
@@ -760,7 +764,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
760 | 764 | ||
761 | /* don't care about result -- but fill bssid & channel */ | 765 | /* don't care about result -- but fill bssid & channel */ |
762 | if (!wdev->conn->params.bssid || !wdev->conn->params.channel) | 766 | if (!wdev->conn->params.bssid || !wdev->conn->params.channel) |
763 | cfg80211_get_conn_bss(wdev); | 767 | bss = cfg80211_get_conn_bss(wdev); |
764 | 768 | ||
765 | wdev->sme_state = CFG80211_SME_CONNECTING; | 769 | wdev->sme_state = CFG80211_SME_CONNECTING; |
766 | wdev->connect_keys = connkeys; | 770 | wdev->connect_keys = connkeys; |
@@ -770,10 +774,11 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
770 | wdev->conn->prev_bssid_valid = true; | 774 | wdev->conn->prev_bssid_valid = true; |
771 | } | 775 | } |
772 | 776 | ||
773 | /* we're good if we have both BSSID and channel */ | 777 | /* we're good if we have a matching bss struct */ |
774 | if (wdev->conn->params.bssid && wdev->conn->params.channel) { | 778 | if (bss) { |
775 | wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; | 779 | wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; |
776 | err = cfg80211_conn_do_work(wdev); | 780 | err = cfg80211_conn_do_work(wdev); |
781 | cfg80211_put_bss(bss); | ||
777 | } else { | 782 | } else { |
778 | /* otherwise we'll need to scan for the AP first */ | 783 | /* otherwise we'll need to scan for the AP first */ |
779 | err = cfg80211_conn_scan(wdev); | 784 | err = cfg80211_conn_scan(wdev); |