diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-05-22 13:58:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-22 13:58:36 -0400 |
commit | 40a10fd740a4d5a9f3da255cf8dae48c6723d1a6 (patch) | |
tree | a65eb4adca8e37ed7335345e94e36918593f7f92 /net/wireless | |
parent | 99abe65ff18b6bbac2e55524827b571c3eccfa86 (diff) | |
parent | 67af9811539be83dbdc0739215d29af23c870405 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/ap.c | 4 | ||||
-rw-r--r-- | net/wireless/chan.c | 5 | ||||
-rw-r--r-- | net/wireless/core.c | 67 | ||||
-rw-r--r-- | net/wireless/core.h | 7 | ||||
-rw-r--r-- | net/wireless/ibss.c | 2 | ||||
-rw-r--r-- | net/wireless/mesh.c | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 140 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 2 | ||||
-rw-r--r-- | net/wireless/reg.c | 3 | ||||
-rw-r--r-- | net/wireless/scan.c | 12 | ||||
-rw-r--r-- | net/wireless/sme.c | 8 | ||||
-rw-r--r-- | net/wireless/trace.h | 37 | ||||
-rw-r--r-- | net/wireless/util.c | 38 |
13 files changed, 252 insertions, 77 deletions
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 84d686e2dbd0..992b34070bcb 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -370,8 +370,8 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, | |||
370 | case NL80211_IFTYPE_AP_VLAN: | 370 | case NL80211_IFTYPE_AP_VLAN: |
371 | case NL80211_IFTYPE_WDS: | 371 | case NL80211_IFTYPE_WDS: |
372 | case NL80211_IFTYPE_P2P_DEVICE: | 372 | case NL80211_IFTYPE_P2P_DEVICE: |
373 | case NL80211_IFTYPE_UNSPECIFIED: | ||
374 | break; | 373 | break; |
374 | case NL80211_IFTYPE_UNSPECIFIED: | ||
375 | case NUM_NL80211_IFTYPES: | 375 | case NUM_NL80211_IFTYPES: |
376 | WARN_ON(1); | 376 | WARN_ON(1); |
377 | } | 377 | } |
@@ -796,8 +796,7 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy, | |||
796 | !cfg80211_go_permissive_chan(rdev, chandef->chan)) | 796 | !cfg80211_go_permissive_chan(rdev, chandef->chan)) |
797 | prohibited_flags |= IEEE80211_CHAN_NO_IR; | 797 | prohibited_flags |= IEEE80211_CHAN_NO_IR; |
798 | 798 | ||
799 | if (cfg80211_chandef_dfs_required(wiphy, chandef, | 799 | if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 && |
800 | NL80211_IFTYPE_UNSPECIFIED) > 0 && | ||
801 | cfg80211_chandef_dfs_available(wiphy, chandef)) { | 800 | cfg80211_chandef_dfs_available(wiphy, chandef)) { |
802 | /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ | 801 | /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ |
803 | prohibited_flags = IEEE80211_CHAN_DISABLED; | 802 | prohibited_flags = IEEE80211_CHAN_DISABLED; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index b3ff3697239a..d03d8bdb29ca 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -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); | ||
237 | 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; | ||
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; |
@@ -394,6 +402,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
394 | rdev->wiphy.rts_threshold = (u32) -1; | 402 | rdev->wiphy.rts_threshold = (u32) -1; |
395 | rdev->wiphy.coverage_class = 0; | 403 | rdev->wiphy.coverage_class = 0; |
396 | 404 | ||
405 | rdev->wiphy.max_num_csa_counters = 1; | ||
406 | |||
397 | return &rdev->wiphy; | 407 | return &rdev->wiphy; |
398 | } | 408 | } |
399 | EXPORT_SYMBOL(wiphy_new); | 409 | EXPORT_SYMBOL(wiphy_new); |
@@ -690,7 +700,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
690 | rtnl_lock(); | 700 | rtnl_lock(); |
691 | rdev->wiphy.registered = false; | 701 | rdev->wiphy.registered = false; |
692 | 702 | ||
693 | BUG_ON(!list_empty(&rdev->wdev_list)); | 703 | WARN_ON(!list_empty(&rdev->wdev_list)); |
694 | 704 | ||
695 | /* | 705 | /* |
696 | * First remove the hardware from everywhere, this makes | 706 | * First remove the hardware from everywhere, this makes |
@@ -792,23 +802,23 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, | |||
792 | rdev->num_running_monitor_ifaces += num; | 802 | rdev->num_running_monitor_ifaces += num; |
793 | } | 803 | } |
794 | 804 | ||
795 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | 805 | void __cfg80211_leave(struct cfg80211_registered_device *rdev, |
796 | struct wireless_dev *wdev) | 806 | struct wireless_dev *wdev) |
797 | { | 807 | { |
798 | struct net_device *dev = wdev->netdev; | 808 | struct net_device *dev = wdev->netdev; |
799 | 809 | ||
800 | ASSERT_RTNL(); | 810 | ASSERT_RTNL(); |
811 | ASSERT_WDEV_LOCK(wdev); | ||
801 | 812 | ||
802 | switch (wdev->iftype) { | 813 | switch (wdev->iftype) { |
803 | case NL80211_IFTYPE_ADHOC: | 814 | case NL80211_IFTYPE_ADHOC: |
804 | cfg80211_leave_ibss(rdev, dev, true); | 815 | __cfg80211_leave_ibss(rdev, dev, true); |
805 | break; | 816 | break; |
806 | case NL80211_IFTYPE_P2P_CLIENT: | 817 | case NL80211_IFTYPE_P2P_CLIENT: |
807 | case NL80211_IFTYPE_STATION: | 818 | case NL80211_IFTYPE_STATION: |
808 | if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) | 819 | if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) |
809 | __cfg80211_stop_sched_scan(rdev, false); | 820 | __cfg80211_stop_sched_scan(rdev, false); |
810 | 821 | ||
811 | wdev_lock(wdev); | ||
812 | #ifdef CONFIG_CFG80211_WEXT | 822 | #ifdef CONFIG_CFG80211_WEXT |
813 | kfree(wdev->wext.ie); | 823 | kfree(wdev->wext.ie); |
814 | wdev->wext.ie = NULL; | 824 | wdev->wext.ie = NULL; |
@@ -817,20 +827,49 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, | |||
817 | #endif | 827 | #endif |
818 | cfg80211_disconnect(rdev, dev, | 828 | cfg80211_disconnect(rdev, dev, |
819 | WLAN_REASON_DEAUTH_LEAVING, true); | 829 | WLAN_REASON_DEAUTH_LEAVING, true); |
820 | wdev_unlock(wdev); | ||
821 | break; | 830 | break; |
822 | case NL80211_IFTYPE_MESH_POINT: | 831 | case NL80211_IFTYPE_MESH_POINT: |
823 | cfg80211_leave_mesh(rdev, dev); | 832 | __cfg80211_leave_mesh(rdev, dev); |
824 | break; | 833 | break; |
825 | case NL80211_IFTYPE_AP: | 834 | case NL80211_IFTYPE_AP: |
826 | case NL80211_IFTYPE_P2P_GO: | 835 | case NL80211_IFTYPE_P2P_GO: |
827 | cfg80211_stop_ap(rdev, dev, true); | 836 | __cfg80211_stop_ap(rdev, dev, true); |
828 | break; | 837 | break; |
829 | default: | 838 | default: |
830 | break; | 839 | break; |
831 | } | 840 | } |
832 | } | 841 | } |
833 | 842 | ||
843 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | ||
844 | struct wireless_dev *wdev) | ||
845 | { | ||
846 | wdev_lock(wdev); | ||
847 | __cfg80211_leave(rdev, wdev); | ||
848 | wdev_unlock(wdev); | ||
849 | } | ||
850 | |||
851 | void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
852 | gfp_t gfp) | ||
853 | { | ||
854 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | ||
855 | struct cfg80211_event *ev; | ||
856 | unsigned long flags; | ||
857 | |||
858 | trace_cfg80211_stop_iface(wiphy, wdev); | ||
859 | |||
860 | ev = kzalloc(sizeof(*ev), gfp); | ||
861 | if (!ev) | ||
862 | return; | ||
863 | |||
864 | ev->type = EVENT_STOPPED; | ||
865 | |||
866 | spin_lock_irqsave(&wdev->event_lock, flags); | ||
867 | list_add_tail(&ev->list, &wdev->event_list); | ||
868 | spin_unlock_irqrestore(&wdev->event_lock, flags); | ||
869 | queue_work(cfg80211_wq, &rdev->event_work); | ||
870 | } | ||
871 | EXPORT_SYMBOL(cfg80211_stop_iface); | ||
872 | |||
834 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | 873 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, |
835 | unsigned long state, void *ptr) | 874 | unsigned long state, void *ptr) |
836 | { | 875 | { |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 681b8fa4355b..e9afbf10e756 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -185,6 +185,7 @@ enum cfg80211_event_type { | |||
185 | EVENT_ROAMED, | 185 | EVENT_ROAMED, |
186 | EVENT_DISCONNECTED, | 186 | EVENT_DISCONNECTED, |
187 | EVENT_IBSS_JOINED, | 187 | EVENT_IBSS_JOINED, |
188 | EVENT_STOPPED, | ||
188 | }; | 189 | }; |
189 | 190 | ||
190 | struct cfg80211_event { | 191 | struct cfg80211_event { |
@@ -281,6 +282,8 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
281 | struct net_device *dev, | 282 | struct net_device *dev, |
282 | struct mesh_setup *setup, | 283 | struct mesh_setup *setup, |
283 | 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); | ||
284 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 287 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
285 | struct net_device *dev); | 288 | struct net_device *dev); |
286 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | 289 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, |
@@ -288,6 +291,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
288 | struct cfg80211_chan_def *chandef); | 291 | struct cfg80211_chan_def *chandef); |
289 | 292 | ||
290 | /* AP */ | 293 | /* AP */ |
294 | int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | ||
295 | struct net_device *dev, bool notify); | ||
291 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | 296 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
292 | struct net_device *dev, bool notify); | 297 | struct net_device *dev, bool notify); |
293 | 298 | ||
@@ -441,6 +446,8 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | |||
441 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, | 446 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, |
442 | enum nl80211_iftype iftype, int num); | 447 | enum nl80211_iftype iftype, int num); |
443 | 448 | ||
449 | void __cfg80211_leave(struct cfg80211_registered_device *rdev, | ||
450 | struct wireless_dev *wdev); | ||
444 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | 451 | void cfg80211_leave(struct cfg80211_registered_device *rdev, |
445 | struct wireless_dev *wdev); | 452 | struct wireless_dev *wdev); |
446 | 453 | ||
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 6b50588b709f..8f345da3ea5f 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -420,8 +420,8 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
420 | if (len > 0 && ssid[len - 1] == '\0') | 420 | if (len > 0 && ssid[len - 1] == '\0') |
421 | len--; | 421 | len--; |
422 | 422 | ||
423 | memcpy(wdev->ssid, ssid, len); | ||
423 | wdev->wext.ibss.ssid = wdev->ssid; | 424 | wdev->wext.ibss.ssid = wdev->ssid; |
424 | memcpy(wdev->wext.ibss.ssid, ssid, len); | ||
425 | wdev->wext.ibss.ssid_len = len; | 425 | wdev->wext.ibss.ssid_len = len; |
426 | 426 | ||
427 | wdev_lock(wdev); | 427 | wdev_lock(wdev); |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 3ddfb7cd335e..092300b30c37 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -238,8 +238,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | 240 | ||
241 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 241 | int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
242 | struct net_device *dev) | 242 | struct net_device *dev) |
243 | { | 243 | { |
244 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 244 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
245 | int err; | 245 | int err; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0f1b18f209d6..62bdb1adaa4d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -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 }, |
@@ -386,6 +386,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
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 }, | 388 | [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, |
389 | [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, | ||
389 | }; | 390 | }; |
390 | 391 | ||
391 | /* policy for the key attributes */ | 392 | /* policy for the key attributes */ |
@@ -970,8 +971,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy, | |||
970 | c->max_interfaces)) | 971 | c->max_interfaces)) |
971 | goto nla_put_failure; | 972 | goto nla_put_failure; |
972 | if (large && | 973 | if (large && |
973 | nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, | 974 | (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, |
974 | 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))) | ||
975 | goto nla_put_failure; | 978 | goto nla_put_failure; |
976 | 979 | ||
977 | nla_nest_end(msg, nl_combi); | 980 | nla_nest_end(msg, nl_combi); |
@@ -1667,6 +1670,13 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1667 | } | 1670 | } |
1668 | nla_nest_end(msg, nested); | 1671 | nla_nest_end(msg, nested); |
1669 | } | 1672 | } |
1673 | state->split_start++; | ||
1674 | break; | ||
1675 | case 12: | ||
1676 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH && | ||
1677 | nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS, | ||
1678 | rdev->wiphy.max_num_csa_counters)) | ||
1679 | goto nla_put_failure; | ||
1670 | 1680 | ||
1671 | /* done */ | 1681 | /* done */ |
1672 | state->split_start = 0; | 1682 | state->split_start = 0; |
@@ -3640,6 +3650,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3640 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, | 3650 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, |
3641 | sinfo->tx_failed)) | 3651 | sinfo->tx_failed)) |
3642 | goto nla_put_failure; | 3652 | goto nla_put_failure; |
3653 | if ((sinfo->filled & STATION_INFO_EXPECTED_THROUGHPUT) && | ||
3654 | nla_put_u32(msg, NL80211_STA_INFO_EXPECTED_THROUGHPUT, | ||
3655 | sinfo->expected_throughput)) | ||
3656 | goto nla_put_failure; | ||
3643 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && | 3657 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && |
3644 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, | 3658 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, |
3645 | sinfo->beacon_loss_count)) | 3659 | sinfo->beacon_loss_count)) |
@@ -5820,7 +5834,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, | |||
5820 | return -EBUSY; | 5834 | return -EBUSY; |
5821 | 5835 | ||
5822 | err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, | 5836 | err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, |
5823 | NL80211_IFTYPE_UNSPECIFIED); | 5837 | wdev->iftype); |
5824 | if (err < 0) | 5838 | if (err < 0) |
5825 | return err; | 5839 | return err; |
5826 | 5840 | ||
@@ -5861,6 +5875,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5861 | u8 radar_detect_width = 0; | 5875 | u8 radar_detect_width = 0; |
5862 | int err; | 5876 | int err; |
5863 | bool need_new_beacon = false; | 5877 | bool need_new_beacon = false; |
5878 | int len, i; | ||
5864 | 5879 | ||
5865 | if (!rdev->ops->channel_switch || | 5880 | if (!rdev->ops->channel_switch || |
5866 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | 5881 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) |
@@ -5919,26 +5934,55 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5919 | if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) | 5934 | if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) |
5920 | return -EINVAL; | 5935 | return -EINVAL; |
5921 | 5936 | ||
5922 | params.counter_offset_beacon = | 5937 | len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); |
5923 | nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); | 5938 | if (!len || (len % sizeof(u16))) |
5924 | if (params.counter_offset_beacon >= params.beacon_csa.tail_len) | ||
5925 | return -EINVAL; | 5939 | return -EINVAL; |
5926 | 5940 | ||
5927 | /* sanity check - counters should be the same */ | 5941 | params.n_counter_offsets_beacon = len / sizeof(u16); |
5928 | if (params.beacon_csa.tail[params.counter_offset_beacon] != | 5942 | if (rdev->wiphy.max_num_csa_counters && |
5929 | params.count) | 5943 | (params.n_counter_offsets_beacon > |
5944 | rdev->wiphy.max_num_csa_counters)) | ||
5930 | return -EINVAL; | 5945 | return -EINVAL; |
5931 | 5946 | ||
5947 | params.counter_offsets_beacon = | ||
5948 | nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); | ||
5949 | |||
5950 | /* sanity checks - counters should fit and be the same */ | ||
5951 | for (i = 0; i < params.n_counter_offsets_beacon; i++) { | ||
5952 | u16 offset = params.counter_offsets_beacon[i]; | ||
5953 | |||
5954 | if (offset >= params.beacon_csa.tail_len) | ||
5955 | return -EINVAL; | ||
5956 | |||
5957 | if (params.beacon_csa.tail[offset] != params.count) | ||
5958 | return -EINVAL; | ||
5959 | } | ||
5960 | |||
5932 | if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { | 5961 | if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { |
5933 | params.counter_offset_presp = | 5962 | len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); |
5934 | nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); | 5963 | if (!len || (len % sizeof(u16))) |
5935 | if (params.counter_offset_presp >= | ||
5936 | params.beacon_csa.probe_resp_len) | ||
5937 | return -EINVAL; | 5964 | return -EINVAL; |
5938 | 5965 | ||
5939 | if (params.beacon_csa.probe_resp[params.counter_offset_presp] != | 5966 | params.n_counter_offsets_presp = len / sizeof(u16); |
5940 | params.count) | 5967 | if (rdev->wiphy.max_num_csa_counters && |
5968 | (params.n_counter_offsets_beacon > | ||
5969 | rdev->wiphy.max_num_csa_counters)) | ||
5941 | return -EINVAL; | 5970 | return -EINVAL; |
5971 | |||
5972 | params.counter_offsets_presp = | ||
5973 | nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); | ||
5974 | |||
5975 | /* sanity checks - counters should fit and be the same */ | ||
5976 | for (i = 0; i < params.n_counter_offsets_presp; i++) { | ||
5977 | u16 offset = params.counter_offsets_presp[i]; | ||
5978 | |||
5979 | if (offset >= params.beacon_csa.probe_resp_len) | ||
5980 | return -EINVAL; | ||
5981 | |||
5982 | if (params.beacon_csa.probe_resp[offset] != | ||
5983 | params.count) | ||
5984 | return -EINVAL; | ||
5985 | } | ||
5942 | } | 5986 | } |
5943 | 5987 | ||
5944 | skip_beacons: | 5988 | skip_beacons: |
@@ -7784,6 +7828,27 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7784 | if (!chandef.chan && params.offchan) | 7828 | if (!chandef.chan && params.offchan) |
7785 | return -EINVAL; | 7829 | return -EINVAL; |
7786 | 7830 | ||
7831 | params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); | ||
7832 | params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); | ||
7833 | |||
7834 | if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) { | ||
7835 | int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); | ||
7836 | int i; | ||
7837 | |||
7838 | if (len % sizeof(u16)) | ||
7839 | return -EINVAL; | ||
7840 | |||
7841 | params.n_csa_offsets = len / sizeof(u16); | ||
7842 | params.csa_offsets = | ||
7843 | nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); | ||
7844 | |||
7845 | /* check that all the offsets fit the frame */ | ||
7846 | for (i = 0; i < params.n_csa_offsets; i++) { | ||
7847 | if (params.csa_offsets[i] >= params.len) | ||
7848 | return -EINVAL; | ||
7849 | } | ||
7850 | } | ||
7851 | |||
7787 | if (!params.dont_wait_for_ack) { | 7852 | if (!params.dont_wait_for_ack) { |
7788 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 7853 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7789 | if (!msg) | 7854 | if (!msg) |
@@ -7797,8 +7862,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7797 | } | 7862 | } |
7798 | } | 7863 | } |
7799 | 7864 | ||
7800 | params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); | ||
7801 | params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); | ||
7802 | params.chan = chandef.chan; | 7865 | params.chan = chandef.chan; |
7803 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie); | 7866 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie); |
7804 | if (err) | 7867 | if (err) |
@@ -8495,6 +8558,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
8495 | 8558 | ||
8496 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], | 8559 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], |
8497 | rem) { | 8560 | rem) { |
8561 | u8 *mask_pat; | ||
8562 | |||
8498 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), | 8563 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), |
8499 | nla_len(pat), NULL); | 8564 | nla_len(pat), NULL); |
8500 | err = -EINVAL; | 8565 | err = -EINVAL; |
@@ -8518,19 +8583,18 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
8518 | goto error; | 8583 | goto error; |
8519 | new_triggers.patterns[i].pkt_offset = pkt_offset; | 8584 | new_triggers.patterns[i].pkt_offset = pkt_offset; |
8520 | 8585 | ||
8521 | new_triggers.patterns[i].mask = | 8586 | mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); |
8522 | kmalloc(mask_len + pat_len, GFP_KERNEL); | 8587 | if (!mask_pat) { |
8523 | if (!new_triggers.patterns[i].mask) { | ||
8524 | err = -ENOMEM; | 8588 | err = -ENOMEM; |
8525 | goto error; | 8589 | goto error; |
8526 | } | 8590 | } |
8527 | new_triggers.patterns[i].pattern = | 8591 | new_triggers.patterns[i].mask = mask_pat; |
8528 | new_triggers.patterns[i].mask + mask_len; | 8592 | memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), |
8529 | memcpy(new_triggers.patterns[i].mask, | ||
8530 | nla_data(pat_tb[NL80211_PKTPAT_MASK]), | ||
8531 | mask_len); | 8593 | mask_len); |
8594 | mask_pat += mask_len; | ||
8595 | new_triggers.patterns[i].pattern = mask_pat; | ||
8532 | new_triggers.patterns[i].pattern_len = pat_len; | 8596 | new_triggers.patterns[i].pattern_len = pat_len; |
8533 | memcpy(new_triggers.patterns[i].pattern, | 8597 | memcpy(mask_pat, |
8534 | nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), | 8598 | nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), |
8535 | pat_len); | 8599 | pat_len); |
8536 | i++; | 8600 | i++; |
@@ -8722,6 +8786,8 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, | |||
8722 | 8786 | ||
8723 | nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], | 8787 | nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], |
8724 | rem) { | 8788 | rem) { |
8789 | u8 *mask_pat; | ||
8790 | |||
8725 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), | 8791 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), |
8726 | nla_len(pat), NULL); | 8792 | nla_len(pat), NULL); |
8727 | if (!pat_tb[NL80211_PKTPAT_MASK] || | 8793 | if (!pat_tb[NL80211_PKTPAT_MASK] || |
@@ -8743,17 +8809,19 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, | |||
8743 | return -EINVAL; | 8809 | return -EINVAL; |
8744 | new_rule->patterns[i].pkt_offset = pkt_offset; | 8810 | new_rule->patterns[i].pkt_offset = pkt_offset; |
8745 | 8811 | ||
8746 | new_rule->patterns[i].mask = | 8812 | mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); |
8747 | kmalloc(mask_len + pat_len, GFP_KERNEL); | 8813 | if (!mask_pat) |
8748 | if (!new_rule->patterns[i].mask) | ||
8749 | return -ENOMEM; | 8814 | return -ENOMEM; |
8750 | new_rule->patterns[i].pattern = | 8815 | |
8751 | new_rule->patterns[i].mask + mask_len; | 8816 | new_rule->patterns[i].mask = mask_pat; |
8752 | memcpy(new_rule->patterns[i].mask, | 8817 | memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), |
8753 | nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len); | 8818 | mask_len); |
8819 | |||
8820 | mask_pat += mask_len; | ||
8821 | new_rule->patterns[i].pattern = mask_pat; | ||
8754 | new_rule->patterns[i].pattern_len = pat_len; | 8822 | new_rule->patterns[i].pattern_len = pat_len; |
8755 | memcpy(new_rule->patterns[i].pattern, | 8823 | memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), |
8756 | nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len); | 8824 | pat_len); |
8757 | i++; | 8825 | i++; |
8758 | } | 8826 | } |
8759 | 8827 | ||
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 00cdf73ba6c4..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; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index e78f532aaa5b..558b0e3a02d8 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1876,7 +1876,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1876 | case NL80211_REGDOM_SET_BY_USER: | 1876 | case NL80211_REGDOM_SET_BY_USER: |
1877 | treatment = reg_process_hint_user(reg_request); | 1877 | treatment = reg_process_hint_user(reg_request); |
1878 | if (treatment == REG_REQ_IGNORE || | 1878 | if (treatment == REG_REQ_IGNORE || |
1879 | treatment == REG_REQ_ALREADY_SET) | 1879 | treatment == REG_REQ_ALREADY_SET || |
1880 | treatment == REG_REQ_USER_HINT_HANDLED) | ||
1880 | return; | 1881 | return; |
1881 | queue_delayed_work(system_power_efficient_wq, | 1882 | queue_delayed_work(system_power_efficient_wq, |
1882 | ®_timeout, msecs_to_jiffies(3142)); | 1883 | ®_timeout, msecs_to_jiffies(3142)); |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index e7329bb6a323..0798c62e6085 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -891,6 +891,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
891 | struct cfg80211_bss_ies *ies; | 891 | struct cfg80211_bss_ies *ies; |
892 | struct ieee80211_channel *channel; | 892 | struct ieee80211_channel *channel; |
893 | struct cfg80211_internal_bss tmp = {}, *res; | 893 | struct cfg80211_internal_bss tmp = {}, *res; |
894 | bool signal_valid; | ||
894 | 895 | ||
895 | if (WARN_ON(!wiphy)) | 896 | if (WARN_ON(!wiphy)) |
896 | return NULL; | 897 | return NULL; |
@@ -927,8 +928,9 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
927 | rcu_assign_pointer(tmp.pub.beacon_ies, ies); | 928 | rcu_assign_pointer(tmp.pub.beacon_ies, ies); |
928 | rcu_assign_pointer(tmp.pub.ies, ies); | 929 | rcu_assign_pointer(tmp.pub.ies, ies); |
929 | 930 | ||
930 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, | 931 | signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= |
931 | rx_channel == channel); | 932 | wiphy->max_adj_channel_rssi_comp; |
933 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); | ||
932 | if (!res) | 934 | if (!res) |
933 | return NULL; | 935 | return NULL; |
934 | 936 | ||
@@ -952,6 +954,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
952 | struct cfg80211_internal_bss tmp = {}, *res; | 954 | struct cfg80211_internal_bss tmp = {}, *res; |
953 | struct cfg80211_bss_ies *ies; | 955 | struct cfg80211_bss_ies *ies; |
954 | struct ieee80211_channel *channel; | 956 | struct ieee80211_channel *channel; |
957 | bool signal_valid; | ||
955 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 958 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
956 | u.probe_resp.variable); | 959 | u.probe_resp.variable); |
957 | 960 | ||
@@ -999,8 +1002,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
999 | 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); |
1000 | 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); |
1001 | 1004 | ||
1002 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, | 1005 | signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= |
1003 | rx_channel == channel); | 1006 | wiphy->max_adj_channel_rssi_comp; |
1007 | res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); | ||
1004 | if (!res) | 1008 | if (!res) |
1005 | return NULL; | 1009 | return NULL; |
1006 | 1010 | ||
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 0c0844b585d1..8bbeeb302216 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -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; |
@@ -877,7 +879,7 @@ 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_rdev(wdev->wiphy); | 885 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index f3c13ff4d04c..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, |
@@ -2636,6 +2640,21 @@ TRACE_EVENT(cfg80211_ft_event, | |||
2636 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) | 2640 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) |
2637 | ); | 2641 | ); |
2638 | 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 | |||
2639 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ | 2658 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ |
2640 | 2659 | ||
2641 | #undef TRACE_INCLUDE_PATH | 2660 | #undef TRACE_INCLUDE_PATH |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 7c47fa07b276..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; |
@@ -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 | ||
@@ -1271,10 +1275,20 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, | |||
1271 | void *data), | 1275 | void *data), |
1272 | void *data) | 1276 | void *data) |
1273 | { | 1277 | { |
1278 | const struct ieee80211_regdomain *regdom; | ||
1279 | enum nl80211_dfs_regions region = 0; | ||
1274 | int i, j, iftype; | 1280 | int i, j, iftype; |
1275 | int num_interfaces = 0; | 1281 | int num_interfaces = 0; |
1276 | u32 used_iftypes = 0; | 1282 | u32 used_iftypes = 0; |
1277 | 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 | |||
1278 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { | 1292 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { |
1279 | num_interfaces += iftype_num[iftype]; | 1293 | num_interfaces += iftype_num[iftype]; |
1280 | if (iftype_num[iftype] > 0 && | 1294 | if (iftype_num[iftype] > 0 && |
@@ -1315,6 +1329,10 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, | |||
1315 | if (radar_detect != (c->radar_detect_widths & radar_detect)) | 1329 | if (radar_detect != (c->radar_detect_widths & radar_detect)) |
1316 | goto cont; | 1330 | goto cont; |
1317 | 1331 | ||
1332 | if (radar_detect && c->radar_detect_regions && | ||
1333 | !(c->radar_detect_regions & BIT(region))) | ||
1334 | goto cont; | ||
1335 | |||
1318 | /* Finally check that all iftypes that we're currently | 1336 | /* Finally check that all iftypes that we're currently |
1319 | * using are actually part of this combination. If they | 1337 | * using are actually part of this combination. If they |
1320 | * aren't then we can't use this combination and have | 1338 | * aren't then we can't use this combination and have |
@@ -1528,6 +1546,24 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy) | |||
1528 | } | 1546 | } |
1529 | EXPORT_SYMBOL(ieee80211_get_num_supported_channels); | 1547 | EXPORT_SYMBOL(ieee80211_get_num_supported_channels); |
1530 | 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 | |||
1531 | /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ | 1567 | /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ |
1532 | /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ | 1568 | /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ |
1533 | const unsigned char rfc1042_header[] __aligned(2) = | 1569 | const unsigned char rfc1042_header[] __aligned(2) = |