aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c589
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c371
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c257
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h319
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h53
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c168
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c75
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c129
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c145
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c117
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c39
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c105
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c4
33 files changed, 2202 insertions, 653 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 807b250ec396..2acc44b40986 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o 5iwlmvm-y += power.o bt-coex.o
6iwlmvm-y += led.o 6iwlmvm-y += led.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
index 73d24aacb90a..93fd1457954b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/binding.c
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
new file mode 100644
index 000000000000..810bfa5f6de0
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -0,0 +1,589 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <net/mac80211.h>
65
66#include "fw-api-bt-coex.h"
67#include "iwl-modparams.h"
68#include "mvm.h"
69#include "iwl-debug.h"
70
71#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
72 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
73 ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
74
75static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
76 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
77 BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
78 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
79 BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
80 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
81 BT_COEX_PRIO_TBL_PRIO_LOW, 0),
82 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
83 BT_COEX_PRIO_TBL_PRIO_LOW, 1),
84 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
85 BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
86 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
87 BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
88 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
89 BT_COEX_PRIO_TBL_DISABLED, 0),
90 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
91 BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
92 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
93 BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
94 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
95 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
96 0, 0, 0, 0, 0, 0,
97};
98
99#undef EVENT_PRIO_ANT
100
101/* BT Antenna Coupling Threshold (dB) */
102#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
103#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3)
104
105#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
106#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
107#define BT_REDUCED_TX_POWER_BIT BIT(7)
108
109static inline bool is_loose_coex(void)
110{
111 return iwlwifi_mod_params.ant_coupling >
112 IWL_BT_ANTENNA_COUPLING_THRESHOLD;
113}
114
115int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
116{
117 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
118 sizeof(struct iwl_bt_coex_prio_tbl_cmd),
119 &iwl_bt_prio_tbl);
120}
121
122static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type)
123{
124 struct iwl_bt_coex_prot_env_cmd env_cmd;
125 int ret;
126
127 env_cmd.action = action;
128 env_cmd.type = type;
129 ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC,
130 sizeof(env_cmd), &env_cmd);
131 if (ret)
132 IWL_ERR(mvm, "failed to send BT env command\n");
133 return ret;
134}
135
136enum iwl_bt_kill_msk {
137 BT_KILL_MSK_DEFAULT,
138 BT_KILL_MSK_SCO_HID_A2DP,
139 BT_KILL_MSK_REDUCED_TXPOW,
140 BT_KILL_MSK_MAX,
141};
142
143static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
144 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
145 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
146 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
147};
148
149static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
150 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
151 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
152 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
153};
154
155#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)
156
157/* Tight Coex */
158static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = {
159 cpu_to_le32(0xaaaaaaaa),
160 cpu_to_le32(0xaaaaaaaa),
161 cpu_to_le32(0xaeaaaaaa),
162 cpu_to_le32(0xaaaaaaaa),
163 cpu_to_le32(0xcc00ff28),
164 cpu_to_le32(0x0000aaaa),
165 cpu_to_le32(0xcc00aaaa),
166 cpu_to_le32(0x0000aaaa),
167 cpu_to_le32(0xc0004000),
168 cpu_to_le32(0x00000000),
169 cpu_to_le32(0xf0005000),
170 cpu_to_le32(0xf0005000),
171};
172
173/* Loose Coex */
174static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = {
175 cpu_to_le32(0xaaaaaaaa),
176 cpu_to_le32(0xaaaaaaaa),
177 cpu_to_le32(0xaeaaaaaa),
178 cpu_to_le32(0xaaaaaaaa),
179 cpu_to_le32(0xcc00ff28),
180 cpu_to_le32(0x0000aaaa),
181 cpu_to_le32(0xcc00aaaa),
182 cpu_to_le32(0x0000aaaa),
183 cpu_to_le32(0x00000000),
184 cpu_to_le32(0x00000000),
185 cpu_to_le32(0xf0005000),
186 cpu_to_le32(0xf0005000),
187};
188
189/* Full concurrency */
190static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
191 cpu_to_le32(0xaaaaaaaa),
192 cpu_to_le32(0xaaaaaaaa),
193 cpu_to_le32(0xaaaaaaaa),
194 cpu_to_le32(0xaaaaaaaa),
195 cpu_to_le32(0xaaaaaaaa),
196 cpu_to_le32(0xaaaaaaaa),
197 cpu_to_le32(0xaaaaaaaa),
198 cpu_to_le32(0xaaaaaaaa),
199 cpu_to_le32(0x00000000),
200 cpu_to_le32(0x00000000),
201 cpu_to_le32(0x00000000),
202 cpu_to_le32(0x00000000),
203};
204
205int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
206{
207 struct iwl_bt_coex_cmd cmd = {
208 .max_kill = 5,
209 .bt3_time_t7_value = 1,
210 .bt3_prio_sample_time = 2,
211 .bt3_timer_t2_value = 0xc,
212 };
213 int ret;
214
215 cmd.flags = iwlwifi_mod_params.bt_coex_active ?
216 BT_COEX_NW : BT_COEX_DISABLE;
217 cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE;
218
219 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
220 BT_VALID_BT_PRIO_BOOST |
221 BT_VALID_MAX_KILL |
222 BT_VALID_3W_TMRS |
223 BT_VALID_KILL_ACK |
224 BT_VALID_KILL_CTS |
225 BT_VALID_REDUCED_TX_POWER |
226 BT_VALID_LUT);
227
228 if (is_loose_coex())
229 memcpy(&cmd.decision_lut, iwl_loose_lookup,
230 sizeof(iwl_tight_lookup));
231 else
232 memcpy(&cmd.decision_lut, iwl_tight_lookup,
233 sizeof(iwl_tight_lookup));
234
235 cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);
236 cmd.kill_ack_msk =
237 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
238 cmd.kill_cts_msk =
239 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
240
241 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
242
243 /* go to CALIB state in internal BT-Coex state machine */
244 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
245 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
246 if (ret)
247 return ret;
248
249 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
250 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
251 if (ret)
252 return ret;
253
254 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
255 sizeof(cmd), &cmd);
256}
257
258static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
259 bool reduced_tx_power)
260{
261 enum iwl_bt_kill_msk bt_kill_msk;
262 struct iwl_bt_coex_cmd cmd = {};
263 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
264
265 lockdep_assert_held(&mvm->mutex);
266
267 if (reduced_tx_power) {
268 /* Reduced Tx power has precedence on the type of the profile */
269 bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW;
270 } else {
271 /* Low latency BT profile is active: give higher prio to BT */
272 if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
273 BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
274 BT_MBOX_MSG(notif, 3, SNIFF_STATE))
275 bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
276 else
277 bt_kill_msk = BT_KILL_MSK_DEFAULT;
278 }
279
280 IWL_DEBUG_COEX(mvm,
281 "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n",
282 bt_kill_msk,
283 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
284 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
285 BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
286
287 /* Don't send HCMD if there is no update */
288 if (bt_kill_msk == mvm->bt_kill_msk)
289 return 0;
290
291 mvm->bt_kill_msk = bt_kill_msk;
292 cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
293 cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
294 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);
295
296 IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk);
297 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
298 sizeof(cmd), &cmd);
299}
300
301static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
302 bool enable)
303{
304 struct iwl_bt_coex_cmd cmd = {
305 .valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER),
306 .bt_reduced_tx_power = sta_id,
307 };
308 struct ieee80211_sta *sta;
309 struct iwl_mvm_sta *mvmsta;
310
311 /* This can happen if the station has been removed right now */
312 if (sta_id == IWL_MVM_STATION_COUNT)
313 return 0;
314
315 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
316 lockdep_is_held(&mvm->mutex));
317 mvmsta = (void *)sta->drv_priv;
318
319 /* nothing to do */
320 if (mvmsta->bt_reduced_txpower == enable)
321 return 0;
322
323 if (enable)
324 cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
325
326 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
327 enable ? "en" : "dis", sta_id);
328
329 mvmsta->bt_reduced_txpower = enable;
330
331 /* Send ASYNC since this can be sent from an atomic context */
332 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC,
333 sizeof(cmd), &cmd);
334}
335
336struct iwl_bt_iterator_data {
337 struct iwl_bt_coex_profile_notif *notif;
338 struct iwl_mvm *mvm;
339 u32 num_bss_ifaces;
340 bool reduced_tx_power;
341};
342
343static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
344 struct ieee80211_vif *vif)
345{
346 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
347 struct iwl_bt_iterator_data *data = _data;
348 struct iwl_mvm *mvm = data->mvm;
349 struct ieee80211_chanctx_conf *chanctx_conf;
350 enum ieee80211_smps_mode smps_mode;
351 enum ieee80211_band band;
352 int ave_rssi;
353
354 if (vif->type != NL80211_IFTYPE_STATION)
355 return;
356
357 rcu_read_lock();
358 chanctx_conf = rcu_dereference(vif->chanctx_conf);
359 if (chanctx_conf && chanctx_conf->def.chan)
360 band = chanctx_conf->def.chan->band;
361 else
362 band = -1;
363 rcu_read_unlock();
364
365 smps_mode = IEEE80211_SMPS_AUTOMATIC;
366
367 if (band != IEEE80211_BAND_2GHZ) {
368 ieee80211_request_smps(vif, smps_mode);
369 return;
370 }
371
372 if (data->notif->bt_status)
373 smps_mode = IEEE80211_SMPS_DYNAMIC;
374
375 if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD)
376 smps_mode = IEEE80211_SMPS_STATIC;
377
378 IWL_DEBUG_COEX(data->mvm,
379 "mac %d: bt_status %d traffic_load %d smps_req %d\n",
380 mvmvif->id, data->notif->bt_status,
381 data->notif->bt_traffic_load, smps_mode);
382
383 ieee80211_request_smps(vif, smps_mode);
384
385 /* don't reduce the Tx power if in loose scheme */
386 if (is_loose_coex())
387 return;
388
389 data->num_bss_ifaces++;
390
391 /* reduced Txpower only if there are open BT connections, so ...*/
392 if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) {
393 /* ... cancel reduced Tx power ... */
394 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
395 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
396 data->reduced_tx_power = false;
397
398 /* ... and there is no need to get reports on RSSI any more. */
399 ieee80211_disable_rssi_reports(vif);
400 return;
401 }
402
403 ave_rssi = ieee80211_ave_rssi(vif);
404
405 /* if the RSSI isn't valid, fake it is very low */
406 if (!ave_rssi)
407 ave_rssi = -100;
408 if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) {
409 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
410 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
411
412 /*
413 * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the
414 * BSS / P2P clients have rssi above threshold.
415 * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before
416 * the iteration, if one interface's rssi isn't good enough,
417 * bt_kill_msk will be set to default values.
418 */
419 } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) {
420 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
421 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
422
423 /*
424 * One interface hasn't rssi above threshold, bt_kill_msk must
425 * be set to default values.
426 */
427 data->reduced_tx_power = false;
428 }
429
430 /* Begin to monitor the RSSI: it may influence the reduced Tx power */
431 ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD,
432 BT_ENABLE_REDUCED_TXPOWER_THRESHOLD);
433}
434
435static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
436{
437 struct iwl_bt_iterator_data data = {
438 .mvm = mvm,
439 .notif = &mvm->last_bt_notif,
440 .reduced_tx_power = true,
441 };
442
443 ieee80211_iterate_active_interfaces_atomic(
444 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
445 iwl_mvm_bt_notif_iterator, &data);
446
447 /*
448 * If there are no BSS / P2P client interfaces, reduced Tx Power is
449 * irrelevant since it is based on the RSSI coming from the beacon.
450 * Use BT_KILL_MSK_DEFAULT in that case.
451 */
452 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
453
454 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
455 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
456}
457
458/* upon association, the fw will send in BT Coex notification */
459int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
460 struct iwl_rx_cmd_buffer *rxb,
461 struct iwl_device_cmd *dev_cmd)
462{
463 struct iwl_rx_packet *pkt = rxb_addr(rxb);
464 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
465
466
467 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
468 IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not ");
469 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
470 IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load);
471 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
472 notif->bt_agg_traffic_load);
473 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
474
475 /* remember this notification for future use: rssi fluctuations */
476 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
477
478 iwl_mvm_bt_coex_notif_handle(mvm);
479
480 /*
481 * This is an async handler for a notification, returning anything other
482 * than 0 doesn't make sense even if HCMD failed.
483 */
484 return 0;
485}
486
487static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
488 struct ieee80211_vif *vif)
489{
490 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
491 struct iwl_bt_iterator_data *data = _data;
492 struct iwl_mvm *mvm = data->mvm;
493
494 struct ieee80211_sta *sta;
495 struct iwl_mvm_sta *mvmsta;
496
497 if (vif->type != NL80211_IFTYPE_STATION ||
498 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
499 return;
500
501 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
502 lockdep_is_held(&mvm->mutex));
503 mvmsta = (void *)sta->drv_priv;
504
505 /*
506 * This interface doesn't support reduced Tx power (because of low
507 * RSSI probably), then set bt_kill_msk to default values.
508 */
509 if (!mvmsta->bt_reduced_txpower)
510 data->reduced_tx_power = false;
511 /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */
512}
513
514void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
515 enum ieee80211_rssi_event rssi_event)
516{
517 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
518 struct iwl_bt_iterator_data data = {
519 .mvm = mvm,
520 .reduced_tx_power = true,
521 };
522 int ret;
523
524 mutex_lock(&mvm->mutex);
525
526 /* Rssi update while not associated ?! */
527 if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT))
528 goto out_unlock;
529
530 /* No open connection - reports should be disabled */
531 if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2))
532 goto out_unlock;
533
534 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
535 rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW");
536
537 /*
538 * Check if rssi is good enough for reduced Tx power, but not in loose
539 * scheme.
540 */
541 if (rssi_event == RSSI_EVENT_LOW || is_loose_coex())
542 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
543 false);
544 else
545 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true);
546
547 if (ret)
548 IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n");
549
550 ieee80211_iterate_active_interfaces_atomic(
551 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
552 iwl_mvm_bt_rssi_iterator, &data);
553
554 /*
555 * If there are no BSS / P2P client interfaces, reduced Tx Power is
556 * irrelevant since it is based on the RSSI coming from the beacon.
557 * Use BT_KILL_MSK_DEFAULT in that case.
558 */
559 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
560
561 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
562 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
563
564 out_unlock:
565 mutex_unlock(&mvm->mutex);
566}
567
568void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
569{
570 struct ieee80211_chanctx_conf *chanctx_conf;
571 enum ieee80211_band band;
572
573 rcu_read_lock();
574 chanctx_conf = rcu_dereference(vif->chanctx_conf);
575 if (chanctx_conf && chanctx_conf->def.chan)
576 band = chanctx_conf->def.chan->band;
577 else
578 band = -1;
579 rcu_read_unlock();
580
581 /* if we are in 2GHz we will get a notification from the fw */
582 if (band == IEEE80211_BAND_2GHZ)
583 return;
584
585 /* else, we can remove all the constraints */
586 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
587
588 iwl_mvm_bt_coex_notif_handle(mvm);
589}
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index c64d864799cd..16bbdcc8627a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -61,8 +61,11 @@
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63 63
64#include <linux/etherdevice.h>
65#include <linux/ip.h>
64#include <net/cfg80211.h> 66#include <net/cfg80211.h>
65#include <net/ipv6.h> 67#include <net/ipv6.h>
68#include <net/tcp.h>
66#include "iwl-modparams.h" 69#include "iwl-modparams.h"
67#include "fw-api.h" 70#include "fw-api.h"
68#include "mvm.h" 71#include "mvm.h"
@@ -192,6 +195,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
192 sizeof(wkc), &wkc); 195 sizeof(wkc), &wkc);
193 data->error = ret != 0; 196 data->error = ret != 0;
194 197
198 mvm->ptk_ivlen = key->iv_len;
199 mvm->ptk_icvlen = key->icv_len;
200 mvm->gtk_ivlen = key->iv_len;
201 mvm->gtk_icvlen = key->icv_len;
202
195 /* don't upload key again */ 203 /* don't upload key again */
196 goto out_unlock; 204 goto out_unlock;
197 } 205 }
@@ -304,9 +312,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
304 */ 312 */
305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 313 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
306 key->hw_key_idx = 0; 314 key->hw_key_idx = 0;
315 mvm->ptk_ivlen = key->iv_len;
316 mvm->ptk_icvlen = key->icv_len;
307 } else { 317 } else {
308 data->gtk_key_idx++; 318 data->gtk_key_idx++;
309 key->hw_key_idx = data->gtk_key_idx; 319 key->hw_key_idx = data->gtk_key_idx;
320 mvm->gtk_ivlen = key->iv_len;
321 mvm->gtk_icvlen = key->icv_len;
310 } 322 }
311 323
312 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); 324 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
@@ -392,6 +404,233 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
392 sizeof(cmd), &cmd); 404 sizeof(cmd), &cmd);
393} 405}
394 406
407enum iwl_mvm_tcp_packet_type {
408 MVM_TCP_TX_SYN,
409 MVM_TCP_RX_SYNACK,
410 MVM_TCP_TX_DATA,
411 MVM_TCP_RX_ACK,
412 MVM_TCP_RX_WAKE,
413 MVM_TCP_TX_FIN,
414};
415
416static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr)
417{
418 __sum16 check = tcp_v4_check(len, saddr, daddr, 0);
419 return cpu_to_le16(be16_to_cpu((__force __be16)check));
420}
421
422static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm,
423 struct ieee80211_vif *vif,
424 struct cfg80211_wowlan_tcp *tcp,
425 void *_pkt, u8 *mask,
426 __le16 *pseudo_hdr_csum,
427 enum iwl_mvm_tcp_packet_type ptype)
428{
429 struct {
430 struct ethhdr eth;
431 struct iphdr ip;
432 struct tcphdr tcp;
433 u8 data[];
434 } __packed *pkt = _pkt;
435 u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
436 int i;
437
438 pkt->eth.h_proto = cpu_to_be16(ETH_P_IP),
439 pkt->ip.version = 4;
440 pkt->ip.ihl = 5;
441 pkt->ip.protocol = IPPROTO_TCP;
442
443 switch (ptype) {
444 case MVM_TCP_TX_SYN:
445 case MVM_TCP_TX_DATA:
446 case MVM_TCP_TX_FIN:
447 memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN);
448 memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN);
449 pkt->ip.ttl = 128;
450 pkt->ip.saddr = tcp->src;
451 pkt->ip.daddr = tcp->dst;
452 pkt->tcp.source = cpu_to_be16(tcp->src_port);
453 pkt->tcp.dest = cpu_to_be16(tcp->dst_port);
454 /* overwritten for TX SYN later */
455 pkt->tcp.doff = sizeof(struct tcphdr) / 4;
456 pkt->tcp.window = cpu_to_be16(65000);
457 break;
458 case MVM_TCP_RX_SYNACK:
459 case MVM_TCP_RX_ACK:
460 case MVM_TCP_RX_WAKE:
461 memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN);
462 memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN);
463 pkt->ip.saddr = tcp->dst;
464 pkt->ip.daddr = tcp->src;
465 pkt->tcp.source = cpu_to_be16(tcp->dst_port);
466 pkt->tcp.dest = cpu_to_be16(tcp->src_port);
467 break;
468 default:
469 WARN_ON(1);
470 return;
471 }
472
473 switch (ptype) {
474 case MVM_TCP_TX_SYN:
475 /* firmware assumes 8 option bytes - 8 NOPs for now */
476 memset(pkt->data, 0x01, 8);
477 ip_tot_len += 8;
478 pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4;
479 pkt->tcp.syn = 1;
480 break;
481 case MVM_TCP_TX_DATA:
482 ip_tot_len += tcp->payload_len;
483 memcpy(pkt->data, tcp->payload, tcp->payload_len);
484 pkt->tcp.psh = 1;
485 pkt->tcp.ack = 1;
486 break;
487 case MVM_TCP_TX_FIN:
488 pkt->tcp.fin = 1;
489 pkt->tcp.ack = 1;
490 break;
491 case MVM_TCP_RX_SYNACK:
492 pkt->tcp.syn = 1;
493 pkt->tcp.ack = 1;
494 break;
495 case MVM_TCP_RX_ACK:
496 pkt->tcp.ack = 1;
497 break;
498 case MVM_TCP_RX_WAKE:
499 ip_tot_len += tcp->wake_len;
500 pkt->tcp.psh = 1;
501 pkt->tcp.ack = 1;
502 memcpy(pkt->data, tcp->wake_data, tcp->wake_len);
503 break;
504 }
505
506 switch (ptype) {
507 case MVM_TCP_TX_SYN:
508 case MVM_TCP_TX_DATA:
509 case MVM_TCP_TX_FIN:
510 pkt->ip.tot_len = cpu_to_be16(ip_tot_len);
511 pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl);
512 break;
513 case MVM_TCP_RX_WAKE:
514 for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) {
515 u8 tmp = tcp->wake_mask[i];
516 mask[i + 6] |= tmp << 6;
517 if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8))
518 mask[i + 7] = tmp >> 2;
519 }
520 /* fall through for ethernet/IP/TCP headers mask */
521 case MVM_TCP_RX_SYNACK:
522 case MVM_TCP_RX_ACK:
523 mask[0] = 0xff; /* match ethernet */
524 /*
525 * match ethernet, ip.version, ip.ihl
526 * the ip.ihl half byte is really masked out by firmware
527 */
528 mask[1] = 0x7f;
529 mask[2] = 0x80; /* match ip.protocol */
530 mask[3] = 0xfc; /* match ip.saddr, ip.daddr */
531 mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */
532 mask[5] = 0x80; /* match tcp flags */
533 /* leave rest (0 or set for MVM_TCP_RX_WAKE) */
534 break;
535 };
536
537 *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr),
538 pkt->ip.saddr, pkt->ip.daddr);
539}
540
541static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm,
542 struct ieee80211_vif *vif,
543 struct cfg80211_wowlan_tcp *tcp)
544{
545 struct iwl_wowlan_remote_wake_config *cfg;
546 struct iwl_host_cmd cmd = {
547 .id = REMOTE_WAKE_CONFIG_CMD,
548 .len = { sizeof(*cfg), },
549 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
550 .flags = CMD_SYNC,
551 };
552 int ret;
553
554 if (!tcp)
555 return 0;
556
557 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
558 if (!cfg)
559 return -ENOMEM;
560 cmd.data[0] = cfg;
561
562 cfg->max_syn_retries = 10;
563 cfg->max_data_retries = 10;
564 cfg->tcp_syn_ack_timeout = 1; /* seconds */
565 cfg->tcp_ack_timeout = 1; /* seconds */
566
567 /* SYN (TX) */
568 iwl_mvm_build_tcp_packet(
569 mvm, vif, tcp, cfg->syn_tx.data, NULL,
570 &cfg->syn_tx.info.tcp_pseudo_header_checksum,
571 MVM_TCP_TX_SYN);
572 cfg->syn_tx.info.tcp_payload_length = 0;
573
574 /* SYN/ACK (RX) */
575 iwl_mvm_build_tcp_packet(
576 mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,
577 &cfg->synack_rx.info.tcp_pseudo_header_checksum,
578 MVM_TCP_RX_SYNACK);
579 cfg->synack_rx.info.tcp_payload_length = 0;
580
581 /* KEEPALIVE/ACK (TX) */
582 iwl_mvm_build_tcp_packet(
583 mvm, vif, tcp, cfg->keepalive_tx.data, NULL,
584 &cfg->keepalive_tx.info.tcp_pseudo_header_checksum,
585 MVM_TCP_TX_DATA);
586 cfg->keepalive_tx.info.tcp_payload_length =
587 cpu_to_le16(tcp->payload_len);
588 cfg->sequence_number_offset = tcp->payload_seq.offset;
589 /* length must be 0..4, the field is little endian */
590 cfg->sequence_number_length = tcp->payload_seq.len;
591 cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start);
592 cfg->keepalive_interval = cpu_to_le16(tcp->data_interval);
593 if (tcp->payload_tok.len) {
594 cfg->token_offset = tcp->payload_tok.offset;
595 cfg->token_length = tcp->payload_tok.len;
596 cfg->num_tokens =
597 cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len);
598 memcpy(cfg->tokens, tcp->payload_tok.token_stream,
599 tcp->tokens_size);
600 } else {
601 /* set tokens to max value to almost never run out */
602 cfg->num_tokens = cpu_to_le16(65535);
603 }
604
605 /* ACK (RX) */
606 iwl_mvm_build_tcp_packet(
607 mvm, vif, tcp, cfg->keepalive_ack_rx.data,
608 cfg->keepalive_ack_rx.rx_mask,
609 &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum,
610 MVM_TCP_RX_ACK);
611 cfg->keepalive_ack_rx.info.tcp_payload_length = 0;
612
613 /* WAKEUP (RX) */
614 iwl_mvm_build_tcp_packet(
615 mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,
616 &cfg->wake_rx.info.tcp_pseudo_header_checksum,
617 MVM_TCP_RX_WAKE);
618 cfg->wake_rx.info.tcp_payload_length =
619 cpu_to_le16(tcp->wake_len);
620
621 /* FIN */
622 iwl_mvm_build_tcp_packet(
623 mvm, vif, tcp, cfg->fin_tx.data, NULL,
624 &cfg->fin_tx.info.tcp_pseudo_header_checksum,
625 MVM_TCP_TX_FIN);
626 cfg->fin_tx.info.tcp_payload_length = 0;
627
628 ret = iwl_mvm_send_cmd(mvm, &cmd);
629 kfree(cfg);
630
631 return ret;
632}
633
395struct iwl_d3_iter_data { 634struct iwl_d3_iter_data {
396 struct iwl_mvm *mvm; 635 struct iwl_mvm *mvm;
397 struct ieee80211_vif *vif; 636 struct ieee80211_vif *vif;
@@ -530,7 +769,14 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
530 struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; 769 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
531 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; 770 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
532 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; 771 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
533 struct iwl_d3_manager_config d3_cfg_cmd = {}; 772 struct iwl_d3_manager_config d3_cfg_cmd = {
773 /*
774 * Program the minimum sleep time to 10 seconds, as many
775 * platforms have issues processing a wakeup signal while
776 * still being in the process of suspending.
777 */
778 .min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
779 };
534 struct wowlan_key_data key_data = { 780 struct wowlan_key_data key_data = {
535 .use_rsc_tsc = false, 781 .use_rsc_tsc = false,
536 .tkip = &tkip_cmd, 782 .tkip = &tkip_cmd,
@@ -627,9 +873,21 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
627 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); 873 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
628 874
629 if (wowlan->rfkill_release) 875 if (wowlan->rfkill_release)
630 d3_cfg_cmd.wakeup_flags |= 876 wowlan_config_cmd.wakeup_filter |=
631 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 877 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
632 878
879 if (wowlan->tcp) {
880 /*
881 * Set the "link change" (really "link lost") flag as well
882 * since that implies losing the TCP connection.
883 */
884 wowlan_config_cmd.wakeup_filter |=
885 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
886 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
887 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
888 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
889 }
890
633 iwl_mvm_cancel_scan(mvm); 891 iwl_mvm_cancel_scan(mvm);
634 892
635 iwl_trans_stop_device(mvm->trans); 893 iwl_trans_stop_device(mvm->trans);
@@ -649,6 +907,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
649 /* We reprogram keys and shouldn't allocate new key indices */ 907 /* We reprogram keys and shouldn't allocate new key indices */
650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 908 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
651 909
910 mvm->ptk_ivlen = 0;
911 mvm->ptk_icvlen = 0;
912 mvm->ptk_ivlen = 0;
913 mvm->ptk_icvlen = 0;
914
652 /* 915 /*
653 * The D3 firmware still hardcodes the AP station ID for the 916 * The D3 firmware still hardcodes the AP station ID for the
654 * BSS we're associated with as 0. As a result, we have to move 917 * BSS we're associated with as 0. As a result, we have to move
@@ -740,6 +1003,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
740 if (ret) 1003 if (ret)
741 goto out; 1004 goto out;
742 1005
1006 ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp);
1007 if (ret)
1008 goto out;
1009
743 /* must be last -- this switches firmware state */ 1010 /* must be last -- this switches firmware state */
744 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1011 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
745 sizeof(d3_cfg_cmd), &d3_cfg_cmd); 1012 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
@@ -783,7 +1050,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
783 struct iwl_wowlan_status *status; 1050 struct iwl_wowlan_status *status;
784 u32 reasons; 1051 u32 reasons;
785 int ret, len; 1052 int ret, len;
786 bool pkt8023 = false;
787 struct sk_buff *pkt = NULL; 1053 struct sk_buff *pkt = NULL;
788 1054
789 iwl_trans_read_mem_bytes(mvm->trans, base, 1055 iwl_trans_read_mem_bytes(mvm->trans, base,
@@ -824,7 +1090,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
824 status = (void *)cmd.resp_pkt->data; 1090 status = (void *)cmd.resp_pkt->data;
825 1091
826 if (len - sizeof(struct iwl_cmd_header) != 1092 if (len - sizeof(struct iwl_cmd_header) !=
827 sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { 1093 sizeof(*status) +
1094 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
828 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1095 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
829 goto out; 1096 goto out;
830 } 1097 }
@@ -836,61 +1103,105 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
836 goto report; 1103 goto report;
837 } 1104 }
838 1105
839 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { 1106 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
840 wakeup.magic_pkt = true; 1107 wakeup.magic_pkt = true;
841 pkt8023 = true;
842 }
843 1108
844 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { 1109 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
845 wakeup.pattern_idx = 1110 wakeup.pattern_idx =
846 le16_to_cpu(status->pattern_number); 1111 le16_to_cpu(status->pattern_number);
847 pkt8023 = true;
848 }
849 1112
850 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 1113 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
851 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) 1114 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
852 wakeup.disconnect = true; 1115 wakeup.disconnect = true;
853 1116
854 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { 1117 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
855 wakeup.gtk_rekey_failure = true; 1118 wakeup.gtk_rekey_failure = true;
856 pkt8023 = true;
857 }
858 1119
859 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { 1120 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
860 wakeup.rfkill_release = true; 1121 wakeup.rfkill_release = true;
861 pkt8023 = true;
862 }
863 1122
864 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { 1123 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
865 wakeup.eap_identity_req = true; 1124 wakeup.eap_identity_req = true;
866 pkt8023 = true;
867 }
868 1125
869 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { 1126 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
870 wakeup.four_way_handshake = true; 1127 wakeup.four_way_handshake = true;
871 pkt8023 = true; 1128
872 } 1129 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
1130 wakeup.tcp_connlost = true;
1131
1132 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
1133 wakeup.tcp_nomoretokens = true;
1134
1135 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
1136 wakeup.tcp_match = true;
873 1137
874 if (status->wake_packet_bufsize) { 1138 if (status->wake_packet_bufsize) {
875 u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); 1139 int pktsize = le32_to_cpu(status->wake_packet_bufsize);
876 u32 pktlen = le32_to_cpu(status->wake_packet_length); 1140 int pktlen = le32_to_cpu(status->wake_packet_length);
1141 const u8 *pktdata = status->wake_packet;
1142 struct ieee80211_hdr *hdr = (void *)pktdata;
1143 int truncated = pktlen - pktsize;
1144
1145 /* this would be a firmware bug */
1146 if (WARN_ON_ONCE(truncated < 0))
1147 truncated = 0;
1148
1149 if (ieee80211_is_data(hdr->frame_control)) {
1150 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
1151 int ivlen = 0, icvlen = 4; /* also FCS */
877 1152
878 if (pkt8023) {
879 pkt = alloc_skb(pktsize, GFP_KERNEL); 1153 pkt = alloc_skb(pktsize, GFP_KERNEL);
880 if (!pkt) 1154 if (!pkt)
881 goto report; 1155 goto report;
882 memcpy(skb_put(pkt, pktsize), status->wake_packet, 1156
883 pktsize); 1157 memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);
1158 pktdata += hdrlen;
1159 pktsize -= hdrlen;
1160
1161 if (ieee80211_has_protected(hdr->frame_control)) {
1162 if (is_multicast_ether_addr(hdr->addr1)) {
1163 ivlen = mvm->gtk_ivlen;
1164 icvlen += mvm->gtk_icvlen;
1165 } else {
1166 ivlen = mvm->ptk_ivlen;
1167 icvlen += mvm->ptk_icvlen;
1168 }
1169 }
1170
1171 /* if truncated, FCS/ICV is (partially) gone */
1172 if (truncated >= icvlen) {
1173 icvlen = 0;
1174 truncated -= icvlen;
1175 } else {
1176 icvlen -= truncated;
1177 truncated = 0;
1178 }
1179
1180 pktsize -= ivlen + icvlen;
1181 pktdata += ivlen;
1182
1183 memcpy(skb_put(pkt, pktsize), pktdata, pktsize);
1184
884 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) 1185 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
885 goto report; 1186 goto report;
886 wakeup.packet = pkt->data; 1187 wakeup.packet = pkt->data;
887 wakeup.packet_present_len = pkt->len; 1188 wakeup.packet_present_len = pkt->len;
888 wakeup.packet_len = pkt->len - (pktlen - pktsize); 1189 wakeup.packet_len = pkt->len - truncated;
889 wakeup.packet_80211 = false; 1190 wakeup.packet_80211 = false;
890 } else { 1191 } else {
1192 int fcslen = 4;
1193
1194 if (truncated >= 4) {
1195 truncated -= 4;
1196 fcslen = 0;
1197 } else {
1198 fcslen -= truncated;
1199 truncated = 0;
1200 }
1201 pktsize -= fcslen;
891 wakeup.packet = status->wake_packet; 1202 wakeup.packet = status->wake_packet;
892 wakeup.packet_present_len = pktsize; 1203 wakeup.packet_present_len = pktsize;
893 wakeup.packet_len = pktlen; 1204 wakeup.packet_len = pktlen - truncated;
894 wakeup.packet_80211 = true; 1205 wakeup.packet_80211 = true;
895 } 1206 }
896 } 1207 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index c1bdb5582126..2053dccefcd6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -69,12 +69,6 @@ struct iwl_dbgfs_mvm_ctx {
69 struct ieee80211_vif *vif; 69 struct ieee80211_vif *vif;
70}; 70};
71 71
72static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
73{
74 file->private_data = inode->i_private;
75 return 0;
76}
77
78static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, 72static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
79 const char __user *user_buf, 73 const char __user *user_buf,
80 size_t count, loff_t *ppos) 74 size_t count, loff_t *ppos)
@@ -306,10 +300,191 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
306 return count; 300 return count;
307} 301}
308 302
303static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
304 char __user *user_buf,
305 size_t count, loff_t *ppos)
306{
307 struct ieee80211_vif *vif = file->private_data;
308 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
309 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
310 u8 ap_sta_id;
311 struct ieee80211_chanctx_conf *chanctx_conf;
312 char buf[512];
313 int bufsz = sizeof(buf);
314 int pos = 0;
315 int i;
316
317 mutex_lock(&mvm->mutex);
318
319 ap_sta_id = mvmvif->ap_sta_id;
320
321 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
322 mvmvif->id, mvmvif->color);
323 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
324 vif->bss_conf.bssid);
325 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
326 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) {
327 pos += scnprintf(buf+pos, bufsz-pos,
328 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
329 i, mvmvif->queue_params[i].txop,
330 mvmvif->queue_params[i].cw_min,
331 mvmvif->queue_params[i].cw_max,
332 mvmvif->queue_params[i].aifs,
333 mvmvif->queue_params[i].uapsd);
334 }
335
336 if (vif->type == NL80211_IFTYPE_STATION &&
337 ap_sta_id != IWL_MVM_STATION_COUNT) {
338 struct ieee80211_sta *sta;
339 struct iwl_mvm_sta *mvm_sta;
340
341 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
342 lockdep_is_held(&mvm->mutex));
343 mvm_sta = (void *)sta->drv_priv;
344 pos += scnprintf(buf+pos, bufsz-pos,
345 "ap_sta_id %d - reduced Tx power %d\n",
346 ap_sta_id, mvm_sta->bt_reduced_txpower);
347 }
348
349 rcu_read_lock();
350 chanctx_conf = rcu_dereference(vif->chanctx_conf);
351 if (chanctx_conf) {
352 pos += scnprintf(buf+pos, bufsz-pos,
353 "idle rx chains %d, active rx chains: %d\n",
354 chanctx_conf->rx_chains_static,
355 chanctx_conf->rx_chains_dynamic);
356 }
357 rcu_read_unlock();
358
359 mutex_unlock(&mvm->mutex);
360
361 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
362}
363
364#define BT_MBOX_MSG(_notif, _num, _field) \
365 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
366 >> BT_MBOX##_num##_##_field##_POS)
367
368
369#define BT_MBOX_PRINT(_num, _field, _end) \
370 pos += scnprintf(buf + pos, bufsz - pos, \
371 "\t%s: %d%s", \
372 #_field, \
373 BT_MBOX_MSG(notif, _num, _field), \
374 true ? "\n" : ", ");
375
376static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
377 size_t count, loff_t *ppos)
378{
379 struct iwl_mvm *mvm = file->private_data;
380 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
381 char *buf;
382 int ret, pos = 0, bufsz = sizeof(char) * 1024;
383
384 buf = kmalloc(bufsz, GFP_KERNEL);
385 if (!buf)
386 return -ENOMEM;
387
388 mutex_lock(&mvm->mutex);
389
390 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
391
392 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
393 BT_MBOX_PRINT(0, LE_PROF1, false);
394 BT_MBOX_PRINT(0, LE_PROF2, false);
395 BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
396 BT_MBOX_PRINT(0, CHL_SEQ_N, false);
397 BT_MBOX_PRINT(0, INBAND_S, false);
398 BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
399 BT_MBOX_PRINT(0, LE_SCAN, false);
400 BT_MBOX_PRINT(0, LE_ADV, false);
401 BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
402 BT_MBOX_PRINT(0, OPEN_CON_1, true);
403
404 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
405
406 BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
407 BT_MBOX_PRINT(1, IP_SR, false);
408 BT_MBOX_PRINT(1, LE_MSTR, false);
409 BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
410 BT_MBOX_PRINT(1, MSG_TYPE, false);
411 BT_MBOX_PRINT(1, SSN, true);
412
413 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
414
415 BT_MBOX_PRINT(2, SNIFF_ACT, false);
416 BT_MBOX_PRINT(2, PAG, false);
417 BT_MBOX_PRINT(2, INQUIRY, false);
418 BT_MBOX_PRINT(2, CONN, false);
419 BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
420 BT_MBOX_PRINT(2, DISC, false);
421 BT_MBOX_PRINT(2, SCO_TX_ACT, false);
422 BT_MBOX_PRINT(2, SCO_RX_ACT, false);
423 BT_MBOX_PRINT(2, ESCO_RE_TX, false);
424 BT_MBOX_PRINT(2, SCO_DURATION, true);
425
426 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
427
428 BT_MBOX_PRINT(3, SCO_STATE, false);
429 BT_MBOX_PRINT(3, SNIFF_STATE, false);
430 BT_MBOX_PRINT(3, A2DP_STATE, false);
431 BT_MBOX_PRINT(3, ACL_STATE, false);
432 BT_MBOX_PRINT(3, MSTR_STATE, false);
433 BT_MBOX_PRINT(3, OBX_STATE, false);
434 BT_MBOX_PRINT(3, OPEN_CON_2, false);
435 BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
436 BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
437 BT_MBOX_PRINT(3, INBAND_P, false);
438 BT_MBOX_PRINT(3, MSG_TYPE_2, false);
439 BT_MBOX_PRINT(3, SSN_2, false);
440 BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
441
442 pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n",
443 notif->bt_status);
444 pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n",
445 notif->bt_open_conn);
446 pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n",
447 notif->bt_traffic_load);
448 pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n",
449 notif->bt_agg_traffic_load);
450 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
451 notif->bt_ci_compliance);
452
453 mutex_unlock(&mvm->mutex);
454
455 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
456 kfree(buf);
457
458 return ret;
459}
460#undef BT_MBOX_PRINT
461
462static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
463 const char __user *user_buf,
464 size_t count, loff_t *ppos)
465{
466 struct iwl_mvm *mvm = file->private_data;
467 bool restart_fw = iwlwifi_mod_params.restart_fw;
468 int ret;
469
470 iwlwifi_mod_params.restart_fw = true;
471
472 mutex_lock(&mvm->mutex);
473
474 /* take the return value to make compiler happy - it will fail anyway */
475 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL);
476
477 mutex_unlock(&mvm->mutex);
478
479 iwlwifi_mod_params.restart_fw = restart_fw;
480
481 return count;
482}
483
309#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 484#define MVM_DEBUGFS_READ_FILE_OPS(name) \
310static const struct file_operations iwl_dbgfs_##name##_ops = { \ 485static const struct file_operations iwl_dbgfs_##name##_ops = { \
311 .read = iwl_dbgfs_##name##_read, \ 486 .read = iwl_dbgfs_##name##_read, \
312 .open = iwl_dbgfs_open_file_generic, \ 487 .open = simple_open, \
313 .llseek = generic_file_llseek, \ 488 .llseek = generic_file_llseek, \
314} 489}
315 490
@@ -317,14 +492,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
317static const struct file_operations iwl_dbgfs_##name##_ops = { \ 492static const struct file_operations iwl_dbgfs_##name##_ops = { \
318 .write = iwl_dbgfs_##name##_write, \ 493 .write = iwl_dbgfs_##name##_write, \
319 .read = iwl_dbgfs_##name##_read, \ 494 .read = iwl_dbgfs_##name##_read, \
320 .open = iwl_dbgfs_open_file_generic, \ 495 .open = simple_open, \
321 .llseek = generic_file_llseek, \ 496 .llseek = generic_file_llseek, \
322}; 497};
323 498
324#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ 499#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
325static const struct file_operations iwl_dbgfs_##name##_ops = { \ 500static const struct file_operations iwl_dbgfs_##name##_ops = { \
326 .write = iwl_dbgfs_##name##_write, \ 501 .write = iwl_dbgfs_##name##_write, \
327 .open = iwl_dbgfs_open_file_generic, \ 502 .open = simple_open, \
328 .llseek = generic_file_llseek, \ 503 .llseek = generic_file_llseek, \
329}; 504};
330 505
@@ -345,8 +520,13 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush);
345MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 520MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
346MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 521MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
347MVM_DEBUGFS_READ_FILE_OPS(stations); 522MVM_DEBUGFS_READ_FILE_OPS(stations);
523MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
348MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 524MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
349MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 525MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
526MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
527
528/* Interface specific debugfs entries */
529MVM_DEBUGFS_READ_FILE_OPS(mac_params);
350 530
351int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 531int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
352{ 532{
@@ -358,8 +538,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
358 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); 538 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
359 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 539 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
360 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 540 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
541 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
361 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 542 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
362 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 543 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
544 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
363 545
364 /* 546 /*
365 * Create a symlink with mac80211. It will be removed when mac80211 547 * Create a symlink with mac80211. It will be removed when mac80211
@@ -376,3 +558,58 @@ err:
376 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); 558 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
377 return -ENOMEM; 559 return -ENOMEM;
378} 560}
561
562void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
563{
564 struct dentry *dbgfs_dir = vif->debugfs_dir;
565 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
566 char buf[100];
567
568 if (!dbgfs_dir)
569 return;
570
571 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
572 mvmvif->dbgfs_data = mvm;
573
574 if (!mvmvif->dbgfs_dir) {
575 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
576 dbgfs_dir->d_name.name);
577 return;
578 }
579
580 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
581 S_IRUSR);
582
583 /*
584 * Create symlink for convenience pointing to interface specific
585 * debugfs entries for the driver. For example, under
586 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
587 * find
588 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
589 */
590 snprintf(buf, 100, "../../../%s/%s/%s/%s",
591 dbgfs_dir->d_parent->d_parent->d_name.name,
592 dbgfs_dir->d_parent->d_name.name,
593 dbgfs_dir->d_name.name,
594 mvmvif->dbgfs_dir->d_name.name);
595
596 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
597 mvm->debugfs_dir, buf);
598 if (!mvmvif->dbgfs_slink)
599 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
600 dbgfs_dir->d_name.name);
601 return;
602err:
603 IWL_ERR(mvm, "Can't create debugfs entity\n");
604}
605
606void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
607{
608 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
609
610 debugfs_remove(mvmvif->dbgfs_slink);
611 mvmvif->dbgfs_slink = NULL;
612
613 debugfs_remove_recursive(mvmvif->dbgfs_dir);
614 mvmvif->dbgfs_dir = NULL;
615}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
new file mode 100644
index 000000000000..05c61d6f384e
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -0,0 +1,319 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_bt_coex_h__
64#define __fw_api_bt_coex_h__
65
66#include <linux/types.h>
67#include <linux/bitops.h>
68
69#define BITS(nb) (BIT(nb) - 1)
70
71/**
72 * enum iwl_bt_coex_flags - flags for BT_COEX command
73 * @BT_CH_PRIMARY_EN:
74 * @BT_CH_SECONDARY_EN:
75 * @BT_NOTIF_COEX_OFF:
76 * @BT_COEX_MODE_POS:
77 * @BT_COEX_MODE_MSK:
78 * @BT_COEX_DISABLE:
79 * @BT_COEX_2W:
80 * @BT_COEX_3W:
81 * @BT_COEX_NW:
82 * @BT_USE_DEFAULTS:
83 * @BT_SYNC_2_BT_DISABLE:
84 * @BT_COEX_CORUNNING_TBL_EN:
85 */
86enum iwl_bt_coex_flags {
87 BT_CH_PRIMARY_EN = BIT(0),
88 BT_CH_SECONDARY_EN = BIT(1),
89 BT_NOTIF_COEX_OFF = BIT(2),
90 BT_COEX_MODE_POS = 3,
91 BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS,
92 BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS,
93 BT_COEX_2W = 0x1 << BT_COEX_MODE_POS,
94 BT_COEX_3W = 0x2 << BT_COEX_MODE_POS,
95 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
96 BT_USE_DEFAULTS = BIT(6),
97 BT_SYNC_2_BT_DISABLE = BIT(7),
98 /*
99 * For future use - when the flags will be enlarged
100 * BT_COEX_CORUNNING_TBL_EN = BIT(8),
101 */
102};
103
104/*
105 * indicates what has changed in the BT_COEX command.
106 */
107enum iwl_bt_coex_valid_bit_msk {
108 BT_VALID_ENABLE = BIT(0),
109 BT_VALID_BT_PRIO_BOOST = BIT(1),
110 BT_VALID_MAX_KILL = BIT(2),
111 BT_VALID_3W_TMRS = BIT(3),
112 BT_VALID_KILL_ACK = BIT(4),
113 BT_VALID_KILL_CTS = BIT(5),
114 BT_VALID_REDUCED_TX_POWER = BIT(6),
115 BT_VALID_LUT = BIT(7),
116 BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8),
117 BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9),
118 BT_VALID_MULTI_PRIO_LUT = BIT(10),
119 BT_VALID_TRM_KICK_FILTER = BIT(11),
120 BT_VALID_CORUN_LUT_20 = BIT(12),
121 BT_VALID_CORUN_LUT_40 = BIT(13),
122 BT_VALID_ANT_ISOLATION = BIT(14),
123 BT_VALID_ANT_ISOLATION_THRS = BIT(15),
124 /*
125 * For future use - when the valid flags will be enlarged
126 * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
127 * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
128 */
129};
130
131/**
132 * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames.
133 * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames
134 * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames
135 *
136 * This mechanism allows to have BT and WiFi run concurrently. Since WiFi
137 * reduces its Tx power, it can work along with BT, hence reducing the amount
138 * of WiFi frames being killed by BT.
139 */
140enum iwl_bt_reduced_tx_power {
141 BT_REDUCED_TX_POWER_CTL = BIT(0),
142 BT_REDUCED_TX_POWER_DATA = BIT(1),
143};
144
145#define BT_COEX_LUT_SIZE (12)
146
147/**
148 * struct iwl_bt_coex_cmd - bt coex configuration command
149 * @flags:&enum iwl_bt_coex_flags
150 * @lead_time:
151 * @max_kill:
152 * @bt3_time_t7_value:
153 * @kill_ack_msk:
154 * @kill_cts_msk:
155 * @bt3_prio_sample_time:
156 * @bt3_timer_t2_value:
157 * @bt4_reaction_time:
158 * @decision_lut[12]:
159 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
160 * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
161 * @bt_prio_boost: values for PTA boost register
162 * @wifi_tx_prio_boost: SW boost of wifi tx priority
163 * @wifi_rx_prio_boost: SW boost of wifi rx priority
164 *
165 * The structure is used for the BT_COEX command.
166 */
167struct iwl_bt_coex_cmd {
168 u8 flags;
169 u8 lead_time;
170 u8 max_kill;
171 u8 bt3_time_t7_value;
172 __le32 kill_ack_msk;
173 __le32 kill_cts_msk;
174 u8 bt3_prio_sample_time;
175 u8 bt3_timer_t2_value;
176 __le16 bt4_reaction_time;
177 __le32 decision_lut[BT_COEX_LUT_SIZE];
178 u8 bt_reduced_tx_power;
179 u8 reserved;
180 __le16 valid_bit_msk;
181 __le32 bt_prio_boost;
182 u8 reserved2;
183 u8 wifi_tx_prio_boost;
184 __le16 wifi_rx_prio_boost;
185} __packed; /* BT_COEX_CMD_API_S_VER_3 */
186
187#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
188 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
189 BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS
190
191enum iwl_bt_mxbox_dw0 {
192 BT_MBOX(0, LE_SLAVE_LAT, 0, 3),
193 BT_MBOX(0, LE_PROF1, 3, 1),
194 BT_MBOX(0, LE_PROF2, 4, 1),
195 BT_MBOX(0, LE_PROF_OTHER, 5, 1),
196 BT_MBOX(0, CHL_SEQ_N, 8, 4),
197 BT_MBOX(0, INBAND_S, 13, 1),
198 BT_MBOX(0, LE_MIN_RSSI, 16, 4),
199 BT_MBOX(0, LE_SCAN, 20, 1),
200 BT_MBOX(0, LE_ADV, 21, 1),
201 BT_MBOX(0, LE_MAX_TX_POWER, 24, 4),
202 BT_MBOX(0, OPEN_CON_1, 28, 2),
203};
204
205enum iwl_bt_mxbox_dw1 {
206 BT_MBOX(1, BR_MAX_TX_POWER, 0, 4),
207 BT_MBOX(1, IP_SR, 4, 1),
208 BT_MBOX(1, LE_MSTR, 5, 1),
209 BT_MBOX(1, AGGR_TRFC_LD, 8, 6),
210 BT_MBOX(1, MSG_TYPE, 16, 3),
211 BT_MBOX(1, SSN, 19, 2),
212};
213
214enum iwl_bt_mxbox_dw2 {
215 BT_MBOX(2, SNIFF_ACT, 0, 3),
216 BT_MBOX(2, PAG, 3, 1),
217 BT_MBOX(2, INQUIRY, 4, 1),
218 BT_MBOX(2, CONN, 5, 1),
219 BT_MBOX(2, SNIFF_INTERVAL, 8, 5),
220 BT_MBOX(2, DISC, 13, 1),
221 BT_MBOX(2, SCO_TX_ACT, 16, 2),
222 BT_MBOX(2, SCO_RX_ACT, 18, 2),
223 BT_MBOX(2, ESCO_RE_TX, 20, 2),
224 BT_MBOX(2, SCO_DURATION, 24, 6),
225};
226
227enum iwl_bt_mxbox_dw3 {
228 BT_MBOX(3, SCO_STATE, 0, 1),
229 BT_MBOX(3, SNIFF_STATE, 1, 1),
230 BT_MBOX(3, A2DP_STATE, 2, 1),
231 BT_MBOX(3, ACL_STATE, 3, 1),
232 BT_MBOX(3, MSTR_STATE, 4, 1),
233 BT_MBOX(3, OBX_STATE, 5, 1),
234 BT_MBOX(3, OPEN_CON_2, 8, 2),
235 BT_MBOX(3, TRAFFIC_LOAD, 10, 2),
236 BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
237 BT_MBOX(3, INBAND_P, 13, 1),
238 BT_MBOX(3, MSG_TYPE_2, 16, 3),
239 BT_MBOX(3, SSN_2, 19, 2),
240 BT_MBOX(3, UPDATE_REQUEST, 21, 1),
241};
242
243#define BT_MBOX_MSG(_notif, _num, _field) \
244 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
245 >> BT_MBOX##_num##_##_field##_POS)
246
247/**
248 * struct iwl_bt_coex_profile_notif - notification about BT coex
249 * @mbox_msg: message from BT to WiFi
250 * @:bt_status: 0 - off, 1 - on
251 * @:bt_open_conn: number of BT connections open
252 * @:bt_traffic_load: load of BT traffic
253 * @:bt_agg_traffic_load: aggregated load of BT traffic
254 * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
255 */
256struct iwl_bt_coex_profile_notif {
257 __le32 mbox_msg[4];
258 u8 bt_status;
259 u8 bt_open_conn;
260 u8 bt_traffic_load;
261 u8 bt_agg_traffic_load;
262 u8 bt_ci_compliance;
263 u8 reserved[3];
264} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
265
266enum iwl_bt_coex_prio_table_event {
267 BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
268 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1,
269 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2,
270 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3,
271 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4,
272 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5,
273 BT_COEX_PRIO_TBL_EVT_DTIM = 6,
274 BT_COEX_PRIO_TBL_EVT_SCAN52 = 7,
275 BT_COEX_PRIO_TBL_EVT_SCAN24 = 8,
276 BT_COEX_PRIO_TBL_EVT_IDLE = 9,
277 BT_COEX_PRIO_TBL_EVT_MAX = 16,
278}; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */
279
280enum iwl_bt_coex_prio_table_prio {
281 BT_COEX_PRIO_TBL_DISABLED = 0,
282 BT_COEX_PRIO_TBL_PRIO_LOW = 1,
283 BT_COEX_PRIO_TBL_PRIO_HIGH = 2,
284 BT_COEX_PRIO_TBL_PRIO_BYPASS = 3,
285 BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4,
286 BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5,
287 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6,
288 BT_COEX_PRIO_TBL_MAX = 8,
289}; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */
290
291#define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0)
292#define BT_COEX_PRIO_TBL_PRIO_POS (1)
293#define BT_COEX_PRIO_TBL_RESERVED_POS (4)
294
295/**
296 * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex
297 * @prio_tbl:
298 */
299struct iwl_bt_coex_prio_tbl_cmd {
300 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
301} __packed;
302
303enum iwl_bt_coex_env_action {
304 BT_COEX_ENV_CLOSE = 0,
305 BT_COEX_ENV_OPEN = 1,
306}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */
307
308/**
309 * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope
310 * @action: enum %iwl_bt_coex_env_action
311 * @type: enum %iwl_bt_coex_prio_table_event
312 */
313struct iwl_bt_coex_prot_env_cmd {
314 u8 action; /* 0 = closed, 1 = open */
315 u8 type; /* 0 .. 15 */
316 u8 reserved[2];
317} __packed;
318
319#endif /* __fw_api_bt_coex_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index cf6f9a02fb74..51e015d1dfb2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -258,7 +258,7 @@ enum iwl_wowlan_wakeup_reason {
258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), 258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8),
259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), 259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9),
260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), 260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10),
261 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11), 261 /* BIT(11) reserved */
262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), 262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ 263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
264 264
@@ -277,6 +277,55 @@ struct iwl_wowlan_status {
277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */ 277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ 278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
279 279
280#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64
281#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128
282#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048
283
284struct iwl_tcp_packet_info {
285 __le16 tcp_pseudo_header_checksum;
286 __le16 tcp_payload_length;
287} __packed; /* TCP_PACKET_INFO_API_S_VER_2 */
288
289struct iwl_tcp_packet {
290 struct iwl_tcp_packet_info info;
291 u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
292 u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN];
293} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */
294
295struct iwl_remote_wake_packet {
296 struct iwl_tcp_packet_info info;
297 u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
298 u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN];
299} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */
300
301struct iwl_wowlan_remote_wake_config {
302 __le32 connection_max_time; /* unused */
303 /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */
304 u8 max_syn_retries;
305 u8 max_data_retries;
306 u8 tcp_syn_ack_timeout;
307 u8 tcp_ack_timeout;
308
309 struct iwl_tcp_packet syn_tx;
310 struct iwl_tcp_packet synack_rx;
311 struct iwl_tcp_packet keepalive_ack_rx;
312 struct iwl_tcp_packet fin_tx;
313
314 struct iwl_remote_wake_packet keepalive_tx;
315 struct iwl_remote_wake_packet wake_rx;
316
317 /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */
318 u8 sequence_number_offset;
319 u8 sequence_number_length;
320 u8 token_offset;
321 u8 token_length;
322 /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */
323 __le32 initial_sequence_number;
324 __le16 keepalive_interval;
325 __le16 num_tokens;
326 u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS];
327} __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */
328
280/* TODO: NetDetect API */ 329/* TODO: NetDetect API */
281 330
282#endif /* __fw_api_d3_h__ */ 331#endif /* __fw_api_d3_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index ae39b7dfda7b..d68640ea41d4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index be36b7604b7f..81fe45f46be7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -68,73 +68,53 @@
68 68
69/** 69/**
70 * enum iwl_scan_flags - masks for power table command flags 70 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
72 * receiver and transmitter. '0' - does not allow.
71 * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, 73 * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
72 * '1' Driver enables PM (use rest of parameters) 74 * '1' Driver enables PM (use rest of parameters)
73 * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, 75 * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
74 * '1' PM could sleep over DTIM till listen Interval. 76 * '1' PM could sleep over DTIM till listen Interval.
75 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
76 * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
77 * access categories are both delivery and trigger enabled.
78 * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
79 * PBW Snoozing enabled
80 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask 77 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
78 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
81*/ 79*/
82enum iwl_power_flags { 80enum iwl_power_flags {
83 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0), 81 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
84 POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1), 82 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1),
85 POWER_FLAGS_LPRX_ENA_MSK = BIT(2), 83 POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2),
86 POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3), 84 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9),
87 POWER_FLAGS_BT_SCO_ENA = BIT(4), 85 POWER_FLAGS_LPRX_ENA_MSK = BIT(11),
88 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5)
89}; 86};
90 87
88#define IWL_POWER_VEC_SIZE 5
89
91/** 90/**
92 * struct iwl_powertable_cmd - Power Table Command 91 * struct iwl_powertable_cmd - Power Table Command
93 * POWER_TABLE_CMD = 0x77 (command, has simple generic response) 92 * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
94 * 93 *
95 * @id_and_color: MAC contex identifier
96 * @action: Action on context - no action, add new,
97 * modify existent, remove
98 * @flags: Power table command flags from POWER_FLAGS_* 94 * @flags: Power table command flags from POWER_FLAGS_*
99 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. 95 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec.
100 * Minimum allowed:- 3 * DTIM 96 * Minimum allowed:- 3 * DTIM. Keep alive period must be
97 * set regardless of power scheme or current power state.
98 * FW use this value also when PM is disabled.
101 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to 99 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to
102 * PSM transition - legacy PM 100 * PSM transition - legacy PM
103 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to 101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
104 * PSM transition - legacy PM 102 * PSM transition - legacy PM
105 * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to 103 * @sleep_interval: not in use
106 * PSM transition - uAPSD 104 * @keep_alive_beacons: not in use
107 * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
108 * PSM transition - uAPSD
109 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. 105 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
110 * Default: 80dbm 106 * Default: 80dbm
111 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
112 * @snooze_interval: TBD
113 * @snooze_window: TBD
114 * @snooze_step: TBD
115 * @qndp_tid: TBD
116 * @uapsd_ac_flags: TBD
117 * @uapsd_max_sp: TBD
118 */ 107 */
119struct iwl_powertable_cmd { 108struct iwl_powertable_cmd {
120 /* COMMON_INDEX_HDR_API_S_VER_1 */ 109 /* PM_POWER_TABLE_CMD_API_S_VER_5 */
121 __le32 id_and_color;
122 __le32 action;
123 __le16 flags; 110 __le16 flags;
124 u8 reserved; 111 u8 keep_alive_seconds;
125 __le16 keep_alive_seconds; 112 u8 debug_flags;
126 __le32 rx_data_timeout; 113 __le32 rx_data_timeout;
127 __le32 tx_data_timeout; 114 __le32 tx_data_timeout;
128 __le32 rx_data_timeout_uapsd; 115 __le32 sleep_interval[IWL_POWER_VEC_SIZE];
129 __le32 tx_data_timeout_uapsd; 116 __le32 keep_alive_beacons;
130 u8 lprx_rssi_threshold; 117 __le32 lprx_rssi_threshold;
131 u8 num_skip_dtim;
132 __le16 snooze_interval;
133 __le16 snooze_window;
134 u8 snooze_step;
135 u8 qndp_tid;
136 u8 uapsd_ac_flags;
137 u8 uapsd_max_sp;
138} __packed; 118} __packed;
139 119
140#endif 120#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index aa3474d08231..fdd33bc0a594 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 670ac8f95e26..b60d14151721 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 0acb53dda22d..a30691a8a85b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 2677914bf0a6..007a93b25bd7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -537,6 +537,12 @@ struct iwl_mac_beacon_cmd {
537 struct ieee80211_hdr frame[0]; 537 struct ieee80211_hdr frame[0];
538} __packed; 538} __packed;
539 539
540struct iwl_beacon_notif {
541 struct iwl_mvm_tx_resp beacon_notify_hdr;
542 __le64 tsf;
543 __le32 ibss_mgr_status;
544} __packed;
545
540/** 546/**
541 * enum iwl_dump_control - dump (flush) control flags 547 * enum iwl_dump_control - dump (flush) control flags
542 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty 548 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 23eebda848b0..191dcae8ba47 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -70,6 +70,7 @@
70#include "fw-api-mac.h" 70#include "fw-api-mac.h"
71#include "fw-api-power.h" 71#include "fw-api-power.h"
72#include "fw-api-d3.h" 72#include "fw-api-d3.h"
73#include "fw-api-bt-coex.h"
73 74
74/* queue and FIFO numbers by usage */ 75/* queue and FIFO numbers by usage */
75enum { 76enum {
@@ -150,8 +151,10 @@ enum {
150 151
151 SET_CALIB_DEFAULT_CMD = 0x8e, 152 SET_CALIB_DEFAULT_CMD = 0x8e,
152 153
154 BEACON_NOTIFICATION = 0x90,
153 BEACON_TEMPLATE_CMD = 0x91, 155 BEACON_TEMPLATE_CMD = 0x91,
154 TX_ANT_CONFIGURATION_CMD = 0x98, 156 TX_ANT_CONFIGURATION_CMD = 0x98,
157 BT_CONFIG = 0x9b,
155 STATISTICS_NOTIFICATION = 0x9d, 158 STATISTICS_NOTIFICATION = 0x9d,
156 159
157 /* RF-KILL commands and notifications */ 160 /* RF-KILL commands and notifications */
@@ -162,6 +165,11 @@ enum {
162 REPLY_RX_MPDU_CMD = 0xc1, 165 REPLY_RX_MPDU_CMD = 0xc1,
163 BA_NOTIF = 0xc5, 166 BA_NOTIF = 0xc5,
164 167
168 /* BT Coex */
169 BT_COEX_PRIO_TABLE = 0xcc,
170 BT_COEX_PROT_ENV = 0xcd,
171 BT_PROFILE_NOTIFICATION = 0xce,
172
165 REPLY_DEBUG_CMD = 0xf0, 173 REPLY_DEBUG_CMD = 0xf0,
166 DEBUG_LOG_MSG = 0xf7, 174 DEBUG_LOG_MSG = 0xf7,
167 175
@@ -271,38 +279,7 @@ enum {
271 NVM_ACCESS_TARGET_EEPROM = 2, 279 NVM_ACCESS_TARGET_EEPROM = 2,
272}; 280};
273 281
274/** 282/* Section types for NVM_ACCESS_CMD */
275 * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
276 * @op_code: 0 - read, 1 - write.
277 * @target: NVM_ACCESS_TARGET_*. should be 0 for read.
278 * @cache_refresh: 0 - None, 1- NVM.
279 * @offset: offset in the nvm data.
280 * @length: of the chunk.
281 * @data: empty on read, the NVM chunk on write
282 */
283struct iwl_nvm_access_cmd_ver1 {
284 u8 op_code;
285 u8 target;
286 u8 cache_refresh;
287 u8 reserved;
288 __le16 offset;
289 __le16 length;
290 u8 data[];
291} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
292
293/**
294 * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
295 * @offset: the offset in the nvm data
296 * @length: of the chunk
297 * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
298 */
299struct iwl_nvm_access_resp_ver1 {
300 __le16 offset;
301 __le16 length;
302 u8 data[];
303} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
304
305/* Section types for NVM_ACCESS_CMD version 2 */
306enum { 283enum {
307 NVM_SECTION_TYPE_HW = 0, 284 NVM_SECTION_TYPE_HW = 0,
308 NVM_SECTION_TYPE_SW, 285 NVM_SECTION_TYPE_SW,
@@ -323,7 +300,7 @@ enum {
323 * @length: in bytes, to read/write 300 * @length: in bytes, to read/write
324 * @data: if write operation, the data to write. On read its empty 301 * @data: if write operation, the data to write. On read its empty
325 */ 302 */
326struct iwl_nvm_access_cmd_ver2 { 303struct iwl_nvm_access_cmd {
327 u8 op_code; 304 u8 op_code;
328 u8 target; 305 u8 target;
329 __le16 type; 306 __le16 type;
@@ -340,7 +317,7 @@ struct iwl_nvm_access_cmd_ver2 {
340 * @status: 0 for success, fail otherwise 317 * @status: 0 for success, fail otherwise
341 * @data: if read operation, the data returned. Empty on write. 318 * @data: if read operation, the data returned. Empty on write.
342 */ 319 */
343struct iwl_nvm_access_resp_ver2 { 320struct iwl_nvm_access_resp {
344 __le16 offset; 321 __le16 offset;
345 __le16 length; 322 __le16 length;
346 __le16 type; 323 __le16 type;
@@ -503,15 +480,34 @@ enum {
503 TE_DEP_TSF = 2, 480 TE_DEP_TSF = 2,
504 TE_EVENT_SOCIOPATHIC = 4, 481 TE_EVENT_SOCIOPATHIC = 4,
505}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ 482}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */
506 483/*
507/* When to send Time Event notifications and to whom (internal = FW) */ 484 * Supported Time event notifications configuration.
485 * A notification (both event and fragment) includes a status indicating weather
486 * the FW was able to schedule the event or not. For fragment start/end
487 * notification the status is always success. There is no start/end fragment
488 * notification for monolithic events.
489 *
490 * @TE_NOTIF_NONE: no notifications
491 * @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start
492 * @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end
493 * @TE_NOTIF_INTERNAL_EVENT_START: internal FW use
494 * @TE_NOTIF_INTERNAL_EVENT_END: internal FW use.
495 * @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start
496 * @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end
497 * @TE_NOTIF_INTERNAL_FRAG_START: internal FW use.
498 * @TE_NOTIF_INTERNAL_FRAG_END: internal FW use.
499 */
508enum { 500enum {
509 TE_NOTIF_NONE = 0, 501 TE_NOTIF_NONE = 0,
510 TE_NOTIF_HOST_START = 0x1, 502 TE_NOTIF_HOST_EVENT_START = 0x1,
511 TE_NOTIF_HOST_END = 0x2, 503 TE_NOTIF_HOST_EVENT_END = 0x2,
512 TE_NOTIF_INTERNAL_START = 0x4, 504 TE_NOTIF_INTERNAL_EVENT_START = 0x4,
513 TE_NOTIF_INTERNAL_END = 0x8 505 TE_NOTIF_INTERNAL_EVENT_END = 0x8,
514}; /* MAC_EVENT_ACTION_API_E_VER_1 */ 506 TE_NOTIF_HOST_FRAG_START = 0x10,
507 TE_NOTIF_HOST_FRAG_END = 0x20,
508 TE_NOTIF_INTERNAL_FRAG_START = 0x40,
509 TE_NOTIF_INTERNAL_FRAG_END = 0x80
510}; /* MAC_EVENT_ACTION_API_E_VER_2 */
515 511
516/* 512/*
517 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. 513 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed.
@@ -762,18 +758,20 @@ struct iwl_phy_context_cmd {
762#define IWL_RX_INFO_PHY_CNT 8 758#define IWL_RX_INFO_PHY_CNT 8
763#define IWL_RX_INFO_AGC_IDX 1 759#define IWL_RX_INFO_AGC_IDX 1
764#define IWL_RX_INFO_RSSI_AB_IDX 2 760#define IWL_RX_INFO_RSSI_AB_IDX 2
765#define IWL_RX_INFO_RSSI_C_IDX 3 761#define IWL_OFDM_AGC_A_MSK 0x0000007f
766#define IWL_OFDM_AGC_DB_MSK 0xfe00 762#define IWL_OFDM_AGC_A_POS 0
767#define IWL_OFDM_AGC_DB_POS 9 763#define IWL_OFDM_AGC_B_MSK 0x00003f80
764#define IWL_OFDM_AGC_B_POS 7
765#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000
766#define IWL_OFDM_AGC_CODE_POS 20
768#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff 767#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
769#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
770#define IWL_OFDM_RSSI_A_POS 0 768#define IWL_OFDM_RSSI_A_POS 0
769#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
770#define IWL_OFDM_RSSI_ALLBAND_A_POS 8
771#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 771#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
772#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
773#define IWL_OFDM_RSSI_B_POS 16 772#define IWL_OFDM_RSSI_B_POS 16
774#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff 773#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
775#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 774#define IWL_OFDM_RSSI_ALLBAND_B_POS 24
776#define IWL_OFDM_RSSI_C_POS 0
777 775
778/** 776/**
779 * struct iwl_rx_phy_info - phy info 777 * struct iwl_rx_phy_info - phy info
@@ -792,6 +790,7 @@ struct iwl_phy_context_cmd {
792 * @byte_count: frame's byte-count 790 * @byte_count: frame's byte-count
793 * @frame_time: frame's time on the air, based on byte count and frame rate 791 * @frame_time: frame's time on the air, based on byte count and frame rate
794 * calculation 792 * calculation
793 * @mac_active_msk: what MACs were active when the frame was received
795 * 794 *
796 * Before each Rx, the device sends this data. It contains PHY information 795 * Before each Rx, the device sends this data. It contains PHY information
797 * about the reception of the packet. 796 * about the reception of the packet.
@@ -809,7 +808,7 @@ struct iwl_rx_phy_info {
809 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; 808 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];
810 __le32 rate_n_flags; 809 __le32 rate_n_flags;
811 __le32 byte_count; 810 __le32 byte_count;
812 __le16 reserved2; 811 __le16 mac_active_msk;
813 __le16 frame_time; 812 __le16 frame_time;
814} __packed; 813} __packed;
815 814
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index d3d959db03a9..e18c92dd60ec 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -79,17 +79,8 @@
79#define UCODE_VALID_OK cpu_to_le32(0x1) 79#define UCODE_VALID_OK cpu_to_le32(0x1)
80 80
81/* Default calibration values for WkP - set to INIT image w/o running */ 81/* Default calibration values for WkP - set to INIT image w/o running */
82static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
83 0x00, 0x18, 0x00 };
84static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
85 0x7f, 0x7f, 0x7f };
86static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
87static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
88 0x00 };
89static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
90static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; 82static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
91static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; 83static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
92static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
93 84
94struct iwl_calib_default_data { 85struct iwl_calib_default_data {
95 u16 size; 86 u16 size;
@@ -99,12 +90,7 @@ struct iwl_calib_default_data {
99#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} 90#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
100 91
101static const struct iwl_calib_default_data wkp_calib_default_data[12] = { 92static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
102 [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
103 [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
104 [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
105 [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
106 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), 93 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
107 [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
108 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), 94 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
109}; 95};
110 96
@@ -128,7 +114,7 @@ static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
128 .valid = cpu_to_le32(valid_tx_ant), 114 .valid = cpu_to_le32(valid_tx_ant),
129 }; 115 };
130 116
131 IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant); 117 IWL_DEBUG_FW(mvm, "select valid tx ant: %u\n", valid_tx_ant);
132 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, 118 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
133 sizeof(tx_ant_cmd), &tx_ant_cmd); 119 sizeof(tx_ant_cmd), &tx_ant_cmd);
134} 120}
@@ -148,9 +134,10 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
148 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); 134 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
149 135
150 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK; 136 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
151 IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n", 137 IWL_DEBUG_FW(mvm,
138 "Alive ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
152 le16_to_cpu(palive->status), palive->ver_type, 139 le16_to_cpu(palive->status), palive->ver_type,
153 palive->ver_subtype); 140 palive->ver_subtype, palive->flags);
154 141
155 return true; 142 return true;
156} 143}
@@ -241,20 +228,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
241 228
242 return 0; 229 return 0;
243} 230}
244#define IWL_HW_REV_ID_RAINBOW 0x2
245#define IWL_PROJ_TYPE_LHP 0x5
246
247static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
248{
249 struct iwl_nvm_data *data = mvm->nvm_data;
250 /* Temp calls to static definitions, will be changed to CSR calls */
251 u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
252 u8 project_type = IWL_PROJ_TYPE_LHP;
253
254 return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
255 (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
256 (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
257}
258 231
259static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) 232static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
260{ 233{
@@ -262,7 +235,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
262 enum iwl_ucode_type ucode_type = mvm->cur_ucode; 235 enum iwl_ucode_type ucode_type = mvm->cur_ucode;
263 236
264 /* Set parameters */ 237 /* Set parameters */
265 phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); 238 phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
266 phy_cfg_cmd.calib_control.event_trigger = 239 phy_cfg_cmd.calib_control.event_trigger =
267 mvm->fw->default_calib[ucode_type].event_trigger; 240 mvm->fw->default_calib[ucode_type].event_trigger;
268 phy_cfg_cmd.calib_control.flow_trigger = 241 phy_cfg_cmd.calib_control.flow_trigger =
@@ -275,103 +248,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
275 sizeof(phy_cfg_cmd), &phy_cfg_cmd); 248 sizeof(phy_cfg_cmd), &phy_cfg_cmd);
276} 249}
277 250
278/* Starting with the new PHY DB implementation - New calibs are enabled */
279/* Value - 0x405e7 */
280#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\
281 IWL_CALIB_CFG_TEMPERATURE_IDX |\
282 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
283 IWL_CALIB_CFG_DC_IDX |\
284 IWL_CALIB_CFG_BB_FILTER_IDX |\
285 IWL_CALIB_CFG_LO_LEAKAGE_IDX |\
286 IWL_CALIB_CFG_TX_IQ_IDX |\
287 IWL_CALIB_CFG_RX_IQ_IDX |\
288 IWL_CALIB_CFG_AGC_IDX)
289
290#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0
291
292/* Value 0x41567 */
293#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\
294 IWL_CALIB_CFG_TEMPERATURE_IDX |\
295 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
296 IWL_CALIB_CFG_BB_FILTER_IDX |\
297 IWL_CALIB_CFG_DC_IDX |\
298 IWL_CALIB_CFG_TX_IQ_IDX |\
299 IWL_CALIB_CFG_RX_IQ_IDX |\
300 IWL_CALIB_CFG_SENSITIVITY_IDX |\
301 IWL_CALIB_CFG_AGC_IDX)
302
303#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\
304 IWL_CALIB_CFG_TEMPERATURE_IDX |\
305 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
306 IWL_CALIB_CFG_TX_PWR_IDX |\
307 IWL_CALIB_CFG_DC_IDX |\
308 IWL_CALIB_CFG_TX_IQ_IDX |\
309 IWL_CALIB_CFG_SENSITIVITY_IDX)
310
311/*
312 * Sets the calibrations trigger values that will be sent to the FW for runtime
313 * and init calibrations.
314 * The ones given in the FW TLV are not correct.
315 */
316static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
317{
318 struct iwl_tlv_calib_ctrl default_calib;
319
320 /*
321 * WkP FW TLV calib bits are wrong, overwrite them.
322 * This defines the dynamic calibrations which are implemented in the
323 * uCode both for init(flow) calculation and event driven calibs.
324 */
325
326 /* Init Image */
327 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
328 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
329
330 if (default_calib.event_trigger !=
331 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
332 IWL_ERR(mvm,
333 "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
334 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
335 default_calib.event_trigger);
336 if (default_calib.flow_trigger !=
337 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
338 IWL_ERR(mvm,
339 "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
340 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
341 default_calib.flow_trigger);
342
343 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
344 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
345 IWL_ERR(mvm,
346 "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
347 default_calib.event_trigger,
348 default_calib.flow_trigger);
349
350 /* Run time image */
351 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
352 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
353
354 if (default_calib.event_trigger !=
355 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
356 IWL_ERR(mvm,
357 "Updating the event calib for RT image: 0x%x -> 0x%x\n",
358 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
359 default_calib.event_trigger);
360 if (default_calib.flow_trigger !=
361 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
362 IWL_ERR(mvm,
363 "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
364 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
365 default_calib.flow_trigger);
366
367 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
368 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
369 IWL_ERR(mvm,
370 "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
371 default_calib.event_trigger,
372 default_calib.flow_trigger);
373}
374
375static int iwl_set_default_calibrations(struct iwl_mvm *mvm) 251static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
376{ 252{
377 u8 cmd_raw[16]; /* holds the variable size commands */ 253 u8 cmd_raw[16]; /* holds the variable size commands */
@@ -434,6 +310,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
434 goto error; 310 goto error;
435 } 311 }
436 312
313 ret = iwl_send_bt_prio_tbl(mvm);
314 if (ret)
315 goto error;
316
437 if (read_nvm) { 317 if (read_nvm) {
438 /* Read nvm */ 318 /* Read nvm */
439 ret = iwl_nvm_init(mvm); 319 ret = iwl_nvm_init(mvm);
@@ -446,15 +326,15 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
447 WARN_ON(ret); 327 WARN_ON(ret);
448 328
449 /* Override the calibrations from TLV and the const of fw */ 329 /* Send TX valid antennas before triggering calibrations */
450 iwl_set_default_calib_trigger(mvm); 330 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
331 if (ret)
332 goto error;
451 333
452 /* WkP doesn't have all calibrations, need to set default values */ 334 /* need to set default values */
453 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 335 ret = iwl_set_default_calibrations(mvm);
454 ret = iwl_set_default_calibrations(mvm); 336 if (ret)
455 if (ret) 337 goto error;
456 goto error;
457 }
458 338
459 /* 339 /*
460 * Send phy configurations command to init uCode 340 * Send phy configurations command to init uCode
@@ -533,7 +413,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
533 goto error; 413 goto error;
534 } 414 }
535 415
536 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 416 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
417 if (ret)
418 goto error;
419
420 ret = iwl_send_bt_prio_tbl(mvm);
421 if (ret)
422 goto error;
423
424 ret = iwl_send_bt_init_conf(mvm);
537 if (ret) 425 if (ret)
538 goto error; 426 goto error;
539 427
@@ -579,7 +467,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
579 goto error; 467 goto error;
580 } 468 }
581 469
582 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 470 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
583 if (ret) 471 if (ret)
584 goto error; 472 goto error;
585 473
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
index 011906e73a05..2269a9e5cc67 100644
--- a/drivers/net/wireless/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 1d20287b1120..e6eca4d66f6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -196,7 +196,7 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
196 u32 qmask, ac; 196 u32 qmask, ac;
197 197
198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
199 return BIT(IWL_OFFCHANNEL_QUEUE); 199 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
200 200
201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ? 201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
202 BIT(vif->cab_queue) : 0; 202 BIT(vif->cab_queue) : 0;
@@ -553,9 +553,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
553 if (vif->bss_conf.qos) 553 if (vif->bss_conf.qos)
554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
555 555
556 /* Don't use cts to self as the fw doesn't support it currently. */
556 if (vif->bss_conf.use_cts_prot) 557 if (vif->bss_conf.use_cts_prot)
557 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | 558 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
558 MAC_PROT_FLG_SELF_CTS_EN);
559 559
560 /* 560 /*
561 * I think that we should enable these 2 flags regardless the HT PROT 561 * I think that we should enable these 2 flags regardless the HT PROT
@@ -651,6 +651,13 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
651 /* Fill the common data for all mac context types */ 651 /* Fill the common data for all mac context types */
652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
653 653
654 /* Allow beacons to pass through as long as we are not associated,or we
655 * do not have dtim period information */
656 if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period)
657 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON);
658 else
659 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
660
654 /* Fill the data specific for station mode */ 661 /* Fill the data specific for station mode */
655 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); 662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
656 663
@@ -687,7 +694,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
687 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); 694 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
688 695
689 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 696 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
690 /* No other data to be filled */ 697
698 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
699 MAC_FILTER_IN_CONTROL_AND_MGMT |
700 MAC_FILTER_IN_BEACON |
701 MAC_FILTER_IN_PROBE_REQUEST);
702
691 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 703 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
692} 704}
693 705
@@ -716,7 +728,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
716 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 728 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
717 729
718 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 730 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
719 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); 731
732 /* Override the filter flags to accept only probe requests */
733 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
720 734
721 /* 735 /*
722 * This flag should be set to true when the P2P Device is 736 * This flag should be set to true when the P2P Device is
@@ -791,7 +805,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
791 TX_CMD_FLG_TSF); 805 TX_CMD_FLG_TSF);
792 806
793 mvm->mgmt_last_antenna_idx = 807 mvm->mgmt_last_antenna_idx =
794 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 808 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
795 mvm->mgmt_last_antenna_idx); 809 mvm->mgmt_last_antenna_idx);
796 810
797 beacon_cmd.tx.rate_n_flags = 811 beacon_cmd.tx.rate_n_flags =
@@ -848,10 +862,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
848 */ 862 */
849static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, 863static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
850 struct ieee80211_vif *vif, 864 struct ieee80211_vif *vif,
851 struct iwl_mac_data_ap *ctxt_ap) 865 struct iwl_mac_data_ap *ctxt_ap,
866 bool add)
852{ 867{
853 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 868 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
854 u32 curr_dev_time;
855 869
856 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); 870 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
857 ctxt_ap->bi_reciprocal = 871 ctxt_ap->bi_reciprocal =
@@ -863,10 +877,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
863 vif->bss_conf.dtim_period)); 877 vif->bss_conf.dtim_period));
864 878
865 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); 879 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
866 curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
867 ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);
868 880
869 ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); 881 /*
882 * Only read the system time when the MAC is being added, when we
883 * just modify the MAC then we should keep the time -- the firmware
884 * can otherwise have a "jumping" TBTT.
885 */
886 if (add)
887 mvmvif->ap_beacon_time =
888 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
889
890 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
891
892 ctxt_ap->beacon_tsf = 0; /* unused */
870 893
871 /* TODO: Assume that the beacon id == mac context id */ 894 /* TODO: Assume that the beacon id == mac context id */
872 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); 895 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);
@@ -883,8 +906,12 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
883 /* Fill the common data for all mac context types */ 906 /* Fill the common data for all mac context types */
884 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 907 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
885 908
909 /* Also enable probe requests to pass */
910 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
911
886 /* Fill the data specific for ap mode */ 912 /* Fill the data specific for ap mode */
887 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); 913 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap,
914 action == FW_CTXT_ACTION_ADD);
888 915
889 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 916 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
890} 917}
@@ -902,7 +929,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
902 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 929 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
903 930
904 /* Fill the data specific for GO mode */ 931 /* Fill the data specific for GO mode */
905 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); 932 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
933 action == FW_CTXT_ACTION_ADD);
906 934
907 cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow & 935 cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow &
908 IEEE80211_P2P_OPPPS_CTWINDOW_MASK); 936 IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
@@ -996,3 +1024,22 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
996 mvmvif->uploaded = false; 1024 mvmvif->uploaded = false;
997 return 0; 1025 return 0;
998} 1026}
1027
1028int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1029 struct iwl_rx_cmd_buffer *rxb,
1030 struct iwl_device_cmd *cmd)
1031{
1032 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1033 struct iwl_beacon_notif *beacon = (void *)pkt->data;
1034 u16 status __maybe_unused =
1035 le16_to_cpu(beacon->beacon_notify_hdr.status.status);
1036 u32 rate __maybe_unused =
1037 le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
1038
1039 IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
1040 status & TX_STATUS_MSK,
1041 beacon->beacon_notify_hdr.failure_frame,
1042 le64_to_cpu(beacon->tsf),
1043 rate);
1044 return 0;
1045}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 23460f4a4c75..fe031608fd91 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -65,7 +65,9 @@
65#include <linux/skbuff.h> 65#include <linux/skbuff.h>
66#include <linux/netdevice.h> 66#include <linux/netdevice.h>
67#include <linux/etherdevice.h> 67#include <linux/etherdevice.h>
68#include <linux/ip.h>
68#include <net/mac80211.h> 69#include <net/mac80211.h>
70#include <net/tcp.h>
69 71
70#include "iwl-op-mode.h" 72#include "iwl-op-mode.h"
71#include "iwl-io.h" 73#include "iwl-io.h"
@@ -102,10 +104,33 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
102 }, 104 },
103}; 105};
104 106
107#ifdef CONFIG_PM_SLEEP
108static const struct nl80211_wowlan_tcp_data_token_feature
109iwl_mvm_wowlan_tcp_token_feature = {
110 .min_len = 0,
111 .max_len = 255,
112 .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
113};
114
115static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
116 .tok = &iwl_mvm_wowlan_tcp_token_feature,
117 .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
118 sizeof(struct ethhdr) -
119 sizeof(struct iphdr) -
120 sizeof(struct tcphdr),
121 .data_interval_max = 65535, /* __le16 in API */
122 .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
123 sizeof(struct ethhdr) -
124 sizeof(struct iphdr) -
125 sizeof(struct tcphdr),
126 .seq = true,
127};
128#endif
129
105int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 130int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
106{ 131{
107 struct ieee80211_hw *hw = mvm->hw; 132 struct ieee80211_hw *hw = mvm->hw;
108 int num_mac, ret; 133 int num_mac, ret, i;
109 134
110 /* Tell mac80211 our characteristics */ 135 /* Tell mac80211 our characteristics */
111 hw->flags = IEEE80211_HW_SIGNAL_DBM | 136 hw->flags = IEEE80211_HW_SIGNAL_DBM |
@@ -118,8 +143,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
118 IEEE80211_HW_AMPDU_AGGREGATION | 143 IEEE80211_HW_AMPDU_AGGREGATION |
119 IEEE80211_HW_TIMING_BEACON_ONLY; 144 IEEE80211_HW_TIMING_BEACON_ONLY;
120 145
121 hw->queues = IWL_FIRST_AMPDU_QUEUE; 146 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
122 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE; 147 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
123 hw->rate_control_algorithm = "iwl-mvm-rs"; 148 hw->rate_control_algorithm = "iwl-mvm-rs";
124 149
125 /* 150 /*
@@ -149,18 +174,22 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
149 hw->wiphy->n_iface_combinations = 174 hw->wiphy->n_iface_combinations =
150 ARRAY_SIZE(iwl_mvm_iface_combinations); 175 ARRAY_SIZE(iwl_mvm_iface_combinations);
151 176
152 hw->wiphy->max_remain_on_channel_duration = 500; 177 hw->wiphy->max_remain_on_channel_duration = 10000;
153 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 178 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
154 179
155 /* Extract MAC address */ 180 /* Extract MAC address */
156 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 181 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
157 hw->wiphy->addresses = mvm->addresses; 182 hw->wiphy->addresses = mvm->addresses;
158 hw->wiphy->n_addresses = 1; 183 hw->wiphy->n_addresses = 1;
159 num_mac = mvm->nvm_data->n_hw_addrs; 184
160 if (num_mac > 1) { 185 /* Extract additional MAC addresses if available */
161 memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, 186 num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
187 min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
188
189 for (i = 1; i < num_mac; i++) {
190 memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
162 ETH_ALEN); 191 ETH_ALEN);
163 mvm->addresses[1].addr[5]++; 192 mvm->addresses[i].addr[5]++;
164 hw->wiphy->n_addresses++; 193 hw->wiphy->n_addresses++;
165 } 194 }
166 195
@@ -206,6 +235,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
206 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 235 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
207 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 236 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
208 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 237 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
238 hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
209 } 239 }
210#endif 240#endif
211 241
@@ -227,7 +257,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
227 goto drop; 257 goto drop;
228 } 258 }
229 259
230 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE && 260 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
231 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) 261 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
232 goto drop; 262 goto drop;
233 263
@@ -273,12 +303,18 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
273 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); 303 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
274 break; 304 break;
275 case IEEE80211_AMPDU_TX_START: 305 case IEEE80211_AMPDU_TX_START:
306 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) {
307 ret = -EINVAL;
308 break;
309 }
276 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); 310 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
277 break; 311 break;
278 case IEEE80211_AMPDU_TX_STOP_CONT: 312 case IEEE80211_AMPDU_TX_STOP_CONT:
313 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
314 break;
279 case IEEE80211_AMPDU_TX_STOP_FLUSH: 315 case IEEE80211_AMPDU_TX_STOP_FLUSH:
280 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 316 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
281 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); 317 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
282 break; 318 break;
283 case IEEE80211_AMPDU_TX_OPERATIONAL: 319 case IEEE80211_AMPDU_TX_OPERATIONAL:
284 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); 320 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
@@ -466,11 +502,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
466 /* 502 /*
467 * TODO: remove this temporary code. 503 * TODO: remove this temporary code.
468 * Currently MVM FW supports power management only on single MAC. 504 * Currently MVM FW supports power management only on single MAC.
469 * Iterate and disable PM on all active interfaces. 505 * If new interface added, disable PM on existing interface.
506 * P2P device is a special case, since it is handled by FW similary to
507 * scan. If P2P deviced is added, PM remains enabled on existing
508 * interface.
470 * Note: the method below does not count the new interface being added 509 * Note: the method below does not count the new interface being added
471 * at this moment. 510 * at this moment.
472 */ 511 */
473 mvm->vif_count++; 512 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
513 mvm->vif_count++;
474 if (mvm->vif_count > 1) { 514 if (mvm->vif_count > 1) {
475 IWL_DEBUG_MAC80211(mvm, 515 IWL_DEBUG_MAC80211(mvm,
476 "Disable power on existing interfaces\n"); 516 "Disable power on existing interfaces\n");
@@ -526,6 +566,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
526 mvm->p2p_device_vif = vif; 566 mvm->p2p_device_vif = vif;
527 } 567 }
528 568
569 iwl_mvm_vif_dbgfs_register(mvm, vif);
529 goto out_unlock; 570 goto out_unlock;
530 571
531 out_unbind: 572 out_unbind:
@@ -539,10 +580,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
539 /* 580 /*
540 * TODO: remove this temporary code. 581 * TODO: remove this temporary code.
541 * Currently MVM FW supports power management only on single MAC. 582 * Currently MVM FW supports power management only on single MAC.
542 * Check if only one additional interface remains after rereasing 583 * Check if only one additional interface remains after releasing
543 * current one. Update power mode on the remaining interface. 584 * current one. Update power mode on the remaining interface.
544 */ 585 */
545 mvm->vif_count--; 586 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
587 mvm->vif_count--;
546 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 588 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
547 mvm->vif_count); 589 mvm->vif_count);
548 if (mvm->vif_count == 1) { 590 if (mvm->vif_count == 1) {
@@ -557,11 +599,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
557 return ret; 599 return ret;
558} 600}
559 601
560static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, 602static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
561 struct ieee80211_vif *vif) 603 struct ieee80211_vif *vif)
562{ 604{
563 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
564 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
565 u32 tfd_msk = 0, ac; 605 u32 tfd_msk = 0, ac;
566 606
567 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 607 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -594,12 +634,23 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
594 */ 634 */
595 flush_work(&mvm->sta_drained_wk); 635 flush_work(&mvm->sta_drained_wk);
596 } 636 }
637}
638
639static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
640 struct ieee80211_vif *vif)
641{
642 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
643 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
644
645 iwl_mvm_prepare_mac_removal(mvm, vif);
597 646
598 mutex_lock(&mvm->mutex); 647 mutex_lock(&mvm->mutex);
599 648
649 iwl_mvm_vif_dbgfs_clean(mvm, vif);
650
600 /* 651 /*
601 * For AP/GO interface, the tear down of the resources allocated to the 652 * For AP/GO interface, the tear down of the resources allocated to the
602 * interface should be handled as part of the bss_info_changed flow. 653 * interface is be handled as part of the stop_ap flow.
603 */ 654 */
604 if (vif->type == NL80211_IFTYPE_AP) { 655 if (vif->type == NL80211_IFTYPE_AP) {
605 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); 656 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
@@ -620,7 +671,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
620 * Check if only one additional interface remains after removing 671 * Check if only one additional interface remains after removing
621 * current one. Update power mode on the remaining interface. 672 * current one. Update power mode on the remaining interface.
622 */ 673 */
623 if (mvm->vif_count) 674 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
624 mvm->vif_count--; 675 mvm->vif_count--;
625 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 676 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
626 mvm->vif_count); 677 mvm->vif_count);
@@ -670,6 +721,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
670 IWL_ERR(mvm, "failed to update quotas\n"); 721 IWL_ERR(mvm, "failed to update quotas\n");
671 return; 722 return;
672 } 723 }
724 iwl_mvm_bt_coex_vif_assoc(mvm, vif);
673 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 725 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
674 /* remove AP station now that the MAC is unassoc */ 726 /* remove AP station now that the MAC is unassoc */
675 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 727 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -763,6 +815,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
763 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 815 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
764 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 816 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
765 817
818 iwl_mvm_prepare_mac_removal(mvm, vif);
819
766 mutex_lock(&mvm->mutex); 820 mutex_lock(&mvm->mutex);
767 821
768 mvmvif->ap_active = false; 822 mvmvif->ap_active = false;
@@ -886,7 +940,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
886 */ 940 */
887 break; 941 break;
888 case STA_NOTIFY_AWAKE: 942 case STA_NOTIFY_AWAKE:
889 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION)) 943 if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
890 break; 944 break;
891 iwl_mvm_sta_modify_ps_wake(mvm, sta); 945 iwl_mvm_sta_modify_ps_wake(mvm, sta);
892 break; 946 break;
@@ -1042,6 +1096,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1042 1096
1043 switch (cmd) { 1097 switch (cmd) {
1044 case SET_KEY: 1098 case SET_KEY:
1099 if (vif->type == NL80211_IFTYPE_AP && !sta) {
1100 /* GTK on AP interface is a TX-only key, return 0 */
1101 ret = 0;
1102 key->hw_key_idx = STA_KEY_IDX_INVALID;
1103 break;
1104 }
1105
1045 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n"); 1106 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1046 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false); 1107 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1047 if (ret) { 1108 if (ret) {
@@ -1050,11 +1111,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1050 * can't add key for RX, but we don't need it 1111 * can't add key for RX, but we don't need it
1051 * in the device for TX so still return 0 1112 * in the device for TX so still return 0
1052 */ 1113 */
1114 key->hw_key_idx = STA_KEY_IDX_INVALID;
1053 ret = 0; 1115 ret = 0;
1054 } 1116 }
1055 1117
1056 break; 1118 break;
1057 case DISABLE_KEY: 1119 case DISABLE_KEY:
1120 if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
1121 ret = 0;
1122 break;
1123 }
1124
1058 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n"); 1125 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1059 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key); 1126 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1060 break; 1127 break;
@@ -1103,7 +1170,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1103 &chandef, 1, 1); 1170 &chandef, 1, 1);
1104 1171
1105 /* Schedule the time events */ 1172 /* Schedule the time events */
1106 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration); 1173 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1107 1174
1108 mutex_unlock(&mvm->mutex); 1175 mutex_unlock(&mvm->mutex);
1109 IWL_DEBUG_MAC80211(mvm, "leave\n"); 1176 IWL_DEBUG_MAC80211(mvm, "leave\n");
@@ -1207,6 +1274,7 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1207 * will handle quota settings. 1274 * will handle quota settings.
1208 */ 1275 */
1209 if (vif->type == NL80211_IFTYPE_MONITOR) { 1276 if (vif->type == NL80211_IFTYPE_MONITOR) {
1277 mvmvif->monitor_active = true;
1210 ret = iwl_mvm_update_quotas(mvm, vif); 1278 ret = iwl_mvm_update_quotas(mvm, vif);
1211 if (ret) 1279 if (ret)
1212 goto out_remove_binding; 1280 goto out_remove_binding;
@@ -1237,15 +1305,16 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1237 if (vif->type == NL80211_IFTYPE_AP) 1305 if (vif->type == NL80211_IFTYPE_AP)
1238 goto out_unlock; 1306 goto out_unlock;
1239 1307
1240 iwl_mvm_binding_remove_vif(mvm, vif);
1241 switch (vif->type) { 1308 switch (vif->type) {
1242 case NL80211_IFTYPE_MONITOR: 1309 case NL80211_IFTYPE_MONITOR:
1243 iwl_mvm_update_quotas(mvm, vif); 1310 mvmvif->monitor_active = false;
1311 iwl_mvm_update_quotas(mvm, NULL);
1244 break; 1312 break;
1245 default: 1313 default:
1246 break; 1314 break;
1247 } 1315 }
1248 1316
1317 iwl_mvm_binding_remove_vif(mvm, vif);
1249out_unlock: 1318out_unlock:
1250 mvmvif->phy_ctxt = NULL; 1319 mvmvif->phy_ctxt = NULL;
1251 mutex_unlock(&mvm->mutex); 1320 mutex_unlock(&mvm->mutex);
@@ -1266,6 +1335,15 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1266 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); 1335 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1267} 1336}
1268 1337
1338static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw,
1339 struct ieee80211_vif *vif,
1340 enum ieee80211_rssi_event rssi_event)
1341{
1342 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1343
1344 iwl_mvm_bt_rssi_event(mvm, vif, rssi_event);
1345}
1346
1269struct ieee80211_ops iwl_mvm_hw_ops = { 1347struct ieee80211_ops iwl_mvm_hw_ops = {
1270 .tx = iwl_mvm_mac_tx, 1348 .tx = iwl_mvm_mac_tx,
1271 .ampdu_action = iwl_mvm_mac_ampdu_action, 1349 .ampdu_action = iwl_mvm_mac_ampdu_action,
@@ -1289,6 +1367,7 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
1289 .update_tkip_key = iwl_mvm_mac_update_tkip_key, 1367 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1290 .remain_on_channel = iwl_mvm_roc, 1368 .remain_on_channel = iwl_mvm_roc,
1291 .cancel_remain_on_channel = iwl_mvm_cancel_roc, 1369 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1370 .rssi_callback = iwl_mvm_mac_rssi_callback,
1292 1371
1293 .add_chanctx = iwl_mvm_add_chanctx, 1372 .add_chanctx = iwl_mvm_add_chanctx,
1294 .remove_chanctx = iwl_mvm_remove_chanctx, 1373 .remove_chanctx = iwl_mvm_remove_chanctx,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4e339ccfa800..8269bc562951 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -79,8 +79,9 @@
79#include "fw-api.h" 79#include "fw-api.h"
80 80
81#define IWL_INVALID_MAC80211_QUEUE 0xff 81#define IWL_INVALID_MAC80211_QUEUE 0xff
82#define IWL_MVM_MAX_ADDRESSES 2 82#define IWL_MVM_MAX_ADDRESSES 5
83#define IWL_RSSI_OFFSET 44 83/* RSSI offset for WkP */
84#define IWL_RSSI_OFFSET 50
84 85
85enum iwl_mvm_tx_fifo { 86enum iwl_mvm_tx_fifo {
86 IWL_MVM_TX_FIFO_BK = 0, 87 IWL_MVM_TX_FIFO_BK = 0,
@@ -89,10 +90,6 @@ enum iwl_mvm_tx_fifo {
89 IWL_MVM_TX_FIFO_VO, 90 IWL_MVM_TX_FIFO_VO,
90}; 91};
91 92
92/* Placeholder */
93#define IWL_OFFCHANNEL_QUEUE 8
94#define IWL_FIRST_AMPDU_QUEUE 11
95
96extern struct ieee80211_ops iwl_mvm_hw_ops; 93extern struct ieee80211_ops iwl_mvm_hw_ops;
97/** 94/**
98 * struct iwl_mvm_mod_params - module parameters for iwlmvm 95 * struct iwl_mvm_mod_params - module parameters for iwlmvm
@@ -160,6 +157,8 @@ enum iwl_power_scheme {
160 * @uploaded: indicates the MAC context has been added to the device 157 * @uploaded: indicates the MAC context has been added to the device
161 * @ap_active: indicates that ap context is configured, and that the interface 158 * @ap_active: indicates that ap context is configured, and that the interface
162 * should get quota etc. 159 * should get quota etc.
160 * @monitor_active: indicates that monitor context is configured, and that the
161 * interface should get quota etc.
163 * @queue_params: QoS params for this MAC 162 * @queue_params: QoS params for this MAC
164 * @bcast_sta: station used for broadcast packets. Used by the following 163 * @bcast_sta: station used for broadcast packets. Used by the following
165 * vifs: P2P_DEVICE, GO and AP. 164 * vifs: P2P_DEVICE, GO and AP.
@@ -172,6 +171,9 @@ struct iwl_mvm_vif {
172 171
173 bool uploaded; 172 bool uploaded;
174 bool ap_active; 173 bool ap_active;
174 bool monitor_active;
175
176 u32 ap_beacon_time;
175 177
176 enum iwl_tsf_id tsf_id; 178 enum iwl_tsf_id tsf_id;
177 179
@@ -210,6 +212,7 @@ struct iwl_mvm_vif {
210 212
211#ifdef CONFIG_IWLWIFI_DEBUGFS 213#ifdef CONFIG_IWLWIFI_DEBUGFS
212 struct dentry *dbgfs_dir; 214 struct dentry *dbgfs_dir;
215 struct dentry *dbgfs_slink;
213 void *dbgfs_data; 216 void *dbgfs_data;
214#endif 217#endif
215}; 218};
@@ -278,10 +281,7 @@ struct iwl_mvm {
278 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; 281 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
279 282
280 struct iwl_nvm_data *nvm_data; 283 struct iwl_nvm_data *nvm_data;
281 /* eeprom blob for debugfs/testmode */ 284 /* NVM sections */
282 u8 *eeprom_blob;
283 size_t eeprom_blob_size;
284 /* NVM sections for 7000 family */
285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS]; 285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
286 286
287 /* EEPROM MAC addresses */ 287 /* EEPROM MAC addresses */
@@ -322,11 +322,26 @@ struct iwl_mvm {
322 * can hold 16 keys at most. Reflect this fact. 322 * can hold 16 keys at most. Reflect this fact.
323 */ 323 */
324 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; 324 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
325
326 /*
327 * This counter of created interfaces is referenced only in conjunction
328 * with FW limitation related to power management. Currently PM is
329 * supported only on a single interface.
330 * IMPORTANT: this variable counts all interfaces except P2P device.
331 */
325 u8 vif_count; 332 u8 vif_count;
326 333
327 struct led_classdev led; 334 struct led_classdev led;
328 335
329 struct ieee80211_vif *p2p_device_vif; 336 struct ieee80211_vif *p2p_device_vif;
337
338#ifdef CONFIG_PM_SLEEP
339 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
340#endif
341
342 /* BT-Coex */
343 u8 bt_kill_msk;
344 struct iwl_bt_coex_profile_notif last_bt_notif;
330}; 345};
331 346
332/* Extract MVM priv from op_mode and _hw */ 347/* Extract MVM priv from op_mode and _hw */
@@ -440,6 +455,9 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
440 struct ieee80211_vif *vif); 455 struct ieee80211_vif *vif);
441int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, 456int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
442 struct ieee80211_vif *vif); 457 struct ieee80211_vif *vif);
458int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
459 struct iwl_rx_cmd_buffer *rxb,
460 struct iwl_device_cmd *cmd);
443 461
444/* Bindings */ 462/* Bindings */
445int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 463int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -461,16 +479,22 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
461/* MVM debugfs */ 479/* MVM debugfs */
462#ifdef CONFIG_IWLWIFI_DEBUGFS 480#ifdef CONFIG_IWLWIFI_DEBUGFS
463int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); 481int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
464int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 482void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
465 struct dentry *dbgfs_dir); 483void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
466void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
467 struct iwl_powertable_cmd *cmd);
468#else 484#else
469static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, 485static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm,
470 struct dentry *dbgfs_dir) 486 struct dentry *dbgfs_dir)
471{ 487{
472 return 0; 488 return 0;
473} 489}
490static inline void
491iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
492{
493}
494static inline void
495iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
496{
497}
474#endif /* CONFIG_IWLWIFI_DEBUGFS */ 498#endif /* CONFIG_IWLWIFI_DEBUGFS */
475 499
476/* rate scaling */ 500/* rate scaling */
@@ -480,6 +504,8 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
480/* power managment */ 504/* power managment */
481int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 505int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
482int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 506int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
507void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
508 struct iwl_powertable_cmd *cmd);
483 509
484int iwl_mvm_leds_init(struct iwl_mvm *mvm); 510int iwl_mvm_leds_init(struct iwl_mvm *mvm);
485void iwl_mvm_leds_exit(struct iwl_mvm *mvm); 511void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
@@ -497,4 +523,14 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
497void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, 523void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
498 struct ieee80211_vif *vif, int idx); 524 struct ieee80211_vif *vif, int idx);
499 525
526/* BT Coex */
527int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
528int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
529int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
530 struct iwl_rx_cmd_buffer *rxb,
531 struct iwl_device_cmd *cmd);
532void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
533 enum ieee80211_rssi_event rssi_event);
534void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
535
500#endif /* __IWL_MVM_H__ */ 536#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 20016bcbdeab..b8ec02f89acc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -74,26 +74,11 @@ static const int nvm_to_read[] = {
74 NVM_SECTION_TYPE_PRODUCTION, 74 NVM_SECTION_TYPE_PRODUCTION,
75}; 75};
76 76
77/* used to simplify the shared operations on NCM_ACCESS_CMD versions */ 77/* Default NVM size to read */
78union iwl_nvm_access_cmd { 78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
79 struct iwl_nvm_access_cmd_ver1 ver1;
80 struct iwl_nvm_access_cmd_ver2 ver2;
81};
82union iwl_nvm_access_resp {
83 struct iwl_nvm_access_resp_ver1 ver1;
84 struct iwl_nvm_access_resp_ver2 ver2;
85};
86
87static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
88 u16 offset, u16 length)
89{
90 cmd->offset = cpu_to_le16(offset);
91 cmd->length = cpu_to_le16(length);
92 cmd->cache_refresh = 1;
93}
94 79
95static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd, 80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd,
96 u16 offset, u16 length, u16 section) 81 u16 offset, u16 length, u16 section)
97{ 82{
98 cmd->offset = cpu_to_le16(offset); 83 cmd->offset = cpu_to_le16(offset);
99 cmd->length = cpu_to_le16(length); 84 cmd->length = cpu_to_le16(length);
@@ -103,8 +88,8 @@ static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
103static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
104 u16 offset, u16 length, u8 *data) 89 u16 offset, u16 length, u8 *data)
105{ 90{
106 union iwl_nvm_access_cmd nvm_access_cmd; 91 struct iwl_nvm_access_cmd nvm_access_cmd = {};
107 union iwl_nvm_access_resp *nvm_resp; 92 struct iwl_nvm_access_resp *nvm_resp;
108 struct iwl_rx_packet *pkt; 93 struct iwl_rx_packet *pkt;
109 struct iwl_host_cmd cmd = { 94 struct iwl_host_cmd cmd = {
110 .id = NVM_ACCESS_CMD, 95 .id = NVM_ACCESS_CMD,
@@ -114,18 +99,8 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
114 int ret, bytes_read, offset_read; 99 int ret, bytes_read, offset_read;
115 u8 *resp_data; 100 u8 *resp_data;
116 101
117 memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd)); 102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
118 103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
119 /* TODO: not sure family should be the decider, maybe FW version? */
120 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
121 iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
122 offset, length, section);
123 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
124 } else {
125 iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
126 offset, length);
127 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
128 }
129 104
130 ret = iwl_mvm_send_cmd(mvm, &cmd); 105 ret = iwl_mvm_send_cmd(mvm, &cmd);
131 if (ret) 106 if (ret)
@@ -141,17 +116,10 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
141 116
142 /* Extract NVM response */ 117 /* Extract NVM response */
143 nvm_resp = (void *)pkt->data; 118 nvm_resp = (void *)pkt->data;
144 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 119 ret = le16_to_cpu(nvm_resp->status);
145 ret = le16_to_cpu(nvm_resp->ver2.status); 120 bytes_read = le16_to_cpu(nvm_resp->length);
146 bytes_read = le16_to_cpu(nvm_resp->ver2.length); 121 offset_read = le16_to_cpu(nvm_resp->offset);
147 offset_read = le16_to_cpu(nvm_resp->ver2.offset); 122 resp_data = nvm_resp->data;
148 resp_data = nvm_resp->ver2.data;
149 } else {
150 ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
151 bytes_read = le16_to_cpu(nvm_resp->ver1.length);
152 offset_read = le16_to_cpu(nvm_resp->ver1.offset);
153 resp_data = nvm_resp->ver1.data;
154 }
155 if (ret) { 123 if (ret) {
156 IWL_ERR(mvm, 124 IWL_ERR(mvm,
157 "NVM access command failed with status %d (device: %s)\n", 125 "NVM access command failed with status %d (device: %s)\n",
@@ -191,17 +159,10 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
191{ 159{
192 u16 length, offset = 0; 160 u16 length, offset = 0;
193 int ret; 161 int ret;
194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
195 162
196 length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) 163 /* Set nvm section read length */
197 - sizeof(union iwl_nvm_access_cmd) 164 length = IWL_NVM_DEFAULT_CHUNK_SIZE;
198 - sizeof(struct iwl_rx_packet); 165
199 /*
200 * if length is greater than EEPROM size, truncate it because uCode
201 * doesn't check it by itself, and exit the loop when reached.
202 */
203 if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
204 length = mvm->cfg->base_params->eeprom_size;
205 ret = length; 166 ret = length;
206 167
207 /* Read the NVM until exhausted (reading less than requested) */ 168 /* Read the NVM until exhausted (reading less than requested) */
@@ -214,8 +175,6 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
214 return ret; 175 return ret;
215 } 176 }
216 offset += ret; 177 offset += ret;
217 if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
218 break;
219 } 178 }
220 179
221 IWL_INFO(mvm, "NVM section %d read completed\n", section); 180 IWL_INFO(mvm, "NVM section %d read completed\n", section);
@@ -249,63 +208,31 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
249 int ret, i, section; 208 int ret, i, section;
250 u8 *nvm_buffer, *temp; 209 u8 *nvm_buffer, *temp;
251 210
252 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 211 /* TODO: find correct NVM max size for a section */
253 /* TODO: find correct NVM max size for a section */ 212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
254 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 213 GFP_KERNEL);
255 GFP_KERNEL); 214 if (!nvm_buffer)
256 if (!nvm_buffer) 215 return -ENOMEM;
257 return -ENOMEM; 216 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
258 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 217 section = nvm_to_read[i];
259 section = nvm_to_read[i]; 218 /* we override the constness for initial read */
260 /* we override the constness for initial read */ 219 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
261 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
262 if (ret < 0)
263 break;
264 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
265 if (!temp) {
266 ret = -ENOMEM;
267 break;
268 }
269 mvm->nvm_sections[section].data = temp;
270 mvm->nvm_sections[section].length = ret;
271 }
272 kfree(nvm_buffer);
273 if (ret < 0) 220 if (ret < 0)
274 return ret; 221 break;
275 } else { 222 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
276 /* allocate eeprom */ 223 if (!temp) {
277 mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size; 224 ret = -ENOMEM;
278 IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n", 225 break;
279 mvm->eeprom_blob_size);
280 mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
281 if (!mvm->eeprom_blob)
282 return -ENOMEM;
283
284 ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
285 if (ret != mvm->eeprom_blob_size) {
286 IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
287 ret, mvm->eeprom_blob_size);
288 kfree(mvm->eeprom_blob);
289 mvm->eeprom_blob = NULL;
290 return -EINVAL;
291 } 226 }
227 mvm->nvm_sections[section].data = temp;
228 mvm->nvm_sections[section].length = ret;
292 } 229 }
230 kfree(nvm_buffer);
231 if (ret < 0)
232 return ret;
293 233
294 ret = 0; 234 ret = 0;
295 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) 235 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
296 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
297 else
298 mvm->nvm_data =
299 iwl_parse_eeprom_data(mvm->trans->dev,
300 mvm->cfg,
301 mvm->eeprom_blob,
302 mvm->eeprom_blob_size);
303
304 if (!mvm->nvm_data) {
305 kfree(mvm->eeprom_blob);
306 mvm->eeprom_blob = NULL;
307 ret = -ENOMEM;
308 }
309 236
310 return ret; 237 return ret;
311} 238}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index aa59adf87db3..fe031d304d1e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -143,21 +143,12 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; 143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
144 u32 reg_val = 0; 144 u32 reg_val = 0;
145 145
146 /* 146 radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >>
147 * We can't upload the correct value to the INIT image 147 FW_PHY_CFG_RADIO_TYPE_POS;
148 * as we don't have nvm_data by that time. 148 radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >>
149 * 149 FW_PHY_CFG_RADIO_STEP_POS;
150 * TODO: Figure out what we should do here 150 radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >>
151 */ 151 FW_PHY_CFG_RADIO_DASH_POS;
152 if (mvm->nvm_data) {
153 radio_cfg_type = mvm->nvm_data->radio_cfg_type;
154 radio_cfg_step = mvm->nvm_data->radio_cfg_step;
155 radio_cfg_dash = mvm->nvm_data->radio_cfg_dash;
156 } else {
157 radio_cfg_type = 0;
158 radio_cfg_step = 0;
159 radio_cfg_dash = 0;
160 }
161 152
162 /* SKU control */ 153 /* SKU control */
163 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << 154 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
@@ -175,7 +166,6 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
175 166
176 /* silicon bits */ 167 /* silicon bits */
177 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; 168 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
178 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
179 169
180 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG, 170 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
181 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | 171 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
@@ -230,6 +220,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 220 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 221 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232 222
223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
225
233 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 226 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
234 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 227 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
235 228
@@ -274,6 +267,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
274 CMD(WEP_KEY), 267 CMD(WEP_KEY),
275 CMD(REPLY_RX_PHY_CMD), 268 CMD(REPLY_RX_PHY_CMD),
276 CMD(REPLY_RX_MPDU_CMD), 269 CMD(REPLY_RX_MPDU_CMD),
270 CMD(BEACON_NOTIFICATION),
277 CMD(BEACON_TEMPLATE_CMD), 271 CMD(BEACON_TEMPLATE_CMD),
278 CMD(STATISTICS_NOTIFICATION), 272 CMD(STATISTICS_NOTIFICATION),
279 CMD(TX_ANT_CONFIGURATION_CMD), 273 CMD(TX_ANT_CONFIGURATION_CMD),
@@ -293,6 +287,11 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
293 CMD(NET_DETECT_PROFILES_CMD), 287 CMD(NET_DETECT_PROFILES_CMD),
294 CMD(NET_DETECT_HOTSPOTS_CMD), 288 CMD(NET_DETECT_HOTSPOTS_CMD),
295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 289 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
290 CMD(CARD_STATE_NOTIFICATION),
291 CMD(BT_COEX_PRIO_TABLE),
292 CMD(BT_COEX_PROT_ENV),
293 CMD(BT_PROFILE_NOTIFICATION),
294 CMD(BT_CONFIG),
296}; 295};
297#undef CMD 296#undef CMD
298 297
@@ -312,16 +311,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
312 }; 311 };
313 int err, scan_size; 312 int err, scan_size;
314 313
315 switch (cfg->device_family) {
316 case IWL_DEVICE_FAMILY_6030:
317 case IWL_DEVICE_FAMILY_6005:
318 case IWL_DEVICE_FAMILY_7000:
319 break;
320 default:
321 IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
322 return NULL;
323 }
324
325 /******************************** 314 /********************************
326 * 1. Allocating and configuring HW data 315 * 1. Allocating and configuring HW data
327 ********************************/ 316 ********************************/
@@ -363,8 +352,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 352 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; 353 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
365 354
366 /* TODO: this should really be a TLV */ 355 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
367 if (cfg->device_family == IWL_DEVICE_FAMILY_7000)
368 trans_cfg.bc_table_dword = true; 356 trans_cfg.bc_table_dword = true;
369 357
370 if (!iwlwifi_mod_params.wd_disable) 358 if (!iwlwifi_mod_params.wd_disable)
@@ -438,7 +426,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
438 out_free: 426 out_free:
439 iwl_phy_db_free(mvm->phy_db); 427 iwl_phy_db_free(mvm->phy_db);
440 kfree(mvm->scan_cmd); 428 kfree(mvm->scan_cmd);
441 kfree(mvm->eeprom_blob);
442 iwl_trans_stop_hw(trans, true); 429 iwl_trans_stop_hw(trans, true);
443 ieee80211_free_hw(mvm->hw); 430 ieee80211_free_hw(mvm->hw);
444 return NULL; 431 return NULL;
@@ -460,7 +447,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
460 iwl_phy_db_free(mvm->phy_db); 447 iwl_phy_db_free(mvm->phy_db);
461 mvm->phy_db = NULL; 448 mvm->phy_db = NULL;
462 449
463 kfree(mvm->eeprom_blob);
464 iwl_free_nvm_data(mvm->nvm_data); 450 iwl_free_nvm_data(mvm->nvm_data);
465 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++) 451 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
466 kfree(mvm->nvm_sections[i].data); 452 kfree(mvm->nvm_sections[i].data);
@@ -624,12 +610,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
624 ieee80211_free_txskb(mvm->hw, skb); 610 ieee80211_free_txskb(mvm->hw, skb);
625} 611}
626 612
627static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 613static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
628{ 614{
629 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
630
631 iwl_mvm_dump_nic_error_log(mvm);
632
633 iwl_abort_notification_waits(&mvm->notif_wait); 615 iwl_abort_notification_waits(&mvm->notif_wait);
634 616
635 /* 617 /*
@@ -663,9 +645,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
663 } 645 }
664} 646}
665 647
648static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
649{
650 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
651
652 iwl_mvm_dump_nic_error_log(mvm);
653
654 iwl_mvm_nic_restart(mvm);
655}
656
666static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) 657static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
667{ 658{
659 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
660
668 WARN_ON(1); 661 WARN_ON(1);
662 iwl_mvm_nic_restart(mvm);
669} 663}
670 664
671static const struct iwl_op_mode_ops iwl_mvm_ops = { 665static const struct iwl_op_mode_ops iwl_mvm_ops = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index b428448f8ddf..0f0b44eabd93 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -142,7 +142,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
142 struct cfg80211_chan_def *chandef, 142 struct cfg80211_chan_def *chandef,
143 u8 chains_static, u8 chains_dynamic) 143 u8 chains_static, u8 chains_dynamic)
144{ 144{
145 u8 valid_rx_chains, active_cnt, idle_cnt; 145 u8 active_cnt, idle_cnt;
146 146
147 /* Set the channel info data */ 147 /* Set the channel info data */
148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ? 148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
@@ -158,17 +158,16 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
158 * Need to add on chain noise calibration limitations, and 158 * Need to add on chain noise calibration limitations, and
159 * BT coex considerations. 159 * BT coex considerations.
160 */ 160 */
161 valid_rx_chains = mvm->nvm_data->valid_rx_ant;
162 idle_cnt = chains_static; 161 idle_cnt = chains_static;
163 active_cnt = chains_dynamic; 162 active_cnt = chains_dynamic;
164 163
165 cmd->rxchain_info = cpu_to_le32(valid_rx_chains << 164 cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) <<
166 PHY_RX_CHAIN_VALID_POS); 165 PHY_RX_CHAIN_VALID_POS);
167 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 166 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
168 cmd->rxchain_info |= cpu_to_le32(active_cnt << 167 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
169 PHY_RX_CHAIN_MIMO_CNT_POS); 168 PHY_RX_CHAIN_MIMO_CNT_POS);
170 169
171 cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant); 170 cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw));
172} 171}
173 172
174/* 173/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 5a92a4978795..9395ab2a1af2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -75,23 +75,49 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 78static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd) 79 struct iwl_powertable_cmd *cmd)
80{
81 IWL_DEBUG_POWER(mvm,
82 "Sending power table command for power level %d, flags = 0x%X\n",
83 iwlmvm_mod_params.power_scheme,
84 le16_to_cpu(cmd->flags));
85 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds);
86
87 if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
88 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
89 le32_to_cpu(cmd->rx_data_timeout));
90 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
91 le32_to_cpu(cmd->tx_data_timeout));
92 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
93 cmd->lprx_rssi_threshold);
94 }
95}
96
97void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
98 struct iwl_powertable_cmd *cmd)
80{ 99{
81 struct ieee80211_hw *hw = mvm->hw; 100 struct ieee80211_hw *hw = mvm->hw;
82 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
83 struct ieee80211_chanctx_conf *chanctx_conf; 101 struct ieee80211_chanctx_conf *chanctx_conf;
84 struct ieee80211_channel *chan; 102 struct ieee80211_channel *chan;
85 int dtimper, dtimper_msec; 103 int dtimper, dtimper_msec;
86 int keep_alive; 104 int keep_alive;
87 bool radar_detect = false; 105 bool radar_detect = false;
88 106
89 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 107 /*
90 mvmvif->color)); 108 * Regardless of power management state the driver must set
91 cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); 109 * keep alive period. FW will use it for sending keep alive NDPs
110 * immediately after association.
111 */
112 cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC;
113
114 if ((iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) ||
115 !iwlwifi_mod_params.power_save)
116 return;
117
118 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
92 119
93 if ((!vif->bss_conf.ps) || 120 if (!vif->bss_conf.ps)
94 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM))
95 return; 121 return;
96 122
97 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 123 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -110,26 +136,23 @@ static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
110 136
111 /* Check skip over DTIM conditions */ 137 /* Check skip over DTIM conditions */
112 if (!radar_detect && (dtimper <= 10) && 138 if (!radar_detect && (dtimper <= 10) &&
113 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) { 139 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP))
114 cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK); 140 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
115 cmd->num_skip_dtim = 2;
116 }
117 141
118 /* Check that keep alive period is at least 3 * DTIM */ 142 /* Check that keep alive period is at least 3 * DTIM */
119 dtimper_msec = dtimper * vif->bss_conf.beacon_int; 143 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
120 keep_alive = max_t(int, 3 * dtimper_msec, 144 keep_alive = max_t(int, 3 * dtimper_msec,
121 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); 145 MSEC_PER_SEC * cmd->keep_alive_seconds);
122 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 146 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
123 147 cmd->keep_alive_seconds = keep_alive;
124 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
125 148
126 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { 149 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) {
127 /* TODO: Also for D3 (device sleep / WoWLAN) */ 150 /* TODO: Also for D3 (device sleep / WoWLAN) */
128 cmd->rx_data_timeout = cpu_to_le32(10); 151 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
129 cmd->tx_data_timeout = cpu_to_le32(10); 152 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
130 } else { 153 } else {
131 cmd->rx_data_timeout = cpu_to_le32(50); 154 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
132 cmd->tx_data_timeout = cpu_to_le32(50); 155 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
133 } 156 }
134} 157}
135 158
@@ -137,36 +160,11 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
137{ 160{
138 struct iwl_powertable_cmd cmd = {}; 161 struct iwl_powertable_cmd cmd = {};
139 162
140 if (!iwlwifi_mod_params.power_save) {
141 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
142 return 0;
143 }
144
145 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 163 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
146 return 0; 164 return 0;
147 165
148 iwl_power_build_cmd(mvm, vif, &cmd); 166 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
149 167 iwl_mvm_power_log(mvm, &cmd);
150 IWL_DEBUG_POWER(mvm,
151 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
152 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
153 le16_to_cpu(cmd.flags));
154
155 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
156 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
157 le16_to_cpu(cmd.keep_alive_seconds));
158 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
159 le32_to_cpu(cmd.rx_data_timeout));
160 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
161 le32_to_cpu(cmd.tx_data_timeout));
162 IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n",
163 le32_to_cpu(cmd.rx_data_timeout_uapsd));
164 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
165 le32_to_cpu(cmd.tx_data_timeout_uapsd));
166 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
167 cmd.lprx_rssi_threshold);
168 IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim);
169 }
170 168
171 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 169 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
172 sizeof(cmd), &cmd); 170 sizeof(cmd), &cmd);
@@ -175,33 +173,16 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
175int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 173int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
176{ 174{
177 struct iwl_powertable_cmd cmd = {}; 175 struct iwl_powertable_cmd cmd = {};
178 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
179
180 if (!iwlwifi_mod_params.power_save) {
181 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
182 return 0;
183 }
184 176
185 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 177 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
186 return 0; 178 return 0;
187 179
188 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 180 if ((iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) &&
189 mvmvif->color)); 181 iwlwifi_mod_params.power_save)
190 cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); 182 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
191 183
192 IWL_DEBUG_POWER(mvm, 184 iwl_mvm_power_log(mvm, &cmd);
193 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
194 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
195 le16_to_cpu(cmd.flags));
196 185
197 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 186 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
198 sizeof(cmd), &cmd); 187 sizeof(cmd), &cmd);
199} 188}
200
201#ifdef CONFIG_IWLWIFI_DEBUGFS
202void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
203 struct iwl_powertable_cmd *cmd)
204{
205 iwl_power_build_cmd(mvm, vif, cmd);
206}
207#endif /* CONFIG_IWLWIFI_DEBUGFS */
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 925628468146..a1e3e923ea3e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -114,7 +114,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
114 data->n_interfaces[id]++; 114 data->n_interfaces[id]++;
115 break; 115 break;
116 case NL80211_IFTYPE_MONITOR: 116 case NL80211_IFTYPE_MONITOR:
117 data->n_interfaces[id]++; 117 if (mvmvif->monitor_active)
118 data->n_interfaces[id]++;
118 break; 119 break;
119 case NL80211_IFTYPE_P2P_DEVICE: 120 case NL80211_IFTYPE_P2P_DEVICE:
120 break; 121 break;
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 56b636d9ab30..55334d542e26 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -680,12 +680,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
680 */ 680 */
681static bool rs_use_green(struct ieee80211_sta *sta) 681static bool rs_use_green(struct ieee80211_sta *sta)
682{ 682{
683 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 683 /*
684 684 * There's a bug somewhere in this code that causes the
685 bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & 685 * scaling to get stuck because GF+SGI can't be combined
686 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 686 * in SISO rates. Until we find that bug, disable GF, it
687 687 * has only limited benefit and we still interoperate with
688 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; 688 * GF APs since we can always receive GF transmissions.
689 */
690 return false;
689} 691}
690 692
691/** 693/**
@@ -791,7 +793,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
791 793
792 if (num_of_ant(tbl->ant_type) > 1) 794 if (num_of_ant(tbl->ant_type) > 1)
793 tbl->ant_type = 795 tbl->ant_type =
794 first_antenna(mvm->nvm_data->valid_tx_ant); 796 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
795 797
796 tbl->is_ht40 = 0; 798 tbl->is_ht40 = 0;
797 tbl->is_SGI = 0; 799 tbl->is_SGI = 0;
@@ -1233,7 +1235,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1233 return -1; 1235 return -1;
1234 1236
1235 /* Need both Tx chains/antennas to support MIMO */ 1237 /* Need both Tx chains/antennas to support MIMO */
1236 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2) 1238 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
1237 return -1; 1239 return -1;
1238 1240
1239 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); 1241 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
@@ -1285,7 +1287,7 @@ static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
1285 return -1; 1287 return -1;
1286 1288
1287 /* Need both Tx chains/antennas to support MIMO */ 1289 /* Need both Tx chains/antennas to support MIMO */
1288 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3) 1290 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 3)
1289 return -1; 1291 return -1;
1290 1292
1291 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n"); 1293 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n");
@@ -1379,7 +1381,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1379 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1381 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1380 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1382 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1381 u8 start_action; 1383 u8 start_action;
1382 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1384 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1383 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1385 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1384 int ret; 1386 int ret;
1385 u8 update_search_tbl_counter = 0; 1387 u8 update_search_tbl_counter = 0;
@@ -1512,7 +1514,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1512 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1514 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1513 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1515 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1514 u8 start_action; 1516 u8 start_action;
1515 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1517 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1516 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1518 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1517 u8 update_search_tbl_counter = 0; 1519 u8 update_search_tbl_counter = 0;
1518 int ret; 1520 int ret;
@@ -1647,7 +1649,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1647 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1649 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1648 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1650 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1649 u8 start_action; 1651 u8 start_action;
1650 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1652 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1651 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1653 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1652 u8 update_search_tbl_counter = 0; 1654 u8 update_search_tbl_counter = 0;
1653 int ret; 1655 int ret;
@@ -1784,7 +1786,7 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
1784 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1786 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1785 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1787 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1786 u8 start_action; 1788 u8 start_action;
1787 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1789 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1788 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1790 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1789 int ret; 1791 int ret;
1790 u8 update_search_tbl_counter = 0; 1792 u8 update_search_tbl_counter = 0;
@@ -2447,7 +2449,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2447 2449
2448 i = lq_sta->last_txrate_idx; 2450 i = lq_sta->last_txrate_idx;
2449 2451
2450 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 2452 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2451 2453
2452 if (!lq_sta->search_better_tbl) 2454 if (!lq_sta->search_better_tbl)
2453 active_tbl = lq_sta->active_tbl; 2455 active_tbl = lq_sta->active_tbl;
@@ -2637,15 +2639,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2637 2639
2638 /* These values will be overridden later */ 2640 /* These values will be overridden later */
2639 lq_sta->lq.single_stream_ant_msk = 2641 lq_sta->lq.single_stream_ant_msk =
2640 first_antenna(mvm->nvm_data->valid_tx_ant); 2642 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2641 lq_sta->lq.dual_stream_ant_msk = 2643 lq_sta->lq.dual_stream_ant_msk =
2642 mvm->nvm_data->valid_tx_ant & 2644 iwl_fw_valid_tx_ant(mvm->fw) &
2643 ~first_antenna(mvm->nvm_data->valid_tx_ant); 2645 ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2644 if (!lq_sta->lq.dual_stream_ant_msk) { 2646 if (!lq_sta->lq.dual_stream_ant_msk) {
2645 lq_sta->lq.dual_stream_ant_msk = ANT_AB; 2647 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2646 } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) { 2648 } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) {
2647 lq_sta->lq.dual_stream_ant_msk = 2649 lq_sta->lq.dual_stream_ant_msk =
2648 mvm->nvm_data->valid_tx_ant; 2650 iwl_fw_valid_tx_ant(mvm->fw);
2649 } 2651 }
2650 2652
2651 /* as default allow aggregation for all tids */ 2653 /* as default allow aggregation for all tids */
@@ -2706,7 +2708,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2706 index++; 2708 index++;
2707 repeat_rate--; 2709 repeat_rate--;
2708 if (mvm) 2710 if (mvm)
2709 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 2711 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2710 2712
2711 /* Fill rest of rate table */ 2713 /* Fill rest of rate table */
2712 while (index < LINK_QUAL_MAX_RETRY_NUM) { 2714 while (index < LINK_QUAL_MAX_RETRY_NUM) {
@@ -2811,7 +2813,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2811 u8 ant_sel_tx; 2813 u8 ant_sel_tx;
2812 2814
2813 mvm = lq_sta->drv; 2815 mvm = lq_sta->drv;
2814 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 2816 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2815 if (lq_sta->dbg_fixed_rate) { 2817 if (lq_sta->dbg_fixed_rate) {
2816 ant_sel_tx = 2818 ant_sel_tx =
2817 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) 2819 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
@@ -2882,9 +2884,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2882 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2884 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2883 lq_sta->dbg_fixed_rate); 2885 lq_sta->dbg_fixed_rate);
2884 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 2886 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2885 (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", 2887 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "",
2886 (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", 2888 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2887 (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); 2889 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2888 desc += sprintf(buff+desc, "lq type %s\n", 2890 desc += sprintf(buff+desc, "lq type %s\n",
2889 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 2891 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2890 if (is_Ht(tbl->lq_type)) { 2892 if (is_Ht(tbl->lq_type)) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3f40ab05bbd8..4dfc21a3e83e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, 131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
132 struct iwl_rx_phy_info *phy_info) 132 struct iwl_rx_phy_info *phy_info)
133{ 133{
134 u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db; 134 int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
135 int rssi_all_band_a, rssi_all_band_b;
136 u32 agc_a, agc_b, max_agc;
135 u32 val; 137 u32 val;
136 138
137 /* Find max rssi among 3 possible receivers. 139 /* Find max rssi among 2 possible receivers.
138 * These values are measured by the Digital Signal Processor (DSP). 140 * These values are measured by the Digital Signal Processor (DSP).
139 * They should stay fairly constant even as the signal strength varies, 141 * They should stay fairly constant even as the signal strength varies,
140 * if the radio's Automatic Gain Control (AGC) is working right. 142 * if the radio's Automatic Gain Control (AGC) is working right.
141 * AGC value (see below) will provide the "interesting" info. 143 * AGC value (see below) will provide the "interesting" info.
142 */ 144 */
145 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
146 agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
147 agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
148 max_agc = max_t(u32, agc_a, agc_b);
149
143 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); 150 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
144 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; 151 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
145 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; 152 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
146 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]); 153 rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
147 rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; 154 IWL_OFDM_RSSI_ALLBAND_A_POS;
148 155 rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
149 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); 156 IWL_OFDM_RSSI_ALLBAND_B_POS;
150 agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
151 157
152 max_rssi = max_t(u32, rssi_a, rssi_b); 158 /*
153 max_rssi = max_t(u32, max_rssi, rssi_c); 159 * dBm = rssi dB - agc dB - constant.
160 * Higher AGC (higher radio gain) means lower signal.
161 */
162 rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
163 rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
164 max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);
154 165
155 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", 166 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
156 rssi_a, rssi_b, rssi_c, max_rssi, agc_db); 167 rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
157 168
158 /* dBm = max_rssi dB - agc dB - constant. 169 return max_rssi_dbm;
159 * Higher AGC (higher radio gain) means lower signal. */
160 return max_rssi - agc_db - IWL_RSSI_OFFSET;
161} 170}
162 171
163/* 172/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 9b21b92aa8d1..2157b0f8ced5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -74,7 +74,7 @@
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 75{
76 u16 rx_chain; 76 u16 rx_chain;
77 u8 rx_ant = mvm->nvm_data->valid_rx_ant; 77 u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw);
78 78
79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; 79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; 80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -115,7 +115,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
115 u32 tx_ant; 115 u32 tx_ant;
116 116
117 mvm->scan_last_antenna_idx = 117 mvm->scan_last_antenna_idx =
118 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 118 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
119 mvm->scan_last_antenna_idx); 119 mvm->scan_last_antenna_idx);
120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; 120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
121 121
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 52aecf20d0df..0fd96e4da461 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -101,8 +101,55 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
101 } 101 }
102 add_sta_cmd.add_modify = update ? 1 : 0; 102 add_sta_cmd.add_modify = update ? 1 : 0;
103 103
104 /* STA_FLG_FAT_EN_MSK ? */ 104 add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |
105 /* STA_FLG_MIMO_EN_MSK ? */ 105 STA_FLG_MIMO_EN_MSK);
106
107 switch (sta->bandwidth) {
108 case IEEE80211_STA_RX_BW_160:
109 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ);
110 /* fall through */
111 case IEEE80211_STA_RX_BW_80:
112 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ);
113 /* fall through */
114 case IEEE80211_STA_RX_BW_40:
115 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ);
116 /* fall through */
117 case IEEE80211_STA_RX_BW_20:
118 if (sta->ht_cap.ht_supported)
119 add_sta_cmd.station_flags |=
120 cpu_to_le32(STA_FLG_FAT_EN_20MHZ);
121 break;
122 }
123
124 switch (sta->rx_nss) {
125 case 1:
126 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
127 break;
128 case 2:
129 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2);
130 break;
131 case 3 ... 8:
132 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3);
133 break;
134 }
135
136 switch (sta->smps_mode) {
137 case IEEE80211_SMPS_AUTOMATIC:
138 case IEEE80211_SMPS_NUM_MODES:
139 WARN_ON(1);
140 break;
141 case IEEE80211_SMPS_STATIC:
142 /* override NSS */
143 add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK);
144 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
145 break;
146 case IEEE80211_SMPS_DYNAMIC:
147 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT);
148 break;
149 case IEEE80211_SMPS_OFF:
150 /* nothing */
151 break;
152 }
106 153
107 if (sta->ht_cap.ht_supported) { 154 if (sta->ht_cap.ht_supported) {
108 add_sta_cmd.station_flags_msk |= 155 add_sta_cmd.station_flags_msk |=
@@ -340,6 +387,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
340 387
341 if (vif->type == NL80211_IFTYPE_STATION && 388 if (vif->type == NL80211_IFTYPE_STATION &&
342 mvmvif->ap_sta_id == mvm_sta->sta_id) { 389 mvmvif->ap_sta_id == mvm_sta->sta_id) {
390 /* flush its queues here since we are freeing mvm_sta */
391 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
392
343 /* 393 /*
344 * Put a non-NULL since the fw station isn't removed. 394 * Put a non-NULL since the fw station isn't removed.
345 * It will be removed after the MAC will be set as 395 * It will be removed after the MAC will be set as
@@ -348,9 +398,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
348 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 398 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
349 ERR_PTR(-EINVAL)); 399 ERR_PTR(-EINVAL));
350 400
351 /* flush its queues here since we are freeing mvm_sta */
352 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
353
354 /* if we are associated - we can't remove the AP STA now */ 401 /* if we are associated - we can't remove the AP STA now */
355 if (vif->bss_conf.assoc) 402 if (vif->bss_conf.assoc)
356 return ret; 403 return ret;
@@ -770,6 +817,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
770 u16 txq_id; 817 u16 txq_id;
771 int err; 818 int err;
772 819
820
821 /*
822 * If mac80211 is cleaning its state, then say that we finished since
823 * our state has been cleared anyway.
824 */
825 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
826 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
827 return 0;
828 }
829
773 spin_lock_bh(&mvmsta->lock); 830 spin_lock_bh(&mvmsta->lock);
774 831
775 txq_id = tid_data->txq_id; 832 txq_id = tid_data->txq_id;
@@ -824,6 +881,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
824 return err; 881 return err;
825} 882}
826 883
884int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
885 struct ieee80211_sta *sta, u16 tid)
886{
887 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
888 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
889 u16 txq_id;
890
891 /*
892 * First set the agg state to OFF to avoid calling
893 * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.
894 */
895 spin_lock_bh(&mvmsta->lock);
896 txq_id = tid_data->txq_id;
897 IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
898 mvmsta->sta_id, tid, txq_id, tid_data->state);
899 tid_data->state = IWL_AGG_OFF;
900 spin_unlock_bh(&mvmsta->lock);
901
902 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
903 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
904
905 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
906 mvm->queue_to_mac80211[tid_data->txq_id] =
907 IWL_INVALID_MAC80211_QUEUE;
908
909 return 0;
910}
911
827static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) 912static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
828{ 913{
829 int i; 914 int i;
@@ -860,7 +945,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
860 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) 945 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
861 return mvmvif->ap_sta_id; 946 return mvmvif->ap_sta_id;
862 947
863 return IWL_INVALID_STATION; 948 return IWL_MVM_STATION_COUNT;
864} 949}
865 950
866static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, 951static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
@@ -1008,7 +1093,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
1008 1093
1009 /* Get the station id from the mvm local station table */ 1094 /* Get the station id from the mvm local station table */
1010 sta_id = iwl_mvm_get_key_sta_id(vif, sta); 1095 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1011 if (sta_id == IWL_INVALID_STATION) { 1096 if (sta_id == IWL_MVM_STATION_COUNT) {
1012 IWL_ERR(mvm, "Failed to find station id\n"); 1097 IWL_ERR(mvm, "Failed to find station id\n");
1013 return -EINVAL; 1098 return -EINVAL;
1014 } 1099 }
@@ -1103,7 +1188,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1103 return -ENOENT; 1188 return -ENOENT;
1104 } 1189 }
1105 1190
1106 if (sta_id == IWL_INVALID_STATION) { 1191 if (sta_id == IWL_MVM_STATION_COUNT) {
1107 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); 1192 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
1108 return 0; 1193 return 0;
1109 } 1194 }
@@ -1169,7 +1254,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1169 struct iwl_mvm_sta *mvm_sta; 1254 struct iwl_mvm_sta *mvm_sta;
1170 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); 1255 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1171 1256
1172 if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) 1257 if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
1173 return; 1258 return;
1174 1259
1175 rcu_read_lock(); 1260 rcu_read_lock();
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 896f88ac8145..12abd2d71835 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -271,6 +271,7 @@ struct iwl_mvm_tid_data {
271 * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for 271 * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for
272 * tid. 272 * tid.
273 * @max_agg_bufsize: the maximal size of the AGG buffer for this station 273 * @max_agg_bufsize: the maximal size of the AGG buffer for this station
274 * @bt_reduced_txpower: is reduced tx power enabled for this station
274 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx 275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
275 * and from Tx response flow, it needs a spinlock. 276 * and from Tx response flow, it needs a spinlock.
276 * @pending_frames: number of frames for this STA on the shared Tx queues. 277 * @pending_frames: number of frames for this STA on the shared Tx queues.
@@ -287,6 +288,7 @@ struct iwl_mvm_sta {
287 u32 mac_id_n_color; 288 u32 mac_id_n_color;
288 u16 tid_disable_agg; 289 u16 tid_disable_agg;
289 u8 max_agg_bufsize; 290 u8 max_agg_bufsize;
291 bool bt_reduced_txpower;
290 spinlock_t lock; 292 spinlock_t lock;
291 atomic_t pending_frames; 293 atomic_t pending_frames;
292 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; 294 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
@@ -348,6 +350,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
348 struct ieee80211_sta *sta, u16 tid, u8 buf_size); 350 struct ieee80211_sta *sta, u16 tid, u8 buf_size);
349int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 351int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
350 struct ieee80211_sta *sta, u16 tid); 352 struct ieee80211_sta *sta, u16 tid);
353int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
354 struct ieee80211_sta *sta, u16 tid);
351 355
352int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); 356int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
353int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, 357int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index e437e02c7149..ad9bbca99213 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -76,14 +76,12 @@
76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) 76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
77#define MSEC_TO_TU(_msec) (_msec*1000/1024) 77#define MSEC_TO_TU(_msec) (_msec*1000/1024)
78 78
79/* For ROC use a TE type which has priority high enough to be scheduled when 79/*
80 * there is a concurrent BSS or GO/AP. Currently, use a TE type that has 80 * For the high priority TE use a time event type that has similar priority to
81 * priority similar to the TE priority used for action scans by the FW. 81 * the FW's action scan priority.
82 * TODO: This needs to be changed, based on the reason for the ROC, i.e., use
83 * TE_P2P_DEVICE_DISCOVERABLE for remain on channel without mgmt skb, and use
84 * TE_P2P_DEVICE_ACTION_SCAN
85 */ 82 */
86#define IWL_MVM_ROC_TE_TYPE TE_P2P_DEVICE_ACTION_SCAN 83#define IWL_MVM_ROC_TE_TYPE_NORMAL TE_P2P_DEVICE_DISCOVERABLE
84#define IWL_MVM_ROC_TE_TYPE_MGMT_TX TE_P2P_CLIENT_ASSOC
87 85
88void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, 86void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
89 struct iwl_mvm_time_event_data *te_data) 87 struct iwl_mvm_time_event_data *te_data)
@@ -116,7 +114,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
116 * issue as it will have to complete before the next command is 114 * issue as it will have to complete before the next command is
117 * executed, and a new time event means a new command. 115 * executed, and a new time event means a new command.
118 */ 116 */
119 iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false); 117 iwl_mvm_flush_tx_path(mvm, BIT(IWL_MVM_OFFCHANNEL_QUEUE), false);
120} 118}
121 119
122static void iwl_mvm_roc_finished(struct iwl_mvm *mvm) 120static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
@@ -168,7 +166,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
168 WARN_ONCE(!le32_to_cpu(notif->status), 166 WARN_ONCE(!le32_to_cpu(notif->status),
169 "Failed to schedule time event\n"); 167 "Failed to schedule time event\n");
170 168
171 if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) { 169 if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) {
172 IWL_DEBUG_TE(mvm, 170 IWL_DEBUG_TE(mvm,
173 "TE ended - current time %lu, estimated end %lu\n", 171 "TE ended - current time %lu, estimated end %lu\n",
174 jiffies, te_data->end_jiffies); 172 jiffies, te_data->end_jiffies);
@@ -191,7 +189,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
191 } 189 }
192 190
193 iwl_mvm_te_clear_data(mvm, te_data); 191 iwl_mvm_te_clear_data(mvm, te_data);
194 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { 192 } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) {
195 te_data->running = true; 193 te_data->running = true;
196 te_data->end_jiffies = jiffies + 194 te_data->end_jiffies = jiffies +
197 TU_TO_JIFFIES(te_data->duration); 195 TU_TO_JIFFIES(te_data->duration);
@@ -370,7 +368,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
370 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); 368 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1));
371 time_cmd.duration = cpu_to_le32(duration); 369 time_cmd.duration = cpu_to_le32(duration);
372 time_cmd.repeat = cpu_to_le32(1); 370 time_cmd.repeat = cpu_to_le32(1);
373 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 371 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START |
372 TE_NOTIF_HOST_EVENT_END);
374 373
375 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 374 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
376} 375}
@@ -438,7 +437,7 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
438} 437}
439 438
440int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 439int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
441 int duration) 440 int duration, enum ieee80211_roc_type type)
442{ 441{
443 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 442 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
444 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 443 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
@@ -459,27 +458,36 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
459 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 458 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
460 time_cmd.id_and_color = 459 time_cmd.id_and_color =
461 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 460 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
462 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE); 461
462 switch (type) {
463 case IEEE80211_ROC_TYPE_NORMAL:
464 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_NORMAL);
465 break;
466 case IEEE80211_ROC_TYPE_MGMT_TX:
467 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_MGMT_TX);
468 break;
469 default:
470 WARN_ONCE(1, "Got an invalid ROC type\n");
471 return -EINVAL;
472 }
463 473
464 time_cmd.apply_time = cpu_to_le32(0); 474 time_cmd.apply_time = cpu_to_le32(0);
465 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT); 475 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
466 time_cmd.is_present = cpu_to_le32(1); 476 time_cmd.is_present = cpu_to_le32(1);
467
468 time_cmd.interval = cpu_to_le32(1); 477 time_cmd.interval = cpu_to_le32(1);
469 478
470 /* 479 /*
471 * IWL_MVM_ROC_TE_TYPE can have lower priority than other events 480 * The P2P Device TEs can have lower priority than other events
472 * that are being scheduled by the driver/fw, and thus it might not be 481 * that are being scheduled by the driver/fw, and thus it might not be
473 * scheduled. To improve the chances of it being scheduled, allow it to 482 * scheduled. To improve the chances of it being scheduled, allow them
474 * be fragmented. 483 * to be fragmented, and in addition allow them to be delayed.
475 * In addition, for the same reasons, allow to delay the scheduling of
476 * the time event.
477 */ 484 */
478 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20); 485 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
479 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); 486 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
480 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); 487 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
481 time_cmd.repeat = cpu_to_le32(1); 488 time_cmd.repeat = cpu_to_le32(1);
482 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 489 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START |
490 TE_NOTIF_HOST_EVENT_END);
483 491
484 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 492 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
485} 493}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index 64fb57a5ab43..f86c51065ed3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -162,6 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE 162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE
163 * @duration: the requested duration in millisecond for the fw to be on the 163 * @duration: the requested duration in millisecond for the fw to be on the
164 * channel that is bound to the vif. 164 * channel that is bound to the vif.
165 * @type: the remain on channel request type
165 * 166 *
166 * This function can be used to issue a remain on channel session, 167 * This function can be used to issue a remain on channel session,
167 * which means that the fw will stay in the channel for the request %duration 168 * which means that the fw will stay in the channel for the request %duration
@@ -172,7 +173,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
172 * another notification to the driver. 173 * another notification to the driver.
173 */ 174 */
174int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 175int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
175 int duration); 176 int duration, enum ieee80211_roc_type type);
176 177
177/** 178/**
178 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity 179 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 56df249b215e..479074303bd7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -205,7 +205,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
205 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); 205 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
206 206
207 mvm->mgmt_last_antenna_idx = 207 mvm->mgmt_last_antenna_idx =
208 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 208 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
209 mvm->mgmt_last_antenna_idx); 209 mvm->mgmt_last_antenna_idx);
210 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; 210 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
211 211
@@ -365,7 +365,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
365 if (WARN_ON_ONCE(!mvmsta)) 365 if (WARN_ON_ONCE(!mvmsta))
366 return -1; 366 return -1;
367 367
368 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION)) 368 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
369 return -1; 369 return -1;
370 370
371 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id); 371 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id);
@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
417 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
418 418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP && 419 if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
420 txq_id < IWL_FIRST_AMPDU_QUEUE) 420 txq_id < IWL_MVM_FIRST_AGG_QUEUE)
421 atomic_inc(&mvmsta->pending_frames); 421 atomic_inc(&mvmsta->pending_frames);
422 422
423 return 0; 423 return 0;
@@ -606,13 +606,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
606 info); 606 info);
607 607
608 /* Single frame failure in an AMPDU queue => send BAR */ 608 /* Single frame failure in an AMPDU queue => send BAR */
609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE && 609 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE &&
610 !(info->flags & IEEE80211_TX_STAT_ACK)) { 610 !(info->flags & IEEE80211_TX_STAT_ACK))
611 /* there must be only one skb in the skb_list */
612 WARN_ON_ONCE(skb_freed > 1 ||
613 !skb_queue_empty(&skbs));
614 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
615 }
616 612
617 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ 613 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */
618 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { 614 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
@@ -623,7 +619,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
623 ieee80211_tx_status_ni(mvm->hw, skb); 619 ieee80211_tx_status_ni(mvm->hw, skb);
624 } 620 }
625 621
626 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) { 622 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) {
627 /* If this is an aggregation queue, we use the ssn since: 623 /* If this is an aggregation queue, we use the ssn since:
628 * ssn = wifi seq_num % 256. 624 * ssn = wifi seq_num % 256.
629 * The seq_ctl is the sequence control of the packet to which 625 * The seq_ctl is the sequence control of the packet to which
@@ -645,10 +641,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
645 } 641 }
646 642
647 IWL_DEBUG_TX_REPLY(mvm, 643 IWL_DEBUG_TX_REPLY(mvm,
648 "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x " 644 "TXQ %d status %s (0x%08x)\n",
649 "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", 645 txq_id, iwl_mvm_get_tx_fail_reason(status), status);
650 txq_id, iwl_mvm_get_tx_fail_reason(status), 646
651 status, le32_to_cpu(tx_resp->initial_rate), 647 IWL_DEBUG_TX_REPLY(mvm,
648 "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n",
649 le32_to_cpu(tx_resp->initial_rate),
652 tx_resp->failure_frame, SEQ_TO_INDEX(sequence), 650 tx_resp->failure_frame, SEQ_TO_INDEX(sequence),
653 ssn, next_reclaimed, seq_ctl); 651 ssn, next_reclaimed, seq_ctl);
654 652
@@ -685,7 +683,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
685 * If there are no pending frames for this STA, notify mac80211 that 683 * If there are no pending frames for this STA, notify mac80211 that
686 * this station can go to sleep in its STA table. 684 * this station can go to sleep in its STA table.
687 */ 685 */
688 if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta && 686 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta &&
689 !WARN_ON(skb_freed > 1) && 687 !WARN_ON(skb_freed > 1) &&
690 mvmsta->vif->type == NL80211_IFTYPE_AP && 688 mvmsta->vif->type == NL80211_IFTYPE_AP &&
691 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { 689 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
@@ -754,7 +752,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
754 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 752 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
755 struct ieee80211_sta *sta; 753 struct ieee80211_sta *sta;
756 754
757 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE)) 755 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE))
758 return; 756 return;
759 757
760 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) 758 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 000e842c2edd..0cc8d8c0d393 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -462,7 +462,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
462 .data = { lq, }, 462 .data = { lq, },
463 }; 463 };
464 464
465 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) 465 if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
466 return -EINVAL; 466 return -EINVAL;
467 467
468 if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) 468 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))