aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-01 13:36:50 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-01 13:36:50 -0400
commita210576cf891e9e6d2c238eabcf5c1286b1e7526 (patch)
tree0fa81a901cf628b25e6ee79057700cf39e59818a /net/mac80211
parent7d4c04fc170087119727119074e72445f2bb192b (diff)
parent3658f3604066d5500ebd73a04084f127dc779441 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: net/mac80211/sta_info.c net/wireless/core.h Two minor conflicts in wireless. Overlapping additions of extern declarations in net/wireless/core.h and a bug fix overlapping with the addition of a boolean parameter to __ieee80211_key_free(). Signed-off-by: David S. Miller <davem@davemloft.net>
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
-rw-r--r--net/mac80211/sta_info.c13
5 files changed, 49 insertions, 22 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d85282f64405..7530c60fe502 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 5ac017f3fcd2..77b5710db241 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1007,7 +1007,8 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
1007 1007
1008 rcu_read_lock(); 1008 rcu_read_lock();
1009 list_for_each_entry_rcu(sdata, &local->interfaces, list) 1009 list_for_each_entry_rcu(sdata, &local->interfaces, list)
1010 if (ieee80211_vif_is_mesh(&sdata->vif)) 1010 if (ieee80211_vif_is_mesh(&sdata->vif) &&
1011 ieee80211_sdata_running(sdata))
1011 ieee80211_queue_work(&local->hw, &sdata->work); 1012 ieee80211_queue_work(&local->hw, &sdata->work);
1012 rcu_read_unlock(); 1013 rcu_read_unlock();
1013} 1014}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fdc06e381c10..167158646593 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3527,8 +3527,10 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
3527 3527
3528 /* Restart STA timers */ 3528 /* Restart STA timers */
3529 rcu_read_lock(); 3529 rcu_read_lock();
3530 list_for_each_entry_rcu(sdata, &local->interfaces, list) 3530 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3531 ieee80211_restart_sta_timer(sdata); 3531 if (ieee80211_sdata_running(sdata))
3532 ieee80211_restart_sta_timer(sdata);
3533 }
3532 rcu_read_unlock(); 3534 rcu_read_unlock();
3533} 3535}
3534 3536
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;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 3644ad79688a..85458a28ffa0 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -771,6 +771,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
771 struct ieee80211_local *local; 771 struct ieee80211_local *local;
772 struct ieee80211_sub_if_data *sdata; 772 struct ieee80211_sub_if_data *sdata;
773 int ret, i; 773 int ret, i;
774 bool have_key = false;
774 775
775 might_sleep(); 776 might_sleep();
776 777
@@ -798,14 +799,22 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
798 list_del_rcu(&sta->list); 799 list_del_rcu(&sta->list);
799 800
800 mutex_lock(&local->key_mtx); 801 mutex_lock(&local->key_mtx);
801 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 802 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
802 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]), 803 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]),
803 true); 804 true);
804 if (sta->ptk) 805 have_key = true;
806 }
807 if (sta->ptk) {
805 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk), 808 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk),
806 true); 809 true);
810 have_key = true;
811 }
812
807 mutex_unlock(&local->key_mtx); 813 mutex_unlock(&local->key_mtx);
808 814
815 if (!have_key)
816 synchronize_net();
817
809 sta->dead = true; 818 sta->dead = true;
810 819
811 local->num_sta--; 820 local->num_sta--;