diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-11-24 01:16:57 -0500 |
---|---|---|
committer | Luciano Coelho <luciano.coelho@nokia.com> | 2010-11-26 08:33:41 -0500 |
commit | 2f6724b24525fc989c0707974b23d96b36132385 (patch) | |
tree | ca2890e52f4a17efe2019189652ea09591e10163 /drivers/net/wireless/wl12xx/main.c | |
parent | 573c67cf819d52d2e12adf75a9a8cfbd216190a3 (diff) |
wl1271: Fix setting of the hardware connection monitoring probe-req template
The probe-request template used in the hardware connection monitoring feature
thus far has been an empty one, without the SSID IE and without supported rate
IEs. This causes problems with some AP's.
Additionally, after connected scans, the template for connection maintenance
would remain to be the one last used for scanning - potentially incorrect.
Fix these by getting a pre-filled directed probe-request template for the
associated-to AP from mac80211.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 97eb186b5a8a..b2432dab4b51 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -1814,21 +1814,21 @@ out: | |||
1814 | return ret; | 1814 | return ret; |
1815 | } | 1815 | } |
1816 | 1816 | ||
1817 | static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) | 1817 | static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, |
1818 | int offset) | ||
1818 | { | 1819 | { |
1819 | u8 *ptr = beacon->data + | 1820 | u8 *ptr = skb->data + offset; |
1820 | offsetof(struct ieee80211_mgmt, u.beacon.variable); | ||
1821 | 1821 | ||
1822 | /* find the location of the ssid in the beacon */ | 1822 | /* find the location of the ssid in the beacon */ |
1823 | while (ptr < beacon->data + beacon->len) { | 1823 | while (ptr < skb->data + skb->len) { |
1824 | if (ptr[0] == WLAN_EID_SSID) { | 1824 | if (ptr[0] == WLAN_EID_SSID) { |
1825 | wl->ssid_len = ptr[1]; | 1825 | wl->ssid_len = ptr[1]; |
1826 | memcpy(wl->ssid, ptr+2, wl->ssid_len); | 1826 | memcpy(wl->ssid, ptr+2, wl->ssid_len); |
1827 | return; | 1827 | return; |
1828 | } | 1828 | } |
1829 | ptr += ptr[1]; | 1829 | ptr += (ptr[1] + 2); |
1830 | } | 1830 | } |
1831 | wl1271_error("ad-hoc beacon template has no SSID!\n"); | 1831 | wl1271_error("No SSID in IEs!\n"); |
1832 | } | 1832 | } |
1833 | 1833 | ||
1834 | static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | 1834 | static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, |
@@ -1871,8 +1871,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1871 | 1871 | ||
1872 | if (beacon) { | 1872 | if (beacon) { |
1873 | struct ieee80211_hdr *hdr; | 1873 | struct ieee80211_hdr *hdr; |
1874 | int ieoffset = offsetof(struct ieee80211_mgmt, | ||
1875 | u.beacon.variable); | ||
1876 | |||
1877 | wl1271_ssid_set(wl, beacon, ieoffset); | ||
1874 | 1878 | ||
1875 | wl1271_ssid_set(wl, beacon); | ||
1876 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, | 1879 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, |
1877 | beacon->data, | 1880 | beacon->data, |
1878 | beacon->len, 0, | 1881 | beacon->len, 0, |
@@ -1952,6 +1955,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1952 | if (changed & BSS_CHANGED_ASSOC) { | 1955 | if (changed & BSS_CHANGED_ASSOC) { |
1953 | if (bss_conf->assoc) { | 1956 | if (bss_conf->assoc) { |
1954 | u32 rates; | 1957 | u32 rates; |
1958 | int ieoffset; | ||
1955 | wl->aid = bss_conf->aid; | 1959 | wl->aid = bss_conf->aid; |
1956 | set_assoc = true; | 1960 | set_assoc = true; |
1957 | 1961 | ||
@@ -1980,13 +1984,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1980 | goto out_sleep; | 1984 | goto out_sleep; |
1981 | 1985 | ||
1982 | /* | 1986 | /* |
1983 | * The SSID is intentionally set to NULL here - the | 1987 | * Get a template for hardware connection maintenance |
1984 | * firmware will set the probe request with a | ||
1985 | * broadcast SSID regardless of what we set in the | ||
1986 | * template. | ||
1987 | */ | 1988 | */ |
1988 | ret = wl1271_cmd_build_probe_req(wl, NULL, 0, | 1989 | dev_kfree_skb(wl->probereq); |
1989 | NULL, 0, wl->band); | 1990 | wl->probereq = wl1271_cmd_build_ap_probe_req(wl, NULL); |
1991 | ieoffset = offsetof(struct ieee80211_mgmt, | ||
1992 | u.probe_req.variable); | ||
1993 | wl1271_ssid_set(wl, wl->probereq, ieoffset); | ||
1990 | 1994 | ||
1991 | /* enable the connection monitoring feature */ | 1995 | /* enable the connection monitoring feature */ |
1992 | ret = wl1271_acx_conn_monit_params(wl, true); | 1996 | ret = wl1271_acx_conn_monit_params(wl, true); |
@@ -2009,6 +2013,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2009 | clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); | 2013 | clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); |
2010 | wl->aid = 0; | 2014 | wl->aid = 0; |
2011 | 2015 | ||
2016 | /* free probe-request template */ | ||
2017 | dev_kfree_skb(wl->probereq); | ||
2018 | wl->probereq = NULL; | ||
2019 | |||
2012 | /* re-enable dynamic ps - just in case */ | 2020 | /* re-enable dynamic ps - just in case */ |
2013 | ieee80211_enable_dyn_ps(wl->vif); | 2021 | ieee80211_enable_dyn_ps(wl->vif); |
2014 | 2022 | ||