Blame view
net/mac80211/main.c
29.6 KB
f0706e828 [MAC80211]: Add m... |
1 2 3 4 5 6 7 8 9 10 11 |
/* * Copyright 2002-2005, Instant802 Networks, Inc. * Copyright 2005-2006, Devicescape Software, Inc. * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <net/mac80211.h> |
f0706e828 [MAC80211]: Add m... |
12 13 14 15 16 17 18 19 |
#include <linux/module.h> #include <linux/init.h> #include <linux/netdevice.h> #include <linux/types.h> #include <linux/slab.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> #include <linux/if_arp.h> |
f0706e828 [MAC80211]: Add m... |
20 |
#include <linux/rtnetlink.h> |
f0706e828 [MAC80211]: Add m... |
21 |
#include <linux/bitmap.h> |
e8db0be12 PM QoS: Move and ... |
22 |
#include <linux/pm_qos.h> |
685429623 mac80211: Fix cir... |
23 |
#include <linux/inetdevice.h> |
881d966b4 [NET]: Make the d... |
24 |
#include <net/net_namespace.h> |
f0706e828 [MAC80211]: Add m... |
25 |
#include <net/cfg80211.h> |
f0706e828 [MAC80211]: Add m... |
26 |
#include "ieee80211_i.h" |
244879813 mac80211: add dri... |
27 |
#include "driver-ops.h" |
2c8dccc77 mac80211: rename ... |
28 |
#include "rate.h" |
f7a921443 mac80211: complet... |
29 |
#include "mesh.h" |
f0706e828 [MAC80211]: Add m... |
30 |
#include "wep.h" |
2c8dccc77 mac80211: rename ... |
31 |
#include "led.h" |
e0eb68596 [MAC80211]: renam... |
32 |
#include "cfg.h" |
e9f207f0f [MAC80211]: Add d... |
33 |
#include "debugfs.h" |
f0706e828 [MAC80211]: Add m... |
34 |
|
681c4d07d mac80211: fix loc... |
35 |
static struct lock_class_key ieee80211_rx_skb_queue_class; |
0d143fe1e mac80211: move re... |
36 |
void ieee80211_configure_filter(struct ieee80211_local *local) |
4150c5721 [PATCH] mac80211:... |
37 |
{ |
3ac64beec mac80211: allow c... |
38 |
u64 mc; |
4150c5721 [PATCH] mac80211:... |
39 40 |
unsigned int changed_flags; unsigned int new_flags = 0; |
53918994b [PATCH] mac80211:... |
41 |
if (atomic_read(&local->iff_promiscs)) |
4150c5721 [PATCH] mac80211:... |
42 |
new_flags |= FIF_PROMISC_IN_BSS; |
53918994b [PATCH] mac80211:... |
43 |
if (atomic_read(&local->iff_allmultis)) |
4150c5721 [PATCH] mac80211:... |
44 |
new_flags |= FIF_ALLMULTI; |
3ac64beec mac80211: allow c... |
45 |
if (local->monitors || local->scanning) |
8cc9a7391 mac80211: Use mon... |
46 |
new_flags |= FIF_BCN_PRBRESP_PROMISC; |
7be5086d4 mac80211: add pro... |
47 48 |
if (local->fif_probe_req || local->probe_req_reg) new_flags |= FIF_PROBE_REQ; |
8cc9a7391 mac80211: Use mon... |
49 50 51 52 53 54 55 56 57 58 59 |
if (local->fif_fcsfail) new_flags |= FIF_FCSFAIL; if (local->fif_plcpfail) new_flags |= FIF_PLCPFAIL; if (local->fif_control) new_flags |= FIF_CONTROL; if (local->fif_other_bss) new_flags |= FIF_OTHER_BSS; |
4150c5721 [PATCH] mac80211:... |
60 |
|
e3b90ca28 mac80211: FIF_PSP... |
61 62 |
if (local->fif_pspoll) new_flags |= FIF_PSPOLL; |
3ac64beec mac80211: allow c... |
63 |
spin_lock_bh(&local->filter_lock); |
4150c5721 [PATCH] mac80211:... |
64 |
changed_flags = local->filter_flags ^ new_flags; |
22bedad3c net: convert mult... |
65 |
mc = drv_prepare_multicast(local, &local->mc_list); |
3ac64beec mac80211: allow c... |
66 |
spin_unlock_bh(&local->filter_lock); |
4150c5721 [PATCH] mac80211:... |
67 68 |
/* be a bit nasty */ new_flags |= (1<<31); |
3ac64beec mac80211: allow c... |
69 |
drv_configure_filter(local, changed_flags, &new_flags, mc); |
4150c5721 [PATCH] mac80211:... |
70 71 72 73 74 |
WARN_ON(new_flags & (1<<31)); local->filter_flags = new_flags & ~(1<<31); } |
3ac64beec mac80211: allow c... |
75 76 77 78 79 80 81 |
static void ieee80211_reconfig_filter(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, reconfig_filter); ieee80211_configure_filter(local); } |
b23b025fe mac80211: Optimiz... |
82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
/* * Returns true if we are logically configured to be on * the operating channel AND the hardware-conf is currently * configured on the operating channel. Compares channel-type * as well. */ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) { struct ieee80211_channel *chan, *scan_chan; enum nl80211_channel_type channel_type; /* This logic needs to match logic in ieee80211_hw_config */ if (local->scan_channel) { chan = local->scan_channel; |
4f2e9d91f mac80211: Allow s... |
96 97 98 99 100 101 102 |
/* If scanning on oper channel, use whatever channel-type * is currently in use. */ if (chan == local->oper_channel) channel_type = local->_oper_channel_type; else channel_type = NL80211_CHAN_NO_HT; |
b23b025fe mac80211: Optimiz... |
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
} else if (local->tmp_channel) { chan = scan_chan = local->tmp_channel; channel_type = local->tmp_channel_type; } else { chan = local->oper_channel; channel_type = local->_oper_channel_type; } if (chan != local->oper_channel || channel_type != local->_oper_channel_type) return false; /* Check current hardware-config against oper_channel. */ if ((local->oper_channel != local->hw.conf.channel) || (local->_oper_channel_type != local->hw.conf.channel_type)) return false; return true; } |
e8975581f mac80211: introdu... |
122 |
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
b2c258fb1 [MAC80211]: reord... |
123 |
{ |
58905ca5b mac80211: fix sca... |
124 |
struct ieee80211_channel *chan, *scan_chan; |
b2c258fb1 [MAC80211]: reord... |
125 |
int ret = 0; |
e8975581f mac80211: introdu... |
126 |
int power; |
094d05dc3 mac80211: Fix HT ... |
127 |
enum nl80211_channel_type channel_type; |
ffd2778bb mac80211: fix dri... |
128 |
u32 offchannel_flag; |
f0706e828 [MAC80211]: Add m... |
129 |
|
cb121bad6 mac80211: add mig... |
130 |
might_sleep(); |
58905ca5b mac80211: fix sca... |
131 |
scan_chan = local->scan_channel; |
b23b025fe mac80211: Optimiz... |
132 133 134 |
/* If this off-channel logic ever changes, ieee80211_on_oper_channel * may need to change as well. */ |
ffd2778bb mac80211: fix dri... |
135 |
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
58905ca5b mac80211: fix sca... |
136 137 |
if (scan_chan) { chan = scan_chan; |
4f2e9d91f mac80211: Allow s... |
138 139 140 141 142 143 144 |
/* If scanning on oper channel, use whatever channel-type * is currently in use. */ if (chan == local->oper_channel) channel_type = local->_oper_channel_type; else channel_type = NL80211_CHAN_NO_HT; |
b23b025fe mac80211: Optimiz... |
145 |
} else if (local->tmp_channel) { |
b8bc4b0aa mac80211: support... |
146 147 |
chan = scan_chan = local->tmp_channel; channel_type = local->tmp_channel_type; |
72bdcf343 nl80211: Add freq... |
148 |
} else { |
b2c258fb1 [MAC80211]: reord... |
149 |
chan = local->oper_channel; |
0aaffa9b9 mac80211: improve... |
150 |
channel_type = local->_oper_channel_type; |
72bdcf343 nl80211: Add freq... |
151 |
} |
b23b025fe mac80211: Optimiz... |
152 153 154 155 156 157 |
if (chan != local->oper_channel || channel_type != local->_oper_channel_type) local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; else local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; |
ffd2778bb mac80211: fix dri... |
158 |
offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
f0706e828 [MAC80211]: Add m... |
159 |
|
ffd2778bb mac80211: fix dri... |
160 |
if (offchannel_flag || chan != local->hw.conf.channel || |
4797938c5 mac80211: clean u... |
161 |
channel_type != local->hw.conf.channel_type) { |
e8975581f mac80211: introdu... |
162 |
local->hw.conf.channel = chan; |
4797938c5 mac80211: clean u... |
163 |
local->hw.conf.channel_type = channel_type; |
e8975581f mac80211: introdu... |
164 165 |
changed |= IEEE80211_CONF_CHANGE_CHANNEL; } |
8318d78a4 cfg80211 API for ... |
166 |
|
0f78231bf mac80211: enable ... |
167 168 169 170 171 172 173 174 175 176 177 |
if (!conf_is_ht(&local->hw.conf)) { /* * mac80211.h documents that this is only valid * when the channel is set to an HT type, and * that otherwise STATIC is used. */ local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC; } else if (local->hw.conf.smps_mode != local->smps_mode) { local->hw.conf.smps_mode = local->smps_mode; changed |= IEEE80211_CONF_CHANGE_SMPS; } |
59bdf3b0f mac80211: Ensure ... |
178 179 |
if ((local->scanning & SCAN_SW_SCANNING) || (local->scanning & SCAN_HW_SCANNING)) |
e8975581f mac80211: introdu... |
180 |
power = chan->max_power; |
8318d78a4 cfg80211 API for ... |
181 |
else |
a8302de93 mac80211: Handle ... |
182 183 184 |
power = local->power_constr_level ? (chan->max_power - local->power_constr_level) : chan->max_power; |
47afbaf5a mac80211: correct... |
185 |
if (local->user_power_level >= 0) |
a8302de93 mac80211: Handle ... |
186 |
power = min(power, local->user_power_level); |
e8975581f mac80211: introdu... |
187 188 189 190 |
if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; local->hw.conf.power_level = power; } |
b2c258fb1 [MAC80211]: reord... |
191 |
|
e8975581f mac80211: introdu... |
192 |
if (changed && local->open_count) { |
244879813 mac80211: add dri... |
193 |
ret = drv_config(local, changed); |
d73782fdd mac80211: clean u... |
194 |
/* |
447107fb3 mac80211: remove ... |
195 |
* Goal: |
d73782fdd mac80211: clean u... |
196 197 |
* HW reconfiguration should never fail, the driver has told * us what it can support so it should live up to that promise. |
447107fb3 mac80211: remove ... |
198 199 200 201 202 203 204 205 206 |
* * Current status: * rfkill is not integrated with mac80211 and a * configuration command can thus fail if hardware rfkill * is enabled * * FIXME: integrate rfkill with mac80211 and then add this * WARN_ON() back * |
d73782fdd mac80211: clean u... |
207 |
*/ |
447107fb3 mac80211: remove ... |
208 |
/* WARN_ON(ret); */ |
d73782fdd mac80211: clean u... |
209 |
} |
f0706e828 [MAC80211]: Add m... |
210 |
|
b2c258fb1 [MAC80211]: reord... |
211 212 |
return ret; } |
f0706e828 [MAC80211]: Add m... |
213 |
|
471b3efdf mac80211: add uni... |
214 215 |
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, u32 changed) |
d9430a328 [MAC80211]: imple... |
216 |
{ |
471b3efdf mac80211: add uni... |
217 |
struct ieee80211_local *local = sdata->local; |
9cef87379 mac80211: fix man... |
218 |
static const u8 zero[ETH_ALEN] = { 0 }; |
471b3efdf mac80211: add uni... |
219 220 221 |
if (!changed) return; |
9cef87379 mac80211: fix man... |
222 223 224 225 226 227 228 229 230 231 232 |
if (sdata->vif.type == NL80211_IFTYPE_STATION) { /* * While not associated, claim a BSSID of all-zeroes * so that drivers don't do any weird things with the * BSSID at that time. */ if (sdata->vif.bss_conf.assoc) sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; else sdata->vif.bss_conf.bssid = zero; } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
2d0ddec5b mac80211: unify c... |
233 234 |
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; else if (sdata->vif.type == NL80211_IFTYPE_AP) |
47846c9b0 mac80211: reduce ... |
235 |
sdata->vif.bss_conf.bssid = sdata->vif.addr; |
1be7fe8de mac80211: fix for... |
236 237 |
else if (sdata->vif.type == NL80211_IFTYPE_WDS) sdata->vif.bss_conf.bssid = NULL; |
2d0ddec5b mac80211: unify c... |
238 |
else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
2d0ddec5b mac80211: unify c... |
239 240 241 242 243 244 245 246 247 |
sdata->vif.bss_conf.bssid = zero; } else { WARN_ON(1); return; } switch (sdata->vif.type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: |
1be7fe8de mac80211: fix for... |
248 |
case NL80211_IFTYPE_WDS: |
2d0ddec5b mac80211: unify c... |
249 250 251 252 253 254 255 256 257 258 259 |
case NL80211_IFTYPE_MESH_POINT: break; default: /* do not warn to simplify caller in scan.c */ changed &= ~BSS_CHANGED_BEACON_ENABLED; if (WARN_ON(changed & BSS_CHANGED_BEACON)) return; break; } if (changed & BSS_CHANGED_BEACON_ENABLED) { |
9607e6b66 mac80211: add iee... |
260 |
if (local->quiescing || !ieee80211_sdata_running(sdata) || |
b23b025fe mac80211: Optimiz... |
261 |
test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) { |
2d0ddec5b mac80211: unify c... |
262 263 264 265 266 267 268 269 270 |
sdata->vif.bss_conf.enable_beacon = false; } else { /* * Beacon should be enabled, but AP mode must * check whether there is a beacon configured. */ switch (sdata->vif.type) { case NL80211_IFTYPE_AP: sdata->vif.bss_conf.enable_beacon = |
0379185b6 mac80211: annotat... |
271 |
!!sdata->u.ap.beacon; |
2d0ddec5b mac80211: unify c... |
272 273 274 |
break; case NL80211_IFTYPE_ADHOC: sdata->vif.bss_conf.enable_beacon = |
0379185b6 mac80211: annotat... |
275 |
!!sdata->u.ibss.presp; |
2d0ddec5b mac80211: unify c... |
276 |
break; |
7659a193f mac80211: Fix com... |
277 |
#ifdef CONFIG_MAC80211_MESH |
2d0ddec5b mac80211: unify c... |
278 |
case NL80211_IFTYPE_MESH_POINT: |
29cbe68c5 cfg80211/mac80211... |
279 280 |
sdata->vif.bss_conf.enable_beacon = !!sdata->u.mesh.mesh_id_len; |
2d0ddec5b mac80211: unify c... |
281 |
break; |
7659a193f mac80211: Fix com... |
282 |
#endif |
2d0ddec5b mac80211: unify c... |
283 284 285 286 287 288 289 |
default: /* not reached */ WARN_ON(1); break; } } } |
12375ef93 mac80211: trace i... |
290 |
drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); |
d9430a328 [MAC80211]: imple... |
291 |
} |
f698d856f replace net_devic... |
292 |
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
d9430a328 [MAC80211]: imple... |
293 |
{ |
bda3933a8 mac80211: move bs... |
294 295 296 |
sdata->vif.bss_conf.use_cts_prot = false; sdata->vif.bss_conf.use_short_preamble = false; sdata->vif.bss_conf.use_short_slot = false; |
7a5158ef8 mac80211: fix sho... |
297 298 299 |
return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_SLOT; |
d9430a328 [MAC80211]: imple... |
300 |
} |
f0706e828 [MAC80211]: Add m... |
301 302 303 |
static void ieee80211_tasklet_handler(unsigned long data) { struct ieee80211_local *local = (struct ieee80211_local *) data; |
37fbd9080 mac80211: allow o... |
304 305 |
struct sta_info *sta, *tmp; struct skb_eosp_msg_data *eosp_data; |
f0706e828 [MAC80211]: Add m... |
306 |
struct sk_buff *skb; |
f0706e828 [MAC80211]: Add m... |
307 308 309 310 311 |
while ((skb = skb_dequeue(&local->skb_queue)) || (skb = skb_dequeue(&local->skb_queue_unreliable))) { switch (skb->pkt_type) { case IEEE80211_RX_MSG: |
51fb61e76 mac80211: move in... |
312 |
/* Clear skb->pkt_type in order to not confuse kernel |
f0706e828 [MAC80211]: Add m... |
313 314 |
* netstack. */ skb->pkt_type = 0; |
f1d58c252 mac80211: push rx... |
315 |
ieee80211_rx(local_to_hw(local), skb); |
f0706e828 [MAC80211]: Add m... |
316 317 |
break; case IEEE80211_TX_STATUS_MSG: |
f0706e828 [MAC80211]: Add m... |
318 |
skb->pkt_type = 0; |
e039fa4a4 mac80211: move TX... |
319 |
ieee80211_tx_status(local_to_hw(local), skb); |
f0706e828 [MAC80211]: Add m... |
320 |
break; |
37fbd9080 mac80211: allow o... |
321 322 323 324 325 326 327 328 329 330 331 332 |
case IEEE80211_EOSP_MSG: eosp_data = (void *)skb->cb; for_each_sta_info(local, eosp_data->sta, sta, tmp) { /* skip wrong virtual interface */ if (memcmp(eosp_data->iface, sta->sdata->vif.addr, ETH_ALEN)) continue; clear_sta_flag(sta, WLAN_STA_SP); break; } dev_kfree_skb(skb); break; |
f4ea83dd7 mac80211: rework ... |
333 |
default: |
5e3f30899 mac80211: Print u... |
334 335 336 |
WARN(1, "mac80211: Packet is of unknown type %d ", skb->pkt_type); |
f0706e828 [MAC80211]: Add m... |
337 338 339 340 341 |
dev_kfree_skb(skb); break; } } } |
f2753ddba mac80211: add har... |
342 343 344 345 |
static void ieee80211_restart_work(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, restart_work); |
bc86863de mac80211: perform... |
346 347 348 349 |
/* wait for scan work complete */ flush_workqueue(local->workqueue); mutex_lock(&local->mtx); |
79f460ca4 mac80211: add sup... |
350 351 |
WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || local->sched_scanning, |
bc86863de mac80211: perform... |
352 353 354 |
"%s called with hardware scan in progress ", __func__); mutex_unlock(&local->mtx); |
f2753ddba mac80211: add har... |
355 |
rtnl_lock(); |
4136c4224 mac80211: assure ... |
356 |
ieee80211_scan_cancel(local); |
f2753ddba mac80211: add har... |
357 358 359 360 361 362 363 |
ieee80211_reconfig(local); rtnl_unlock(); } void ieee80211_restart_hw(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); |
b5878a2dc mac80211: enhance... |
364 |
trace_api_restart_hw(local); |
b196d031f mac80211: Add log... |
365 366 367 |
wiphy_info(hw->wiphy, "Hardware restart was requested "); |
18145c693 mac80211: cancel ... |
368 |
/* use this reason, ieee80211_reconfig will unblock it */ |
f2753ddba mac80211: add har... |
369 370 371 372 373 374 |
ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); schedule_work(&local->restart_work); } EXPORT_SYMBOL(ieee80211_restart_hw); |
0f78231bf mac80211: enable ... |
375 376 377 378 379 380 |
static void ieee80211_recalc_smps_work(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, recalc_smps); mutex_lock(&local->iflist_mtx); |
025e6be22 mac80211: fix dea... |
381 |
ieee80211_recalc_smps(local); |
0f78231bf mac80211: enable ... |
382 383 |
mutex_unlock(&local->iflist_mtx); } |
26b36cfef mac80211: make AR... |
384 |
#ifdef CONFIG_INET |
2b2c009ec mac80211: Add sup... |
385 386 387 388 389 390 391 392 393 |
static int ieee80211_ifa_changed(struct notifier_block *nb, unsigned long data, void *arg) { struct in_ifaddr *ifa = arg; struct ieee80211_local *local = container_of(nb, struct ieee80211_local, ifa_notifier); struct net_device *ndev = ifa->ifa_dev->dev; struct wireless_dev *wdev = ndev->ieee80211_ptr; |
685429623 mac80211: Fix cir... |
394 |
struct in_device *idev; |
2b2c009ec mac80211: Add sup... |
395 |
struct ieee80211_sub_if_data *sdata; |
685429623 mac80211: Fix cir... |
396 |
struct ieee80211_bss_conf *bss_conf; |
2b2c009ec mac80211: Add sup... |
397 |
struct ieee80211_if_managed *ifmgd; |
685429623 mac80211: Fix cir... |
398 |
int c = 0; |
2b2c009ec mac80211: Add sup... |
399 400 401 402 403 404 405 |
/* Make sure it's our interface that got changed */ if (!wdev) return NOTIFY_DONE; if (wdev->wiphy != local->hw.wiphy) return NOTIFY_DONE; |
2b2c009ec mac80211: Add sup... |
406 |
sdata = IEEE80211_DEV_TO_SUB_IF(ndev); |
685429623 mac80211: Fix cir... |
407 |
bss_conf = &sdata->vif.bss_conf; |
2b2c009ec mac80211: Add sup... |
408 |
|
26a58456b mac80211: switch ... |
409 410 |
if (!ieee80211_sdata_running(sdata)) return NOTIFY_DONE; |
2b2c009ec mac80211: Add sup... |
411 412 413 |
/* ARP filtering is only supported in managed mode */ if (sdata->vif.type != NL80211_IFTYPE_STATION) return NOTIFY_DONE; |
95ae6b228 ipv4: ip_ptr clea... |
414 |
idev = __in_dev_get_rtnl(sdata->dev); |
685429623 mac80211: Fix cir... |
415 416 |
if (!idev) return NOTIFY_DONE; |
2b2c009ec mac80211: Add sup... |
417 418 |
ifmgd = &sdata->u.mgd; mutex_lock(&ifmgd->mtx); |
685429623 mac80211: Fix cir... |
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
/* Copy the addresses to the bss_conf list */ ifa = idev->ifa_list; while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) { bss_conf->arp_addr_list[c] = ifa->ifa_address; ifa = ifa->ifa_next; c++; } /* If not all addresses fit the list, disable filtering */ if (ifa) { sdata->arp_filter_state = false; c = 0; } else { sdata->arp_filter_state = true; } bss_conf->arp_addr_cnt = c; /* Configure driver only if associated */ if (ifmgd->associated) { bss_conf->arp_filter_enabled = sdata->arp_filter_state; ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_ARP_FILTER); } |
2b2c009ec mac80211: Add sup... |
443 444 445 446 |
mutex_unlock(&ifmgd->mtx); return NOTIFY_DONE; } |
26b36cfef mac80211: make AR... |
447 |
#endif |
2b2c009ec mac80211: Add sup... |
448 |
|
4e6cbfd09 mac80211: support... |
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
static int ieee80211_napi_poll(struct napi_struct *napi, int budget) { struct ieee80211_local *local = container_of(napi, struct ieee80211_local, napi); return local->ops->napi_poll(&local->hw, budget); } void ieee80211_napi_schedule(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); napi_schedule(&local->napi); } EXPORT_SYMBOL(ieee80211_napi_schedule); void ieee80211_napi_complete(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); napi_complete(&local->napi); } EXPORT_SYMBOL(ieee80211_napi_complete); |
2e161f78e cfg80211/mac80211... |
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
/* There isn't a lot of sense in it, but you can transmit anything you like */ static const struct ieee80211_txrx_stypes ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_ADHOC] = { .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ACTION >> 4), }, [NL80211_IFTYPE_STATION] = { .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4), }, [NL80211_IFTYPE_AP] = { .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_DISASSOC >> 4) | BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4), }, [NL80211_IFTYPE_AP_VLAN] = { /* copy AP */ .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_DISASSOC >> 4) | BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4) | |
2ca27bcff mac80211: add p2p... |
503 504 505 506 507 508 509 510 511 512 513 514 |
BIT(IEEE80211_STYPE_ACTION >> 4), }, [NL80211_IFTYPE_P2P_CLIENT] = { .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4), }, [NL80211_IFTYPE_P2P_GO] = { .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | |
2e161f78e cfg80211/mac80211... |
515 516 517 518 519 |
BIT(IEEE80211_STYPE_DISASSOC >> 4) | BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4), }, |
c7108a711 mac80211: Send me... |
520 521 |
[NL80211_IFTYPE_MESH_POINT] = { .tx = 0xffff, |
71839121a mac80211: Let use... |
522 523 524 |
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4), |
c7108a711 mac80211: Send me... |
525 |
}, |
2e161f78e cfg80211/mac80211... |
526 |
}; |
f0706e828 [MAC80211]: Add m... |
527 528 529 |
struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { |
f0706e828 [MAC80211]: Add m... |
530 |
struct ieee80211_local *local; |
96f5e66e8 mac80211: fix agg... |
531 |
int priv_size, i; |
f0706e828 [MAC80211]: Add m... |
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
struct wiphy *wiphy; /* Ensure 32-byte alignment of our private data and hw private data. * We use the wiphy priv data for both our ieee80211_local and for * the driver's private data * * In memory it'll be like this: * * +-------------------------+ * | struct wiphy | * +-------------------------+ * | struct ieee80211_local | * +-------------------------+ * | driver's private data | * +-------------------------+ * */ |
1ce8e7b57 net: ALIGN/PTR_AL... |
549 |
priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; |
f0706e828 [MAC80211]: Add m... |
550 551 552 553 554 |
wiphy = wiphy_new(&mac80211_config_ops, priv_size); if (!wiphy) return NULL; |
2e161f78e cfg80211/mac80211... |
555 |
wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; |
207aba601 mac80211: support... |
556 |
wiphy->privid = mac80211_wiphy_privid; |
9bc383de3 cfg80211: introdu... |
557 558 |
wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP | |
f0dc7999b cfg80211: Remove ... |
559 |
WIPHY_FLAG_4ADDR_STATION; |
207aba601 mac80211: support... |
560 561 562 |
if (!ops->set_key) wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
18a836599 cfg80211: introdu... |
563 |
|
0c1ad2cac mac80211: proper ... |
564 |
wiphy->bss_priv_size = sizeof(struct ieee80211_bss); |
f0706e828 [MAC80211]: Add m... |
565 566 |
local = wiphy_priv(wiphy); |
de95a54b1 mac80211: pass al... |
567 |
|
f0706e828 [MAC80211]: Add m... |
568 |
local->hw.wiphy = wiphy; |
1ce8e7b57 net: ALIGN/PTR_AL... |
569 |
local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); |
f0706e828 [MAC80211]: Add m... |
570 |
|
4480f15ca [PATCH] mac80211:... |
571 |
BUG_ON(!ops->tx); |
4150c5721 [PATCH] mac80211:... |
572 573 |
BUG_ON(!ops->start); BUG_ON(!ops->stop); |
4480f15ca [PATCH] mac80211:... |
574 575 |
BUG_ON(!ops->config); BUG_ON(!ops->add_interface); |
4150c5721 [PATCH] mac80211:... |
576 577 |
BUG_ON(!ops->remove_interface); BUG_ON(!ops->configure_filter); |
f0706e828 [MAC80211]: Add m... |
578 |
local->ops = ops; |
e6a9854b0 mac80211/drivers:... |
579 580 581 |
/* set up some defaults */ local->hw.queues = 1; local->hw.max_rates = 1; |
78be49ec2 mac80211: distinc... |
582 |
local->hw.max_report_rates = 0; |
df6ba5d80 mac80211: add hw ... |
583 |
local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF; |
39e68712d mac80211: Don't u... |
584 |
local->hw.max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF; |
b9a5f8cab nl80211: Add set/... |
585 586 |
local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
c428c8920 mac80211: default... |
587 |
local->user_power_level = -1; |
50ae0cf15 mac80211: add deb... |
588 589 |
local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; |
f0706e828 [MAC80211]: Add m... |
590 |
|
79010420c [PATCH] mac80211:... |
591 |
INIT_LIST_HEAD(&local->interfaces); |
2f787b0b7 mac80211: Ensure ... |
592 593 |
__hw_addr_init(&local->mc_list); |
c771c9d8d mac80211: add int... |
594 |
mutex_init(&local->iflist_mtx); |
a1699b75a mac80211: unify s... |
595 |
mutex_init(&local->mtx); |
f0706e828 [MAC80211]: Add m... |
596 |
|
ad0e2b5a0 mac80211: simplif... |
597 |
mutex_init(&local->key_mtx); |
3b8d81e02 mac80211: remove ... |
598 |
spin_lock_init(&local->filter_lock); |
ce7c9111a mac80211: track m... |
599 |
spin_lock_init(&local->queue_stop_reason_lock); |
681c4d07d mac80211: fix loc... |
600 601 602 603 604 605 606 607 608 |
/* * The rx_skb_queue is only accessed from tasklets, * but other SKB queues are used from within IRQ * context. Therefore, this one needs a different * locking class so our direct, non-irq-safe use of * the queue's lock doesn't throw lockdep warnings. */ skb_queue_head_init_class(&local->rx_skb_queue, &ieee80211_rx_skb_queue_class); |
24a8fdad3 mac80211: seriali... |
609 |
|
c2b13452b mac80211: clean u... |
610 |
INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
f0706e828 [MAC80211]: Add m... |
611 |
|
af6b63741 mac80211: general... |
612 |
ieee80211_work_init(local); |
f2753ddba mac80211: add har... |
613 |
INIT_WORK(&local->restart_work, ieee80211_restart_work); |
3ac64beec mac80211: allow c... |
614 |
INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); |
0f78231bf mac80211: enable ... |
615 616 |
INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work); local->smps_mode = IEEE80211_SMPS_OFF; |
3ac64beec mac80211: allow c... |
617 |
|
520eb8207 mac80211: impleme... |
618 619 620 621 622 623 |
INIT_WORK(&local->dynamic_ps_enable_work, ieee80211_dynamic_ps_enable_work); INIT_WORK(&local->dynamic_ps_disable_work, ieee80211_dynamic_ps_disable_work); setup_timer(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, (unsigned long) local); |
85a9994a0 cfg80211/mac80211... |
624 625 |
INIT_WORK(&local->sched_scan_stopped_work, ieee80211_sched_scan_stopped_work); |
f0706e828 [MAC80211]: Add m... |
626 |
sta_info_init(local); |
a6a67db2b mac80211: refcoun... |
627 |
for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { |
2a577d987 mac80211: rework ... |
628 |
skb_queue_head_init(&local->pending[i]); |
a6a67db2b mac80211: refcoun... |
629 630 |
atomic_set(&local->agg_queue_stop[i], 0); } |
f0706e828 [MAC80211]: Add m... |
631 632 |
tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, (unsigned long)local); |
f0706e828 [MAC80211]: Add m... |
633 634 635 636 |
tasklet_init(&local->tasklet, ieee80211_tasklet_handler, (unsigned long) local); |
f0706e828 [MAC80211]: Add m... |
637 638 639 |
skb_queue_head_init(&local->skb_queue); skb_queue_head_init(&local->skb_queue_unreliable); |
4e6cbfd09 mac80211: support... |
640 641 |
/* init dummy netdev for use w/ NAPI */ init_dummy_netdev(&local->napi_dev); |
fe67c913f mac80211: make LE... |
642 |
ieee80211_led_names(local); |
21f835896 mac80211: impleme... |
643 |
ieee80211_hw_roc_setup(local); |
f0706e828 [MAC80211]: Add m... |
644 645 646 647 648 649 650 |
return local_to_hw(local); } EXPORT_SYMBOL(ieee80211_alloc_hw); int ieee80211_register_hw(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); |
7527a782e cfg80211: adverti... |
651 |
int result, i; |
8318d78a4 cfg80211 API for ... |
652 |
enum ieee80211_band band; |
be4a4b6a5 mac80211: improve... |
653 |
int channels, max_bitrates; |
5ef2d41af mac80211: include... |
654 |
bool supp_ht; |
25e47c18a cfg80211: add cip... |
655 |
static const u32 cipher_suites[] = { |
5daa8a8e6 mac80211: dont ad... |
656 |
/* keep WEP first, it may be removed below */ |
25e47c18a cfg80211: add cip... |
657 658 659 660 661 662 663 664 |
WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, /* keep last -- depends on hw flags! */ WLAN_CIPHER_SUITE_AES_CMAC }; |
8318d78a4 cfg80211 API for ... |
665 |
|
38bb3e9da mac80211: Fix bui... |
666 667 668 669 670 |
if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) #ifdef CONFIG_PM && (!local->ops->suspend || !local->ops->resume) #endif ) |
eecc48000 mac80211: add bas... |
671 |
return -EINVAL; |
78be49ec2 mac80211: distinc... |
672 673 |
if (hw->max_report_rates == 0) hw->max_report_rates = hw->max_rates; |
8318d78a4 cfg80211 API for ... |
674 675 676 677 678 |
/* * generic code guarantees at least one band, * set this very early because much code assumes * that hw.conf.channel is assigned */ |
2a5193119 cfg80211/nl80211:... |
679 |
channels = 0; |
de95a54b1 mac80211: pass al... |
680 |
max_bitrates = 0; |
5ef2d41af mac80211: include... |
681 |
supp_ht = false; |
8318d78a4 cfg80211 API for ... |
682 683 684 685 |
for (band = 0; band < IEEE80211_NUM_BANDS; band++) { struct ieee80211_supported_band *sband; sband = local->hw.wiphy->bands[band]; |
de95a54b1 mac80211: pass al... |
686 687 688 |
if (!sband) continue; if (!local->oper_channel) { |
8318d78a4 cfg80211 API for ... |
689 690 |
/* init channel we're on */ local->hw.conf.channel = |
58905ca5b mac80211: fix sca... |
691 692 |
local->oper_channel = &sband->channels[0]; local->hw.conf.channel_type = NL80211_CHAN_NO_HT; |
8318d78a4 cfg80211 API for ... |
693 |
} |
de95a54b1 mac80211: pass al... |
694 695 696 697 |
channels += sband->n_channels; if (max_bitrates < sband->n_bitrates) max_bitrates = sband->n_bitrates; |
5ef2d41af mac80211: include... |
698 |
supp_ht = supp_ht || sband->ht_cap.ht_supported; |
8318d78a4 cfg80211 API for ... |
699 |
} |
f0706e828 [MAC80211]: Add m... |
700 |
|
5ba63533b cfg80211: fix ali... |
701 702 703 |
local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + sizeof(void *) * channels, GFP_KERNEL); if (!local->int_scan_req) |
2a5193119 cfg80211/nl80211:... |
704 |
return -ENOMEM; |
c72e8d335 mac80211: fill ra... |
705 706 707 708 709 |
for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (!local->hw.wiphy->bands[band]) continue; local->int_scan_req->rates[band] = (u32) -1; } |
f59ac0481 cfg80211: keep tr... |
710 |
/* if low-level driver supports AP, we also support VLAN */ |
7527a782e cfg80211: adverti... |
711 712 713 714 |
if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); } |
f59ac0481 cfg80211: keep tr... |
715 716 |
/* mac80211 always supports monitor */ |
7527a782e cfg80211: adverti... |
717 718 |
hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); |
8e621fc90 mac80211: verify ... |
719 720 721 722 723 724 725 726 727 728 729 |
/* * mac80211 doesn't support more than 1 channel, and also not more * than one IBSS interface */ for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { const struct ieee80211_iface_combination *c; int j; c = &hw->wiphy->iface_combinations[i]; if (c->num_different_channels > 1) |
7527a782e cfg80211: adverti... |
730 |
return -EINVAL; |
f59ac0481 cfg80211: keep tr... |
731 |
|
8e621fc90 mac80211: verify ... |
732 733 734 735 736 |
for (j = 0; j < c->n_limits; j++) if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && c->limits[j].max > 1) return -EINVAL; } |
5eb5a52da mac80211: fix mes... |
737 738 739 740 |
#ifndef CONFIG_MAC80211_MESH /* mesh depends on Kconfig, but drivers should set it if they want */ local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); #endif |
1570ca592 mac80211: send no... |
741 742 743 744 |
/* if the underlying driver supports mesh, mac80211 will (at least) * provide routing of mesh authentication frames to userspace */ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) local->hw.wiphy->flags |= WIPHY_FLAG_MESH_AUTH; |
a621fa4d6 mac80211: allow c... |
745 746 |
/* mac80211 supports control port protocol changing */ local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; |
77965c970 cfg80211: clean u... |
747 748 749 750 |
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; |
ab13315af mac80211: add U-A... |
751 752 753 754 |
WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK), "U-APSD not supported with HW_PS_NULLFUNC_STACK "); |
de95a54b1 mac80211: pass al... |
755 756 757 |
/* * Calculate scan IE length -- we need this to alloc * memory and to subtract from the driver limit. It |
dc9f48ce7 mac80211: Fix sca... |
758 |
* includes the DS Params, (extended) supported rates, and HT |
de95a54b1 mac80211: pass al... |
759 760 |
* information -- SSID is the driver's responsibility. */ |
dc9f48ce7 mac80211: Fix sca... |
761 762 |
local->scan_ies_len = 4 + max_bitrates /* (ext) supp rates */ + 3 /* DS Params */; |
5ef2d41af mac80211: include... |
763 764 |
if (supp_ht) local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); |
de95a54b1 mac80211: pass al... |
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
if (!local->ops->hw_scan) { /* For hw_scan, driver needs to set these up. */ local->hw.wiphy->max_scan_ssids = 4; local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; } /* * If the driver supports any scan IEs, then assume the * limit includes the IEs mac80211 will add, otherwise * leave it at zero and let the driver sort it out; we * still pass our IEs to the driver but userspace will * not be allowed to in that case. */ if (local->hw.wiphy->max_scan_ie_len) local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; |
3ffc2a905 mac80211: allow v... |
781 782 783 784 785 786 787 |
/* Set up cipher suites unless driver already did */ if (!local->hw.wiphy->cipher_suites) { local->hw.wiphy->cipher_suites = cipher_suites; local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) local->hw.wiphy->n_cipher_suites--; } |
5daa8a8e6 mac80211: dont ad... |
788 |
if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { |
3ffc2a905 mac80211: allow v... |
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
if (local->hw.wiphy->cipher_suites == cipher_suites) { local->hw.wiphy->cipher_suites += 2; local->hw.wiphy->n_cipher_suites -= 2; } else { u32 *suites; int r, w = 0; /* Filter out WEP */ suites = kmemdup( local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); if (!suites) return -ENOMEM; for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || suite == WLAN_CIPHER_SUITE_WEP104) continue; suites[w++] = suite; } local->hw.wiphy->cipher_suites = suites; local->hw.wiphy->n_cipher_suites = w; local->wiphy_ciphers_allocated = true; } |
5daa8a8e6 mac80211: dont ad... |
815 |
} |
25e47c18a cfg80211: add cip... |
816 |
|
21f835896 mac80211: impleme... |
817 818 |
if (!local->ops->remain_on_channel) local->hw.wiphy->max_remain_on_channel_duration = 5000; |
a293911d4 nl80211: advertis... |
819 |
|
79f460ca4 mac80211: add sup... |
820 821 |
if (local->ops->sched_scan_start) local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
dfe018bf9 mac80211: handle ... |
822 823 824 |
/* mac80211 based drivers don't support internal TDLS setup */ if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; |
f0706e828 [MAC80211]: Add m... |
825 826 |
result = wiphy_register(local->hw.wiphy); if (result < 0) |
2a5193119 cfg80211/nl80211:... |
827 |
goto fail_wiphy_register; |
f0706e828 [MAC80211]: Add m... |
828 |
|
e25300836 mac80211: use mul... |
829 830 831 832 |
/* * We use the number of queues for feature tests (QoS, HT) internally * so restrict them appropriately. */ |
e25300836 mac80211: use mul... |
833 834 |
if (hw->queues > IEEE80211_MAX_QUEUES) hw->queues = IEEE80211_MAX_QUEUES; |
e25300836 mac80211: use mul... |
835 |
|
42935ecaf mac80211: redefin... |
836 |
local->workqueue = |
99b88a0ec mac80211: cancel ... |
837 |
alloc_ordered_workqueue(wiphy_name(local->hw.wiphy), 0); |
42935ecaf mac80211: redefin... |
838 |
if (!local->workqueue) { |
f0706e828 [MAC80211]: Add m... |
839 840 841 |
result = -ENOMEM; goto fail_workqueue; } |
b306f4530 [PATCH] mac80211:... |
842 843 844 845 846 |
/* * The hardware needs headroom for sending the frame, * and we need some headroom for passing the frame to monitor * interfaces, but never both at the same time. */ |
33ccad35a [PATCH] mac80211:... |
847 |
local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, |
a2fe81667 mac80211: Build T... |
848 |
IEEE80211_TX_STATUS_HEADROOM); |
b306f4530 [PATCH] mac80211:... |
849 |
|
e9f207f0f [MAC80211]: Add d... |
850 |
debugfs_hw_add(local); |
b446918b7 mac80211: use lis... |
851 852 853 854 |
/* * if the driver doesn't specify a max listen interval we * use 5 which should be a safe default */ |
ea95bba41 mac80211: make li... |
855 |
if (local->hw.max_listen_interval == 0) |
b446918b7 mac80211: use lis... |
856 |
local->hw.max_listen_interval = 5; |
ea95bba41 mac80211: make li... |
857 858 |
local->hw.conf.listen_interval = local->hw.max_listen_interval; |
ff6163810 mac80211: Fix ps-... |
859 |
local->dynamic_ps_forced_timeout = -1; |
195e294d2 mac80211: Determi... |
860 |
|
d4c4a9a1b mac80211: fix mod... |
861 |
result = ieee80211_wep_init(local); |
3473187d2 mac80211: remove ... |
862 |
if (result < 0) |
0fb9a9ec2 net/mac80211: Use... |
863 864 865 |
wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d ", result); |
d4c4a9a1b mac80211: fix mod... |
866 |
|
f0706e828 [MAC80211]: Add m... |
867 |
rtnl_lock(); |
f0706e828 [MAC80211]: Add m... |
868 |
|
830f90386 mac80211: allow d... |
869 870 |
result = ieee80211_init_rate_ctrl_alg(local, hw->rate_control_algorithm); |
f0706e828 [MAC80211]: Add m... |
871 |
if (result < 0) { |
0fb9a9ec2 net/mac80211: Use... |
872 873 874 |
wiphy_debug(local->hw.wiphy, "Failed to initialize rate control algorithm "); |
f0706e828 [MAC80211]: Add m... |
875 876 |
goto fail_rate; } |
8dffff216 mac80211: only cr... |
877 878 879 880 881 |
/* add one default STA interface if supported */ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { result = ieee80211_if_add(local, "wlan%d", NULL, NL80211_IFTYPE_STATION, NULL); if (result) |
0fb9a9ec2 net/mac80211: Use... |
882 883 884 |
wiphy_warn(local->hw.wiphy, "Failed to add default virtual iface "); |
8dffff216 mac80211: only cr... |
885 |
} |
f0706e828 [MAC80211]: Add m... |
886 |
|
f0706e828 [MAC80211]: Add m... |
887 888 889 |
rtnl_unlock(); ieee80211_led_init(local); |
10f644a47 mac80211: disable... |
890 891 892 893 |
local->network_latency_notifier.notifier_call = ieee80211_max_network_latency; result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); |
10f644a47 mac80211: disable... |
894 895 896 897 |
if (result) { rtnl_lock(); goto fail_pm_qos; } |
26b36cfef mac80211: make AR... |
898 |
#ifdef CONFIG_INET |
2b2c009ec mac80211: Add sup... |
899 900 901 902 |
local->ifa_notifier.notifier_call = ieee80211_ifa_changed; result = register_inetaddr_notifier(&local->ifa_notifier); if (result) goto fail_ifa; |
26b36cfef mac80211: make AR... |
903 |
#endif |
2b2c009ec mac80211: Add sup... |
904 |
|
4e6cbfd09 mac80211: support... |
905 906 |
netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, local->hw.napi_weight); |
f0706e828 [MAC80211]: Add m... |
907 |
return 0; |
93c08c329 mac80211: Fix com... |
908 |
#ifdef CONFIG_INET |
2b2c009ec mac80211: Add sup... |
909 910 911 912 |
fail_ifa: pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); rtnl_lock(); |
93c08c329 mac80211: Fix com... |
913 |
#endif |
10f644a47 mac80211: disable... |
914 915 916 |
fail_pm_qos: ieee80211_led_exit(local); ieee80211_remove_interfaces(local); |
10f644a47 mac80211: disable... |
917 |
fail_rate: |
f0706e828 [MAC80211]: Add m... |
918 |
rtnl_unlock(); |
d4c4a9a1b mac80211: fix mod... |
919 |
ieee80211_wep_free(local); |
f0706e828 [MAC80211]: Add m... |
920 |
sta_info_stop(local); |
42935ecaf mac80211: redefin... |
921 |
destroy_workqueue(local->workqueue); |
10f644a47 mac80211: disable... |
922 |
fail_workqueue: |
f0706e828 [MAC80211]: Add m... |
923 |
wiphy_unregister(local->hw.wiphy); |
10f644a47 mac80211: disable... |
924 |
fail_wiphy_register: |
3ffc2a905 mac80211: allow v... |
925 926 |
if (local->wiphy_ciphers_allocated) kfree(local->hw.wiphy->cipher_suites); |
11ba964d4 mac80211: fix reg... |
927 |
kfree(local->int_scan_req); |
f0706e828 [MAC80211]: Add m... |
928 929 930 |
return result; } EXPORT_SYMBOL(ieee80211_register_hw); |
f0706e828 [MAC80211]: Add m... |
931 932 933 |
void ieee80211_unregister_hw(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); |
f0706e828 [MAC80211]: Add m... |
934 935 936 |
tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); |
10f644a47 mac80211: disable... |
937 938 |
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); |
26b36cfef mac80211: make AR... |
939 |
#ifdef CONFIG_INET |
2b2c009ec mac80211: Add sup... |
940 |
unregister_inetaddr_notifier(&local->ifa_notifier); |
26b36cfef mac80211: make AR... |
941 |
#endif |
10f644a47 mac80211: disable... |
942 |
|
f0706e828 [MAC80211]: Add m... |
943 |
rtnl_lock(); |
79010420c [PATCH] mac80211:... |
944 945 946 947 948 |
/* * At this point, interface list manipulations are fine * because the driver cannot be handing us frames any * more and the tasklet is killed. */ |
75636525f mac80211: revamp ... |
949 |
ieee80211_remove_interfaces(local); |
5b2812e92 [PATCH] mac80211:... |
950 |
|
f0706e828 [MAC80211]: Add m... |
951 |
rtnl_unlock(); |
071249b1d mac80211: delete ... |
952 953 954 955 956 |
/* * Now all work items will be gone, but the * timer might still be armed, so delete it */ del_timer_sync(&local->work_timer); |
258086a48 mac80211: cancel ... |
957 |
cancel_work_sync(&local->restart_work); |
3ac64beec mac80211: allow c... |
958 |
cancel_work_sync(&local->reconfig_filter); |
f0706e828 [MAC80211]: Add m... |
959 |
ieee80211_clear_tx_pending(local); |
f0706e828 [MAC80211]: Add m... |
960 |
rate_control_deinitialize(local); |
f64f9e719 net: Move && and ... |
961 962 |
if (skb_queue_len(&local->skb_queue) || skb_queue_len(&local->skb_queue_unreliable)) |
0fb9a9ec2 net/mac80211: Use... |
963 964 |
wiphy_warn(local->hw.wiphy, "skb_queue not empty "); |
f0706e828 [MAC80211]: Add m... |
965 966 |
skb_queue_purge(&local->skb_queue); skb_queue_purge(&local->skb_queue_unreliable); |
24a8fdad3 mac80211: seriali... |
967 |
skb_queue_purge(&local->rx_skb_queue); |
f0706e828 [MAC80211]: Add m... |
968 |
|
42935ecaf mac80211: redefin... |
969 |
destroy_workqueue(local->workqueue); |
f0706e828 [MAC80211]: Add m... |
970 |
wiphy_unregister(local->hw.wiphy); |
ecb443355 mac80211: fix sus... |
971 |
sta_info_stop(local); |
f0706e828 [MAC80211]: Add m... |
972 973 |
ieee80211_wep_free(local); ieee80211_led_exit(local); |
5ba63533b cfg80211: fix ali... |
974 |
kfree(local->int_scan_req); |
f0706e828 [MAC80211]: Add m... |
975 976 977 978 979 980 |
} EXPORT_SYMBOL(ieee80211_unregister_hw); void ieee80211_free_hw(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); |
c771c9d8d mac80211: add int... |
981 |
mutex_destroy(&local->iflist_mtx); |
a1699b75a mac80211: unify s... |
982 |
mutex_destroy(&local->mtx); |
c771c9d8d mac80211: add int... |
983 |
|
3ffc2a905 mac80211: allow v... |
984 985 |
if (local->wiphy_ciphers_allocated) kfree(local->hw.wiphy->cipher_suites); |
f0706e828 [MAC80211]: Add m... |
986 987 988 |
wiphy_free(local->hw.wiphy); } EXPORT_SYMBOL(ieee80211_free_hw); |
f0706e828 [MAC80211]: Add m... |
989 990 991 992 |
static int __init ieee80211_init(void) { struct sk_buff *skb; int ret; |
e039fa4a4 mac80211: move TX... |
993 994 |
BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + |
c6a1fa12d mac80211: minor c... |
995 |
IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); |
f0706e828 [MAC80211]: Add m... |
996 |
|
cccf129f8 mac80211: add the... |
997 998 999 |
ret = rc80211_minstrel_init(); if (ret) return ret; |
ec8aa669b mac80211: add the... |
1000 1001 1002 |
ret = rc80211_minstrel_ht_init(); if (ret) goto err_minstrel; |
4b475898e mac80211: better ... |
1003 |
ret = rc80211_pid_init(); |
ad0183759 mac80211: add PID... |
1004 |
if (ret) |
47846c9b0 mac80211: reduce ... |
1005 |
goto err_pid; |
f0706e828 [MAC80211]: Add m... |
1006 |
|
47846c9b0 mac80211: reduce ... |
1007 1008 1009 |
ret = ieee80211_iface_init(); if (ret) goto err_netdev; |
e9f207f0f [MAC80211]: Add d... |
1010 |
|
f0706e828 [MAC80211]: Add m... |
1011 |
return 0; |
47846c9b0 mac80211: reduce ... |
1012 1013 1014 |
err_netdev: rc80211_pid_exit(); err_pid: |
ec8aa669b mac80211: add the... |
1015 1016 |
rc80211_minstrel_ht_exit(); err_minstrel: |
47846c9b0 mac80211: reduce ... |
1017 1018 1019 |
rc80211_minstrel_exit(); return ret; |
f0706e828 [MAC80211]: Add m... |
1020 |
} |
f0706e828 [MAC80211]: Add m... |
1021 1022 |
static void __exit ieee80211_exit(void) { |
4b475898e mac80211: better ... |
1023 |
rc80211_pid_exit(); |
ec8aa669b mac80211: add the... |
1024 |
rc80211_minstrel_ht_exit(); |
cccf129f8 mac80211: add the... |
1025 |
rc80211_minstrel_exit(); |
ac71c691e mac80211: make si... |
1026 |
|
f7a921443 mac80211: complet... |
1027 1028 |
if (mesh_allocated) ieee80211s_stop(); |
902acc789 mac80211: clean u... |
1029 |
|
47846c9b0 mac80211: reduce ... |
1030 |
ieee80211_iface_exit(); |
d07c7cf49 mac80211: add mis... |
1031 1032 |
rcu_barrier(); |
f0706e828 [MAC80211]: Add m... |
1033 |
} |
ca9938fea [PATCH] mac80211:... |
1034 |
subsys_initcall(ieee80211_init); |
f0706e828 [MAC80211]: Add m... |
1035 1036 1037 1038 |
module_exit(ieee80211_exit); MODULE_DESCRIPTION("IEEE 802.11 subsystem"); MODULE_LICENSE("GPL"); |