aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-07-17 15:07:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-17 15:07:31 -0400
commit707be0ae13f7a4533d11f0d88687223c4bd8f85f (patch)
treecf2c9fa680828ea4a9882ee2561e9b12d643adbe /net/mac80211
parent040a78314fe3cbb1472ac220cb3400116f6967bc (diff)
parent88bc40e8c3d3bca7d26c756bb0b823d4abad3355 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c13
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c16
-rw-r--r--net/mac80211/mlme.c17
-rw-r--r--net/mac80211/offchannel.c6
5 files changed, 36 insertions, 20 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index cfdc03f59e27..efbbdc8a2be0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2493,6 +2493,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2493 skb->dev = sdata->dev; 2493 skb->dev = sdata->dev;
2494 2494
2495 if (!need_offchan) { 2495 if (!need_offchan) {
2496 *cookie = (unsigned long) skb;
2496 ieee80211_tx_skb(sdata, skb); 2497 ieee80211_tx_skb(sdata, skb);
2497 ret = 0; 2498 ret = 0;
2498 goto out_unlock; 2499 goto out_unlock;
@@ -2982,14 +2983,14 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
2982 return 0; 2983 return 0;
2983} 2984}
2984 2985
2985static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled) 2986static struct ieee80211_channel *
2987ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
2988 enum nl80211_channel_type *type)
2986{ 2989{
2987 struct ieee80211_local *local = wiphy_priv(wiphy); 2990 struct ieee80211_local *local = wiphy_priv(wiphy);
2988 2991
2989 if (enabled) 2992 *type = local->_oper_channel_type;
2990 WARN_ON(ieee80211_add_virtual_monitor(local)); 2993 return local->oper_channel;
2991 else
2992 ieee80211_del_virtual_monitor(local);
2993} 2994}
2994 2995
2995#ifdef CONFIG_PM 2996#ifdef CONFIG_PM
@@ -3066,11 +3067,11 @@ struct cfg80211_ops mac80211_config_ops = {
3066 .tdls_mgmt = ieee80211_tdls_mgmt, 3067 .tdls_mgmt = ieee80211_tdls_mgmt,
3067 .probe_client = ieee80211_probe_client, 3068 .probe_client = ieee80211_probe_client,
3068 .set_noack_map = ieee80211_set_noack_map, 3069 .set_noack_map = ieee80211_set_noack_map,
3069 .set_monitor_enabled = ieee80211_set_monitor_enabled,
3070#ifdef CONFIG_PM 3070#ifdef CONFIG_PM
3071 .set_wakeup = ieee80211_set_wakeup, 3071 .set_wakeup = ieee80211_set_wakeup,
3072#endif 3072#endif
3073 .get_et_sset_count = ieee80211_get_et_sset_count, 3073 .get_et_sset_count = ieee80211_get_et_sset_count,
3074 .get_et_stats = ieee80211_get_et_stats, 3074 .get_et_stats = ieee80211_get_et_stats,
3075 .get_et_strings = ieee80211_get_et_strings, 3075 .get_et_strings = ieee80211_get_et_strings,
3076 .get_channel = ieee80211_cfg_get_channel,
3076}; 3077};
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7998513ec831..bb61f7718c4c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1491,10 +1491,6 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1491int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, 1491int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1492 struct sk_buff *skb, bool need_basic); 1492 struct sk_buff *skb, bool need_basic);
1493 1493
1494/* virtual monitor */
1495int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
1496void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
1497
1498/* channel management */ 1494/* channel management */
1499enum ieee80211_chan_mode { 1495enum ieee80211_chan_mode {
1500 CHAN_MODE_UNDEFINED, 1496 CHAN_MODE_UNDEFINED,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 334ee0fb18ca..bfb57dcc1538 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -331,7 +331,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
331 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; 331 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
332} 332}
333 333
334int ieee80211_add_virtual_monitor(struct ieee80211_local *local) 334static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
335{ 335{
336 struct ieee80211_sub_if_data *sdata; 336 struct ieee80211_sub_if_data *sdata;
337 int ret = 0; 337 int ret = 0;
@@ -377,7 +377,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
377 return ret; 377 return ret;
378} 378}
379 379
380void ieee80211_del_virtual_monitor(struct ieee80211_local *local) 380static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
381{ 381{
382 struct ieee80211_sub_if_data *sdata; 382 struct ieee80211_sub_if_data *sdata;
383 383
@@ -497,6 +497,12 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
497 break; 497 break;
498 } 498 }
499 499
500 if (local->monitors == 0 && local->open_count == 0) {
501 res = ieee80211_add_virtual_monitor(local);
502 if (res)
503 goto err_stop;
504 }
505
500 /* must be before the call to ieee80211_configure_filter */ 506 /* must be before the call to ieee80211_configure_filter */
501 local->monitors++; 507 local->monitors++;
502 if (local->monitors == 1) { 508 if (local->monitors == 1) {
@@ -511,6 +517,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
511 break; 517 break;
512 default: 518 default:
513 if (coming_up) { 519 if (coming_up) {
520 ieee80211_del_virtual_monitor(local);
521
514 res = drv_add_interface(local, sdata); 522 res = drv_add_interface(local, sdata);
515 if (res) 523 if (res)
516 goto err_stop; 524 goto err_stop;
@@ -745,6 +753,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
745 if (local->monitors == 0) { 753 if (local->monitors == 0) {
746 local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; 754 local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
747 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 755 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
756 ieee80211_del_virtual_monitor(local);
748 } 757 }
749 758
750 ieee80211_adjust_monitor_flags(sdata, -1); 759 ieee80211_adjust_monitor_flags(sdata, -1);
@@ -818,6 +827,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
818 } 827 }
819 } 828 }
820 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 829 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
830
831 if (local->monitors == local->open_count && local->monitors > 0)
832 ieee80211_add_virtual_monitor(local);
821} 833}
822 834
823static int ieee80211_stop(struct net_device *dev) 835static int ieee80211_stop(struct net_device *dev)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index de4350fce11e..cef0c9e79aba 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1360,6 +1360,17 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1360 } 1360 }
1361 mutex_unlock(&local->sta_mtx); 1361 mutex_unlock(&local->sta_mtx);
1362 1362
1363 /*
1364 * if we want to get out of ps before disassoc (why?) we have
1365 * to do it before sending disassoc, as otherwise the null-packet
1366 * won't be valid.
1367 */
1368 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1369 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
1370 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1371 }
1372 local->ps_sdata = NULL;
1373
1363 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ 1374 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
1364 if (tx) 1375 if (tx)
1365 drv_flush(local, false); 1376 drv_flush(local, false);
@@ -1395,12 +1406,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1395 del_timer_sync(&local->dynamic_ps_timer); 1406 del_timer_sync(&local->dynamic_ps_timer);
1396 cancel_work_sync(&local->dynamic_ps_enable_work); 1407 cancel_work_sync(&local->dynamic_ps_enable_work);
1397 1408
1398 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1399 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
1400 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1401 }
1402 local->ps_sdata = NULL;
1403
1404 /* Disable ARP filtering */ 1409 /* Disable ARP filtering */
1405 if (sdata->vif.bss_conf.arp_filter_enabled) { 1410 if (sdata->vif.bss_conf.arp_filter_enabled) {
1406 sdata->vif.bss_conf.arp_filter_enabled = false; 1411 sdata->vif.bss_conf.arp_filter_enabled = false;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 8c047fc8b325..635c3250c668 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -324,6 +324,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
324 container_of(work, struct ieee80211_roc_work, work.work); 324 container_of(work, struct ieee80211_roc_work, work.work);
325 struct ieee80211_sub_if_data *sdata = roc->sdata; 325 struct ieee80211_sub_if_data *sdata = roc->sdata;
326 struct ieee80211_local *local = sdata->local; 326 struct ieee80211_local *local = sdata->local;
327 bool started;
327 328
328 mutex_lock(&local->mtx); 329 mutex_lock(&local->mtx);
329 330
@@ -366,9 +367,10 @@ void ieee80211_sw_roc_work(struct work_struct *work)
366 /* finish this ROC */ 367 /* finish this ROC */
367 finish: 368 finish:
368 list_del(&roc->list); 369 list_del(&roc->list);
370 started = roc->started;
369 ieee80211_roc_notify_destroy(roc); 371 ieee80211_roc_notify_destroy(roc);
370 372
371 if (roc->started) { 373 if (started) {
372 drv_flush(local, false); 374 drv_flush(local, false);
373 375
374 local->tmp_channel = NULL; 376 local->tmp_channel = NULL;
@@ -379,7 +381,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
379 381
380 ieee80211_recalc_idle(local); 382 ieee80211_recalc_idle(local);
381 383
382 if (roc->started) 384 if (started)
383 ieee80211_start_next_roc(local); 385 ieee80211_start_next_roc(local);
384 } 386 }
385 387