~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/wireless/iwlwifi/iwl-agn-rxon.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
2
 *
3
 
 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
 
3
 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify it
6
6
 * under the terms of version 2 of the GNU General Public License as
29
29
#include "iwl-sta.h"
30
30
#include "iwl-core.h"
31
31
#include "iwl-agn-calib.h"
 
32
#include "iwl-helpers.h"
32
33
 
33
34
static int iwlagn_disable_bss(struct iwl_priv *priv,
34
35
                              struct iwl_rxon_context *ctx,
52
53
                              struct iwl_rxon_context *ctx,
53
54
                              struct iwl_rxon_cmd *send)
54
55
{
 
56
        struct iwl_notification_wait disable_wait;
55
57
        __le32 old_filter = send->filter_flags;
56
58
        u8 old_dev_type = send->dev_type;
57
59
        int ret;
58
60
 
 
61
        iwlagn_init_notification_wait(priv, &disable_wait,
 
62
                                      REPLY_WIPAN_DEACTIVATION_COMPLETE,
 
63
                                      NULL, NULL);
 
64
 
59
65
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
60
66
        send->dev_type = RXON_DEV_TYPE_P2P;
61
67
        ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
63
69
        send->filter_flags = old_filter;
64
70
        send->dev_type = old_dev_type;
65
71
 
66
 
        if (ret)
 
72
        if (ret) {
67
73
                IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
68
 
 
69
 
        /* FIXME: WAIT FOR PAN DISABLE */
70
 
        msleep(300);
 
74
                iwlagn_remove_notification(priv, &disable_wait);
 
75
        } else {
 
76
                ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
 
77
                if (ret)
 
78
                        IWL_ERR(priv, "Timed out waiting for PAN disable\n");
 
79
        }
71
80
 
72
81
        return ret;
73
82
}
112
121
        return iwlagn_send_beacon_cmd(priv);
113
122
}
114
123
 
 
124
static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
 
125
                           struct iwl_rxon_context *ctx)
 
126
{
 
127
        int ret = 0;
 
128
        struct iwl_rxon_assoc_cmd rxon_assoc;
 
129
        const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
 
130
        const struct iwl_rxon_cmd *rxon2 = &ctx->active;
 
131
 
 
132
        if ((rxon1->flags == rxon2->flags) &&
 
133
            (rxon1->filter_flags == rxon2->filter_flags) &&
 
134
            (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
 
135
            (rxon1->ofdm_ht_single_stream_basic_rates ==
 
136
             rxon2->ofdm_ht_single_stream_basic_rates) &&
 
137
            (rxon1->ofdm_ht_dual_stream_basic_rates ==
 
138
             rxon2->ofdm_ht_dual_stream_basic_rates) &&
 
139
            (rxon1->ofdm_ht_triple_stream_basic_rates ==
 
140
             rxon2->ofdm_ht_triple_stream_basic_rates) &&
 
141
            (rxon1->acquisition_data == rxon2->acquisition_data) &&
 
142
            (rxon1->rx_chain == rxon2->rx_chain) &&
 
143
            (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
 
144
                IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
 
145
                return 0;
 
146
        }
 
147
 
 
148
        rxon_assoc.flags = ctx->staging.flags;
 
149
        rxon_assoc.filter_flags = ctx->staging.filter_flags;
 
150
        rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
 
151
        rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
 
152
        rxon_assoc.reserved1 = 0;
 
153
        rxon_assoc.reserved2 = 0;
 
154
        rxon_assoc.reserved3 = 0;
 
155
        rxon_assoc.ofdm_ht_single_stream_basic_rates =
 
156
            ctx->staging.ofdm_ht_single_stream_basic_rates;
 
157
        rxon_assoc.ofdm_ht_dual_stream_basic_rates =
 
158
            ctx->staging.ofdm_ht_dual_stream_basic_rates;
 
159
        rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
 
160
        rxon_assoc.ofdm_ht_triple_stream_basic_rates =
 
161
                 ctx->staging.ofdm_ht_triple_stream_basic_rates;
 
162
        rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
 
163
 
 
164
        ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
 
165
                                     sizeof(rxon_assoc), &rxon_assoc, NULL);
 
166
        if (ret)
 
167
                return ret;
 
168
 
 
169
        return ret;
 
170
}
 
171
 
 
172
static int iwlagn_rxon_disconn(struct iwl_priv *priv,
 
173
                               struct iwl_rxon_context *ctx)
 
174
{
 
175
        int ret;
 
176
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
 
177
 
 
178
        if (ctx->ctxid == IWL_RXON_CTX_BSS)
 
179
                ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
 
180
        else
 
181
                ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
 
182
        if (ret)
 
183
                return ret;
 
184
 
 
185
        /*
 
186
         * Un-assoc RXON clears the station table and WEP
 
187
         * keys, so we have to restore those afterwards.
 
188
         */
 
189
        iwl_clear_ucode_stations(priv, ctx);
 
190
        iwl_restore_stations(priv, ctx);
 
191
        ret = iwl_restore_default_wep_keys(priv, ctx);
 
192
        if (ret) {
 
193
                IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
 
194
                return ret;
 
195
        }
 
196
 
 
197
        memcpy(active, &ctx->staging, sizeof(*active));
 
198
        return 0;
 
199
}
 
200
 
 
201
static int iwlagn_rxon_connect(struct iwl_priv *priv,
 
202
                               struct iwl_rxon_context *ctx)
 
203
{
 
204
        int ret;
 
205
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
 
206
 
 
207
        /* RXON timing must be before associated RXON */
 
208
        ret = iwl_send_rxon_timing(priv, ctx);
 
209
        if (ret) {
 
210
                IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
 
211
                return ret;
 
212
        }
 
213
        /* QoS info may be cleared by previous un-assoc RXON */
 
214
        iwlagn_update_qos(priv, ctx);
 
215
 
 
216
        /*
 
217
         * We'll run into this code path when beaconing is
 
218
         * enabled, but then we also need to send the beacon
 
219
         * to the device.
 
220
         */
 
221
        if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
 
222
                ret = iwlagn_update_beacon(priv, ctx->vif);
 
223
                if (ret) {
 
224
                        IWL_ERR(priv,
 
225
                                "Error sending required beacon (%d)!\n",
 
226
                                ret);
 
227
                        return ret;
 
228
                }
 
229
        }
 
230
 
 
231
        priv->start_calib = 0;
 
232
        /*
 
233
         * Apply the new configuration.
 
234
         *
 
235
         * Associated RXON doesn't clear the station table in uCode,
 
236
         * so we don't need to restore stations etc. after this.
 
237
         */
 
238
        ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
 
239
                      sizeof(struct iwl_rxon_cmd), &ctx->staging);
 
240
        if (ret) {
 
241
                IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
 
242
                return ret;
 
243
        }
 
244
        memcpy(active, &ctx->staging, sizeof(*active));
 
245
 
 
246
        iwl_reprogram_ap_sta(priv, ctx);
 
247
 
 
248
        /* IBSS beacon needs to be sent after setting assoc */
 
249
        if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
 
250
                if (iwlagn_update_beacon(priv, ctx->vif))
 
251
                        IWL_ERR(priv, "Error sending IBSS beacon\n");
 
252
        iwl_init_sensitivity(priv);
 
253
 
 
254
        /*
 
255
         * If we issue a new RXON command which required a tune then
 
256
         * we must send a new TXPOWER command or we won't be able to
 
257
         * Tx any frames.
 
258
         *
 
259
         * It's expected we set power here if channel is changing.
 
260
         */
 
261
        ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
 
262
        if (ret) {
 
263
                IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
 
264
                return ret;
 
265
        }
 
266
        return 0;
 
267
}
 
268
 
115
269
/**
116
270
 * iwlagn_commit_rxon - commit staging_rxon to hardware
117
271
 *
119
273
 * the active_rxon structure is updated with the new data.  This
120
274
 * function correctly transitions out of the RXON_ASSOC_MSK state if
121
275
 * a HW tune is required based on the RXON structure changes.
 
276
 *
 
277
 * The connect/disconnect flow should be as the following:
 
278
 *
 
279
 * 1. make sure send RXON command with association bit unset if not connect
 
280
 *      this should include the channel and the band for the candidate
 
281
 *      to be connected to
 
282
 * 2. Add Station before RXON association with the AP
 
283
 * 3. RXON_timing has to send before RXON for connection
 
284
 * 4. full RXON command - associated bit set
 
285
 * 5. use RXON_ASSOC command to update any flags changes
122
286
 */
123
287
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
124
288
{
125
289
        /* cast away the const for active_rxon in this function */
126
290
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
127
291
        bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
128
 
        bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
129
292
        int ret;
130
293
 
131
294
        lockdep_assert_held(&priv->mutex);
145
308
        /* always get timestamp with Rx frame */
146
309
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
147
310
 
 
311
        if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->_agn.hw_roc_channel) {
 
312
                struct ieee80211_channel *chan = priv->_agn.hw_roc_channel;
 
313
 
 
314
                iwl_set_rxon_channel(priv, chan, ctx);
 
315
                iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
 
316
                ctx->staging.filter_flags |=
 
317
                        RXON_FILTER_ASSOC_MSK |
 
318
                        RXON_FILTER_PROMISC_MSK |
 
319
                        RXON_FILTER_CTL2HOST_MSK;
 
320
                ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
 
321
                new_assoc = true;
 
322
 
 
323
                if (memcmp(&ctx->staging, &ctx->active,
 
324
                           sizeof(ctx->staging)) == 0)
 
325
                        return 0;
 
326
        }
 
327
 
 
328
        /*
 
329
         * force CTS-to-self frames protection if RTS-CTS is not preferred
 
330
         * one aggregation protection method
 
331
         */
 
332
        if (!(priv->cfg->ht_params &&
 
333
              priv->cfg->ht_params->use_rts_for_aggregation))
 
334
                ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
 
335
 
148
336
        if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
149
337
            !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
150
338
                ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
151
339
        else
152
340
                ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
153
341
 
 
342
        iwl_print_rx_config_cmd(priv, ctx);
154
343
        ret = iwl_check_rxon_cmd(priv, ctx);
155
344
        if (ret) {
156
345
                IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
161
350
         * receive commit_rxon request
162
351
         * abort any previous channel switch if still in process
163
352
         */
164
 
        if (priv->switch_rxon.switch_in_progress &&
165
 
            (priv->switch_rxon.channel != ctx->staging.channel)) {
 
353
        if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
 
354
            (priv->switch_channel != ctx->staging.channel)) {
166
355
                IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
167
 
                      le16_to_cpu(priv->switch_rxon.channel));
 
356
                              le16_to_cpu(priv->switch_channel));
168
357
                iwl_chswitch_done(priv, false);
169
358
        }
170
359
 
174
363
         * and other flags for the current radio configuration.
175
364
         */
176
365
        if (!iwl_full_rxon_required(priv, ctx)) {
177
 
                ret = iwl_send_rxon_assoc(priv, ctx);
 
366
                ret = iwlagn_send_rxon_assoc(priv, ctx);
178
367
                if (ret) {
179
368
                        IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
180
369
                        return ret;
181
370
                }
182
371
 
183
372
                memcpy(active, &ctx->staging, sizeof(*active));
184
 
                iwl_print_rx_config_cmd(priv, ctx);
 
373
                /*
 
374
                 * We do not commit tx power settings while channel changing,
 
375
                 * do it now if after settings changed.
 
376
                 */
 
377
                iwl_set_tx_power(priv, priv->tx_power_next, false);
185
378
                return 0;
186
379
        }
187
380
 
191
384
                        return ret;
192
385
        }
193
386
 
194
 
        iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
 
387
        iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
195
388
 
196
389
        IWL_DEBUG_INFO(priv,
197
390
                       "Going to commit RXON\n"
208
401
         * AP station must be done after the BSSID is set to correctly
209
402
         * set up filters in the device.
210
403
         */
211
 
        if ((old_assoc && new_assoc) || !new_assoc) {
212
 
                if (ctx->ctxid == IWL_RXON_CTX_BSS)
213
 
                        ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
214
 
                else
215
 
                        ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
216
 
                if (ret)
217
 
                        return ret;
218
 
 
219
 
                memcpy(active, &ctx->staging, sizeof(*active));
220
 
 
221
 
                /*
222
 
                 * Un-assoc RXON clears the station table and WEP
223
 
                 * keys, so we have to restore those afterwards.
224
 
                 */
225
 
                iwl_clear_ucode_stations(priv, ctx);
226
 
                iwl_restore_stations(priv, ctx);
227
 
                ret = iwl_restore_default_wep_keys(priv, ctx);
228
 
                if (ret) {
229
 
                        IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
230
 
                        return ret;
231
 
                }
232
 
        }
233
 
 
234
 
        /* RXON timing must be before associated RXON */
235
 
        ret = iwl_send_rxon_timing(priv, ctx);
236
 
        if (ret) {
237
 
                IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
238
 
                return ret;
239
 
        }
240
 
 
241
 
        if (new_assoc) {
242
 
                /* QoS info may be cleared by previous un-assoc RXON */
243
 
                iwlagn_update_qos(priv, ctx);
244
 
 
245
 
                /*
246
 
                 * We'll run into this code path when beaconing is
247
 
                 * enabled, but then we also need to send the beacon
248
 
                 * to the device.
249
 
                 */
250
 
                if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
251
 
                        ret = iwlagn_update_beacon(priv, ctx->vif);
252
 
                        if (ret) {
253
 
                                IWL_ERR(priv,
254
 
                                        "Error sending required beacon (%d)!\n",
255
 
                                        ret);
256
 
                                return ret;
257
 
                        }
258
 
                }
259
 
 
260
 
                priv->start_calib = 0;
261
 
                /*
262
 
                 * Apply the new configuration.
263
 
                 *
264
 
                 * Associated RXON doesn't clear the station table in uCode,
265
 
                 * so we don't need to restore stations etc. after this.
266
 
                 */
267
 
                ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
268
 
                              sizeof(struct iwl_rxon_cmd), &ctx->staging);
269
 
                if (ret) {
270
 
                        IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
271
 
                        return ret;
272
 
                }
273
 
                memcpy(active, &ctx->staging, sizeof(*active));
274
 
 
275
 
                iwl_reprogram_ap_sta(priv, ctx);
276
 
 
277
 
                /* IBSS beacon needs to be sent after setting assoc */
278
 
                if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
279
 
                        if (iwlagn_update_beacon(priv, ctx->vif))
280
 
                                IWL_ERR(priv, "Error sending IBSS beacon\n");
281
 
        }
282
 
 
283
 
        iwl_print_rx_config_cmd(priv, ctx);
284
 
 
285
 
        iwl_init_sensitivity(priv);
286
 
 
287
 
        /*
288
 
         * If we issue a new RXON command which required a tune then we must
289
 
         * send a new TXPOWER command or we won't be able to Tx any frames.
290
 
         *
291
 
         * FIXME: which RXON requires a tune? Can we optimise this out in
292
 
         *        some cases?
293
 
         */
294
 
        ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
295
 
        if (ret) {
296
 
                IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
297
 
                return ret;
298
 
        }
 
404
        ret = iwlagn_rxon_disconn(priv, ctx);
 
405
        if (ret)
 
406
                return ret;
 
407
 
 
408
        if (new_assoc)
 
409
                return iwlagn_rxon_connect(priv, ctx);
299
410
 
300
411
        return 0;
301
412
}
308
419
        struct ieee80211_channel *channel = conf->channel;
309
420
        const struct iwl_channel_info *ch_info;
310
421
        int ret = 0;
311
 
        bool ht_changed[NUM_IWL_RXON_CTX] = {};
312
422
 
313
423
        IWL_DEBUG_MAC80211(priv, "changed %#x", changed);
314
424
 
356
466
 
357
467
                for_each_context(priv, ctx) {
358
468
                        /* Configure HT40 channels */
359
 
                        if (ctx->ht.enabled != conf_is_ht(conf)) {
 
469
                        if (ctx->ht.enabled != conf_is_ht(conf))
360
470
                                ctx->ht.enabled = conf_is_ht(conf);
361
 
                                ht_changed[ctx->ctxid] = true;
362
 
                        }
363
471
 
364
472
                        if (ctx->ht.enabled) {
365
473
                                if (conf_is_ht40_minus(conf)) {
428
536
                if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
429
537
                        continue;
430
538
                iwlagn_commit_rxon(priv, ctx);
431
 
                if (ht_changed[ctx->ctxid])
432
 
                        iwlagn_update_qos(priv, ctx);
433
539
        }
434
540
 out:
435
541
        mutex_unlock(&priv->mutex);
444
550
        struct iwl_rxon_context *tmp;
445
551
        struct ieee80211_sta *sta;
446
552
        struct iwl_ht_config *ht_conf = &priv->current_ht_config;
 
553
        struct ieee80211_sta_ht_cap *ht_cap;
447
554
        bool need_multiple;
448
555
 
449
556
        lockdep_assert_held(&priv->mutex);
452
559
        case NL80211_IFTYPE_STATION:
453
560
                rcu_read_lock();
454
561
                sta = ieee80211_find_sta(vif, bss_conf->bssid);
455
 
                if (sta) {
456
 
                        struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 
562
                if (!sta) {
 
563
                        /*
 
564
                         * If at all, this can only happen through a race
 
565
                         * when the AP disconnects us while we're still
 
566
                         * setting up the connection, in that case mac80211
 
567
                         * will soon tell us about that.
 
568
                         */
 
569
                        need_multiple = false;
 
570
                        rcu_read_unlock();
 
571
                        break;
 
572
                }
 
573
 
 
574
                ht_cap = &sta->ht_cap;
 
575
 
 
576
                need_multiple = true;
 
577
 
 
578
                /*
 
579
                 * If the peer advertises no support for receiving 2 and 3
 
580
                 * stream MCS rates, it can't be transmitting them either.
 
581
                 */
 
582
                if (ht_cap->mcs.rx_mask[1] == 0 &&
 
583
                    ht_cap->mcs.rx_mask[2] == 0) {
 
584
                        need_multiple = false;
 
585
                } else if (!(ht_cap->mcs.tx_params &
 
586
                                                IEEE80211_HT_MCS_TX_DEFINED)) {
 
587
                        /* If it can't TX MCS at all ... */
 
588
                        need_multiple = false;
 
589
                } else if (ht_cap->mcs.tx_params &
 
590
                                                IEEE80211_HT_MCS_TX_RX_DIFF) {
457
591
                        int maxstreams;
458
592
 
 
593
                        /*
 
594
                         * But if it can receive them, it might still not
 
595
                         * be able to transmit them, which is what we need
 
596
                         * to check here -- so check the number of streams
 
597
                         * it advertises for TX (if different from RX).
 
598
                         */
 
599
 
459
600
                        maxstreams = (ht_cap->mcs.tx_params &
460
 
                                      IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
461
 
                                        >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
 
601
                                 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK);
 
602
                        maxstreams >>=
 
603
                                IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
462
604
                        maxstreams += 1;
463
605
 
464
 
                        need_multiple = true;
465
 
 
466
 
                        if ((ht_cap->mcs.rx_mask[1] == 0) &&
467
 
                            (ht_cap->mcs.rx_mask[2] == 0))
468
 
                                need_multiple = false;
469
606
                        if (maxstreams <= 1)
470
607
                                need_multiple = false;
471
 
                } else {
472
 
                        /*
473
 
                         * If at all, this can only happen through a race
474
 
                         * when the AP disconnects us while we're still
475
 
                         * setting up the connection, in that case mac80211
476
 
                         * will soon tell us about that.
477
 
                         */
478
 
                        need_multiple = false;
479
608
                }
 
609
 
480
610
                rcu_read_unlock();
481
611
                break;
482
612
        case NL80211_IFTYPE_ADHOC:
546
676
 
547
677
        if (changes & BSS_CHANGED_ASSOC) {
548
678
                if (bss_conf->assoc) {
549
 
                        iwl_led_associate(priv);
550
679
                        priv->timestamp = bss_conf->timestamp;
551
680
                        ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
552
681
                } else {
 
682
                        /*
 
683
                         * If we disassociate while there are pending
 
684
                         * frames, just wake up the queues and let the
 
685
                         * frames "escape" ... This shouldn't really
 
686
                         * be happening to start with, but we should
 
687
                         * not get stuck in this case either since it
 
688
                         * can happen if userspace gets confused.
 
689
                         */
 
690
                        if (ctx->last_tx_rejected) {
 
691
                                ctx->last_tx_rejected = false;
 
692
                                iwl_wake_any_queue(priv, ctx);
 
693
                        }
553
694
                        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
554
 
                        iwl_led_disassociate(priv);
555
695
                }
556
696
        }
557
697