diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/Kconfig | 37 | ||||
-rw-r--r-- | net/wireless/ap.c | 4 | ||||
-rw-r--r-- | net/wireless/chan.c | 175 | ||||
-rw-r--r-- | net/wireless/core.c | 147 | ||||
-rw-r--r-- | net/wireless/core.h | 53 | ||||
-rw-r--r-- | net/wireless/ethtool.c | 10 | ||||
-rw-r--r-- | net/wireless/genregdb.awk | 14 | ||||
-rw-r--r-- | net/wireless/ibss.c | 43 | ||||
-rw-r--r-- | net/wireless/mesh.c | 32 | ||||
-rw-r--r-- | net/wireless/mlme.c | 38 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 654 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 3 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 15 | ||||
-rw-r--r-- | net/wireless/reg.c | 156 | ||||
-rw-r--r-- | net/wireless/reg.h | 18 | ||||
-rw-r--r-- | net/wireless/scan.c | 162 | ||||
-rw-r--r-- | net/wireless/sme.c | 48 | ||||
-rw-r--r-- | net/wireless/trace.h | 66 | ||||
-rw-r--r-- | net/wireless/util.c | 209 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 40 | ||||
-rw-r--r-- | net/wireless/wext-compat.h | 2 | ||||
-rw-r--r-- | net/wireless/wext-sme.c | 12 |
22 files changed, 1255 insertions, 683 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 16d08b399210..405f3c4cf70c 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -95,6 +95,43 @@ config CFG80211_CERTIFICATION_ONUS | |||
95 | you are a wireless researcher and are working in a controlled | 95 | you are a wireless researcher and are working in a controlled |
96 | and approved environment by your local regulatory agency. | 96 | and approved environment by your local regulatory agency. |
97 | 97 | ||
98 | config CFG80211_REG_CELLULAR_HINTS | ||
99 | bool "cfg80211 regulatory support for cellular base station hints" | ||
100 | depends on CFG80211_CERTIFICATION_ONUS | ||
101 | ---help--- | ||
102 | This option enables support for parsing regulatory hints | ||
103 | from cellular base stations. If enabled and at least one driver | ||
104 | claims support for parsing cellular base station hints the | ||
105 | regulatory core will allow and parse these regulatory hints. | ||
106 | The regulatory core will only apply these regulatory hints on | ||
107 | drivers that support this feature. You should only enable this | ||
108 | feature if you have tested and validated this feature on your | ||
109 | systems. | ||
110 | |||
111 | config CFG80211_REG_RELAX_NO_IR | ||
112 | bool "cfg80211 support for NO_IR relaxation" | ||
113 | depends on CFG80211_CERTIFICATION_ONUS | ||
114 | ---help--- | ||
115 | This option enables support for relaxation of the NO_IR flag for | ||
116 | situations that certain regulatory bodies have provided clarifications | ||
117 | on how relaxation can occur. This feature has an inherent dependency on | ||
118 | userspace features which must have been properly tested and as such is | ||
119 | not enabled by default. | ||
120 | |||
121 | A relaxation feature example is allowing the operation of a P2P group | ||
122 | owner (GO) on channels marked with NO_IR if there is an additional BSS | ||
123 | interface which associated to an AP which userspace assumes or confirms | ||
124 | to be an authorized master, i.e., with radar detection support and DFS | ||
125 | capabilities. However, note that in order to not create daisy chain | ||
126 | scenarios, this relaxation is not allowed in cases that the BSS client | ||
127 | is associated to P2P GO and in addition the P2P GO instantiated on | ||
128 | a channel due to this relaxation should not allow connection from | ||
129 | non P2P clients. | ||
130 | |||
131 | The regulatory core will apply these relaxations only for drivers that | ||
132 | support this feature by declaring the appropriate channel flags and | ||
133 | capabilities in their registration flow. | ||
134 | |||
98 | config CFG80211_DEFAULT_PS | 135 | config CFG80211_DEFAULT_PS |
99 | bool "enable powersave by default" | 136 | bool "enable powersave by default" |
100 | depends on CFG80211 | 137 | depends on CFG80211 |
diff --git a/net/wireless/ap.c b/net/wireless/ap.c index 3e02ade508d8..bdad1f951561 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c | |||
@@ -6,8 +6,8 @@ | |||
6 | #include "rdev-ops.h" | 6 | #include "rdev-ops.h" |
7 | 7 | ||
8 | 8 | ||
9 | static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | 9 | int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
10 | struct net_device *dev, bool notify) | 10 | struct net_device *dev, bool notify) |
11 | { | 11 | { |
12 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 12 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
13 | int err; | 13 | int err; |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 9c9501a35fb5..992b34070bcb 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -326,28 +326,57 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy, | |||
326 | 326 | ||
327 | 327 | ||
328 | int cfg80211_chandef_dfs_required(struct wiphy *wiphy, | 328 | int cfg80211_chandef_dfs_required(struct wiphy *wiphy, |
329 | const struct cfg80211_chan_def *chandef) | 329 | const struct cfg80211_chan_def *chandef, |
330 | enum nl80211_iftype iftype) | ||
330 | { | 331 | { |
331 | int width; | 332 | int width; |
332 | int r; | 333 | int ret; |
333 | 334 | ||
334 | if (WARN_ON(!cfg80211_chandef_valid(chandef))) | 335 | if (WARN_ON(!cfg80211_chandef_valid(chandef))) |
335 | return -EINVAL; | 336 | return -EINVAL; |
336 | 337 | ||
337 | width = cfg80211_chandef_get_width(chandef); | 338 | switch (iftype) { |
338 | if (width < 0) | 339 | case NL80211_IFTYPE_ADHOC: |
339 | return -EINVAL; | 340 | case NL80211_IFTYPE_AP: |
341 | case NL80211_IFTYPE_P2P_GO: | ||
342 | case NL80211_IFTYPE_MESH_POINT: | ||
343 | width = cfg80211_chandef_get_width(chandef); | ||
344 | if (width < 0) | ||
345 | return -EINVAL; | ||
340 | 346 | ||
341 | r = cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq1, | 347 | ret = cfg80211_get_chans_dfs_required(wiphy, |
342 | width); | 348 | chandef->center_freq1, |
343 | if (r) | 349 | width); |
344 | return r; | 350 | if (ret < 0) |
351 | return ret; | ||
352 | else if (ret > 0) | ||
353 | return BIT(chandef->width); | ||
345 | 354 | ||
346 | if (!chandef->center_freq2) | 355 | if (!chandef->center_freq2) |
347 | return 0; | 356 | return 0; |
357 | |||
358 | ret = cfg80211_get_chans_dfs_required(wiphy, | ||
359 | chandef->center_freq2, | ||
360 | width); | ||
361 | if (ret < 0) | ||
362 | return ret; | ||
363 | else if (ret > 0) | ||
364 | return BIT(chandef->width); | ||
348 | 365 | ||
349 | return cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq2, | 366 | break; |
350 | width); | 367 | case NL80211_IFTYPE_STATION: |
368 | case NL80211_IFTYPE_P2P_CLIENT: | ||
369 | case NL80211_IFTYPE_MONITOR: | ||
370 | case NL80211_IFTYPE_AP_VLAN: | ||
371 | case NL80211_IFTYPE_WDS: | ||
372 | case NL80211_IFTYPE_P2P_DEVICE: | ||
373 | break; | ||
374 | case NL80211_IFTYPE_UNSPECIFIED: | ||
375 | case NUM_NL80211_IFTYPES: | ||
376 | WARN_ON(1); | ||
377 | } | ||
378 | |||
379 | return 0; | ||
351 | } | 380 | } |
352 | EXPORT_SYMBOL(cfg80211_chandef_dfs_required); | 381 | EXPORT_SYMBOL(cfg80211_chandef_dfs_required); |
353 | 382 | ||
@@ -587,12 +616,14 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
587 | width = 5; | 616 | width = 5; |
588 | break; | 617 | break; |
589 | case NL80211_CHAN_WIDTH_10: | 618 | case NL80211_CHAN_WIDTH_10: |
619 | prohibited_flags |= IEEE80211_CHAN_NO_10MHZ; | ||
590 | width = 10; | 620 | width = 10; |
591 | break; | 621 | break; |
592 | case NL80211_CHAN_WIDTH_20: | 622 | case NL80211_CHAN_WIDTH_20: |
593 | if (!ht_cap->ht_supported) | 623 | if (!ht_cap->ht_supported) |
594 | return false; | 624 | return false; |
595 | case NL80211_CHAN_WIDTH_20_NOHT: | 625 | case NL80211_CHAN_WIDTH_20_NOHT: |
626 | prohibited_flags |= IEEE80211_CHAN_NO_20MHZ; | ||
596 | width = 20; | 627 | width = 20; |
597 | break; | 628 | break; |
598 | case NL80211_CHAN_WIDTH_40: | 629 | case NL80211_CHAN_WIDTH_40: |
@@ -661,17 +692,111 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
661 | } | 692 | } |
662 | EXPORT_SYMBOL(cfg80211_chandef_usable); | 693 | EXPORT_SYMBOL(cfg80211_chandef_usable); |
663 | 694 | ||
695 | /* | ||
696 | * For GO only, check if the channel can be used under permissive conditions | ||
697 | * mandated by the some regulatory bodies, i.e., the channel is marked with | ||
698 | * IEEE80211_CHAN_GO_CONCURRENT and there is an additional station interface | ||
699 | * associated to an AP on the same channel or on the same UNII band | ||
700 | * (assuming that the AP is an authorized master). | ||
701 | * In addition allow the GO to operate on a channel on which indoor operation is | ||
702 | * allowed, iff we are currently operating in an indoor environment. | ||
703 | */ | ||
704 | static bool cfg80211_go_permissive_chan(struct cfg80211_registered_device *rdev, | ||
705 | struct ieee80211_channel *chan) | ||
706 | { | ||
707 | struct wireless_dev *wdev_iter; | ||
708 | struct wiphy *wiphy = wiphy_idx_to_wiphy(rdev->wiphy_idx); | ||
709 | |||
710 | ASSERT_RTNL(); | ||
711 | |||
712 | if (!config_enabled(CONFIG_CFG80211_REG_RELAX_NO_IR) || | ||
713 | !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR)) | ||
714 | return false; | ||
715 | |||
716 | if (regulatory_indoor_allowed() && | ||
717 | (chan->flags & IEEE80211_CHAN_INDOOR_ONLY)) | ||
718 | return true; | ||
719 | |||
720 | if (!(chan->flags & IEEE80211_CHAN_GO_CONCURRENT)) | ||
721 | return false; | ||
722 | |||
723 | /* | ||
724 | * Generally, it is possible to rely on another device/driver to allow | ||
725 | * the GO concurrent relaxation, however, since the device can further | ||
726 | * enforce the relaxation (by doing a similar verifications as this), | ||
727 | * and thus fail the GO instantiation, consider only the interfaces of | ||
728 | * the current registered device. | ||
729 | */ | ||
730 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { | ||
731 | struct ieee80211_channel *other_chan = NULL; | ||
732 | int r1, r2; | ||
733 | |||
734 | if (wdev_iter->iftype != NL80211_IFTYPE_STATION || | ||
735 | !netif_running(wdev_iter->netdev)) | ||
736 | continue; | ||
737 | |||
738 | wdev_lock(wdev_iter); | ||
739 | if (wdev_iter->current_bss) | ||
740 | other_chan = wdev_iter->current_bss->pub.channel; | ||
741 | wdev_unlock(wdev_iter); | ||
742 | |||
743 | if (!other_chan) | ||
744 | continue; | ||
745 | |||
746 | if (chan == other_chan) | ||
747 | return true; | ||
748 | |||
749 | if (chan->band != IEEE80211_BAND_5GHZ) | ||
750 | continue; | ||
751 | |||
752 | r1 = cfg80211_get_unii(chan->center_freq); | ||
753 | r2 = cfg80211_get_unii(other_chan->center_freq); | ||
754 | |||
755 | if (r1 != -EINVAL && r1 == r2) { | ||
756 | /* | ||
757 | * At some locations channels 149-165 are considered a | ||
758 | * bundle, but at other locations, e.g., Indonesia, | ||
759 | * channels 149-161 are considered a bundle while | ||
760 | * channel 165 is left out and considered to be in a | ||
761 | * different bundle. Thus, in case that there is a | ||
762 | * station interface connected to an AP on channel 165, | ||
763 | * it is assumed that channels 149-161 are allowed for | ||
764 | * GO operations. However, having a station interface | ||
765 | * connected to an AP on channels 149-161, does not | ||
766 | * allow GO operation on channel 165. | ||
767 | */ | ||
768 | if (chan->center_freq == 5825 && | ||
769 | other_chan->center_freq != 5825) | ||
770 | continue; | ||
771 | return true; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | return false; | ||
776 | } | ||
777 | |||
664 | bool cfg80211_reg_can_beacon(struct wiphy *wiphy, | 778 | bool cfg80211_reg_can_beacon(struct wiphy *wiphy, |
665 | struct cfg80211_chan_def *chandef) | 779 | struct cfg80211_chan_def *chandef, |
780 | enum nl80211_iftype iftype) | ||
666 | { | 781 | { |
782 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | ||
667 | bool res; | 783 | bool res; |
668 | u32 prohibited_flags = IEEE80211_CHAN_DISABLED | | 784 | u32 prohibited_flags = IEEE80211_CHAN_DISABLED | |
669 | IEEE80211_CHAN_NO_IR | | ||
670 | IEEE80211_CHAN_RADAR; | 785 | IEEE80211_CHAN_RADAR; |
671 | 786 | ||
672 | trace_cfg80211_reg_can_beacon(wiphy, chandef); | 787 | trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype); |
673 | 788 | ||
674 | if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 && | 789 | /* |
790 | * Under certain conditions suggested by the some regulatory bodies | ||
791 | * a GO can operate on channels marked with IEEE80211_NO_IR | ||
792 | * so set this flag only if such relaxations are not enabled and | ||
793 | * the conditions are not met. | ||
794 | */ | ||
795 | if (iftype != NL80211_IFTYPE_P2P_GO || | ||
796 | !cfg80211_go_permissive_chan(rdev, chandef->chan)) | ||
797 | prohibited_flags |= IEEE80211_CHAN_NO_IR; | ||
798 | |||
799 | if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 && | ||
675 | cfg80211_chandef_dfs_available(wiphy, chandef)) { | 800 | cfg80211_chandef_dfs_available(wiphy, chandef)) { |
676 | /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ | 801 | /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ |
677 | prohibited_flags = IEEE80211_CHAN_DISABLED; | 802 | prohibited_flags = IEEE80211_CHAN_DISABLED; |
@@ -701,6 +826,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
701 | enum cfg80211_chan_mode *chanmode, | 826 | enum cfg80211_chan_mode *chanmode, |
702 | u8 *radar_detect) | 827 | u8 *radar_detect) |
703 | { | 828 | { |
829 | int ret; | ||
830 | |||
704 | *chan = NULL; | 831 | *chan = NULL; |
705 | *chanmode = CHAN_MODE_UNDEFINED; | 832 | *chanmode = CHAN_MODE_UNDEFINED; |
706 | 833 | ||
@@ -743,8 +870,11 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
743 | *chan = wdev->chandef.chan; | 870 | *chan = wdev->chandef.chan; |
744 | *chanmode = CHAN_MODE_SHARED; | 871 | *chanmode = CHAN_MODE_SHARED; |
745 | 872 | ||
746 | if (cfg80211_chandef_dfs_required(wdev->wiphy, | 873 | ret = cfg80211_chandef_dfs_required(wdev->wiphy, |
747 | &wdev->chandef)) | 874 | &wdev->chandef, |
875 | wdev->iftype); | ||
876 | WARN_ON(ret < 0); | ||
877 | if (ret > 0) | ||
748 | *radar_detect |= BIT(wdev->chandef.width); | 878 | *radar_detect |= BIT(wdev->chandef.width); |
749 | } | 879 | } |
750 | return; | 880 | return; |
@@ -753,8 +883,11 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
753 | *chan = wdev->chandef.chan; | 883 | *chan = wdev->chandef.chan; |
754 | *chanmode = CHAN_MODE_SHARED; | 884 | *chanmode = CHAN_MODE_SHARED; |
755 | 885 | ||
756 | if (cfg80211_chandef_dfs_required(wdev->wiphy, | 886 | ret = cfg80211_chandef_dfs_required(wdev->wiphy, |
757 | &wdev->chandef)) | 887 | &wdev->chandef, |
888 | wdev->iftype); | ||
889 | WARN_ON(ret < 0); | ||
890 | if (ret > 0) | ||
758 | *radar_detect |= BIT(wdev->chandef.width); | 891 | *radar_detect |= BIT(wdev->chandef.width); |
759 | } | 892 | } |
760 | return; | 893 | return; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 086cddd03ba6..a1c40654dd9b 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -69,7 +69,7 @@ struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) | |||
69 | 69 | ||
70 | int get_wiphy_idx(struct wiphy *wiphy) | 70 | int get_wiphy_idx(struct wiphy *wiphy) |
71 | { | 71 | { |
72 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 72 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
73 | 73 | ||
74 | return rdev->wiphy_idx; | 74 | return rdev->wiphy_idx; |
75 | } | 75 | } |
@@ -130,7 +130,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
130 | newname)) | 130 | newname)) |
131 | pr_err("failed to rename debugfs dir to %s!\n", newname); | 131 | pr_err("failed to rename debugfs dir to %s!\n", newname); |
132 | 132 | ||
133 | nl80211_notify_dev_rename(rdev); | 133 | nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); |
134 | 134 | ||
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
@@ -210,15 +210,12 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | 213 | void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy) |
214 | { | 214 | { |
215 | struct cfg80211_registered_device *rdev = data; | 215 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
216 | struct wireless_dev *wdev; | 216 | struct wireless_dev *wdev; |
217 | 217 | ||
218 | if (!blocked) | 218 | ASSERT_RTNL(); |
219 | return 0; | ||
220 | |||
221 | rtnl_lock(); | ||
222 | 219 | ||
223 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 220 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
224 | if (wdev->netdev) { | 221 | if (wdev->netdev) { |
@@ -234,7 +231,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) | |||
234 | break; | 231 | break; |
235 | } | 232 | } |
236 | } | 233 | } |
234 | } | ||
235 | EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces); | ||
236 | |||
237 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | ||
238 | { | ||
239 | struct cfg80211_registered_device *rdev = data; | ||
240 | |||
241 | if (!blocked) | ||
242 | return 0; | ||
237 | 243 | ||
244 | rtnl_lock(); | ||
245 | cfg80211_shutdown_all_interfaces(&rdev->wiphy); | ||
238 | rtnl_unlock(); | 246 | rtnl_unlock(); |
239 | 247 | ||
240 | return 0; | 248 | return 0; |
@@ -260,6 +268,45 @@ static void cfg80211_event_work(struct work_struct *work) | |||
260 | rtnl_unlock(); | 268 | rtnl_unlock(); |
261 | } | 269 | } |
262 | 270 | ||
271 | void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev) | ||
272 | { | ||
273 | struct cfg80211_iface_destroy *item; | ||
274 | |||
275 | ASSERT_RTNL(); | ||
276 | |||
277 | spin_lock_irq(&rdev->destroy_list_lock); | ||
278 | while ((item = list_first_entry_or_null(&rdev->destroy_list, | ||
279 | struct cfg80211_iface_destroy, | ||
280 | list))) { | ||
281 | struct wireless_dev *wdev, *tmp; | ||
282 | u32 nlportid = item->nlportid; | ||
283 | |||
284 | list_del(&item->list); | ||
285 | kfree(item); | ||
286 | spin_unlock_irq(&rdev->destroy_list_lock); | ||
287 | |||
288 | list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) { | ||
289 | if (nlportid == wdev->owner_nlportid) | ||
290 | rdev_del_virtual_intf(rdev, wdev); | ||
291 | } | ||
292 | |||
293 | spin_lock_irq(&rdev->destroy_list_lock); | ||
294 | } | ||
295 | spin_unlock_irq(&rdev->destroy_list_lock); | ||
296 | } | ||
297 | |||
298 | static void cfg80211_destroy_iface_wk(struct work_struct *work) | ||
299 | { | ||
300 | struct cfg80211_registered_device *rdev; | ||
301 | |||
302 | rdev = container_of(work, struct cfg80211_registered_device, | ||
303 | destroy_work); | ||
304 | |||
305 | rtnl_lock(); | ||
306 | cfg80211_destroy_ifaces(rdev); | ||
307 | rtnl_unlock(); | ||
308 | } | ||
309 | |||
263 | /* exported functions */ | 310 | /* exported functions */ |
264 | 311 | ||
265 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | 312 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) |
@@ -318,6 +365,10 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
318 | rdev->wiphy.dev.class = &ieee80211_class; | 365 | rdev->wiphy.dev.class = &ieee80211_class; |
319 | rdev->wiphy.dev.platform_data = rdev; | 366 | rdev->wiphy.dev.platform_data = rdev; |
320 | 367 | ||
368 | INIT_LIST_HEAD(&rdev->destroy_list); | ||
369 | spin_lock_init(&rdev->destroy_list_lock); | ||
370 | INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk); | ||
371 | |||
321 | #ifdef CONFIG_CFG80211_DEFAULT_PS | 372 | #ifdef CONFIG_CFG80211_DEFAULT_PS |
322 | rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | 373 | rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; |
323 | #endif | 374 | #endif |
@@ -351,6 +402,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
351 | rdev->wiphy.rts_threshold = (u32) -1; | 402 | rdev->wiphy.rts_threshold = (u32) -1; |
352 | rdev->wiphy.coverage_class = 0; | 403 | rdev->wiphy.coverage_class = 0; |
353 | 404 | ||
405 | rdev->wiphy.max_num_csa_counters = 1; | ||
406 | |||
354 | return &rdev->wiphy; | 407 | return &rdev->wiphy; |
355 | } | 408 | } |
356 | EXPORT_SYMBOL(wiphy_new); | 409 | EXPORT_SYMBOL(wiphy_new); |
@@ -396,10 +449,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) | |||
396 | for (j = 0; j < c->n_limits; j++) { | 449 | for (j = 0; j < c->n_limits; j++) { |
397 | u16 types = c->limits[j].types; | 450 | u16 types = c->limits[j].types; |
398 | 451 | ||
399 | /* | 452 | /* interface types shouldn't overlap */ |
400 | * interface types shouldn't overlap, this is | ||
401 | * used in cfg80211_can_change_interface() | ||
402 | */ | ||
403 | if (WARN_ON(types & all_iftypes)) | 453 | if (WARN_ON(types & all_iftypes)) |
404 | return -EINVAL; | 454 | return -EINVAL; |
405 | all_iftypes |= types; | 455 | all_iftypes |= types; |
@@ -435,7 +485,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) | |||
435 | 485 | ||
436 | int wiphy_register(struct wiphy *wiphy) | 486 | int wiphy_register(struct wiphy *wiphy) |
437 | { | 487 | { |
438 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 488 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
439 | int res; | 489 | int res; |
440 | enum ieee80211_band band; | 490 | enum ieee80211_band band; |
441 | struct ieee80211_supported_band *sband; | 491 | struct ieee80211_supported_band *sband; |
@@ -610,13 +660,15 @@ int wiphy_register(struct wiphy *wiphy) | |||
610 | return res; | 660 | return res; |
611 | } | 661 | } |
612 | 662 | ||
663 | nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY); | ||
664 | |||
613 | return 0; | 665 | return 0; |
614 | } | 666 | } |
615 | EXPORT_SYMBOL(wiphy_register); | 667 | EXPORT_SYMBOL(wiphy_register); |
616 | 668 | ||
617 | void wiphy_rfkill_start_polling(struct wiphy *wiphy) | 669 | void wiphy_rfkill_start_polling(struct wiphy *wiphy) |
618 | { | 670 | { |
619 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 671 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
620 | 672 | ||
621 | if (!rdev->ops->rfkill_poll) | 673 | if (!rdev->ops->rfkill_poll) |
622 | return; | 674 | return; |
@@ -627,7 +679,7 @@ EXPORT_SYMBOL(wiphy_rfkill_start_polling); | |||
627 | 679 | ||
628 | void wiphy_rfkill_stop_polling(struct wiphy *wiphy) | 680 | void wiphy_rfkill_stop_polling(struct wiphy *wiphy) |
629 | { | 681 | { |
630 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 682 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
631 | 683 | ||
632 | rfkill_pause_polling(rdev->rfkill); | 684 | rfkill_pause_polling(rdev->rfkill); |
633 | } | 685 | } |
@@ -635,7 +687,7 @@ EXPORT_SYMBOL(wiphy_rfkill_stop_polling); | |||
635 | 687 | ||
636 | void wiphy_unregister(struct wiphy *wiphy) | 688 | void wiphy_unregister(struct wiphy *wiphy) |
637 | { | 689 | { |
638 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 690 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
639 | 691 | ||
640 | wait_event(rdev->dev_wait, ({ | 692 | wait_event(rdev->dev_wait, ({ |
641 | int __count; | 693 | int __count; |
@@ -648,9 +700,10 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
648 | rfkill_unregister(rdev->rfkill); | 700 | rfkill_unregister(rdev->rfkill); |
649 | 701 | ||
650 | rtnl_lock(); | 702 | rtnl_lock(); |
703 | nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); | ||
651 | rdev->wiphy.registered = false; | 704 | rdev->wiphy.registered = false; |
652 | 705 | ||
653 | BUG_ON(!list_empty(&rdev->wdev_list)); | 706 | WARN_ON(!list_empty(&rdev->wdev_list)); |
654 | 707 | ||
655 | /* | 708 | /* |
656 | * First remove the hardware from everywhere, this makes | 709 | * First remove the hardware from everywhere, this makes |
@@ -675,6 +728,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
675 | cancel_work_sync(&rdev->conn_work); | 728 | cancel_work_sync(&rdev->conn_work); |
676 | flush_work(&rdev->event_work); | 729 | flush_work(&rdev->event_work); |
677 | cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); | 730 | cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); |
731 | flush_work(&rdev->destroy_work); | ||
678 | 732 | ||
679 | #ifdef CONFIG_PM | 733 | #ifdef CONFIG_PM |
680 | if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) | 734 | if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) |
@@ -707,7 +761,7 @@ EXPORT_SYMBOL(wiphy_free); | |||
707 | 761 | ||
708 | void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked) | 762 | void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked) |
709 | { | 763 | { |
710 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 764 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
711 | 765 | ||
712 | if (rfkill_set_hw_state(rdev->rfkill, blocked)) | 766 | if (rfkill_set_hw_state(rdev->rfkill, blocked)) |
713 | schedule_work(&rdev->rfkill_sync); | 767 | schedule_work(&rdev->rfkill_sync); |
@@ -716,7 +770,7 @@ EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); | |||
716 | 770 | ||
717 | void cfg80211_unregister_wdev(struct wireless_dev *wdev) | 771 | void cfg80211_unregister_wdev(struct wireless_dev *wdev) |
718 | { | 772 | { |
719 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 773 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
720 | 774 | ||
721 | ASSERT_RTNL(); | 775 | ASSERT_RTNL(); |
722 | 776 | ||
@@ -751,23 +805,23 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, | |||
751 | rdev->num_running_monitor_ifaces += num; | 805 | rdev->num_running_monitor_ifaces += num; |
752 | } | 806 | } |
753 | 807 | ||
754 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | 808 | void __cfg80211_leave(struct cfg80211_registered_device *rdev, |
755 | struct wireless_dev *wdev) | 809 | struct wireless_dev *wdev) |
756 | { | 810 | { |
757 | struct net_device *dev = wdev->netdev; | 811 | struct net_device *dev = wdev->netdev; |
758 | 812 | ||
759 | ASSERT_RTNL(); | 813 | ASSERT_RTNL(); |
814 | ASSERT_WDEV_LOCK(wdev); | ||
760 | 815 | ||
761 | switch (wdev->iftype) { | 816 | switch (wdev->iftype) { |
762 | case NL80211_IFTYPE_ADHOC: | 817 | case NL80211_IFTYPE_ADHOC: |
763 | cfg80211_leave_ibss(rdev, dev, true); | 818 | __cfg80211_leave_ibss(rdev, dev, true); |
764 | break; | 819 | break; |
765 | case NL80211_IFTYPE_P2P_CLIENT: | 820 | case NL80211_IFTYPE_P2P_CLIENT: |
766 | case NL80211_IFTYPE_STATION: | 821 | case NL80211_IFTYPE_STATION: |
767 | if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) | 822 | if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) |
768 | __cfg80211_stop_sched_scan(rdev, false); | 823 | __cfg80211_stop_sched_scan(rdev, false); |
769 | 824 | ||
770 | wdev_lock(wdev); | ||
771 | #ifdef CONFIG_CFG80211_WEXT | 825 | #ifdef CONFIG_CFG80211_WEXT |
772 | kfree(wdev->wext.ie); | 826 | kfree(wdev->wext.ie); |
773 | wdev->wext.ie = NULL; | 827 | wdev->wext.ie = NULL; |
@@ -776,32 +830,60 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, | |||
776 | #endif | 830 | #endif |
777 | cfg80211_disconnect(rdev, dev, | 831 | cfg80211_disconnect(rdev, dev, |
778 | WLAN_REASON_DEAUTH_LEAVING, true); | 832 | WLAN_REASON_DEAUTH_LEAVING, true); |
779 | wdev_unlock(wdev); | ||
780 | break; | 833 | break; |
781 | case NL80211_IFTYPE_MESH_POINT: | 834 | case NL80211_IFTYPE_MESH_POINT: |
782 | cfg80211_leave_mesh(rdev, dev); | 835 | __cfg80211_leave_mesh(rdev, dev); |
783 | break; | 836 | break; |
784 | case NL80211_IFTYPE_AP: | 837 | case NL80211_IFTYPE_AP: |
785 | case NL80211_IFTYPE_P2P_GO: | 838 | case NL80211_IFTYPE_P2P_GO: |
786 | cfg80211_stop_ap(rdev, dev, true); | 839 | __cfg80211_stop_ap(rdev, dev, true); |
787 | break; | 840 | break; |
788 | default: | 841 | default: |
789 | break; | 842 | break; |
790 | } | 843 | } |
791 | } | 844 | } |
792 | 845 | ||
846 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | ||
847 | struct wireless_dev *wdev) | ||
848 | { | ||
849 | wdev_lock(wdev); | ||
850 | __cfg80211_leave(rdev, wdev); | ||
851 | wdev_unlock(wdev); | ||
852 | } | ||
853 | |||
854 | void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
855 | gfp_t gfp) | ||
856 | { | ||
857 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | ||
858 | struct cfg80211_event *ev; | ||
859 | unsigned long flags; | ||
860 | |||
861 | trace_cfg80211_stop_iface(wiphy, wdev); | ||
862 | |||
863 | ev = kzalloc(sizeof(*ev), gfp); | ||
864 | if (!ev) | ||
865 | return; | ||
866 | |||
867 | ev->type = EVENT_STOPPED; | ||
868 | |||
869 | spin_lock_irqsave(&wdev->event_lock, flags); | ||
870 | list_add_tail(&ev->list, &wdev->event_list); | ||
871 | spin_unlock_irqrestore(&wdev->event_lock, flags); | ||
872 | queue_work(cfg80211_wq, &rdev->event_work); | ||
873 | } | ||
874 | EXPORT_SYMBOL(cfg80211_stop_iface); | ||
875 | |||
793 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | 876 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, |
794 | unsigned long state, void *ptr) | 877 | unsigned long state, void *ptr) |
795 | { | 878 | { |
796 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 879 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
797 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 880 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
798 | struct cfg80211_registered_device *rdev; | 881 | struct cfg80211_registered_device *rdev; |
799 | int ret; | ||
800 | 882 | ||
801 | if (!wdev) | 883 | if (!wdev) |
802 | return NOTIFY_DONE; | 884 | return NOTIFY_DONE; |
803 | 885 | ||
804 | rdev = wiphy_to_dev(wdev->wiphy); | 886 | rdev = wiphy_to_rdev(wdev->wiphy); |
805 | 887 | ||
806 | WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED); | 888 | WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED); |
807 | 889 | ||
@@ -959,13 +1041,14 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
959 | case NETDEV_PRE_UP: | 1041 | case NETDEV_PRE_UP: |
960 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) | 1042 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) |
961 | return notifier_from_errno(-EOPNOTSUPP); | 1043 | return notifier_from_errno(-EOPNOTSUPP); |
962 | ret = cfg80211_can_add_interface(rdev, wdev->iftype); | 1044 | if (rfkill_blocked(rdev->rfkill)) |
963 | if (ret) | 1045 | return notifier_from_errno(-ERFKILL); |
964 | return notifier_from_errno(ret); | ||
965 | break; | 1046 | break; |
1047 | default: | ||
1048 | return NOTIFY_DONE; | ||
966 | } | 1049 | } |
967 | 1050 | ||
968 | return NOTIFY_DONE; | 1051 | return NOTIFY_OK; |
969 | } | 1052 | } |
970 | 1053 | ||
971 | static struct notifier_block cfg80211_netdev_notifier = { | 1054 | static struct notifier_block cfg80211_netdev_notifier = { |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 5b1fdcadd469..e9afbf10e756 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -80,13 +80,17 @@ struct cfg80211_registered_device { | |||
80 | 80 | ||
81 | struct cfg80211_coalesce *coalesce; | 81 | struct cfg80211_coalesce *coalesce; |
82 | 82 | ||
83 | spinlock_t destroy_list_lock; | ||
84 | struct list_head destroy_list; | ||
85 | struct work_struct destroy_work; | ||
86 | |||
83 | /* must be last because of the way we do wiphy_priv(), | 87 | /* must be last because of the way we do wiphy_priv(), |
84 | * and it should at least be aligned to NETDEV_ALIGN */ | 88 | * and it should at least be aligned to NETDEV_ALIGN */ |
85 | struct wiphy wiphy __aligned(NETDEV_ALIGN); | 89 | struct wiphy wiphy __aligned(NETDEV_ALIGN); |
86 | }; | 90 | }; |
87 | 91 | ||
88 | static inline | 92 | static inline |
89 | struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy) | 93 | struct cfg80211_registered_device *wiphy_to_rdev(struct wiphy *wiphy) |
90 | { | 94 | { |
91 | BUG_ON(!wiphy); | 95 | BUG_ON(!wiphy); |
92 | return container_of(wiphy, struct cfg80211_registered_device, wiphy); | 96 | return container_of(wiphy, struct cfg80211_registered_device, wiphy); |
@@ -181,6 +185,7 @@ enum cfg80211_event_type { | |||
181 | EVENT_ROAMED, | 185 | EVENT_ROAMED, |
182 | EVENT_DISCONNECTED, | 186 | EVENT_DISCONNECTED, |
183 | EVENT_IBSS_JOINED, | 187 | EVENT_IBSS_JOINED, |
188 | EVENT_STOPPED, | ||
184 | }; | 189 | }; |
185 | 190 | ||
186 | struct cfg80211_event { | 191 | struct cfg80211_event { |
@@ -232,6 +237,13 @@ struct cfg80211_beacon_registration { | |||
232 | u32 nlportid; | 237 | u32 nlportid; |
233 | }; | 238 | }; |
234 | 239 | ||
240 | struct cfg80211_iface_destroy { | ||
241 | struct list_head list; | ||
242 | u32 nlportid; | ||
243 | }; | ||
244 | |||
245 | void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev); | ||
246 | |||
235 | /* free object */ | 247 | /* free object */ |
236 | void cfg80211_dev_free(struct cfg80211_registered_device *rdev); | 248 | void cfg80211_dev_free(struct cfg80211_registered_device *rdev); |
237 | 249 | ||
@@ -240,8 +252,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
240 | 252 | ||
241 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); | 253 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); |
242 | 254 | ||
243 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); | 255 | void cfg80211_bss_expire(struct cfg80211_registered_device *rdev); |
244 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | 256 | void cfg80211_bss_age(struct cfg80211_registered_device *rdev, |
245 | unsigned long age_secs); | 257 | unsigned long age_secs); |
246 | 258 | ||
247 | /* IBSS */ | 259 | /* IBSS */ |
@@ -270,6 +282,8 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
270 | struct net_device *dev, | 282 | struct net_device *dev, |
271 | struct mesh_setup *setup, | 283 | struct mesh_setup *setup, |
272 | const struct mesh_config *conf); | 284 | const struct mesh_config *conf); |
285 | int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | ||
286 | struct net_device *dev); | ||
273 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 287 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
274 | struct net_device *dev); | 288 | struct net_device *dev); |
275 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | 289 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, |
@@ -277,6 +291,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
277 | struct cfg80211_chan_def *chandef); | 291 | struct cfg80211_chan_def *chandef); |
278 | 292 | ||
279 | /* AP */ | 293 | /* AP */ |
294 | int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | ||
295 | struct net_device *dev, bool notify); | ||
280 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | 296 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
281 | struct net_device *dev, bool notify); | 297 | struct net_device *dev, bool notify); |
282 | 298 | ||
@@ -401,35 +417,6 @@ unsigned int | |||
401 | cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, | 417 | cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, |
402 | const struct cfg80211_chan_def *chandef); | 418 | const struct cfg80211_chan_def *chandef); |
403 | 419 | ||
404 | static inline int | ||
405 | cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | ||
406 | struct wireless_dev *wdev, | ||
407 | enum nl80211_iftype iftype) | ||
408 | { | ||
409 | return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL, | ||
410 | CHAN_MODE_UNDEFINED, 0); | ||
411 | } | ||
412 | |||
413 | static inline int | ||
414 | cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, | ||
415 | enum nl80211_iftype iftype) | ||
416 | { | ||
417 | if (rfkill_blocked(rdev->rfkill)) | ||
418 | return -ERFKILL; | ||
419 | |||
420 | return cfg80211_can_change_interface(rdev, NULL, iftype); | ||
421 | } | ||
422 | |||
423 | static inline int | ||
424 | cfg80211_can_use_chan(struct cfg80211_registered_device *rdev, | ||
425 | struct wireless_dev *wdev, | ||
426 | struct ieee80211_channel *chan, | ||
427 | enum cfg80211_chan_mode chanmode) | ||
428 | { | ||
429 | return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | ||
430 | chan, chanmode, 0); | ||
431 | } | ||
432 | |||
433 | static inline unsigned int elapsed_jiffies_msecs(unsigned long start) | 420 | static inline unsigned int elapsed_jiffies_msecs(unsigned long start) |
434 | { | 421 | { |
435 | unsigned long end = jiffies; | 422 | unsigned long end = jiffies; |
@@ -459,6 +446,8 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | |||
459 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, | 446 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, |
460 | enum nl80211_iftype iftype, int num); | 447 | enum nl80211_iftype iftype, int num); |
461 | 448 | ||
449 | void __cfg80211_leave(struct cfg80211_registered_device *rdev, | ||
450 | struct wireless_dev *wdev); | ||
462 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | 451 | void cfg80211_leave(struct cfg80211_registered_device *rdev, |
463 | struct wireless_dev *wdev); | 452 | struct wireless_dev *wdev); |
464 | 453 | ||
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c index e37862f1b127..d4860bfc020e 100644 --- a/net/wireless/ethtool.c +++ b/net/wireless/ethtool.c | |||
@@ -43,7 +43,7 @@ static void cfg80211_get_ringparam(struct net_device *dev, | |||
43 | struct ethtool_ringparam *rp) | 43 | struct ethtool_ringparam *rp) |
44 | { | 44 | { |
45 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 45 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
46 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 46 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
47 | 47 | ||
48 | memset(rp, 0, sizeof(*rp)); | 48 | memset(rp, 0, sizeof(*rp)); |
49 | 49 | ||
@@ -56,7 +56,7 @@ static int cfg80211_set_ringparam(struct net_device *dev, | |||
56 | struct ethtool_ringparam *rp) | 56 | struct ethtool_ringparam *rp) |
57 | { | 57 | { |
58 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 58 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
59 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 59 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
60 | 60 | ||
61 | if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) | 61 | if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) |
62 | return -EINVAL; | 62 | return -EINVAL; |
@@ -70,7 +70,7 @@ static int cfg80211_set_ringparam(struct net_device *dev, | |||
70 | static int cfg80211_get_sset_count(struct net_device *dev, int sset) | 70 | static int cfg80211_get_sset_count(struct net_device *dev, int sset) |
71 | { | 71 | { |
72 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 72 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
73 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 73 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
74 | if (rdev->ops->get_et_sset_count) | 74 | if (rdev->ops->get_et_sset_count) |
75 | return rdev_get_et_sset_count(rdev, dev, sset); | 75 | return rdev_get_et_sset_count(rdev, dev, sset); |
76 | return -EOPNOTSUPP; | 76 | return -EOPNOTSUPP; |
@@ -80,7 +80,7 @@ static void cfg80211_get_stats(struct net_device *dev, | |||
80 | struct ethtool_stats *stats, u64 *data) | 80 | struct ethtool_stats *stats, u64 *data) |
81 | { | 81 | { |
82 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 82 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
83 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 83 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
84 | if (rdev->ops->get_et_stats) | 84 | if (rdev->ops->get_et_stats) |
85 | rdev_get_et_stats(rdev, dev, stats, data); | 85 | rdev_get_et_stats(rdev, dev, stats, data); |
86 | } | 86 | } |
@@ -88,7 +88,7 @@ static void cfg80211_get_stats(struct net_device *dev, | |||
88 | static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) | 88 | static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) |
89 | { | 89 | { |
90 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 90 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
91 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 91 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
92 | if (rdev->ops->get_et_strings) | 92 | if (rdev->ops->get_et_strings) |
93 | rdev_get_et_strings(rdev, dev, sset, data); | 93 | rdev_get_et_strings(rdev, dev, sset, data); |
94 | } | 94 | } |
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk index b35da8dc85de..40c37fc5b67c 100644 --- a/net/wireless/genregdb.awk +++ b/net/wireless/genregdb.awk | |||
@@ -68,17 +68,7 @@ function parse_reg_rule() | |||
68 | sub(/,/, "", units) | 68 | sub(/,/, "", units) |
69 | dfs_cac = $9 | 69 | dfs_cac = $9 |
70 | if (units == "mW") { | 70 | if (units == "mW") { |
71 | if (power == 100) { | 71 | power = 10 * log(power)/log(10) |
72 | power = 20 | ||
73 | } else if (power == 200) { | ||
74 | power = 23 | ||
75 | } else if (power == 500) { | ||
76 | power = 27 | ||
77 | } else if (power == 1000) { | ||
78 | power = 30 | ||
79 | } else { | ||
80 | print "Unknown power value in database!" | ||
81 | } | ||
82 | } else { | 72 | } else { |
83 | dfs_cac = $8 | 73 | dfs_cac = $8 |
84 | } | 74 | } |
@@ -117,7 +107,7 @@ function parse_reg_rule() | |||
117 | 107 | ||
118 | } | 108 | } |
119 | flags = flags "0" | 109 | flags = flags "0" |
120 | printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags | 110 | printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags |
121 | rules++ | 111 | rules++ |
122 | } | 112 | } |
123 | 113 | ||
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index a6b5bdad039c..8f345da3ea5f 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -45,7 +45,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, | |||
45 | 45 | ||
46 | cfg80211_upload_connect_keys(wdev); | 46 | cfg80211_upload_connect_keys(wdev); |
47 | 47 | ||
48 | nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, | 48 | nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid, |
49 | GFP_KERNEL); | 49 | GFP_KERNEL); |
50 | #ifdef CONFIG_CFG80211_WEXT | 50 | #ifdef CONFIG_CFG80211_WEXT |
51 | memset(&wrqu, 0, sizeof(wrqu)); | 51 | memset(&wrqu, 0, sizeof(wrqu)); |
@@ -58,7 +58,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, | |||
58 | struct ieee80211_channel *channel, gfp_t gfp) | 58 | struct ieee80211_channel *channel, gfp_t gfp) |
59 | { | 59 | { |
60 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 60 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
61 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 61 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
62 | struct cfg80211_event *ev; | 62 | struct cfg80211_event *ev; |
63 | unsigned long flags; | 63 | unsigned long flags; |
64 | 64 | ||
@@ -88,8 +88,6 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
88 | struct cfg80211_cached_keys *connkeys) | 88 | struct cfg80211_cached_keys *connkeys) |
89 | { | 89 | { |
90 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 90 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
91 | struct ieee80211_channel *check_chan; | ||
92 | u8 radar_detect_width = 0; | ||
93 | int err; | 91 | int err; |
94 | 92 | ||
95 | ASSERT_WDEV_LOCK(wdev); | 93 | ASSERT_WDEV_LOCK(wdev); |
@@ -126,28 +124,6 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
126 | #ifdef CONFIG_CFG80211_WEXT | 124 | #ifdef CONFIG_CFG80211_WEXT |
127 | wdev->wext.ibss.chandef = params->chandef; | 125 | wdev->wext.ibss.chandef = params->chandef; |
128 | #endif | 126 | #endif |
129 | check_chan = params->chandef.chan; | ||
130 | if (params->userspace_handles_dfs) { | ||
131 | /* Check for radar even if the current channel is not | ||
132 | * a radar channel - it might decide to change to DFS | ||
133 | * channel later. | ||
134 | */ | ||
135 | radar_detect_width = BIT(params->chandef.width); | ||
136 | } | ||
137 | |||
138 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | ||
139 | check_chan, | ||
140 | (params->channel_fixed && | ||
141 | !radar_detect_width) | ||
142 | ? CHAN_MODE_SHARED | ||
143 | : CHAN_MODE_EXCLUSIVE, | ||
144 | radar_detect_width); | ||
145 | |||
146 | if (err) { | ||
147 | wdev->connect_keys = NULL; | ||
148 | return err; | ||
149 | } | ||
150 | |||
151 | err = rdev_join_ibss(rdev, dev, params); | 127 | err = rdev_join_ibss(rdev, dev, params); |
152 | if (err) { | 128 | if (err) { |
153 | wdev->connect_keys = NULL; | 129 | wdev->connect_keys = NULL; |
@@ -180,7 +156,7 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
180 | static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | 156 | static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) |
181 | { | 157 | { |
182 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 158 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
183 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 159 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
184 | int i; | 160 | int i; |
185 | 161 | ||
186 | ASSERT_WDEV_LOCK(wdev); | 162 | ASSERT_WDEV_LOCK(wdev); |
@@ -335,7 +311,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
335 | struct iw_freq *wextfreq, char *extra) | 311 | struct iw_freq *wextfreq, char *extra) |
336 | { | 312 | { |
337 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 313 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
338 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 314 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
339 | struct ieee80211_channel *chan = NULL; | 315 | struct ieee80211_channel *chan = NULL; |
340 | int err, freq; | 316 | int err, freq; |
341 | 317 | ||
@@ -346,7 +322,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
346 | if (!rdev->ops->join_ibss) | 322 | if (!rdev->ops->join_ibss) |
347 | return -EOPNOTSUPP; | 323 | return -EOPNOTSUPP; |
348 | 324 | ||
349 | freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); | 325 | freq = cfg80211_wext_freq(wextfreq); |
350 | if (freq < 0) | 326 | if (freq < 0) |
351 | return freq; | 327 | return freq; |
352 | 328 | ||
@@ -420,7 +396,7 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
420 | struct iw_point *data, char *ssid) | 396 | struct iw_point *data, char *ssid) |
421 | { | 397 | { |
422 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 398 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
423 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 399 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
424 | size_t len = data->length; | 400 | size_t len = data->length; |
425 | int err; | 401 | int err; |
426 | 402 | ||
@@ -444,8 +420,8 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
444 | if (len > 0 && ssid[len - 1] == '\0') | 420 | if (len > 0 && ssid[len - 1] == '\0') |
445 | len--; | 421 | len--; |
446 | 422 | ||
423 | memcpy(wdev->ssid, ssid, len); | ||
447 | wdev->wext.ibss.ssid = wdev->ssid; | 424 | wdev->wext.ibss.ssid = wdev->ssid; |
448 | memcpy(wdev->wext.ibss.ssid, ssid, len); | ||
449 | wdev->wext.ibss.ssid_len = len; | 425 | wdev->wext.ibss.ssid_len = len; |
450 | 426 | ||
451 | wdev_lock(wdev); | 427 | wdev_lock(wdev); |
@@ -487,7 +463,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
487 | struct sockaddr *ap_addr, char *extra) | 463 | struct sockaddr *ap_addr, char *extra) |
488 | { | 464 | { |
489 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 465 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
490 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 466 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
491 | u8 *bssid = ap_addr->sa_data; | 467 | u8 *bssid = ap_addr->sa_data; |
492 | int err; | 468 | int err; |
493 | 469 | ||
@@ -505,6 +481,9 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
505 | if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) | 481 | if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) |
506 | bssid = NULL; | 482 | bssid = NULL; |
507 | 483 | ||
484 | if (bssid && !is_valid_ether_addr(bssid)) | ||
485 | return -EINVAL; | ||
486 | |||
508 | /* both automatic */ | 487 | /* both automatic */ |
509 | if (!bssid && !wdev->wext.ibss.bssid) | 488 | if (!bssid && !wdev->wext.ibss.bssid) |
510 | return 0; | 489 | return 0; |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 5af5cc6b2c4c..092300b30c37 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -99,7 +99,6 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
99 | const struct mesh_config *conf) | 99 | const struct mesh_config *conf) |
100 | { | 100 | { |
101 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 101 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
102 | u8 radar_detect_width = 0; | ||
103 | int err; | 102 | int err; |
104 | 103 | ||
105 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); | 104 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); |
@@ -175,22 +174,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
175 | scan_width); | 174 | scan_width); |
176 | } | 175 | } |
177 | 176 | ||
178 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) | 177 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef, |
178 | NL80211_IFTYPE_MESH_POINT)) | ||
179 | return -EINVAL; | 179 | return -EINVAL; |
180 | 180 | ||
181 | err = cfg80211_chandef_dfs_required(wdev->wiphy, &setup->chandef); | ||
182 | if (err < 0) | ||
183 | return err; | ||
184 | if (err) | ||
185 | radar_detect_width = BIT(setup->chandef.width); | ||
186 | |||
187 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | ||
188 | setup->chandef.chan, | ||
189 | CHAN_MODE_SHARED, | ||
190 | radar_detect_width); | ||
191 | if (err) | ||
192 | return err; | ||
193 | |||
194 | err = rdev_join_mesh(rdev, dev, conf, setup); | 181 | err = rdev_join_mesh(rdev, dev, conf, setup); |
195 | if (!err) { | 182 | if (!err) { |
196 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); | 183 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); |
@@ -236,17 +223,6 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
236 | if (!netif_running(wdev->netdev)) | 223 | if (!netif_running(wdev->netdev)) |
237 | return -ENETDOWN; | 224 | return -ENETDOWN; |
238 | 225 | ||
239 | /* cfg80211_can_use_chan() calls | ||
240 | * cfg80211_can_use_iftype_chan() with no radar | ||
241 | * detection, so if we're trying to use a radar | ||
242 | * channel here, something is wrong. | ||
243 | */ | ||
244 | WARN_ON_ONCE(chandef->chan->flags & IEEE80211_CHAN_RADAR); | ||
245 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, | ||
246 | CHAN_MODE_SHARED); | ||
247 | if (err) | ||
248 | return err; | ||
249 | |||
250 | err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, | 226 | err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, |
251 | chandef->chan); | 227 | chandef->chan); |
252 | if (!err) | 228 | if (!err) |
@@ -262,8 +238,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
262 | return 0; | 238 | return 0; |
263 | } | 239 | } |
264 | 240 | ||
265 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 241 | int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
266 | struct net_device *dev) | 242 | struct net_device *dev) |
267 | { | 243 | { |
268 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 244 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
269 | int err; | 245 | int err; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index c52ff59a3e96..266766b8d80b 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -23,7 +23,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | |||
23 | { | 23 | { |
24 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 24 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
25 | struct wiphy *wiphy = wdev->wiphy; | 25 | struct wiphy *wiphy = wdev->wiphy; |
26 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 26 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
27 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | 27 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; |
28 | u8 *ie = mgmt->u.assoc_resp.variable; | 28 | u8 *ie = mgmt->u.assoc_resp.variable; |
29 | int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); | 29 | int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); |
@@ -54,7 +54,7 @@ EXPORT_SYMBOL(cfg80211_rx_assoc_resp); | |||
54 | static void cfg80211_process_auth(struct wireless_dev *wdev, | 54 | static void cfg80211_process_auth(struct wireless_dev *wdev, |
55 | const u8 *buf, size_t len) | 55 | const u8 *buf, size_t len) |
56 | { | 56 | { |
57 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 57 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
58 | 58 | ||
59 | nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL); | 59 | nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL); |
60 | cfg80211_sme_rx_auth(wdev, buf, len); | 60 | cfg80211_sme_rx_auth(wdev, buf, len); |
@@ -63,7 +63,7 @@ static void cfg80211_process_auth(struct wireless_dev *wdev, | |||
63 | static void cfg80211_process_deauth(struct wireless_dev *wdev, | 63 | static void cfg80211_process_deauth(struct wireless_dev *wdev, |
64 | const u8 *buf, size_t len) | 64 | const u8 *buf, size_t len) |
65 | { | 65 | { |
66 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 66 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
67 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | 67 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; |
68 | const u8 *bssid = mgmt->bssid; | 68 | const u8 *bssid = mgmt->bssid; |
69 | u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 69 | u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
@@ -82,7 +82,7 @@ static void cfg80211_process_deauth(struct wireless_dev *wdev, | |||
82 | static void cfg80211_process_disassoc(struct wireless_dev *wdev, | 82 | static void cfg80211_process_disassoc(struct wireless_dev *wdev, |
83 | const u8 *buf, size_t len) | 83 | const u8 *buf, size_t len) |
84 | { | 84 | { |
85 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 85 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
86 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | 86 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; |
87 | const u8 *bssid = mgmt->bssid; | 87 | const u8 *bssid = mgmt->bssid; |
88 | u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 88 | u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
@@ -123,7 +123,7 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr) | |||
123 | { | 123 | { |
124 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 124 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
125 | struct wiphy *wiphy = wdev->wiphy; | 125 | struct wiphy *wiphy = wdev->wiphy; |
126 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 126 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
127 | 127 | ||
128 | trace_cfg80211_send_auth_timeout(dev, addr); | 128 | trace_cfg80211_send_auth_timeout(dev, addr); |
129 | 129 | ||
@@ -136,7 +136,7 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss) | |||
136 | { | 136 | { |
137 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 137 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
138 | struct wiphy *wiphy = wdev->wiphy; | 138 | struct wiphy *wiphy = wdev->wiphy; |
139 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 139 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
140 | 140 | ||
141 | trace_cfg80211_send_assoc_timeout(dev, bss->bssid); | 141 | trace_cfg80211_send_assoc_timeout(dev, bss->bssid); |
142 | 142 | ||
@@ -172,7 +172,7 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, | |||
172 | const u8 *tsc, gfp_t gfp) | 172 | const u8 *tsc, gfp_t gfp) |
173 | { | 173 | { |
174 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 174 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
175 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 175 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
176 | #ifdef CONFIG_CFG80211_WEXT | 176 | #ifdef CONFIG_CFG80211_WEXT |
177 | union iwreq_data wrqu; | 177 | union iwreq_data wrqu; |
178 | char *buf = kmalloc(128, gfp); | 178 | char *buf = kmalloc(128, gfp); |
@@ -233,14 +233,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
233 | if (!req.bss) | 233 | if (!req.bss) |
234 | return -ENOENT; | 234 | return -ENOENT; |
235 | 235 | ||
236 | err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel, | ||
237 | CHAN_MODE_SHARED); | ||
238 | if (err) | ||
239 | goto out; | ||
240 | |||
241 | err = rdev_auth(rdev, dev, &req); | 236 | err = rdev_auth(rdev, dev, &req); |
242 | 237 | ||
243 | out: | ||
244 | cfg80211_put_bss(&rdev->wiphy, req.bss); | 238 | cfg80211_put_bss(&rdev->wiphy, req.bss); |
245 | return err; | 239 | return err; |
246 | } | 240 | } |
@@ -306,16 +300,10 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
306 | if (!req->bss) | 300 | if (!req->bss) |
307 | return -ENOENT; | 301 | return -ENOENT; |
308 | 302 | ||
309 | err = cfg80211_can_use_chan(rdev, wdev, chan, CHAN_MODE_SHARED); | ||
310 | if (err) | ||
311 | goto out; | ||
312 | |||
313 | err = rdev_assoc(rdev, dev, req); | 303 | err = rdev_assoc(rdev, dev, req); |
314 | if (!err) | 304 | if (!err) |
315 | cfg80211_hold_bss(bss_from_pub(req->bss)); | 305 | cfg80211_hold_bss(bss_from_pub(req->bss)); |
316 | 306 | else | |
317 | out: | ||
318 | if (err) | ||
319 | cfg80211_put_bss(&rdev->wiphy, req->bss); | 307 | cfg80211_put_bss(&rdev->wiphy, req->bss); |
320 | 308 | ||
321 | return err; | 309 | return err; |
@@ -414,7 +402,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, | |||
414 | int match_len) | 402 | int match_len) |
415 | { | 403 | { |
416 | struct wiphy *wiphy = wdev->wiphy; | 404 | struct wiphy *wiphy = wdev->wiphy; |
417 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 405 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
418 | struct cfg80211_mgmt_registration *reg, *nreg; | 406 | struct cfg80211_mgmt_registration *reg, *nreg; |
419 | int err = 0; | 407 | int err = 0; |
420 | u16 mgmt_type; | 408 | u16 mgmt_type; |
@@ -473,7 +461,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, | |||
473 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) | 461 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) |
474 | { | 462 | { |
475 | struct wiphy *wiphy = wdev->wiphy; | 463 | struct wiphy *wiphy = wdev->wiphy; |
476 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 464 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
477 | struct cfg80211_mgmt_registration *reg, *tmp; | 465 | struct cfg80211_mgmt_registration *reg, *tmp; |
478 | 466 | ||
479 | spin_lock_bh(&wdev->mgmt_registrations_lock); | 467 | spin_lock_bh(&wdev->mgmt_registrations_lock); |
@@ -620,7 +608,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | |||
620 | const u8 *buf, size_t len, u32 flags, gfp_t gfp) | 608 | const u8 *buf, size_t len, u32 flags, gfp_t gfp) |
621 | { | 609 | { |
622 | struct wiphy *wiphy = wdev->wiphy; | 610 | struct wiphy *wiphy = wdev->wiphy; |
623 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 611 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
624 | struct cfg80211_mgmt_registration *reg; | 612 | struct cfg80211_mgmt_registration *reg; |
625 | const struct ieee80211_txrx_stypes *stypes = | 613 | const struct ieee80211_txrx_stypes *stypes = |
626 | &wiphy->mgmt_stypes[wdev->iftype]; | 614 | &wiphy->mgmt_stypes[wdev->iftype]; |
@@ -739,7 +727,7 @@ void cfg80211_radar_event(struct wiphy *wiphy, | |||
739 | struct cfg80211_chan_def *chandef, | 727 | struct cfg80211_chan_def *chandef, |
740 | gfp_t gfp) | 728 | gfp_t gfp) |
741 | { | 729 | { |
742 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 730 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
743 | unsigned long timeout; | 731 | unsigned long timeout; |
744 | 732 | ||
745 | trace_cfg80211_radar_event(wiphy, chandef); | 733 | trace_cfg80211_radar_event(wiphy, chandef); |
@@ -764,7 +752,7 @@ void cfg80211_cac_event(struct net_device *netdev, | |||
764 | { | 752 | { |
765 | struct wireless_dev *wdev = netdev->ieee80211_ptr; | 753 | struct wireless_dev *wdev = netdev->ieee80211_ptr; |
766 | struct wiphy *wiphy = wdev->wiphy; | 754 | struct wiphy *wiphy = wdev->wiphy; |
767 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 755 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
768 | unsigned long timeout; | 756 | unsigned long timeout; |
769 | 757 | ||
770 | trace_cfg80211_cac_event(netdev, event); | 758 | trace_cfg80211_cac_event(netdev, event); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 052c1bf8ffac..ba4f1723c83a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -168,8 +168,8 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) | |||
168 | netdev = __dev_get_by_index(netns, ifindex); | 168 | netdev = __dev_get_by_index(netns, ifindex); |
169 | if (netdev) { | 169 | if (netdev) { |
170 | if (netdev->ieee80211_ptr) | 170 | if (netdev->ieee80211_ptr) |
171 | tmp = wiphy_to_dev( | 171 | tmp = wiphy_to_rdev( |
172 | netdev->ieee80211_ptr->wiphy); | 172 | netdev->ieee80211_ptr->wiphy); |
173 | else | 173 | else |
174 | tmp = NULL; | 174 | tmp = NULL; |
175 | 175 | ||
@@ -371,8 +371,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
371 | [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, | 371 | [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, |
372 | [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, | 372 | [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, |
373 | [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, | 373 | [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, |
374 | [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, | 374 | [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY }, |
375 | [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, | 375 | [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY }, |
376 | [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, | 376 | [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, |
377 | [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, | 377 | [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, |
378 | [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, | 378 | [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, |
@@ -385,6 +385,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
385 | [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, | 385 | [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, |
386 | [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, | 386 | [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, |
387 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, | 387 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, |
388 | [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, | ||
389 | [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, | ||
388 | }; | 390 | }; |
389 | 391 | ||
390 | /* policy for the key attributes */ | 392 | /* policy for the key attributes */ |
@@ -484,7 +486,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, | |||
484 | err = PTR_ERR(*wdev); | 486 | err = PTR_ERR(*wdev); |
485 | goto out_unlock; | 487 | goto out_unlock; |
486 | } | 488 | } |
487 | *rdev = wiphy_to_dev((*wdev)->wiphy); | 489 | *rdev = wiphy_to_rdev((*wdev)->wiphy); |
488 | /* 0 is the first index - add 1 to parse only once */ | 490 | /* 0 is the first index - add 1 to parse only once */ |
489 | cb->args[0] = (*rdev)->wiphy_idx + 1; | 491 | cb->args[0] = (*rdev)->wiphy_idx + 1; |
490 | cb->args[1] = (*wdev)->identifier; | 492 | cb->args[1] = (*wdev)->identifier; |
@@ -497,7 +499,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, | |||
497 | err = -ENODEV; | 499 | err = -ENODEV; |
498 | goto out_unlock; | 500 | goto out_unlock; |
499 | } | 501 | } |
500 | *rdev = wiphy_to_dev(wiphy); | 502 | *rdev = wiphy_to_rdev(wiphy); |
501 | *wdev = NULL; | 503 | *wdev = NULL; |
502 | 504 | ||
503 | list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { | 505 | list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { |
@@ -566,6 +568,13 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, | |||
566 | struct ieee80211_channel *chan, | 568 | struct ieee80211_channel *chan, |
567 | bool large) | 569 | bool large) |
568 | { | 570 | { |
571 | /* Some channels must be completely excluded from the | ||
572 | * list to protect old user-space tools from breaking | ||
573 | */ | ||
574 | if (!large && chan->flags & | ||
575 | (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ)) | ||
576 | return 0; | ||
577 | |||
569 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, | 578 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, |
570 | chan->center_freq)) | 579 | chan->center_freq)) |
571 | goto nla_put_failure; | 580 | goto nla_put_failure; |
@@ -613,6 +622,18 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, | |||
613 | if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) && | 622 | if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) && |
614 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ)) | 623 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ)) |
615 | goto nla_put_failure; | 624 | goto nla_put_failure; |
625 | if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) && | ||
626 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY)) | ||
627 | goto nla_put_failure; | ||
628 | if ((chan->flags & IEEE80211_CHAN_GO_CONCURRENT) && | ||
629 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_GO_CONCURRENT)) | ||
630 | goto nla_put_failure; | ||
631 | if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) && | ||
632 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ)) | ||
633 | goto nla_put_failure; | ||
634 | if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) && | ||
635 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ)) | ||
636 | goto nla_put_failure; | ||
616 | } | 637 | } |
617 | 638 | ||
618 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, | 639 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, |
@@ -950,8 +971,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy, | |||
950 | c->max_interfaces)) | 971 | c->max_interfaces)) |
951 | goto nla_put_failure; | 972 | goto nla_put_failure; |
952 | if (large && | 973 | if (large && |
953 | nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, | 974 | (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, |
954 | c->radar_detect_widths)) | 975 | c->radar_detect_widths) || |
976 | nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, | ||
977 | c->radar_detect_regions))) | ||
955 | goto nla_put_failure; | 978 | goto nla_put_failure; |
956 | 979 | ||
957 | nla_nest_end(msg, nl_combi); | 980 | nla_nest_end(msg, nl_combi); |
@@ -1006,42 +1029,42 @@ static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev, | |||
1006 | } | 1029 | } |
1007 | 1030 | ||
1008 | static int nl80211_send_wowlan(struct sk_buff *msg, | 1031 | static int nl80211_send_wowlan(struct sk_buff *msg, |
1009 | struct cfg80211_registered_device *dev, | 1032 | struct cfg80211_registered_device *rdev, |
1010 | bool large) | 1033 | bool large) |
1011 | { | 1034 | { |
1012 | struct nlattr *nl_wowlan; | 1035 | struct nlattr *nl_wowlan; |
1013 | 1036 | ||
1014 | if (!dev->wiphy.wowlan) | 1037 | if (!rdev->wiphy.wowlan) |
1015 | return 0; | 1038 | return 0; |
1016 | 1039 | ||
1017 | nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); | 1040 | nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); |
1018 | if (!nl_wowlan) | 1041 | if (!nl_wowlan) |
1019 | return -ENOBUFS; | 1042 | return -ENOBUFS; |
1020 | 1043 | ||
1021 | if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) && | 1044 | if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) && |
1022 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || | 1045 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || |
1023 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) && | 1046 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) && |
1024 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || | 1047 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || |
1025 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) && | 1048 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) && |
1026 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || | 1049 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || |
1027 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && | 1050 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && |
1028 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) || | 1051 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) || |
1029 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | 1052 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && |
1030 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || | 1053 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || |
1031 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && | 1054 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && |
1032 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || | 1055 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || |
1033 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && | 1056 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && |
1034 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || | 1057 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || |
1035 | ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) && | 1058 | ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) && |
1036 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) | 1059 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) |
1037 | return -ENOBUFS; | 1060 | return -ENOBUFS; |
1038 | 1061 | ||
1039 | if (dev->wiphy.wowlan->n_patterns) { | 1062 | if (rdev->wiphy.wowlan->n_patterns) { |
1040 | struct nl80211_pattern_support pat = { | 1063 | struct nl80211_pattern_support pat = { |
1041 | .max_patterns = dev->wiphy.wowlan->n_patterns, | 1064 | .max_patterns = rdev->wiphy.wowlan->n_patterns, |
1042 | .min_pattern_len = dev->wiphy.wowlan->pattern_min_len, | 1065 | .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len, |
1043 | .max_pattern_len = dev->wiphy.wowlan->pattern_max_len, | 1066 | .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len, |
1044 | .max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset, | 1067 | .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset, |
1045 | }; | 1068 | }; |
1046 | 1069 | ||
1047 | if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, | 1070 | if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, |
@@ -1049,7 +1072,7 @@ static int nl80211_send_wowlan(struct sk_buff *msg, | |||
1049 | return -ENOBUFS; | 1072 | return -ENOBUFS; |
1050 | } | 1073 | } |
1051 | 1074 | ||
1052 | if (large && nl80211_send_wowlan_tcp_caps(dev, msg)) | 1075 | if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) |
1053 | return -ENOBUFS; | 1076 | return -ENOBUFS; |
1054 | 1077 | ||
1055 | nla_nest_end(msg, nl_wowlan); | 1078 | nla_nest_end(msg, nl_wowlan); |
@@ -1059,19 +1082,19 @@ static int nl80211_send_wowlan(struct sk_buff *msg, | |||
1059 | #endif | 1082 | #endif |
1060 | 1083 | ||
1061 | static int nl80211_send_coalesce(struct sk_buff *msg, | 1084 | static int nl80211_send_coalesce(struct sk_buff *msg, |
1062 | struct cfg80211_registered_device *dev) | 1085 | struct cfg80211_registered_device *rdev) |
1063 | { | 1086 | { |
1064 | struct nl80211_coalesce_rule_support rule; | 1087 | struct nl80211_coalesce_rule_support rule; |
1065 | 1088 | ||
1066 | if (!dev->wiphy.coalesce) | 1089 | if (!rdev->wiphy.coalesce) |
1067 | return 0; | 1090 | return 0; |
1068 | 1091 | ||
1069 | rule.max_rules = dev->wiphy.coalesce->n_rules; | 1092 | rule.max_rules = rdev->wiphy.coalesce->n_rules; |
1070 | rule.max_delay = dev->wiphy.coalesce->max_delay; | 1093 | rule.max_delay = rdev->wiphy.coalesce->max_delay; |
1071 | rule.pat.max_patterns = dev->wiphy.coalesce->n_patterns; | 1094 | rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns; |
1072 | rule.pat.min_pattern_len = dev->wiphy.coalesce->pattern_min_len; | 1095 | rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len; |
1073 | rule.pat.max_pattern_len = dev->wiphy.coalesce->pattern_max_len; | 1096 | rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len; |
1074 | rule.pat.max_pkt_offset = dev->wiphy.coalesce->max_pkt_offset; | 1097 | rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset; |
1075 | 1098 | ||
1076 | if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule)) | 1099 | if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule)) |
1077 | return -ENOBUFS; | 1100 | return -ENOBUFS; |
@@ -1202,7 +1225,8 @@ struct nl80211_dump_wiphy_state { | |||
1202 | bool split; | 1225 | bool split; |
1203 | }; | 1226 | }; |
1204 | 1227 | ||
1205 | static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | 1228 | static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, |
1229 | enum nl80211_commands cmd, | ||
1206 | struct sk_buff *msg, u32 portid, u32 seq, | 1230 | struct sk_buff *msg, u32 portid, u32 seq, |
1207 | int flags, struct nl80211_dump_wiphy_state *state) | 1231 | int flags, struct nl80211_dump_wiphy_state *state) |
1208 | { | 1232 | { |
@@ -1214,63 +1238,66 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1214 | struct ieee80211_channel *chan; | 1238 | struct ieee80211_channel *chan; |
1215 | int i; | 1239 | int i; |
1216 | const struct ieee80211_txrx_stypes *mgmt_stypes = | 1240 | const struct ieee80211_txrx_stypes *mgmt_stypes = |
1217 | dev->wiphy.mgmt_stypes; | 1241 | rdev->wiphy.mgmt_stypes; |
1218 | u32 features; | 1242 | u32 features; |
1219 | 1243 | ||
1220 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); | 1244 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
1221 | if (!hdr) | 1245 | if (!hdr) |
1222 | return -ENOBUFS; | 1246 | return -ENOBUFS; |
1223 | 1247 | ||
1224 | if (WARN_ON(!state)) | 1248 | if (WARN_ON(!state)) |
1225 | return -EINVAL; | 1249 | return -EINVAL; |
1226 | 1250 | ||
1227 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || | 1251 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
1228 | nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, | 1252 | nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, |
1229 | wiphy_name(&dev->wiphy)) || | 1253 | wiphy_name(&rdev->wiphy)) || |
1230 | nla_put_u32(msg, NL80211_ATTR_GENERATION, | 1254 | nla_put_u32(msg, NL80211_ATTR_GENERATION, |
1231 | cfg80211_rdev_list_generation)) | 1255 | cfg80211_rdev_list_generation)) |
1232 | goto nla_put_failure; | 1256 | goto nla_put_failure; |
1233 | 1257 | ||
1258 | if (cmd != NL80211_CMD_NEW_WIPHY) | ||
1259 | goto finish; | ||
1260 | |||
1234 | switch (state->split_start) { | 1261 | switch (state->split_start) { |
1235 | case 0: | 1262 | case 0: |
1236 | if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, | 1263 | if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, |
1237 | dev->wiphy.retry_short) || | 1264 | rdev->wiphy.retry_short) || |
1238 | nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, | 1265 | nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, |
1239 | dev->wiphy.retry_long) || | 1266 | rdev->wiphy.retry_long) || |
1240 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | 1267 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, |
1241 | dev->wiphy.frag_threshold) || | 1268 | rdev->wiphy.frag_threshold) || |
1242 | nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, | 1269 | nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, |
1243 | dev->wiphy.rts_threshold) || | 1270 | rdev->wiphy.rts_threshold) || |
1244 | nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, | 1271 | nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, |
1245 | dev->wiphy.coverage_class) || | 1272 | rdev->wiphy.coverage_class) || |
1246 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, | 1273 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, |
1247 | dev->wiphy.max_scan_ssids) || | 1274 | rdev->wiphy.max_scan_ssids) || |
1248 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, | 1275 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, |
1249 | dev->wiphy.max_sched_scan_ssids) || | 1276 | rdev->wiphy.max_sched_scan_ssids) || |
1250 | nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, | 1277 | nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, |
1251 | dev->wiphy.max_scan_ie_len) || | 1278 | rdev->wiphy.max_scan_ie_len) || |
1252 | nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, | 1279 | nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, |
1253 | dev->wiphy.max_sched_scan_ie_len) || | 1280 | rdev->wiphy.max_sched_scan_ie_len) || |
1254 | nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS, | 1281 | nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS, |
1255 | dev->wiphy.max_match_sets)) | 1282 | rdev->wiphy.max_match_sets)) |
1256 | goto nla_put_failure; | 1283 | goto nla_put_failure; |
1257 | 1284 | ||
1258 | if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) && | 1285 | if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) && |
1259 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN)) | 1286 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN)) |
1260 | goto nla_put_failure; | 1287 | goto nla_put_failure; |
1261 | if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && | 1288 | if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && |
1262 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH)) | 1289 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH)) |
1263 | goto nla_put_failure; | 1290 | goto nla_put_failure; |
1264 | if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && | 1291 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && |
1265 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD)) | 1292 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD)) |
1266 | goto nla_put_failure; | 1293 | goto nla_put_failure; |
1267 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) && | 1294 | if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) && |
1268 | nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT)) | 1295 | nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT)) |
1269 | goto nla_put_failure; | 1296 | goto nla_put_failure; |
1270 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) && | 1297 | if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) && |
1271 | nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT)) | 1298 | nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT)) |
1272 | goto nla_put_failure; | 1299 | goto nla_put_failure; |
1273 | if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && | 1300 | if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && |
1274 | nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) | 1301 | nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) |
1275 | goto nla_put_failure; | 1302 | goto nla_put_failure; |
1276 | state->split_start++; | 1303 | state->split_start++; |
@@ -1278,35 +1305,35 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1278 | break; | 1305 | break; |
1279 | case 1: | 1306 | case 1: |
1280 | if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, | 1307 | if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, |
1281 | sizeof(u32) * dev->wiphy.n_cipher_suites, | 1308 | sizeof(u32) * rdev->wiphy.n_cipher_suites, |
1282 | dev->wiphy.cipher_suites)) | 1309 | rdev->wiphy.cipher_suites)) |
1283 | goto nla_put_failure; | 1310 | goto nla_put_failure; |
1284 | 1311 | ||
1285 | if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, | 1312 | if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, |
1286 | dev->wiphy.max_num_pmkids)) | 1313 | rdev->wiphy.max_num_pmkids)) |
1287 | goto nla_put_failure; | 1314 | goto nla_put_failure; |
1288 | 1315 | ||
1289 | if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && | 1316 | if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && |
1290 | nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE)) | 1317 | nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE)) |
1291 | goto nla_put_failure; | 1318 | goto nla_put_failure; |
1292 | 1319 | ||
1293 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, | 1320 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, |
1294 | dev->wiphy.available_antennas_tx) || | 1321 | rdev->wiphy.available_antennas_tx) || |
1295 | nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 1322 | nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
1296 | dev->wiphy.available_antennas_rx)) | 1323 | rdev->wiphy.available_antennas_rx)) |
1297 | goto nla_put_failure; | 1324 | goto nla_put_failure; |
1298 | 1325 | ||
1299 | if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) && | 1326 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) && |
1300 | nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, | 1327 | nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, |
1301 | dev->wiphy.probe_resp_offload)) | 1328 | rdev->wiphy.probe_resp_offload)) |
1302 | goto nla_put_failure; | 1329 | goto nla_put_failure; |
1303 | 1330 | ||
1304 | if ((dev->wiphy.available_antennas_tx || | 1331 | if ((rdev->wiphy.available_antennas_tx || |
1305 | dev->wiphy.available_antennas_rx) && | 1332 | rdev->wiphy.available_antennas_rx) && |
1306 | dev->ops->get_antenna) { | 1333 | rdev->ops->get_antenna) { |
1307 | u32 tx_ant = 0, rx_ant = 0; | 1334 | u32 tx_ant = 0, rx_ant = 0; |
1308 | int res; | 1335 | int res; |
1309 | res = rdev_get_antenna(dev, &tx_ant, &rx_ant); | 1336 | res = rdev_get_antenna(rdev, &tx_ant, &rx_ant); |
1310 | if (!res) { | 1337 | if (!res) { |
1311 | if (nla_put_u32(msg, | 1338 | if (nla_put_u32(msg, |
1312 | NL80211_ATTR_WIPHY_ANTENNA_TX, | 1339 | NL80211_ATTR_WIPHY_ANTENNA_TX, |
@@ -1323,7 +1350,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1323 | break; | 1350 | break; |
1324 | case 2: | 1351 | case 2: |
1325 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, | 1352 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, |
1326 | dev->wiphy.interface_modes)) | 1353 | rdev->wiphy.interface_modes)) |
1327 | goto nla_put_failure; | 1354 | goto nla_put_failure; |
1328 | state->split_start++; | 1355 | state->split_start++; |
1329 | if (state->split) | 1356 | if (state->split) |
@@ -1337,7 +1364,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1337 | band < IEEE80211_NUM_BANDS; band++) { | 1364 | band < IEEE80211_NUM_BANDS; band++) { |
1338 | struct ieee80211_supported_band *sband; | 1365 | struct ieee80211_supported_band *sband; |
1339 | 1366 | ||
1340 | sband = dev->wiphy.bands[band]; | 1367 | sband = rdev->wiphy.bands[band]; |
1341 | 1368 | ||
1342 | if (!sband) | 1369 | if (!sband) |
1343 | continue; | 1370 | continue; |
@@ -1414,7 +1441,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1414 | i = 0; | 1441 | i = 0; |
1415 | #define CMD(op, n) \ | 1442 | #define CMD(op, n) \ |
1416 | do { \ | 1443 | do { \ |
1417 | if (dev->ops->op) { \ | 1444 | if (rdev->ops->op) { \ |
1418 | i++; \ | 1445 | i++; \ |
1419 | if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \ | 1446 | if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \ |
1420 | goto nla_put_failure; \ | 1447 | goto nla_put_failure; \ |
@@ -1438,32 +1465,32 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1438 | CMD(set_pmksa, SET_PMKSA); | 1465 | CMD(set_pmksa, SET_PMKSA); |
1439 | CMD(del_pmksa, DEL_PMKSA); | 1466 | CMD(del_pmksa, DEL_PMKSA); |
1440 | CMD(flush_pmksa, FLUSH_PMKSA); | 1467 | CMD(flush_pmksa, FLUSH_PMKSA); |
1441 | if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) | 1468 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) |
1442 | CMD(remain_on_channel, REMAIN_ON_CHANNEL); | 1469 | CMD(remain_on_channel, REMAIN_ON_CHANNEL); |
1443 | CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); | 1470 | CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); |
1444 | CMD(mgmt_tx, FRAME); | 1471 | CMD(mgmt_tx, FRAME); |
1445 | CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); | 1472 | CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); |
1446 | if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { | 1473 | if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { |
1447 | i++; | 1474 | i++; |
1448 | if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) | 1475 | if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) |
1449 | goto nla_put_failure; | 1476 | goto nla_put_failure; |
1450 | } | 1477 | } |
1451 | if (dev->ops->set_monitor_channel || dev->ops->start_ap || | 1478 | if (rdev->ops->set_monitor_channel || rdev->ops->start_ap || |
1452 | dev->ops->join_mesh) { | 1479 | rdev->ops->join_mesh) { |
1453 | i++; | 1480 | i++; |
1454 | if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) | 1481 | if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) |
1455 | goto nla_put_failure; | 1482 | goto nla_put_failure; |
1456 | } | 1483 | } |
1457 | CMD(set_wds_peer, SET_WDS_PEER); | 1484 | CMD(set_wds_peer, SET_WDS_PEER); |
1458 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { | 1485 | if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { |
1459 | CMD(tdls_mgmt, TDLS_MGMT); | 1486 | CMD(tdls_mgmt, TDLS_MGMT); |
1460 | CMD(tdls_oper, TDLS_OPER); | 1487 | CMD(tdls_oper, TDLS_OPER); |
1461 | } | 1488 | } |
1462 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | 1489 | if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) |
1463 | CMD(sched_scan_start, START_SCHED_SCAN); | 1490 | CMD(sched_scan_start, START_SCHED_SCAN); |
1464 | CMD(probe_client, PROBE_CLIENT); | 1491 | CMD(probe_client, PROBE_CLIENT); |
1465 | CMD(set_noack_map, SET_NOACK_MAP); | 1492 | CMD(set_noack_map, SET_NOACK_MAP); |
1466 | if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { | 1493 | if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { |
1467 | i++; | 1494 | i++; |
1468 | if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) | 1495 | if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) |
1469 | goto nla_put_failure; | 1496 | goto nla_put_failure; |
@@ -1473,7 +1500,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1473 | if (state->split) { | 1500 | if (state->split) { |
1474 | CMD(crit_proto_start, CRIT_PROTOCOL_START); | 1501 | CMD(crit_proto_start, CRIT_PROTOCOL_START); |
1475 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); | 1502 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); |
1476 | if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) | 1503 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) |
1477 | CMD(channel_switch, CHANNEL_SWITCH); | 1504 | CMD(channel_switch, CHANNEL_SWITCH); |
1478 | } | 1505 | } |
1479 | CMD(set_qos_map, SET_QOS_MAP); | 1506 | CMD(set_qos_map, SET_QOS_MAP); |
@@ -1484,13 +1511,13 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1484 | 1511 | ||
1485 | #undef CMD | 1512 | #undef CMD |
1486 | 1513 | ||
1487 | if (dev->ops->connect || dev->ops->auth) { | 1514 | if (rdev->ops->connect || rdev->ops->auth) { |
1488 | i++; | 1515 | i++; |
1489 | if (nla_put_u32(msg, i, NL80211_CMD_CONNECT)) | 1516 | if (nla_put_u32(msg, i, NL80211_CMD_CONNECT)) |
1490 | goto nla_put_failure; | 1517 | goto nla_put_failure; |
1491 | } | 1518 | } |
1492 | 1519 | ||
1493 | if (dev->ops->disconnect || dev->ops->deauth) { | 1520 | if (rdev->ops->disconnect || rdev->ops->deauth) { |
1494 | i++; | 1521 | i++; |
1495 | if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT)) | 1522 | if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT)) |
1496 | goto nla_put_failure; | 1523 | goto nla_put_failure; |
@@ -1501,14 +1528,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1501 | if (state->split) | 1528 | if (state->split) |
1502 | break; | 1529 | break; |
1503 | case 5: | 1530 | case 5: |
1504 | if (dev->ops->remain_on_channel && | 1531 | if (rdev->ops->remain_on_channel && |
1505 | (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) && | 1532 | (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) && |
1506 | nla_put_u32(msg, | 1533 | nla_put_u32(msg, |
1507 | NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, | 1534 | NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, |
1508 | dev->wiphy.max_remain_on_channel_duration)) | 1535 | rdev->wiphy.max_remain_on_channel_duration)) |
1509 | goto nla_put_failure; | 1536 | goto nla_put_failure; |
1510 | 1537 | ||
1511 | if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) && | 1538 | if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) && |
1512 | nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) | 1539 | nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) |
1513 | goto nla_put_failure; | 1540 | goto nla_put_failure; |
1514 | 1541 | ||
@@ -1519,7 +1546,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1519 | break; | 1546 | break; |
1520 | case 6: | 1547 | case 6: |
1521 | #ifdef CONFIG_PM | 1548 | #ifdef CONFIG_PM |
1522 | if (nl80211_send_wowlan(msg, dev, state->split)) | 1549 | if (nl80211_send_wowlan(msg, rdev, state->split)) |
1523 | goto nla_put_failure; | 1550 | goto nla_put_failure; |
1524 | state->split_start++; | 1551 | state->split_start++; |
1525 | if (state->split) | 1552 | if (state->split) |
@@ -1529,10 +1556,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1529 | #endif | 1556 | #endif |
1530 | case 7: | 1557 | case 7: |
1531 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, | 1558 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, |
1532 | dev->wiphy.software_iftypes)) | 1559 | rdev->wiphy.software_iftypes)) |
1533 | goto nla_put_failure; | 1560 | goto nla_put_failure; |
1534 | 1561 | ||
1535 | if (nl80211_put_iface_combinations(&dev->wiphy, msg, | 1562 | if (nl80211_put_iface_combinations(&rdev->wiphy, msg, |
1536 | state->split)) | 1563 | state->split)) |
1537 | goto nla_put_failure; | 1564 | goto nla_put_failure; |
1538 | 1565 | ||
@@ -1540,12 +1567,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1540 | if (state->split) | 1567 | if (state->split) |
1541 | break; | 1568 | break; |
1542 | case 8: | 1569 | case 8: |
1543 | if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && | 1570 | if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && |
1544 | nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, | 1571 | nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, |
1545 | dev->wiphy.ap_sme_capa)) | 1572 | rdev->wiphy.ap_sme_capa)) |
1546 | goto nla_put_failure; | 1573 | goto nla_put_failure; |
1547 | 1574 | ||
1548 | features = dev->wiphy.features; | 1575 | features = rdev->wiphy.features; |
1549 | /* | 1576 | /* |
1550 | * We can only add the per-channel limit information if the | 1577 | * We can only add the per-channel limit information if the |
1551 | * dump is split, otherwise it makes it too big. Therefore | 1578 | * dump is split, otherwise it makes it too big. Therefore |
@@ -1556,16 +1583,16 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1556 | if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features)) | 1583 | if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features)) |
1557 | goto nla_put_failure; | 1584 | goto nla_put_failure; |
1558 | 1585 | ||
1559 | if (dev->wiphy.ht_capa_mod_mask && | 1586 | if (rdev->wiphy.ht_capa_mod_mask && |
1560 | nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, | 1587 | nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, |
1561 | sizeof(*dev->wiphy.ht_capa_mod_mask), | 1588 | sizeof(*rdev->wiphy.ht_capa_mod_mask), |
1562 | dev->wiphy.ht_capa_mod_mask)) | 1589 | rdev->wiphy.ht_capa_mod_mask)) |
1563 | goto nla_put_failure; | 1590 | goto nla_put_failure; |
1564 | 1591 | ||
1565 | if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME && | 1592 | if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME && |
1566 | dev->wiphy.max_acl_mac_addrs && | 1593 | rdev->wiphy.max_acl_mac_addrs && |
1567 | nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX, | 1594 | nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX, |
1568 | dev->wiphy.max_acl_mac_addrs)) | 1595 | rdev->wiphy.max_acl_mac_addrs)) |
1569 | goto nla_put_failure; | 1596 | goto nla_put_failure; |
1570 | 1597 | ||
1571 | /* | 1598 | /* |
@@ -1581,41 +1608,41 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1581 | state->split_start++; | 1608 | state->split_start++; |
1582 | break; | 1609 | break; |
1583 | case 9: | 1610 | case 9: |
1584 | if (dev->wiphy.extended_capabilities && | 1611 | if (rdev->wiphy.extended_capabilities && |
1585 | (nla_put(msg, NL80211_ATTR_EXT_CAPA, | 1612 | (nla_put(msg, NL80211_ATTR_EXT_CAPA, |
1586 | dev->wiphy.extended_capabilities_len, | 1613 | rdev->wiphy.extended_capabilities_len, |
1587 | dev->wiphy.extended_capabilities) || | 1614 | rdev->wiphy.extended_capabilities) || |
1588 | nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK, | 1615 | nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK, |
1589 | dev->wiphy.extended_capabilities_len, | 1616 | rdev->wiphy.extended_capabilities_len, |
1590 | dev->wiphy.extended_capabilities_mask))) | 1617 | rdev->wiphy.extended_capabilities_mask))) |
1591 | goto nla_put_failure; | 1618 | goto nla_put_failure; |
1592 | 1619 | ||
1593 | if (dev->wiphy.vht_capa_mod_mask && | 1620 | if (rdev->wiphy.vht_capa_mod_mask && |
1594 | nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, | 1621 | nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, |
1595 | sizeof(*dev->wiphy.vht_capa_mod_mask), | 1622 | sizeof(*rdev->wiphy.vht_capa_mod_mask), |
1596 | dev->wiphy.vht_capa_mod_mask)) | 1623 | rdev->wiphy.vht_capa_mod_mask)) |
1597 | goto nla_put_failure; | 1624 | goto nla_put_failure; |
1598 | 1625 | ||
1599 | state->split_start++; | 1626 | state->split_start++; |
1600 | break; | 1627 | break; |
1601 | case 10: | 1628 | case 10: |
1602 | if (nl80211_send_coalesce(msg, dev)) | 1629 | if (nl80211_send_coalesce(msg, rdev)) |
1603 | goto nla_put_failure; | 1630 | goto nla_put_failure; |
1604 | 1631 | ||
1605 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) && | 1632 | if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) && |
1606 | (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) || | 1633 | (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) || |
1607 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ))) | 1634 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ))) |
1608 | goto nla_put_failure; | 1635 | goto nla_put_failure; |
1609 | 1636 | ||
1610 | if (dev->wiphy.max_ap_assoc_sta && | 1637 | if (rdev->wiphy.max_ap_assoc_sta && |
1611 | nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA, | 1638 | nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA, |
1612 | dev->wiphy.max_ap_assoc_sta)) | 1639 | rdev->wiphy.max_ap_assoc_sta)) |
1613 | goto nla_put_failure; | 1640 | goto nla_put_failure; |
1614 | 1641 | ||
1615 | state->split_start++; | 1642 | state->split_start++; |
1616 | break; | 1643 | break; |
1617 | case 11: | 1644 | case 11: |
1618 | if (dev->wiphy.n_vendor_commands) { | 1645 | if (rdev->wiphy.n_vendor_commands) { |
1619 | const struct nl80211_vendor_cmd_info *info; | 1646 | const struct nl80211_vendor_cmd_info *info; |
1620 | struct nlattr *nested; | 1647 | struct nlattr *nested; |
1621 | 1648 | ||
@@ -1623,15 +1650,15 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1623 | if (!nested) | 1650 | if (!nested) |
1624 | goto nla_put_failure; | 1651 | goto nla_put_failure; |
1625 | 1652 | ||
1626 | for (i = 0; i < dev->wiphy.n_vendor_commands; i++) { | 1653 | for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) { |
1627 | info = &dev->wiphy.vendor_commands[i].info; | 1654 | info = &rdev->wiphy.vendor_commands[i].info; |
1628 | if (nla_put(msg, i + 1, sizeof(*info), info)) | 1655 | if (nla_put(msg, i + 1, sizeof(*info), info)) |
1629 | goto nla_put_failure; | 1656 | goto nla_put_failure; |
1630 | } | 1657 | } |
1631 | nla_nest_end(msg, nested); | 1658 | nla_nest_end(msg, nested); |
1632 | } | 1659 | } |
1633 | 1660 | ||
1634 | if (dev->wiphy.n_vendor_events) { | 1661 | if (rdev->wiphy.n_vendor_events) { |
1635 | const struct nl80211_vendor_cmd_info *info; | 1662 | const struct nl80211_vendor_cmd_info *info; |
1636 | struct nlattr *nested; | 1663 | struct nlattr *nested; |
1637 | 1664 | ||
@@ -1640,18 +1667,26 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1640 | if (!nested) | 1667 | if (!nested) |
1641 | goto nla_put_failure; | 1668 | goto nla_put_failure; |
1642 | 1669 | ||
1643 | for (i = 0; i < dev->wiphy.n_vendor_events; i++) { | 1670 | for (i = 0; i < rdev->wiphy.n_vendor_events; i++) { |
1644 | info = &dev->wiphy.vendor_events[i]; | 1671 | info = &rdev->wiphy.vendor_events[i]; |
1645 | if (nla_put(msg, i + 1, sizeof(*info), info)) | 1672 | if (nla_put(msg, i + 1, sizeof(*info), info)) |
1646 | goto nla_put_failure; | 1673 | goto nla_put_failure; |
1647 | } | 1674 | } |
1648 | nla_nest_end(msg, nested); | 1675 | nla_nest_end(msg, nested); |
1649 | } | 1676 | } |
1677 | state->split_start++; | ||
1678 | break; | ||
1679 | case 12: | ||
1680 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH && | ||
1681 | nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS, | ||
1682 | rdev->wiphy.max_num_csa_counters)) | ||
1683 | goto nla_put_failure; | ||
1650 | 1684 | ||
1651 | /* done */ | 1685 | /* done */ |
1652 | state->split_start = 0; | 1686 | state->split_start = 0; |
1653 | break; | 1687 | break; |
1654 | } | 1688 | } |
1689 | finish: | ||
1655 | return genlmsg_end(msg, hdr); | 1690 | return genlmsg_end(msg, hdr); |
1656 | 1691 | ||
1657 | nla_put_failure: | 1692 | nla_put_failure: |
@@ -1684,7 +1719,7 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb, | |||
1684 | if (!netdev) | 1719 | if (!netdev) |
1685 | return -ENODEV; | 1720 | return -ENODEV; |
1686 | if (netdev->ieee80211_ptr) { | 1721 | if (netdev->ieee80211_ptr) { |
1687 | rdev = wiphy_to_dev( | 1722 | rdev = wiphy_to_rdev( |
1688 | netdev->ieee80211_ptr->wiphy); | 1723 | netdev->ieee80211_ptr->wiphy); |
1689 | state->filter_wiphy = rdev->wiphy_idx; | 1724 | state->filter_wiphy = rdev->wiphy_idx; |
1690 | } | 1725 | } |
@@ -1697,7 +1732,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1697 | { | 1732 | { |
1698 | int idx = 0, ret; | 1733 | int idx = 0, ret; |
1699 | struct nl80211_dump_wiphy_state *state = (void *)cb->args[0]; | 1734 | struct nl80211_dump_wiphy_state *state = (void *)cb->args[0]; |
1700 | struct cfg80211_registered_device *dev; | 1735 | struct cfg80211_registered_device *rdev; |
1701 | 1736 | ||
1702 | rtnl_lock(); | 1737 | rtnl_lock(); |
1703 | if (!state) { | 1738 | if (!state) { |
@@ -1716,17 +1751,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1716 | cb->args[0] = (long)state; | 1751 | cb->args[0] = (long)state; |
1717 | } | 1752 | } |
1718 | 1753 | ||
1719 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { | 1754 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
1720 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) | 1755 | if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) |
1721 | continue; | 1756 | continue; |
1722 | if (++idx <= state->start) | 1757 | if (++idx <= state->start) |
1723 | continue; | 1758 | continue; |
1724 | if (state->filter_wiphy != -1 && | 1759 | if (state->filter_wiphy != -1 && |
1725 | state->filter_wiphy != dev->wiphy_idx) | 1760 | state->filter_wiphy != rdev->wiphy_idx) |
1726 | continue; | 1761 | continue; |
1727 | /* attempt to fit multiple wiphy data chunks into the skb */ | 1762 | /* attempt to fit multiple wiphy data chunks into the skb */ |
1728 | do { | 1763 | do { |
1729 | ret = nl80211_send_wiphy(dev, skb, | 1764 | ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, |
1765 | skb, | ||
1730 | NETLINK_CB(cb->skb).portid, | 1766 | NETLINK_CB(cb->skb).portid, |
1731 | cb->nlh->nlmsg_seq, | 1767 | cb->nlh->nlmsg_seq, |
1732 | NLM_F_MULTI, state); | 1768 | NLM_F_MULTI, state); |
@@ -1774,14 +1810,15 @@ static int nl80211_dump_wiphy_done(struct netlink_callback *cb) | |||
1774 | static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | 1810 | static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) |
1775 | { | 1811 | { |
1776 | struct sk_buff *msg; | 1812 | struct sk_buff *msg; |
1777 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1813 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1778 | struct nl80211_dump_wiphy_state state = {}; | 1814 | struct nl80211_dump_wiphy_state state = {}; |
1779 | 1815 | ||
1780 | msg = nlmsg_new(4096, GFP_KERNEL); | 1816 | msg = nlmsg_new(4096, GFP_KERNEL); |
1781 | if (!msg) | 1817 | if (!msg) |
1782 | return -ENOMEM; | 1818 | return -ENOMEM; |
1783 | 1819 | ||
1784 | if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0, | 1820 | if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg, |
1821 | info->snd_portid, info->snd_seq, 0, | ||
1785 | &state) < 0) { | 1822 | &state) < 0) { |
1786 | nlmsg_free(msg); | 1823 | nlmsg_free(msg); |
1787 | return -ENOBUFS; | 1824 | return -ENOBUFS; |
@@ -1908,18 +1945,20 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, | |||
1908 | } | 1945 | } |
1909 | 1946 | ||
1910 | static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, | 1947 | static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, |
1911 | struct wireless_dev *wdev, | 1948 | struct net_device *dev, |
1912 | struct genl_info *info) | 1949 | struct genl_info *info) |
1913 | { | 1950 | { |
1914 | struct cfg80211_chan_def chandef; | 1951 | struct cfg80211_chan_def chandef; |
1915 | int result; | 1952 | int result; |
1916 | enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; | 1953 | enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; |
1954 | struct wireless_dev *wdev = NULL; | ||
1917 | 1955 | ||
1918 | if (wdev) | 1956 | if (dev) |
1919 | iftype = wdev->iftype; | 1957 | wdev = dev->ieee80211_ptr; |
1920 | |||
1921 | if (!nl80211_can_set_dev_channel(wdev)) | 1958 | if (!nl80211_can_set_dev_channel(wdev)) |
1922 | return -EOPNOTSUPP; | 1959 | return -EOPNOTSUPP; |
1960 | if (wdev) | ||
1961 | iftype = wdev->iftype; | ||
1923 | 1962 | ||
1924 | result = nl80211_parse_chandef(rdev, info, &chandef); | 1963 | result = nl80211_parse_chandef(rdev, info, &chandef); |
1925 | if (result) | 1964 | if (result) |
@@ -1928,14 +1967,27 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, | |||
1928 | switch (iftype) { | 1967 | switch (iftype) { |
1929 | case NL80211_IFTYPE_AP: | 1968 | case NL80211_IFTYPE_AP: |
1930 | case NL80211_IFTYPE_P2P_GO: | 1969 | case NL80211_IFTYPE_P2P_GO: |
1931 | if (wdev->beacon_interval) { | 1970 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, iftype)) { |
1932 | result = -EBUSY; | ||
1933 | break; | ||
1934 | } | ||
1935 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) { | ||
1936 | result = -EINVAL; | 1971 | result = -EINVAL; |
1937 | break; | 1972 | break; |
1938 | } | 1973 | } |
1974 | if (wdev->beacon_interval) { | ||
1975 | if (!dev || !rdev->ops->set_ap_chanwidth || | ||
1976 | !(rdev->wiphy.features & | ||
1977 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) { | ||
1978 | result = -EBUSY; | ||
1979 | break; | ||
1980 | } | ||
1981 | |||
1982 | /* Only allow dynamic channel width changes */ | ||
1983 | if (chandef.chan != wdev->preset_chandef.chan) { | ||
1984 | result = -EBUSY; | ||
1985 | break; | ||
1986 | } | ||
1987 | result = rdev_set_ap_chanwidth(rdev, dev, &chandef); | ||
1988 | if (result) | ||
1989 | break; | ||
1990 | } | ||
1939 | wdev->preset_chandef = chandef; | 1991 | wdev->preset_chandef = chandef; |
1940 | result = 0; | 1992 | result = 0; |
1941 | break; | 1993 | break; |
@@ -1957,7 +2009,7 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) | |||
1957 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2009 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1958 | struct net_device *netdev = info->user_ptr[1]; | 2010 | struct net_device *netdev = info->user_ptr[1]; |
1959 | 2011 | ||
1960 | return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); | 2012 | return __nl80211_set_channel(rdev, netdev, info); |
1961 | } | 2013 | } |
1962 | 2014 | ||
1963 | static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) | 2015 | static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) |
@@ -2013,7 +2065,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
2013 | 2065 | ||
2014 | netdev = __dev_get_by_index(genl_info_net(info), ifindex); | 2066 | netdev = __dev_get_by_index(genl_info_net(info), ifindex); |
2015 | if (netdev && netdev->ieee80211_ptr) | 2067 | if (netdev && netdev->ieee80211_ptr) |
2016 | rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); | 2068 | rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy); |
2017 | else | 2069 | else |
2018 | netdev = NULL; | 2070 | netdev = NULL; |
2019 | } | 2071 | } |
@@ -2079,9 +2131,10 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
2079 | } | 2131 | } |
2080 | 2132 | ||
2081 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 2133 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { |
2082 | result = __nl80211_set_channel(rdev, | 2134 | result = __nl80211_set_channel( |
2083 | nl80211_can_set_dev_channel(wdev) ? wdev : NULL, | 2135 | rdev, |
2084 | info); | 2136 | nl80211_can_set_dev_channel(wdev) ? netdev : NULL, |
2137 | info); | ||
2085 | if (result) | 2138 | if (result) |
2086 | return result; | 2139 | return result; |
2087 | } | 2140 | } |
@@ -2229,7 +2282,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
2229 | static inline u64 wdev_id(struct wireless_dev *wdev) | 2282 | static inline u64 wdev_id(struct wireless_dev *wdev) |
2230 | { | 2283 | { |
2231 | return (u64)wdev->identifier | | 2284 | return (u64)wdev->identifier | |
2232 | ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); | 2285 | ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32); |
2233 | } | 2286 | } |
2234 | 2287 | ||
2235 | static int nl80211_send_chandef(struct sk_buff *msg, | 2288 | static int nl80211_send_chandef(struct sk_buff *msg, |
@@ -2355,7 +2408,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * | |||
2355 | static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | 2408 | static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) |
2356 | { | 2409 | { |
2357 | struct sk_buff *msg; | 2410 | struct sk_buff *msg; |
2358 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 2411 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2359 | struct wireless_dev *wdev = info->user_ptr[1]; | 2412 | struct wireless_dev *wdev = info->user_ptr[1]; |
2360 | 2413 | ||
2361 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 2414 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
@@ -2363,7 +2416,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
2363 | return -ENOMEM; | 2416 | return -ENOMEM; |
2364 | 2417 | ||
2365 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, | 2418 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, |
2366 | dev, wdev) < 0) { | 2419 | rdev, wdev) < 0) { |
2367 | nlmsg_free(msg); | 2420 | nlmsg_free(msg); |
2368 | return -ENOBUFS; | 2421 | return -ENOBUFS; |
2369 | } | 2422 | } |
@@ -2514,6 +2567,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2514 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 2567 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
2515 | u32 flags; | 2568 | u32 flags; |
2516 | 2569 | ||
2570 | /* to avoid failing a new interface creation due to pending removal */ | ||
2571 | cfg80211_destroy_ifaces(rdev); | ||
2572 | |||
2517 | memset(¶ms, 0, sizeof(params)); | 2573 | memset(¶ms, 0, sizeof(params)); |
2518 | 2574 | ||
2519 | if (!info->attrs[NL80211_ATTR_IFNAME]) | 2575 | if (!info->attrs[NL80211_ATTR_IFNAME]) |
@@ -2563,6 +2619,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2563 | return PTR_ERR(wdev); | 2619 | return PTR_ERR(wdev); |
2564 | } | 2620 | } |
2565 | 2621 | ||
2622 | if (info->attrs[NL80211_ATTR_IFACE_SOCKET_OWNER]) | ||
2623 | wdev->owner_nlportid = info->snd_portid; | ||
2624 | |||
2566 | switch (type) { | 2625 | switch (type) { |
2567 | case NL80211_IFTYPE_MESH_POINT: | 2626 | case NL80211_IFTYPE_MESH_POINT: |
2568 | if (!info->attrs[NL80211_ATTR_MESH_ID]) | 2627 | if (!info->attrs[NL80211_ATTR_MESH_ID]) |
@@ -3142,7 +3201,6 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
3142 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 3201 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
3143 | struct cfg80211_ap_settings params; | 3202 | struct cfg80211_ap_settings params; |
3144 | int err; | 3203 | int err; |
3145 | u8 radar_detect_width = 0; | ||
3146 | 3204 | ||
3147 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 3205 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
3148 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 3206 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
@@ -3258,24 +3316,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
3258 | } else if (!nl80211_get_ap_channel(rdev, ¶ms)) | 3316 | } else if (!nl80211_get_ap_channel(rdev, ¶ms)) |
3259 | return -EINVAL; | 3317 | return -EINVAL; |
3260 | 3318 | ||
3261 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) | 3319 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef, |
3320 | wdev->iftype)) | ||
3262 | return -EINVAL; | 3321 | return -EINVAL; |
3263 | 3322 | ||
3264 | err = cfg80211_chandef_dfs_required(wdev->wiphy, ¶ms.chandef); | ||
3265 | if (err < 0) | ||
3266 | return err; | ||
3267 | if (err) { | ||
3268 | radar_detect_width = BIT(params.chandef.width); | ||
3269 | params.radar_required = true; | ||
3270 | } | ||
3271 | |||
3272 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | ||
3273 | params.chandef.chan, | ||
3274 | CHAN_MODE_SHARED, | ||
3275 | radar_detect_width); | ||
3276 | if (err) | ||
3277 | return err; | ||
3278 | |||
3279 | if (info->attrs[NL80211_ATTR_ACL_POLICY]) { | 3323 | if (info->attrs[NL80211_ATTR_ACL_POLICY]) { |
3280 | params.acl = parse_acl_data(&rdev->wiphy, info); | 3324 | params.acl = parse_acl_data(&rdev->wiphy, info); |
3281 | if (IS_ERR(params.acl)) | 3325 | if (IS_ERR(params.acl)) |
@@ -3613,6 +3657,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3613 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, | 3657 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, |
3614 | sinfo->tx_failed)) | 3658 | sinfo->tx_failed)) |
3615 | goto nla_put_failure; | 3659 | goto nla_put_failure; |
3660 | if ((sinfo->filled & STATION_INFO_EXPECTED_THROUGHPUT) && | ||
3661 | nla_put_u32(msg, NL80211_STA_INFO_EXPECTED_THROUGHPUT, | ||
3662 | sinfo->expected_throughput)) | ||
3663 | goto nla_put_failure; | ||
3616 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && | 3664 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && |
3617 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, | 3665 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, |
3618 | sinfo->beacon_loss_count)) | 3666 | sinfo->beacon_loss_count)) |
@@ -3675,13 +3723,13 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
3675 | struct netlink_callback *cb) | 3723 | struct netlink_callback *cb) |
3676 | { | 3724 | { |
3677 | struct station_info sinfo; | 3725 | struct station_info sinfo; |
3678 | struct cfg80211_registered_device *dev; | 3726 | struct cfg80211_registered_device *rdev; |
3679 | struct wireless_dev *wdev; | 3727 | struct wireless_dev *wdev; |
3680 | u8 mac_addr[ETH_ALEN]; | 3728 | u8 mac_addr[ETH_ALEN]; |
3681 | int sta_idx = cb->args[2]; | 3729 | int sta_idx = cb->args[2]; |
3682 | int err; | 3730 | int err; |
3683 | 3731 | ||
3684 | err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev); | 3732 | err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); |
3685 | if (err) | 3733 | if (err) |
3686 | return err; | 3734 | return err; |
3687 | 3735 | ||
@@ -3690,14 +3738,14 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
3690 | goto out_err; | 3738 | goto out_err; |
3691 | } | 3739 | } |
3692 | 3740 | ||
3693 | if (!dev->ops->dump_station) { | 3741 | if (!rdev->ops->dump_station) { |
3694 | err = -EOPNOTSUPP; | 3742 | err = -EOPNOTSUPP; |
3695 | goto out_err; | 3743 | goto out_err; |
3696 | } | 3744 | } |
3697 | 3745 | ||
3698 | while (1) { | 3746 | while (1) { |
3699 | memset(&sinfo, 0, sizeof(sinfo)); | 3747 | memset(&sinfo, 0, sizeof(sinfo)); |
3700 | err = rdev_dump_station(dev, wdev->netdev, sta_idx, | 3748 | err = rdev_dump_station(rdev, wdev->netdev, sta_idx, |
3701 | mac_addr, &sinfo); | 3749 | mac_addr, &sinfo); |
3702 | if (err == -ENOENT) | 3750 | if (err == -ENOENT) |
3703 | break; | 3751 | break; |
@@ -3707,7 +3755,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
3707 | if (nl80211_send_station(skb, | 3755 | if (nl80211_send_station(skb, |
3708 | NETLINK_CB(cb->skb).portid, | 3756 | NETLINK_CB(cb->skb).portid, |
3709 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3757 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
3710 | dev, wdev->netdev, mac_addr, | 3758 | rdev, wdev->netdev, mac_addr, |
3711 | &sinfo) < 0) | 3759 | &sinfo) < 0) |
3712 | goto out; | 3760 | goto out; |
3713 | 3761 | ||
@@ -3719,7 +3767,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
3719 | cb->args[2] = sta_idx; | 3767 | cb->args[2] = sta_idx; |
3720 | err = skb->len; | 3768 | err = skb->len; |
3721 | out_err: | 3769 | out_err: |
3722 | nl80211_finish_wdev_dump(dev); | 3770 | nl80211_finish_wdev_dump(rdev); |
3723 | 3771 | ||
3724 | return err; | 3772 | return err; |
3725 | } | 3773 | } |
@@ -4380,18 +4428,18 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
4380 | struct netlink_callback *cb) | 4428 | struct netlink_callback *cb) |
4381 | { | 4429 | { |
4382 | struct mpath_info pinfo; | 4430 | struct mpath_info pinfo; |
4383 | struct cfg80211_registered_device *dev; | 4431 | struct cfg80211_registered_device *rdev; |
4384 | struct wireless_dev *wdev; | 4432 | struct wireless_dev *wdev; |
4385 | u8 dst[ETH_ALEN]; | 4433 | u8 dst[ETH_ALEN]; |
4386 | u8 next_hop[ETH_ALEN]; | 4434 | u8 next_hop[ETH_ALEN]; |
4387 | int path_idx = cb->args[2]; | 4435 | int path_idx = cb->args[2]; |
4388 | int err; | 4436 | int err; |
4389 | 4437 | ||
4390 | err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev); | 4438 | err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); |
4391 | if (err) | 4439 | if (err) |
4392 | return err; | 4440 | return err; |
4393 | 4441 | ||
4394 | if (!dev->ops->dump_mpath) { | 4442 | if (!rdev->ops->dump_mpath) { |
4395 | err = -EOPNOTSUPP; | 4443 | err = -EOPNOTSUPP; |
4396 | goto out_err; | 4444 | goto out_err; |
4397 | } | 4445 | } |
@@ -4402,7 +4450,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
4402 | } | 4450 | } |
4403 | 4451 | ||
4404 | while (1) { | 4452 | while (1) { |
4405 | err = rdev_dump_mpath(dev, wdev->netdev, path_idx, dst, | 4453 | err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst, |
4406 | next_hop, &pinfo); | 4454 | next_hop, &pinfo); |
4407 | if (err == -ENOENT) | 4455 | if (err == -ENOENT) |
4408 | break; | 4456 | break; |
@@ -4423,7 +4471,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
4423 | cb->args[2] = path_idx; | 4471 | cb->args[2] = path_idx; |
4424 | err = skb->len; | 4472 | err = skb->len; |
4425 | out_err: | 4473 | out_err: |
4426 | nl80211_finish_wdev_dump(dev); | 4474 | nl80211_finish_wdev_dump(rdev); |
4427 | return err; | 4475 | return err; |
4428 | } | 4476 | } |
4429 | 4477 | ||
@@ -4663,7 +4711,6 @@ static int parse_reg_rule(struct nlattr *tb[], | |||
4663 | 4711 | ||
4664 | static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | 4712 | static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) |
4665 | { | 4713 | { |
4666 | int r; | ||
4667 | char *data = NULL; | 4714 | char *data = NULL; |
4668 | enum nl80211_user_reg_hint_type user_reg_hint_type; | 4715 | enum nl80211_user_reg_hint_type user_reg_hint_type; |
4669 | 4716 | ||
@@ -4676,11 +4723,6 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
4676 | if (unlikely(!rcu_access_pointer(cfg80211_regdomain))) | 4723 | if (unlikely(!rcu_access_pointer(cfg80211_regdomain))) |
4677 | return -EINPROGRESS; | 4724 | return -EINPROGRESS; |
4678 | 4725 | ||
4679 | if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) | ||
4680 | return -EINVAL; | ||
4681 | |||
4682 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | ||
4683 | |||
4684 | if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]) | 4726 | if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]) |
4685 | user_reg_hint_type = | 4727 | user_reg_hint_type = |
4686 | nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]); | 4728 | nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]); |
@@ -4690,14 +4732,16 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
4690 | switch (user_reg_hint_type) { | 4732 | switch (user_reg_hint_type) { |
4691 | case NL80211_USER_REG_HINT_USER: | 4733 | case NL80211_USER_REG_HINT_USER: |
4692 | case NL80211_USER_REG_HINT_CELL_BASE: | 4734 | case NL80211_USER_REG_HINT_CELL_BASE: |
4693 | break; | 4735 | if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) |
4736 | return -EINVAL; | ||
4737 | |||
4738 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | ||
4739 | return regulatory_hint_user(data, user_reg_hint_type); | ||
4740 | case NL80211_USER_REG_HINT_INDOOR: | ||
4741 | return regulatory_hint_indoor_user(); | ||
4694 | default: | 4742 | default: |
4695 | return -EINVAL; | 4743 | return -EINVAL; |
4696 | } | 4744 | } |
4697 | |||
4698 | r = regulatory_hint_user(data, user_reg_hint_type); | ||
4699 | |||
4700 | return r; | ||
4701 | } | 4745 | } |
4702 | 4746 | ||
4703 | static int nl80211_get_mesh_config(struct sk_buff *skb, | 4747 | static int nl80211_get_mesh_config(struct sk_buff *skb, |
@@ -5796,7 +5840,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, | |||
5796 | if (wdev->cac_started) | 5840 | if (wdev->cac_started) |
5797 | return -EBUSY; | 5841 | return -EBUSY; |
5798 | 5842 | ||
5799 | err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef); | 5843 | err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, |
5844 | wdev->iftype); | ||
5800 | if (err < 0) | 5845 | if (err < 0) |
5801 | return err; | 5846 | return err; |
5802 | 5847 | ||
@@ -5809,12 +5854,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, | |||
5809 | if (!rdev->ops->start_radar_detection) | 5854 | if (!rdev->ops->start_radar_detection) |
5810 | return -EOPNOTSUPP; | 5855 | return -EOPNOTSUPP; |
5811 | 5856 | ||
5812 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | ||
5813 | chandef.chan, CHAN_MODE_SHARED, | ||
5814 | BIT(chandef.width)); | ||
5815 | if (err) | ||
5816 | return err; | ||
5817 | |||
5818 | cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); | 5857 | cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); |
5819 | if (WARN_ON(!cac_time_ms)) | 5858 | if (WARN_ON(!cac_time_ms)) |
5820 | cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; | 5859 | cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; |
@@ -5843,6 +5882,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5843 | u8 radar_detect_width = 0; | 5882 | u8 radar_detect_width = 0; |
5844 | int err; | 5883 | int err; |
5845 | bool need_new_beacon = false; | 5884 | bool need_new_beacon = false; |
5885 | int len, i; | ||
5846 | 5886 | ||
5847 | if (!rdev->ops->channel_switch || | 5887 | if (!rdev->ops->channel_switch || |
5848 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | 5888 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) |
@@ -5901,26 +5941,55 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5901 | if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) | 5941 | if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) |
5902 | return -EINVAL; | 5942 | return -EINVAL; |
5903 | 5943 | ||
5904 | params.counter_offset_beacon = | 5944 | len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); |
5905 | nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); | 5945 | if (!len || (len % sizeof(u16))) |
5906 | if (params.counter_offset_beacon >= params.beacon_csa.tail_len) | ||
5907 | return -EINVAL; | 5946 | return -EINVAL; |
5908 | 5947 | ||
5909 | /* sanity check - counters should be the same */ | 5948 | params.n_counter_offsets_beacon = len / sizeof(u16); |
5910 | if (params.beacon_csa.tail[params.counter_offset_beacon] != | 5949 | if (rdev->wiphy.max_num_csa_counters && |
5911 | params.count) | 5950 | (params.n_counter_offsets_beacon > |
5951 | rdev->wiphy.max_num_csa_counters)) | ||
5912 | return -EINVAL; | 5952 | return -EINVAL; |
5913 | 5953 | ||
5954 | params.counter_offsets_beacon = | ||
5955 | nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); | ||
5956 | |||
5957 | /* sanity checks - counters should fit and be the same */ | ||
5958 | for (i = 0; i < params.n_counter_offsets_beacon; i++) { | ||
5959 | u16 offset = params.counter_offsets_beacon[i]; | ||
5960 | |||
5961 | if (offset >= params.beacon_csa.tail_len) | ||
5962 | return -EINVAL; | ||
5963 | |||
5964 | if (params.beacon_csa.tail[offset] != params.count) | ||
5965 | return -EINVAL; | ||
5966 | } | ||
5967 | |||
5914 | if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { | 5968 | if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { |
5915 | params.counter_offset_presp = | 5969 | len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); |
5916 | nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); | 5970 | if (!len || (len % sizeof(u16))) |
5917 | if (params.counter_offset_presp >= | ||
5918 | params.beacon_csa.probe_resp_len) | ||
5919 | return -EINVAL; | 5971 | return -EINVAL; |
5920 | 5972 | ||
5921 | if (params.beacon_csa.probe_resp[params.counter_offset_presp] != | 5973 | params.n_counter_offsets_presp = len / sizeof(u16); |
5922 | params.count) | 5974 | if (rdev->wiphy.max_num_csa_counters && |
5975 | (params.n_counter_offsets_beacon > | ||
5976 | rdev->wiphy.max_num_csa_counters)) | ||
5923 | return -EINVAL; | 5977 | return -EINVAL; |
5978 | |||
5979 | params.counter_offsets_presp = | ||
5980 | nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); | ||
5981 | |||
5982 | /* sanity checks - counters should fit and be the same */ | ||
5983 | for (i = 0; i < params.n_counter_offsets_presp; i++) { | ||
5984 | u16 offset = params.counter_offsets_presp[i]; | ||
5985 | |||
5986 | if (offset >= params.beacon_csa.probe_resp_len) | ||
5987 | return -EINVAL; | ||
5988 | |||
5989 | if (params.beacon_csa.probe_resp[offset] != | ||
5990 | params.count) | ||
5991 | return -EINVAL; | ||
5992 | } | ||
5924 | } | 5993 | } |
5925 | 5994 | ||
5926 | skip_beacons: | 5995 | skip_beacons: |
@@ -5928,27 +5997,25 @@ skip_beacons: | |||
5928 | if (err) | 5997 | if (err) |
5929 | return err; | 5998 | return err; |
5930 | 5999 | ||
5931 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) | 6000 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef, |
6001 | wdev->iftype)) | ||
5932 | return -EINVAL; | 6002 | return -EINVAL; |
5933 | 6003 | ||
5934 | switch (dev->ieee80211_ptr->iftype) { | 6004 | err = cfg80211_chandef_dfs_required(wdev->wiphy, |
5935 | case NL80211_IFTYPE_AP: | 6005 | ¶ms.chandef, |
5936 | case NL80211_IFTYPE_P2P_GO: | 6006 | wdev->iftype); |
5937 | case NL80211_IFTYPE_ADHOC: | 6007 | if (err < 0) |
5938 | case NL80211_IFTYPE_MESH_POINT: | 6008 | return err; |
5939 | err = cfg80211_chandef_dfs_required(wdev->wiphy, | 6009 | |
5940 | ¶ms.chandef); | 6010 | if (err > 0) { |
5941 | if (err < 0) | 6011 | radar_detect_width = BIT(params.chandef.width); |
5942 | return err; | 6012 | params.radar_required = true; |
5943 | if (err) { | ||
5944 | radar_detect_width = BIT(params.chandef.width); | ||
5945 | params.radar_required = true; | ||
5946 | } | ||
5947 | break; | ||
5948 | default: | ||
5949 | break; | ||
5950 | } | 6013 | } |
5951 | 6014 | ||
6015 | /* TODO: I left this here for now. With channel switch, the | ||
6016 | * verification is a bit more complicated, because we only do | ||
6017 | * it later when the channel switch really happens. | ||
6018 | */ | ||
5952 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | 6019 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, |
5953 | params.chandef.chan, | 6020 | params.chandef.chan, |
5954 | CHAN_MODE_SHARED, | 6021 | CHAN_MODE_SHARED, |
@@ -6175,12 +6242,12 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6175 | struct netlink_callback *cb) | 6242 | struct netlink_callback *cb) |
6176 | { | 6243 | { |
6177 | struct survey_info survey; | 6244 | struct survey_info survey; |
6178 | struct cfg80211_registered_device *dev; | 6245 | struct cfg80211_registered_device *rdev; |
6179 | struct wireless_dev *wdev; | 6246 | struct wireless_dev *wdev; |
6180 | int survey_idx = cb->args[2]; | 6247 | int survey_idx = cb->args[2]; |
6181 | int res; | 6248 | int res; |
6182 | 6249 | ||
6183 | res = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev); | 6250 | res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); |
6184 | if (res) | 6251 | if (res) |
6185 | return res; | 6252 | return res; |
6186 | 6253 | ||
@@ -6189,7 +6256,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6189 | goto out_err; | 6256 | goto out_err; |
6190 | } | 6257 | } |
6191 | 6258 | ||
6192 | if (!dev->ops->dump_survey) { | 6259 | if (!rdev->ops->dump_survey) { |
6193 | res = -EOPNOTSUPP; | 6260 | res = -EOPNOTSUPP; |
6194 | goto out_err; | 6261 | goto out_err; |
6195 | } | 6262 | } |
@@ -6197,7 +6264,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6197 | while (1) { | 6264 | while (1) { |
6198 | struct ieee80211_channel *chan; | 6265 | struct ieee80211_channel *chan; |
6199 | 6266 | ||
6200 | res = rdev_dump_survey(dev, wdev->netdev, survey_idx, &survey); | 6267 | res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey); |
6201 | if (res == -ENOENT) | 6268 | if (res == -ENOENT) |
6202 | break; | 6269 | break; |
6203 | if (res) | 6270 | if (res) |
@@ -6209,7 +6276,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6209 | goto out; | 6276 | goto out; |
6210 | } | 6277 | } |
6211 | 6278 | ||
6212 | chan = ieee80211_get_channel(&dev->wiphy, | 6279 | chan = ieee80211_get_channel(&rdev->wiphy, |
6213 | survey.channel->center_freq); | 6280 | survey.channel->center_freq); |
6214 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { | 6281 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { |
6215 | survey_idx++; | 6282 | survey_idx++; |
@@ -6228,7 +6295,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6228 | cb->args[2] = survey_idx; | 6295 | cb->args[2] = survey_idx; |
6229 | res = skb->len; | 6296 | res = skb->len; |
6230 | out_err: | 6297 | out_err: |
6231 | nl80211_finish_wdev_dump(dev); | 6298 | nl80211_finish_wdev_dump(rdev); |
6232 | return res; | 6299 | return res; |
6233 | } | 6300 | } |
6234 | 6301 | ||
@@ -6704,7 +6771,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
6704 | if (err) | 6771 | if (err) |
6705 | return err; | 6772 | return err; |
6706 | 6773 | ||
6707 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) | 6774 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef, |
6775 | NL80211_IFTYPE_ADHOC)) | ||
6708 | return -EINVAL; | 6776 | return -EINVAL; |
6709 | 6777 | ||
6710 | switch (ibss.chandef.width) { | 6778 | switch (ibss.chandef.width) { |
@@ -6879,7 +6947,7 @@ struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | |||
6879 | int vendor_event_idx, | 6947 | int vendor_event_idx, |
6880 | int approxlen, gfp_t gfp) | 6948 | int approxlen, gfp_t gfp) |
6881 | { | 6949 | { |
6882 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 6950 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
6883 | const struct nl80211_vendor_cmd_info *info; | 6951 | const struct nl80211_vendor_cmd_info *info; |
6884 | 6952 | ||
6885 | switch (cmd) { | 6953 | switch (cmd) { |
@@ -7767,6 +7835,27 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7767 | if (!chandef.chan && params.offchan) | 7835 | if (!chandef.chan && params.offchan) |
7768 | return -EINVAL; | 7836 | return -EINVAL; |
7769 | 7837 | ||
7838 | params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); | ||
7839 | params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); | ||
7840 | |||
7841 | if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) { | ||
7842 | int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); | ||
7843 | int i; | ||
7844 | |||
7845 | if (len % sizeof(u16)) | ||
7846 | return -EINVAL; | ||
7847 | |||
7848 | params.n_csa_offsets = len / sizeof(u16); | ||
7849 | params.csa_offsets = | ||
7850 | nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); | ||
7851 | |||
7852 | /* check that all the offsets fit the frame */ | ||
7853 | for (i = 0; i < params.n_csa_offsets; i++) { | ||
7854 | if (params.csa_offsets[i] >= params.len) | ||
7855 | return -EINVAL; | ||
7856 | } | ||
7857 | } | ||
7858 | |||
7770 | if (!params.dont_wait_for_ack) { | 7859 | if (!params.dont_wait_for_ack) { |
7771 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 7860 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7772 | if (!msg) | 7861 | if (!msg) |
@@ -7780,8 +7869,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7780 | } | 7869 | } |
7781 | } | 7870 | } |
7782 | 7871 | ||
7783 | params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); | ||
7784 | params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); | ||
7785 | params.chan = chandef.chan; | 7872 | params.chan = chandef.chan; |
7786 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie); | 7873 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie); |
7787 | if (err) | 7874 | if (err) |
@@ -8478,6 +8565,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
8478 | 8565 | ||
8479 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], | 8566 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], |
8480 | rem) { | 8567 | rem) { |
8568 | u8 *mask_pat; | ||
8569 | |||
8481 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), | 8570 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), |
8482 | nla_len(pat), NULL); | 8571 | nla_len(pat), NULL); |
8483 | err = -EINVAL; | 8572 | err = -EINVAL; |
@@ -8501,19 +8590,18 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
8501 | goto error; | 8590 | goto error; |
8502 | new_triggers.patterns[i].pkt_offset = pkt_offset; | 8591 | new_triggers.patterns[i].pkt_offset = pkt_offset; |
8503 | 8592 | ||
8504 | new_triggers.patterns[i].mask = | 8593 | mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); |
8505 | kmalloc(mask_len + pat_len, GFP_KERNEL); | 8594 | if (!mask_pat) { |
8506 | if (!new_triggers.patterns[i].mask) { | ||
8507 | err = -ENOMEM; | 8595 | err = -ENOMEM; |
8508 | goto error; | 8596 | goto error; |
8509 | } | 8597 | } |
8510 | new_triggers.patterns[i].pattern = | 8598 | new_triggers.patterns[i].mask = mask_pat; |
8511 | new_triggers.patterns[i].mask + mask_len; | 8599 | memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), |
8512 | memcpy(new_triggers.patterns[i].mask, | ||
8513 | nla_data(pat_tb[NL80211_PKTPAT_MASK]), | ||
8514 | mask_len); | 8600 | mask_len); |
8601 | mask_pat += mask_len; | ||
8602 | new_triggers.patterns[i].pattern = mask_pat; | ||
8515 | new_triggers.patterns[i].pattern_len = pat_len; | 8603 | new_triggers.patterns[i].pattern_len = pat_len; |
8516 | memcpy(new_triggers.patterns[i].pattern, | 8604 | memcpy(mask_pat, |
8517 | nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), | 8605 | nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), |
8518 | pat_len); | 8606 | pat_len); |
8519 | i++; | 8607 | i++; |
@@ -8705,6 +8793,8 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, | |||
8705 | 8793 | ||
8706 | nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], | 8794 | nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], |
8707 | rem) { | 8795 | rem) { |
8796 | u8 *mask_pat; | ||
8797 | |||
8708 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), | 8798 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), |
8709 | nla_len(pat), NULL); | 8799 | nla_len(pat), NULL); |
8710 | if (!pat_tb[NL80211_PKTPAT_MASK] || | 8800 | if (!pat_tb[NL80211_PKTPAT_MASK] || |
@@ -8726,17 +8816,19 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, | |||
8726 | return -EINVAL; | 8816 | return -EINVAL; |
8727 | new_rule->patterns[i].pkt_offset = pkt_offset; | 8817 | new_rule->patterns[i].pkt_offset = pkt_offset; |
8728 | 8818 | ||
8729 | new_rule->patterns[i].mask = | 8819 | mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); |
8730 | kmalloc(mask_len + pat_len, GFP_KERNEL); | 8820 | if (!mask_pat) |
8731 | if (!new_rule->patterns[i].mask) | ||
8732 | return -ENOMEM; | 8821 | return -ENOMEM; |
8733 | new_rule->patterns[i].pattern = | 8822 | |
8734 | new_rule->patterns[i].mask + mask_len; | 8823 | new_rule->patterns[i].mask = mask_pat; |
8735 | memcpy(new_rule->patterns[i].mask, | 8824 | memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), |
8736 | nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len); | 8825 | mask_len); |
8826 | |||
8827 | mask_pat += mask_len; | ||
8828 | new_rule->patterns[i].pattern = mask_pat; | ||
8737 | new_rule->patterns[i].pattern_len = pat_len; | 8829 | new_rule->patterns[i].pattern_len = pat_len; |
8738 | memcpy(new_rule->patterns[i].pattern, | 8830 | memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), |
8739 | nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len); | 8831 | pat_len); |
8740 | i++; | 8832 | i++; |
8741 | } | 8833 | } |
8742 | 8834 | ||
@@ -8981,9 +9073,8 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) | |||
8981 | if (wdev->p2p_started) | 9073 | if (wdev->p2p_started) |
8982 | return 0; | 9074 | return 0; |
8983 | 9075 | ||
8984 | err = cfg80211_can_add_interface(rdev, wdev->iftype); | 9076 | if (rfkill_blocked(rdev->rfkill)) |
8985 | if (err) | 9077 | return -ERFKILL; |
8986 | return err; | ||
8987 | 9078 | ||
8988 | err = rdev_start_p2p_device(rdev, wdev); | 9079 | err = rdev_start_p2p_device(rdev, wdev); |
8989 | if (err) | 9080 | if (err) |
@@ -9192,7 +9283,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy, | |||
9192 | enum nl80211_attrs attr, | 9283 | enum nl80211_attrs attr, |
9193 | int approxlen) | 9284 | int approxlen) |
9194 | { | 9285 | { |
9195 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 9286 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
9196 | 9287 | ||
9197 | if (WARN_ON(!rdev->cur_cmd_info)) | 9288 | if (WARN_ON(!rdev->cur_cmd_info)) |
9198 | return NULL; | 9289 | return NULL; |
@@ -9316,7 +9407,7 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, | |||
9316 | } | 9407 | } |
9317 | 9408 | ||
9318 | dev = wdev->netdev; | 9409 | dev = wdev->netdev; |
9319 | rdev = wiphy_to_dev(wdev->wiphy); | 9410 | rdev = wiphy_to_rdev(wdev->wiphy); |
9320 | 9411 | ||
9321 | if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { | 9412 | if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { |
9322 | if (!dev) { | 9413 | if (!dev) { |
@@ -10017,16 +10108,20 @@ static const struct genl_ops nl80211_ops[] = { | |||
10017 | 10108 | ||
10018 | /* notification functions */ | 10109 | /* notification functions */ |
10019 | 10110 | ||
10020 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | 10111 | void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, |
10112 | enum nl80211_commands cmd) | ||
10021 | { | 10113 | { |
10022 | struct sk_buff *msg; | 10114 | struct sk_buff *msg; |
10023 | struct nl80211_dump_wiphy_state state = {}; | 10115 | struct nl80211_dump_wiphy_state state = {}; |
10024 | 10116 | ||
10117 | WARN_ON(cmd != NL80211_CMD_NEW_WIPHY && | ||
10118 | cmd != NL80211_CMD_DEL_WIPHY); | ||
10119 | |||
10025 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 10120 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
10026 | if (!msg) | 10121 | if (!msg) |
10027 | return; | 10122 | return; |
10028 | 10123 | ||
10029 | if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, &state) < 0) { | 10124 | if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) { |
10030 | nlmsg_free(msg); | 10125 | nlmsg_free(msg); |
10031 | return; | 10126 | return; |
10032 | } | 10127 | } |
@@ -10345,7 +10440,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, | |||
10345 | { | 10440 | { |
10346 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 10441 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
10347 | struct wiphy *wiphy = wdev->wiphy; | 10442 | struct wiphy *wiphy = wdev->wiphy; |
10348 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 10443 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10349 | const struct ieee80211_mgmt *mgmt = (void *)buf; | 10444 | const struct ieee80211_mgmt *mgmt = (void *)buf; |
10350 | u32 cmd; | 10445 | u32 cmd; |
10351 | 10446 | ||
@@ -10567,7 +10662,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, | |||
10567 | const u8* ie, u8 ie_len, gfp_t gfp) | 10662 | const u8* ie, u8 ie_len, gfp_t gfp) |
10568 | { | 10663 | { |
10569 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 10664 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
10570 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 10665 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
10571 | struct sk_buff *msg; | 10666 | struct sk_buff *msg; |
10572 | void *hdr; | 10667 | void *hdr; |
10573 | 10668 | ||
@@ -10747,7 +10842,7 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, | |||
10747 | unsigned int duration, gfp_t gfp) | 10842 | unsigned int duration, gfp_t gfp) |
10748 | { | 10843 | { |
10749 | struct wiphy *wiphy = wdev->wiphy; | 10844 | struct wiphy *wiphy = wdev->wiphy; |
10750 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 10845 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10751 | 10846 | ||
10752 | trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration); | 10847 | trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration); |
10753 | nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, | 10848 | nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, |
@@ -10761,7 +10856,7 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, | |||
10761 | gfp_t gfp) | 10856 | gfp_t gfp) |
10762 | { | 10857 | { |
10763 | struct wiphy *wiphy = wdev->wiphy; | 10858 | struct wiphy *wiphy = wdev->wiphy; |
10764 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 10859 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10765 | 10860 | ||
10766 | trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan); | 10861 | trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan); |
10767 | nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, | 10862 | nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, |
@@ -10773,7 +10868,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | |||
10773 | struct station_info *sinfo, gfp_t gfp) | 10868 | struct station_info *sinfo, gfp_t gfp) |
10774 | { | 10869 | { |
10775 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 10870 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
10776 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 10871 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10777 | struct sk_buff *msg; | 10872 | struct sk_buff *msg; |
10778 | 10873 | ||
10779 | trace_cfg80211_new_sta(dev, mac_addr, sinfo); | 10874 | trace_cfg80211_new_sta(dev, mac_addr, sinfo); |
@@ -10796,7 +10891,7 @@ EXPORT_SYMBOL(cfg80211_new_sta); | |||
10796 | void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | 10891 | void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) |
10797 | { | 10892 | { |
10798 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 10893 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
10799 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 10894 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10800 | struct sk_buff *msg; | 10895 | struct sk_buff *msg; |
10801 | void *hdr; | 10896 | void *hdr; |
10802 | 10897 | ||
@@ -10833,7 +10928,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | |||
10833 | gfp_t gfp) | 10928 | gfp_t gfp) |
10834 | { | 10929 | { |
10835 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 10930 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
10836 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 10931 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10837 | struct sk_buff *msg; | 10932 | struct sk_buff *msg; |
10838 | void *hdr; | 10933 | void *hdr; |
10839 | 10934 | ||
@@ -10868,7 +10963,7 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | |||
10868 | const u8 *addr, gfp_t gfp) | 10963 | const u8 *addr, gfp_t gfp) |
10869 | { | 10964 | { |
10870 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 10965 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
10871 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 10966 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
10872 | struct sk_buff *msg; | 10967 | struct sk_buff *msg; |
10873 | void *hdr; | 10968 | void *hdr; |
10874 | u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); | 10969 | u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); |
@@ -10988,7 +11083,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | |||
10988 | const u8 *buf, size_t len, bool ack, gfp_t gfp) | 11083 | const u8 *buf, size_t len, bool ack, gfp_t gfp) |
10989 | { | 11084 | { |
10990 | struct wiphy *wiphy = wdev->wiphy; | 11085 | struct wiphy *wiphy = wdev->wiphy; |
10991 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11086 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
10992 | struct net_device *netdev = wdev->netdev; | 11087 | struct net_device *netdev = wdev->netdev; |
10993 | struct sk_buff *msg; | 11088 | struct sk_buff *msg; |
10994 | void *hdr; | 11089 | void *hdr; |
@@ -11032,7 +11127,7 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, | |||
11032 | { | 11127 | { |
11033 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11128 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11034 | struct wiphy *wiphy = wdev->wiphy; | 11129 | struct wiphy *wiphy = wdev->wiphy; |
11035 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11130 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11036 | struct sk_buff *msg; | 11131 | struct sk_buff *msg; |
11037 | struct nlattr *pinfoattr; | 11132 | struct nlattr *pinfoattr; |
11038 | void *hdr; | 11133 | void *hdr; |
@@ -11124,7 +11219,7 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, | |||
11124 | { | 11219 | { |
11125 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11220 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11126 | struct wiphy *wiphy = wdev->wiphy; | 11221 | struct wiphy *wiphy = wdev->wiphy; |
11127 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11222 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11128 | 11223 | ||
11129 | trace_cfg80211_gtk_rekey_notify(dev, bssid); | 11224 | trace_cfg80211_gtk_rekey_notify(dev, bssid); |
11130 | nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); | 11225 | nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); |
@@ -11182,7 +11277,7 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | |||
11182 | { | 11277 | { |
11183 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11278 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11184 | struct wiphy *wiphy = wdev->wiphy; | 11279 | struct wiphy *wiphy = wdev->wiphy; |
11185 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11280 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11186 | 11281 | ||
11187 | trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth); | 11282 | trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth); |
11188 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); | 11283 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); |
@@ -11229,7 +11324,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev, | |||
11229 | { | 11324 | { |
11230 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11325 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11231 | struct wiphy *wiphy = wdev->wiphy; | 11326 | struct wiphy *wiphy = wdev->wiphy; |
11232 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11327 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11233 | 11328 | ||
11234 | ASSERT_WDEV_LOCK(wdev); | 11329 | ASSERT_WDEV_LOCK(wdev); |
11235 | 11330 | ||
@@ -11253,7 +11348,7 @@ void cfg80211_cqm_txe_notify(struct net_device *dev, | |||
11253 | { | 11348 | { |
11254 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11349 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11255 | struct wiphy *wiphy = wdev->wiphy; | 11350 | struct wiphy *wiphy = wdev->wiphy; |
11256 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11351 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11257 | struct sk_buff *msg; | 11352 | struct sk_buff *msg; |
11258 | struct nlattr *pinfoattr; | 11353 | struct nlattr *pinfoattr; |
11259 | void *hdr; | 11354 | void *hdr; |
@@ -11353,7 +11448,7 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, | |||
11353 | { | 11448 | { |
11354 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11449 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11355 | struct wiphy *wiphy = wdev->wiphy; | 11450 | struct wiphy *wiphy = wdev->wiphy; |
11356 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11451 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11357 | struct sk_buff *msg; | 11452 | struct sk_buff *msg; |
11358 | struct nlattr *pinfoattr; | 11453 | struct nlattr *pinfoattr; |
11359 | void *hdr; | 11454 | void *hdr; |
@@ -11400,7 +11495,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
11400 | u64 cookie, bool acked, gfp_t gfp) | 11495 | u64 cookie, bool acked, gfp_t gfp) |
11401 | { | 11496 | { |
11402 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11497 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11403 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 11498 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
11404 | struct sk_buff *msg; | 11499 | struct sk_buff *msg; |
11405 | void *hdr; | 11500 | void *hdr; |
11406 | 11501 | ||
@@ -11440,7 +11535,7 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, | |||
11440 | const u8 *frame, size_t len, | 11535 | const u8 *frame, size_t len, |
11441 | int freq, int sig_dbm) | 11536 | int freq, int sig_dbm) |
11442 | { | 11537 | { |
11443 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11538 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11444 | struct sk_buff *msg; | 11539 | struct sk_buff *msg; |
11445 | void *hdr; | 11540 | void *hdr; |
11446 | struct cfg80211_beacon_registration *reg; | 11541 | struct cfg80211_beacon_registration *reg; |
@@ -11487,7 +11582,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
11487 | struct cfg80211_wowlan_wakeup *wakeup, | 11582 | struct cfg80211_wowlan_wakeup *wakeup, |
11488 | gfp_t gfp) | 11583 | gfp_t gfp) |
11489 | { | 11584 | { |
11490 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 11585 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
11491 | struct sk_buff *msg; | 11586 | struct sk_buff *msg; |
11492 | void *hdr; | 11587 | void *hdr; |
11493 | int size = 200; | 11588 | int size = 200; |
@@ -11597,7 +11692,7 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, | |||
11597 | u16 reason_code, gfp_t gfp) | 11692 | u16 reason_code, gfp_t gfp) |
11598 | { | 11693 | { |
11599 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 11694 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11600 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 11695 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
11601 | struct sk_buff *msg; | 11696 | struct sk_buff *msg; |
11602 | void *hdr; | 11697 | void *hdr; |
11603 | 11698 | ||
@@ -11649,9 +11744,15 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
11649 | rcu_read_lock(); | 11744 | rcu_read_lock(); |
11650 | 11745 | ||
11651 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { | 11746 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
11652 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) | 11747 | bool schedule_destroy_work = false; |
11748 | |||
11749 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { | ||
11653 | cfg80211_mlme_unregister_socket(wdev, notify->portid); | 11750 | cfg80211_mlme_unregister_socket(wdev, notify->portid); |
11654 | 11751 | ||
11752 | if (wdev->owner_nlportid == notify->portid) | ||
11753 | schedule_destroy_work = true; | ||
11754 | } | ||
11755 | |||
11655 | spin_lock_bh(&rdev->beacon_registrations_lock); | 11756 | spin_lock_bh(&rdev->beacon_registrations_lock); |
11656 | list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations, | 11757 | list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations, |
11657 | list) { | 11758 | list) { |
@@ -11662,11 +11763,24 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
11662 | } | 11763 | } |
11663 | } | 11764 | } |
11664 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 11765 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
11766 | |||
11767 | if (schedule_destroy_work) { | ||
11768 | struct cfg80211_iface_destroy *destroy; | ||
11769 | |||
11770 | destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC); | ||
11771 | if (destroy) { | ||
11772 | destroy->nlportid = notify->portid; | ||
11773 | spin_lock(&rdev->destroy_list_lock); | ||
11774 | list_add(&destroy->list, &rdev->destroy_list); | ||
11775 | spin_unlock(&rdev->destroy_list_lock); | ||
11776 | schedule_work(&rdev->destroy_work); | ||
11777 | } | ||
11778 | } | ||
11665 | } | 11779 | } |
11666 | 11780 | ||
11667 | rcu_read_unlock(); | 11781 | rcu_read_unlock(); |
11668 | 11782 | ||
11669 | return NOTIFY_DONE; | 11783 | return NOTIFY_OK; |
11670 | } | 11784 | } |
11671 | 11785 | ||
11672 | static struct notifier_block nl80211_netlink_notifier = { | 11786 | static struct notifier_block nl80211_netlink_notifier = { |
@@ -11677,7 +11791,7 @@ void cfg80211_ft_event(struct net_device *netdev, | |||
11677 | struct cfg80211_ft_event_params *ft_event) | 11791 | struct cfg80211_ft_event_params *ft_event) |
11678 | { | 11792 | { |
11679 | struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy; | 11793 | struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy; |
11680 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11794 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11681 | struct sk_buff *msg; | 11795 | struct sk_buff *msg; |
11682 | void *hdr; | 11796 | void *hdr; |
11683 | 11797 | ||
@@ -11724,7 +11838,7 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp) | |||
11724 | void *hdr; | 11838 | void *hdr; |
11725 | u32 nlportid; | 11839 | u32 nlportid; |
11726 | 11840 | ||
11727 | rdev = wiphy_to_dev(wdev->wiphy); | 11841 | rdev = wiphy_to_rdev(wdev->wiphy); |
11728 | if (!rdev->crit_proto_nlportid) | 11842 | if (!rdev->crit_proto_nlportid) |
11729 | return; | 11843 | return; |
11730 | 11844 | ||
@@ -11759,7 +11873,7 @@ EXPORT_SYMBOL(cfg80211_crit_proto_stopped); | |||
11759 | void nl80211_send_ap_stopped(struct wireless_dev *wdev) | 11873 | void nl80211_send_ap_stopped(struct wireless_dev *wdev) |
11760 | { | 11874 | { |
11761 | struct wiphy *wiphy = wdev->wiphy; | 11875 | struct wiphy *wiphy = wdev->wiphy; |
11762 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 11876 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11763 | struct sk_buff *msg; | 11877 | struct sk_buff *msg; |
11764 | void *hdr; | 11878 | void *hdr; |
11765 | 11879 | ||
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 1e6df9630f42..49c9a482dd12 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -5,7 +5,8 @@ | |||
5 | 5 | ||
6 | int nl80211_init(void); | 6 | int nl80211_init(void); |
7 | void nl80211_exit(void); | 7 | void nl80211_exit(void); |
8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); | 8 | void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, |
9 | enum nl80211_commands cmd); | ||
9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 10 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
10 | struct wireless_dev *wdev); | 11 | struct wireless_dev *wdev); |
11 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, | 12 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 74d97d33c938..d95bbe348138 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -199,7 +199,7 @@ static inline int rdev_change_station(struct cfg80211_registered_device *rdev, | |||
199 | } | 199 | } |
200 | 200 | ||
201 | static inline int rdev_get_station(struct cfg80211_registered_device *rdev, | 201 | static inline int rdev_get_station(struct cfg80211_registered_device *rdev, |
202 | struct net_device *dev, u8 *mac, | 202 | struct net_device *dev, const u8 *mac, |
203 | struct station_info *sinfo) | 203 | struct station_info *sinfo) |
204 | { | 204 | { |
205 | int ret; | 205 | int ret; |
@@ -950,4 +950,17 @@ static inline int rdev_set_qos_map(struct cfg80211_registered_device *rdev, | |||
950 | return ret; | 950 | return ret; |
951 | } | 951 | } |
952 | 952 | ||
953 | static inline int | ||
954 | rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, | ||
955 | struct net_device *dev, struct cfg80211_chan_def *chandef) | ||
956 | { | ||
957 | int ret; | ||
958 | |||
959 | trace_rdev_set_ap_chanwidth(&rdev->wiphy, dev, chandef); | ||
960 | ret = rdev->ops->set_ap_chanwidth(&rdev->wiphy, dev, chandef); | ||
961 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
962 | |||
963 | return ret; | ||
964 | } | ||
965 | |||
953 | #endif /* __CFG80211_RDEV_OPS */ | 966 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index f59aaac586f8..558b0e3a02d8 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -65,11 +65,26 @@ | |||
65 | #define REG_DBG_PRINT(args...) | 65 | #define REG_DBG_PRINT(args...) |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | /** | ||
69 | * enum reg_request_treatment - regulatory request treatment | ||
70 | * | ||
71 | * @REG_REQ_OK: continue processing the regulatory request | ||
72 | * @REG_REQ_IGNORE: ignore the regulatory request | ||
73 | * @REG_REQ_INTERSECT: the regulatory domain resulting from this request should | ||
74 | * be intersected with the current one. | ||
75 | * @REG_REQ_ALREADY_SET: the regulatory request will not change the current | ||
76 | * regulatory settings, and no further processing is required. | ||
77 | * @REG_REQ_USER_HINT_HANDLED: a non alpha2 user hint was handled and no | ||
78 | * further processing is required, i.e., not need to update last_request | ||
79 | * etc. This should be used for user hints that do not provide an alpha2 | ||
80 | * but some other type of regulatory hint, i.e., indoor operation. | ||
81 | */ | ||
68 | enum reg_request_treatment { | 82 | enum reg_request_treatment { |
69 | REG_REQ_OK, | 83 | REG_REQ_OK, |
70 | REG_REQ_IGNORE, | 84 | REG_REQ_IGNORE, |
71 | REG_REQ_INTERSECT, | 85 | REG_REQ_INTERSECT, |
72 | REG_REQ_ALREADY_SET, | 86 | REG_REQ_ALREADY_SET, |
87 | REG_REQ_USER_HINT_HANDLED, | ||
73 | }; | 88 | }; |
74 | 89 | ||
75 | static struct regulatory_request core_request_world = { | 90 | static struct regulatory_request core_request_world = { |
@@ -106,6 +121,14 @@ const struct ieee80211_regdomain __rcu *cfg80211_regdomain; | |||
106 | */ | 121 | */ |
107 | static int reg_num_devs_support_basehint; | 122 | static int reg_num_devs_support_basehint; |
108 | 123 | ||
124 | /* | ||
125 | * State variable indicating if the platform on which the devices | ||
126 | * are attached is operating in an indoor environment. The state variable | ||
127 | * is relevant for all registered devices. | ||
128 | * (protected by RTNL) | ||
129 | */ | ||
130 | static bool reg_is_indoor; | ||
131 | |||
109 | static const struct ieee80211_regdomain *get_cfg80211_regdom(void) | 132 | static const struct ieee80211_regdomain *get_cfg80211_regdom(void) |
110 | { | 133 | { |
111 | return rtnl_dereference(cfg80211_regdomain); | 134 | return rtnl_dereference(cfg80211_regdomain); |
@@ -240,8 +263,16 @@ static char user_alpha2[2]; | |||
240 | module_param(ieee80211_regdom, charp, 0444); | 263 | module_param(ieee80211_regdom, charp, 0444); |
241 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); | 264 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); |
242 | 265 | ||
243 | static void reg_free_request(struct regulatory_request *lr) | 266 | static void reg_free_request(struct regulatory_request *request) |
244 | { | 267 | { |
268 | if (request != get_last_request()) | ||
269 | kfree(request); | ||
270 | } | ||
271 | |||
272 | static void reg_free_last_request(void) | ||
273 | { | ||
274 | struct regulatory_request *lr = get_last_request(); | ||
275 | |||
245 | if (lr != &core_request_world && lr) | 276 | if (lr != &core_request_world && lr) |
246 | kfree_rcu(lr, rcu_head); | 277 | kfree_rcu(lr, rcu_head); |
247 | } | 278 | } |
@@ -254,7 +285,7 @@ static void reg_update_last_request(struct regulatory_request *request) | |||
254 | if (lr == request) | 285 | if (lr == request) |
255 | return; | 286 | return; |
256 | 287 | ||
257 | reg_free_request(lr); | 288 | reg_free_last_request(); |
258 | rcu_assign_pointer(last_request, request); | 289 | rcu_assign_pointer(last_request, request); |
259 | } | 290 | } |
260 | 291 | ||
@@ -873,6 +904,8 @@ static u32 map_regdom_flags(u32 rd_flags) | |||
873 | channel_flags |= IEEE80211_CHAN_RADAR; | 904 | channel_flags |= IEEE80211_CHAN_RADAR; |
874 | if (rd_flags & NL80211_RRF_NO_OFDM) | 905 | if (rd_flags & NL80211_RRF_NO_OFDM) |
875 | channel_flags |= IEEE80211_CHAN_NO_OFDM; | 906 | channel_flags |= IEEE80211_CHAN_NO_OFDM; |
907 | if (rd_flags & NL80211_RRF_NO_OUTDOOR) | ||
908 | channel_flags |= IEEE80211_CHAN_INDOOR_ONLY; | ||
876 | return channel_flags; | 909 | return channel_flags; |
877 | } | 910 | } |
878 | 911 | ||
@@ -902,7 +935,7 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, | |||
902 | if (!band_rule_found) | 935 | if (!band_rule_found) |
903 | band_rule_found = freq_in_rule_band(fr, center_freq); | 936 | band_rule_found = freq_in_rule_band(fr, center_freq); |
904 | 937 | ||
905 | bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(20)); | 938 | bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(5)); |
906 | 939 | ||
907 | if (band_rule_found && bw_fits) | 940 | if (band_rule_found && bw_fits) |
908 | return rr; | 941 | return rr; |
@@ -986,10 +1019,10 @@ static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, | |||
986 | } | 1019 | } |
987 | #endif | 1020 | #endif |
988 | 1021 | ||
989 | /* | 1022 | /* Find an ieee80211_reg_rule such that a 5MHz channel with frequency |
990 | * Note that right now we assume the desired channel bandwidth | 1023 | * chan->center_freq fits there. |
991 | * is always 20 MHz for each individual channel (HT40 uses 20 MHz | 1024 | * If there is no such reg_rule, disable the channel, otherwise set the |
992 | * per channel, the primary and the extension channel). | 1025 | * flags corresponding to the bandwidths allowed in the particular reg_rule |
993 | */ | 1026 | */ |
994 | static void handle_channel(struct wiphy *wiphy, | 1027 | static void handle_channel(struct wiphy *wiphy, |
995 | enum nl80211_reg_initiator initiator, | 1028 | enum nl80211_reg_initiator initiator, |
@@ -1050,8 +1083,12 @@ static void handle_channel(struct wiphy *wiphy, | |||
1050 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) | 1083 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1051 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1084 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1052 | 1085 | ||
1086 | if (max_bandwidth_khz < MHZ_TO_KHZ(10)) | ||
1087 | bw_flags = IEEE80211_CHAN_NO_10MHZ; | ||
1088 | if (max_bandwidth_khz < MHZ_TO_KHZ(20)) | ||
1089 | bw_flags |= IEEE80211_CHAN_NO_20MHZ; | ||
1053 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1090 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
1054 | bw_flags = IEEE80211_CHAN_NO_HT40; | 1091 | bw_flags |= IEEE80211_CHAN_NO_HT40; |
1055 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) | 1092 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) |
1056 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; | 1093 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; |
1057 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) | 1094 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) |
@@ -1071,6 +1108,13 @@ static void handle_channel(struct wiphy *wiphy, | |||
1071 | (int) MBI_TO_DBI(power_rule->max_antenna_gain); | 1108 | (int) MBI_TO_DBI(power_rule->max_antenna_gain); |
1072 | chan->max_reg_power = chan->max_power = chan->orig_mpwr = | 1109 | chan->max_reg_power = chan->max_power = chan->orig_mpwr = |
1073 | (int) MBM_TO_DBM(power_rule->max_eirp); | 1110 | (int) MBM_TO_DBM(power_rule->max_eirp); |
1111 | |||
1112 | if (chan->flags & IEEE80211_CHAN_RADAR) { | ||
1113 | chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; | ||
1114 | if (reg_rule->dfs_cac_ms) | ||
1115 | chan->dfs_cac_ms = reg_rule->dfs_cac_ms; | ||
1116 | } | ||
1117 | |||
1074 | return; | 1118 | return; |
1075 | } | 1119 | } |
1076 | 1120 | ||
@@ -1126,12 +1170,19 @@ static bool reg_request_cell_base(struct regulatory_request *request) | |||
1126 | return request->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE; | 1170 | return request->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE; |
1127 | } | 1171 | } |
1128 | 1172 | ||
1173 | static bool reg_request_indoor(struct regulatory_request *request) | ||
1174 | { | ||
1175 | if (request->initiator != NL80211_REGDOM_SET_BY_USER) | ||
1176 | return false; | ||
1177 | return request->user_reg_hint_type == NL80211_USER_REG_HINT_INDOOR; | ||
1178 | } | ||
1179 | |||
1129 | bool reg_last_request_cell_base(void) | 1180 | bool reg_last_request_cell_base(void) |
1130 | { | 1181 | { |
1131 | return reg_request_cell_base(get_last_request()); | 1182 | return reg_request_cell_base(get_last_request()); |
1132 | } | 1183 | } |
1133 | 1184 | ||
1134 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS | 1185 | #ifdef CONFIG_CFG80211_REG_CELLULAR_HINTS |
1135 | /* Core specific check */ | 1186 | /* Core specific check */ |
1136 | static enum reg_request_treatment | 1187 | static enum reg_request_treatment |
1137 | reg_ignore_cell_hint(struct regulatory_request *pending_request) | 1188 | reg_ignore_cell_hint(struct regulatory_request *pending_request) |
@@ -1471,8 +1522,12 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1471 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) | 1522 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1472 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1523 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1473 | 1524 | ||
1525 | if (max_bandwidth_khz < MHZ_TO_KHZ(10)) | ||
1526 | bw_flags = IEEE80211_CHAN_NO_10MHZ; | ||
1527 | if (max_bandwidth_khz < MHZ_TO_KHZ(20)) | ||
1528 | bw_flags |= IEEE80211_CHAN_NO_20MHZ; | ||
1474 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1529 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
1475 | bw_flags = IEEE80211_CHAN_NO_HT40; | 1530 | bw_flags |= IEEE80211_CHAN_NO_HT40; |
1476 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) | 1531 | if (max_bandwidth_khz < MHZ_TO_KHZ(80)) |
1477 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; | 1532 | bw_flags |= IEEE80211_CHAN_NO_80MHZ; |
1478 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) | 1533 | if (max_bandwidth_khz < MHZ_TO_KHZ(160)) |
@@ -1568,6 +1623,11 @@ __reg_process_hint_user(struct regulatory_request *user_request) | |||
1568 | { | 1623 | { |
1569 | struct regulatory_request *lr = get_last_request(); | 1624 | struct regulatory_request *lr = get_last_request(); |
1570 | 1625 | ||
1626 | if (reg_request_indoor(user_request)) { | ||
1627 | reg_is_indoor = true; | ||
1628 | return REG_REQ_USER_HINT_HANDLED; | ||
1629 | } | ||
1630 | |||
1571 | if (reg_request_cell_base(user_request)) | 1631 | if (reg_request_cell_base(user_request)) |
1572 | return reg_ignore_cell_hint(user_request); | 1632 | return reg_ignore_cell_hint(user_request); |
1573 | 1633 | ||
@@ -1615,8 +1675,9 @@ reg_process_hint_user(struct regulatory_request *user_request) | |||
1615 | 1675 | ||
1616 | treatment = __reg_process_hint_user(user_request); | 1676 | treatment = __reg_process_hint_user(user_request); |
1617 | if (treatment == REG_REQ_IGNORE || | 1677 | if (treatment == REG_REQ_IGNORE || |
1618 | treatment == REG_REQ_ALREADY_SET) { | 1678 | treatment == REG_REQ_ALREADY_SET || |
1619 | kfree(user_request); | 1679 | treatment == REG_REQ_USER_HINT_HANDLED) { |
1680 | reg_free_request(user_request); | ||
1620 | return treatment; | 1681 | return treatment; |
1621 | } | 1682 | } |
1622 | 1683 | ||
@@ -1676,14 +1737,15 @@ reg_process_hint_driver(struct wiphy *wiphy, | |||
1676 | case REG_REQ_OK: | 1737 | case REG_REQ_OK: |
1677 | break; | 1738 | break; |
1678 | case REG_REQ_IGNORE: | 1739 | case REG_REQ_IGNORE: |
1679 | kfree(driver_request); | 1740 | case REG_REQ_USER_HINT_HANDLED: |
1741 | reg_free_request(driver_request); | ||
1680 | return treatment; | 1742 | return treatment; |
1681 | case REG_REQ_INTERSECT: | 1743 | case REG_REQ_INTERSECT: |
1682 | /* fall through */ | 1744 | /* fall through */ |
1683 | case REG_REQ_ALREADY_SET: | 1745 | case REG_REQ_ALREADY_SET: |
1684 | regd = reg_copy_regd(get_cfg80211_regdom()); | 1746 | regd = reg_copy_regd(get_cfg80211_regdom()); |
1685 | if (IS_ERR(regd)) { | 1747 | if (IS_ERR(regd)) { |
1686 | kfree(driver_request); | 1748 | reg_free_request(driver_request); |
1687 | return REG_REQ_IGNORE; | 1749 | return REG_REQ_IGNORE; |
1688 | } | 1750 | } |
1689 | rcu_assign_pointer(wiphy->regd, regd); | 1751 | rcu_assign_pointer(wiphy->regd, regd); |
@@ -1775,12 +1837,13 @@ reg_process_hint_country_ie(struct wiphy *wiphy, | |||
1775 | case REG_REQ_OK: | 1837 | case REG_REQ_OK: |
1776 | break; | 1838 | break; |
1777 | case REG_REQ_IGNORE: | 1839 | case REG_REQ_IGNORE: |
1840 | case REG_REQ_USER_HINT_HANDLED: | ||
1778 | /* fall through */ | 1841 | /* fall through */ |
1779 | case REG_REQ_ALREADY_SET: | 1842 | case REG_REQ_ALREADY_SET: |
1780 | kfree(country_ie_request); | 1843 | reg_free_request(country_ie_request); |
1781 | return treatment; | 1844 | return treatment; |
1782 | case REG_REQ_INTERSECT: | 1845 | case REG_REQ_INTERSECT: |
1783 | kfree(country_ie_request); | 1846 | reg_free_request(country_ie_request); |
1784 | /* | 1847 | /* |
1785 | * This doesn't happen yet, not sure we | 1848 | * This doesn't happen yet, not sure we |
1786 | * ever want to support it for this case. | 1849 | * ever want to support it for this case. |
@@ -1813,7 +1876,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1813 | case NL80211_REGDOM_SET_BY_USER: | 1876 | case NL80211_REGDOM_SET_BY_USER: |
1814 | treatment = reg_process_hint_user(reg_request); | 1877 | treatment = reg_process_hint_user(reg_request); |
1815 | if (treatment == REG_REQ_IGNORE || | 1878 | if (treatment == REG_REQ_IGNORE || |
1816 | treatment == REG_REQ_ALREADY_SET) | 1879 | treatment == REG_REQ_ALREADY_SET || |
1880 | treatment == REG_REQ_USER_HINT_HANDLED) | ||
1817 | return; | 1881 | return; |
1818 | queue_delayed_work(system_power_efficient_wq, | 1882 | queue_delayed_work(system_power_efficient_wq, |
1819 | ®_timeout, msecs_to_jiffies(3142)); | 1883 | ®_timeout, msecs_to_jiffies(3142)); |
@@ -1841,7 +1905,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1841 | return; | 1905 | return; |
1842 | 1906 | ||
1843 | out_free: | 1907 | out_free: |
1844 | kfree(reg_request); | 1908 | reg_free_request(reg_request); |
1845 | } | 1909 | } |
1846 | 1910 | ||
1847 | /* | 1911 | /* |
@@ -1857,7 +1921,7 @@ static void reg_process_pending_hints(void) | |||
1857 | 1921 | ||
1858 | /* When last_request->processed becomes true this will be rescheduled */ | 1922 | /* When last_request->processed becomes true this will be rescheduled */ |
1859 | if (lr && !lr->processed) { | 1923 | if (lr && !lr->processed) { |
1860 | REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); | 1924 | reg_process_hint(lr); |
1861 | return; | 1925 | return; |
1862 | } | 1926 | } |
1863 | 1927 | ||
@@ -1967,6 +2031,22 @@ int regulatory_hint_user(const char *alpha2, | |||
1967 | return 0; | 2031 | return 0; |
1968 | } | 2032 | } |
1969 | 2033 | ||
2034 | int regulatory_hint_indoor_user(void) | ||
2035 | { | ||
2036 | struct regulatory_request *request; | ||
2037 | |||
2038 | request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); | ||
2039 | if (!request) | ||
2040 | return -ENOMEM; | ||
2041 | |||
2042 | request->wiphy_idx = WIPHY_IDX_INVALID; | ||
2043 | request->initiator = NL80211_REGDOM_SET_BY_USER; | ||
2044 | request->user_reg_hint_type = NL80211_USER_REG_HINT_INDOOR; | ||
2045 | queue_regulatory_request(request); | ||
2046 | |||
2047 | return 0; | ||
2048 | } | ||
2049 | |||
1970 | /* Driver hints */ | 2050 | /* Driver hints */ |
1971 | int regulatory_hint(struct wiphy *wiphy, const char *alpha2) | 2051 | int regulatory_hint(struct wiphy *wiphy, const char *alpha2) |
1972 | { | 2052 | { |
@@ -2134,6 +2214,8 @@ static void restore_regulatory_settings(bool reset_user) | |||
2134 | 2214 | ||
2135 | ASSERT_RTNL(); | 2215 | ASSERT_RTNL(); |
2136 | 2216 | ||
2217 | reg_is_indoor = false; | ||
2218 | |||
2137 | reset_regdomains(true, &world_regdom); | 2219 | reset_regdomains(true, &world_regdom); |
2138 | restore_alpha2(alpha2, reset_user); | 2220 | restore_alpha2(alpha2, reset_user); |
2139 | 2221 | ||
@@ -2594,7 +2676,7 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy) | |||
2594 | reg_num_devs_support_basehint--; | 2676 | reg_num_devs_support_basehint--; |
2595 | 2677 | ||
2596 | rcu_free_regdom(get_wiphy_regdom(wiphy)); | 2678 | rcu_free_regdom(get_wiphy_regdom(wiphy)); |
2597 | rcu_assign_pointer(wiphy->regd, NULL); | 2679 | RCU_INIT_POINTER(wiphy->regd, NULL); |
2598 | 2680 | ||
2599 | if (lr) | 2681 | if (lr) |
2600 | request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); | 2682 | request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); |
@@ -2614,6 +2696,40 @@ static void reg_timeout_work(struct work_struct *work) | |||
2614 | rtnl_unlock(); | 2696 | rtnl_unlock(); |
2615 | } | 2697 | } |
2616 | 2698 | ||
2699 | /* | ||
2700 | * See http://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii, for | ||
2701 | * UNII band definitions | ||
2702 | */ | ||
2703 | int cfg80211_get_unii(int freq) | ||
2704 | { | ||
2705 | /* UNII-1 */ | ||
2706 | if (freq >= 5150 && freq <= 5250) | ||
2707 | return 0; | ||
2708 | |||
2709 | /* UNII-2A */ | ||
2710 | if (freq > 5250 && freq <= 5350) | ||
2711 | return 1; | ||
2712 | |||
2713 | /* UNII-2B */ | ||
2714 | if (freq > 5350 && freq <= 5470) | ||
2715 | return 2; | ||
2716 | |||
2717 | /* UNII-2C */ | ||
2718 | if (freq > 5470 && freq <= 5725) | ||
2719 | return 3; | ||
2720 | |||
2721 | /* UNII-3 */ | ||
2722 | if (freq > 5725 && freq <= 5825) | ||
2723 | return 4; | ||
2724 | |||
2725 | return -EINVAL; | ||
2726 | } | ||
2727 | |||
2728 | bool regulatory_indoor_allowed(void) | ||
2729 | { | ||
2730 | return reg_is_indoor; | ||
2731 | } | ||
2732 | |||
2617 | int __init regulatory_init(void) | 2733 | int __init regulatory_init(void) |
2618 | { | 2734 | { |
2619 | int err = 0; | 2735 | int err = 0; |
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index 37c180df34b7..5e48031ccb9a 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -25,6 +25,7 @@ enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy); | |||
25 | 25 | ||
26 | int regulatory_hint_user(const char *alpha2, | 26 | int regulatory_hint_user(const char *alpha2, |
27 | enum nl80211_user_reg_hint_type user_reg_hint_type); | 27 | enum nl80211_user_reg_hint_type user_reg_hint_type); |
28 | int regulatory_hint_indoor_user(void); | ||
28 | 29 | ||
29 | void wiphy_regulatory_register(struct wiphy *wiphy); | 30 | void wiphy_regulatory_register(struct wiphy *wiphy); |
30 | void wiphy_regulatory_deregister(struct wiphy *wiphy); | 31 | void wiphy_regulatory_deregister(struct wiphy *wiphy); |
@@ -104,4 +105,21 @@ void regulatory_hint_country_ie(struct wiphy *wiphy, | |||
104 | */ | 105 | */ |
105 | void regulatory_hint_disconnect(void); | 106 | void regulatory_hint_disconnect(void); |
106 | 107 | ||
108 | /** | ||
109 | * cfg80211_get_unii - get the U-NII band for the frequency | ||
110 | * @freq: the frequency for which we want to get the UNII band. | ||
111 | |||
112 | * Get a value specifying the U-NII band frequency belongs to. | ||
113 | * U-NII bands are defined by the FCC in C.F.R 47 part 15. | ||
114 | * | ||
115 | * Returns -EINVAL if freq is invalid, 0 for UNII-1, 1 for UNII-2A, | ||
116 | * 2 for UNII-2B, 3 for UNII-2C and 4 for UNII-3. | ||
117 | */ | ||
118 | int cfg80211_get_unii(int freq); | ||
119 | |||
120 | /** | ||
121 | * regulatory_indoor_allowed - is indoor operation allowed | ||
122 | */ | ||
123 | bool regulatory_indoor_allowed(void); | ||
124 | |||
107 | #endif /* __NET_WIRELESS_REG_H */ | 125 | #endif /* __NET_WIRELESS_REG_H */ |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 88f108edfb58..0798c62e6085 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -81,10 +81,10 @@ static void bss_free(struct cfg80211_internal_bss *bss) | |||
81 | kfree(bss); | 81 | kfree(bss); |
82 | } | 82 | } |
83 | 83 | ||
84 | static inline void bss_ref_get(struct cfg80211_registered_device *dev, | 84 | static inline void bss_ref_get(struct cfg80211_registered_device *rdev, |
85 | struct cfg80211_internal_bss *bss) | 85 | struct cfg80211_internal_bss *bss) |
86 | { | 86 | { |
87 | lockdep_assert_held(&dev->bss_lock); | 87 | lockdep_assert_held(&rdev->bss_lock); |
88 | 88 | ||
89 | bss->refcount++; | 89 | bss->refcount++; |
90 | if (bss->pub.hidden_beacon_bss) { | 90 | if (bss->pub.hidden_beacon_bss) { |
@@ -95,10 +95,10 @@ static inline void bss_ref_get(struct cfg80211_registered_device *dev, | |||
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | static inline void bss_ref_put(struct cfg80211_registered_device *dev, | 98 | static inline void bss_ref_put(struct cfg80211_registered_device *rdev, |
99 | struct cfg80211_internal_bss *bss) | 99 | struct cfg80211_internal_bss *bss) |
100 | { | 100 | { |
101 | lockdep_assert_held(&dev->bss_lock); | 101 | lockdep_assert_held(&rdev->bss_lock); |
102 | 102 | ||
103 | if (bss->pub.hidden_beacon_bss) { | 103 | if (bss->pub.hidden_beacon_bss) { |
104 | struct cfg80211_internal_bss *hbss; | 104 | struct cfg80211_internal_bss *hbss; |
@@ -114,10 +114,10 @@ static inline void bss_ref_put(struct cfg80211_registered_device *dev, | |||
114 | bss_free(bss); | 114 | bss_free(bss); |
115 | } | 115 | } |
116 | 116 | ||
117 | static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, | 117 | static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev, |
118 | struct cfg80211_internal_bss *bss) | 118 | struct cfg80211_internal_bss *bss) |
119 | { | 119 | { |
120 | lockdep_assert_held(&dev->bss_lock); | 120 | lockdep_assert_held(&rdev->bss_lock); |
121 | 121 | ||
122 | if (!list_empty(&bss->hidden_list)) { | 122 | if (!list_empty(&bss->hidden_list)) { |
123 | /* | 123 | /* |
@@ -134,31 +134,31 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | list_del_init(&bss->list); | 136 | list_del_init(&bss->list); |
137 | rb_erase(&bss->rbn, &dev->bss_tree); | 137 | rb_erase(&bss->rbn, &rdev->bss_tree); |
138 | bss_ref_put(dev, bss); | 138 | bss_ref_put(rdev, bss); |
139 | return true; | 139 | return true; |
140 | } | 140 | } |
141 | 141 | ||
142 | static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, | 142 | static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev, |
143 | unsigned long expire_time) | 143 | unsigned long expire_time) |
144 | { | 144 | { |
145 | struct cfg80211_internal_bss *bss, *tmp; | 145 | struct cfg80211_internal_bss *bss, *tmp; |
146 | bool expired = false; | 146 | bool expired = false; |
147 | 147 | ||
148 | lockdep_assert_held(&dev->bss_lock); | 148 | lockdep_assert_held(&rdev->bss_lock); |
149 | 149 | ||
150 | list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { | 150 | list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) { |
151 | if (atomic_read(&bss->hold)) | 151 | if (atomic_read(&bss->hold)) |
152 | continue; | 152 | continue; |
153 | if (!time_after(expire_time, bss->ts)) | 153 | if (!time_after(expire_time, bss->ts)) |
154 | continue; | 154 | continue; |
155 | 155 | ||
156 | if (__cfg80211_unlink_bss(dev, bss)) | 156 | if (__cfg80211_unlink_bss(rdev, bss)) |
157 | expired = true; | 157 | expired = true; |
158 | } | 158 | } |
159 | 159 | ||
160 | if (expired) | 160 | if (expired) |
161 | dev->bss_generation++; | 161 | rdev->bss_generation++; |
162 | } | 162 | } |
163 | 163 | ||
164 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, | 164 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, |
@@ -238,11 +238,11 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
238 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | 238 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) |
239 | { | 239 | { |
240 | trace_cfg80211_scan_done(request, aborted); | 240 | trace_cfg80211_scan_done(request, aborted); |
241 | WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); | 241 | WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req); |
242 | 242 | ||
243 | request->aborted = aborted; | 243 | request->aborted = aborted; |
244 | request->notified = true; | 244 | request->notified = true; |
245 | queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk); | 245 | queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk); |
246 | } | 246 | } |
247 | EXPORT_SYMBOL(cfg80211_scan_done); | 247 | EXPORT_SYMBOL(cfg80211_scan_done); |
248 | 248 | ||
@@ -278,15 +278,15 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy) | |||
278 | { | 278 | { |
279 | trace_cfg80211_sched_scan_results(wiphy); | 279 | trace_cfg80211_sched_scan_results(wiphy); |
280 | /* ignore if we're not scanning */ | 280 | /* ignore if we're not scanning */ |
281 | if (wiphy_to_dev(wiphy)->sched_scan_req) | 281 | if (wiphy_to_rdev(wiphy)->sched_scan_req) |
282 | queue_work(cfg80211_wq, | 282 | queue_work(cfg80211_wq, |
283 | &wiphy_to_dev(wiphy)->sched_scan_results_wk); | 283 | &wiphy_to_rdev(wiphy)->sched_scan_results_wk); |
284 | } | 284 | } |
285 | EXPORT_SYMBOL(cfg80211_sched_scan_results); | 285 | EXPORT_SYMBOL(cfg80211_sched_scan_results); |
286 | 286 | ||
287 | void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy) | 287 | void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy) |
288 | { | 288 | { |
289 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 289 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
290 | 290 | ||
291 | ASSERT_RTNL(); | 291 | ASSERT_RTNL(); |
292 | 292 | ||
@@ -330,21 +330,21 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
330 | return 0; | 330 | return 0; |
331 | } | 331 | } |
332 | 332 | ||
333 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | 333 | void cfg80211_bss_age(struct cfg80211_registered_device *rdev, |
334 | unsigned long age_secs) | 334 | unsigned long age_secs) |
335 | { | 335 | { |
336 | struct cfg80211_internal_bss *bss; | 336 | struct cfg80211_internal_bss *bss; |
337 | unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); | 337 | unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); |
338 | 338 | ||
339 | spin_lock_bh(&dev->bss_lock); | 339 | spin_lock_bh(&rdev->bss_lock); |
340 | list_for_each_entry(bss, &dev->bss_list, list) | 340 | list_for_each_entry(bss, &rdev->bss_list, list) |
341 | bss->ts -= age_jiffies; | 341 | bss->ts -= age_jiffies; |
342 | spin_unlock_bh(&dev->bss_lock); | 342 | spin_unlock_bh(&rdev->bss_lock); |
343 | } | 343 | } |
344 | 344 | ||
345 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev) | 345 | void cfg80211_bss_expire(struct cfg80211_registered_device *rdev) |
346 | { | 346 | { |
347 | __cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); | 347 | __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); |
348 | } | 348 | } |
349 | 349 | ||
350 | const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) | 350 | const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) |
@@ -534,32 +534,34 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | |||
534 | const u8 *ssid, size_t ssid_len, | 534 | const u8 *ssid, size_t ssid_len, |
535 | u16 capa_mask, u16 capa_val) | 535 | u16 capa_mask, u16 capa_val) |
536 | { | 536 | { |
537 | struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); | 537 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
538 | struct cfg80211_internal_bss *bss, *res = NULL; | 538 | struct cfg80211_internal_bss *bss, *res = NULL; |
539 | unsigned long now = jiffies; | 539 | unsigned long now = jiffies; |
540 | 540 | ||
541 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, | 541 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, |
542 | capa_val); | 542 | capa_val); |
543 | 543 | ||
544 | spin_lock_bh(&dev->bss_lock); | 544 | spin_lock_bh(&rdev->bss_lock); |
545 | 545 | ||
546 | list_for_each_entry(bss, &dev->bss_list, list) { | 546 | list_for_each_entry(bss, &rdev->bss_list, list) { |
547 | if ((bss->pub.capability & capa_mask) != capa_val) | 547 | if ((bss->pub.capability & capa_mask) != capa_val) |
548 | continue; | 548 | continue; |
549 | if (channel && bss->pub.channel != channel) | 549 | if (channel && bss->pub.channel != channel) |
550 | continue; | 550 | continue; |
551 | if (!is_valid_ether_addr(bss->pub.bssid)) | ||
552 | continue; | ||
551 | /* Don't get expired BSS structs */ | 553 | /* Don't get expired BSS structs */ |
552 | if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) && | 554 | if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) && |
553 | !atomic_read(&bss->hold)) | 555 | !atomic_read(&bss->hold)) |
554 | continue; | 556 | continue; |
555 | if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { | 557 | if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { |
556 | res = bss; | 558 | res = bss; |
557 | bss_ref_get(dev, res); | 559 | bss_ref_get(rdev, res); |
558 | break; | 560 | break; |
559 | } | 561 | } |
560 | } | 562 | } |
561 | 563 | ||
562 | spin_unlock_bh(&dev->bss_lock); | 564 | spin_unlock_bh(&rdev->bss_lock); |
563 | if (!res) | 565 | if (!res) |
564 | return NULL; | 566 | return NULL; |
565 | trace_cfg80211_return_bss(&res->pub); | 567 | trace_cfg80211_return_bss(&res->pub); |
@@ -567,10 +569,10 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | |||
567 | } | 569 | } |
568 | EXPORT_SYMBOL(cfg80211_get_bss); | 570 | EXPORT_SYMBOL(cfg80211_get_bss); |
569 | 571 | ||
570 | static void rb_insert_bss(struct cfg80211_registered_device *dev, | 572 | static void rb_insert_bss(struct cfg80211_registered_device *rdev, |
571 | struct cfg80211_internal_bss *bss) | 573 | struct cfg80211_internal_bss *bss) |
572 | { | 574 | { |
573 | struct rb_node **p = &dev->bss_tree.rb_node; | 575 | struct rb_node **p = &rdev->bss_tree.rb_node; |
574 | struct rb_node *parent = NULL; | 576 | struct rb_node *parent = NULL; |
575 | struct cfg80211_internal_bss *tbss; | 577 | struct cfg80211_internal_bss *tbss; |
576 | int cmp; | 578 | int cmp; |
@@ -593,15 +595,15 @@ static void rb_insert_bss(struct cfg80211_registered_device *dev, | |||
593 | } | 595 | } |
594 | 596 | ||
595 | rb_link_node(&bss->rbn, parent, p); | 597 | rb_link_node(&bss->rbn, parent, p); |
596 | rb_insert_color(&bss->rbn, &dev->bss_tree); | 598 | rb_insert_color(&bss->rbn, &rdev->bss_tree); |
597 | } | 599 | } |
598 | 600 | ||
599 | static struct cfg80211_internal_bss * | 601 | static struct cfg80211_internal_bss * |
600 | rb_find_bss(struct cfg80211_registered_device *dev, | 602 | rb_find_bss(struct cfg80211_registered_device *rdev, |
601 | struct cfg80211_internal_bss *res, | 603 | struct cfg80211_internal_bss *res, |
602 | enum bss_compare_mode mode) | 604 | enum bss_compare_mode mode) |
603 | { | 605 | { |
604 | struct rb_node *n = dev->bss_tree.rb_node; | 606 | struct rb_node *n = rdev->bss_tree.rb_node; |
605 | struct cfg80211_internal_bss *bss; | 607 | struct cfg80211_internal_bss *bss; |
606 | int r; | 608 | int r; |
607 | 609 | ||
@@ -620,7 +622,7 @@ rb_find_bss(struct cfg80211_registered_device *dev, | |||
620 | return NULL; | 622 | return NULL; |
621 | } | 623 | } |
622 | 624 | ||
623 | static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, | 625 | static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, |
624 | struct cfg80211_internal_bss *new) | 626 | struct cfg80211_internal_bss *new) |
625 | { | 627 | { |
626 | const struct cfg80211_bss_ies *ies; | 628 | const struct cfg80211_bss_ies *ies; |
@@ -650,7 +652,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, | |||
650 | 652 | ||
651 | /* This is the bad part ... */ | 653 | /* This is the bad part ... */ |
652 | 654 | ||
653 | list_for_each_entry(bss, &dev->bss_list, list) { | 655 | list_for_each_entry(bss, &rdev->bss_list, list) { |
654 | if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid)) | 656 | if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid)) |
655 | continue; | 657 | continue; |
656 | if (bss->pub.channel != new->pub.channel) | 658 | if (bss->pub.channel != new->pub.channel) |
@@ -684,7 +686,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, | |||
684 | 686 | ||
685 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | 687 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
686 | static struct cfg80211_internal_bss * | 688 | static struct cfg80211_internal_bss * |
687 | cfg80211_bss_update(struct cfg80211_registered_device *dev, | 689 | cfg80211_bss_update(struct cfg80211_registered_device *rdev, |
688 | struct cfg80211_internal_bss *tmp, | 690 | struct cfg80211_internal_bss *tmp, |
689 | bool signal_valid) | 691 | bool signal_valid) |
690 | { | 692 | { |
@@ -695,14 +697,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
695 | 697 | ||
696 | tmp->ts = jiffies; | 698 | tmp->ts = jiffies; |
697 | 699 | ||
698 | spin_lock_bh(&dev->bss_lock); | 700 | spin_lock_bh(&rdev->bss_lock); |
699 | 701 | ||
700 | if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) { | 702 | if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) { |
701 | spin_unlock_bh(&dev->bss_lock); | 703 | spin_unlock_bh(&rdev->bss_lock); |
702 | return NULL; | 704 | return NULL; |
703 | } | 705 | } |
704 | 706 | ||
705 | found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR); | 707 | found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR); |
706 | 708 | ||
707 | if (found) { | 709 | if (found) { |
708 | /* Update IEs */ | 710 | /* Update IEs */ |
@@ -789,7 +791,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
789 | * is allocated on the stack since it's not needed in the | 791 | * is allocated on the stack since it's not needed in the |
790 | * more common case of an update | 792 | * more common case of an update |
791 | */ | 793 | */ |
792 | new = kzalloc(sizeof(*new) + dev->wiphy.bss_priv_size, | 794 | new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size, |
793 | GFP_ATOMIC); | 795 | GFP_ATOMIC); |
794 | if (!new) { | 796 | if (!new) { |
795 | ies = (void *)rcu_dereference(tmp->pub.beacon_ies); | 797 | ies = (void *)rcu_dereference(tmp->pub.beacon_ies); |
@@ -805,9 +807,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
805 | INIT_LIST_HEAD(&new->hidden_list); | 807 | INIT_LIST_HEAD(&new->hidden_list); |
806 | 808 | ||
807 | if (rcu_access_pointer(tmp->pub.proberesp_ies)) { | 809 | if (rcu_access_pointer(tmp->pub.proberesp_ies)) { |
808 | hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_ZLEN); | 810 | hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); |
809 | if (!hidden) | 811 | if (!hidden) |
810 | hidden = rb_find_bss(dev, tmp, | 812 | hidden = rb_find_bss(rdev, tmp, |
811 | BSS_CMP_HIDE_NUL); | 813 | BSS_CMP_HIDE_NUL); |
812 | if (hidden) { | 814 | if (hidden) { |
813 | new->pub.hidden_beacon_bss = &hidden->pub; | 815 | new->pub.hidden_beacon_bss = &hidden->pub; |
@@ -824,24 +826,24 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
824 | * expensive search for any probe responses that should | 826 | * expensive search for any probe responses that should |
825 | * be grouped with this beacon for updates ... | 827 | * be grouped with this beacon for updates ... |
826 | */ | 828 | */ |
827 | if (!cfg80211_combine_bsses(dev, new)) { | 829 | if (!cfg80211_combine_bsses(rdev, new)) { |
828 | kfree(new); | 830 | kfree(new); |
829 | goto drop; | 831 | goto drop; |
830 | } | 832 | } |
831 | } | 833 | } |
832 | 834 | ||
833 | list_add_tail(&new->list, &dev->bss_list); | 835 | list_add_tail(&new->list, &rdev->bss_list); |
834 | rb_insert_bss(dev, new); | 836 | rb_insert_bss(rdev, new); |
835 | found = new; | 837 | found = new; |
836 | } | 838 | } |
837 | 839 | ||
838 | dev->bss_generation++; | 840 | rdev->bss_generation++; |
839 | bss_ref_get(dev, found); | 841 | bss_ref_get(rdev, found); |
840 | spin_unlock_bh(&dev->bss_lock); | 842 | spin_unlock_bh(&rdev->bss_lock); |
841 | 843 | ||
842 | return found; | 844 | return found; |
843 | drop: | 845 | drop: |
844 | spin_unlock_bh(&dev->bss_lock); | 846 | spin_unlock_bh(&rdev->bss_lock); |
845 | return NULL; | 847 | return NULL; |
846 | } | 848 | } |
847 | 849 | ||
@@ -889,6 +891,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
889 | struct cfg80211_bss_ies *ies; | 891 | struct cfg80211_bss_ies *ies; |
890 | struct ieee80211_channel *channel; | 892 | struct ieee80211_channel *channel; |
891 | struct cfg80211_internal_bss tmp = {}, *res; | 893 | struct cfg80211_internal_bss tmp = {}, *res; |
894 | bool signal_valid; | ||
892 | 895 | ||
893 | if (WARN_ON(!wiphy)) | 896 | if (WARN_ON(!wiphy)) |
894 | return NULL; | 897 | return NULL; |
@@ -925,8 +928,9 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
925 | rcu_assign_pointer(tmp.pub.beacon_ies, ies); | 928 | rcu_assign_pointer(tmp.pub.beacon_ies, ies); |
926 | rcu_assign_pointer(tmp.pub.ies, ies); | 929 | rcu_assign_pointer(tmp.pub.ies, ies); |
927 | 930 | ||
928 | res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp, | 931 | signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= |
929 | rx_channel == channel); | 932 | wiphy->max_adj_channel_rssi_comp; |
933 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); | ||
930 | if (!res) | 934 | if (!res) |
931 | return NULL; | 935 | return NULL; |
932 | 936 | ||
@@ -950,6 +954,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
950 | struct cfg80211_internal_bss tmp = {}, *res; | 954 | struct cfg80211_internal_bss tmp = {}, *res; |
951 | struct cfg80211_bss_ies *ies; | 955 | struct cfg80211_bss_ies *ies; |
952 | struct ieee80211_channel *channel; | 956 | struct ieee80211_channel *channel; |
957 | bool signal_valid; | ||
953 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 958 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
954 | u.probe_resp.variable); | 959 | u.probe_resp.variable); |
955 | 960 | ||
@@ -997,8 +1002,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
997 | tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); | 1002 | tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); |
998 | tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); | 1003 | tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); |
999 | 1004 | ||
1000 | res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp, | 1005 | signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= |
1001 | rx_channel == channel); | 1006 | wiphy->max_adj_channel_rssi_comp; |
1007 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); | ||
1002 | if (!res) | 1008 | if (!res) |
1003 | return NULL; | 1009 | return NULL; |
1004 | 1010 | ||
@@ -1013,7 +1019,7 @@ EXPORT_SYMBOL(cfg80211_inform_bss_width_frame); | |||
1013 | 1019 | ||
1014 | void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | 1020 | void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) |
1015 | { | 1021 | { |
1016 | struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); | 1022 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1017 | struct cfg80211_internal_bss *bss; | 1023 | struct cfg80211_internal_bss *bss; |
1018 | 1024 | ||
1019 | if (!pub) | 1025 | if (!pub) |
@@ -1021,15 +1027,15 @@ void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | |||
1021 | 1027 | ||
1022 | bss = container_of(pub, struct cfg80211_internal_bss, pub); | 1028 | bss = container_of(pub, struct cfg80211_internal_bss, pub); |
1023 | 1029 | ||
1024 | spin_lock_bh(&dev->bss_lock); | 1030 | spin_lock_bh(&rdev->bss_lock); |
1025 | bss_ref_get(dev, bss); | 1031 | bss_ref_get(rdev, bss); |
1026 | spin_unlock_bh(&dev->bss_lock); | 1032 | spin_unlock_bh(&rdev->bss_lock); |
1027 | } | 1033 | } |
1028 | EXPORT_SYMBOL(cfg80211_ref_bss); | 1034 | EXPORT_SYMBOL(cfg80211_ref_bss); |
1029 | 1035 | ||
1030 | void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | 1036 | void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) |
1031 | { | 1037 | { |
1032 | struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); | 1038 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1033 | struct cfg80211_internal_bss *bss; | 1039 | struct cfg80211_internal_bss *bss; |
1034 | 1040 | ||
1035 | if (!pub) | 1041 | if (!pub) |
@@ -1037,15 +1043,15 @@ void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | |||
1037 | 1043 | ||
1038 | bss = container_of(pub, struct cfg80211_internal_bss, pub); | 1044 | bss = container_of(pub, struct cfg80211_internal_bss, pub); |
1039 | 1045 | ||
1040 | spin_lock_bh(&dev->bss_lock); | 1046 | spin_lock_bh(&rdev->bss_lock); |
1041 | bss_ref_put(dev, bss); | 1047 | bss_ref_put(rdev, bss); |
1042 | spin_unlock_bh(&dev->bss_lock); | 1048 | spin_unlock_bh(&rdev->bss_lock); |
1043 | } | 1049 | } |
1044 | EXPORT_SYMBOL(cfg80211_put_bss); | 1050 | EXPORT_SYMBOL(cfg80211_put_bss); |
1045 | 1051 | ||
1046 | void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | 1052 | void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) |
1047 | { | 1053 | { |
1048 | struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); | 1054 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1049 | struct cfg80211_internal_bss *bss; | 1055 | struct cfg80211_internal_bss *bss; |
1050 | 1056 | ||
1051 | if (WARN_ON(!pub)) | 1057 | if (WARN_ON(!pub)) |
@@ -1053,12 +1059,12 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) | |||
1053 | 1059 | ||
1054 | bss = container_of(pub, struct cfg80211_internal_bss, pub); | 1060 | bss = container_of(pub, struct cfg80211_internal_bss, pub); |
1055 | 1061 | ||
1056 | spin_lock_bh(&dev->bss_lock); | 1062 | spin_lock_bh(&rdev->bss_lock); |
1057 | if (!list_empty(&bss->list)) { | 1063 | if (!list_empty(&bss->list)) { |
1058 | if (__cfg80211_unlink_bss(dev, bss)) | 1064 | if (__cfg80211_unlink_bss(rdev, bss)) |
1059 | dev->bss_generation++; | 1065 | rdev->bss_generation++; |
1060 | } | 1066 | } |
1061 | spin_unlock_bh(&dev->bss_lock); | 1067 | spin_unlock_bh(&rdev->bss_lock); |
1062 | } | 1068 | } |
1063 | EXPORT_SYMBOL(cfg80211_unlink_bss); | 1069 | EXPORT_SYMBOL(cfg80211_unlink_bss); |
1064 | 1070 | ||
@@ -1075,7 +1081,7 @@ cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) | |||
1075 | if (!dev) | 1081 | if (!dev) |
1076 | return ERR_PTR(-ENODEV); | 1082 | return ERR_PTR(-ENODEV); |
1077 | if (dev->ieee80211_ptr) | 1083 | if (dev->ieee80211_ptr) |
1078 | rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); | 1084 | rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy); |
1079 | else | 1085 | else |
1080 | rdev = ERR_PTR(-ENODEV); | 1086 | rdev = ERR_PTR(-ENODEV); |
1081 | dev_put(dev); | 1087 | dev_put(dev); |
@@ -1155,7 +1161,11 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
1155 | int k; | 1161 | int k; |
1156 | int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; | 1162 | int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; |
1157 | for (k = 0; k < wreq->num_channels; k++) { | 1163 | for (k = 0; k < wreq->num_channels; k++) { |
1158 | int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]); | 1164 | struct iw_freq *freq = |
1165 | &wreq->channel_list[k]; | ||
1166 | int wext_freq = | ||
1167 | cfg80211_wext_freq(freq); | ||
1168 | |||
1159 | if (wext_freq == wiphy_freq) | 1169 | if (wext_freq == wiphy_freq) |
1160 | goto wext_freq_found; | 1170 | goto wext_freq_found; |
1161 | } | 1171 | } |
@@ -1467,7 +1477,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1467 | } | 1477 | } |
1468 | 1478 | ||
1469 | 1479 | ||
1470 | static int ieee80211_scan_results(struct cfg80211_registered_device *dev, | 1480 | static int ieee80211_scan_results(struct cfg80211_registered_device *rdev, |
1471 | struct iw_request_info *info, | 1481 | struct iw_request_info *info, |
1472 | char *buf, size_t len) | 1482 | char *buf, size_t len) |
1473 | { | 1483 | { |
@@ -1475,18 +1485,18 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *dev, | |||
1475 | char *end_buf = buf + len; | 1485 | char *end_buf = buf + len; |
1476 | struct cfg80211_internal_bss *bss; | 1486 | struct cfg80211_internal_bss *bss; |
1477 | 1487 | ||
1478 | spin_lock_bh(&dev->bss_lock); | 1488 | spin_lock_bh(&rdev->bss_lock); |
1479 | cfg80211_bss_expire(dev); | 1489 | cfg80211_bss_expire(rdev); |
1480 | 1490 | ||
1481 | list_for_each_entry(bss, &dev->bss_list, list) { | 1491 | list_for_each_entry(bss, &rdev->bss_list, list) { |
1482 | if (buf + len - current_ev <= IW_EV_ADDR_LEN) { | 1492 | if (buf + len - current_ev <= IW_EV_ADDR_LEN) { |
1483 | spin_unlock_bh(&dev->bss_lock); | 1493 | spin_unlock_bh(&rdev->bss_lock); |
1484 | return -E2BIG; | 1494 | return -E2BIG; |
1485 | } | 1495 | } |
1486 | current_ev = ieee80211_bss(&dev->wiphy, info, bss, | 1496 | current_ev = ieee80211_bss(&rdev->wiphy, info, bss, |
1487 | current_ev, end_buf); | 1497 | current_ev, end_buf); |
1488 | } | 1498 | } |
1489 | spin_unlock_bh(&dev->bss_lock); | 1499 | spin_unlock_bh(&rdev->bss_lock); |
1490 | return current_ev - buf; | 1500 | return current_ev - buf; |
1491 | } | 1501 | } |
1492 | 1502 | ||
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 3546a77033de..8bbeeb302216 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -59,7 +59,7 @@ static void cfg80211_sme_free(struct wireless_dev *wdev) | |||
59 | 59 | ||
60 | static int cfg80211_conn_scan(struct wireless_dev *wdev) | 60 | static int cfg80211_conn_scan(struct wireless_dev *wdev) |
61 | { | 61 | { |
62 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 62 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
63 | struct cfg80211_scan_request *request; | 63 | struct cfg80211_scan_request *request; |
64 | int n_channels, err; | 64 | int n_channels, err; |
65 | 65 | ||
@@ -130,7 +130,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
130 | 130 | ||
131 | static int cfg80211_conn_do_work(struct wireless_dev *wdev) | 131 | static int cfg80211_conn_do_work(struct wireless_dev *wdev) |
132 | { | 132 | { |
133 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 133 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
134 | struct cfg80211_connect_params *params; | 134 | struct cfg80211_connect_params *params; |
135 | struct cfg80211_assoc_request req = {}; | 135 | struct cfg80211_assoc_request req = {}; |
136 | int err; | 136 | int err; |
@@ -149,7 +149,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
149 | case CFG80211_CONN_SCAN_AGAIN: | 149 | case CFG80211_CONN_SCAN_AGAIN: |
150 | return cfg80211_conn_scan(wdev); | 150 | return cfg80211_conn_scan(wdev); |
151 | case CFG80211_CONN_AUTHENTICATE_NEXT: | 151 | case CFG80211_CONN_AUTHENTICATE_NEXT: |
152 | BUG_ON(!rdev->ops->auth); | 152 | if (WARN_ON(!rdev->ops->auth)) |
153 | return -EOPNOTSUPP; | ||
153 | wdev->conn->state = CFG80211_CONN_AUTHENTICATING; | 154 | wdev->conn->state = CFG80211_CONN_AUTHENTICATING; |
154 | return cfg80211_mlme_auth(rdev, wdev->netdev, | 155 | return cfg80211_mlme_auth(rdev, wdev->netdev, |
155 | params->channel, params->auth_type, | 156 | params->channel, params->auth_type, |
@@ -161,7 +162,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
161 | case CFG80211_CONN_AUTH_FAILED: | 162 | case CFG80211_CONN_AUTH_FAILED: |
162 | return -ENOTCONN; | 163 | return -ENOTCONN; |
163 | case CFG80211_CONN_ASSOCIATE_NEXT: | 164 | case CFG80211_CONN_ASSOCIATE_NEXT: |
164 | BUG_ON(!rdev->ops->assoc); | 165 | if (WARN_ON(!rdev->ops->assoc)) |
166 | return -EOPNOTSUPP; | ||
165 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; | 167 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; |
166 | if (wdev->conn->prev_bssid_valid) | 168 | if (wdev->conn->prev_bssid_valid) |
167 | req.prev_bssid = wdev->conn->prev_bssid; | 169 | req.prev_bssid = wdev->conn->prev_bssid; |
@@ -244,7 +246,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
244 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | 246 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
245 | static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) | 247 | static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) |
246 | { | 248 | { |
247 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 249 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
248 | struct cfg80211_bss *bss; | 250 | struct cfg80211_bss *bss; |
249 | u16 capa = WLAN_CAPABILITY_ESS; | 251 | u16 capa = WLAN_CAPABILITY_ESS; |
250 | 252 | ||
@@ -274,7 +276,7 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) | |||
274 | static void __cfg80211_sme_scan_done(struct net_device *dev) | 276 | static void __cfg80211_sme_scan_done(struct net_device *dev) |
275 | { | 277 | { |
276 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 278 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
277 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 279 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
278 | struct cfg80211_bss *bss; | 280 | struct cfg80211_bss *bss; |
279 | 281 | ||
280 | ASSERT_WDEV_LOCK(wdev); | 282 | ASSERT_WDEV_LOCK(wdev); |
@@ -305,7 +307,7 @@ void cfg80211_sme_scan_done(struct net_device *dev) | |||
305 | void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len) | 307 | void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len) |
306 | { | 308 | { |
307 | struct wiphy *wiphy = wdev->wiphy; | 309 | struct wiphy *wiphy = wdev->wiphy; |
308 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 310 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
309 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | 311 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; |
310 | u16 status_code = le16_to_cpu(mgmt->u.auth.status_code); | 312 | u16 status_code = le16_to_cpu(mgmt->u.auth.status_code); |
311 | 313 | ||
@@ -351,7 +353,7 @@ void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len) | |||
351 | 353 | ||
352 | bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status) | 354 | bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status) |
353 | { | 355 | { |
354 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 356 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
355 | 357 | ||
356 | if (!wdev->conn) | 358 | if (!wdev->conn) |
357 | return false; | 359 | return false; |
@@ -385,7 +387,7 @@ void cfg80211_sme_deauth(struct wireless_dev *wdev) | |||
385 | 387 | ||
386 | void cfg80211_sme_auth_timeout(struct wireless_dev *wdev) | 388 | void cfg80211_sme_auth_timeout(struct wireless_dev *wdev) |
387 | { | 389 | { |
388 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 390 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
389 | 391 | ||
390 | if (!wdev->conn) | 392 | if (!wdev->conn) |
391 | return; | 393 | return; |
@@ -396,7 +398,7 @@ void cfg80211_sme_auth_timeout(struct wireless_dev *wdev) | |||
396 | 398 | ||
397 | void cfg80211_sme_disassoc(struct wireless_dev *wdev) | 399 | void cfg80211_sme_disassoc(struct wireless_dev *wdev) |
398 | { | 400 | { |
399 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 401 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
400 | 402 | ||
401 | if (!wdev->conn) | 403 | if (!wdev->conn) |
402 | return; | 404 | return; |
@@ -407,7 +409,7 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev) | |||
407 | 409 | ||
408 | void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev) | 410 | void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev) |
409 | { | 411 | { |
410 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 412 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
411 | 413 | ||
412 | if (!wdev->conn) | 414 | if (!wdev->conn) |
413 | return; | 415 | return; |
@@ -420,7 +422,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, | |||
420 | struct cfg80211_connect_params *connect, | 422 | struct cfg80211_connect_params *connect, |
421 | const u8 *prev_bssid) | 423 | const u8 *prev_bssid) |
422 | { | 424 | { |
423 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 425 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
424 | struct cfg80211_bss *bss; | 426 | struct cfg80211_bss *bss; |
425 | int err; | 427 | int err; |
426 | 428 | ||
@@ -467,7 +469,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, | |||
467 | } | 469 | } |
468 | 470 | ||
469 | wdev->conn->params.ssid = wdev->ssid; | 471 | wdev->conn->params.ssid = wdev->ssid; |
470 | wdev->conn->params.ssid_len = connect->ssid_len; | 472 | wdev->conn->params.ssid_len = wdev->ssid_len; |
471 | 473 | ||
472 | /* see if we have the bss already */ | 474 | /* see if we have the bss already */ |
473 | bss = cfg80211_get_conn_bss(wdev); | 475 | bss = cfg80211_get_conn_bss(wdev); |
@@ -479,7 +481,6 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, | |||
479 | 481 | ||
480 | /* we're good if we have a matching bss struct */ | 482 | /* we're good if we have a matching bss struct */ |
481 | if (bss) { | 483 | if (bss) { |
482 | wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; | ||
483 | err = cfg80211_conn_do_work(wdev); | 484 | err = cfg80211_conn_do_work(wdev); |
484 | cfg80211_put_bss(wdev->wiphy, bss); | 485 | cfg80211_put_bss(wdev->wiphy, bss); |
485 | } else { | 486 | } else { |
@@ -505,7 +506,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, | |||
505 | 506 | ||
506 | static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason) | 507 | static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason) |
507 | { | 508 | { |
508 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 509 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
509 | int err; | 510 | int err; |
510 | 511 | ||
511 | if (!wdev->conn) | 512 | if (!wdev->conn) |
@@ -593,7 +594,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
593 | return; | 594 | return; |
594 | } | 595 | } |
595 | 596 | ||
596 | nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, | 597 | nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, |
597 | bssid, req_ie, req_ie_len, | 598 | bssid, req_ie, req_ie_len, |
598 | resp_ie, resp_ie_len, | 599 | resp_ie, resp_ie_len, |
599 | status, GFP_KERNEL); | 600 | status, GFP_KERNEL); |
@@ -624,7 +625,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
624 | #endif | 625 | #endif |
625 | 626 | ||
626 | if (!bss && (status == WLAN_STATUS_SUCCESS)) { | 627 | if (!bss && (status == WLAN_STATUS_SUCCESS)) { |
627 | WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect); | 628 | WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect); |
628 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 629 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, |
629 | wdev->ssid, wdev->ssid_len, | 630 | wdev->ssid, wdev->ssid_len, |
630 | WLAN_CAPABILITY_ESS, | 631 | WLAN_CAPABILITY_ESS, |
@@ -687,7 +688,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
687 | u16 status, gfp_t gfp) | 688 | u16 status, gfp_t gfp) |
688 | { | 689 | { |
689 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 690 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
690 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 691 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
691 | struct cfg80211_event *ev; | 692 | struct cfg80211_event *ev; |
692 | unsigned long flags; | 693 | unsigned long flags; |
693 | 694 | ||
@@ -742,7 +743,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, | |||
742 | cfg80211_hold_bss(bss_from_pub(bss)); | 743 | cfg80211_hold_bss(bss_from_pub(bss)); |
743 | wdev->current_bss = bss_from_pub(bss); | 744 | wdev->current_bss = bss_from_pub(bss); |
744 | 745 | ||
745 | nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), wdev->netdev, bss->bssid, | 746 | nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), |
747 | wdev->netdev, bss->bssid, | ||
746 | req_ie, req_ie_len, resp_ie, resp_ie_len, | 748 | req_ie, req_ie_len, resp_ie, resp_ie_len, |
747 | GFP_KERNEL); | 749 | GFP_KERNEL); |
748 | 750 | ||
@@ -801,7 +803,7 @@ void cfg80211_roamed_bss(struct net_device *dev, | |||
801 | size_t resp_ie_len, gfp_t gfp) | 803 | size_t resp_ie_len, gfp_t gfp) |
802 | { | 804 | { |
803 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 805 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
804 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 806 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
805 | struct cfg80211_event *ev; | 807 | struct cfg80211_event *ev; |
806 | unsigned long flags; | 808 | unsigned long flags; |
807 | 809 | ||
@@ -834,7 +836,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
834 | size_t ie_len, u16 reason, bool from_ap) | 836 | size_t ie_len, u16 reason, bool from_ap) |
835 | { | 837 | { |
836 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 838 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
837 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 839 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
838 | int i; | 840 | int i; |
839 | #ifdef CONFIG_CFG80211_WEXT | 841 | #ifdef CONFIG_CFG80211_WEXT |
840 | union iwreq_data wrqu; | 842 | union iwreq_data wrqu; |
@@ -877,10 +879,10 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
877 | } | 879 | } |
878 | 880 | ||
879 | void cfg80211_disconnected(struct net_device *dev, u16 reason, | 881 | void cfg80211_disconnected(struct net_device *dev, u16 reason, |
880 | u8 *ie, size_t ie_len, gfp_t gfp) | 882 | const u8 *ie, size_t ie_len, gfp_t gfp) |
881 | { | 883 | { |
882 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 884 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
883 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 885 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
884 | struct cfg80211_event *ev; | 886 | struct cfg80211_event *ev; |
885 | unsigned long flags; | 887 | unsigned long flags; |
886 | 888 | ||
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index aabccf13e07b..560ed77084e9 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1876,29 +1876,33 @@ TRACE_EVENT(rdev_channel_switch, | |||
1876 | WIPHY_ENTRY | 1876 | WIPHY_ENTRY |
1877 | NETDEV_ENTRY | 1877 | NETDEV_ENTRY |
1878 | CHAN_DEF_ENTRY | 1878 | CHAN_DEF_ENTRY |
1879 | __field(u16, counter_offset_beacon) | ||
1880 | __field(u16, counter_offset_presp) | ||
1881 | __field(bool, radar_required) | 1879 | __field(bool, radar_required) |
1882 | __field(bool, block_tx) | 1880 | __field(bool, block_tx) |
1883 | __field(u8, count) | 1881 | __field(u8, count) |
1882 | __dynamic_array(u16, bcn_ofs, params->n_counter_offsets_beacon) | ||
1883 | __dynamic_array(u16, pres_ofs, params->n_counter_offsets_presp) | ||
1884 | ), | 1884 | ), |
1885 | TP_fast_assign( | 1885 | TP_fast_assign( |
1886 | WIPHY_ASSIGN; | 1886 | WIPHY_ASSIGN; |
1887 | NETDEV_ASSIGN; | 1887 | NETDEV_ASSIGN; |
1888 | CHAN_DEF_ASSIGN(¶ms->chandef); | 1888 | CHAN_DEF_ASSIGN(¶ms->chandef); |
1889 | __entry->counter_offset_beacon = params->counter_offset_beacon; | ||
1890 | __entry->counter_offset_presp = params->counter_offset_presp; | ||
1891 | __entry->radar_required = params->radar_required; | 1889 | __entry->radar_required = params->radar_required; |
1892 | __entry->block_tx = params->block_tx; | 1890 | __entry->block_tx = params->block_tx; |
1893 | __entry->count = params->count; | 1891 | __entry->count = params->count; |
1892 | memcpy(__get_dynamic_array(bcn_ofs), | ||
1893 | params->counter_offsets_beacon, | ||
1894 | params->n_counter_offsets_beacon * sizeof(u16)); | ||
1895 | |||
1896 | /* probe response offsets are optional */ | ||
1897 | if (params->n_counter_offsets_presp) | ||
1898 | memcpy(__get_dynamic_array(pres_ofs), | ||
1899 | params->counter_offsets_presp, | ||
1900 | params->n_counter_offsets_presp * sizeof(u16)); | ||
1894 | ), | 1901 | ), |
1895 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT | 1902 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT |
1896 | ", block_tx: %d, count: %u, radar_required: %d" | 1903 | ", block_tx: %d, count: %u, radar_required: %d", |
1897 | ", counter offsets (beacon/presp): %u/%u", | ||
1898 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, | 1904 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, |
1899 | __entry->block_tx, __entry->count, __entry->radar_required, | 1905 | __entry->block_tx, __entry->count, __entry->radar_required) |
1900 | __entry->counter_offset_beacon, | ||
1901 | __entry->counter_offset_presp) | ||
1902 | ); | 1906 | ); |
1903 | 1907 | ||
1904 | TRACE_EVENT(rdev_set_qos_map, | 1908 | TRACE_EVENT(rdev_set_qos_map, |
@@ -1919,6 +1923,24 @@ TRACE_EVENT(rdev_set_qos_map, | |||
1919 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->num_des) | 1923 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->num_des) |
1920 | ); | 1924 | ); |
1921 | 1925 | ||
1926 | TRACE_EVENT(rdev_set_ap_chanwidth, | ||
1927 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1928 | struct cfg80211_chan_def *chandef), | ||
1929 | TP_ARGS(wiphy, netdev, chandef), | ||
1930 | TP_STRUCT__entry( | ||
1931 | WIPHY_ENTRY | ||
1932 | NETDEV_ENTRY | ||
1933 | CHAN_DEF_ENTRY | ||
1934 | ), | ||
1935 | TP_fast_assign( | ||
1936 | WIPHY_ASSIGN; | ||
1937 | NETDEV_ASSIGN; | ||
1938 | CHAN_DEF_ASSIGN(chandef); | ||
1939 | ), | ||
1940 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT, | ||
1941 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) | ||
1942 | ); | ||
1943 | |||
1922 | /************************************************************* | 1944 | /************************************************************* |
1923 | * cfg80211 exported functions traces * | 1945 | * cfg80211 exported functions traces * |
1924 | *************************************************************/ | 1946 | *************************************************************/ |
@@ -2193,18 +2215,21 @@ TRACE_EVENT(cfg80211_cqm_rssi_notify, | |||
2193 | ); | 2215 | ); |
2194 | 2216 | ||
2195 | TRACE_EVENT(cfg80211_reg_can_beacon, | 2217 | TRACE_EVENT(cfg80211_reg_can_beacon, |
2196 | TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), | 2218 | TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, |
2197 | TP_ARGS(wiphy, chandef), | 2219 | enum nl80211_iftype iftype), |
2220 | TP_ARGS(wiphy, chandef, iftype), | ||
2198 | TP_STRUCT__entry( | 2221 | TP_STRUCT__entry( |
2199 | WIPHY_ENTRY | 2222 | WIPHY_ENTRY |
2200 | CHAN_DEF_ENTRY | 2223 | CHAN_DEF_ENTRY |
2224 | __field(enum nl80211_iftype, iftype) | ||
2201 | ), | 2225 | ), |
2202 | TP_fast_assign( | 2226 | TP_fast_assign( |
2203 | WIPHY_ASSIGN; | 2227 | WIPHY_ASSIGN; |
2204 | CHAN_DEF_ASSIGN(chandef); | 2228 | CHAN_DEF_ASSIGN(chandef); |
2229 | __entry->iftype = iftype; | ||
2205 | ), | 2230 | ), |
2206 | TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, | 2231 | TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", iftype=%d", |
2207 | WIPHY_PR_ARG, CHAN_DEF_PR_ARG) | 2232 | WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->iftype) |
2208 | ); | 2233 | ); |
2209 | 2234 | ||
2210 | TRACE_EVENT(cfg80211_chandef_dfs_required, | 2235 | TRACE_EVENT(cfg80211_chandef_dfs_required, |
@@ -2615,6 +2640,21 @@ TRACE_EVENT(cfg80211_ft_event, | |||
2615 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) | 2640 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) |
2616 | ); | 2641 | ); |
2617 | 2642 | ||
2643 | TRACE_EVENT(cfg80211_stop_iface, | ||
2644 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
2645 | TP_ARGS(wiphy, wdev), | ||
2646 | TP_STRUCT__entry( | ||
2647 | WIPHY_ENTRY | ||
2648 | WDEV_ENTRY | ||
2649 | ), | ||
2650 | TP_fast_assign( | ||
2651 | WIPHY_ASSIGN; | ||
2652 | WDEV_ASSIGN; | ||
2653 | ), | ||
2654 | TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, | ||
2655 | WIPHY_PR_ARG, WDEV_PR_ARG) | ||
2656 | ); | ||
2657 | |||
2618 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ | 2658 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ |
2619 | 2659 | ||
2620 | #undef TRACE_INCLUDE_PATH | 2660 | #undef TRACE_INCLUDE_PATH |
diff --git a/net/wireless/util.c b/net/wireless/util.c index e5872ff2c27c..728f1c0dc70d 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -476,7 +476,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
476 | EXPORT_SYMBOL(ieee80211_data_to_8023); | 476 | EXPORT_SYMBOL(ieee80211_data_to_8023); |
477 | 477 | ||
478 | int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, | 478 | int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, |
479 | enum nl80211_iftype iftype, u8 *bssid, bool qos) | 479 | enum nl80211_iftype iftype, |
480 | const u8 *bssid, bool qos) | ||
480 | { | 481 | { |
481 | struct ieee80211_hdr hdr; | 482 | struct ieee80211_hdr hdr; |
482 | u16 hdrlen, ethertype; | 483 | u16 hdrlen, ethertype; |
@@ -770,7 +771,7 @@ EXPORT_SYMBOL(ieee80211_bss_get_ie); | |||
770 | 771 | ||
771 | void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | 772 | void cfg80211_upload_connect_keys(struct wireless_dev *wdev) |
772 | { | 773 | { |
773 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 774 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
774 | struct net_device *dev = wdev->netdev; | 775 | struct net_device *dev = wdev->netdev; |
775 | int i; | 776 | int i; |
776 | 777 | ||
@@ -839,6 +840,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) | |||
839 | __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, | 840 | __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, |
840 | ev->ij.channel); | 841 | ev->ij.channel); |
841 | break; | 842 | break; |
843 | case EVENT_STOPPED: | ||
844 | __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev); | ||
845 | break; | ||
842 | } | 846 | } |
843 | wdev_unlock(wdev); | 847 | wdev_unlock(wdev); |
844 | 848 | ||
@@ -888,11 +892,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
888 | return -EBUSY; | 892 | return -EBUSY; |
889 | 893 | ||
890 | if (ntype != otype && netif_running(dev)) { | 894 | if (ntype != otype && netif_running(dev)) { |
891 | err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, | ||
892 | ntype); | ||
893 | if (err) | ||
894 | return err; | ||
895 | |||
896 | dev->ieee80211_ptr->use_4addr = false; | 895 | dev->ieee80211_ptr->use_4addr = false; |
897 | dev->ieee80211_ptr->mesh_id_up_len = 0; | 896 | dev->ieee80211_ptr->mesh_id_up_len = 0; |
898 | wdev_lock(dev->ieee80211_ptr); | 897 | wdev_lock(dev->ieee80211_ptr); |
@@ -1268,6 +1267,120 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | |||
1268 | return res; | 1267 | return res; |
1269 | } | 1268 | } |
1270 | 1269 | ||
1270 | int cfg80211_iter_combinations(struct wiphy *wiphy, | ||
1271 | const int num_different_channels, | ||
1272 | const u8 radar_detect, | ||
1273 | const int iftype_num[NUM_NL80211_IFTYPES], | ||
1274 | void (*iter)(const struct ieee80211_iface_combination *c, | ||
1275 | void *data), | ||
1276 | void *data) | ||
1277 | { | ||
1278 | const struct ieee80211_regdomain *regdom; | ||
1279 | enum nl80211_dfs_regions region = 0; | ||
1280 | int i, j, iftype; | ||
1281 | int num_interfaces = 0; | ||
1282 | u32 used_iftypes = 0; | ||
1283 | |||
1284 | if (radar_detect) { | ||
1285 | rcu_read_lock(); | ||
1286 | regdom = rcu_dereference(cfg80211_regdomain); | ||
1287 | if (regdom) | ||
1288 | region = regdom->dfs_region; | ||
1289 | rcu_read_unlock(); | ||
1290 | } | ||
1291 | |||
1292 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { | ||
1293 | num_interfaces += iftype_num[iftype]; | ||
1294 | if (iftype_num[iftype] > 0 && | ||
1295 | !(wiphy->software_iftypes & BIT(iftype))) | ||
1296 | used_iftypes |= BIT(iftype); | ||
1297 | } | ||
1298 | |||
1299 | for (i = 0; i < wiphy->n_iface_combinations; i++) { | ||
1300 | const struct ieee80211_iface_combination *c; | ||
1301 | struct ieee80211_iface_limit *limits; | ||
1302 | u32 all_iftypes = 0; | ||
1303 | |||
1304 | c = &wiphy->iface_combinations[i]; | ||
1305 | |||
1306 | if (num_interfaces > c->max_interfaces) | ||
1307 | continue; | ||
1308 | if (num_different_channels > c->num_different_channels) | ||
1309 | continue; | ||
1310 | |||
1311 | limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, | ||
1312 | GFP_KERNEL); | ||
1313 | if (!limits) | ||
1314 | return -ENOMEM; | ||
1315 | |||
1316 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { | ||
1317 | if (wiphy->software_iftypes & BIT(iftype)) | ||
1318 | continue; | ||
1319 | for (j = 0; j < c->n_limits; j++) { | ||
1320 | all_iftypes |= limits[j].types; | ||
1321 | if (!(limits[j].types & BIT(iftype))) | ||
1322 | continue; | ||
1323 | if (limits[j].max < iftype_num[iftype]) | ||
1324 | goto cont; | ||
1325 | limits[j].max -= iftype_num[iftype]; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | if (radar_detect != (c->radar_detect_widths & radar_detect)) | ||
1330 | goto cont; | ||
1331 | |||
1332 | if (radar_detect && c->radar_detect_regions && | ||
1333 | !(c->radar_detect_regions & BIT(region))) | ||
1334 | goto cont; | ||
1335 | |||
1336 | /* Finally check that all iftypes that we're currently | ||
1337 | * using are actually part of this combination. If they | ||
1338 | * aren't then we can't use this combination and have | ||
1339 | * to continue to the next. | ||
1340 | */ | ||
1341 | if ((all_iftypes & used_iftypes) != used_iftypes) | ||
1342 | goto cont; | ||
1343 | |||
1344 | /* This combination covered all interface types and | ||
1345 | * supported the requested numbers, so we're good. | ||
1346 | */ | ||
1347 | |||
1348 | (*iter)(c, data); | ||
1349 | cont: | ||
1350 | kfree(limits); | ||
1351 | } | ||
1352 | |||
1353 | return 0; | ||
1354 | } | ||
1355 | EXPORT_SYMBOL(cfg80211_iter_combinations); | ||
1356 | |||
1357 | static void | ||
1358 | cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c, | ||
1359 | void *data) | ||
1360 | { | ||
1361 | int *num = data; | ||
1362 | (*num)++; | ||
1363 | } | ||
1364 | |||
1365 | int cfg80211_check_combinations(struct wiphy *wiphy, | ||
1366 | const int num_different_channels, | ||
1367 | const u8 radar_detect, | ||
1368 | const int iftype_num[NUM_NL80211_IFTYPES]) | ||
1369 | { | ||
1370 | int err, num = 0; | ||
1371 | |||
1372 | err = cfg80211_iter_combinations(wiphy, num_different_channels, | ||
1373 | radar_detect, iftype_num, | ||
1374 | cfg80211_iter_sum_ifcombs, &num); | ||
1375 | if (err) | ||
1376 | return err; | ||
1377 | if (num == 0) | ||
1378 | return -EBUSY; | ||
1379 | |||
1380 | return 0; | ||
1381 | } | ||
1382 | EXPORT_SYMBOL(cfg80211_check_combinations); | ||
1383 | |||
1271 | int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | 1384 | int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, |
1272 | struct wireless_dev *wdev, | 1385 | struct wireless_dev *wdev, |
1273 | enum nl80211_iftype iftype, | 1386 | enum nl80211_iftype iftype, |
@@ -1276,7 +1389,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1276 | u8 radar_detect) | 1389 | u8 radar_detect) |
1277 | { | 1390 | { |
1278 | struct wireless_dev *wdev_iter; | 1391 | struct wireless_dev *wdev_iter; |
1279 | u32 used_iftypes = BIT(iftype); | ||
1280 | int num[NUM_NL80211_IFTYPES]; | 1392 | int num[NUM_NL80211_IFTYPES]; |
1281 | struct ieee80211_channel | 1393 | struct ieee80211_channel |
1282 | *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; | 1394 | *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; |
@@ -1284,7 +1396,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1284 | enum cfg80211_chan_mode chmode; | 1396 | enum cfg80211_chan_mode chmode; |
1285 | int num_different_channels = 0; | 1397 | int num_different_channels = 0; |
1286 | int total = 1; | 1398 | int total = 1; |
1287 | int i, j; | 1399 | int i; |
1288 | 1400 | ||
1289 | ASSERT_RTNL(); | 1401 | ASSERT_RTNL(); |
1290 | 1402 | ||
@@ -1306,6 +1418,11 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1306 | 1418 | ||
1307 | num[iftype] = 1; | 1419 | num[iftype] = 1; |
1308 | 1420 | ||
1421 | /* TODO: We'll probably not need this anymore, since this | ||
1422 | * should only be called with CHAN_MODE_UNDEFINED. There are | ||
1423 | * still a couple of pending calls where other chanmodes are | ||
1424 | * used, but we should get rid of them. | ||
1425 | */ | ||
1309 | switch (chanmode) { | 1426 | switch (chanmode) { |
1310 | case CHAN_MODE_UNDEFINED: | 1427 | case CHAN_MODE_UNDEFINED: |
1311 | break; | 1428 | break; |
@@ -1369,65 +1486,13 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1369 | 1486 | ||
1370 | num[wdev_iter->iftype]++; | 1487 | num[wdev_iter->iftype]++; |
1371 | total++; | 1488 | total++; |
1372 | used_iftypes |= BIT(wdev_iter->iftype); | ||
1373 | } | 1489 | } |
1374 | 1490 | ||
1375 | if (total == 1 && !radar_detect) | 1491 | if (total == 1 && !radar_detect) |
1376 | return 0; | 1492 | return 0; |
1377 | 1493 | ||
1378 | for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { | 1494 | return cfg80211_check_combinations(&rdev->wiphy, num_different_channels, |
1379 | const struct ieee80211_iface_combination *c; | 1495 | radar_detect, num); |
1380 | struct ieee80211_iface_limit *limits; | ||
1381 | u32 all_iftypes = 0; | ||
1382 | |||
1383 | c = &rdev->wiphy.iface_combinations[i]; | ||
1384 | |||
1385 | if (total > c->max_interfaces) | ||
1386 | continue; | ||
1387 | if (num_different_channels > c->num_different_channels) | ||
1388 | continue; | ||
1389 | |||
1390 | limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, | ||
1391 | GFP_KERNEL); | ||
1392 | if (!limits) | ||
1393 | return -ENOMEM; | ||
1394 | |||
1395 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { | ||
1396 | if (rdev->wiphy.software_iftypes & BIT(iftype)) | ||
1397 | continue; | ||
1398 | for (j = 0; j < c->n_limits; j++) { | ||
1399 | all_iftypes |= limits[j].types; | ||
1400 | if (!(limits[j].types & BIT(iftype))) | ||
1401 | continue; | ||
1402 | if (limits[j].max < num[iftype]) | ||
1403 | goto cont; | ||
1404 | limits[j].max -= num[iftype]; | ||
1405 | } | ||
1406 | } | ||
1407 | |||
1408 | if (radar_detect && !(c->radar_detect_widths & radar_detect)) | ||
1409 | goto cont; | ||
1410 | |||
1411 | /* | ||
1412 | * Finally check that all iftypes that we're currently | ||
1413 | * using are actually part of this combination. If they | ||
1414 | * aren't then we can't use this combination and have | ||
1415 | * to continue to the next. | ||
1416 | */ | ||
1417 | if ((all_iftypes & used_iftypes) != used_iftypes) | ||
1418 | goto cont; | ||
1419 | |||
1420 | /* | ||
1421 | * This combination covered all interface types and | ||
1422 | * supported the requested numbers, so we're good. | ||
1423 | */ | ||
1424 | kfree(limits); | ||
1425 | return 0; | ||
1426 | cont: | ||
1427 | kfree(limits); | ||
1428 | } | ||
1429 | |||
1430 | return -EBUSY; | ||
1431 | } | 1496 | } |
1432 | 1497 | ||
1433 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, | 1498 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, |
@@ -1481,6 +1546,24 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy) | |||
1481 | } | 1546 | } |
1482 | EXPORT_SYMBOL(ieee80211_get_num_supported_channels); | 1547 | EXPORT_SYMBOL(ieee80211_get_num_supported_channels); |
1483 | 1548 | ||
1549 | int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, | ||
1550 | struct station_info *sinfo) | ||
1551 | { | ||
1552 | struct cfg80211_registered_device *rdev; | ||
1553 | struct wireless_dev *wdev; | ||
1554 | |||
1555 | wdev = dev->ieee80211_ptr; | ||
1556 | if (!wdev) | ||
1557 | return -EOPNOTSUPP; | ||
1558 | |||
1559 | rdev = wiphy_to_rdev(wdev->wiphy); | ||
1560 | if (!rdev->ops->get_station) | ||
1561 | return -EOPNOTSUPP; | ||
1562 | |||
1563 | return rdev_get_station(rdev, dev, mac_addr, sinfo); | ||
1564 | } | ||
1565 | EXPORT_SYMBOL(cfg80211_get_station); | ||
1566 | |||
1484 | /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ | 1567 | /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ |
1485 | /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ | 1568 | /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ |
1486 | const unsigned char rfc1042_header[] __aligned(2) = | 1569 | const unsigned char rfc1042_header[] __aligned(2) = |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 5661a54ac7ee..11120bb14162 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -73,7 +73,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | |||
73 | struct vif_params vifparams; | 73 | struct vif_params vifparams; |
74 | enum nl80211_iftype type; | 74 | enum nl80211_iftype type; |
75 | 75 | ||
76 | rdev = wiphy_to_dev(wdev->wiphy); | 76 | rdev = wiphy_to_rdev(wdev->wiphy); |
77 | 77 | ||
78 | switch (*mode) { | 78 | switch (*mode) { |
79 | case IW_MODE_INFRA: | 79 | case IW_MODE_INFRA: |
@@ -253,12 +253,12 @@ EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange); | |||
253 | 253 | ||
254 | /** | 254 | /** |
255 | * cfg80211_wext_freq - get wext frequency for non-"auto" | 255 | * cfg80211_wext_freq - get wext frequency for non-"auto" |
256 | * @wiphy: the wiphy | 256 | * @dev: the net device |
257 | * @freq: the wext freq encoding | 257 | * @freq: the wext freq encoding |
258 | * | 258 | * |
259 | * Returns a frequency, or a negative error code, or 0 for auto. | 259 | * Returns a frequency, or a negative error code, or 0 for auto. |
260 | */ | 260 | */ |
261 | int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq) | 261 | int cfg80211_wext_freq(struct iw_freq *freq) |
262 | { | 262 | { |
263 | /* | 263 | /* |
264 | * Parse frequency - return 0 for auto and | 264 | * Parse frequency - return 0 for auto and |
@@ -286,7 +286,7 @@ int cfg80211_wext_siwrts(struct net_device *dev, | |||
286 | struct iw_param *rts, char *extra) | 286 | struct iw_param *rts, char *extra) |
287 | { | 287 | { |
288 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 288 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
289 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 289 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
290 | u32 orts = wdev->wiphy->rts_threshold; | 290 | u32 orts = wdev->wiphy->rts_threshold; |
291 | int err; | 291 | int err; |
292 | 292 | ||
@@ -324,7 +324,7 @@ int cfg80211_wext_siwfrag(struct net_device *dev, | |||
324 | struct iw_param *frag, char *extra) | 324 | struct iw_param *frag, char *extra) |
325 | { | 325 | { |
326 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 326 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
327 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 327 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
328 | u32 ofrag = wdev->wiphy->frag_threshold; | 328 | u32 ofrag = wdev->wiphy->frag_threshold; |
329 | int err; | 329 | int err; |
330 | 330 | ||
@@ -364,7 +364,7 @@ static int cfg80211_wext_siwretry(struct net_device *dev, | |||
364 | struct iw_param *retry, char *extra) | 364 | struct iw_param *retry, char *extra) |
365 | { | 365 | { |
366 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 366 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
367 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 367 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
368 | u32 changed = 0; | 368 | u32 changed = 0; |
369 | u8 olong = wdev->wiphy->retry_long; | 369 | u8 olong = wdev->wiphy->retry_long; |
370 | u8 oshort = wdev->wiphy->retry_short; | 370 | u8 oshort = wdev->wiphy->retry_short; |
@@ -587,7 +587,7 @@ static int cfg80211_wext_siwencode(struct net_device *dev, | |||
587 | struct iw_point *erq, char *keybuf) | 587 | struct iw_point *erq, char *keybuf) |
588 | { | 588 | { |
589 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 589 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
590 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 590 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
591 | int idx, err; | 591 | int idx, err; |
592 | bool remove = false; | 592 | bool remove = false; |
593 | struct key_params params; | 593 | struct key_params params; |
@@ -647,7 +647,7 @@ static int cfg80211_wext_siwencodeext(struct net_device *dev, | |||
647 | struct iw_point *erq, char *extra) | 647 | struct iw_point *erq, char *extra) |
648 | { | 648 | { |
649 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 649 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
650 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 650 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
651 | struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; | 651 | struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; |
652 | const u8 *addr; | 652 | const u8 *addr; |
653 | int idx; | 653 | int idx; |
@@ -775,7 +775,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, | |||
775 | struct iw_freq *wextfreq, char *extra) | 775 | struct iw_freq *wextfreq, char *extra) |
776 | { | 776 | { |
777 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 777 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
778 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 778 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
779 | struct cfg80211_chan_def chandef = { | 779 | struct cfg80211_chan_def chandef = { |
780 | .width = NL80211_CHAN_WIDTH_20_NOHT, | 780 | .width = NL80211_CHAN_WIDTH_20_NOHT, |
781 | }; | 781 | }; |
@@ -787,7 +787,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, | |||
787 | case NL80211_IFTYPE_ADHOC: | 787 | case NL80211_IFTYPE_ADHOC: |
788 | return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra); | 788 | return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra); |
789 | case NL80211_IFTYPE_MONITOR: | 789 | case NL80211_IFTYPE_MONITOR: |
790 | freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); | 790 | freq = cfg80211_wext_freq(wextfreq); |
791 | if (freq < 0) | 791 | if (freq < 0) |
792 | return freq; | 792 | return freq; |
793 | if (freq == 0) | 793 | if (freq == 0) |
@@ -798,7 +798,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, | |||
798 | return -EINVAL; | 798 | return -EINVAL; |
799 | return cfg80211_set_monitor_channel(rdev, &chandef); | 799 | return cfg80211_set_monitor_channel(rdev, &chandef); |
800 | case NL80211_IFTYPE_MESH_POINT: | 800 | case NL80211_IFTYPE_MESH_POINT: |
801 | freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); | 801 | freq = cfg80211_wext_freq(wextfreq); |
802 | if (freq < 0) | 802 | if (freq < 0) |
803 | return freq; | 803 | return freq; |
804 | if (freq == 0) | 804 | if (freq == 0) |
@@ -818,7 +818,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, | |||
818 | struct iw_freq *freq, char *extra) | 818 | struct iw_freq *freq, char *extra) |
819 | { | 819 | { |
820 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 820 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
821 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 821 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
822 | struct cfg80211_chan_def chandef; | 822 | struct cfg80211_chan_def chandef; |
823 | int ret; | 823 | int ret; |
824 | 824 | ||
@@ -847,7 +847,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev, | |||
847 | union iwreq_data *data, char *extra) | 847 | union iwreq_data *data, char *extra) |
848 | { | 848 | { |
849 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 849 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
850 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 850 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
851 | enum nl80211_tx_power_setting type; | 851 | enum nl80211_tx_power_setting type; |
852 | int dbm = 0; | 852 | int dbm = 0; |
853 | 853 | ||
@@ -899,7 +899,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev, | |||
899 | union iwreq_data *data, char *extra) | 899 | union iwreq_data *data, char *extra) |
900 | { | 900 | { |
901 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 901 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
902 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 902 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
903 | int err, val; | 903 | int err, val; |
904 | 904 | ||
905 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) | 905 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) |
@@ -1119,7 +1119,7 @@ static int cfg80211_wext_siwpower(struct net_device *dev, | |||
1119 | struct iw_param *wrq, char *extra) | 1119 | struct iw_param *wrq, char *extra) |
1120 | { | 1120 | { |
1121 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1121 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1122 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 1122 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1123 | bool ps = wdev->ps; | 1123 | bool ps = wdev->ps; |
1124 | int timeout = wdev->ps_timeout; | 1124 | int timeout = wdev->ps_timeout; |
1125 | int err; | 1125 | int err; |
@@ -1177,7 +1177,7 @@ static int cfg80211_wds_wext_siwap(struct net_device *dev, | |||
1177 | struct sockaddr *addr, char *extra) | 1177 | struct sockaddr *addr, char *extra) |
1178 | { | 1178 | { |
1179 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1179 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1180 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 1180 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1181 | int err; | 1181 | int err; |
1182 | 1182 | ||
1183 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS)) | 1183 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS)) |
@@ -1221,7 +1221,7 @@ static int cfg80211_wext_siwrate(struct net_device *dev, | |||
1221 | struct iw_param *rate, char *extra) | 1221 | struct iw_param *rate, char *extra) |
1222 | { | 1222 | { |
1223 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1223 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1224 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 1224 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1225 | struct cfg80211_bitrate_mask mask; | 1225 | struct cfg80211_bitrate_mask mask; |
1226 | u32 fixed, maxrate; | 1226 | u32 fixed, maxrate; |
1227 | struct ieee80211_supported_band *sband; | 1227 | struct ieee80211_supported_band *sband; |
@@ -1272,7 +1272,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev, | |||
1272 | struct iw_param *rate, char *extra) | 1272 | struct iw_param *rate, char *extra) |
1273 | { | 1273 | { |
1274 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1274 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1275 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 1275 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1276 | /* we are under RTNL - globally locked - so can use a static struct */ | 1276 | /* we are under RTNL - globally locked - so can use a static struct */ |
1277 | static struct station_info sinfo; | 1277 | static struct station_info sinfo; |
1278 | u8 addr[ETH_ALEN]; | 1278 | u8 addr[ETH_ALEN]; |
@@ -1310,7 +1310,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev, | |||
1310 | static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | 1310 | static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) |
1311 | { | 1311 | { |
1312 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1312 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1313 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 1313 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1314 | /* we are under RTNL - globally locked - so can use static structs */ | 1314 | /* we are under RTNL - globally locked - so can use static structs */ |
1315 | static struct iw_statistics wstats; | 1315 | static struct iw_statistics wstats; |
1316 | static struct station_info sinfo; | 1316 | static struct station_info sinfo; |
@@ -1449,7 +1449,7 @@ static int cfg80211_wext_siwpmksa(struct net_device *dev, | |||
1449 | struct iw_point *data, char *extra) | 1449 | struct iw_point *data, char *extra) |
1450 | { | 1450 | { |
1451 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1451 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1452 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 1452 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1453 | struct cfg80211_pmksa cfg_pmksa; | 1453 | struct cfg80211_pmksa cfg_pmksa; |
1454 | struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; | 1454 | struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; |
1455 | 1455 | ||
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index 5d766b0118e8..ebcacca2f731 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h | |||
@@ -50,7 +50,7 @@ int cfg80211_wext_siwgenie(struct net_device *dev, | |||
50 | struct iw_point *data, char *extra); | 50 | struct iw_point *data, char *extra); |
51 | 51 | ||
52 | 52 | ||
53 | int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); | 53 | int cfg80211_wext_freq(struct iw_freq *freq); |
54 | 54 | ||
55 | 55 | ||
56 | extern const struct iw_handler_def cfg80211_wext_handler; | 56 | extern const struct iw_handler_def cfg80211_wext_handler; |
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 86c331a65664..c7e5c8eb4f24 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c | |||
@@ -67,7 +67,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, | |||
67 | struct iw_freq *wextfreq, char *extra) | 67 | struct iw_freq *wextfreq, char *extra) |
68 | { | 68 | { |
69 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 69 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
70 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 70 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
71 | struct ieee80211_channel *chan = NULL; | 71 | struct ieee80211_channel *chan = NULL; |
72 | int err, freq; | 72 | int err, freq; |
73 | 73 | ||
@@ -75,7 +75,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, | |||
75 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) | 75 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) |
76 | return -EINVAL; | 76 | return -EINVAL; |
77 | 77 | ||
78 | freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); | 78 | freq = cfg80211_wext_freq(wextfreq); |
79 | if (freq < 0) | 79 | if (freq < 0) |
80 | return freq; | 80 | return freq; |
81 | 81 | ||
@@ -169,7 +169,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, | |||
169 | struct iw_point *data, char *ssid) | 169 | struct iw_point *data, char *ssid) |
170 | { | 170 | { |
171 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 171 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
172 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 172 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
173 | size_t len = data->length; | 173 | size_t len = data->length; |
174 | int err; | 174 | int err; |
175 | 175 | ||
@@ -260,7 +260,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, | |||
260 | struct sockaddr *ap_addr, char *extra) | 260 | struct sockaddr *ap_addr, char *extra) |
261 | { | 261 | { |
262 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 262 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
263 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 263 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
264 | u8 *bssid = ap_addr->sa_data; | 264 | u8 *bssid = ap_addr->sa_data; |
265 | int err; | 265 | int err; |
266 | 266 | ||
@@ -333,7 +333,7 @@ int cfg80211_wext_siwgenie(struct net_device *dev, | |||
333 | struct iw_point *data, char *extra) | 333 | struct iw_point *data, char *extra) |
334 | { | 334 | { |
335 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 335 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
336 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 336 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
337 | u8 *ie = extra; | 337 | u8 *ie = extra; |
338 | int ie_len = data->length, err; | 338 | int ie_len = data->length, err; |
339 | 339 | ||
@@ -390,7 +390,7 @@ int cfg80211_wext_siwmlme(struct net_device *dev, | |||
390 | if (!wdev) | 390 | if (!wdev) |
391 | return -EOPNOTSUPP; | 391 | return -EOPNOTSUPP; |
392 | 392 | ||
393 | rdev = wiphy_to_dev(wdev->wiphy); | 393 | rdev = wiphy_to_rdev(wdev->wiphy); |
394 | 394 | ||
395 | if (wdev->iftype != NL80211_IFTYPE_STATION) | 395 | if (wdev->iftype != NL80211_IFTYPE_STATION) |
396 | return -EINVAL; | 396 | return -EINVAL; |