diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 219 |
1 files changed, 94 insertions, 125 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 09a80b55cf5a..2c059e54e885 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -78,8 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) | |||
78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); | 78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); |
79 | } | 79 | } |
80 | 80 | ||
81 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | 81 | static u32 ieee80211_idle_off(struct ieee80211_local *local) |
82 | const char *reason) | ||
83 | { | 82 | { |
84 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | 83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) |
85 | return 0; | 84 | return 0; |
@@ -99,125 +98,51 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
99 | return IEEE80211_CONF_CHANGE_IDLE; | 98 | return IEEE80211_CONF_CHANGE_IDLE; |
100 | } | 99 | } |
101 | 100 | ||
102 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | 101 | void ieee80211_recalc_idle(struct ieee80211_local *local) |
103 | { | 102 | { |
104 | struct ieee80211_sub_if_data *sdata; | 103 | bool working = false, scanning, active; |
105 | int count = 0; | ||
106 | bool working = false, scanning = false; | ||
107 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 104 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
108 | struct ieee80211_roc_work *roc; | 105 | struct ieee80211_roc_work *roc; |
106 | u32 change; | ||
109 | 107 | ||
110 | #ifdef CONFIG_PROVE_LOCKING | ||
111 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | ||
112 | !lockdep_is_held(&local->iflist_mtx)); | ||
113 | #endif | ||
114 | lockdep_assert_held(&local->mtx); | 108 | lockdep_assert_held(&local->mtx); |
115 | 109 | ||
116 | list_for_each_entry(sdata, &local->interfaces, list) { | 110 | active = !list_empty(&local->chanctx_list); |
117 | if (!ieee80211_sdata_running(sdata)) { | ||
118 | sdata->vif.bss_conf.idle = true; | ||
119 | continue; | ||
120 | } | ||
121 | |||
122 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
123 | |||
124 | /* do not count disabled managed interfaces */ | ||
125 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
126 | !sdata->u.mgd.associated && | ||
127 | !sdata->u.mgd.auth_data && | ||
128 | !sdata->u.mgd.assoc_data) { | ||
129 | sdata->vif.bss_conf.idle = true; | ||
130 | continue; | ||
131 | } | ||
132 | /* do not count unused IBSS interfaces */ | ||
133 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
134 | !sdata->u.ibss.ssid_len) { | ||
135 | sdata->vif.bss_conf.idle = true; | ||
136 | continue; | ||
137 | } | ||
138 | |||
139 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
140 | continue; | ||
141 | |||
142 | /* count everything else */ | ||
143 | sdata->vif.bss_conf.idle = false; | ||
144 | count++; | ||
145 | } | ||
146 | 111 | ||
147 | if (!local->ops->remain_on_channel) { | 112 | if (!local->ops->remain_on_channel) { |
148 | list_for_each_entry(roc, &local->roc_list, list) { | 113 | list_for_each_entry(roc, &local->roc_list, list) { |
149 | working = true; | 114 | working = true; |
150 | roc->sdata->vif.bss_conf.idle = false; | 115 | break; |
151 | } | 116 | } |
152 | } | 117 | } |
153 | 118 | ||
154 | sdata = rcu_dereference_protected(local->scan_sdata, | 119 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || |
155 | lockdep_is_held(&local->mtx)); | 120 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); |
156 | if (sdata && !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | ||
157 | scanning = true; | ||
158 | sdata->vif.bss_conf.idle = false; | ||
159 | } | ||
160 | |||
161 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
162 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | ||
163 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | ||
164 | sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
165 | continue; | ||
166 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
167 | continue; | ||
168 | if (!ieee80211_sdata_running(sdata)) | ||
169 | continue; | ||
170 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
171 | } | ||
172 | 121 | ||
173 | if (working || scanning) | 122 | if (working || scanning) |
174 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | 123 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; |
175 | else | 124 | else |
176 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | 125 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; |
177 | 126 | ||
178 | if (count) | 127 | if (active) |
179 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | 128 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; |
180 | else | 129 | else |
181 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | 130 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; |
182 | 131 | ||
183 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | 132 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); |
184 | 133 | ||
185 | if (working) | 134 | if (working || scanning || active) |
186 | return ieee80211_idle_off(local, "working"); | 135 | change = ieee80211_idle_off(local); |
187 | if (scanning) | ||
188 | return ieee80211_idle_off(local, "scanning"); | ||
189 | if (!count) | ||
190 | return ieee80211_idle_on(local); | ||
191 | else | 136 | else |
192 | return ieee80211_idle_off(local, "in use"); | 137 | change = ieee80211_idle_on(local); |
193 | 138 | if (change) | |
194 | return 0; | 139 | ieee80211_hw_config(local, change); |
195 | } | ||
196 | |||
197 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
198 | { | ||
199 | u32 chg; | ||
200 | |||
201 | mutex_lock(&local->iflist_mtx); | ||
202 | chg = __ieee80211_recalc_idle(local); | ||
203 | mutex_unlock(&local->iflist_mtx); | ||
204 | if (chg) | ||
205 | ieee80211_hw_config(local, chg); | ||
206 | } | 140 | } |
207 | 141 | ||
208 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | 142 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) |
209 | { | 143 | { |
210 | int meshhdrlen; | 144 | if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) |
211 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
212 | |||
213 | meshhdrlen = (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ? 5 : 0; | ||
214 | |||
215 | /* FIX: what would be proper limits for MTU? | ||
216 | * This interface uses 802.3 frames. */ | ||
217 | if (new_mtu < 256 || | ||
218 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | ||
219 | return -EINVAL; | 145 | return -EINVAL; |
220 | } | ||
221 | 146 | ||
222 | dev->mtu = new_mtu; | 147 | dev->mtu = new_mtu; |
223 | return 0; | 148 | return 0; |
@@ -369,7 +294,8 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata) | |||
369 | } | 294 | } |
370 | } | 295 | } |
371 | 296 | ||
372 | if ((sdata->vif.type != NL80211_IFTYPE_AP) || | 297 | if ((sdata->vif.type != NL80211_IFTYPE_AP && |
298 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) || | ||
373 | !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) { | 299 | !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) { |
374 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; | 300 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; |
375 | return 0; | 301 | return 0; |
@@ -586,11 +512,13 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
586 | 512 | ||
587 | switch (sdata->vif.type) { | 513 | switch (sdata->vif.type) { |
588 | case NL80211_IFTYPE_AP_VLAN: | 514 | case NL80211_IFTYPE_AP_VLAN: |
589 | /* no need to tell driver, but set carrier */ | 515 | /* no need to tell driver, but set carrier and chanctx */ |
590 | if (rtnl_dereference(sdata->bss->beacon)) | 516 | if (rtnl_dereference(sdata->bss->beacon)) { |
517 | ieee80211_vif_vlan_copy_chanctx(sdata); | ||
591 | netif_carrier_on(dev); | 518 | netif_carrier_on(dev); |
592 | else | 519 | } else { |
593 | netif_carrier_off(dev); | 520 | netif_carrier_off(dev); |
521 | } | ||
594 | break; | 522 | break; |
595 | case NL80211_IFTYPE_MONITOR: | 523 | case NL80211_IFTYPE_MONITOR: |
596 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | 524 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { |
@@ -628,6 +556,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
628 | goto err_del_interface; | 556 | goto err_del_interface; |
629 | } | 557 | } |
630 | 558 | ||
559 | drv_add_interface_debugfs(local, sdata); | ||
560 | |||
631 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 561 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
632 | local->fif_pspoll++; | 562 | local->fif_pspoll++; |
633 | local->fif_probe_req++; | 563 | local->fif_probe_req++; |
@@ -701,10 +631,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
701 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 631 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
702 | atomic_inc(&local->iff_promiscs); | 632 | atomic_inc(&local->iff_promiscs); |
703 | 633 | ||
704 | mutex_lock(&local->mtx); | ||
705 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | ||
706 | mutex_unlock(&local->mtx); | ||
707 | |||
708 | if (coming_up) | 634 | if (coming_up) |
709 | local->open_count++; | 635 | local->open_count++; |
710 | 636 | ||
@@ -754,7 +680,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
754 | unsigned long flags; | 680 | unsigned long flags; |
755 | struct sk_buff *skb, *tmp; | 681 | struct sk_buff *skb, *tmp; |
756 | u32 hw_reconf_flags = 0; | 682 | u32 hw_reconf_flags = 0; |
757 | int i; | 683 | int i, flushed; |
684 | struct ps_data *ps; | ||
758 | 685 | ||
759 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | 686 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); |
760 | 687 | ||
@@ -769,6 +696,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
769 | 696 | ||
770 | ieee80211_roc_purge(sdata); | 697 | ieee80211_roc_purge(sdata); |
771 | 698 | ||
699 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
700 | ieee80211_mgd_stop(sdata); | ||
701 | |||
772 | /* | 702 | /* |
773 | * Remove all stations associated with this interface. | 703 | * Remove all stations associated with this interface. |
774 | * | 704 | * |
@@ -779,11 +709,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
779 | * (because if we remove a STA after ops->remove_interface() | 709 | * (because if we remove a STA after ops->remove_interface() |
780 | * the driver will have removed the vif info already!) | 710 | * the driver will have removed the vif info already!) |
781 | * | 711 | * |
782 | * This is relevant only in AP, WDS and mesh modes, since in | 712 | * This is relevant only in WDS mode, in all other modes we've |
783 | * all other modes we've already removed all stations when | 713 | * already removed all stations when disconnecting or similar, |
784 | * disconnecting etc. | 714 | * so warn otherwise. |
715 | * | ||
716 | * We call sta_info_flush_cleanup() later, to combine RCU waits. | ||
785 | */ | 717 | */ |
786 | sta_info_flush(local, sdata); | 718 | flushed = sta_info_flush_defer(sdata); |
719 | WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || | ||
720 | (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); | ||
787 | 721 | ||
788 | /* | 722 | /* |
789 | * Don't count this interface for promisc/allmulti while it | 723 | * Don't count this interface for promisc/allmulti while it |
@@ -820,6 +754,16 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
820 | 754 | ||
821 | cancel_work_sync(&sdata->recalc_smps); | 755 | cancel_work_sync(&sdata->recalc_smps); |
822 | 756 | ||
757 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | ||
758 | |||
759 | if (sdata->wdev.cac_started) { | ||
760 | mutex_lock(&local->iflist_mtx); | ||
761 | ieee80211_vif_release_channel(sdata); | ||
762 | mutex_unlock(&local->iflist_mtx); | ||
763 | cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, | ||
764 | GFP_KERNEL); | ||
765 | } | ||
766 | |||
823 | /* APs need special treatment */ | 767 | /* APs need special treatment */ |
824 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 768 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
825 | struct ieee80211_sub_if_data *vlan, *tmpsdata; | 769 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
@@ -829,8 +773,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
829 | u.vlan.list) | 773 | u.vlan.list) |
830 | dev_close(vlan->dev); | 774 | dev_close(vlan->dev); |
831 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | 775 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); |
832 | } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 776 | } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
833 | ieee80211_mgd_stop(sdata); | 777 | /* remove all packets in parent bc_buf pointing to this dev */ |
778 | ps = &sdata->bss->ps; | ||
779 | |||
780 | spin_lock_irqsave(&ps->bc_buf.lock, flags); | ||
781 | skb_queue_walk_safe(&ps->bc_buf, skb, tmp) { | ||
782 | if (skb->dev == sdata->dev) { | ||
783 | __skb_unlink(skb, &ps->bc_buf); | ||
784 | local->total_ps_buffered--; | ||
785 | ieee80211_free_txskb(&local->hw, skb); | ||
786 | } | ||
787 | } | ||
788 | spin_unlock_irqrestore(&ps->bc_buf.lock, flags); | ||
834 | } | 789 | } |
835 | 790 | ||
836 | if (going_down) | 791 | if (going_down) |
@@ -839,6 +794,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
839 | switch (sdata->vif.type) { | 794 | switch (sdata->vif.type) { |
840 | case NL80211_IFTYPE_AP_VLAN: | 795 | case NL80211_IFTYPE_AP_VLAN: |
841 | list_del(&sdata->u.vlan.list); | 796 | list_del(&sdata->u.vlan.list); |
797 | rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); | ||
842 | /* no need to tell driver */ | 798 | /* no need to tell driver */ |
843 | break; | 799 | break; |
844 | case NL80211_IFTYPE_MONITOR: | 800 | case NL80211_IFTYPE_MONITOR: |
@@ -865,19 +821,16 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
865 | cancel_work_sync(&sdata->work); | 821 | cancel_work_sync(&sdata->work); |
866 | /* | 822 | /* |
867 | * When we get here, the interface is marked down. | 823 | * When we get here, the interface is marked down. |
868 | * Call rcu_barrier() to wait both for the RX path | 824 | * |
869 | * should it be using the interface and enqueuing | 825 | * sta_info_flush_cleanup() requires rcu_barrier() |
870 | * frames at this very time on another CPU, and | 826 | * first to wait for the station call_rcu() calls |
871 | * for the sta free call_rcu callbacks. | 827 | * to complete, here we need at least sychronize_rcu() |
828 | * it to wait for the RX path in case it is using the | ||
829 | * interface and enqueuing frames at this very time on | ||
830 | * another CPU. | ||
872 | */ | 831 | */ |
873 | rcu_barrier(); | 832 | rcu_barrier(); |
874 | 833 | sta_info_flush_cleanup(sdata); | |
875 | /* | ||
876 | * free_sta_rcu() enqueues a work for the actual | ||
877 | * sta cleanup, so we need to flush it while | ||
878 | * sdata is still valid. | ||
879 | */ | ||
880 | flush_workqueue(local->workqueue); | ||
881 | 834 | ||
882 | skb_queue_purge(&sdata->skb_queue); | 835 | skb_queue_purge(&sdata->skb_queue); |
883 | 836 | ||
@@ -887,16 +840,14 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
887 | */ | 840 | */ |
888 | ieee80211_free_keys(sdata); | 841 | ieee80211_free_keys(sdata); |
889 | 842 | ||
843 | drv_remove_interface_debugfs(local, sdata); | ||
844 | |||
890 | if (going_down) | 845 | if (going_down) |
891 | drv_remove_interface(local, sdata); | 846 | drv_remove_interface(local, sdata); |
892 | } | 847 | } |
893 | 848 | ||
894 | sdata->bss = NULL; | 849 | sdata->bss = NULL; |
895 | 850 | ||
896 | mutex_lock(&local->mtx); | ||
897 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | ||
898 | mutex_unlock(&local->mtx); | ||
899 | |||
900 | ieee80211_recalc_ps(local, -1); | 851 | ieee80211_recalc_ps(local, -1); |
901 | 852 | ||
902 | if (local->open_count == 0) { | 853 | if (local->open_count == 0) { |
@@ -976,7 +927,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
976 | */ | 927 | */ |
977 | static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) | 928 | static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) |
978 | { | 929 | { |
979 | struct ieee80211_local *local = sdata->local; | ||
980 | int flushed; | 930 | int flushed; |
981 | int i; | 931 | int i; |
982 | 932 | ||
@@ -992,7 +942,7 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) | |||
992 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 942 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
993 | mesh_rmc_free(sdata); | 943 | mesh_rmc_free(sdata); |
994 | 944 | ||
995 | flushed = sta_info_flush(local, sdata); | 945 | flushed = sta_info_flush(sdata); |
996 | WARN_ON(flushed); | 946 | WARN_ON(flushed); |
997 | } | 947 | } |
998 | 948 | ||
@@ -1233,6 +1183,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1233 | case NL80211_IFTYPE_AP: | 1183 | case NL80211_IFTYPE_AP: |
1234 | skb_queue_head_init(&sdata->u.ap.ps.bc_buf); | 1184 | skb_queue_head_init(&sdata->u.ap.ps.bc_buf); |
1235 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 1185 | INIT_LIST_HEAD(&sdata->u.ap.vlans); |
1186 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | ||
1236 | break; | 1187 | break; |
1237 | case NL80211_IFTYPE_P2P_CLIENT: | 1188 | case NL80211_IFTYPE_P2P_CLIENT: |
1238 | type = NL80211_IFTYPE_STATION; | 1189 | type = NL80211_IFTYPE_STATION; |
@@ -1240,9 +1191,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1240 | sdata->vif.p2p = true; | 1191 | sdata->vif.p2p = true; |
1241 | /* fall through */ | 1192 | /* fall through */ |
1242 | case NL80211_IFTYPE_STATION: | 1193 | case NL80211_IFTYPE_STATION: |
1194 | sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; | ||
1243 | ieee80211_sta_setup_sdata(sdata); | 1195 | ieee80211_sta_setup_sdata(sdata); |
1244 | break; | 1196 | break; |
1245 | case NL80211_IFTYPE_ADHOC: | 1197 | case NL80211_IFTYPE_ADHOC: |
1198 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | ||
1246 | ieee80211_ibss_setup_sdata(sdata); | 1199 | ieee80211_ibss_setup_sdata(sdata); |
1247 | break; | 1200 | break; |
1248 | case NL80211_IFTYPE_MESH_POINT: | 1201 | case NL80211_IFTYPE_MESH_POINT: |
@@ -1256,8 +1209,12 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1256 | MONITOR_FLAG_OTHER_BSS; | 1209 | MONITOR_FLAG_OTHER_BSS; |
1257 | break; | 1210 | break; |
1258 | case NL80211_IFTYPE_WDS: | 1211 | case NL80211_IFTYPE_WDS: |
1212 | sdata->vif.bss_conf.bssid = NULL; | ||
1213 | break; | ||
1259 | case NL80211_IFTYPE_AP_VLAN: | 1214 | case NL80211_IFTYPE_AP_VLAN: |
1215 | break; | ||
1260 | case NL80211_IFTYPE_P2P_DEVICE: | 1216 | case NL80211_IFTYPE_P2P_DEVICE: |
1217 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | ||
1261 | break; | 1218 | break; |
1262 | case NL80211_IFTYPE_UNSPECIFIED: | 1219 | case NL80211_IFTYPE_UNSPECIFIED: |
1263 | case NUM_NL80211_IFTYPES: | 1220 | case NUM_NL80211_IFTYPES: |
@@ -1498,6 +1455,15 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1498 | mutex_unlock(&local->iflist_mtx); | 1455 | mutex_unlock(&local->iflist_mtx); |
1499 | } | 1456 | } |
1500 | 1457 | ||
1458 | static void ieee80211_cleanup_sdata_stas_wk(struct work_struct *wk) | ||
1459 | { | ||
1460 | struct ieee80211_sub_if_data *sdata; | ||
1461 | |||
1462 | sdata = container_of(wk, struct ieee80211_sub_if_data, cleanup_stations_wk); | ||
1463 | |||
1464 | ieee80211_cleanup_sdata_stas(sdata); | ||
1465 | } | ||
1466 | |||
1501 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1467 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1502 | struct wireless_dev **new_wdev, enum nl80211_iftype type, | 1468 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1503 | struct vif_params *params) | 1469 | struct vif_params *params) |
@@ -1564,15 +1530,18 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1564 | /* initialise type-independent data */ | 1530 | /* initialise type-independent data */ |
1565 | sdata->wdev.wiphy = local->hw.wiphy; | 1531 | sdata->wdev.wiphy = local->hw.wiphy; |
1566 | sdata->local = local; | 1532 | sdata->local = local; |
1567 | #ifdef CONFIG_INET | ||
1568 | sdata->arp_filter_state = true; | ||
1569 | #endif | ||
1570 | 1533 | ||
1571 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) | 1534 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) |
1572 | skb_queue_head_init(&sdata->fragments[i].skb_list); | 1535 | skb_queue_head_init(&sdata->fragments[i].skb_list); |
1573 | 1536 | ||
1574 | INIT_LIST_HEAD(&sdata->key_list); | 1537 | INIT_LIST_HEAD(&sdata->key_list); |
1575 | 1538 | ||
1539 | spin_lock_init(&sdata->cleanup_stations_lock); | ||
1540 | INIT_LIST_HEAD(&sdata->cleanup_stations); | ||
1541 | INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk); | ||
1542 | INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work, | ||
1543 | ieee80211_dfs_cac_timer_work); | ||
1544 | |||
1576 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 1545 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
1577 | struct ieee80211_supported_band *sband; | 1546 | struct ieee80211_supported_band *sband; |
1578 | sband = local->hw.wiphy->bands[i]; | 1547 | sband = local->hw.wiphy->bands[i]; |