diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-02-13 14:43:02 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-13 14:43:02 -0500 |
commit | 0e028ab0fb2da47fd235dafd4159859892e73d08 (patch) | |
tree | e9e1348372b413e6b1b503209582b03c9005f614 /net/mac80211 | |
parent | e57f1734d87aa0e9a00905ed08888f0c62f56227 (diff) | |
parent | 348f7d4adee97f222e3ad9ff97956ca3793d11c6 (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.c | 44 | ||||
-rw-r--r-- | net/mac80211/ht.c | 4 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 5 | ||||
-rw-r--r-- | net/mac80211/iface.c | 27 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 |
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, ¶ms->beacon); | 1023 | err = ieee80211_assign_beacon(sdata, ¶ms->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 | ||