aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-09-04 13:45:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-04 13:45:56 -0400
commitd17ec4d55223d9487df195012762da6f85862d4c (patch)
tree7dd8d60ed5f642add44b53f67c5a987b1145a030
parentef4ead3f29256ed83991cd77b39334aadd25672a (diff)
parent712b24adc105518f7cbbb6f9f353efea48954bb9 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scd.h118
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h67
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c76
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h48
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c106
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c104
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h41
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/offloading.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c148
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c94
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/testmode.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c61
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c24
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c23
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h8
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c137
57 files changed, 1053 insertions, 315 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 6451d2b6abcf..760e96f63bb0 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -87,6 +87,16 @@ config IWLWIFI_BCAST_FILTERING
87 If unsure, don't enable this option, as some programs might 87 If unsure, don't enable this option, as some programs might
88 expect incoming broadcasts for their normal operations. 88 expect incoming broadcasts for their normal operations.
89 89
90config IWLWIFI_UAPSD
91 bool "enable U-APSD by default"
92 depends on IWLMVM
93 help
94 Say Y here to enable U-APSD by default. This may cause
95 interoperability problems with some APs, manifesting in lower than
96 expected throughput due to those APs not enabling aggregation
97
98 If unsure, say N.
99
90menu "Debugging Options" 100menu "Debugging Options"
91 101
92config IWLWIFI_DEBUG 102config IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 3255a1723d17..d1ce3ce13591 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -580,7 +580,7 @@ turn_off:
580 * time, or we hadn't time to drain the AC queues. 580 * time, or we hadn't time to drain the AC queues.
581 */ 581 */
582 if (agg_state == IWL_AGG_ON) 582 if (agg_state == IWL_AGG_ON)
583 iwl_trans_txq_disable(priv->trans, txq_id); 583 iwl_trans_txq_disable(priv->trans, txq_id, true);
584 else 584 else
585 IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", 585 IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
586 agg_state); 586 agg_state);
@@ -686,7 +686,7 @@ int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif,
686 * time, or we hadn't time to drain the AC queues. 686 * time, or we hadn't time to drain the AC queues.
687 */ 687 */
688 if (agg_state == IWL_AGG_ON) 688 if (agg_state == IWL_AGG_ON)
689 iwl_trans_txq_disable(priv->trans, txq_id); 689 iwl_trans_txq_disable(priv->trans, txq_id, true);
690 else 690 else
691 IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", 691 IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
692 agg_state); 692 agg_state);
@@ -781,7 +781,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
781 "Can continue DELBA flow ssn = next_recl = %d\n", 781 "Can continue DELBA flow ssn = next_recl = %d\n",
782 tid_data->next_reclaimed); 782 tid_data->next_reclaimed);
783 iwl_trans_txq_disable(priv->trans, 783 iwl_trans_txq_disable(priv->trans,
784 tid_data->agg.txq_id); 784 tid_data->agg.txq_id, true);
785 iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); 785 iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id);
786 tid_data->agg.state = IWL_AGG_OFF; 786 tid_data->agg.state = IWL_AGG_OFF;
787 ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); 787 ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 48730064da73..446654aed017 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 44b19e015102..90388e70db9b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index fe129c94ae3e..23d059af6476 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 295083510e72..0a70bcd241f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -145,6 +145,7 @@ do { \
145#define IWL_DL_HCMD 0x00000004 145#define IWL_DL_HCMD 0x00000004
146#define IWL_DL_STATE 0x00000008 146#define IWL_DL_STATE 0x00000008
147/* 0x000000F0 - 0x00000010 */ 147/* 0x000000F0 - 0x00000010 */
148#define IWL_DL_QUOTA 0x00000010
148#define IWL_DL_TE 0x00000020 149#define IWL_DL_TE 0x00000020
149#define IWL_DL_EEPROM 0x00000040 150#define IWL_DL_EEPROM 0x00000040
150#define IWL_DL_RADIO 0x00000080 151#define IWL_DL_RADIO 0x00000080
@@ -189,6 +190,7 @@ do { \
189#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) 190#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
190#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) 191#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
191#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) 192#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
193#define IWL_DEBUG_QUOTA(p, f, a...) IWL_DEBUG(p, IWL_DL_QUOTA, f, ## a)
192#define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a) 194#define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a)
193#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) 195#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a)
194#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) 196#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 23e7351e02de..90987d6f348e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -36,15 +36,8 @@
36EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8); 36EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8);
37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); 37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); 38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_tx);
41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
42EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
43EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); 41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
44EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); 42EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
45EXPORT_TRACEPOINT_SYMBOL(iwlwifi_info);
46EXPORT_TRACEPOINT_SYMBOL(iwlwifi_warn);
47EXPORT_TRACEPOINT_SYMBOL(iwlwifi_crit);
48EXPORT_TRACEPOINT_SYMBOL(iwlwifi_err);
49EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dbg);
50#endif 43#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 77e3178040b2..aefd94cb6e91 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -1254,7 +1256,9 @@ struct iwl_mod_params iwlwifi_mod_params = {
1254 .bt_coex_active = true, 1256 .bt_coex_active = true,
1255 .power_level = IWL_POWER_INDEX_1, 1257 .power_level = IWL_POWER_INDEX_1,
1256 .wd_disable = true, 1258 .wd_disable = true,
1257 .uapsd_disable = false, 1259#ifndef CONFIG_IWLWIFI_UAPSD
1260 .uapsd_disable = true,
1261#endif /* CONFIG_IWLWIFI_UAPSD */
1258 /* the rest are 0 by default */ 1262 /* the rest are 0 by default */
1259}; 1263};
1260IWL_EXPORT_SYMBOL(iwlwifi_mod_params); 1264IWL_EXPORT_SYMBOL(iwlwifi_mod_params);
@@ -1370,7 +1374,11 @@ MODULE_PARM_DESC(nvm_file, "NVM file name");
1370 1374
1371module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, 1375module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
1372 bool, S_IRUGO); 1376 bool, S_IRUGO);
1377#ifdef CONFIG_IWLWIFI_UAPSD
1373MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); 1378MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)");
1379#else
1380MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: Y)");
1381#endif
1374 1382
1375/* 1383/*
1376 * set bt_coex_active to true, uCode will do kill/defer 1384 * set bt_coex_active to true, uCode will do kill/defer
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 3c72cb710b0c..be4f8972241a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index de5994a776c7..e30a41d04c8b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 929a8063354c..401f7be36b93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 1bb5193c5b1b..f68cba4e0444 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -125,6 +127,8 @@ enum iwl_ucode_tlv_flag {
125 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. 127 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
126 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 128 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
127 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. 129 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
130 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
131 * longer than the passive one, which is essential for fragmented scan.
128 */ 132 */
129enum iwl_ucode_tlv_api { 133enum iwl_ucode_tlv_api {
130 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), 134 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
@@ -133,6 +137,7 @@ enum iwl_ucode_tlv_api {
133 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), 137 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
134 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 138 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
135 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), 139 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
140 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
136}; 141};
137 142
138/** 143/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 018af2957d3b..8e7af798abd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index 99785c892f96..b6d666ee8359 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 47033a35a402..1560f4576c7d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -281,6 +283,7 @@
281#define SCD_CHAINEXT_EN (SCD_BASE + 0x244) 283#define SCD_CHAINEXT_EN (SCD_BASE + 0x244)
282#define SCD_AGGR_SEL (SCD_BASE + 0x248) 284#define SCD_AGGR_SEL (SCD_BASE + 0x248)
283#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) 285#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108)
286#define SCD_EN_CTRL (SCD_BASE + 0x254)
284 287
285static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) 288static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
286{ 289{
diff --git a/drivers/net/wireless/iwlwifi/iwl-scd.h b/drivers/net/wireless/iwlwifi/iwl-scd.h
new file mode 100644
index 000000000000..6c622b21bba7
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-scd.h
@@ -0,0 +1,118 @@
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 Mobile Communications GmbH
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 Mobile Communications GmbH
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __iwl_scd_h__
65#define __iwl_scd_h__
66
67#include "iwl-trans.h"
68#include "iwl-io.h"
69#include "iwl-prph.h"
70
71
72static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans,
73 u16 txq_id)
74{
75 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
76 (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
77 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
78}
79
80static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans,
81 u16 txq_id)
82{
83 iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id));
84}
85
86static inline void iwl_scd_txq_enable_agg(struct iwl_trans *trans,
87 u16 txq_id)
88{
89 iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
90}
91
92static inline void iwl_scd_txq_disable_agg(struct iwl_trans *trans,
93 u16 txq_id)
94{
95 iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
96}
97
98static inline void iwl_scd_disable_agg(struct iwl_trans *trans)
99{
100 iwl_set_bits_prph(trans, SCD_AGGR_SEL, 0);
101}
102
103static inline void iwl_scd_activate_fifos(struct iwl_trans *trans)
104{
105 iwl_write_prph(trans, SCD_TXFACT, IWL_MASK(0, 7));
106}
107
108static inline void iwl_scd_deactivate_fifos(struct iwl_trans *trans)
109{
110 iwl_write_prph(trans, SCD_TXFACT, 0);
111}
112
113static inline void iwl_scd_enable_set_active(struct iwl_trans *trans,
114 u32 value)
115{
116 iwl_write_prph(trans, SCD_EN_CTRL, value);
117}
118#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 656371a668da..c89985a58803 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -401,6 +403,14 @@ struct iwl_trans_dump_data {
401 403
402struct iwl_trans; 404struct iwl_trans;
403 405
406struct iwl_trans_txq_scd_cfg {
407 u8 fifo;
408 s8 sta_id;
409 u8 tid;
410 bool aggregate;
411 int frame_limit;
412};
413
404/** 414/**
405 * struct iwl_trans_ops - transport specific operations 415 * struct iwl_trans_ops - transport specific operations
406 * 416 *
@@ -437,7 +447,9 @@ struct iwl_trans;
437 * Must be atomic 447 * Must be atomic
438 * @txq_enable: setup a queue. To setup an AC queue, use the 448 * @txq_enable: setup a queue. To setup an AC queue, use the
439 * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before 449 * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before
440 * this one. The op_mode must not configure the HCMD queue. May sleep. 450 * this one. The op_mode must not configure the HCMD queue. The scheduler
451 * configuration may be %NULL, in which case the hardware will not be
452 * configured. May sleep.
441 * @txq_disable: de-configure a Tx queue to send AMPDUs 453 * @txq_disable: de-configure a Tx queue to send AMPDUs
442 * Must be atomic 454 * Must be atomic
443 * @wait_tx_queue_empty: wait until tx queues are empty. May sleep. 455 * @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
@@ -492,9 +504,10 @@ struct iwl_trans_ops {
492 void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, 504 void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
493 struct sk_buff_head *skbs); 505 struct sk_buff_head *skbs);
494 506
495 void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo, 507 void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
496 int sta_id, int tid, int frame_limit, u16 ssn); 508 const struct iwl_trans_txq_scd_cfg *cfg);
497 void (*txq_disable)(struct iwl_trans *trans, int queue); 509 void (*txq_disable)(struct iwl_trans *trans, int queue,
510 bool configure_scd);
498 511
499 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); 512 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
500 int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm); 513 int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
@@ -766,29 +779,57 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
766 trans->ops->reclaim(trans, queue, ssn, skbs); 779 trans->ops->reclaim(trans, queue, ssn, skbs);
767} 780}
768 781
769static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) 782static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
783 bool configure_scd)
770{ 784{
771 trans->ops->txq_disable(trans, queue); 785 trans->ops->txq_disable(trans, queue, configure_scd);
772} 786}
773 787
774static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, 788static inline void
775 int fifo, int sta_id, int tid, 789iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
776 int frame_limit, u16 ssn) 790 const struct iwl_trans_txq_scd_cfg *cfg)
777{ 791{
778 might_sleep(); 792 might_sleep();
779 793
780 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) 794 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
781 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); 795 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
782 796
783 trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, 797 trans->ops->txq_enable(trans, queue, ssn, cfg);
784 frame_limit, ssn); 798}
799
800static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
801 int fifo, int sta_id, int tid,
802 int frame_limit, u16 ssn)
803{
804 struct iwl_trans_txq_scd_cfg cfg = {
805 .fifo = fifo,
806 .sta_id = sta_id,
807 .tid = tid,
808 .frame_limit = frame_limit,
809 .aggregate = sta_id >= 0,
810 };
811
812 iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg);
785} 813}
786 814
787static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, 815static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
788 int fifo) 816 int fifo)
789{ 817{
790 iwl_trans_txq_enable(trans, queue, fifo, -1, 818 struct iwl_trans_txq_scd_cfg cfg = {
791 IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); 819 .fifo = fifo,
820 .sta_id = -1,
821 .tid = IWL_MAX_TID_COUNT,
822 .frame_limit = IWL_FRAME_LIMIT,
823 .aggregate = false,
824 };
825
826 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg);
827}
828
829static inline void
830iwl_trans_txq_enable_no_scd(struct iwl_trans *trans, int queue, u16 ssn)
831{
832 iwl_trans_txq_enable_cfg(trans, queue, ssn, NULL);
792} 833}
793 834
794static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, 835static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 2291bbcaaeab..2262d6dc61ae 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index a3be33359927..585c0ab4a3ec 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index ca79f7160573..dd00e8f7f765 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 645b3cfc29a5..c17be0fb7283 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -700,7 +702,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
700 return ret; 702 return ret;
701 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); 703 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
702 704
703 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); 705 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
704 if (ret) 706 if (ret)
705 return ret; 707 return ret;
706 708
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 2e90ff795c13..d919b4ebc83c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -119,6 +121,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
119 IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val); 121 IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
120 dbgfs_pm->uapsd_misbehaving = val; 122 dbgfs_pm->uapsd_misbehaving = val;
121 break; 123 break;
124 case MVM_DEBUGFS_PM_USE_PS_POLL:
125 IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val);
126 dbgfs_pm->use_ps_poll = val;
127 break;
122 } 128 }
123} 129}
124 130
@@ -169,6 +175,10 @@ static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
169 if (sscanf(buf + 18, "%d", &val) != 1) 175 if (sscanf(buf + 18, "%d", &val) != 1)
170 return -EINVAL; 176 return -EINVAL;
171 param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING; 177 param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
178 } else if (!strncmp("use_ps_poll=", buf, 12)) {
179 if (sscanf(buf + 12, "%d", &val) != 1)
180 return -EINVAL;
181 param = MVM_DEBUGFS_PM_USE_PS_POLL;
172 } else { 182 } else {
173 return -EINVAL; 183 return -EINVAL;
174 } 184 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 7d18f466fbb3..d98ee109c5e9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -257,6 +259,70 @@ static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
257 return count; 259 return count;
258} 260}
259 261
262static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file,
263 char __user *user_buf,
264 size_t count, loff_t *ppos)
265{
266 struct iwl_mvm *mvm = file->private_data;
267 char buf[16];
268 int pos;
269
270 if (!mvm->temperature_test)
271 pos = scnprintf(buf , sizeof(buf), "disabled\n");
272 else
273 pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature);
274
275 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
276}
277
278/*
279 * Set NIC Temperature
280 * Cause the driver to ignore the actual NIC temperature reported by the FW
281 * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
282 * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
283 * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
284 */
285static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
286 char *buf, size_t count,
287 loff_t *ppos)
288{
289 int temperature;
290
291 if (kstrtoint(buf, 10, &temperature))
292 return -EINVAL;
293 /* not a legal temperature */
294 if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX &&
295 temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) ||
296 temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN)
297 return -EINVAL;
298
299 mutex_lock(&mvm->mutex);
300 if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) {
301 if (!mvm->temperature_test)
302 goto out;
303
304 mvm->temperature_test = false;
305 /* Since we can't read the temp while awake, just set
306 * it to zero until we get the next RX stats from the
307 * firmware.
308 */
309 mvm->temperature = 0;
310 } else {
311 mvm->temperature_test = true;
312 mvm->temperature = temperature;
313 }
314 IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n",
315 mvm->temperature_test ? "En" : "Dis" ,
316 mvm->temperature);
317 /* handle the temperature change */
318 iwl_mvm_tt_handler(mvm);
319
320out:
321 mutex_unlock(&mvm->mutex);
322
323 return count;
324}
325
260static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 326static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
261 size_t count, loff_t *ppos) 327 size_t count, loff_t *ppos)
262{ 328{
@@ -1296,6 +1362,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1296MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); 1362MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1297MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); 1363MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1298MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); 1364MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1365MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
1299MVM_DEBUGFS_READ_FILE_OPS(stations); 1366MVM_DEBUGFS_READ_FILE_OPS(stations);
1300MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 1367MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1301MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 1368MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
@@ -1336,6 +1403,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1336 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); 1403 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR);
1337 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); 1404 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
1338 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 1405 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
1406 MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir,
1407 S_IWUSR | S_IRUSR);
1339 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 1408 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
1340 MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); 1409 MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
1341 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); 1410 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
@@ -1380,6 +1449,13 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1380 goto err; 1449 goto err;
1381#endif 1450#endif
1382 1451
1452 if (!debugfs_create_u8("low_latency_agg_frame_limit", S_IRUSR | S_IWUSR,
1453 mvm->debugfs_dir,
1454 &mvm->low_latency_agg_frame_limit))
1455 goto err;
1456 if (!debugfs_create_u8("ps_disabled", S_IRUSR,
1457 mvm->debugfs_dir, &mvm->ps_disabled))
1458 goto err;
1383 if (!debugfs_create_blob("nvm_hw", S_IRUSR, 1459 if (!debugfs_create_blob("nvm_hw", S_IRUSR,
1384 mvm->debugfs_dir, &mvm->nvm_hw_blob)) 1460 mvm->debugfs_dir, &mvm->nvm_hw_blob))
1385 goto err; 1461 goto err;
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
index e3a9774af495..8c4190e7e027 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
index 69875716dcdb..816883f9ff94 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 13696fe419b7..e74cdf2132f8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index c3a8c86b550d..27dd86395b39 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index c02a9e45ec5e..8f2216694004 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 47bd0406355d..21dd5b771660 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 95f5b3274efb..9c975f9ecfcb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -73,16 +75,20 @@
73#include "fw-api-coex.h" 75#include "fw-api-coex.h"
74#include "fw-api-scan.h" 76#include "fw-api-scan.h"
75 77
76/* maximal number of Tx queues in any platform */
77#define IWL_MVM_MAX_QUEUES 20
78
79/* Tx queue numbers */ 78/* Tx queue numbers */
80enum { 79enum {
81 IWL_MVM_OFFCHANNEL_QUEUE = 8, 80 IWL_MVM_OFFCHANNEL_QUEUE = 8,
82 IWL_MVM_CMD_QUEUE = 9, 81 IWL_MVM_CMD_QUEUE = 9,
83}; 82};
84 83
85#define IWL_MVM_CMD_FIFO 7 84enum iwl_mvm_tx_fifo {
85 IWL_MVM_TX_FIFO_BK = 0,
86 IWL_MVM_TX_FIFO_BE,
87 IWL_MVM_TX_FIFO_VI,
88 IWL_MVM_TX_FIFO_VO,
89 IWL_MVM_TX_FIFO_MCAST = 5,
90 IWL_MVM_TX_FIFO_CMD = 7,
91};
86 92
87#define IWL_MVM_STATION_COUNT 16 93#define IWL_MVM_STATION_COUNT 16
88 94
@@ -184,6 +190,8 @@ enum {
184 REPLY_RX_MPDU_CMD = 0xc1, 190 REPLY_RX_MPDU_CMD = 0xc1,
185 BA_NOTIF = 0xc5, 191 BA_NOTIF = 0xc5,
186 192
193 MARKER_CMD = 0xcb,
194
187 /* BT Coex */ 195 /* BT Coex */
188 BT_COEX_PRIO_TABLE = 0xcc, 196 BT_COEX_PRIO_TABLE = 0xcc,
189 BT_COEX_PROT_ENV = 0xcd, 197 BT_COEX_PROT_ENV = 0xcd,
@@ -1307,6 +1315,38 @@ struct iwl_bcast_filter_cmd {
1307 struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER]; 1315 struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER];
1308} __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */ 1316} __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */
1309 1317
1318/*
1319 * enum iwl_mvm_marker_id - maker ids
1320 *
1321 * The ids for different type of markers to insert into the usniffer logs
1322 */
1323enum iwl_mvm_marker_id {
1324 MARKER_ID_TX_FRAME_LATENCY = 1,
1325}; /* MARKER_ID_API_E_VER_1 */
1326
1327/**
1328 * struct iwl_mvm_marker - mark info into the usniffer logs
1329 *
1330 * (MARKER_CMD = 0xcb)
1331 *
1332 * Mark the UTC time stamp into the usniffer logs together with additional
1333 * metadata, so the usniffer output can be parsed.
1334 * In the command response the ucode will return the GP2 time.
1335 *
1336 * @dw_len: The amount of dwords following this byte including this byte.
1337 * @marker_id: A unique marker id (iwl_mvm_marker_id).
1338 * @reserved: reserved.
1339 * @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC
1340 * @metadata: additional meta data that will be written to the unsiffer log
1341 */
1342struct iwl_mvm_marker {
1343 u8 dwLen;
1344 u8 markerId;
1345 __le16 reserved;
1346 __le64 timestamp;
1347 __le32 metadata[0];
1348} __packed; /* MARKER_API_S_VER_1 */
1349
1310struct mvm_statistics_dbg { 1350struct mvm_statistics_dbg {
1311 __le32 burst_check; 1351 __le32 burst_check;
1312 __le32 burst_count; 1352 __le32 burst_count;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 883e702152d5..21d606028ca6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -242,10 +244,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
242 mvm->queue_to_mac80211[i] = i; 244 mvm->queue_to_mac80211[i] = i;
243 else 245 else
244 mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; 246 mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
245 atomic_set(&mvm->queue_stop_count[i], 0);
246 } 247 }
247 248
248 mvm->transport_queue_stop = 0; 249 for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
250 atomic_set(&mvm->mac80211_queue_stop_count[i], 0);
249 251
250 mvm->ucode_loaded = true; 252 mvm->ucode_loaded = true;
251 253
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 0e523e28cabf..9cbb192f680e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -81,7 +83,7 @@ struct iwl_mvm_mac_iface_iterator_data {
81 struct ieee80211_vif *vif; 83 struct ieee80211_vif *vif;
82 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; 84 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
83 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; 85 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
84 unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)]; 86 u32 used_hw_queues;
85 enum iwl_tsf_id preferred_tsf; 87 enum iwl_tsf_id preferred_tsf;
86 bool found_vif; 88 bool found_vif;
87}; 89};
@@ -192,12 +194,31 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
192 data->preferred_tsf = NUM_TSF_IDS; 194 data->preferred_tsf = NUM_TSF_IDS;
193} 195}
194 196
197/*
198 * Get the mask of the queues used by the vif
199 */
200u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
201 struct ieee80211_vif *vif)
202{
203 u32 qmask = 0, ac;
204
205 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
206 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
207
208 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
209 qmask |= BIT(vif->hw_queue[ac]);
210
211 if (vif->type == NL80211_IFTYPE_AP)
212 qmask |= BIT(vif->cab_queue);
213
214 return qmask;
215}
216
195static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, 217static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
196 struct ieee80211_vif *vif) 218 struct ieee80211_vif *vif)
197{ 219{
198 struct iwl_mvm_mac_iface_iterator_data *data = _data; 220 struct iwl_mvm_mac_iface_iterator_data *data = _data;
199 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 221 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
200 u32 ac;
201 222
202 /* Iterator may already find the interface being added -- skip it */ 223 /* Iterator may already find the interface being added -- skip it */
203 if (vif == data->vif) { 224 if (vif == data->vif) {
@@ -206,12 +227,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
206 } 227 }
207 228
208 /* Mark the queues used by the vif */ 229 /* Mark the queues used by the vif */
209 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 230 data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif);
210 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
211 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
212
213 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
214 __set_bit(vif->cab_queue, data->used_hw_queues);
215 231
216 /* Mark MAC IDs as used by clearing the available bit, and 232 /* Mark MAC IDs as used by clearing the available bit, and
217 * (below) mark TSFs as used if their existing use is not 233 * (below) mark TSFs as used if their existing use is not
@@ -225,24 +241,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
225 iwl_mvm_mac_tsf_id_iter(_data, mac, vif); 241 iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
226} 242}
227 243
228/*
229 * Get the mask of the queus used by the vif
230 */
231u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
232 struct ieee80211_vif *vif)
233{
234 u32 qmask = 0, ac;
235
236 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
237 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
238
239 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
240 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
241 qmask |= BIT(vif->hw_queue[ac]);
242
243 return qmask;
244}
245
246void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, 244void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
247 struct ieee80211_vif *vif) 245 struct ieee80211_vif *vif)
248{ 246{
@@ -277,15 +275,15 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
277 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, 275 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
278 /* no preference yet */ 276 /* no preference yet */
279 .preferred_tsf = NUM_TSF_IDS, 277 .preferred_tsf = NUM_TSF_IDS,
280 .used_hw_queues = { 278 .used_hw_queues =
281 BIT(IWL_MVM_OFFCHANNEL_QUEUE) | 279 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
282 BIT(mvm->aux_queue) | 280 BIT(mvm->aux_queue) |
283 BIT(IWL_MVM_CMD_QUEUE) 281 BIT(IWL_MVM_CMD_QUEUE),
284 },
285 .found_vif = false, 282 .found_vif = false,
286 }; 283 };
287 u32 ac; 284 u32 ac;
288 int ret, i; 285 int ret, i;
286 unsigned long used_hw_queues;
289 287
290 /* 288 /*
291 * Allocate a MAC ID and a TSF for this MAC, along with the queues 289 * Allocate a MAC ID and a TSF for this MAC, along with the queues
@@ -368,9 +366,11 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
368 return 0; 366 return 0;
369 } 367 }
370 368
369 used_hw_queues = data.used_hw_queues;
370
371 /* Find available queues, and allocate them to the ACs */ 371 /* Find available queues, and allocate them to the ACs */
372 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 372 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
373 u8 queue = find_first_zero_bit(data.used_hw_queues, 373 u8 queue = find_first_zero_bit(&used_hw_queues,
374 mvm->first_agg_queue); 374 mvm->first_agg_queue);
375 375
376 if (queue >= mvm->first_agg_queue) { 376 if (queue >= mvm->first_agg_queue) {
@@ -379,13 +379,13 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
379 goto exit_fail; 379 goto exit_fail;
380 } 380 }
381 381
382 __set_bit(queue, data.used_hw_queues); 382 __set_bit(queue, &used_hw_queues);
383 vif->hw_queue[ac] = queue; 383 vif->hw_queue[ac] = queue;
384 } 384 }
385 385
386 /* Allocate the CAB queue for softAP and GO interfaces */ 386 /* Allocate the CAB queue for softAP and GO interfaces */
387 if (vif->type == NL80211_IFTYPE_AP) { 387 if (vif->type == NL80211_IFTYPE_AP) {
388 u8 queue = find_first_zero_bit(data.used_hw_queues, 388 u8 queue = find_first_zero_bit(&used_hw_queues,
389 mvm->first_agg_queue); 389 mvm->first_agg_queue);
390 390
391 if (queue >= mvm->first_agg_queue) { 391 if (queue >= mvm->first_agg_queue) {
@@ -452,14 +452,16 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
452 452
453 switch (vif->type) { 453 switch (vif->type) {
454 case NL80211_IFTYPE_P2P_DEVICE: 454 case NL80211_IFTYPE_P2P_DEVICE:
455 iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE); 455 iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
456 true);
456 break; 457 break;
457 case NL80211_IFTYPE_AP: 458 case NL80211_IFTYPE_AP:
458 iwl_trans_txq_disable(mvm->trans, vif->cab_queue); 459 iwl_trans_txq_disable(mvm->trans, vif->cab_queue, true);
459 /* fall through */ 460 /* fall through */
460 default: 461 default:
461 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 462 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
462 iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]); 463 iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac],
464 true);
463 } 465 }
464} 466}
465 467
@@ -586,6 +588,7 @@ static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm,
586static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, 588static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
587 struct ieee80211_vif *vif, 589 struct ieee80211_vif *vif,
588 struct iwl_mac_ctx_cmd *cmd, 590 struct iwl_mac_ctx_cmd *cmd,
591 const u8 *bssid_override,
589 u32 action) 592 u32 action)
590{ 593{
591 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 594 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -593,6 +596,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
593 bool ht_enabled = !!(vif->bss_conf.ht_operation_mode & 596 bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
594 IEEE80211_HT_OP_MODE_PROTECTION); 597 IEEE80211_HT_OP_MODE_PROTECTION);
595 u8 cck_ack_rates, ofdm_ack_rates; 598 u8 cck_ack_rates, ofdm_ack_rates;
599 const u8 *bssid = bssid_override ?: vif->bss_conf.bssid;
596 int i; 600 int i;
597 601
598 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 602 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
@@ -625,8 +629,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
625 cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id); 629 cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id);
626 630
627 memcpy(cmd->node_addr, vif->addr, ETH_ALEN); 631 memcpy(cmd->node_addr, vif->addr, ETH_ALEN);
628 if (vif->bss_conf.bssid) 632
629 memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN); 633 if (bssid)
634 memcpy(cmd->bssid_addr, bssid, ETH_ALEN);
630 else 635 else
631 eth_broadcast_addr(cmd->bssid_addr); 636 eth_broadcast_addr(cmd->bssid_addr);
632 637
@@ -695,7 +700,8 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
695 700
696static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, 701static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
697 struct ieee80211_vif *vif, 702 struct ieee80211_vif *vif,
698 u32 action, bool force_assoc_off) 703 u32 action, bool force_assoc_off,
704 const u8 *bssid_override)
699{ 705{
700 struct iwl_mac_ctx_cmd cmd = {}; 706 struct iwl_mac_ctx_cmd cmd = {};
701 struct iwl_mac_data_sta *ctxt_sta; 707 struct iwl_mac_data_sta *ctxt_sta;
@@ -703,7 +709,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
703 WARN_ON(vif->type != NL80211_IFTYPE_STATION); 709 WARN_ON(vif->type != NL80211_IFTYPE_STATION);
704 710
705 /* Fill the common data for all mac context types */ 711 /* Fill the common data for all mac context types */
706 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 712 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, bssid_override, action);
707 713
708 if (vif->p2p) { 714 if (vif->p2p) {
709 struct ieee80211_p2p_noa_attr *noa = 715 struct ieee80211_p2p_noa_attr *noa =
@@ -784,7 +790,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
784 790
785 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); 791 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
786 792
787 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 793 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
788 794
789 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | 795 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
790 MAC_FILTER_IN_CONTROL_AND_MGMT | 796 MAC_FILTER_IN_CONTROL_AND_MGMT |
@@ -805,7 +811,7 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
805 811
806 WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); 812 WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
807 813
808 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 814 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
809 815
810 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON | 816 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
811 MAC_FILTER_IN_PROBE_REQUEST); 817 MAC_FILTER_IN_PROBE_REQUEST);
@@ -844,7 +850,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
844 850
845 WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE); 851 WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);
846 852
847 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 853 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
848 854
849 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 855 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
850 856
@@ -1072,7 +1078,7 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
1072 WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p); 1078 WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p);
1073 1079
1074 /* Fill the common data for all mac context types */ 1080 /* Fill the common data for all mac context types */
1075 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 1081 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
1076 1082
1077 /* 1083 /*
1078 * pass probe requests and beacons from other APs (needed 1084 * pass probe requests and beacons from other APs (needed
@@ -1098,7 +1104,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
1098 WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); 1104 WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);
1099 1105
1100 /* Fill the common data for all mac context types */ 1106 /* Fill the common data for all mac context types */
1101 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 1107 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
1102 1108
1103 /* 1109 /*
1104 * pass probe requests and beacons from other APs (needed 1110 * pass probe requests and beacons from other APs (needed
@@ -1121,12 +1127,14 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
1121} 1127}
1122 1128
1123static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1129static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1124 u32 action, bool force_assoc_off) 1130 u32 action, bool force_assoc_off,
1131 const u8 *bssid_override)
1125{ 1132{
1126 switch (vif->type) { 1133 switch (vif->type) {
1127 case NL80211_IFTYPE_STATION: 1134 case NL80211_IFTYPE_STATION:
1128 return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action, 1135 return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action,
1129 force_assoc_off); 1136 force_assoc_off,
1137 bssid_override);
1130 break; 1138 break;
1131 case NL80211_IFTYPE_AP: 1139 case NL80211_IFTYPE_AP:
1132 if (!vif->p2p) 1140 if (!vif->p2p)
@@ -1157,7 +1165,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1157 return -EIO; 1165 return -EIO;
1158 1166
1159 ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD, 1167 ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD,
1160 true); 1168 true, NULL);
1161 if (ret) 1169 if (ret)
1162 return ret; 1170 return ret;
1163 1171
@@ -1169,7 +1177,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1169} 1177}
1170 1178
1171int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1179int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1172 bool force_assoc_off) 1180 bool force_assoc_off, const u8 *bssid_override)
1173{ 1181{
1174 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1182 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1175 1183
@@ -1178,7 +1186,7 @@ int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1178 return -EIO; 1186 return -EIO;
1179 1187
1180 return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY, 1188 return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY,
1181 force_assoc_off); 1189 force_assoc_off, bssid_override);
1182} 1190}
1183 1191
1184int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 1192int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 7c8796584c25..8d1d4b40b0a3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -776,6 +778,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
776 iwl_trans_stop_device(mvm->trans); 778 iwl_trans_stop_device(mvm->trans);
777 779
778 mvm->scan_status = IWL_MVM_SCAN_NONE; 780 mvm->scan_status = IWL_MVM_SCAN_NONE;
781 mvm->ps_disabled = false;
779 782
780 /* just in case one was running */ 783 /* just in case one was running */
781 ieee80211_remain_on_channel_expired(mvm->hw); 784 ieee80211_remain_on_channel_expired(mvm->hw);
@@ -803,6 +806,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
803 * ucode_down ref until reconfig is complete */ 806 * ucode_down ref until reconfig is complete */
804 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); 807 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
805 808
809 /* clear any stale d0i3 state */
810 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
811
806 mvm->vif_count = 0; 812 mvm->vif_count = 0;
807 mvm->rx_ba_sessions = 0; 813 mvm->rx_ba_sessions = 0;
808} 814}
@@ -880,7 +886,7 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
880 /* async_handlers_list is empty and will stay empty: HW is stopped */ 886 /* async_handlers_list is empty and will stay empty: HW is stopped */
881 887
882 /* the fw is stopped, the aux sta is dead: clean up driver state */ 888 /* the fw is stopped, the aux sta is dead: clean up driver state */
883 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); 889 iwl_mvm_del_aux_sta(mvm);
884 890
885 mutex_unlock(&mvm->mutex); 891 mutex_unlock(&mvm->mutex);
886 892
@@ -965,10 +971,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
965 */ 971 */
966 if (vif->type == NL80211_IFTYPE_AP || 972 if (vif->type == NL80211_IFTYPE_AP ||
967 vif->type == NL80211_IFTYPE_ADHOC) { 973 vif->type == NL80211_IFTYPE_ADHOC) {
968 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); 974 ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
969 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
970 qmask,
971 ieee80211_vif_type_p2p(vif));
972 if (ret) { 975 if (ret) {
973 IWL_ERR(mvm, "Failed to allocate bcast sta\n"); 976 IWL_ERR(mvm, "Failed to allocate bcast sta\n");
974 goto out_release; 977 goto out_release;
@@ -1016,7 +1019,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1016 if (ret) 1019 if (ret)
1017 goto out_unref_phy; 1020 goto out_unref_phy;
1018 1021
1019 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); 1022 ret = iwl_mvm_add_bcast_sta(mvm, vif);
1020 if (ret) 1023 if (ret)
1021 goto out_unbind; 1024 goto out_unbind;
1022 1025
@@ -1057,14 +1060,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1057static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, 1060static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
1058 struct ieee80211_vif *vif) 1061 struct ieee80211_vif *vif)
1059{ 1062{
1060 u32 tfd_msk = 0, ac; 1063 u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif);
1061
1062 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
1063 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
1064 tfd_msk |= BIT(vif->hw_queue[ac]);
1065
1066 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
1067 tfd_msk |= BIT(vif->cab_queue);
1068 1064
1069 if (tfd_msk) { 1065 if (tfd_msk) {
1070 mutex_lock(&mvm->mutex); 1066 mutex_lock(&mvm->mutex);
@@ -1120,13 +1116,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
1120 mvm->noa_duration = 0; 1116 mvm->noa_duration = 0;
1121 } 1117 }
1122#endif 1118#endif
1123 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); 1119 iwl_mvm_dealloc_bcast_sta(mvm, vif);
1124 goto out_release; 1120 goto out_release;
1125 } 1121 }
1126 1122
1127 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 1123 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1128 mvm->p2p_device_vif = NULL; 1124 mvm->p2p_device_vif = NULL;
1129 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1125 iwl_mvm_rm_bcast_sta(mvm, vif);
1130 iwl_mvm_binding_remove_vif(mvm, vif); 1126 iwl_mvm_binding_remove_vif(mvm, vif);
1131 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); 1127 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1132 mvmvif->phy_ctxt = NULL; 1128 mvmvif->phy_ctxt = NULL;
@@ -1445,10 +1441,23 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1445 if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) 1441 if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
1446 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); 1442 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
1447 1443
1448 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); 1444 /*
1445 * If we're not associated yet, take the (new) BSSID before associating
1446 * so the firmware knows. If we're already associated, then use the old
1447 * BSSID here, and we'll send a cleared one later in the CHANGED_ASSOC
1448 * branch for disassociation below.
1449 */
1450 if (changes & BSS_CHANGED_BSSID && !mvmvif->associated)
1451 memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
1452
1453 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid);
1449 if (ret) 1454 if (ret)
1450 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 1455 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1451 1456
1457 /* after sending it once, adopt mac80211 data */
1458 memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
1459 mvmvif->associated = bss_conf->assoc;
1460
1452 if (changes & BSS_CHANGED_ASSOC) { 1461 if (changes & BSS_CHANGED_ASSOC) {
1453 if (bss_conf->assoc) { 1462 if (bss_conf->assoc) {
1454 /* add quota for this interface */ 1463 /* add quota for this interface */
@@ -1476,13 +1485,17 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1476 */ 1485 */
1477 u32 dur = (11 * vif->bss_conf.beacon_int) / 10; 1486 u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
1478 iwl_mvm_protect_session(mvm, vif, dur, dur, 1487 iwl_mvm_protect_session(mvm, vif, dur, dur,
1479 5 * dur); 1488 5 * dur, false);
1480 } 1489 }
1481 1490
1482 iwl_mvm_sf_update(mvm, vif, false); 1491 iwl_mvm_sf_update(mvm, vif, false);
1483 iwl_mvm_power_vif_assoc(mvm, vif); 1492 iwl_mvm_power_vif_assoc(mvm, vif);
1484 if (vif->p2p) 1493 if (vif->p2p) {
1485 iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT); 1494 iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT);
1495 iwl_mvm_update_smps(mvm, vif,
1496 IWL_MVM_SMPS_REQ_PROT,
1497 IEEE80211_SMPS_DYNAMIC);
1498 }
1486 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 1499 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
1487 /* 1500 /*
1488 * If update fails - SF might be running in associated 1501 * If update fails - SF might be running in associated
@@ -1506,6 +1519,13 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1506 1519
1507 if (vif->p2p) 1520 if (vif->p2p)
1508 iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT); 1521 iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT);
1522
1523 /* this will take the cleared BSSID from bss_conf */
1524 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
1525 if (ret)
1526 IWL_ERR(mvm,
1527 "failed to update MAC %pM (clear after unassoc)\n",
1528 vif->addr);
1509 } 1529 }
1510 1530
1511 iwl_mvm_recalc_multicast(mvm); 1531 iwl_mvm_recalc_multicast(mvm);
@@ -1601,7 +1621,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1601 1621
1602 /* Send the bcast station. At this stage the TBTT and DTIM time events 1622 /* Send the bcast station. At this stage the TBTT and DTIM time events
1603 * are added and applied to the scheduler */ 1623 * are added and applied to the scheduler */
1604 ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta); 1624 ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
1605 if (ret) 1625 if (ret)
1606 goto out_unbind; 1626 goto out_unbind;
1607 1627
@@ -1617,7 +1637,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1617 1637
1618 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 1638 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
1619 if (vif->p2p && mvm->p2p_device_vif) 1639 if (vif->p2p && mvm->p2p_device_vif)
1620 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); 1640 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
1621 1641
1622 iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS); 1642 iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS);
1623 1643
@@ -1633,7 +1653,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1633out_quota_failed: 1653out_quota_failed:
1634 iwl_mvm_power_update_mac(mvm); 1654 iwl_mvm_power_update_mac(mvm);
1635 mvmvif->ap_ibss_active = false; 1655 mvmvif->ap_ibss_active = false;
1636 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1656 iwl_mvm_send_rm_bcast_sta(mvm, vif);
1637out_unbind: 1657out_unbind:
1638 iwl_mvm_binding_remove_vif(mvm, vif); 1658 iwl_mvm_binding_remove_vif(mvm, vif);
1639out_remove: 1659out_remove:
@@ -1675,10 +1695,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
1675 1695
1676 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 1696 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
1677 if (vif->p2p && mvm->p2p_device_vif) 1697 if (vif->p2p && mvm->p2p_device_vif)
1678 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); 1698 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
1679 1699
1680 iwl_mvm_update_quotas(mvm, NULL); 1700 iwl_mvm_update_quotas(mvm, NULL);
1681 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1701 iwl_mvm_send_rm_bcast_sta(mvm, vif);
1682 iwl_mvm_binding_remove_vif(mvm, vif); 1702 iwl_mvm_binding_remove_vif(mvm, vif);
1683 1703
1684 iwl_mvm_power_update_mac(mvm); 1704 iwl_mvm_power_update_mac(mvm);
@@ -1702,7 +1722,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
1702 1722
1703 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | 1723 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT |
1704 BSS_CHANGED_BANDWIDTH) && 1724 BSS_CHANGED_BANDWIDTH) &&
1705 iwl_mvm_mac_ctxt_changed(mvm, vif, false)) 1725 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL))
1706 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 1726 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1707 1727
1708 /* Need to send a new beacon template to the FW */ 1728 /* Need to send a new beacon template to the FW */
@@ -2113,7 +2133,7 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
2113 int ret; 2133 int ret;
2114 2134
2115 mutex_lock(&mvm->mutex); 2135 mutex_lock(&mvm->mutex);
2116 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); 2136 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2117 mutex_unlock(&mvm->mutex); 2137 mutex_unlock(&mvm->mutex);
2118 return ret; 2138 return ret;
2119 } 2139 }
@@ -2141,7 +2161,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
2141 2161
2142 mutex_lock(&mvm->mutex); 2162 mutex_lock(&mvm->mutex);
2143 /* Try really hard to protect the session and hear a beacon */ 2163 /* Try really hard to protect the session and hear a beacon */
2144 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500); 2164 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
2145 mutex_unlock(&mvm->mutex); 2165 mutex_unlock(&mvm->mutex);
2146 2166
2147 iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); 2167 iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
@@ -2162,7 +2182,7 @@ static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
2162 2182
2163 mutex_lock(&mvm->mutex); 2183 mutex_lock(&mvm->mutex);
2164 /* Protect the session to hear the TDLS setup response on the channel */ 2184 /* Protect the session to hear the TDLS setup response on the channel */
2165 iwl_mvm_protect_session(mvm, vif, duration, duration, 100); 2185 iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
2166 mutex_unlock(&mvm->mutex); 2186 mutex_unlock(&mvm->mutex);
2167 2187
2168 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); 2188 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
@@ -2700,7 +2720,10 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
2700 ret = 0; 2720 ret = 0;
2701 goto out; 2721 goto out;
2702 case NL80211_IFTYPE_STATION: 2722 case NL80211_IFTYPE_STATION:
2723 break;
2703 case NL80211_IFTYPE_MONITOR: 2724 case NL80211_IFTYPE_MONITOR:
2725 /* always disable PS when a monitor interface is active */
2726 mvmvif->ps_disabled = true;
2704 break; 2727 break;
2705 default: 2728 default:
2706 ret = -EINVAL; 2729 ret = -EINVAL;
@@ -2732,7 +2755,20 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
2732 if ((vif->type == NL80211_IFTYPE_AP) || 2755 if ((vif->type == NL80211_IFTYPE_AP) ||
2733 (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) { 2756 (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) {
2734 iwl_mvm_update_quotas(mvm, NULL); 2757 iwl_mvm_update_quotas(mvm, NULL);
2735 iwl_mvm_mac_ctxt_changed(mvm, vif, false); 2758 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2759 }
2760
2761 if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) {
2762 struct iwl_mvm_sta *mvmsta;
2763
2764 mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
2765 mvmvif->ap_sta_id);
2766
2767 if (WARN_ON(!mvmsta))
2768 goto out;
2769
2770 /* TODO: only re-enable after the first beacon */
2771 iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
2736 } 2772 }
2737 2773
2738 goto out; 2774 goto out;
@@ -2766,6 +2802,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
2766{ 2802{
2767 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2803 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2768 struct ieee80211_vif *disabled_vif = NULL; 2804 struct ieee80211_vif *disabled_vif = NULL;
2805 struct iwl_mvm_sta *mvmsta;
2769 2806
2770 lockdep_assert_held(&mvm->mutex); 2807 lockdep_assert_held(&mvm->mutex);
2771 2808
@@ -2776,6 +2813,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
2776 goto out; 2813 goto out;
2777 case NL80211_IFTYPE_MONITOR: 2814 case NL80211_IFTYPE_MONITOR:
2778 mvmvif->monitor_active = false; 2815 mvmvif->monitor_active = false;
2816 mvmvif->ps_disabled = false;
2779 break; 2817 break;
2780 case NL80211_IFTYPE_AP: 2818 case NL80211_IFTYPE_AP:
2781 /* This part is triggered only during CSA */ 2819 /* This part is triggered only during CSA */
@@ -2796,7 +2834,13 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
2796 2834
2797 disabled_vif = vif; 2835 disabled_vif = vif;
2798 2836
2799 iwl_mvm_mac_ctxt_changed(mvm, vif, true); 2837 mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
2838 mvmvif->ap_sta_id);
2839
2840 if (!WARN_ON(!mvmsta))
2841 iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true);
2842
2843 iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
2800 break; 2844 break;
2801 default: 2845 default:
2802 break; 2846 break;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 2e73d3bd7757..e292de96e09a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -103,14 +105,6 @@
103 */ 105 */
104#define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3 106#define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3
105 107
106enum iwl_mvm_tx_fifo {
107 IWL_MVM_TX_FIFO_BK = 0,
108 IWL_MVM_TX_FIFO_BE,
109 IWL_MVM_TX_FIFO_VI,
110 IWL_MVM_TX_FIFO_VO,
111 IWL_MVM_TX_FIFO_MCAST = 5,
112};
113
114extern const struct ieee80211_ops iwl_mvm_hw_ops; 108extern const struct ieee80211_ops iwl_mvm_hw_ops;
115 109
116/** 110/**
@@ -203,6 +197,7 @@ enum iwl_dbgfs_pm_mask {
203 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), 197 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
204 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), 198 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8),
205 MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9), 199 MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9),
200 MVM_DEBUGFS_PM_USE_PS_POLL = BIT(10),
206}; 201};
207 202
208struct iwl_dbgfs_pm { 203struct iwl_dbgfs_pm {
@@ -215,6 +210,7 @@ struct iwl_dbgfs_pm {
215 u32 lprx_rssi_threshold; 210 u32 lprx_rssi_threshold;
216 bool snooze_ena; 211 bool snooze_ena;
217 bool uapsd_misbehaving; 212 bool uapsd_misbehaving;
213 bool use_ps_poll;
218 int mask; 214 int mask;
219}; 215};
220 216
@@ -253,6 +249,7 @@ struct iwl_dbgfs_bf {
253enum iwl_mvm_smps_type_request { 249enum iwl_mvm_smps_type_request {
254 IWL_MVM_SMPS_REQ_BT_COEX, 250 IWL_MVM_SMPS_REQ_BT_COEX,
255 IWL_MVM_SMPS_REQ_TT, 251 IWL_MVM_SMPS_REQ_TT,
252 IWL_MVM_SMPS_REQ_PROT,
256 NUM_IWL_MVM_SMPS_REQ, 253 NUM_IWL_MVM_SMPS_REQ,
257}; 254};
258 255
@@ -315,6 +312,9 @@ struct iwl_mvm_vif_bf_data {
315 * @id: between 0 and 3 312 * @id: between 0 and 3
316 * @color: to solve races upon MAC addition and removal 313 * @color: to solve races upon MAC addition and removal
317 * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA 314 * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
315 * @bssid: BSSID for this (client) interface
316 * @associated: indicates that we're currently associated, used only for
317 * managing the firmware state in iwl_mvm_bss_info_changed_station()
318 * @uploaded: indicates the MAC context has been added to the device 318 * @uploaded: indicates the MAC context has been added to the device
319 * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface 319 * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
320 * should get quota etc. 320 * should get quota etc.
@@ -323,6 +323,7 @@ struct iwl_mvm_vif_bf_data {
323 * interface should get quota etc. 323 * interface should get quota etc.
324 * @low_latency: indicates that this interface is in low-latency mode 324 * @low_latency: indicates that this interface is in low-latency mode
325 * (VMACLowLatencyMode) 325 * (VMACLowLatencyMode)
326 * @ps_disabled: indicates that this interface requires PS to be disabled
326 * @queue_params: QoS params for this MAC 327 * @queue_params: QoS params for this MAC
327 * @bcast_sta: station used for broadcast packets. Used by the following 328 * @bcast_sta: station used for broadcast packets. Used by the following
328 * vifs: P2P_DEVICE, GO and AP. 329 * vifs: P2P_DEVICE, GO and AP.
@@ -335,11 +336,15 @@ struct iwl_mvm_vif {
335 u16 color; 336 u16 color;
336 u8 ap_sta_id; 337 u8 ap_sta_id;
337 338
339 u8 bssid[ETH_ALEN];
340 bool associated;
341
338 bool uploaded; 342 bool uploaded;
339 bool ap_ibss_active; 343 bool ap_ibss_active;
340 bool pm_enabled; 344 bool pm_enabled;
341 bool monitor_active; 345 bool monitor_active;
342 bool low_latency; 346 bool low_latency;
347 bool ps_disabled;
343 struct iwl_mvm_vif_bf_data bf_data; 348 struct iwl_mvm_vif_bf_data bf_data;
344 349
345 u32 ap_beacon_time; 350 u32 ap_beacon_time;
@@ -512,6 +517,10 @@ enum {
512 D0I3_PENDING_WAKEUP, 517 D0I3_PENDING_WAKEUP,
513}; 518};
514 519
520#define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff
521#define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100
522#define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200
523
515struct iwl_mvm { 524struct iwl_mvm {
516 /* for logger access */ 525 /* for logger access */
517 struct device *dev; 526 struct device *dev;
@@ -553,9 +562,8 @@ struct iwl_mvm {
553 562
554 struct mvm_statistics_rx rx_stats; 563 struct mvm_statistics_rx rx_stats;
555 564
556 unsigned long transport_queue_stop;
557 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; 565 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
558 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; 566 atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES];
559 567
560 const char *nvm_file_name; 568 const char *nvm_file_name;
561 struct iwl_nvm_data *nvm_data; 569 struct iwl_nvm_data *nvm_data;
@@ -694,6 +702,12 @@ struct iwl_mvm {
694 /* Thermal Throttling and CTkill */ 702 /* Thermal Throttling and CTkill */
695 struct iwl_mvm_tt_mgmt thermal_throttle; 703 struct iwl_mvm_tt_mgmt thermal_throttle;
696 s32 temperature; /* Celsius */ 704 s32 temperature; /* Celsius */
705 /*
706 * Debug option to set the NIC temperature. This option makes the
707 * driver think this is the actual NIC temperature, and ignore the
708 * real temperature that is received from the fw
709 */
710 bool temperature_test; /* Debug test temperature is enabled */
697 711
698#ifdef CONFIG_NL80211_TESTMODE 712#ifdef CONFIG_NL80211_TESTMODE
699 u32 noa_duration; 713 u32 noa_duration;
@@ -706,7 +720,7 @@ struct iwl_mvm {
706 u8 last_agg_queue; 720 u8 last_agg_queue;
707 721
708 /* Indicate if device power save is allowed */ 722 /* Indicate if device power save is allowed */
709 bool ps_disabled; 723 u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */
710 724
711 struct ieee80211_vif __rcu *csa_vif; 725 struct ieee80211_vif __rcu *csa_vif;
712 struct ieee80211_vif __rcu *csa_tx_blocked_vif; 726 struct ieee80211_vif __rcu *csa_tx_blocked_vif;
@@ -714,6 +728,8 @@ struct iwl_mvm {
714 728
715 /* system time of last beacon (for AP/GO interface) */ 729 /* system time of last beacon (for AP/GO interface) */
716 u32 ap_last_beacon_gp2; 730 u32 ap_last_beacon_gp2;
731
732 u8 low_latency_agg_frame_limit;
717}; 733};
718 734
719/* Extract MVM priv from op_mode and _hw */ 735/* Extract MVM priv from op_mode and _hw */
@@ -878,7 +894,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
878void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 894void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
879int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 895int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
880int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 896int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
881 bool force_assoc_off); 897 bool force_assoc_off, const u8 *bssid_override);
882int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 898int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
883u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, 899u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
884 struct ieee80211_vif *vif); 900 struct ieee80211_vif *vif);
@@ -968,6 +984,7 @@ int rs_pretty_print_rate(char *buf, const u32 rate);
968/* power management */ 984/* power management */
969int iwl_mvm_power_update_device(struct iwl_mvm *mvm); 985int iwl_mvm_power_update_device(struct iwl_mvm *mvm);
970int iwl_mvm_power_update_mac(struct iwl_mvm *mvm); 986int iwl_mvm_power_update_mac(struct iwl_mvm *mvm);
987int iwl_mvm_power_update_ps(struct iwl_mvm *mvm);
971int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 988int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
972 char *buf, int bufsz); 989 char *buf, int bufsz);
973 990
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index cfdd314fdd5d..4fafd4bd89f4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/offloading.c b/drivers/net/wireless/iwlwifi/mvm/offloading.c
index 9bfb95e89cfb..adcbf4c8edd8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/offloading.c
+++ b/drivers/net/wireless/iwlwifi/mvm/offloading.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 610dbcb0dc27..87f278cc9b2c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -415,6 +417,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
415 mvm->first_agg_queue = 12; 417 mvm->first_agg_queue = 12;
416 } 418 }
417 mvm->sf_state = SF_UNINIT; 419 mvm->sf_state = SF_UNINIT;
420 mvm->low_latency_agg_frame_limit = 1;
418 421
419 mutex_init(&mvm->mutex); 422 mutex_init(&mvm->mutex);
420 mutex_init(&mvm->d0i3_suspend_mutex); 423 mutex_init(&mvm->d0i3_suspend_mutex);
@@ -456,7 +459,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
456 trans_cfg.command_names = iwl_mvm_cmd_strings; 459 trans_cfg.command_names = iwl_mvm_cmd_strings;
457 460
458 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; 461 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
459 trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO; 462 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
460 463
461 snprintf(mvm->hw->wiphy->fw_version, 464 snprintf(mvm->hw->wiphy->fw_version,
462 sizeof(mvm->hw->wiphy->fw_version), 465 sizeof(mvm->hw->wiphy->fw_version),
@@ -494,7 +497,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
494 goto out_free; 497 goto out_free;
495 498
496 /* 499 /*
497 * Even if nvm exists in the nvm_file driver should read agin the nvm 500 * Even if nvm exists in the nvm_file driver should read again the nvm
498 * from the nic because there might be entries that exist in the OTP 501 * from the nic because there might be entries that exist in the OTP
499 * and not in the file. 502 * and not in the file.
500 * for nics with no_power_up_nic_in_init: rely completley on nvm_file 503 * for nics with no_power_up_nic_in_init: rely completley on nvm_file
@@ -700,14 +703,13 @@ static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
700 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) 703 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
701 return; 704 return;
702 705
703 if (atomic_inc_return(&mvm->queue_stop_count[mq]) > 1) { 706 if (atomic_inc_return(&mvm->mac80211_queue_stop_count[mq]) > 1) {
704 IWL_DEBUG_TX_QUEUES(mvm, 707 IWL_DEBUG_TX_QUEUES(mvm,
705 "queue %d (mac80211 %d) already stopped\n", 708 "queue %d (mac80211 %d) already stopped\n",
706 queue, mq); 709 queue, mq);
707 return; 710 return;
708 } 711 }
709 712
710 set_bit(mq, &mvm->transport_queue_stop);
711 ieee80211_stop_queue(mvm->hw, mq); 713 ieee80211_stop_queue(mvm->hw, mq);
712} 714}
713 715
@@ -719,15 +721,13 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
719 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) 721 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
720 return; 722 return;
721 723
722 if (atomic_dec_return(&mvm->queue_stop_count[mq]) > 0) { 724 if (atomic_dec_return(&mvm->mac80211_queue_stop_count[mq]) > 0) {
723 IWL_DEBUG_TX_QUEUES(mvm, 725 IWL_DEBUG_TX_QUEUES(mvm,
724 "queue %d (mac80211 %d) already awake\n", 726 "queue %d (mac80211 %d) still stopped\n",
725 queue, mq); 727 queue, mq);
726 return; 728 return;
727 } 729 }
728 730
729 clear_bit(mq, &mvm->transport_queue_stop);
730
731 ieee80211_wake_queue(mvm->hw, mq); 731 ieee80211_wake_queue(mvm->hw, mq);
732} 732}
733 733
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 6cc243f7cf60..12283b55ee84 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 2b2d10800a55..e7a6626fe839 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -198,8 +200,15 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
198 } 200 }
199 } 201 }
200 202
201 if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) 203 if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
204#ifdef CONFIG_IWLWIFI_DEBUGFS
205 /* set advanced pm flag with no uapsd ACs to enable ps-poll */
206 if (mvmvif->dbgfs_pm.use_ps_poll)
207 cmd->flags |=
208 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
209#endif
202 return; 210 return;
211 }
203 212
204 cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK); 213 cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK);
205 214
@@ -497,13 +506,31 @@ struct iwl_power_vifs {
497 bool p2p_tdls; 506 bool p2p_tdls;
498}; 507};
499 508
500static void iwl_mvm_power_iterator(void *_data, u8 *mac, 509static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac,
501 struct ieee80211_vif *vif) 510 struct ieee80211_vif *vif)
502{ 511{
503 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 512 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
504 struct iwl_power_vifs *power_iterator = _data;
505 513
506 mvmvif->pm_enabled = false; 514 mvmvif->pm_enabled = false;
515}
516
517static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac,
518 struct ieee80211_vif *vif)
519{
520 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
521 bool *disable_ps = _data;
522
523 if (mvmvif->phy_ctxt)
524 if (mvmvif->phy_ctxt->id < MAX_PHYS)
525 *disable_ps |= mvmvif->ps_disabled;
526}
527
528static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
529 struct ieee80211_vif *vif)
530{
531 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
532 struct iwl_power_vifs *power_iterator = _data;
533
507 switch (ieee80211_vif_type_p2p(vif)) { 534 switch (ieee80211_vif_type_p2p(vif)) {
508 case NL80211_IFTYPE_P2P_DEVICE: 535 case NL80211_IFTYPE_P2P_DEVICE:
509 break; 536 break;
@@ -559,9 +586,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
559 } 586 }
560} 587}
561 588
562static void 589static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
563iwl_mvm_power_set_pm(struct iwl_mvm *mvm, 590 struct iwl_power_vifs *vifs)
564 struct iwl_power_vifs *vifs)
565{ 591{
566 struct iwl_mvm_vif *bss_mvmvif = NULL; 592 struct iwl_mvm_vif *bss_mvmvif = NULL;
567 struct iwl_mvm_vif *p2p_mvmvif = NULL; 593 struct iwl_mvm_vif *p2p_mvmvif = NULL;
@@ -571,10 +597,11 @@ iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
571 597
572 lockdep_assert_held(&mvm->mutex); 598 lockdep_assert_held(&mvm->mutex);
573 599
574 /* get vifs info + set pm_enable to false */ 600 /* set pm_enable to false */
575 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 601 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
576 IEEE80211_IFACE_ITER_NORMAL, 602 IEEE80211_IFACE_ITER_NORMAL,
577 iwl_mvm_power_iterator, vifs); 603 iwl_mvm_power_disable_pm_iterator,
604 NULL);
578 605
579 if (vifs->bss_vif) 606 if (vifs->bss_vif)
580 bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif); 607 bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif);
@@ -817,32 +844,92 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
817 return ret; 844 return ret;
818} 845}
819 846
820int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) 847static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm)
848{
849 bool disable_ps;
850 int ret;
851
852 /* disable PS if CAM */
853 disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM);
854 /* ...or if any of the vifs require PS to be off */
855 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
856 IEEE80211_IFACE_ITER_NORMAL,
857 iwl_mvm_power_ps_disabled_iterator,
858 &disable_ps);
859
860 /* update device power state if it has changed */
861 if (mvm->ps_disabled != disable_ps) {
862 bool old_ps_disabled = mvm->ps_disabled;
863
864 mvm->ps_disabled = disable_ps;
865 ret = iwl_mvm_power_update_device(mvm);
866 if (ret) {
867 mvm->ps_disabled = old_ps_disabled;
868 return ret;
869 }
870 }
871
872 return 0;
873}
874
875static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm,
876 struct iwl_power_vifs *vifs)
821{ 877{
822 struct iwl_mvm_vif *mvmvif; 878 struct iwl_mvm_vif *mvmvif;
879 bool ba_enable;
880
881 if (!vifs->bf_vif)
882 return 0;
883
884 mvmvif = iwl_mvm_vif_from_mac80211(vifs->bf_vif);
885
886 ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
887 !vifs->bf_vif->bss_conf.ps ||
888 iwl_mvm_vif_low_latency(mvmvif));
889
890 return iwl_mvm_update_beacon_abort(mvm, vifs->bf_vif, ba_enable);
891}
892
893int iwl_mvm_power_update_ps(struct iwl_mvm *mvm)
894{
895 struct iwl_power_vifs vifs = {
896 .mvm = mvm,
897 };
898 int ret;
899
900 lockdep_assert_held(&mvm->mutex);
901
902 /* get vifs info */
903 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
904 IEEE80211_IFACE_ITER_NORMAL,
905 iwl_mvm_power_get_vifs_iterator, &vifs);
906
907 ret = iwl_mvm_power_set_ps(mvm);
908 if (ret)
909 return ret;
910
911 return iwl_mvm_power_set_ba(mvm, &vifs);
912}
913
914int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
915{
823 struct iwl_power_vifs vifs = { 916 struct iwl_power_vifs vifs = {
824 .mvm = mvm, 917 .mvm = mvm,
825 }; 918 };
826 bool ba_enable;
827 int ret; 919 int ret;
828 920
829 lockdep_assert_held(&mvm->mutex); 921 lockdep_assert_held(&mvm->mutex);
830 922
923 /* get vifs info */
924 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
925 IEEE80211_IFACE_ITER_NORMAL,
926 iwl_mvm_power_get_vifs_iterator, &vifs);
927
831 iwl_mvm_power_set_pm(mvm, &vifs); 928 iwl_mvm_power_set_pm(mvm, &vifs);
832 929
833 /* disable PS if CAM */ 930 ret = iwl_mvm_power_set_ps(mvm);
834 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) { 931 if (ret)
835 mvm->ps_disabled = true; 932 return ret;
836 } else {
837 /* don't update device power state unless we add / remove monitor */
838 if (vifs.monitor_vif) {
839 if (vifs.monitor_active)
840 mvm->ps_disabled = true;
841 ret = iwl_mvm_power_update_device(mvm);
842 if (ret)
843 return ret;
844 }
845 }
846 933
847 if (vifs.bss_vif) { 934 if (vifs.bss_vif) {
848 ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif); 935 ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif);
@@ -856,16 +943,7 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
856 return ret; 943 return ret;
857 } 944 }
858 945
859 if (!vifs.bf_vif) 946 return iwl_mvm_power_set_ba(mvm, &vifs);
860 return 0;
861
862 mvmvif = iwl_mvm_vif_from_mac80211(vifs.bf_vif);
863
864 ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
865 !vifs.bf_vif->bss_conf.ps ||
866 iwl_mvm_vif_low_latency(mvmvif));
867
868 return iwl_mvm_update_beacon_abort(mvm, vifs.bf_vif, ba_enable);
869} 947}
870 948
871int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, 949int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 4e20b3ce2b6a..5fd502db03d1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -161,6 +163,9 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
161 quota *= (beacon_int - mvm->noa_duration); 163 quota *= (beacon_int - mvm->noa_duration);
162 quota /= beacon_int; 164 quota /= beacon_int;
163 165
166 IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n",
167 le32_to_cpu(cmd->quotas[i].quota), quota);
168
164 cmd->quotas[i].quota = cpu_to_le32(quota); 169 cmd->quotas[i].quota = cpu_to_le32(quota);
165 } 170 }
166#endif 171#endif
@@ -222,6 +227,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
222 quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat; 227 quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat;
223 quota_rem = QUOTA_100 - n_non_lowlat * quota - 228 quota_rem = QUOTA_100 - n_non_lowlat * quota -
224 QUOTA_LOWLAT_MIN; 229 QUOTA_LOWLAT_MIN;
230 IWL_DEBUG_QUOTA(mvm,
231 "quota: low-latency binding active, remaining quota per other binding: %d\n",
232 quota);
225 } else if (num_active_macs) { 233 } else if (num_active_macs) {
226 /* 234 /*
227 * There are 0 or more than 1 low latency bindings, or all the 235 * There are 0 or more than 1 low latency bindings, or all the
@@ -230,6 +238,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
230 */ 238 */
231 quota = QUOTA_100 / num_active_macs; 239 quota = QUOTA_100 / num_active_macs;
232 quota_rem = QUOTA_100 % num_active_macs; 240 quota_rem = QUOTA_100 % num_active_macs;
241 IWL_DEBUG_QUOTA(mvm,
242 "quota: splitting evenly per binding: %d\n",
243 quota);
233 } else { 244 } else {
234 /* values don't really matter - won't be used */ 245 /* values don't really matter - won't be used */
235 quota = 0; 246 quota = 0;
@@ -271,6 +282,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
271 for (i = 0; i < MAX_BINDINGS; i++) { 282 for (i = 0; i < MAX_BINDINGS; i++) {
272 if (le32_to_cpu(cmd.quotas[i].quota) != 0) { 283 if (le32_to_cpu(cmd.quotas[i].quota) != 0) {
273 le32_add_cpu(&cmd.quotas[i].quota, quota_rem); 284 le32_add_cpu(&cmd.quotas[i].quota, quota_rem);
285 IWL_DEBUG_QUOTA(mvm,
286 "quota: giving remainder of %d to binding %d\n",
287 quota_rem, i);
274 break; 288 break;
275 } 289 }
276 } 290 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index c70e959bf0e3..17002cf437db 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1,6 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
4 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 7 * under the terms of version 2 of the GNU General Public License as
@@ -2678,6 +2679,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
2678 int i; 2679 int i;
2679 int num_rates = ARRAY_SIZE(lq_cmd->rs_table); 2680 int num_rates = ARRAY_SIZE(lq_cmd->rs_table);
2680 __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate); 2681 __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);
2682 u8 ant = (ucode_rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
2681 2683
2682 for (i = 0; i < num_rates; i++) 2684 for (i = 0; i < num_rates; i++)
2683 lq_cmd->rs_table[i] = ucode_rate_le32; 2685 lq_cmd->rs_table[i] = ucode_rate_le32;
@@ -2688,6 +2690,13 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
2688 lq_cmd->mimo_delim = num_rates - 1; 2690 lq_cmd->mimo_delim = num_rates - 1;
2689 else 2691 else
2690 lq_cmd->mimo_delim = 0; 2692 lq_cmd->mimo_delim = 0;
2693
2694 lq_cmd->reduced_tpc = 0;
2695
2696 if (num_of_ant(ant) == 1)
2697 lq_cmd->single_stream_ant_msk = ant;
2698
2699 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
2691} 2700}
2692#endif /* CONFIG_MAC80211_DEBUGFS */ 2701#endif /* CONFIG_MAC80211_DEBUGFS */
2693 2702
@@ -2811,31 +2820,55 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2811 const struct rs_rate *initial_rate) 2820 const struct rs_rate *initial_rate)
2812{ 2821{
2813 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2822 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2814 u8 ant = initial_rate->ant; 2823 struct iwl_mvm_sta *mvmsta;
2824 struct iwl_mvm_vif *mvmvif;
2825
2826 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
2827 lq_cmd->agg_time_limit =
2828 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2815 2829
2816#ifdef CONFIG_MAC80211_DEBUGFS 2830#ifdef CONFIG_MAC80211_DEBUGFS
2817 if (lq_sta->pers.dbg_fixed_rate) { 2831 if (lq_sta->pers.dbg_fixed_rate) {
2818 rs_build_rates_table_from_fixed(mvm, lq_cmd, 2832 rs_build_rates_table_from_fixed(mvm, lq_cmd,
2819 lq_sta->band, 2833 lq_sta->band,
2820 lq_sta->pers.dbg_fixed_rate); 2834 lq_sta->pers.dbg_fixed_rate);
2821 lq_cmd->reduced_tpc = 0; 2835 return;
2822 ant = (lq_sta->pers.dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >> 2836 }
2823 RATE_MCS_ANT_POS;
2824 } else
2825#endif 2837#endif
2826 rs_build_rates_table(mvm, lq_sta, initial_rate); 2838 if (WARN_ON_ONCE(!sta || !initial_rate))
2839 return;
2827 2840
2828 if (num_of_ant(ant) == 1) 2841 rs_build_rates_table(mvm, lq_sta, initial_rate);
2829 lq_cmd->single_stream_ant_msk = ant;
2830 2842
2831 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 2843 if (num_of_ant(initial_rate->ant) == 1)
2832 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 2844 lq_cmd->single_stream_ant_msk = initial_rate->ant;
2833 2845
2834 lq_cmd->agg_time_limit = 2846 mvmsta = iwl_mvm_sta_from_mac80211(sta);
2835 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 2847 mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
2848
2849 if (num_of_ant(initial_rate->ant) == 1)
2850 lq_cmd->single_stream_ant_msk = initial_rate->ant;
2851
2852 lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
2836 2853
2837 if (sta) 2854 /*
2838 lq_cmd->agg_time_limit = 2855 * In case of low latency, tell the firwmare to leave a frame in the
2856 * Tx Fifo so that it can start a transaction in the same TxOP. This
2857 * basically allows the firmware to send bursts.
2858 */
2859 if (iwl_mvm_vif_low_latency(mvmvif)) {
2860 lq_cmd->agg_frame_cnt_limit--;
2861
2862 if (mvm->low_latency_agg_frame_limit)
2863 lq_cmd->agg_frame_cnt_limit =
2864 min(lq_cmd->agg_frame_cnt_limit,
2865 mvm->low_latency_agg_frame_limit);
2866 }
2867
2868 if (mvmsta->vif->p2p)
2869 lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK;
2870
2871 lq_cmd->agg_time_limit =
2839 cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); 2872 cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta));
2840} 2873}
2841 2874
@@ -2932,10 +2965,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
2932 lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); 2965 lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate);
2933 2966
2934 if (lq_sta->pers.dbg_fixed_rate) { 2967 if (lq_sta->pers.dbg_fixed_rate) {
2935 struct rs_rate rate; 2968 rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL);
2936 rs_rate_from_ucode_rate(lq_sta->pers.dbg_fixed_rate,
2937 lq_sta->band, &rate);
2938 rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate);
2939 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false); 2969 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false);
2940 } 2970 }
2941} 2971}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 4b98987fc413..48144e3ad527 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -491,10 +493,29 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
491 .mvm = mvm, 493 .mvm = mvm,
492 }; 494 };
493 495
496 /*
497 * set temperature debug enabled - ignore FW temperature updates
498 * and use the user set temperature.
499 */
500 if (mvm->temperature_test) {
501 if (mvm->temperature < le32_to_cpu(common->temperature))
502 IWL_DEBUG_TEMP(mvm,
503 "Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n",
504 mvm->temperature,
505 le32_to_cpu(common->temperature));
506 /*
507 * skip iwl_mvm_tt_handler since we are in
508 * temperature debug mode and we are ignoring
509 * the new temperature value
510 */
511 goto update;
512 }
513
494 if (mvm->temperature != le32_to_cpu(common->temperature)) { 514 if (mvm->temperature != le32_to_cpu(common->temperature)) {
495 mvm->temperature = le32_to_cpu(common->temperature); 515 mvm->temperature = le32_to_cpu(common->temperature);
496 iwl_mvm_tt_handler(mvm); 516 iwl_mvm_tt_handler(mvm);
497 } 517 }
518update:
498 iwl_mvm_update_rx_statistics(mvm, stats); 519 iwl_mvm_update_rx_statistics(mvm, stats);
499 520
500 ieee80211_iterate_active_interfaces(mvm->hw, 521 ieee80211_iterate_active_interfaces(mvm->hw,
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 004b1f5d0314..bf9c63dc4a7d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -279,6 +281,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
279{ 281{
280 bool global_bound = false; 282 bool global_bound = false;
281 enum ieee80211_band band; 283 enum ieee80211_band band;
284 u8 frag_passive_dwell = 0;
282 285
283 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 286 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
284 IEEE80211_IFACE_ITER_NORMAL, 287 IEEE80211_IFACE_ITER_NORMAL,
@@ -288,12 +291,36 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
288 if (!global_bound) 291 if (!global_bound)
289 goto not_bound; 292 goto not_bound;
290 293
291 params->suspend_time = 100; 294 params->suspend_time = 30;
292 params->max_out_time = 600; 295 params->max_out_time = 170;
293 296
294 if (iwl_mvm_low_latency(mvm)) { 297 if (iwl_mvm_low_latency(mvm)) {
295 params->suspend_time = 250; 298 if (mvm->fw->ucode_capa.api[0] &
296 params->max_out_time = 250; 299 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
300 params->suspend_time = 105;
301 params->max_out_time = 70;
302 frag_passive_dwell = 20;
303 } else {
304 params->suspend_time = 120;
305 params->max_out_time = 120;
306 }
307 }
308
309 if (frag_passive_dwell && (mvm->fw->ucode_capa.api[0] &
310 IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
311 /*
312 * P2P device scan should not be fragmented to avoid negative
313 * impact on P2P device discovery. Configure max_out_time to be
314 * equal to dwell time on passive channel. Take a longest
315 * possible value, one that corresponds to 2GHz band
316 */
317 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
318 u32 passive_dwell =
319 iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ);
320 params->max_out_time = passive_dwell;
321 } else {
322 params->passive_fragmented = true;
323 }
297 } 324 }
298 325
299 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY) 326 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
@@ -302,7 +329,11 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
302not_bound: 329not_bound:
303 330
304 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 331 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
305 params->dwell[band].passive = iwl_mvm_get_passive_dwell(band); 332 if (params->passive_fragmented)
333 params->dwell[band].passive = frag_passive_dwell;
334 else
335 params->dwell[band].passive =
336 iwl_mvm_get_passive_dwell(band);
306 params->dwell[band].active = iwl_mvm_get_active_dwell(band, 337 params->dwell[band].active = iwl_mvm_get_active_dwell(band,
307 n_ssids); 338 n_ssids);
308 } 339 }
@@ -1100,10 +1131,11 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1100 struct iwl_mvm_scan_params *params) 1131 struct iwl_mvm_scan_params *params)
1101{ 1132{
1102 memset(cmd, 0, ksize(cmd)); 1133 memset(cmd, 0, ksize(cmd));
1103 cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active; 1134 cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active;
1104 cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive; 1135 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
1105 /* TODO: Use params; now fragmented isn't used. */ 1136 if (params->passive_fragmented)
1106 cmd->fragmented_dwell = 0; 1137 cmd->fragmented_dwell =
1138 params->dwell[IEEE80211_BAND_2GHZ].passive;
1107 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); 1139 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
1108 cmd->max_out_time = cpu_to_le32(params->max_out_time); 1140 cmd->max_out_time = cpu_to_le32(params->max_out_time);
1109 cmd->suspend_time = cpu_to_le32(params->suspend_time); 1141 cmd->suspend_time = cpu_to_le32(params->suspend_time);
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
index 7edfd15efc9d..d1922afe06f4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 763548880399..dd9f3a4347f6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -250,10 +252,14 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
250 if (ret) 252 if (ret)
251 return ret; 253 return ret;
252 254
253 /* The first station added is the AP, the others are TDLS STAs */ 255 if (vif->type == NL80211_IFTYPE_STATION) {
254 if (vif->type == NL80211_IFTYPE_STATION && 256 if (!sta->tdls) {
255 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) 257 WARN_ON(mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT);
256 mvmvif->ap_sta_id = sta_id; 258 mvmvif->ap_sta_id = sta_id;
259 } else {
260 WARN_ON(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT);
261 }
262 }
257 263
258 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); 264 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
259 265
@@ -458,8 +464,9 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
458 return ret; 464 return ret;
459} 465}
460 466
461int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, 467static int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm,
462 u32 qmask, enum nl80211_iftype iftype) 468 struct iwl_mvm_int_sta *sta,
469 u32 qmask, enum nl80211_iftype iftype)
463{ 470{
464 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 471 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
465 sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); 472 sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
@@ -474,7 +481,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
474 return 0; 481 return 0;
475} 482}
476 483
477void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta) 484static void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
485 struct iwl_mvm_int_sta *sta)
478{ 486{
479 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL); 487 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
480 memset(sta, 0, sizeof(struct iwl_mvm_int_sta)); 488 memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
@@ -544,6 +552,13 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
544 return ret; 552 return ret;
545} 553}
546 554
555void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm)
556{
557 lockdep_assert_held(&mvm->mutex);
558
559 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
560}
561
547/* 562/*
548 * Send the add station command for the vif's broadcast station. 563 * Send the add station command for the vif's broadcast station.
549 * Assumes that the station was already allocated. 564 * Assumes that the station was already allocated.
@@ -552,10 +567,10 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
552 * @vif: the interface to which the broadcast station is added 567 * @vif: the interface to which the broadcast station is added
553 * @bsta: the broadcast station to add. 568 * @bsta: the broadcast station to add.
554 */ 569 */
555int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 570int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
556 struct iwl_mvm_int_sta *bsta)
557{ 571{
558 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 572 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
573 struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
559 static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 574 static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
560 const u8 *baddr = _baddr; 575 const u8 *baddr = _baddr;
561 576
@@ -573,19 +588,40 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
573 588
574/* Send the FW a request to remove the station from it's internal data 589/* Send the FW a request to remove the station from it's internal data
575 * structures, but DO NOT remove the entry from the local data structures. */ 590 * structures, but DO NOT remove the entry from the local data structures. */
576int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, 591int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
577 struct iwl_mvm_int_sta *bsta)
578{ 592{
593 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
579 int ret; 594 int ret;
580 595
581 lockdep_assert_held(&mvm->mutex); 596 lockdep_assert_held(&mvm->mutex);
582 597
583 ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); 598 ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id);
584 if (ret) 599 if (ret)
585 IWL_WARN(mvm, "Failed sending remove station\n"); 600 IWL_WARN(mvm, "Failed sending remove station\n");
586 return ret; 601 return ret;
587} 602}
588 603
604int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
605{
606 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
607 u32 qmask;
608
609 lockdep_assert_held(&mvm->mutex);
610
611 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
612
613 /*
614 * The firmware defines the TFD queue mask to only be relevant
615 * for *unicast* queues, so the multicast (CAB) queue shouldn't
616 * be included.
617 */
618 if (vif->type == NL80211_IFTYPE_AP)
619 qmask &= ~BIT(vif->cab_queue);
620
621 return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask,
622 ieee80211_vif_type_p2p(vif));
623}
624
589/* Allocate a new station entry for the broadcast station to the given vif, 625/* Allocate a new station entry for the broadcast station to the given vif,
590 * and send it to the FW. 626 * and send it to the FW.
591 * Note that each P2P mac should have its own broadcast station. 627 * Note that each P2P mac should have its own broadcast station.
@@ -593,45 +629,47 @@ int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
593 * @mvm: the mvm component 629 * @mvm: the mvm component
594 * @vif: the interface to which the broadcast station is added 630 * @vif: the interface to which the broadcast station is added
595 * @bsta: the broadcast station to add. */ 631 * @bsta: the broadcast station to add. */
596int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 632int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
597 struct iwl_mvm_int_sta *bsta)
598{ 633{
599 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 634 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
600 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 635 struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
601 u32 qmask;
602 int ret; 636 int ret;
603 637
604 lockdep_assert_held(&mvm->mutex); 638 lockdep_assert_held(&mvm->mutex);
605 639
606 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); 640 ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
607 ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask,
608 ieee80211_vif_type_p2p(vif));
609 if (ret) 641 if (ret)
610 return ret; 642 return ret;
611 643
612 ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr, 644 ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
613 mvmvif->id, mvmvif->color);
614 645
615 if (ret) 646 if (ret)
616 iwl_mvm_dealloc_int_sta(mvm, bsta); 647 iwl_mvm_dealloc_int_sta(mvm, bsta);
648
617 return ret; 649 return ret;
618} 650}
619 651
652void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
653{
654 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
655
656 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
657}
658
620/* 659/*
621 * Send the FW a request to remove the station from it's internal data 660 * Send the FW a request to remove the station from it's internal data
622 * structures, and in addition remove it from the local data structure. 661 * structures, and in addition remove it from the local data structure.
623 */ 662 */
624int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) 663int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
625{ 664{
626 int ret; 665 int ret;
627 666
628 lockdep_assert_held(&mvm->mutex); 667 lockdep_assert_held(&mvm->mutex);
629 668
630 ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); 669 ret = iwl_mvm_send_rm_bcast_sta(mvm, vif);
631 if (ret) 670
632 return ret; 671 iwl_mvm_dealloc_bcast_sta(mvm, vif);
633 672
634 iwl_mvm_dealloc_int_sta(mvm, bsta);
635 return ret; 673 return ret;
636} 674}
637 675
@@ -910,7 +948,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
910 } 948 }
911 949
912 tid_data->ssn = 0xffff; 950 tid_data->ssn = 0xffff;
913 iwl_trans_txq_disable(mvm->trans, txq_id); 951 iwl_trans_txq_disable(mvm->trans, txq_id, true);
914 /* fall through */ 952 /* fall through */
915 case IWL_AGG_STARTING: 953 case IWL_AGG_STARTING:
916 case IWL_EMPTYING_HW_QUEUE_ADDBA: 954 case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -965,7 +1003,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
965 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) 1003 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
966 IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); 1004 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
967 1005
968 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); 1006 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
969 } 1007 }
970 1008
971 mvm->queue_to_mac80211[tid_data->txq_id] = 1009 mvm->queue_to_mac80211[tid_data->txq_id] =
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 3b1c8bd6cb54..aeb3a7f80ceb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -387,17 +389,15 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
387 struct ieee80211_sta *sta, u16 tid); 389 struct ieee80211_sta *sta, u16 tid);
388 390
389int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); 391int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
390int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, 392void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm);
391 u32 qmask, enum nl80211_iftype iftype); 393
392void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, 394int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
393 struct iwl_mvm_int_sta *sta); 395int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
394int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 396int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
395 struct iwl_mvm_int_sta *bsta); 397int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
396int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, 398int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
397 struct iwl_mvm_int_sta *bsta); 399void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
398int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 400
399 struct iwl_mvm_int_sta *bsta);
400int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
401void iwl_mvm_sta_drained_wk(struct work_struct *wk); 401void iwl_mvm_sta_drained_wk(struct work_struct *wk);
402void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, 402void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
403 struct ieee80211_sta *sta); 403 struct ieee80211_sta *sta);
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h
index 0241665925f7..79ab6beb6b26 100644
--- a/drivers/net/wireless/iwlwifi/mvm/testmode.h
+++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 33e5041f1efc..447d3b1003df 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -348,6 +350,38 @@ unlock:
348 return 0; 350 return 0;
349} 351}
350 352
353static bool iwl_mvm_te_notif(struct iwl_notif_wait_data *notif_wait,
354 struct iwl_rx_packet *pkt, void *data)
355{
356 struct iwl_mvm *mvm =
357 container_of(notif_wait, struct iwl_mvm, notif_wait);
358 struct iwl_mvm_time_event_data *te_data = data;
359 struct iwl_time_event_notif *resp;
360 int resp_len = iwl_rx_packet_payload_len(pkt);
361
362 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_NOTIFICATION))
363 return true;
364
365 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
366 IWL_ERR(mvm, "Invalid TIME_EVENT_NOTIFICATION response\n");
367 return true;
368 }
369
370 resp = (void *)pkt->data;
371
372 /* te_data->uid is already set in the TIME_EVENT_CMD response */
373 if (le32_to_cpu(resp->unique_id) != te_data->uid)
374 return false;
375
376 IWL_DEBUG_TE(mvm, "TIME_EVENT_NOTIFICATION response - UID = 0x%x\n",
377 te_data->uid);
378 if (!resp->status)
379 IWL_ERR(mvm,
380 "TIME_EVENT_NOTIFICATION received but not executed\n");
381
382 return true;
383}
384
351static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait, 385static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
352 struct iwl_rx_packet *pkt, void *data) 386 struct iwl_rx_packet *pkt, void *data)
353{ 387{
@@ -441,10 +475,12 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
441void iwl_mvm_protect_session(struct iwl_mvm *mvm, 475void iwl_mvm_protect_session(struct iwl_mvm *mvm,
442 struct ieee80211_vif *vif, 476 struct ieee80211_vif *vif,
443 u32 duration, u32 min_duration, 477 u32 duration, u32 min_duration,
444 u32 max_delay) 478 u32 max_delay, bool wait_for_notif)
445{ 479{
446 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 480 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
447 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 481 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
482 const u8 te_notif_response[] = { TIME_EVENT_NOTIFICATION };
483 struct iwl_notification_wait wait_te_notif;
448 struct iwl_time_event_cmd time_cmd = {}; 484 struct iwl_time_event_cmd time_cmd = {};
449 485
450 lockdep_assert_held(&mvm->mutex); 486 lockdep_assert_held(&mvm->mutex);
@@ -489,7 +525,28 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
489 TE_V2_NOTIF_HOST_EVENT_END | 525 TE_V2_NOTIF_HOST_EVENT_END |
490 T2_V2_START_IMMEDIATELY); 526 T2_V2_START_IMMEDIATELY);
491 527
492 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 528 if (!wait_for_notif) {
529 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
530 return;
531 }
532
533 /*
534 * Create notification_wait for the TIME_EVENT_NOTIFICATION to use
535 * right after we send the time event
536 */
537 iwl_init_notification_wait(&mvm->notif_wait, &wait_te_notif,
538 te_notif_response,
539 ARRAY_SIZE(te_notif_response),
540 iwl_mvm_te_notif, te_data);
541
542 /* If TE was sent OK - wait for the notification that started */
543 if (iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd)) {
544 IWL_ERR(mvm, "Failed to add TE to protect session\n");
545 iwl_remove_notification(&mvm->notif_wait, &wait_te_notif);
546 } else if (iwl_wait_notification(&mvm->notif_wait, &wait_te_notif,
547 TU_TO_JIFFIES(max_delay))) {
548 IWL_ERR(mvm, "Failed to protect session until TE\n");
549 }
493} 550}
494 551
495/* 552/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index 2f48a90d4ad3..bee3b2446b35 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -124,10 +126,12 @@
124 * @min_duration: will start a new session if the current session will end 126 * @min_duration: will start a new session if the current session will end
125 * in less than min_duration. 127 * in less than min_duration.
126 * @max_delay: maximum delay before starting the time event (in TU) 128 * @max_delay: maximum delay before starting the time event (in TU)
129 * @wait_for_notif: true if it is required that a time event notification be
130 * waited for (that the time event has been scheduled before returning)
127 * 131 *
128 * This function can be used to start a session protection which means that the 132 * This function can be used to start a session protection which means that the
129 * fw will stay on the channel for %duration_ms milliseconds. This function 133 * fw will stay on the channel for %duration_ms milliseconds. This function
130 * will block (sleep) until the session starts. This function can also be used 134 * can block (sleep) until the session starts. This function can also be used
131 * to extend a currently running session. 135 * to extend a currently running session.
132 * This function is meant to be used for BSS association for example, where we 136 * This function is meant to be used for BSS association for example, where we
133 * want to make sure that the fw stays on the channel during the association. 137 * want to make sure that the fw stays on the channel during the association.
@@ -135,7 +139,7 @@
135void iwl_mvm_protect_session(struct iwl_mvm *mvm, 139void iwl_mvm_protect_session(struct iwl_mvm *mvm,
136 struct ieee80211_vif *vif, 140 struct ieee80211_vif *vif,
137 u32 duration, u32 min_duration, 141 u32 duration, u32 min_duration,
138 u32 max_delay); 142 u32 max_delay, bool wait_for_notif);
139 143
140/** 144/**
141 * iwl_mvm_stop_session_protection - cancel the session protection. 145 * iwl_mvm_stop_session_protection - cancel the session protection.
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 0464599c111e..c3e1fe4282f1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -314,14 +316,26 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
314{ 316{
315 u32 duration = mvm->thermal_throttle.params->ct_kill_duration; 317 u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
316 318
319 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
320 return;
321
317 IWL_ERR(mvm, "Enter CT Kill\n"); 322 IWL_ERR(mvm, "Enter CT Kill\n");
318 iwl_mvm_set_hw_ctkill_state(mvm, true); 323 iwl_mvm_set_hw_ctkill_state(mvm, true);
319 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, 324
320 round_jiffies_relative(duration * HZ)); 325 /* Don't schedule an exit work if we're in test mode, since
326 * the temperature will not change unless we manually set it
327 * again (or disable testing).
328 */
329 if (!mvm->temperature_test)
330 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
331 round_jiffies_relative(duration * HZ));
321} 332}
322 333
323static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) 334static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
324{ 335{
336 if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
337 return;
338
325 IWL_ERR(mvm, "Exit CT Kill\n"); 339 IWL_ERR(mvm, "Exit CT Kill\n");
326 iwl_mvm_set_hw_ctkill_state(mvm, false); 340 iwl_mvm_set_hw_ctkill_state(mvm, false);
327} 341}
@@ -444,6 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
444 return; 458 return;
445 } 459 }
446 460
461 if (params->support_ct_kill &&
462 temperature <= tt->params->ct_kill_exit) {
463 iwl_mvm_exit_ctkill(mvm);
464 return;
465 }
466
447 if (params->support_dynamic_smps) { 467 if (params->support_dynamic_smps) {
448 if (!tt->dynamic_smps && 468 if (!tt->dynamic_smps &&
449 temperature >= params->dynamic_smps_entry) { 469 temperature >= params->dynamic_smps_entry) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index dbc870713882..963edb8656ad 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -482,7 +484,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
482 IWL_DEBUG_TX_QUEUES(mvm, 484 IWL_DEBUG_TX_QUEUES(mvm,
483 "Can continue DELBA flow ssn = next_recl = %d\n", 485 "Can continue DELBA flow ssn = next_recl = %d\n",
484 tid_data->next_reclaimed); 486 tid_data->next_reclaimed);
485 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); 487 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
486 tid_data->state = IWL_AGG_OFF; 488 tid_data->state = IWL_AGG_OFF;
487 /* 489 /*
488 * we can't hold the mutex - but since we are after a sequence 490 * we can't hold the mutex - but since we are after a sequence
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index ac249da8a22b..1958f298ac8b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -387,15 +389,19 @@ struct iwl_error_event_table {
387struct iwl_umac_error_event_table { 389struct iwl_umac_error_event_table {
388 u32 valid; /* (nonzero) valid, (0) log is empty */ 390 u32 valid; /* (nonzero) valid, (0) log is empty */
389 u32 error_id; /* type of error */ 391 u32 error_id; /* type of error */
390 u32 pc; /* program counter */
391 u32 blink1; /* branch link */ 392 u32 blink1; /* branch link */
392 u32 blink2; /* branch link */ 393 u32 blink2; /* branch link */
393 u32 ilink1; /* interrupt link */ 394 u32 ilink1; /* interrupt link */
394 u32 ilink2; /* interrupt link */ 395 u32 ilink2; /* interrupt link */
395 u32 data1; /* error-specific data */ 396 u32 data1; /* error-specific data */
396 u32 data2; /* error-specific data */ 397 u32 data2; /* error-specific data */
397 u32 line; /* source code line of error */ 398 u32 data3; /* error-specific data */
398 u32 umac_ver; /* umac version */ 399 u32 umac_fw_ver; /* UMAC version */
400 u32 umac_fw_api_ver; /* UMAC FW API ver */
401 u32 frame_pointer; /* core register 27*/
402 u32 stack_pointer; /* core register 28 */
403 u32 cmd_header; /* latest host cmd sent to UMAC */
404 u32 nic_isr_pref; /* ISR status register */
399} __packed; 405} __packed;
400 406
401#define ERROR_START_OFFSET (1 * sizeof(u32)) 407#define ERROR_START_OFFSET (1 * sizeof(u32))
@@ -409,7 +415,7 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
409 415
410 base = mvm->umac_error_event_table; 416 base = mvm->umac_error_event_table;
411 417
412 if (base < 0x800000 || base >= 0x80C000) { 418 if (base < 0x800000) {
413 IWL_ERR(mvm, 419 IWL_ERR(mvm,
414 "Not valid error log pointer 0x%08X for %s uCode\n", 420 "Not valid error log pointer 0x%08X for %s uCode\n",
415 base, 421 base,
@@ -428,14 +434,19 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
428 434
429 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, 435 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
430 desc_lookup(table.error_id)); 436 desc_lookup(table.error_id));
431 IWL_ERR(mvm, "0x%08X | umac uPc\n", table.pc);
432 IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); 437 IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1);
433 IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); 438 IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2);
434 IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1); 439 IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1);
435 IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2); 440 IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2);
436 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); 441 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1);
437 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); 442 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2);
438 IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_ver); 443 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3);
444 IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver);
445 IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver);
446 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer);
447 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer);
448 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header);
449 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref);
439} 450}
440 451
441void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) 452void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index f0e722ced080..dbbbf23082a2 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 78f72c34438a..a4fedc4a7448 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -1,6 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
4 * 5 *
5 * Portions of this file are derived from the ipw3945 project, as well 6 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 7 * as portions of the ieee80211 subsystem header files.
@@ -364,9 +365,10 @@ int iwl_pcie_tx_init(struct iwl_trans *trans);
364void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); 365void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr);
365int iwl_pcie_tx_stop(struct iwl_trans *trans); 366int iwl_pcie_tx_stop(struct iwl_trans *trans);
366void iwl_pcie_tx_free(struct iwl_trans *trans); 367void iwl_pcie_tx_free(struct iwl_trans *trans);
367void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 368void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn,
368 int sta_id, int tid, int frame_limit, u16 ssn); 369 const struct iwl_trans_txq_scd_cfg *cfg);
369void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); 370void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue,
371 bool configure_scd);
370int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, 372int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
371 struct iwl_device_cmd *dev_cmd, int txq_id); 373 struct iwl_device_cmd *dev_cmd, int txq_id);
372void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); 374void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index a2698e5e062c..702f47fb16fe 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -1,6 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
4 * 5 *
5 * Portions of this file are derived from the ipw3945 project, as well 6 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 7 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 06e04aaf61ee..3076e0e9a490 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
31 * BSD LICENSE 32 * BSD LICENSE
32 * 33 *
33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34 * All rights reserved. 36 * All rights reserved.
35 * 37 *
36 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 6acccb19c4f3..a6336b4aa3a4 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1,6 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
4 * 5 *
5 * Portions of this file are derived from the ipw3945 project, as well 6 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 7 * as portions of the ieee80211 subsystem header files.
@@ -34,6 +35,7 @@
34#include "iwl-csr.h" 35#include "iwl-csr.h"
35#include "iwl-prph.h" 36#include "iwl-prph.h"
36#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-scd.h"
37#include "iwl-op-mode.h" 39#include "iwl-op-mode.h"
38#include "internal.h" 40#include "internal.h"
39/* FIXME: need to abstract out TX command (once we know what it looks like) */ 41/* FIXME: need to abstract out TX command (once we know what it looks like) */
@@ -644,17 +646,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
644 memset(txq, 0, sizeof(*txq)); 646 memset(txq, 0, sizeof(*txq));
645} 647}
646 648
647/*
648 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
649 */
650static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask)
651{
652 struct iwl_trans_pcie __maybe_unused *trans_pcie =
653 IWL_TRANS_GET_PCIE_TRANS(trans);
654
655 iwl_write_prph(trans, SCD_TXFACT, mask);
656}
657
658void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) 649void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
659{ 650{
660 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 651 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -692,7 +683,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
692 trans_pcie->cmd_fifo); 683 trans_pcie->cmd_fifo);
693 684
694 /* Activate all Tx DMA/FIFO channels */ 685 /* Activate all Tx DMA/FIFO channels */
695 iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7)); 686 iwl_scd_activate_fifos(trans);
696 687
697 /* Enable DMA channel */ 688 /* Enable DMA channel */
698 for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) 689 for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++)
@@ -745,7 +736,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans)
745 /* Turn off all Tx DMA fifos */ 736 /* Turn off all Tx DMA fifos */
746 spin_lock(&trans_pcie->irq_lock); 737 spin_lock(&trans_pcie->irq_lock);
747 738
748 iwl_pcie_txq_set_sched(trans, 0); 739 iwl_scd_deactivate_fifos(trans);
749 740
750 /* Stop each Tx DMA channel, and wait for it to be idle */ 741 /* Stop each Tx DMA channel, and wait for it to be idle */
751 for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { 742 for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
@@ -886,7 +877,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
886 spin_lock(&trans_pcie->irq_lock); 877 spin_lock(&trans_pcie->irq_lock);
887 878
888 /* Turn off all Tx DMA fifos */ 879 /* Turn off all Tx DMA fifos */
889 iwl_write_prph(trans, SCD_TXFACT, 0); 880 iwl_scd_deactivate_fifos(trans);
890 881
891 /* Tell NIC where to find the "keep warm" buffer */ 882 /* Tell NIC where to find the "keep warm" buffer */
892 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, 883 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
@@ -1072,55 +1063,52 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
1072 return 0; 1063 return 0;
1073} 1064}
1074 1065
1075static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans,
1076 u16 txq_id)
1077{
1078 /* Simply stop the queue, but don't change any configuration;
1079 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
1080 iwl_write_prph(trans,
1081 SCD_QUEUE_STATUS_BITS(txq_id),
1082 (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
1083 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1084}
1085
1086/* Receiver address (actually, Rx station's index into station table), 1066/* Receiver address (actually, Rx station's index into station table),
1087 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ 1067 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
1088#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) 1068#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1089 1069
1090void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 1070void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1091 int sta_id, int tid, int frame_limit, u16 ssn) 1071 const struct iwl_trans_txq_scd_cfg *cfg)
1092{ 1072{
1093 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1073 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1074 int fifo = -1;
1094 1075
1095 if (test_and_set_bit(txq_id, trans_pcie->queue_used)) 1076 if (test_and_set_bit(txq_id, trans_pcie->queue_used))
1096 WARN_ONCE(1, "queue %d already used - expect issues", txq_id); 1077 WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
1097 1078
1098 /* Stop this Tx queue before configuring it */ 1079 if (cfg) {
1099 iwl_pcie_txq_set_inactive(trans, txq_id); 1080 fifo = cfg->fifo;
1100 1081
1101 /* Set this queue as a chain-building queue unless it is CMD queue */ 1082 /* Disable the scheduler prior configuring the cmd queue */
1102 if (txq_id != trans_pcie->cmd_queue) 1083 if (txq_id == trans_pcie->cmd_queue)
1103 iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); 1084 iwl_scd_enable_set_active(trans, 0);
1104 1085
1105 /* If this queue is mapped to a certain station: it is an AGG queue */ 1086 /* Stop this Tx queue before configuring it */
1106 if (sta_id >= 0) { 1087 iwl_scd_txq_set_inactive(trans, txq_id);
1107 u16 ra_tid = BUILD_RAxTID(sta_id, tid);
1108 1088
1109 /* Map receiver-address / traffic-ID to this queue */ 1089 /* Set this queue as a chain-building queue unless it is CMD */
1110 iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); 1090 if (txq_id != trans_pcie->cmd_queue)
1091 iwl_scd_txq_set_chain(trans, txq_id);
1111 1092
1112 /* enable aggregations for the queue */ 1093 if (cfg->aggregate) {
1113 iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); 1094 u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid);
1114 trans_pcie->txq[txq_id].ampdu = true; 1095
1115 } else { 1096 /* Map receiver-address / traffic-ID to this queue */
1116 /* 1097 iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id);
1117 * disable aggregations for the queue, this will also make the 1098
1118 * ra_tid mapping configuration irrelevant since it is now a 1099 /* enable aggregations for the queue */
1119 * non-AGG queue. 1100 iwl_scd_txq_enable_agg(trans, txq_id);
1120 */ 1101 trans_pcie->txq[txq_id].ampdu = true;
1121 iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); 1102 } else {
1103 /*
1104 * disable aggregations for the queue, this will also
1105 * make the ra_tid mapping configuration irrelevant
1106 * since it is now a non-AGG queue.
1107 */
1108 iwl_scd_txq_disable_agg(trans, txq_id);
1122 1109
1123 ssn = trans_pcie->txq[txq_id].q.read_ptr; 1110 ssn = trans_pcie->txq[txq_id].q.read_ptr;
1111 }
1124 } 1112 }
1125 1113
1126 /* Place first TFD at index corresponding to start sequence number. 1114 /* Place first TFD at index corresponding to start sequence number.
@@ -1128,32 +1116,43 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
1128 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 1116 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff);
1129 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 1117 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff);
1130 1118
1131 iwl_write_direct32(trans, HBUS_TARG_WRPTR, 1119 if (cfg) {
1132 (ssn & 0xff) | (txq_id << 8)); 1120 u8 frame_limit = cfg->frame_limit;
1133 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); 1121
1122 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1123 (ssn & 0xff) | (txq_id << 8));
1124 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
1134 1125
1135 /* Set up Tx window size and frame limit for this queue */ 1126 /* Set up Tx window size and frame limit for this queue */
1136 iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + 1127 iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr +
1137 SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); 1128 SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0);
1138 iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + 1129 iwl_trans_write_mem32(trans,
1130 trans_pcie->scd_base_addr +
1139 SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), 1131 SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
1140 ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & 1132 ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
1141 SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | 1133 SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
1142 ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & 1134 ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
1143 SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); 1135 SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
1144 1136
1145 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ 1137 /* Set up status area in SRAM, map to Tx DMA/FIFO, activate */
1146 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), 1138 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
1147 (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | 1139 (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
1148 (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | 1140 (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
1149 (1 << SCD_QUEUE_STTS_REG_POS_WSL) | 1141 (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
1150 SCD_QUEUE_STTS_REG_MSK); 1142 SCD_QUEUE_STTS_REG_MSK);
1143
1144 /* enable the scheduler for this queue (only) */
1145 if (txq_id == trans_pcie->cmd_queue)
1146 iwl_scd_enable_set_active(trans, BIT(txq_id));
1147 }
1148
1151 trans_pcie->txq[txq_id].active = true; 1149 trans_pcie->txq[txq_id].active = true;
1152 IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", 1150 IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
1153 txq_id, fifo, ssn & 0xff); 1151 txq_id, fifo, ssn & 0xff);
1154} 1152}
1155 1153
1156void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) 1154void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
1155 bool configure_scd)
1157{ 1156{
1158 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1157 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1159 u32 stts_addr = trans_pcie->scd_base_addr + 1158 u32 stts_addr = trans_pcie->scd_base_addr +
@@ -1172,10 +1171,12 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
1172 return; 1171 return;
1173 } 1172 }
1174 1173
1175 iwl_pcie_txq_set_inactive(trans, txq_id); 1174 if (configure_scd) {
1175 iwl_scd_txq_set_inactive(trans, txq_id);
1176 1176
1177 iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, 1177 iwl_trans_write_mem(trans, stts_addr, (void *)zero_val,
1178 ARRAY_SIZE(zero_val)); 1178 ARRAY_SIZE(zero_val));
1179 }
1179 1180
1180 iwl_pcie_txq_unmap(trans, txq_id); 1181 iwl_pcie_txq_unmap(trans, txq_id);
1181 trans_pcie->txq[txq_id].ampdu = false; 1182 trans_pcie->txq[txq_id].ampdu = false;