diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 29 |
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 | ||
1142 | static int wl1271_join(struct wl1271 *wl) | 1142 | static 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; |