aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2016-05-03 09:52:04 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-05-12 05:16:40 -0400
commit53873f134d285191ef6435882d55837093a36c53 (patch)
treea49f49d0f940a902f2fe0aa271d12d66c98c7a34 /net/wireless
parent8b9b2f06998f33bdd1774a9860ec60e945977384 (diff)
cfg80211: make wdev_list accessible to drivers
There's no harm in having drivers read the list, since they can use RCU protection or RTNL locking; allow this to not require each and every driver to also implement its own bookkeeping. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c2
-rw-r--r--net/wireless/core.c17
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/nl80211.c16
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/sme.c4
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c4
8 files changed, 26 insertions, 24 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index a6631fb319c1..da49c0b1fd32 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -739,7 +739,7 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
739 * and thus fail the GO instantiation, consider only the interfaces of 739 * and thus fail the GO instantiation, consider only the interfaces of
740 * the current registered device. 740 * the current registered device.
741 */ 741 */
742 list_for_each_entry(wdev, &rdev->wdev_list, list) { 742 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
743 struct ieee80211_channel *other_chan = NULL; 743 struct ieee80211_channel *other_chan = NULL;
744 int r1, r2; 744 int r1, r2;
745 745
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7f7b9409bf4c..d25c82bc1bbe 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2014 Intel Mobile Communications GmbH 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
6 * Copyright 2015 Intel Deutschland GmbH
6 */ 7 */
7 8
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -157,7 +158,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
157 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) 158 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
158 return -EOPNOTSUPP; 159 return -EOPNOTSUPP;
159 160
160 list_for_each_entry(wdev, &rdev->wdev_list, list) { 161 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
161 if (!wdev->netdev) 162 if (!wdev->netdev)
162 continue; 163 continue;
163 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; 164 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
@@ -171,7 +172,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
171 /* failed -- clean up to old netns */ 172 /* failed -- clean up to old netns */
172 net = wiphy_net(&rdev->wiphy); 173 net = wiphy_net(&rdev->wiphy);
173 174
174 list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list, 175 list_for_each_entry_continue_reverse(wdev,
176 &rdev->wiphy.wdev_list,
175 list) { 177 list) {
176 if (!wdev->netdev) 178 if (!wdev->netdev)
177 continue; 179 continue;
@@ -230,7 +232,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
230 232
231 ASSERT_RTNL(); 233 ASSERT_RTNL();
232 234
233 list_for_each_entry(wdev, &rdev->wdev_list, list) { 235 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
234 if (wdev->netdev) { 236 if (wdev->netdev) {
235 dev_close(wdev->netdev); 237 dev_close(wdev->netdev);
236 continue; 238 continue;
@@ -298,7 +300,8 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
298 kfree(item); 300 kfree(item);
299 spin_unlock_irq(&rdev->destroy_list_lock); 301 spin_unlock_irq(&rdev->destroy_list_lock);
300 302
301 list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) { 303 list_for_each_entry_safe(wdev, tmp,
304 &rdev->wiphy.wdev_list, list) {
302 if (nlportid == wdev->owner_nlportid) 305 if (nlportid == wdev->owner_nlportid)
303 rdev_del_virtual_intf(rdev, wdev); 306 rdev_del_virtual_intf(rdev, wdev);
304 } 307 }
@@ -410,7 +413,7 @@ use_default_name:
410 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 413 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
411 } 414 }
412 415
413 INIT_LIST_HEAD(&rdev->wdev_list); 416 INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
414 INIT_LIST_HEAD(&rdev->beacon_registrations); 417 INIT_LIST_HEAD(&rdev->beacon_registrations);
415 spin_lock_init(&rdev->beacon_registrations_lock); 418 spin_lock_init(&rdev->beacon_registrations_lock);
416 spin_lock_init(&rdev->bss_lock); 419 spin_lock_init(&rdev->bss_lock);
@@ -799,7 +802,7 @@ void wiphy_unregister(struct wiphy *wiphy)
799 nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); 802 nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
800 rdev->wiphy.registered = false; 803 rdev->wiphy.registered = false;
801 804
802 WARN_ON(!list_empty(&rdev->wdev_list)); 805 WARN_ON(!list_empty(&rdev->wiphy.wdev_list));
803 806
804 /* 807 /*
805 * First remove the hardware from everywhere, this makes 808 * First remove the hardware from everywhere, this makes
@@ -1021,7 +1024,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1021 spin_lock_init(&wdev->mgmt_registrations_lock); 1024 spin_lock_init(&wdev->mgmt_registrations_lock);
1022 1025
1023 wdev->identifier = ++rdev->wdev_id; 1026 wdev->identifier = ++rdev->wdev_id;
1024 list_add_rcu(&wdev->list, &rdev->wdev_list); 1027 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
1025 rdev->devlist_generation++; 1028 rdev->devlist_generation++;
1026 /* can only change netns with wiphy */ 1029 /* can only change netns with wiphy */
1027 dev->features |= NETIF_F_NETNS_LOCAL; 1030 dev->features |= NETIF_F_NETNS_LOCAL;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f75d7605bc38..025b7a5d508b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -50,8 +50,7 @@ struct cfg80211_registered_device {
50 /* wiphy index, internal only */ 50 /* wiphy index, internal only */
51 int wiphy_idx; 51 int wiphy_idx;
52 52
53 /* associated wireless interfaces, protected by rtnl or RCU */ 53 /* protected by RTNL */
54 struct list_head wdev_list;
55 int devlist_generation, wdev_id; 54 int devlist_generation, wdev_id;
56 int opencount; 55 int opencount;
57 wait_queue_head_t dev_wait; 56 wait_queue_head_t dev_wait;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9bc84a2ddd34..d7599014055d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -103,7 +103,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
103 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) 103 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
104 continue; 104 continue;
105 105
106 list_for_each_entry(wdev, &rdev->wdev_list, list) { 106 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
107 if (have_ifidx && wdev->netdev && 107 if (have_ifidx && wdev->netdev &&
108 wdev->netdev->ifindex == ifidx) { 108 wdev->netdev->ifindex == ifidx) {
109 result = wdev; 109 result = wdev;
@@ -149,7 +149,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
149 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); 149 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
150 if (tmp) { 150 if (tmp) {
151 /* make sure wdev exists */ 151 /* make sure wdev exists */
152 list_for_each_entry(wdev, &tmp->wdev_list, list) { 152 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
153 if (wdev->identifier != (u32)wdev_id) 153 if (wdev->identifier != (u32)wdev_id)
154 continue; 154 continue;
155 found = true; 155 found = true;
@@ -535,7 +535,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
535 *rdev = wiphy_to_rdev(wiphy); 535 *rdev = wiphy_to_rdev(wiphy);
536 *wdev = NULL; 536 *wdev = NULL;
537 537
538 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 538 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
539 if (tmp->identifier == cb->args[1]) { 539 if (tmp->identifier == cb->args[1]) {
540 *wdev = tmp; 540 *wdev = tmp;
541 break; 541 break;
@@ -2490,7 +2490,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2490 } 2490 }
2491 if_idx = 0; 2491 if_idx = 0;
2492 2492
2493 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2493 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
2494 if (if_idx < if_start) { 2494 if (if_idx < if_start) {
2495 if_idx++; 2495 if_idx++;
2496 continue; 2496 continue;
@@ -2762,7 +2762,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2762 spin_lock_init(&wdev->mgmt_registrations_lock); 2762 spin_lock_init(&wdev->mgmt_registrations_lock);
2763 2763
2764 wdev->identifier = ++rdev->wdev_id; 2764 wdev->identifier = ++rdev->wdev_id;
2765 list_add_rcu(&wdev->list, &rdev->wdev_list); 2765 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
2766 rdev->devlist_generation++; 2766 rdev->devlist_generation++;
2767 break; 2767 break;
2768 default: 2768 default:
@@ -3298,7 +3298,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3298 struct wireless_dev *wdev; 3298 struct wireless_dev *wdev;
3299 bool ret = false; 3299 bool ret = false;
3300 3300
3301 list_for_each_entry(wdev, &rdev->wdev_list, list) { 3301 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
3302 if (wdev->iftype != NL80211_IFTYPE_AP && 3302 if (wdev->iftype != NL80211_IFTYPE_AP &&
3303 wdev->iftype != NL80211_IFTYPE_P2P_GO) 3303 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3304 continue; 3304 continue;
@@ -10392,7 +10392,7 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
10392 *wdev = NULL; 10392 *wdev = NULL;
10393 10393
10394 if (cb->args[1]) { 10394 if (cb->args[1]) {
10395 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 10395 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
10396 if (tmp->identifier == cb->args[1] - 1) { 10396 if (tmp->identifier == cb->args[1] - 1) {
10397 *wdev = tmp; 10397 *wdev = tmp;
10398 break; 10398 break;
@@ -13413,7 +13413,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
13413 sched_scan_req->owner_nlportid == notify->portid) 13413 sched_scan_req->owner_nlportid == notify->portid)
13414 schedule_scan_stop = true; 13414 schedule_scan_stop = true;
13415 13415
13416 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { 13416 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
13417 cfg80211_mlme_unregister_socket(wdev, notify->portid); 13417 cfg80211_mlme_unregister_socket(wdev, notify->portid);
13418 13418
13419 if (wdev->owner_nlportid == notify->portid) 13419 if (wdev->owner_nlportid == notify->portid)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e271dea6bc02..5dbac3749738 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1639,7 +1639,7 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy)
1639 1639
1640 ASSERT_RTNL(); 1640 ASSERT_RTNL();
1641 1641
1642 list_for_each_entry(wdev, &rdev->wdev_list, list) 1642 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
1643 if (!reg_wdev_chan_valid(wiphy, wdev)) 1643 if (!reg_wdev_chan_valid(wiphy, wdev))
1644 cfg80211_leave(rdev, wdev); 1644 cfg80211_leave(rdev, wdev);
1645} 1645}
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index d814279fb556..584fdc347221 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -223,7 +223,7 @@ void cfg80211_conn_work(struct work_struct *work)
223 223
224 rtnl_lock(); 224 rtnl_lock();
225 225
226 list_for_each_entry(wdev, &rdev->wdev_list, list) { 226 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
227 if (!wdev->netdev) 227 if (!wdev->netdev)
228 continue; 228 continue;
229 229
@@ -617,7 +617,7 @@ static bool cfg80211_is_all_idle(void)
617 * count as new regulatory hints. 617 * count as new regulatory hints.
618 */ 618 */
619 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 619 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
620 list_for_each_entry(wdev, &rdev->wdev_list, list) { 620 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
621 wdev_lock(wdev); 621 wdev_lock(wdev);
622 if (wdev->conn || wdev->current_bss) 622 if (wdev->conn || wdev->current_bss)
623 is_all_idle = false; 623 is_all_idle = false;
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 9cee0220665d..e46469bc130f 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -91,7 +91,7 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
91{ 91{
92 struct wireless_dev *wdev; 92 struct wireless_dev *wdev;
93 93
94 list_for_each_entry(wdev, &rdev->wdev_list, list) 94 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
95 cfg80211_leave(rdev, wdev); 95 cfg80211_leave(rdev, wdev);
96} 96}
97 97
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 7cfabd6e83c6..219bd197039e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -986,7 +986,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
986 986
987 ASSERT_RTNL(); 987 ASSERT_RTNL();
988 988
989 list_for_each_entry(wdev, &rdev->wdev_list, list) 989 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
990 cfg80211_process_wdev_events(wdev); 990 cfg80211_process_wdev_events(wdev);
991} 991}
992 992
@@ -1560,7 +1560,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1560 if (!beacon_int) 1560 if (!beacon_int)
1561 return -EINVAL; 1561 return -EINVAL;
1562 1562
1563 list_for_each_entry(wdev, &rdev->wdev_list, list) { 1563 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
1564 if (!wdev->beacon_interval) 1564 if (!wdev->beacon_interval)
1565 continue; 1565 continue;
1566 if (wdev->beacon_interval != beacon_int) { 1566 if (wdev->beacon_interval != beacon_int) {