Blame view
net/wireless/core.c
39.2 KB
09c434b8a treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
704232c27 [WIRELESS] cfg802... |
2 3 4 |
/* * This is the linux wireless configuration interface. * |
5f2aa25e0 cfg80211: rcu-ify... |
5 |
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
2740f0cf8 cfg80211: add Int... |
6 |
* Copyright 2013-2014 Intel Mobile Communications GmbH |
c4cbaf797 cfg80211: Add sup... |
7 |
* Copyright 2015-2017 Intel Deutschland GmbH |
461ce35d5 cfg80211: reject ... |
8 |
* Copyright (C) 2018-2020 Intel Corporation |
704232c27 [WIRELESS] cfg802... |
9 |
*/ |
e9c0268f0 net/wireless: Use... |
10 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
704232c27 [WIRELESS] cfg802... |
11 12 13 |
#include <linux/if.h> #include <linux/module.h> #include <linux/err.h> |
704232c27 [WIRELESS] cfg802... |
14 |
#include <linux/list.h> |
5a0e3ad6a include cleanup: ... |
15 |
#include <linux/slab.h> |
704232c27 [WIRELESS] cfg802... |
16 17 18 19 |
#include <linux/nl80211.h> #include <linux/debugfs.h> #include <linux/notifier.h> #include <linux/device.h> |
16a832e78 cfg80211: allow c... |
20 |
#include <linux/etherdevice.h> |
1f87f7d3a cfg80211: add rfk... |
21 |
#include <linux/rtnetlink.h> |
d43c36dc6 headers: remove s... |
22 |
#include <linux/sched.h> |
704232c27 [WIRELESS] cfg802... |
23 24 |
#include <net/genetlink.h> #include <net/cfg80211.h> |
556829657 [NL80211]: add ne... |
25 |
#include "nl80211.h" |
704232c27 [WIRELESS] cfg802... |
26 27 |
#include "core.h" #include "sysfs.h" |
1ac61302d mac80211/cfg80211... |
28 |
#include "debugfs.h" |
a9a11622c cfg80211: self-co... |
29 |
#include "wext-compat.h" |
e35e4d28b cfg80211: add wra... |
30 |
#include "rdev-ops.h" |
704232c27 [WIRELESS] cfg802... |
31 32 33 34 35 36 37 |
/* name for sysfs, %d is appended */ #define PHY_NAME "phy" MODULE_AUTHOR("Johannes Berg"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("wireless configuration support"); |
fb4e15688 nl80211: Add gene... |
38 |
MODULE_ALIAS_GENL_FAMILY(NL80211_GENL_NAME); |
704232c27 [WIRELESS] cfg802... |
39 |
|
5fe231e87 cfg80211: vastly ... |
40 |
/* RCU-protected (and RTNL for writers) */ |
79c97e97a cfg80211: clean u... |
41 |
LIST_HEAD(cfg80211_rdev_list); |
f5ea9120b nl80211: add gene... |
42 |
int cfg80211_rdev_list_generation; |
a1794390f cfg80211: rename ... |
43 |
|
704232c27 [WIRELESS] cfg802... |
44 45 |
/* for debugfs */ static struct dentry *ieee80211_debugfs_dir; |
e60d7443e wireless : use a ... |
46 47 |
/* for the cleanup, scan and event works */ struct workqueue_struct *cfg80211_wq; |
40db6c77a cfg80211: module_... |
48 49 50 51 |
static bool cfg80211_disable_40mhz_24ghz; module_param(cfg80211_disable_40mhz_24ghz, bool, 0644); MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz, "Disable 40MHz support in the 2.4GHz band"); |
79c97e97a cfg80211: clean u... |
52 |
struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) |
556829657 [NL80211]: add ne... |
53 |
{ |
79c97e97a cfg80211: clean u... |
54 |
struct cfg80211_registered_device *result = NULL, *rdev; |
556829657 [NL80211]: add ne... |
55 |
|
5fe231e87 cfg80211: vastly ... |
56 |
ASSERT_RTNL(); |
761cf7ecf cfg80211: add ass... |
57 |
|
79c97e97a cfg80211: clean u... |
58 59 60 |
list_for_each_entry(rdev, &cfg80211_rdev_list, list) { if (rdev->wiphy_idx == wiphy_idx) { result = rdev; |
556829657 [NL80211]: add ne... |
61 62 63 64 65 66 |
break; } } return result; } |
806a9e396 cfg80211: make re... |
67 68 |
int get_wiphy_idx(struct wiphy *wiphy) { |
f26cbf401 cfg80211: change ... |
69 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
f41737669 cfg80211: remove ... |
70 |
|
79c97e97a cfg80211: clean u... |
71 |
return rdev->wiphy_idx; |
806a9e396 cfg80211: make re... |
72 |
} |
806a9e396 cfg80211: make re... |
73 74 |
struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) { |
79c97e97a cfg80211: clean u... |
75 |
struct cfg80211_registered_device *rdev; |
806a9e396 cfg80211: make re... |
76 |
|
5fe231e87 cfg80211: vastly ... |
77 |
ASSERT_RTNL(); |
806a9e396 cfg80211: make re... |
78 |
|
79c97e97a cfg80211: clean u... |
79 80 |
rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx); if (!rdev) |
806a9e396 cfg80211: make re... |
81 |
return NULL; |
79c97e97a cfg80211: clean u... |
82 |
return &rdev->wiphy; |
806a9e396 cfg80211: make re... |
83 |
} |
1998d90ad cfg80211: support... |
84 85 |
static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev, const char *newname) |
556829657 [NL80211]: add ne... |
86 |
{ |
79c97e97a cfg80211: clean u... |
87 |
struct cfg80211_registered_device *rdev2; |
1998d90ad cfg80211: support... |
88 |
int wiphy_idx, taken = -1, digits; |
556829657 [NL80211]: add ne... |
89 |
|
5fe231e87 cfg80211: vastly ... |
90 |
ASSERT_RTNL(); |
2940bb69f wireless: Add mis... |
91 |
|
a7cfebcb7 cfg80211: limit w... |
92 93 |
if (strlen(newname) > NL80211_WIPHY_NAME_MAXLEN) return -EINVAL; |
7623225f9 Revert "wireless:... |
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
/* prohibit calling the thing phy%d when %d is not its number */ sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) { /* count number of places needed to print wiphy_idx */ digits = 1; while (wiphy_idx /= 10) digits++; /* * deny the name if it is phy<idx> where <idx> is printed * without leading zeroes. taken == strlen(newname) here */ if (taken == strlen(PHY_NAME) + digits) return -EINVAL; } |
1998d90ad cfg80211: support... |
108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
/* Ensure another device does not already have this name. */ list_for_each_entry(rdev2, &cfg80211_rdev_list, list) if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0) return -EINVAL; return 0; } int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, char *newname) { int result; ASSERT_RTNL(); |
7623225f9 Revert "wireless:... |
122 |
|
2940bb69f wireless: Add mis... |
123 |
/* Ignore nop renames */ |
1998d90ad cfg80211: support... |
124 |
if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0) |
4bbf4d565 cfg80211: fix loc... |
125 |
return 0; |
2940bb69f wireless: Add mis... |
126 |
|
1998d90ad cfg80211: support... |
127 128 129 |
result = cfg80211_dev_check_name(rdev, newname); if (result < 0) return result; |
556829657 [NL80211]: add ne... |
130 |
|
556829657 [NL80211]: add ne... |
131 132 |
result = device_rename(&rdev->wiphy.dev, newname); if (result) |
4bbf4d565 cfg80211: fix loc... |
133 |
return result; |
556829657 [NL80211]: add ne... |
134 |
|
0bbab5f03 cfg80211: fix deb... |
135 |
if (!IS_ERR_OR_NULL(rdev->wiphy.debugfsdir)) |
d82574a8e cfg80211: no need... |
136 137 138 |
debugfs_rename(rdev->wiphy.debugfsdir->d_parent, rdev->wiphy.debugfsdir, rdev->wiphy.debugfsdir->d_parent, newname); |
556829657 [NL80211]: add ne... |
139 |
|
3bb205567 cfg80211: send ev... |
140 |
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); |
556829657 [NL80211]: add ne... |
141 |
|
4bbf4d565 cfg80211: fix loc... |
142 |
return 0; |
556829657 [NL80211]: add ne... |
143 |
} |
463d01832 cfg80211: make aw... |
144 145 146 147 148 |
int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, struct net *net) { struct wireless_dev *wdev; int err = 0; |
5be83de54 cfg80211: convert... |
149 |
if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) |
463d01832 cfg80211: make aw... |
150 |
return -EOPNOTSUPP; |
53873f134 cfg80211: make wd... |
151 |
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { |
ba22fb5b2 nl80211: don't as... |
152 153 |
if (!wdev->netdev) continue; |
463d01832 cfg80211: make aw... |
154 155 156 157 158 159 160 161 162 163 |
wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); if (err) break; wdev->netdev->features |= NETIF_F_NETNS_LOCAL; } if (err) { /* failed -- clean up to old netns */ net = wiphy_net(&rdev->wiphy); |
53873f134 cfg80211: make wd... |
164 165 |
list_for_each_entry_continue_reverse(wdev, &rdev->wiphy.wdev_list, |
463d01832 cfg80211: make aw... |
166 |
list) { |
ba22fb5b2 nl80211: don't as... |
167 168 |
if (!wdev->netdev) continue; |
463d01832 cfg80211: make aw... |
169 170 171 172 173 174 |
wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); WARN_ON(err); wdev->netdev->features |= NETIF_F_NETNS_LOCAL; } |
046007949 cfg80211: support... |
175 176 |
return err; |
463d01832 cfg80211: make aw... |
177 |
} |
c90b670b5 nl80211: announce... |
178 179 180 181 182 183 |
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE); } nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); |
463d01832 cfg80211: make aw... |
184 |
wiphy_net_set(&rdev->wiphy, net); |
046007949 cfg80211: support... |
185 186 |
err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev)); WARN_ON(err); |
c90b670b5 nl80211: announce... |
187 188 189 190 191 192 |
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE); } |
046007949 cfg80211: support... |
193 |
return 0; |
463d01832 cfg80211: make aw... |
194 |
} |
1f87f7d3a cfg80211: add rfk... |
195 196 |
static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) { |
79c97e97a cfg80211: clean u... |
197 |
struct cfg80211_registered_device *rdev = data; |
1f87f7d3a cfg80211: add rfk... |
198 |
|
e35e4d28b cfg80211: add wra... |
199 |
rdev_rfkill_poll(rdev); |
1f87f7d3a cfg80211: add rfk... |
200 |
} |
f9f475292 cfg80211: always ... |
201 202 203 |
void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) { |
5fe231e87 cfg80211: vastly ... |
204 |
ASSERT_RTNL(); |
f9f475292 cfg80211: always ... |
205 206 207 |
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)) return; |
73c7da3da cfg80211: add gen... |
208 |
if (!wdev_running(wdev)) |
f9f475292 cfg80211: always ... |
209 210 211 |
return; rdev_stop_p2p_device(rdev, wdev); |
73c7da3da cfg80211: add gen... |
212 |
wdev->is_running = false; |
f9f475292 cfg80211: always ... |
213 214 |
rdev->opencount--; |
a617302c5 cfg80211: fix sca... |
215 |
if (rdev->scan_req && rdev->scan_req->wdev == wdev) { |
c8cb5b854 nl80211/cfg80211:... |
216 217 218 |
if (WARN_ON(!rdev->scan_req->notified && (!rdev->int_scan_req || !rdev->int_scan_req->notified))) |
1d76250bd nl80211: support ... |
219 |
rdev->scan_req->info.aborted = true; |
f9d15d162 cfg80211: send sc... |
220 |
___cfg80211_scan_done(rdev, false); |
a617302c5 cfg80211: fix sca... |
221 |
} |
f9f475292 cfg80211: always ... |
222 |
} |
cb3b7d876 cfg80211: add sta... |
223 224 225 226 227 228 229 |
void cfg80211_stop_nan(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) { ASSERT_RTNL(); if (WARN_ON(wdev->iftype != NL80211_IFTYPE_NAN)) return; |
73c7da3da cfg80211: add gen... |
230 |
if (!wdev_running(wdev)) |
cb3b7d876 cfg80211: add sta... |
231 232 233 |
return; rdev_stop_nan(rdev, wdev); |
73c7da3da cfg80211: add gen... |
234 |
wdev->is_running = false; |
cb3b7d876 cfg80211: add sta... |
235 236 237 |
rdev->opencount--; } |
f6837ba8c mac80211: handle ... |
238 |
void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy) |
1f87f7d3a cfg80211: add rfk... |
239 |
{ |
f6837ba8c mac80211: handle ... |
240 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1f87f7d3a cfg80211: add rfk... |
241 |
struct wireless_dev *wdev; |
f6837ba8c mac80211: handle ... |
242 |
ASSERT_RTNL(); |
f9f475292 cfg80211: always ... |
243 |
|
53873f134 cfg80211: make wd... |
244 |
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { |
98104fded cfg80211: add P2P... |
245 |
if (wdev->netdev) { |
ba22fb5b2 nl80211: don't as... |
246 |
dev_close(wdev->netdev); |
98104fded cfg80211: add P2P... |
247 248 249 250 251 |
continue; } /* otherwise, check iftype */ switch (wdev->iftype) { case NL80211_IFTYPE_P2P_DEVICE: |
f9f475292 cfg80211: always ... |
252 |
cfg80211_stop_p2p_device(rdev, wdev); |
98104fded cfg80211: add P2P... |
253 |
break; |
cb3b7d876 cfg80211: add sta... |
254 255 256 |
case NL80211_IFTYPE_NAN: cfg80211_stop_nan(rdev, wdev); break; |
98104fded cfg80211: add P2P... |
257 258 259 260 |
default: break; } } |
f6837ba8c mac80211: handle ... |
261 262 |
} EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces); |
1f87f7d3a cfg80211: add rfk... |
263 |
|
f6837ba8c mac80211: handle ... |
264 265 266 267 268 269 270 271 272 |
static int cfg80211_rfkill_set_block(void *data, bool blocked) { struct cfg80211_registered_device *rdev = data; if (!blocked) return 0; rtnl_lock(); cfg80211_shutdown_all_interfaces(&rdev->wiphy); |
1f87f7d3a cfg80211: add rfk... |
273 274 275 276 |
rtnl_unlock(); return 0; } |
3cfe91c4c cfg80211: always ... |
277 |
static void cfg80211_rfkill_block_work(struct work_struct *work) |
1f87f7d3a cfg80211: add rfk... |
278 |
{ |
79c97e97a cfg80211: clean u... |
279 |
struct cfg80211_registered_device *rdev; |
1f87f7d3a cfg80211: add rfk... |
280 |
|
3cfe91c4c cfg80211: always ... |
281 282 283 |
rdev = container_of(work, struct cfg80211_registered_device, rfkill_block); cfg80211_rfkill_set_block(rdev, true); |
1f87f7d3a cfg80211: add rfk... |
284 |
} |
667503ddc cfg80211: fix loc... |
285 286 287 |
static void cfg80211_event_work(struct work_struct *work) { struct cfg80211_registered_device *rdev; |
667503ddc cfg80211: fix loc... |
288 289 290 291 292 |
rdev = container_of(work, struct cfg80211_registered_device, event_work); rtnl_lock(); |
3d54d2551 cfg80211: clean u... |
293 |
cfg80211_process_rdev_events(rdev); |
667503ddc cfg80211: fix loc... |
294 295 |
rtnl_unlock(); } |
78f22b6a3 cfg80211: allow u... |
296 297 |
void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev) { |
ab81007a7 cfg80211: simplif... |
298 |
struct wireless_dev *wdev, *tmp; |
78f22b6a3 cfg80211: allow u... |
299 300 |
ASSERT_RTNL(); |
ab81007a7 cfg80211: simplif... |
301 302 303 |
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) { if (wdev->nl_owner_dead) rdev_del_virtual_intf(rdev, wdev); |
78f22b6a3 cfg80211: allow u... |
304 |
} |
78f22b6a3 cfg80211: allow u... |
305 306 307 308 309 310 311 312 313 314 315 316 317 |
} static void cfg80211_destroy_iface_wk(struct work_struct *work) { struct cfg80211_registered_device *rdev; rdev = container_of(work, struct cfg80211_registered_device, destroy_work); rtnl_lock(); cfg80211_destroy_ifaces(rdev); rtnl_unlock(); } |
93a1e86ce nl80211: Stop sch... |
318 319 320 |
static void cfg80211_sched_scan_stop_wk(struct work_struct *work) { struct cfg80211_registered_device *rdev; |
ca986ad9b nl80211: allow mu... |
321 |
struct cfg80211_sched_scan_request *req, *tmp; |
93a1e86ce nl80211: Stop sch... |
322 323 324 325 326 |
rdev = container_of(work, struct cfg80211_registered_device, sched_scan_stop_wk); rtnl_lock(); |
ca986ad9b nl80211: allow mu... |
327 328 329 330 |
list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) { if (req->nl_owner_dead) cfg80211_stop_sched_scan_req(rdev, req, false); } |
93a1e86ce nl80211: Stop sch... |
331 332 |
rtnl_unlock(); } |
897667273 cfg80211: Share C... |
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
static void cfg80211_propagate_radar_detect_wk(struct work_struct *work) { struct cfg80211_registered_device *rdev; rdev = container_of(work, struct cfg80211_registered_device, propagate_radar_detect_wk); rtnl_lock(); regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->radar_chandef, NL80211_DFS_UNAVAILABLE, NL80211_RADAR_DETECTED); rtnl_unlock(); } static void cfg80211_propagate_cac_done_wk(struct work_struct *work) { struct cfg80211_registered_device *rdev; rdev = container_of(work, struct cfg80211_registered_device, propagate_cac_done_wk); rtnl_lock(); regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->cac_done_chandef, NL80211_DFS_AVAILABLE, NL80211_RADAR_CAC_FINISHED); rtnl_unlock(); } |
704232c27 [WIRELESS] cfg802... |
364 |
/* exported functions */ |
1998d90ad cfg80211: support... |
365 366 |
struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, const char *requested_name) |
704232c27 [WIRELESS] cfg802... |
367 |
{ |
73810b77d cfg80211: use ato... |
368 |
static atomic_t wiphy_counter = ATOMIC_INIT(0); |
7623225f9 Revert "wireless:... |
369 370 |
struct cfg80211_registered_device *rdev; |
704232c27 [WIRELESS] cfg802... |
371 |
int alloc_size; |
0b20633d9 cfg80211: disallo... |
372 373 374 375 376 377 378 |
WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); WARN_ON(ops->connect && !ops->disconnect); WARN_ON(ops->join_ibss && !ops->leave_ibss); WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf); WARN_ON(ops->add_station && !ops->del_station); WARN_ON(ops->add_mpath && !ops->del_mpath); |
29cbe68c5 cfg80211/mac80211... |
379 |
WARN_ON(ops->join_mesh && !ops->leave_mesh); |
de3bb771f cfg80211: add mor... |
380 381 382 383 384 385 386 387 |
WARN_ON(ops->start_p2p_device && !ops->stop_p2p_device); WARN_ON(ops->start_ap && !ops->stop_ap); WARN_ON(ops->join_ocb && !ops->leave_ocb); WARN_ON(ops->suspend && !ops->resume); WARN_ON(ops->sched_scan_start && !ops->sched_scan_stop); WARN_ON(ops->remain_on_channel && !ops->cancel_remain_on_channel); WARN_ON(ops->tdls_channel_switch && !ops->tdls_cancel_channel_switch); WARN_ON(ops->add_tx_ts && !ops->del_tx_ts); |
41ade00f2 cfg80211/nl80211:... |
388 |
|
79c97e97a cfg80211: clean u... |
389 |
alloc_size = sizeof(*rdev) + sizeof_priv; |
704232c27 [WIRELESS] cfg802... |
390 |
|
79c97e97a cfg80211: clean u... |
391 392 |
rdev = kzalloc(alloc_size, GFP_KERNEL); if (!rdev) |
704232c27 [WIRELESS] cfg802... |
393 |
return NULL; |
79c97e97a cfg80211: clean u... |
394 |
rdev->ops = ops; |
704232c27 [WIRELESS] cfg802... |
395 |
|
73810b77d cfg80211: use ato... |
396 |
rdev->wiphy_idx = atomic_inc_return(&wiphy_counter); |
a4d73ee16 [WIRELESS] cfg802... |
397 |
|
f41737669 cfg80211: remove ... |
398 |
if (unlikely(rdev->wiphy_idx < 0)) { |
7623225f9 Revert "wireless:... |
399 |
/* ugh, wrapped! */ |
73810b77d cfg80211: use ato... |
400 |
atomic_dec(&wiphy_counter); |
79c97e97a cfg80211: clean u... |
401 |
kfree(rdev); |
704232c27 [WIRELESS] cfg802... |
402 403 |
return NULL; } |
704232c27 [WIRELESS] cfg802... |
404 |
|
9b881963c cfg80211: make wi... |
405 406 |
/* atomic_inc_return makes it start at 1, make it start at 0 */ rdev->wiphy_idx--; |
7623225f9 Revert "wireless:... |
407 |
/* give it a proper name */ |
1998d90ad cfg80211: support... |
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
if (requested_name && requested_name[0]) { int rv; rtnl_lock(); rv = cfg80211_dev_check_name(rdev, requested_name); if (rv < 0) { rtnl_unlock(); goto use_default_name; } rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name); rtnl_unlock(); if (rv) goto use_default_name; } else { |
59b179b48 cfg80211: check d... |
424 |
int rv; |
1998d90ad cfg80211: support... |
425 426 427 428 429 430 431 |
use_default_name: /* NOTE: This is *probably* safe w/out holding rtnl because of * the restrictions on phy names. Probably this call could * fail if some other part of the kernel (re)named a device * phyX. But, might should add some locking and check return * value, and use a different name if this one exists? */ |
59b179b48 cfg80211: check d... |
432 433 434 435 436 |
rv = dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); if (rv < 0) { kfree(rdev); return NULL; } |
1998d90ad cfg80211: support... |
437 |
} |
7623225f9 Revert "wireless:... |
438 |
|
53873f134 cfg80211: make wd... |
439 |
INIT_LIST_HEAD(&rdev->wiphy.wdev_list); |
37c73b5f3 cfg80211: allow r... |
440 441 |
INIT_LIST_HEAD(&rdev->beacon_registrations); spin_lock_init(&rdev->beacon_registrations_lock); |
79c97e97a cfg80211: clean u... |
442 443 |
spin_lock_init(&rdev->bss_lock); INIT_LIST_HEAD(&rdev->bss_list); |
ca986ad9b nl80211: allow mu... |
444 |
INIT_LIST_HEAD(&rdev->sched_scan_req_list); |
79c97e97a cfg80211: clean u... |
445 |
INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); |
04f39047a nl80211/cfg80211:... |
446 447 |
INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk, cfg80211_dfs_channels_update_work); |
3d23e349d wext: refactor |
448 449 450 |
#ifdef CONFIG_CFG80211_WEXT rdev->wiphy.wext = &cfg80211_wext_handler; #endif |
79c97e97a cfg80211: clean u... |
451 452 453 |
device_initialize(&rdev->wiphy.dev); rdev->wiphy.dev.class = &ieee80211_class; rdev->wiphy.dev.platform_data = rdev; |
9f0e13546 net/wireless: ena... |
454 |
device_enable_async_suspend(&rdev->wiphy.dev); |
79c97e97a cfg80211: clean u... |
455 |
|
78f22b6a3 cfg80211: allow u... |
456 |
INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk); |
93a1e86ce nl80211: Stop sch... |
457 |
INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk); |
b34939b98 cfg80211: add req... |
458 |
INIT_WORK(&rdev->sched_scan_res_wk, cfg80211_sched_scan_results_wk); |
897667273 cfg80211: Share C... |
459 460 461 |
INIT_WORK(&rdev->propagate_radar_detect_wk, cfg80211_propagate_radar_detect_wk); INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk); |
79ea1e12c cfg80211: fix man... |
462 463 |
INIT_WORK(&rdev->mgmt_registrations_update_wk, cfg80211_mgmt_registrations_update_wk); |
78f22b6a3 cfg80211: allow u... |
464 |
|
5be83de54 cfg80211: convert... |
465 466 467 |
#ifdef CONFIG_CFG80211_DEFAULT_PS rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; #endif |
16cb9d42b cfg80211: allow d... |
468 |
|
463d01832 cfg80211: make aw... |
469 |
wiphy_net_set(&rdev->wiphy, &init_net); |
79c97e97a cfg80211: clean u... |
470 471 472 473 474 475 |
rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block; rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev), &rdev->wiphy.dev, RFKILL_TYPE_WLAN, &rdev->rfkill_ops, rdev); if (!rdev->rfkill) { |
4f488fbca cfg80211: fix mem... |
476 |
wiphy_free(&rdev->wiphy); |
1f87f7d3a cfg80211: add rfk... |
477 478 |
return NULL; } |
3cfe91c4c cfg80211: always ... |
479 |
INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); |
79c97e97a cfg80211: clean u... |
480 481 |
INIT_WORK(&rdev->conn_work, cfg80211_conn_work); INIT_WORK(&rdev->event_work, cfg80211_event_work); |
1f87f7d3a cfg80211: add rfk... |
482 |
|
ad002395f cfg80211: fix dan... |
483 |
init_waitqueue_head(&rdev->dev_wait); |
b9a5f8cab nl80211: Add set/... |
484 485 486 487 488 |
/* * Initialize wiphy parameters to IEEE 802.11 MIB default values. * Fragmentation and RTS threshold are disabled by default with the * special -1 value. */ |
79c97e97a cfg80211: clean u... |
489 490 491 492 |
rdev->wiphy.retry_short = 7; rdev->wiphy.retry_long = 4; rdev->wiphy.frag_threshold = (u32) -1; rdev->wiphy.rts_threshold = (u32) -1; |
81077e82c nl80211: Add new ... |
493 |
rdev->wiphy.coverage_class = 0; |
b9a5f8cab nl80211: Add set/... |
494 |
|
9a774c78e cfg80211: Support... |
495 |
rdev->wiphy.max_num_csa_counters = 1; |
3b06d2779 cfg80211: Add mul... |
496 497 |
rdev->wiphy.max_sched_scan_plans = 1; rdev->wiphy.max_sched_scan_plan_interval = U32_MAX; |
79c97e97a cfg80211: clean u... |
498 |
return &rdev->wiphy; |
704232c27 [WIRELESS] cfg802... |
499 |
} |
1998d90ad cfg80211: support... |
500 |
EXPORT_SYMBOL(wiphy_new_nm); |
704232c27 [WIRELESS] cfg802... |
501 |
|
7527a782e cfg80211: adverti... |
502 503 504 505 |
static int wiphy_verify_combinations(struct wiphy *wiphy) { const struct ieee80211_iface_combination *c; int i, j; |
7527a782e cfg80211: adverti... |
506 507 508 509 510 |
for (i = 0; i < wiphy->n_iface_combinations; i++) { u32 cnt = 0; u16 all_iftypes = 0; c = &wiphy->iface_combinations[i]; |
11c4a075d cfg80211: check r... |
511 512 513 514 515 |
/* * Combinations with just one interface aren't real, * however we make an exception for DFS. */ if (WARN_ON((c->max_interfaces < 2) && !c->radar_detect_widths)) |
7527a782e cfg80211: adverti... |
516 517 518 519 520 |
return -EINVAL; /* Need at least one channel */ if (WARN_ON(!c->num_different_channels)) return -EINVAL; |
d4e50c591 cfg80211: add cha... |
521 522 523 524 525 526 527 |
/* * Put a sane limit on maximum number of different * channels to simplify channel accounting code. */ if (WARN_ON(c->num_different_channels > CFG80211_MAX_NUM_DIFFERENT_CHANNELS)) return -EINVAL; |
11c4a075d cfg80211: check r... |
528 529 530 531 |
/* DFS only works on one channel. */ if (WARN_ON(c->radar_detect_widths && (c->num_different_channels > 1))) return -EINVAL; |
7527a782e cfg80211: adverti... |
532 533 534 535 536 |
if (WARN_ON(!c->n_limits)) return -EINVAL; for (j = 0; j < c->n_limits; j++) { u16 types = c->limits[j].types; |
b6a550156 cfg80211/mac80211... |
537 |
/* interface types shouldn't overlap */ |
7527a782e cfg80211: adverti... |
538 539 540 541 542 543 544 545 546 547 |
if (WARN_ON(types & all_iftypes)) return -EINVAL; all_iftypes |= types; if (WARN_ON(!c->limits[j].max)) return -EINVAL; /* Shouldn't list software iftypes in combinations! */ if (WARN_ON(wiphy->software_iftypes & types)) return -EINVAL; |
98104fded cfg80211: add P2P... |
548 549 550 551 |
/* Only a single P2P_DEVICE can be allowed */ if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && c->limits[j].max > 1)) return -EINVAL; |
cb3b7d876 cfg80211: add sta... |
552 553 554 555 |
/* Only a single NAN can be allowed */ if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && c->limits[j].max > 1)) return -EINVAL; |
56271da29 cfg80211: disallo... |
556 557 558 559 560 561 562 563 564 565 566 567 568 569 |
/* * This isn't well-defined right now. If you have an * IBSS interface, then its beacon interval may change * by joining other networks, and nothing prevents it * from doing that. * So technically we probably shouldn't even allow AP * and IBSS in the same interface, but it seems that * some drivers support that, possibly only with fixed * beacon intervals for IBSS. */ if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) && c->beacon_int_min_gcd)) { return -EINVAL; } |
7527a782e cfg80211: adverti... |
570 571 572 573 574 575 576 577 |
cnt += c->limits[j].max; /* * Don't advertise an unsupported type * in a combination. */ if (WARN_ON((wiphy->interface_modes & types) != types)) return -EINVAL; } |
8f2054238 wireless: depreca... |
578 579 580 581 |
#ifndef CONFIG_WIRELESS_WDS if (WARN_ON(all_iftypes & BIT(NL80211_IFTYPE_WDS))) return -EINVAL; #endif |
7527a782e cfg80211: adverti... |
582 583 584 585 586 587 588 |
/* You can't even choose that many! */ if (WARN_ON(cnt < c->max_interfaces)) return -EINVAL; } return 0; } |
704232c27 [WIRELESS] cfg802... |
589 590 |
int wiphy_register(struct wiphy *wiphy) { |
f26cbf401 cfg80211: change ... |
591 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
704232c27 [WIRELESS] cfg802... |
592 |
int res; |
57fbcce37 cfg80211: remove ... |
593 |
enum nl80211_band band; |
8318d78a4 cfg80211 API for ... |
594 595 596 |
struct ieee80211_supported_band *sband; bool have_band = false; int i; |
f59ac0481 cfg80211: keep tr... |
597 |
u16 ifmodes = wiphy->interface_modes; |
dfb89c56a cfg80211: don't a... |
598 |
#ifdef CONFIG_PM |
964dc9e2c cfg80211: take Wo... |
599 600 601 602 603 604 605 |
if (WARN_ON(wiphy->wowlan && (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && !(wiphy->wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) return -EINVAL; if (WARN_ON(wiphy->wowlan && !wiphy->wowlan->flags && !wiphy->wowlan->n_patterns && !wiphy->wowlan->tcp)) |
77dbbb138 nl80211: advertis... |
606 |
return -EINVAL; |
dfb89c56a cfg80211: don't a... |
607 |
#endif |
1057d35ed cfg80211: introdu... |
608 609 610 611 |
if (WARN_ON((wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) && (!rdev->ops->tdls_channel_switch || !rdev->ops->tdls_cancel_channel_switch))) return -EINVAL; |
77dbbb138 nl80211: advertis... |
612 |
|
cb3b7d876 cfg80211: add sta... |
613 |
if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_NAN)) && |
a442b761b cfg80211: add add... |
614 |
(!rdev->ops->start_nan || !rdev->ops->stop_nan || |
8585989d1 cfg80211: fix NAN... |
615 616 |
!rdev->ops->add_nan_func || !rdev->ops->del_nan_func || !(wiphy->nan_supported_bands & BIT(NL80211_BAND_2GHZ))))) |
cb3b7d876 cfg80211: add sta... |
617 |
return -EINVAL; |
8f2054238 wireless: depreca... |
618 619 620 621 |
#ifndef CONFIG_WIRELESS_WDS if (WARN_ON(wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS))) return -EINVAL; #endif |
9bb7e0f24 cfg80211: add pee... |
622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
if (WARN_ON(wiphy->pmsr_capa && !wiphy->pmsr_capa->ftm.supported)) return -EINVAL; if (wiphy->pmsr_capa && wiphy->pmsr_capa->ftm.supported) { if (WARN_ON(!wiphy->pmsr_capa->ftm.asap && !wiphy->pmsr_capa->ftm.non_asap)) return -EINVAL; if (WARN_ON(!wiphy->pmsr_capa->ftm.preambles || !wiphy->pmsr_capa->ftm.bandwidths)) return -EINVAL; if (WARN_ON(wiphy->pmsr_capa->ftm.preambles & ~(BIT(NL80211_PREAMBLE_LEGACY) | BIT(NL80211_PREAMBLE_HT) | BIT(NL80211_PREAMBLE_VHT) | |
efb5520d0 nl80211/cfg80211:... |
636 |
BIT(NL80211_PREAMBLE_HE) | |
9bb7e0f24 cfg80211: add pee... |
637 638 |
BIT(NL80211_PREAMBLE_DMG)))) return -EINVAL; |
efb5520d0 nl80211/cfg80211:... |
639 640 641 642 643 |
if (WARN_ON((wiphy->pmsr_capa->ftm.trigger_based || wiphy->pmsr_capa->ftm.non_trigger_based) && !(wiphy->pmsr_capa->ftm.preambles & BIT(NL80211_PREAMBLE_HE)))) return -EINVAL; |
9bb7e0f24 cfg80211: add pee... |
644 645 646 647 648 649 650 651 652 653 654 |
if (WARN_ON(wiphy->pmsr_capa->ftm.bandwidths & ~(BIT(NL80211_CHAN_WIDTH_20_NOHT) | BIT(NL80211_CHAN_WIDTH_20) | BIT(NL80211_CHAN_WIDTH_40) | BIT(NL80211_CHAN_WIDTH_80) | BIT(NL80211_CHAN_WIDTH_80P80) | BIT(NL80211_CHAN_WIDTH_160) | BIT(NL80211_CHAN_WIDTH_5) | BIT(NL80211_CHAN_WIDTH_10)))) return -EINVAL; } |
ad932f046 cfg80211: leave i... |
655 656 657 658 659 660 661 662 663 664 |
/* * if a wiphy has unsupported modes for regulatory channel enforcement, * opt-out of enforcement checking */ if (wiphy->interface_modes & ~(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_P2P_DEVICE) | |
cb3b7d876 cfg80211: add sta... |
665 |
BIT(NL80211_IFTYPE_NAN) | |
ad932f046 cfg80211: leave i... |
666 667 668 |
BIT(NL80211_IFTYPE_AP_VLAN) | BIT(NL80211_IFTYPE_MONITOR))) wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; |
b0d7aa595 cfg80211: allow w... |
669 670 671 672 673 674 675 |
if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) && (wiphy->regulatory_flags & (REGULATORY_CUSTOM_REG | REGULATORY_STRICT_REG | REGULATORY_COUNTRY_IE_FOLLOW_POWER | REGULATORY_COUNTRY_IE_IGNORE)))) return -EINVAL; |
be29b99a9 cfg80211/nl80211:... |
676 677 678 679 680 681 682 |
if (WARN_ON(wiphy->coalesce && (!wiphy->coalesce->n_rules || !wiphy->coalesce->n_patterns) && (!wiphy->coalesce->pattern_min_len || wiphy->coalesce->pattern_min_len > wiphy->coalesce->pattern_max_len))) return -EINVAL; |
562a74803 nl80211: advertis... |
683 684 685 |
if (WARN_ON(wiphy->ap_sme_capa && !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) return -EINVAL; |
ef15aac60 cfg80211: export ... |
686 687 688 689 690 691 692 693 |
if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) return -EINVAL; if (WARN_ON(wiphy->addresses && !is_zero_ether_addr(wiphy->perm_addr) && memcmp(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN))) return -EINVAL; |
77765eaf5 cfg80211/nl80211:... |
694 695 696 697 |
if (WARN_ON(wiphy->max_acl_mac_addrs && (!(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME) || !rdev->ops->set_mac_acl))) return -EINVAL; |
38de03d2a nl80211: add feat... |
698 699 700 701 702 703 |
/* assure only valid behaviours are flagged by driver * hence subtract 2 as bit 0 is invalid. */ if (WARN_ON(wiphy->bss_select_support && (wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2)))) return -EINVAL; |
3a00df570 cfg80211: support... |
704 705 706 707 |
if (WARN_ON(wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X) && (!rdev->ops->set_pmk || !rdev->ops->del_pmk))) return -EINVAL; |
7f9a3e150 nl80211: Update E... |
708 709 710 |
if (WARN_ON(!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) && rdev->ops->update_connect_params)) return -EINVAL; |
ef15aac60 cfg80211: export ... |
711 712 |
if (wiphy->addresses) memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN); |
f59ac0481 cfg80211: keep tr... |
713 714 |
/* sanity check ifmodes */ WARN_ON(!ifmodes); |
2e161f78e cfg80211/mac80211... |
715 |
ifmodes &= ((1 << NUM_NL80211_IFTYPES) - 1) & ~1; |
f59ac0481 cfg80211: keep tr... |
716 717 |
if (WARN_ON(ifmodes != wiphy->interface_modes)) wiphy->interface_modes = ifmodes; |
8318d78a4 cfg80211 API for ... |
718 |
|
7527a782e cfg80211: adverti... |
719 720 721 |
res = wiphy_verify_combinations(wiphy); if (res) return res; |
8318d78a4 cfg80211 API for ... |
722 |
/* sanity check supported bands/channels */ |
57fbcce37 cfg80211: remove ... |
723 |
for (band = 0; band < NUM_NL80211_BANDS; band++) { |
c4cbaf797 cfg80211: Add sup... |
724 |
u16 types = 0; |
f43813652 cfg80211: require... |
725 |
bool have_he = false; |
c4cbaf797 cfg80211: Add sup... |
726 |
|
8318d78a4 cfg80211 API for ... |
727 728 729 730 731 |
sband = wiphy->bands[band]; if (!sband) continue; sband->band = band; |
3a0c52a6d cfg80211: add 802... |
732 733 734 |
if (WARN_ON(!sband->n_channels)) return -EINVAL; /* |
df78a0c0b nl80211: S1G band... |
735 |
* on 60GHz or sub-1Ghz band, there are no legacy rates, so |
3a0c52a6d cfg80211: add 802... |
736 737 |
* n_bitrates is 0 */ |
df78a0c0b nl80211: S1G band... |
738 739 |
if (WARN_ON((band != NL80211_BAND_60GHZ && band != NL80211_BAND_S1GHZ) && |
3a0c52a6d cfg80211: add 802... |
740 |
!sband->n_bitrates)) |
881d948c2 wireless: restric... |
741 |
return -EINVAL; |
461ce35d5 cfg80211: reject ... |
742 743 744 745 |
if (WARN_ON(band == NL80211_BAND_6GHZ && (sband->ht_cap.ht_supported || sband->vht_cap.vht_supported))) return -EINVAL; |
881d948c2 wireless: restric... |
746 |
/* |
40db6c77a cfg80211: module_... |
747 748 749 750 751 |
* Since cfg80211_disable_40mhz_24ghz is global, we can * modify the sband's ht data even if the driver uses a * global structure for that. */ if (cfg80211_disable_40mhz_24ghz && |
57fbcce37 cfg80211: remove ... |
752 |
band == NL80211_BAND_2GHZ && |
40db6c77a cfg80211: module_... |
753 754 755 756 757 758 |
sband->ht_cap.ht_supported) { sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; } /* |
881d948c2 wireless: restric... |
759 760 761 762 763 |
* Since we use a u32 for rate bitmaps in * ieee80211_get_response_rate, we cannot * have more than 32 legacy rates. */ if (WARN_ON(sband->n_bitrates > 32)) |
8318d78a4 cfg80211 API for ... |
764 |
return -EINVAL; |
8318d78a4 cfg80211 API for ... |
765 766 767 768 |
for (i = 0; i < sband->n_channels; i++) { sband->channels[i].orig_flags = sband->channels[i].flags; |
c4a9fafc7 cfg80211: fix ant... |
769 |
sband->channels[i].orig_mag = INT_MAX; |
8318d78a4 cfg80211 API for ... |
770 771 772 |
sband->channels[i].orig_mpwr = sband->channels[i].max_power; sband->channels[i].band = band; |
be689f68d cfg80211: reject ... |
773 774 775 |
if (WARN_ON(sband->channels[i].freq_offset >= 1000)) return -EINVAL; |
8318d78a4 cfg80211 API for ... |
776 |
} |
c4cbaf797 cfg80211: Add sup... |
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
for (i = 0; i < sband->n_iftype_data; i++) { const struct ieee80211_sband_iftype_data *iftd; iftd = &sband->iftype_data[i]; if (WARN_ON(!iftd->types_mask)) return -EINVAL; if (WARN_ON(types & iftd->types_mask)) return -EINVAL; /* at least one piece of information must be present */ if (WARN_ON(!iftd->he_cap.has_he)) return -EINVAL; types |= iftd->types_mask; |
f43813652 cfg80211: require... |
792 793 794 795 796 797 |
if (i == 0) have_he = iftd->he_cap.has_he; else have_he = have_he && iftd->he_cap.has_he; |
c4cbaf797 cfg80211: Add sup... |
798 |
} |
f43813652 cfg80211: require... |
799 800 |
if (WARN_ON(!have_he && band == NL80211_BAND_6GHZ)) return -EINVAL; |
8318d78a4 cfg80211 API for ... |
801 802 803 804 805 806 807 |
have_band = true; } if (!have_band) { WARN_ON(1); return -EINVAL; } |
901bb9891 nl80211: require ... |
808 809 810 811 812 813 814 815 816 817 818 819 |
for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) { /* * Validate we have a policy (can be explicitly set to * VENDOR_CMD_RAW_DATA which is non-NULL) and also that * we have at least one of doit/dumpit. */ if (WARN_ON(!rdev->wiphy.vendor_commands[i].policy)) return -EINVAL; if (WARN_ON(!rdev->wiphy.vendor_commands[i].doit && !rdev->wiphy.vendor_commands[i].dumpit)) return -EINVAL; } |
dfb89c56a cfg80211: don't a... |
820 |
#ifdef CONFIG_PM |
964dc9e2c cfg80211: take Wo... |
821 822 823 824 825 |
if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns && (!rdev->wiphy.wowlan->pattern_min_len || rdev->wiphy.wowlan->pattern_min_len > rdev->wiphy.wowlan->pattern_max_len))) return -EINVAL; |
dfb89c56a cfg80211: don't a... |
826 |
#endif |
ff1b6e69a nl80211/cfg80211:... |
827 |
|
8318d78a4 cfg80211 API for ... |
828 829 |
/* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); |
00c3a6ed6 cfg80211: don't a... |
830 |
rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH; |
aa5f66d5a cfg80211: fix sys... |
831 |
rtnl_lock(); |
79c97e97a cfg80211: clean u... |
832 |
res = device_add(&rdev->wiphy.dev); |
c3d34d5d9 wireless: registe... |
833 |
if (res) { |
aa5f66d5a cfg80211: fix sys... |
834 |
rtnl_unlock(); |
c3d34d5d9 wireless: registe... |
835 836 |
return res; } |
1f87f7d3a cfg80211: add rfk... |
837 |
|
2f0accc13 cfg80211: fix rfk... |
838 |
/* set up regulatory info */ |
57b5ce072 cfg80211: add cel... |
839 |
wiphy_regulatory_register(wiphy); |
2f0accc13 cfg80211: fix rfk... |
840 |
|
5f2aa25e0 cfg80211: rcu-ify... |
841 |
list_add_rcu(&rdev->list, &cfg80211_rdev_list); |
f5ea9120b nl80211: add gene... |
842 |
cfg80211_rdev_list_generation++; |
704232c27 [WIRELESS] cfg802... |
843 844 |
/* add to debugfs */ |
d82574a8e cfg80211: no need... |
845 846 |
rdev->wiphy.debugfsdir = debugfs_create_dir(wiphy_name(&rdev->wiphy), ieee80211_debugfs_dir); |
704232c27 [WIRELESS] cfg802... |
847 |
|
a796dac9a wireless: core: R... |
848 849 |
cfg80211_debugfs_rdev_add(rdev); nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); |
a2f73b6c5 cfg80211: move re... |
850 |
if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) { |
73d54c9e7 cfg80211: add reg... |
851 852 853 854 855 856 857 858 859 |
struct regulatory_request request; request.wiphy_idx = get_wiphy_idx(wiphy); request.initiator = NL80211_REGDOM_SET_BY_DRIVER; request.alpha2[0] = '9'; request.alpha2[1] = '9'; nl80211_send_reg_change_event(&request); } |
019ae3a91 cfg80211: Adverti... |
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 |
/* Check that nobody globally advertises any capabilities they do not * advertise on all possible interface types. */ if (wiphy->extended_capabilities_len && wiphy->num_iftype_ext_capab && wiphy->iftype_ext_capab) { u8 supported_on_all, j; const struct wiphy_iftype_ext_capab *capab; capab = wiphy->iftype_ext_capab; for (j = 0; j < wiphy->extended_capabilities_len; j++) { if (capab[0].extended_capabilities_len > j) supported_on_all = capab[0].extended_capabilities[j]; else supported_on_all = 0x00; for (i = 1; i < wiphy->num_iftype_ext_capab; i++) { if (j >= capab[i].extended_capabilities_len) { supported_on_all = 0x00; break; } supported_on_all &= capab[i].extended_capabilities[j]; } if (WARN_ON(wiphy->extended_capabilities[j] & ~supported_on_all)) break; } } |
ecb443355 mac80211: fix sus... |
889 890 |
rdev->wiphy.registered = true; rtnl_unlock(); |
aa5f66d5a cfg80211: fix sys... |
891 892 893 894 895 896 897 898 |
res = rfkill_register(rdev->rfkill); if (res) { rfkill_destroy(rdev->rfkill); rdev->rfkill = NULL; wiphy_unregister(&rdev->wiphy); return res; } |
2f0accc13 cfg80211: fix rfk... |
899 |
return 0; |
704232c27 [WIRELESS] cfg802... |
900 901 |
} EXPORT_SYMBOL(wiphy_register); |
1f87f7d3a cfg80211: add rfk... |
902 903 |
void wiphy_rfkill_start_polling(struct wiphy *wiphy) { |
f26cbf401 cfg80211: change ... |
904 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1f87f7d3a cfg80211: add rfk... |
905 |
|
79c97e97a cfg80211: clean u... |
906 |
if (!rdev->ops->rfkill_poll) |
1f87f7d3a cfg80211: add rfk... |
907 |
return; |
79c97e97a cfg80211: clean u... |
908 909 |
rdev->rfkill_ops.poll = cfg80211_rfkill_poll; rfkill_resume_polling(rdev->rfkill); |
1f87f7d3a cfg80211: add rfk... |
910 911 912 913 914 |
} EXPORT_SYMBOL(wiphy_rfkill_start_polling); void wiphy_rfkill_stop_polling(struct wiphy *wiphy) { |
f26cbf401 cfg80211: change ... |
915 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1f87f7d3a cfg80211: add rfk... |
916 |
|
79c97e97a cfg80211: clean u... |
917 |
rfkill_pause_polling(rdev->rfkill); |
1f87f7d3a cfg80211: add rfk... |
918 919 |
} EXPORT_SYMBOL(wiphy_rfkill_stop_polling); |
704232c27 [WIRELESS] cfg802... |
920 921 |
void wiphy_unregister(struct wiphy *wiphy) { |
f26cbf401 cfg80211: change ... |
922 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
704232c27 [WIRELESS] cfg802... |
923 |
|
ad002395f cfg80211: fix dan... |
924 925 |
wait_event(rdev->dev_wait, ({ int __count; |
5fe231e87 cfg80211: vastly ... |
926 |
rtnl_lock(); |
ad002395f cfg80211: fix dan... |
927 |
__count = rdev->opencount; |
5fe231e87 cfg80211: vastly ... |
928 |
rtnl_unlock(); |
c4f608462 Net: wireless: co... |
929 |
__count == 0; })); |
ad002395f cfg80211: fix dan... |
930 |
|
aa5f66d5a cfg80211: fix sys... |
931 932 |
if (rdev->rfkill) rfkill_unregister(rdev->rfkill); |
256c90ded cfg80211: fix pot... |
933 |
|
5fe231e87 cfg80211: vastly ... |
934 |
rtnl_lock(); |
3bb205567 cfg80211: send ev... |
935 |
nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); |
5fe231e87 cfg80211: vastly ... |
936 |
rdev->wiphy.registered = false; |
53873f134 cfg80211: make wd... |
937 |
WARN_ON(!list_empty(&rdev->wiphy.wdev_list)); |
ad002395f cfg80211: fix dan... |
938 939 940 941 942 |
/* * First remove the hardware from everywhere, this makes * it impossible to find from userspace. */ |
7bcfaf2f4 cfg80211/mac80211... |
943 |
debugfs_remove_recursive(rdev->wiphy.debugfsdir); |
5f2aa25e0 cfg80211: rcu-ify... |
944 945 |
list_del_rcu(&rdev->list); synchronize_rcu(); |
f16bfc1c0 [WIRELESS] cfg802... |
946 947 |
/* |
bfead0808 cfg80211: rename ... |
948 949 950 951 |
* If this device got a regulatory hint tell core its * free to listen now to a new shiny device regulatory hint */ wiphy_regulatory_deregister(wiphy); |
3f2355cb9 cfg80211/mac80211... |
952 |
|
f5ea9120b nl80211: add gene... |
953 |
cfg80211_rdev_list_generation++; |
79c97e97a cfg80211: clean u... |
954 |
device_del(&rdev->wiphy.dev); |
704232c27 [WIRELESS] cfg802... |
955 |
|
5fe231e87 cfg80211: vastly ... |
956 |
rtnl_unlock(); |
6682588a0 cfg80211: fix unr... |
957 |
|
36e6fea84 cfg80211: check f... |
958 |
flush_work(&rdev->scan_done_wk); |
6682588a0 cfg80211: fix unr... |
959 |
cancel_work_sync(&rdev->conn_work); |
6682588a0 cfg80211: fix unr... |
960 |
flush_work(&rdev->event_work); |
04f39047a nl80211/cfg80211:... |
961 |
cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); |
78f22b6a3 cfg80211: allow u... |
962 |
flush_work(&rdev->destroy_work); |
93a1e86ce nl80211: Stop sch... |
963 |
flush_work(&rdev->sched_scan_stop_wk); |
897667273 cfg80211: Share C... |
964 965 |
flush_work(&rdev->propagate_radar_detect_wk); flush_work(&rdev->propagate_cac_done_wk); |
79ea1e12c cfg80211: fix man... |
966 |
flush_work(&rdev->mgmt_registrations_update_wk); |
6d52563f2 cfg80211/mac80211... |
967 |
|
6abb9cb99 cfg80211: make Wo... |
968 969 |
#ifdef CONFIG_PM if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) |
e35e4d28b cfg80211: add wra... |
970 |
rdev_set_wakeup(rdev, false); |
6abb9cb99 cfg80211: make Wo... |
971 |
#endif |
6d52563f2 cfg80211/mac80211... |
972 |
cfg80211_rdev_free_wowlan(rdev); |
be29b99a9 cfg80211/nl80211:... |
973 |
cfg80211_rdev_free_coalesce(rdev); |
704232c27 [WIRELESS] cfg802... |
974 975 |
} EXPORT_SYMBOL(wiphy_unregister); |
79c97e97a cfg80211: clean u... |
976 |
void cfg80211_dev_free(struct cfg80211_registered_device *rdev) |
704232c27 [WIRELESS] cfg802... |
977 |
{ |
2a5193119 cfg80211/nl80211:... |
978 |
struct cfg80211_internal_bss *scan, *tmp; |
37c73b5f3 cfg80211: allow r... |
979 |
struct cfg80211_beacon_registration *reg, *treg; |
79c97e97a cfg80211: clean u... |
980 |
rfkill_destroy(rdev->rfkill); |
37c73b5f3 cfg80211: allow r... |
981 982 983 984 |
list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) { list_del(®->list); kfree(reg); } |
79c97e97a cfg80211: clean u... |
985 |
list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) |
5b112d3d0 cfg80211: pass wi... |
986 |
cfg80211_put_bss(&rdev->wiphy, &scan->pub); |
79c97e97a cfg80211: clean u... |
987 |
kfree(rdev); |
704232c27 [WIRELESS] cfg802... |
988 989 990 991 992 993 994 |
} void wiphy_free(struct wiphy *wiphy) { put_device(&wiphy->dev); } EXPORT_SYMBOL(wiphy_free); |
1f87f7d3a cfg80211: add rfk... |
995 996 |
void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked) { |
f26cbf401 cfg80211: change ... |
997 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1f87f7d3a cfg80211: add rfk... |
998 |
|
79c97e97a cfg80211: clean u... |
999 |
if (rfkill_set_hw_state(rdev->rfkill, blocked)) |
3cfe91c4c cfg80211: always ... |
1000 |
schedule_work(&rdev->rfkill_block); |
1f87f7d3a cfg80211: add rfk... |
1001 1002 |
} EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); |
4a4b81695 cfg80211: Accept ... |
1003 1004 1005 1006 1007 |
void cfg80211_cqm_config_free(struct wireless_dev *wdev) { kfree(wdev->cqm_config); wdev->cqm_config = NULL; } |
85dd3da43 cfg80211: combine... |
1008 |
static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync) |
98104fded cfg80211: add P2P... |
1009 |
{ |
f26cbf401 cfg80211: change ... |
1010 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
98104fded cfg80211: add P2P... |
1011 1012 |
ASSERT_RTNL(); |
73350424b cfg80211: pmsr: f... |
1013 |
flush_work(&wdev->pmsr_free_wk); |
7f8ed01ea cfg80211: always ... |
1014 |
nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE); |
98104fded cfg80211: add P2P... |
1015 |
list_del_rcu(&wdev->list); |
85dd3da43 cfg80211: combine... |
1016 1017 |
if (sync) synchronize_rcu(); |
98104fded cfg80211: add P2P... |
1018 |
rdev->devlist_generation++; |
85dd3da43 cfg80211: combine... |
1019 |
cfg80211_mlme_purge_registrations(wdev); |
98104fded cfg80211: add P2P... |
1020 1021 |
switch (wdev->iftype) { case NL80211_IFTYPE_P2P_DEVICE: |
f9f475292 cfg80211: always ... |
1022 |
cfg80211_stop_p2p_device(rdev, wdev); |
98104fded cfg80211: add P2P... |
1023 |
break; |
cb3b7d876 cfg80211: add sta... |
1024 1025 1026 |
case NL80211_IFTYPE_NAN: cfg80211_stop_nan(rdev, wdev); break; |
98104fded cfg80211: add P2P... |
1027 |
default: |
98104fded cfg80211: add P2P... |
1028 1029 |
break; } |
4a4b81695 cfg80211: Accept ... |
1030 |
|
85dd3da43 cfg80211: combine... |
1031 |
#ifdef CONFIG_CFG80211_WEXT |
453431a54 mm, treewide: ren... |
1032 |
kfree_sensitive(wdev->wext.keys); |
56cb31e18 cfg80211: fix dou... |
1033 |
wdev->wext.keys = NULL; |
85dd3da43 cfg80211: combine... |
1034 1035 1036 1037 |
#endif /* only initialized if we have a netdev */ if (wdev->netdev) flush_work(&wdev->disconnect_wk); |
4a4b81695 cfg80211: Accept ... |
1038 |
cfg80211_cqm_config_free(wdev); |
98104fded cfg80211: add P2P... |
1039 |
} |
85dd3da43 cfg80211: combine... |
1040 1041 1042 1043 1044 1045 1046 1047 |
void cfg80211_unregister_wdev(struct wireless_dev *wdev) { if (WARN_ON(wdev->netdev)) return; __cfg80211_unregister_wdev(wdev, true); } |
98104fded cfg80211: add P2P... |
1048 |
EXPORT_SYMBOL(cfg80211_unregister_wdev); |
f1e3d556a cfg80211: make de... |
1049 |
static const struct device_type wiphy_type = { |
053a93dd1 cfg80211: assign ... |
1050 1051 |
.name = "wlan", }; |
dbbae26af cfg80211: track m... |
1052 1053 1054 |
void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num) { |
c5a7e5824 cfg80211: fix loc... |
1055 |
ASSERT_RTNL(); |
dbbae26af cfg80211: track m... |
1056 1057 1058 1059 |
rdev->num_running_ifaces += num; if (iftype == NL80211_IFTYPE_MONITOR) rdev->num_running_monitor_ifaces += num; |
dbbae26af cfg80211: track m... |
1060 |
} |
f04c22033 cfg80211: export ... |
1061 1062 |
void __cfg80211_leave(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) |
812569699 cfg80211/mac80211... |
1063 1064 |
{ struct net_device *dev = wdev->netdev; |
ca986ad9b nl80211: allow mu... |
1065 |
struct cfg80211_sched_scan_request *pos, *tmp; |
812569699 cfg80211/mac80211... |
1066 |
|
24d584d70 cfg80211: stop sc... |
1067 |
ASSERT_RTNL(); |
f04c22033 cfg80211: export ... |
1068 |
ASSERT_WDEV_LOCK(wdev); |
24d584d70 cfg80211: stop sc... |
1069 |
|
9bb7e0f24 cfg80211: add pee... |
1070 |
cfg80211_pmsr_wdev_down(wdev); |
812569699 cfg80211/mac80211... |
1071 1072 |
switch (wdev->iftype) { case NL80211_IFTYPE_ADHOC: |
f04c22033 cfg80211: export ... |
1073 |
__cfg80211_leave_ibss(rdev, dev, true); |
812569699 cfg80211/mac80211... |
1074 1075 1076 |
break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: |
ca986ad9b nl80211: allow mu... |
1077 1078 1079 1080 1081 |
list_for_each_entry_safe(pos, tmp, &rdev->sched_scan_req_list, list) { if (dev == pos->dev) cfg80211_stop_sched_scan_req(rdev, pos, false); } |
812569699 cfg80211/mac80211... |
1082 |
|
812569699 cfg80211/mac80211... |
1083 1084 1085 1086 1087 1088 |
#ifdef CONFIG_CFG80211_WEXT kfree(wdev->wext.ie); wdev->wext.ie = NULL; wdev->wext.ie_len = 0; wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; #endif |
83739b03d cfg80211: remove ... |
1089 1090 |
cfg80211_disconnect(rdev, dev, WLAN_REASON_DEAUTH_LEAVING, true); |
812569699 cfg80211/mac80211... |
1091 1092 |
break; case NL80211_IFTYPE_MESH_POINT: |
f04c22033 cfg80211: export ... |
1093 |
__cfg80211_leave_mesh(rdev, dev); |
812569699 cfg80211/mac80211... |
1094 1095 |
break; case NL80211_IFTYPE_AP: |
74418edec cfg80211: fix P2P... |
1096 |
case NL80211_IFTYPE_P2P_GO: |
f04c22033 cfg80211: export ... |
1097 |
__cfg80211_stop_ap(rdev, dev, true); |
812569699 cfg80211/mac80211... |
1098 |
break; |
6e0bd6c35 cfg80211: 802.11p... |
1099 1100 1101 |
case NL80211_IFTYPE_OCB: __cfg80211_leave_ocb(rdev, dev); break; |
de4fcbadd cfg80211: avoid u... |
1102 1103 1104 1105 |
case NL80211_IFTYPE_WDS: /* must be handled by mac80211/driver, has no APIs */ break; case NL80211_IFTYPE_P2P_DEVICE: |
cb3b7d876 cfg80211: add sta... |
1106 |
case NL80211_IFTYPE_NAN: |
de4fcbadd cfg80211: avoid u... |
1107 1108 1109 1110 1111 1112 1113 1114 1115 |
/* cannot happen, has no netdev */ break; case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_MONITOR: /* nothing to do */ break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: /* invalid */ |
812569699 cfg80211/mac80211... |
1116 1117 |
break; } |
812569699 cfg80211/mac80211... |
1118 |
} |
f04c22033 cfg80211: export ... |
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 |
void cfg80211_leave(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) { wdev_lock(wdev); __cfg80211_leave(rdev, wdev); wdev_unlock(wdev); } void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, gfp_t gfp) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct cfg80211_event *ev; unsigned long flags; trace_cfg80211_stop_iface(wiphy, wdev); ev = kzalloc(sizeof(*ev), gfp); if (!ev) return; ev->type = EVENT_STOPPED; spin_lock_irqsave(&wdev->event_lock, flags); list_add_tail(&ev->list, &wdev->event_list); spin_unlock_irqrestore(&wdev->event_lock, flags); queue_work(cfg80211_wq, &rdev->event_work); } EXPORT_SYMBOL(cfg80211_stop_iface); |
9bdaf3b91 cfg80211: initial... |
1148 |
void cfg80211_init_wdev(struct wireless_dev *wdev) |
e4d4216e9 cfg80211: combine... |
1149 1150 1151 1152 1153 1154 |
{ mutex_init(&wdev->mtx); INIT_LIST_HEAD(&wdev->event_list); spin_lock_init(&wdev->event_lock); INIT_LIST_HEAD(&wdev->mgmt_registrations); spin_lock_init(&wdev->mgmt_registrations_lock); |
9bb7e0f24 cfg80211: add pee... |
1155 1156 1157 |
INIT_LIST_HEAD(&wdev->pmsr_list); spin_lock_init(&wdev->pmsr_lock); INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk); |
e4d4216e9 cfg80211: combine... |
1158 |
|
9bdaf3b91 cfg80211: initial... |
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 |
#ifdef CONFIG_CFG80211_WEXT wdev->wext.default_key = -1; wdev->wext.default_mgmt_key = -1; wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; #endif if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) wdev->ps = true; else wdev->ps = false; /* allow mac80211 to determine the timeout */ wdev->ps_timeout = -1; if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) wdev->netdev->priv_flags |= IFF_DONT_BRIDGE; INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk); } void cfg80211_register_wdev(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) { |
e4d4216e9 cfg80211: combine... |
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 |
/* * We get here also when the interface changes network namespaces, * as it's registered into the new one, but we don't want it to * change ID in that case. Checking if the ID is already assigned * works, because 0 isn't considered a valid ID and the memory is * 0-initialized. */ if (!wdev->identifier) wdev->identifier = ++rdev->wdev_id; list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list); rdev->devlist_generation++; |
ec8f170bc cfg80211: unify s... |
1194 1195 |
nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE); |
e4d4216e9 cfg80211: combine... |
1196 |
} |
c4f608462 Net: wireless: co... |
1197 |
static int cfg80211_netdev_notifier_call(struct notifier_block *nb, |
351638e7d net: pass info st... |
1198 |
unsigned long state, void *ptr) |
704232c27 [WIRELESS] cfg802... |
1199 |
{ |
351638e7d net: pass info st... |
1200 |
struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
2a783c136 cfg80211: move br... |
1201 |
struct wireless_dev *wdev = dev->ieee80211_ptr; |
704232c27 [WIRELESS] cfg802... |
1202 |
struct cfg80211_registered_device *rdev; |
ca986ad9b nl80211: allow mu... |
1203 |
struct cfg80211_sched_scan_request *pos, *tmp; |
704232c27 [WIRELESS] cfg802... |
1204 |
|
2a783c136 cfg80211: move br... |
1205 |
if (!wdev) |
1f87f7d3a cfg80211: add rfk... |
1206 |
return NOTIFY_DONE; |
704232c27 [WIRELESS] cfg802... |
1207 |
|
f26cbf401 cfg80211: change ... |
1208 |
rdev = wiphy_to_rdev(wdev->wiphy); |
704232c27 [WIRELESS] cfg802... |
1209 |
|
2a783c136 cfg80211: move br... |
1210 |
WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED); |
60719ffd7 cfg80211: show in... |
1211 |
|
704232c27 [WIRELESS] cfg802... |
1212 |
switch (state) { |
053a93dd1 cfg80211: assign ... |
1213 1214 |
case NETDEV_POST_INIT: SET_NETDEV_DEVTYPE(dev, &wiphy_type); |
9bdaf3b91 cfg80211: initial... |
1215 1216 1217 1218 1219 |
wdev->netdev = dev; /* can only change netns with wiphy */ dev->features |= NETIF_F_NETNS_LOCAL; cfg80211_init_wdev(wdev); |
053a93dd1 cfg80211: assign ... |
1220 |
break; |
704232c27 [WIRELESS] cfg802... |
1221 |
case NETDEV_REGISTER: |
0ff6ce7b3 cfg80211: fix dea... |
1222 1223 1224 1225 1226 |
/* * NB: cannot take rdev->mtx here because this may be * called within code protected by it when interfaces * are added with nl80211. */ |
704232c27 [WIRELESS] cfg802... |
1227 1228 |
if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj, "phy80211")) { |
e9c0268f0 net/wireless: Use... |
1229 1230 |
pr_err("failed to add phy80211 symlink to netdev! "); |
704232c27 [WIRELESS] cfg802... |
1231 |
} |
bd2522b16 cfg80211: NL80211... |
1232 |
|
9bdaf3b91 cfg80211: initial... |
1233 |
cfg80211_register_wdev(rdev, wdev); |
704232c27 [WIRELESS] cfg802... |
1234 |
break; |
04a773ade cfg80211/nl80211:... |
1235 |
case NETDEV_GOING_DOWN: |
812569699 cfg80211/mac80211... |
1236 |
cfg80211_leave(rdev, wdev); |
01a0ac417 cfg80211: check l... |
1237 1238 |
break; case NETDEV_DOWN: |
dbbae26af cfg80211: track m... |
1239 |
cfg80211_update_iface_num(rdev, wdev->iftype, -1); |
a617302c5 cfg80211: fix sca... |
1240 |
if (rdev->scan_req && rdev->scan_req->wdev == wdev) { |
c8cb5b854 nl80211/cfg80211:... |
1241 1242 1243 |
if (WARN_ON(!rdev->scan_req->notified && (!rdev->int_scan_req || !rdev->int_scan_req->notified))) |
1d76250bd nl80211: support ... |
1244 |
rdev->scan_req->info.aborted = true; |
f9d15d162 cfg80211: send sc... |
1245 |
___cfg80211_scan_done(rdev, false); |
a617302c5 cfg80211: fix sca... |
1246 |
} |
5fe231e87 cfg80211: vastly ... |
1247 |
|
ca986ad9b nl80211: allow mu... |
1248 1249 |
list_for_each_entry_safe(pos, tmp, &rdev->sched_scan_req_list, list) { |
d25d062f5 cfg80211: remove ... |
1250 |
if (WARN_ON(pos->dev == wdev->netdev)) |
ca986ad9b nl80211: allow mu... |
1251 |
cfg80211_stop_sched_scan_req(rdev, pos, false); |
5fe231e87 cfg80211: vastly ... |
1252 1253 1254 1255 |
} rdev->opencount--; wake_up(&rdev->dev_wait); |
04a773ade cfg80211/nl80211:... |
1256 1257 |
break; case NETDEV_UP: |
4290cb4bf cfg80211: reduce ... |
1258 |
cfg80211_update_iface_num(rdev, wdev->iftype, 1); |
667503ddc cfg80211: fix loc... |
1259 |
wdev_lock(wdev); |
f21293549 cfg80211: managed... |
1260 |
switch (wdev->iftype) { |
29cbe68c5 cfg80211/mac80211... |
1261 |
#ifdef CONFIG_CFG80211_WEXT |
f21293549 cfg80211: managed... |
1262 |
case NL80211_IFTYPE_ADHOC: |
fffd0934b cfg80211: rework ... |
1263 |
cfg80211_ibss_wext_join(rdev, wdev); |
04a773ade cfg80211/nl80211:... |
1264 |
break; |
f21293549 cfg80211: managed... |
1265 |
case NL80211_IFTYPE_STATION: |
fffd0934b cfg80211: rework ... |
1266 |
cfg80211_mgd_wext_connect(rdev, wdev); |
f21293549 cfg80211: managed... |
1267 |
break; |
29cbe68c5 cfg80211/mac80211... |
1268 |
#endif |
c80d545da mac80211: Let use... |
1269 |
#ifdef CONFIG_MAC80211_MESH |
29cbe68c5 cfg80211/mac80211... |
1270 |
case NL80211_IFTYPE_MESH_POINT: |
c80d545da mac80211: Let use... |
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 |
{ /* backward compat code... */ struct mesh_setup setup; memcpy(&setup, &default_mesh_setup, sizeof(setup)); /* back compat only needed for mesh_id */ setup.mesh_id = wdev->ssid; setup.mesh_id_len = wdev->mesh_id_up_len; if (wdev->mesh_id_up_len) __cfg80211_join_mesh(rdev, dev, &setup, &default_mesh_config); break; } #endif |
f21293549 cfg80211: managed... |
1286 |
default: |
04a773ade cfg80211/nl80211:... |
1287 |
break; |
f21293549 cfg80211: managed... |
1288 |
} |
667503ddc cfg80211: fix loc... |
1289 |
wdev_unlock(wdev); |
ad002395f cfg80211: fix dan... |
1290 |
rdev->opencount++; |
bf6a0579f cfg80211: Fix pow... |
1291 1292 1293 1294 1295 |
/* * Configure power management to the driver here so that its * correctly set also after interface type changes etc. */ |
5966f2ddc cfg80211: enter p... |
1296 1297 |
if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && |
d4f299786 cfg80211: combine... |
1298 1299 1300 1301 1302 1303 |
rdev->ops->set_power_mgmt && rdev_set_power_mgmt(rdev, dev, wdev->ps, wdev->ps_timeout)) { /* assume this means it's off */ wdev->ps = false; } |
2a783c136 cfg80211: move br... |
1304 |
break; |
704232c27 [WIRELESS] cfg802... |
1305 |
case NETDEV_UNREGISTER: |
0ff6ce7b3 cfg80211: fix dea... |
1306 |
/* |
e40cbdac0 cfg80211: fix NET... |
1307 1308 1309 1310 1311 1312 |
* It is possible to get NETDEV_UNREGISTER * multiple times. To detect that, check * that the interface is still on the list * of registered interfaces, and only then * remove and clean it up. */ |
2a783c136 cfg80211: move br... |
1313 |
if (!list_empty(&wdev->list)) { |
85dd3da43 cfg80211: combine... |
1314 |
__cfg80211_unregister_wdev(wdev, false); |
704232c27 [WIRELESS] cfg802... |
1315 |
sysfs_remove_link(&dev->dev.kobj, "phy80211"); |
e40cbdac0 cfg80211: fix NET... |
1316 |
} |
5f2aa25e0 cfg80211: rcu-ify... |
1317 1318 1319 1320 1321 1322 1323 1324 |
/* * synchronise (so that we won't find this netdev * from other code any more) and then clear the list * head so that the above code can safely check for * !list_empty() to avoid double-cleanup. */ synchronize_rcu(); INIT_LIST_HEAD(&wdev->list); |
1f6fc43e6 cfg80211: process... |
1325 1326 1327 1328 1329 |
/* * Ensure that all events have been processed and * freed. */ cfg80211_process_wdev_events(wdev); |
f9bef3df5 wireless: check f... |
1330 1331 1332 1333 1334 1335 |
if (WARN_ON(wdev->current_bss)) { cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); wdev->current_bss = NULL; } |
704232c27 [WIRELESS] cfg802... |
1336 |
break; |
1f87f7d3a cfg80211: add rfk... |
1337 |
case NETDEV_PRE_UP: |
e6f405112 {nl,mac}80211: fi... |
1338 1339 |
if (!cfg80211_iftype_allowed(wdev->wiphy, wdev->iftype, wdev->use_4addr, 0)) |
0b20633d9 cfg80211: disallo... |
1340 |
return notifier_from_errno(-EOPNOTSUPP); |
33d915d9e {nl,mac}80211: al... |
1341 |
|
b6a550156 cfg80211/mac80211... |
1342 1343 |
if (rfkill_blocked(rdev->rfkill)) return notifier_from_errno(-ERFKILL); |
1f87f7d3a cfg80211: add rfk... |
1344 |
break; |
6784c7db8 cfg80211: change ... |
1345 1346 |
default: return NOTIFY_DONE; |
704232c27 [WIRELESS] cfg802... |
1347 |
} |
cb150b9d2 cfg80211/wext: fi... |
1348 |
wireless_nlevent_flush(); |
6784c7db8 cfg80211: change ... |
1349 |
return NOTIFY_OK; |
704232c27 [WIRELESS] cfg802... |
1350 1351 1352 1353 1354 |
} static struct notifier_block cfg80211_netdev_notifier = { .notifier_call = cfg80211_netdev_notifier_call, }; |
463d01832 cfg80211: make aw... |
1355 1356 1357 1358 1359 |
static void __net_exit cfg80211_pernet_exit(struct net *net) { struct cfg80211_registered_device *rdev; rtnl_lock(); |
463d01832 cfg80211: make aw... |
1360 1361 1362 1363 |
list_for_each_entry(rdev, &cfg80211_rdev_list, list) { if (net_eq(wiphy_net(&rdev->wiphy), net)) WARN_ON(cfg80211_switch_netns(rdev, &init_net)); } |
463d01832 cfg80211: make aw... |
1364 1365 1366 1367 1368 1369 1370 1371 |
rtnl_unlock(); } static struct pernet_operations cfg80211_pernet_ops = { .exit = cfg80211_pernet_exit, }; static int __init cfg80211_init(void) |
704232c27 [WIRELESS] cfg802... |
1372 |
{ |
b2e1b3029 cfg80211: Add new... |
1373 |
int err; |
463d01832 cfg80211: make aw... |
1374 1375 1376 |
err = register_pernet_device(&cfg80211_pernet_ops); if (err) goto out_fail_pernet; |
b2e1b3029 cfg80211: Add new... |
1377 |
err = wiphy_sysfs_init(); |
704232c27 [WIRELESS] cfg802... |
1378 1379 1380 1381 1382 1383 |
if (err) goto out_fail_sysfs; err = register_netdevice_notifier(&cfg80211_netdev_notifier); if (err) goto out_fail_notifier; |
556829657 [NL80211]: add ne... |
1384 1385 1386 |
err = nl80211_init(); if (err) goto out_fail_nl80211; |
704232c27 [WIRELESS] cfg802... |
1387 |
ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL); |
b2e1b3029 cfg80211: Add new... |
1388 1389 1390 |
err = regulatory_init(); if (err) goto out_fail_reg; |
e48190138 cfg80211: Remove ... |
1391 |
cfg80211_wq = alloc_ordered_workqueue("cfg80211", WQ_MEM_RECLAIM); |
f00f188f8 cfg80211: fix err... |
1392 1393 |
if (!cfg80211_wq) { err = -ENOMEM; |
e60d7443e wireless : use a ... |
1394 |
goto out_fail_wq; |
f00f188f8 cfg80211: fix err... |
1395 |
} |
e60d7443e wireless : use a ... |
1396 |
|
704232c27 [WIRELESS] cfg802... |
1397 |
return 0; |
e60d7443e wireless : use a ... |
1398 1399 |
out_fail_wq: regulatory_exit(); |
b2e1b3029 cfg80211: Add new... |
1400 1401 |
out_fail_reg: debugfs_remove(ieee80211_debugfs_dir); |
81daf735f cfg80211: calls n... |
1402 |
nl80211_exit(); |
556829657 [NL80211]: add ne... |
1403 1404 |
out_fail_nl80211: unregister_netdevice_notifier(&cfg80211_netdev_notifier); |
704232c27 [WIRELESS] cfg802... |
1405 1406 1407 |
out_fail_notifier: wiphy_sysfs_exit(); out_fail_sysfs: |
463d01832 cfg80211: make aw... |
1408 1409 |
unregister_pernet_device(&cfg80211_pernet_ops); out_fail_pernet: |
704232c27 [WIRELESS] cfg802... |
1410 1411 |
return err; } |
007f6c5e6 cfg80211: support... |
1412 |
fs_initcall(cfg80211_init); |
704232c27 [WIRELESS] cfg802... |
1413 |
|
f884e3879 cfg80211: move cf... |
1414 |
static void __exit cfg80211_exit(void) |
704232c27 [WIRELESS] cfg802... |
1415 1416 |
{ debugfs_remove(ieee80211_debugfs_dir); |
556829657 [NL80211]: add ne... |
1417 |
nl80211_exit(); |
704232c27 [WIRELESS] cfg802... |
1418 1419 |
unregister_netdevice_notifier(&cfg80211_netdev_notifier); wiphy_sysfs_exit(); |
b2e1b3029 cfg80211: Add new... |
1420 |
regulatory_exit(); |
463d01832 cfg80211: make aw... |
1421 |
unregister_pernet_device(&cfg80211_pernet_ops); |
e60d7443e wireless : use a ... |
1422 |
destroy_workqueue(cfg80211_wq); |
704232c27 [WIRELESS] cfg802... |
1423 1424 |
} module_exit(cfg80211_exit); |