aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/assoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r--drivers/net/wireless/libertas/assoc.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 4bc128fa5848..3f2dfaf879c5 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -22,6 +22,10 @@ static int assoc_helper_essid(wlan_private *priv,
22 22
23 lbs_deb_enter(LBS_DEB_ASSOC); 23 lbs_deb_enter(LBS_DEB_ASSOC);
24 24
25 /* FIXME: take channel into account when picking SSIDs if a channel
26 * is set.
27 */
28
25 lbs_deb_assoc("New SSID requested: %s\n", assoc_req->ssid.ssid); 29 lbs_deb_assoc("New SSID requested: %s\n", assoc_req->ssid.ssid);
26 if (assoc_req->mode == IW_MODE_INFRA) { 30 if (assoc_req->mode == IW_MODE_INFRA) {
27 if (adapter->prescan) { 31 if (adapter->prescan) {
@@ -158,6 +162,69 @@ done:
158} 162}
159 163
160 164
165static int update_channel(wlan_private * priv)
166{
167 /* the channel in f/w could be out of sync, get the current channel */
168 return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
169 cmd_opt_802_11_rf_channel_get,
170 cmd_option_waitforrsp, 0, NULL);
171}
172
173static int assoc_helper_channel(wlan_private *priv,
174 struct assoc_request * assoc_req)
175{
176 wlan_adapter *adapter = priv->adapter;
177 int ret = 0;
178
179 lbs_deb_enter(LBS_DEB_ASSOC);
180
181 ret = update_channel(priv);
182 if (ret < 0) {
183 lbs_deb_assoc("ASSOC: channel: error getting channel.");
184 }
185
186 if (assoc_req->channel == adapter->curbssparams.channel)
187 goto done;
188
189 lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
190 adapter->curbssparams.channel, assoc_req->channel);
191
192 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
193 cmd_opt_802_11_rf_channel_set,
194 cmd_option_waitforrsp, 0, &assoc_req->channel);
195 if (ret < 0) {
196 lbs_deb_assoc("ASSOC: channel: error setting channel.");
197 }
198
199 ret = update_channel(priv);
200 if (ret < 0) {
201 lbs_deb_assoc("ASSOC: channel: error getting channel.");
202 }
203
204 if (assoc_req->channel != adapter->curbssparams.channel) {
205 lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
206 assoc_req->channel);
207 goto done;
208 }
209
210 if ( assoc_req->secinfo.wep_enabled
211 && (assoc_req->wep_keys[0].len
212 || assoc_req->wep_keys[1].len
213 || assoc_req->wep_keys[2].len
214 || assoc_req->wep_keys[3].len)) {
215 /* Make sure WEP keys are re-sent to firmware */
216 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
217 }
218
219 /* Must restart/rejoin adhoc networks after channel change */
220 set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
221
222done:
223 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
224 return ret;
225}
226
227
161static int assoc_helper_wep_keys(wlan_private *priv, 228static int assoc_helper_wep_keys(wlan_private *priv,
162 struct assoc_request * assoc_req) 229 struct assoc_request * assoc_req)
163{ 230{
@@ -334,6 +401,11 @@ static int should_stop_adhoc(wlan_adapter *adapter,
334 return 1; 401 return 1;
335 } 402 }
336 403
404 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
405 if (assoc_req->channel != adapter->curbssparams.channel)
406 return 1;
407 }
408
337 return 0; 409 return 0;
338} 410}
339 411
@@ -423,6 +495,15 @@ lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
423 } 495 }
424 } 496 }
425 497
498 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
499 ret = assoc_helper_channel(priv, assoc_req);
500 if (ret) {
501 lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
502 __LINE__, ret);
503 goto out;
504 }
505 }
506
426 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) 507 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
427 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { 508 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
428 ret = assoc_helper_wep_keys(priv, assoc_req); 509 ret = assoc_helper_wep_keys(priv, assoc_req);