diff options
author | Johannes Berg <johannes.berg@intel.com> | 2016-05-03 09:52:04 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2016-05-12 05:16:40 -0400 |
commit | 53873f134d285191ef6435882d55837093a36c53 (patch) | |
tree | a49f49d0f940a902f2fe0aa271d12d66c98c7a34 /net/wireless | |
parent | 8b9b2f06998f33bdd1774a9860ec60e945977384 (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.c | 2 | ||||
-rw-r--r-- | net/wireless/core.c | 17 | ||||
-rw-r--r-- | net/wireless/core.h | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 16 | ||||
-rw-r--r-- | net/wireless/reg.c | 2 | ||||
-rw-r--r-- | net/wireless/sme.c | 4 | ||||
-rw-r--r-- | net/wireless/sysfs.c | 2 | ||||
-rw-r--r-- | net/wireless/util.c | 4 |
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) { |