aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r--net/wireless/core.c134
1 files changed, 57 insertions, 77 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index a87d43552974..31b40cc4a9c3 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -96,69 +96,6 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
96 return &rdev->wiphy; 96 return &rdev->wiphy;
97} 97}
98 98
99/* requires cfg80211_mutex to be held! */
100struct cfg80211_registered_device *
101__cfg80211_rdev_from_info(struct genl_info *info)
102{
103 int ifindex;
104 struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
105 struct net_device *dev;
106 int err = -EINVAL;
107
108 assert_cfg80211_lock();
109
110 if (info->attrs[NL80211_ATTR_WIPHY]) {
111 bywiphyidx = cfg80211_rdev_by_wiphy_idx(
112 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
113 err = -ENODEV;
114 }
115
116 if (info->attrs[NL80211_ATTR_IFINDEX]) {
117 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
118 dev = dev_get_by_index(genl_info_net(info), ifindex);
119 if (dev) {
120 if (dev->ieee80211_ptr)
121 byifidx =
122 wiphy_to_dev(dev->ieee80211_ptr->wiphy);
123 dev_put(dev);
124 }
125 err = -ENODEV;
126 }
127
128 if (bywiphyidx && byifidx) {
129 if (bywiphyidx != byifidx)
130 return ERR_PTR(-EINVAL);
131 else
132 return bywiphyidx; /* == byifidx */
133 }
134 if (bywiphyidx)
135 return bywiphyidx;
136
137 if (byifidx)
138 return byifidx;
139
140 return ERR_PTR(err);
141}
142
143struct cfg80211_registered_device *
144cfg80211_get_dev_from_info(struct genl_info *info)
145{
146 struct cfg80211_registered_device *rdev;
147
148 mutex_lock(&cfg80211_mutex);
149 rdev = __cfg80211_rdev_from_info(info);
150
151 /* if it is not an error we grab the lock on
152 * it to assure it won't be going away while
153 * we operate on it */
154 if (!IS_ERR(rdev))
155 mutex_lock(&rdev->mtx);
156
157 mutex_unlock(&cfg80211_mutex);
158
159 return rdev;
160}
161
162struct cfg80211_registered_device * 99struct cfg80211_registered_device *
163cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) 100cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
164{ 101{
@@ -239,7 +176,9 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
239 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) 176 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
240 return -EOPNOTSUPP; 177 return -EOPNOTSUPP;
241 178
242 list_for_each_entry(wdev, &rdev->netdev_list, list) { 179 list_for_each_entry(wdev, &rdev->wdev_list, list) {
180 if (!wdev->netdev)
181 continue;
243 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; 182 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
244 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); 183 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
245 if (err) 184 if (err)
@@ -251,8 +190,10 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
251 /* failed -- clean up to old netns */ 190 /* failed -- clean up to old netns */
252 net = wiphy_net(&rdev->wiphy); 191 net = wiphy_net(&rdev->wiphy);
253 192
254 list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list, 193 list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list,
255 list) { 194 list) {
195 if (!wdev->netdev)
196 continue;
256 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; 197 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
257 err = dev_change_net_namespace(wdev->netdev, net, 198 err = dev_change_net_namespace(wdev->netdev, net,
258 "wlan%d"); 199 "wlan%d");
@@ -289,8 +230,9 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
289 rtnl_lock(); 230 rtnl_lock();
290 mutex_lock(&rdev->devlist_mtx); 231 mutex_lock(&rdev->devlist_mtx);
291 232
292 list_for_each_entry(wdev, &rdev->netdev_list, list) 233 list_for_each_entry(wdev, &rdev->wdev_list, list)
293 dev_close(wdev->netdev); 234 if (wdev->netdev)
235 dev_close(wdev->netdev);
294 236
295 mutex_unlock(&rdev->devlist_mtx); 237 mutex_unlock(&rdev->devlist_mtx);
296 rtnl_unlock(); 238 rtnl_unlock();
@@ -367,7 +309,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
367 mutex_init(&rdev->mtx); 309 mutex_init(&rdev->mtx);
368 mutex_init(&rdev->devlist_mtx); 310 mutex_init(&rdev->devlist_mtx);
369 mutex_init(&rdev->sched_scan_mtx); 311 mutex_init(&rdev->sched_scan_mtx);
370 INIT_LIST_HEAD(&rdev->netdev_list); 312 INIT_LIST_HEAD(&rdev->wdev_list);
371 spin_lock_init(&rdev->bss_lock); 313 spin_lock_init(&rdev->bss_lock);
372 INIT_LIST_HEAD(&rdev->bss_list); 314 INIT_LIST_HEAD(&rdev->bss_list);
373 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 315 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
@@ -436,6 +378,14 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
436 if (WARN_ON(!c->num_different_channels)) 378 if (WARN_ON(!c->num_different_channels))
437 return -EINVAL; 379 return -EINVAL;
438 380
381 /*
382 * Put a sane limit on maximum number of different
383 * channels to simplify channel accounting code.
384 */
385 if (WARN_ON(c->num_different_channels >
386 CFG80211_MAX_NUM_DIFFERENT_CHANNELS))
387 return -EINVAL;
388
439 if (WARN_ON(!c->n_limits)) 389 if (WARN_ON(!c->n_limits))
440 return -EINVAL; 390 return -EINVAL;
441 391
@@ -484,9 +434,11 @@ int wiphy_register(struct wiphy *wiphy)
484 int i; 434 int i;
485 u16 ifmodes = wiphy->interface_modes; 435 u16 ifmodes = wiphy->interface_modes;
486 436
437#ifdef CONFIG_PM
487 if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 438 if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
488 !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) 439 !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
489 return -EINVAL; 440 return -EINVAL;
441#endif
490 442
491 if (WARN_ON(wiphy->ap_sme_capa && 443 if (WARN_ON(wiphy->ap_sme_capa &&
492 !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) 444 !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
@@ -521,8 +473,14 @@ int wiphy_register(struct wiphy *wiphy)
521 continue; 473 continue;
522 474
523 sband->band = band; 475 sband->band = band;
524 476 if (WARN_ON(!sband->n_channels))
525 if (WARN_ON(!sband->n_channels || !sband->n_bitrates)) 477 return -EINVAL;
478 /*
479 * on 60gHz band, there are no legacy rates, so
480 * n_bitrates is 0
481 */
482 if (WARN_ON(band != IEEE80211_BAND_60GHZ &&
483 !sband->n_bitrates))
526 return -EINVAL; 484 return -EINVAL;
527 485
528 /* 486 /*
@@ -563,12 +521,14 @@ int wiphy_register(struct wiphy *wiphy)
563 return -EINVAL; 521 return -EINVAL;
564 } 522 }
565 523
524#ifdef CONFIG_PM
566 if (rdev->wiphy.wowlan.n_patterns) { 525 if (rdev->wiphy.wowlan.n_patterns) {
567 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len || 526 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
568 rdev->wiphy.wowlan.pattern_min_len > 527 rdev->wiphy.wowlan.pattern_min_len >
569 rdev->wiphy.wowlan.pattern_max_len)) 528 rdev->wiphy.wowlan.pattern_max_len))
570 return -EINVAL; 529 return -EINVAL;
571 } 530 }
531#endif
572 532
573 /* check and set up bitrates */ 533 /* check and set up bitrates */
574 ieee80211_set_bitrate_flags(wiphy); 534 ieee80211_set_bitrate_flags(wiphy);
@@ -582,7 +542,7 @@ int wiphy_register(struct wiphy *wiphy)
582 } 542 }
583 543
584 /* set up regulatory info */ 544 /* set up regulatory info */
585 regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); 545 wiphy_regulatory_register(wiphy);
586 546
587 list_add_rcu(&rdev->list, &cfg80211_rdev_list); 547 list_add_rcu(&rdev->list, &cfg80211_rdev_list);
588 cfg80211_rdev_list_generation++; 548 cfg80211_rdev_list_generation++;
@@ -667,7 +627,7 @@ void wiphy_unregister(struct wiphy *wiphy)
667 __count == 0; })); 627 __count == 0; }));
668 628
669 mutex_lock(&rdev->devlist_mtx); 629 mutex_lock(&rdev->devlist_mtx);
670 BUG_ON(!list_empty(&rdev->netdev_list)); 630 BUG_ON(!list_empty(&rdev->wdev_list));
671 mutex_unlock(&rdev->devlist_mtx); 631 mutex_unlock(&rdev->devlist_mtx);
672 632
673 /* 633 /*
@@ -692,9 +652,11 @@ void wiphy_unregister(struct wiphy *wiphy)
692 /* nothing */ 652 /* nothing */
693 cfg80211_unlock_rdev(rdev); 653 cfg80211_unlock_rdev(rdev);
694 654
695 /* If this device got a regulatory hint tell core its 655 /*
696 * free to listen now to a new shiny device regulatory hint */ 656 * If this device got a regulatory hint tell core its
697 reg_device_remove(wiphy); 657 * free to listen now to a new shiny device regulatory hint
658 */
659 wiphy_regulatory_deregister(wiphy);
698 660
699 cfg80211_rdev_list_generation++; 661 cfg80211_rdev_list_generation++;
700 device_del(&rdev->wiphy.dev); 662 device_del(&rdev->wiphy.dev);
@@ -748,7 +710,7 @@ static void wdev_cleanup_work(struct work_struct *work)
748 710
749 cfg80211_lock_rdev(rdev); 711 cfg80211_lock_rdev(rdev);
750 712
751 if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == wdev->netdev)) { 713 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
752 rdev->scan_req->aborted = true; 714 rdev->scan_req->aborted = true;
753 ___cfg80211_scan_done(rdev, true); 715 ___cfg80211_scan_done(rdev, true);
754 } 716 }
@@ -776,6 +738,16 @@ static struct device_type wiphy_type = {
776 .name = "wlan", 738 .name = "wlan",
777}; 739};
778 740
741void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
742 enum nl80211_iftype iftype, int num)
743{
744 ASSERT_RTNL();
745
746 rdev->num_running_ifaces += num;
747 if (iftype == NL80211_IFTYPE_MONITOR)
748 rdev->num_running_monitor_ifaces += num;
749}
750
779static int cfg80211_netdev_notifier_call(struct notifier_block *nb, 751static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
780 unsigned long state, 752 unsigned long state,
781 void *ndev) 753 void *ndev)
@@ -810,7 +782,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
810 spin_lock_init(&wdev->mgmt_registrations_lock); 782 spin_lock_init(&wdev->mgmt_registrations_lock);
811 783
812 mutex_lock(&rdev->devlist_mtx); 784 mutex_lock(&rdev->devlist_mtx);
813 list_add_rcu(&wdev->list, &rdev->netdev_list); 785 wdev->identifier = ++rdev->wdev_id;
786 list_add_rcu(&wdev->list, &rdev->wdev_list);
814 rdev->devlist_generation++; 787 rdev->devlist_generation++;
815 /* can only change netns with wiphy */ 788 /* can only change netns with wiphy */
816 dev->features |= NETIF_F_NETNS_LOCAL; 789 dev->features |= NETIF_F_NETNS_LOCAL;
@@ -869,12 +842,16 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
869 case NL80211_IFTYPE_MESH_POINT: 842 case NL80211_IFTYPE_MESH_POINT:
870 cfg80211_leave_mesh(rdev, dev); 843 cfg80211_leave_mesh(rdev, dev);
871 break; 844 break;
845 case NL80211_IFTYPE_AP:
846 cfg80211_stop_ap(rdev, dev);
847 break;
872 default: 848 default:
873 break; 849 break;
874 } 850 }
875 wdev->beacon_interval = 0; 851 wdev->beacon_interval = 0;
876 break; 852 break;
877 case NETDEV_DOWN: 853 case NETDEV_DOWN:
854 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
878 dev_hold(dev); 855 dev_hold(dev);
879 queue_work(cfg80211_wq, &wdev->cleanup_work); 856 queue_work(cfg80211_wq, &wdev->cleanup_work);
880 break; 857 break;
@@ -891,6 +868,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
891 mutex_unlock(&rdev->devlist_mtx); 868 mutex_unlock(&rdev->devlist_mtx);
892 dev_put(dev); 869 dev_put(dev);
893 } 870 }
871 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
894 cfg80211_lock_rdev(rdev); 872 cfg80211_lock_rdev(rdev);
895 mutex_lock(&rdev->devlist_mtx); 873 mutex_lock(&rdev->devlist_mtx);
896 wdev_lock(wdev); 874 wdev_lock(wdev);
@@ -980,7 +958,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
980 return notifier_from_errno(-EOPNOTSUPP); 958 return notifier_from_errno(-EOPNOTSUPP);
981 if (rfkill_blocked(rdev->rfkill)) 959 if (rfkill_blocked(rdev->rfkill))
982 return notifier_from_errno(-ERFKILL); 960 return notifier_from_errno(-ERFKILL);
961 mutex_lock(&rdev->devlist_mtx);
983 ret = cfg80211_can_add_interface(rdev, wdev->iftype); 962 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
963 mutex_unlock(&rdev->devlist_mtx);
984 if (ret) 964 if (ret)
985 return notifier_from_errno(ret); 965 return notifier_from_errno(ret);
986 break; 966 break;