aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-03-29 16:41:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-03-29 16:41:36 -0400
commit9a574cd67a447059f9c14bbef47873315d7f7b35 (patch)
tree0ebb71d213d868d8884b1fa0e05b7393c66c665b /net/mac80211
parent689b66cb53fbb5d567aa4e095eaa828aff73aef0 (diff)
parent2e1253d640eb7f8707d2591c93097c1e9f9c71d5 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: net/mac80211/sta_info.c net/wireless/core.h
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/iface.c35
-rw-r--r--net/mac80211/mesh.c3
-rw-r--r--net/mac80211/mlme.c6
-rw-r--r--net/mac80211/rx.c14
4 files changed, 38 insertions, 20 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d646e12e55a6..2a3c1e9bdf25 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -349,21 +349,19 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
349static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) 349static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
350{ 350{
351 struct ieee80211_sub_if_data *sdata; 351 struct ieee80211_sub_if_data *sdata;
352 int ret = 0; 352 int ret;
353 353
354 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) 354 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))
355 return 0; 355 return 0;
356 356
357 mutex_lock(&local->iflist_mtx); 357 ASSERT_RTNL();
358 358
359 if (local->monitor_sdata) 359 if (local->monitor_sdata)
360 goto out_unlock; 360 return 0;
361 361
362 sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); 362 sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
363 if (!sdata) { 363 if (!sdata)
364 ret = -ENOMEM; 364 return -ENOMEM;
365 goto out_unlock;
366 }
367 365
368 /* set up data */ 366 /* set up data */
369 sdata->local = local; 367 sdata->local = local;
@@ -377,13 +375,13 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
377 if (WARN_ON(ret)) { 375 if (WARN_ON(ret)) {
378 /* ok .. stupid driver, it asked for this! */ 376 /* ok .. stupid driver, it asked for this! */
379 kfree(sdata); 377 kfree(sdata);
380 goto out_unlock; 378 return ret;
381 } 379 }
382 380
383 ret = ieee80211_check_queues(sdata); 381 ret = ieee80211_check_queues(sdata);
384 if (ret) { 382 if (ret) {
385 kfree(sdata); 383 kfree(sdata);
386 goto out_unlock; 384 return ret;
387 } 385 }
388 386
389 ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, 387 ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
@@ -391,13 +389,14 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
391 if (ret) { 389 if (ret) {
392 drv_remove_interface(local, sdata); 390 drv_remove_interface(local, sdata);
393 kfree(sdata); 391 kfree(sdata);
394 goto out_unlock; 392 return ret;
395 } 393 }
396 394
395 mutex_lock(&local->iflist_mtx);
397 rcu_assign_pointer(local->monitor_sdata, sdata); 396 rcu_assign_pointer(local->monitor_sdata, sdata);
398 out_unlock:
399 mutex_unlock(&local->iflist_mtx); 397 mutex_unlock(&local->iflist_mtx);
400 return ret; 398
399 return 0;
401} 400}
402 401
403static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) 402static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
@@ -407,14 +406,20 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
407 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) 406 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))
408 return; 407 return;
409 408
409 ASSERT_RTNL();
410
410 mutex_lock(&local->iflist_mtx); 411 mutex_lock(&local->iflist_mtx);
411 412
412 sdata = rcu_dereference_protected(local->monitor_sdata, 413 sdata = rcu_dereference_protected(local->monitor_sdata,
413 lockdep_is_held(&local->iflist_mtx)); 414 lockdep_is_held(&local->iflist_mtx));
414 if (!sdata) 415 if (!sdata) {
415 goto out_unlock; 416 mutex_unlock(&local->iflist_mtx);
417 return;
418 }
416 419
417 rcu_assign_pointer(local->monitor_sdata, NULL); 420 rcu_assign_pointer(local->monitor_sdata, NULL);
421 mutex_unlock(&local->iflist_mtx);
422
418 synchronize_net(); 423 synchronize_net();
419 424
420 ieee80211_vif_release_channel(sdata); 425 ieee80211_vif_release_channel(sdata);
@@ -422,8 +427,6 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
422 drv_remove_interface(local, sdata); 427 drv_remove_interface(local, sdata);
423 428
424 kfree(sdata); 429 kfree(sdata);
425 out_unlock:
426 mutex_unlock(&local->iflist_mtx);
427} 430}
428 431
429/* 432/*
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index aead5410c622..123a300cef57 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1004,7 +1004,8 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
1004 1004
1005 rcu_read_lock(); 1005 rcu_read_lock();
1006 list_for_each_entry_rcu(sdata, &local->interfaces, list) 1006 list_for_each_entry_rcu(sdata, &local->interfaces, list)
1007 if (ieee80211_vif_is_mesh(&sdata->vif)) 1007 if (ieee80211_vif_is_mesh(&sdata->vif) &&
1008 ieee80211_sdata_running(sdata))
1008 ieee80211_queue_work(&local->hw, &sdata->work); 1009 ieee80211_queue_work(&local->hw, &sdata->work);
1009 rcu_read_unlock(); 1010 rcu_read_unlock();
1010} 1011}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4d383a93ea73..e06dbbf8cb4c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3531,8 +3531,10 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
3531 3531
3532 /* Restart STA timers */ 3532 /* Restart STA timers */
3533 rcu_read_lock(); 3533 rcu_read_lock();
3534 list_for_each_entry_rcu(sdata, &local->interfaces, list) 3534 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3535 ieee80211_restart_sta_timer(sdata); 3535 if (ieee80211_sdata_running(sdata))
3536 ieee80211_restart_sta_timer(sdata);
3537 }
3536 rcu_read_unlock(); 3538 rcu_read_unlock();
3537} 3539}
3538 3540
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5b4492af4e85..2528b5a4d6d4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2666,7 +2666,19 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
2666 2666
2667 memset(nskb->cb, 0, sizeof(nskb->cb)); 2667 memset(nskb->cb, 0, sizeof(nskb->cb));
2668 2668
2669 ieee80211_tx_skb(rx->sdata, nskb); 2669 if (rx->sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {
2670 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(nskb);
2671
2672 info->flags = IEEE80211_TX_CTL_TX_OFFCHAN |
2673 IEEE80211_TX_INTFL_OFFCHAN_TX_OK |
2674 IEEE80211_TX_CTL_NO_CCK_RATE;
2675 if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
2676 info->hw_queue =
2677 local->hw.offchannel_tx_hw_queue;
2678 }
2679
2680 __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7,
2681 status->band);
2670 } 2682 }
2671 dev_kfree_skb(rx->skb); 2683 dev_kfree_skb(rx->skb);
2672 return RX_QUEUED; 2684 return RX_QUEUED;