Blame view

net/mac80211/iface.c 55.9 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
f0706e828   Jiri Benc   [MAC80211]: Add m...
2
  /*
c5d54fbf0   Johannes Berg   mac80211: remove ...
3
   * Interface handling
0d143fe1e   Johannes Berg   mac80211: move re...
4
   *
f0706e828   Jiri Benc   [MAC80211]: Add m...
5
6
7
   * Copyright 2002-2005, Instant802 Networks, Inc.
   * Copyright 2005-2006, Devicescape Software, Inc.
   * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
75636525f   Johannes Berg   mac80211: revamp ...
8
   * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
d98ad83ee   Johannes Berg   mac80211: add Int...
9
   * Copyright 2013-2014  Intel Mobile Communications GmbH
d2941df8f   Johannes Berg   mac80211: recalcu...
10
   * Copyright (c) 2016        Intel Deutschland GmbH
52b4810be   Ilan Peer   mac80211: Remove ...
11
   * Copyright (C) 2018-2020 Intel Corporation
f0706e828   Jiri Benc   [MAC80211]: Add m...
12
   */
5a0e3ad6a   Tejun Heo   include cleanup: ...
13
  #include <linux/slab.h>
f0706e828   Jiri Benc   [MAC80211]: Add m...
14
15
16
17
18
  #include <linux/kernel.h>
  #include <linux/if_arp.h>
  #include <linux/netdevice.h>
  #include <linux/rtnetlink.h>
  #include <net/mac80211.h>
cf0277e71   Johannes Berg   mac80211: fix skb...
19
  #include <net/ieee80211_radiotap.h>
f0706e828   Jiri Benc   [MAC80211]: Add m...
20
21
  #include "ieee80211_i.h"
  #include "sta_info.h"
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
22
  #include "debugfs_netdev.h"
ee3858551   Luis Carlos Cobo   mac80211: mesh da...
23
  #include "mesh.h"
0d143fe1e   Johannes Berg   mac80211: move re...
24
  #include "led.h"
244879813   Johannes Berg   mac80211: add dri...
25
  #include "driver-ops.h"
cf0277e71   Johannes Berg   mac80211: fix skb...
26
  #include "wme.h"
1be7fe8de   Bill Jordan   mac80211: fix for...
27
  #include "rate.h"
0d143fe1e   Johannes Berg   mac80211: move re...
28

c771c9d8d   Johannes Berg   mac80211: add int...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  /**
   * DOC: Interface list locking
   *
   * The interface list in each struct ieee80211_local is protected
   * three-fold:
   *
   * (1) modifications may only be done under the RTNL
   * (2) modifications and readers are protected against each other by
   *     the iflist_mtx.
   * (3) modifications are done in an RCU manner so atomic readers
   *     can traverse the list in RCU-safe blocks.
   *
   * As a consequence, reads (traversals) of the list can be protected
   * by either the RTNL, the iflist_mtx or RCU.
   */
42bd20d99   Aviya Erenfeld   mac80211: add sup...
44
  static void ieee80211_iface_work(struct work_struct *work);
1ea6f9c0d   Johannes Berg   mac80211: handle ...
45
46
47
48
49
50
51
52
53
54
55
  bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
  {
  	struct ieee80211_chanctx_conf *chanctx_conf;
  	int power;
  
  	rcu_read_lock();
  	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
  	if (!chanctx_conf) {
  		rcu_read_unlock();
  		return false;
  	}
0430c8834   Simon Wunderlich   cfg80211/mac80211...
56
  	power = ieee80211_chandef_max_power(&chanctx_conf->def);
1ea6f9c0d   Johannes Berg   mac80211: handle ...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  	rcu_read_unlock();
  
  	if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
  		power = min(power, sdata->user_power_level);
  
  	if (sdata->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
  		power = min(power, sdata->ap_power_level);
  
  	if (power != sdata->vif.bss_conf.txpower) {
  		sdata->vif.bss_conf.txpower = power;
  		ieee80211_hw_config(sdata->local, 0);
  		return true;
  	}
  
  	return false;
  }
db82d8a96   Lorenzo Bianconi   mac80211: enable ...
73
74
  void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
  			      bool update_bss)
1ea6f9c0d   Johannes Berg   mac80211: handle ...
75
  {
5ad11b50f   Emmanuel Grumbach   mac80211: ensure ...
76
77
  	if (__ieee80211_recalc_txpower(sdata) ||
  	    (update_bss && ieee80211_sdata_running(sdata)))
1ea6f9c0d   Johannes Berg   mac80211: handle ...
78
79
  		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
  }
c771c9d8d   Johannes Berg   mac80211: add int...
80

62a40a155   Johannes Berg   mac80211: fix LED...
81
  static u32 __ieee80211_idle_off(struct ieee80211_local *local)
cc45ae547   Johannes Berg   mac80211: make __...
82
83
84
85
86
87
88
  {
  	if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
  		return 0;
  
  	local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
  	return IEEE80211_CONF_CHANGE_IDLE;
  }
62a40a155   Johannes Berg   mac80211: fix LED...
89
  static u32 __ieee80211_idle_on(struct ieee80211_local *local)
cc45ae547   Johannes Berg   mac80211: make __...
90
91
92
  {
  	if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
  		return 0;
3b24f4c65   Emmanuel Grumbach   mac80211: let flu...
93
  	ieee80211_flush_queues(local, NULL, false);
cc45ae547   Johannes Berg   mac80211: make __...
94
95
96
97
  
  	local->hw.conf.flags |= IEEE80211_CONF_IDLE;
  	return IEEE80211_CONF_CHANGE_IDLE;
  }
62a40a155   Johannes Berg   mac80211: fix LED...
98
99
  static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
  				   bool force_active)
cc45ae547   Johannes Berg   mac80211: make __...
100
  {
1d5e1266c   Johannes Berg   mac80211: simplif...
101
  	bool working, scanning, active;
cc45ae547   Johannes Berg   mac80211: make __...
102
  	unsigned int led_trig_start = 0, led_trig_stop = 0;
cc45ae547   Johannes Berg   mac80211: make __...
103

cc45ae547   Johannes Berg   mac80211: make __...
104
  	lockdep_assert_held(&local->mtx);
62a40a155   Johannes Berg   mac80211: fix LED...
105
106
107
  	active = force_active ||
  		 !list_empty(&local->chanctx_list) ||
  		 local->monitors;
cc45ae547   Johannes Berg   mac80211: make __...
108

1d5e1266c   Johannes Berg   mac80211: simplif...
109
110
  	working = !local->ops->remain_on_channel &&
  		  !list_empty(&local->roc_list);
cc45ae547   Johannes Berg   mac80211: make __...
111

f1e3e0515   Johannes Berg   mac80211: remove ...
112
113
  	scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
  		   test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
cc45ae547   Johannes Berg   mac80211: make __...
114

cc45ae547   Johannes Berg   mac80211: make __...
115
116
117
118
  	if (working || scanning)
  		led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
  	else
  		led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
fd0f979a1   Johannes Berg   mac80211: simplif...
119
  	if (active)
cc45ae547   Johannes Berg   mac80211: make __...
120
121
122
123
124
  		led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
  	else
  		led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
  
  	ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
fd0f979a1   Johannes Berg   mac80211: simplif...
125
  	if (working || scanning || active)
62a40a155   Johannes Berg   mac80211: fix LED...
126
127
128
129
130
131
132
133
134
135
136
137
  		return __ieee80211_idle_off(local);
  	return __ieee80211_idle_on(local);
  }
  
  u32 ieee80211_idle_off(struct ieee80211_local *local)
  {
  	return __ieee80211_recalc_idle(local, true);
  }
  
  void ieee80211_recalc_idle(struct ieee80211_local *local)
  {
  	u32 change = __ieee80211_recalc_idle(local, false);
fd0f979a1   Johannes Berg   mac80211: simplif...
138
139
  	if (change)
  		ieee80211_hw_config(local, change);
cc45ae547   Johannes Berg   mac80211: make __...
140
  }
3899ba90a   John W. Linville   Merge branch 'mas...
141
  static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
31eba5bc5   Felix Fietkau   mac80211: support...
142
  				bool check_dup)
478622e81   Helmut Schaa   mac80211: reject ...
143
  {
ac20976dc   Helmut Schaa   mac80211: Allow s...
144
145
  	struct ieee80211_local *local = sdata->local;
  	struct ieee80211_sub_if_data *iter;
478622e81   Helmut Schaa   mac80211: reject ...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  	u64 new, mask, tmp;
  	u8 *m;
  	int ret = 0;
  
  	if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
  		return 0;
  
  	m = addr;
  	new =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
  		((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
  		((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
  
  	m = local->hw.wiphy->addr_mask;
  	mask =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
  		((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
  		((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
31eba5bc5   Felix Fietkau   mac80211: support...
162
163
  	if (!check_dup)
  		return ret;
478622e81   Helmut Schaa   mac80211: reject ...
164
165
  
  	mutex_lock(&local->iflist_mtx);
ac20976dc   Helmut Schaa   mac80211: Allow s...
166
167
  	list_for_each_entry(iter, &local->interfaces, list) {
  		if (iter == sdata)
478622e81   Helmut Schaa   mac80211: reject ...
168
  			continue;
3899ba90a   John W. Linville   Merge branch 'mas...
169
  		if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
d82121845   Aviya Erenfeld   mac80211: refacto...
170
  		    !(iter->u.mntr.flags & MONITOR_FLAG_ACTIVE))
478622e81   Helmut Schaa   mac80211: reject ...
171
  			continue;
ac20976dc   Helmut Schaa   mac80211: Allow s...
172
  		m = iter->vif.addr;
478622e81   Helmut Schaa   mac80211: reject ...
173
174
175
176
177
178
179
180
181
182
183
184
185
  		tmp =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
  			((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
  			((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
  
  		if ((new & ~mask) != (tmp & ~mask)) {
  			ret = -EINVAL;
  			break;
  		}
  	}
  	mutex_unlock(&local->iflist_mtx);
  
  	return ret;
  }
47846c9b0   Johannes Berg   mac80211: reduce ...
186
187
188
  static int ieee80211_change_mac(struct net_device *dev, void *addr)
  {
  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
fc5f75773   Kalle Valo   mac80211: fix iee...
189
  	struct sockaddr *sa = addr;
31eba5bc5   Felix Fietkau   mac80211: support...
190
  	bool check_dup = true;
47846c9b0   Johannes Berg   mac80211: reduce ...
191
  	int ret;
9607e6b66   Johannes Berg   mac80211: add iee...
192
  	if (ieee80211_sdata_running(sdata))
47846c9b0   Johannes Berg   mac80211: reduce ...
193
  		return -EBUSY;
31eba5bc5   Felix Fietkau   mac80211: support...
194
  	if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
d82121845   Aviya Erenfeld   mac80211: refacto...
195
  	    !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
31eba5bc5   Felix Fietkau   mac80211: support...
196
  		check_dup = false;
3899ba90a   John W. Linville   Merge branch 'mas...
197
  	ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
478622e81   Helmut Schaa   mac80211: reject ...
198
199
  	if (ret)
  		return ret;
fc5f75773   Kalle Valo   mac80211: fix iee...
200
  	ret = eth_mac_addr(dev, sa);
47846c9b0   Johannes Berg   mac80211: reduce ...
201
202
  
  	if (ret == 0)
fc5f75773   Kalle Valo   mac80211: fix iee...
203
  		memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
47846c9b0   Johannes Berg   mac80211: reduce ...
204
205
206
  
  	return ret;
  }
0d143fe1e   Johannes Berg   mac80211: move re...
207
208
209
210
  static inline int identical_mac_addr_allowed(int type1, int type2)
  {
  	return type1 == NL80211_IFTYPE_MONITOR ||
  		type2 == NL80211_IFTYPE_MONITOR ||
f142c6b90   Johannes Berg   mac80211: support...
211
212
  		type1 == NL80211_IFTYPE_P2P_DEVICE ||
  		type2 == NL80211_IFTYPE_P2P_DEVICE ||
0d143fe1e   Johannes Berg   mac80211: move re...
213
214
215
216
217
218
219
220
221
  		(type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) ||
  		(type1 == NL80211_IFTYPE_WDS &&
  			(type2 == NL80211_IFTYPE_WDS ||
  			 type2 == NL80211_IFTYPE_AP)) ||
  		(type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_AP_VLAN) ||
  		(type1 == NL80211_IFTYPE_AP_VLAN &&
  			(type2 == NL80211_IFTYPE_AP ||
  			 type2 == NL80211_IFTYPE_AP_VLAN));
  }
87490f6db   Johannes Berg   mac80211: split o...
222
223
  static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
  					    enum nl80211_iftype iftype)
0d143fe1e   Johannes Berg   mac80211: move re...
224
  {
b4a4bf5d7   Johannes Berg   mac80211: fixups ...
225
  	struct ieee80211_local *local = sdata->local;
87490f6db   Johannes Berg   mac80211: split o...
226
  	struct ieee80211_sub_if_data *nsdata;
b6a550156   Luciano Coelho   cfg80211/mac80211...
227
  	int ret;
0d143fe1e   Johannes Berg   mac80211: move re...
228

87490f6db   Johannes Berg   mac80211: split o...
229
  	ASSERT_RTNL();
0d143fe1e   Johannes Berg   mac80211: move re...
230
231
232
  
  	/* we hold the RTNL here so can safely walk the list */
  	list_for_each_entry(nsdata, &local->interfaces, list) {
371a255e8   Johannes Berg   mac80211: make ie...
233
  		if (nsdata != sdata && ieee80211_sdata_running(nsdata)) {
0d143fe1e   Johannes Berg   mac80211: move re...
234
  			/*
239281f80   Rostislav Lisovy   mac80211: 802.11p...
235
236
237
238
239
240
241
242
243
  			 * Only OCB and monitor mode may coexist
  			 */
  			if ((sdata->vif.type == NL80211_IFTYPE_OCB &&
  			     nsdata->vif.type != NL80211_IFTYPE_MONITOR) ||
  			    (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
  			     nsdata->vif.type == NL80211_IFTYPE_OCB))
  				return -EBUSY;
  
  			/*
0d143fe1e   Johannes Berg   mac80211: move re...
244
245
246
247
248
249
250
251
252
  			 * Allow only a single IBSS interface to be up at any
  			 * time. This is restricted because beacon distribution
  			 * cannot work properly if both are in the same IBSS.
  			 *
  			 * To remove this restriction we'd have to disallow them
  			 * from setting the same SSID on different IBSS interfaces
  			 * belonging to the same hardware. Then, however, we're
  			 * faced with having to adopt two different TSF timers...
  			 */
87490f6db   Johannes Berg   mac80211: split o...
253
  			if (iftype == NL80211_IFTYPE_ADHOC &&
0d143fe1e   Johannes Berg   mac80211: move re...
254
255
  			    nsdata->vif.type == NL80211_IFTYPE_ADHOC)
  				return -EBUSY;
73da7d5ba   Simon Wunderlich   mac80211: add cha...
256
257
258
259
260
261
  			/*
  			 * will not add another interface while any channel
  			 * switch is active.
  			 */
  			if (nsdata->vif.csa_active)
  				return -EBUSY;
0d143fe1e   Johannes Berg   mac80211: move re...
262
263
264
265
266
  
  			/*
  			 * The remaining checks are only performed for interfaces
  			 * with the same MAC address.
  			 */
371a255e8   Johannes Berg   mac80211: make ie...
267
268
  			if (!ether_addr_equal(sdata->vif.addr,
  					      nsdata->vif.addr))
0d143fe1e   Johannes Berg   mac80211: move re...
269
270
271
272
273
  				continue;
  
  			/*
  			 * check whether it may have the same address
  			 */
87490f6db   Johannes Berg   mac80211: split o...
274
  			if (!identical_mac_addr_allowed(iftype,
0d143fe1e   Johannes Berg   mac80211: move re...
275
276
277
278
279
280
  							nsdata->vif.type))
  				return -ENOTUNIQ;
  
  			/*
  			 * can only add VLANs to enabled APs
  			 */
87490f6db   Johannes Berg   mac80211: split o...
281
  			if (iftype == NL80211_IFTYPE_AP_VLAN &&
0d143fe1e   Johannes Berg   mac80211: move re...
282
283
284
285
  			    nsdata->vif.type == NL80211_IFTYPE_AP)
  				sdata->bss = &nsdata->u.ap;
  		}
  	}
b6a550156   Luciano Coelho   cfg80211/mac80211...
286
287
288
289
  	mutex_lock(&local->chanctx_mtx);
  	ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
  	mutex_unlock(&local->chanctx_mtx);
  	return ret;
87490f6db   Johannes Berg   mac80211: split o...
290
  }
a98655387   Johannes Berg   mac80211: fix cha...
291
292
  static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
  				  enum nl80211_iftype iftype)
3a25a8c8b   Johannes Berg   mac80211: add imp...
293
294
295
  {
  	int n_queues = sdata->local->hw.queues;
  	int i;
708d50edb   Ayala Beker   mac80211: add boi...
296
297
  	if (iftype == NL80211_IFTYPE_NAN)
  		return 0;
a98655387   Johannes Berg   mac80211: fix cha...
298
  	if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
0ef24e528   Ilan Peer   mac80211: Do not ...
299
300
301
302
303
304
305
306
  		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
  			if (WARN_ON_ONCE(sdata->vif.hw_queue[i] ==
  					 IEEE80211_INVAL_HW_QUEUE))
  				return -EINVAL;
  			if (WARN_ON_ONCE(sdata->vif.hw_queue[i] >=
  					 n_queues))
  				return -EINVAL;
  		}
3a25a8c8b   Johannes Berg   mac80211: add imp...
307
  	}
a98655387   Johannes Berg   mac80211: fix cha...
308
309
310
  	if ((iftype != NL80211_IFTYPE_AP &&
  	     iftype != NL80211_IFTYPE_P2P_GO &&
  	     iftype != NL80211_IFTYPE_MESH_POINT) ||
30686bf7f   Johannes Berg   mac80211: convert...
311
  	    !ieee80211_hw_check(&sdata->local->hw, QUEUE_CONTROL)) {
3a25a8c8b   Johannes Berg   mac80211: add imp...
312
313
314
315
316
317
318
319
320
321
322
323
  		sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
  		return 0;
  	}
  
  	if (WARN_ON_ONCE(sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE))
  		return -EINVAL;
  
  	if (WARN_ON_ONCE(sdata->vif.cab_queue >= n_queues))
  		return -EINVAL;
  
  	return 0;
  }
4b7afb52c   Felix Fietkau   mac80211: reorgan...
324
  static int ieee80211_open(struct net_device *dev)
6aea26ce5   Felix Fietkau   mac80211: rework ...
325
  {
4b7afb52c   Felix Fietkau   mac80211: reorgan...
326
327
328
329
330
331
332
333
334
335
336
337
  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  	int err;
  
  	/* fail early if user set an invalid address */
  	if (!is_valid_ether_addr(dev->dev_addr))
  		return -EADDRNOTAVAIL;
  
  	err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type);
  	if (err)
  		return err;
  
  	return ieee80211_do_open(&sdata->wdev, true);
6aea26ce5   Felix Fietkau   mac80211: rework ...
338
  }
4b7afb52c   Felix Fietkau   mac80211: reorgan...
339
340
  static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
  			      bool going_down)
6aea26ce5   Felix Fietkau   mac80211: rework ...
341
342
  {
  	struct ieee80211_local *local = sdata->local;
4b7afb52c   Felix Fietkau   mac80211: reorgan...
343
344
345
346
347
348
349
350
  	unsigned long flags;
  	struct sk_buff *skb, *tmp;
  	u32 hw_reconf_flags = 0;
  	int i, flushed;
  	struct ps_data *ps;
  	struct cfg80211_chan_def chandef;
  	bool cancel_scan;
  	struct cfg80211_nan_func *func;
6aea26ce5   Felix Fietkau   mac80211: rework ...
351

4b7afb52c   Felix Fietkau   mac80211: reorgan...
352
  	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
6aea26ce5   Felix Fietkau   mac80211: rework ...
353

4b7afb52c   Felix Fietkau   mac80211: reorgan...
354
355
356
  	cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
  	if (cancel_scan)
  		ieee80211_scan_cancel(local);
6aea26ce5   Felix Fietkau   mac80211: rework ...
357

4b7afb52c   Felix Fietkau   mac80211: reorgan...
358
359
360
361
362
  	/*
  	 * Stop TX on this interface first.
  	 */
  	if (sdata->dev)
  		netif_tx_stop_all_queues(sdata->dev);
6aea26ce5   Felix Fietkau   mac80211: rework ...
363

4b7afb52c   Felix Fietkau   mac80211: reorgan...
364
  	ieee80211_roc_purge(local, sdata);
6aea26ce5   Felix Fietkau   mac80211: rework ...
365

4b7afb52c   Felix Fietkau   mac80211: reorgan...
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_STATION:
  		ieee80211_mgd_stop(sdata);
  		break;
  	case NL80211_IFTYPE_ADHOC:
  		ieee80211_ibss_stop(sdata);
  		break;
  	case NL80211_IFTYPE_MONITOR:
  		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
  			break;
  		list_del_rcu(&sdata->u.mntr.list);
  		break;
  	default:
  		break;
  	}
6aea26ce5   Felix Fietkau   mac80211: rework ...
381

4b7afb52c   Felix Fietkau   mac80211: reorgan...
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
  	/*
  	 * Remove all stations associated with this interface.
  	 *
  	 * This must be done before calling ops->remove_interface()
  	 * because otherwise we can later invoke ops->sta_notify()
  	 * whenever the STAs are removed, and that invalidates driver
  	 * assumptions about always getting a vif pointer that is valid
  	 * (because if we remove a STA after ops->remove_interface()
  	 * the driver will have removed the vif info already!)
  	 *
  	 * In WDS mode a station must exist here and be flushed, for
  	 * AP_VLANs stations may exist since there's nothing else that
  	 * would have removed them, but in other modes there shouldn't
  	 * be any stations.
  	 */
  	flushed = sta_info_flush(sdata);
  	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  		     ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
  		      (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)));
6aea26ce5   Felix Fietkau   mac80211: rework ...
401

4b7afb52c   Felix Fietkau   mac80211: reorgan...
402
403
404
  	/* don't count this interface for allmulti while it is down */
  	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
  		atomic_dec(&local->iff_allmultis);
6aea26ce5   Felix Fietkau   mac80211: rework ...
405

4b7afb52c   Felix Fietkau   mac80211: reorgan...
406
407
408
409
410
  	if (sdata->vif.type == NL80211_IFTYPE_AP) {
  		local->fif_pspoll--;
  		local->fif_probe_req--;
  	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
  		local->fif_probe_req--;
6aea26ce5   Felix Fietkau   mac80211: rework ...
411
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
412
413
414
415
416
417
418
  	if (sdata->dev) {
  		netif_addr_lock_bh(sdata->dev);
  		spin_lock_bh(&local->filter_lock);
  		__hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
  				 sdata->dev->addr_len);
  		spin_unlock_bh(&local->filter_lock);
  		netif_addr_unlock_bh(sdata->dev);
6aea26ce5   Felix Fietkau   mac80211: rework ...
419
  	}
6aea26ce5   Felix Fietkau   mac80211: rework ...
420

4b7afb52c   Felix Fietkau   mac80211: reorgan...
421
422
  	del_timer_sync(&local->dynamic_ps_timer);
  	cancel_work_sync(&local->dynamic_ps_enable_work);
6aea26ce5   Felix Fietkau   mac80211: rework ...
423

4b7afb52c   Felix Fietkau   mac80211: reorgan...
424
425
426
427
428
429
430
431
432
433
  	cancel_work_sync(&sdata->recalc_smps);
  	sdata_lock(sdata);
  	mutex_lock(&local->mtx);
  	sdata->vif.csa_active = false;
  	if (sdata->vif.type == NL80211_IFTYPE_STATION)
  		sdata->u.mgd.csa_waiting_bcn = false;
  	if (sdata->csa_block_tx) {
  		ieee80211_wake_vif_queues(local, sdata,
  					  IEEE80211_QUEUE_STOP_REASON_CSA);
  		sdata->csa_block_tx = false;
6aea26ce5   Felix Fietkau   mac80211: rework ...
434
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
435
436
  	mutex_unlock(&local->mtx);
  	sdata_unlock(sdata);
6aea26ce5   Felix Fietkau   mac80211: rework ...
437

4b7afb52c   Felix Fietkau   mac80211: reorgan...
438
  	cancel_work_sync(&sdata->csa_finalize_work);
85416a4fa   Christian Lamparter   mac80211: fix rx ...
439

4b7afb52c   Felix Fietkau   mac80211: reorgan...
440
  	cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
85416a4fa   Christian Lamparter   mac80211: fix rx ...
441

4b7afb52c   Felix Fietkau   mac80211: reorgan...
442
443
444
445
446
447
448
449
450
451
  	if (sdata->wdev.cac_started) {
  		chandef = sdata->vif.bss_conf.chandef;
  		WARN_ON(local->suspended);
  		mutex_lock(&local->mtx);
  		ieee80211_vif_release_channel(sdata);
  		mutex_unlock(&local->mtx);
  		cfg80211_cac_event(sdata->dev, &chandef,
  				   NL80211_RADAR_CAC_ABORTED,
  				   GFP_KERNEL);
  	}
85416a4fa   Christian Lamparter   mac80211: fix rx ...
452

4b7afb52c   Felix Fietkau   mac80211: reorgan...
453
454
455
  	/* APs need special treatment */
  	if (sdata->vif.type == NL80211_IFTYPE_AP) {
  		struct ieee80211_sub_if_data *vlan, *tmpsdata;
85416a4fa   Christian Lamparter   mac80211: fix rx ...
456

4b7afb52c   Felix Fietkau   mac80211: reorgan...
457
458
459
460
461
462
463
464
  		/* down all dependent devices, that is VLANs */
  		list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
  					 u.vlan.list)
  			dev_close(vlan->dev);
  		WARN_ON(!list_empty(&sdata->u.ap.vlans));
  	} else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
  		/* remove all packets in parent bc_buf pointing to this dev */
  		ps = &sdata->bss->ps;
3a25a8c8b   Johannes Berg   mac80211: add imp...
465

4b7afb52c   Felix Fietkau   mac80211: reorgan...
466
467
468
469
470
471
472
473
474
  		spin_lock_irqsave(&ps->bc_buf.lock, flags);
  		skb_queue_walk_safe(&ps->bc_buf, skb, tmp) {
  			if (skb->dev == sdata->dev) {
  				__skb_unlink(skb, &ps->bc_buf);
  				local->total_ps_buffered--;
  				ieee80211_free_txskb(&local->hw, skb);
  			}
  		}
  		spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
3a25a8c8b   Johannes Berg   mac80211: add imp...
475
  	}
3a25a8c8b   Johannes Berg   mac80211: add imp...
476

4b7afb52c   Felix Fietkau   mac80211: reorgan...
477
478
  	if (going_down)
  		local->open_count--;
4b6f1dd6a   Johannes Berg   mac80211: add exp...
479

4b7afb52c   Felix Fietkau   mac80211: reorgan...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_AP_VLAN:
  		mutex_lock(&local->mtx);
  		list_del(&sdata->u.vlan.list);
  		mutex_unlock(&local->mtx);
  		RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL);
  		/* see comment in the default case below */
  		ieee80211_free_keys(sdata, true);
  		/* no need to tell driver */
  		break;
  	case NL80211_IFTYPE_MONITOR:
  		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
  			local->cooked_mntrs--;
  			break;
  		}
685fb72b6   Johannes Berg   mac80211: iterate...
495

4b7afb52c   Felix Fietkau   mac80211: reorgan...
496
497
498
499
500
  		local->monitors--;
  		if (local->monitors == 0) {
  			local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
  			hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
  		}
4b6f1dd6a   Johannes Berg   mac80211: add exp...
501

4b7afb52c   Felix Fietkau   mac80211: reorgan...
502
503
504
505
506
  		ieee80211_adjust_monitor_flags(sdata, -1);
  		break;
  	case NL80211_IFTYPE_NAN:
  		/* clean all the functions */
  		spin_lock_bh(&sdata->u.nan.func_lock);
4b6f1dd6a   Johannes Berg   mac80211: add exp...
507

4b7afb52c   Felix Fietkau   mac80211: reorgan...
508
509
510
511
512
  		idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) {
  			idr_remove(&sdata->u.nan.function_inst_ids, i);
  			cfg80211_free_nan_func(func);
  		}
  		idr_destroy(&sdata->u.nan.function_inst_ids);
3a25a8c8b   Johannes Berg   mac80211: add imp...
513

4b7afb52c   Felix Fietkau   mac80211: reorgan...
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
  		spin_unlock_bh(&sdata->u.nan.func_lock);
  		break;
  	case NL80211_IFTYPE_P2P_DEVICE:
  		/* relies on synchronize_rcu() below */
  		RCU_INIT_POINTER(local->p2p_sdata, NULL);
  		fallthrough;
  	default:
  		cancel_work_sync(&sdata->work);
  		/*
  		 * When we get here, the interface is marked down.
  		 * Free the remaining keys, if there are any
  		 * (which can happen in AP mode if userspace sets
  		 * keys before the interface is operating, and maybe
  		 * also in WDS mode)
  		 *
  		 * Force the key freeing to always synchronize_net()
  		 * to wait for the RX path in case it is using this
  		 * interface enqueuing frames at this very time on
  		 * another CPU.
  		 */
  		ieee80211_free_keys(sdata, true);
  		skb_queue_purge(&sdata->skb_queue);
4b6f1dd6a   Johannes Berg   mac80211: add exp...
536
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
537
538
539
540
541
542
543
544
545
  	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
  	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
  		skb_queue_walk_safe(&local->pending[i], skb, tmp) {
  			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  			if (info->control.vif == &sdata->vif) {
  				__skb_unlink(skb, &local->pending[i]);
  				ieee80211_free_txskb(&local->hw, skb);
  			}
  		}
3a25a8c8b   Johannes Berg   mac80211: add imp...
546
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
547
  	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
3a25a8c8b   Johannes Berg   mac80211: add imp...
548

4b7afb52c   Felix Fietkau   mac80211: reorgan...
549
550
  	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  		ieee80211_txq_remove_vlan(local, sdata);
fab57a6cc   Johannes Berg   mac80211: fix vir...
551

4b7afb52c   Felix Fietkau   mac80211: reorgan...
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
  	sdata->bss = NULL;
  
  	if (local->open_count == 0)
  		ieee80211_clear_tx_pending(local);
  
  	sdata->vif.bss_conf.beacon_int = 0;
  
  	/*
  	 * If the interface goes down while suspended, presumably because
  	 * the device was unplugged and that happens before our resume,
  	 * then the driver is already unconfigured and the remainder of
  	 * this function isn't needed.
  	 * XXX: what about WoWLAN? If the device has software state, e.g.
  	 *	memory allocated, it might expect teardown commands from
  	 *	mac80211 here?
  	 */
  	if (local->suspended) {
  		WARN_ON(local->wowlan);
  		WARN_ON(rtnl_dereference(local->monitor_sdata));
  		return;
55de908ab   Johannes Berg   mac80211: use cha...
572
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
573
574
575
576
577
578
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_AP_VLAN:
  		break;
  	case NL80211_IFTYPE_MONITOR:
  		if (local->monitors == 0)
  			ieee80211_del_virtual_monitor(local);
42bd20d99   Aviya Erenfeld   mac80211: add sup...
579

4b7afb52c   Felix Fietkau   mac80211: reorgan...
580
581
582
  		mutex_lock(&local->mtx);
  		ieee80211_recalc_idle(local);
  		mutex_unlock(&local->mtx);
4b6f1dd6a   Johannes Berg   mac80211: add exp...
583

4b7afb52c   Felix Fietkau   mac80211: reorgan...
584
585
  		if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
  			break;
4b6f1dd6a   Johannes Berg   mac80211: add exp...
586

4b7afb52c   Felix Fietkau   mac80211: reorgan...
587
588
589
590
591
  		fallthrough;
  	default:
  		if (going_down)
  			drv_remove_interface(local, sdata);
  	}
4b6f1dd6a   Johannes Berg   mac80211: add exp...
592

4b7afb52c   Felix Fietkau   mac80211: reorgan...
593
  	ieee80211_recalc_ps(local);
8b305780e   Johannes Berg   mac80211: fix vir...
594

4b7afb52c   Felix Fietkau   mac80211: reorgan...
595
596
  	if (cancel_scan)
  		flush_delayed_work(&local->scan_work);
4b6f1dd6a   Johannes Berg   mac80211: add exp...
597

4b7afb52c   Felix Fietkau   mac80211: reorgan...
598
599
600
601
  	if (local->open_count == 0) {
  		ieee80211_stop_device(local);
  
  		/* no reconfiguring after stop! */
8b305780e   Johannes Berg   mac80211: fix vir...
602
603
  		return;
  	}
4b6f1dd6a   Johannes Berg   mac80211: add exp...
604

4b7afb52c   Felix Fietkau   mac80211: reorgan...
605
606
607
  	/* do after stop to avoid reconfiguring when we stop anyway */
  	ieee80211_configure_filter(local);
  	ieee80211_hw_config(local, hw_reconf_flags);
8b305780e   Johannes Berg   mac80211: fix vir...
608

4b7afb52c   Felix Fietkau   mac80211: reorgan...
609
610
611
  	if (local->monitors == local->open_count)
  		ieee80211_add_virtual_monitor(local);
  }
4b6f1dd6a   Johannes Berg   mac80211: add exp...
612

4b7afb52c   Felix Fietkau   mac80211: reorgan...
613
614
615
  static int ieee80211_stop(struct net_device *dev)
  {
  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
55de908ab   Johannes Berg   mac80211: use cha...
616

4b7afb52c   Felix Fietkau   mac80211: reorgan...
617
  	ieee80211_do_stop(sdata, true);
4b6f1dd6a   Johannes Berg   mac80211: add exp...
618

4b7afb52c   Felix Fietkau   mac80211: reorgan...
619
  	return 0;
4b6f1dd6a   Johannes Berg   mac80211: add exp...
620
  }
4b7afb52c   Felix Fietkau   mac80211: reorgan...
621
  static void ieee80211_set_multicast_list(struct net_device *dev)
87490f6db   Johannes Berg   mac80211: split o...
622
  {
4b7afb52c   Felix Fietkau   mac80211: reorgan...
623
  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
87490f6db   Johannes Berg   mac80211: split o...
624
  	struct ieee80211_local *local = sdata->local;
4b7afb52c   Felix Fietkau   mac80211: reorgan...
625
  	int allmulti, sdata_allmulti;
87490f6db   Johannes Berg   mac80211: split o...
626

4b7afb52c   Felix Fietkau   mac80211: reorgan...
627
628
  	allmulti = !!(dev->flags & IFF_ALLMULTI);
  	sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
665c93a93   Johannes Berg   mac80211: add sup...
629

4b7afb52c   Felix Fietkau   mac80211: reorgan...
630
631
632
633
634
635
636
  	if (allmulti != sdata_allmulti) {
  		if (dev->flags & IFF_ALLMULTI)
  			atomic_inc(&local->iff_allmultis);
  		else
  			atomic_dec(&local->iff_allmultis);
  		sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
  	}
665c93a93   Johannes Berg   mac80211: add sup...
637

4b7afb52c   Felix Fietkau   mac80211: reorgan...
638
639
640
641
642
  	spin_lock_bh(&local->filter_lock);
  	__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
  	spin_unlock_bh(&local->filter_lock);
  	ieee80211_queue_work(&local->hw, &local->reconfig_filter);
  }
665c93a93   Johannes Berg   mac80211: add sup...
643

4b7afb52c   Felix Fietkau   mac80211: reorgan...
644
645
646
647
648
649
650
  /*
   * Called when the netdev is removed or, by the code below, before
   * the interface type changes.
   */
  static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
  {
  	int i;
f9dca80b9   Michal Kazior   mac80211: fix AP_...
651

4b7afb52c   Felix Fietkau   mac80211: reorgan...
652
653
  	/* free extra data */
  	ieee80211_free_keys(sdata, false);
f9dca80b9   Michal Kazior   mac80211: fix AP_...
654

4b7afb52c   Felix Fietkau   mac80211: reorgan...
655
  	ieee80211_debugfs_remove_netdev(sdata);
0d143fe1e   Johannes Berg   mac80211: move re...
656

4b7afb52c   Felix Fietkau   mac80211: reorgan...
657
658
659
  	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
  		__skb_queue_purge(&sdata->fragments[i].skb_list);
  	sdata->fragment_next = 0;
0d143fe1e   Johannes Berg   mac80211: move re...
660

4b7afb52c   Felix Fietkau   mac80211: reorgan...
661
662
663
  	if (ieee80211_vif_is_mesh(&sdata->vif))
  		ieee80211_mesh_teardown_sdata(sdata);
  }
0d143fe1e   Johannes Berg   mac80211: move re...
664

4b7afb52c   Felix Fietkau   mac80211: reorgan...
665
666
667
668
  static void ieee80211_uninit(struct net_device *dev)
  {
  	ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
  }
075e08477   Johannes Berg   Revert "mac80211:...
669

4b7afb52c   Felix Fietkau   mac80211: reorgan...
670
671
672
673
674
675
  static u16 ieee80211_netdev_select_queue(struct net_device *dev,
  					 struct sk_buff *skb,
  					 struct net_device *sb_dev)
  {
  	return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
  }
0d143fe1e   Johannes Berg   mac80211: move re...
676

4b7afb52c   Felix Fietkau   mac80211: reorgan...
677
678
679
  static void
  ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
  {
6401297e7   Heiner Kallweit   mac80211: use new...
680
  	dev_fetch_sw_netstats(stats, dev->tstats);
4b7afb52c   Felix Fietkau   mac80211: reorgan...
681
  }
e3b90ca28   Igor Perminov   mac80211: FIF_PSP...
682

4b7afb52c   Felix Fietkau   mac80211: reorgan...
683
684
685
686
687
688
689
690
691
692
  static const struct net_device_ops ieee80211_dataif_ops = {
  	.ndo_open		= ieee80211_open,
  	.ndo_stop		= ieee80211_stop,
  	.ndo_uninit		= ieee80211_uninit,
  	.ndo_start_xmit		= ieee80211_subif_start_xmit,
  	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
  	.ndo_set_mac_address 	= ieee80211_change_mac,
  	.ndo_select_queue	= ieee80211_netdev_select_queue,
  	.ndo_get_stats64	= ieee80211_get_stats64,
  };
e3b90ca28   Igor Perminov   mac80211: FIF_PSP...
693

4b7afb52c   Felix Fietkau   mac80211: reorgan...
694
695
696
697
698
699
700
701
702
  static u16 ieee80211_monitor_select_queue(struct net_device *dev,
  					  struct sk_buff *skb,
  					  struct net_device *sb_dev)
  {
  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  	struct ieee80211_local *local = sdata->local;
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  	struct ieee80211_hdr *hdr;
  	int len_rthdr;
90e8f58df   Johannes Berg   mac80211: fix drv...
703

4b7afb52c   Felix Fietkau   mac80211: reorgan...
704
705
  	if (local->hw.queues < IEEE80211_NUM_ACS)
  		return 0;
0d143fe1e   Johannes Berg   mac80211: move re...
706

4b7afb52c   Felix Fietkau   mac80211: reorgan...
707
708
  	/* reset flags and info before parsing radiotap header */
  	memset(info, 0, sizeof(*info));
590345910   Eliad Peller   mac80211: call se...
709

4b7afb52c   Felix Fietkau   mac80211: reorgan...
710
711
  	if (!ieee80211_parse_tx_radiotap(skb, dev))
  		return 0; /* doesn't matter, frame will be dropped */
0d143fe1e   Johannes Berg   mac80211: move re...
712

4b7afb52c   Felix Fietkau   mac80211: reorgan...
713
714
715
716
717
  	len_rthdr = ieee80211_get_radiotap_len(skb->data);
  	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
  	if (skb->len < len_rthdr + 2 ||
  	    skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
  		return 0; /* doesn't matter, frame will be dropped */
2d2080c3c   Johannes Berg   mac80211: set run...
718

4b7afb52c   Felix Fietkau   mac80211: reorgan...
719
720
  	return ieee80211_select_queue_80211(sdata, skb, hdr);
  }
0d143fe1e   Johannes Berg   mac80211: move re...
721

4b7afb52c   Felix Fietkau   mac80211: reorgan...
722
723
724
725
726
727
728
729
730
731
  static const struct net_device_ops ieee80211_monitorif_ops = {
  	.ndo_open		= ieee80211_open,
  	.ndo_stop		= ieee80211_stop,
  	.ndo_uninit		= ieee80211_uninit,
  	.ndo_start_xmit		= ieee80211_monitor_start_xmit,
  	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
  	.ndo_set_mac_address 	= ieee80211_change_mac,
  	.ndo_select_queue	= ieee80211_monitor_select_queue,
  	.ndo_get_stats64	= ieee80211_get_stats64,
  };
0d143fe1e   Johannes Berg   mac80211: move re...
732

4b7afb52c   Felix Fietkau   mac80211: reorgan...
733
734
735
736
737
738
739
740
741
742
  static const struct net_device_ops ieee80211_dataif_8023_ops = {
  	.ndo_open		= ieee80211_open,
  	.ndo_stop		= ieee80211_stop,
  	.ndo_uninit		= ieee80211_uninit,
  	.ndo_start_xmit		= ieee80211_subif_start_xmit_8023,
  	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
  	.ndo_set_mac_address	= ieee80211_change_mac,
  	.ndo_select_queue	= ieee80211_netdev_select_queue,
  	.ndo_get_stats64	= ieee80211_get_stats64,
  };
1be7fe8de   Bill Jordan   mac80211: fix for...
743

4b7afb52c   Felix Fietkau   mac80211: reorgan...
744
745
746
747
748
749
750
  static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
  {
  	switch (iftype) {
  	/* P2P GO and client are mapped to AP/STATION types */
  	case NL80211_IFTYPE_AP:
  	case NL80211_IFTYPE_STATION:
  		return true;
f64331d58   Johannes Berg   mac80211: keep a ...
751
  	default:
4b7afb52c   Felix Fietkau   mac80211: reorgan...
752
  		return false;
0d143fe1e   Johannes Berg   mac80211: move re...
753
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
754
  }
0d143fe1e   Johannes Berg   mac80211: move re...
755

4b7afb52c   Felix Fietkau   mac80211: reorgan...
756
757
758
759
  static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdata)
  {
  	struct ieee80211_local *local = sdata->local;
  	u32 flags;
965bedadc   Johannes Berg   mac80211: improve...
760

4b7afb52c   Felix Fietkau   mac80211: reorgan...
761
  	flags = sdata->vif.offload_flags;
2b730daac   Johannes Berg   mac80211: don't s...
762

4b7afb52c   Felix Fietkau   mac80211: reorgan...
763
764
765
  	if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
  	    ieee80211_iftype_supports_encap_offload(sdata->vif.type)) {
  		flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;
2b730daac   Johannes Berg   mac80211: don't s...
766

4b7afb52c   Felix Fietkau   mac80211: reorgan...
767
768
769
  		if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
  		    local->hw.wiphy->frag_threshold != (u32)-1)
  			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
2b730daac   Johannes Berg   mac80211: don't s...
770

4b7afb52c   Felix Fietkau   mac80211: reorgan...
771
772
773
774
  		if (local->monitors)
  			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
  	} else {
  		flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
2b730daac   Johannes Berg   mac80211: don't s...
775
  	}
0d143fe1e   Johannes Berg   mac80211: move re...
776

4b7afb52c   Felix Fietkau   mac80211: reorgan...
777
778
779
780
781
  	if (sdata->vif.offload_flags == flags)
  		return false;
  
  	sdata->vif.offload_flags = flags;
  	return true;
0d143fe1e   Johannes Berg   mac80211: move re...
782
  }
4b7afb52c   Felix Fietkau   mac80211: reorgan...
783
  static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata)
0d143fe1e   Johannes Berg   mac80211: move re...
784
  {
4b7afb52c   Felix Fietkau   mac80211: reorgan...
785
786
787
  	struct ieee80211_local *local = sdata->local;
  	struct ieee80211_sub_if_data *bss = sdata;
  	bool enabled;
34d4bc4d4   Johannes Berg   mac80211: support...
788

4b7afb52c   Felix Fietkau   mac80211: reorgan...
789
790
791
  	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
  		if (!sdata->bss)
  			return;
34d4bc4d4   Johannes Berg   mac80211: support...
792

4b7afb52c   Felix Fietkau   mac80211: reorgan...
793
794
  		bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
  	}
34d4bc4d4   Johannes Berg   mac80211: support...
795

4b7afb52c   Felix Fietkau   mac80211: reorgan...
796
797
798
  	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
  	    !ieee80211_iftype_supports_encap_offload(bss->vif.type))
  		return;
34d4bc4d4   Johannes Berg   mac80211: support...
799

4b7afb52c   Felix Fietkau   mac80211: reorgan...
800
801
802
803
  	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
  	if (sdata->wdev.use_4addr &&
  	    !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR))
  		enabled = false;
0d143fe1e   Johannes Berg   mac80211: move re...
804

4b7afb52c   Felix Fietkau   mac80211: reorgan...
805
806
807
  	sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops :
  					   &ieee80211_dataif_ops;
  }
c29acf201   Rajkumar Manoharan   mac80211: abort s...
808

4b7afb52c   Felix Fietkau   mac80211: reorgan...
809
810
811
812
  static void ieee80211_recalc_sdata_offload(struct ieee80211_sub_if_data *sdata)
  {
  	struct ieee80211_local *local = sdata->local;
  	struct ieee80211_sub_if_data *vsdata;
352ffad64   Brian Cavagnolo   mac80211: unset S...
813

4b7afb52c   Felix Fietkau   mac80211: reorgan...
814
815
816
817
  	if (ieee80211_set_sdata_offload_flags(sdata)) {
  		drv_update_vif_offload(local, sdata);
  		ieee80211_set_vif_encap_ops(sdata);
  	}
0d143fe1e   Johannes Berg   mac80211: move re...
818

4b7afb52c   Felix Fietkau   mac80211: reorgan...
819
820
821
822
  	list_for_each_entry(vsdata, &local->interfaces, list) {
  		if (vsdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
  		    vsdata->bss != &sdata->u.ap)
  			continue;
af6b63741   Johannes Berg   mac80211: general...
823

4b7afb52c   Felix Fietkau   mac80211: reorgan...
824
  		ieee80211_set_vif_encap_ops(vsdata);
8ffcc704c   Emmanuel Grumbach   mac80211: avoid d...
825
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
826
  }
cd7760e62   Simon Wunderlich   mac80211: add sup...
827

4b7afb52c   Felix Fietkau   mac80211: reorgan...
828
829
830
  void ieee80211_recalc_offload(struct ieee80211_local *local)
  {
  	struct ieee80211_sub_if_data *sdata;
0d143fe1e   Johannes Berg   mac80211: move re...
831

4b7afb52c   Felix Fietkau   mac80211: reorgan...
832
833
  	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD))
  		return;
0d143fe1e   Johannes Berg   mac80211: move re...
834

4b7afb52c   Felix Fietkau   mac80211: reorgan...
835
  	mutex_lock(&local->iflist_mtx);
e3b90ca28   Igor Perminov   mac80211: FIF_PSP...
836

4b7afb52c   Felix Fietkau   mac80211: reorgan...
837
838
839
840
841
  	list_for_each_entry(sdata, &local->interfaces, list) {
  		if (!ieee80211_sdata_running(sdata))
  			continue;
  
  		ieee80211_recalc_sdata_offload(sdata);
f142c6b90   Johannes Berg   mac80211: support...
842
  	}
3ac64beec   Johannes Berg   mac80211: allow c...
843

4b7afb52c   Felix Fietkau   mac80211: reorgan...
844
845
  	mutex_unlock(&local->iflist_mtx);
  }
0d143fe1e   Johannes Berg   mac80211: move re...
846

4b7afb52c   Felix Fietkau   mac80211: reorgan...
847
848
849
850
851
  void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
  				    const int offset)
  {
  	struct ieee80211_local *local = sdata->local;
  	u32 flags = sdata->u.mntr.flags;
59af6928d   Michal Kazior   mac80211: fix CSA...
852

4b7afb52c   Felix Fietkau   mac80211: reorgan...
853
854
855
856
  #define ADJUST(_f, _s)	do {					\
  	if (flags & MONITOR_FLAG_##_f)				\
  		local->fif_##_s += offset;			\
  	} while (0)
04ecd2578   Johannes Berg   mac80211: track n...
857

4b7afb52c   Felix Fietkau   mac80211: reorgan...
858
859
860
861
862
  	ADJUST(FCSFAIL, fcsfail);
  	ADJUST(PLCPFAIL, plcpfail);
  	ADJUST(CONTROL, control);
  	ADJUST(CONTROL, pspoll);
  	ADJUST(OTHER_BSS, other_bss);
164eb02d0   Simon Wunderlich   mac80211: add rad...
863

4b7afb52c   Felix Fietkau   mac80211: reorgan...
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
  #undef ADJUST
  }
  
  static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
  {
  	struct ieee80211_local *local = sdata->local;
  	int i;
  
  	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
  		if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
  			sdata->vif.hw_queue[i] = IEEE80211_INVAL_HW_QUEUE;
  		else if (local->hw.queues >= IEEE80211_NUM_ACS)
  			sdata->vif.hw_queue[i] = i;
  		else
  			sdata->vif.hw_queue[i] = 0;
164eb02d0   Simon Wunderlich   mac80211: add rad...
879
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
880
881
  	sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
  }
164eb02d0   Simon Wunderlich   mac80211: add rad...
882

4b7afb52c   Felix Fietkau   mac80211: reorgan...
883
884
885
886
  int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
  {
  	struct ieee80211_sub_if_data *sdata;
  	int ret;
0d143fe1e   Johannes Berg   mac80211: move re...
887

4b7afb52c   Felix Fietkau   mac80211: reorgan...
888
889
  	if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
  		return 0;
397a7a24e   Michael Braun   mac80211: free ps...
890

4b7afb52c   Felix Fietkau   mac80211: reorgan...
891
  	ASSERT_RTNL();
0d143fe1e   Johannes Berg   mac80211: move re...
892

4b7afb52c   Felix Fietkau   mac80211: reorgan...
893
894
  	if (local->monitor_sdata)
  		return 0;
0d143fe1e   Johannes Berg   mac80211: move re...
895

4b7afb52c   Felix Fietkau   mac80211: reorgan...
896
897
898
  	sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
  	if (!sdata)
  		return -ENOMEM;
0d143fe1e   Johannes Berg   mac80211: move re...
899

4b7afb52c   Felix Fietkau   mac80211: reorgan...
900
901
902
903
904
905
  	/* set up data */
  	sdata->local = local;
  	sdata->vif.type = NL80211_IFTYPE_MONITOR;
  	snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
  		 wiphy_name(local->hw.wiphy));
  	sdata->wdev.iftype = NL80211_IFTYPE_MONITOR;
0d143fe1e   Johannes Berg   mac80211: move re...
906

4b7afb52c   Felix Fietkau   mac80211: reorgan...
907
  	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
167e33f4f   Ayala Beker   mac80211: Impleme...
908

4b7afb52c   Felix Fietkau   mac80211: reorgan...
909
  	ieee80211_set_default_queues(sdata);
167e33f4f   Ayala Beker   mac80211: Impleme...
910

4b7afb52c   Felix Fietkau   mac80211: reorgan...
911
912
913
914
915
916
  	ret = drv_add_interface(local, sdata);
  	if (WARN_ON(ret)) {
  		/* ok .. stupid driver, it asked for this! */
  		kfree(sdata);
  		return ret;
  	}
bdeca45a0   Borwankar, Antara   mac80211: set SDA...
917
  	set_bit(SDATA_STATE_RUNNING, &sdata->state);
4b7afb52c   Felix Fietkau   mac80211: reorgan...
918
919
920
921
  	ret = ieee80211_check_queues(sdata, NL80211_IFTYPE_MONITOR);
  	if (ret) {
  		kfree(sdata);
  		return ret;
0d143fe1e   Johannes Berg   mac80211: move re...
922
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
  	mutex_lock(&local->iflist_mtx);
  	rcu_assign_pointer(local->monitor_sdata, sdata);
  	mutex_unlock(&local->iflist_mtx);
  
  	mutex_lock(&local->mtx);
  	ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
  					IEEE80211_CHANCTX_EXCLUSIVE);
  	mutex_unlock(&local->mtx);
  	if (ret) {
  		mutex_lock(&local->iflist_mtx);
  		RCU_INIT_POINTER(local->monitor_sdata, NULL);
  		mutex_unlock(&local->iflist_mtx);
  		synchronize_net();
  		drv_remove_interface(local, sdata);
  		kfree(sdata);
  		return ret;
5061b0c2b   Johannes Berg   mac80211: coopera...
939
  	}
075e08477   Johannes Berg   Revert "mac80211:...
940

4b7afb52c   Felix Fietkau   mac80211: reorgan...
941
942
  	skb_queue_head_init(&sdata->skb_queue);
  	INIT_WORK(&sdata->work, ieee80211_iface_work);
531682159   Johannes Berg   mac80211: fix VLA...
943

4b7afb52c   Felix Fietkau   mac80211: reorgan...
944
945
  	return 0;
  }
ba8c3d6f1   Felix Fietkau   mac80211: add an ...
946

4b7afb52c   Felix Fietkau   mac80211: reorgan...
947
948
949
  void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
  {
  	struct ieee80211_sub_if_data *sdata;
b2c0958b2   Johannes Berg   mac80211: fix do_...
950

4b7afb52c   Felix Fietkau   mac80211: reorgan...
951
952
  	if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
  		return;
5c21e8100   Ben Greear   mac80211: Clear b...
953

4b7afb52c   Felix Fietkau   mac80211: reorgan...
954
955
956
957
958
959
960
961
  	ASSERT_RTNL();
  
  	mutex_lock(&local->iflist_mtx);
  
  	sdata = rcu_dereference_protected(local->monitor_sdata,
  					  lockdep_is_held(&local->iflist_mtx));
  	if (!sdata) {
  		mutex_unlock(&local->iflist_mtx);
b2c0958b2   Johannes Berg   mac80211: fix do_...
962
963
  		return;
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
  	RCU_INIT_POINTER(local->monitor_sdata, NULL);
  	mutex_unlock(&local->iflist_mtx);
  
  	synchronize_net();
  
  	mutex_lock(&local->mtx);
  	ieee80211_vif_release_channel(sdata);
  	mutex_unlock(&local->mtx);
  
  	drv_remove_interface(local, sdata);
  
  	kfree(sdata);
  }
  
  /*
   * NOTE: Be very careful when changing this function, it must NOT return
   * an error on interface type changes that have been pre-checked, so most
   * checks should be in ieee80211_check_concurrent_iface.
   */
  int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
  {
  	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
  	struct net_device *dev = wdev->netdev;
  	struct ieee80211_local *local = sdata->local;
  	struct sta_info *sta;
  	u32 changed = 0;
  	int res;
  	u32 hw_reconf_flags = 0;
b2c0958b2   Johannes Berg   mac80211: fix do_...
992
  	switch (sdata->vif.type) {
4b7afb52c   Felix Fietkau   mac80211: reorgan...
993
994
995
  	case NL80211_IFTYPE_WDS:
  		if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
  			return -ENOLINK;
b2c0958b2   Johannes Berg   mac80211: fix do_...
996
  		break;
4b7afb52c   Felix Fietkau   mac80211: reorgan...
997
998
999
1000
1001
  	case NL80211_IFTYPE_AP_VLAN: {
  		struct ieee80211_sub_if_data *master;
  
  		if (!sdata->bss)
  			return -ENOLINK;
b2c0958b2   Johannes Berg   mac80211: fix do_...
1002
1003
  
  		mutex_lock(&local->mtx);
4b7afb52c   Felix Fietkau   mac80211: reorgan...
1004
  		list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
b2c0958b2   Johannes Berg   mac80211: fix do_...
1005
  		mutex_unlock(&local->mtx);
31eba5bc5   Felix Fietkau   mac80211: support...
1006

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
  		master = container_of(sdata->bss,
  				      struct ieee80211_sub_if_data, u.ap);
  		sdata->control_port_protocol =
  			master->control_port_protocol;
  		sdata->control_port_no_encrypt =
  			master->control_port_no_encrypt;
  		sdata->control_port_over_nl80211 =
  			master->control_port_over_nl80211;
  		sdata->control_port_no_preauth =
  			master->control_port_no_preauth;
  		sdata->vif.cab_queue = master->vif.cab_queue;
  		memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
  		       sizeof(sdata->vif.hw_queue));
  		sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;
b2c0958b2   Johannes Berg   mac80211: fix do_...
1021

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1022
1023
1024
1025
  		mutex_lock(&local->key_mtx);
  		sdata->crypto_tx_tailroom_needed_cnt +=
  			master->crypto_tx_tailroom_needed_cnt;
  		mutex_unlock(&local->key_mtx);
b2c0958b2   Johannes Berg   mac80211: fix do_...
1026

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
  		break;
  		}
  	case NL80211_IFTYPE_AP:
  		sdata->bss = &sdata->u.ap;
  		break;
  	case NL80211_IFTYPE_MESH_POINT:
  	case NL80211_IFTYPE_STATION:
  	case NL80211_IFTYPE_MONITOR:
  	case NL80211_IFTYPE_ADHOC:
  	case NL80211_IFTYPE_P2P_DEVICE:
  	case NL80211_IFTYPE_OCB:
  	case NL80211_IFTYPE_NAN:
  		/* no special treatment */
  		break;
  	case NL80211_IFTYPE_UNSPECIFIED:
  	case NUM_NL80211_IFTYPES:
  	case NL80211_IFTYPE_P2P_CLIENT:
  	case NL80211_IFTYPE_P2P_GO:
  		/* cannot happen */
  		WARN_ON(1);
  		break;
  	}
46238845b   Johannes Berg   mac80211: properl...
1049

b2c0958b2   Johannes Berg   mac80211: fix do_...
1050
  	if (local->open_count == 0) {
4b7afb52c   Felix Fietkau   mac80211: reorgan...
1051
1052
1053
1054
1055
1056
1057
1058
  		res = drv_start(local);
  		if (res)
  			goto err_del_bss;
  		/* we're brought up, everything changes */
  		hw_reconf_flags = ~0;
  		ieee80211_led_radio(local, true);
  		ieee80211_mod_tpt_led_trig(local,
  					   IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
b2c0958b2   Johannes Berg   mac80211: fix do_...
1059
  	}
4b7afb52c   Felix Fietkau   mac80211: reorgan...
1060
1061
1062
1063
1064
1065
1066
1067
1068
  	/*
  	 * Copy the hopefully now-present MAC address to
  	 * this interface, if it has the special null one.
  	 */
  	if (dev && is_zero_ether_addr(dev->dev_addr)) {
  		memcpy(dev->dev_addr,
  		       local->hw.wiphy->perm_addr,
  		       ETH_ALEN);
  		memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
34d4bc4d4   Johannes Berg   mac80211: support...
1069

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1070
1071
1072
1073
1074
  		if (!is_valid_ether_addr(dev->dev_addr)) {
  			res = -EADDRNOTAVAIL;
  			goto err_stop;
  		}
  	}
34d4bc4d4   Johannes Berg   mac80211: support...
1075

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_AP_VLAN:
  		/* no need to tell driver, but set carrier and chanctx */
  		if (rtnl_dereference(sdata->bss->beacon)) {
  			ieee80211_vif_vlan_copy_chanctx(sdata);
  			netif_carrier_on(dev);
  			ieee80211_set_vif_encap_ops(sdata);
  		} else {
  			netif_carrier_off(dev);
  		}
  		break;
  	case NL80211_IFTYPE_MONITOR:
  		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
  			local->cooked_mntrs++;
  			break;
  		}
5061b0c2b   Johannes Berg   mac80211: coopera...
1092

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1093
1094
1095
1096
1097
1098
1099
1100
1101
  		if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
  			res = drv_add_interface(local, sdata);
  			if (res)
  				goto err_stop;
  		} else if (local->monitors == 0 && local->open_count == 0) {
  			res = ieee80211_add_virtual_monitor(local);
  			if (res)
  				goto err_stop;
  		}
0d143fe1e   Johannes Berg   mac80211: move re...
1102

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1103
1104
1105
1106
1107
1108
  		/* must be before the call to ieee80211_configure_filter */
  		local->monitors++;
  		if (local->monitors == 1) {
  			local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
  			hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
  		}
0d143fe1e   Johannes Berg   mac80211: move re...
1109

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1110
1111
1112
1113
1114
1115
  		ieee80211_adjust_monitor_flags(sdata, 1);
  		ieee80211_configure_filter(local);
  		ieee80211_recalc_offload(local);
  		mutex_lock(&local->mtx);
  		ieee80211_recalc_idle(local);
  		mutex_unlock(&local->mtx);
0d143fe1e   Johannes Berg   mac80211: move re...
1116

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1117
1118
1119
1120
1121
1122
  		netif_carrier_on(dev);
  		break;
  	default:
  		if (coming_up) {
  			ieee80211_del_virtual_monitor(local);
  			ieee80211_set_sdata_offload_flags(sdata);
0d143fe1e   Johannes Berg   mac80211: move re...
1123

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1124
1125
1126
  			res = drv_add_interface(local, sdata);
  			if (res)
  				goto err_stop;
0d143fe1e   Johannes Berg   mac80211: move re...
1127

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1128
1129
1130
1131
1132
1133
  			ieee80211_set_vif_encap_ops(sdata);
  			res = ieee80211_check_queues(sdata,
  				ieee80211_vif_type_p2p(&sdata->vif));
  			if (res)
  				goto err_del_interface;
  		}
f0706e828   Jiri Benc   [MAC80211]: Add m...
1134

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1135
1136
1137
  		if (sdata->vif.type == NL80211_IFTYPE_AP) {
  			local->fif_pspoll++;
  			local->fif_probe_req++;
75636525f   Johannes Berg   mac80211: revamp ...
1138

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1139
1140
1141
1142
  			ieee80211_configure_filter(local);
  		} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
  			local->fif_probe_req++;
  		}
aee14ceb5   Jouni Malinen   mac80211: Reorder...
1143

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1144
1145
1146
1147
  		if (sdata->vif.probe_req_reg)
  			drv_config_iface_filter(local, sdata,
  						FIF_PROBE_REQ,
  						FIF_PROBE_REQ);
11a843b7e   Johannes Berg   [MAC80211]: rewor...
1148

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1149
1150
1151
1152
  		if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
  		    sdata->vif.type != NL80211_IFTYPE_NAN)
  			changed |= ieee80211_reset_erp_info(sdata);
  		ieee80211_bss_info_change_notify(sdata, changed);
f0706e828   Jiri Benc   [MAC80211]: Add m...
1153

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  		switch (sdata->vif.type) {
  		case NL80211_IFTYPE_STATION:
  		case NL80211_IFTYPE_ADHOC:
  		case NL80211_IFTYPE_AP:
  		case NL80211_IFTYPE_MESH_POINT:
  		case NL80211_IFTYPE_OCB:
  			netif_carrier_off(dev);
  			break;
  		case NL80211_IFTYPE_WDS:
  		case NL80211_IFTYPE_P2P_DEVICE:
  		case NL80211_IFTYPE_NAN:
  			break;
  		default:
  			/* not reached */
  			WARN_ON(1);
  		}
f142c6b90   Johannes Berg   mac80211: support...
1170

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1171
1172
1173
1174
1175
1176
1177
1178
1179
  		/*
  		 * Set default queue parameters so drivers don't
  		 * need to initialise the hardware if the hardware
  		 * doesn't start up with sane defaults.
  		 * Enable QoS for anything but station interfaces.
  		 */
  		ieee80211_set_wmm_default(sdata, true,
  			sdata->vif.type != NL80211_IFTYPE_STATION);
  	}
cf0277e71   Johannes Berg   mac80211: fix skb...
1180

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1181
  	set_bit(SDATA_STATE_RUNNING, &sdata->state);
5a490510b   Johannes Berg   mac80211: use per...
1182

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1183
1184
1185
1186
1187
1188
1189
1190
1191
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_WDS:
  		/* Create STA entry for the WDS peer */
  		sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
  				     GFP_KERNEL);
  		if (!sta) {
  			res = -ENOMEM;
  			goto err_del_interface;
  		}
5a490510b   Johannes Berg   mac80211: use per...
1192

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1193
1194
1195
  		sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
  		sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
  		sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
5a490510b   Johannes Berg   mac80211: use per...
1196

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1197
1198
1199
1200
1201
  		res = sta_info_insert(sta);
  		if (res) {
  			/* STA has been freed */
  			goto err_del_interface;
  		}
5a490510b   Johannes Berg   mac80211: use per...
1202

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
  		rate_control_rate_init(sta);
  		netif_carrier_on(dev);
  		break;
  	case NL80211_IFTYPE_P2P_DEVICE:
  		rcu_assign_pointer(local->p2p_sdata, sdata);
  		break;
  	case NL80211_IFTYPE_MONITOR:
  		if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
  			break;
  		list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
  		break;
  	default:
  		break;
5a490510b   Johannes Berg   mac80211: use per...
1216
  	}
5a490510b   Johannes Berg   mac80211: use per...
1217

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1218
1219
1220
1221
1222
1223
1224
  	/*
  	 * set_multicast_list will be invoked by the networking core
  	 * which will check whether any increments here were done in
  	 * error and sync them down to the hardware as filter flags.
  	 */
  	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
  		atomic_inc(&local->iff_allmultis);
587e729ec   Johannes Berg   mac80211: convert...
1225

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1226
1227
  	if (coming_up)
  		local->open_count++;
cf0277e71   Johannes Berg   mac80211: fix skb...
1228

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1229
1230
  	if (hw_reconf_flags)
  		ieee80211_hw_config(local, hw_reconf_flags);
cf0277e71   Johannes Berg   mac80211: fix skb...
1231

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1232
  	ieee80211_recalc_ps(local);
cb17ed29a   Mathy Vanhoef   mac80211: parse r...
1233

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
  	if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
  	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
  	    local->ops->wake_tx_queue) {
  		/* XXX: for AP_VLAN, actually track AP queues */
  		if (dev)
  			netif_tx_start_all_queues(dev);
  	} else if (dev) {
  		unsigned long flags;
  		int n_acs = IEEE80211_NUM_ACS;
  		int ac;
cf0277e71   Johannes Berg   mac80211: fix skb...
1244

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1245
1246
  		if (local->hw.queues < IEEE80211_NUM_ACS)
  			n_acs = 1;
cf0277e71   Johannes Berg   mac80211: fix skb...
1247

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1248
1249
1250
1251
1252
1253
  		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
  		if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE ||
  		    (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 &&
  		     skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) {
  			for (ac = 0; ac < n_acs; ac++) {
  				int ac_queue = sdata->vif.hw_queue[ac];
cf0277e71   Johannes Berg   mac80211: fix skb...
1254

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1255
1256
1257
1258
1259
1260
1261
  				if (local->queue_stop_reasons[ac_queue] == 0 &&
  				    skb_queue_empty(&local->pending[ac_queue]))
  					netif_start_subqueue(dev, ac);
  			}
  		}
  		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
  	}
587e729ec   Johannes Berg   mac80211: convert...
1262

4b7afb52c   Felix Fietkau   mac80211: reorgan...
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
  	return 0;
   err_del_interface:
  	drv_remove_interface(local, sdata);
   err_stop:
  	if (!local->open_count)
  		drv_stop(local);
   err_del_bss:
  	sdata->bss = NULL;
  	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
  		mutex_lock(&local->mtx);
  		list_del(&sdata->u.vlan.list);
  		mutex_unlock(&local->mtx);
  	}
  	/* might already be clear but that doesn't matter */
  	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
  	return res;
  }
50ff477a8   John Crispin   mac80211: add 802...
1280

5a490510b   Johannes Berg   mac80211: use per...
1281
1282
1283
  static void ieee80211_if_free(struct net_device *dev)
  {
  	free_percpu(dev->tstats);
5a490510b   Johannes Berg   mac80211: use per...
1284
  }
587e729ec   Johannes Berg   mac80211: convert...
1285
1286
1287
  static void ieee80211_if_setup(struct net_device *dev)
  {
  	ether_setup(dev);
550fd08c2   Neil Horman   net: Audit driver...
1288
  	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
587e729ec   Johannes Berg   mac80211: convert...
1289
  	dev->netdev_ops = &ieee80211_dataif_ops;
cf124db56   David S. Miller   net: Fix inconsis...
1290
1291
  	dev->needs_free_netdev = true;
  	dev->priv_destructor = ieee80211_if_free;
587e729ec   Johannes Berg   mac80211: convert...
1292
  }
80a83cfc4   Michal Kazior   mac80211: skip ne...
1293
1294
1295
1296
1297
  static void ieee80211_if_setup_no_queue(struct net_device *dev)
  {
  	ieee80211_if_setup(dev);
  	dev->priv_flags |= IFF_NO_QUEUE;
  }
1fa57d017   Johannes Berg   mac80211: use com...
1298
1299
1300
1301
1302
1303
  static void ieee80211_iface_work(struct work_struct *work)
  {
  	struct ieee80211_sub_if_data *sdata =
  		container_of(work, struct ieee80211_sub_if_data, work);
  	struct ieee80211_local *local = sdata->local;
  	struct sk_buff *skb;
344eec67c   Johannes Berg   mac80211: move bl...
1304
  	struct sta_info *sta;
1fa57d017   Johannes Berg   mac80211: use com...
1305
1306
1307
  
  	if (!ieee80211_sdata_running(sdata))
  		return;
fc58c47ef   Andrei Otcheretianski   mac80211: process...
1308
  	if (test_bit(SCAN_SW_SCANNING, &local->scanning))
1fa57d017   Johannes Berg   mac80211: use com...
1309
  		return;
4afaff176   Emmanuel Grumbach   mac80211: avoid r...
1310
  	if (!ieee80211_can_run_worker(local))
1fa57d017   Johannes Berg   mac80211: use com...
1311
1312
1313
1314
  		return;
  
  	/* first process frames */
  	while ((skb = skb_dequeue(&sdata->skb_queue))) {
bed7ee6e4   Johannes Berg   mac80211: always ...
1315
  		struct ieee80211_mgmt *mgmt = (void *)skb->data;
699cb58c8   Johannes Berg   mac80211: manage ...
1316
1317
  		if (ieee80211_is_action(mgmt->frame_control) &&
  		    mgmt->u.action.category == WLAN_CATEGORY_BACK) {
bed7ee6e4   Johannes Berg   mac80211: always ...
1318
  			int len = skb->len;
bed7ee6e4   Johannes Berg   mac80211: always ...
1319

a93e36443   Johannes Berg   mac80211: change ...
1320
  			mutex_lock(&local->sta_mtx);
875ae5f68   Felix Fietkau   mac80211: fix agg...
1321
  			sta = sta_info_get_bss(sdata, mgmt->sa);
bed7ee6e4   Johannes Berg   mac80211: always ...
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
  			if (sta) {
  				switch (mgmt->u.action.u.addba_req.action_code) {
  				case WLAN_ACTION_ADDBA_REQ:
  					ieee80211_process_addba_request(
  							local, sta, mgmt, len);
  					break;
  				case WLAN_ACTION_ADDBA_RESP:
  					ieee80211_process_addba_resp(local, sta,
  								     mgmt, len);
  					break;
  				case WLAN_ACTION_DELBA:
  					ieee80211_process_delba(sdata, sta,
  								mgmt, len);
  					break;
  				default:
  					WARN_ON(1);
  					break;
  				}
  			}
a93e36443   Johannes Berg   mac80211: change ...
1341
  			mutex_unlock(&local->sta_mtx);
23a1f8d44   Sara Sharon   mac80211: process...
1342
1343
1344
  		} else if (ieee80211_is_action(mgmt->frame_control) &&
  			   mgmt->u.action.category == WLAN_CATEGORY_VHT) {
  			switch (mgmt->u.action.u.vht_group_notif.action_code) {
d2941df8f   Johannes Berg   mac80211: recalcu...
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
  			case WLAN_VHT_ACTION_OPMODE_NOTIF: {
  				struct ieee80211_rx_status *status;
  				enum nl80211_band band;
  				u8 opmode;
  
  				status = IEEE80211_SKB_RXCB(skb);
  				band = status->band;
  				opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
  
  				mutex_lock(&local->sta_mtx);
  				sta = sta_info_get_bss(sdata, mgmt->sa);
  
  				if (sta)
  					ieee80211_vht_handle_opmode(sdata, sta,
  								    opmode,
  								    band);
  
  				mutex_unlock(&local->sta_mtx);
  				break;
  			}
23a1f8d44   Sara Sharon   mac80211: process...
1365
1366
1367
1368
1369
1370
1371
  			case WLAN_VHT_ACTION_GROUPID_MGMT:
  				ieee80211_process_mu_groups(sdata, mgmt);
  				break;
  			default:
  				WARN_ON(1);
  				break;
  			}
09a740ce3   Thomas Pedersen   mac80211: receive...
1372
1373
1374
1375
1376
  		} else if (ieee80211_is_ext(mgmt->frame_control)) {
  			if (sdata->vif.type == NL80211_IFTYPE_STATION)
  				ieee80211_sta_rx_queued_ext(sdata, skb);
  			else
  				WARN_ON(1);
344eec67c   Johannes Berg   mac80211: move bl...
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
  		} else if (ieee80211_is_data_qos(mgmt->frame_control)) {
  			struct ieee80211_hdr *hdr = (void *)mgmt;
  			/*
  			 * So the frame isn't mgmt, but frame_control
  			 * is at the right place anyway, of course, so
  			 * the if statement is correct.
  			 *
  			 * Warn if we have other data frame types here,
  			 * they must not get here.
  			 */
  			WARN_ON(hdr->frame_control &
  					cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
  			WARN_ON(!(hdr->seq_ctrl &
  					cpu_to_le16(IEEE80211_SCTL_FRAG)));
  			/*
  			 * This was a fragment of a frame, received while
  			 * a block-ack session was active. That cannot be
  			 * right, so terminate the session.
  			 */
a93e36443   Johannes Berg   mac80211: change ...
1396
  			mutex_lock(&local->sta_mtx);
875ae5f68   Felix Fietkau   mac80211: fix agg...
1397
  			sta = sta_info_get_bss(sdata, mgmt->sa);
344eec67c   Johannes Berg   mac80211: move bl...
1398
  			if (sta) {
a1f2ba04c   Sara Sharon   mac80211: add get...
1399
  				u16 tid = ieee80211_get_tid(hdr);
344eec67c   Johannes Berg   mac80211: move bl...
1400
1401
1402
  
  				__ieee80211_stop_rx_ba_session(
  					sta, tid, WLAN_BACK_RECIPIENT,
53f73c09d   Johannes Berg   mac80211: avoid t...
1403
1404
  					WLAN_REASON_QSTA_REQUIRE_SETUP,
  					true);
344eec67c   Johannes Berg   mac80211: move bl...
1405
  			}
a93e36443   Johannes Berg   mac80211: change ...
1406
  			mutex_unlock(&local->sta_mtx);
bed7ee6e4   Johannes Berg   mac80211: always ...
1407
  		} else switch (sdata->vif.type) {
1fa57d017   Johannes Berg   mac80211: use com...
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
  		case NL80211_IFTYPE_STATION:
  			ieee80211_sta_rx_queued_mgmt(sdata, skb);
  			break;
  		case NL80211_IFTYPE_ADHOC:
  			ieee80211_ibss_rx_queued_mgmt(sdata, skb);
  			break;
  		case NL80211_IFTYPE_MESH_POINT:
  			if (!ieee80211_vif_is_mesh(&sdata->vif))
  				break;
  			ieee80211_mesh_rx_queued_mgmt(sdata, skb);
  			break;
  		default:
  			WARN(1, "frame for unexpected interface type");
1fa57d017   Johannes Berg   mac80211: use com...
1421
1422
  			break;
  		}
36b3a628a   Johannes Berg   mac80211: common ...
1423
1424
  
  		kfree_skb(skb);
1fa57d017   Johannes Berg   mac80211: use com...
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
  	}
  
  	/* then other type-dependent work */
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_STATION:
  		ieee80211_sta_work(sdata);
  		break;
  	case NL80211_IFTYPE_ADHOC:
  		ieee80211_ibss_work(sdata);
  		break;
  	case NL80211_IFTYPE_MESH_POINT:
  		if (!ieee80211_vif_is_mesh(&sdata->vif))
  			break;
  		ieee80211_mesh_work(sdata);
  		break;
239281f80   Rostislav Lisovy   mac80211: 802.11p...
1440
1441
1442
  	case NL80211_IFTYPE_OCB:
  		ieee80211_ocb_work(sdata);
  		break;
1fa57d017   Johannes Berg   mac80211: use com...
1443
1444
1445
1446
  	default:
  		break;
  	}
  }
04ecd2578   Johannes Berg   mac80211: track n...
1447
1448
1449
1450
1451
1452
1453
  static void ieee80211_recalc_smps_work(struct work_struct *work)
  {
  	struct ieee80211_sub_if_data *sdata =
  		container_of(work, struct ieee80211_sub_if_data, recalc_smps);
  
  	ieee80211_recalc_smps(sdata);
  }
1fa57d017   Johannes Berg   mac80211: use com...
1454

75636525f   Johannes Berg   mac80211: revamp ...
1455
1456
1457
1458
  /*
   * Helper function to initialise an interface to a specific type.
   */
  static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
05c914fe3   Johannes Berg   mac80211: use nl8...
1459
  				  enum nl80211_iftype type)
f0706e828   Jiri Benc   [MAC80211]: Add m...
1460
  {
239281f80   Rostislav Lisovy   mac80211: 802.11p...
1461
1462
  	static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff,
  						    0xff, 0xff, 0xff};
75636525f   Johannes Berg   mac80211: revamp ...
1463
1464
1465
1466
1467
  	/* clear type-dependent union */
  	memset(&sdata->u, 0, sizeof(sdata->u));
  
  	/* and set some type-dependent values */
  	sdata->vif.type = type;
2ca27bcff   Johannes Berg   mac80211: add p2p...
1468
  	sdata->vif.p2p = false;
60719ffd7   Johannes Berg   cfg80211: show in...
1469
  	sdata->wdev.iftype = type;
75636525f   Johannes Berg   mac80211: revamp ...
1470

a621fa4d6   Johannes Berg   mac80211: allow c...
1471
1472
  	sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
  	sdata->control_port_no_encrypt = false;
7f3f96ced   Markus Theil   mac80211: handle ...
1473
1474
  	sdata->control_port_over_nl80211 = false;
  	sdata->control_port_no_preauth = false;
2475b1cc0   Max Stepanov   mac80211: add gen...
1475
  	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
d3a58df87   Avraham Stern   mac80211: set new...
1476
  	sdata->vif.bss_conf.idle = true;
db6d9e9e8   Ben Greear   mac80211: Fix set...
1477
  	sdata->vif.bss_conf.txpower = INT_MIN; /* unset */
a621fa4d6   Johannes Berg   mac80211: allow c...
1478

b53be7920   Simon Wunderlich   mac80211: Add NoA...
1479
  	sdata->noack_map = 0;
f142c6b90   Johannes Berg   mac80211: support...
1480
1481
1482
1483
1484
  	/* only monitor/p2p-device differ */
  	if (sdata->dev) {
  		sdata->dev->netdev_ops = &ieee80211_dataif_ops;
  		sdata->dev->type = ARPHRD_ETHER;
  	}
75636525f   Johannes Berg   mac80211: revamp ...
1485

35f20c14a   Johannes Berg   mac80211: use com...
1486
  	skb_queue_head_init(&sdata->skb_queue);
1fa57d017   Johannes Berg   mac80211: use com...
1487
  	INIT_WORK(&sdata->work, ieee80211_iface_work);
04ecd2578   Johannes Berg   mac80211: track n...
1488
  	INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
73da7d5ba   Simon Wunderlich   mac80211: add cha...
1489
  	INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
484298ad1   Michal Kazior   mac80211: track a...
1490
  	INIT_LIST_HEAD(&sdata->assigned_chanctx_list);
e3afb9202   Michal Kazior   mac80211: track r...
1491
  	INIT_LIST_HEAD(&sdata->reserved_chanctx_list);
35f20c14a   Johannes Berg   mac80211: use com...
1492

75636525f   Johannes Berg   mac80211: revamp ...
1493
  	switch (type) {
2ca27bcff   Johannes Berg   mac80211: add p2p...
1494
1495
1496
1497
  	case NL80211_IFTYPE_P2P_GO:
  		type = NL80211_IFTYPE_AP;
  		sdata->vif.type = type;
  		sdata->vif.p2p = true;
fc0561dc6   Gustavo A. R. Silva   mac80211: Use fal...
1498
  		fallthrough;
05c914fe3   Johannes Berg   mac80211: use nl8...
1499
  	case NL80211_IFTYPE_AP:
d012a6051   Marco Porsch   mac80211: make cl...
1500
  		skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
75636525f   Johannes Berg   mac80211: revamp ...
1501
  		INIT_LIST_HEAD(&sdata->u.ap.vlans);
ad2d223aa   Johannes Berg   mac80211: assign ...
1502
  		sdata->vif.bss_conf.bssid = sdata->vif.addr;
75636525f   Johannes Berg   mac80211: revamp ...
1503
  		break;
2ca27bcff   Johannes Berg   mac80211: add p2p...
1504
1505
1506
1507
  	case NL80211_IFTYPE_P2P_CLIENT:
  		type = NL80211_IFTYPE_STATION;
  		sdata->vif.type = type;
  		sdata->vif.p2p = true;
fc0561dc6   Gustavo A. R. Silva   mac80211: Use fal...
1508
  		fallthrough;
05c914fe3   Johannes Berg   mac80211: use nl8...
1509
  	case NL80211_IFTYPE_STATION:
ad2d223aa   Johannes Berg   mac80211: assign ...
1510
  		sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
9c6bd7901   Johannes Berg   mac80211: reorder...
1511
  		ieee80211_sta_setup_sdata(sdata);
472dbc45d   Johannes Berg   mac80211: split o...
1512
  		break;
6e0bd6c35   Rostislav Lisovy   cfg80211: 802.11p...
1513
  	case NL80211_IFTYPE_OCB:
239281f80   Rostislav Lisovy   mac80211: 802.11p...
1514
1515
  		sdata->vif.bss_conf.bssid = bssid_wildcard;
  		ieee80211_ocb_setup_sdata(sdata);
6e0bd6c35   Rostislav Lisovy   cfg80211: 802.11p...
1516
  		break;
469002983   Johannes Berg   mac80211: split I...
1517
  	case NL80211_IFTYPE_ADHOC:
ad2d223aa   Johannes Berg   mac80211: assign ...
1518
  		sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
469002983   Johannes Berg   mac80211: split I...
1519
1520
  		ieee80211_ibss_setup_sdata(sdata);
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
1521
  	case NL80211_IFTYPE_MESH_POINT:
75636525f   Johannes Berg   mac80211: revamp ...
1522
1523
1524
  		if (ieee80211_vif_is_mesh(&sdata->vif))
  			ieee80211_mesh_init_sdata(sdata);
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
1525
  	case NL80211_IFTYPE_MONITOR:
75636525f   Johannes Berg   mac80211: revamp ...
1526
  		sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
587e729ec   Johannes Berg   mac80211: convert...
1527
  		sdata->dev->netdev_ops = &ieee80211_monitorif_ops;
d82121845   Aviya Erenfeld   mac80211: refacto...
1528
  		sdata->u.mntr.flags = MONITOR_FLAG_CONTROL |
75636525f   Johannes Berg   mac80211: revamp ...
1529
1530
  				      MONITOR_FLAG_OTHER_BSS;
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
1531
  	case NL80211_IFTYPE_WDS:
ad2d223aa   Johannes Berg   mac80211: assign ...
1532
1533
  		sdata->vif.bss_conf.bssid = NULL;
  		break;
167e33f4f   Ayala Beker   mac80211: Impleme...
1534
1535
1536
1537
1538
  	case NL80211_IFTYPE_NAN:
  		idr_init(&sdata->u.nan.function_inst_ids);
  		spin_lock_init(&sdata->u.nan.func_lock);
  		sdata->vif.bss_conf.bssid = sdata->vif.addr;
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
1539
  	case NL80211_IFTYPE_AP_VLAN:
98104fded   Johannes Berg   cfg80211: add P2P...
1540
  	case NL80211_IFTYPE_P2P_DEVICE:
ad2d223aa   Johannes Berg   mac80211: assign ...
1541
  		sdata->vif.bss_conf.bssid = sdata->vif.addr;
f142c6b90   Johannes Berg   mac80211: support...
1542
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
1543
  	case NL80211_IFTYPE_UNSPECIFIED:
2e161f78e   Johannes Berg   cfg80211/mac80211...
1544
  	case NUM_NL80211_IFTYPES:
c7976f527   Luca Coelho   mac80211: remove ...
1545
  		WARN_ON(1);
75636525f   Johannes Berg   mac80211: revamp ...
1546
1547
1548
1549
1550
  		break;
  	}
  
  	ieee80211_debugfs_add_netdev(sdata);
  }
34d4bc4d4   Johannes Berg   mac80211: support...
1551
1552
1553
1554
1555
  static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
  					   enum nl80211_iftype type)
  {
  	struct ieee80211_local *local = sdata->local;
  	int ret, err;
2ca27bcff   Johannes Berg   mac80211: add p2p...
1556
1557
  	enum nl80211_iftype internal_type = type;
  	bool p2p = false;
34d4bc4d4   Johannes Berg   mac80211: support...
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  
  	ASSERT_RTNL();
  
  	if (!local->ops->change_interface)
  		return -EBUSY;
  
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_AP:
  	case NL80211_IFTYPE_STATION:
  	case NL80211_IFTYPE_ADHOC:
239281f80   Rostislav Lisovy   mac80211: 802.11p...
1568
  	case NL80211_IFTYPE_OCB:
34d4bc4d4   Johannes Berg   mac80211: support...
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
  		/*
  		 * Could maybe also all others here?
  		 * Just not sure how that interacts
  		 * with the RX/config path e.g. for
  		 * mesh.
  		 */
  		break;
  	default:
  		return -EBUSY;
  	}
  
  	switch (type) {
  	case NL80211_IFTYPE_AP:
  	case NL80211_IFTYPE_STATION:
  	case NL80211_IFTYPE_ADHOC:
239281f80   Rostislav Lisovy   mac80211: 802.11p...
1584
  	case NL80211_IFTYPE_OCB:
34d4bc4d4   Johannes Berg   mac80211: support...
1585
1586
1587
1588
1589
1590
1591
  		/*
  		 * Could probably support everything
  		 * but WDS here (WDS do_open can fail
  		 * under memory pressure, which this
  		 * code isn't prepared to handle).
  		 */
  		break;
2ca27bcff   Johannes Berg   mac80211: add p2p...
1592
1593
1594
1595
1596
1597
1598
1599
  	case NL80211_IFTYPE_P2P_CLIENT:
  		p2p = true;
  		internal_type = NL80211_IFTYPE_STATION;
  		break;
  	case NL80211_IFTYPE_P2P_GO:
  		p2p = true;
  		internal_type = NL80211_IFTYPE_AP;
  		break;
34d4bc4d4   Johannes Berg   mac80211: support...
1600
1601
1602
  	default:
  		return -EBUSY;
  	}
2ca27bcff   Johannes Berg   mac80211: add p2p...
1603
  	ret = ieee80211_check_concurrent_iface(sdata, internal_type);
34d4bc4d4   Johannes Berg   mac80211: support...
1604
1605
1606
1607
  	if (ret)
  		return ret;
  
  	ieee80211_do_stop(sdata, false);
f142c6b90   Johannes Berg   mac80211: support...
1608
  	ieee80211_teardown_sdata(sdata);
34d4bc4d4   Johannes Berg   mac80211: support...
1609

6aea26ce5   Felix Fietkau   mac80211: rework ...
1610
  	ieee80211_set_sdata_offload_flags(sdata);
2ca27bcff   Johannes Berg   mac80211: add p2p...
1611
  	ret = drv_change_interface(local, sdata, internal_type, p2p);
34d4bc4d4   Johannes Berg   mac80211: support...
1612
  	if (ret)
a98655387   Johannes Berg   mac80211: fix cha...
1613
  		type = ieee80211_vif_type_p2p(&sdata->vif);
34d4bc4d4   Johannes Berg   mac80211: support...
1614

3a25a8c8b   Johannes Berg   mac80211: add imp...
1615
1616
1617
1618
1619
  	/*
  	 * Ignore return value here, there's not much we can do since
  	 * the driver changed the interface type internally already.
  	 * The warnings will hopefully make driver authors fix it :-)
  	 */
a98655387   Johannes Berg   mac80211: fix cha...
1620
  	ieee80211_check_queues(sdata, type);
3a25a8c8b   Johannes Berg   mac80211: add imp...
1621

34d4bc4d4   Johannes Berg   mac80211: support...
1622
  	ieee80211_setup_sdata(sdata, type);
6aea26ce5   Felix Fietkau   mac80211: rework ...
1623
  	ieee80211_set_vif_encap_ops(sdata);
34d4bc4d4   Johannes Berg   mac80211: support...
1624

f142c6b90   Johannes Berg   mac80211: support...
1625
  	err = ieee80211_do_open(&sdata->wdev, false);
34d4bc4d4   Johannes Berg   mac80211: support...
1626
1627
1628
1629
  	WARN(err, "type change: do_open returned %d", err);
  
  	return ret;
  }
f3947e2df   Johannes Berg   mac80211: push in...
1630
  int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
05c914fe3   Johannes Berg   mac80211: use nl8...
1631
  			     enum nl80211_iftype type)
75636525f   Johannes Berg   mac80211: revamp ...
1632
  {
34d4bc4d4   Johannes Berg   mac80211: support...
1633
  	int ret;
f3947e2df   Johannes Berg   mac80211: push in...
1634
  	ASSERT_RTNL();
2ca27bcff   Johannes Berg   mac80211: add p2p...
1635
  	if (type == ieee80211_vif_type_p2p(&sdata->vif))
f3947e2df   Johannes Berg   mac80211: push in...
1636
  		return 0;
34d4bc4d4   Johannes Berg   mac80211: support...
1637
1638
1639
1640
1641
1642
  	if (ieee80211_sdata_running(sdata)) {
  		ret = ieee80211_runtime_change_iftype(sdata, type);
  		if (ret)
  			return ret;
  	} else {
  		/* Purge and reset type-dependent state. */
f142c6b90   Johannes Berg   mac80211: support...
1643
  		ieee80211_teardown_sdata(sdata);
34d4bc4d4   Johannes Berg   mac80211: support...
1644
1645
  		ieee80211_setup_sdata(sdata, type);
  	}
75636525f   Johannes Berg   mac80211: revamp ...
1646
1647
  
  	/* reset some values that shouldn't be kept across type changes */
9bc383de3   Johannes Berg   cfg80211: introdu...
1648
1649
  	if (type == NL80211_IFTYPE_STATION)
  		sdata->u.mgd.use_4addr = false;
f3947e2df   Johannes Berg   mac80211: push in...
1650
1651
  
  	return 0;
f0706e828   Jiri Benc   [MAC80211]: Add m...
1652
  }
fa9029f8c   Johannes Berg   mac80211: use dif...
1653
  static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
f142c6b90   Johannes Berg   mac80211: support...
1654
  				       u8 *perm_addr, enum nl80211_iftype type)
fa9029f8c   Johannes Berg   mac80211: use dif...
1655
1656
1657
1658
1659
1660
1661
1662
  {
  	struct ieee80211_sub_if_data *sdata;
  	u64 mask, start, addr, val, inc;
  	u8 *m;
  	u8 tmp_addr[ETH_ALEN];
  	int i;
  
  	/* default ... something at least */
f142c6b90   Johannes Berg   mac80211: support...
1663
  	memcpy(perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
fa9029f8c   Johannes Berg   mac80211: use dif...
1664
1665
1666
1667
  
  	if (is_zero_ether_addr(local->hw.wiphy->addr_mask) &&
  	    local->hw.wiphy->n_addresses <= 1)
  		return;
fa9029f8c   Johannes Berg   mac80211: use dif...
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
  	mutex_lock(&local->iflist_mtx);
  
  	switch (type) {
  	case NL80211_IFTYPE_MONITOR:
  		/* doesn't matter */
  		break;
  	case NL80211_IFTYPE_WDS:
  	case NL80211_IFTYPE_AP_VLAN:
  		/* match up with an AP interface */
  		list_for_each_entry(sdata, &local->interfaces, list) {
  			if (sdata->vif.type != NL80211_IFTYPE_AP)
  				continue;
f142c6b90   Johannes Berg   mac80211: support...
1680
  			memcpy(perm_addr, sdata->vif.addr, ETH_ALEN);
fa9029f8c   Johannes Berg   mac80211: use dif...
1681
1682
1683
1684
  			break;
  		}
  		/* keep default if no AP interface present */
  		break;
6d71117a2   Johannes Berg   mac80211: add IEE...
1685
1686
  	case NL80211_IFTYPE_P2P_CLIENT:
  	case NL80211_IFTYPE_P2P_GO:
30686bf7f   Johannes Berg   mac80211: convert...
1687
  		if (ieee80211_hw_check(&local->hw, P2P_DEV_ADDR_FOR_INTF)) {
6d71117a2   Johannes Berg   mac80211: add IEE...
1688
1689
1690
1691
1692
1693
1694
1695
1696
  			list_for_each_entry(sdata, &local->interfaces, list) {
  				if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE)
  					continue;
  				if (!ieee80211_sdata_running(sdata))
  					continue;
  				memcpy(perm_addr, sdata->vif.addr, ETH_ALEN);
  				goto out_unlock;
  			}
  		}
fc0561dc6   Gustavo A. R. Silva   mac80211: Use fal...
1697
  		fallthrough;
fa9029f8c   Johannes Berg   mac80211: use dif...
1698
1699
1700
1701
1702
1703
  	default:
  		/* assign a new address if possible -- try n_addresses first */
  		for (i = 0; i < local->hw.wiphy->n_addresses; i++) {
  			bool used = false;
  
  			list_for_each_entry(sdata, &local->interfaces, list) {
496d7e8ea   dingtianhong   mac8011: slight o...
1704
1705
  				if (ether_addr_equal(local->hw.wiphy->addresses[i].addr,
  						     sdata->vif.addr)) {
fa9029f8c   Johannes Berg   mac80211: use dif...
1706
1707
1708
1709
1710
1711
  					used = true;
  					break;
  				}
  			}
  
  			if (!used) {
f142c6b90   Johannes Berg   mac80211: support...
1712
  				memcpy(perm_addr,
fa9029f8c   Johannes Berg   mac80211: use dif...
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
  				       local->hw.wiphy->addresses[i].addr,
  				       ETH_ALEN);
  				break;
  			}
  		}
  
  		/* try mask if available */
  		if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
  			break;
  
  		m = local->hw.wiphy->addr_mask;
  		mask =	((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
  			((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
  			((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
  
  		if (__ffs64(mask) + hweight64(mask) != fls64(mask)) {
  			/* not a contiguous mask ... not handled now! */
bdcbd8e0e   Johannes Berg   mac80211: clean u...
1730
1731
  			pr_info("not contiguous
  ");
fa9029f8c   Johannes Berg   mac80211: use dif...
1732
1733
  			break;
  		}
ac20976dc   Helmut Schaa   mac80211: Allow s...
1734
1735
1736
1737
  		/*
  		 * Pick address of existing interface in case user changed
  		 * MAC address manually, default to perm_addr.
  		 */
fa9029f8c   Johannes Berg   mac80211: use dif...
1738
  		m = local->hw.wiphy->perm_addr;
ac20976dc   Helmut Schaa   mac80211: Allow s...
1739
1740
1741
1742
1743
1744
  		list_for_each_entry(sdata, &local->interfaces, list) {
  			if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
  				continue;
  			m = sdata->vif.addr;
  			break;
  		}
fa9029f8c   Johannes Berg   mac80211: use dif...
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
  		start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
  			((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
  			((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
  
  		inc = 1ULL<<__ffs64(mask);
  		val = (start & mask);
  		addr = (start & ~mask) | (val & mask);
  		do {
  			bool used = false;
  
  			tmp_addr[5] = addr >> 0*8;
  			tmp_addr[4] = addr >> 1*8;
  			tmp_addr[3] = addr >> 2*8;
  			tmp_addr[2] = addr >> 3*8;
  			tmp_addr[1] = addr >> 4*8;
  			tmp_addr[0] = addr >> 5*8;
  
  			val += inc;
  
  			list_for_each_entry(sdata, &local->interfaces, list) {
496d7e8ea   dingtianhong   mac8011: slight o...
1765
  				if (ether_addr_equal(tmp_addr, sdata->vif.addr)) {
fa9029f8c   Johannes Berg   mac80211: use dif...
1766
1767
1768
1769
1770
1771
  					used = true;
  					break;
  				}
  			}
  
  			if (!used) {
f142c6b90   Johannes Berg   mac80211: support...
1772
  				memcpy(perm_addr, tmp_addr, ETH_ALEN);
fa9029f8c   Johannes Berg   mac80211: use dif...
1773
1774
1775
1776
1777
1778
1779
  				break;
  			}
  			addr = (start & ~mask) | (val & mask);
  		} while (addr != start);
  
  		break;
  	}
6d71117a2   Johannes Berg   mac80211: add IEE...
1780
   out_unlock:
fa9029f8c   Johannes Berg   mac80211: use dif...
1781
1782
  	mutex_unlock(&local->iflist_mtx);
  }
3e122be08   Johannes Berg   mac80211: make ma...
1783
  int ieee80211_if_add(struct ieee80211_local *local, const char *name,
6bab2e19c   Tom Gundersen   cfg80211: pass na...
1784
  		     unsigned char name_assign_type,
84efbb84c   Johannes Berg   cfg80211: use wir...
1785
  		     struct wireless_dev **new_wdev, enum nl80211_iftype type,
ee3858551   Luis Carlos Cobo   mac80211: mesh da...
1786
  		     struct vif_params *params)
f0706e828   Jiri Benc   [MAC80211]: Add m...
1787
  {
f142c6b90   Johannes Berg   mac80211: support...
1788
  	struct net_device *ndev = NULL;
f0706e828   Jiri Benc   [MAC80211]: Add m...
1789
  	struct ieee80211_sub_if_data *sdata = NULL;
ba8c3d6f1   Felix Fietkau   mac80211: add an ...
1790
  	struct txq_info *txqi;
80a83cfc4   Michal Kazior   mac80211: skip ne...
1791
  	void (*if_setup)(struct net_device *dev);
75636525f   Johannes Berg   mac80211: revamp ...
1792
  	int ret, i;
ded81f6ba   Johannes Berg   mac80211: decoupl...
1793
  	int txqs = 1;
f0706e828   Jiri Benc   [MAC80211]: Add m...
1794
1795
  
  	ASSERT_RTNL();
75636525f   Johannes Berg   mac80211: revamp ...
1796

708d50edb   Ayala Beker   mac80211: add boi...
1797
  	if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) {
f142c6b90   Johannes Berg   mac80211: support...
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
  		struct wireless_dev *wdev;
  
  		sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size,
  				GFP_KERNEL);
  		if (!sdata)
  			return -ENOMEM;
  		wdev = &sdata->wdev;
  
  		sdata->dev = NULL;
  		strlcpy(sdata->name, name, IFNAMSIZ);
  		ieee80211_assign_perm_addr(local, wdev->address, type);
  		memcpy(sdata->vif.addr, wdev->address, ETH_ALEN);
  	} else {
ba8c3d6f1   Felix Fietkau   mac80211: add an ...
1811
1812
1813
  		int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size,
  				 sizeof(void *));
  		int txq_size = 0;
79af1f866   Johannes Berg   mac80211: avoid a...
1814
1815
  		if (local->ops->wake_tx_queue &&
  		    type != NL80211_IFTYPE_AP_VLAN &&
8105f9b8a   Felix Fietkau   mac80211: allocat...
1816
1817
  		    (type != NL80211_IFTYPE_MONITOR ||
  		     (params->flags & MONITOR_FLAG_ACTIVE)))
ba8c3d6f1   Felix Fietkau   mac80211: add an ...
1818
1819
  			txq_size += sizeof(struct txq_info) +
  				    local->hw.txq_data_size;
dbd50a851   Johannes Berg   mac80211: only al...
1820
  		if (local->ops->wake_tx_queue) {
80a83cfc4   Michal Kazior   mac80211: skip ne...
1821
  			if_setup = ieee80211_if_setup_no_queue;
dbd50a851   Johannes Berg   mac80211: only al...
1822
  		} else {
80a83cfc4   Michal Kazior   mac80211: skip ne...
1823
  			if_setup = ieee80211_if_setup;
dbd50a851   Johannes Berg   mac80211: only al...
1824
1825
1826
  			if (local->hw.queues >= IEEE80211_NUM_ACS)
  				txqs = IEEE80211_NUM_ACS;
  		}
f142c6b90   Johannes Berg   mac80211: support...
1827

ba8c3d6f1   Felix Fietkau   mac80211: add an ...
1828
  		ndev = alloc_netdev_mqs(size + txq_size,
6bab2e19c   Tom Gundersen   cfg80211: pass na...
1829
  					name, name_assign_type,
80a83cfc4   Michal Kazior   mac80211: skip ne...
1830
  					if_setup, txqs, 1);
f142c6b90   Johannes Berg   mac80211: support...
1831
1832
  		if (!ndev)
  			return -ENOMEM;
1f6e0baa7   John Crispin   mac80211: allow s...
1833
1834
1835
  
  		if (!local->ops->wake_tx_queue && local->hw.wiphy->tx_queue_len)
  			ndev->tx_queue_len = local->hw.wiphy->tx_queue_len;
f142c6b90   Johannes Berg   mac80211: support...
1836
  		dev_net_set(ndev, wiphy_net(local->hw.wiphy));
5a490510b   Johannes Berg   mac80211: use per...
1837
1838
1839
1840
1841
  		ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
  		if (!ndev->tstats) {
  			free_netdev(ndev);
  			return -ENOMEM;
  		}
f142c6b90   Johannes Berg   mac80211: support...
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
  		ndev->needed_headroom = local->tx_headroom +
  					4*6 /* four MAC addresses */
  					+ 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
  					+ 6 /* mesh */
  					+ 8 /* rfc1042/bridge tunnel */
  					- ETH_HLEN /* ethernet hard_header_len */
  					+ IEEE80211_ENCRYPT_HEADROOM;
  		ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
  
  		ret = dev_alloc_name(ndev, ndev->name);
  		if (ret < 0) {
e6436be21   Johannes Berg   mac80211: fix sta...
1853
  			ieee80211_if_free(ndev);
c7a61cba7   Johannes Berg   mac80211: free ne...
1854
  			free_netdev(ndev);
f142c6b90   Johannes Berg   mac80211: support...
1855
1856
1857
1858
  			return ret;
  		}
  
  		ieee80211_assign_perm_addr(local, ndev->perm_addr, type);
dd665d23c   Johannes Berg   mac80211: never p...
1859
  		if (is_valid_ether_addr(params->macaddr))
b5dfae020   Ben Greear   mac80211: support...
1860
1861
1862
  			memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN);
  		else
  			memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
f142c6b90   Johannes Berg   mac80211: support...
1863
1864
1865
1866
1867
1868
1869
  		SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
  
  		/* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */
  		sdata = netdev_priv(ndev);
  		ndev->ieee80211_ptr = &sdata->wdev;
  		memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN);
  		memcpy(sdata->name, ndev->name, IFNAMSIZ);
ba8c3d6f1   Felix Fietkau   mac80211: add an ...
1870
1871
  		if (txq_size) {
  			txqi = netdev_priv(ndev) + size;
fa962b921   Michal Kazior   mac80211: impleme...
1872
  			ieee80211_txq_init(sdata, NULL, txqi, 0);
ba8c3d6f1   Felix Fietkau   mac80211: add an ...
1873
  		}
f142c6b90   Johannes Berg   mac80211: support...
1874
1875
  		sdata->dev = ndev;
  	}
75636525f   Johannes Berg   mac80211: revamp ...
1876
1877
  
  	/* initialise type-independent data */
f0706e828   Jiri Benc   [MAC80211]: Add m...
1878
  	sdata->wdev.wiphy = local->hw.wiphy;
f0706e828   Jiri Benc   [MAC80211]: Add m...
1879
  	sdata->local = local;
75636525f   Johannes Berg   mac80211: revamp ...
1880
1881
1882
1883
1884
  
  	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
  		skb_queue_head_init(&sdata->fragments[i].skb_list);
  
  	INIT_LIST_HEAD(&sdata->key_list);
164eb02d0   Simon Wunderlich   mac80211: add rad...
1885
1886
  	INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work,
  			  ieee80211_dfs_cac_timer_work);
8d1f7ecd2   Johannes Berg   mac80211: defer t...
1887
1888
  	INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk,
  			  ieee80211_delayed_tailroom_dec);
97f97b1f5   Johannes Berg   mac80211: fix sta...
1889

57fbcce37   Johannes Berg   cfg80211: remove ...
1890
  	for (i = 0; i < NUM_NL80211_BANDS; i++) {
37eb0b164   Jouni Malinen   cfg80211/mac80211...
1891
1892
1893
1894
  		struct ieee80211_supported_band *sband;
  		sband = local->hw.wiphy->bands[i];
  		sdata->rc_rateidx_mask[i] =
  			sband ? (1 << sband->n_bitrates) - 1 : 0;
b119ad6e7   Lorenzo Bianconi   mac80211: add rat...
1895
1896
1897
  		if (sband) {
  			__le16 cap;
  			u16 *vht_rate_mask;
19468413e   Simon Wunderlich   mac80211: add sup...
1898
1899
1900
  			memcpy(sdata->rc_rateidx_mcs_mask[i],
  			       sband->ht_cap.mcs.rx_mask,
  			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
b119ad6e7   Lorenzo Bianconi   mac80211: add rat...
1901
1902
1903
1904
1905
  
  			cap = sband->vht_cap.vht_mcs.rx_mcs_map;
  			vht_rate_mask = sdata->rc_rateidx_vht_mcs_mask[i];
  			ieee80211_get_vht_mask_from_cap(cap, vht_rate_mask);
  		} else {
19468413e   Simon Wunderlich   mac80211: add sup...
1906
1907
  			memset(sdata->rc_rateidx_mcs_mask[i], 0,
  			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
b119ad6e7   Lorenzo Bianconi   mac80211: add rat...
1908
1909
1910
  			memset(sdata->rc_rateidx_vht_mcs_mask[i], 0,
  			       sizeof(sdata->rc_rateidx_vht_mcs_mask[i]));
  		}
37eb0b164   Jouni Malinen   cfg80211/mac80211...
1911
  	}
75636525f   Johannes Berg   mac80211: revamp ...
1912

3a25a8c8b   Johannes Berg   mac80211: add imp...
1913
  	ieee80211_set_default_queues(sdata);
1ea6f9c0d   Johannes Berg   mac80211: handle ...
1914
1915
  	sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
  	sdata->user_power_level = local->user_power_level;
2475b1cc0   Max Stepanov   mac80211: add gen...
1916
  	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
75636525f   Johannes Berg   mac80211: revamp ...
1917
1918
  	/* setup type-dependent data */
  	ieee80211_setup_sdata(sdata, type);
f0706e828   Jiri Benc   [MAC80211]: Add m...
1919

f142c6b90   Johannes Berg   mac80211: support...
1920
  	if (ndev) {
dd665d23c   Johannes Berg   mac80211: never p...
1921
1922
1923
  		ndev->ieee80211_ptr->use_4addr = params->use_4addr;
  		if (type == NL80211_IFTYPE_STATION)
  			sdata->u.mgd.use_4addr = params->use_4addr;
9bc383de3   Johannes Berg   cfg80211: introdu...
1924

f142c6b90   Johannes Berg   mac80211: support...
1925
  		ndev->features |= local->hw.netdev_features;
07b83d2ec   Johannes Berg   mac80211: allow c...
1926
1927
  		ndev->hw_features |= ndev->features &
  					MAC80211_SUPPORTED_FEATURES_TX;
72d787285   Arik Nemtsov   mac80211: allow l...
1928

b7ffbd7ef   Johannes Berg   cfg80211: make et...
1929
  		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
9c22b4a34   Jarod Wilson   net: use core MTU...
1930
1931
  		/* MTU range: 256 - 2304 */
  		ndev->min_mtu = 256;
06354665f   Wen Gong   mac80211: allow d...
1932
  		ndev->max_mtu = local->hw.max_mtu;
9c22b4a34   Jarod Wilson   net: use core MTU...
1933

f142c6b90   Johannes Berg   mac80211: support...
1934
1935
  		ret = register_netdevice(ndev);
  		if (ret) {
cf124db56   David S. Miller   net: Fix inconsis...
1936
  			free_netdev(ndev);
f142c6b90   Johannes Berg   mac80211: support...
1937
1938
1939
  			return ret;
  		}
  	}
f0706e828   Jiri Benc   [MAC80211]: Add m...
1940

c771c9d8d   Johannes Berg   mac80211: add int...
1941
  	mutex_lock(&local->iflist_mtx);
79010420c   Johannes Berg   [PATCH] mac80211:...
1942
  	list_add_tail_rcu(&sdata->list, &local->interfaces);
c771c9d8d   Johannes Berg   mac80211: add int...
1943
  	mutex_unlock(&local->iflist_mtx);
79010420c   Johannes Berg   [PATCH] mac80211:...
1944

84efbb84c   Johannes Berg   cfg80211: use wir...
1945
1946
  	if (new_wdev)
  		*new_wdev = &sdata->wdev;
f0706e828   Jiri Benc   [MAC80211]: Add m...
1947

f0706e828   Jiri Benc   [MAC80211]: Add m...
1948
  	return 0;
f0706e828   Jiri Benc   [MAC80211]: Add m...
1949
  }
f698d856f   Jasper Bryant-Greene   replace net_devic...
1950
  void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
f0706e828   Jiri Benc   [MAC80211]: Add m...
1951
  {
f0706e828   Jiri Benc   [MAC80211]: Add m...
1952
  	ASSERT_RTNL();
11a843b7e   Johannes Berg   [MAC80211]: rewor...
1953

c771c9d8d   Johannes Berg   mac80211: add int...
1954
  	mutex_lock(&sdata->local->iflist_mtx);
75636525f   Johannes Berg   mac80211: revamp ...
1955
  	list_del_rcu(&sdata->list);
c771c9d8d   Johannes Berg   mac80211: add int...
1956
  	mutex_unlock(&sdata->local->iflist_mtx);
f1267cf3c   Bhagavathi Perumal S   mac80211: Fix ker...
1957
1958
  	if (sdata->vif.txq)
  		ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq));
75636525f   Johannes Berg   mac80211: revamp ...
1959
  	synchronize_rcu();
f142c6b90   Johannes Berg   mac80211: support...
1960
1961
1962
1963
1964
  
  	if (sdata->dev) {
  		unregister_netdevice(sdata->dev);
  	} else {
  		cfg80211_unregister_wdev(&sdata->wdev);
835112b28   Eliad Peller   mac80211: don't t...
1965
  		ieee80211_teardown_sdata(sdata);
f142c6b90   Johannes Berg   mac80211: support...
1966
1967
1968
1969
1970
1971
1972
1973
1974
  		kfree(sdata);
  	}
  }
  
  void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata)
  {
  	if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state)))
  		return;
  	ieee80211_do_stop(sdata, true);
f0706e828   Jiri Benc   [MAC80211]: Add m...
1975
  }
75636525f   Johannes Berg   mac80211: revamp ...
1976
  void ieee80211_remove_interfaces(struct ieee80211_local *local)
f0706e828   Jiri Benc   [MAC80211]: Add m...
1977
  {
75636525f   Johannes Berg   mac80211: revamp ...
1978
  	struct ieee80211_sub_if_data *sdata, *tmp;
efe117ab8   Eric Dumazet   mac80211: Speedup...
1979
  	LIST_HEAD(unreg_list);
f142c6b90   Johannes Berg   mac80211: support...
1980
  	LIST_HEAD(wdev_list);
f0706e828   Jiri Benc   [MAC80211]: Add m...
1981
1982
  
  	ASSERT_RTNL();
d8d9008cf   Johannes Berg   mac80211: shut do...
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
  	/* Before destroying the interfaces, make sure they're all stopped so
  	 * that the hardware is stopped. Otherwise, the driver might still be
  	 * iterating the interfaces during the shutdown, e.g. from a worker
  	 * or from RX processing or similar, and if it does so (using atomic
  	 * iteration) while we're manipulating the list, the iteration will
  	 * crash.
  	 *
  	 * After this, the hardware should be stopped and the driver should
  	 * have stopped all of its activities, so that we can do RCU-unaware
  	 * manipulations of the interface list below.
c8aa22db0   Johannes Berg   mac80211: close A...
1993
  	 */
d8d9008cf   Johannes Berg   mac80211: shut do...
1994
1995
1996
1997
1998
  	cfg80211_shutdown_all_interfaces(local->hw.wiphy);
  
  	WARN(local->open_count, "%s: open count remains %d
  ",
  	     wiphy_name(local->hw.wiphy), local->open_count);
c8aa22db0   Johannes Berg   mac80211: close A...
1999

a50e5fb8d   Sara Sharon   mac80211: fix a k...
2000
  	ieee80211_txq_teardown_flows(local);
efe117ab8   Eric Dumazet   mac80211: Speedup...
2001
  	mutex_lock(&local->iflist_mtx);
75636525f   Johannes Berg   mac80211: revamp ...
2002
2003
  	list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
  		list_del(&sdata->list);
c771c9d8d   Johannes Berg   mac80211: add int...
2004

f142c6b90   Johannes Berg   mac80211: support...
2005
2006
2007
2008
  		if (sdata->dev)
  			unregister_netdevice_queue(sdata->dev, &unreg_list);
  		else
  			list_add(&sdata->list, &wdev_list);
f0706e828   Jiri Benc   [MAC80211]: Add m...
2009
  	}
efe117ab8   Eric Dumazet   mac80211: Speedup...
2010
2011
  	mutex_unlock(&local->iflist_mtx);
  	unregister_netdevice_many(&unreg_list);
f142c6b90   Johannes Berg   mac80211: support...
2012
2013
2014
2015
2016
2017
  
  	list_for_each_entry_safe(sdata, tmp, &wdev_list, list) {
  		list_del(&sdata->list);
  		cfg80211_unregister_wdev(&sdata->wdev);
  		kfree(sdata);
  	}
f0706e828   Jiri Benc   [MAC80211]: Add m...
2018
  }
5cff20e6c   Johannes Berg   mac80211: tell dr...
2019

47846c9b0   Johannes Berg   mac80211: reduce ...
2020
  static int netdev_notify(struct notifier_block *nb,
351638e7d   Jiri Pirko   net: pass info st...
2021
  			 unsigned long state, void *ptr)
47846c9b0   Johannes Berg   mac80211: reduce ...
2022
  {
351638e7d   Jiri Pirko   net: pass info st...
2023
  	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
47846c9b0   Johannes Berg   mac80211: reduce ...
2024
2025
2026
  	struct ieee80211_sub_if_data *sdata;
  
  	if (state != NETDEV_CHANGENAME)
8bd811aa6   Zhao, Gang   mac80211: change ...
2027
  		return NOTIFY_DONE;
47846c9b0   Johannes Berg   mac80211: reduce ...
2028
2029
  
  	if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
8bd811aa6   Zhao, Gang   mac80211: change ...
2030
  		return NOTIFY_DONE;
47846c9b0   Johannes Berg   mac80211: reduce ...
2031
2032
  
  	if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
8bd811aa6   Zhao, Gang   mac80211: change ...
2033
  		return NOTIFY_DONE;
47846c9b0   Johannes Berg   mac80211: reduce ...
2034
2035
  
  	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2f5265e6e   Johannes Berg   mac80211: fix net...
2036
  	memcpy(sdata->name, dev->name, IFNAMSIZ);
47846c9b0   Johannes Berg   mac80211: reduce ...
2037
  	ieee80211_debugfs_rename_netdev(sdata);
8bd811aa6   Zhao, Gang   mac80211: change ...
2038
2039
  
  	return NOTIFY_OK;
47846c9b0   Johannes Berg   mac80211: reduce ...
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
  }
  
  static struct notifier_block mac80211_netdev_notifier = {
  	.notifier_call = netdev_notify,
  };
  
  int ieee80211_iface_init(void)
  {
  	return register_netdevice_notifier(&mac80211_netdev_notifier);
  }
  
  void ieee80211_iface_exit(void)
  {
  	unregister_netdevice_notifier(&mac80211_netdev_notifier);
  }
72f15d53f   Michael Braun   mac80211: filter ...
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
  
  void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata)
  {
  	if (sdata->vif.type == NL80211_IFTYPE_AP)
  		atomic_inc(&sdata->u.ap.num_mcast_sta);
  	else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  		atomic_inc(&sdata->u.vlan.num_mcast_sta);
  }
  
  void ieee80211_vif_dec_num_mcast(struct ieee80211_sub_if_data *sdata)
  {
  	if (sdata->vif.type == NL80211_IFTYPE_AP)
  		atomic_dec(&sdata->u.ap.num_mcast_sta);
  	else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  		atomic_dec(&sdata->u.vlan.num_mcast_sta);
  }