aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-05-07 04:39:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-05-07 14:57:19 -0400
commit69e5434cd536c7eb4d5be0d0b7db06ed420c1315 (patch)
tree49e4bc2fe8388f97aa978a685da31945ea0bb4f0
parent554d7209c87a7b7ec70c14d9ed1c01e05f5dbc23 (diff)
wl1271: Fix to join and channel number handling
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>
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 36dfdee5fbf..3e4b9fbe8a0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1139,10 +1139,25 @@ out:
1139 return ret; 1139 return ret;
1140} 1140}
1141 1141
1142static int wl1271_join(struct wl1271 *wl) 1142static int wl1271_join(struct wl1271 *wl, bool set_assoc)
1143{ 1143{
1144 int ret; 1144 int ret;
1145 1145
1146 /*
1147 * One of the side effects of the JOIN command is that is clears
1148 * WPA/WPA2 keys from the chipset. Performing a JOIN while associated
1149 * to a WPA/WPA2 access point will therefore kill the data-path.
1150 * Currently there is no supported scenario for JOIN during
1151 * association - if it becomes a supported scenario, the WPA/WPA2 keys
1152 * must be handled somehow.
1153 *
1154 */
1155 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1156 wl1271_info("JOIN while associated.");
1157
1158 if (set_assoc)
1159 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1160
1146 ret = wl1271_cmd_join(wl, wl->set_bss_type); 1161 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1147 if (ret < 0) 1162 if (ret < 0)
1148 goto out; 1163 goto out;
@@ -1189,7 +1204,6 @@ static int wl1271_unjoin(struct wl1271 *wl)
1189 goto out; 1204 goto out;
1190 1205
1191 clear_bit(WL1271_FLAG_JOINED, &wl->flags); 1206 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
1192 wl->channel = 0;
1193 memset(wl->bssid, 0, ETH_ALEN); 1207 memset(wl->bssid, 0, ETH_ALEN);
1194 1208
1195 /* stop filterting packets based on bssid */ 1209 /* stop filterting packets based on bssid */
@@ -1249,7 +1263,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1249 goto out; 1263 goto out;
1250 1264
1251 /* if the channel changes while joined, join again */ 1265 /* if the channel changes while joined, join again */
1252 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1266 if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
1267 ((wl->band != conf->channel->band) ||
1268 (wl->channel != channel))) {
1253 wl->band = conf->channel->band; 1269 wl->band = conf->channel->band;
1254 wl->channel = channel; 1270 wl->channel = channel;
1255 1271
@@ -1269,7 +1285,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1269 "failed %d", ret); 1285 "failed %d", ret);
1270 1286
1271 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { 1287 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1272 ret = wl1271_join(wl); 1288 ret = wl1271_join(wl, false);
1273 if (ret < 0) 1289 if (ret < 0)
1274 wl1271_warning("cmd join to update channel " 1290 wl1271_warning("cmd join to update channel "
1275 "failed %d", ret); 1291 "failed %d", ret);
@@ -1651,6 +1667,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1651 enum wl1271_cmd_ps_mode mode; 1667 enum wl1271_cmd_ps_mode mode;
1652 struct wl1271 *wl = hw->priv; 1668 struct wl1271 *wl = hw->priv;
1653 bool do_join = false; 1669 bool do_join = false;
1670 bool set_assoc = false;
1654 int ret; 1671 int ret;
1655 1672
1656 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 1673 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1760,7 +1777,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1760 if (bss_conf->assoc) { 1777 if (bss_conf->assoc) {
1761 u32 rates; 1778 u32 rates;
1762 wl->aid = bss_conf->aid; 1779 wl->aid = bss_conf->aid;
1763 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1780 set_assoc = true;
1764 1781
1765 /* 1782 /*
1766 * use basic rates from AP, and determine lowest rate 1783 * use basic rates from AP, and determine lowest rate
@@ -1860,7 +1877,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1860 } 1877 }
1861 1878
1862 if (do_join) { 1879 if (do_join) {
1863 ret = wl1271_join(wl); 1880 ret = wl1271_join(wl, set_assoc);
1864 if (ret < 0) { 1881 if (ret < 0) {
1865 wl1271_warning("cmd join failed %d", ret); 1882 wl1271_warning("cmd join failed %d", ret);
1866 goto out_sleep; 1883 goto out_sleep;