aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-09-15 14:51:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-15 14:51:23 -0400
commit6bd2bd27baf12fa0f2e6d611509fc0e1bffb0f97 (patch)
tree1aa11eb70af1e43bc122cb516bab264ddda76050 /net/wireless
parenteb2eacf77ec4828c9a2e451b06bc6fc44266f4c0 (diff)
parent0d8614b4b926d0f657d15d7eb5125bcb24b9fd41 (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.c1
-rw-r--r--net/wireless/core.c3
-rw-r--r--net/wireless/ibss.c4
-rw-r--r--net/wireless/mlme.c4
-rw-r--r--net/wireless/nl80211.c233
-rw-r--r--net/wireless/nl80211.h3
-rw-r--r--net/wireless/rdev-ops.h31
-rw-r--r--net/wireless/reg.c82
-rw-r--r--net/wireless/scan.c1
-rw-r--r--net/wireless/sme.c6
-rw-r--r--net/wireless/trace.h45
-rw-r--r--net/wireless/util.c3
-rw-r--r--net/wireless/wext-compat.c2
-rw-r--r--net/wireless/wext-sme.c2
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
21void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, 21void 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, &params); 3373 err = rdev_start_ap(rdev, dev, &params);
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
9423static 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
9488static 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
9379static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, 9522static 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
9465static const struct genl_ops nl80211_ops[] = { 9620static 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:
10373static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, 10548static 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
10415void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, 10604void 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
10423void nl80211_send_deauth(struct cfg80211_registered_device *rdev, 10612void 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
10431void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 10620void 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
10439void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, 10628void 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}
10459EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); 10648EXPORT_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);
24void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, 24void 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);
27void nl80211_send_deauth(struct cfg80211_registered_device *rdev, 28void 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
918static inline int
919rdev_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
935static inline int
936rdev_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 */
803static 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 */
830static 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 = &reg_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(&reg_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
1899TRACE_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
1924TRACE_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}