summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-24 16:27:02 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-24 16:27:02 -0400
commit8bfadc32b7ef56ac6245b7ae0a06f5ece193004b (patch)
tree571c0c29cee15aa59088cf9a66f798b20005c1f5 /net/wireless
parent1bf9310a1336c26873dc3eb5fa188d4263897929 (diff)
parent6ed0e321a0aef14a894e26658108bf7e895c36a6 (diff)
downloadlinux-8bfadc32b7ef56ac6245b7ae0a06f5ece193004b.tar.gz
linux-8bfadc32b7ef56ac6245b7ae0a06f5ece193004b.tar.bz2
linux-8bfadc32b7ef56ac6245b7ae0a06f5ece193004b.zip
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== Here is one last(?) big wireless bits pull request before the merge window... Regarding the mac80211 bits, Johannes says: "Here's another big pull request for the -next stream. This one has a ton of driver updates, which hopefully addresses all drivers, but maybe you have more new drivers than I have in my tree? Not entirely sure, let me know if this is the case and then I can merge wireless-next. I'm including a large number of small changes, see the shortlog. The two bigger things are making VHT compatible with not using channel contexts (from Karl) and the stop-while-suspended fixes I developed together with Stanislaw." ...and... "This time I have a relatively large number of fixes and small improvements, the most important one being Bob's RCU fix. The two big things are Felix's work on rate scaling tables (with a big thanks to Karl too) and my own work on CSA handling to finally properly handle HT (and some VHT.)" As for the iwlwifi bits, Johannes says: "The biggest work here is Bluetooth coexistence and power saving. Other than that, I have a few small fixes that weren't really needed for 3.9 and a new PCI ID." About the NFC bits, Samuel says: "With this one we have: - A major pn533 update. The pn533 framing support has been changed in order to easily support all pn533 derivatives. For example we now support the ACR122 USB dongle. - An NFC MEI physical layer code factorization through the mei_phy NFC API. Both the microread and the pn544 drivers now use it. - LLCP aggregation support. This allows NFC p2p devices to send aggregated frames containing all sort of LLCP frames except SYMM and aggregation frames. - More LLCP socket options for getting the remote device link parameters. - Fixes for the LLCP socket option code added with the first pull request for 3.10. - Some support for LLCP corner cases like 0 length SDUs and general DISC (tagged with a 0,0 dsap ssap couple) handling. - RFKILL support for NFC." For the b43 bits, RafaƂ says: "Let me remind the changes for b43: > Changes include: > 1) Minor improvements for HT-PHY code (BCM4331) > 2) Code cleaning for HT-PHY and N-PHY" Concerning the bluetooth bits, Gustavo says: "A set of changes intended for 3.10. The biggest changes here are from David Herrmann, he rewrote most of the HIDP layer making it more reliable. Marcel added a driver setup stage for device that need special handling on their early initialization. Other than that we have the usual clean ups, bugfixes and small improvements." Along with all that, there is the usual collection of random/various updates to ath9k, mwifiex, brcmfmac, brcmsmac, rt2x00, and wil6210. I also included a pull of the wireless tree to resolve a merge conflict. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/mlme.c5
-rw-r--r--net/wireless/nl80211.c285
-rw-r--r--net/wireless/rdev-ops.h24
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/trace.h35
-rw-r--r--net/wireless/util.c28
7 files changed, 301 insertions, 81 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 124e5e773fbc..fd35dae547c4 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -88,6 +88,9 @@ struct cfg80211_registered_device {
struct delayed_work dfs_update_channels_wk;
+ /* netlink port which started critical protocol (0 means not started) */
+ u32 crit_proto_nlportid;
+
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __aligned(NETDEV_ALIGN);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 390198bf4b36..0c7b7dd855f6 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -648,6 +648,11 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
spin_unlock_bh(&wdev->mgmt_registrations_lock);
+ if (nlportid && rdev->crit_proto_nlportid == nlportid) {
+ rdev->crit_proto_nlportid = 0;
+ rdev_crit_proto_stop(rdev, wdev);
+ }
+
if (nlportid == wdev->ap_unexpected_nlportid)
wdev->ap_unexpected_nlportid = 0;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 671b69a3c136..afa283841e8c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -447,62 +447,69 @@ nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
};
-/* ifidx get helper */
-static int nl80211_get_ifidx(struct netlink_callback *cb)
+static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct cfg80211_registered_device **rdev,
+ struct wireless_dev **wdev)
{
- int res;
-
- res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
- nl80211_fam.attrbuf, nl80211_fam.maxattr,
- nl80211_policy);
- if (res)
- return res;
-
- if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
- return -EINVAL;
+ int err;
- res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
- if (!res)
- return -EINVAL;
- return res;
-}
+ rtnl_lock();
+ mutex_lock(&cfg80211_mutex);
-static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
- struct netlink_callback *cb,
- struct cfg80211_registered_device **rdev,
- struct net_device **dev)
-{
- int ifidx = cb->args[0];
- int err;
+ if (!cb->args[0]) {
+ err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+ nl80211_fam.attrbuf, nl80211_fam.maxattr,
+ nl80211_policy);
+ if (err)
+ goto out_unlock;
- if (!ifidx)
- ifidx = nl80211_get_ifidx(cb);
- if (ifidx < 0)
- return ifidx;
+ *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
+ nl80211_fam.attrbuf);
+ if (IS_ERR(*wdev)) {
+ err = PTR_ERR(*wdev);
+ goto out_unlock;
+ }
+ *rdev = wiphy_to_dev((*wdev)->wiphy);
+ cb->args[0] = (*rdev)->wiphy_idx;
+ cb->args[1] = (*wdev)->identifier;
+ } else {
+ struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0]);
+ struct wireless_dev *tmp;
- cb->args[0] = ifidx;
+ if (!wiphy) {
+ err = -ENODEV;
+ goto out_unlock;
+ }
+ *rdev = wiphy_to_dev(wiphy);
+ *wdev = NULL;
- rtnl_lock();
+ mutex_lock(&(*rdev)->devlist_mtx);
+ list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
+ if (tmp->identifier == cb->args[1]) {
+ *wdev = tmp;
+ break;
+ }
+ }
+ mutex_unlock(&(*rdev)->devlist_mtx);
- *dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
- if (!*dev) {
- err = -ENODEV;
- goto out_rtnl;
+ if (!*wdev) {
+ err = -ENODEV;
+ goto out_unlock;
+ }
}
- *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
- if (IS_ERR(*rdev)) {
- err = PTR_ERR(*rdev);
- goto out_rtnl;
- }
+ cfg80211_lock_rdev(*rdev);
+ mutex_unlock(&cfg80211_mutex);
return 0;
- out_rtnl:
+ out_unlock:
+ mutex_unlock(&cfg80211_mutex);
rtnl_unlock();
return err;
}
-static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
+static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
{
cfg80211_unlock_rdev(rdev);
rtnl_unlock();
@@ -1417,6 +1424,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
}
CMD(start_p2p_device, START_P2P_DEVICE);
CMD(set_mcast_rate, SET_MCAST_RATE);
+ if (split) {
+ CMD(crit_proto_start, CRIT_PROTOCOL_START);
+ CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
+ }
#ifdef CONFIG_NL80211_TESTMODE
CMD(testmode_cmd, TESTMODE);
@@ -3525,15 +3536,20 @@ static int nl80211_dump_station(struct sk_buff *skb,
{
struct station_info sinfo;
struct cfg80211_registered_device *dev;
- struct net_device *netdev;
+ struct wireless_dev *wdev;
u8 mac_addr[ETH_ALEN];
- int sta_idx = cb->args[1];
+ int sta_idx = cb->args[2];
int err;
- err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
+ err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
if (err)
return err;
+ if (!wdev->netdev) {
+ err = -EINVAL;
+ goto out_err;
+ }
+
if (!dev->ops->dump_station) {
err = -EOPNOTSUPP;
goto out_err;
@@ -3541,7 +3557,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
while (1) {
memset(&sinfo, 0, sizeof(sinfo));
- err = rdev_dump_station(dev, netdev, sta_idx,
+ err = rdev_dump_station(dev, wdev->netdev, sta_idx,
mac_addr, &sinfo);
if (err == -ENOENT)
break;
@@ -3551,7 +3567,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
if (nl80211_send_station(skb,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
- dev, netdev, mac_addr,
+ dev, wdev->netdev, mac_addr,
&sinfo) < 0)
goto out;
@@ -3560,10 +3576,10 @@ static int nl80211_dump_station(struct sk_buff *skb,
out:
- cb->args[1] = sta_idx;
+ cb->args[2] = sta_idx;
err = skb->len;
out_err:
- nl80211_finish_netdev_dump(dev);
+ nl80211_finish_wdev_dump(dev);
return err;
}
@@ -4167,13 +4183,13 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
{
struct mpath_info pinfo;
struct cfg80211_registered_device *dev;
- struct net_device *netdev;
+ struct wireless_dev *wdev;
u8 dst[ETH_ALEN];
u8 next_hop[ETH_ALEN];
- int path_idx = cb->args[1];
+ int path_idx = cb->args[2];
int err;
- err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
+ err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
if (err)
return err;
@@ -4182,14 +4198,14 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
goto out_err;
}
- if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
+ if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
err = -EOPNOTSUPP;
goto out_err;
}
while (1) {
- err = rdev_dump_mpath(dev, netdev, path_idx, dst, next_hop,
- &pinfo);
+ err = rdev_dump_mpath(dev, wdev->netdev, path_idx, dst,
+ next_hop, &pinfo);
if (err == -ENOENT)
break;
if (err)
@@ -4197,7 +4213,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
- netdev, dst, next_hop,
+ wdev->netdev, dst, next_hop,
&pinfo) < 0)
goto out;
@@ -4206,10 +4222,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
out:
- cb->args[1] = path_idx;
+ cb->args[2] = path_idx;
err = skb->len;
out_err:
- nl80211_finish_netdev_dump(dev);
+ nl80211_finish_wdev_dump(dev);
return err;
}
@@ -5565,9 +5581,13 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
genl_dump_check_consistent(cb, hdr, &nl80211_fam);
- if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation) ||
+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
+ goto nla_put_failure;
+ if (wdev->netdev &&
nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
goto nla_put_failure;
+ if (nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+ goto nla_put_failure;
bss = nla_nest_start(msg, NL80211_ATTR_BSS);
if (!bss)
@@ -5647,22 +5667,18 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
return -EMSGSIZE;
}
-static int nl80211_dump_scan(struct sk_buff *skb,
- struct netlink_callback *cb)
+static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
{
struct cfg80211_registered_device *rdev;
- struct net_device *dev;
struct cfg80211_internal_bss *scan;
struct wireless_dev *wdev;
- int start = cb->args[1], idx = 0;
+ int start = cb->args[2], idx = 0;
int err;
- err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
+ err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
if (err)
return err;
- wdev = dev->ieee80211_ptr;
-
wdev_lock(wdev);
spin_lock_bh(&rdev->bss_lock);
cfg80211_bss_expire(rdev);
@@ -5683,8 +5699,8 @@ static int nl80211_dump_scan(struct sk_buff *skb,
spin_unlock_bh(&rdev->bss_lock);
wdev_unlock(wdev);
- cb->args[1] = idx;
- nl80211_finish_netdev_dump(rdev);
+ cb->args[2] = idx;
+ nl80211_finish_wdev_dump(rdev);
return skb->len;
}
@@ -5753,14 +5769,19 @@ static int nl80211_dump_survey(struct sk_buff *skb,
{
struct survey_info survey;
struct cfg80211_registered_device *dev;
- struct net_device *netdev;
- int survey_idx = cb->args[1];
+ struct wireless_dev *wdev;
+ int survey_idx = cb->args[2];
int res;
- res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
+ res = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
if (res)
return res;
+ if (!wdev->netdev) {
+ res = -EINVAL;
+ goto out_err;
+ }
+
if (!dev->ops->dump_survey) {
res = -EOPNOTSUPP;
goto out_err;
@@ -5769,7 +5790,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
while (1) {
struct ieee80211_channel *chan;
- res = rdev_dump_survey(dev, netdev, survey_idx, &survey);
+ res = rdev_dump_survey(dev, wdev->netdev, survey_idx, &survey);
if (res == -ENOENT)
break;
if (res)
@@ -5791,17 +5812,16 @@ static int nl80211_dump_survey(struct sk_buff *skb,
if (nl80211_send_survey(skb,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
- netdev,
- &survey) < 0)
+ wdev->netdev, &survey) < 0)
goto out;
survey_idx++;
}
out:
- cb->args[1] = survey_idx;
+ cb->args[2] = survey_idx;
res = skb->len;
out_err:
- nl80211_finish_netdev_dump(dev);
+ nl80211_finish_wdev_dump(dev);
return res;
}
@@ -8143,9 +8163,11 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->stop_p2p_device)
return -EOPNOTSUPP;
+ mutex_lock(&rdev->devlist_mtx);
mutex_lock(&rdev->sched_scan_mtx);
cfg80211_stop_p2p_device(rdev, wdev);
mutex_unlock(&rdev->sched_scan_mtx);
+ mutex_unlock(&rdev->devlist_mtx);
return 0;
}
@@ -8198,6 +8220,64 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
return rdev_update_ft_ies(rdev, dev, &ft_params);
}
+static int nl80211_crit_protocol_start(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct wireless_dev *wdev = info->user_ptr[1];
+ enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
+ u16 duration;
+ int ret;
+
+ if (!rdev->ops->crit_proto_start)
+ return -EOPNOTSUPP;
+
+ if (WARN_ON(!rdev->ops->crit_proto_stop))
+ return -EINVAL;
+
+ if (rdev->crit_proto_nlportid)
+ return -EBUSY;
+
+ /* determine protocol if provided */
+ if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
+ proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
+
+ if (proto >= NUM_NL80211_CRIT_PROTO)
+ return -EINVAL;
+
+ /* timeout must be provided */
+ if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
+ return -EINVAL;
+
+ duration =
+ nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
+
+ if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
+ return -ERANGE;
+
+ ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
+ if (!ret)
+ rdev->crit_proto_nlportid = info->snd_portid;
+
+ return ret;
+}
+
+static int nl80211_crit_protocol_stop(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct wireless_dev *wdev = info->user_ptr[1];
+
+ if (!rdev->ops->crit_proto_stop)
+ return -EOPNOTSUPP;
+
+ if (rdev->crit_proto_nlportid) {
+ rdev->crit_proto_nlportid = 0;
+ rdev_crit_proto_stop(rdev, wdev);
+ }
+ return 0;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -8887,6 +8967,22 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
+ .doit = nl80211_crit_protocol_start,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
+ .doit = nl80211_crit_protocol_stop,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ }
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -10632,6 +10728,45 @@ void cfg80211_ft_event(struct net_device *netdev,
}
EXPORT_SYMBOL(cfg80211_ft_event);
+void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
+{
+ struct cfg80211_registered_device *rdev;
+ struct sk_buff *msg;
+ void *hdr;
+ u32 nlportid;
+
+ rdev = wiphy_to_dev(wdev->wiphy);
+ if (!rdev->crit_proto_nlportid)
+ return;
+
+ nlportid = rdev->crit_proto_nlportid;
+ rdev->crit_proto_nlportid = 0;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
+ return;
+
+ nla_put_failure:
+ if (hdr)
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+
+}
+EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
+
/* initialisation/exit functions */
int nl80211_init(void)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index d77e1c1d3a0e..9f15f0ac824d 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -875,7 +875,7 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev,
trace_rdev_stop_p2p_device(&rdev->wiphy, wdev);
rdev->ops->stop_p2p_device(&rdev->wiphy, wdev);
trace_rdev_return_void(&rdev->wiphy);
-}
+}
static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
struct net_device *dev,
@@ -901,4 +901,26 @@ static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int rdev_crit_proto_start(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ enum nl80211_crit_proto_id protocol,
+ u16 duration)
+{
+ int ret;
+
+ trace_rdev_crit_proto_start(&rdev->wiphy, wdev, protocol, duration);
+ ret = rdev->ops->crit_proto_start(&rdev->wiphy, wdev,
+ protocol, duration);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
+static inline void rdev_crit_proto_stop(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev)
+{
+ trace_rdev_crit_proto_stop(&rdev->wiphy, wdev);
+ rdev->ops->crit_proto_stop(&rdev->wiphy, wdev);
+ trace_rdev_return_void(&rdev->wiphy);
+}
+
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e6df52dc8c69..cc35fbaa4578 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -855,7 +855,7 @@ static void handle_channel(struct wiphy *wiphy,
return;
REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
- chan->flags = IEEE80211_CHAN_DISABLED;
+ chan->flags |= IEEE80211_CHAN_DISABLED;
return;
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 3c2033b8f596..ecd4fcec3c94 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1806,6 +1806,41 @@ TRACE_EVENT(rdev_update_ft_ies,
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md)
);
+TRACE_EVENT(rdev_crit_proto_start,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+ enum nl80211_crit_proto_id protocol, u16 duration),
+ TP_ARGS(wiphy, wdev, protocol, duration),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ __field(u16, proto)
+ __field(u16, duration)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ __entry->proto = protocol;
+ __entry->duration = duration;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", proto=%x, duration=%u",
+ WIPHY_PR_ARG, WDEV_PR_ARG, __entry->proto, __entry->duration)
+);
+
+TRACE_EVENT(rdev_crit_proto_stop,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+ TP_ARGS(wiphy, wdev),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT,
+ WIPHY_PR_ARG, WDEV_PR_ARG)
+);
+
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 6cbac99ae03d..f5ad4d94ba88 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1155,6 +1155,26 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
}
EXPORT_SYMBOL(cfg80211_get_p2p_attr);
+bool ieee80211_operating_class_to_band(u8 operating_class,
+ enum ieee80211_band *band)
+{
+ switch (operating_class) {
+ case 112:
+ case 115 ... 127:
+ *band = IEEE80211_BAND_5GHZ;
+ return true;
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ *band = IEEE80211_BAND_2GHZ;
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(ieee80211_operating_class_to_band);
+
int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
u32 beacon_int)
{
@@ -1258,12 +1278,12 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
list_for_each_entry(wdev_iter, &rdev->wdev_list, list) {
if (wdev_iter == wdev)
continue;
- if (wdev_iter->netdev) {
- if (!netif_running(wdev_iter->netdev))
- continue;
- } else if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) {
+ if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) {
if (!wdev_iter->p2p_started)
continue;
+ } else if (wdev_iter->netdev) {
+ if (!netif_running(wdev_iter->netdev))
+ continue;
} else {
WARN_ON(1);
}