aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c75
1 files changed, 65 insertions, 10 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index f1cb7cbd7c1c..f6d42e613a56 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1130,6 +1130,47 @@ out:
1130} 1130}
1131#endif 1131#endif
1132 1132
1133static int wl1271_join_channel(struct wl1271 *wl, int channel)
1134{
1135 int ret;
1136 /* we need to use a dummy BSSID for now */
1137 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1138 0xad, 0xbe, 0xef };
1139
1140 /* disable mac filter, so we hear everything */
1141 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1142
1143 wl->channel = channel;
1144 memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
1145
1146 ret = wl1271_cmd_join(wl);
1147 if (ret < 0)
1148 goto out;
1149
1150 wl->joined = true;
1151
1152out:
1153 return ret;
1154}
1155
1156static int wl1271_unjoin_channel(struct wl1271 *wl)
1157{
1158 int ret;
1159
1160 /* to stop listening to a channel, we disconnect */
1161 ret = wl1271_cmd_disconnect(wl);
1162 if (ret < 0)
1163 goto out;
1164
1165 wl->joined = false;
1166 wl->channel = 0;
1167 memset(wl->bssid, 0, ETH_ALEN);
1168 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1169
1170out:
1171 return ret;
1172}
1173
1133static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1174static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1134{ 1175{
1135 struct wl1271 *wl = hw->priv; 1176 struct wl1271 *wl = hw->priv;
@@ -1138,10 +1179,11 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1138 1179
1139 channel = ieee80211_frequency_to_channel(conf->channel->center_freq); 1180 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
1140 1181
1141 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", 1182 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s",
1142 channel, 1183 channel,
1143 conf->flags & IEEE80211_CONF_PS ? "on" : "off", 1184 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
1144 conf->power_level); 1185 conf->power_level,
1186 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use");
1145 1187
1146 mutex_lock(&wl->mutex); 1188 mutex_lock(&wl->mutex);
1147 1189
@@ -1151,16 +1193,17 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1151 if (ret < 0) 1193 if (ret < 0)
1152 goto out; 1194 goto out;
1153 1195
1154 if (channel != wl->channel) { 1196 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1155 /* 1197 if (conf->flags & IEEE80211_CONF_IDLE && wl->joined)
1156 * We assume that the stack will configure the right channel 1198 wl1271_unjoin_channel(wl);
1157 * before associating, so we don't need to send a join 1199 else
1158 * command here. We will join the right channel when the 1200 wl1271_join_channel(wl, channel);
1159 * BSSID changes
1160 */
1161 wl->channel = channel;
1162 } 1201 }
1163 1202
1203 /* if the channel changes while joined, join again */
1204 if (channel != wl->channel && wl->joined)
1205 wl1271_join_channel(wl, channel);
1206
1164 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { 1207 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
1165 wl1271_info("psm enabled"); 1208 wl1271_info("psm enabled");
1166 1209
@@ -1494,6 +1537,18 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1494 if (ret < 0) 1537 if (ret < 0)
1495 goto out; 1538 goto out;
1496 1539
1540 if ((changed & BSS_CHANGED_BSSID) &&
1541 /*
1542 * Now we know the correct bssid, so we send a new join command
1543 * and enable the BSSID filter
1544 */
1545 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1546 wl->rx_config |= CFG_BSSID_FILTER_EN;
1547 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1548 wl1271_cmd_join(wl);
1549 wl->joined = true;
1550 }
1551
1497 if (changed & BSS_CHANGED_ASSOC) { 1552 if (changed & BSS_CHANGED_ASSOC) {
1498 if (bss_conf->assoc) { 1553 if (bss_conf->assoc) {
1499 wl->aid = bss_conf->aid; 1554 wl->aid = bss_conf->aid;