aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-04-12 14:25:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-12 14:41:59 -0400
commit7eab0f64a9eba5405222fdef0ede2468bf495efd (patch)
treeec99640b8d0b12adbfacb85c27683125debd14f2 /net/wireless
parentcade455596504fae8e134a27189713ddf7c6d04d (diff)
parent8065248069097dddf9945acfb2081025e9618c16 (diff)
Merge branch 'master' into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-testmode.c net/wireless/nl80211.c
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c5
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/mlme.c59
-rw-r--r--net/wireless/nl80211.c92
-rw-r--r--net/wireless/nl80211.h4
-rw-r--r--net/wireless/reg.c10
-rw-r--r--net/wireless/scan.c2
-rw-r--r--net/wireless/wext-core.c6
8 files changed, 147 insertions, 34 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index ccdfed897651..59f4a7e7c092 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -708,6 +708,10 @@ void wiphy_unregister(struct wiphy *wiphy)
708 flush_work(&rdev->scan_done_wk); 708 flush_work(&rdev->scan_done_wk);
709 cancel_work_sync(&rdev->conn_work); 709 cancel_work_sync(&rdev->conn_work);
710 flush_work(&rdev->event_work); 710 flush_work(&rdev->event_work);
711
712 if (rdev->wowlan && rdev->ops->set_wakeup)
713 rdev->ops->set_wakeup(&rdev->wiphy, false);
714 cfg80211_rdev_free_wowlan(rdev);
711} 715}
712EXPORT_SYMBOL(wiphy_unregister); 716EXPORT_SYMBOL(wiphy_unregister);
713 717
@@ -720,7 +724,6 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
720 mutex_destroy(&rdev->sched_scan_mtx); 724 mutex_destroy(&rdev->sched_scan_mtx);
721 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 725 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
722 cfg80211_put_bss(&scan->pub); 726 cfg80211_put_bss(&scan->pub);
723 cfg80211_rdev_free_wowlan(rdev);
724 kfree(rdev); 727 kfree(rdev);
725} 728}
726 729
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index ba21ab22187b..8c747fa9319b 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -38,6 +38,7 @@
38 38
39#define MESH_MAX_PREQ_RETRIES 4 39#define MESH_MAX_PREQ_RETRIES 4
40 40
41#define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50
41 42
42const struct mesh_config default_mesh_config = { 43const struct mesh_config default_mesh_config = {
43 .dot11MeshRetryTimeout = MESH_RET_T, 44 .dot11MeshRetryTimeout = MESH_RET_T,
@@ -48,6 +49,7 @@ const struct mesh_config default_mesh_config = {
48 .element_ttl = MESH_DEFAULT_ELEMENT_TTL, 49 .element_ttl = MESH_DEFAULT_ELEMENT_TTL,
49 .auto_open_plinks = true, 50 .auto_open_plinks = true,
50 .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, 51 .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS,
52 .dot11MeshNbrOffsetMaxNeighbor = MESH_SYNC_NEIGHBOR_OFFSET_MAX,
51 .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, 53 .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT,
52 .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, 54 .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT,
53 .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT, 55 .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT,
@@ -62,6 +64,7 @@ const struct mesh_config default_mesh_config = {
62}; 64};
63 65
64const struct mesh_setup default_mesh_setup = { 66const struct mesh_setup default_mesh_setup = {
67 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
65 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 68 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
66 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 69 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
67 .ie = NULL, 70 .ie = NULL,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index f5a7ac3a0939..6801d96bc224 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -6,6 +6,7 @@
6 6
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/etherdevice.h>
9#include <linux/netdevice.h> 10#include <linux/netdevice.h>
10#include <linux/nl80211.h> 11#include <linux/nl80211.h>
11#include <linux/slab.h> 12#include <linux/slab.h>
@@ -100,7 +101,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
100 ASSERT_WDEV_LOCK(wdev); 101 ASSERT_WDEV_LOCK(wdev);
101 102
102 if (wdev->current_bss && 103 if (wdev->current_bss &&
103 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 104 compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) {
104 cfg80211_unhold_bss(wdev->current_bss); 105 cfg80211_unhold_bss(wdev->current_bss);
105 cfg80211_put_bss(&wdev->current_bss->pub); 106 cfg80211_put_bss(&wdev->current_bss->pub);
106 wdev->current_bss = NULL; 107 wdev->current_bss = NULL;
@@ -115,7 +116,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
115 116
116 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 117 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
117 118
118 from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0; 119 from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0;
119 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 120 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
120 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { 121 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
121 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 122 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
@@ -154,7 +155,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
154 return; 155 return;
155 156
156 if (wdev->current_bss && 157 if (wdev->current_bss &&
157 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 158 compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) {
158 cfg80211_sme_disassoc(dev, wdev->current_bss); 159 cfg80211_sme_disassoc(dev, wdev->current_bss);
159 cfg80211_unhold_bss(wdev->current_bss); 160 cfg80211_unhold_bss(wdev->current_bss);
160 cfg80211_put_bss(&wdev->current_bss->pub); 161 cfg80211_put_bss(&wdev->current_bss->pub);
@@ -165,7 +166,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
165 166
166 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 167 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
167 168
168 from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0; 169 from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0;
169 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 170 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
170} 171}
171EXPORT_SYMBOL(__cfg80211_send_disassoc); 172EXPORT_SYMBOL(__cfg80211_send_disassoc);
@@ -285,7 +286,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
285 return -EINVAL; 286 return -EINVAL;
286 287
287 if (wdev->current_bss && 288 if (wdev->current_bss &&
288 memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0) 289 compare_ether_addr(bssid, wdev->current_bss->pub.bssid) == 0)
289 return -EALREADY; 290 return -EALREADY;
290 291
291 memset(&req, 0, sizeof(req)); 292 memset(&req, 0, sizeof(req));
@@ -362,7 +363,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
362 memset(&req, 0, sizeof(req)); 363 memset(&req, 0, sizeof(req));
363 364
364 if (wdev->current_bss && prev_bssid && 365 if (wdev->current_bss && prev_bssid &&
365 memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) { 366 compare_ether_addr(wdev->current_bss->pub.bssid, prev_bssid) == 0) {
366 /* 367 /*
367 * Trying to reassociate: Allow this to proceed and let the old 368 * Trying to reassociate: Allow this to proceed and let the old
368 * association to be dropped when the new one is completed. 369 * association to be dropped when the new one is completed.
@@ -446,7 +447,8 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
446 447
447 if (local_state_change) { 448 if (local_state_change) {
448 if (wdev->current_bss && 449 if (wdev->current_bss &&
449 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 450 compare_ether_addr(wdev->current_bss->pub.bssid, bssid)
451 == 0) {
450 cfg80211_unhold_bss(wdev->current_bss); 452 cfg80211_unhold_bss(wdev->current_bss);
451 cfg80211_put_bss(&wdev->current_bss->pub); 453 cfg80211_put_bss(&wdev->current_bss->pub);
452 wdev->current_bss = NULL; 454 wdev->current_bss = NULL;
@@ -495,7 +497,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
495 req.local_state_change = local_state_change; 497 req.local_state_change = local_state_change;
496 req.ie = ie; 498 req.ie = ie;
497 req.ie_len = ie_len; 499 req.ie_len = ie_len;
498 if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) 500 if (compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0)
499 req.bss = &wdev->current_bss->pub; 501 req.bss = &wdev->current_bss->pub;
500 else 502 else
501 return -ENOTCONN; 503 return -ENOTCONN;
@@ -758,8 +760,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
758 break; 760 break;
759 } 761 }
760 762
761 if (memcmp(wdev->current_bss->pub.bssid, 763 if (compare_ether_addr(wdev->current_bss->pub.bssid,
762 mgmt->bssid, ETH_ALEN)) { 764 mgmt->bssid)) {
763 err = -ENOTCONN; 765 err = -ENOTCONN;
764 break; 766 break;
765 } 767 }
@@ -772,8 +774,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
772 break; 774 break;
773 775
774 /* for station, check that DA is the AP */ 776 /* for station, check that DA is the AP */
775 if (memcmp(wdev->current_bss->pub.bssid, 777 if (compare_ether_addr(wdev->current_bss->pub.bssid,
776 mgmt->da, ETH_ALEN)) { 778 mgmt->da)) {
777 err = -ENOTCONN; 779 err = -ENOTCONN;
778 break; 780 break;
779 } 781 }
@@ -781,11 +783,11 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
781 case NL80211_IFTYPE_AP: 783 case NL80211_IFTYPE_AP:
782 case NL80211_IFTYPE_P2P_GO: 784 case NL80211_IFTYPE_P2P_GO:
783 case NL80211_IFTYPE_AP_VLAN: 785 case NL80211_IFTYPE_AP_VLAN:
784 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) 786 if (compare_ether_addr(mgmt->bssid, dev->dev_addr))
785 err = -EINVAL; 787 err = -EINVAL;
786 break; 788 break;
787 case NL80211_IFTYPE_MESH_POINT: 789 case NL80211_IFTYPE_MESH_POINT:
788 if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) { 790 if (compare_ether_addr(mgmt->sa, mgmt->bssid)) {
789 err = -EINVAL; 791 err = -EINVAL;
790 break; 792 break;
791 } 793 }
@@ -804,7 +806,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
804 return err; 806 return err;
805 } 807 }
806 808
807 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) 809 if (compare_ether_addr(mgmt->sa, dev->dev_addr) != 0)
808 return -EINVAL; 810 return -EINVAL;
809 811
810 /* Transmit the Action frame as requested by user space */ 812 /* Transmit the Action frame as requested by user space */
@@ -928,6 +930,33 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
928} 930}
929EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); 931EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
930 932
933void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
934 enum nl80211_channel_type type)
935{
936 struct wireless_dev *wdev = dev->ieee80211_ptr;
937 struct wiphy *wiphy = wdev->wiphy;
938 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
939 struct ieee80211_channel *chan;
940
941 wdev_lock(wdev);
942
943 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
944 wdev->iftype != NL80211_IFTYPE_P2P_GO))
945 goto out;
946
947 chan = rdev_freq_to_chan(rdev, freq, type);
948 if (WARN_ON(!chan))
949 goto out;
950
951 wdev->channel = chan;
952
953 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
954out:
955 wdev_unlock(wdev);
956 return;
957}
958EXPORT_SYMBOL(cfg80211_ch_switch_notify);
959
931bool cfg80211_rx_spurious_frame(struct net_device *dev, 960bool cfg80211_rx_spurious_frame(struct net_device *dev,
932 const u8 *addr, gfp_t gfp) 961 const u8 *addr, gfp_t gfp)
933{ 962{
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a4aab1d36285..ff1a6c7fbe33 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1142,17 +1142,20 @@ static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
1142static int parse_txq_params(struct nlattr *tb[], 1142static int parse_txq_params(struct nlattr *tb[],
1143 struct ieee80211_txq_params *txq_params) 1143 struct ieee80211_txq_params *txq_params)
1144{ 1144{
1145 if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] || 1145 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
1146 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || 1146 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
1147 !tb[NL80211_TXQ_ATTR_AIFS]) 1147 !tb[NL80211_TXQ_ATTR_AIFS])
1148 return -EINVAL; 1148 return -EINVAL;
1149 1149
1150 txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]); 1150 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
1151 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); 1151 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
1152 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); 1152 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
1153 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); 1153 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
1154 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); 1154 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
1155 1155
1156 if (txq_params->ac >= NL80211_NUM_ACS)
1157 return -EINVAL;
1158
1156 return 0; 1159 return 0;
1157} 1160}
1158 1161
@@ -1332,6 +1335,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1332 goto bad_res; 1335 goto bad_res;
1333 } 1336 }
1334 1337
1338 if (!netif_running(netdev)) {
1339 result = -ENETDOWN;
1340 goto bad_res;
1341 }
1342
1335 nla_for_each_nested(nl_txq_params, 1343 nla_for_each_nested(nl_txq_params,
1336 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], 1344 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
1337 rem_txq_params) { 1345 rem_txq_params) {
@@ -2540,6 +2548,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2540 sizeof(struct nl80211_sta_flag_update), 2548 sizeof(struct nl80211_sta_flag_update),
2541 &sinfo->sta_flags)) 2549 &sinfo->sta_flags))
2542 goto nla_put_failure; 2550 goto nla_put_failure;
2551 if ((sinfo->filled & STATION_INFO_T_OFFSET) &&
2552 nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET,
2553 sinfo->t_offset))
2554 goto nla_put_failure;
2543 nla_nest_end(msg, sinfoattr); 2555 nla_nest_end(msg, sinfoattr);
2544 2556
2545 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) && 2557 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) &&
@@ -3340,6 +3352,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
3340 cur_params.element_ttl) || 3352 cur_params.element_ttl) ||
3341 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, 3353 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
3342 cur_params.auto_open_plinks) || 3354 cur_params.auto_open_plinks) ||
3355 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3356 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
3343 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 3357 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3344 cur_params.dot11MeshHWMPmaxPREQretries) || 3358 cur_params.dot11MeshHWMPmaxPREQretries) ||
3345 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME, 3359 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
@@ -3385,6 +3399,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3385 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 }, 3399 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
3386 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, 3400 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
3387 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, 3401 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
3402 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
3388 3403
3389 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, 3404 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
3390 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, 3405 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
@@ -3402,6 +3417,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3402 3417
3403static const struct nla_policy 3418static const struct nla_policy
3404 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { 3419 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
3420 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
3405 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 3421 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
3406 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 3422 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
3407 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 3423 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
@@ -3454,6 +3470,9 @@ do {\
3454 mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); 3470 mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
3455 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 3471 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
3456 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); 3472 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
3473 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
3474 mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3475 nla_get_u32);
3457 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 3476 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
3458 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 3477 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3459 nla_get_u8); 3478 nla_get_u8);
@@ -3511,6 +3530,12 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
3511 nl80211_mesh_setup_params_policy)) 3530 nl80211_mesh_setup_params_policy))
3512 return -EINVAL; 3531 return -EINVAL;
3513 3532
3533 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
3534 setup->sync_method =
3535 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
3536 IEEE80211_SYNC_METHOD_VENDOR :
3537 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
3538
3514 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL]) 3539 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
3515 setup->path_sel_proto = 3540 setup->path_sel_proto =
3516 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ? 3541 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
@@ -6077,6 +6102,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6077 struct cfg80211_wowlan new_triggers = {}; 6102 struct cfg80211_wowlan new_triggers = {};
6078 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; 6103 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
6079 int err, i; 6104 int err, i;
6105 bool prev_enabled = rdev->wowlan;
6080 6106
6081 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) 6107 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
6082 return -EOPNOTSUPP; 6108 return -EOPNOTSUPP;
@@ -6209,6 +6235,9 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6209 rdev->wowlan = NULL; 6235 rdev->wowlan = NULL;
6210 } 6236 }
6211 6237
6238 if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan)
6239 rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan);
6240
6212 return 0; 6241 return 0;
6213 error: 6242 error:
6214 for (i = 0; i < new_triggers.n_patterns; i++) 6243 for (i = 0; i < new_triggers.n_patterns; i++)
@@ -6467,7 +6496,7 @@ static struct genl_ops nl80211_ops[] = {
6467 .doit = nl80211_get_key, 6496 .doit = nl80211_get_key,
6468 .policy = nl80211_policy, 6497 .policy = nl80211_policy,
6469 .flags = GENL_ADMIN_PERM, 6498 .flags = GENL_ADMIN_PERM,
6470 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6499 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6471 NL80211_FLAG_NEED_RTNL, 6500 NL80211_FLAG_NEED_RTNL,
6472 }, 6501 },
6473 { 6502 {
@@ -6499,7 +6528,7 @@ static struct genl_ops nl80211_ops[] = {
6499 .policy = nl80211_policy, 6528 .policy = nl80211_policy,
6500 .flags = GENL_ADMIN_PERM, 6529 .flags = GENL_ADMIN_PERM,
6501 .doit = nl80211_set_beacon, 6530 .doit = nl80211_set_beacon,
6502 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6531 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6503 NL80211_FLAG_NEED_RTNL, 6532 NL80211_FLAG_NEED_RTNL,
6504 }, 6533 },
6505 { 6534 {
@@ -6507,7 +6536,7 @@ static struct genl_ops nl80211_ops[] = {
6507 .policy = nl80211_policy, 6536 .policy = nl80211_policy,
6508 .flags = GENL_ADMIN_PERM, 6537 .flags = GENL_ADMIN_PERM,
6509 .doit = nl80211_start_ap, 6538 .doit = nl80211_start_ap,
6510 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6539 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6511 NL80211_FLAG_NEED_RTNL, 6540 NL80211_FLAG_NEED_RTNL,
6512 }, 6541 },
6513 { 6542 {
@@ -6515,7 +6544,7 @@ static struct genl_ops nl80211_ops[] = {
6515 .policy = nl80211_policy, 6544 .policy = nl80211_policy,
6516 .flags = GENL_ADMIN_PERM, 6545 .flags = GENL_ADMIN_PERM,
6517 .doit = nl80211_stop_ap, 6546 .doit = nl80211_stop_ap,
6518 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6547 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6519 NL80211_FLAG_NEED_RTNL, 6548 NL80211_FLAG_NEED_RTNL,
6520 }, 6549 },
6521 { 6550 {
@@ -6531,7 +6560,7 @@ static struct genl_ops nl80211_ops[] = {
6531 .doit = nl80211_set_station, 6560 .doit = nl80211_set_station,
6532 .policy = nl80211_policy, 6561 .policy = nl80211_policy,
6533 .flags = GENL_ADMIN_PERM, 6562 .flags = GENL_ADMIN_PERM,
6534 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6563 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6535 NL80211_FLAG_NEED_RTNL, 6564 NL80211_FLAG_NEED_RTNL,
6536 }, 6565 },
6537 { 6566 {
@@ -6547,7 +6576,7 @@ static struct genl_ops nl80211_ops[] = {
6547 .doit = nl80211_del_station, 6576 .doit = nl80211_del_station,
6548 .policy = nl80211_policy, 6577 .policy = nl80211_policy,
6549 .flags = GENL_ADMIN_PERM, 6578 .flags = GENL_ADMIN_PERM,
6550 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6579 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6551 NL80211_FLAG_NEED_RTNL, 6580 NL80211_FLAG_NEED_RTNL,
6552 }, 6581 },
6553 { 6582 {
@@ -6580,7 +6609,7 @@ static struct genl_ops nl80211_ops[] = {
6580 .doit = nl80211_del_mpath, 6609 .doit = nl80211_del_mpath,
6581 .policy = nl80211_policy, 6610 .policy = nl80211_policy,
6582 .flags = GENL_ADMIN_PERM, 6611 .flags = GENL_ADMIN_PERM,
6583 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6612 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6584 NL80211_FLAG_NEED_RTNL, 6613 NL80211_FLAG_NEED_RTNL,
6585 }, 6614 },
6586 { 6615 {
@@ -6588,7 +6617,7 @@ static struct genl_ops nl80211_ops[] = {
6588 .doit = nl80211_set_bss, 6617 .doit = nl80211_set_bss,
6589 .policy = nl80211_policy, 6618 .policy = nl80211_policy,
6590 .flags = GENL_ADMIN_PERM, 6619 .flags = GENL_ADMIN_PERM,
6591 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6620 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6592 NL80211_FLAG_NEED_RTNL, 6621 NL80211_FLAG_NEED_RTNL,
6593 }, 6622 },
6594 { 6623 {
@@ -6614,7 +6643,7 @@ static struct genl_ops nl80211_ops[] = {
6614 .doit = nl80211_get_mesh_config, 6643 .doit = nl80211_get_mesh_config,
6615 .policy = nl80211_policy, 6644 .policy = nl80211_policy,
6616 /* can be retrieved by unprivileged users */ 6645 /* can be retrieved by unprivileged users */
6617 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6646 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6618 NL80211_FLAG_NEED_RTNL, 6647 NL80211_FLAG_NEED_RTNL,
6619 }, 6648 },
6620 { 6649 {
@@ -6747,7 +6776,7 @@ static struct genl_ops nl80211_ops[] = {
6747 .doit = nl80211_setdel_pmksa, 6776 .doit = nl80211_setdel_pmksa,
6748 .policy = nl80211_policy, 6777 .policy = nl80211_policy,
6749 .flags = GENL_ADMIN_PERM, 6778 .flags = GENL_ADMIN_PERM,
6750 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6779 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6751 NL80211_FLAG_NEED_RTNL, 6780 NL80211_FLAG_NEED_RTNL,
6752 }, 6781 },
6753 { 6782 {
@@ -6755,7 +6784,7 @@ static struct genl_ops nl80211_ops[] = {
6755 .doit = nl80211_setdel_pmksa, 6784 .doit = nl80211_setdel_pmksa,
6756 .policy = nl80211_policy, 6785 .policy = nl80211_policy,
6757 .flags = GENL_ADMIN_PERM, 6786 .flags = GENL_ADMIN_PERM,
6758 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6787 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6759 NL80211_FLAG_NEED_RTNL, 6788 NL80211_FLAG_NEED_RTNL,
6760 }, 6789 },
6761 { 6790 {
@@ -6763,7 +6792,7 @@ static struct genl_ops nl80211_ops[] = {
6763 .doit = nl80211_flush_pmksa, 6792 .doit = nl80211_flush_pmksa,
6764 .policy = nl80211_policy, 6793 .policy = nl80211_policy,
6765 .flags = GENL_ADMIN_PERM, 6794 .flags = GENL_ADMIN_PERM,
6766 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6795 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6767 NL80211_FLAG_NEED_RTNL, 6796 NL80211_FLAG_NEED_RTNL,
6768 }, 6797 },
6769 { 6798 {
@@ -6923,7 +6952,7 @@ static struct genl_ops nl80211_ops[] = {
6923 .doit = nl80211_probe_client, 6952 .doit = nl80211_probe_client,
6924 .policy = nl80211_policy, 6953 .policy = nl80211_policy,
6925 .flags = GENL_ADMIN_PERM, 6954 .flags = GENL_ADMIN_PERM,
6926 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6955 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6927 NL80211_FLAG_NEED_RTNL, 6956 NL80211_FLAG_NEED_RTNL,
6928 }, 6957 },
6929 { 6958 {
@@ -8012,6 +8041,39 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8012 nlmsg_free(msg); 8041 nlmsg_free(msg);
8013} 8042}
8014 8043
8044void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8045 struct net_device *netdev, int freq,
8046 enum nl80211_channel_type type, gfp_t gfp)
8047{
8048 struct sk_buff *msg;
8049 void *hdr;
8050
8051 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8052 if (!msg)
8053 return;
8054
8055 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY);
8056 if (!hdr) {
8057 nlmsg_free(msg);
8058 return;
8059 }
8060
8061 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8062 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
8063 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type))
8064 goto nla_put_failure;
8065
8066 genlmsg_end(msg, hdr);
8067
8068 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8069 nl80211_mlme_mcgrp.id, gfp);
8070 return;
8071
8072 nla_put_failure:
8073 genlmsg_cancel(msg, hdr);
8074 nlmsg_free(msg);
8075}
8076
8015void 8077void
8016nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 8078nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
8017 struct net_device *netdev, const u8 *peer, 8079 struct net_device *netdev, const u8 *peer,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 4ffe50df9f31..01a1122c3b33 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -118,6 +118,10 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
118 struct net_device *netdev, int index, 118 struct net_device *netdev, int index,
119 const u8 *bssid, bool preauth, gfp_t gfp); 119 const u8 *bssid, bool preauth, gfp_t gfp);
120 120
121void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
122 struct net_device *dev, int freq,
123 enum nl80211_channel_type type, gfp_t gfp);
124
121bool nl80211_unexpected_frame(struct net_device *dev, 125bool nl80211_unexpected_frame(struct net_device *dev,
122 const u8 *addr, gfp_t gfp); 126 const u8 *addr, gfp_t gfp);
123bool nl80211_unexpected_4addr_frame(struct net_device *dev, 127bool nl80211_unexpected_4addr_frame(struct net_device *dev,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e9a0ac83b84c..15f347477a99 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -388,7 +388,15 @@ static void reg_regdb_query(const char *alpha2)
388 388
389 schedule_work(&reg_regdb_work); 389 schedule_work(&reg_regdb_work);
390} 390}
391
392/* Feel free to add any other sanity checks here */
393static void reg_regdb_size_check(void)
394{
395 /* We should ideally BUILD_BUG_ON() but then random builds would fail */
396 WARN_ONCE(!reg_regdb_size, "db.txt is empty, you should update it...");
397}
391#else 398#else
399static inline void reg_regdb_size_check(void) {}
392static inline void reg_regdb_query(const char *alpha2) {} 400static inline void reg_regdb_query(const char *alpha2) {}
393#endif /* CONFIG_CFG80211_INTERNAL_REGDB */ 401#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
394 402
@@ -2322,6 +2330,8 @@ int __init regulatory_init(void)
2322 spin_lock_init(&reg_requests_lock); 2330 spin_lock_init(&reg_requests_lock);
2323 spin_lock_init(&reg_pending_beacons_lock); 2331 spin_lock_init(&reg_pending_beacons_lock);
2324 2332
2333 reg_regdb_size_check();
2334
2325 cfg80211_regdomain = cfg80211_world_regdom; 2335 cfg80211_regdomain = cfg80211_world_regdom;
2326 2336
2327 user_alpha2[0] = '9'; 2337 user_alpha2[0] = '9';
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 70faadf16a32..fdbcfe692a36 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -378,7 +378,7 @@ static int cmp_bss_core(struct cfg80211_bss *a,
378 b->len_information_elements); 378 b->len_information_elements);
379 } 379 }
380 380
381 return memcmp(a->bssid, b->bssid, ETH_ALEN); 381 return compare_ether_addr(a->bssid, b->bssid);
382} 382}
383 383
384static int cmp_bss(struct cfg80211_bss *a, 384static int cmp_bss(struct cfg80211_bss *a,
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 9f544c95171c..22adfebaad27 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -781,8 +781,10 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
781 if (cmd == SIOCSIWENCODEEXT) { 781 if (cmd == SIOCSIWENCODEEXT) {
782 struct iw_encode_ext *ee = (void *) extra; 782 struct iw_encode_ext *ee = (void *) extra;
783 783
784 if (iwp->length < sizeof(*ee) + ee->key_len) 784 if (iwp->length < sizeof(*ee) + ee->key_len) {
785 return -EFAULT; 785 err = -EFAULT;
786 goto out;
787 }
786 } 788 }
787 } 789 }
788 790