From 50425b0977c53c6ac608f0b2c8a562a5c7cd5602 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Fri, 11 Sep 2009 10:13:53 +0200 Subject: cfg80211: use cfg80211_wext_freq() for freq conversion WEXT's "struct iw_freq" can also be used to handle a channel. This patch now uses cfg80211_wext_freq() instead of hand-converting the frequency. That allows user-space to specify channels as well, like with SIOCSIWFREQ. Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- net/wireless/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 4c210c2debc..6c20b6515ab 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -662,7 +662,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, int k; int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; for (k = 0; k < wreq->num_channels; k++) { - int wext_freq = wreq->channel_list[k].m / 100000; + int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]); if (wext_freq == wiphy_freq) goto wext_freq_found; } -- cgit v1.2.3 From 012a1b3e5e3561376dacf07efee15688284302c6 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Fri, 11 Sep 2009 10:13:55 +0200 Subject: cfg80211: minimal error handling for wext-compat freq scanning Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- net/wireless/scan.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 6c20b6515ab..e5f92ee758f 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -675,6 +675,11 @@ int cfg80211_wext_siwscan(struct net_device *dev, wext_freq_not_found: ; } } + /* No channels found? */ + if (!i) { + err = -EINVAL; + goto out; + } /* Set real number of channels specified in creq->channels[] */ creq->n_channels = i; -- cgit v1.2.3 From 909a203566a75d26c65370d7dd933fa513d47990 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Tue, 15 Sep 2009 22:24:30 -0400 Subject: rc80211_minstrel: fix contention window calculation The contention window is supposed to be a power of two minus one, i.e. 15, 31, 63, 127... minstrel_rate_init() forgets to subtract 1, so the sequence becomes 15, 32, 66, 134... Bug reported by Dan Halperin Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 7c5142988bb..6e5d68b4e42 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -418,7 +418,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, /* contention window */ tx_time_single += t_slot + min(cw, mp->cw_max); - cw = (cw + 1) << 1; + cw = (cw << 1) | 1; tx_time += tx_time_single; tx_time_cts += tx_time_single + mi->sp_ack_dur; -- cgit v1.2.3 From 90c215c47675be42f164a4bac282666753e09225 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 Sep 2009 09:04:26 -0700 Subject: 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 Tested-by: Holger Schurig Signed-off-by: John W. Linville --- net/wireless/sme.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 68307883ec8..7fae7eee65d 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -188,7 +188,7 @@ void cfg80211_conn_work(struct work_struct *work) rtnl_unlock(); } -static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) +static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); struct cfg80211_bss *bss; @@ -205,7 +205,7 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, capa); if (!bss) - return false; + return NULL; memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN); wdev->conn->params.bssid = wdev->conn->bssid; @@ -213,14 +213,14 @@ static bool cfg80211_get_conn_bss(struct wireless_dev *wdev) wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; schedule_work(&rdev->conn_work); - cfg80211_put_bss(bss); - return true; + return bss; } static void __cfg80211_sme_scan_done(struct net_device *dev) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + struct cfg80211_bss *bss; ASSERT_WDEV_LOCK(wdev); @@ -234,7 +234,10 @@ static void __cfg80211_sme_scan_done(struct net_device *dev) wdev->conn->state != CFG80211_CONN_SCAN_AGAIN) return; - if (!cfg80211_get_conn_bss(wdev)) { + bss = cfg80211_get_conn_bss(wdev); + if (bss) { + cfg80211_put_bss(bss); + } else { /* not found */ if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) schedule_work(&rdev->conn_work); @@ -670,6 +673,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, { struct wireless_dev *wdev = dev->ieee80211_ptr; struct ieee80211_channel *chan; + struct cfg80211_bss *bss = NULL; int err; ASSERT_WDEV_LOCK(wdev); @@ -760,7 +764,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, /* don't care about result -- but fill bssid & channel */ if (!wdev->conn->params.bssid || !wdev->conn->params.channel) - cfg80211_get_conn_bss(wdev); + bss = cfg80211_get_conn_bss(wdev); wdev->sme_state = CFG80211_SME_CONNECTING; wdev->connect_keys = connkeys; @@ -770,10 +774,11 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, wdev->conn->prev_bssid_valid = true; } - /* we're good if we have both BSSID and channel */ - if (wdev->conn->params.bssid && wdev->conn->params.channel) { + /* we're good if we have a matching bss struct */ + if (bss) { wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; err = cfg80211_conn_do_work(wdev); + cfg80211_put_bss(bss); } else { /* otherwise we'll need to scan for the AP first */ err = cfg80211_conn_scan(wdev); -- cgit v1.2.3 From 6a211bf1fc63891bfbc510d9caa751c4dee4bc37 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Sep 2009 10:19:23 -0700 Subject: mac80211: fix DTIM setting When the DTIM setting is read from beacons, mac80211 will assume it is 1 if the TIM IE is not present or the value is 0. This sounds fine, but the same function processes probe responses as well, which don't have a TIM IE. This leads to overwriting any values previously parsed out of beacon frames. Thus, instead of checking for the presence of the TIM IE when setting the default, simply check whether the DTIM period value is valid already. If the TIM IE is not there then the value cannot be valid (it is initialised to 0) and probe responses received after beacons will not lead to overwriting an already valid value. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/scan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 039901109fa..71e10cabf81 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -90,8 +90,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss->dtim_period = tim_ie->dtim_period; } - /* set default value for buggy APs */ - if (!elems->tim || bss->dtim_period == 0) + /* set default value for buggy AP/no TIM element */ + if (bss->dtim_period == 0) bss->dtim_period = 1; bss->supp_rates_len = 0; -- cgit v1.2.3 From 94f85853324e02c3a32bc3101f090dc9a3f512b4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Sep 2009 17:15:31 -0700 Subject: cfg80211: don't overwrite privacy setting When cfg80211 is instructed to connect, it always uses the default WEP key for the privacy setting, which clearly is wrong when using wpa_supplicant. Don't overwrite the setting, and rely on it being false when wpa_supplicant is not running, instead set it to true when we have keys. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/wext-sme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index d16cd9ea4d0..bf725275eb8 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -26,11 +26,11 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, wdev->wext.connect.ie = wdev->wext.ie; wdev->wext.connect.ie_len = wdev->wext.ie_len; - wdev->wext.connect.privacy = wdev->wext.default_key != -1; if (wdev->wext.keys) { wdev->wext.keys->def = wdev->wext.default_key; wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; + wdev->wext.connect.privacy = true; } if (!wdev->wext.connect.ssid_len) -- cgit v1.2.3