aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-05-16 14:55:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-16 19:32:19 -0400
commite00cf3b9eb7839b952e434a75bff6b99e47337ac (patch)
treeef583ab8ac09bf703026650d4bc7777e6a3864d3 /net/wireless
parent1a8218e96271790a07dd7065a2ef173e0f67e328 (diff)
parent3b8ab88acaceb505aa06ef3bbf3a73b92470ae78 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-agn-tx.c net/mac80211/sta_info.h
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c89
-rw-r--r--net/wireless/core.h33
-rw-r--r--net/wireless/lib80211_crypt_wep.c3
-rw-r--r--net/wireless/mlme.c10
-rw-r--r--net/wireless/nl80211.c670
-rw-r--r--net/wireless/nl80211.h4
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/scan.c77
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c126
10 files changed, 953 insertions, 63 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index bbf1fa11107a..c22ef3492ee6 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -370,7 +370,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
370 spin_lock_init(&rdev->bss_lock); 370 spin_lock_init(&rdev->bss_lock);
371 INIT_LIST_HEAD(&rdev->bss_list); 371 INIT_LIST_HEAD(&rdev->bss_list);
372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
373 373 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
374#ifdef CONFIG_CFG80211_WEXT 374#ifdef CONFIG_CFG80211_WEXT
375 rdev->wiphy.wext = &cfg80211_wext_handler; 375 rdev->wiphy.wext = &cfg80211_wext_handler;
376#endif 376#endif
@@ -416,6 +416,67 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
416} 416}
417EXPORT_SYMBOL(wiphy_new); 417EXPORT_SYMBOL(wiphy_new);
418 418
419static int wiphy_verify_combinations(struct wiphy *wiphy)
420{
421 const struct ieee80211_iface_combination *c;
422 int i, j;
423
424 /* If we have combinations enforce them */
425 if (wiphy->n_iface_combinations)
426 wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS;
427
428 for (i = 0; i < wiphy->n_iface_combinations; i++) {
429 u32 cnt = 0;
430 u16 all_iftypes = 0;
431
432 c = &wiphy->iface_combinations[i];
433
434 /* Combinations with just one interface aren't real */
435 if (WARN_ON(c->max_interfaces < 2))
436 return -EINVAL;
437
438 /* Need at least one channel */
439 if (WARN_ON(!c->num_different_channels))
440 return -EINVAL;
441
442 if (WARN_ON(!c->n_limits))
443 return -EINVAL;
444
445 for (j = 0; j < c->n_limits; j++) {
446 u16 types = c->limits[j].types;
447
448 /*
449 * interface types shouldn't overlap, this is
450 * used in cfg80211_can_change_interface()
451 */
452 if (WARN_ON(types & all_iftypes))
453 return -EINVAL;
454 all_iftypes |= types;
455
456 if (WARN_ON(!c->limits[j].max))
457 return -EINVAL;
458
459 /* Shouldn't list software iftypes in combinations! */
460 if (WARN_ON(wiphy->software_iftypes & types))
461 return -EINVAL;
462
463 cnt += c->limits[j].max;
464 /*
465 * Don't advertise an unsupported type
466 * in a combination.
467 */
468 if (WARN_ON((wiphy->interface_modes & types) != types))
469 return -EINVAL;
470 }
471
472 /* You can't even choose that many! */
473 if (WARN_ON(cnt < c->max_interfaces))
474 return -EINVAL;
475 }
476
477 return 0;
478}
479
419int wiphy_register(struct wiphy *wiphy) 480int wiphy_register(struct wiphy *wiphy)
420{ 481{
421 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 482 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -444,6 +505,10 @@ int wiphy_register(struct wiphy *wiphy)
444 if (WARN_ON(ifmodes != wiphy->interface_modes)) 505 if (WARN_ON(ifmodes != wiphy->interface_modes))
445 wiphy->interface_modes = ifmodes; 506 wiphy->interface_modes = ifmodes;
446 507
508 res = wiphy_verify_combinations(wiphy);
509 if (res)
510 return res;
511
447 /* sanity check supported bands/channels */ 512 /* sanity check supported bands/channels */
448 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 513 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
449 sband = wiphy->bands[band]; 514 sband = wiphy->bands[band];
@@ -493,6 +558,13 @@ int wiphy_register(struct wiphy *wiphy)
493 return -EINVAL; 558 return -EINVAL;
494 } 559 }
495 560
561 if (rdev->wiphy.wowlan.n_patterns) {
562 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
563 rdev->wiphy.wowlan.pattern_min_len >
564 rdev->wiphy.wowlan.pattern_max_len))
565 return -EINVAL;
566 }
567
496 /* check and set up bitrates */ 568 /* check and set up bitrates */
497 ieee80211_set_bitrate_flags(wiphy); 569 ieee80211_set_bitrate_flags(wiphy);
498 570
@@ -631,6 +703,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
631 mutex_destroy(&rdev->devlist_mtx); 703 mutex_destroy(&rdev->devlist_mtx);
632 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 704 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
633 cfg80211_put_bss(&scan->pub); 705 cfg80211_put_bss(&scan->pub);
706 cfg80211_rdev_free_wowlan(rdev);
634 kfree(rdev); 707 kfree(rdev);
635} 708}
636 709
@@ -664,6 +737,11 @@ static void wdev_cleanup_work(struct work_struct *work)
664 ___cfg80211_scan_done(rdev, true); 737 ___cfg80211_scan_done(rdev, true);
665 } 738 }
666 739
740 if (WARN_ON(rdev->sched_scan_req &&
741 rdev->sched_scan_req->dev == wdev->netdev)) {
742 __cfg80211_stop_sched_scan(rdev, false);
743 }
744
667 cfg80211_unlock_rdev(rdev); 745 cfg80211_unlock_rdev(rdev);
668 746
669 mutex_lock(&rdev->devlist_mtx); 747 mutex_lock(&rdev->devlist_mtx);
@@ -685,6 +763,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
685 struct net_device *dev = ndev; 763 struct net_device *dev = ndev;
686 struct wireless_dev *wdev = dev->ieee80211_ptr; 764 struct wireless_dev *wdev = dev->ieee80211_ptr;
687 struct cfg80211_registered_device *rdev; 765 struct cfg80211_registered_device *rdev;
766 int ret;
688 767
689 if (!wdev) 768 if (!wdev)
690 return NOTIFY_DONE; 769 return NOTIFY_DONE;
@@ -751,6 +830,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
751 break; 830 break;
752 case NL80211_IFTYPE_P2P_CLIENT: 831 case NL80211_IFTYPE_P2P_CLIENT:
753 case NL80211_IFTYPE_STATION: 832 case NL80211_IFTYPE_STATION:
833 cfg80211_lock_rdev(rdev);
834 __cfg80211_stop_sched_scan(rdev, false);
835 cfg80211_unlock_rdev(rdev);
836
754 wdev_lock(wdev); 837 wdev_lock(wdev);
755#ifdef CONFIG_CFG80211_WEXT 838#ifdef CONFIG_CFG80211_WEXT
756 kfree(wdev->wext.ie); 839 kfree(wdev->wext.ie);
@@ -769,6 +852,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
769 default: 852 default:
770 break; 853 break;
771 } 854 }
855 wdev->beacon_interval = 0;
772 break; 856 break;
773 case NETDEV_DOWN: 857 case NETDEV_DOWN:
774 dev_hold(dev); 858 dev_hold(dev);
@@ -875,6 +959,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
875 return notifier_from_errno(-EOPNOTSUPP); 959 return notifier_from_errno(-EOPNOTSUPP);
876 if (rfkill_blocked(rdev->rfkill)) 960 if (rfkill_blocked(rdev->rfkill))
877 return notifier_from_errno(-ERFKILL); 961 return notifier_from_errno(-ERFKILL);
962 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
963 if (ret)
964 return notifier_from_errno(ret);
878 break; 965 break;
879 } 966 }
880 967
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 26a0a084e16b..bf0fb40e3c8b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -60,8 +60,10 @@ struct cfg80211_registered_device {
60 struct rb_root bss_tree; 60 struct rb_root bss_tree;
61 u32 bss_generation; 61 u32 bss_generation;
62 struct cfg80211_scan_request *scan_req; /* protected by RTNL */ 62 struct cfg80211_scan_request *scan_req; /* protected by RTNL */
63 struct cfg80211_sched_scan_request *sched_scan_req;
63 unsigned long suspend_at; 64 unsigned long suspend_at;
64 struct work_struct scan_done_wk; 65 struct work_struct scan_done_wk;
66 struct work_struct sched_scan_results_wk;
65 67
66#ifdef CONFIG_NL80211_TESTMODE 68#ifdef CONFIG_NL80211_TESTMODE
67 struct genl_info *testmode_info; 69 struct genl_info *testmode_info;
@@ -70,6 +72,8 @@ struct cfg80211_registered_device {
70 struct work_struct conn_work; 72 struct work_struct conn_work;
71 struct work_struct event_work; 73 struct work_struct event_work;
72 74
75 struct cfg80211_wowlan *wowlan;
76
73 /* must be last because of the way we do wiphy_priv(), 77 /* must be last because of the way we do wiphy_priv(),
74 * and it should at least be aligned to NETDEV_ALIGN */ 78 * and it should at least be aligned to NETDEV_ALIGN */
75 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); 79 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -89,6 +93,18 @@ bool wiphy_idx_valid(int wiphy_idx)
89 return wiphy_idx >= 0; 93 return wiphy_idx >= 0;
90} 94}
91 95
96static inline void
97cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
98{
99 int i;
100
101 if (!rdev->wowlan)
102 return;
103 for (i = 0; i < rdev->wowlan->n_patterns; i++)
104 kfree(rdev->wowlan->patterns[i].mask);
105 kfree(rdev->wowlan->patterns);
106 kfree(rdev->wowlan);
107}
92 108
93extern struct workqueue_struct *cfg80211_wq; 109extern struct workqueue_struct *cfg80211_wq;
94extern struct mutex cfg80211_mutex; 110extern struct mutex cfg80211_mutex;
@@ -397,12 +413,26 @@ void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
397void cfg80211_sme_disassoc(struct net_device *dev, int idx); 413void cfg80211_sme_disassoc(struct net_device *dev, int idx);
398void __cfg80211_scan_done(struct work_struct *wk); 414void __cfg80211_scan_done(struct work_struct *wk);
399void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak); 415void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
416void __cfg80211_sched_scan_results(struct work_struct *wk);
417int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
418 bool driver_initiated);
400void cfg80211_upload_connect_keys(struct wireless_dev *wdev); 419void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
401int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 420int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
402 struct net_device *dev, enum nl80211_iftype ntype, 421 struct net_device *dev, enum nl80211_iftype ntype,
403 u32 *flags, struct vif_params *params); 422 u32 *flags, struct vif_params *params);
404void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); 423void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
405 424
425int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
426 struct wireless_dev *wdev,
427 enum nl80211_iftype iftype);
428
429static inline int
430cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
431 enum nl80211_iftype iftype)
432{
433 return cfg80211_can_change_interface(rdev, NULL, iftype);
434}
435
406struct ieee80211_channel * 436struct ieee80211_channel *
407rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 437rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
408 int freq, enum nl80211_channel_type channel_type); 438 int freq, enum nl80211_channel_type channel_type);
@@ -412,6 +442,9 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
412 442
413u16 cfg80211_calculate_bitrate(struct rate_info *rate); 443u16 cfg80211_calculate_bitrate(struct rate_info *rate);
414 444
445int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
446 u32 beacon_int);
447
415#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 448#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
416#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) 449#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
417#else 450#else
diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c
index e2e88878ba35..2f265e033ae2 100644
--- a/net/wireless/lib80211_crypt_wep.c
+++ b/net/wireless/lib80211_crypt_wep.c
@@ -96,13 +96,12 @@ static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
96 u8 *key, int keylen, void *priv) 96 u8 *key, int keylen, void *priv)
97{ 97{
98 struct lib80211_wep_data *wep = priv; 98 struct lib80211_wep_data *wep = priv;
99 u32 klen, len; 99 u32 klen;
100 u8 *pos; 100 u8 *pos;
101 101
102 if (skb_headroom(skb) < 4 || skb->len < hdr_len) 102 if (skb_headroom(skb) < 4 || skb->len < hdr_len)
103 return -1; 103 return -1;
104 104
105 len = skb->len - hdr_len;
106 pos = skb_push(skb, 4); 105 pos = skb_push(skb, 4);
107 memmove(pos, pos + 4, hdr_len); 106 memmove(pos, pos + 4, hdr_len);
108 pos += hdr_len; 107 pos += hdr_len;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 16881fea4ce6..493b939970cd 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -963,6 +963,16 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
963 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) 963 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
964 err = -EINVAL; 964 err = -EINVAL;
965 break; 965 break;
966 case NL80211_IFTYPE_MESH_POINT:
967 if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) {
968 err = -EINVAL;
969 break;
970 }
971 /*
972 * check for mesh DA must be done by driver as
973 * cfg80211 doesn't track the stations
974 */
975 break;
966 default: 976 default:
967 err = -EOPNOTSUPP; 977 err = -EOPNOTSUPP;
968 break; 978 break;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0efa7fd01150..2222ce08ee91 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -173,6 +173,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
173 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, 173 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
174 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 174 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
175 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, 175 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
176 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
177 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
176}; 179};
177 180
178/* policy for the key attributes */ 181/* policy for the key attributes */
@@ -194,6 +197,15 @@ nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
194 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG }, 197 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
195}; 198};
196 199
200/* policy for WoWLAN attributes */
201static const struct nla_policy
202nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
203 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
204 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
205 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
206 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
207};
208
197/* ifidx get helper */ 209/* ifidx get helper */
198static int nl80211_get_ifidx(struct netlink_callback *cb) 210static int nl80211_get_ifidx(struct netlink_callback *cb)
199{ 211{
@@ -534,6 +546,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
534 case NL80211_IFTYPE_AP: 546 case NL80211_IFTYPE_AP:
535 case NL80211_IFTYPE_AP_VLAN: 547 case NL80211_IFTYPE_AP_VLAN:
536 case NL80211_IFTYPE_P2P_GO: 548 case NL80211_IFTYPE_P2P_GO:
549 case NL80211_IFTYPE_MESH_POINT:
537 break; 550 break;
538 case NL80211_IFTYPE_ADHOC: 551 case NL80211_IFTYPE_ADHOC:
539 if (!wdev->current_bss) 552 if (!wdev->current_bss)
@@ -551,6 +564,88 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
551 return 0; 564 return 0;
552} 565}
553 566
567static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
568{
569 struct nlattr *nl_modes = nla_nest_start(msg, attr);
570 int i;
571
572 if (!nl_modes)
573 goto nla_put_failure;
574
575 i = 0;
576 while (ifmodes) {
577 if (ifmodes & 1)
578 NLA_PUT_FLAG(msg, i);
579 ifmodes >>= 1;
580 i++;
581 }
582
583 nla_nest_end(msg, nl_modes);
584 return 0;
585
586nla_put_failure:
587 return -ENOBUFS;
588}
589
590static int nl80211_put_iface_combinations(struct wiphy *wiphy,
591 struct sk_buff *msg)
592{
593 struct nlattr *nl_combis;
594 int i, j;
595
596 nl_combis = nla_nest_start(msg,
597 NL80211_ATTR_INTERFACE_COMBINATIONS);
598 if (!nl_combis)
599 goto nla_put_failure;
600
601 for (i = 0; i < wiphy->n_iface_combinations; i++) {
602 const struct ieee80211_iface_combination *c;
603 struct nlattr *nl_combi, *nl_limits;
604
605 c = &wiphy->iface_combinations[i];
606
607 nl_combi = nla_nest_start(msg, i + 1);
608 if (!nl_combi)
609 goto nla_put_failure;
610
611 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
612 if (!nl_limits)
613 goto nla_put_failure;
614
615 for (j = 0; j < c->n_limits; j++) {
616 struct nlattr *nl_limit;
617
618 nl_limit = nla_nest_start(msg, j + 1);
619 if (!nl_limit)
620 goto nla_put_failure;
621 NLA_PUT_U32(msg, NL80211_IFACE_LIMIT_MAX,
622 c->limits[j].max);
623 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
624 c->limits[j].types))
625 goto nla_put_failure;
626 nla_nest_end(msg, nl_limit);
627 }
628
629 nla_nest_end(msg, nl_limits);
630
631 if (c->beacon_int_infra_match)
632 NLA_PUT_FLAG(msg,
633 NL80211_IFACE_COMB_STA_AP_BI_MATCH);
634 NLA_PUT_U32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
635 c->num_different_channels);
636 NLA_PUT_U32(msg, NL80211_IFACE_COMB_MAXNUM,
637 c->max_interfaces);
638
639 nla_nest_end(msg, nl_combi);
640 }
641
642 nla_nest_end(msg, nl_combis);
643
644 return 0;
645nla_put_failure:
646 return -ENOBUFS;
647}
648
554static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 649static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
555 struct cfg80211_registered_device *dev) 650 struct cfg80211_registered_device *dev)
556{ 651{
@@ -558,13 +653,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
558 struct nlattr *nl_bands, *nl_band; 653 struct nlattr *nl_bands, *nl_band;
559 struct nlattr *nl_freqs, *nl_freq; 654 struct nlattr *nl_freqs, *nl_freq;
560 struct nlattr *nl_rates, *nl_rate; 655 struct nlattr *nl_rates, *nl_rate;
561 struct nlattr *nl_modes;
562 struct nlattr *nl_cmds; 656 struct nlattr *nl_cmds;
563 enum ieee80211_band band; 657 enum ieee80211_band band;
564 struct ieee80211_channel *chan; 658 struct ieee80211_channel *chan;
565 struct ieee80211_rate *rate; 659 struct ieee80211_rate *rate;
566 int i; 660 int i;
567 u16 ifmodes = dev->wiphy.interface_modes;
568 const struct ieee80211_txrx_stypes *mgmt_stypes = 661 const struct ieee80211_txrx_stypes *mgmt_stypes =
569 dev->wiphy.mgmt_stypes; 662 dev->wiphy.mgmt_stypes;
570 663
@@ -624,20 +717,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
624 } 717 }
625 } 718 }
626 719
627 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 720 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
628 if (!nl_modes) 721 dev->wiphy.interface_modes))
629 goto nla_put_failure; 722 goto nla_put_failure;
630 723
631 i = 0;
632 while (ifmodes) {
633 if (ifmodes & 1)
634 NLA_PUT_FLAG(msg, i);
635 ifmodes >>= 1;
636 i++;
637 }
638
639 nla_nest_end(msg, nl_modes);
640
641 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 724 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
642 if (!nl_bands) 725 if (!nl_bands)
643 goto nla_put_failure; 726 goto nla_put_failure;
@@ -749,6 +832,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
749 } 832 }
750 CMD(set_channel, SET_CHANNEL); 833 CMD(set_channel, SET_CHANNEL);
751 CMD(set_wds_peer, SET_WDS_PEER); 834 CMD(set_wds_peer, SET_WDS_PEER);
835 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
836 CMD(sched_scan_start, START_SCHED_SCAN);
752 837
753#undef CMD 838#undef CMD
754 839
@@ -821,6 +906,42 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
821 nla_nest_end(msg, nl_ifs); 906 nla_nest_end(msg, nl_ifs);
822 } 907 }
823 908
909 if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) {
910 struct nlattr *nl_wowlan;
911
912 nl_wowlan = nla_nest_start(msg,
913 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
914 if (!nl_wowlan)
915 goto nla_put_failure;
916
917 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY)
918 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
919 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT)
920 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
921 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
922 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
923 if (dev->wiphy.wowlan.n_patterns) {
924 struct nl80211_wowlan_pattern_support pat = {
925 .max_patterns = dev->wiphy.wowlan.n_patterns,
926 .min_pattern_len =
927 dev->wiphy.wowlan.pattern_min_len,
928 .max_pattern_len =
929 dev->wiphy.wowlan.pattern_max_len,
930 };
931 NLA_PUT(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
932 sizeof(pat), &pat);
933 }
934
935 nla_nest_end(msg, nl_wowlan);
936 }
937
938 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
939 dev->wiphy.software_iftypes))
940 goto nla_put_failure;
941
942 if (nl80211_put_iface_combinations(&dev->wiphy, msg))
943 goto nla_put_failure;
944
824 return genlmsg_end(msg, hdr); 945 return genlmsg_end(msg, hdr);
825 946
826 nla_put_failure: 947 nla_put_failure:
@@ -1682,14 +1803,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1682 if (err) 1803 if (err)
1683 goto out; 1804 goto out;
1684 1805
1685 if (!(rdev->wiphy.flags &
1686 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
1687 if (!key.def_uni || !key.def_multi) {
1688 err = -EOPNOTSUPP;
1689 goto out;
1690 }
1691 }
1692
1693 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx, 1806 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
1694 key.def_uni, key.def_multi); 1807 key.def_uni, key.def_multi);
1695 1808
@@ -1840,8 +1953,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1840 struct beacon_parameters *info); 1953 struct beacon_parameters *info);
1841 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 1954 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1842 struct net_device *dev = info->user_ptr[1]; 1955 struct net_device *dev = info->user_ptr[1];
1956 struct wireless_dev *wdev = dev->ieee80211_ptr;
1843 struct beacon_parameters params; 1957 struct beacon_parameters params;
1844 int haveinfo = 0; 1958 int haveinfo = 0, err;
1845 1959
1846 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1960 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1847 return -EINVAL; 1961 return -EINVAL;
@@ -1850,6 +1964,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1850 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 1964 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1851 return -EOPNOTSUPP; 1965 return -EOPNOTSUPP;
1852 1966
1967 memset(&params, 0, sizeof(params));
1968
1853 switch (info->genlhdr->cmd) { 1969 switch (info->genlhdr->cmd) {
1854 case NL80211_CMD_NEW_BEACON: 1970 case NL80211_CMD_NEW_BEACON:
1855 /* these are required for NEW_BEACON */ 1971 /* these are required for NEW_BEACON */
@@ -1858,6 +1974,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1858 !info->attrs[NL80211_ATTR_BEACON_HEAD]) 1974 !info->attrs[NL80211_ATTR_BEACON_HEAD])
1859 return -EINVAL; 1975 return -EINVAL;
1860 1976
1977 params.interval =
1978 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1979 params.dtim_period =
1980 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1981
1982 err = cfg80211_validate_beacon_int(rdev, params.interval);
1983 if (err)
1984 return err;
1985
1861 call = rdev->ops->add_beacon; 1986 call = rdev->ops->add_beacon;
1862 break; 1987 break;
1863 case NL80211_CMD_SET_BEACON: 1988 case NL80211_CMD_SET_BEACON:
@@ -1871,20 +1996,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1871 if (!call) 1996 if (!call)
1872 return -EOPNOTSUPP; 1997 return -EOPNOTSUPP;
1873 1998
1874 memset(&params, 0, sizeof(params));
1875
1876 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
1877 params.interval =
1878 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1879 haveinfo = 1;
1880 }
1881
1882 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1883 params.dtim_period =
1884 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1885 haveinfo = 1;
1886 }
1887
1888 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 1999 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1889 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 2000 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1890 params.head_len = 2001 params.head_len =
@@ -1902,13 +2013,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1902 if (!haveinfo) 2013 if (!haveinfo)
1903 return -EINVAL; 2014 return -EINVAL;
1904 2015
1905 return call(&rdev->wiphy, dev, &params); 2016 err = call(&rdev->wiphy, dev, &params);
2017 if (!err && params.interval)
2018 wdev->beacon_interval = params.interval;
2019 return err;
1906} 2020}
1907 2021
1908static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 2022static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1909{ 2023{
1910 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2024 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1911 struct net_device *dev = info->user_ptr[1]; 2025 struct net_device *dev = info->user_ptr[1];
2026 struct wireless_dev *wdev = dev->ieee80211_ptr;
2027 int err;
1912 2028
1913 if (!rdev->ops->del_beacon) 2029 if (!rdev->ops->del_beacon)
1914 return -EOPNOTSUPP; 2030 return -EOPNOTSUPP;
@@ -1917,7 +2033,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1917 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2033 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1918 return -EOPNOTSUPP; 2034 return -EOPNOTSUPP;
1919 2035
1920 return rdev->ops->del_beacon(&rdev->wiphy, dev); 2036 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
2037 if (!err)
2038 wdev->beacon_interval = 0;
2039 return err;
1921} 2040}
1922 2041
1923static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 2042static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -2216,6 +2335,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2216 memset(&params, 0, sizeof(params)); 2335 memset(&params, 0, sizeof(params));
2217 2336
2218 params.listen_interval = -1; 2337 params.listen_interval = -1;
2338 params.plink_state = -1;
2219 2339
2220 if (info->attrs[NL80211_ATTR_STA_AID]) 2340 if (info->attrs[NL80211_ATTR_STA_AID])
2221 return -EINVAL; 2341 return -EINVAL;
@@ -2247,6 +2367,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2247 params.plink_action = 2367 params.plink_action =
2248 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 2368 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2249 2369
2370 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE])
2371 params.plink_state =
2372 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
2373
2250 err = get_vlan(info, rdev, &params.vlan); 2374 err = get_vlan(info, rdev, &params.vlan);
2251 if (err) 2375 if (err)
2252 goto out; 2376 goto out;
@@ -2286,10 +2410,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2286 err = -EINVAL; 2410 err = -EINVAL;
2287 if (params.listen_interval >= 0) 2411 if (params.listen_interval >= 0)
2288 err = -EINVAL; 2412 err = -EINVAL;
2289 if (params.supported_rates)
2290 err = -EINVAL;
2291 if (params.sta_flags_mask & 2413 if (params.sta_flags_mask &
2292 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | 2414 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2415 BIT(NL80211_STA_FLAG_MFP) |
2293 BIT(NL80211_STA_FLAG_AUTHORIZED))) 2416 BIT(NL80211_STA_FLAG_AUTHORIZED)))
2294 err = -EINVAL; 2417 err = -EINVAL;
2295 break; 2418 break;
@@ -2840,6 +2963,7 @@ static const struct nla_policy
2840 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 2963 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
2841 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 2964 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
2842 .len = IEEE80211_MAX_DATA_LEN }, 2965 .len = IEEE80211_MAX_DATA_LEN },
2966 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
2843}; 2967};
2844 2968
2845static int nl80211_parse_mesh_config(struct genl_info *info, 2969static int nl80211_parse_mesh_config(struct genl_info *info,
@@ -2949,7 +3073,8 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
2949 setup->ie = nla_data(ieattr); 3073 setup->ie = nla_data(ieattr);
2950 setup->ie_len = nla_len(ieattr); 3074 setup->ie_len = nla_len(ieattr);
2951 } 3075 }
2952 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); 3076 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
3077 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
2953 3078
2954 return 0; 3079 return 0;
2955} 3080}
@@ -3318,6 +3443,188 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3318 return err; 3443 return err;
3319} 3444}
3320 3445
3446static int nl80211_start_sched_scan(struct sk_buff *skb,
3447 struct genl_info *info)
3448{
3449 struct cfg80211_sched_scan_request *request;
3450 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3451 struct net_device *dev = info->user_ptr[1];
3452 struct cfg80211_ssid *ssid;
3453 struct ieee80211_channel *channel;
3454 struct nlattr *attr;
3455 struct wiphy *wiphy;
3456 int err, tmp, n_ssids = 0, n_channels, i;
3457 u32 interval;
3458 enum ieee80211_band band;
3459 size_t ie_len;
3460
3461 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
3462 !rdev->ops->sched_scan_start)
3463 return -EOPNOTSUPP;
3464
3465 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3466 return -EINVAL;
3467
3468 if (rdev->sched_scan_req)
3469 return -EINPROGRESS;
3470
3471 if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
3472 return -EINVAL;
3473
3474 interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
3475 if (interval == 0)
3476 return -EINVAL;
3477
3478 wiphy = &rdev->wiphy;
3479
3480 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3481 n_channels = validate_scan_freqs(
3482 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
3483 if (!n_channels)
3484 return -EINVAL;
3485 } else {
3486 n_channels = 0;
3487
3488 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
3489 if (wiphy->bands[band])
3490 n_channels += wiphy->bands[band]->n_channels;
3491 }
3492
3493 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
3494 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
3495 tmp)
3496 n_ssids++;
3497
3498 if (n_ssids > wiphy->max_scan_ssids)
3499 return -EINVAL;
3500
3501 if (info->attrs[NL80211_ATTR_IE])
3502 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3503 else
3504 ie_len = 0;
3505
3506 if (ie_len > wiphy->max_scan_ie_len)
3507 return -EINVAL;
3508
3509 request = kzalloc(sizeof(*request)
3510 + sizeof(*ssid) * n_ssids
3511 + sizeof(channel) * n_channels
3512 + ie_len, GFP_KERNEL);
3513 if (!request)
3514 return -ENOMEM;
3515
3516 if (n_ssids)
3517 request->ssids = (void *)&request->channels[n_channels];
3518 request->n_ssids = n_ssids;
3519 if (ie_len) {
3520 if (request->ssids)
3521 request->ie = (void *)(request->ssids + n_ssids);
3522 else
3523 request->ie = (void *)(request->channels + n_channels);
3524 }
3525
3526 i = 0;
3527 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3528 /* user specified, bail out if channel not found */
3529 nla_for_each_nested(attr,
3530 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES],
3531 tmp) {
3532 struct ieee80211_channel *chan;
3533
3534 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
3535
3536 if (!chan) {
3537 err = -EINVAL;
3538 goto out_free;
3539 }
3540
3541 /* ignore disabled channels */
3542 if (chan->flags & IEEE80211_CHAN_DISABLED)
3543 continue;
3544
3545 request->channels[i] = chan;
3546 i++;
3547 }
3548 } else {
3549 /* all channels */
3550 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
3551 int j;
3552 if (!wiphy->bands[band])
3553 continue;
3554 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
3555 struct ieee80211_channel *chan;
3556
3557 chan = &wiphy->bands[band]->channels[j];
3558
3559 if (chan->flags & IEEE80211_CHAN_DISABLED)
3560 continue;
3561
3562 request->channels[i] = chan;
3563 i++;
3564 }
3565 }
3566 }
3567
3568 if (!i) {
3569 err = -EINVAL;
3570 goto out_free;
3571 }
3572
3573 request->n_channels = i;
3574
3575 i = 0;
3576 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
3577 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
3578 tmp) {
3579 if (request->ssids[i].ssid_len >
3580 IEEE80211_MAX_SSID_LEN) {
3581 err = -EINVAL;
3582 goto out_free;
3583 }
3584 memcpy(request->ssids[i].ssid, nla_data(attr),
3585 nla_len(attr));
3586 request->ssids[i].ssid_len = nla_len(attr);
3587 i++;
3588 }
3589 }
3590
3591 if (info->attrs[NL80211_ATTR_IE]) {
3592 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3593 memcpy((void *)request->ie,
3594 nla_data(info->attrs[NL80211_ATTR_IE]),
3595 request->ie_len);
3596 }
3597
3598 request->dev = dev;
3599 request->wiphy = &rdev->wiphy;
3600 request->interval = interval;
3601
3602 err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request);
3603 if (!err) {
3604 rdev->sched_scan_req = request;
3605 nl80211_send_sched_scan(rdev, dev,
3606 NL80211_CMD_START_SCHED_SCAN);
3607 goto out;
3608 }
3609
3610out_free:
3611 kfree(request);
3612out:
3613 return err;
3614}
3615
3616static int nl80211_stop_sched_scan(struct sk_buff *skb,
3617 struct genl_info *info)
3618{
3619 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3620
3621 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
3622 !rdev->ops->sched_scan_stop)
3623 return -EOPNOTSUPP;
3624
3625 return __cfg80211_stop_sched_scan(rdev, false);
3626}
3627
3321static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, 3628static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
3322 struct cfg80211_registered_device *rdev, 3629 struct cfg80211_registered_device *rdev,
3323 struct wireless_dev *wdev, 3630 struct wireless_dev *wdev,
@@ -4816,6 +5123,194 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
4816 return cfg80211_leave_mesh(rdev, dev); 5123 return cfg80211_leave_mesh(rdev, dev);
4817} 5124}
4818 5125
5126static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
5127{
5128 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5129 struct sk_buff *msg;
5130 void *hdr;
5131
5132 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
5133 return -EOPNOTSUPP;
5134
5135 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5136 if (!msg)
5137 return -ENOMEM;
5138
5139 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5140 NL80211_CMD_GET_WOWLAN);
5141 if (!hdr)
5142 goto nla_put_failure;
5143
5144 if (rdev->wowlan) {
5145 struct nlattr *nl_wowlan;
5146
5147 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
5148 if (!nl_wowlan)
5149 goto nla_put_failure;
5150
5151 if (rdev->wowlan->any)
5152 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
5153 if (rdev->wowlan->disconnect)
5154 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
5155 if (rdev->wowlan->magic_pkt)
5156 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
5157 if (rdev->wowlan->n_patterns) {
5158 struct nlattr *nl_pats, *nl_pat;
5159 int i, pat_len;
5160
5161 nl_pats = nla_nest_start(msg,
5162 NL80211_WOWLAN_TRIG_PKT_PATTERN);
5163 if (!nl_pats)
5164 goto nla_put_failure;
5165
5166 for (i = 0; i < rdev->wowlan->n_patterns; i++) {
5167 nl_pat = nla_nest_start(msg, i + 1);
5168 if (!nl_pat)
5169 goto nla_put_failure;
5170 pat_len = rdev->wowlan->patterns[i].pattern_len;
5171 NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_MASK,
5172 DIV_ROUND_UP(pat_len, 8),
5173 rdev->wowlan->patterns[i].mask);
5174 NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
5175 pat_len,
5176 rdev->wowlan->patterns[i].pattern);
5177 nla_nest_end(msg, nl_pat);
5178 }
5179 nla_nest_end(msg, nl_pats);
5180 }
5181
5182 nla_nest_end(msg, nl_wowlan);
5183 }
5184
5185 genlmsg_end(msg, hdr);
5186 return genlmsg_reply(msg, info);
5187
5188nla_put_failure:
5189 nlmsg_free(msg);
5190 return -ENOBUFS;
5191}
5192
5193static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5194{
5195 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5196 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
5197 struct cfg80211_wowlan no_triggers = {};
5198 struct cfg80211_wowlan new_triggers = {};
5199 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
5200 int err, i;
5201
5202 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
5203 return -EOPNOTSUPP;
5204
5205 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS])
5206 goto no_triggers;
5207
5208 err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
5209 nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
5210 nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
5211 nl80211_wowlan_policy);
5212 if (err)
5213 return err;
5214
5215 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
5216 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
5217 return -EINVAL;
5218 new_triggers.any = true;
5219 }
5220
5221 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
5222 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
5223 return -EINVAL;
5224 new_triggers.disconnect = true;
5225 }
5226
5227 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
5228 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
5229 return -EINVAL;
5230 new_triggers.magic_pkt = true;
5231 }
5232
5233 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
5234 struct nlattr *pat;
5235 int n_patterns = 0;
5236 int rem, pat_len, mask_len;
5237 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
5238
5239 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
5240 rem)
5241 n_patterns++;
5242 if (n_patterns > wowlan->n_patterns)
5243 return -EINVAL;
5244
5245 new_triggers.patterns = kcalloc(n_patterns,
5246 sizeof(new_triggers.patterns[0]),
5247 GFP_KERNEL);
5248 if (!new_triggers.patterns)
5249 return -ENOMEM;
5250
5251 new_triggers.n_patterns = n_patterns;
5252 i = 0;
5253
5254 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
5255 rem) {
5256 nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
5257 nla_data(pat), nla_len(pat), NULL);
5258 err = -EINVAL;
5259 if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
5260 !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
5261 goto error;
5262 pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
5263 mask_len = DIV_ROUND_UP(pat_len, 8);
5264 if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
5265 mask_len)
5266 goto error;
5267 if (pat_len > wowlan->pattern_max_len ||
5268 pat_len < wowlan->pattern_min_len)
5269 goto error;
5270
5271 new_triggers.patterns[i].mask =
5272 kmalloc(mask_len + pat_len, GFP_KERNEL);
5273 if (!new_triggers.patterns[i].mask) {
5274 err = -ENOMEM;
5275 goto error;
5276 }
5277 new_triggers.patterns[i].pattern =
5278 new_triggers.patterns[i].mask + mask_len;
5279 memcpy(new_triggers.patterns[i].mask,
5280 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
5281 mask_len);
5282 new_triggers.patterns[i].pattern_len = pat_len;
5283 memcpy(new_triggers.patterns[i].pattern,
5284 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
5285 pat_len);
5286 i++;
5287 }
5288 }
5289
5290 if (memcmp(&new_triggers, &no_triggers, sizeof(new_triggers))) {
5291 struct cfg80211_wowlan *ntrig;
5292 ntrig = kmemdup(&new_triggers, sizeof(new_triggers),
5293 GFP_KERNEL);
5294 if (!ntrig) {
5295 err = -ENOMEM;
5296 goto error;
5297 }
5298 cfg80211_rdev_free_wowlan(rdev);
5299 rdev->wowlan = ntrig;
5300 } else {
5301 no_triggers:
5302 cfg80211_rdev_free_wowlan(rdev);
5303 rdev->wowlan = NULL;
5304 }
5305
5306 return 0;
5307 error:
5308 for (i = 0; i < new_triggers.n_patterns; i++)
5309 kfree(new_triggers.patterns[i].mask);
5310 kfree(new_triggers.patterns);
5311 return err;
5312}
5313
4819#define NL80211_FLAG_NEED_WIPHY 0x01 5314#define NL80211_FLAG_NEED_WIPHY 0x01
4820#define NL80211_FLAG_NEED_NETDEV 0x02 5315#define NL80211_FLAG_NEED_NETDEV 0x02
4821#define NL80211_FLAG_NEED_RTNL 0x04 5316#define NL80211_FLAG_NEED_RTNL 0x04
@@ -5100,6 +5595,22 @@ static struct genl_ops nl80211_ops[] = {
5100 .dumpit = nl80211_dump_scan, 5595 .dumpit = nl80211_dump_scan,
5101 }, 5596 },
5102 { 5597 {
5598 .cmd = NL80211_CMD_START_SCHED_SCAN,
5599 .doit = nl80211_start_sched_scan,
5600 .policy = nl80211_policy,
5601 .flags = GENL_ADMIN_PERM,
5602 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5603 NL80211_FLAG_NEED_RTNL,
5604 },
5605 {
5606 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
5607 .doit = nl80211_stop_sched_scan,
5608 .policy = nl80211_policy,
5609 .flags = GENL_ADMIN_PERM,
5610 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5611 NL80211_FLAG_NEED_RTNL,
5612 },
5613 {
5103 .cmd = NL80211_CMD_AUTHENTICATE, 5614 .cmd = NL80211_CMD_AUTHENTICATE,
5104 .doit = nl80211_authenticate, 5615 .doit = nl80211_authenticate,
5105 .policy = nl80211_policy, 5616 .policy = nl80211_policy,
@@ -5314,6 +5825,22 @@ static struct genl_ops nl80211_ops[] = {
5314 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 5825 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5315 NL80211_FLAG_NEED_RTNL, 5826 NL80211_FLAG_NEED_RTNL,
5316 }, 5827 },
5828 {
5829 .cmd = NL80211_CMD_GET_WOWLAN,
5830 .doit = nl80211_get_wowlan,
5831 .policy = nl80211_policy,
5832 /* can be retrieved by unprivileged users */
5833 .internal_flags = NL80211_FLAG_NEED_WIPHY |
5834 NL80211_FLAG_NEED_RTNL,
5835 },
5836 {
5837 .cmd = NL80211_CMD_SET_WOWLAN,
5838 .doit = nl80211_set_wowlan,
5839 .policy = nl80211_policy,
5840 .flags = GENL_ADMIN_PERM,
5841 .internal_flags = NL80211_FLAG_NEED_WIPHY |
5842 NL80211_FLAG_NEED_RTNL,
5843 },
5317}; 5844};
5318 5845
5319static struct genl_multicast_group nl80211_mlme_mcgrp = { 5846static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -5409,6 +5936,28 @@ static int nl80211_send_scan_msg(struct sk_buff *msg,
5409 return -EMSGSIZE; 5936 return -EMSGSIZE;
5410} 5937}
5411 5938
5939static int
5940nl80211_send_sched_scan_msg(struct sk_buff *msg,
5941 struct cfg80211_registered_device *rdev,
5942 struct net_device *netdev,
5943 u32 pid, u32 seq, int flags, u32 cmd)
5944{
5945 void *hdr;
5946
5947 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
5948 if (!hdr)
5949 return -1;
5950
5951 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5952 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5953
5954 return genlmsg_end(msg, hdr);
5955
5956 nla_put_failure:
5957 genlmsg_cancel(msg, hdr);
5958 return -EMSGSIZE;
5959}
5960
5412void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, 5961void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
5413 struct net_device *netdev) 5962 struct net_device *netdev)
5414{ 5963{
@@ -5466,6 +6015,43 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
5466 nl80211_scan_mcgrp.id, GFP_KERNEL); 6015 nl80211_scan_mcgrp.id, GFP_KERNEL);
5467} 6016}
5468 6017
6018void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
6019 struct net_device *netdev)
6020{
6021 struct sk_buff *msg;
6022
6023 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6024 if (!msg)
6025 return;
6026
6027 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
6028 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
6029 nlmsg_free(msg);
6030 return;
6031 }
6032
6033 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
6034 nl80211_scan_mcgrp.id, GFP_KERNEL);
6035}
6036
6037void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
6038 struct net_device *netdev, u32 cmd)
6039{
6040 struct sk_buff *msg;
6041
6042 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
6043 if (!msg)
6044 return;
6045
6046 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
6047 nlmsg_free(msg);
6048 return;
6049 }
6050
6051 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
6052 nl80211_scan_mcgrp.id, GFP_KERNEL);
6053}
6054
5469/* 6055/*
5470 * This can happen on global regulatory changes or device specific settings 6056 * This can happen on global regulatory changes or device specific settings
5471 * based on custom world regulatory domains. 6057 * based on custom world regulatory domains.
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f2af6955a665..2f1bfb87a651 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -12,6 +12,10 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
12 struct net_device *netdev); 12 struct net_device *netdev);
13void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 13void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
14 struct net_device *netdev); 14 struct net_device *netdev);
15void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
16 struct net_device *netdev, u32 cmd);
17void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
18 struct net_device *netdev);
15void nl80211_send_reg_change_event(struct regulatory_request *request); 19void nl80211_send_reg_change_event(struct regulatory_request *request);
16void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, 20void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
17 struct net_device *netdev, 21 struct net_device *netdev,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 1613080a96b9..1ad0f39fe091 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -672,11 +672,9 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
672 for (i = 0; i < regd->n_reg_rules; i++) { 672 for (i = 0; i < regd->n_reg_rules; i++) {
673 const struct ieee80211_reg_rule *rr; 673 const struct ieee80211_reg_rule *rr;
674 const struct ieee80211_freq_range *fr = NULL; 674 const struct ieee80211_freq_range *fr = NULL;
675 const struct ieee80211_power_rule *pr = NULL;
676 675
677 rr = &regd->reg_rules[i]; 676 rr = &regd->reg_rules[i];
678 fr = &rr->freq_range; 677 fr = &rr->freq_range;
679 pr = &rr->power_rule;
680 678
681 /* 679 /*
682 * We only need to know if one frequency rule was 680 * We only need to know if one frequency rule was
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index fbf6f33ae4d0..73a441d237b5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -93,6 +93,69 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
93} 93}
94EXPORT_SYMBOL(cfg80211_scan_done); 94EXPORT_SYMBOL(cfg80211_scan_done);
95 95
96void __cfg80211_sched_scan_results(struct work_struct *wk)
97{
98 struct cfg80211_registered_device *rdev;
99
100 rdev = container_of(wk, struct cfg80211_registered_device,
101 sched_scan_results_wk);
102
103 cfg80211_lock_rdev(rdev);
104
105 /* we don't have sched_scan_req anymore if the scan is stopping */
106 if (rdev->sched_scan_req)
107 nl80211_send_sched_scan_results(rdev,
108 rdev->sched_scan_req->dev);
109
110 cfg80211_unlock_rdev(rdev);
111}
112
113void cfg80211_sched_scan_results(struct wiphy *wiphy)
114{
115 /* ignore if we're not scanning */
116 if (wiphy_to_dev(wiphy)->sched_scan_req)
117 queue_work(cfg80211_wq,
118 &wiphy_to_dev(wiphy)->sched_scan_results_wk);
119}
120EXPORT_SYMBOL(cfg80211_sched_scan_results);
121
122void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
123{
124 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
125
126 cfg80211_lock_rdev(rdev);
127 __cfg80211_stop_sched_scan(rdev, true);
128 cfg80211_unlock_rdev(rdev);
129}
130EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
131
132int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
133 bool driver_initiated)
134{
135 int err;
136 struct net_device *dev;
137
138 ASSERT_RDEV_LOCK(rdev);
139
140 if (!rdev->sched_scan_req)
141 return 0;
142
143 dev = rdev->sched_scan_req->dev;
144
145 if (!driver_initiated) {
146 err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
147 if (err)
148 return err;
149 }
150
151 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
152
153 kfree(rdev->sched_scan_req);
154 rdev->sched_scan_req = NULL;
155
156 return err;
157}
158
96static void bss_release(struct kref *ref) 159static void bss_release(struct kref *ref)
97{ 160{
98 struct cfg80211_internal_bss *bss; 161 struct cfg80211_internal_bss *bss;
@@ -210,7 +273,7 @@ static bool is_mesh(struct cfg80211_bss *a,
210{ 273{
211 const u8 *ie; 274 const u8 *ie;
212 275
213 if (!is_zero_ether_addr(a->bssid)) 276 if (!WLAN_CAPABILITY_IS_MBSS(a->capability))
214 return false; 277 return false;
215 278
216 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, 279 ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
@@ -248,11 +311,7 @@ static int cmp_bss(struct cfg80211_bss *a,
248 if (a->channel != b->channel) 311 if (a->channel != b->channel)
249 return b->channel->center_freq - a->channel->center_freq; 312 return b->channel->center_freq - a->channel->center_freq;
250 313
251 r = memcmp(a->bssid, b->bssid, ETH_ALEN); 314 if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) {
252 if (r)
253 return r;
254
255 if (is_zero_ether_addr(a->bssid)) {
256 r = cmp_ies(WLAN_EID_MESH_ID, 315 r = cmp_ies(WLAN_EID_MESH_ID,
257 a->information_elements, 316 a->information_elements,
258 a->len_information_elements, 317 a->len_information_elements,
@@ -267,6 +326,10 @@ static int cmp_bss(struct cfg80211_bss *a,
267 b->len_information_elements); 326 b->len_information_elements);
268 } 327 }
269 328
329 r = memcmp(a->bssid, b->bssid, ETH_ALEN);
330 if (r)
331 return r;
332
270 return cmp_ies(WLAN_EID_SSID, 333 return cmp_ies(WLAN_EID_SSID,
271 a->information_elements, 334 a->information_elements,
272 a->len_information_elements, 335 a->len_information_elements,
@@ -407,7 +470,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
407 470
408 res->ts = jiffies; 471 res->ts = jiffies;
409 472
410 if (is_zero_ether_addr(res->pub.bssid)) { 473 if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) {
411 /* must be mesh, verify */ 474 /* must be mesh, verify */
412 meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, 475 meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
413 res->pub.information_elements, 476 res->pub.information_elements,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 4294fa22bb2d..c6e4ca6a7d2e 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -93,7 +93,7 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
93 93
94 if (rdev->ops->suspend) { 94 if (rdev->ops->suspend) {
95 rtnl_lock(); 95 rtnl_lock();
96 ret = rdev->ops->suspend(&rdev->wiphy); 96 ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
97 rtnl_unlock(); 97 rtnl_unlock();
98 } 98 }
99 99
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 6a750bc6bcfe..f0536d44d43c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -544,7 +544,8 @@ EXPORT_SYMBOL(ieee80211_data_from_8023);
544 544
545void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, 545void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
546 const u8 *addr, enum nl80211_iftype iftype, 546 const u8 *addr, enum nl80211_iftype iftype,
547 const unsigned int extra_headroom) 547 const unsigned int extra_headroom,
548 bool has_80211_header)
548{ 549{
549 struct sk_buff *frame = NULL; 550 struct sk_buff *frame = NULL;
550 u16 ethertype; 551 u16 ethertype;
@@ -553,14 +554,18 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
553 int remaining, err; 554 int remaining, err;
554 u8 dst[ETH_ALEN], src[ETH_ALEN]; 555 u8 dst[ETH_ALEN], src[ETH_ALEN];
555 556
556 err = ieee80211_data_to_8023(skb, addr, iftype); 557 if (has_80211_header) {
557 if (err) 558 err = ieee80211_data_to_8023(skb, addr, iftype);
558 goto out; 559 if (err)
560 goto out;
559 561
560 /* skip the wrapping header */ 562 /* skip the wrapping header */
561 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); 563 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
562 if (!eth) 564 if (!eth)
563 goto out; 565 goto out;
566 } else {
567 eth = (struct ethhdr *) skb->data;
568 }
564 569
565 while (skb != frame) { 570 while (skb != frame) {
566 u8 padding; 571 u8 padding;
@@ -803,6 +808,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
803 return -EBUSY; 808 return -EBUSY;
804 809
805 if (ntype != otype) { 810 if (ntype != otype) {
811 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
812 ntype);
813 if (err)
814 return err;
815
806 dev->ieee80211_ptr->use_4addr = false; 816 dev->ieee80211_ptr->use_4addr = false;
807 dev->ieee80211_ptr->mesh_id_up_len = 0; 817 dev->ieee80211_ptr->mesh_id_up_len = 0;
808 818
@@ -896,3 +906,103 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
896 /* do NOT round down here */ 906 /* do NOT round down here */
897 return (bitrate + 50000) / 100000; 907 return (bitrate + 50000) / 100000;
898} 908}
909
910int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
911 u32 beacon_int)
912{
913 struct wireless_dev *wdev;
914 int res = 0;
915
916 if (!beacon_int)
917 return -EINVAL;
918
919 mutex_lock(&rdev->devlist_mtx);
920
921 list_for_each_entry(wdev, &rdev->netdev_list, list) {
922 if (!wdev->beacon_interval)
923 continue;
924 if (wdev->beacon_interval != beacon_int) {
925 res = -EINVAL;
926 break;
927 }
928 }
929
930 mutex_unlock(&rdev->devlist_mtx);
931
932 return res;
933}
934
935int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
936 struct wireless_dev *wdev,
937 enum nl80211_iftype iftype)
938{
939 struct wireless_dev *wdev_iter;
940 int num[NUM_NL80211_IFTYPES];
941 int total = 1;
942 int i, j;
943
944 ASSERT_RTNL();
945
946 /* Always allow software iftypes */
947 if (rdev->wiphy.software_iftypes & BIT(iftype))
948 return 0;
949
950 /*
951 * Drivers will gradually all set this flag, until all
952 * have it we only enforce for those that set it.
953 */
954 if (!(rdev->wiphy.flags & WIPHY_FLAG_ENFORCE_COMBINATIONS))
955 return 0;
956
957 memset(num, 0, sizeof(num));
958
959 num[iftype] = 1;
960
961 mutex_lock(&rdev->devlist_mtx);
962 list_for_each_entry(wdev_iter, &rdev->netdev_list, list) {
963 if (wdev_iter == wdev)
964 continue;
965 if (!netif_running(wdev_iter->netdev))
966 continue;
967
968 if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype))
969 continue;
970
971 num[wdev_iter->iftype]++;
972 total++;
973 }
974 mutex_unlock(&rdev->devlist_mtx);
975
976 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
977 const struct ieee80211_iface_combination *c;
978 struct ieee80211_iface_limit *limits;
979
980 c = &rdev->wiphy.iface_combinations[i];
981
982 limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits,
983 GFP_KERNEL);
984 if (!limits)
985 return -ENOMEM;
986 if (total > c->max_interfaces)
987 goto cont;
988
989 for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
990 if (rdev->wiphy.software_iftypes & BIT(iftype))
991 continue;
992 for (j = 0; j < c->n_limits; j++) {
993 if (!(limits[j].types & iftype))
994 continue;
995 if (limits[j].max < num[iftype])
996 goto cont;
997 limits[j].max -= num[iftype];
998 }
999 }
1000 /* yay, it fits */
1001 kfree(limits);
1002 return 0;
1003 cont:
1004 kfree(limits);
1005 }
1006
1007 return -EBUSY;
1008}