diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-05-14 15:39:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-14 15:39:45 -0400 |
commit | eac94da8b4cc3dd4336ed434fbc2370c3c850003 (patch) | |
tree | c8b9f912ce06c38d2e379006e511ef9d185de7eb /net | |
parent | 209f6c37540a6cc1c74333a7ede0da729488a8cd (diff) | |
parent | b4b177a5556a686909e643f1e9b6434c10de079f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 20 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 27 |
3 files changed, 34 insertions, 14 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 222c28b75315..f169b6ee94ee 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -317,6 +317,7 @@ struct ieee80211_roc_work { | |||
317 | 317 | ||
318 | bool started, abort, hw_begun, notified; | 318 | bool started, abort, hw_begun, notified; |
319 | bool to_be_freed; | 319 | bool to_be_freed; |
320 | bool on_channel; | ||
320 | 321 | ||
321 | unsigned long hw_start_time; | 322 | unsigned long hw_start_time; |
322 | 323 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dee50aefd6e8..27600a9808ba 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3598,18 +3598,24 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata) | |||
3598 | 3598 | ||
3599 | sdata_lock(sdata); | 3599 | sdata_lock(sdata); |
3600 | 3600 | ||
3601 | if (ifmgd->auth_data) { | 3601 | if (ifmgd->auth_data || ifmgd->assoc_data) { |
3602 | const u8 *bssid = ifmgd->auth_data ? | ||
3603 | ifmgd->auth_data->bss->bssid : | ||
3604 | ifmgd->assoc_data->bss->bssid; | ||
3605 | |||
3602 | /* | 3606 | /* |
3603 | * If we are trying to authenticate while suspending, cfg80211 | 3607 | * If we are trying to authenticate / associate while suspending, |
3604 | * won't know and won't actually abort those attempts, thus we | 3608 | * cfg80211 won't know and won't actually abort those attempts, |
3605 | * need to do that ourselves. | 3609 | * thus we need to do that ourselves. |
3606 | */ | 3610 | */ |
3607 | ieee80211_send_deauth_disassoc(sdata, | 3611 | ieee80211_send_deauth_disassoc(sdata, bssid, |
3608 | ifmgd->auth_data->bss->bssid, | ||
3609 | IEEE80211_STYPE_DEAUTH, | 3612 | IEEE80211_STYPE_DEAUTH, |
3610 | WLAN_REASON_DEAUTH_LEAVING, | 3613 | WLAN_REASON_DEAUTH_LEAVING, |
3611 | false, frame_buf); | 3614 | false, frame_buf); |
3612 | ieee80211_destroy_auth_data(sdata, false); | 3615 | if (ifmgd->assoc_data) |
3616 | ieee80211_destroy_assoc_data(sdata, false); | ||
3617 | if (ifmgd->auth_data) | ||
3618 | ieee80211_destroy_auth_data(sdata, false); | ||
3613 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 3619 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
3614 | IEEE80211_DEAUTH_FRAME_LEN); | 3620 | IEEE80211_DEAUTH_FRAME_LEN); |
3615 | } | 3621 | } |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 6fb38558a5e6..7a17decd27f9 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -333,7 +333,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
333 | container_of(work, struct ieee80211_roc_work, work.work); | 333 | container_of(work, struct ieee80211_roc_work, work.work); |
334 | struct ieee80211_sub_if_data *sdata = roc->sdata; | 334 | struct ieee80211_sub_if_data *sdata = roc->sdata; |
335 | struct ieee80211_local *local = sdata->local; | 335 | struct ieee80211_local *local = sdata->local; |
336 | bool started; | 336 | bool started, on_channel; |
337 | 337 | ||
338 | mutex_lock(&local->mtx); | 338 | mutex_lock(&local->mtx); |
339 | 339 | ||
@@ -354,14 +354,26 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
354 | if (!roc->started) { | 354 | if (!roc->started) { |
355 | struct ieee80211_roc_work *dep; | 355 | struct ieee80211_roc_work *dep; |
356 | 356 | ||
357 | /* start this ROC */ | 357 | WARN_ON(local->use_chanctx); |
358 | ieee80211_offchannel_stop_vifs(local); | 358 | |
359 | /* If actually operating on the desired channel (with at least | ||
360 | * 20 MHz channel width) don't stop all the operations but still | ||
361 | * treat it as though the ROC operation started properly, so | ||
362 | * other ROC operations won't interfere with this one. | ||
363 | */ | ||
364 | roc->on_channel = roc->chan == local->_oper_chandef.chan && | ||
365 | local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 && | ||
366 | local->_oper_chandef.width != NL80211_CHAN_WIDTH_10; | ||
359 | 367 | ||
360 | /* switch channel etc */ | 368 | /* start this ROC */ |
361 | ieee80211_recalc_idle(local); | 369 | ieee80211_recalc_idle(local); |
362 | 370 | ||
363 | local->tmp_channel = roc->chan; | 371 | if (!roc->on_channel) { |
364 | ieee80211_hw_config(local, 0); | 372 | ieee80211_offchannel_stop_vifs(local); |
373 | |||
374 | local->tmp_channel = roc->chan; | ||
375 | ieee80211_hw_config(local, 0); | ||
376 | } | ||
365 | 377 | ||
366 | /* tell userspace or send frame */ | 378 | /* tell userspace or send frame */ |
367 | ieee80211_handle_roc_started(roc); | 379 | ieee80211_handle_roc_started(roc); |
@@ -380,9 +392,10 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
380 | finish: | 392 | finish: |
381 | list_del(&roc->list); | 393 | list_del(&roc->list); |
382 | started = roc->started; | 394 | started = roc->started; |
395 | on_channel = roc->on_channel; | ||
383 | ieee80211_roc_notify_destroy(roc, !roc->abort); | 396 | ieee80211_roc_notify_destroy(roc, !roc->abort); |
384 | 397 | ||
385 | if (started) { | 398 | if (started && !on_channel) { |
386 | ieee80211_flush_queues(local, NULL); | 399 | ieee80211_flush_queues(local, NULL); |
387 | 400 | ||
388 | local->tmp_channel = NULL; | 401 | local->tmp_channel = NULL; |