aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-23 13:13:30 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-23 13:13:30 -0500
commita130883d9528eefb66285728ba6a232d8fff9465 (patch)
tree304b63e59d910be2ee2798404fe4a940bdfdd2af /net/wireless
parentd9f4fbaf7053af43e6c72909c2aff18654717aed (diff)
parent65a6538a56d4c7ae8465f2a8420ddc65877b6779 (diff)
Merge branch 'for-davem' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c22
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/mesh.c24
-rw-r--r--net/wireless/mlme.c22
-rw-r--r--net/wireless/nl80211.c276
-rw-r--r--net/wireless/nl80211.h6
-rw-r--r--net/wireless/reg.c3
-rw-r--r--net/wireless/scan.c11
-rw-r--r--net/wireless/util.c3
-rw-r--r--net/wireless/wext-compat.c8
10 files changed, 309 insertions, 71 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 79772fcc37bc..e9a5f8ca4c27 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -789,13 +789,23 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
789 cfg80211_mgd_wext_connect(rdev, wdev); 789 cfg80211_mgd_wext_connect(rdev, wdev);
790 break; 790 break;
791#endif 791#endif
792#ifdef CONFIG_MAC80211_MESH
792 case NL80211_IFTYPE_MESH_POINT: 793 case NL80211_IFTYPE_MESH_POINT:
793 /* backward compat code ... */ 794 {
794 if (wdev->mesh_id_up_len) 795 /* backward compat code... */
795 __cfg80211_join_mesh(rdev, dev, wdev->ssid, 796 struct mesh_setup setup;
796 wdev->mesh_id_up_len, 797 memcpy(&setup, &default_mesh_setup,
797 &default_mesh_config); 798 sizeof(setup));
798 break; 799 /* back compat only needed for mesh_id */
800 setup.mesh_id = wdev->ssid;
801 setup.mesh_id_len = wdev->mesh_id_up_len;
802 if (wdev->mesh_id_up_len)
803 __cfg80211_join_mesh(rdev, dev,
804 &setup,
805 &default_mesh_config);
806 break;
807 }
808#endif
799 default: 809 default:
800 break; 810 break;
801 } 811 }
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 743203bb61ac..26a0a084e16b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -287,13 +287,14 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
287 287
288/* mesh */ 288/* mesh */
289extern const struct mesh_config default_mesh_config; 289extern const struct mesh_config default_mesh_config;
290extern const struct mesh_setup default_mesh_setup;
290int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 291int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
291 struct net_device *dev, 292 struct net_device *dev,
292 const u8 *mesh_id, u8 mesh_id_len, 293 const struct mesh_setup *setup,
293 const struct mesh_config *conf); 294 const struct mesh_config *conf);
294int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 295int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
295 struct net_device *dev, 296 struct net_device *dev,
296 const u8 *mesh_id, u8 mesh_id_len, 297 const struct mesh_setup *setup,
297 const struct mesh_config *conf); 298 const struct mesh_config *conf);
298int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 299int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
299 struct net_device *dev); 300 struct net_device *dev);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index e0b9747fe50a..73e39c171ffb 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -50,17 +50,19 @@ const struct mesh_config default_mesh_config = {
50 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, 50 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
51}; 51};
52 52
53const struct mesh_setup default_mesh_setup = {
54 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
55 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
56 .vendor_ie = NULL,
57 .vendor_ie_len = 0,
58};
53 59
54int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 60int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
55 struct net_device *dev, 61 struct net_device *dev,
56 const u8 *mesh_id, u8 mesh_id_len, 62 const struct mesh_setup *setup,
57 const struct mesh_config *conf) 63 const struct mesh_config *conf)
58{ 64{
59 struct wireless_dev *wdev = dev->ieee80211_ptr; 65 struct wireless_dev *wdev = dev->ieee80211_ptr;
60 struct mesh_setup setup = {
61 .mesh_id = mesh_id,
62 .mesh_id_len = mesh_id_len,
63 };
64 int err; 66 int err;
65 67
66 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); 68 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
@@ -73,16 +75,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
73 if (wdev->mesh_id_len) 75 if (wdev->mesh_id_len)
74 return -EALREADY; 76 return -EALREADY;
75 77
76 if (!mesh_id_len) 78 if (!setup->mesh_id_len)
77 return -EINVAL; 79 return -EINVAL;
78 80
79 if (!rdev->ops->join_mesh) 81 if (!rdev->ops->join_mesh)
80 return -EOPNOTSUPP; 82 return -EOPNOTSUPP;
81 83
82 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup); 84 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
83 if (!err) { 85 if (!err) {
84 memcpy(wdev->ssid, mesh_id, mesh_id_len); 86 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
85 wdev->mesh_id_len = mesh_id_len; 87 wdev->mesh_id_len = setup->mesh_id_len;
86 } 88 }
87 89
88 return err; 90 return err;
@@ -90,14 +92,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
90 92
91int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 93int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
92 struct net_device *dev, 94 struct net_device *dev,
93 const u8 *mesh_id, u8 mesh_id_len, 95 const struct mesh_setup *setup,
94 const struct mesh_config *conf) 96 const struct mesh_config *conf)
95{ 97{
96 struct wireless_dev *wdev = dev->ieee80211_ptr; 98 struct wireless_dev *wdev = dev->ieee80211_ptr;
97 int err; 99 int err;
98 100
99 wdev_lock(wdev); 101 wdev_lock(wdev);
100 err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf); 102 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
101 wdev_unlock(wdev); 103 wdev_unlock(wdev);
102 104
103 return err; 105 return err;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index d7680f2a4c5b..aa5df8865ff7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
263} 263}
264EXPORT_SYMBOL(cfg80211_send_disassoc); 264EXPORT_SYMBOL(cfg80211_send_disassoc);
265 265
266void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
267 size_t len)
268{
269 struct wireless_dev *wdev = dev->ieee80211_ptr;
270 struct wiphy *wiphy = wdev->wiphy;
271 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
272
273 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
274}
275EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
276
277void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
278 size_t len)
279{
280 struct wireless_dev *wdev = dev->ieee80211_ptr;
281 struct wiphy *wiphy = wdev->wiphy;
282 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
283
284 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
285}
286EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
287
266static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) 288static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
267{ 289{
268 int i; 290 int i;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3f80e565365..9b62710891a2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
123 .len = NL80211_MAX_SUPP_RATES }, 123 .len = NL80211_MAX_SUPP_RATES },
124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, 124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
125 125
126 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 127
128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
129 .len = NL80211_HT_CAPABILITY_LEN }, 129 .len = NL80211_HT_CAPABILITY_LEN },
@@ -171,6 +171,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, 171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, 172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
174 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
174}; 175};
175 176
176/* policy for the key attributes */ 177/* policy for the key attributes */
@@ -182,6 +183,14 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
182 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 183 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
183 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 184 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
184 [NL80211_KEY_TYPE] = { .type = NLA_U32 }, 185 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
186 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
187};
188
189/* policy for the key default flags */
190static const struct nla_policy
191nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
192 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
193 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
185}; 194};
186 195
187/* ifidx get helper */ 196/* ifidx get helper */
@@ -314,6 +323,7 @@ struct key_parse {
314 int idx; 323 int idx;
315 int type; 324 int type;
316 bool def, defmgmt; 325 bool def, defmgmt;
326 bool def_uni, def_multi;
317}; 327};
318 328
319static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) 329static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -327,6 +337,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
327 k->def = !!tb[NL80211_KEY_DEFAULT]; 337 k->def = !!tb[NL80211_KEY_DEFAULT];
328 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; 338 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
329 339
340 if (k->def) {
341 k->def_uni = true;
342 k->def_multi = true;
343 }
344 if (k->defmgmt)
345 k->def_multi = true;
346
330 if (tb[NL80211_KEY_IDX]) 347 if (tb[NL80211_KEY_IDX])
331 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); 348 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
332 349
@@ -349,6 +366,19 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
349 return -EINVAL; 366 return -EINVAL;
350 } 367 }
351 368
369 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
370 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
371 int err = nla_parse_nested(kdt,
372 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
373 tb[NL80211_KEY_DEFAULT_TYPES],
374 nl80211_key_default_policy);
375 if (err)
376 return err;
377
378 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
379 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
380 }
381
352 return 0; 382 return 0;
353} 383}
354 384
@@ -373,12 +403,32 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
373 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; 403 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
374 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; 404 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
375 405
406 if (k->def) {
407 k->def_uni = true;
408 k->def_multi = true;
409 }
410 if (k->defmgmt)
411 k->def_multi = true;
412
376 if (info->attrs[NL80211_ATTR_KEY_TYPE]) { 413 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
377 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); 414 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
378 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) 415 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
379 return -EINVAL; 416 return -EINVAL;
380 } 417 }
381 418
419 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
420 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
421 int err = nla_parse_nested(
422 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
423 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
424 nl80211_key_default_policy);
425 if (err)
426 return err;
427
428 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
429 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
430 }
431
382 return 0; 432 return 0;
383} 433}
384 434
@@ -401,6 +451,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
401 if (k->def && k->defmgmt) 451 if (k->def && k->defmgmt)
402 return -EINVAL; 452 return -EINVAL;
403 453
454 if (k->defmgmt) {
455 if (k->def_uni || !k->def_multi)
456 return -EINVAL;
457 }
458
404 if (k->idx != -1) { 459 if (k->idx != -1) {
405 if (k->defmgmt) { 460 if (k->defmgmt) {
406 if (k->idx < 4 || k->idx > 5) 461 if (k->idx < 4 || k->idx > 5)
@@ -450,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
450 goto error; 505 goto error;
451 def = 1; 506 def = 1;
452 result->def = parse.idx; 507 result->def = parse.idx;
508 if (!parse.def_uni || !parse.def_multi)
509 goto error;
453 } else if (parse.defmgmt) 510 } else if (parse.defmgmt)
454 goto error; 511 goto error;
455 err = cfg80211_validate_key_settings(rdev, &parse.p, 512 err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -548,7 +605,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
548 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) 605 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
549 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); 606 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
550 607
551 if (dev->ops->get_antenna) { 608 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
609 dev->wiphy.available_antennas_tx);
610 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
611 dev->wiphy.available_antennas_rx);
612
613 if ((dev->wiphy.available_antennas_tx ||
614 dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
552 u32 tx_ant = 0, rx_ant = 0; 615 u32 tx_ant = 0, rx_ant = 0;
553 int res; 616 int res;
554 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); 617 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
@@ -662,7 +725,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
662 CMD(add_beacon, NEW_BEACON); 725 CMD(add_beacon, NEW_BEACON);
663 CMD(add_station, NEW_STATION); 726 CMD(add_station, NEW_STATION);
664 CMD(add_mpath, NEW_MPATH); 727 CMD(add_mpath, NEW_MPATH);
665 CMD(update_mesh_params, SET_MESH_PARAMS); 728 CMD(update_mesh_config, SET_MESH_CONFIG);
666 CMD(change_bss, SET_BSS); 729 CMD(change_bss, SET_BSS);
667 CMD(auth, AUTHENTICATE); 730 CMD(auth, AUTHENTICATE);
668 CMD(assoc, ASSOCIATE); 731 CMD(assoc, ASSOCIATE);
@@ -698,6 +761,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
698 761
699 nla_nest_end(msg, nl_cmds); 762 nla_nest_end(msg, nl_cmds);
700 763
764 if (dev->ops->remain_on_channel)
765 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
766 dev->wiphy.max_remain_on_channel_duration);
767
701 /* for now at least assume all drivers have it */ 768 /* for now at least assume all drivers have it */
702 if (dev->ops->mgmt_tx) 769 if (dev->ops->mgmt_tx)
703 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 770 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
@@ -1046,7 +1113,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1046 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && 1113 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
1047 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { 1114 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
1048 u32 tx_ant, rx_ant; 1115 u32 tx_ant, rx_ant;
1049 if (!rdev->ops->set_antenna) { 1116 if ((!rdev->wiphy.available_antennas_tx &&
1117 !rdev->wiphy.available_antennas_rx) ||
1118 !rdev->ops->set_antenna) {
1050 result = -EOPNOTSUPP; 1119 result = -EOPNOTSUPP;
1051 goto bad_res; 1120 goto bad_res;
1052 } 1121 }
@@ -1054,6 +1123,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); 1123 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
1055 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); 1124 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
1056 1125
1126 /* reject antenna configurations which don't match the
1127 * available antenna masks, except for the "all" mask */
1128 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
1129 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
1130 result = -EINVAL;
1131 goto bad_res;
1132 }
1133
1134 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
1135 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
1136
1057 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); 1137 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
1058 if (result) 1138 if (result)
1059 goto bad_res; 1139 goto bad_res;
@@ -1575,8 +1655,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1575 struct key_parse key; 1655 struct key_parse key;
1576 int err; 1656 int err;
1577 struct net_device *dev = info->user_ptr[1]; 1657 struct net_device *dev = info->user_ptr[1];
1578 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1579 u8 key_index);
1580 1658
1581 err = nl80211_parse_key(info, &key); 1659 err = nl80211_parse_key(info, &key);
1582 if (err) 1660 if (err)
@@ -1589,27 +1667,61 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1589 if (!key.def && !key.defmgmt) 1667 if (!key.def && !key.defmgmt)
1590 return -EINVAL; 1668 return -EINVAL;
1591 1669
1592 if (key.def) 1670 wdev_lock(dev->ieee80211_ptr);
1593 func = rdev->ops->set_default_key;
1594 else
1595 func = rdev->ops->set_default_mgmt_key;
1596 1671
1597 if (!func) 1672 if (key.def) {
1598 return -EOPNOTSUPP; 1673 if (!rdev->ops->set_default_key) {
1674 err = -EOPNOTSUPP;
1675 goto out;
1676 }
1599 1677
1600 wdev_lock(dev->ieee80211_ptr); 1678 err = nl80211_key_allowed(dev->ieee80211_ptr);
1601 err = nl80211_key_allowed(dev->ieee80211_ptr); 1679 if (err)
1602 if (!err) 1680 goto out;
1603 err = func(&rdev->wiphy, dev, key.idx); 1681
1682 if (!(rdev->wiphy.flags &
1683 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
1684 if (!key.def_uni || !key.def_multi) {
1685 err = -EOPNOTSUPP;
1686 goto out;
1687 }
1688 }
1689
1690 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
1691 key.def_uni, key.def_multi);
1692
1693 if (err)
1694 goto out;
1604 1695
1605#ifdef CONFIG_CFG80211_WEXT 1696#ifdef CONFIG_CFG80211_WEXT
1606 if (!err) { 1697 dev->ieee80211_ptr->wext.default_key = key.idx;
1607 if (func == rdev->ops->set_default_key)
1608 dev->ieee80211_ptr->wext.default_key = key.idx;
1609 else
1610 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1611 }
1612#endif 1698#endif
1699 } else {
1700 if (key.def_uni || !key.def_multi) {
1701 err = -EINVAL;
1702 goto out;
1703 }
1704
1705 if (!rdev->ops->set_default_mgmt_key) {
1706 err = -EOPNOTSUPP;
1707 goto out;
1708 }
1709
1710 err = nl80211_key_allowed(dev->ieee80211_ptr);
1711 if (err)
1712 goto out;
1713
1714 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
1715 dev, key.idx);
1716 if (err)
1717 goto out;
1718
1719#ifdef CONFIG_CFG80211_WEXT
1720 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1721#endif
1722 }
1723
1724 out:
1613 wdev_unlock(dev->ieee80211_ptr); 1725 wdev_unlock(dev->ieee80211_ptr);
1614 1726
1615 return err; 1727 return err;
@@ -2569,7 +2681,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2569 return r; 2681 return r;
2570} 2682}
2571 2683
2572static int nl80211_get_mesh_params(struct sk_buff *skb, 2684static int nl80211_get_mesh_config(struct sk_buff *skb,
2573 struct genl_info *info) 2685 struct genl_info *info)
2574{ 2686{
2575 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2687 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2584,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2584 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2696 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2585 return -EOPNOTSUPP; 2697 return -EOPNOTSUPP;
2586 2698
2587 if (!rdev->ops->get_mesh_params) 2699 if (!rdev->ops->get_mesh_config)
2588 return -EOPNOTSUPP; 2700 return -EOPNOTSUPP;
2589 2701
2590 wdev_lock(wdev); 2702 wdev_lock(wdev);
@@ -2592,7 +2704,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2592 if (!wdev->mesh_id_len) 2704 if (!wdev->mesh_id_len)
2593 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); 2705 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
2594 else 2706 else
2595 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, 2707 err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
2596 &cur_params); 2708 &cur_params);
2597 wdev_unlock(wdev); 2709 wdev_unlock(wdev);
2598 2710
@@ -2604,10 +2716,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2604 if (!msg) 2716 if (!msg)
2605 return -ENOMEM; 2717 return -ENOMEM;
2606 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2718 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2607 NL80211_CMD_GET_MESH_PARAMS); 2719 NL80211_CMD_GET_MESH_CONFIG);
2608 if (!hdr) 2720 if (!hdr)
2609 goto nla_put_failure; 2721 goto nla_put_failure;
2610 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); 2722 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
2611 if (!pinfoattr) 2723 if (!pinfoattr)
2612 goto nla_put_failure; 2724 goto nla_put_failure;
2613 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 2725 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2669,7 +2781,15 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2669 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 2781 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2670}; 2782};
2671 2783
2672static int nl80211_parse_mesh_params(struct genl_info *info, 2784static const struct nla_policy
2785 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
2786 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
2787 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
2788 [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
2789 .len = IEEE80211_MAX_DATA_LEN },
2790};
2791
2792static int nl80211_parse_mesh_config(struct genl_info *info,
2673 struct mesh_config *cfg, 2793 struct mesh_config *cfg,
2674 u32 *mask_out) 2794 u32 *mask_out)
2675{ 2795{
@@ -2685,10 +2805,10 @@ do {\
2685} while (0);\ 2805} while (0);\
2686 2806
2687 2807
2688 if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) 2808 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
2689 return -EINVAL; 2809 return -EINVAL;
2690 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, 2810 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2691 info->attrs[NL80211_ATTR_MESH_PARAMS], 2811 info->attrs[NL80211_ATTR_MESH_CONFIG],
2692 nl80211_meshconf_params_policy)) 2812 nl80211_meshconf_params_policy))
2693 return -EINVAL; 2813 return -EINVAL;
2694 2814
@@ -2735,15 +2855,51 @@ do {\
2735 dot11MeshHWMPRootMode, mask, 2855 dot11MeshHWMPRootMode, mask,
2736 NL80211_MESHCONF_HWMP_ROOTMODE, 2856 NL80211_MESHCONF_HWMP_ROOTMODE,
2737 nla_get_u8); 2857 nla_get_u8);
2738
2739 if (mask_out) 2858 if (mask_out)
2740 *mask_out = mask; 2859 *mask_out = mask;
2860
2741 return 0; 2861 return 0;
2742 2862
2743#undef FILL_IN_MESH_PARAM_IF_SET 2863#undef FILL_IN_MESH_PARAM_IF_SET
2744} 2864}
2745 2865
2746static int nl80211_update_mesh_params(struct sk_buff *skb, 2866static int nl80211_parse_mesh_setup(struct genl_info *info,
2867 struct mesh_setup *setup)
2868{
2869 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
2870
2871 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
2872 return -EINVAL;
2873 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
2874 info->attrs[NL80211_ATTR_MESH_SETUP],
2875 nl80211_mesh_setup_params_policy))
2876 return -EINVAL;
2877
2878 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
2879 setup->path_sel_proto =
2880 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
2881 IEEE80211_PATH_PROTOCOL_VENDOR :
2882 IEEE80211_PATH_PROTOCOL_HWMP;
2883
2884 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
2885 setup->path_metric =
2886 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
2887 IEEE80211_PATH_METRIC_VENDOR :
2888 IEEE80211_PATH_METRIC_AIRTIME;
2889
2890 if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
2891 struct nlattr *ieattr =
2892 tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
2893 if (!is_valid_ie_attr(ieattr))
2894 return -EINVAL;
2895 setup->vendor_ie = nla_data(ieattr);
2896 setup->vendor_ie_len = nla_len(ieattr);
2897 }
2898
2899 return 0;
2900}
2901
2902static int nl80211_update_mesh_config(struct sk_buff *skb,
2747 struct genl_info *info) 2903 struct genl_info *info)
2748{ 2904{
2749 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2905 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2756,10 +2912,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2756 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2912 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2757 return -EOPNOTSUPP; 2913 return -EOPNOTSUPP;
2758 2914
2759 if (!rdev->ops->update_mesh_params) 2915 if (!rdev->ops->update_mesh_config)
2760 return -EOPNOTSUPP; 2916 return -EOPNOTSUPP;
2761 2917
2762 err = nl80211_parse_mesh_params(info, &cfg, &mask); 2918 err = nl80211_parse_mesh_config(info, &cfg, &mask);
2763 if (err) 2919 if (err)
2764 return err; 2920 return err;
2765 2921
@@ -2768,7 +2924,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2768 err = -ENOLINK; 2924 err = -ENOLINK;
2769 2925
2770 if (!err) 2926 if (!err)
2771 err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, 2927 err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
2772 mask, &cfg); 2928 mask, &cfg);
2773 2929
2774 wdev_unlock(wdev); 2930 wdev_unlock(wdev);
@@ -4128,7 +4284,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4128 * We should be on that channel for at least one jiffie, 4284 * We should be on that channel for at least one jiffie,
4129 * and more than 5 seconds seems excessive. 4285 * and more than 5 seconds seems excessive.
4130 */ 4286 */
4131 if (!duration || !msecs_to_jiffies(duration) || duration > 5000) 4287 if (!duration || !msecs_to_jiffies(duration) ||
4288 duration > rdev->wiphy.max_remain_on_channel_duration)
4132 return -EINVAL; 4289 return -EINVAL;
4133 4290
4134 if (!rdev->ops->remain_on_channel) 4291 if (!rdev->ops->remain_on_channel)
@@ -4296,6 +4453,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4453 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4454 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4298 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4455 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4456 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4299 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4457 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4300 return -EOPNOTSUPP; 4458 return -EOPNOTSUPP;
4301 4459
@@ -4336,6 +4494,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4336 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4494 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4337 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4495 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4338 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4496 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4497 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4339 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4498 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4340 return -EOPNOTSUPP; 4499 return -EOPNOTSUPP;
4341 4500
@@ -4562,14 +4721,16 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4562 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4563 struct net_device *dev = info->user_ptr[1]; 4722 struct net_device *dev = info->user_ptr[1];
4564 struct mesh_config cfg; 4723 struct mesh_config cfg;
4724 struct mesh_setup setup;
4565 int err; 4725 int err;
4566 4726
4567 /* start with default */ 4727 /* start with default */
4568 memcpy(&cfg, &default_mesh_config, sizeof(cfg)); 4728 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
4729 memcpy(&setup, &default_mesh_setup, sizeof(setup));
4569 4730
4570 if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { 4731 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
4571 /* and parse parameters if given */ 4732 /* and parse parameters if given */
4572 err = nl80211_parse_mesh_params(info, &cfg, NULL); 4733 err = nl80211_parse_mesh_config(info, &cfg, NULL);
4573 if (err) 4734 if (err)
4574 return err; 4735 return err;
4575 } 4736 }
@@ -4578,10 +4739,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4578 !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) 4739 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
4579 return -EINVAL; 4740 return -EINVAL;
4580 4741
4581 return cfg80211_join_mesh(rdev, dev, 4742 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
4582 nla_data(info->attrs[NL80211_ATTR_MESH_ID]), 4743 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4583 nla_len(info->attrs[NL80211_ATTR_MESH_ID]), 4744
4584 &cfg); 4745 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
4746 /* parse additional setup parameters if given */
4747 err = nl80211_parse_mesh_setup(info, &setup);
4748 if (err)
4749 return err;
4750 }
4751
4752 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
4585} 4753}
4586 4754
4587static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) 4755static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
@@ -4847,16 +5015,16 @@ static struct genl_ops nl80211_ops[] = {
4847 .flags = GENL_ADMIN_PERM, 5015 .flags = GENL_ADMIN_PERM,
4848 }, 5016 },
4849 { 5017 {
4850 .cmd = NL80211_CMD_GET_MESH_PARAMS, 5018 .cmd = NL80211_CMD_GET_MESH_CONFIG,
4851 .doit = nl80211_get_mesh_params, 5019 .doit = nl80211_get_mesh_config,
4852 .policy = nl80211_policy, 5020 .policy = nl80211_policy,
4853 /* can be retrieved by unprivileged users */ 5021 /* can be retrieved by unprivileged users */
4854 .internal_flags = NL80211_FLAG_NEED_NETDEV | 5022 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4855 NL80211_FLAG_NEED_RTNL, 5023 NL80211_FLAG_NEED_RTNL,
4856 }, 5024 },
4857 { 5025 {
4858 .cmd = NL80211_CMD_SET_MESH_PARAMS, 5026 .cmd = NL80211_CMD_SET_MESH_CONFIG,
4859 .doit = nl80211_update_mesh_params, 5027 .doit = nl80211_update_mesh_config,
4860 .policy = nl80211_policy, 5028 .policy = nl80211_policy,
4861 .flags = GENL_ADMIN_PERM, 5029 .flags = GENL_ADMIN_PERM,
4862 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 5030 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -5368,6 +5536,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
5368 NL80211_CMD_DISASSOCIATE, gfp); 5536 NL80211_CMD_DISASSOCIATE, gfp);
5369} 5537}
5370 5538
5539void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
5540 struct net_device *netdev, const u8 *buf,
5541 size_t len, gfp_t gfp)
5542{
5543 nl80211_send_mlme_event(rdev, netdev, buf, len,
5544 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
5545}
5546
5547void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
5548 struct net_device *netdev, const u8 *buf,
5549 size_t len, gfp_t gfp)
5550{
5551 nl80211_send_mlme_event(rdev, netdev, buf, len,
5552 NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
5553}
5554
5371static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 5555static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
5372 struct net_device *netdev, int cmd, 5556 struct net_device *netdev, int cmd,
5373 const u8 *addr, gfp_t gfp) 5557 const u8 *addr, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 16c2f7190768..e3f7fa886966 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
26 struct net_device *netdev, 26 struct net_device *netdev,
27 const u8 *buf, size_t len, gfp_t gfp); 27 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev,
30 const u8 *buf, size_t len, gfp_t gfp);
31void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
32 struct net_device *netdev,
33 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, 34void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev, 35 struct net_device *netdev,
30 const u8 *addr, gfp_t gfp); 36 const u8 *addr, gfp_t gfp);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5ed615f94e0c..99d41831d76e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -661,7 +661,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
661 * Follow the driver's regulatory domain, if present, unless a country 661 * Follow the driver's regulatory domain, if present, unless a country
662 * IE has been processed or a user wants to help complaince further 662 * IE has been processed or a user wants to help complaince further
663 */ 663 */
664 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 664 if (!custom_regd &&
665 last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
665 last_request->initiator != NL80211_REGDOM_SET_BY_USER && 666 last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
666 wiphy->regd) 667 wiphy->regd)
667 regd = wiphy->regd; 668 regd = wiphy->regd;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 503ebb86ba18..ea427f418f64 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -464,6 +464,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
464 if (res->pub.beacon_ies) { 464 if (res->pub.beacon_ies) {
465 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 465 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
466 size_t ielen = res->pub.len_beacon_ies; 466 size_t ielen = res->pub.len_beacon_ies;
467 bool information_elements_is_beacon_ies =
468 (found->pub.information_elements ==
469 found->pub.beacon_ies);
467 470
468 if (found->pub.beacon_ies && 471 if (found->pub.beacon_ies &&
469 !found->beacon_ies_allocated && 472 !found->beacon_ies_allocated &&
@@ -487,6 +490,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
487 found->pub.len_beacon_ies = ielen; 490 found->pub.len_beacon_ies = ielen;
488 } 491 }
489 } 492 }
493
494 /* Override IEs if they were from a beacon before */
495 if (information_elements_is_beacon_ies) {
496 found->pub.information_elements =
497 found->pub.beacon_ies;
498 found->pub.len_information_elements =
499 found->pub.len_beacon_ies;
500 }
490 } 501 }
491 502
492 kref_put(&res->ref, bss_release); 503 kref_put(&res->ref, bss_release);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4de624ca4c63..7620ae2fcf18 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -689,7 +689,8 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
689 continue; 689 continue;
690 } 690 }
691 if (wdev->connect_keys->def == i) 691 if (wdev->connect_keys->def == i)
692 if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) { 692 if (rdev->ops->set_default_key(wdev->wiphy, dev,
693 i, true, true)) {
693 netdev_err(dev, "failed to set defkey %d\n", i); 694 netdev_err(dev, "failed to set defkey %d\n", i);
694 continue; 695 continue;
695 } 696 }
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 12222ee6ebf2..3e5dbd4e4cd5 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
548 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 548 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
549 rejoin = true; 549 rejoin = true;
550 } 550 }
551 err = rdev->ops->set_default_key(&rdev->wiphy, 551 err = rdev->ops->set_default_key(&rdev->wiphy, dev,
552 dev, idx); 552 idx, true, true);
553 } 553 }
554 if (!err) { 554 if (!err) {
555 wdev->wext.default_key = idx; 555 wdev->wext.default_key = idx;
@@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_device *dev,
627 err = 0; 627 err = 0;
628 wdev_lock(wdev); 628 wdev_lock(wdev);
629 if (wdev->current_bss) 629 if (wdev->current_bss)
630 err = rdev->ops->set_default_key(&rdev->wiphy, 630 err = rdev->ops->set_default_key(&rdev->wiphy, dev,
631 dev, idx); 631 idx, true, true);
632 if (!err) 632 if (!err)
633 wdev->wext.default_key = idx; 633 wdev->wext.default_key = idx;
634 wdev_unlock(wdev); 634 wdev_unlock(wdev);