aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-02-13 14:43:02 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-13 14:43:02 -0500
commit0e028ab0fb2da47fd235dafd4159859892e73d08 (patch)
treee9e1348372b413e6b1b503209582b03c9005f614 /net/mac80211
parente57f1734d87aa0e9a00905ed08888f0c62f56227 (diff)
parent348f7d4adee97f222e3ad9ff97956ca3793d11c6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c44
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c5
-rw-r--r--net/mac80211/iface.c27
-rw-r--r--net/mac80211/tx.c2
5 files changed, 47 insertions, 35 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6973ccdd230b..363d19b5d5c8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
1021 IEEE80211_P2P_OPPPS_ENABLE_BIT; 1021 IEEE80211_P2P_OPPPS_ENABLE_BIT;
1022 1022
1023 err = ieee80211_assign_beacon(sdata, &params->beacon); 1023 err = ieee80211_assign_beacon(sdata, &params->beacon);
1024 if (err < 0) 1024 if (err < 0) {
1025 ieee80211_vif_release_channel(sdata);
1025 return err; 1026 return err;
1027 }
1026 changed |= err; 1028 changed |= err;
1027 1029
1028 err = drv_start_ap(sdata->local, sdata); 1030 err = drv_start_ap(sdata->local, sdata);
@@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
1032 if (old) 1034 if (old)
1033 kfree_rcu(old, rcu_head); 1035 kfree_rcu(old, rcu_head);
1034 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 1036 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
1037 ieee80211_vif_release_channel(sdata);
1035 return err; 1038 return err;
1036 } 1039 }
1037 1040
@@ -1093,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1093 kfree(sdata->u.ap.next_beacon); 1096 kfree(sdata->u.ap.next_beacon);
1094 sdata->u.ap.next_beacon = NULL; 1097 sdata->u.ap.next_beacon = NULL;
1095 1098
1096 cancel_work_sync(&sdata->u.ap.request_smps_work);
1097
1098 /* turn off carrier for this interface and dependent VLANs */ 1099 /* turn off carrier for this interface and dependent VLANs */
1099 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 1100 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
1100 netif_carrier_off(vlan->dev); 1101 netif_carrier_off(vlan->dev);
@@ -1106,6 +1107,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1106 kfree_rcu(old_beacon, rcu_head); 1107 kfree_rcu(old_beacon, rcu_head);
1107 if (old_probe_resp) 1108 if (old_probe_resp)
1108 kfree_rcu(old_probe_resp, rcu_head); 1109 kfree_rcu(old_probe_resp, rcu_head);
1110 sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
1109 1111
1110 __sta_info_flush(sdata, true); 1112 __sta_info_flush(sdata, true);
1111 ieee80211_free_keys(sdata, true); 1113 ieee80211_free_keys(sdata, true);
@@ -2665,6 +2667,24 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2665 INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); 2667 INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
2666 INIT_LIST_HEAD(&roc->dependents); 2668 INIT_LIST_HEAD(&roc->dependents);
2667 2669
2670 /*
2671 * cookie is either the roc cookie (for normal roc)
2672 * or the SKB (for mgmt TX)
2673 */
2674 if (!txskb) {
2675 /* local->mtx protects this */
2676 local->roc_cookie_counter++;
2677 roc->cookie = local->roc_cookie_counter;
2678 /* wow, you wrapped 64 bits ... more likely a bug */
2679 if (WARN_ON(roc->cookie == 0)) {
2680 roc->cookie = 1;
2681 local->roc_cookie_counter++;
2682 }
2683 *cookie = roc->cookie;
2684 } else {
2685 *cookie = (unsigned long)txskb;
2686 }
2687
2668 /* if there's one pending or we're scanning, queue this one */ 2688 /* if there's one pending or we're scanning, queue this one */
2669 if (!list_empty(&local->roc_list) || 2689 if (!list_empty(&local->roc_list) ||
2670 local->scanning || local->radar_detect_enabled) 2690 local->scanning || local->radar_detect_enabled)
@@ -2787,24 +2807,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2787 if (!queued) 2807 if (!queued)
2788 list_add_tail(&roc->list, &local->roc_list); 2808 list_add_tail(&roc->list, &local->roc_list);
2789 2809
2790 /*
2791 * cookie is either the roc cookie (for normal roc)
2792 * or the SKB (for mgmt TX)
2793 */
2794 if (!txskb) {
2795 /* local->mtx protects this */
2796 local->roc_cookie_counter++;
2797 roc->cookie = local->roc_cookie_counter;
2798 /* wow, you wrapped 64 bits ... more likely a bug */
2799 if (WARN_ON(roc->cookie == 0)) {
2800 roc->cookie = 1;
2801 local->roc_cookie_counter++;
2802 }
2803 *cookie = roc->cookie;
2804 } else {
2805 *cookie = (unsigned long)txskb;
2806 }
2807
2808 return 0; 2810 return 0;
2809} 2811}
2810 2812
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index dc3c28002e3e..afbe2b203c3e 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(struct work_struct *work)
466 u.ap.request_smps_work); 466 u.ap.request_smps_work);
467 467
468 sdata_lock(sdata); 468 sdata_lock(sdata);
469 __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode); 469 if (sdata_dereference(sdata->u.ap.beacon, sdata))
470 __ieee80211_request_smps_ap(sdata,
471 sdata->u.ap.driver_smps_mode);
470 sdata_unlock(sdata); 472 sdata_unlock(sdata);
471} 473}
472 474
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 9c84b75f3de8..4453e2725e40 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -684,12 +684,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
684 struct cfg80211_bss *cbss; 684 struct cfg80211_bss *cbss;
685 struct beacon_data *presp; 685 struct beacon_data *presp;
686 struct sta_info *sta; 686 struct sta_info *sta;
687 int active_ibss;
688 u16 capability; 687 u16 capability;
689 688
690 active_ibss = ieee80211_sta_active_ibss(sdata); 689 if (!is_zero_ether_addr(ifibss->bssid)) {
691
692 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
693 capability = WLAN_CAPABILITY_IBSS; 690 capability = WLAN_CAPABILITY_IBSS;
694 691
695 if (ifibss->privacy) 692 if (ifibss->privacy)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8880bc8fce0d..96518ad200c4 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
418 return ret; 418 return ret;
419 } 419 }
420 420
421 mutex_lock(&local->iflist_mtx);
422 rcu_assign_pointer(local->monitor_sdata, sdata);
423 mutex_unlock(&local->iflist_mtx);
424
421 mutex_lock(&local->mtx); 425 mutex_lock(&local->mtx);
422 ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, 426 ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
423 IEEE80211_CHANCTX_EXCLUSIVE); 427 IEEE80211_CHANCTX_EXCLUSIVE);
424 mutex_unlock(&local->mtx); 428 mutex_unlock(&local->mtx);
425 if (ret) { 429 if (ret) {
430 mutex_lock(&local->iflist_mtx);
431 rcu_assign_pointer(local->monitor_sdata, NULL);
432 mutex_unlock(&local->iflist_mtx);
433 synchronize_net();
426 drv_remove_interface(local, sdata); 434 drv_remove_interface(local, sdata);
427 kfree(sdata); 435 kfree(sdata);
428 return ret; 436 return ret;
429 } 437 }
430 438
431 mutex_lock(&local->iflist_mtx);
432 rcu_assign_pointer(local->monitor_sdata, sdata);
433 mutex_unlock(&local->iflist_mtx);
434
435 return 0; 439 return 0;
436} 440}
437 441
@@ -770,12 +774,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
770 774
771 ieee80211_roc_purge(local, sdata); 775 ieee80211_roc_purge(local, sdata);
772 776
773 if (sdata->vif.type == NL80211_IFTYPE_STATION) 777 switch (sdata->vif.type) {
778 case NL80211_IFTYPE_STATION:
774 ieee80211_mgd_stop(sdata); 779 ieee80211_mgd_stop(sdata);
775 780 break;
776 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 781 case NL80211_IFTYPE_ADHOC:
777 ieee80211_ibss_stop(sdata); 782 ieee80211_ibss_stop(sdata);
778 783 break;
784 case NL80211_IFTYPE_AP:
785 cancel_work_sync(&sdata->u.ap.request_smps_work);
786 break;
787 default:
788 break;
789 }
779 790
780 /* 791 /*
781 * Remove all stations associated with this interface. 792 * Remove all stations associated with this interface.
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5476a69b45c9..722151fa5dce 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -874,7 +874,7 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx,
874 } 874 }
875 875
876 /* adjust first fragment's length */ 876 /* adjust first fragment's length */
877 skb->len = hdrlen + per_fragm; 877 skb_trim(skb, hdrlen + per_fragm);
878 return 0; 878 return 0;
879} 879}
880 880