summaryrefslogtreecommitdiff
path: root/net/wireless
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-09-11 04:34:46 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-09-11 04:34:46 -0300
commit863981e96738983919de841ec669e157e6bdaeb0 (patch)
treed6d89a12e7eb8017837c057935a2271290907f76 /net/wireless
parent8dec7c70575785729a6a9e6719a955e9c545bcab (diff)
Linux-libre 4.7.1-gnupck-4.7.1-gnu
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c4
-rw-r--r--net/wireless/core.c32
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/debugfs.c4
-rw-r--r--net/wireless/ibss.c6
-rw-r--r--net/wireless/mesh.c4
-rw-r--r--net/wireless/mlme.c2
-rw-r--r--net/wireless/nl80211.c348
-rw-r--r--net/wireless/rdev-ops.h2
-rw-r--r--net/wireless/reg.c32
-rw-r--r--net/wireless/reg.h2
-rw-r--r--net/wireless/scan.c24
-rw-r--r--net/wireless/sme.c54
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/trace.h26
-rw-r--r--net/wireless/util.c50
-rw-r--r--net/wireless/wext-compat.c45
-rw-r--r--net/wireless/wext-core.c5
18 files changed, 424 insertions, 224 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 59cabc9bc..da49c0b1f 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -739,7 +739,7 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
* and thus fail the GO instantiation, consider only the interfaces of
* the current registered device.
*/
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
struct ieee80211_channel *other_chan = NULL;
int r1, r2;
@@ -768,7 +768,7 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
if (chan == other_chan)
return true;
- if (chan->band != IEEE80211_BAND_5GHZ)
+ if (chan->band != NL80211_BAND_5GHZ)
continue;
r1 = cfg80211_get_unii(chan->center_freq);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index c878045d1..ecca3896b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -3,6 +3,7 @@
*
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
+ * Copyright 2015 Intel Deutschland GmbH
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -157,7 +158,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
return -EOPNOTSUPP;
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (!wdev->netdev)
continue;
wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
@@ -171,7 +172,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
/* failed -- clean up to old netns */
net = wiphy_net(&rdev->wiphy);
- list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list,
+ list_for_each_entry_continue_reverse(wdev,
+ &rdev->wiphy.wdev_list,
list) {
if (!wdev->netdev)
continue;
@@ -230,7 +232,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
ASSERT_RTNL();
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (wdev->netdev) {
dev_close(wdev->netdev);
continue;
@@ -298,7 +300,8 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
kfree(item);
spin_unlock_irq(&rdev->destroy_list_lock);
- list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) {
+ list_for_each_entry_safe(wdev, tmp,
+ &rdev->wiphy.wdev_list, list) {
if (nlportid == wdev->owner_nlportid)
rdev_del_virtual_intf(rdev, wdev);
}
@@ -408,7 +411,7 @@ use_default_name:
dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
}
- INIT_LIST_HEAD(&rdev->wdev_list);
+ INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
INIT_LIST_HEAD(&rdev->beacon_registrations);
spin_lock_init(&rdev->beacon_registrations_lock);
spin_lock_init(&rdev->bss_lock);
@@ -555,7 +558,7 @@ int wiphy_register(struct wiphy *wiphy)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
int res;
- enum ieee80211_band band;
+ enum nl80211_band band;
struct ieee80211_supported_band *sband;
bool have_band = false;
int i;
@@ -624,6 +627,13 @@ int wiphy_register(struct wiphy *wiphy)
!rdev->ops->set_mac_acl)))
return -EINVAL;
+ /* assure only valid behaviours are flagged by driver
+ * hence subtract 2 as bit 0 is invalid.
+ */
+ if (WARN_ON(wiphy->bss_select_support &&
+ (wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2))))
+ return -EINVAL;
+
if (wiphy->addresses)
memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
@@ -638,7 +648,7 @@ int wiphy_register(struct wiphy *wiphy)
return res;
/* sanity check supported bands/channels */
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
sband = wiphy->bands[band];
if (!sband)
continue;
@@ -650,7 +660,7 @@ int wiphy_register(struct wiphy *wiphy)
* on 60GHz band, there are no legacy rates, so
* n_bitrates is 0
*/
- if (WARN_ON(band != IEEE80211_BAND_60GHZ &&
+ if (WARN_ON(band != NL80211_BAND_60GHZ &&
!sband->n_bitrates))
return -EINVAL;
@@ -660,7 +670,7 @@ int wiphy_register(struct wiphy *wiphy)
* global structure for that.
*/
if (cfg80211_disable_40mhz_24ghz &&
- band == IEEE80211_BAND_2GHZ &&
+ band == NL80211_BAND_2GHZ &&
sband->ht_cap.ht_supported) {
sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
@@ -790,7 +800,7 @@ void wiphy_unregister(struct wiphy *wiphy)
nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
rdev->wiphy.registered = false;
- WARN_ON(!list_empty(&rdev->wdev_list));
+ WARN_ON(!list_empty(&rdev->wiphy.wdev_list));
/*
* First remove the hardware from everywhere, this makes
@@ -1012,7 +1022,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
spin_lock_init(&wdev->mgmt_registrations_lock);
wdev->identifier = ++rdev->wdev_id;
- list_add_rcu(&wdev->list, &rdev->wdev_list);
+ list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
rdev->devlist_generation++;
/* can only change netns with wiphy */
dev->features |= NETIF_F_NETNS_LOCAL;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 022ccad06..025b7a5d5 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -50,10 +50,9 @@ struct cfg80211_registered_device {
/* wiphy index, internal only */
int wiphy_idx;
- /* associated wireless interfaces, protected by rtnl or RCU */
- struct list_head wdev_list;
+ /* protected by RTNL */
int devlist_generation, wdev_id;
- int opencount; /* also protected by devlist_mtx */
+ int opencount;
wait_queue_head_t dev_wait;
struct list_head beacon_registrations;
@@ -214,6 +213,7 @@ struct cfg80211_event {
const u8 *resp_ie;
size_t req_ie_len;
size_t resp_ie_len;
+ struct cfg80211_bss *bss;
u16 status;
} cr;
struct {
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 454157717..5d453916a 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -69,7 +69,7 @@ static ssize_t ht40allow_map_read(struct file *file,
struct wiphy *wiphy = file->private_data;
char *buf;
unsigned int offset = 0, buf_size = PAGE_SIZE, i, r;
- enum ieee80211_band band;
+ enum nl80211_band band;
struct ieee80211_supported_band *sband;
buf = kzalloc(buf_size, GFP_KERNEL);
@@ -78,7 +78,7 @@ static ssize_t ht40allow_map_read(struct file *file,
rtnl_lock();
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
sband = wiphy->bands[band];
if (!sband)
continue;
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 4c55fab9b..4a4dda53b 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -104,7 +104,7 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
struct ieee80211_supported_band *sband =
rdev->wiphy.bands[params->chandef.chan->band];
int j;
- u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
+ u32 flag = params->chandef.chan->band == NL80211_BAND_5GHZ ?
IEEE80211_RATE_MANDATORY_A :
IEEE80211_RATE_MANDATORY_B;
@@ -236,7 +236,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev)
{
struct cfg80211_cached_keys *ck = NULL;
- enum ieee80211_band band;
+ enum nl80211_band band;
int i, err;
ASSERT_WDEV_LOCK(wdev);
@@ -248,7 +248,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
if (!wdev->wext.ibss.chandef.chan) {
struct ieee80211_channel *new_chan = NULL;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan;
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 092300b30..fa2066b56 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -128,9 +128,9 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
if (!setup->chandef.chan) {
/* if we don't have that either, use the first usable channel */
- enum ieee80211_band band;
+ enum nl80211_band band;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan;
int i;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index ff328250b..c284d883c 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -726,7 +726,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
wiphy = &rdev->wiphy;
rtnl_lock();
- for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
+ for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
sband = wiphy->bands[bandid];
if (!sband)
continue;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 056a73078..7d7228390 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)
if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
continue;
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (have_ifidx && wdev->netdev &&
wdev->netdev->ifindex == ifidx) {
result = wdev;
@@ -149,7 +149,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
if (tmp) {
/* make sure wdev exists */
- list_for_each_entry(wdev, &tmp->wdev_list, list) {
+ list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
if (wdev->identifier != (u32)wdev_id)
continue;
found = true;
@@ -402,6 +402,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
+ [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
+ [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
};
/* policy for the key attributes */
@@ -486,6 +488,15 @@ nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
[NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
};
+static const struct nla_policy
+nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
+ [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
+ [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
+ [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
+ .len = sizeof(struct nl80211_bss_select_rssi_adjust)
+ },
+};
+
static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct cfg80211_registered_device **rdev,
@@ -524,7 +535,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
*rdev = wiphy_to_rdev(wiphy);
*wdev = NULL;
- list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
+ list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
if (tmp->identifier == cb->args[1]) {
*wdev = tmp;
break;
@@ -1266,7 +1277,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
struct nlattr *nl_bands, *nl_band;
struct nlattr *nl_freqs, *nl_freq;
struct nlattr *nl_cmds;
- enum ieee80211_band band;
+ enum nl80211_band band;
struct ieee80211_channel *chan;
int i;
const struct ieee80211_txrx_stypes *mgmt_stypes =
@@ -1399,7 +1410,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
goto nla_put_failure;
for (band = state->band_start;
- band < IEEE80211_NUM_BANDS; band++) {
+ band < NUM_NL80211_BANDS; band++) {
struct ieee80211_supported_band *sband;
sband = rdev->wiphy.bands[band];
@@ -1461,7 +1472,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
}
nla_nest_end(msg, nl_bands);
- if (band < IEEE80211_NUM_BANDS)
+ if (band < NUM_NL80211_BANDS)
state->band_start = band + 1;
else
state->band_start = 0;
@@ -1731,6 +1742,25 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
rdev->wiphy.ext_features))
goto nla_put_failure;
+ if (rdev->wiphy.bss_select_support) {
+ struct nlattr *nested;
+ u32 bss_select_support = rdev->wiphy.bss_select_support;
+
+ nested = nla_nest_start(msg, NL80211_ATTR_BSS_SELECT);
+ if (!nested)
+ goto nla_put_failure;
+
+ i = 0;
+ while (bss_select_support) {
+ if ((bss_select_support & 1) &&
+ nla_put_flag(msg, i))
+ goto nla_put_failure;
+ i++;
+ bss_select_support >>= 1;
+ }
+ nla_nest_end(msg, nested);
+ }
+
/* done */
state->split_start = 0;
break;
@@ -2399,7 +2429,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
nla_put_u32(msg, NL80211_ATTR_GENERATION,
rdev->devlist_generation ^
@@ -2459,7 +2490,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
}
if_idx = 0;
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (if_idx < if_start) {
if_idx++;
continue;
@@ -2731,7 +2762,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
spin_lock_init(&wdev->mgmt_registrations_lock);
wdev->identifier = ++rdev->wdev_id;
- list_add_rcu(&wdev->list, &rdev->wdev_list);
+ list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
rdev->devlist_generation++;
break;
default:
@@ -3267,7 +3298,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev;
bool ret = false;
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (wdev->iftype != NL80211_IFTYPE_AP &&
wdev->iftype != NL80211_IFTYPE_P2P_GO)
continue;
@@ -3456,16 +3487,16 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.smps_mode = NL80211_SMPS_OFF;
}
+ params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
+ if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
+ return -EOPNOTSUPP;
+
if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
params.acl = parse_acl_data(&rdev->wiphy, info);
if (IS_ERR(params.acl))
return PTR_ERR(params.acl);
}
- params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
- if (params.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ])
- return -EOPNOTSUPP;
-
wdev_lock(wdev);
err = rdev_start_ap(rdev, dev, &params);
if (!err) {
@@ -3724,11 +3755,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
goto nla_put_failure;
#define PUT_SINFO(attr, memb, type) do { \
- if (sinfo->filled & BIT(NL80211_STA_INFO_ ## attr) && \
+ BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
+ if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
sinfo->memb)) \
goto nla_put_failure; \
} while (0)
+#define PUT_SINFO_U64(attr, memb) do { \
+ if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
+ nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
+ sinfo->memb, NL80211_STA_INFO_PAD)) \
+ goto nla_put_failure; \
+ } while (0)
PUT_SINFO(CONNECTED_TIME, connected_time, u32);
PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
@@ -3745,11 +3783,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
(u32)sinfo->tx_bytes))
goto nla_put_failure;
- PUT_SINFO(RX_BYTES64, rx_bytes, u64);
- PUT_SINFO(TX_BYTES64, tx_bytes, u64);
+ PUT_SINFO_U64(RX_BYTES64, rx_bytes);
+ PUT_SINFO_U64(TX_BYTES64, tx_bytes);
PUT_SINFO(LLID, llid, u16);
PUT_SINFO(PLID, plid, u16);
PUT_SINFO(PLINK_STATE, plink_state, u8);
+ PUT_SINFO_U64(RX_DURATION, rx_duration);
switch (rdev->wiphy.signal_type) {
case CFG80211_SIGNAL_TYPE_MBM:
@@ -3817,12 +3856,13 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
&sinfo->sta_flags))
goto nla_put_failure;
- PUT_SINFO(T_OFFSET, t_offset, u64);
- PUT_SINFO(RX_DROP_MISC, rx_dropped_misc, u64);
- PUT_SINFO(BEACON_RX, rx_beacon, u64);
+ PUT_SINFO_U64(T_OFFSET, t_offset);
+ PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
+ PUT_SINFO_U64(BEACON_RX, rx_beacon);
PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
#undef PUT_SINFO
+#undef PUT_SINFO_U64
if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
struct nlattr *tidsattr;
@@ -3845,19 +3885,19 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
if (!tidattr)
goto nla_put_failure;
-#define PUT_TIDVAL(attr, memb, type) do { \
+#define PUT_TIDVAL_U64(attr, memb) do { \
if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
- nla_put_ ## type(msg, NL80211_TID_STATS_ ## attr, \
- tidstats->memb)) \
+ nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
+ tidstats->memb, NL80211_TID_STATS_PAD)) \
goto nla_put_failure; \
} while (0)
- PUT_TIDVAL(RX_MSDU, rx_msdu, u64);
- PUT_TIDVAL(TX_MSDU, tx_msdu, u64);
- PUT_TIDVAL(TX_MSDU_RETRIES, tx_msdu_retries, u64);
- PUT_TIDVAL(TX_MSDU_FAILED, tx_msdu_failed, u64);
+ PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
+ PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
+ PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
+ PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
-#undef PUT_TIDVAL
+#undef PUT_TIDVAL_U64
nla_nest_end(msg, tidattr);
}
@@ -3977,6 +4017,10 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
statype != CFG80211_STA_AP_CLIENT_UNASSOC)
return -EINVAL;
+ if (params->support_p2p_ps != -1 &&
+ statype != CFG80211_STA_AP_CLIENT_UNASSOC)
+ return -EINVAL;
+
if (params->aid &&
!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
statype != CFG80211_STA_AP_CLIENT_UNASSOC)
@@ -4270,6 +4314,18 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
else
params.listen_interval = -1;
+ if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
+ u8 tmp;
+
+ tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
+ if (tmp >= NUM_NL80211_P2P_PS_STATUS)
+ return -EINVAL;
+
+ params.support_p2p_ps = tmp;
+ } else {
+ params.support_p2p_ps = -1;
+ }
+
if (!info->attrs[NL80211_ATTR_MAC])
return -EINVAL;
@@ -4393,6 +4449,23 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params.listen_interval =
nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
+ if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
+ u8 tmp;
+
+ tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
+ if (tmp >= NUM_NL80211_P2P_PS_STATUS)
+ return -EINVAL;
+
+ params.support_p2p_ps = tmp;
+ } else {
+ /*
+ * if not specified, assume it's supported for P2P GO interface,
+ * and is NOT supported for AP interface
+ */
+ params.support_p2p_ps =
+ dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
+ }
+
if (info->attrs[NL80211_ATTR_PEER_AID])
params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
else
@@ -5758,6 +5831,73 @@ static int validate_scan_freqs(struct nlattr *freqs)
return n_channels;
}
+static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
+{
+ return b < NUM_NL80211_BANDS && wiphy->bands[b];
+}
+
+static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
+ struct cfg80211_bss_selection *bss_select)
+{
+ struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
+ struct nlattr *nest;
+ int err;
+ bool found = false;
+ int i;
+
+ /* only process one nested attribute */
+ nest = nla_data(nla);
+ if (!nla_ok(nest, nla_len(nest)))
+ return -EINVAL;
+
+ err = nla_parse(attr, NL80211_BSS_SELECT_ATTR_MAX, nla_data(nest),
+ nla_len(nest), nl80211_bss_select_policy);
+ if (err)
+ return err;
+
+ /* only one attribute may be given */
+ for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
+ if (attr[i]) {
+ if (found)
+ return -EINVAL;
+ found = true;
+ }
+ }
+
+ bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
+
+ if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
+ bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
+
+ if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
+ bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
+ bss_select->param.band_pref =
+ nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
+ if (!is_band_valid(wiphy, bss_select->param.band_pref))
+ return -EINVAL;
+ }
+
+ if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
+ struct nl80211_bss_select_rssi_adjust *adj_param;
+
+ adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
+ bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
+ bss_select->param.adjust.band = adj_param->band;
+ bss_select->param.adjust.delta = adj_param->delta;
+ if (!is_band_valid(wiphy, bss_select->param.adjust.band))
+ return -EINVAL;
+ }
+
+ /* user-space did not provide behaviour attribute */
+ if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
+ return -EINVAL;
+
+ if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
+ return -EINVAL;
+
+ return 0;
+}
+
static int nl80211_parse_random_mac(struct nlattr **attrs,
u8 *mac_addr, u8 *mac_addr_mask)
{
@@ -5888,10 +6028,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
i++;
}
} else {
- enum ieee80211_band band;
+ enum nl80211_band band;
/* all channels */
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
int j;
if (!wiphy->bands[band])
continue;
@@ -5936,7 +6076,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
request->ie_len);
}
- for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ for (i = 0; i < NUM_NL80211_BANDS; i++)
if (wiphy->bands[i])
request->rates[i] =
(1 << wiphy->bands[i]->n_bitrates) - 1;
@@ -5945,9 +6085,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
nla_for_each_nested(attr,
info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
tmp) {
- enum ieee80211_band band = nla_type(attr);
+ enum nl80211_band band = nla_type(attr);
- if (band < 0 || band >= IEEE80211_NUM_BANDS) {
+ if (band < 0 || band >= NUM_NL80211_BANDS) {
err = -EINVAL;
goto out_free;
}
@@ -5996,6 +6136,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
request->no_cck =
nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
+ if (info->attrs[NL80211_ATTR_MAC])
+ memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
+ ETH_ALEN);
+ else
+ eth_broadcast_addr(request->bssid);
+
request->wdev = wdev;
request->wiphy = &rdev->wiphy;
request->scan_start = jiffies;
@@ -6129,7 +6275,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_sched_scan_request *request;
struct nlattr *attr;
int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
- enum ieee80211_band band;
+ enum nl80211_band band;
size_t ie_len;
struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
@@ -6294,7 +6440,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
}
} else {
/* all channels */
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
int j;
if (!wiphy->bands[band])
continue;
@@ -6738,7 +6884,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
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)))
+ if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD))
goto nla_put_failure;
bss = nla_nest_start(msg, NL80211_ATTR_BSS);
@@ -6759,7 +6906,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
*/
ies = rcu_dereference(res->ies);
if (ies) {
- if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
+ if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
+ NL80211_BSS_PAD))
goto fail_unlock_rcu;
if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
ies->len, ies->data))
@@ -6769,7 +6917,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
/* and this pointer is always (unless driver didn't know) beacon data */
ies = rcu_dereference(res->beacon_ies);
if (ies && ies->from_beacon) {
- if (nla_put_u64(msg, NL80211_BSS_BEACON_TSF, ies->tsf))
+ if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
+ NL80211_BSS_PAD))
goto fail_unlock_rcu;
if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
ies->len, ies->data))
@@ -6788,8 +6937,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
goto nla_put_failure;
if (intbss->ts_boottime &&
- nla_put_u64(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
- intbss->ts_boottime))
+ nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
+ intbss->ts_boottime, NL80211_BSS_PAD))
goto nla_put_failure;
switch (rdev->wiphy.signal_type) {
@@ -6909,28 +7058,28 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
goto nla_put_failure;
if ((survey->filled & SURVEY_INFO_TIME) &&
- nla_put_u64(msg, NL80211_SURVEY_INFO_TIME,
- survey->time))
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
+ survey->time, NL80211_SURVEY_INFO_PAD))
goto nla_put_failure;
if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
- nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_BUSY,
- survey->time_busy))
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
+ survey->time_busy, NL80211_SURVEY_INFO_PAD))
goto nla_put_failure;
if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
- nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
- survey->time_ext_busy))
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
+ survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
goto nla_put_failure;
if ((survey->filled & SURVEY_INFO_TIME_RX) &&
- nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_RX,
- survey->time_rx))
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
+ survey->time_rx, NL80211_SURVEY_INFO_PAD))
goto nla_put_failure;
if ((survey->filled & SURVEY_INFO_TIME_TX) &&
- nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_TX,
- survey->time_tx))
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
+ survey->time_tx, NL80211_SURVEY_INFO_PAD))
goto nla_put_failure;
if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
- nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_SCAN,
- survey->time_scan))
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
+ survey->time_scan, NL80211_SURVEY_INFO_PAD))
goto nla_put_failure;
nla_nest_end(msg, infoattr);
@@ -7402,14 +7551,14 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
static bool
nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
- int mcast_rate[IEEE80211_NUM_BANDS],
+ int mcast_rate[NUM_NL80211_BANDS],
int rateval)
{
struct wiphy *wiphy = &rdev->wiphy;
bool found = false;
int band, i;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
struct ieee80211_supported_band *sband;
sband = wiphy->bands[band];
@@ -7589,7 +7738,7 @@ static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
- int mcast_rate[IEEE80211_NUM_BANDS];
+ int mcast_rate[NUM_NL80211_BANDS];
u32 nla_rate;
int err;
@@ -7650,8 +7799,8 @@ __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
}
if (wdev) {
- if (nla_put_u64(skb, NL80211_ATTR_WDEV,
- wdev_id(wdev)))
+ if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
+ wdev_id(wdev), NL80211_ATTR_PAD))
goto nla_put_failure;
if (wdev->netdev &&
nla_put_u32(skb, NL80211_ATTR_IFINDEX,
@@ -7922,6 +8071,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
connect.mfp = NL80211_MFP_NO;
}
+ if (info->attrs[NL80211_ATTR_PREV_BSSID])
+ connect.prev_bssid =
+ nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
+
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
connect.channel = nl80211_get_valid_chan(
wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
@@ -7990,13 +8143,29 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
}
connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
- if (connect.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ]) {
+ if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
kzfree(connkeys);
return -EOPNOTSUPP;
}
+ if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
+ /* bss selection makes no sense if bssid is set */
+ if (connect.bssid) {
+ kzfree(connkeys);
+ return -EINVAL;
+ }
+
+ err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
+ wiphy, &connect.bss_select);
+ if (err) {
+ kzfree(connkeys);
+ return err;
+ }
+ }
+
wdev_lock(dev->ieee80211_ptr);
- err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
+ err = cfg80211_connect(rdev, dev, &connect, connkeys,
+ connect.prev_bssid);
wdev_unlock(dev->ieee80211_ptr);
if (err)
kzfree(connkeys);
@@ -8224,7 +8393,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (err)
goto free_msg;
- if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+ NL80211_ATTR_PAD))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -8394,7 +8564,7 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
memset(&mask, 0, sizeof(mask));
/* Default to all rates enabled */
- for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+ for (i = 0; i < NUM_NL80211_BANDS; i++) {
sband = rdev->wiphy.bands[i];
if (!sband)
@@ -8418,14 +8588,14 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
/*
* The nested attribute uses enum nl80211_band as the index. This maps
- * directly to the enum ieee80211_band values used in cfg80211.
+ * directly to the enum nl80211_band values used in cfg80211.
*/
BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
- enum ieee80211_band band = nla_type(tx_rates);
+ enum nl80211_band band = nla_type(tx_rates);
int err;
- if (band < 0 || band >= IEEE80211_NUM_BANDS)
+ if (band < 0 || band >= NUM_NL80211_BANDS)
return -EINVAL;
sband = rdev->wiphy.bands[band];
if (sband == NULL)
@@ -8636,7 +8806,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
goto free_msg;
if (msg) {
- if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+ NL80211_ATTR_PAD))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -9922,7 +10093,8 @@ static int nl80211_probe_client(struct sk_buff *skb,
if (err)
goto free_msg;
- if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+ NL80211_ATTR_PAD))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -10220,7 +10392,7 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
*wdev = NULL;
if (cb->args[1]) {
- list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
+ list_for_each_entry(tmp, &wiphy->wdev_list, list) {
if (tmp->identifier == cb->args[1] - 1) {
*wdev = tmp;
break;
@@ -10347,8 +10519,9 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
break;
if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
- (wdev && nla_put_u64(skb, NL80211_ATTR_WDEV,
- wdev_id(wdev)))) {
+ (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
+ wdev_id(wdev),
+ NL80211_ATTR_PAD))) {
genlmsg_cancel(skb, hdr);
break;
}
@@ -10590,7 +10763,7 @@ static int nl80211_tdls_channel_switch(struct sk_buff *skb,
* section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
* specification is not defined for them.
*/
- if (chandef.chan->band == IEEE80211_BAND_2GHZ &&
+ if (chandef.chan->band == NL80211_BAND_2GHZ &&
chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
chandef.width != NL80211_CHAN_WIDTH_20)
return -EINVAL;
@@ -11555,7 +11728,8 @@ static int nl80211_send_scan_msg(struct sk_buff *msg,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
(wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
wdev->netdev->ifindex)) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD))
goto nla_put_failure;
/* ignore errors and send incomplete event anyway */
@@ -12222,11 +12396,13 @@ static void nl80211_send_remain_on_chan_event(
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
(wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
wdev->netdev->ifindex)) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
NL80211_CHAN_NO_HT) ||
- nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+ NL80211_ATTR_PAD))
goto nla_put_failure;
if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
@@ -12460,7 +12636,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
(netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
netdev->ifindex)) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
(sig_dbm &&
nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
@@ -12503,9 +12680,11 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
(netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
netdev->ifindex)) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
- nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+ NL80211_ATTR_PAD) ||
(ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
goto nla_put_failure;
@@ -12885,7 +13064,8 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev = netdev->ieee80211_ptr;
if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD))
goto nla_put_failure;
}
@@ -12930,7 +13110,8 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
- nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
+ NL80211_ATTR_PAD) ||
(acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
goto nla_put_failure;
@@ -13075,7 +13256,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
goto free_msg;
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD))
goto free_msg;
if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
@@ -13231,7 +13413,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
sched_scan_req->owner_nlportid == notify->portid)
schedule_scan_stop = true;
- list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
cfg80211_mlme_unregister_socket(wdev, notify->portid);
if (wdev->owner_nlportid == notify->portid)
@@ -13350,7 +13532,8 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
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)))
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -13383,7 +13566,8 @@ void nl80211_send_ap_stopped(struct wireless_dev *wdev)
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
- nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD))
goto out;
genlmsg_end(msg, hdr);
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 8ae0c04f9..85ff30bee 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1048,7 +1048,7 @@ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
static inline int
rdev_set_mcast_rate(struct cfg80211_registered_device *rdev,
struct net_device *dev,
- int mcast_rate[IEEE80211_NUM_BANDS])
+ int mcast_rate[NUM_NL80211_BANDS])
{
int ret = -ENOTSUPP;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index c5fb317ee..5dbac3749 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1546,12 +1546,12 @@ static void reg_process_ht_flags_band(struct wiphy *wiphy,
static void reg_process_ht_flags(struct wiphy *wiphy)
{
- enum ieee80211_band band;
+ enum nl80211_band band;
if (!wiphy)
return;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ for (band = 0; band < NUM_NL80211_BANDS; band++)
reg_process_ht_flags_band(wiphy, wiphy->bands[band]);
}
@@ -1639,7 +1639,7 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy)
ASSERT_RTNL();
- list_for_each_entry(wdev, &rdev->wdev_list, list)
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
if (!reg_wdev_chan_valid(wiphy, wdev))
cfg80211_leave(rdev, wdev);
}
@@ -1673,7 +1673,7 @@ static void reg_check_channels(void)
static void wiphy_update_regulatory(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
- enum ieee80211_band band;
+ enum nl80211_band band;
struct regulatory_request *lr = get_last_request();
if (ignore_reg_update(wiphy, initiator)) {
@@ -1690,7 +1690,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
lr->dfs_region = get_cfg80211_regdom()->dfs_region;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ for (band = 0; band < NUM_NL80211_BANDS; band++)
handle_band(wiphy, initiator, wiphy->bands[band]);
reg_process_beacons(wiphy);
@@ -1786,14 +1786,14 @@ static void handle_band_custom(struct wiphy *wiphy,
void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
const struct ieee80211_regdomain *regd)
{
- enum ieee80211_band band;
+ enum nl80211_band band;
unsigned int bands_set = 0;
WARN(!(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG),
"wiphy should have REGULATORY_CUSTOM_REG\n");
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
if (!wiphy->bands[band])
continue;
handle_band_custom(wiphy, wiphy->bands[band], regd);
@@ -2228,7 +2228,7 @@ static void reg_process_self_managed_hints(void)
struct wiphy *wiphy;
const struct ieee80211_regdomain *tmp;
const struct ieee80211_regdomain *regd;
- enum ieee80211_band band;
+ enum nl80211_band band;
struct regulatory_request request = {};
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
@@ -2246,7 +2246,7 @@ static void reg_process_self_managed_hints(void)
rcu_assign_pointer(wiphy->regd, regd);
rcu_free_regdom(tmp);
- for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ for (band = 0; band < NUM_NL80211_BANDS; band++)
handle_band_custom(wiphy, wiphy->bands[band], regd);
reg_process_ht_flags(wiphy);
@@ -2404,7 +2404,7 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
}
EXPORT_SYMBOL(regulatory_hint);
-void regulatory_hint_country_ie(struct wiphy *wiphy, enum ieee80211_band band,
+void regulatory_hint_country_ie(struct wiphy *wiphy, enum nl80211_band band,
const u8 *country_ie, u8 country_ie_len)
{
char alpha2[2];
@@ -2504,11 +2504,11 @@ static void restore_alpha2(char *alpha2, bool reset_user)
static void restore_custom_reg_settings(struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
- enum ieee80211_band band;
+ enum nl80211_band band;
struct ieee80211_channel *chan;
int i;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
sband = wiphy->bands[band];
if (!sband)
continue;
@@ -2623,9 +2623,9 @@ void regulatory_hint_disconnect(void)
static bool freq_is_chan_12_13_14(u16 freq)
{
- if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) ||
- freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) ||
- freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ))
+ if (freq == ieee80211_channel_to_frequency(12, NL80211_BAND_2GHZ) ||
+ freq == ieee80211_channel_to_frequency(13, NL80211_BAND_2GHZ) ||
+ freq == ieee80211_channel_to_frequency(14, NL80211_BAND_2GHZ))
return true;
return false;
}
@@ -2650,7 +2650,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
if (beacon_chan->beacon_found ||
beacon_chan->flags & IEEE80211_CHAN_RADAR ||
- (beacon_chan->band == IEEE80211_BAND_2GHZ &&
+ (beacon_chan->band == NL80211_BAND_2GHZ &&
!freq_is_chan_12_13_14(beacon_chan->center_freq)))
return 0;
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 9f495d76e..f6ced316b 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -104,7 +104,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
* information for a band the BSS is not present in it will be ignored.
*/
void regulatory_hint_country_ie(struct wiphy *wiphy,
- enum ieee80211_band band,
+ enum nl80211_band band,
const u8 *country_ie,
u8 country_ie_len);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 14d5369eb..ef2955c89 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -364,13 +364,16 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
}
EXPORT_SYMBOL(cfg80211_find_ie);
-const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
+const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
const u8 *ies, int len)
{
struct ieee80211_vendor_ie *ie;
const u8 *pos = ies, *end = ies + len;
int ie_oui;
+ if (WARN_ON(oui_type > 0xff))
+ return NULL;
+
while (pos < end) {
pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos,
end - pos);
@@ -386,7 +389,8 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
goto cont;
ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
- if (ie_oui == oui && ie->oui_type == oui_type)
+ if (ie_oui == oui &&
+ (oui_type < 0 || ie->oui_type == oui_type))
return pos;
cont:
pos += 2 + ie->len;
@@ -531,7 +535,7 @@ static int cmp_bss(struct cfg80211_bss *a,
}
static bool cfg80211_bss_type_match(u16 capability,
- enum ieee80211_band band,
+ enum nl80211_band band,
enum ieee80211_bss_type bss_type)
{
bool ret = true;
@@ -540,7 +544,7 @@ static bool cfg80211_bss_type_match(u16 capability,
if (bss_type == IEEE80211_BSS_TYPE_ANY)
return ret;
- if (band == IEEE80211_BAND_60GHZ) {
+ if (band == NL80211_BAND_60GHZ) {
mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
switch (bss_type) {
case IEEE80211_BSS_TYPE_ESS:
@@ -1006,7 +1010,7 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
if (!res)
return NULL;
- if (channel->band == IEEE80211_BAND_60GHZ) {
+ if (channel->band == NL80211_BAND_60GHZ) {
bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
@@ -1089,7 +1093,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
if (!res)
return NULL;
- if (channel->band == IEEE80211_BAND_60GHZ) {
+ if (channel->band == NL80211_BAND_60GHZ) {
bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
@@ -1185,7 +1189,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
struct iw_scan_req *wreq = NULL;
struct cfg80211_scan_request *creq = NULL;
int i, err, n_channels = 0;
- enum ieee80211_band band;
+ enum nl80211_band band;
if (!netif_running(dev))
return -ENETDOWN;
@@ -1229,7 +1233,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
/* translate "Scan on frequencies" request */
i = 0;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
int j;
if (!wiphy->bands[band])
@@ -1289,10 +1293,12 @@ int cfg80211_wext_siwscan(struct net_device *dev,
creq->n_ssids = 0;
}
- for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ for (i = 0; i < NUM_NL80211_BANDS; i++)
if (wiphy->bands[i])
creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
+ eth_broadcast_addr(creq->bssid);
+
rdev->scan_req = creq;
err = rdev_scan(rdev, creq);
if (err) {
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 544558171..584fdc347 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -81,7 +81,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
return -ENOMEM;
if (wdev->conn->params.channel) {
- enum ieee80211_band band = wdev->conn->params.channel->band;
+ enum nl80211_band band = wdev->conn->params.channel->band;
struct ieee80211_supported_band *sband =
wdev->wiphy->bands[band];
@@ -93,11 +93,11 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
request->rates[band] = (1 << sband->n_bitrates) - 1;
} else {
int i = 0, j;
- enum ieee80211_band band;
+ enum nl80211_band band;
struct ieee80211_supported_band *bands;
struct ieee80211_channel *channel;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
bands = wdev->wiphy->bands[band];
if (!bands)
continue;
@@ -119,6 +119,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
wdev->conn->params.ssid_len);
request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
+ eth_broadcast_addr(request->bssid);
+
request->wdev = wdev;
request->wiphy = &rdev->wiphy;
request->scan_start = jiffies;
@@ -221,7 +223,7 @@ void cfg80211_conn_work(struct work_struct *work)
rtnl_lock();
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (!wdev->netdev)
continue;
@@ -490,8 +492,18 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
if (!rdev->ops->auth || !rdev->ops->assoc)
return -EOPNOTSUPP;
- if (wdev->current_bss)
- return -EALREADY;
+ if (wdev->current_bss) {
+ if (!prev_bssid)
+ return -EALREADY;
+ if (prev_bssid &&
+ !ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid))
+ return -ENOTCONN;
+ cfg80211_unhold_bss(wdev->current_bss);
+ cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
+ wdev->current_bss = NULL;
+
+ cfg80211_sme_free(wdev);
+ }
if (WARN_ON(wdev->conn))
return -EINPROGRESS;
@@ -605,7 +617,7 @@ static bool cfg80211_is_all_idle(void)
* count as new regulatory hints.
*/
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
wdev_lock(wdev);
if (wdev->conn || wdev->current_bss)
is_all_idle = false;
@@ -741,19 +753,32 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
kfree(country_ie);
}
-void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
- const u8 *req_ie, size_t req_ie_len,
- const u8 *resp_ie, size_t resp_ie_len,
- u16 status, gfp_t gfp)
+/* Consumes bss object one way or another */
+void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
+ struct cfg80211_bss *bss, const u8 *req_ie,
+ size_t req_ie_len, const u8 *resp_ie,
+ size_t resp_ie_len, u16 status, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
struct cfg80211_event *ev;
unsigned long flags;
+ if (bss) {
+ /* Make sure the bss entry provided by the driver is valid. */
+ struct cfg80211_internal_bss *ibss = bss_from_pub(bss);
+
+ if (WARN_ON(list_empty(&ibss->list))) {
+ cfg80211_put_bss(wdev->wiphy, bss);
+ return;
+ }
+ }
+
ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
- if (!ev)
+ if (!ev) {
+ cfg80211_put_bss(wdev->wiphy, bss);
return;
+ }
ev->type = EVENT_CONNECT_RESULT;
if (bssid)
@@ -768,6 +793,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
ev->cr.resp_ie_len = resp_ie_len;
memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
}
+ if (bss)
+ cfg80211_hold_bss(bss_from_pub(bss));
+ ev->cr.bss = bss;
ev->cr.status = status;
spin_lock_irqsave(&wdev->event_lock, flags);
@@ -775,7 +803,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
spin_unlock_irqrestore(&wdev->event_lock, flags);
queue_work(cfg80211_wq, &rdev->event_work);
}
-EXPORT_SYMBOL(cfg80211_connect_result);
+EXPORT_SYMBOL(cfg80211_connect_bss);
/* Consumes bss object one way or another */
void __cfg80211_roamed(struct wireless_dev *wdev,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 9cee02206..e46469bc1 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)
{
struct wireless_dev *wdev;
- list_for_each_entry(wdev, &rdev->wdev_list, list)
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
cfg80211_leave(rdev, wdev);
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 09b242b09..3c1091ae6 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -110,7 +110,7 @@
conf->dot11MeshHWMPconfirmationInterval; \
} while (0)
-#define CHAN_ENTRY __field(enum ieee80211_band, band) \
+#define CHAN_ENTRY __field(enum nl80211_band, band) \
__field(u16, center_freq)
#define CHAN_ASSIGN(chan) \
do { \
@@ -125,7 +125,7 @@
#define CHAN_PR_FMT "band: %d, freq: %u"
#define CHAN_PR_ARG __entry->band, __entry->center_freq
-#define CHAN_DEF_ENTRY __field(enum ieee80211_band, band) \
+#define CHAN_DEF_ENTRY __field(enum nl80211_band, band) \
__field(u32, control_freq) \
__field(u32, width) \
__field(u32, center_freq1) \
@@ -1259,6 +1259,7 @@ TRACE_EVENT(rdev_connect,
__field(bool, privacy)
__field(u32, wpa_versions)
__field(u32, flags)
+ MAC_ENTRY(prev_bssid)
),
TP_fast_assign(
WIPHY_ASSIGN;
@@ -1270,13 +1271,14 @@ TRACE_EVENT(rdev_connect,
__entry->privacy = sme->privacy;
__entry->wpa_versions = sme->crypto.wpa_versions;
__entry->flags = sme->flags;
+ MAC_ASSIGN(prev_bssid, sme->prev_bssid);
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, "
- "flags: %u",
+ "flags: %u, previous bssid: " MAC_PR_FMT,
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid,
__entry->auth_type, BOOL_TO_STR(__entry->privacy),
- __entry->wpa_versions, __entry->flags)
+ __entry->wpa_versions, __entry->flags, MAC_PR_ARG(prev_bssid))
);
TRACE_EVENT(rdev_set_cqm_rssi_config,
@@ -2645,7 +2647,7 @@ TRACE_EVENT(cfg80211_scan_done,
TP_STRUCT__entry(
__field(u32, n_channels)
__dynamic_array(u8, ie, request ? request->ie_len : 0)
- __array(u32, rates, IEEE80211_NUM_BANDS)
+ __array(u32, rates, NUM_NL80211_BANDS)
__field(u32, wdev_id)
MAC_ENTRY(wiphy_mac)
__field(bool, no_cck)
@@ -2656,7 +2658,7 @@ TRACE_EVENT(cfg80211_scan_done,
memcpy(__get_dynamic_array(ie), request->ie,
request->ie_len);
memcpy(__entry->rates, request->rates,
- IEEE80211_NUM_BANDS);
+ NUM_NL80211_BANDS);
__entry->wdev_id = request->wdev ?
request->wdev->identifier : 0;
if (request->wiphy)
@@ -2881,25 +2883,25 @@ TRACE_EVENT(rdev_start_radar_detection,
TRACE_EVENT(rdev_set_mcast_rate,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
- int mcast_rate[IEEE80211_NUM_BANDS]),
+ int mcast_rate[NUM_NL80211_BANDS]),
TP_ARGS(wiphy, netdev, mcast_rate),
TP_STRUCT__entry(
WIPHY_ENTRY
NETDEV_ENTRY
- __array(int, mcast_rate, IEEE80211_NUM_BANDS)
+ __array(int, mcast_rate, NUM_NL80211_BANDS)
),
TP_fast_assign(
WIPHY_ASSIGN;
NETDEV_ASSIGN;
memcpy(__entry->mcast_rate, mcast_rate,
- sizeof(int) * IEEE80211_NUM_BANDS);
+ sizeof(int) * NUM_NL80211_BANDS);
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", "
"mcast_rates [2.4GHz=0x%x, 5.2GHz=0x%x, 60GHz=0x%x]",
WIPHY_PR_ARG, NETDEV_PR_ARG,
- __entry->mcast_rate[IEEE80211_BAND_2GHZ],
- __entry->mcast_rate[IEEE80211_BAND_5GHZ],
- __entry->mcast_rate[IEEE80211_BAND_60GHZ])
+ __entry->mcast_rate[NL80211_BAND_2GHZ],
+ __entry->mcast_rate[NL80211_BAND_5GHZ],
+ __entry->mcast_rate[NL80211_BAND_60GHZ])
);
TRACE_EVENT(rdev_set_coalesce,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 47b917841..b7d1592bd 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -47,7 +47,7 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
if (WARN_ON(!sband))
return 1;
- if (sband->band == IEEE80211_BAND_2GHZ) {
+ if (sband->band == NL80211_BAND_2GHZ) {
if (scan_width == NL80211_BSS_CHAN_WIDTH_5 ||
scan_width == NL80211_BSS_CHAN_WIDTH_10)
mandatory_flag = IEEE80211_RATE_MANDATORY_G;
@@ -65,26 +65,26 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
}
EXPORT_SYMBOL(ieee80211_mandatory_rates);
-int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
+int ieee80211_channel_to_frequency(int chan, enum nl80211_band band)
{
/* see 802.11 17.3.8.3.2 and Annex J
* there are overlapping channel numbers in 5GHz and 2GHz bands */
if (chan <= 0)
return 0; /* not supported */
switch (band) {
- case IEEE80211_BAND_2GHZ:
+ case NL80211_BAND_2GHZ:
if (chan == 14)
return 2484;
else if (chan < 14)
return 2407 + chan * 5;
break;
- case IEEE80211_BAND_5GHZ:
+ case NL80211_BAND_5GHZ:
if (chan >= 182 && chan <= 196)
return 4000 + chan * 5;
else
return 5000 + chan * 5;
break;
- case IEEE80211_BAND_60GHZ:
+ case NL80211_BAND_60GHZ:
if (chan < 5)
return 56160 + chan * 2160;
break;
@@ -116,11 +116,11 @@ EXPORT_SYMBOL(ieee80211_frequency_to_channel);
struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
int freq)
{
- enum ieee80211_band band;
+ enum nl80211_band band;
struct ieee80211_supported_band *sband;
int i;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
sband = wiphy->bands[band];
if (!sband)
@@ -137,12 +137,12 @@ struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
EXPORT_SYMBOL(__ieee80211_get_channel);
static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
- enum ieee80211_band band)
+ enum nl80211_band band)
{
int i, want;
switch (band) {
- case IEEE80211_BAND_5GHZ:
+ case NL80211_BAND_5GHZ:
want = 3;
for (i = 0; i < sband->n_bitrates; i++) {
if (sband->bitrates[i].bitrate == 60 ||
@@ -155,7 +155,7 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
}
WARN_ON(want);
break;
- case IEEE80211_BAND_2GHZ:
+ case NL80211_BAND_2GHZ:
want = 7;
for (i = 0; i < sband->n_bitrates; i++) {
if (sband->bitrates[i].bitrate == 10) {
@@ -185,12 +185,12 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
}
WARN_ON(want != 0 && want != 3 && want != 6);
break;
- case IEEE80211_BAND_60GHZ:
+ case NL80211_BAND_60GHZ:
/* check for mandatory HT MCS 1..4 */
WARN_ON(!sband->ht_cap.ht_supported);
WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e);
break;
- case IEEE80211_NUM_BANDS:
+ case NUM_NL80211_BANDS:
WARN_ON(1);
break;
}
@@ -198,9 +198,9 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
{
- enum ieee80211_band band;
+ enum nl80211_band band;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ for (band = 0; band < NUM_NL80211_BANDS; band++)
if (wiphy->bands[band])
set_mandatory_flags_band(wiphy->bands[band], band);
}
@@ -651,7 +651,7 @@ __frame_add_frag(struct sk_buff *skb, struct page *page,
struct skb_shared_info *sh = skb_shinfo(skb);
int page_offset;
- atomic_inc(&page->_count);
+ page_ref_inc(page);
page_offset = ptr - page_address(page);
skb_add_rx_frag(skb, sh->nr_frags, page, page_offset, len, size);
}
@@ -721,6 +721,8 @@ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
* alignment since sizeof(struct ethhdr) is 14.
*/
frame = dev_alloc_skb(hlen + sizeof(struct ethhdr) + 2 + cur_len);
+ if (!frame)
+ return NULL;
skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len);
@@ -950,7 +952,7 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
ev->cr.resp_ie, ev->cr.resp_ie_len,
ev->cr.status,
ev->cr.status == WLAN_STATUS_SUCCESS,
- NULL);
+ ev->cr.bss);
break;
case EVENT_ROAMED:
__cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
@@ -986,7 +988,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
ASSERT_RTNL();
- list_for_each_entry(wdev, &rdev->wdev_list, list)
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
cfg80211_process_wdev_events(wdev);
}
@@ -1399,22 +1401,22 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
EXPORT_SYMBOL(ieee80211_ie_split_ric);
bool ieee80211_operating_class_to_band(u8 operating_class,
- enum ieee80211_band *band)
+ enum nl80211_band *band)
{
switch (operating_class) {
case 112:
case 115 ... 127:
case 128 ... 130:
- *band = IEEE80211_BAND_5GHZ;
+ *band = NL80211_BAND_5GHZ;
return true;
case 81:
case 82:
case 83:
case 84:
- *band = IEEE80211_BAND_2GHZ;
+ *band = NL80211_BAND_2GHZ;
return true;
case 180:
- *band = IEEE80211_BAND_60GHZ;
+ *band = NL80211_BAND_60GHZ;
return true;
}
@@ -1560,7 +1562,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
if (!beacon_int)
return -EINVAL;
- list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (!wdev->beacon_interval)
continue;
if (wdev->beacon_interval != beacon_int) {
@@ -1726,10 +1728,10 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy)
{
- enum ieee80211_band band;
+ enum nl80211_band band;
unsigned int n_channels = 0;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ for (band = 0; band < NUM_NL80211_BANDS; band++)
if (wiphy->bands[band])
n_channels += wiphy->bands[band]->n_channels;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index fd682832a..9f27221c8 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -25,42 +25,7 @@ int cfg80211_wext_giwname(struct net_device *dev,
struct iw_request_info *info,
char *name, char *extra)
{
- struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct ieee80211_supported_band *sband;
- bool is_ht = false, is_a = false, is_b = false, is_g = false;
-
- if (!wdev)
- return -EOPNOTSUPP;
-
- sband = wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
- if (sband) {
- is_a = true;
- is_ht |= sband->ht_cap.ht_supported;
- }
-
- sband = wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
- if (sband) {
- int i;
- /* Check for mandatory rates */
- for (i = 0; i < sband->n_bitrates; i++) {
- if (sband->bitrates[i].bitrate == 10)
- is_b = true;
- if (sband->bitrates[i].bitrate == 60)
- is_g = true;
- }
- is_ht |= sband->ht_cap.ht_supported;
- }
-
strcpy(name, "IEEE 802.11");
- if (is_a)
- strcat(name, "a");
- if (is_b)
- strcat(name, "b");
- if (is_g)
- strcat(name, "g");
- if (is_ht)
- strcat(name, "n");
-
return 0;
}
EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);
@@ -143,7 +108,7 @@ int cfg80211_wext_giwrange(struct net_device *dev,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct iw_range *range = (struct iw_range *) extra;
- enum ieee80211_band band;
+ enum nl80211_band band;
int i, c = 0;
if (!wdev)
@@ -215,7 +180,7 @@ int cfg80211_wext_giwrange(struct net_device *dev,
}
}
- for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band ++) {
struct ieee80211_supported_band *sband;
sband = wdev->wiphy->bands[band];
@@ -265,11 +230,11 @@ int cfg80211_wext_freq(struct iw_freq *freq)
* -EINVAL for impossible things.
*/
if (freq->e == 0) {
- enum ieee80211_band band = IEEE80211_BAND_2GHZ;
+ enum nl80211_band band = NL80211_BAND_2GHZ;
if (freq->m < 0)
return 0;
if (freq->m > 14)
- band = IEEE80211_BAND_5GHZ;
+ band = NL80211_BAND_5GHZ;
return ieee80211_channel_to_frequency(freq->m, band);
} else {
int i, div = 1000000;
@@ -1245,7 +1210,7 @@ static int cfg80211_wext_siwrate(struct net_device *dev,
maxrate = rate->value / 100000;
}
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
sband = wdev->wiphy->bands[band];
if (sband == NULL)
continue;
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index c753211cb..dbb2738e3 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -399,7 +399,10 @@ static int __init wireless_nlevent_init(void)
if (err)
return err;
- return register_netdevice_notifier(&wext_netdev_notifier);
+ err = register_netdevice_notifier(&wext_netdev_notifier);
+ if (err)
+ unregister_pernet_subsys(&wext_pernet_ops);
+ return err;
}
subsys_initcall(wireless_nlevent_init);