diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-09-15 14:51:23 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-15 14:51:23 -0400 |
commit | 6bd2bd27baf12fa0f2e6d611509fc0e1bffb0f97 (patch) | |
tree | 1aa11eb70af1e43bc122cb516bab264ddda76050 /net/wireless | |
parent | eb2eacf77ec4828c9a2e451b06bc6fc44266f4c0 (diff) | |
parent | 0d8614b4b926d0f657d15d7eb5125bcb24b9fd41 (diff) |
Merge tag 'mac80211-next-for-john-2014-09-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg <johannes@sipsolutions.net> says:
"This time, I have some rate minstrel improvements, support for a very
small feature from CCX that Steinar reverse-engineered, dynamic ACK
timeout support, a number of changes for TDLS, early support for radio
resource measurement and many fixes. Also, I'm changing a number of
places to clear key memory when it's freed and Intel claims copyright
for code they developed."
Conflicts:
net/mac80211/iface.c
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/chan.c | 1 | ||||
-rw-r--r-- | net/wireless/core.c | 3 | ||||
-rw-r--r-- | net/wireless/ibss.c | 4 | ||||
-rw-r--r-- | net/wireless/mlme.c | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 233 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 3 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 31 | ||||
-rw-r--r-- | net/wireless/reg.c | 82 | ||||
-rw-r--r-- | net/wireless/scan.c | 1 | ||||
-rw-r--r-- | net/wireless/sme.c | 6 | ||||
-rw-r--r-- | net/wireless/trace.h | 45 | ||||
-rw-r--r-- | net/wireless/util.c | 3 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 2 | ||||
-rw-r--r-- | net/wireless/wext-sme.c | 2 |
14 files changed, 366 insertions, 54 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 992b34070bcb..72d81e2154d5 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * any point in time. | 4 | * any point in time. |
5 | * | 5 | * |
6 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | #include <linux/export.h> | 10 | #include <linux/export.h> |
diff --git a/net/wireless/core.c b/net/wireless/core.c index c6620aa679e0..f52a4cd7017c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * This is the linux wireless configuration interface. | 2 | * This is the linux wireless configuration interface. |
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
@@ -1005,7 +1006,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
1005 | rdev->devlist_generation++; | 1006 | rdev->devlist_generation++; |
1006 | cfg80211_mlme_purge_registrations(wdev); | 1007 | cfg80211_mlme_purge_registrations(wdev); |
1007 | #ifdef CONFIG_CFG80211_WEXT | 1008 | #ifdef CONFIG_CFG80211_WEXT |
1008 | kfree(wdev->wext.keys); | 1009 | kzfree(wdev->wext.keys); |
1009 | #endif | 1010 | #endif |
1010 | } | 1011 | } |
1011 | /* | 1012 | /* |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 8f345da3ea5f..e24fc585c883 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -115,7 +115,7 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
115 | } | 115 | } |
116 | 116 | ||
117 | if (WARN_ON(wdev->connect_keys)) | 117 | if (WARN_ON(wdev->connect_keys)) |
118 | kfree(wdev->connect_keys); | 118 | kzfree(wdev->connect_keys); |
119 | wdev->connect_keys = connkeys; | 119 | wdev->connect_keys = connkeys; |
120 | 120 | ||
121 | wdev->ibss_fixed = params->channel_fixed; | 121 | wdev->ibss_fixed = params->channel_fixed; |
@@ -161,7 +161,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | |||
161 | 161 | ||
162 | ASSERT_WDEV_LOCK(wdev); | 162 | ASSERT_WDEV_LOCK(wdev); |
163 | 163 | ||
164 | kfree(wdev->connect_keys); | 164 | kzfree(wdev->connect_keys); |
165 | wdev->connect_keys = NULL; | 165 | wdev->connect_keys = NULL; |
166 | 166 | ||
167 | rdev_set_qos_map(rdev, dev, NULL); | 167 | rdev_set_qos_map(rdev, dev, NULL); |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 369fc334fdad..2c52b59e43f3 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | 20 | ||
21 | void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | 21 | void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, |
22 | const u8 *buf, size_t len) | 22 | const u8 *buf, size_t len, int uapsd_queues) |
23 | { | 23 | { |
24 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 24 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
25 | struct wiphy *wiphy = wdev->wiphy; | 25 | struct wiphy *wiphy = wdev->wiphy; |
@@ -43,7 +43,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | |||
43 | return; | 43 | return; |
44 | } | 44 | } |
45 | 45 | ||
46 | nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); | 46 | nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues); |
47 | /* update current_bss etc., consumes the bss reference */ | 47 | /* update current_bss etc., consumes the bss reference */ |
48 | __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, | 48 | __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, |
49 | status_code, | 49 | status_code, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 3011401f52c0..4cce3e17964d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * This is the new netlink-based wireless configuration interface. | 2 | * This is the new netlink-based wireless configuration interface. |
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | #include <linux/if.h> | 8 | #include <linux/if.h> |
@@ -225,6 +226,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
225 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, | 226 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, |
226 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, | 227 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, |
227 | [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, | 228 | [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, |
229 | [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG }, | ||
228 | 230 | ||
229 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, | 231 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, |
230 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 232 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
@@ -388,6 +390,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
388 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, | 390 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, |
389 | [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, | 391 | [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, |
390 | [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, | 392 | [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, |
393 | [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG }, | ||
394 | [NL80211_ATTR_TSID] = { .type = NLA_U8 }, | ||
395 | [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 }, | ||
396 | [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, | ||
397 | [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, | ||
391 | }; | 398 | }; |
392 | 399 | ||
393 | /* policy for the key attributes */ | 400 | /* policy for the key attributes */ |
@@ -1507,6 +1514,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1507 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) | 1514 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) |
1508 | CMD(channel_switch, CHANNEL_SWITCH); | 1515 | CMD(channel_switch, CHANNEL_SWITCH); |
1509 | CMD(set_qos_map, SET_QOS_MAP); | 1516 | CMD(set_qos_map, SET_QOS_MAP); |
1517 | if (rdev->wiphy.flags & | ||
1518 | WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) | ||
1519 | CMD(add_tx_ts, ADD_TX_TS); | ||
1510 | } | 1520 | } |
1511 | /* add into the if now */ | 1521 | /* add into the if now */ |
1512 | #undef CMD | 1522 | #undef CMD |
@@ -2237,11 +2247,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
2237 | } | 2247 | } |
2238 | 2248 | ||
2239 | if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { | 2249 | if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { |
2250 | if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) | ||
2251 | return -EINVAL; | ||
2252 | |||
2240 | coverage_class = nla_get_u8( | 2253 | coverage_class = nla_get_u8( |
2241 | info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); | 2254 | info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); |
2242 | changed |= WIPHY_PARAM_COVERAGE_CLASS; | 2255 | changed |= WIPHY_PARAM_COVERAGE_CLASS; |
2243 | } | 2256 | } |
2244 | 2257 | ||
2258 | if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) { | ||
2259 | if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) | ||
2260 | return -EOPNOTSUPP; | ||
2261 | |||
2262 | changed |= WIPHY_PARAM_DYN_ACK; | ||
2263 | } | ||
2264 | |||
2245 | if (changed) { | 2265 | if (changed) { |
2246 | u8 old_retry_short, old_retry_long; | 2266 | u8 old_retry_short, old_retry_long; |
2247 | u32 old_frag_threshold, old_rts_threshold; | 2267 | u32 old_frag_threshold, old_rts_threshold; |
@@ -3326,6 +3346,29 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
3326 | return PTR_ERR(params.acl); | 3346 | return PTR_ERR(params.acl); |
3327 | } | 3347 | } |
3328 | 3348 | ||
3349 | if (info->attrs[NL80211_ATTR_SMPS_MODE]) { | ||
3350 | params.smps_mode = | ||
3351 | nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]); | ||
3352 | switch (params.smps_mode) { | ||
3353 | case NL80211_SMPS_OFF: | ||
3354 | break; | ||
3355 | case NL80211_SMPS_STATIC: | ||
3356 | if (!(rdev->wiphy.features & | ||
3357 | NL80211_FEATURE_STATIC_SMPS)) | ||
3358 | return -EINVAL; | ||
3359 | break; | ||
3360 | case NL80211_SMPS_DYNAMIC: | ||
3361 | if (!(rdev->wiphy.features & | ||
3362 | NL80211_FEATURE_DYNAMIC_SMPS)) | ||
3363 | return -EINVAL; | ||
3364 | break; | ||
3365 | default: | ||
3366 | return -EINVAL; | ||
3367 | } | ||
3368 | } else { | ||
3369 | params.smps_mode = NL80211_SMPS_OFF; | ||
3370 | } | ||
3371 | |||
3329 | wdev_lock(wdev); | 3372 | wdev_lock(wdev); |
3330 | err = rdev_start_ap(rdev, dev, ¶ms); | 3373 | err = rdev_start_ap(rdev, dev, ¶ms); |
3331 | if (!err) { | 3374 | if (!err) { |
@@ -6583,6 +6626,14 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
6583 | sizeof(req.vht_capa)); | 6626 | sizeof(req.vht_capa)); |
6584 | } | 6627 | } |
6585 | 6628 | ||
6629 | if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { | ||
6630 | if (!(rdev->wiphy.features & | ||
6631 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || | ||
6632 | !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) | ||
6633 | return -EINVAL; | ||
6634 | req.flags |= ASSOC_REQ_USE_RRM; | ||
6635 | } | ||
6636 | |||
6586 | err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); | 6637 | err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); |
6587 | if (!err) { | 6638 | if (!err) { |
6588 | wdev_lock(dev->ieee80211_ptr); | 6639 | wdev_lock(dev->ieee80211_ptr); |
@@ -6845,7 +6896,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
6845 | 6896 | ||
6846 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 6897 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); |
6847 | if (err) | 6898 | if (err) |
6848 | kfree(connkeys); | 6899 | kzfree(connkeys); |
6849 | return err; | 6900 | return err; |
6850 | } | 6901 | } |
6851 | 6902 | ||
@@ -7214,7 +7265,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7214 | 7265 | ||
7215 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | 7266 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { |
7216 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { | 7267 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { |
7217 | kfree(connkeys); | 7268 | kzfree(connkeys); |
7218 | return -EINVAL; | 7269 | return -EINVAL; |
7219 | } | 7270 | } |
7220 | memcpy(&connect.ht_capa, | 7271 | memcpy(&connect.ht_capa, |
@@ -7232,7 +7283,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7232 | 7283 | ||
7233 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) { | 7284 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) { |
7234 | if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) { | 7285 | if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) { |
7235 | kfree(connkeys); | 7286 | kzfree(connkeys); |
7236 | return -EINVAL; | 7287 | return -EINVAL; |
7237 | } | 7288 | } |
7238 | memcpy(&connect.vht_capa, | 7289 | memcpy(&connect.vht_capa, |
@@ -7240,11 +7291,19 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7240 | sizeof(connect.vht_capa)); | 7291 | sizeof(connect.vht_capa)); |
7241 | } | 7292 | } |
7242 | 7293 | ||
7294 | if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { | ||
7295 | if (!(rdev->wiphy.features & | ||
7296 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || | ||
7297 | !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) | ||
7298 | return -EINVAL; | ||
7299 | connect.flags |= ASSOC_REQ_USE_RRM; | ||
7300 | } | ||
7301 | |||
7243 | wdev_lock(dev->ieee80211_ptr); | 7302 | wdev_lock(dev->ieee80211_ptr); |
7244 | err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL); | 7303 | err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL); |
7245 | wdev_unlock(dev->ieee80211_ptr); | 7304 | wdev_unlock(dev->ieee80211_ptr); |
7246 | if (err) | 7305 | if (err) |
7247 | kfree(connkeys); | 7306 | kzfree(connkeys); |
7248 | return err; | 7307 | return err; |
7249 | } | 7308 | } |
7250 | 7309 | ||
@@ -8930,13 +8989,9 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) | |||
8930 | if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) | 8989 | if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) |
8931 | return -ERANGE; | 8990 | return -ERANGE; |
8932 | 8991 | ||
8933 | memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]), | 8992 | rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]); |
8934 | NL80211_KEK_LEN); | 8993 | rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]); |
8935 | memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]), | 8994 | rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]); |
8936 | NL80211_KCK_LEN); | ||
8937 | memcpy(rekey_data.replay_ctr, | ||
8938 | nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]), | ||
8939 | NL80211_REPLAY_CTR_LEN); | ||
8940 | 8995 | ||
8941 | wdev_lock(wdev); | 8996 | wdev_lock(wdev); |
8942 | if (!wdev->current_bss) { | 8997 | if (!wdev->current_bss) { |
@@ -9365,6 +9420,93 @@ static int nl80211_set_qos_map(struct sk_buff *skb, | |||
9365 | return ret; | 9420 | return ret; |
9366 | } | 9421 | } |
9367 | 9422 | ||
9423 | static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) | ||
9424 | { | ||
9425 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
9426 | struct net_device *dev = info->user_ptr[1]; | ||
9427 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
9428 | const u8 *peer; | ||
9429 | u8 tsid, up; | ||
9430 | u16 admitted_time = 0; | ||
9431 | int err; | ||
9432 | |||
9433 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) | ||
9434 | return -EOPNOTSUPP; | ||
9435 | |||
9436 | if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || | ||
9437 | !info->attrs[NL80211_ATTR_USER_PRIO]) | ||
9438 | return -EINVAL; | ||
9439 | |||
9440 | tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]); | ||
9441 | if (tsid >= IEEE80211_NUM_TIDS) | ||
9442 | return -EINVAL; | ||
9443 | |||
9444 | up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]); | ||
9445 | if (up >= IEEE80211_NUM_UPS) | ||
9446 | return -EINVAL; | ||
9447 | |||
9448 | /* WMM uses TIDs 0-7 even for TSPEC */ | ||
9449 | if (tsid < IEEE80211_FIRST_TSPEC_TSID) { | ||
9450 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) | ||
9451 | return -EINVAL; | ||
9452 | } else { | ||
9453 | /* TODO: handle 802.11 TSPEC/admission control | ||
9454 | * need more attributes for that (e.g. BA session requirement) | ||
9455 | */ | ||
9456 | return -EINVAL; | ||
9457 | } | ||
9458 | |||
9459 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
9460 | |||
9461 | if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) { | ||
9462 | admitted_time = | ||
9463 | nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]); | ||
9464 | if (!admitted_time) | ||
9465 | return -EINVAL; | ||
9466 | } | ||
9467 | |||
9468 | wdev_lock(wdev); | ||
9469 | switch (wdev->iftype) { | ||
9470 | case NL80211_IFTYPE_STATION: | ||
9471 | case NL80211_IFTYPE_P2P_CLIENT: | ||
9472 | if (wdev->current_bss) | ||
9473 | break; | ||
9474 | err = -ENOTCONN; | ||
9475 | goto out; | ||
9476 | default: | ||
9477 | err = -EOPNOTSUPP; | ||
9478 | goto out; | ||
9479 | } | ||
9480 | |||
9481 | err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time); | ||
9482 | |||
9483 | out: | ||
9484 | wdev_unlock(wdev); | ||
9485 | return err; | ||
9486 | } | ||
9487 | |||
9488 | static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info) | ||
9489 | { | ||
9490 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
9491 | struct net_device *dev = info->user_ptr[1]; | ||
9492 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
9493 | const u8 *peer; | ||
9494 | u8 tsid; | ||
9495 | int err; | ||
9496 | |||
9497 | if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC]) | ||
9498 | return -EINVAL; | ||
9499 | |||
9500 | tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]); | ||
9501 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
9502 | |||
9503 | wdev_lock(wdev); | ||
9504 | err = rdev_del_tx_ts(rdev, dev, tsid, peer); | ||
9505 | wdev_unlock(wdev); | ||
9506 | |||
9507 | return err; | ||
9508 | } | ||
9509 | |||
9368 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 9510 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
9369 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 9511 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
9370 | #define NL80211_FLAG_NEED_RTNL 0x04 | 9512 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -9375,6 +9517,7 @@ static int nl80211_set_qos_map(struct sk_buff *skb, | |||
9375 | /* If a netdev is associated, it must be UP, P2P must be started */ | 9517 | /* If a netdev is associated, it must be UP, P2P must be started */ |
9376 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ | 9518 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ |
9377 | NL80211_FLAG_CHECK_NETDEV_UP) | 9519 | NL80211_FLAG_CHECK_NETDEV_UP) |
9520 | #define NL80211_FLAG_CLEAR_SKB 0x20 | ||
9378 | 9521 | ||
9379 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, | 9522 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, |
9380 | struct genl_info *info) | 9523 | struct genl_info *info) |
@@ -9458,8 +9601,20 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, | |||
9458 | dev_put(info->user_ptr[1]); | 9601 | dev_put(info->user_ptr[1]); |
9459 | } | 9602 | } |
9460 | } | 9603 | } |
9604 | |||
9461 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) | 9605 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) |
9462 | rtnl_unlock(); | 9606 | rtnl_unlock(); |
9607 | |||
9608 | /* If needed, clear the netlink message payload from the SKB | ||
9609 | * as it might contain key data that shouldn't stick around on | ||
9610 | * the heap after the SKB is freed. The netlink message header | ||
9611 | * is still needed for further processing, so leave it intact. | ||
9612 | */ | ||
9613 | if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) { | ||
9614 | struct nlmsghdr *nlh = nlmsg_hdr(skb); | ||
9615 | |||
9616 | memset(nlmsg_data(nlh), 0, nlmsg_len(nlh)); | ||
9617 | } | ||
9463 | } | 9618 | } |
9464 | 9619 | ||
9465 | static const struct genl_ops nl80211_ops[] = { | 9620 | static const struct genl_ops nl80211_ops[] = { |
@@ -9527,7 +9682,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9527 | .policy = nl80211_policy, | 9682 | .policy = nl80211_policy, |
9528 | .flags = GENL_ADMIN_PERM, | 9683 | .flags = GENL_ADMIN_PERM, |
9529 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 9684 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9530 | NL80211_FLAG_NEED_RTNL, | 9685 | NL80211_FLAG_NEED_RTNL | |
9686 | NL80211_FLAG_CLEAR_SKB, | ||
9531 | }, | 9687 | }, |
9532 | { | 9688 | { |
9533 | .cmd = NL80211_CMD_NEW_KEY, | 9689 | .cmd = NL80211_CMD_NEW_KEY, |
@@ -9535,7 +9691,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9535 | .policy = nl80211_policy, | 9691 | .policy = nl80211_policy, |
9536 | .flags = GENL_ADMIN_PERM, | 9692 | .flags = GENL_ADMIN_PERM, |
9537 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 9693 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9538 | NL80211_FLAG_NEED_RTNL, | 9694 | NL80211_FLAG_NEED_RTNL | |
9695 | NL80211_FLAG_CLEAR_SKB, | ||
9539 | }, | 9696 | }, |
9540 | { | 9697 | { |
9541 | .cmd = NL80211_CMD_DEL_KEY, | 9698 | .cmd = NL80211_CMD_DEL_KEY, |
@@ -9713,7 +9870,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9713 | .policy = nl80211_policy, | 9870 | .policy = nl80211_policy, |
9714 | .flags = GENL_ADMIN_PERM, | 9871 | .flags = GENL_ADMIN_PERM, |
9715 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 9872 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9716 | NL80211_FLAG_NEED_RTNL, | 9873 | NL80211_FLAG_NEED_RTNL | |
9874 | NL80211_FLAG_CLEAR_SKB, | ||
9717 | }, | 9875 | }, |
9718 | { | 9876 | { |
9719 | .cmd = NL80211_CMD_ASSOCIATE, | 9877 | .cmd = NL80211_CMD_ASSOCIATE, |
@@ -9947,7 +10105,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9947 | .policy = nl80211_policy, | 10105 | .policy = nl80211_policy, |
9948 | .flags = GENL_ADMIN_PERM, | 10106 | .flags = GENL_ADMIN_PERM, |
9949 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 10107 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9950 | NL80211_FLAG_NEED_RTNL, | 10108 | NL80211_FLAG_NEED_RTNL | |
10109 | NL80211_FLAG_CLEAR_SKB, | ||
9951 | }, | 10110 | }, |
9952 | { | 10111 | { |
9953 | .cmd = NL80211_CMD_TDLS_MGMT, | 10112 | .cmd = NL80211_CMD_TDLS_MGMT, |
@@ -10105,6 +10264,22 @@ static const struct genl_ops nl80211_ops[] = { | |||
10105 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 10264 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
10106 | NL80211_FLAG_NEED_RTNL, | 10265 | NL80211_FLAG_NEED_RTNL, |
10107 | }, | 10266 | }, |
10267 | { | ||
10268 | .cmd = NL80211_CMD_ADD_TX_TS, | ||
10269 | .doit = nl80211_add_tx_ts, | ||
10270 | .policy = nl80211_policy, | ||
10271 | .flags = GENL_ADMIN_PERM, | ||
10272 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
10273 | NL80211_FLAG_NEED_RTNL, | ||
10274 | }, | ||
10275 | { | ||
10276 | .cmd = NL80211_CMD_DEL_TX_TS, | ||
10277 | .doit = nl80211_del_tx_ts, | ||
10278 | .policy = nl80211_policy, | ||
10279 | .flags = GENL_ADMIN_PERM, | ||
10280 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
10281 | NL80211_FLAG_NEED_RTNL, | ||
10282 | }, | ||
10108 | }; | 10283 | }; |
10109 | 10284 | ||
10110 | /* notification functions */ | 10285 | /* notification functions */ |
@@ -10373,7 +10548,8 @@ nla_put_failure: | |||
10373 | static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | 10548 | static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, |
10374 | struct net_device *netdev, | 10549 | struct net_device *netdev, |
10375 | const u8 *buf, size_t len, | 10550 | const u8 *buf, size_t len, |
10376 | enum nl80211_commands cmd, gfp_t gfp) | 10551 | enum nl80211_commands cmd, gfp_t gfp, |
10552 | int uapsd_queues) | ||
10377 | { | 10553 | { |
10378 | struct sk_buff *msg; | 10554 | struct sk_buff *msg; |
10379 | void *hdr; | 10555 | void *hdr; |
@@ -10393,6 +10569,19 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | |||
10393 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) | 10569 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) |
10394 | goto nla_put_failure; | 10570 | goto nla_put_failure; |
10395 | 10571 | ||
10572 | if (uapsd_queues >= 0) { | ||
10573 | struct nlattr *nla_wmm = | ||
10574 | nla_nest_start(msg, NL80211_ATTR_STA_WME); | ||
10575 | if (!nla_wmm) | ||
10576 | goto nla_put_failure; | ||
10577 | |||
10578 | if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES, | ||
10579 | uapsd_queues)) | ||
10580 | goto nla_put_failure; | ||
10581 | |||
10582 | nla_nest_end(msg, nla_wmm); | ||
10583 | } | ||
10584 | |||
10396 | genlmsg_end(msg, hdr); | 10585 | genlmsg_end(msg, hdr); |
10397 | 10586 | ||
10398 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 10587 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
@@ -10409,15 +10598,15 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, | |||
10409 | size_t len, gfp_t gfp) | 10598 | size_t len, gfp_t gfp) |
10410 | { | 10599 | { |
10411 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10600 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10412 | NL80211_CMD_AUTHENTICATE, gfp); | 10601 | NL80211_CMD_AUTHENTICATE, gfp, -1); |
10413 | } | 10602 | } |
10414 | 10603 | ||
10415 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, | 10604 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, |
10416 | struct net_device *netdev, const u8 *buf, | 10605 | struct net_device *netdev, const u8 *buf, |
10417 | size_t len, gfp_t gfp) | 10606 | size_t len, gfp_t gfp, int uapsd_queues) |
10418 | { | 10607 | { |
10419 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10608 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10420 | NL80211_CMD_ASSOCIATE, gfp); | 10609 | NL80211_CMD_ASSOCIATE, gfp, uapsd_queues); |
10421 | } | 10610 | } |
10422 | 10611 | ||
10423 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | 10612 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, |
@@ -10425,7 +10614,7 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | |||
10425 | size_t len, gfp_t gfp) | 10614 | size_t len, gfp_t gfp) |
10426 | { | 10615 | { |
10427 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10616 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10428 | NL80211_CMD_DEAUTHENTICATE, gfp); | 10617 | NL80211_CMD_DEAUTHENTICATE, gfp, -1); |
10429 | } | 10618 | } |
10430 | 10619 | ||
10431 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, | 10620 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, |
@@ -10433,7 +10622,7 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, | |||
10433 | size_t len, gfp_t gfp) | 10622 | size_t len, gfp_t gfp) |
10434 | { | 10623 | { |
10435 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10624 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10436 | NL80211_CMD_DISASSOCIATE, gfp); | 10625 | NL80211_CMD_DISASSOCIATE, gfp, -1); |
10437 | } | 10626 | } |
10438 | 10627 | ||
10439 | void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, | 10628 | void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, |
@@ -10454,7 +10643,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, | |||
10454 | cmd = NL80211_CMD_UNPROT_DISASSOCIATE; | 10643 | cmd = NL80211_CMD_UNPROT_DISASSOCIATE; |
10455 | 10644 | ||
10456 | trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); | 10645 | trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); |
10457 | nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC); | 10646 | nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1); |
10458 | } | 10647 | } |
10459 | EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); | 10648 | EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); |
10460 | 10649 | ||
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 49c9a482dd12..7ad70d6f0cc6 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -23,7 +23,8 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, | |||
23 | const u8 *buf, size_t len, gfp_t gfp); | 23 | const u8 *buf, size_t len, gfp_t gfp); |
24 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, | 24 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, |
25 | struct net_device *netdev, | 25 | struct net_device *netdev, |
26 | const u8 *buf, size_t len, gfp_t gfp); | 26 | const u8 *buf, size_t len, gfp_t gfp, |
27 | int uapsd_queues); | ||
27 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | 28 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, |
28 | struct net_device *netdev, | 29 | struct net_device *netdev, |
29 | const u8 *buf, size_t len, gfp_t gfp); | 30 | const u8 *buf, size_t len, gfp_t gfp); |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 56c2240c30ce..f6d457d6a558 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -915,4 +915,35 @@ rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, | |||
915 | return ret; | 915 | return ret; |
916 | } | 916 | } |
917 | 917 | ||
918 | static inline int | ||
919 | rdev_add_tx_ts(struct cfg80211_registered_device *rdev, | ||
920 | struct net_device *dev, u8 tsid, const u8 *peer, | ||
921 | u8 user_prio, u16 admitted_time) | ||
922 | { | ||
923 | int ret = -EOPNOTSUPP; | ||
924 | |||
925 | trace_rdev_add_tx_ts(&rdev->wiphy, dev, tsid, peer, | ||
926 | user_prio, admitted_time); | ||
927 | if (rdev->ops->add_tx_ts) | ||
928 | ret = rdev->ops->add_tx_ts(&rdev->wiphy, dev, tsid, peer, | ||
929 | user_prio, admitted_time); | ||
930 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
931 | |||
932 | return ret; | ||
933 | } | ||
934 | |||
935 | static inline int | ||
936 | rdev_del_tx_ts(struct cfg80211_registered_device *rdev, | ||
937 | struct net_device *dev, u8 tsid, const u8 *peer) | ||
938 | { | ||
939 | int ret = -EOPNOTSUPP; | ||
940 | |||
941 | trace_rdev_del_tx_ts(&rdev->wiphy, dev, tsid, peer); | ||
942 | if (rdev->ops->del_tx_ts) | ||
943 | ret = rdev->ops->del_tx_ts(&rdev->wiphy, dev, tsid, peer); | ||
944 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
945 | |||
946 | return ret; | ||
947 | } | ||
948 | |||
918 | #endif /* __CFG80211_RDEV_OPS */ | 949 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 1afdf45db38f..b725a31a4751 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> | 5 | * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * Permission to use, copy, modify, and/or distribute this software for any | 8 | * Permission to use, copy, modify, and/or distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above | 9 | * purpose with or without fee is hereby granted, provided that the above |
@@ -798,6 +799,57 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
798 | return 0; | 799 | return 0; |
799 | } | 800 | } |
800 | 801 | ||
802 | /* check whether old rule contains new rule */ | ||
803 | static bool rule_contains(struct ieee80211_reg_rule *r1, | ||
804 | struct ieee80211_reg_rule *r2) | ||
805 | { | ||
806 | /* for simplicity, currently consider only same flags */ | ||
807 | if (r1->flags != r2->flags) | ||
808 | return false; | ||
809 | |||
810 | /* verify r1 is more restrictive */ | ||
811 | if ((r1->power_rule.max_antenna_gain > | ||
812 | r2->power_rule.max_antenna_gain) || | ||
813 | r1->power_rule.max_eirp > r2->power_rule.max_eirp) | ||
814 | return false; | ||
815 | |||
816 | /* make sure r2's range is contained within r1 */ | ||
817 | if (r1->freq_range.start_freq_khz > r2->freq_range.start_freq_khz || | ||
818 | r1->freq_range.end_freq_khz < r2->freq_range.end_freq_khz) | ||
819 | return false; | ||
820 | |||
821 | /* and finally verify that r1.max_bw >= r2.max_bw */ | ||
822 | if (r1->freq_range.max_bandwidth_khz < | ||
823 | r2->freq_range.max_bandwidth_khz) | ||
824 | return false; | ||
825 | |||
826 | return true; | ||
827 | } | ||
828 | |||
829 | /* add or extend current rules. do nothing if rule is already contained */ | ||
830 | static void add_rule(struct ieee80211_reg_rule *rule, | ||
831 | struct ieee80211_reg_rule *reg_rules, u32 *n_rules) | ||
832 | { | ||
833 | struct ieee80211_reg_rule *tmp_rule; | ||
834 | int i; | ||
835 | |||
836 | for (i = 0; i < *n_rules; i++) { | ||
837 | tmp_rule = ®_rules[i]; | ||
838 | /* rule is already contained - do nothing */ | ||
839 | if (rule_contains(tmp_rule, rule)) | ||
840 | return; | ||
841 | |||
842 | /* extend rule if possible */ | ||
843 | if (rule_contains(rule, tmp_rule)) { | ||
844 | memcpy(tmp_rule, rule, sizeof(*rule)); | ||
845 | return; | ||
846 | } | ||
847 | } | ||
848 | |||
849 | memcpy(®_rules[*n_rules], rule, sizeof(*rule)); | ||
850 | (*n_rules)++; | ||
851 | } | ||
852 | |||
801 | /** | 853 | /** |
802 | * regdom_intersect - do the intersection between two regulatory domains | 854 | * regdom_intersect - do the intersection between two regulatory domains |
803 | * @rd1: first regulatory domain | 855 | * @rd1: first regulatory domain |
@@ -817,12 +869,10 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, | |||
817 | { | 869 | { |
818 | int r, size_of_regd; | 870 | int r, size_of_regd; |
819 | unsigned int x, y; | 871 | unsigned int x, y; |
820 | unsigned int num_rules = 0, rule_idx = 0; | 872 | unsigned int num_rules = 0; |
821 | const struct ieee80211_reg_rule *rule1, *rule2; | 873 | const struct ieee80211_reg_rule *rule1, *rule2; |
822 | struct ieee80211_reg_rule *intersected_rule; | 874 | struct ieee80211_reg_rule intersected_rule; |
823 | struct ieee80211_regdomain *rd; | 875 | struct ieee80211_regdomain *rd; |
824 | /* This is just a dummy holder to help us count */ | ||
825 | struct ieee80211_reg_rule dummy_rule; | ||
826 | 876 | ||
827 | if (!rd1 || !rd2) | 877 | if (!rd1 || !rd2) |
828 | return NULL; | 878 | return NULL; |
@@ -840,7 +890,7 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, | |||
840 | for (y = 0; y < rd2->n_reg_rules; y++) { | 890 | for (y = 0; y < rd2->n_reg_rules; y++) { |
841 | rule2 = &rd2->reg_rules[y]; | 891 | rule2 = &rd2->reg_rules[y]; |
842 | if (!reg_rules_intersect(rd1, rd2, rule1, rule2, | 892 | if (!reg_rules_intersect(rd1, rd2, rule1, rule2, |
843 | &dummy_rule)) | 893 | &intersected_rule)) |
844 | num_rules++; | 894 | num_rules++; |
845 | } | 895 | } |
846 | } | 896 | } |
@@ -855,34 +905,24 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, | |||
855 | if (!rd) | 905 | if (!rd) |
856 | return NULL; | 906 | return NULL; |
857 | 907 | ||
858 | for (x = 0; x < rd1->n_reg_rules && rule_idx < num_rules; x++) { | 908 | for (x = 0; x < rd1->n_reg_rules; x++) { |
859 | rule1 = &rd1->reg_rules[x]; | 909 | rule1 = &rd1->reg_rules[x]; |
860 | for (y = 0; y < rd2->n_reg_rules && rule_idx < num_rules; y++) { | 910 | for (y = 0; y < rd2->n_reg_rules; y++) { |
861 | rule2 = &rd2->reg_rules[y]; | 911 | rule2 = &rd2->reg_rules[y]; |
862 | /* | ||
863 | * This time around instead of using the stack lets | ||
864 | * write to the target rule directly saving ourselves | ||
865 | * a memcpy() | ||
866 | */ | ||
867 | intersected_rule = &rd->reg_rules[rule_idx]; | ||
868 | r = reg_rules_intersect(rd1, rd2, rule1, rule2, | 912 | r = reg_rules_intersect(rd1, rd2, rule1, rule2, |
869 | intersected_rule); | 913 | &intersected_rule); |
870 | /* | 914 | /* |
871 | * No need to memset here the intersected rule here as | 915 | * No need to memset here the intersected rule here as |
872 | * we're not using the stack anymore | 916 | * we're not using the stack anymore |
873 | */ | 917 | */ |
874 | if (r) | 918 | if (r) |
875 | continue; | 919 | continue; |
876 | rule_idx++; | ||
877 | } | ||
878 | } | ||
879 | 920 | ||
880 | if (rule_idx != num_rules) { | 921 | add_rule(&intersected_rule, rd->reg_rules, |
881 | kfree(rd); | 922 | &rd->n_reg_rules); |
882 | return NULL; | 923 | } |
883 | } | 924 | } |
884 | 925 | ||
885 | rd->n_reg_rules = num_rules; | ||
886 | rd->alpha2[0] = '9'; | 926 | rd->alpha2[0] = '9'; |
887 | rd->alpha2[1] = '8'; | 927 | rd->alpha2[1] = '8'; |
888 | rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region, | 928 | rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 620a4b40d466..bda39f149810 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * cfg80211 scan result handling | 2 | * cfg80211 scan result handling |
3 | * | 3 | * |
4 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
7 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 8bbeeb302216..dc1668ff543b 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -641,7 +641,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
641 | } | 641 | } |
642 | 642 | ||
643 | if (status != WLAN_STATUS_SUCCESS) { | 643 | if (status != WLAN_STATUS_SUCCESS) { |
644 | kfree(wdev->connect_keys); | 644 | kzfree(wdev->connect_keys); |
645 | wdev->connect_keys = NULL; | 645 | wdev->connect_keys = NULL; |
646 | wdev->ssid_len = 0; | 646 | wdev->ssid_len = 0; |
647 | if (bss) { | 647 | if (bss) { |
@@ -918,7 +918,7 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
918 | ASSERT_WDEV_LOCK(wdev); | 918 | ASSERT_WDEV_LOCK(wdev); |
919 | 919 | ||
920 | if (WARN_ON(wdev->connect_keys)) { | 920 | if (WARN_ON(wdev->connect_keys)) { |
921 | kfree(wdev->connect_keys); | 921 | kzfree(wdev->connect_keys); |
922 | wdev->connect_keys = NULL; | 922 | wdev->connect_keys = NULL; |
923 | } | 923 | } |
924 | 924 | ||
@@ -978,7 +978,7 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
978 | 978 | ||
979 | ASSERT_WDEV_LOCK(wdev); | 979 | ASSERT_WDEV_LOCK(wdev); |
980 | 980 | ||
981 | kfree(wdev->connect_keys); | 981 | kzfree(wdev->connect_keys); |
982 | wdev->connect_keys = NULL; | 982 | wdev->connect_keys = NULL; |
983 | 983 | ||
984 | if (wdev->conn) | 984 | if (wdev->conn) |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 0c524cd76c83..625a6e6d1168 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1896,6 +1896,51 @@ TRACE_EVENT(rdev_set_ap_chanwidth, | |||
1896 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) | 1896 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) |
1897 | ); | 1897 | ); |
1898 | 1898 | ||
1899 | TRACE_EVENT(rdev_add_tx_ts, | ||
1900 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1901 | u8 tsid, const u8 *peer, u8 user_prio, u16 admitted_time), | ||
1902 | TP_ARGS(wiphy, netdev, tsid, peer, user_prio, admitted_time), | ||
1903 | TP_STRUCT__entry( | ||
1904 | WIPHY_ENTRY | ||
1905 | NETDEV_ENTRY | ||
1906 | MAC_ENTRY(peer) | ||
1907 | __field(u8, tsid) | ||
1908 | __field(u8, user_prio) | ||
1909 | __field(u16, admitted_time) | ||
1910 | ), | ||
1911 | TP_fast_assign( | ||
1912 | WIPHY_ASSIGN; | ||
1913 | NETDEV_ASSIGN; | ||
1914 | MAC_ASSIGN(peer, peer); | ||
1915 | __entry->tsid = tsid; | ||
1916 | __entry->user_prio = user_prio; | ||
1917 | __entry->admitted_time = admitted_time; | ||
1918 | ), | ||
1919 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", TSID %d, UP %d, time %d", | ||
1920 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), | ||
1921 | __entry->tsid, __entry->user_prio, __entry->admitted_time) | ||
1922 | ); | ||
1923 | |||
1924 | TRACE_EVENT(rdev_del_tx_ts, | ||
1925 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1926 | u8 tsid, const u8 *peer), | ||
1927 | TP_ARGS(wiphy, netdev, tsid, peer), | ||
1928 | TP_STRUCT__entry( | ||
1929 | WIPHY_ENTRY | ||
1930 | NETDEV_ENTRY | ||
1931 | MAC_ENTRY(peer) | ||
1932 | __field(u8, tsid) | ||
1933 | ), | ||
1934 | TP_fast_assign( | ||
1935 | WIPHY_ASSIGN; | ||
1936 | NETDEV_ASSIGN; | ||
1937 | MAC_ASSIGN(peer, peer); | ||
1938 | __entry->tsid = tsid; | ||
1939 | ), | ||
1940 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", TSID %d", | ||
1941 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tsid) | ||
1942 | ); | ||
1943 | |||
1899 | /************************************************************* | 1944 | /************************************************************* |
1900 | * cfg80211 exported functions traces * | 1945 | * cfg80211 exported functions traces * |
1901 | *************************************************************/ | 1946 | *************************************************************/ |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 728f1c0dc70d..5e233a577d0f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Wireless utility functions | 2 | * Wireless utility functions |
3 | * | 3 | * |
4 | * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | #include <linux/export.h> | 7 | #include <linux/export.h> |
7 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
@@ -796,7 +797,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | |||
796 | netdev_err(dev, "failed to set mgtdef %d\n", i); | 797 | netdev_err(dev, "failed to set mgtdef %d\n", i); |
797 | } | 798 | } |
798 | 799 | ||
799 | kfree(wdev->connect_keys); | 800 | kzfree(wdev->connect_keys); |
800 | wdev->connect_keys = NULL; | 801 | wdev->connect_keys = NULL; |
801 | } | 802 | } |
802 | 803 | ||
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 11120bb14162..0f47948c572f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -496,6 +496,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
496 | err = 0; | 496 | err = 0; |
497 | if (!err) { | 497 | if (!err) { |
498 | if (!addr) { | 498 | if (!addr) { |
499 | memset(wdev->wext.keys->data[idx], 0, | ||
500 | sizeof(wdev->wext.keys->data[idx])); | ||
499 | wdev->wext.keys->params[idx].key_len = 0; | 501 | wdev->wext.keys->params[idx].key_len = 0; |
500 | wdev->wext.keys->params[idx].cipher = 0; | 502 | wdev->wext.keys->params[idx].cipher = 0; |
501 | } | 503 | } |
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index c7e5c8eb4f24..368611c05739 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c | |||
@@ -57,7 +57,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | |||
57 | err = cfg80211_connect(rdev, wdev->netdev, | 57 | err = cfg80211_connect(rdev, wdev->netdev, |
58 | &wdev->wext.connect, ck, prev_bssid); | 58 | &wdev->wext.connect, ck, prev_bssid); |
59 | if (err) | 59 | if (err) |
60 | kfree(ck); | 60 | kzfree(ck); |
61 | 61 | ||
62 | return err; | 62 | return err; |
63 | } | 63 | } |