Skip to content

Commit

Permalink
wl1271: Fix to join and channel number handling
Browse files Browse the repository at this point in the history
This patch changes the way JOIN's are performed, and channel numbers updated.
The reason for this is that the firmware JOIN command clears WPA(2) key
material, and if done while associated to a WPA(2) secured AP, will render
the data-path unusable.

While the channel is not usually changed while associated (and currently we
could not even support something like that), after performing a scan operation
while associated, mac80211 will re-set the current channel to the driver. This
caused our problem.

Also, the mac80211 is assuming that the driver channel configuration remains
persistent over periods of IDLE. Therefore remove channel resetting to zero
from the unjoin function.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Juuso Oikarinen authored and John W. Linville committed May 7, 2010
1 parent 554d720 commit 69e5434
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions drivers/net/wireless/wl12xx/wl1271_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1139,10 +1139,25 @@ static int wl1271_dummy_join(struct wl1271 *wl)
return ret;
}

static int wl1271_join(struct wl1271 *wl)
static int wl1271_join(struct wl1271 *wl, bool set_assoc)
{
int ret;

/*
* One of the side effects of the JOIN command is that is clears
* WPA/WPA2 keys from the chipset. Performing a JOIN while associated
* to a WPA/WPA2 access point will therefore kill the data-path.
* Currently there is no supported scenario for JOIN during
* association - if it becomes a supported scenario, the WPA/WPA2 keys
* must be handled somehow.
*
*/
if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
wl1271_info("JOIN while associated.");

if (set_assoc)
set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);

ret = wl1271_cmd_join(wl, wl->set_bss_type);
if (ret < 0)
goto out;
Expand Down Expand Up @@ -1189,7 +1204,6 @@ static int wl1271_unjoin(struct wl1271 *wl)
goto out;

clear_bit(WL1271_FLAG_JOINED, &wl->flags);
wl->channel = 0;
memset(wl->bssid, 0, ETH_ALEN);

/* stop filterting packets based on bssid */
Expand Down Expand Up @@ -1249,7 +1263,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
goto out;

/* if the channel changes while joined, join again */
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
((wl->band != conf->channel->band) ||
(wl->channel != channel))) {
wl->band = conf->channel->band;
wl->channel = channel;

Expand All @@ -1269,7 +1285,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
"failed %d", ret);

if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
ret = wl1271_join(wl);
ret = wl1271_join(wl, false);
if (ret < 0)
wl1271_warning("cmd join to update channel "
"failed %d", ret);
Expand Down Expand Up @@ -1651,6 +1667,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
enum wl1271_cmd_ps_mode mode;
struct wl1271 *wl = hw->priv;
bool do_join = false;
bool set_assoc = false;
int ret;

wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
Expand Down Expand Up @@ -1760,7 +1777,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (bss_conf->assoc) {
u32 rates;
wl->aid = bss_conf->aid;
set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
set_assoc = true;

/*
* use basic rates from AP, and determine lowest rate
Expand Down Expand Up @@ -1860,7 +1877,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
}

if (do_join) {
ret = wl1271_join(wl);
ret = wl1271_join(wl, set_assoc);
if (ret < 0) {
wl1271_warning("cmd join failed %d", ret);
goto out_sleep;
Expand Down

0 comments on commit 69e5434

Please sign in to comment.