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/Makefile4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c (renamed from drivers/net/wireless/iwlwifi/mvm/bt-coex.c)336
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c195
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c112
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h (renamed from drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h)4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h106
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c145
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h56
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/offloading.c215
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c232
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c88
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c240
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c49
23 files changed, 1460 insertions, 415 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 41d390fd2ac8..ccdd3b7c4cce 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,8 +2,8 @@ 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 sf.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o bt-coex.o 5iwlmvm-y += power.o coex.o
6iwlmvm-y += led.o tt.o 6iwlmvm-y += led.o tt.o offloading.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 9
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 2aa3ee93c68e..685f7e8e6943 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -61,9 +61,11 @@
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63 63
64#include <linux/ieee80211.h>
65#include <linux/etherdevice.h>
64#include <net/mac80211.h> 66#include <net/mac80211.h>
65 67
66#include "fw-api-bt-coex.h" 68#include "fw-api-coex.h"
67#include "iwl-modparams.h" 69#include "iwl-modparams.h"
68#include "mvm.h" 70#include "mvm.h"
69#include "iwl-debug.h" 71#include "iwl-debug.h"
@@ -305,6 +307,215 @@ static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
305 cpu_to_le32(0x33113311), 307 cpu_to_le32(0x33113311),
306}; 308};
307 309
310struct corunning_block_luts {
311 u8 range;
312 __le32 lut20[BT_COEX_CORUN_LUT_SIZE];
313};
314
315/*
316 * Ranges for the antenna coupling calibration / co-running block LUT:
317 * LUT0: [ 0, 12[
318 * LUT1: [12, 20[
319 * LUT2: [20, 21[
320 * LUT3: [21, 23[
321 * LUT4: [23, 27[
322 * LUT5: [27, 30[
323 * LUT6: [30, 32[
324 * LUT7: [32, 33[
325 * LUT8: [33, - [
326 */
327static const struct corunning_block_luts antenna_coupling_ranges[] = {
328 {
329 .range = 0,
330 .lut20 = {
331 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
332 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
333 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
334 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
335 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
336 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
337 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
338 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
339 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
340 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
341 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
342 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
343 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
344 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
345 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
346 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
347 },
348 },
349 {
350 .range = 12,
351 .lut20 = {
352 cpu_to_le32(0x00000001), cpu_to_le32(0x00000000),
353 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
354 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
355 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
356 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
357 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
358 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
359 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
360 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
361 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
362 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
363 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
364 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
365 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
366 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
367 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
368 },
369 },
370 {
371 .range = 20,
372 .lut20 = {
373 cpu_to_le32(0x00000002), cpu_to_le32(0x00000000),
374 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
375 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
376 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
377 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
378 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
379 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
380 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
381 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
382 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
383 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
384 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
385 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
386 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
387 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
388 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
389 },
390 },
391 {
392 .range = 21,
393 .lut20 = {
394 cpu_to_le32(0x00000003), cpu_to_le32(0x00000000),
395 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
396 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
397 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
398 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
399 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
400 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
401 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
402 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
403 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
404 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
405 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
406 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
407 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
408 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
409 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
410 },
411 },
412 {
413 .range = 23,
414 .lut20 = {
415 cpu_to_le32(0x00000004), cpu_to_le32(0x00000000),
416 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
417 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
418 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
419 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
420 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
421 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
422 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
423 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
424 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
425 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
426 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
427 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
428 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
429 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
430 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
431 },
432 },
433 {
434 .range = 27,
435 .lut20 = {
436 cpu_to_le32(0x00000005), cpu_to_le32(0x00000000),
437 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
438 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
439 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
440 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
441 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
442 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
443 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
444 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
445 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
446 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
447 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
448 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
449 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
450 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
451 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
452 },
453 },
454 {
455 .range = 30,
456 .lut20 = {
457 cpu_to_le32(0x00000006), cpu_to_le32(0x00000000),
458 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
459 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
460 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
461 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
462 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
463 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
464 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
465 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
466 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
467 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
468 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
469 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
470 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
471 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
472 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
473 },
474 },
475 {
476 .range = 32,
477 .lut20 = {
478 cpu_to_le32(0x00000007), cpu_to_le32(0x00000000),
479 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
480 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
481 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
482 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
483 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
484 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
485 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
486 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
487 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
488 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
489 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
490 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
491 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
492 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
493 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
494 },
495 },
496 {
497 .range = 33,
498 .lut20 = {
499 cpu_to_le32(0x00000008), cpu_to_le32(0x00000000),
500 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
501 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
502 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
503 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
504 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
505 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
506 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
507 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
508 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
509 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
510 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
511 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
512 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
513 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
514 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
515 },
516 },
517};
518
308static enum iwl_bt_coex_lut_type 519static enum iwl_bt_coex_lut_type
309iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif) 520iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
310{ 521{
@@ -390,8 +601,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
390 BT_VALID_LUT | 601 BT_VALID_LUT |
391 BT_VALID_WIFI_RX_SW_PRIO_BOOST | 602 BT_VALID_WIFI_RX_SW_PRIO_BOOST |
392 BT_VALID_WIFI_TX_SW_PRIO_BOOST | 603 BT_VALID_WIFI_TX_SW_PRIO_BOOST |
393 BT_VALID_CORUN_LUT_20 |
394 BT_VALID_CORUN_LUT_40 |
395 BT_VALID_ANT_ISOLATION | 604 BT_VALID_ANT_ISOLATION |
396 BT_VALID_ANT_ISOLATION_THRS | 605 BT_VALID_ANT_ISOLATION_THRS |
397 BT_VALID_TXTX_DELTA_FREQ_THRS | 606 BT_VALID_TXTX_DELTA_FREQ_THRS |
@@ -401,6 +610,17 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
401 if (IWL_MVM_BT_COEX_SYNC2SCO) 610 if (IWL_MVM_BT_COEX_SYNC2SCO)
402 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); 611 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
403 612
613 if (IWL_MVM_BT_COEX_CORUNNING) {
614 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_CORUN_LUT_20 |
615 BT_VALID_CORUN_LUT_40);
616 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
617 }
618
619 if (IWL_MVM_BT_COEX_MPLUT) {
620 bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
621 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
622 }
623
404 if (mvm->cfg->bt_shared_single_ant) 624 if (mvm->cfg->bt_shared_single_ant)
405 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant, 625 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
406 sizeof(iwl_single_shared_ant)); 626 sizeof(iwl_single_shared_ant));
@@ -408,6 +628,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
408 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup, 628 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
409 sizeof(iwl_combined_lookup)); 629 sizeof(iwl_combined_lookup));
410 630
631 /* Take first Co-running block LUT to get started */
632 memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[0].lut20,
633 sizeof(bt_cmd->bt4_corun_lut20));
634 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[0].lut20,
635 sizeof(bt_cmd->bt4_corun_lut40));
636
411 memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost, 637 memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost,
412 sizeof(iwl_bt_prio_boost)); 638 sizeof(iwl_bt_prio_boost));
413 memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut, 639 memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut,
@@ -498,7 +724,7 @@ int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, bool enable)
498 struct iwl_host_cmd cmd = { 724 struct iwl_host_cmd cmd = {
499 .id = BT_CONFIG, 725 .id = BT_CONFIG,
500 .len = { sizeof(*bt_cmd), }, 726 .len = { sizeof(*bt_cmd), },
501 .dataflags = { IWL_HCMD_DFL_DUP, }, 727 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
502 .flags = CMD_ASYNC, 728 .flags = CMD_ASYNC,
503 }; 729 };
504 struct iwl_mvm_sta *mvmsta; 730 struct iwl_mvm_sta *mvmsta;
@@ -952,8 +1178,8 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
952#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) 1178#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
953#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) 1179#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200)
954 1180
955u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, 1181u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
956 struct ieee80211_sta *sta) 1182 struct ieee80211_sta *sta)
957{ 1183{
958 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1184 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
959 enum iwl_bt_coex_lut_type lut_type; 1185 enum iwl_bt_coex_lut_type lut_type;
@@ -989,6 +1215,38 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
989 return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT; 1215 return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT;
990} 1216}
991 1217
1218u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
1219 struct ieee80211_tx_info *info, u8 ac)
1220{
1221 __le16 fc = hdr->frame_control;
1222
1223 if (info->band != IEEE80211_BAND_2GHZ)
1224 return 0;
1225
1226 if (unlikely(mvm->bt_tx_prio))
1227 return mvm->bt_tx_prio - 1;
1228
1229 /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
1230 if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO ||
1231 is_multicast_ether_addr(hdr->addr1) ||
1232 ieee80211_is_ctl(fc) || ieee80211_is_mgmt(fc) ||
1233 ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc))
1234 return 3;
1235
1236 switch (ac) {
1237 case IEEE80211_AC_BE:
1238 return 1;
1239 case IEEE80211_AC_VO:
1240 return 3;
1241 case IEEE80211_AC_VI:
1242 return 2;
1243 default:
1244 break;
1245 }
1246
1247 return 0;
1248}
1249
992void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm) 1250void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
993{ 1251{
994 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX)) 1252 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
@@ -996,3 +1254,69 @@ void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
996 1254
997 iwl_mvm_bt_coex_notif_handle(mvm); 1255 iwl_mvm_bt_coex_notif_handle(mvm);
998} 1256}
1257
1258int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1259 struct iwl_rx_cmd_buffer *rxb,
1260 struct iwl_device_cmd *dev_cmd)
1261{
1262 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1263 u32 ant_isolation = le32_to_cpup((void *)pkt->data);
1264 u8 __maybe_unused lower_bound, upper_bound;
1265 u8 lut;
1266
1267 struct iwl_bt_coex_cmd *bt_cmd;
1268 struct iwl_host_cmd cmd = {
1269 .id = BT_CONFIG,
1270 .len = { sizeof(*bt_cmd), },
1271 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1272 .flags = CMD_SYNC,
1273 };
1274
1275 if (!IWL_MVM_BT_COEX_CORUNNING)
1276 return 0;
1277
1278 lockdep_assert_held(&mvm->mutex);
1279
1280 if (ant_isolation == mvm->last_ant_isol)
1281 return 0;
1282
1283 for (lut = 0; lut < ARRAY_SIZE(antenna_coupling_ranges) - 1; lut++)
1284 if (ant_isolation < antenna_coupling_ranges[lut + 1].range)
1285 break;
1286
1287 lower_bound = antenna_coupling_ranges[lut].range;
1288
1289 if (lut < ARRAY_SIZE(antenna_coupling_ranges) - 1)
1290 upper_bound = antenna_coupling_ranges[lut + 1].range;
1291 else
1292 upper_bound = antenna_coupling_ranges[lut].range;
1293
1294 IWL_DEBUG_COEX(mvm, "Antenna isolation=%d in range [%d,%d[, lut=%d\n",
1295 ant_isolation, lower_bound, upper_bound, lut);
1296
1297 mvm->last_ant_isol = ant_isolation;
1298
1299 if (mvm->last_corun_lut == lut)
1300 return 0;
1301
1302 mvm->last_corun_lut = lut;
1303
1304 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
1305 if (!bt_cmd)
1306 return 0;
1307 cmd.data[0] = bt_cmd;
1308
1309 bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
1310 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
1311 BT_VALID_CORUN_LUT_20 |
1312 BT_VALID_CORUN_LUT_40);
1313
1314 /* For the moment, use the same LUT for 20GHz and 40GHz */
1315 memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[lut].lut20,
1316 sizeof(bt_cmd->bt4_corun_lut20));
1317
1318 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
1319 sizeof(bt_cmd->bt4_corun_lut40));
1320
1321 return 0;
1322}
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 2d133b1b2dde..51685693af2e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -79,8 +79,8 @@
79#define IWL_MVM_PS_SNOOZE_WINDOW 50 79#define IWL_MVM_PS_SNOOZE_WINDOW 50
80#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25 80#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
81#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64 81#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
82#define IWL_MVM_LOWLAT_SINGLE_BINDING_MAXDUR 24 /* TU */
83#define IWL_MVM_LOWLAT_DUAL_BINDING_MAXDUR 24 /* TU */
84#define IWL_MVM_BT_COEX_SYNC2SCO 1 82#define IWL_MVM_BT_COEX_SYNC2SCO 1
83#define IWL_MVM_BT_COEX_CORUNNING 1
84#define IWL_MVM_BT_COEX_MPLUT 1
85 85
86#endif /* __MVM_CONSTANTS_H */ 86#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index b956e2f0b631..e56f5a0edf85 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -376,139 +376,6 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
376 return err; 376 return err;
377} 377}
378 378
379static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
380 struct ieee80211_vif *vif)
381{
382 union {
383 struct iwl_proto_offload_cmd_v1 v1;
384 struct iwl_proto_offload_cmd_v2 v2;
385 struct iwl_proto_offload_cmd_v3_small v3s;
386 struct iwl_proto_offload_cmd_v3_large v3l;
387 } cmd = {};
388 struct iwl_host_cmd hcmd = {
389 .id = PROT_OFFLOAD_CONFIG_CMD,
390 .flags = CMD_SYNC,
391 .data[0] = &cmd,
392 .dataflags[0] = IWL_HCMD_DFL_DUP,
393 };
394 struct iwl_proto_offload_cmd_common *common;
395 u32 enabled = 0, size;
396 u32 capa_flags = mvm->fw->ucode_capa.flags;
397#if IS_ENABLED(CONFIG_IPV6)
398 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
399 int i;
400
401 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL ||
402 capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
403 struct iwl_ns_config *nsc;
404 struct iwl_targ_addr *addrs;
405 int n_nsc, n_addrs;
406 int c;
407
408 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
409 nsc = cmd.v3s.ns_config;
410 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S;
411 addrs = cmd.v3s.targ_addrs;
412 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S;
413 } else {
414 nsc = cmd.v3l.ns_config;
415 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L;
416 addrs = cmd.v3l.targ_addrs;
417 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
418 }
419
420 if (mvmvif->num_target_ipv6_addrs)
421 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
422
423 /*
424 * For each address we have (and that will fit) fill a target
425 * address struct and combine for NS offload structs with the
426 * solicited node addresses.
427 */
428 for (i = 0, c = 0;
429 i < mvmvif->num_target_ipv6_addrs &&
430 i < n_addrs && c < n_nsc; i++) {
431 struct in6_addr solicited_addr;
432 int j;
433
434 addrconf_addr_solict_mult(&mvmvif->target_ipv6_addrs[i],
435 &solicited_addr);
436 for (j = 0; j < c; j++)
437 if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
438 &solicited_addr) == 0)
439 break;
440 if (j == c)
441 c++;
442 addrs[i].addr = mvmvif->target_ipv6_addrs[i];
443 addrs[i].config_num = cpu_to_le32(j);
444 nsc[j].dest_ipv6_addr = solicited_addr;
445 memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN);
446 }
447
448 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL)
449 cmd.v3s.num_valid_ipv6_addrs = cpu_to_le32(i);
450 else
451 cmd.v3l.num_valid_ipv6_addrs = cpu_to_le32(i);
452 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
453 if (mvmvif->num_target_ipv6_addrs) {
454 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
455 memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN);
456 }
457
458 BUILD_BUG_ON(sizeof(cmd.v2.target_ipv6_addr[0]) !=
459 sizeof(mvmvif->target_ipv6_addrs[0]));
460
461 for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
462 IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2); i++)
463 memcpy(cmd.v2.target_ipv6_addr[i],
464 &mvmvif->target_ipv6_addrs[i],
465 sizeof(cmd.v2.target_ipv6_addr[i]));
466 } else {
467 if (mvmvif->num_target_ipv6_addrs) {
468 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
469 memcpy(cmd.v1.ndp_mac_addr, vif->addr, ETH_ALEN);
470 }
471
472 BUILD_BUG_ON(sizeof(cmd.v1.target_ipv6_addr[0]) !=
473 sizeof(mvmvif->target_ipv6_addrs[0]));
474
475 for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
476 IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1); i++)
477 memcpy(cmd.v1.target_ipv6_addr[i],
478 &mvmvif->target_ipv6_addrs[i],
479 sizeof(cmd.v1.target_ipv6_addr[i]));
480 }
481#endif
482
483 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
484 common = &cmd.v3s.common;
485 size = sizeof(cmd.v3s);
486 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
487 common = &cmd.v3l.common;
488 size = sizeof(cmd.v3l);
489 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
490 common = &cmd.v2.common;
491 size = sizeof(cmd.v2);
492 } else {
493 common = &cmd.v1.common;
494 size = sizeof(cmd.v1);
495 }
496
497 if (vif->bss_conf.arp_addr_cnt) {
498 enabled |= IWL_D3_PROTO_OFFLOAD_ARP;
499 common->host_ipv4_addr = vif->bss_conf.arp_addr_list[0];
500 memcpy(common->arp_mac_addr, vif->addr, ETH_ALEN);
501 }
502
503 if (!enabled)
504 return 0;
505
506 common->enabled = cpu_to_le32(enabled);
507
508 hcmd.len[0] = size;
509 return iwl_mvm_send_cmd(mvm, &hcmd);
510}
511
512enum iwl_mvm_tcp_packet_type { 379enum iwl_mvm_tcp_packet_type {
513 MVM_TCP_TX_SYN, 380 MVM_TCP_TX_SYN,
514 MVM_TCP_RX_SYNACK, 381 MVM_TCP_RX_SYNACK,
@@ -846,8 +713,8 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
846 quota_cmd.quotas[0].id_and_color = 713 quota_cmd.quotas[0].id_and_color =
847 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id, 714 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
848 mvmvif->phy_ctxt->color)); 715 mvmvif->phy_ctxt->color));
849 quota_cmd.quotas[0].quota = cpu_to_le32(100); 716 quota_cmd.quotas[0].quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
850 quota_cmd.quotas[0].max_duration = cpu_to_le32(1000); 717 quota_cmd.quotas[0].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
851 718
852 for (i = 1; i < MAX_BINDINGS; i++) 719 for (i = 1; i < MAX_BINDINGS; i++)
853 quota_cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID); 720 quota_cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
@@ -927,6 +794,20 @@ void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
927 IWL_ERR(mvm, "failed to set non-QoS seqno\n"); 794 IWL_ERR(mvm, "failed to set non-QoS seqno\n");
928} 795}
929 796
797static int
798iwl_mvm_send_wowlan_config_cmd(struct iwl_mvm *mvm,
799 const struct iwl_wowlan_config_cmd_v3 *cmd)
800{
801 /* start only with the v2 part of the command */
802 u16 cmd_len = sizeof(cmd->common);
803
804 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID)
805 cmd_len = sizeof(*cmd);
806
807 return iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, CMD_SYNC,
808 cmd_len, cmd);
809}
810
930static int __iwl_mvm_suspend(struct ieee80211_hw *hw, 811static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
931 struct cfg80211_wowlan *wowlan, 812 struct cfg80211_wowlan *wowlan,
932 bool test) 813 bool test)
@@ -939,7 +820,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
939 struct iwl_mvm_vif *mvmvif; 820 struct iwl_mvm_vif *mvmvif;
940 struct ieee80211_sta *ap_sta; 821 struct ieee80211_sta *ap_sta;
941 struct iwl_mvm_sta *mvm_ap_sta; 822 struct iwl_mvm_sta *mvm_ap_sta;
942 struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; 823 struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {};
943 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; 824 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
944 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; 825 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
945 struct iwl_d3_manager_config d3_cfg_cmd_data = { 826 struct iwl_d3_manager_config d3_cfg_cmd_data = {
@@ -961,7 +842,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
961 .tkip = &tkip_cmd, 842 .tkip = &tkip_cmd,
962 .use_tkip = false, 843 .use_tkip = false,
963 }; 844 };
964 int ret, i; 845 int ret;
965 int len __maybe_unused; 846 int len __maybe_unused;
966 847
967 if (!wowlan) { 848 if (!wowlan) {
@@ -1002,49 +883,41 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1002 883
1003 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; 884 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
1004 885
1005 /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */ 886 /* TODO: wowlan_config_cmd.common.wowlan_ba_teardown_tids */
1006 887
1007 wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported; 888 wowlan_config_cmd.common.is_11n_connection =
889 ap_sta->ht_cap.ht_supported;
1008 890
1009 /* Query the last used seqno and set it */ 891 /* Query the last used seqno and set it */
1010 ret = iwl_mvm_get_last_nonqos_seq(mvm, vif); 892 ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
1011 if (ret < 0) 893 if (ret < 0)
1012 goto out_noreset; 894 goto out_noreset;
1013 wowlan_config_cmd.non_qos_seq = cpu_to_le16(ret); 895 wowlan_config_cmd.common.non_qos_seq = cpu_to_le16(ret);
1014 896
1015 /* 897 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &wowlan_config_cmd.common);
1016 * For QoS counters, we store the one to use next, so subtract 0x10
1017 * since the uCode will add 0x10 *before* using the value while we
1018 * increment after using the value (i.e. store the next value to use).
1019 */
1020 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1021 u16 seq = mvm_ap_sta->tid_data[i].seq_number;
1022 seq -= 0x10;
1023 wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq);
1024 }
1025 898
1026 if (wowlan->disconnect) 899 if (wowlan->disconnect)
1027 wowlan_config_cmd.wakeup_filter |= 900 wowlan_config_cmd.common.wakeup_filter |=
1028 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | 901 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
1029 IWL_WOWLAN_WAKEUP_LINK_CHANGE); 902 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
1030 if (wowlan->magic_pkt) 903 if (wowlan->magic_pkt)
1031 wowlan_config_cmd.wakeup_filter |= 904 wowlan_config_cmd.common.wakeup_filter |=
1032 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET); 905 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
1033 if (wowlan->gtk_rekey_failure) 906 if (wowlan->gtk_rekey_failure)
1034 wowlan_config_cmd.wakeup_filter |= 907 wowlan_config_cmd.common.wakeup_filter |=
1035 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL); 908 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
1036 if (wowlan->eap_identity_req) 909 if (wowlan->eap_identity_req)
1037 wowlan_config_cmd.wakeup_filter |= 910 wowlan_config_cmd.common.wakeup_filter |=
1038 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ); 911 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
1039 if (wowlan->four_way_handshake) 912 if (wowlan->four_way_handshake)
1040 wowlan_config_cmd.wakeup_filter |= 913 wowlan_config_cmd.common.wakeup_filter |=
1041 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE); 914 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
1042 if (wowlan->n_patterns) 915 if (wowlan->n_patterns)
1043 wowlan_config_cmd.wakeup_filter |= 916 wowlan_config_cmd.common.wakeup_filter |=
1044 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); 917 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
1045 918
1046 if (wowlan->rfkill_release) 919 if (wowlan->rfkill_release)
1047 wowlan_config_cmd.wakeup_filter |= 920 wowlan_config_cmd.common.wakeup_filter |=
1048 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 921 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
1049 922
1050 if (wowlan->tcp) { 923 if (wowlan->tcp) {
@@ -1052,7 +925,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1052 * Set the "link change" (really "link lost") flag as well 925 * Set the "link change" (really "link lost") flag as well
1053 * since that implies losing the TCP connection. 926 * since that implies losing the TCP connection.
1054 */ 927 */
1055 wowlan_config_cmd.wakeup_filter |= 928 wowlan_config_cmd.common.wakeup_filter |=
1056 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | 929 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
1057 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | 930 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
1058 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | 931 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
@@ -1150,9 +1023,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1150 } 1023 }
1151 } 1024 }
1152 1025
1153 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 1026 ret = iwl_mvm_send_wowlan_config_cmd(mvm, &wowlan_config_cmd);
1154 CMD_SYNC, sizeof(wowlan_config_cmd),
1155 &wowlan_config_cmd);
1156 if (ret) 1027 if (ret)
1157 goto out; 1028 goto out;
1158 1029
@@ -1160,7 +1031,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1160 if (ret) 1031 if (ret)
1161 goto out; 1032 goto out;
1162 1033
1163 ret = iwl_mvm_send_proto_offload(mvm, vif); 1034 ret = iwl_mvm_send_proto_offload(mvm, vif, false, CMD_SYNC);
1164 if (ret) 1035 if (ret)
1165 goto out; 1036 goto out;
1166 1037
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index f64e972191eb..9b59e1d7ae71 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -312,6 +312,11 @@ static ssize_t iwl_dbgfs_reduced_txp_write(struct ieee80211_vif *vif,
312 mutex_lock(&mvm->mutex); 312 mutex_lock(&mvm->mutex);
313 313
314 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id); 314 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id);
315 if (IS_ERR_OR_NULL(mvmsta)) {
316 mutex_unlock(&mvm->mutex);
317 return -ENOTCONN;
318 }
319
315 mvmsta->bt_reduced_txpower_dbg = false; 320 mvmsta->bt_reduced_txpower_dbg = false;
316 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, 321 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
317 reduced_tx_power); 322 reduced_tx_power);
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index e0ff43ed2482..1b52deea6081 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -60,11 +60,14 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/vmalloc.h>
64
63#include "mvm.h" 65#include "mvm.h"
64#include "sta.h" 66#include "sta.h"
65#include "iwl-io.h" 67#include "iwl-io.h"
66#include "iwl-prph.h" 68#include "iwl-prph.h"
67#include "debugfs.h" 69#include "debugfs.h"
70#include "fw-error-dump.h"
68 71
69static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf, 72static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
70 size_t count, loff_t *ppos) 73 size_t count, loff_t *ppos)
@@ -117,6 +120,51 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
117 return ret; 120 return ret;
118} 121}
119 122
123static int iwl_dbgfs_fw_error_dump_open(struct inode *inode, struct file *file)
124{
125 struct iwl_mvm *mvm = inode->i_private;
126 int ret;
127
128 if (!mvm)
129 return -EINVAL;
130
131 mutex_lock(&mvm->mutex);
132 if (!mvm->fw_error_dump) {
133 ret = -ENODATA;
134 goto out;
135 }
136
137 file->private_data = mvm->fw_error_dump;
138 mvm->fw_error_dump = NULL;
139 kfree(mvm->fw_error_sram);
140 mvm->fw_error_sram = NULL;
141 mvm->fw_error_sram_len = 0;
142 ret = 0;
143
144out:
145 mutex_unlock(&mvm->mutex);
146 return ret;
147}
148
149static ssize_t iwl_dbgfs_fw_error_dump_read(struct file *file,
150 char __user *user_buf,
151 size_t count, loff_t *ppos)
152{
153 struct iwl_fw_error_dump_file *dump_file = file->private_data;
154
155 return simple_read_from_buffer(user_buf, count, ppos,
156 dump_file,
157 le32_to_cpu(dump_file->file_len));
158}
159
160static int iwl_dbgfs_fw_error_dump_release(struct inode *inode,
161 struct file *file)
162{
163 vfree(file->private_data);
164
165 return 0;
166}
167
120static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, 168static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
121 size_t count, loff_t *ppos) 169 size_t count, loff_t *ppos)
122{ 170{
@@ -350,6 +398,9 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
350 le32_to_cpu(notif->secondary_ch_lut)); 398 le32_to_cpu(notif->secondary_ch_lut));
351 pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n", 399 pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n",
352 le32_to_cpu(notif->bt_activity_grading)); 400 le32_to_cpu(notif->bt_activity_grading));
401 pos += scnprintf(buf+pos, bufsz-pos,
402 "antenna isolation = %d CORUN LUT index = %d\n",
403 mvm->last_ant_isol, mvm->last_corun_lut);
353 404
354 mutex_unlock(&mvm->mutex); 405 mutex_unlock(&mvm->mutex);
355 406
@@ -392,6 +443,22 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
392 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 443 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
393} 444}
394 445
446static ssize_t
447iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
448 size_t count, loff_t *ppos)
449{
450 u32 bt_tx_prio;
451
452 if (sscanf(buf, "%u", &bt_tx_prio) != 1)
453 return -EINVAL;
454 if (bt_tx_prio > 4)
455 return -EINVAL;
456
457 mvm->bt_tx_prio = bt_tx_prio;
458
459 return count;
460}
461
395#define PRINT_STATS_LE32(_str, _val) \ 462#define PRINT_STATS_LE32(_str, _val) \
396 pos += scnprintf(buf + pos, bufsz - pos, \ 463 pos += scnprintf(buf + pos, bufsz - pos, \
397 fmt_table, _str, \ 464 fmt_table, _str, \
@@ -536,56 +603,60 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
536 loff_t *ppos, 603 loff_t *ppos,
537 struct iwl_mvm_frame_stats *stats) 604 struct iwl_mvm_frame_stats *stats)
538{ 605{
539 char *buff; 606 char *buff, *pos, *endpos;
540 int pos = 0, idx, i; 607 int idx, i;
541 int ret; 608 int ret;
542 size_t bufsz = 1024; 609 static const size_t bufsz = 1024;
543 610
544 buff = kmalloc(bufsz, GFP_KERNEL); 611 buff = kmalloc(bufsz, GFP_KERNEL);
545 if (!buff) 612 if (!buff)
546 return -ENOMEM; 613 return -ENOMEM;
547 614
548 spin_lock_bh(&mvm->drv_stats_lock); 615 spin_lock_bh(&mvm->drv_stats_lock);
549 pos += scnprintf(buff + pos, bufsz - pos, 616
617 pos = buff;
618 endpos = pos + bufsz;
619
620 pos += scnprintf(pos, endpos - pos,
550 "Legacy/HT/VHT\t:\t%d/%d/%d\n", 621 "Legacy/HT/VHT\t:\t%d/%d/%d\n",
551 stats->legacy_frames, 622 stats->legacy_frames,
552 stats->ht_frames, 623 stats->ht_frames,
553 stats->vht_frames); 624 stats->vht_frames);
554 pos += scnprintf(buff + pos, bufsz - pos, "20/40/80\t:\t%d/%d/%d\n", 625 pos += scnprintf(pos, endpos - pos, "20/40/80\t:\t%d/%d/%d\n",
555 stats->bw_20_frames, 626 stats->bw_20_frames,
556 stats->bw_40_frames, 627 stats->bw_40_frames,
557 stats->bw_80_frames); 628 stats->bw_80_frames);
558 pos += scnprintf(buff + pos, bufsz - pos, "NGI/SGI\t\t:\t%d/%d\n", 629 pos += scnprintf(pos, endpos - pos, "NGI/SGI\t\t:\t%d/%d\n",
559 stats->ngi_frames, 630 stats->ngi_frames,
560 stats->sgi_frames); 631 stats->sgi_frames);
561 pos += scnprintf(buff + pos, bufsz - pos, "SISO/MIMO2\t:\t%d/%d\n", 632 pos += scnprintf(pos, endpos - pos, "SISO/MIMO2\t:\t%d/%d\n",
562 stats->siso_frames, 633 stats->siso_frames,
563 stats->mimo2_frames); 634 stats->mimo2_frames);
564 pos += scnprintf(buff + pos, bufsz - pos, "FAIL/SCSS\t:\t%d/%d\n", 635 pos += scnprintf(pos, endpos - pos, "FAIL/SCSS\t:\t%d/%d\n",
565 stats->fail_frames, 636 stats->fail_frames,
566 stats->success_frames); 637 stats->success_frames);
567 pos += scnprintf(buff + pos, bufsz - pos, "MPDUs agg\t:\t%d\n", 638 pos += scnprintf(pos, endpos - pos, "MPDUs agg\t:\t%d\n",
568 stats->agg_frames); 639 stats->agg_frames);
569 pos += scnprintf(buff + pos, bufsz - pos, "A-MPDUs\t\t:\t%d\n", 640 pos += scnprintf(pos, endpos - pos, "A-MPDUs\t\t:\t%d\n",
570 stats->ampdu_count); 641 stats->ampdu_count);
571 pos += scnprintf(buff + pos, bufsz - pos, "Avg MPDUs/A-MPDU:\t%d\n", 642 pos += scnprintf(pos, endpos - pos, "Avg MPDUs/A-MPDU:\t%d\n",
572 stats->ampdu_count > 0 ? 643 stats->ampdu_count > 0 ?
573 (stats->agg_frames / stats->ampdu_count) : 0); 644 (stats->agg_frames / stats->ampdu_count) : 0);
574 645
575 pos += scnprintf(buff + pos, bufsz - pos, "Last Rates\n"); 646 pos += scnprintf(pos, endpos - pos, "Last Rates\n");
576 647
577 idx = stats->last_frame_idx - 1; 648 idx = stats->last_frame_idx - 1;
578 for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) { 649 for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) {
579 idx = (idx + 1) % ARRAY_SIZE(stats->last_rates); 650 idx = (idx + 1) % ARRAY_SIZE(stats->last_rates);
580 if (stats->last_rates[idx] == 0) 651 if (stats->last_rates[idx] == 0)
581 continue; 652 continue;
582 pos += scnprintf(buff + pos, bufsz - pos, "Rate[%d]: ", 653 pos += scnprintf(pos, endpos - pos, "Rate[%d]: ",
583 (int)(ARRAY_SIZE(stats->last_rates) - i)); 654 (int)(ARRAY_SIZE(stats->last_rates) - i));
584 pos += rs_pretty_print_rate(buff + pos, stats->last_rates[idx]); 655 pos += rs_pretty_print_rate(pos, stats->last_rates[idx]);
585 } 656 }
586 spin_unlock_bh(&mvm->drv_stats_lock); 657 spin_unlock_bh(&mvm->drv_stats_lock);
587 658
588 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos); 659 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
589 kfree(buff); 660 kfree(buff);
590 661
591 return ret; 662 return ret;
@@ -1032,9 +1103,16 @@ MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1032MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats); 1103MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
1033MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); 1104MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1034MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); 1105MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
1106MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
1035MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); 1107MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1036MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); 1108MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
1037 1109
1110static const struct file_operations iwl_dbgfs_fw_error_dump_ops = {
1111 .open = iwl_dbgfs_fw_error_dump_open,
1112 .read = iwl_dbgfs_fw_error_dump_read,
1113 .release = iwl_dbgfs_fw_error_dump_release,
1114};
1115
1038#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1116#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1039MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); 1117MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
1040MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256); 1118MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
@@ -1049,12 +1127,15 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1049 struct dentry *bcast_dir __maybe_unused; 1127 struct dentry *bcast_dir __maybe_unused;
1050 char buf[100]; 1128 char buf[100];
1051 1129
1130 spin_lock_init(&mvm->drv_stats_lock);
1131
1052 mvm->debugfs_dir = dbgfs_dir; 1132 mvm->debugfs_dir = dbgfs_dir;
1053 1133
1054 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); 1134 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR);
1055 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); 1135 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
1056 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 1136 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
1057 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 1137 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
1138 MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
1058 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); 1139 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
1059 MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR); 1140 MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
1060 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD) 1141 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)
@@ -1064,6 +1145,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1064 MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR); 1145 MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
1065 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 1146 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
1066 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR); 1147 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
1148 MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, S_IWUSR);
1067 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 1149 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
1068 S_IWUSR | S_IRUSR); 1150 S_IWUSR | S_IRUSR);
1069 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 1151 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
index 20b723d6270f..21877e5966a8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
@@ -77,6 +77,8 @@
77 * @BT_COEX_3W: 77 * @BT_COEX_3W:
78 * @BT_COEX_NW: 78 * @BT_COEX_NW:
79 * @BT_COEX_SYNC2SCO: 79 * @BT_COEX_SYNC2SCO:
80 * @BT_COEX_CORUNNING:
81 * @BT_COEX_MPLUT:
80 * 82 *
81 * The COEX_MODE must be set for each command. Even if it is not changed. 83 * The COEX_MODE must be set for each command. Even if it is not changed.
82 */ 84 */
@@ -88,6 +90,8 @@ enum iwl_bt_coex_flags {
88 BT_COEX_3W = 0x2 << BT_COEX_MODE_POS, 90 BT_COEX_3W = 0x2 << BT_COEX_MODE_POS,
89 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, 91 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
90 BT_COEX_SYNC2SCO = BIT(7), 92 BT_COEX_SYNC2SCO = BIT(7),
93 BT_COEX_CORUNNING = BIT(8),
94 BT_COEX_MPLUT = BIT(9),
91}; 95};
92 96
93/* 97/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 521997669c99..10fcc1a79ebd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -239,7 +239,7 @@ enum iwl_wowlan_wakeup_filters {
239 IWL_WOWLAN_WAKEUP_BCN_FILTERING = BIT(16), 239 IWL_WOWLAN_WAKEUP_BCN_FILTERING = BIT(16),
240}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */ 240}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
241 241
242struct iwl_wowlan_config_cmd { 242struct iwl_wowlan_config_cmd_v2 {
243 __le32 wakeup_filter; 243 __le32 wakeup_filter;
244 __le16 non_qos_seq; 244 __le16 non_qos_seq;
245 __le16 qos_seq[8]; 245 __le16 qos_seq[8];
@@ -247,6 +247,12 @@ struct iwl_wowlan_config_cmd {
247 u8 is_11n_connection; 247 u8 is_11n_connection;
248} __packed; /* WOWLAN_CONFIG_API_S_VER_2 */ 248} __packed; /* WOWLAN_CONFIG_API_S_VER_2 */
249 249
250struct iwl_wowlan_config_cmd_v3 {
251 struct iwl_wowlan_config_cmd_v2 common;
252 u8 offloading_tid;
253 u8 reserved[3];
254} __packed; /* WOWLAN_CONFIG_API_S_VER_3 */
255
250/* 256/*
251 * WOWLAN_TSC_RSC_PARAMS 257 * WOWLAN_TSC_RSC_PARAMS
252 */ 258 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index b674c2a2b51c..8e122f3a7a74 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -76,6 +76,8 @@
76 * @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence 76 * @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
77 * @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence 77 * @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
78 * @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC) 78 * @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
79 * @TX_CMD_FLG_BT_PRIO_POS: the position of the BT priority (bit 11 is ignored
80 * on old firmwares).
79 * @TX_CMD_FLG_BT_DIS: disable BT priority for this frame 81 * @TX_CMD_FLG_BT_DIS: disable BT priority for this frame
80 * @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control. 82 * @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
81 * Should be set for mgmt, non-QOS data, mcast, bcast and in scan command 83 * Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
@@ -107,6 +109,7 @@ enum iwl_tx_flags {
107 TX_CMD_FLG_VHT_NDPA = BIT(8), 109 TX_CMD_FLG_VHT_NDPA = BIT(8),
108 TX_CMD_FLG_HT_NDPA = BIT(9), 110 TX_CMD_FLG_HT_NDPA = BIT(9),
109 TX_CMD_FLG_CSI_FDBK2HOST = BIT(10), 111 TX_CMD_FLG_CSI_FDBK2HOST = BIT(10),
112 TX_CMD_FLG_BT_PRIO_POS = 11,
110 TX_CMD_FLG_BT_DIS = BIT(12), 113 TX_CMD_FLG_BT_DIS = BIT(12),
111 TX_CMD_FLG_SEQ_CTL = BIT(13), 114 TX_CMD_FLG_SEQ_CTL = BIT(13),
112 TX_CMD_FLG_MORE_FRAG = BIT(14), 115 TX_CMD_FLG_MORE_FRAG = BIT(14),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 807fa525cafe..6e75b52588de 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -70,7 +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#include "fw-api-coex.h"
74 74
75/* maximal number of Tx queues in any platform */ 75/* maximal number of Tx queues in any platform */
76#define IWL_MVM_MAX_QUEUES 20 76#define IWL_MVM_MAX_QUEUES 20
@@ -95,6 +95,7 @@ enum {
95 /* PHY context commands */ 95 /* PHY context commands */
96 PHY_CONTEXT_CMD = 0x8, 96 PHY_CONTEXT_CMD = 0x8,
97 DBG_CFG = 0x9, 97 DBG_CFG = 0x9,
98 ANTENNA_COUPLING_NOTIFICATION = 0xa,
98 99
99 /* station table */ 100 /* station table */
100 ADD_STA_KEY = 0x17, 101 ADD_STA_KEY = 0x17,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h b/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
new file mode 100644
index 000000000000..58c8941c0d95
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
@@ -0,0 +1,106 @@
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) 2014 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) 2014 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_error_dump_h__
64#define __fw_error_dump_h__
65
66#include <linux/types.h>
67
68#define IWL_FW_ERROR_DUMP_BARKER 0x14789632
69
70/**
71 * enum iwl_fw_error_dump_type - types of data in the dump file
72 * @IWL_FW_ERROR_DUMP_SRAM:
73 * @IWL_FW_ERROR_DUMP_REG:
74 */
75enum iwl_fw_error_dump_type {
76 IWL_FW_ERROR_DUMP_SRAM = 0,
77 IWL_FW_ERROR_DUMP_REG = 1,
78
79 IWL_FW_ERROR_DUMP_MAX,
80};
81
82/**
83 * struct iwl_fw_error_dump_data - data for one type
84 * @type: %enum iwl_fw_error_dump_type
85 * @len: the length starting from %data - must be a multiplier of 4.
86 * @data: the data itself padded to be a multiplier of 4.
87 */
88struct iwl_fw_error_dump_data {
89 __le32 type;
90 __le32 len;
91 __u8 data[];
92} __packed __aligned(4);
93
94/**
95 * struct iwl_fw_error_dump_file - the layout of the header of the file
96 * @barker: must be %IWL_FW_ERROR_DUMP_BARKER
97 * @file_len: the length of all the file starting from %barker
98 * @data: array of %struct iwl_fw_error_dump_data
99 */
100struct iwl_fw_error_dump_file {
101 __le32 barker;
102 __le32 file_len;
103 u8 data[0];
104} __packed __aligned(4);
105
106#endif /* __fw_error_dump_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
index 6b4ea6bf8ffe..e3b3cf4dbd77 100644
--- a/drivers/net/wireless/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -94,6 +94,8 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
94 int ret; 94 int ret;
95 95
96 switch (mode) { 96 switch (mode) {
97 case IWL_LED_BLINK:
98 IWL_ERR(mvm, "Blink led mode not supported, used default\n");
97 case IWL_LED_DEFAULT: 99 case IWL_LED_DEFAULT:
98 case IWL_LED_RF_STATE: 100 case IWL_LED_RF_STATE:
99 mode = IWL_LED_RF_STATE; 101 mode = IWL_LED_RF_STATE;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index c2ab6a3318cb..4dd9ff43b8b6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -205,7 +205,7 @@ static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
205 205
206void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) 206void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
207{ 207{
208 if (!mvm->trans->cfg->d0i3) 208 if (!iwl_mvm_is_d0i3_supported(mvm))
209 return; 209 return;
210 210
211 IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type); 211 IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type);
@@ -215,7 +215,7 @@ void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
215 215
216void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) 216void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
217{ 217{
218 if (!mvm->trans->cfg->d0i3) 218 if (!iwl_mvm_is_d0i3_supported(mvm))
219 return; 219 return;
220 220
221 IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type); 221 IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type);
@@ -228,7 +228,7 @@ iwl_mvm_unref_all_except(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref)
228{ 228{
229 int i; 229 int i;
230 230
231 if (!mvm->trans->cfg->d0i3) 231 if (!iwl_mvm_is_d0i3_supported(mvm))
232 return; 232 return;
233 233
234 for_each_set_bit(i, mvm->ref_bitmap, IWL_MVM_REF_COUNT) { 234 for_each_set_bit(i, mvm->ref_bitmap, IWL_MVM_REF_COUNT) {
@@ -295,7 +295,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
295 !iwlwifi_mod_params.sw_crypto) 295 !iwlwifi_mod_params.sw_crypto)
296 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 296 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
297 297
298 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT) { 298 if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT) {
299 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; 299 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
300 hw->uapsd_queues = IWL_UAPSD_AC_INFO; 300 hw->uapsd_queues = IWL_UAPSD_AC_INFO;
301 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; 301 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
@@ -365,7 +365,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
365 else 365 else
366 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 366 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
367 367
368 if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { 368 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
369 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 369 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
370 hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; 370 hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
371 hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; 371 hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
@@ -375,8 +375,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
375 } 375 }
376 376
377 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 377 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
378 NL80211_FEATURE_P2P_GO_OPPPS | 378 NL80211_FEATURE_P2P_GO_OPPPS;
379 NL80211_FEATURE_LOW_PRIORITY_SCAN;
380 379
381 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 380 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
382 381
@@ -424,6 +423,47 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
424 return ret; 423 return ret;
425} 424}
426 425
426static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm,
427 struct ieee80211_sta *sta,
428 struct sk_buff *skb)
429{
430 struct iwl_mvm_sta *mvmsta;
431 bool defer = false;
432
433 /*
434 * double check the IN_D0I3 flag both before and after
435 * taking the spinlock, in order to prevent taking
436 * the spinlock when not needed.
437 */
438 if (likely(!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)))
439 return false;
440
441 spin_lock(&mvm->d0i3_tx_lock);
442 /*
443 * testing the flag again ensures the skb dequeue
444 * loop (on d0i3 exit) hasn't run yet.
445 */
446 if (!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))
447 goto out;
448
449 mvmsta = iwl_mvm_sta_from_mac80211(sta);
450 if (mvmsta->sta_id == IWL_MVM_STATION_COUNT ||
451 mvmsta->sta_id != mvm->d0i3_ap_sta_id)
452 goto out;
453
454 __skb_queue_tail(&mvm->d0i3_tx, skb);
455 ieee80211_stop_queues(mvm->hw);
456
457 /* trigger wakeup */
458 iwl_mvm_ref(mvm, IWL_MVM_REF_TX);
459 iwl_mvm_unref(mvm, IWL_MVM_REF_TX);
460
461 defer = true;
462out:
463 spin_unlock(&mvm->d0i3_tx_lock);
464 return defer;
465}
466
427static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, 467static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
428 struct ieee80211_tx_control *control, 468 struct ieee80211_tx_control *control,
429 struct sk_buff *skb) 469 struct sk_buff *skb)
@@ -451,6 +491,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
451 sta = NULL; 491 sta = NULL;
452 492
453 if (sta) { 493 if (sta) {
494 if (iwl_mvm_defer_tx(mvm, sta, skb))
495 return;
454 if (iwl_mvm_tx_skb(mvm, skb, sta)) 496 if (iwl_mvm_tx_skb(mvm, skb, sta))
455 goto drop; 497 goto drop;
456 return; 498 return;
@@ -489,6 +531,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
489{ 531{
490 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 532 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
491 int ret; 533 int ret;
534 bool tx_agg_ref = false;
492 535
493 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n", 536 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
494 sta->addr, tid, action); 537 sta->addr, tid, action);
@@ -496,6 +539,23 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
496 if (!(mvm->nvm_data->sku_cap_11n_enable)) 539 if (!(mvm->nvm_data->sku_cap_11n_enable))
497 return -EACCES; 540 return -EACCES;
498 541
542 /* return from D0i3 before starting a new Tx aggregation */
543 if (action == IEEE80211_AMPDU_TX_START) {
544 iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG);
545 tx_agg_ref = true;
546
547 /*
548 * wait synchronously until D0i3 exit to get the correct
549 * sequence number for the tid
550 */
551 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
552 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) {
553 WARN_ON_ONCE(1);
554 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
555 return -EIO;
556 }
557 }
558
499 mutex_lock(&mvm->mutex); 559 mutex_lock(&mvm->mutex);
500 560
501 switch (action) { 561 switch (action) {
@@ -533,6 +593,13 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
533 } 593 }
534 mutex_unlock(&mvm->mutex); 594 mutex_unlock(&mvm->mutex);
535 595
596 /*
597 * If the tid is marked as started, we won't use it for offloaded
598 * traffic on the next D0i3 entry. It's safe to unref.
599 */
600 if (tx_agg_ref)
601 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
602
536 return ret; 603 return ret;
537} 604}
538 605
@@ -557,6 +624,15 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
557 624
558static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 625static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
559{ 626{
627#ifdef CONFIG_IWLWIFI_DEBUGFS
628 static char *env[] = { "DRIVER=iwlwifi", "EVENT=error_dump", NULL };
629
630 iwl_mvm_fw_error_dump(mvm);
631
632 /* notify the userspace about the error we had */
633 kobject_uevent_env(&mvm->hw->wiphy->dev.kobj, KOBJ_CHANGE, env);
634#endif
635
560 iwl_trans_stop_device(mvm->trans); 636 iwl_trans_stop_device(mvm->trans);
561 637
562 mvm->scan_status = IWL_MVM_SCAN_NONE; 638 mvm->scan_status = IWL_MVM_SCAN_NONE;
@@ -610,6 +686,7 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
610 mutex_lock(&mvm->mutex); 686 mutex_lock(&mvm->mutex);
611 687
612 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 688 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
689 iwl_mvm_d0i3_enable_tx(mvm, NULL);
613 ret = iwl_mvm_update_quotas(mvm, NULL); 690 ret = iwl_mvm_update_quotas(mvm, NULL);
614 if (ret) 691 if (ret)
615 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", 692 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
@@ -1255,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1255 */ 1332 */
1256 iwl_mvm_remove_time_event(mvm, mvmvif, 1333 iwl_mvm_remove_time_event(mvm, mvmvif,
1257 &mvmvif->time_event_data); 1334 &mvmvif->time_event_data);
1335 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC));
1258 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | 1336 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
1259 BSS_CHANGED_QOS)) { 1337 BSS_CHANGED_QOS)) {
1260 ret = iwl_mvm_power_update_mac(mvm, vif); 1338 ret = iwl_mvm_power_update_mac(mvm, vif);
@@ -1437,8 +1515,6 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1437 struct cfg80211_scan_request *req) 1515 struct cfg80211_scan_request *req)
1438{ 1516{
1439 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1517 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1440 struct iwl_notification_wait wait_scan_done;
1441 static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, };
1442 int ret; 1518 int ret;
1443 1519
1444 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS) 1520 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
@@ -1448,22 +1524,11 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1448 1524
1449 switch (mvm->scan_status) { 1525 switch (mvm->scan_status) {
1450 case IWL_MVM_SCAN_SCHED: 1526 case IWL_MVM_SCAN_SCHED:
1451 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, 1527 ret = iwl_mvm_sched_scan_stop(mvm);
1452 scan_done_notif,
1453 ARRAY_SIZE(scan_done_notif),
1454 NULL, NULL);
1455 iwl_mvm_sched_scan_stop(mvm);
1456 ret = iwl_wait_notification(&mvm->notif_wait,
1457 &wait_scan_done, HZ);
1458 if (ret) { 1528 if (ret) {
1459 ret = -EBUSY; 1529 ret = -EBUSY;
1460 goto out; 1530 goto out;
1461 } 1531 }
1462 /* iwl_mvm_rx_scan_offload_complete_notif() will be called
1463 * soon but will not reset the scan status as it won't be
1464 * IWL_MVM_SCAN_SCHED any more since we queue the next scan
1465 * immediately (below)
1466 */
1467 break; 1532 break;
1468 case IWL_MVM_SCAN_NONE: 1533 case IWL_MVM_SCAN_NONE:
1469 break; 1534 break;
@@ -1479,7 +1544,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1479 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1544 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1480out: 1545out:
1481 mutex_unlock(&mvm->mutex); 1546 mutex_unlock(&mvm->mutex);
1482 1547 /* make sure to flush the Rx handler before the next scan arrives */
1548 iwl_mvm_wait_for_async_handlers(mvm);
1483 return ret; 1549 return ret;
1484} 1550}
1485 1551
@@ -1641,7 +1707,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1641 } else if (old_state == IEEE80211_STA_ASSOC && 1707 } else if (old_state == IEEE80211_STA_ASSOC &&
1642 new_state == IEEE80211_STA_AUTHORIZED) { 1708 new_state == IEEE80211_STA_AUTHORIZED) {
1643 /* enable beacon filtering */ 1709 /* enable beacon filtering */
1644 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC)); 1710 if (vif->bss_conf.dtim_period)
1711 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif,
1712 CMD_SYNC));
1645 ret = 0; 1713 ret = 0;
1646 } else if (old_state == IEEE80211_STA_AUTHORIZED && 1714 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
1647 new_state == IEEE80211_STA_ASSOC) { 1715 new_state == IEEE80211_STA_ASSOC) {
@@ -1738,9 +1806,26 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1738 1806
1739 mutex_lock(&mvm->mutex); 1807 mutex_lock(&mvm->mutex);
1740 1808
1741 if (mvm->scan_status != IWL_MVM_SCAN_NONE) { 1809 switch (mvm->scan_status) {
1742 IWL_DEBUG_SCAN(mvm, 1810 case IWL_MVM_SCAN_OS:
1743 "SCHED SCAN request during internal scan - abort\n"); 1811 IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
1812 ret = iwl_mvm_cancel_scan(mvm);
1813 if (ret) {
1814 ret = -EBUSY;
1815 goto out;
1816 }
1817
1818 /*
1819 * iwl_mvm_rx_scan_complete() will be called soon but will
1820 * not reset the scan status as it won't be IWL_MVM_SCAN_OS
1821 * any more since we queue the next scan immediately (below).
1822 * We make sure it is called before the next scan starts by
1823 * flushing the async-handlers work.
1824 */
1825 break;
1826 case IWL_MVM_SCAN_NONE:
1827 break;
1828 default:
1744 ret = -EBUSY; 1829 ret = -EBUSY;
1745 goto out; 1830 goto out;
1746 } 1831 }
@@ -1762,6 +1847,8 @@ err:
1762 mvm->scan_status = IWL_MVM_SCAN_NONE; 1847 mvm->scan_status = IWL_MVM_SCAN_NONE;
1763out: 1848out:
1764 mutex_unlock(&mvm->mutex); 1849 mutex_unlock(&mvm->mutex);
1850 /* make sure to flush the Rx handler before the next scan arrives */
1851 iwl_mvm_wait_for_async_handlers(mvm);
1765 return ret; 1852 return ret;
1766} 1853}
1767 1854
@@ -1769,12 +1856,14 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
1769 struct ieee80211_vif *vif) 1856 struct ieee80211_vif *vif)
1770{ 1857{
1771 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1858 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1859 int ret;
1772 1860
1773 mutex_lock(&mvm->mutex); 1861 mutex_lock(&mvm->mutex);
1774 iwl_mvm_sched_scan_stop(mvm); 1862 ret = iwl_mvm_sched_scan_stop(mvm);
1775 mutex_unlock(&mvm->mutex); 1863 mutex_unlock(&mvm->mutex);
1864 iwl_mvm_wait_for_async_handlers(mvm);
1776 1865
1777 return 0; 1866 return ret;
1778} 1867}
1779 1868
1780static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, 1869static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 302cf779c172..d564233a65da 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -230,6 +230,8 @@ enum iwl_mvm_ref_type {
230 IWL_MVM_REF_P2P_CLIENT, 230 IWL_MVM_REF_P2P_CLIENT,
231 IWL_MVM_REF_AP_IBSS, 231 IWL_MVM_REF_AP_IBSS,
232 IWL_MVM_REF_USER, 232 IWL_MVM_REF_USER,
233 IWL_MVM_REF_TX,
234 IWL_MVM_REF_TX_AGG,
233 235
234 IWL_MVM_REF_COUNT, 236 IWL_MVM_REF_COUNT,
235}; 237};
@@ -317,13 +319,13 @@ struct iwl_mvm_vif {
317 319
318 bool seqno_valid; 320 bool seqno_valid;
319 u16 seqno; 321 u16 seqno;
322#endif
320 323
321#if IS_ENABLED(CONFIG_IPV6) 324#if IS_ENABLED(CONFIG_IPV6)
322 /* IPv6 addresses for WoWLAN */ 325 /* IPv6 addresses for WoWLAN */
323 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX]; 326 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX];
324 int num_target_ipv6_addrs; 327 int num_target_ipv6_addrs;
325#endif 328#endif
326#endif
327 329
328#ifdef CONFIG_IWLWIFI_DEBUGFS 330#ifdef CONFIG_IWLWIFI_DEBUGFS
329 struct iwl_mvm *mvm; 331 struct iwl_mvm *mvm;
@@ -346,6 +348,8 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
346 return (void *)vif->drv_priv; 348 return (void *)vif->drv_priv;
347} 349}
348 350
351extern const u8 tid_to_mac80211_ac[];
352
349enum iwl_scan_status { 353enum iwl_scan_status {
350 IWL_MVM_SCAN_NONE, 354 IWL_MVM_SCAN_NONE,
351 IWL_MVM_SCAN_OS, 355 IWL_MVM_SCAN_OS,
@@ -571,6 +575,9 @@ struct iwl_mvm {
571 575
572 /* -1 for always, 0 for never, >0 for that many times */ 576 /* -1 for always, 0 for never, >0 for that many times */
573 s8 restart_fw; 577 s8 restart_fw;
578 void *fw_error_dump;
579 void *fw_error_sram;
580 u32 fw_error_sram_len;
574 581
575 struct led_classdev led; 582 struct led_classdev led;
576 583
@@ -591,12 +598,20 @@ struct iwl_mvm {
591 598
592 /* d0i3 */ 599 /* d0i3 */
593 u8 d0i3_ap_sta_id; 600 u8 d0i3_ap_sta_id;
601 bool d0i3_offloading;
594 struct work_struct d0i3_exit_work; 602 struct work_struct d0i3_exit_work;
603 struct sk_buff_head d0i3_tx;
604 /* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
605 spinlock_t d0i3_tx_lock;
606 wait_queue_head_t d0i3_exit_waitq;
595 607
596 /* BT-Coex */ 608 /* BT-Coex */
597 u8 bt_kill_msk; 609 u8 bt_kill_msk;
598 struct iwl_bt_coex_profile_notif last_bt_notif; 610 struct iwl_bt_coex_profile_notif last_bt_notif;
599 struct iwl_bt_coex_ci_cmd last_bt_ci_cmd; 611 struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
612 u32 last_ant_isol;
613 u8 last_corun_lut;
614 u8 bt_tx_prio;
600 615
601 /* Thermal Throttling and CTkill */ 616 /* Thermal Throttling and CTkill */
602 struct iwl_mvm_tt_mgmt thermal_throttle; 617 struct iwl_mvm_tt_mgmt thermal_throttle;
@@ -630,6 +645,7 @@ enum iwl_mvm_status {
630 IWL_MVM_STATUS_HW_CTKILL, 645 IWL_MVM_STATUS_HW_CTKILL,
631 IWL_MVM_STATUS_ROC_RUNNING, 646 IWL_MVM_STATUS_ROC_RUNNING,
632 IWL_MVM_STATUS_IN_HW_RESTART, 647 IWL_MVM_STATUS_IN_HW_RESTART,
648 IWL_MVM_STATUS_IN_D0I3,
633}; 649};
634 650
635static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) 651static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
@@ -656,6 +672,12 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id)
656 return iwl_mvm_sta_from_mac80211(sta); 672 return iwl_mvm_sta_from_mac80211(sta);
657} 673}
658 674
675static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
676{
677 return mvm->trans->cfg->d0i3 &&
678 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
679}
680
659extern const u8 iwl_mvm_ac_to_tx_fifo[]; 681extern const u8 iwl_mvm_ac_to_tx_fifo[];
660 682
661struct iwl_rate_info { 683struct iwl_rate_info {
@@ -680,7 +702,10 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
680 struct ieee80211_tx_rate *r); 702 struct ieee80211_tx_rate *r);
681u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); 703u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
682void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm); 704void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
683void iwl_mvm_dump_sram(struct iwl_mvm *mvm); 705#ifdef CONFIG_IWLWIFI_DEBUGFS
706void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
707void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm);
708#endif
684u8 first_antenna(u8 mask); 709u8 first_antenna(u8 mask);
685u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx); 710u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
686 711
@@ -706,6 +731,11 @@ static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
706int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync); 731int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync);
707void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm); 732void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm);
708 733
734static inline void iwl_mvm_wait_for_async_handlers(struct iwl_mvm *mvm)
735{
736 flush_work(&mvm->async_handlers_wk);
737}
738
709/* Statistics */ 739/* Statistics */
710int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm, 740int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm,
711 struct iwl_rx_cmd_buffer *rxb, 741 struct iwl_rx_cmd_buffer *rxb,
@@ -739,6 +769,9 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
739 struct iwl_device_cmd *cmd); 769 struct iwl_device_cmd *cmd);
740int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 770int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
741 struct iwl_device_cmd *cmd); 771 struct iwl_device_cmd *cmd);
772int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
773 struct iwl_rx_cmd_buffer *rxb,
774 struct iwl_device_cmd *cmd);
742int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 775int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
743 struct iwl_device_cmd *cmd); 776 struct iwl_device_cmd *cmd);
744int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm, 777int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
@@ -793,7 +826,7 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
793 struct iwl_device_cmd *cmd); 826 struct iwl_device_cmd *cmd);
794int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 827int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
795 struct iwl_device_cmd *cmd); 828 struct iwl_device_cmd *cmd);
796void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); 829int iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
797 830
798/* Scheduled scan */ 831/* Scheduled scan */
799int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 832int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
@@ -807,7 +840,7 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
807 struct cfg80211_sched_scan_request *req); 840 struct cfg80211_sched_scan_request *req);
808int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, 841int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
809 struct cfg80211_sched_scan_request *req); 842 struct cfg80211_sched_scan_request *req);
810void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm); 843int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm);
811int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm, 844int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
812 struct iwl_rx_cmd_buffer *rxb, 845 struct iwl_rx_cmd_buffer *rxb,
813 struct iwl_device_cmd *cmd); 846 struct iwl_device_cmd *cmd);
@@ -878,10 +911,17 @@ iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
878{ 911{
879} 912}
880#endif 913#endif
914void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
915 struct iwl_wowlan_config_cmd_v2 *cmd);
916int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
917 struct ieee80211_vif *vif,
918 bool disable_offloading,
919 u32 cmd_flags);
881 920
882/* D0i3 */ 921/* D0i3 */
883void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); 922void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
884void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); 923void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
924void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
885 925
886/* BT Coex */ 926/* BT Coex */
887int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); 927int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
@@ -892,10 +932,12 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
892void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 932void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
893 enum ieee80211_rssi_event rssi_event); 933 enum ieee80211_rssi_event rssi_event);
894void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm); 934void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm);
895u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, 935u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
896 struct ieee80211_sta *sta); 936 struct ieee80211_sta *sta);
897bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, 937bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
898 struct ieee80211_sta *sta); 938 struct ieee80211_sta *sta);
939u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
940 struct ieee80211_tx_info *info, u8 ac);
899int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, bool enable); 941int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, bool enable);
900 942
901enum iwl_bt_kill_msk { 943enum iwl_bt_kill_msk {
@@ -942,6 +984,8 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
942/* Low latency */ 984/* Low latency */
943int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 985int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
944 bool value); 986 bool value);
987/* get SystemLowLatencyMode - only needed for beacon threshold? */
988bool iwl_mvm_low_latency(struct iwl_mvm *mvm);
945/* get VMACLowLatencyMode */ 989/* get VMACLowLatencyMode */
946static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif) 990static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
947{ 991{
diff --git a/drivers/net/wireless/iwlwifi/mvm/offloading.c b/drivers/net/wireless/iwlwifi/mvm/offloading.c
new file mode 100644
index 000000000000..9bfb95e89cfb
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/offloading.c
@@ -0,0 +1,215 @@
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) 2012 - 2014 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) 2012 - 2014 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#include <net/ipv6.h>
64#include <net/addrconf.h>
65#include "mvm.h"
66
67void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
68 struct iwl_wowlan_config_cmd_v2 *cmd)
69{
70 int i;
71
72 /*
73 * For QoS counters, we store the one to use next, so subtract 0x10
74 * since the uCode will add 0x10 *before* using the value while we
75 * increment after using the value (i.e. store the next value to use).
76 */
77 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
78 u16 seq = mvm_ap_sta->tid_data[i].seq_number;
79 seq -= 0x10;
80 cmd->qos_seq[i] = cpu_to_le16(seq);
81 }
82}
83
84int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
85 struct ieee80211_vif *vif,
86 bool disable_offloading,
87 u32 cmd_flags)
88{
89 union {
90 struct iwl_proto_offload_cmd_v1 v1;
91 struct iwl_proto_offload_cmd_v2 v2;
92 struct iwl_proto_offload_cmd_v3_small v3s;
93 struct iwl_proto_offload_cmd_v3_large v3l;
94 } cmd = {};
95 struct iwl_host_cmd hcmd = {
96 .id = PROT_OFFLOAD_CONFIG_CMD,
97 .flags = cmd_flags,
98 .data[0] = &cmd,
99 .dataflags[0] = IWL_HCMD_DFL_DUP,
100 };
101 struct iwl_proto_offload_cmd_common *common;
102 u32 enabled = 0, size;
103 u32 capa_flags = mvm->fw->ucode_capa.flags;
104#if IS_ENABLED(CONFIG_IPV6)
105 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
106 int i;
107
108 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL ||
109 capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
110 struct iwl_ns_config *nsc;
111 struct iwl_targ_addr *addrs;
112 int n_nsc, n_addrs;
113 int c;
114
115 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
116 nsc = cmd.v3s.ns_config;
117 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S;
118 addrs = cmd.v3s.targ_addrs;
119 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S;
120 } else {
121 nsc = cmd.v3l.ns_config;
122 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L;
123 addrs = cmd.v3l.targ_addrs;
124 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
125 }
126
127 if (mvmvif->num_target_ipv6_addrs)
128 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
129
130 /*
131 * For each address we have (and that will fit) fill a target
132 * address struct and combine for NS offload structs with the
133 * solicited node addresses.
134 */
135 for (i = 0, c = 0;
136 i < mvmvif->num_target_ipv6_addrs &&
137 i < n_addrs && c < n_nsc; i++) {
138 struct in6_addr solicited_addr;
139 int j;
140
141 addrconf_addr_solict_mult(&mvmvif->target_ipv6_addrs[i],
142 &solicited_addr);
143 for (j = 0; j < c; j++)
144 if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
145 &solicited_addr) == 0)
146 break;
147 if (j == c)
148 c++;
149 addrs[i].addr = mvmvif->target_ipv6_addrs[i];
150 addrs[i].config_num = cpu_to_le32(j);
151 nsc[j].dest_ipv6_addr = solicited_addr;
152 memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN);
153 }
154
155 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL)
156 cmd.v3s.num_valid_ipv6_addrs = cpu_to_le32(i);
157 else
158 cmd.v3l.num_valid_ipv6_addrs = cpu_to_le32(i);
159 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
160 if (mvmvif->num_target_ipv6_addrs) {
161 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
162 memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN);
163 }
164
165 BUILD_BUG_ON(sizeof(cmd.v2.target_ipv6_addr[0]) !=
166 sizeof(mvmvif->target_ipv6_addrs[0]));
167
168 for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
169 IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2); i++)
170 memcpy(cmd.v2.target_ipv6_addr[i],
171 &mvmvif->target_ipv6_addrs[i],
172 sizeof(cmd.v2.target_ipv6_addr[i]));
173 } else {
174 if (mvmvif->num_target_ipv6_addrs) {
175 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
176 memcpy(cmd.v1.ndp_mac_addr, vif->addr, ETH_ALEN);
177 }
178
179 BUILD_BUG_ON(sizeof(cmd.v1.target_ipv6_addr[0]) !=
180 sizeof(mvmvif->target_ipv6_addrs[0]));
181
182 for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
183 IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1); i++)
184 memcpy(cmd.v1.target_ipv6_addr[i],
185 &mvmvif->target_ipv6_addrs[i],
186 sizeof(cmd.v1.target_ipv6_addr[i]));
187 }
188#endif
189
190 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
191 common = &cmd.v3s.common;
192 size = sizeof(cmd.v3s);
193 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
194 common = &cmd.v3l.common;
195 size = sizeof(cmd.v3l);
196 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
197 common = &cmd.v2.common;
198 size = sizeof(cmd.v2);
199 } else {
200 common = &cmd.v1.common;
201 size = sizeof(cmd.v1);
202 }
203
204 if (vif->bss_conf.arp_addr_cnt) {
205 enabled |= IWL_D3_PROTO_OFFLOAD_ARP;
206 common->host_ipv4_addr = vif->bss_conf.arp_addr_list[0];
207 memcpy(common->arp_mac_addr, vif->addr, ETH_ALEN);
208 }
209
210 if (!disable_offloading)
211 common->enabled = cpu_to_le32(enabled);
212
213 hcmd.len[0] = size;
214 return iwl_mvm_send_cmd(mvm, &hcmd);
215}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index ae347fb16a5d..9545d7fdd4bf 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -61,6 +61,7 @@
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/module.h> 63#include <linux/module.h>
64#include <linux/vmalloc.h>
64#include <net/mac80211.h> 65#include <net/mac80211.h>
65 66
66#include "iwl-notif-wait.h" 67#include "iwl-notif-wait.h"
@@ -78,6 +79,7 @@
78#include "iwl-prph.h" 79#include "iwl-prph.h"
79#include "rs.h" 80#include "rs.h"
80#include "fw-api-scan.h" 81#include "fw-api-scan.h"
82#include "fw-error-dump.h"
81#include "time-event.h" 83#include "time-event.h"
82 84
83/* 85/*
@@ -220,13 +222,15 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
220 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), 222 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
221 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false), 223 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
222 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true), 224 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
225 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
226 iwl_mvm_rx_ant_coupling_notif, true),
223 227
224 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false), 228 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
225 229
226 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false), 230 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
227 231
228 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 232 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
229 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 233 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
230 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 234 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
231 iwl_mvm_rx_scan_offload_complete_notif, true), 235 iwl_mvm_rx_scan_offload_complete_notif, true),
232 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results, 236 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results,
@@ -321,6 +325,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
321 CMD(MAC_PM_POWER_TABLE), 325 CMD(MAC_PM_POWER_TABLE),
322 CMD(BT_COEX_CI), 326 CMD(BT_COEX_CI),
323 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION), 327 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
328 CMD(ANTENNA_COUPLING_NOTIFICATION),
324}; 329};
325#undef CMD 330#undef CMD
326 331
@@ -407,6 +412,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
407 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); 412 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
408 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); 413 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
409 414
415 spin_lock_init(&mvm->d0i3_tx_lock);
416 skb_queue_head_init(&mvm->d0i3_tx);
417 init_waitqueue_head(&mvm->d0i3_exit_waitq);
418
410 SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev); 419 SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev);
411 420
412 /* 421 /*
@@ -527,6 +536,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
527 ieee80211_unregister_hw(mvm->hw); 536 ieee80211_unregister_hw(mvm->hw);
528 537
529 kfree(mvm->scan_cmd); 538 kfree(mvm->scan_cmd);
539 vfree(mvm->fw_error_dump);
540 kfree(mvm->fw_error_sram);
530 kfree(mvm->mcast_filter_cmd); 541 kfree(mvm->mcast_filter_cmd);
531 mvm->mcast_filter_cmd = NULL; 542 mvm->mcast_filter_cmd = NULL;
532 543
@@ -690,7 +701,7 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
690 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); 701 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
691} 702}
692 703
693static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) 704static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
694{ 705{
695 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 706 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
696 707
@@ -699,9 +710,9 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
699 else 710 else
700 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 711 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
701 712
702 if (state && mvm->cur_ucode != IWL_UCODE_INIT)
703 iwl_trans_stop_device(mvm->trans);
704 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); 713 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
714
715 return state && mvm->cur_ucode != IWL_UCODE_INIT;
705} 716}
706 717
707static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) 718static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
@@ -797,13 +808,52 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
797 } 808 }
798} 809}
799 810
811#ifdef CONFIG_IWLWIFI_DEBUGFS
812void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
813{
814 struct iwl_fw_error_dump_file *dump_file;
815 struct iwl_fw_error_dump_data *dump_data;
816 u32 file_len;
817
818 lockdep_assert_held(&mvm->mutex);
819
820 if (mvm->fw_error_dump)
821 return;
822
823 file_len = mvm->fw_error_sram_len +
824 sizeof(*dump_file) +
825 sizeof(*dump_data);
826
827 dump_file = vmalloc(file_len);
828 if (!dump_file)
829 return;
830
831 mvm->fw_error_dump = dump_file;
832
833 dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
834 dump_file->file_len = cpu_to_le32(file_len);
835 dump_data = (void *)dump_file->data;
836 dump_data->type = IWL_FW_ERROR_DUMP_SRAM;
837 dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
838
839 /*
840 * No need for lock since at the stage the FW isn't loaded. So it
841 * can't assert - we are the only one who can possibly be accessing
842 * mvm->fw_error_sram right now.
843 */
844 memcpy(dump_data->data, mvm->fw_error_sram, mvm->fw_error_sram_len);
845}
846#endif
847
800static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 848static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
801{ 849{
802 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 850 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
803 851
804 iwl_mvm_dump_nic_error_log(mvm); 852 iwl_mvm_dump_nic_error_log(mvm);
805 if (!mvm->restart_fw) 853
806 iwl_mvm_dump_sram(mvm); 854#ifdef CONFIG_IWLWIFI_DEBUGFS
855 iwl_mvm_fw_error_sram_dump(mvm);
856#endif
807 857
808 iwl_mvm_nic_restart(mvm); 858 iwl_mvm_nic_restart(mvm);
809} 859}
@@ -820,8 +870,62 @@ struct iwl_d0i3_iter_data {
820 struct iwl_mvm *mvm; 870 struct iwl_mvm *mvm;
821 u8 ap_sta_id; 871 u8 ap_sta_id;
822 u8 vif_count; 872 u8 vif_count;
873 u8 offloading_tid;
874 bool disable_offloading;
823}; 875};
824 876
877static bool iwl_mvm_disallow_offloading(struct iwl_mvm *mvm,
878 struct ieee80211_vif *vif,
879 struct iwl_d0i3_iter_data *iter_data)
880{
881 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
882 struct ieee80211_sta *ap_sta;
883 struct iwl_mvm_sta *mvmsta;
884 u32 available_tids = 0;
885 u8 tid;
886
887 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION ||
888 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT))
889 return false;
890
891 ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
892 if (IS_ERR_OR_NULL(ap_sta))
893 return false;
894
895 mvmsta = iwl_mvm_sta_from_mac80211(ap_sta);
896 spin_lock_bh(&mvmsta->lock);
897 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
898 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
899
900 /*
901 * in case of pending tx packets, don't use this tid
902 * for offloading in order to prevent reuse of the same
903 * qos seq counters.
904 */
905 if (iwl_mvm_tid_queued(tid_data))
906 continue;
907
908 if (tid_data->state != IWL_AGG_OFF)
909 continue;
910
911 available_tids |= BIT(tid);
912 }
913 spin_unlock_bh(&mvmsta->lock);
914
915 /*
916 * disallow protocol offloading if we have no available tid
917 * (with no pending frames and no active aggregation,
918 * as we don't handle "holes" properly - the scheduler needs the
919 * frame's seq number and TFD index to match)
920 */
921 if (!available_tids)
922 return true;
923
924 /* for simplicity, just use the first available tid */
925 iter_data->offloading_tid = ffs(available_tids) - 1;
926 return false;
927}
928
825static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac, 929static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
826 struct ieee80211_vif *vif) 930 struct ieee80211_vif *vif)
827{ 931{
@@ -835,7 +939,16 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
835 !vif->bss_conf.assoc) 939 !vif->bss_conf.assoc)
836 return; 940 return;
837 941
942 /*
943 * in case of pending tx packets or active aggregations,
944 * avoid offloading features in order to prevent reuse of
945 * the same qos seq counters.
946 */
947 if (iwl_mvm_disallow_offloading(mvm, vif, data))
948 data->disable_offloading = true;
949
838 iwl_mvm_update_d0i3_power_mode(mvm, vif, true, flags); 950 iwl_mvm_update_d0i3_power_mode(mvm, vif, true, flags);
951 iwl_mvm_send_proto_offload(mvm, vif, data->disable_offloading, flags);
839 952
840 /* 953 /*
841 * on init/association, mvm already configures POWER_TABLE_CMD 954 * on init/association, mvm already configures POWER_TABLE_CMD
@@ -847,6 +960,34 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
847 data->vif_count++; 960 data->vif_count++;
848} 961}
849 962
963static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
964 struct iwl_wowlan_config_cmd_v3 *cmd,
965 struct iwl_d0i3_iter_data *iter_data)
966{
967 struct ieee80211_sta *ap_sta;
968 struct iwl_mvm_sta *mvm_ap_sta;
969
970 if (iter_data->ap_sta_id == IWL_MVM_STATION_COUNT)
971 return;
972
973 rcu_read_lock();
974
975 ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[iter_data->ap_sta_id]);
976 if (IS_ERR_OR_NULL(ap_sta))
977 goto out;
978
979 mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
980 cmd->common.is_11n_connection = ap_sta->ht_cap.ht_supported;
981 cmd->offloading_tid = iter_data->offloading_tid;
982
983 /*
984 * The d0i3 uCode takes care of the nonqos counters,
985 * so configure only the qos seq ones.
986 */
987 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &cmd->common);
988out:
989 rcu_read_unlock();
990}
850static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) 991static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
851{ 992{
852 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 993 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
@@ -855,11 +996,14 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
855 struct iwl_d0i3_iter_data d0i3_iter_data = { 996 struct iwl_d0i3_iter_data d0i3_iter_data = {
856 .mvm = mvm, 997 .mvm = mvm,
857 }; 998 };
858 struct iwl_wowlan_config_cmd wowlan_config_cmd = { 999 struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {
859 .wakeup_filter = cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME | 1000 .common = {
860 IWL_WOWLAN_WAKEUP_BEACON_MISS | 1001 .wakeup_filter =
861 IWL_WOWLAN_WAKEUP_LINK_CHANGE | 1002 cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
862 IWL_WOWLAN_WAKEUP_BCN_FILTERING), 1003 IWL_WOWLAN_WAKEUP_BEACON_MISS |
1004 IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1005 IWL_WOWLAN_WAKEUP_BCN_FILTERING),
1006 },
863 }; 1007 };
864 struct iwl_d3_manager_config d3_cfg_cmd = { 1008 struct iwl_d3_manager_config d3_cfg_cmd = {
865 .min_sleep_time = cpu_to_le32(1000), 1009 .min_sleep_time = cpu_to_le32(1000),
@@ -867,17 +1011,24 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
867 1011
868 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n"); 1012 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
869 1013
1014 /* make sure we have no running tx while configuring the qos */
1015 set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
1016 synchronize_net();
1017
870 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 1018 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
871 IEEE80211_IFACE_ITER_NORMAL, 1019 IEEE80211_IFACE_ITER_NORMAL,
872 iwl_mvm_enter_d0i3_iterator, 1020 iwl_mvm_enter_d0i3_iterator,
873 &d0i3_iter_data); 1021 &d0i3_iter_data);
874 if (d0i3_iter_data.vif_count == 1) { 1022 if (d0i3_iter_data.vif_count == 1) {
875 mvm->d0i3_ap_sta_id = d0i3_iter_data.ap_sta_id; 1023 mvm->d0i3_ap_sta_id = d0i3_iter_data.ap_sta_id;
1024 mvm->d0i3_offloading = !d0i3_iter_data.disable_offloading;
876 } else { 1025 } else {
877 WARN_ON_ONCE(d0i3_iter_data.vif_count > 1); 1026 WARN_ON_ONCE(d0i3_iter_data.vif_count > 1);
878 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; 1027 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1028 mvm->d0i3_offloading = false;
879 } 1029 }
880 1030
1031 iwl_mvm_set_wowlan_data(mvm, &wowlan_config_cmd, &d0i3_iter_data);
881 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, flags, 1032 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, flags,
882 sizeof(wowlan_config_cmd), 1033 sizeof(wowlan_config_cmd),
883 &wowlan_config_cmd); 1034 &wowlan_config_cmd);
@@ -914,6 +1065,62 @@ static void iwl_mvm_d0i3_disconnect_iter(void *data, u8 *mac,
914 ieee80211_connection_loss(vif); 1065 ieee80211_connection_loss(vif);
915} 1066}
916 1067
1068void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
1069{
1070 struct ieee80211_sta *sta = NULL;
1071 struct iwl_mvm_sta *mvm_ap_sta;
1072 int i;
1073 bool wake_queues = false;
1074
1075 lockdep_assert_held(&mvm->mutex);
1076
1077 spin_lock_bh(&mvm->d0i3_tx_lock);
1078
1079 if (mvm->d0i3_ap_sta_id == IWL_MVM_STATION_COUNT)
1080 goto out;
1081
1082 IWL_DEBUG_RPM(mvm, "re-enqueue packets\n");
1083
1084 /* get the sta in order to update seq numbers and re-enqueue skbs */
1085 sta = rcu_dereference_protected(
1086 mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id],
1087 lockdep_is_held(&mvm->mutex));
1088
1089 if (IS_ERR_OR_NULL(sta)) {
1090 sta = NULL;
1091 goto out;
1092 }
1093
1094 if (mvm->d0i3_offloading && qos_seq) {
1095 /* update qos seq numbers if offloading was enabled */
1096 mvm_ap_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1097 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1098 u16 seq = le16_to_cpu(qos_seq[i]);
1099 /* firmware stores last-used one, we store next one */
1100 seq += 0x10;
1101 mvm_ap_sta->tid_data[i].seq_number = seq;
1102 }
1103 }
1104out:
1105 /* re-enqueue (or drop) all packets */
1106 while (!skb_queue_empty(&mvm->d0i3_tx)) {
1107 struct sk_buff *skb = __skb_dequeue(&mvm->d0i3_tx);
1108
1109 if (!sta || iwl_mvm_tx_skb(mvm, skb, sta))
1110 ieee80211_free_txskb(mvm->hw, skb);
1111
1112 /* if the skb_queue is not empty, we need to wake queues */
1113 wake_queues = true;
1114 }
1115 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
1116 wake_up(&mvm->d0i3_exit_waitq);
1117 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1118 if (wake_queues)
1119 ieee80211_wake_queues(mvm->hw);
1120
1121 spin_unlock_bh(&mvm->d0i3_tx_lock);
1122}
1123
917static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) 1124static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
918{ 1125{
919 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work); 1126 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work);
@@ -924,6 +1131,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
924 struct iwl_wowlan_status_v6 *status; 1131 struct iwl_wowlan_status_v6 *status;
925 int ret; 1132 int ret;
926 u32 disconnection_reasons, wakeup_reasons; 1133 u32 disconnection_reasons, wakeup_reasons;
1134 __le16 *qos_seq = NULL;
927 1135
928 mutex_lock(&mvm->mutex); 1136 mutex_lock(&mvm->mutex);
929 ret = iwl_mvm_send_cmd(mvm, &get_status_cmd); 1137 ret = iwl_mvm_send_cmd(mvm, &get_status_cmd);
@@ -935,6 +1143,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
935 1143
936 status = (void *)get_status_cmd.resp_pkt->data; 1144 status = (void *)get_status_cmd.resp_pkt->data;
937 wakeup_reasons = le32_to_cpu(status->wakeup_reasons); 1145 wakeup_reasons = le32_to_cpu(status->wakeup_reasons);
1146 qos_seq = status->qos_seq_ctr;
938 1147
939 IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons); 1148 IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons);
940 1149
@@ -948,6 +1157,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
948 1157
949 iwl_free_resp(&get_status_cmd); 1158 iwl_free_resp(&get_status_cmd);
950out: 1159out:
1160 iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
951 mutex_unlock(&mvm->mutex); 1161 mutex_unlock(&mvm->mutex);
952} 1162}
953 1163
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index def6ec5173b9..6b636eab3339 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -511,6 +511,7 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
511struct iwl_power_constraint { 511struct iwl_power_constraint {
512 struct ieee80211_vif *bf_vif; 512 struct ieee80211_vif *bf_vif;
513 struct ieee80211_vif *bss_vif; 513 struct ieee80211_vif *bss_vif;
514 struct ieee80211_vif *p2p_vif;
514 u16 bss_phyctx_id; 515 u16 bss_phyctx_id;
515 u16 p2p_phyctx_id; 516 u16 p2p_phyctx_id;
516 bool pm_disabled; 517 bool pm_disabled;
@@ -546,6 +547,10 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
546 if (mvmvif->phy_ctxt) 547 if (mvmvif->phy_ctxt)
547 power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id; 548 power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id;
548 549
550 /* we should have only one P2P vif */
551 WARN_ON(power_iterator->p2p_vif);
552 power_iterator->p2p_vif = vif;
553
549 IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n", 554 IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n",
550 power_iterator->p2p_phyctx_id, 555 power_iterator->p2p_phyctx_id,
551 power_iterator->bss_phyctx_id); 556 power_iterator->bss_phyctx_id);
@@ -633,16 +638,18 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
633 return ret; 638 return ret;
634 } 639 }
635 640
636 ret = iwl_mvm_power_send_cmd(mvm, vif); 641 if (constraint.bss_vif) {
637 if (ret)
638 return ret;
639
640 if (constraint.bss_vif && vif != constraint.bss_vif) {
641 ret = iwl_mvm_power_send_cmd(mvm, constraint.bss_vif); 642 ret = iwl_mvm_power_send_cmd(mvm, constraint.bss_vif);
642 if (ret) 643 if (ret)
643 return ret; 644 return ret;
644 } 645 }
645 646
647 if (constraint.p2p_vif) {
648 ret = iwl_mvm_power_send_cmd(mvm, constraint.p2p_vif);
649 if (ret)
650 return ret;
651 }
652
646 if (!constraint.bf_vif) 653 if (!constraint.bf_vif)
647 return 0; 654 return 0;
648 655
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 06d8429be1fb..35e86e06dffd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -180,7 +180,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
180 .colors = { -1, -1, -1, -1 }, 180 .colors = { -1, -1, -1, -1 },
181 .new_vif = newvif, 181 .new_vif = newvif,
182 }; 182 };
183 u32 ll_max_duration;
184 183
185 lockdep_assert_held(&mvm->mutex); 184 lockdep_assert_held(&mvm->mutex);
186 185
@@ -199,21 +198,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
199 iwl_mvm_quota_iterator(&data, newvif->addr, newvif); 198 iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
200 } 199 }
201 200
202 switch (data.n_low_latency_bindings) {
203 case 0: /* no low latency - use default */
204 ll_max_duration = 0;
205 break;
206 case 1: /* SingleBindingLowLatencyMode */
207 ll_max_duration = IWL_MVM_LOWLAT_SINGLE_BINDING_MAXDUR;
208 break;
209 case 2: /* DualBindingLowLatencyMode */
210 ll_max_duration = IWL_MVM_LOWLAT_DUAL_BINDING_MAXDUR;
211 break;
212 default: /* MultiBindingLowLatencyMode */
213 ll_max_duration = 0;
214 break;
215 }
216
217 /* 201 /*
218 * The FW's scheduling session consists of 202 * The FW's scheduling session consists of
219 * IWL_MVM_MAX_QUOTA fragments. Divide these fragments 203 * IWL_MVM_MAX_QUOTA fragments. Divide these fragments
@@ -278,7 +262,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
278 * binding. 262 * binding.
279 */ 263 */
280 cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN); 264 cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
281
282 else 265 else
283 cmd.quotas[idx].quota = 266 cmd.quotas[idx].quota =
284 cpu_to_le32(quota * data.n_interfaces[i]); 267 cpu_to_le32(quota * data.n_interfaces[i]);
@@ -287,11 +270,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
287 "Binding=%d, quota=%u > max=%u\n", 270 "Binding=%d, quota=%u > max=%u\n",
288 idx, le32_to_cpu(cmd.quotas[idx].quota), QUOTA_100); 271 idx, le32_to_cpu(cmd.quotas[idx].quota), QUOTA_100);
289 272
290 if (data.n_interfaces[i] && !data.low_latency[i]) 273 cmd.quotas[idx].max_duration = cpu_to_le32(0);
291 cmd.quotas[idx].max_duration =
292 cpu_to_le32(ll_max_duration);
293 else
294 cmd.quotas[idx].max_duration = cpu_to_le32(0);
295 274
296 idx++; 275 idx++;
297 } 276 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 399709f2be2e..568abd61b14f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -211,9 +211,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
211 .next_columns = { 211 .next_columns = {
212 RS_COLUMN_LEGACY_ANT_B, 212 RS_COLUMN_LEGACY_ANT_B,
213 RS_COLUMN_SISO_ANT_A, 213 RS_COLUMN_SISO_ANT_A,
214 RS_COLUMN_SISO_ANT_B,
214 RS_COLUMN_MIMO2, 215 RS_COLUMN_MIMO2,
215 RS_COLUMN_INVALID, 216 RS_COLUMN_MIMO2_SGI,
216 RS_COLUMN_INVALID,
217 }, 217 },
218 }, 218 },
219 [RS_COLUMN_LEGACY_ANT_B] = { 219 [RS_COLUMN_LEGACY_ANT_B] = {
@@ -221,10 +221,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
221 .ant = ANT_B, 221 .ant = ANT_B,
222 .next_columns = { 222 .next_columns = {
223 RS_COLUMN_LEGACY_ANT_A, 223 RS_COLUMN_LEGACY_ANT_A,
224 RS_COLUMN_SISO_ANT_A,
224 RS_COLUMN_SISO_ANT_B, 225 RS_COLUMN_SISO_ANT_B,
225 RS_COLUMN_MIMO2, 226 RS_COLUMN_MIMO2,
226 RS_COLUMN_INVALID, 227 RS_COLUMN_MIMO2_SGI,
227 RS_COLUMN_INVALID,
228 }, 228 },
229 }, 229 },
230 [RS_COLUMN_SISO_ANT_A] = { 230 [RS_COLUMN_SISO_ANT_A] = {
@@ -234,8 +234,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
234 RS_COLUMN_SISO_ANT_B, 234 RS_COLUMN_SISO_ANT_B,
235 RS_COLUMN_MIMO2, 235 RS_COLUMN_MIMO2,
236 RS_COLUMN_SISO_ANT_A_SGI, 236 RS_COLUMN_SISO_ANT_A_SGI,
237 RS_COLUMN_INVALID, 237 RS_COLUMN_SISO_ANT_B_SGI,
238 RS_COLUMN_INVALID, 238 RS_COLUMN_MIMO2_SGI,
239 }, 239 },
240 .checks = { 240 .checks = {
241 rs_siso_allow, 241 rs_siso_allow,
@@ -248,8 +248,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
248 RS_COLUMN_SISO_ANT_A, 248 RS_COLUMN_SISO_ANT_A,
249 RS_COLUMN_MIMO2, 249 RS_COLUMN_MIMO2,
250 RS_COLUMN_SISO_ANT_B_SGI, 250 RS_COLUMN_SISO_ANT_B_SGI,
251 RS_COLUMN_INVALID, 251 RS_COLUMN_SISO_ANT_A_SGI,
252 RS_COLUMN_INVALID, 252 RS_COLUMN_MIMO2_SGI,
253 }, 253 },
254 .checks = { 254 .checks = {
255 rs_siso_allow, 255 rs_siso_allow,
@@ -263,8 +263,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
263 RS_COLUMN_SISO_ANT_B_SGI, 263 RS_COLUMN_SISO_ANT_B_SGI,
264 RS_COLUMN_MIMO2_SGI, 264 RS_COLUMN_MIMO2_SGI,
265 RS_COLUMN_SISO_ANT_A, 265 RS_COLUMN_SISO_ANT_A,
266 RS_COLUMN_INVALID, 266 RS_COLUMN_SISO_ANT_B,
267 RS_COLUMN_INVALID, 267 RS_COLUMN_MIMO2,
268 }, 268 },
269 .checks = { 269 .checks = {
270 rs_siso_allow, 270 rs_siso_allow,
@@ -279,8 +279,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
279 RS_COLUMN_SISO_ANT_A_SGI, 279 RS_COLUMN_SISO_ANT_A_SGI,
280 RS_COLUMN_MIMO2_SGI, 280 RS_COLUMN_MIMO2_SGI,
281 RS_COLUMN_SISO_ANT_B, 281 RS_COLUMN_SISO_ANT_B,
282 RS_COLUMN_INVALID, 282 RS_COLUMN_SISO_ANT_A,
283 RS_COLUMN_INVALID, 283 RS_COLUMN_MIMO2,
284 }, 284 },
285 .checks = { 285 .checks = {
286 rs_siso_allow, 286 rs_siso_allow,
@@ -292,10 +292,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
292 .ant = ANT_AB, 292 .ant = ANT_AB,
293 .next_columns = { 293 .next_columns = {
294 RS_COLUMN_SISO_ANT_A, 294 RS_COLUMN_SISO_ANT_A,
295 RS_COLUMN_SISO_ANT_B,
296 RS_COLUMN_SISO_ANT_A_SGI,
297 RS_COLUMN_SISO_ANT_B_SGI,
295 RS_COLUMN_MIMO2_SGI, 298 RS_COLUMN_MIMO2_SGI,
296 RS_COLUMN_INVALID,
297 RS_COLUMN_INVALID,
298 RS_COLUMN_INVALID,
299 }, 299 },
300 .checks = { 300 .checks = {
301 rs_mimo_allow, 301 rs_mimo_allow,
@@ -307,10 +307,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
307 .sgi = true, 307 .sgi = true,
308 .next_columns = { 308 .next_columns = {
309 RS_COLUMN_SISO_ANT_A_SGI, 309 RS_COLUMN_SISO_ANT_A_SGI,
310 RS_COLUMN_SISO_ANT_B_SGI,
311 RS_COLUMN_SISO_ANT_A,
312 RS_COLUMN_SISO_ANT_B,
310 RS_COLUMN_MIMO2, 313 RS_COLUMN_MIMO2,
311 RS_COLUMN_INVALID,
312 RS_COLUMN_INVALID,
313 RS_COLUMN_INVALID,
314 }, 314 },
315 .checks = { 315 .checks = {
316 rs_mimo_allow, 316 rs_mimo_allow,
@@ -503,6 +503,14 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
503 window->average_tpt = IWL_INVALID_VALUE; 503 window->average_tpt = IWL_INVALID_VALUE;
504} 504}
505 505
506static void rs_rate_scale_clear_tbl_windows(struct iwl_scale_tbl_info *tbl)
507{
508 int i;
509
510 for (i = 0; i < IWL_RATE_COUNT; i++)
511 rs_rate_scale_clear_window(&tbl->win[i]);
512}
513
506static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) 514static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
507{ 515{
508 return (ant_type & valid_antenna) == ant_type; 516 return (ant_type & valid_antenna) == ant_type;
@@ -566,19 +574,13 @@ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
566 * at this rate. window->data contains the bitmask of successful 574 * at this rate. window->data contains the bitmask of successful
567 * packets. 575 * packets.
568 */ 576 */
569static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, 577static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
570 int scale_index, int attempts, int successes) 578 int scale_index, int attempts, int successes,
579 struct iwl_rate_scale_data *window)
571{ 580{
572 struct iwl_rate_scale_data *window = NULL;
573 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); 581 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
574 s32 fail_count, tpt; 582 s32 fail_count, tpt;
575 583
576 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
577 return -EINVAL;
578
579 /* Select window for current tx bit rate */
580 window = &(tbl->win[scale_index]);
581
582 /* Get expected throughput */ 584 /* Get expected throughput */
583 tpt = get_expected_tpt(tbl, scale_index); 585 tpt = get_expected_tpt(tbl, scale_index);
584 586
@@ -636,6 +638,21 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
636 return 0; 638 return 0;
637} 639}
638 640
641static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
642 int scale_index, int attempts, int successes)
643{
644 struct iwl_rate_scale_data *window = NULL;
645
646 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
647 return -EINVAL;
648
649 /* Select window for current tx bit rate */
650 window = &(tbl->win[scale_index]);
651
652 return _rs_collect_tx_data(tbl, scale_index, attempts, successes,
653 window);
654}
655
639/* Convert rs_rate object into ucode rate bitmask */ 656/* Convert rs_rate object into ucode rate bitmask */
640static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, 657static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
641 struct rs_rate *rate) 658 struct rs_rate *rate)
@@ -1361,7 +1378,6 @@ static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
1361static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) 1378static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1362{ 1379{
1363 struct iwl_scale_tbl_info *tbl; 1380 struct iwl_scale_tbl_info *tbl;
1364 int i;
1365 int active_tbl; 1381 int active_tbl;
1366 int flush_interval_passed = 0; 1382 int flush_interval_passed = 0;
1367 struct iwl_mvm *mvm; 1383 struct iwl_mvm *mvm;
@@ -1422,9 +1438,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1422 1438
1423 IWL_DEBUG_RATE(mvm, 1439 IWL_DEBUG_RATE(mvm,
1424 "LQ: stay in table clear win\n"); 1440 "LQ: stay in table clear win\n");
1425 for (i = 0; i < IWL_RATE_COUNT; i++) 1441 rs_rate_scale_clear_tbl_windows(tbl);
1426 rs_rate_scale_clear_window(
1427 &(tbl->win[i]));
1428 } 1442 }
1429 } 1443 }
1430 1444
@@ -1433,8 +1447,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1433 * "search" table). */ 1447 * "search" table). */
1434 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { 1448 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
1435 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n"); 1449 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
1436 for (i = 0; i < IWL_RATE_COUNT; i++) 1450 rs_rate_scale_clear_tbl_windows(tbl);
1437 rs_rate_scale_clear_window(&(tbl->win[i]));
1438 } 1451 }
1439 } 1452 }
1440} 1453}
@@ -1724,7 +1737,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1724 int low = IWL_RATE_INVALID; 1737 int low = IWL_RATE_INVALID;
1725 int high = IWL_RATE_INVALID; 1738 int high = IWL_RATE_INVALID;
1726 int index; 1739 int index;
1727 int i;
1728 struct iwl_rate_scale_data *window = NULL; 1740 struct iwl_rate_scale_data *window = NULL;
1729 int current_tpt = IWL_INVALID_VALUE; 1741 int current_tpt = IWL_INVALID_VALUE;
1730 int low_tpt = IWL_INVALID_VALUE; 1742 int low_tpt = IWL_INVALID_VALUE;
@@ -2009,8 +2021,7 @@ lq_update:
2009 if (lq_sta->search_better_tbl) { 2021 if (lq_sta->search_better_tbl) {
2010 /* Access the "search" table, clear its history. */ 2022 /* Access the "search" table, clear its history. */
2011 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 2023 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
2012 for (i = 0; i < IWL_RATE_COUNT; i++) 2024 rs_rate_scale_clear_tbl_windows(tbl);
2013 rs_rate_scale_clear_window(&(tbl->win[i]));
2014 2025
2015 /* Use new "search" start rate */ 2026 /* Use new "search" start rate */
2016 index = tbl->rate.index; 2027 index = tbl->rate.index;
@@ -2331,8 +2342,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2331 lq_sta->lq.sta_id = sta_priv->sta_id; 2342 lq_sta->lq.sta_id = sta_priv->sta_id;
2332 2343
2333 for (j = 0; j < LQ_SIZE; j++) 2344 for (j = 0; j < LQ_SIZE; j++)
2334 for (i = 0; i < IWL_RATE_COUNT; i++) 2345 rs_rate_scale_clear_tbl_windows(&lq_sta->lq_info[j]);
2335 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2336 2346
2337 lq_sta->flush_timer = 0; 2347 lq_sta->flush_timer = 0;
2338 2348
@@ -2591,7 +2601,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2591 2601
2592 if (sta) 2602 if (sta)
2593 lq_cmd->agg_time_limit = 2603 lq_cmd->agg_time_limit =
2594 cpu_to_le16(iwl_mvm_bt_coex_agg_time_limit(mvm, sta)); 2604 cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta));
2595} 2605}
2596 2606
2597static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 2607static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 713efd71efe2..c91dc8498852 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -70,9 +70,16 @@
70 70
71#define IWL_PLCP_QUIET_THRESH 1 71#define IWL_PLCP_QUIET_THRESH 1
72#define IWL_ACTIVE_QUIET_TIME 10 72#define IWL_ACTIVE_QUIET_TIME 10
73#define LONG_OUT_TIME_PERIOD 600 73
74#define SHORT_OUT_TIME_PERIOD 200 74struct iwl_mvm_scan_params {
75#define SUSPEND_TIME_PERIOD 100 75 u32 max_out_time;
76 u32 suspend_time;
77 bool passive_fragmented;
78 struct _dwell {
79 u16 passive;
80 u16 active;
81 } dwell[IEEE80211_NUM_BANDS];
82};
76 83
77static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 84static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
78{ 85{
@@ -90,24 +97,6 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
90 return cpu_to_le16(rx_chain); 97 return cpu_to_le16(rx_chain);
91} 98}
92 99
93static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif,
94 u32 flags, bool is_assoc)
95{
96 if (!is_assoc)
97 return 0;
98 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
99 return cpu_to_le32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
100 return cpu_to_le32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
101}
102
103static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif,
104 bool is_assoc)
105{
106 if (!is_assoc)
107 return 0;
108 return cpu_to_le32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
109}
110
111static inline __le32 100static inline __le32
112iwl_mvm_scan_rxon_flags(struct cfg80211_scan_request *req) 101iwl_mvm_scan_rxon_flags(struct cfg80211_scan_request *req)
113{ 102{
@@ -181,15 +170,14 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
181 170
182static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, 171static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
183 struct cfg80211_scan_request *req, 172 struct cfg80211_scan_request *req,
184 bool basic_ssid) 173 bool basic_ssid,
174 struct iwl_mvm_scan_params *params)
185{ 175{
186 u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band);
187 u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band,
188 req->n_ssids);
189 struct iwl_scan_channel *chan = (struct iwl_scan_channel *) 176 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
190 (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); 177 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
191 int i; 178 int i;
192 int type = BIT(req->n_ssids) - 1; 179 int type = BIT(req->n_ssids) - 1;
180 enum ieee80211_band band = req->channels[0]->band;
193 181
194 if (!basic_ssid) 182 if (!basic_ssid)
195 type |= BIT(req->n_ssids); 183 type |= BIT(req->n_ssids);
@@ -199,8 +187,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
199 chan->type = cpu_to_le32(type); 187 chan->type = cpu_to_le32(type);
200 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) 188 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
201 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 189 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
202 chan->active_dwell = cpu_to_le16(active_dwell); 190 chan->active_dwell = cpu_to_le16(params->dwell[band].active);
203 chan->passive_dwell = cpu_to_le16(passive_dwell); 191 chan->passive_dwell = cpu_to_le16(params->dwell[band].passive);
204 chan->iteration_count = cpu_to_le16(1); 192 chan->iteration_count = cpu_to_le16(1);
205 chan++; 193 chan++;
206 } 194 }
@@ -267,13 +255,76 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
267 return (u16)len; 255 return (u16)len;
268} 256}
269 257
270static void iwl_mvm_vif_assoc_iterator(void *data, u8 *mac, 258static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
271 struct ieee80211_vif *vif) 259 struct ieee80211_vif *vif)
272{ 260{
273 bool *is_assoc = data; 261 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
262 bool *global_bound = data;
274 263
275 if (vif->bss_conf.assoc) 264 if (mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < MAX_PHYS)
276 *is_assoc = true; 265 *global_bound = true;
266}
267
268static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
269 struct ieee80211_vif *vif,
270 int n_ssids,
271 struct iwl_mvm_scan_params *params)
272{
273 bool global_bound = false;
274 enum ieee80211_band band;
275
276 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
277 IEEE80211_IFACE_ITER_NORMAL,
278 iwl_mvm_scan_condition_iterator,
279 &global_bound);
280 /*
281 * Under low latency traffic passive scan is fragmented meaning
282 * that dwell on a particular channel will be fragmented. Each fragment
283 * dwell time is 20ms and fragments period is 105ms. Skipping to next
284 * channel will be delayed by the same period - 105ms. So suspend_time
285 * parameter describing both fragments and channels skipping periods is
286 * set to 105ms. This value is chosen so that overall passive scan
287 * duration will not be too long. Max_out_time in this case is set to
288 * 70ms, so for active scanning operating channel will be left for 70ms
289 * while for passive still for 20ms (fragment dwell).
290 */
291 if (global_bound) {
292 if (!iwl_mvm_low_latency(mvm)) {
293 params->suspend_time = ieee80211_tu_to_usec(100);
294 params->max_out_time = ieee80211_tu_to_usec(600);
295 } else {
296 params->suspend_time = ieee80211_tu_to_usec(105);
297 /* P2P doesn't support fragmented passive scan, so
298 * configure max_out_time to be at least longest dwell
299 * time for passive scan.
300 */
301 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
302 params->max_out_time = ieee80211_tu_to_usec(70);
303 params->passive_fragmented = true;
304 } else {
305 u32 passive_dwell;
306
307 /*
308 * Use band G so that passive channel dwell time
309 * will be assigned with maximum value.
310 */
311 band = IEEE80211_BAND_2GHZ;
312 passive_dwell = iwl_mvm_get_passive_dwell(band);
313 params->max_out_time =
314 ieee80211_tu_to_usec(passive_dwell);
315 }
316 }
317 }
318
319 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
320 if (params->passive_fragmented)
321 params->dwell[band].passive = 20;
322 else
323 params->dwell[band].passive =
324 iwl_mvm_get_passive_dwell(band);
325 params->dwell[band].active = iwl_mvm_get_active_dwell(band,
326 n_ssids);
327 }
277} 328}
278 329
279int iwl_mvm_scan_request(struct iwl_mvm *mvm, 330int iwl_mvm_scan_request(struct iwl_mvm *mvm,
@@ -288,13 +339,13 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
288 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 339 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
289 }; 340 };
290 struct iwl_scan_cmd *cmd = mvm->scan_cmd; 341 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
291 bool is_assoc = false;
292 int ret; 342 int ret;
293 u32 status; 343 u32 status;
294 int ssid_len = 0; 344 int ssid_len = 0;
295 u8 *ssid = NULL; 345 u8 *ssid = NULL;
296 bool basic_ssid = !(mvm->fw->ucode_capa.flags & 346 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
297 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID); 347 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
348 struct iwl_mvm_scan_params params = {};
298 349
299 lockdep_assert_held(&mvm->mutex); 350 lockdep_assert_held(&mvm->mutex);
300 BUG_ON(mvm->scan_cmd == NULL); 351 BUG_ON(mvm->scan_cmd == NULL);
@@ -304,17 +355,18 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
304 memset(cmd, 0, sizeof(struct iwl_scan_cmd) + 355 memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
305 mvm->fw->ucode_capa.max_probe_length + 356 mvm->fw->ucode_capa.max_probe_length +
306 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel))); 357 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
307 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 358
308 IEEE80211_IFACE_ITER_NORMAL,
309 iwl_mvm_vif_assoc_iterator,
310 &is_assoc);
311 cmd->channel_count = (u8)req->n_channels; 359 cmd->channel_count = (u8)req->n_channels;
312 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 360 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
313 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 361 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
314 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 362 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
315 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags, 363
316 is_assoc); 364 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params);
317 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc); 365 cmd->max_out_time = cpu_to_le32(params.max_out_time);
366 cmd->suspend_time = cpu_to_le32(params.suspend_time);
367 if (params.passive_fragmented)
368 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
369
318 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 370 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
319 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 371 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
320 MAC_FILTER_IN_BEACON); 372 MAC_FILTER_IN_BEACON);
@@ -360,7 +412,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
360 req->ie, req->ie_len, 412 req->ie, req->ie_len,
361 mvm->fw->ucode_capa.max_probe_length)); 413 mvm->fw->ucode_capa.max_probe_length));
362 414
363 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid); 415 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
364 416
365 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + 417 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
366 le16_to_cpu(cmd->tx_cmd.len) + 418 le16_to_cpu(cmd->tx_cmd.len) +
@@ -402,10 +454,13 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
402 struct iwl_rx_packet *pkt = rxb_addr(rxb); 454 struct iwl_rx_packet *pkt = rxb_addr(rxb);
403 struct iwl_scan_complete_notif *notif = (void *)pkt->data; 455 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
404 456
457 lockdep_assert_held(&mvm->mutex);
458
405 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n", 459 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n",
406 notif->status, notif->scanned_channels); 460 notif->status, notif->scanned_channels);
407 461
408 mvm->scan_status = IWL_MVM_SCAN_NONE; 462 if (mvm->scan_status == IWL_MVM_SCAN_OS)
463 mvm->scan_status = IWL_MVM_SCAN_NONE;
409 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK); 464 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK);
410 465
411 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 466 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
@@ -466,7 +521,7 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
466 }; 521 };
467} 522}
468 523
469void iwl_mvm_cancel_scan(struct iwl_mvm *mvm) 524int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
470{ 525{
471 struct iwl_notification_wait wait_scan_abort; 526 struct iwl_notification_wait wait_scan_abort;
472 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD, 527 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
@@ -474,13 +529,13 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
474 int ret; 529 int ret;
475 530
476 if (mvm->scan_status == IWL_MVM_SCAN_NONE) 531 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
477 return; 532 return 0;
478 533
479 if (iwl_mvm_is_radio_killed(mvm)) { 534 if (iwl_mvm_is_radio_killed(mvm)) {
480 ieee80211_scan_completed(mvm->hw, true); 535 ieee80211_scan_completed(mvm->hw, true);
481 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 536 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
482 mvm->scan_status = IWL_MVM_SCAN_NONE; 537 mvm->scan_status = IWL_MVM_SCAN_NONE;
483 return; 538 return 0;
484 } 539 }
485 540
486 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, 541 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
@@ -495,14 +550,11 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
495 goto out_remove_notif; 550 goto out_remove_notif;
496 } 551 }
497 552
498 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, 1 * HZ); 553 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, HZ);
499 if (ret)
500 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
501
502 return;
503 554
504out_remove_notif: 555out_remove_notif:
505 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort); 556 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
557 return ret;
506} 558}
507 559
508int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 560int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
@@ -519,10 +571,11 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
519 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? 571 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
520 "completed" : "aborted"); 572 "completed" : "aborted");
521 573
522 /* might already be something else again, don't reset if so */ 574 /* only call mac80211 completion if the stop was initiated by FW */
523 if (mvm->scan_status == IWL_MVM_SCAN_SCHED) 575 if (mvm->scan_status == IWL_MVM_SCAN_SCHED) {
524 mvm->scan_status = IWL_MVM_SCAN_NONE; 576 mvm->scan_status = IWL_MVM_SCAN_NONE;
525 ieee80211_sched_scan_stopped(mvm->hw); 577 ieee80211_sched_scan_stopped(mvm->hw);
578 }
526 579
527 return 0; 580 return 0;
528} 581}
@@ -553,14 +606,9 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
553static void iwl_build_scan_cmd(struct iwl_mvm *mvm, 606static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
554 struct ieee80211_vif *vif, 607 struct ieee80211_vif *vif,
555 struct cfg80211_sched_scan_request *req, 608 struct cfg80211_sched_scan_request *req,
556 struct iwl_scan_offload_cmd *scan) 609 struct iwl_scan_offload_cmd *scan,
610 struct iwl_mvm_scan_params *params)
557{ 611{
558 bool is_assoc = false;
559
560 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
561 IEEE80211_IFACE_ITER_NORMAL,
562 iwl_mvm_vif_assoc_iterator,
563 &is_assoc);
564 scan->channel_count = 612 scan->channel_count =
565 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 613 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
566 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 614 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -568,13 +616,17 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
568 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 616 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
569 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 617 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
570 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); 618 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
571 scan->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags, 619
572 is_assoc); 620 scan->max_out_time = cpu_to_le32(params->max_out_time);
573 scan->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc); 621 scan->suspend_time = cpu_to_le32(params->suspend_time);
622
574 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 623 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
575 MAC_FILTER_IN_BEACON); 624 MAC_FILTER_IN_BEACON);
576 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); 625 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
577 scan->rep_count = cpu_to_le32(1); 626 scan->rep_count = cpu_to_le32(1);
627
628 if (params->passive_fragmented)
629 scan->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
578} 630}
579 631
580static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) 632static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
@@ -639,12 +691,11 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
639 struct iwl_scan_channel_cfg *channels, 691 struct iwl_scan_channel_cfg *channels,
640 enum ieee80211_band band, 692 enum ieee80211_band band,
641 int *head, int *tail, 693 int *head, int *tail,
642 u32 ssid_bitmap) 694 u32 ssid_bitmap,
695 struct iwl_mvm_scan_params *params)
643{ 696{
644 struct ieee80211_supported_band *s_band; 697 struct ieee80211_supported_band *s_band;
645 int n_probes = req->n_ssids;
646 int n_channels = req->n_channels; 698 int n_channels = req->n_channels;
647 u8 active_dwell, passive_dwell;
648 int i, j, index = 0; 699 int i, j, index = 0;
649 bool partial; 700 bool partial;
650 701
@@ -654,8 +705,6 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
654 * to scan. So add requested channels to head of the list and others to 705 * to scan. So add requested channels to head of the list and others to
655 * the end. 706 * the end.
656 */ 707 */
657 active_dwell = iwl_mvm_get_active_dwell(band, n_probes);
658 passive_dwell = iwl_mvm_get_passive_dwell(band);
659 s_band = &mvm->nvm_data->bands[band]; 708 s_band = &mvm->nvm_data->bands[band];
660 709
661 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) { 710 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) {
@@ -679,8 +728,8 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
679 channels->channel_number[index] = 728 channels->channel_number[index] =
680 cpu_to_le16(ieee80211_frequency_to_channel( 729 cpu_to_le16(ieee80211_frequency_to_channel(
681 s_band->channels[i].center_freq)); 730 s_band->channels[i].center_freq));
682 channels->dwell_time[index][0] = active_dwell; 731 channels->dwell_time[index][0] = params->dwell[band].active;
683 channels->dwell_time[index][1] = passive_dwell; 732 channels->dwell_time[index][1] = params->dwell[band].passive;
684 733
685 channels->iter_count[index] = cpu_to_le16(1); 734 channels->iter_count[index] = cpu_to_le16(1);
686 channels->iter_interval[index] = 0; 735 channels->iter_interval[index] = 0;
@@ -709,7 +758,6 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
709 struct cfg80211_sched_scan_request *req, 758 struct cfg80211_sched_scan_request *req,
710 struct ieee80211_sched_scan_ies *ies) 759 struct ieee80211_sched_scan_ies *ies)
711{ 760{
712 int supported_bands = 0;
713 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; 761 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
714 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 762 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
715 int head = 0; 763 int head = 0;
@@ -723,22 +771,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
723 .id = SCAN_OFFLOAD_CONFIG_CMD, 771 .id = SCAN_OFFLOAD_CONFIG_CMD,
724 .flags = CMD_SYNC, 772 .flags = CMD_SYNC,
725 }; 773 };
774 struct iwl_mvm_scan_params params = {};
726 775
727 lockdep_assert_held(&mvm->mutex); 776 lockdep_assert_held(&mvm->mutex);
728 777
729 if (band_2ghz)
730 supported_bands++;
731 if (band_5ghz)
732 supported_bands++;
733
734 cmd_len = sizeof(struct iwl_scan_offload_cfg) + 778 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
735 supported_bands * SCAN_OFFLOAD_PROBE_REQ_SIZE; 779 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
736 780
737 scan_cfg = kzalloc(cmd_len, GFP_KERNEL); 781 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
738 if (!scan_cfg) 782 if (!scan_cfg)
739 return -ENOMEM; 783 return -ENOMEM;
740 784
741 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd); 785 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params);
786 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
742 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len); 787 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
743 788
744 iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap); 789 iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap);
@@ -750,7 +795,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
750 scan_cfg->data); 795 scan_cfg->data);
751 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 796 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
752 IEEE80211_BAND_2GHZ, &head, &tail, 797 IEEE80211_BAND_2GHZ, &head, &tail,
753 ssid_bitmap); 798 ssid_bitmap, &params);
754 } 799 }
755 if (band_5ghz) { 800 if (band_5ghz) {
756 iwl_scan_offload_build_tx_cmd(mvm, vif, ies, 801 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
@@ -760,7 +805,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
760 SCAN_OFFLOAD_PROBE_REQ_SIZE); 805 SCAN_OFFLOAD_PROBE_REQ_SIZE);
761 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 806 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
762 IEEE80211_BAND_5GHZ, &head, &tail, 807 IEEE80211_BAND_5GHZ, &head, &tail,
763 ssid_bitmap); 808 ssid_bitmap, &params);
764 } 809 }
765 810
766 cmd.data[0] = scan_cfg; 811 cmd.data[0] = scan_cfg;
@@ -900,26 +945,49 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
900 * microcode has notified us that a scan is completed. 945 * microcode has notified us that a scan is completed.
901 */ 946 */
902 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status); 947 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status);
903 ret = -EIO; 948 ret = -ENOENT;
904 } 949 }
905 950
906 return ret; 951 return ret;
907} 952}
908 953
909void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm) 954int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm)
910{ 955{
911 int ret; 956 int ret;
957 struct iwl_notification_wait wait_scan_done;
958 static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, };
912 959
913 lockdep_assert_held(&mvm->mutex); 960 lockdep_assert_held(&mvm->mutex);
914 961
915 if (mvm->scan_status != IWL_MVM_SCAN_SCHED) { 962 if (mvm->scan_status != IWL_MVM_SCAN_SCHED) {
916 IWL_DEBUG_SCAN(mvm, "No offloaded scan to stop\n"); 963 IWL_DEBUG_SCAN(mvm, "No offloaded scan to stop\n");
917 return; 964 return 0;
918 } 965 }
919 966
967 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
968 scan_done_notif,
969 ARRAY_SIZE(scan_done_notif),
970 NULL, NULL);
971
920 ret = iwl_mvm_send_sched_scan_abort(mvm); 972 ret = iwl_mvm_send_sched_scan_abort(mvm);
921 if (ret) 973 if (ret) {
922 IWL_DEBUG_SCAN(mvm, "Send stop offload scan failed %d\n", ret); 974 IWL_DEBUG_SCAN(mvm, "Send stop offload scan failed %d\n", ret);
923 else 975 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
924 IWL_DEBUG_SCAN(mvm, "Successfully sent stop offload scan\n"); 976 return ret;
977 }
978
979 IWL_DEBUG_SCAN(mvm, "Successfully sent stop offload scan\n");
980
981 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ);
982 if (ret)
983 return ret;
984
985 /*
986 * Clear the scan status so the next scan requests will succeed. This
987 * also ensures the Rx handler doesn't do anything, as the scan was
988 * stopped from above.
989 */
990 mvm->scan_status = IWL_MVM_SCAN_NONE;
991
992 return 0;
925} 993}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 2677d1c0e1a1..f339ef884250 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -851,7 +851,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
851 return ret; 851 return ret;
852} 852}
853 853
854static const u8 tid_to_mac80211_ac[] = { 854const u8 tid_to_mac80211_ac[] = {
855 IEEE80211_AC_BE, 855 IEEE80211_AC_BE,
856 IEEE80211_AC_BK, 856 IEEE80211_AC_BK,
857 IEEE80211_AC_BK, 857 IEEE80211_AC_BK,
@@ -902,10 +902,18 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
902 return -EIO; 902 return -EIO;
903 } 903 }
904 904
905 spin_lock_bh(&mvmsta->lock);
906
907 /* possible race condition - we entered D0i3 while starting agg */
908 if (test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)) {
909 spin_unlock_bh(&mvmsta->lock);
910 IWL_ERR(mvm, "Entered D0i3 while starting Tx agg\n");
911 return -EIO;
912 }
913
905 /* the new tx queue is still connected to the same mac80211 queue */ 914 /* the new tx queue is still connected to the same mac80211 queue */
906 mvm->queue_to_mac80211[txq_id] = vif->hw_queue[tid_to_mac80211_ac[tid]]; 915 mvm->queue_to_mac80211[txq_id] = vif->hw_queue[tid_to_mac80211_ac[tid]];
907 916
908 spin_lock_bh(&mvmsta->lock);
909 tid_data = &mvmsta->tid_data[tid]; 917 tid_data = &mvmsta->tid_data[tid];
910 tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); 918 tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
911 tid_data->txq_id = txq_id; 919 tid_data->txq_id = txq_id;
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 0ba96654d2c3..879aeac46cc1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -79,6 +79,7 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
79 __le16 fc = hdr->frame_control; 79 __le16 fc = hdr->frame_control;
80 u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); 80 u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags);
81 u32 len = skb->len + FCS_LEN; 81 u32 len = skb->len + FCS_LEN;
82 u8 ac;
82 83
83 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 84 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
84 tx_flags |= TX_CMD_FLG_ACK; 85 tx_flags |= TX_CMD_FLG_ACK;
@@ -90,13 +91,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
90 else if (ieee80211_is_back_req(fc)) 91 else if (ieee80211_is_back_req(fc))
91 tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; 92 tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
92 93
93 /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
94 if (info->band == IEEE80211_BAND_2GHZ &&
95 (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO ||
96 is_multicast_ether_addr(hdr->addr1) ||
97 ieee80211_is_back_req(fc) || ieee80211_is_mgmt(fc)))
98 tx_flags |= TX_CMD_FLG_BT_DIS;
99
100 if (ieee80211_has_morefrags(fc)) 94 if (ieee80211_has_morefrags(fc))
101 tx_flags |= TX_CMD_FLG_MORE_FRAG; 95 tx_flags |= TX_CMD_FLG_MORE_FRAG;
102 96
@@ -112,6 +106,11 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
112 tx_flags &= ~TX_CMD_FLG_SEQ_CTL; 106 tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
113 } 107 }
114 108
109 /* tid_tspec will default to 0 = BE when QOS isn't enabled */
110 ac = tid_to_mac80211_ac[tx_cmd->tid_tspec];
111 tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) <<
112 TX_CMD_FLG_BT_PRIO_POS;
113
115 if (ieee80211_is_mgmt(fc)) { 114 if (ieee80211_is_mgmt(fc)) {
116 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) 115 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
117 tx_cmd->pm_frame_timeout = cpu_to_le16(3); 116 tx_cmd->pm_frame_timeout = cpu_to_le16(3);
@@ -128,9 +127,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
128 tx_cmd->pm_frame_timeout = 0; 127 tx_cmd->pm_frame_timeout = 0;
129 } 128 }
130 129
131 if (info->flags & IEEE80211_TX_CTL_AMPDU)
132 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
133
134 if (ieee80211_is_data(fc) && len > mvm->rts_threshold && 130 if (ieee80211_is_data(fc) && len > mvm->rts_threshold &&
135 !is_multicast_ether_addr(ieee80211_get_DA(hdr))) 131 !is_multicast_ether_addr(ieee80211_get_DA(hdr)))
136 tx_flags |= TX_CMD_FLG_PROT_REQUIRE; 132 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index bbfe529d7b64..d619851745a1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -516,33 +516,26 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
516 iwl_mvm_dump_umac_error_log(mvm); 516 iwl_mvm_dump_umac_error_log(mvm);
517} 517}
518 518
519void iwl_mvm_dump_sram(struct iwl_mvm *mvm) 519void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm)
520{ 520{
521 const struct fw_img *img; 521 const struct fw_img *img;
522 int ofs, len = 0; 522 u32 ofs, sram_len;
523 int i; 523 void *sram;
524 __le32 *buf;
525 524
526 if (!mvm->ucode_loaded) 525 if (!mvm->ucode_loaded || mvm->fw_error_sram)
527 return; 526 return;
528 527
529 img = &mvm->fw->img[mvm->cur_ucode]; 528 img = &mvm->fw->img[mvm->cur_ucode];
530 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 529 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
531 len = img->sec[IWL_UCODE_SECTION_DATA].len; 530 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
532 531
533 buf = kzalloc(len, GFP_ATOMIC); 532 sram = kzalloc(sram_len, GFP_ATOMIC);
534 if (!buf) 533 if (!sram)
535 return; 534 return;
536 535
537 iwl_trans_read_mem_bytes(mvm->trans, ofs, buf, len); 536 iwl_trans_read_mem_bytes(mvm->trans, ofs, sram, sram_len);
538 len = len >> 2; 537 mvm->fw_error_sram = sram;
539 for (i = 0; i < len; i++) { 538 mvm->fw_error_sram_len = sram_len;
540 IWL_ERR(mvm, "0x%08X\n", le32_to_cpu(buf[i]));
541 /* Add a small delay to let syslog catch up */
542 udelay(10);
543 }
544
545 kfree(buf);
546} 539}
547 540
548/** 541/**
@@ -619,6 +612,9 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
619 612
620 lockdep_assert_held(&mvm->mutex); 613 lockdep_assert_held(&mvm->mutex);
621 614
615 if (mvmvif->low_latency == value)
616 return 0;
617
622 mvmvif->low_latency = value; 618 mvmvif->low_latency = value;
623 619
624 res = iwl_mvm_update_quotas(mvm, NULL); 620 res = iwl_mvm_update_quotas(mvm, NULL);
@@ -629,3 +625,22 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
629 625
630 return iwl_mvm_power_update_mac(mvm, vif); 626 return iwl_mvm_power_update_mac(mvm, vif);
631} 627}
628
629static void iwl_mvm_ll_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
630{
631 bool *result = _data;
632
633 if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(vif)))
634 *result = true;
635}
636
637bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
638{
639 bool result = false;
640
641 ieee80211_iterate_active_interfaces_atomic(
642 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
643 iwl_mvm_ll_iter, &result);
644
645 return result;
646}