diff mbox

[3/5] wl1271: Fix to join and channel number handling

Message ID 1273221542-14283-4-git-send-email-luciano.coelho@nokia.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Luciano Coelho May 7, 2010, 8:39 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 5ad94fc..360daf8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1140,10 +1140,25 @@  out:
 	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;
@@ -1190,7 +1205,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 */
@@ -1250,7 +1264,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;
 
@@ -1270,7 +1286,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);
@@ -1652,6 +1668,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");
@@ -1761,7 +1778,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
@@ -1861,7 +1878,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;