aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-11-28 14:11:18 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 14:11:18 -0500
commit39338b56382ac640614851a80e0bd71994cc664d (patch)
treec319e23181be286b1d320c29f755a81e5ef61172 /net/wireless
parent8b7ff200010600ef7cd9d002f9f8f97edfc7578e (diff)
parenteb1852b10593dc3ca73e02bf9ac4753a5a464905 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.h10
-rw-r--r--net/wireless/mlme.c37
-rw-r--r--net/wireless/nl80211.c133
-rw-r--r--net/wireless/reg.c39
-rw-r--r--net/wireless/reg.h1
-rw-r--r--net/wireless/sme.c7
-rw-r--r--net/wireless/util.c186
7 files changed, 201 insertions, 212 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 1c7d4df5418c..fb08c28fc90a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -341,13 +341,17 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
341 const u8 *bssid, const u8 *prev_bssid, 341 const u8 *bssid, const u8 *prev_bssid,
342 const u8 *ssid, int ssid_len, 342 const u8 *ssid, int ssid_len,
343 const u8 *ie, int ie_len, bool use_mfp, 343 const u8 *ie, int ie_len, bool use_mfp,
344 struct cfg80211_crypto_settings *crypt); 344 struct cfg80211_crypto_settings *crypt,
345 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
346 struct ieee80211_ht_cap *ht_capa_mask);
345int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 347int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
346 struct net_device *dev, struct ieee80211_channel *chan, 348 struct net_device *dev, struct ieee80211_channel *chan,
347 const u8 *bssid, const u8 *prev_bssid, 349 const u8 *bssid, const u8 *prev_bssid,
348 const u8 *ssid, int ssid_len, 350 const u8 *ssid, int ssid_len,
349 const u8 *ie, int ie_len, bool use_mfp, 351 const u8 *ie, int ie_len, bool use_mfp,
350 struct cfg80211_crypto_settings *crypt); 352 struct cfg80211_crypto_settings *crypt,
353 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
354 struct ieee80211_ht_cap *ht_capa_mask);
351int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 355int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
352 struct net_device *dev, const u8 *bssid, 356 struct net_device *dev, const u8 *bssid,
353 const u8 *ie, int ie_len, u16 reason, 357 const u8 *ie, int ie_len, u16 reason,
@@ -379,6 +383,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
379 bool channel_type_valid, unsigned int wait, 383 bool channel_type_valid, unsigned int wait,
380 const u8 *buf, size_t len, bool no_cck, 384 const u8 *buf, size_t len, bool no_cck,
381 bool dont_wait_for_ack, u64 *cookie); 385 bool dont_wait_for_ack, u64 *cookie);
386void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
387 const struct ieee80211_ht_cap *ht_capa_mask);
382 388
383/* SME */ 389/* SME */
384int __cfg80211_connect(struct cfg80211_registered_device *rdev, 390int __cfg80211_connect(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 6c1bafd508c8..438dfc105b4a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -501,13 +501,32 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
501 return err; 501 return err;
502} 502}
503 503
504/* Do a logical ht_capa &= ht_capa_mask. */
505void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
506 const struct ieee80211_ht_cap *ht_capa_mask)
507{
508 int i;
509 u8 *p1, *p2;
510 if (!ht_capa_mask) {
511 memset(ht_capa, 0, sizeof(*ht_capa));
512 return;
513 }
514
515 p1 = (u8*)(ht_capa);
516 p2 = (u8*)(ht_capa_mask);
517 for (i = 0; i<sizeof(*ht_capa); i++)
518 p1[i] &= p2[i];
519}
520
504int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 521int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
505 struct net_device *dev, 522 struct net_device *dev,
506 struct ieee80211_channel *chan, 523 struct ieee80211_channel *chan,
507 const u8 *bssid, const u8 *prev_bssid, 524 const u8 *bssid, const u8 *prev_bssid,
508 const u8 *ssid, int ssid_len, 525 const u8 *ssid, int ssid_len,
509 const u8 *ie, int ie_len, bool use_mfp, 526 const u8 *ie, int ie_len, bool use_mfp,
510 struct cfg80211_crypto_settings *crypt) 527 struct cfg80211_crypto_settings *crypt,
528 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
529 struct ieee80211_ht_cap *ht_capa_mask)
511{ 530{
512 struct wireless_dev *wdev = dev->ieee80211_ptr; 531 struct wireless_dev *wdev = dev->ieee80211_ptr;
513 struct cfg80211_assoc_request req; 532 struct cfg80211_assoc_request req;
@@ -537,6 +556,15 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
537 memcpy(&req.crypto, crypt, sizeof(req.crypto)); 556 memcpy(&req.crypto, crypt, sizeof(req.crypto));
538 req.use_mfp = use_mfp; 557 req.use_mfp = use_mfp;
539 req.prev_bssid = prev_bssid; 558 req.prev_bssid = prev_bssid;
559 req.flags = assoc_flags;
560 if (ht_capa)
561 memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
562 if (ht_capa_mask)
563 memcpy(&req.ht_capa_mask, ht_capa_mask,
564 sizeof(req.ht_capa_mask));
565 cfg80211_oper_and_ht_capa(&req.ht_capa_mask,
566 rdev->wiphy.ht_capa_mod_mask);
567
540 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 568 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
541 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 569 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
542 if (!req.bss) { 570 if (!req.bss) {
@@ -574,14 +602,17 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
574 const u8 *bssid, const u8 *prev_bssid, 602 const u8 *bssid, const u8 *prev_bssid,
575 const u8 *ssid, int ssid_len, 603 const u8 *ssid, int ssid_len,
576 const u8 *ie, int ie_len, bool use_mfp, 604 const u8 *ie, int ie_len, bool use_mfp,
577 struct cfg80211_crypto_settings *crypt) 605 struct cfg80211_crypto_settings *crypt,
606 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
607 struct ieee80211_ht_cap *ht_capa_mask)
578{ 608{
579 struct wireless_dev *wdev = dev->ieee80211_ptr; 609 struct wireless_dev *wdev = dev->ieee80211_ptr;
580 int err; 610 int err;
581 611
582 wdev_lock(wdev); 612 wdev_lock(wdev);
583 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, 613 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
584 ssid, ssid_len, ie, ie_len, use_mfp, crypt); 614 ssid, ssid_len, ie, ie_len, use_mfp, crypt,
615 assoc_flags, ht_capa, ht_capa_mask);
585 wdev_unlock(wdev); 616 wdev_unlock(wdev);
586 617
587 return err; 618 return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6bc7c4b32fa5..a1cabde7cb5f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -199,6 +199,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
199 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, 199 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
200 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, 200 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
201 .len = IEEE80211_MAX_DATA_LEN }, 201 .len = IEEE80211_MAX_DATA_LEN },
202 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
203 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
204 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
205 .len = NL80211_HT_CAPABILITY_LEN
206 },
202}; 207};
203 208
204/* policy for the key attributes */ 209/* policy for the key attributes */
@@ -881,7 +886,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
881 CMD(set_pmksa, SET_PMKSA); 886 CMD(set_pmksa, SET_PMKSA);
882 CMD(del_pmksa, DEL_PMKSA); 887 CMD(del_pmksa, DEL_PMKSA);
883 CMD(flush_pmksa, FLUSH_PMKSA); 888 CMD(flush_pmksa, FLUSH_PMKSA);
884 CMD(remain_on_channel, REMAIN_ON_CHANNEL); 889 if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
890 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
885 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); 891 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
886 CMD(mgmt_tx, FRAME); 892 CMD(mgmt_tx, FRAME);
887 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); 893 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
@@ -903,6 +909,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
903 NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS); 909 NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS);
904 } 910 }
905 911
912#ifdef CONFIG_NL80211_TESTMODE
913 CMD(testmode_cmd, TESTMODE);
914#endif
915
906#undef CMD 916#undef CMD
907 917
908 if (dev->ops->connect || dev->ops->auth) { 918 if (dev->ops->connect || dev->ops->auth) {
@@ -917,11 +927,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
917 927
918 nla_nest_end(msg, nl_cmds); 928 nla_nest_end(msg, nl_cmds);
919 929
920 if (dev->ops->remain_on_channel) 930 if (dev->ops->remain_on_channel &&
931 dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
921 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, 932 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
922 dev->wiphy.max_remain_on_channel_duration); 933 dev->wiphy.max_remain_on_channel_duration);
923 934
924 if (dev->ops->mgmt_tx_cancel_wait) 935 if (dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)
925 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 936 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
926 937
927 if (mgmt_stypes) { 938 if (mgmt_stypes) {
@@ -1025,6 +1036,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
1025 1036
1026 NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features); 1037 NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features);
1027 1038
1039 if (dev->wiphy.ht_capa_mod_mask)
1040 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1041 sizeof(*dev->wiphy.ht_capa_mod_mask),
1042 dev->wiphy.ht_capa_mod_mask);
1043
1028 return genlmsg_end(msg, hdr); 1044 return genlmsg_end(msg, hdr);
1029 1045
1030 nla_put_failure: 1046 nla_put_failure:
@@ -2478,26 +2494,34 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
2478/* 2494/*
2479 * Get vlan interface making sure it is running and on the right wiphy. 2495 * Get vlan interface making sure it is running and on the right wiphy.
2480 */ 2496 */
2481static int get_vlan(struct genl_info *info, 2497static struct net_device *get_vlan(struct genl_info *info,
2482 struct cfg80211_registered_device *rdev, 2498 struct cfg80211_registered_device *rdev)
2483 struct net_device **vlan)
2484{ 2499{
2485 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN]; 2500 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
2486 *vlan = NULL; 2501 struct net_device *v;
2487 2502 int ret;
2488 if (vlanattr) { 2503
2489 *vlan = dev_get_by_index(genl_info_net(info), 2504 if (!vlanattr)
2490 nla_get_u32(vlanattr)); 2505 return NULL;
2491 if (!*vlan) 2506
2492 return -ENODEV; 2507 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
2493 if (!(*vlan)->ieee80211_ptr) 2508 if (!v)
2494 return -EINVAL; 2509 return ERR_PTR(-ENODEV);
2495 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy) 2510
2496 return -EINVAL; 2511 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
2497 if (!netif_running(*vlan)) 2512 ret = -EINVAL;
2498 return -ENETDOWN; 2513 goto error;
2499 } 2514 }
2500 return 0; 2515
2516 if (!netif_running(v)) {
2517 ret = -ENETDOWN;
2518 goto error;
2519 }
2520
2521 return v;
2522 error:
2523 dev_put(v);
2524 return ERR_PTR(ret);
2501} 2525}
2502 2526
2503static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) 2527static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
@@ -2547,9 +2571,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2547 params.plink_state = 2571 params.plink_state =
2548 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); 2572 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
2549 2573
2550 err = get_vlan(info, rdev, &params.vlan); 2574 params.vlan = get_vlan(info, rdev);
2551 if (err) 2575 if (IS_ERR(params.vlan))
2552 goto out; 2576 return PTR_ERR(params.vlan);
2553 2577
2554 /* validate settings */ 2578 /* validate settings */
2555 err = 0; 2579 err = 0;
@@ -2717,9 +2741,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2717 (rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))) 2741 (rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)))
2718 return -EINVAL; 2742 return -EINVAL;
2719 2743
2720 err = get_vlan(info, rdev, &params.vlan); 2744 params.vlan = get_vlan(info, rdev);
2721 if (err) 2745 if (IS_ERR(params.vlan))
2722 goto out; 2746 return PTR_ERR(params.vlan);
2723 2747
2724 /* validate settings */ 2748 /* validate settings */
2725 err = 0; 2749 err = 0;
@@ -3382,6 +3406,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
3382 3406
3383 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, 3407 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
3384 cfg80211_regdomain->alpha2); 3408 cfg80211_regdomain->alpha2);
3409 if (cfg80211_regdomain->dfs_region)
3410 NLA_PUT_U8(msg, NL80211_ATTR_DFS_REGION,
3411 cfg80211_regdomain->dfs_region);
3385 3412
3386 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); 3413 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
3387 if (!nl_reg_rules) 3414 if (!nl_reg_rules)
@@ -3440,6 +3467,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3440 char *alpha2 = NULL; 3467 char *alpha2 = NULL;
3441 int rem_reg_rules = 0, r = 0; 3468 int rem_reg_rules = 0, r = 0;
3442 u32 num_rules = 0, rule_idx = 0, size_of_regd; 3469 u32 num_rules = 0, rule_idx = 0, size_of_regd;
3470 u8 dfs_region = 0;
3443 struct ieee80211_regdomain *rd = NULL; 3471 struct ieee80211_regdomain *rd = NULL;
3444 3472
3445 if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) 3473 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
@@ -3450,6 +3478,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3450 3478
3451 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); 3479 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
3452 3480
3481 if (info->attrs[NL80211_ATTR_DFS_REGION])
3482 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
3483
3453 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], 3484 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
3454 rem_reg_rules) { 3485 rem_reg_rules) {
3455 num_rules++; 3486 num_rules++;
@@ -3477,6 +3508,13 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3477 rd->alpha2[0] = alpha2[0]; 3508 rd->alpha2[0] = alpha2[0];
3478 rd->alpha2[1] = alpha2[1]; 3509 rd->alpha2[1] = alpha2[1];
3479 3510
3511 /*
3512 * Disable DFS master mode if the DFS region was
3513 * not supported or known on this kernel.
3514 */
3515 if (reg_supported_dfs_region(dfs_region))
3516 rd->dfs_region = dfs_region;
3517
3480 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], 3518 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
3481 rem_reg_rules) { 3519 rem_reg_rules) {
3482 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, 3520 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
@@ -4384,6 +4422,9 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
4384 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; 4422 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
4385 int err, ssid_len, ie_len = 0; 4423 int err, ssid_len, ie_len = 0;
4386 bool use_mfp = false; 4424 bool use_mfp = false;
4425 u32 flags = 0;
4426 struct ieee80211_ht_cap *ht_capa = NULL;
4427 struct ieee80211_ht_cap *ht_capa_mask = NULL;
4387 4428
4388 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 4429 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4389 return -EINVAL; 4430 return -EINVAL;
@@ -4427,11 +4468,25 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
4427 if (info->attrs[NL80211_ATTR_PREV_BSSID]) 4468 if (info->attrs[NL80211_ATTR_PREV_BSSID])
4428 prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); 4469 prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
4429 4470
4471 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
4472 flags |= ASSOC_REQ_DISABLE_HT;
4473
4474 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
4475 ht_capa_mask =
4476 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]);
4477
4478 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
4479 if (!ht_capa_mask)
4480 return -EINVAL;
4481 ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4482 }
4483
4430 err = nl80211_crypto_settings(rdev, info, &crypto, 1); 4484 err = nl80211_crypto_settings(rdev, info, &crypto, 1);
4431 if (!err) 4485 if (!err)
4432 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, 4486 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
4433 ssid, ssid_len, ie, ie_len, use_mfp, 4487 ssid, ssid_len, ie, ie_len, use_mfp,
4434 &crypto); 4488 &crypto, flags, ht_capa,
4489 ht_capa_mask);
4435 4490
4436 return err; 4491 return err;
4437} 4492}
@@ -4921,6 +4976,22 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4921 return PTR_ERR(connkeys); 4976 return PTR_ERR(connkeys);
4922 } 4977 }
4923 4978
4979 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
4980 connect.flags |= ASSOC_REQ_DISABLE_HT;
4981
4982 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
4983 memcpy(&connect.ht_capa_mask,
4984 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
4985 sizeof(connect.ht_capa_mask));
4986
4987 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
4988 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
4989 return -EINVAL;
4990 memcpy(&connect.ht_capa,
4991 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
4992 sizeof(connect.ht_capa));
4993 }
4994
4924 err = cfg80211_connect(rdev, dev, &connect, connkeys); 4995 err = cfg80211_connect(rdev, dev, &connect, connkeys);
4925 if (err) 4996 if (err)
4926 kfree(connkeys); 4997 kfree(connkeys);
@@ -5108,7 +5179,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5108 duration > rdev->wiphy.max_remain_on_channel_duration) 5179 duration > rdev->wiphy.max_remain_on_channel_duration)
5109 return -EINVAL; 5180 return -EINVAL;
5110 5181
5111 if (!rdev->ops->remain_on_channel) 5182 if (!rdev->ops->remain_on_channel ||
5183 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
5112 return -EOPNOTSUPP; 5184 return -EOPNOTSUPP;
5113 5185
5114 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 5186 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
@@ -5321,7 +5393,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5321 return -EOPNOTSUPP; 5393 return -EOPNOTSUPP;
5322 5394
5323 if (info->attrs[NL80211_ATTR_DURATION]) { 5395 if (info->attrs[NL80211_ATTR_DURATION]) {
5324 if (!rdev->ops->mgmt_tx_cancel_wait) 5396 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
5325 return -EINVAL; 5397 return -EINVAL;
5326 wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); 5398 wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
5327 } 5399 }
@@ -5339,6 +5411,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5339 5411
5340 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 5412 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
5341 5413
5414 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
5415 return -EINVAL;
5416
5342 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 5417 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
5343 5418
5344 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 5419 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 77e926738014..76b35df39623 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1123,6 +1123,8 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
1123 if (ignore_reg_update(wiphy, initiator)) 1123 if (ignore_reg_update(wiphy, initiator))
1124 return; 1124 return;
1125 1125
1126 last_request->dfs_region = cfg80211_regdomain->dfs_region;
1127
1126 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1128 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1127 if (wiphy->bands[band]) 1129 if (wiphy->bands[band])
1128 handle_band(wiphy, band, initiator); 1130 handle_band(wiphy, band, initiator);
@@ -1948,6 +1950,42 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1948 } 1950 }
1949} 1951}
1950 1952
1953bool reg_supported_dfs_region(u8 dfs_region)
1954{
1955 switch (dfs_region) {
1956 case NL80211_DFS_UNSET:
1957 case NL80211_DFS_FCC:
1958 case NL80211_DFS_ETSI:
1959 case NL80211_DFS_JP:
1960 return true;
1961 default:
1962 REG_DBG_PRINT("Ignoring uknown DFS master region: %d\n",
1963 dfs_region);
1964 return false;
1965 }
1966}
1967
1968static void print_dfs_region(u8 dfs_region)
1969{
1970 if (!dfs_region)
1971 return;
1972
1973 switch (dfs_region) {
1974 case NL80211_DFS_FCC:
1975 pr_info(" DFS Master region FCC");
1976 break;
1977 case NL80211_DFS_ETSI:
1978 pr_info(" DFS Master region ETSI");
1979 break;
1980 case NL80211_DFS_JP:
1981 pr_info(" DFS Master region JP");
1982 break;
1983 default:
1984 pr_info(" DFS Master region Uknown");
1985 break;
1986 }
1987}
1988
1951static void print_regdomain(const struct ieee80211_regdomain *rd) 1989static void print_regdomain(const struct ieee80211_regdomain *rd)
1952{ 1990{
1953 1991
@@ -1975,6 +2013,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1975 pr_info("Regulatory domain changed to country: %c%c\n", 2013 pr_info("Regulatory domain changed to country: %c%c\n",
1976 rd->alpha2[0], rd->alpha2[1]); 2014 rd->alpha2[0], rd->alpha2[1]);
1977 } 2015 }
2016 print_dfs_region(rd->dfs_region);
1978 print_rd_rules(rd); 2017 print_rd_rules(rd);
1979} 2018}
1980 2019
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 4a56799d868d..786e414afd91 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -5,6 +5,7 @@ extern const struct ieee80211_regdomain *cfg80211_regdomain;
5 5
6bool is_world_regdom(const char *alpha2); 6bool is_world_regdom(const char *alpha2);
7bool reg_is_valid_request(const char *alpha2); 7bool reg_is_valid_request(const char *alpha2);
8bool reg_supported_dfs_region(u8 dfs_region);
8 9
9int regulatory_hint_user(const char *alpha2); 10int regulatory_hint_user(const char *alpha2);
10 11
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 0acfdc9beacf..f0c900ce2fb9 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -190,7 +190,9 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
190 prev_bssid, 190 prev_bssid,
191 params->ssid, params->ssid_len, 191 params->ssid, params->ssid_len,
192 params->ie, params->ie_len, 192 params->ie, params->ie_len,
193 false, &params->crypto); 193 false, &params->crypto,
194 params->flags, &params->ht_capa,
195 &params->ht_capa_mask);
194 if (err) 196 if (err)
195 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 197 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
196 NULL, 0, 198 NULL, 0,
@@ -774,6 +776,9 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
774 wdev->connect_keys = NULL; 776 wdev->connect_keys = NULL;
775 } 777 }
776 778
779 cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
780 rdev->wiphy.ht_capa_mod_mask);
781
777 if (connkeys && connkeys->def >= 0) { 782 if (connkeys && connkeys->def >= 0) {
778 int idx; 783 int idx;
779 u32 cipher; 784 u32 cipher;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4dde429441d2..9c601d59b77a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -7,7 +7,6 @@
7#include <linux/bitops.h> 7#include <linux/bitops.h>
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/crc32.h>
11#include <net/cfg80211.h> 10#include <net/cfg80211.h>
12#include <net/ip.h> 11#include <net/ip.h>
13#include "core.h" 12#include "core.h"
@@ -240,17 +239,6 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
240 return 0; 239 return 0;
241} 240}
242 241
243/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
244/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
245const unsigned char rfc1042_header[] __aligned(2) =
246 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
247EXPORT_SYMBOL(rfc1042_header);
248
249/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
250const unsigned char bridge_tunnel_header[] __aligned(2) =
251 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
252EXPORT_SYMBOL(bridge_tunnel_header);
253
254unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) 242unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc)
255{ 243{
256 unsigned int hdrlen = 24; 244 unsigned int hdrlen = 24;
@@ -1051,169 +1039,13 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
1051 return 0; 1039 return 0;
1052} 1040}
1053 1041
1054u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, 1042/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
1055 struct ieee802_11_elems *elems, 1043/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
1056 u64 filter, u32 crc) 1044const unsigned char rfc1042_header[] __aligned(2) =
1057{ 1045 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
1058 size_t left = len; 1046EXPORT_SYMBOL(rfc1042_header);
1059 u8 *pos = start;
1060 bool calc_crc = filter != 0;
1061
1062 memset(elems, 0, sizeof(*elems));
1063 elems->ie_start = start;
1064 elems->total_len = len;
1065
1066 while (left >= 2) {
1067 u8 id, elen;
1068
1069 id = *pos++;
1070 elen = *pos++;
1071 left -= 2;
1072
1073 if (elen > left)
1074 break;
1075
1076 if (calc_crc && id < 64 && (filter & (1ULL << id)))
1077 crc = crc32_be(crc, pos - 2, elen + 2);
1078
1079 switch (id) {
1080 case WLAN_EID_SSID:
1081 elems->ssid = pos;
1082 elems->ssid_len = elen;
1083 break;
1084 case WLAN_EID_SUPP_RATES:
1085 elems->supp_rates = pos;
1086 elems->supp_rates_len = elen;
1087 break;
1088 case WLAN_EID_FH_PARAMS:
1089 elems->fh_params = pos;
1090 elems->fh_params_len = elen;
1091 break;
1092 case WLAN_EID_DS_PARAMS:
1093 elems->ds_params = pos;
1094 elems->ds_params_len = elen;
1095 break;
1096 case WLAN_EID_CF_PARAMS:
1097 elems->cf_params = pos;
1098 elems->cf_params_len = elen;
1099 break;
1100 case WLAN_EID_TIM:
1101 if (elen >= sizeof(struct ieee80211_tim_ie)) {
1102 elems->tim = (void *)pos;
1103 elems->tim_len = elen;
1104 }
1105 break;
1106 case WLAN_EID_IBSS_PARAMS:
1107 elems->ibss_params = pos;
1108 elems->ibss_params_len = elen;
1109 break;
1110 case WLAN_EID_CHALLENGE:
1111 elems->challenge = pos;
1112 elems->challenge_len = elen;
1113 break;
1114 case WLAN_EID_VENDOR_SPECIFIC:
1115 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
1116 pos[2] == 0xf2) {
1117 /* Microsoft OUI (00:50:F2) */
1118
1119 if (calc_crc)
1120 crc = crc32_be(crc, pos - 2, elen + 2);
1121
1122 if (pos[3] == 1) {
1123 /* OUI Type 1 - WPA IE */
1124 elems->wpa = pos;
1125 elems->wpa_len = elen;
1126 } else if (elen >= 5 && pos[3] == 2) {
1127 /* OUI Type 2 - WMM IE */
1128 if (pos[4] == 0) {
1129 elems->wmm_info = pos;
1130 elems->wmm_info_len = elen;
1131 } else if (pos[4] == 1) {
1132 elems->wmm_param = pos;
1133 elems->wmm_param_len = elen;
1134 }
1135 }
1136 }
1137 break;
1138 case WLAN_EID_RSN:
1139 elems->rsn = pos;
1140 elems->rsn_len = elen;
1141 break;
1142 case WLAN_EID_ERP_INFO:
1143 elems->erp_info = pos;
1144 elems->erp_info_len = elen;
1145 break;
1146 case WLAN_EID_EXT_SUPP_RATES:
1147 elems->ext_supp_rates = pos;
1148 elems->ext_supp_rates_len = elen;
1149 break;
1150 case WLAN_EID_HT_CAPABILITY:
1151 if (elen >= sizeof(struct ieee80211_ht_cap))
1152 elems->ht_cap_elem = (void *)pos;
1153 break;
1154 case WLAN_EID_HT_INFORMATION:
1155 if (elen >= sizeof(struct ieee80211_ht_info))
1156 elems->ht_info_elem = (void *)pos;
1157 break;
1158 case WLAN_EID_MESH_ID:
1159 elems->mesh_id = pos;
1160 elems->mesh_id_len = elen;
1161 break;
1162 case WLAN_EID_MESH_CONFIG:
1163 if (elen >= sizeof(struct ieee80211_meshconf_ie))
1164 elems->mesh_config = (void *)pos;
1165 break;
1166 case WLAN_EID_PEER_MGMT:
1167 elems->peering = pos;
1168 elems->peering_len = elen;
1169 break;
1170 case WLAN_EID_PREQ:
1171 elems->preq = pos;
1172 elems->preq_len = elen;
1173 break;
1174 case WLAN_EID_PREP:
1175 elems->prep = pos;
1176 elems->prep_len = elen;
1177 break;
1178 case WLAN_EID_PERR:
1179 elems->perr = pos;
1180 elems->perr_len = elen;
1181 break;
1182 case WLAN_EID_RANN:
1183 if (elen >= sizeof(struct ieee80211_rann_ie))
1184 elems->rann = (void *)pos;
1185 break;
1186 case WLAN_EID_CHANNEL_SWITCH:
1187 elems->ch_switch_elem = pos;
1188 elems->ch_switch_elem_len = elen;
1189 break;
1190 case WLAN_EID_QUIET:
1191 if (!elems->quiet_elem) {
1192 elems->quiet_elem = pos;
1193 elems->quiet_elem_len = elen;
1194 }
1195 elems->num_of_quiet_elem++;
1196 break;
1197 case WLAN_EID_COUNTRY:
1198 elems->country_elem = pos;
1199 elems->country_elem_len = elen;
1200 break;
1201 case WLAN_EID_PWR_CONSTRAINT:
1202 elems->pwr_constr_elem = pos;
1203 elems->pwr_constr_elem_len = elen;
1204 break;
1205 case WLAN_EID_TIMEOUT_INTERVAL:
1206 elems->timeout_int = pos;
1207 elems->timeout_int_len = elen;
1208 break;
1209 default:
1210 break;
1211 }
1212
1213 left -= elen;
1214 pos += elen;
1215 }
1216 1047
1217 return crc; 1048/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
1218} 1049const unsigned char bridge_tunnel_header[] __aligned(2) =
1219EXPORT_SYMBOL(ieee802_11_parse_elems_crc); 1050 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
1051EXPORT_SYMBOL(bridge_tunnel_header);