aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-09-18 22:29:08 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-18 22:29:08 -0400
commitc13ed534b8db543e4d8ead3885f4b06585a5771c (patch)
treeb371024a63efe057e0bed95fc5ed77900b113e7d /net
parent22da73492541736eff5f6a6634c732e36c52a133 (diff)
parentfbd05e4a6e82fd573d3aa79e284e424b8d78c149 (diff)
Merge tag 'mac80211-next-for-davem-2016-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== This time we have various things - all across the board: * MU-MIMO sniffer support in mac80211 * a create_singlethread_workqueue() cleanup * interface dump filtering that was documented but not implemented * support for the new radiotap timestamp field * send delBA in two unexpected conditions (as required by the spec) * connect keys cleanups - allow only WEP with index 0-3 * per-station aggregation limit to work around broken APs * debugfs improvement for the integrated codel algorithm and various other small improvements and cleanups. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-rx.c11
-rw-r--r--net/mac80211/cfg.c35
-rw-r--r--net/mac80211/debugfs.c152
-rw-r--r--net/mac80211/debugfs_netdev.c37
-rw-r--r--net/mac80211/debugfs_sta.c56
-rw-r--r--net/mac80211/driver-ops.c2
-rw-r--r--net/mac80211/driver-ops.h18
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/iface.c21
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mlme.c12
-rw-r--r--net/mac80211/pm.c3
-rw-r--r--net/mac80211/rx.c69
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/sta_info.c5
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/status.c8
-rw-r--r--net/mac80211/tx.c21
-rw-r--r--net/mac80211/util.c3
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/ibss.c11
-rw-r--r--net/wireless/mlme.c2
-rw-r--r--net/wireless/nl80211.c85
-rw-r--r--net/wireless/scan.c58
-rw-r--r--net/wireless/sme.c3
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c13
-rw-r--r--net/wireless/wext-compat.c9
-rw-r--r--net/wireless/wext-sme.c5
30 files changed, 404 insertions, 264 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index a9aff6079c42..a5d69dfc8e03 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -298,10 +298,13 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
298 buf_size = IEEE80211_MAX_AMPDU_BUF; 298 buf_size = IEEE80211_MAX_AMPDU_BUF;
299 299
300 /* make sure the size doesn't exceed the maximum supported by the hw */ 300 /* make sure the size doesn't exceed the maximum supported by the hw */
301 if (buf_size > local->hw.max_rx_aggregation_subframes) 301 if (buf_size > sta->sta.max_rx_aggregation_subframes)
302 buf_size = local->hw.max_rx_aggregation_subframes; 302 buf_size = sta->sta.max_rx_aggregation_subframes;
303 params.buf_size = buf_size; 303 params.buf_size = buf_size;
304 304
305 ht_dbg(sta->sdata, "AddBA Req buf_size=%d for %pM\n",
306 buf_size, sta->sta.addr);
307
305 /* examine state machine */ 308 /* examine state machine */
306 mutex_lock(&sta->ampdu_mlme.mtx); 309 mutex_lock(&sta->ampdu_mlme.mtx);
307 310
@@ -406,8 +409,10 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
406 } 409 }
407 410
408end: 411end:
409 if (status == WLAN_STATUS_SUCCESS) 412 if (status == WLAN_STATUS_SUCCESS) {
410 __set_bit(tid, sta->ampdu_mlme.agg_session_valid); 413 __set_bit(tid, sta->ampdu_mlme.agg_session_valid);
414 __clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
415 }
411 mutex_unlock(&sta->ampdu_mlme.mtx); 416 mutex_unlock(&sta->ampdu_mlme.mtx);
412 417
413end_no_lock: 418end_no_lock:
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 543b1d4fc33d..e29ff5749944 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -39,7 +39,7 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
39 39
40 if (type == NL80211_IFTYPE_MONITOR && flags) { 40 if (type == NL80211_IFTYPE_MONITOR && flags) {
41 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 41 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
42 sdata->u.mntr_flags = *flags; 42 sdata->u.mntr.flags = *flags;
43 } 43 }
44 44
45 return wdev; 45 return wdev;
@@ -73,8 +73,29 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
73 sdata->u.mgd.use_4addr = params->use_4addr; 73 sdata->u.mgd.use_4addr = params->use_4addr;
74 } 74 }
75 75
76 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) { 76 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
77 struct ieee80211_local *local = sdata->local; 77 struct ieee80211_local *local = sdata->local;
78 struct ieee80211_sub_if_data *monitor_sdata;
79 u32 mu_mntr_cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
80
81 monitor_sdata = rtnl_dereference(local->monitor_sdata);
82 if (monitor_sdata &&
83 wiphy_ext_feature_isset(wiphy, mu_mntr_cap_flag)) {
84 memcpy(monitor_sdata->vif.bss_conf.mu_group.membership,
85 params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN);
86 memcpy(monitor_sdata->vif.bss_conf.mu_group.position,
87 params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
88 WLAN_USER_POSITION_LEN);
89 monitor_sdata->vif.mu_mimo_owner = true;
90 ieee80211_bss_info_change_notify(monitor_sdata,
91 BSS_CHANGED_MU_GROUPS);
92
93 ether_addr_copy(monitor_sdata->u.mntr.mu_follow_addr,
94 params->macaddr);
95 }
96
97 if (!flags)
98 return 0;
78 99
79 if (ieee80211_sdata_running(sdata)) { 100 if (ieee80211_sdata_running(sdata)) {
80 u32 mask = MONITOR_FLAG_COOK_FRAMES | 101 u32 mask = MONITOR_FLAG_COOK_FRAMES |
@@ -89,11 +110,11 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
89 * cooked_mntrs, monitor and all fif_* counters 110 * cooked_mntrs, monitor and all fif_* counters
90 * reconfigure hardware 111 * reconfigure hardware
91 */ 112 */
92 if ((*flags & mask) != (sdata->u.mntr_flags & mask)) 113 if ((*flags & mask) != (sdata->u.mntr.flags & mask))
93 return -EBUSY; 114 return -EBUSY;
94 115
95 ieee80211_adjust_monitor_flags(sdata, -1); 116 ieee80211_adjust_monitor_flags(sdata, -1);
96 sdata->u.mntr_flags = *flags; 117 sdata->u.mntr.flags = *flags;
97 ieee80211_adjust_monitor_flags(sdata, 1); 118 ieee80211_adjust_monitor_flags(sdata, 1);
98 119
99 ieee80211_configure_filter(local); 120 ieee80211_configure_filter(local);
@@ -103,7 +124,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
103 * and ieee80211_do_open take care of "everything" 124 * and ieee80211_do_open take care of "everything"
104 * mentioned in the comment above. 125 * mentioned in the comment above.
105 */ 126 */
106 sdata->u.mntr_flags = *flags; 127 sdata->u.mntr.flags = *flags;
107 } 128 }
108 } 129 }
109 130
@@ -2940,10 +2961,6 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
2940 } 2961 }
2941 2962
2942 chanctx = container_of(conf, struct ieee80211_chanctx, conf); 2963 chanctx = container_of(conf, struct ieee80211_chanctx, conf);
2943 if (!chanctx) {
2944 err = -EBUSY;
2945 goto out;
2946 }
2947 2964
2948 ch_switch.timestamp = 0; 2965 ch_switch.timestamp = 0;
2949 ch_switch.device_timestamp = 0; 2966 ch_switch.device_timestamp = 0;
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 2906c1004e1a..8ca62b6bb02a 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -71,138 +71,39 @@ DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
71DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s", 71DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
72 local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); 72 local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
73 73
74struct aqm_info { 74static ssize_t aqm_read(struct file *file,
75 struct ieee80211_local *local; 75 char __user *user_buf,
76 size_t size; 76 size_t count,
77 size_t len; 77 loff_t *ppos)
78 unsigned char buf[0];
79};
80
81#define AQM_HDR_LEN 200
82#define AQM_HW_ENTRY_LEN 40
83#define AQM_TXQ_ENTRY_LEN 110
84
85static int aqm_open(struct inode *inode, struct file *file)
86{ 78{
87 struct ieee80211_local *local = inode->i_private; 79 struct ieee80211_local *local = file->private_data;
88 struct ieee80211_sub_if_data *sdata;
89 struct sta_info *sta;
90 struct txq_info *txqi;
91 struct fq *fq = &local->fq; 80 struct fq *fq = &local->fq;
92 struct aqm_info *info = NULL; 81 char buf[200];
93 int len = 0; 82 int len = 0;
94 int i;
95
96 if (!local->ops->wake_tx_queue)
97 return -EOPNOTSUPP;
98
99 len += AQM_HDR_LEN;
100 len += 6 * AQM_HW_ENTRY_LEN;
101
102 rcu_read_lock();
103 list_for_each_entry_rcu(sdata, &local->interfaces, list)
104 len += AQM_TXQ_ENTRY_LEN;
105 list_for_each_entry_rcu(sta, &local->sta_list, list)
106 len += AQM_TXQ_ENTRY_LEN * ARRAY_SIZE(sta->sta.txq);
107 rcu_read_unlock();
108
109 info = vmalloc(len);
110 if (!info)
111 return -ENOMEM;
112 83
113 spin_lock_bh(&local->fq.lock); 84 spin_lock_bh(&local->fq.lock);
114 rcu_read_lock(); 85 rcu_read_lock();
115 86
116 file->private_data = info; 87 len = scnprintf(buf, sizeof(buf),
117 info->local = local; 88 "access name value\n"
118 info->size = len; 89 "R fq_flows_cnt %u\n"
119 len = 0; 90 "R fq_backlog %u\n"
120 91 "R fq_overlimit %u\n"
121 len += scnprintf(info->buf + len, info->size - len, 92 "R fq_collisions %u\n"
122 "* hw\n" 93 "RW fq_limit %u\n"
123 "access name value\n" 94 "RW fq_quantum %u\n",
124 "R fq_flows_cnt %u\n" 95 fq->flows_cnt,
125 "R fq_backlog %u\n" 96 fq->backlog,
126 "R fq_overlimit %u\n" 97 fq->overlimit,
127 "R fq_collisions %u\n" 98 fq->collisions,
128 "RW fq_limit %u\n" 99 fq->limit,
129 "RW fq_quantum %u\n", 100 fq->quantum);
130 fq->flows_cnt,
131 fq->backlog,
132 fq->overlimit,
133 fq->collisions,
134 fq->limit,
135 fq->quantum);
136
137 len += scnprintf(info->buf + len,
138 info->size - len,
139 "* vif\n"
140 "ifname addr ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
141
142 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
143 txqi = to_txq_info(sdata->vif.txq);
144 len += scnprintf(info->buf + len, info->size - len,
145 "%s %pM %u %u %u %u %u %u %u %u\n",
146 sdata->name,
147 sdata->vif.addr,
148 txqi->txq.ac,
149 txqi->tin.backlog_bytes,
150 txqi->tin.backlog_packets,
151 txqi->tin.flows,
152 txqi->tin.overlimit,
153 txqi->tin.collisions,
154 txqi->tin.tx_bytes,
155 txqi->tin.tx_packets);
156 }
157
158 len += scnprintf(info->buf + len,
159 info->size - len,
160 "* sta\n"
161 "ifname addr tid ac backlog-bytes backlog-packets flows overlimit collisions tx-bytes tx-packets\n");
162
163 list_for_each_entry_rcu(sta, &local->sta_list, list) {
164 sdata = sta->sdata;
165 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
166 txqi = to_txq_info(sta->sta.txq[i]);
167 len += scnprintf(info->buf + len, info->size - len,
168 "%s %pM %d %d %u %u %u %u %u %u %u\n",
169 sdata->name,
170 sta->sta.addr,
171 txqi->txq.tid,
172 txqi->txq.ac,
173 txqi->tin.backlog_bytes,
174 txqi->tin.backlog_packets,
175 txqi->tin.flows,
176 txqi->tin.overlimit,
177 txqi->tin.collisions,
178 txqi->tin.tx_bytes,
179 txqi->tin.tx_packets);
180 }
181 }
182
183 info->len = len;
184 101
185 rcu_read_unlock(); 102 rcu_read_unlock();
186 spin_unlock_bh(&local->fq.lock); 103 spin_unlock_bh(&local->fq.lock);
187 104
188 return 0;
189}
190
191static int aqm_release(struct inode *inode, struct file *file)
192{
193 vfree(file->private_data);
194 return 0;
195}
196
197static ssize_t aqm_read(struct file *file,
198 char __user *user_buf,
199 size_t count,
200 loff_t *ppos)
201{
202 struct aqm_info *info = file->private_data;
203
204 return simple_read_from_buffer(user_buf, count, ppos, 105 return simple_read_from_buffer(user_buf, count, ppos,
205 info->buf, info->len); 106 buf, len);
206} 107}
207 108
208static ssize_t aqm_write(struct file *file, 109static ssize_t aqm_write(struct file *file,
@@ -210,8 +111,7 @@ static ssize_t aqm_write(struct file *file,
210 size_t count, 111 size_t count,
211 loff_t *ppos) 112 loff_t *ppos)
212{ 113{
213 struct aqm_info *info = file->private_data; 114 struct ieee80211_local *local = file->private_data;
214 struct ieee80211_local *local = info->local;
215 char buf[100]; 115 char buf[100];
216 size_t len; 116 size_t len;
217 117
@@ -237,8 +137,7 @@ static ssize_t aqm_write(struct file *file,
237static const struct file_operations aqm_ops = { 137static const struct file_operations aqm_ops = {
238 .write = aqm_write, 138 .write = aqm_write,
239 .read = aqm_read, 139 .read = aqm_read,
240 .open = aqm_open, 140 .open = simple_open,
241 .release = aqm_release,
242 .llseek = default_llseek, 141 .llseek = default_llseek,
243}; 142};
244 143
@@ -302,6 +201,7 @@ static const char *hw_flag_names[] = {
302 FLAG(USES_RSS), 201 FLAG(USES_RSS),
303 FLAG(TX_AMSDU), 202 FLAG(TX_AMSDU),
304 FLAG(TX_FRAG_LIST), 203 FLAG(TX_FRAG_LIST),
204 FLAG(REPORTS_LOW_ACK),
305#undef FLAG 205#undef FLAG
306}; 206};
307 207
@@ -428,7 +328,9 @@ void debugfs_hw_add(struct ieee80211_local *local)
428 DEBUGFS_ADD(hwflags); 328 DEBUGFS_ADD(hwflags);
429 DEBUGFS_ADD(user_power); 329 DEBUGFS_ADD(user_power);
430 DEBUGFS_ADD(power); 330 DEBUGFS_ADD(power);
431 DEBUGFS_ADD_MODE(aqm, 0600); 331
332 if (local->ops->wake_tx_queue)
333 DEBUGFS_ADD_MODE(aqm, 0600);
432 334
433 statsd = debugfs_create_dir("statistics", phyd); 335 statsd = debugfs_create_dir("statistics", phyd);
434 336
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index a5ba739cd2a7..5d35c0f37bb7 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -30,7 +30,7 @@ static ssize_t ieee80211_if_read(
30 size_t count, loff_t *ppos, 30 size_t count, loff_t *ppos,
31 ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int)) 31 ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
32{ 32{
33 char buf[70]; 33 char buf[200];
34 ssize_t ret = -EINVAL; 34 ssize_t ret = -EINVAL;
35 35
36 read_lock(&dev_base_lock); 36 read_lock(&dev_base_lock);
@@ -486,6 +486,38 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
486} 486}
487IEEE80211_IF_FILE_R(num_buffered_multicast); 487IEEE80211_IF_FILE_R(num_buffered_multicast);
488 488
489static ssize_t ieee80211_if_fmt_aqm(
490 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
491{
492 struct ieee80211_local *local = sdata->local;
493 struct txq_info *txqi = to_txq_info(sdata->vif.txq);
494 int len;
495
496 spin_lock_bh(&local->fq.lock);
497 rcu_read_lock();
498
499 len = scnprintf(buf,
500 buflen,
501 "ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n"
502 "%u %u %u %u %u %u %u %u %u %u\n",
503 txqi->txq.ac,
504 txqi->tin.backlog_bytes,
505 txqi->tin.backlog_packets,
506 txqi->tin.flows,
507 txqi->cstats.drop_count,
508 txqi->cstats.ecn_mark,
509 txqi->tin.overlimit,
510 txqi->tin.collisions,
511 txqi->tin.tx_bytes,
512 txqi->tin.tx_packets);
513
514 rcu_read_unlock();
515 spin_unlock_bh(&local->fq.lock);
516
517 return len;
518}
519IEEE80211_IF_FILE_R(aqm);
520
489/* IBSS attributes */ 521/* IBSS attributes */
490static ssize_t ieee80211_if_fmt_tsf( 522static ssize_t ieee80211_if_fmt_tsf(
491 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) 523 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
@@ -618,6 +650,9 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
618 DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_2ghz); 650 DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_2ghz);
619 DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz); 651 DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
620 DEBUGFS_ADD(hw_queues); 652 DEBUGFS_ADD(hw_queues);
653
654 if (sdata->local->ops->wake_tx_queue)
655 DEBUGFS_ADD(aqm);
621} 656}
622 657
623static void add_sta_files(struct ieee80211_sub_if_data *sdata) 658static void add_sta_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index fd334133ff45..a2fcdb47a0e6 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -133,6 +133,55 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
133} 133}
134STA_OPS(last_seq_ctrl); 134STA_OPS(last_seq_ctrl);
135 135
136#define AQM_TXQ_ENTRY_LEN 130
137
138static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
139 size_t count, loff_t *ppos)
140{
141 struct sta_info *sta = file->private_data;
142 struct ieee80211_local *local = sta->local;
143 size_t bufsz = AQM_TXQ_ENTRY_LEN*(IEEE80211_NUM_TIDS+1);
144 char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
145 struct txq_info *txqi;
146 ssize_t rv;
147 int i;
148
149 if (!buf)
150 return -ENOMEM;
151
152 spin_lock_bh(&local->fq.lock);
153 rcu_read_lock();
154
155 p += scnprintf(p,
156 bufsz+buf-p,
157 "tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n");
158
159 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
160 txqi = to_txq_info(sta->sta.txq[i]);
161 p += scnprintf(p, bufsz+buf-p,
162 "%d %d %u %u %u %u %u %u %u %u %u\n",
163 txqi->txq.tid,
164 txqi->txq.ac,
165 txqi->tin.backlog_bytes,
166 txqi->tin.backlog_packets,
167 txqi->tin.flows,
168 txqi->cstats.drop_count,
169 txqi->cstats.ecn_mark,
170 txqi->tin.overlimit,
171 txqi->tin.collisions,
172 txqi->tin.tx_bytes,
173 txqi->tin.tx_packets);
174 }
175
176 rcu_read_unlock();
177 spin_unlock_bh(&local->fq.lock);
178
179 rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
180 kfree(buf);
181 return rv;
182}
183STA_OPS(aqm);
184
136static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 185static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
137 size_t count, loff_t *ppos) 186 size_t count, loff_t *ppos)
138{ 187{
@@ -478,6 +527,9 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
478 DEBUGFS_ADD_COUNTER(rx_fragments, rx_stats.fragments); 527 DEBUGFS_ADD_COUNTER(rx_fragments, rx_stats.fragments);
479 DEBUGFS_ADD_COUNTER(tx_filtered, status_stats.filtered); 528 DEBUGFS_ADD_COUNTER(tx_filtered, status_stats.filtered);
480 529
530 if (local->ops->wake_tx_queue)
531 DEBUGFS_ADD(aqm);
532
481 if (sizeof(sta->driver_buffered_tids) == sizeof(u32)) 533 if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
482 debugfs_create_x32("driver_buffered_tids", 0400, 534 debugfs_create_x32("driver_buffered_tids", 0400,
483 sta->debugfs_dir, 535 sta->debugfs_dir,
@@ -492,10 +544,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
492 544
493void ieee80211_sta_debugfs_remove(struct sta_info *sta) 545void ieee80211_sta_debugfs_remove(struct sta_info *sta)
494{ 546{
495 struct ieee80211_local *local = sta->local;
496 struct ieee80211_sub_if_data *sdata = sta->sdata;
497
498 drv_sta_remove_debugfs(local, sdata, &sta->sta, sta->debugfs_dir);
499 debugfs_remove_recursive(sta->debugfs_dir); 547 debugfs_remove_recursive(sta->debugfs_dir);
500 sta->debugfs_dir = NULL; 548 sta->debugfs_dir = NULL;
501} 549}
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index c258f1041d33..c701b6438bd9 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -62,7 +62,7 @@ int drv_add_interface(struct ieee80211_local *local,
62 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 62 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
63 (sdata->vif.type == NL80211_IFTYPE_MONITOR && 63 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
64 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && 64 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
65 !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)))) 65 !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))))
66 return -EINVAL; 66 return -EINVAL;
67 67
68 trace_drv_add_interface(local, sdata); 68 trace_drv_add_interface(local, sdata);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 42a41ae405ba..fe35a1c0dc86 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -162,7 +162,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
162 return; 162 return;
163 163
164 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 164 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
165 sdata->vif.type == NL80211_IFTYPE_MONITOR)) 165 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
166 !sdata->vif.mu_mimo_owner)))
166 return; 167 return;
167 168
168 if (!check_sdata_in_driver(sdata)) 169 if (!check_sdata_in_driver(sdata))
@@ -498,21 +499,6 @@ static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
498 local->ops->sta_add_debugfs(&local->hw, &sdata->vif, 499 local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
499 sta, dir); 500 sta, dir);
500} 501}
501
502static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
503 struct ieee80211_sub_if_data *sdata,
504 struct ieee80211_sta *sta,
505 struct dentry *dir)
506{
507 might_sleep();
508
509 sdata = get_bss_sdata(sdata);
510 check_sdata_in_driver(sdata);
511
512 if (local->ops->sta_remove_debugfs)
513 local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
514 sta, dir);
515}
516#endif 502#endif
517 503
518static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local, 504static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f56d342c31b8..c71c73594790 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -3,7 +3,7 @@
3 * Copyright 2005, Devicescape Software, Inc. 3 * Copyright 2005, Devicescape Software, Inc.
4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
5 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2014 Intel Mobile Communications GmbH 6 * Copyright 2013-2015 Intel Mobile Communications GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -818,12 +818,18 @@ struct txq_info {
818 struct fq_tin tin; 818 struct fq_tin tin;
819 struct fq_flow def_flow; 819 struct fq_flow def_flow;
820 struct codel_vars def_cvars; 820 struct codel_vars def_cvars;
821 struct codel_stats cstats;
821 unsigned long flags; 822 unsigned long flags;
822 823
823 /* keep last! */ 824 /* keep last! */
824 struct ieee80211_txq txq; 825 struct ieee80211_txq txq;
825}; 826};
826 827
828struct ieee80211_if_mntr {
829 u32 flags;
830 u8 mu_follow_addr[ETH_ALEN] __aligned(2);
831};
832
827struct ieee80211_sub_if_data { 833struct ieee80211_sub_if_data {
828 struct list_head list; 834 struct list_head list;
829 835
@@ -922,7 +928,7 @@ struct ieee80211_sub_if_data {
922 struct ieee80211_if_ibss ibss; 928 struct ieee80211_if_ibss ibss;
923 struct ieee80211_if_mesh mesh; 929 struct ieee80211_if_mesh mesh;
924 struct ieee80211_if_ocb ocb; 930 struct ieee80211_if_ocb ocb;
925 u32 mntr_flags; 931 struct ieee80211_if_mntr mntr;
926 } u; 932 } u;
927 933
928#ifdef CONFIG_MAC80211_DEBUGFS 934#ifdef CONFIG_MAC80211_DEBUGFS
@@ -1112,7 +1118,6 @@ struct ieee80211_local {
1112 struct fq fq; 1118 struct fq fq;
1113 struct codel_vars *cvars; 1119 struct codel_vars *cvars;
1114 struct codel_params cparams; 1120 struct codel_params cparams;
1115 struct codel_stats cstats;
1116 1121
1117 const struct ieee80211_ops *ops; 1122 const struct ieee80211_ops *ops;
1118 1123
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b123a9e325b3..b0abddc714ef 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -43,6 +43,8 @@
43 * by either the RTNL, the iflist_mtx or RCU. 43 * by either the RTNL, the iflist_mtx or RCU.
44 */ 44 */
45 45
46static void ieee80211_iface_work(struct work_struct *work);
47
46bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) 48bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
47{ 49{
48 struct ieee80211_chanctx_conf *chanctx_conf; 50 struct ieee80211_chanctx_conf *chanctx_conf;
@@ -188,7 +190,7 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
188 continue; 190 continue;
189 191
190 if (iter->vif.type == NL80211_IFTYPE_MONITOR && 192 if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
191 !(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE)) 193 !(iter->u.mntr.flags & MONITOR_FLAG_ACTIVE))
192 continue; 194 continue;
193 195
194 m = iter->vif.addr; 196 m = iter->vif.addr;
@@ -217,7 +219,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
217 return -EBUSY; 219 return -EBUSY;
218 220
219 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && 221 if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
220 !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) 222 !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
221 check_dup = false; 223 check_dup = false;
222 224
223 ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup); 225 ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
@@ -357,7 +359,7 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
357 const int offset) 359 const int offset)
358{ 360{
359 struct ieee80211_local *local = sdata->local; 361 struct ieee80211_local *local = sdata->local;
360 u32 flags = sdata->u.mntr_flags; 362 u32 flags = sdata->u.mntr.flags;
361 363
362#define ADJUST(_f, _s) do { \ 364#define ADJUST(_f, _s) do { \
363 if (flags & MONITOR_FLAG_##_f) \ 365 if (flags & MONITOR_FLAG_##_f) \
@@ -448,6 +450,9 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
448 return ret; 450 return ret;
449 } 451 }
450 452
453 skb_queue_head_init(&sdata->skb_queue);
454 INIT_WORK(&sdata->work, ieee80211_iface_work);
455
451 return 0; 456 return 0;
452} 457}
453 458
@@ -589,12 +594,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
589 } 594 }
590 break; 595 break;
591 case NL80211_IFTYPE_MONITOR: 596 case NL80211_IFTYPE_MONITOR:
592 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { 597 if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
593 local->cooked_mntrs++; 598 local->cooked_mntrs++;
594 break; 599 break;
595 } 600 }
596 601
597 if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) { 602 if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
598 res = drv_add_interface(local, sdata); 603 res = drv_add_interface(local, sdata);
599 if (res) 604 if (res)
600 goto err_stop; 605 goto err_stop;
@@ -926,7 +931,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
926 /* no need to tell driver */ 931 /* no need to tell driver */
927 break; 932 break;
928 case NL80211_IFTYPE_MONITOR: 933 case NL80211_IFTYPE_MONITOR:
929 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { 934 if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
930 local->cooked_mntrs--; 935 local->cooked_mntrs--;
931 break; 936 break;
932 } 937 }
@@ -1012,7 +1017,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
1012 ieee80211_recalc_idle(local); 1017 ieee80211_recalc_idle(local);
1013 mutex_unlock(&local->mtx); 1018 mutex_unlock(&local->mtx);
1014 1019
1015 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) 1020 if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
1016 break; 1021 break;
1017 1022
1018 /* fall through */ 1023 /* fall through */
@@ -1444,7 +1449,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1444 case NL80211_IFTYPE_MONITOR: 1449 case NL80211_IFTYPE_MONITOR:
1445 sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP; 1450 sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
1446 sdata->dev->netdev_ops = &ieee80211_monitorif_ops; 1451 sdata->dev->netdev_ops = &ieee80211_monitorif_ops;
1447 sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | 1452 sdata->u.mntr.flags = MONITOR_FLAG_CONTROL |
1448 MONITOR_FLAG_OTHER_BSS; 1453 MONITOR_FLAG_OTHER_BSS;
1449 break; 1454 break;
1450 case NL80211_IFTYPE_WDS: 1455 case NL80211_IFTYPE_WDS:
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d00ea9b13f49..ac053a9df36d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -660,6 +660,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
660 660
661 ieee80211_roc_setup(local); 661 ieee80211_roc_setup(local);
662 662
663 local->hw.radiotap_timestamp.units_pos = -1;
664 local->hw.radiotap_timestamp.accuracy = -1;
665
663 return &local->hw; 666 return &local->hw;
664 err_free: 667 err_free:
665 wiphy_free(wiphy); 668 wiphy_free(wiphy);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8d426f637f58..7486f2dab4ba 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1672,11 +1672,15 @@ __ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
1672 non_acm_ac++) 1672 non_acm_ac++)
1673 if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac))) 1673 if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac)))
1674 break; 1674 break;
1675 /* The loop will result in using BK even if it requires 1675 /* Usually the loop will result in using BK even if it
1676 * admission control, such configuration makes no sense 1676 * requires admission control, but such a configuration
1677 * and we have to transmit somehow - the AC selection 1677 * makes no sense and we have to transmit somehow - the
1678 * does the same thing. 1678 * AC selection does the same thing.
1679 * If we started out trying to downgrade from BK, then
1680 * the extra condition here might be needed.
1679 */ 1681 */
1682 if (non_acm_ac >= IEEE80211_NUM_ACS)
1683 non_acm_ac = IEEE80211_AC_BK;
1680 if (drv_conf_tx(local, sdata, ac, 1684 if (drv_conf_tx(local, sdata, ac,
1681 &sdata->tx_conf[non_acm_ac])) 1685 &sdata->tx_conf[non_acm_ac]))
1682 sdata_err(sdata, 1686 sdata_err(sdata,
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 00a43a70e1fc..28a3a0957c9e 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -178,8 +178,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
178 WARN_ON(!list_empty(&local->chanctx_list)); 178 WARN_ON(!list_empty(&local->chanctx_list));
179 179
180 /* stop hardware - this must stop RX */ 180 /* stop hardware - this must stop RX */
181 if (local->open_count) 181 ieee80211_stop_device(local);
182 ieee80211_stop_device(local);
183 182
184 suspend: 183 suspend:
185 local->suspended = true; 184 local->suspended = true;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9dce3b157908..e796060b7c5e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -180,6 +180,11 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
180 len += 12; 180 len += 12;
181 } 181 }
182 182
183 if (local->hw.radiotap_timestamp.units_pos >= 0) {
184 len = ALIGN(len, 8);
185 len += 12;
186 }
187
183 if (status->chains) { 188 if (status->chains) {
184 /* antenna and antenna signal fields */ 189 /* antenna and antenna signal fields */
185 len += 2 * hweight8(status->chains); 190 len += 2 * hweight8(status->chains);
@@ -447,6 +452,31 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
447 pos += 2; 452 pos += 2;
448 } 453 }
449 454
455 if (local->hw.radiotap_timestamp.units_pos >= 0) {
456 u16 accuracy = 0;
457 u8 flags = IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT;
458
459 rthdr->it_present |=
460 cpu_to_le32(1 << IEEE80211_RADIOTAP_TIMESTAMP);
461
462 /* ensure 8 byte alignment */
463 while ((pos - (u8 *)rthdr) & 7)
464 pos++;
465
466 put_unaligned_le64(status->device_timestamp, pos);
467 pos += sizeof(u64);
468
469 if (local->hw.radiotap_timestamp.accuracy >= 0) {
470 accuracy = local->hw.radiotap_timestamp.accuracy;
471 flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY;
472 }
473 put_unaligned_le16(accuracy, pos);
474 pos += sizeof(u16);
475
476 *pos++ = local->hw.radiotap_timestamp.units_pos;
477 *pos++ = flags;
478 }
479
450 for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) { 480 for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
451 *pos++ = status->chain_signal[chain]; 481 *pos++ = status->chain_signal[chain];
452 *pos++ = chain; 482 *pos++ = chain;
@@ -485,6 +515,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
485 struct net_device *prev_dev = NULL; 515 struct net_device *prev_dev = NULL;
486 int present_fcs_len = 0; 516 int present_fcs_len = 0;
487 unsigned int rtap_vendor_space = 0; 517 unsigned int rtap_vendor_space = 0;
518 struct ieee80211_mgmt *mgmt;
519 struct ieee80211_sub_if_data *monitor_sdata =
520 rcu_dereference(local->monitor_sdata);
488 521
489 if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) { 522 if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) {
490 struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data; 523 struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data;
@@ -567,7 +600,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
567 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) 600 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
568 continue; 601 continue;
569 602
570 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) 603 if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
571 continue; 604 continue;
572 605
573 if (!ieee80211_sdata_running(sdata)) 606 if (!ieee80211_sdata_running(sdata))
@@ -585,6 +618,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
585 ieee80211_rx_stats(sdata->dev, skb->len); 618 ieee80211_rx_stats(sdata->dev, skb->len);
586 } 619 }
587 620
621 mgmt = (void *)skb->data;
622 if (monitor_sdata &&
623 skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + VHT_MUMIMO_GROUPS_DATA_LEN &&
624 ieee80211_is_action(mgmt->frame_control) &&
625 mgmt->u.action.category == WLAN_CATEGORY_VHT &&
626 mgmt->u.action.u.vht_group_notif.action_code == WLAN_VHT_ACTION_GROUPID_MGMT &&
627 is_valid_ether_addr(monitor_sdata->u.mntr.mu_follow_addr) &&
628 ether_addr_equal(mgmt->da, monitor_sdata->u.mntr.mu_follow_addr)) {
629 struct sk_buff *mu_skb = skb_copy(skb, GFP_ATOMIC);
630
631 if (mu_skb) {
632 mu_skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
633 skb_queue_tail(&monitor_sdata->skb_queue, mu_skb);
634 ieee80211_queue_work(&local->hw, &monitor_sdata->work);
635 }
636 }
637
588 if (prev_dev) { 638 if (prev_dev) {
589 skb->dev = prev_dev; 639 skb->dev = prev_dev;
590 netif_receive_skb(skb); 640 netif_receive_skb(skb);
@@ -1072,8 +1122,15 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
1072 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 1122 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
1073 1123
1074 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); 1124 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
1075 if (!tid_agg_rx) 1125 if (!tid_agg_rx) {
1126 if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
1127 !test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
1128 !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
1129 ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
1130 WLAN_BACK_RECIPIENT,
1131 WLAN_REASON_QSTA_REQUIRE_SETUP);
1076 goto dont_reorder; 1132 goto dont_reorder;
1133 }
1077 1134
1078 /* qos null data frames are excluded */ 1135 /* qos null data frames are excluded */
1079 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 1136 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
@@ -2535,6 +2592,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
2535 2592
2536 tid = le16_to_cpu(bar_data.control) >> 12; 2593 tid = le16_to_cpu(bar_data.control) >> 12;
2537 2594
2595 if (!test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
2596 !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
2597 ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
2598 WLAN_BACK_RECIPIENT,
2599 WLAN_REASON_QSTA_REQUIRE_SETUP);
2600
2538 tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]); 2601 tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]);
2539 if (!tid_agg_rx) 2602 if (!tid_agg_rx)
2540 return RX_DROP_MONITOR; 2603 return RX_DROP_MONITOR;
@@ -3147,7 +3210,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
3147 continue; 3210 continue;
3148 3211
3149 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || 3212 if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
3150 !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) 3213 !(sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES))
3151 continue; 3214 continue;
3152 3215
3153 if (prev_dev) { 3216 if (prev_dev) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 070b40f15850..23d8ac829279 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -420,7 +420,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw,
420{ 420{
421 struct ieee80211_local *local = hw_to_local(hw); 421 struct ieee80211_local *local = hw_to_local(hw);
422 422
423 trace_api_scan_completed(local, info); 423 trace_api_scan_completed(local, info->aborted);
424 424
425 set_bit(SCAN_COMPLETED, &local->scanning); 425 set_bit(SCAN_COMPLETED, &local->scanning);
426 if (info->aborted) 426 if (info->aborted)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 19f14c907d74..1b1b28ff4fdb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -340,6 +340,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
340 340
341 memcpy(sta->addr, addr, ETH_ALEN); 341 memcpy(sta->addr, addr, ETH_ALEN);
342 memcpy(sta->sta.addr, addr, ETH_ALEN); 342 memcpy(sta->sta.addr, addr, ETH_ALEN);
343 sta->sta.max_rx_aggregation_subframes =
344 local->hw.max_rx_aggregation_subframes;
345
343 sta->local = local; 346 sta->local = local;
344 sta->sdata = sdata; 347 sta->sdata = sdata;
345 sta->rx_stats.last_rx = jiffies; 348 sta->rx_stats.last_rx = jiffies;
@@ -687,7 +690,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
687 } 690 }
688 691
689 /* No need to do anything if the driver does all */ 692 /* No need to do anything if the driver does all */
690 if (ieee80211_hw_check(&local->hw, AP_LINK_PS)) 693 if (!local->ops->set_tim)
691 return; 694 return;
692 695
693 if (sta->dead) 696 if (sta->dead)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 0556be3e3628..530231b73278 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -230,6 +230,8 @@ struct tid_ampdu_rx {
230 * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the 230 * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the
231 * driver requested to close until the work for it runs 231 * driver requested to close until the work for it runs
232 * @agg_session_valid: bitmap indicating which TID has a rx BA session open on 232 * @agg_session_valid: bitmap indicating which TID has a rx BA session open on
233 * @unexpected_agg: bitmap indicating which TID already sent a delBA due to
234 * unexpected aggregation related frames outside a session
233 * @work: work struct for starting/stopping aggregation 235 * @work: work struct for starting/stopping aggregation
234 * @tid_tx: aggregation info for Tx per TID 236 * @tid_tx: aggregation info for Tx per TID
235 * @tid_start_tx: sessions where start was requested 237 * @tid_start_tx: sessions where start was requested
@@ -244,6 +246,7 @@ struct sta_ampdu_mlme {
244 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; 246 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
245 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; 247 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
246 unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; 248 unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
249 unsigned long unexpected_agg[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
247 /* tx */ 250 /* tx */
248 struct work_struct work; 251 struct work_struct work;
249 struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS]; 252 struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index a2a68269675d..ea39f8a7baf3 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -557,6 +557,12 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
557static void ieee80211_lost_packet(struct sta_info *sta, 557static void ieee80211_lost_packet(struct sta_info *sta,
558 struct ieee80211_tx_info *info) 558 struct ieee80211_tx_info *info)
559{ 559{
560 /* If driver relies on its own algorithm for station kickout, skip
561 * mac80211 packet loss mechanism.
562 */
563 if (ieee80211_hw_check(&sta->local->hw, REPORTS_LOW_ACK))
564 return;
565
560 /* This packet was aggregated but doesn't carry status info */ 566 /* This packet was aggregated but doesn't carry status info */
561 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 567 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
562 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 568 !(info->flags & IEEE80211_TX_STAT_AMPDU))
@@ -709,7 +715,7 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
709 if (!ieee80211_sdata_running(sdata)) 715 if (!ieee80211_sdata_running(sdata))
710 continue; 716 continue;
711 717
712 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 718 if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
713 !send_to_cooked) 719 !send_to_cooked)
714 continue; 720 continue;
715 721
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1d0746dfea57..61d302d97145 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1343,7 +1343,7 @@ static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
1343 local = container_of(fq, struct ieee80211_local, fq); 1343 local = container_of(fq, struct ieee80211_local, fq);
1344 txqi = container_of(tin, struct txq_info, tin); 1344 txqi = container_of(tin, struct txq_info, tin);
1345 cparams = &local->cparams; 1345 cparams = &local->cparams;
1346 cstats = &local->cstats; 1346 cstats = &txqi->cstats;
1347 1347
1348 if (flow == &txqi->def_flow) 1348 if (flow == &txqi->def_flow)
1349 cvars = &txqi->def_cvars; 1349 cvars = &txqi->def_cvars;
@@ -1403,6 +1403,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
1403 fq_tin_init(&txqi->tin); 1403 fq_tin_init(&txqi->tin);
1404 fq_flow_init(&txqi->def_flow); 1404 fq_flow_init(&txqi->def_flow);
1405 codel_vars_init(&txqi->def_cvars); 1405 codel_vars_init(&txqi->def_cvars);
1406 codel_stats_init(&txqi->cstats);
1406 1407
1407 txqi->txq.vif = &sdata->vif; 1408 txqi->txq.vif = &sdata->vif;
1408 1409
@@ -1441,7 +1442,6 @@ int ieee80211_txq_setup_flows(struct ieee80211_local *local)
1441 return ret; 1442 return ret;
1442 1443
1443 codel_params_init(&local->cparams); 1444 codel_params_init(&local->cparams);
1444 codel_stats_init(&local->cstats);
1445 local->cparams.interval = MS2TIME(100); 1445 local->cparams.interval = MS2TIME(100);
1446 local->cparams.target = MS2TIME(20); 1446 local->cparams.target = MS2TIME(20);
1447 local->cparams.ecn = true; 1447 local->cparams.ecn = true;
@@ -1643,7 +1643,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
1643 1643
1644 switch (sdata->vif.type) { 1644 switch (sdata->vif.type) {
1645 case NL80211_IFTYPE_MONITOR: 1645 case NL80211_IFTYPE_MONITOR:
1646 if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) { 1646 if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
1647 vif = &sdata->vif; 1647 vif = &sdata->vif;
1648 break; 1648 break;
1649 } 1649 }
@@ -2263,15 +2263,9 @@ static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
2263 case NL80211_IFTYPE_STATION: 2263 case NL80211_IFTYPE_STATION:
2264 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { 2264 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
2265 sta = sta_info_get(sdata, skb->data); 2265 sta = sta_info_get(sdata, skb->data);
2266 if (sta) { 2266 if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
2267 bool tdls_peer, tdls_auth; 2267 if (test_sta_flag(sta,
2268 2268 WLAN_STA_TDLS_PEER_AUTH)) {
2269 tdls_peer = test_sta_flag(sta,
2270 WLAN_STA_TDLS_PEER);
2271 tdls_auth = test_sta_flag(sta,
2272 WLAN_STA_TDLS_PEER_AUTH);
2273
2274 if (tdls_peer && tdls_auth) {
2275 *sta_out = sta; 2269 *sta_out = sta;
2276 return 0; 2270 return 0;
2277 } 2271 }
@@ -2283,8 +2277,7 @@ static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
2283 * after a TDLS sta is removed due to being 2277 * after a TDLS sta is removed due to being
2284 * unreachable. 2278 * unreachable.
2285 */ 2279 */
2286 if (tdls_peer && !tdls_auth && 2280 if (!ieee80211_is_tdls_setup(skb))
2287 !ieee80211_is_tdls_setup(skb))
2288 return -EINVAL; 2281 return -EINVAL;
2289 } 2282 }
2290 2283
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 42bf0b6685e8..b6865d884487 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -598,7 +598,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
598 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 598 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
599 switch (sdata->vif.type) { 599 switch (sdata->vif.type) {
600 case NL80211_IFTYPE_MONITOR: 600 case NL80211_IFTYPE_MONITOR:
601 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) 601 if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
602 continue; 602 continue;
603 break; 603 break;
604 case NL80211_IFTYPE_AP_VLAN: 604 case NL80211_IFTYPE_AP_VLAN:
@@ -2555,7 +2555,6 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2555 2555
2556 if (need_basic && basic_rates & BIT(i)) 2556 if (need_basic && basic_rates & BIT(i))
2557 basic = 0x80; 2557 basic = 0x80;
2558 rate = sband->bitrates[i].bitrate;
2559 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, 2558 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2560 5 * (1 << shift)); 2559 5 * (1 << shift));
2561 *pos++ = basic | (u8) rate; 2560 *pos++ = basic | (u8) rate;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 2029b49a1df3..4911cd997b9a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1252,7 +1252,7 @@ static int __init cfg80211_init(void)
1252 if (err) 1252 if (err)
1253 goto out_fail_reg; 1253 goto out_fail_reg;
1254 1254
1255 cfg80211_wq = create_singlethread_workqueue("cfg80211"); 1255 cfg80211_wq = alloc_ordered_workqueue("cfg80211", WQ_MEM_RECLAIM);
1256 if (!cfg80211_wq) { 1256 if (!cfg80211_wq) {
1257 err = -ENOMEM; 1257 err = -ENOMEM;
1258 goto out_fail_wq; 1258 goto out_fail_wq;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index eee91443924d..5555e3c13ae9 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -249,9 +249,9 @@ struct cfg80211_event {
249}; 249};
250 250
251struct cfg80211_cached_keys { 251struct cfg80211_cached_keys {
252 struct key_params params[6]; 252 struct key_params params[4];
253 u8 data[6][WLAN_MAX_KEY_LEN]; 253 u8 data[4][WLAN_KEY_LEN_WEP104];
254 int def, defmgmt; 254 int def;
255}; 255};
256 256
257enum cfg80211_chan_mode { 257enum cfg80211_chan_mode {
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 4a4dda53bdf1..eafdfa5798ae 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -114,6 +114,9 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
114 } 114 }
115 } 115 }
116 116
117 if (WARN_ON(connkeys && connkeys->def < 0))
118 return -EINVAL;
119
117 if (WARN_ON(wdev->connect_keys)) 120 if (WARN_ON(wdev->connect_keys))
118 kzfree(wdev->connect_keys); 121 kzfree(wdev->connect_keys);
119 wdev->connect_keys = connkeys; 122 wdev->connect_keys = connkeys;
@@ -284,18 +287,16 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
284 if (!netif_running(wdev->netdev)) 287 if (!netif_running(wdev->netdev))
285 return 0; 288 return 0;
286 289
287 if (wdev->wext.keys) { 290 if (wdev->wext.keys)
288 wdev->wext.keys->def = wdev->wext.default_key; 291 wdev->wext.keys->def = wdev->wext.default_key;
289 wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;
290 }
291 292
292 wdev->wext.ibss.privacy = wdev->wext.default_key != -1; 293 wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
293 294
294 if (wdev->wext.keys) { 295 if (wdev->wext.keys && wdev->wext.keys->def != -1) {
295 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); 296 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
296 if (!ck) 297 if (!ck)
297 return -ENOMEM; 298 return -ENOMEM;
298 for (i = 0; i < 6; i++) 299 for (i = 0; i < 4; i++)
299 ck->params[i].key = ck->data[i]; 300 ck->params[i].key = ck->data[i];
300 } 301 }
301 err = __cfg80211_join_ibss(rdev, wdev->netdev, 302 err = __cfg80211_join_ibss(rdev, wdev->netdev,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index c284d883c349..d6abb0704db5 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -222,7 +222,7 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
222 ASSERT_WDEV_LOCK(wdev); 222 ASSERT_WDEV_LOCK(wdev);
223 223
224 if (auth_type == NL80211_AUTHTYPE_SHARED_KEY) 224 if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
225 if (!key || !key_len || key_idx < 0 || key_idx > 4) 225 if (!key || !key_len || key_idx < 0 || key_idx > 3)
226 return -EINVAL; 226 return -EINVAL;
227 227
228 if (wdev->current_bss && 228 if (wdev->current_bss &&
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 499785778983..887c4c114206 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -848,13 +848,21 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
848 struct nlattr *key; 848 struct nlattr *key;
849 struct cfg80211_cached_keys *result; 849 struct cfg80211_cached_keys *result;
850 int rem, err, def = 0; 850 int rem, err, def = 0;
851 bool have_key = false;
852
853 nla_for_each_nested(key, keys, rem) {
854 have_key = true;
855 break;
856 }
857
858 if (!have_key)
859 return NULL;
851 860
852 result = kzalloc(sizeof(*result), GFP_KERNEL); 861 result = kzalloc(sizeof(*result), GFP_KERNEL);
853 if (!result) 862 if (!result)
854 return ERR_PTR(-ENOMEM); 863 return ERR_PTR(-ENOMEM);
855 864
856 result->def = -1; 865 result->def = -1;
857 result->defmgmt = -1;
858 866
859 nla_for_each_nested(key, keys, rem) { 867 nla_for_each_nested(key, keys, rem) {
860 memset(&parse, 0, sizeof(parse)); 868 memset(&parse, 0, sizeof(parse));
@@ -866,7 +874,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
866 err = -EINVAL; 874 err = -EINVAL;
867 if (!parse.p.key) 875 if (!parse.p.key)
868 goto error; 876 goto error;
869 if (parse.idx < 0 || parse.idx > 4) 877 if (parse.idx < 0 || parse.idx > 3)
870 goto error; 878 goto error;
871 if (parse.def) { 879 if (parse.def) {
872 if (def) 880 if (def)
@@ -881,16 +889,24 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
881 parse.idx, false, NULL); 889 parse.idx, false, NULL);
882 if (err) 890 if (err)
883 goto error; 891 goto error;
892 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
893 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
894 err = -EINVAL;
895 goto error;
896 }
884 result->params[parse.idx].cipher = parse.p.cipher; 897 result->params[parse.idx].cipher = parse.p.cipher;
885 result->params[parse.idx].key_len = parse.p.key_len; 898 result->params[parse.idx].key_len = parse.p.key_len;
886 result->params[parse.idx].key = result->data[parse.idx]; 899 result->params[parse.idx].key = result->data[parse.idx];
887 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len); 900 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
888 901
889 if (parse.p.cipher == WLAN_CIPHER_SUITE_WEP40 || 902 /* must be WEP key if we got here */
890 parse.p.cipher == WLAN_CIPHER_SUITE_WEP104) { 903 if (no_ht)
891 if (no_ht) 904 *no_ht = true;
892 *no_ht = true; 905 }
893 } 906
907 if (result->def < 0) {
908 err = -EINVAL;
909 goto error;
894 } 910 }
895 911
896 return result; 912 return result;
@@ -2525,10 +2541,35 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2525 int if_idx = 0; 2541 int if_idx = 0;
2526 int wp_start = cb->args[0]; 2542 int wp_start = cb->args[0];
2527 int if_start = cb->args[1]; 2543 int if_start = cb->args[1];
2544 int filter_wiphy = -1;
2528 struct cfg80211_registered_device *rdev; 2545 struct cfg80211_registered_device *rdev;
2529 struct wireless_dev *wdev; 2546 struct wireless_dev *wdev;
2530 2547
2531 rtnl_lock(); 2548 rtnl_lock();
2549 if (!cb->args[2]) {
2550 struct nl80211_dump_wiphy_state state = {
2551 .filter_wiphy = -1,
2552 };
2553 int ret;
2554
2555 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
2556 if (ret)
2557 return ret;
2558
2559 filter_wiphy = state.filter_wiphy;
2560
2561 /*
2562 * if filtering, set cb->args[2] to +1 since 0 is the default
2563 * value needed to determine that parsing is necessary.
2564 */
2565 if (filter_wiphy >= 0)
2566 cb->args[2] = filter_wiphy + 1;
2567 else
2568 cb->args[2] = -1;
2569 } else if (cb->args[2] > 0) {
2570 filter_wiphy = cb->args[2] - 1;
2571 }
2572
2532 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2573 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2533 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) 2574 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
2534 continue; 2575 continue;
@@ -2536,6 +2577,10 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2536 wp_idx++; 2577 wp_idx++;
2537 continue; 2578 continue;
2538 } 2579 }
2580
2581 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
2582 continue;
2583
2539 if_idx = 0; 2584 if_idx = 0;
2540 2585
2541 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 2586 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
@@ -7359,7 +7404,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
7359 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 || 7404 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
7360 key.p.key_len != WLAN_KEY_LEN_WEP104)) 7405 key.p.key_len != WLAN_KEY_LEN_WEP104))
7361 return -EINVAL; 7406 return -EINVAL;
7362 if (key.idx > 4) 7407 if (key.idx > 3)
7363 return -EINVAL; 7408 return -EINVAL;
7364 } else { 7409 } else {
7365 key.p.key_len = 0; 7410 key.p.key_len = 0;
@@ -7977,6 +8022,8 @@ __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
7977 } 8022 }
7978 8023
7979 data = nla_nest_start(skb, attr); 8024 data = nla_nest_start(skb, attr);
8025 if (!data)
8026 goto nla_put_failure;
7980 8027
7981 ((void **)skb->cb)[0] = rdev; 8028 ((void **)skb->cb)[0] = rdev;
7982 ((void **)skb->cb)[1] = hdr; 8029 ((void **)skb->cb)[1] = hdr;
@@ -9406,18 +9453,27 @@ static int nl80211_send_wowlan_nd(struct sk_buff *msg,
9406 if (!freqs) 9453 if (!freqs)
9407 return -ENOBUFS; 9454 return -ENOBUFS;
9408 9455
9409 for (i = 0; i < req->n_channels; i++) 9456 for (i = 0; i < req->n_channels; i++) {
9410 nla_put_u32(msg, i, req->channels[i]->center_freq); 9457 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
9458 return -ENOBUFS;
9459 }
9411 9460
9412 nla_nest_end(msg, freqs); 9461 nla_nest_end(msg, freqs);
9413 9462
9414 if (req->n_match_sets) { 9463 if (req->n_match_sets) {
9415 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH); 9464 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
9465 if (!matches)
9466 return -ENOBUFS;
9467
9416 for (i = 0; i < req->n_match_sets; i++) { 9468 for (i = 0; i < req->n_match_sets; i++) {
9417 match = nla_nest_start(msg, i); 9469 match = nla_nest_start(msg, i);
9418 nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID, 9470 if (!match)
9419 req->match_sets[i].ssid.ssid_len, 9471 return -ENOBUFS;
9420 req->match_sets[i].ssid.ssid); 9472
9473 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
9474 req->match_sets[i].ssid.ssid_len,
9475 req->match_sets[i].ssid.ssid))
9476 return -ENOBUFS;
9421 nla_nest_end(msg, match); 9477 nla_nest_end(msg, match);
9422 } 9478 }
9423 nla_nest_end(msg, matches); 9479 nla_nest_end(msg, matches);
@@ -9429,6 +9485,9 @@ static int nl80211_send_wowlan_nd(struct sk_buff *msg,
9429 9485
9430 for (i = 0; i < req->n_scan_plans; i++) { 9486 for (i = 0; i < req->n_scan_plans; i++) {
9431 scan_plan = nla_nest_start(msg, i + 1); 9487 scan_plan = nla_nest_start(msg, i + 1);
9488 if (!scan_plan)
9489 return -ENOBUFS;
9490
9432 if (!scan_plan || 9491 if (!scan_plan ||
9433 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, 9492 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
9434 req->scan_plans[i].interval) || 9493 req->scan_plans[i].interval) ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0358e12be54b..b5bd58d0f731 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -352,52 +352,48 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
352 __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); 352 __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
353} 353}
354 354
355const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) 355const u8 *cfg80211_find_ie_match(u8 eid, const u8 *ies, int len,
356 const u8 *match, int match_len,
357 int match_offset)
356{ 358{
357 while (len > 2 && ies[0] != eid) { 359 /* match_offset can't be smaller than 2, unless match_len is
360 * zero, in which case match_offset must be zero as well.
361 */
362 if (WARN_ON((match_len && match_offset < 2) ||
363 (!match_len && match_offset)))
364 return NULL;
365
366 while (len >= 2 && len >= ies[1] + 2) {
367 if ((ies[0] == eid) &&
368 (ies[1] + 2 >= match_offset + match_len) &&
369 !memcmp(ies + match_offset, match, match_len))
370 return ies;
371
358 len -= ies[1] + 2; 372 len -= ies[1] + 2;
359 ies += ies[1] + 2; 373 ies += ies[1] + 2;
360 } 374 }
361 if (len < 2) 375
362 return NULL; 376 return NULL;
363 if (len < 2 + ies[1])
364 return NULL;
365 return ies;
366} 377}
367EXPORT_SYMBOL(cfg80211_find_ie); 378EXPORT_SYMBOL(cfg80211_find_ie_match);
368 379
369const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type, 380const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
370 const u8 *ies, int len) 381 const u8 *ies, int len)
371{ 382{
372 struct ieee80211_vendor_ie *ie; 383 const u8 *ie;
373 const u8 *pos = ies, *end = ies + len; 384 u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
374 int ie_oui; 385 int match_len = (oui_type < 0) ? 3 : sizeof(match);
375 386
376 if (WARN_ON(oui_type > 0xff)) 387 if (WARN_ON(oui_type > 0xff))
377 return NULL; 388 return NULL;
378 389
379 while (pos < end) { 390 ie = cfg80211_find_ie_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
380 pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, 391 match, match_len, 2);
381 end - pos);
382 if (!pos)
383 return NULL;
384
385 ie = (struct ieee80211_vendor_ie *)pos;
386
387 /* make sure we can access ie->len */
388 BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1);
389 392
390 if (ie->len < sizeof(*ie)) 393 if (ie && (ie[1] < 4))
391 goto cont; 394 return NULL;
392 395
393 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; 396 return ie;
394 if (ie_oui == oui &&
395 (oui_type < 0 || ie->oui_type == oui_type))
396 return pos;
397cont:
398 pos += 2 + ie->len;
399 }
400 return NULL;
401} 397}
402EXPORT_SYMBOL(cfg80211_find_vendor_ie); 398EXPORT_SYMBOL(cfg80211_find_vendor_ie);
403 399
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index add6824c44fd..c08a3b57dca1 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1043,6 +1043,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
1043 connect->crypto.ciphers_pairwise[0] = cipher; 1043 connect->crypto.ciphers_pairwise[0] = cipher;
1044 } 1044 }
1045 } 1045 }
1046 } else {
1047 if (WARN_ON(connkeys))
1048 return -EINVAL;
1046 } 1049 }
1047 1050
1048 wdev->connect_keys = connkeys; 1051 wdev->connect_keys = connkeys;
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index e46469bc130f..0082f4b01795 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -57,7 +57,7 @@ static ssize_t addresses_show(struct device *dev,
57 return sprintf(buf, "%pM\n", wiphy->perm_addr); 57 return sprintf(buf, "%pM\n", wiphy->perm_addr);
58 58
59 for (i = 0; i < wiphy->n_addresses; i++) 59 for (i = 0; i < wiphy->n_addresses; i++)
60 buf += sprintf(buf, "%pM\n", &wiphy->addresses[i].addr); 60 buf += sprintf(buf, "%pM\n", wiphy->addresses[i].addr);
61 61
62 return buf - start; 62 return buf - start;
63} 63}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0675f513e7b9..9e6e2aaa7766 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -218,7 +218,7 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
218 struct key_params *params, int key_idx, 218 struct key_params *params, int key_idx,
219 bool pairwise, const u8 *mac_addr) 219 bool pairwise, const u8 *mac_addr)
220{ 220{
221 if (key_idx > 5) 221 if (key_idx < 0 || key_idx > 5)
222 return -EINVAL; 222 return -EINVAL;
223 223
224 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) 224 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
@@ -249,7 +249,13 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
249 /* Disallow BIP (group-only) cipher as pairwise cipher */ 249 /* Disallow BIP (group-only) cipher as pairwise cipher */
250 if (pairwise) 250 if (pairwise)
251 return -EINVAL; 251 return -EINVAL;
252 if (key_idx < 4)
253 return -EINVAL;
252 break; 254 break;
255 case WLAN_CIPHER_SUITE_WEP40:
256 case WLAN_CIPHER_SUITE_WEP104:
257 if (key_idx > 3)
258 return -EINVAL;
253 default: 259 default:
254 break; 260 break;
255 } 261 }
@@ -906,7 +912,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
906 if (!wdev->connect_keys) 912 if (!wdev->connect_keys)
907 return; 913 return;
908 914
909 for (i = 0; i < 6; i++) { 915 for (i = 0; i < 4; i++) {
910 if (!wdev->connect_keys->params[i].cipher) 916 if (!wdev->connect_keys->params[i].cipher)
911 continue; 917 continue;
912 if (rdev_add_key(rdev, dev, i, false, NULL, 918 if (rdev_add_key(rdev, dev, i, false, NULL,
@@ -919,9 +925,6 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
919 netdev_err(dev, "failed to set defkey %d\n", i); 925 netdev_err(dev, "failed to set defkey %d\n", i);
920 continue; 926 continue;
921 } 927 }
922 if (wdev->connect_keys->defmgmt == i)
923 if (rdev_set_default_mgmt_key(rdev, dev, i))
924 netdev_err(dev, "failed to set mgtdef %d\n", i);
925 } 928 }
926 929
927 kzfree(wdev->connect_keys); 930 kzfree(wdev->connect_keys);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9f27221c8913..7b97d43b27e1 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -408,10 +408,10 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
408 408
409 if (!wdev->wext.keys) { 409 if (!wdev->wext.keys) {
410 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), 410 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
411 GFP_KERNEL); 411 GFP_KERNEL);
412 if (!wdev->wext.keys) 412 if (!wdev->wext.keys)
413 return -ENOMEM; 413 return -ENOMEM;
414 for (i = 0; i < 6; i++) 414 for (i = 0; i < 4; i++)
415 wdev->wext.keys->params[i].key = 415 wdev->wext.keys->params[i].key =
416 wdev->wext.keys->data[i]; 416 wdev->wext.keys->data[i];
417 } 417 }
@@ -460,7 +460,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
460 if (err == -ENOENT) 460 if (err == -ENOENT)
461 err = 0; 461 err = 0;
462 if (!err) { 462 if (!err) {
463 if (!addr) { 463 if (!addr && idx < 4) {
464 memset(wdev->wext.keys->data[idx], 0, 464 memset(wdev->wext.keys->data[idx], 0,
465 sizeof(wdev->wext.keys->data[idx])); 465 sizeof(wdev->wext.keys->data[idx]));
466 wdev->wext.keys->params[idx].key_len = 0; 466 wdev->wext.keys->params[idx].key_len = 0;
@@ -487,6 +487,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
487 err = 0; 487 err = 0;
488 if (wdev->current_bss) 488 if (wdev->current_bss)
489 err = rdev_add_key(rdev, dev, idx, pairwise, addr, params); 489 err = rdev_add_key(rdev, dev, idx, pairwise, addr, params);
490 else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
491 params->cipher != WLAN_CIPHER_SUITE_WEP104)
492 return -EINVAL;
490 if (err) 493 if (err)
491 return err; 494 return err;
492 495
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index a4e8af3321d2..88f1f6931ab8 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -35,7 +35,6 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
35 35
36 if (wdev->wext.keys) { 36 if (wdev->wext.keys) {
37 wdev->wext.keys->def = wdev->wext.default_key; 37 wdev->wext.keys->def = wdev->wext.default_key;
38 wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;
39 if (wdev->wext.default_key != -1) 38 if (wdev->wext.default_key != -1)
40 wdev->wext.connect.privacy = true; 39 wdev->wext.connect.privacy = true;
41 } 40 }
@@ -43,11 +42,11 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
43 if (!wdev->wext.connect.ssid_len) 42 if (!wdev->wext.connect.ssid_len)
44 return 0; 43 return 0;
45 44
46 if (wdev->wext.keys) { 45 if (wdev->wext.keys && wdev->wext.keys->def != -1) {
47 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); 46 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
48 if (!ck) 47 if (!ck)
49 return -ENOMEM; 48 return -ENOMEM;
50 for (i = 0; i < 6; i++) 49 for (i = 0; i < 4; i++)
51 ck->params[i].key = ck->data[i]; 50 ck->params[i].key = ck->data[i];
52 } 51 }
53 52