aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h5
-rw-r--r--include/net/cfg80211.h22
-rw-r--r--net/wireless/core.c13
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/nl80211.c135
-rw-r--r--net/wireless/sme.c4
-rw-r--r--net/wireless/util.c6
7 files changed, 144 insertions, 47 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index db961a59247..e791487ead3 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -771,6 +771,9 @@ enum nl80211_commands {
771 * @NL80211_ATTR_IFNAME: network interface name 771 * @NL80211_ATTR_IFNAME: network interface name
772 * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype 772 * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
773 * 773 *
774 * @NL80211_ATTR_WDEV: wireless device identifier, used for pseudo-devices
775 * that don't have a netdev (u64)
776 *
774 * @NL80211_ATTR_MAC: MAC address (various uses) 777 * @NL80211_ATTR_MAC: MAC address (various uses)
775 * 778 *
776 * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of 779 * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of
@@ -1493,6 +1496,8 @@ enum nl80211_attrs {
1493 1496
1494 NL80211_ATTR_BG_SCAN_PERIOD, 1497 NL80211_ATTR_BG_SCAN_PERIOD,
1495 1498
1499 NL80211_ATTR_WDEV,
1500
1496 /* add attributes here, update the policy in nl80211.c */ 1501 /* add attributes here, update the policy in nl80211.c */
1497 1502
1498 __NL80211_ATTR_AFTER_LAST, 1503 __NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 51f67a9003a..a14e6a40668 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2341,17 +2341,25 @@ struct cfg80211_internal_bss;
2341struct cfg80211_cached_keys; 2341struct cfg80211_cached_keys;
2342 2342
2343/** 2343/**
2344 * struct wireless_dev - wireless per-netdev state 2344 * struct wireless_dev - wireless device state
2345 * 2345 *
2346 * This structure must be allocated by the driver/stack 2346 * For netdevs, this structure must be allocated by the driver
2347 * that uses the ieee80211_ptr field in struct net_device 2347 * that uses the ieee80211_ptr field in struct net_device (this
2348 * (this is intentional so it can be allocated along with 2348 * is intentional so it can be allocated along with the netdev.)
2349 * the netdev.) 2349 * It need not be registered then as netdev registration will
2350 * be intercepted by cfg80211 to see the new wireless device.
2351 *
2352 * For non-netdev uses, it must also be allocated by the driver
2353 * in response to the cfg80211 callbacks that require it, as
2354 * there's no netdev registration in that case it may not be
2355 * allocated outside of callback operations that return it.
2350 * 2356 *
2351 * @wiphy: pointer to hardware description 2357 * @wiphy: pointer to hardware description
2352 * @iftype: interface type 2358 * @iftype: interface type
2353 * @list: (private) Used to collect the interfaces 2359 * @list: (private) Used to collect the interfaces
2354 * @netdev: (private) Used to reference back to the netdev 2360 * @netdev: (private) Used to reference back to the netdev, may be %NULL
2361 * @identifier: (private) Identifier used in nl80211 to identify this
2362 * wireless device if it has no netdev
2355 * @current_bss: (private) Used by the internal configuration code 2363 * @current_bss: (private) Used by the internal configuration code
2356 * @channel: (private) Used by the internal configuration code to track 2364 * @channel: (private) Used by the internal configuration code to track
2357 * the user-set AP, monitor and WDS channel 2365 * the user-set AP, monitor and WDS channel
@@ -2383,6 +2391,8 @@ struct wireless_dev {
2383 struct list_head list; 2391 struct list_head list;
2384 struct net_device *netdev; 2392 struct net_device *netdev;
2385 2393
2394 u32 identifier;
2395
2386 struct list_head mgmt_registrations; 2396 struct list_head mgmt_registrations;
2387 spinlock_t mgmt_registrations_lock; 2397 spinlock_t mgmt_registrations_lock;
2388 2398
diff --git a/net/wireless/core.c b/net/wireless/core.c
index e42a97b5b97..b110a8a242d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -176,7 +176,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
176 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) 176 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
177 return -EOPNOTSUPP; 177 return -EOPNOTSUPP;
178 178
179 list_for_each_entry(wdev, &rdev->netdev_list, list) { 179 list_for_each_entry(wdev, &rdev->wdev_list, list) {
180 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; 180 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
181 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); 181 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
182 if (err) 182 if (err)
@@ -188,7 +188,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
188 /* failed -- clean up to old netns */ 188 /* failed -- clean up to old netns */
189 net = wiphy_net(&rdev->wiphy); 189 net = wiphy_net(&rdev->wiphy);
190 190
191 list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list, 191 list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list,
192 list) { 192 list) {
193 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; 193 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
194 err = dev_change_net_namespace(wdev->netdev, net, 194 err = dev_change_net_namespace(wdev->netdev, net,
@@ -226,7 +226,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
226 rtnl_lock(); 226 rtnl_lock();
227 mutex_lock(&rdev->devlist_mtx); 227 mutex_lock(&rdev->devlist_mtx);
228 228
229 list_for_each_entry(wdev, &rdev->netdev_list, list) 229 list_for_each_entry(wdev, &rdev->wdev_list, list)
230 dev_close(wdev->netdev); 230 dev_close(wdev->netdev);
231 231
232 mutex_unlock(&rdev->devlist_mtx); 232 mutex_unlock(&rdev->devlist_mtx);
@@ -304,7 +304,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
304 mutex_init(&rdev->mtx); 304 mutex_init(&rdev->mtx);
305 mutex_init(&rdev->devlist_mtx); 305 mutex_init(&rdev->devlist_mtx);
306 mutex_init(&rdev->sched_scan_mtx); 306 mutex_init(&rdev->sched_scan_mtx);
307 INIT_LIST_HEAD(&rdev->netdev_list); 307 INIT_LIST_HEAD(&rdev->wdev_list);
308 spin_lock_init(&rdev->bss_lock); 308 spin_lock_init(&rdev->bss_lock);
309 INIT_LIST_HEAD(&rdev->bss_list); 309 INIT_LIST_HEAD(&rdev->bss_list);
310 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 310 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
@@ -622,7 +622,7 @@ void wiphy_unregister(struct wiphy *wiphy)
622 __count == 0; })); 622 __count == 0; }));
623 623
624 mutex_lock(&rdev->devlist_mtx); 624 mutex_lock(&rdev->devlist_mtx);
625 BUG_ON(!list_empty(&rdev->netdev_list)); 625 BUG_ON(!list_empty(&rdev->wdev_list));
626 mutex_unlock(&rdev->devlist_mtx); 626 mutex_unlock(&rdev->devlist_mtx);
627 627
628 /* 628 /*
@@ -821,7 +821,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
821 spin_lock_init(&wdev->mgmt_registrations_lock); 821 spin_lock_init(&wdev->mgmt_registrations_lock);
822 822
823 mutex_lock(&rdev->devlist_mtx); 823 mutex_lock(&rdev->devlist_mtx);
824 list_add_rcu(&wdev->list, &rdev->netdev_list); 824 wdev->identifier = ++rdev->wdev_id;
825 list_add_rcu(&wdev->list, &rdev->wdev_list);
825 rdev->devlist_generation++; 826 rdev->devlist_generation++;
826 /* can only change netns with wiphy */ 827 /* can only change netns with wiphy */
827 dev->features |= NETIF_F_NETNS_LOCAL; 828 dev->features |= NETIF_F_NETNS_LOCAL;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 377dc394f48..6b0170a5f05 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -47,11 +47,11 @@ struct cfg80211_registered_device {
47 /* wiphy index, internal only */ 47 /* wiphy index, internal only */
48 int wiphy_idx; 48 int wiphy_idx;
49 49
50 /* associate netdev list */ 50 /* associated wireless interfaces */
51 struct mutex devlist_mtx; 51 struct mutex devlist_mtx;
52 /* protected by devlist_mtx or RCU */ 52 /* protected by devlist_mtx or RCU */
53 struct list_head netdev_list; 53 struct list_head wdev_list;
54 int devlist_generation; 54 int devlist_generation, wdev_id;
55 int opencount; /* also protected by devlist_mtx */ 55 int opencount; /* also protected by devlist_mtx */
56 wait_queue_head_t dev_wait; 56 wait_queue_head_t dev_wait;
57 57
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2a5cdb60bc6..35a9b15289f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -46,28 +46,60 @@ static struct genl_family nl80211_fam = {
46 .post_doit = nl80211_post_doit, 46 .post_doit = nl80211_post_doit,
47}; 47};
48 48
49/* internal helper: get rdev and dev */ 49/* returns ERR_PTR values */
50static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, 50static struct wireless_dev *
51 struct cfg80211_registered_device **rdev, 51__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
52 struct net_device **dev)
53{ 52{
54 int ifindex; 53 struct cfg80211_registered_device *rdev;
54 struct wireless_dev *result = NULL;
55 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
56 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
57 u64 wdev_id;
58 int wiphy_idx = -1;
59 int ifidx = -1;
55 60
56 if (!attrs[NL80211_ATTR_IFINDEX]) 61 assert_cfg80211_lock();
57 return -EINVAL;
58 62
59 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 63 if (!have_ifidx && !have_wdev_id)
60 *dev = dev_get_by_index(netns, ifindex); 64 return ERR_PTR(-EINVAL);
61 if (!*dev)
62 return -ENODEV;
63 65
64 *rdev = cfg80211_get_dev_from_ifindex(netns, ifindex); 66 if (have_ifidx)
65 if (IS_ERR(*rdev)) { 67 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
66 dev_put(*dev); 68 if (have_wdev_id) {
67 return PTR_ERR(*rdev); 69 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
70 wiphy_idx = wdev_id >> 32;
68 } 71 }
69 72
70 return 0; 73 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
74 struct wireless_dev *wdev;
75
76 if (wiphy_net(&rdev->wiphy) != netns)
77 continue;
78
79 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
80 continue;
81
82 mutex_lock(&rdev->devlist_mtx);
83 list_for_each_entry(wdev, &rdev->wdev_list, list) {
84 if (have_ifidx && wdev->netdev &&
85 wdev->netdev->ifindex == ifidx) {
86 result = wdev;
87 break;
88 }
89 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
90 result = wdev;
91 break;
92 }
93 }
94 mutex_unlock(&rdev->devlist_mtx);
95
96 if (result)
97 break;
98 }
99
100 if (result)
101 return result;
102 return ERR_PTR(-ENODEV);
71} 103}
72 104
73static struct cfg80211_registered_device * 105static struct cfg80211_registered_device *
@@ -79,13 +111,40 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
79 assert_cfg80211_lock(); 111 assert_cfg80211_lock();
80 112
81 if (!attrs[NL80211_ATTR_WIPHY] && 113 if (!attrs[NL80211_ATTR_WIPHY] &&
82 !attrs[NL80211_ATTR_IFINDEX]) 114 !attrs[NL80211_ATTR_IFINDEX] &&
115 !attrs[NL80211_ATTR_WDEV])
83 return ERR_PTR(-EINVAL); 116 return ERR_PTR(-EINVAL);
84 117
85 if (attrs[NL80211_ATTR_WIPHY]) 118 if (attrs[NL80211_ATTR_WIPHY])
86 rdev = cfg80211_rdev_by_wiphy_idx( 119 rdev = cfg80211_rdev_by_wiphy_idx(
87 nla_get_u32(attrs[NL80211_ATTR_WIPHY])); 120 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
88 121
122 if (attrs[NL80211_ATTR_WDEV]) {
123 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
124 struct wireless_dev *wdev;
125 bool found = false;
126
127 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
128 if (tmp) {
129 /* make sure wdev exists */
130 mutex_lock(&tmp->devlist_mtx);
131 list_for_each_entry(wdev, &tmp->wdev_list, list) {
132 if (wdev->identifier != (u32)wdev_id)
133 continue;
134 found = true;
135 break;
136 }
137 mutex_unlock(&tmp->devlist_mtx);
138
139 if (!found)
140 tmp = NULL;
141
142 if (rdev && tmp != rdev)
143 return ERR_PTR(-EINVAL);
144 rdev = tmp;
145 }
146 }
147
89 if (attrs[NL80211_ATTR_IFINDEX]) { 148 if (attrs[NL80211_ATTR_IFINDEX]) {
90 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 149 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
91 netdev = dev_get_by_index(netns, ifindex); 150 netdev = dev_get_by_index(netns, ifindex);
@@ -294,6 +353,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
294 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, 353 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
295 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, 354 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
296 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, 355 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
356 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
297}; 357};
298 358
299/* policy for the key attributes */ 359/* policy for the key attributes */
@@ -1674,6 +1734,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
1674 struct net_device *dev) 1734 struct net_device *dev)
1675{ 1735{
1676 void *hdr; 1736 void *hdr;
1737 u64 wdev_id = (u64)dev->ieee80211_ptr->identifier |
1738 ((u64)rdev->wiphy_idx << 32);
1677 1739
1678 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE); 1740 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
1679 if (!hdr) 1741 if (!hdr)
@@ -1684,6 +1746,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
1684 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) || 1746 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) ||
1685 nla_put_u32(msg, NL80211_ATTR_IFTYPE, 1747 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
1686 dev->ieee80211_ptr->iftype) || 1748 dev->ieee80211_ptr->iftype) ||
1749 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id) ||
1687 nla_put_u32(msg, NL80211_ATTR_GENERATION, 1750 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1688 rdev->devlist_generation ^ 1751 rdev->devlist_generation ^
1689 (cfg80211_rdev_list_generation << 2))) 1752 (cfg80211_rdev_list_generation << 2)))
@@ -1724,7 +1787,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
1724 if_idx = 0; 1787 if_idx = 0;
1725 1788
1726 mutex_lock(&rdev->devlist_mtx); 1789 mutex_lock(&rdev->devlist_mtx);
1727 list_for_each_entry(wdev, &rdev->netdev_list, list) { 1790 list_for_each_entry(wdev, &rdev->wdev_list, list) {
1728 if (if_idx < if_start) { 1791 if (if_idx < if_start) {
1729 if_idx++; 1792 if_idx++;
1730 continue; 1793 continue;
@@ -2350,7 +2413,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2350 2413
2351 mutex_lock(&rdev->devlist_mtx); 2414 mutex_lock(&rdev->devlist_mtx);
2352 2415
2353 list_for_each_entry(wdev, &rdev->netdev_list, list) { 2416 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2354 if (wdev->iftype != NL80211_IFTYPE_AP && 2417 if (wdev->iftype != NL80211_IFTYPE_AP &&
2355 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2418 wdev->iftype != NL80211_IFTYPE_P2P_GO)
2356 continue; 2419 continue;
@@ -6660,8 +6723,8 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
6660 struct genl_info *info) 6723 struct genl_info *info)
6661{ 6724{
6662 struct cfg80211_registered_device *rdev; 6725 struct cfg80211_registered_device *rdev;
6726 struct wireless_dev *wdev;
6663 struct net_device *dev; 6727 struct net_device *dev;
6664 int err;
6665 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; 6728 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
6666 6729
6667 if (rtnl) 6730 if (rtnl)
@@ -6676,21 +6739,39 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
6676 } 6739 }
6677 info->user_ptr[0] = rdev; 6740 info->user_ptr[0] = rdev;
6678 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { 6741 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
6679 err = get_rdev_dev_by_ifindex(genl_info_net(info), info->attrs, 6742 mutex_lock(&cfg80211_mutex);
6680 &rdev, &dev); 6743 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
6681 if (err) { 6744 info->attrs);
6745 if (IS_ERR(wdev)) {
6746 mutex_unlock(&cfg80211_mutex);
6682 if (rtnl) 6747 if (rtnl)
6683 rtnl_unlock(); 6748 rtnl_unlock();
6684 return err; 6749 return PTR_ERR(wdev);
6685 } 6750 }
6751
6752 if (!wdev->netdev) {
6753 mutex_unlock(&cfg80211_mutex);
6754 if (rtnl)
6755 rtnl_unlock();
6756 return -EINVAL;
6757 }
6758
6759 dev = wdev->netdev;
6760 rdev = wiphy_to_dev(wdev->wiphy);
6761
6686 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && 6762 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
6687 !netif_running(dev)) { 6763 !netif_running(dev)) {
6688 cfg80211_unlock_rdev(rdev); 6764 mutex_unlock(&cfg80211_mutex);
6689 dev_put(dev);
6690 if (rtnl) 6765 if (rtnl)
6691 rtnl_unlock(); 6766 rtnl_unlock();
6692 return -ENETDOWN; 6767 return -ENETDOWN;
6693 } 6768 }
6769
6770 dev_hold(dev);
6771 cfg80211_lock_rdev(rdev);
6772
6773 mutex_unlock(&cfg80211_mutex);
6774
6694 info->user_ptr[0] = rdev; 6775 info->user_ptr[0] = rdev;
6695 info->user_ptr[1] = dev; 6776 info->user_ptr[1] = dev;
6696 } 6777 }
@@ -8483,7 +8564,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
8483 rcu_read_lock(); 8564 rcu_read_lock();
8484 8565
8485 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { 8566 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
8486 list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) 8567 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list)
8487 cfg80211_mlme_unregister_socket(wdev, notify->pid); 8568 cfg80211_mlme_unregister_socket(wdev, notify->pid);
8488 if (rdev->ap_beacons_nlpid == notify->pid) 8569 if (rdev->ap_beacons_nlpid == notify->pid)
8489 rdev->ap_beacons_nlpid = 0; 8570 rdev->ap_beacons_nlpid = 0;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index f7e937ff897..dec97981e68 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -51,7 +51,7 @@ static bool cfg80211_is_all_idle(void)
51 */ 51 */
52 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 52 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
53 cfg80211_lock_rdev(rdev); 53 cfg80211_lock_rdev(rdev);
54 list_for_each_entry(wdev, &rdev->netdev_list, list) { 54 list_for_each_entry(wdev, &rdev->wdev_list, list) {
55 wdev_lock(wdev); 55 wdev_lock(wdev);
56 if (wdev->sme_state != CFG80211_SME_IDLE) 56 if (wdev->sme_state != CFG80211_SME_IDLE)
57 is_all_idle = false; 57 is_all_idle = false;
@@ -221,7 +221,7 @@ void cfg80211_conn_work(struct work_struct *work)
221 cfg80211_lock_rdev(rdev); 221 cfg80211_lock_rdev(rdev);
222 mutex_lock(&rdev->devlist_mtx); 222 mutex_lock(&rdev->devlist_mtx);
223 223
224 list_for_each_entry(wdev, &rdev->netdev_list, list) { 224 list_for_each_entry(wdev, &rdev->wdev_list, list) {
225 wdev_lock(wdev); 225 wdev_lock(wdev);
226 if (!netif_running(wdev->netdev)) { 226 if (!netif_running(wdev->netdev)) {
227 wdev_unlock(wdev); 227 wdev_unlock(wdev);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index e31f1dba79e..f7a0647bde9 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -793,7 +793,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
793 793
794 mutex_lock(&rdev->devlist_mtx); 794 mutex_lock(&rdev->devlist_mtx);
795 795
796 list_for_each_entry(wdev, &rdev->netdev_list, list) 796 list_for_each_entry(wdev, &rdev->wdev_list, list)
797 cfg80211_process_wdev_events(wdev); 797 cfg80211_process_wdev_events(wdev);
798 798
799 mutex_unlock(&rdev->devlist_mtx); 799 mutex_unlock(&rdev->devlist_mtx);
@@ -994,7 +994,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
994 994
995 mutex_lock(&rdev->devlist_mtx); 995 mutex_lock(&rdev->devlist_mtx);
996 996
997 list_for_each_entry(wdev, &rdev->netdev_list, list) { 997 list_for_each_entry(wdev, &rdev->wdev_list, list) {
998 if (!wdev->beacon_interval) 998 if (!wdev->beacon_interval)
999 continue; 999 continue;
1000 if (wdev->beacon_interval != beacon_int) { 1000 if (wdev->beacon_interval != beacon_int) {
@@ -1050,7 +1050,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1050 break; 1050 break;
1051 } 1051 }
1052 1052
1053 list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { 1053 list_for_each_entry(wdev_iter, &rdev->wdev_list, list) {
1054 if (wdev_iter == wdev) 1054 if (wdev_iter == wdev)
1055 continue; 1055 continue;
1056 if (!netif_running(wdev_iter->netdev)) 1056 if (!netif_running(wdev_iter->netdev))